কম্পিউটার টিউটোরিয়াল

পাইথনে এক্সেল স্প্রেডশিট অপারেশন (ফর্মুলা ইভ্যালুয়েশন) করা


সমস্যা বিবরণ

একটি ২D ম্যাট্রিক্স দেওয়া আছে যা এক্সেল স্প্রেডশিটকে প্রতীকী করে। প্রতিটি সেলে হতে পারে:

  • সামান্য ভ্যালু (যেমন: "7", "B1")
  • ফর্মুলা (যেমন: "=A1+A2", "=2+5")
সকল ফর্মুলা ইভ্যালুয়েট করে ফাইনাল ভ্যালু ম্যাট্রিক্স রিটার্ন করতে হবে।

উদাহরণ


Input:  [["B1", "7", "0"],
         ["3", "5", "=A1+A2"]]

Output: [["7", "7", "0"],
         ["3", "5", "10"]]

ব্যাখ্যা: B1 = 7 (রো ০, কলাম ১), A1=7, A2=3 → A1+A2 = 10

সমাধানের কৌশল

রিকার্সিভ ফাংশন দিয়ে সেল রিজলভ করুন। সাইকেল (circular reference) হ্যান্ডলিং জটিল, এখানে ধরে নেওয়া হয়েছে সাইকেল নেই।

পাইথন কোড


class Solution:
    def solve(self, matrix):
        def resolve(s):
            """স্ট্রিংকে ভ্যালুতে রিজলভ করুন"""
            try:
                return int(s)  # নাম্বার হলে ডাইরেক্ট
            except:
                # সেল রেফারেন্স (যেমন "B1") হলে রিকার্সিভ কল
                return solve(*getIdx(s))
        
        def getIdx(s):
            """'B1' -> (row=0, col=1)"""
            return [int(s[1:]) - 1, ord(s[0]) - ord("A")]
        
        def do(a, b, op):
            """অপারেশন এক্সিকিউট"""
            if op == "+": return a + b
            if op == "-": return a - b
            if op == "*": return a * b
            if op == "/": return a / b
        
        def solve(i, j):
            """সেল (i,j) এর ফাইনাল ভ্যালু"""
            try:
                return int(matrix[i][j])
            except:
                s = matrix[i][j]
                if s[0] == "=":
                    # ফর্মুলা পার্স: =A1+B2
                    for c in s[2:]:
                        if c in "+-*/":
                            op = c
                            break
                    a, b = s[1:].split(op)
                    aRes, bRes = resolve(a), resolve(b)
                    return do(aRes, bRes, op)
                else:
                    # সেল রেফারেন্স
                    return solve(*getIdx(s))
        
        # সব সেল আপডেট
        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                matrix[i][j] = str(solve(i, j))
        
        return matrix

ob = Solution()
matrix = [["B1", "7", "0"], ["3", "5", "=A1+A2"]]
print(ob.solve(matrix))
# [['7', '7', '0'], ['3', '5', '10']]

লিমিটেশন ও এক্সটেনশন

  • সাইকেল ডিটেকশন নেই (A1=B1, B1=A1 → ইনফিনিট রিকার্শন)
  • রেঞ্জ রেফারেন্স (A1:A10) সাপোর্ট নেই
  • ফাংশন (SUM, AVERAGE) সাপোর্ট নেই
  • রিয়েল ওয়ার্ল্ডে openpyxl বা xlwings ব্যবহার করুন

উপসংহার

রিকার্সিভ ডিসেন্ড পার্সিং দিয়ে সিম্পল এক্সেল ফর্মুলা ইভ্যালুয়েটর বানানো সম্ভব। প্রোডাকশনে বিদ্যমান লাইব্রেরি ব্যবহার করুন।

  1. পাইথনে চেসবোর্ডের সেলের রঙ (সাদা/কালো) নির্ণয়

  2. পাইথনে দুটি আয়তাকার ওভারল্যাপ হচ্ছে কিনা যাচাই করার প্রোগ্রাম

  3. পাইথনে তালিকার প্রতিটি উপাদানের সাথে দেওয়া মান দিয়ে অপারেশন চালানোর প্রোগ্রাম

  4. পাইথন প্রোগ্রামে callable() ফাংশন