Python Forum
Evaluating arithmetic expression with recursion.
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Evaluating arithmetic expression with recursion.
#1
Hi, I am tasked to make a recursive function which evaluates the expression starting from the given position. Return the value and the first position after the read sub-expression. If the string starting at the given expression is not an arithmetic expression, return None. To avoid divisions by zero we do not allow division in arithmetic expressions.
  • If a is a number, then evaluate(a) is that number.
  • If a and b are arithmetic expressions, then evaluate((a+b)) = evaluate(a)+evaluate(b), evaluate((a-b)) = evaluate(a)-evaluate(b), and evaluate((a*b)) = evaluate(a)*evaluate(b).

def read_positive_integer(text, position):
    text_mod = text[position:]
    if not (text[position]).isdigit():
        return None
    try:
        return (int(text_mod), len(text_mod) + position )
    except:
        return read_positive_integer(text[:-1], position)

def evaluate(expression, position):
    r = read_positive_integer(expression, position)
    if r != None:
        return r

    else:
        if expression[position] == "(":
            a,pos = evaluate(expression, position+1)
            operator = expression[pos]
            b,pos = evaluate(expression, pos+1)
            op_dict = {"+":a+b, "-":a-b, "*":a*b}

            if expression[pos] == ")":
                return op_dict[operator] 
I have tried giving it the following input:
evaluate("((1-1)+(2*1))", 0)
But it outputs this error:
Error:
cannot unpack non-iterable int object
PD: The function read_positive_integer has no flaws and it works as it should (it got accepted by the auto-corrector)
Reply
#2
On line 17a,pos =is looking for two return values andevaluate () is only returning one. This is the source of the error that you are getting.
Reply
#3
(Dec-16-2021, 01:40 PM)muddybucket Wrote: Hi, I am tasked to make a recursive function which evaluates the expression starting from the given position. Return the value and the first position after the read sub-expression. If the string starting at the given expression is not an arithmetic expression, return None. To avoid divisions by zero we do not allow division in arithmetic expressions.
  • If a is a number, then evaluate(a) is that number.
  • If a and b are arithmetic expressions, then evaluate((a+b)) = evaluate(a)+evaluate(b), evaluate((a-b)) = evaluate(a)-evaluate(b), and evaluate((a*b)) = evaluate(a)*evaluate(b).

def read_positive_integer(text, position):
    text_mod = text[position:]
    if not (text[position]).isdigit():
        return None
    try:
        return (int(text_mod), len(text_mod) + position )
    except:
        return read_positive_integer(text[:-1], position)

def evaluate(expression, position):
    r = read_positive_integer(expression, position)
    if r != None:
        return r

    else:
        if expression[position] == "(":
            a,pos = evaluate(expression, position+1)
            operator = expression[pos]
            b,pos = evaluate(expression, pos+1)
            op_dict = {"+":a+b, "-":a-b, "*":a*b}

            if expression[pos] == ")":
                return op_dict[operator] 
I have tried giving it the following input:
evaluate("((1-1)+(2*1))", 0)
But it outputs this error:
Error:
cannot unpack non-iterable int object
PD: The function read_positive_integer has no flaws and it works as it should (it got accepted by the auto-corrector)

The error occurred on some line. Without knowing what line that is, it is hard to guess.
Reply
#4
Your error occurs when this code executes:
            if expression[pos] == ")":
                return op_dict[operator] 
This is seen if you print out the value(s) returned by evaluate()
def read_positive_integer(text, position):
    text_mod = text[position:]
    if not (text[position]).isdigit():
        return None
    try:
        return (int(text_mod), len(text_mod) + position )
    except:
        return read_positive_integer(text[:-1], position)
 
def evaluate(expression, position):
    r = read_positive_integer(expression, position)
    if r != None:
        return r
 
    else:
        if expression[position] == "(":
            results = evaluate(expression, position+1)
            print("A", results)
            a = results[0]
            pos = results[1]
            operator = expression[pos]
            results = evaluate(expression, pos+1)
            print("B", results)
            b = results[0]
            pos = results[1]
            op_dict = {"+":a+b, "-":a-b, "*":a*b}
 
            if expression[pos] == ")":
                print("C", op_dict[operator])
                return op_dict[operator]
                
evaluate("((1-1)+(2*1))", 0)
Output:
A (1, 3) B (1, 5) C 0 A 0
When you execute the operator you are only returning the result and not a position. This raises a type error when the return value is unpacked.

Changing your code to return a position for every condition fixes the error.
def read_positive_integer(text, position):
    text_mod = text[position:]
    if not (text[position]).isdigit():
        return None
    try:
        return (int(text_mod), len(text_mod) + position )
    except:
        return read_positive_integer(text[:-1], position)
 
def evaluate(expression, position):
    r = read_positive_integer(expression, position)
    if r != None:
        return r
 
    else:
        if expression[position] == "(":
            a, pos = evaluate(expression, position+1)
            operator = expression[pos]
            b, pos = evaluate(expression, pos+1)
            op_dict = {"+":a+b, "-":a-b, "*":a*b}
 
            if expression[pos] == ")":
                print("C", op_dict[operator])
                return op_dict[operator], pos

evaluate("((1-1)+(2*1))", 0)
And gets you to the next error.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Simple arithmetic question ebolisa 5 2,075 Dec-15-2021, 04:56 PM
Last Post: deanhystad
  Magic Method Arithmetic Operators ClownPrinceOfCrime 3 2,330 Jan-10-2021, 03:24 PM
Last Post: ndc85430
  Scipy kolmogorov smirnov test for evaluating the fitting of a non-normal distribution mcva 0 1,997 May-26-2020, 12:01 PM
Last Post: mcva
  Pass results of expression to another expression cmdr_eggplant 2 2,298 Mar-26-2020, 06:59 AM
Last Post: ndc85430
  floating point arithmetic exDeveloper 2 2,122 Sep-25-2019, 04:33 PM
Last Post: DeaD_EyE
  Evaluating multiple lists in a tuple cdogo 2 2,491 Apr-14-2019, 09:15 AM
Last Post: Yoriz
  Need help with arithmetic calculation rakesh561 0 1,895 Mar-08-2019, 09:54 PM
Last Post: rakesh561
  Scoping Question: If else in for loop not evaluating i as expected datasundae 3 3,201 May-25-2018, 06:43 PM
Last Post: datasundae

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020