From 5bbcee5c0de3768d229fdba24b95624887802bbe Mon Sep 17 00:00:00 2001 From: Arijit De Date: Tue, 30 May 2023 14:58:22 +0530 Subject: [PATCH 01/15] Updated postfix_evaluation.py to support Unary operators and floating point numbers Fixes #8754 and #8724 Also merged evaluate_postfix_notations.py and postfix_evaluation.py into postfix_evaluation.py Signed-off-by: Arijit De --- .../stacks/evaluate_postfix_notations.py | 52 ----- data_structures/stacks/postfix_evaluation.py | 189 +++++++++++++++--- 2 files changed, 157 insertions(+), 84 deletions(-) delete mode 100644 data_structures/stacks/evaluate_postfix_notations.py diff --git a/data_structures/stacks/evaluate_postfix_notations.py b/data_structures/stacks/evaluate_postfix_notations.py deleted file mode 100644 index 51ea353b17de..000000000000 --- a/data_structures/stacks/evaluate_postfix_notations.py +++ /dev/null @@ -1,52 +0,0 @@ -""" -The Reverse Polish Nation also known as Polish postfix notation -or simply postfix notation. -https://en.wikipedia.org/wiki/Reverse_Polish_notation -Classic examples of simple stack implementations -Valid operators are +, -, *, /. -Each operand may be an integer or another expression. -""" -from __future__ import annotations - -from typing import Any - - -def evaluate_postfix(postfix_notation: list) -> int: - """ - >>> evaluate_postfix(["2", "1", "+", "3", "*"]) - 9 - >>> evaluate_postfix(["4", "13", "5", "/", "+"]) - 6 - >>> evaluate_postfix([]) - 0 - """ - if not postfix_notation: - return 0 - - operations = {"+", "-", "*", "/"} - stack: list[Any] = [] - - for token in postfix_notation: - if token in operations: - b, a = stack.pop(), stack.pop() - if token == "+": - stack.append(a + b) - elif token == "-": - stack.append(a - b) - elif token == "*": - stack.append(a * b) - else: - if a * b < 0 and a % b != 0: - stack.append(a // b + 1) - else: - stack.append(a // b) - else: - stack.append(int(token)) - - return stack.pop() - - -if __name__ == "__main__": - import doctest - - doctest.testmod() diff --git a/data_structures/stacks/postfix_evaluation.py b/data_structures/stacks/postfix_evaluation.py index 28128f82ec19..1644f2caffec 100644 --- a/data_structures/stacks/postfix_evaluation.py +++ b/data_structures/stacks/postfix_evaluation.py @@ -1,4 +1,11 @@ """ +The Reverse Polish Nation also known as Polish postfix notation +or simply postfix notation. +https://en.wikipedia.org/wiki/Reverse_Polish_notation +Classic examples of simple stack implementations +Valid operators are +, -, *, /. +Each operand may be an integer or another expression. + Output: Enter a Postfix Equation (space separated) = 5 6 9 * + @@ -20,49 +27,167 @@ import operator as op -def solve(post_fix): +def get_number(data: str) -> [bool, int, float, str]: + """ + Converts the given data to appropriate number if it is indeed a number, else returns the data as it is with a False + flag. This function also serves as a check of whether the input is a number or not. + + Parameters + ---------- + data : str + The data which needs to be converted to the appropriate number + + Returns + ------- + bool, int or float + Returns a tuple of (a, b) where a is True if data is indeed a number (integer or numeric) and b is either an + integer of a floating point number. If a is False, then b is 'data' + """ + try: + val = int(data) + return True, val + except ValueError: + try: + val = float(data) + return True, val + except ValueError: + return False, data + + +def is_operator(data: str) -> bool: + """ + Checks whether a given input is one of the valid operators or not. Valid operators being '-', '+', '*', '^' and '/'. + + Parameters + ---------- + data : str + The value that needs to be checked for operator + + Returns + ------- + bool + True if data is an operator else False. + """ + if data in ['-', '+', '*', '^', '/']: + return True + else: + return False + + +def evaluate(post_fix: list, verbose: bool = False) -> int: + """ + Function that evaluates postfix expression using a stack. + >>> evaluate(["2", "1", "+", "3", "*"]) + 9 + >>> evaluate(["4", "13", "5", "/", "+"]) + 6 + >>> evaluate(["2", "-", "3", "+"]) + 1 + >>> evaluate([]) + 0 + + + Parameters + ---------- + post_fix : list + The postfix expression tokenized into operators and operands and stored as a python list + + verbose : bool + Display stack contents while evaluating the expression if verbose is True + + Returns + ------- + int + The evaluated value + """ stack = [] - div = lambda x, y: int(x / y) # noqa: E731 integer division operation opr = { - "^": op.pow, - "*": op.mul, - "/": div, - "+": op.add, - "-": op.sub, + "^": lambda p, q: p ** q, + "*": lambda p, q: p * q, + "/": lambda p, q: p / q, + "+": lambda p, q: p + q, + "-": lambda p, q: p - q, } # operators & their respective operation - # print table header - print("Symbol".center(8), "Action".center(12), "Stack", sep=" | ") - print("-" * (30 + len(post_fix))) + if verbose: + # print table header + print("Symbol".center(8), "Action".center(12), "Stack", sep=" | ") + print("-" * (30 + len(post_fix))) for x in post_fix: - if x.isdigit(): # if x in digit + is_number, x = get_number(x) + if is_number: # if x is a number (integer, float) stack.append(x) # append x to stack - # output in tabular format - print(x.rjust(8), ("push(" + x + ")").ljust(12), ",".join(stack), sep=" | ") + if verbose: + # output in tabular format + print(str(x).rjust(8), ("push(" + str(x) + ")").ljust(12), stack, sep=" | ") + elif is_operator(x): + # If only 1 value is inside stack and + or - is encountered, then this is unary + or - case + if x in ['-', '+'] and len(stack) < 2: + b = stack.pop() # pop stack + if x == '-': + stack.append(-b) # negate b and push again into stack + else: # when x is unary + + stack.append(b) + if verbose: + # output in tabular format + print("".rjust(8), ("pop(" + str(b) + ")").ljust(12), stack, sep=" | ") + print(str(x).rjust(8), ("push(" + str(x) + str(b) + ")").ljust(12), stack, sep=" | ") + + else: + b = stack.pop() # pop stack + if verbose: + # output in tabular format + print("".rjust(8), ("pop(" + str(b) + ")").ljust(12), stack, sep=" | ") + + a = stack.pop() # pop stack + if verbose: + # output in tabular format + print("".rjust(8), ("pop(" + str(a) + ")").ljust(12), stack, sep=" | ") + + stack.append(opr[x](a, b)) # evaluate the 2 values popped from stack & push result to stack + if verbose: + # output in tabular format + print(str(x).rjust(8), ("push(" + str(a) + str(x) + str(b) + ")").ljust(12), stack, sep=" | ") else: - b = stack.pop() # pop stack - # output in tabular format - print("".rjust(8), ("pop(" + b + ")").ljust(12), ",".join(stack), sep=" | ") + print(f"{x} is neither a number, nor a valid operator") + break + if len(stack) == 1: # If everything executed correctly, the stack will contain only one element which is the result + _, result = get_number(stack[0]) + else: + result = None + return result + - a = stack.pop() # pop stack - # output in tabular format - print("".rjust(8), ("pop(" + a + ")").ljust(12), ",".join(stack), sep=" | ") +def is_yes(val: str) -> bool: + """ + Function that checks whether a user has entered any representation of a Yes (y, Y). + Any other input is considered as a No. - stack.append( - str(opr[x](int(a), int(b))) - ) # evaluate the 2 values popped from stack & push result to stack - # output in tabular format - print( - x.rjust(8), - ("push(" + a + x + b + ")").ljust(12), - ",".join(stack), - sep=" | ", - ) + Parameters + ----------- + val : str + The value entered by user - return int(stack[0]) + Returns + ------- + bool + True if Yes, otherwise False + """ + if val in ['Y', 'y']: + return True + else: + return False if __name__ == "__main__": - Postfix = input("\n\nEnter a Postfix Equation (space separated) = ").split(" ") - print("\n\tResult = ", solve(Postfix)) + loop = True + while loop: # Creating a loop so that user can evaluate postfix expression multiple times + expression = input("Enter a Postfix Equation (space separated) For Example: 5 6 9 * +\n: ").split(" ") + choice = input("Do you want to see stack contents while evaluating? [y/N]: ") + display = is_yes(choice) + output = evaluate(expression, display) + if output is not None: + print("Result = ", output) + choice = input("Do you want to enter another expression? [y/N]: ") + loop = is_yes(choice) From b4565e0f60b5394c6c479bf9eb2024d5f13e7820 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 09:31:16 +0000 Subject: [PATCH 02/15] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- data_structures/stacks/postfix_evaluation.py | 59 +++++++++++++++----- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/data_structures/stacks/postfix_evaluation.py b/data_structures/stacks/postfix_evaluation.py index 1644f2caffec..1d46642cdce2 100644 --- a/data_structures/stacks/postfix_evaluation.py +++ b/data_structures/stacks/postfix_evaluation.py @@ -68,7 +68,7 @@ def is_operator(data: str) -> bool: bool True if data is an operator else False. """ - if data in ['-', '+', '*', '^', '/']: + if data in ["-", "+", "*", "^", "/"]: return True else: return False @@ -102,7 +102,7 @@ def evaluate(post_fix: list, verbose: bool = False) -> int: """ stack = [] opr = { - "^": lambda p, q: p ** q, + "^": lambda p, q: p**q, "*": lambda p, q: p * q, "/": lambda p, q: p / q, "+": lambda p, q: p + q, @@ -120,39 +120,64 @@ def evaluate(post_fix: list, verbose: bool = False) -> int: stack.append(x) # append x to stack if verbose: # output in tabular format - print(str(x).rjust(8), ("push(" + str(x) + ")").ljust(12), stack, sep=" | ") + print( + str(x).rjust(8), + ("push(" + str(x) + ")").ljust(12), + stack, + sep=" | ", + ) elif is_operator(x): # If only 1 value is inside stack and + or - is encountered, then this is unary + or - case - if x in ['-', '+'] and len(stack) < 2: + if x in ["-", "+"] and len(stack) < 2: b = stack.pop() # pop stack - if x == '-': + if x == "-": stack.append(-b) # negate b and push again into stack else: # when x is unary + stack.append(b) if verbose: # output in tabular format - print("".rjust(8), ("pop(" + str(b) + ")").ljust(12), stack, sep=" | ") - print(str(x).rjust(8), ("push(" + str(x) + str(b) + ")").ljust(12), stack, sep=" | ") + print( + "".rjust(8), ("pop(" + str(b) + ")").ljust(12), stack, sep=" | " + ) + print( + str(x).rjust(8), + ("push(" + str(x) + str(b) + ")").ljust(12), + stack, + sep=" | ", + ) else: b = stack.pop() # pop stack if verbose: # output in tabular format - print("".rjust(8), ("pop(" + str(b) + ")").ljust(12), stack, sep=" | ") + print( + "".rjust(8), ("pop(" + str(b) + ")").ljust(12), stack, sep=" | " + ) a = stack.pop() # pop stack if verbose: # output in tabular format - print("".rjust(8), ("pop(" + str(a) + ")").ljust(12), stack, sep=" | ") + print( + "".rjust(8), ("pop(" + str(a) + ")").ljust(12), stack, sep=" | " + ) - stack.append(opr[x](a, b)) # evaluate the 2 values popped from stack & push result to stack + stack.append( + opr[x](a, b) + ) # evaluate the 2 values popped from stack & push result to stack if verbose: # output in tabular format - print(str(x).rjust(8), ("push(" + str(a) + str(x) + str(b) + ")").ljust(12), stack, sep=" | ") + print( + str(x).rjust(8), + ("push(" + str(a) + str(x) + str(b) + ")").ljust(12), + stack, + sep=" | ", + ) else: print(f"{x} is neither a number, nor a valid operator") break - if len(stack) == 1: # If everything executed correctly, the stack will contain only one element which is the result + if ( + len(stack) == 1 + ): # If everything executed correctly, the stack will contain only one element which is the result _, result = get_number(stack[0]) else: result = None @@ -174,7 +199,7 @@ def is_yes(val: str) -> bool: bool True if Yes, otherwise False """ - if val in ['Y', 'y']: + if val in ["Y", "y"]: return True else: return False @@ -182,8 +207,12 @@ def is_yes(val: str) -> bool: if __name__ == "__main__": loop = True - while loop: # Creating a loop so that user can evaluate postfix expression multiple times - expression = input("Enter a Postfix Equation (space separated) For Example: 5 6 9 * +\n: ").split(" ") + while ( + loop + ): # Creating a loop so that user can evaluate postfix expression multiple times + expression = input( + "Enter a Postfix Equation (space separated) For Example: 5 6 9 * +\n: " + ).split(" ") choice = input("Do you want to see stack contents while evaluating? [y/N]: ") display = is_yes(choice) output = evaluate(expression, display) From b98514164a5584f2cdf82bafad5f70a0dfe2f2b5 Mon Sep 17 00:00:00 2001 From: Arijit De Date: Tue, 30 May 2023 15:35:53 +0530 Subject: [PATCH 03/15] Updated postfix_evaluation.py to support Unary operators and floating point numbers. Fixes #8754 and formatted code to pass ruff and black test. Also merged evaluate_postfix_notations.py and postfix_evaluation.py into postfix_evaluation.py which fixes #8724 and made sure it passes doctest Signed-off-by: Arijit De --- data_structures/stacks/postfix_evaluation.py | 159 +++++++++++-------- 1 file changed, 94 insertions(+), 65 deletions(-) diff --git a/data_structures/stacks/postfix_evaluation.py b/data_structures/stacks/postfix_evaluation.py index 1644f2caffec..9860fddf08b2 100644 --- a/data_structures/stacks/postfix_evaluation.py +++ b/data_structures/stacks/postfix_evaluation.py @@ -24,13 +24,12 @@ Result = 59 """ -import operator as op - def get_number(data: str) -> [bool, int, float, str]: """ - Converts the given data to appropriate number if it is indeed a number, else returns the data as it is with a False - flag. This function also serves as a check of whether the input is a number or not. + Converts the given data to appropriate number if it is indeed a number, else returns + the data as it is with a False flag. This function also serves as a check of whether + the input is a number or not. Parameters ---------- @@ -40,8 +39,9 @@ def get_number(data: str) -> [bool, int, float, str]: Returns ------- bool, int or float - Returns a tuple of (a, b) where a is True if data is indeed a number (integer or numeric) and b is either an - integer of a floating point number. If a is False, then b is 'data' + Returns a tuple of (a, b) where 'a' is True if data is indeed a number (integer + or numeric) and 'b' is either an integer of a floating point number. + If 'a' is False, then b is 'data' """ try: val = int(data) @@ -56,7 +56,8 @@ def get_number(data: str) -> [bool, int, float, str]: def is_operator(data: str) -> bool: """ - Checks whether a given input is one of the valid operators or not. Valid operators being '-', '+', '*', '^' and '/'. + Checks whether a given input is one of the valid operators or not. + Valid operators being '-', '+', '*', '^' and '/'. Parameters ---------- @@ -68,10 +69,7 @@ def is_operator(data: str) -> bool: bool True if data is an operator else False. """ - if data in ['-', '+', '*', '^', '/']: - return True - else: - return False + return data in ["-", "+", "*", "^", "/"] def evaluate(post_fix: list, verbose: bool = False) -> int: @@ -86,11 +84,11 @@ def evaluate(post_fix: list, verbose: bool = False) -> int: >>> evaluate([]) 0 - Parameters ---------- post_fix : list - The postfix expression tokenized into operators and operands and stored as a python list + The postfix expression tokenized into operators and operands and stored as a + python list verbose : bool Display stack contents while evaluating the expression if verbose is True @@ -102,61 +100,94 @@ def evaluate(post_fix: list, verbose: bool = False) -> int: """ stack = [] opr = { - "^": lambda p, q: p ** q, + "^": lambda p, q: p**q, "*": lambda p, q: p * q, "/": lambda p, q: p / q, "+": lambda p, q: p + q, "-": lambda p, q: p - q, } # operators & their respective operation - - if verbose: - # print table header - print("Symbol".center(8), "Action".center(12), "Stack", sep=" | ") - print("-" * (30 + len(post_fix))) - - for x in post_fix: - is_number, x = get_number(x) - if is_number: # if x is a number (integer, float) - stack.append(x) # append x to stack - if verbose: - # output in tabular format - print(str(x).rjust(8), ("push(" + str(x) + ")").ljust(12), stack, sep=" | ") - elif is_operator(x): - # If only 1 value is inside stack and + or - is encountered, then this is unary + or - case - if x in ['-', '+'] and len(stack) < 2: - b = stack.pop() # pop stack - if x == '-': - stack.append(-b) # negate b and push again into stack - else: # when x is unary + - stack.append(b) + if len(post_fix) > 0: + if verbose: + # print table header + print("Symbol".center(8), "Action".center(12), "Stack", sep=" | ") + print("-" * (30 + len(post_fix))) + + for x in post_fix: + is_number, x = get_number(x) + if is_number: # if x is a number (integer, float) + stack.append(x) # append x to stack if verbose: # output in tabular format - print("".rjust(8), ("pop(" + str(b) + ")").ljust(12), stack, sep=" | ") - print(str(x).rjust(8), ("push(" + str(x) + str(b) + ")").ljust(12), stack, sep=" | ") - + print( + str(x).rjust(8), + ("push(" + str(x) + ")").ljust(12), + stack, + sep=" | ", + ) + elif is_operator(x): + # If only 1 value is inside stack and + or - is encountered + # then this is unary + or - case + if x in ["-", "+"] and len(stack) < 2: + b = stack.pop() # pop stack + if x == "-": + stack.append(-b) # negate b and push again into stack + else: # when x is unary + + stack.append(b) + if verbose: + # output in tabular format + print( + "".rjust(8), + ("pop(" + str(b) + ")").ljust(12), + stack, + sep=" | ", + ) + print( + str(x).rjust(8), + ("push(" + str(x) + str(b) + ")").ljust(12), + stack, + sep=" | ", + ) + + else: + b = stack.pop() # pop stack + if verbose: + # output in tabular format + print( + "".rjust(8), + ("pop(" + str(b) + ")").ljust(12), + stack, + sep=" | ", + ) + + a = stack.pop() # pop stack + if verbose: + # output in tabular format + print( + "".rjust(8), + ("pop(" + str(a) + ")").ljust(12), + stack, + sep=" | ", + ) + # evaluate the 2 values popped from stack & push result to stack + stack.append(opr[x](a, b)) + if verbose: + # output in tabular format + print( + str(x).rjust(8), + ("push(" + str(a) + str(x) + str(b) + ")").ljust(12), + stack, + sep=" | ", + ) else: - b = stack.pop() # pop stack - if verbose: - # output in tabular format - print("".rjust(8), ("pop(" + str(b) + ")").ljust(12), stack, sep=" | ") - - a = stack.pop() # pop stack - if verbose: - # output in tabular format - print("".rjust(8), ("pop(" + str(a) + ")").ljust(12), stack, sep=" | ") - - stack.append(opr[x](a, b)) # evaluate the 2 values popped from stack & push result to stack - if verbose: - # output in tabular format - print(str(x).rjust(8), ("push(" + str(a) + str(x) + str(b) + ")").ljust(12), stack, sep=" | ") + print(f"{x} is neither a number, nor a valid operator") + break + if len(stack) == 1: # If everything executed correctly,the stack will contain + # only one element which is the result + _, result = get_number(stack[0]) else: - print(f"{x} is neither a number, nor a valid operator") - break - if len(stack) == 1: # If everything executed correctly, the stack will contain only one element which is the result - _, result = get_number(stack[0]) - else: - result = None - return result + result = None + return result + return 0 def is_yes(val: str) -> bool: @@ -174,16 +205,14 @@ def is_yes(val: str) -> bool: bool True if Yes, otherwise False """ - if val in ['Y', 'y']: - return True - else: - return False + return val in ["Y", "y"] if __name__ == "__main__": loop = True - while loop: # Creating a loop so that user can evaluate postfix expression multiple times - expression = input("Enter a Postfix Equation (space separated) For Example: 5 6 9 * +\n: ").split(" ") + # Creating a loop so that user can evaluate postfix expression multiple times + while loop: + expression = input("Enter a Postfix Expression (space separated): ").split(" ") choice = input("Do you want to see stack contents while evaluating? [y/N]: ") display = is_yes(choice) output = evaluate(expression, display) From 70fd7fd5fe192d57e742012049872407ca4b7263 Mon Sep 17 00:00:00 2001 From: Arijit De Date: Tue, 30 May 2023 16:11:49 +0530 Subject: [PATCH 04/15] Fixed return type hinting required by pre commit for evaluate function Signed-off-by: Arijit De --- data_structures/stacks/postfix_evaluation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/stacks/postfix_evaluation.py b/data_structures/stacks/postfix_evaluation.py index dea29858dd27..bac96cdbcad9 100644 --- a/data_structures/stacks/postfix_evaluation.py +++ b/data_structures/stacks/postfix_evaluation.py @@ -74,7 +74,7 @@ def is_operator(data: str) -> bool: return data in ["-", "+", "*", "^", "/"] -def evaluate(post_fix: list, verbose: bool = False) -> int: +def evaluate(post_fix: list, verbose: bool = False) -> int | float | str | None: """ Function that evaluates postfix expression using a stack. >>> evaluate(["2", "1", "+", "3", "*"]) From ef175af3668ccfc26146a1220e22ccfe86a31d7a Mon Sep 17 00:00:00 2001 From: Arijit De Date: Tue, 30 May 2023 16:26:53 +0530 Subject: [PATCH 05/15] Changed line 186 to return only top of stack instead of calling the get_number function as it was converting float values to int, resulting in data loss. Fixes #8754 and #8724 Signed-off-by: Arijit De --- data_structures/stacks/postfix_evaluation.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/data_structures/stacks/postfix_evaluation.py b/data_structures/stacks/postfix_evaluation.py index bac96cdbcad9..cfac4f93c742 100644 --- a/data_structures/stacks/postfix_evaluation.py +++ b/data_structures/stacks/postfix_evaluation.py @@ -80,7 +80,7 @@ def evaluate(post_fix: list, verbose: bool = False) -> int | float | str | None: >>> evaluate(["2", "1", "+", "3", "*"]) 9 >>> evaluate(["4", "13", "5", "/", "+"]) - 6 + 6.6 >>> evaluate(["2", "-", "3", "+"]) 1 >>> evaluate([]) @@ -181,11 +181,9 @@ def evaluate(post_fix: list, verbose: bool = False) -> int | float | str | None: else: print(f"{x} is neither a number, nor a valid operator") break - if len(stack) == 1: # If everything executed correctly,the stack will contain - # only one element which is the result - _, result = get_number(stack[0]) - else: - result = None + # If everything executed correctly,the stack will contain + # only one element which is the result + result = stack[0] if len(stack) == 1 else None return result return 0 From d6874ad24fa963de962d2bb700411d2a35f4f2b5 Mon Sep 17 00:00:00 2001 From: Arijit De Date: Fri, 4 Aug 2023 19:14:10 +0530 Subject: [PATCH 06/15] Made the requested changes Also changed the code to make the evaluate function first convert all the numbers and then process the valid expression. --- data_structures/stacks/postfix_evaluation.py | 200 ++++++++++--------- 1 file changed, 106 insertions(+), 94 deletions(-) diff --git a/data_structures/stacks/postfix_evaluation.py b/data_structures/stacks/postfix_evaluation.py index cfac4f93c742..808162faf4ec 100644 --- a/data_structures/stacks/postfix_evaluation.py +++ b/data_structures/stacks/postfix_evaluation.py @@ -24,8 +24,14 @@ Result = 59 """ +# Defining valid unary operator symbols +UNARY_OP_SYMBOLS = ("-", "+") -def get_number(data: str) -> tuple[bool, int] | tuple[bool, float] | tuple[bool, str]: +# Defining valid binary operator symbols +BINARY_OP_SYMBOLS = ("-", "+", "*", "^", "/") + + +def get_number(data: str) -> int | float | str: """ Converts the given data to appropriate number if it is indeed a number, else returns the data as it is with a False flag. This function also serves as a check of whether @@ -43,20 +49,19 @@ def get_number(data: str) -> tuple[bool, int] | tuple[bool, float] | tuple[bool, or numeric) and 'b' is either an integer of a floating point number. If 'a' is False, then b is 'data' """ - int_val = 0 - float_val = 0.0 try: - int_val = int(data) - return True, int_val + return int(data) except ValueError: try: - float_val = float(data) - return True, float_val + return float(data) except ValueError: - return False, data + if is_operator(data): + return data + msg = f"{data} is neither a number nor a valid operator" + raise ValueError(msg) -def is_operator(data: str) -> bool: +def is_operator(data: str | int | float) -> bool: """ Checks whether a given input is one of the valid operators or not. Valid operators being '-', '+', '*', '^' and '/'. @@ -71,10 +76,10 @@ def is_operator(data: str) -> bool: bool True if data is an operator else False. """ - return data in ["-", "+", "*", "^", "/"] + return data in BINARY_OP_SYMBOLS -def evaluate(post_fix: list, verbose: bool = False) -> int | float | str | None: +def evaluate(post_fix: list[str], verbose: bool = False) -> int | float | str | None: """ Function that evaluates postfix expression using a stack. >>> evaluate(["2", "1", "+", "3", "*"]) @@ -100,7 +105,9 @@ def evaluate(post_fix: list, verbose: bool = False) -> int | float | str | None: int The evaluated value """ + x: str | int | float stack = [] + valid_expression = [] opr = { "^": lambda p, q: p**q, "*": lambda p, q: p * q, @@ -108,84 +115,87 @@ def evaluate(post_fix: list, verbose: bool = False) -> int | float | str | None: "+": lambda p, q: p + q, "-": lambda p, q: p - q, } # operators & their respective operation - if len(post_fix) > 0: + if len(post_fix) == 0: + return 0 + # Checking the list to find out whether the postfix expression is valid + for x in post_fix: + valid_expression.append(get_number(x)) + if verbose: + # print table header + print("Symbol".center(8), "Action".center(12), "Stack", sep=" | ") + print("-" * (30 + len(post_fix))) + for x in valid_expression: + if not is_operator(x): + stack.append(x) # append x to stack + if verbose: + # output in tabular format + print( + str(x).rjust(8), + ("push(" + str(x) + ")").ljust(12), + stack, + sep=" | ", + ) + continue + # If x is operator + # If only 1 value is inside stack and + or - is encountered + # then this is unary + or - case + if x in UNARY_OP_SYMBOLS and len(stack) < 2: + b = stack.pop() # pop stack + if x == "-": + b *= -1 # negate b + stack.append(b) + if verbose: + # output in tabular format + print( + "".rjust(8), + ("pop(" + str(b) + ")").ljust(12), + stack, + sep=" | ", + ) + print( + str(x).rjust(8), + ("push(" + str(x) + str(b) + ")").ljust(12), + stack, + sep=" | ", + ) + continue + b = stack.pop() # pop stack + if verbose: + # output in tabular format + print( + "".rjust(8), + ("pop(" + str(b) + ")").ljust(12), + stack, + sep=" | ", + ) + + a = stack.pop() # pop stack + if verbose: + # output in tabular format + print( + "".rjust(8), + ("pop(" + str(a) + ")").ljust(12), + stack, + sep=" | ", + ) + # evaluate the 2 values popped from stack & push result to stack + stack.append(opr[str(x)](a, b)) if verbose: - # print table header - print("Symbol".center(8), "Action".center(12), "Stack", sep=" | ") - print("-" * (30 + len(post_fix))) - for x in post_fix: - is_number, x = get_number(x) - if is_number: # if x is a number (integer, float) - stack.append(x) # append x to stack - if verbose: - # output in tabular format - print( - str(x).rjust(8), - ("push(" + str(x) + ")").ljust(12), - stack, - sep=" | ", - ) - elif is_operator(x): - # If only 1 value is inside stack and + or - is encountered - # then this is unary + or - case - if x in ["-", "+"] and len(stack) < 2: - b = stack.pop() # pop stack - if x == "-": - stack.append(-b) # negate b and push again into stack - else: # when x is unary + - stack.append(b) - if verbose: - # output in tabular format - print( - "".rjust(8), - ("pop(" + str(b) + ")").ljust(12), - stack, - sep=" | ", - ) - print( - str(x).rjust(8), - ("push(" + str(x) + str(b) + ")").ljust(12), - stack, - sep=" | ", - ) - else: - b = stack.pop() # pop stack - if verbose: - # output in tabular format - print( - "".rjust(8), - ("pop(" + str(b) + ")").ljust(12), - stack, - sep=" | ", - ) - - a = stack.pop() # pop stack - if verbose: - # output in tabular format - print( - "".rjust(8), - ("pop(" + str(a) + ")").ljust(12), - stack, - sep=" | ", - ) - # evaluate the 2 values popped from stack & push result to stack - stack.append(opr[x](a, b)) - if verbose: - # output in tabular format - print( - str(x).rjust(8), - ("push(" + str(a) + str(x) + str(b) + ")").ljust(12), - stack, - sep=" | ", - ) - else: - print(f"{x} is neither a number, nor a valid operator") - break - # If everything executed correctly,the stack will contain - # only one element which is the result - result = stack[0] if len(stack) == 1 else None - return result - return 0 + # output in tabular format + print( + str(x).rjust(8), + ("push(" + str(a) + str(x) + str(b) + ")").ljust(12), + stack, + sep=" | ", + ) + # else: + # msg = f"{x} is neither a number nor a valid operator" + # raise ValueError(msg) + # If everything executed correctly, the stack will contain + # only one element which is the result + if len(stack) != 1: + raise ArithmeticError("Input is not a valid postfix expression") + return stack[0] def is_yes(val: str) -> bool: @@ -203,18 +213,20 @@ def is_yes(val: str) -> bool: bool True if Yes, otherwise False """ - return val in ["Y", "y"] + return val in ("Y", "y") if __name__ == "__main__": loop = True # Creating a loop so that user can evaluate postfix expression multiple times - while loop: + while True: expression = input("Enter a Postfix Expression (space separated): ").split(" ") - choice = input("Do you want to see stack contents while evaluating? [y/N]: ") + choice = input( + "Do you want to see stack contents while evaluating? [y/N]: " + ).strip() display = is_yes(choice) output = evaluate(expression, display) - if output is not None: - print("Result = ", output) + print("Result = ", output) choice = input("Do you want to enter another expression? [y/N]: ") - loop = is_yes(choice) + if not is_yes(choice): + break From b4521ea28f4377774832008ecdda87ca171155c0 Mon Sep 17 00:00:00 2001 From: Arijit De Date: Fri, 4 Aug 2023 21:27:20 +0530 Subject: [PATCH 07/15] Fixes #8754, #8724 Updated postfix_evaluation.py postfix_evaluation.py now supports Unary operators and floating point numbers. Also merged evaluate_postfix_notations.py and postfix_evaluation.py into postfix_evaluation.py which fixes #8724. Added a doctest example with unary operator. --- data_structures/stacks/postfix_evaluation.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data_structures/stacks/postfix_evaluation.py b/data_structures/stacks/postfix_evaluation.py index 808162faf4ec..36062abb1644 100644 --- a/data_structures/stacks/postfix_evaluation.py +++ b/data_structures/stacks/postfix_evaluation.py @@ -88,6 +88,8 @@ def evaluate(post_fix: list[str], verbose: bool = False) -> int | float | str | 6.6 >>> evaluate(["2", "-", "3", "+"]) 1 + >>> evaluate(["-4", "5", "*", "6", "-"]) + -26 >>> evaluate([]) 0 From b4f51a6ac36d35bc8ebe87541b4b9b676f67f2be Mon Sep 17 00:00:00 2001 From: Arijit De Date: Wed, 23 Aug 2023 13:25:30 +0530 Subject: [PATCH 08/15] Fixes #8754, #8724 Updated postfix_evaluation.py postfix_evaluation.py now supports Unary operators and floating point numbers. Also merged evaluate_postfix_notations.py and postfix_evaluation.py into postfix_evaluation.py which fixes #8724. Added a doctest example with unary operator. --- data_structures/stacks/postfix_evaluation.py | 31 ++++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/data_structures/stacks/postfix_evaluation.py b/data_structures/stacks/postfix_evaluation.py index 36062abb1644..bc65052c04d0 100644 --- a/data_structures/stacks/postfix_evaluation.py +++ b/data_structures/stacks/postfix_evaluation.py @@ -31,7 +31,7 @@ BINARY_OP_SYMBOLS = ("-", "+", "*", "^", "/") -def get_number(data: str) -> int | float | str: +def parse_token(data: str) -> float | str: """ Converts the given data to appropriate number if it is indeed a number, else returns the data as it is with a False flag. This function also serves as a check of whether @@ -61,14 +61,14 @@ def get_number(data: str) -> int | float | str: raise ValueError(msg) -def is_operator(data: str | int | float) -> bool: +def is_operator(token: str | float) -> bool: """ Checks whether a given input is one of the valid operators or not. Valid operators being '-', '+', '*', '^' and '/'. Parameters ---------- - data : str + token : str The value that needs to be checked for operator Returns @@ -76,22 +76,26 @@ def is_operator(data: str | int | float) -> bool: bool True if data is an operator else False. """ - return data in BINARY_OP_SYMBOLS + return token in BINARY_OP_SYMBOLS -def evaluate(post_fix: list[str], verbose: bool = False) -> int | float | str | None: +def evaluate(post_fix: list[str], verbose: bool = False) -> float: """ Function that evaluates postfix expression using a stack. >>> evaluate(["2", "1", "+", "3", "*"]) - 9 + 9.0 >>> evaluate(["4", "13", "5", "/", "+"]) 6.6 >>> evaluate(["2", "-", "3", "+"]) - 1 + 1.0 >>> evaluate(["-4", "5", "*", "6", "-"]) - -26 + -26.0 >>> evaluate([]) 0 + >>> evaluate(["4", "-", "6", "7", "/", "9", "8"]) + Traceback (most recent call last): + ... + ArithmeticError: Input is not a valid postfix expression Parameters ---------- @@ -104,10 +108,9 @@ def evaluate(post_fix: list[str], verbose: bool = False) -> int | float | str | Returns ------- - int + float The evaluated value """ - x: str | int | float stack = [] valid_expression = [] opr = { @@ -120,8 +123,7 @@ def evaluate(post_fix: list[str], verbose: bool = False) -> int | float | str | if len(post_fix) == 0: return 0 # Checking the list to find out whether the postfix expression is valid - for x in post_fix: - valid_expression.append(get_number(x)) + valid_expression = [parse_token(token) for token in post_fix] if verbose: # print table header print("Symbol".center(8), "Action".center(12), "Stack", sep=" | ") @@ -190,14 +192,11 @@ def evaluate(post_fix: list[str], verbose: bool = False) -> int | float | str | stack, sep=" | ", ) - # else: - # msg = f"{x} is neither a number nor a valid operator" - # raise ValueError(msg) # If everything executed correctly, the stack will contain # only one element which is the result if len(stack) != 1: raise ArithmeticError("Input is not a valid postfix expression") - return stack[0] + return float(stack[0]) def is_yes(val: str) -> bool: From 9a15148f8becc9616165e3581a6b88588c2eecbe Mon Sep 17 00:00:00 2001 From: Arijit De Date: Wed, 23 Aug 2023 16:01:23 +0530 Subject: [PATCH 09/15] Fixes #8754, #8724 Updated the parse_token function of postfix_evaluation.py ostfix_evaluation.py now supports Unary operators and floating point numbers. Also merged evaluate_postfix_notations.py and postfix_evaluation.py into postfix_evaluation.py which fixes #8724. Added a doctest example with unary operator and invalid expression. --- data_structures/stacks/postfix_evaluation.py | 23 ++++++++------------ 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/data_structures/stacks/postfix_evaluation.py b/data_structures/stacks/postfix_evaluation.py index bc65052c04d0..c3a0024f4082 100644 --- a/data_structures/stacks/postfix_evaluation.py +++ b/data_structures/stacks/postfix_evaluation.py @@ -31,7 +31,7 @@ BINARY_OP_SYMBOLS = ("-", "+", "*", "^", "/") -def parse_token(data: str) -> float | str: +def parse_token(token: str | float) -> float | str: """ Converts the given data to appropriate number if it is indeed a number, else returns the data as it is with a False flag. This function also serves as a check of whether @@ -39,26 +39,21 @@ def parse_token(data: str) -> float | str: Parameters ---------- - data : str + token : str or float The data which needs to be converted to the appropriate number Returns ------- - bool, int or float - Returns a tuple of (a, b) where 'a' is True if data is indeed a number (integer - or numeric) and 'b' is either an integer of a floating point number. - If 'a' is False, then b is 'data' + float or str + Returns a float if `token` is a number and returns `token` if it's an operator """ + if is_operator(token): + return token try: - return int(data) + return float(token) except ValueError: - try: - return float(data) - except ValueError: - if is_operator(data): - return data - msg = f"{data} is neither a number nor a valid operator" - raise ValueError(msg) + msg = f"{token} is neither a number nor a valid operator" + raise ValueError(msg) def is_operator(token: str | float) -> bool: From c11b18fed8b287f77acac164a7bfc6bf3e0c5383 Mon Sep 17 00:00:00 2001 From: Arijit De Date: Wed, 23 Aug 2023 16:33:01 +0530 Subject: [PATCH 10/15] Fixes #8754, #8724 Updated postfix_evaluation.py postfix_evaluation.py now supports Unary operators and floating point numbers. Also merged evaluate_postfix_notations.py and postfix_evaluation.py into postfix_evaluation.py which fixes #8724. Added a doctest example with unary operator and invalid expression. --- data_structures/stacks/postfix_evaluation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data_structures/stacks/postfix_evaluation.py b/data_structures/stacks/postfix_evaluation.py index c3a0024f4082..dc8fd192265f 100644 --- a/data_structures/stacks/postfix_evaluation.py +++ b/data_structures/stacks/postfix_evaluation.py @@ -31,7 +31,7 @@ BINARY_OP_SYMBOLS = ("-", "+", "*", "^", "/") -def parse_token(token: str | float) -> float | str: +def parse_token(token: str) -> float | str: """ Converts the given data to appropriate number if it is indeed a number, else returns the data as it is with a False flag. This function also serves as a check of whether @@ -39,7 +39,7 @@ def parse_token(token: str | float) -> float | str: Parameters ---------- - token : str or float + token : str The data which needs to be converted to the appropriate number Returns @@ -63,7 +63,7 @@ def is_operator(token: str | float) -> bool: Parameters ---------- - token : str + token : str or float The value that needs to be checked for operator Returns From b2bb0afd5ea91eea882574582b5d4fbe3d733237 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Wed, 23 Aug 2023 13:37:39 +0200 Subject: [PATCH 11/15] Update postfix_evaluation.py --- data_structures/stacks/postfix_evaluation.py | 119 +++++++------------ 1 file changed, 46 insertions(+), 73 deletions(-) diff --git a/data_structures/stacks/postfix_evaluation.py b/data_structures/stacks/postfix_evaluation.py index dc8fd192265f..ea000f79a183 100644 --- a/data_structures/stacks/postfix_evaluation.py +++ b/data_structures/stacks/postfix_evaluation.py @@ -1,8 +1,8 @@ """ -The Reverse Polish Nation also known as Polish postfix notation -or simply postfix notation. +The Reverse Polish Nation also known as Polish postfix notation or simply postfix +notation. https://en.wikipedia.org/wiki/Reverse_Polish_notation -Classic examples of simple stack implementations +Classic examples of simple stack implementations. Valid operators are +, -, *, /. Each operand may be an integer or another expression. @@ -27,11 +27,16 @@ # Defining valid unary operator symbols UNARY_OP_SYMBOLS = ("-", "+") -# Defining valid binary operator symbols -BINARY_OP_SYMBOLS = ("-", "+", "*", "^", "/") +# operators & their respective operation +OPERATORS = { + "^": lambda p, q: p**q, + "*": lambda p, q: p * q, + "/": lambda p, q: p / q, + "+": lambda p, q: p + q, + "-": lambda p, q: p - q, +} - -def parse_token(token: str) -> float | str: +def parse_token(token: str | float) -> float | str: """ Converts the given data to appropriate number if it is indeed a number, else returns the data as it is with a False flag. This function also serves as a check of whether @@ -39,15 +44,14 @@ def parse_token(token: str) -> float | str: Parameters ---------- - token : str - The data which needs to be converted to the appropriate number + token: The data which needs to be converted to the appropriate operator or number. Returns ------- float or str - Returns a float if `token` is a number and returns `token` if it's an operator + Returns a float if `token` is a number or a str if `token` is an operator """ - if is_operator(token): + if token in OPERATORS: return token try: return float(token) @@ -56,29 +60,25 @@ def parse_token(token: str) -> float | str: raise ValueError(msg) -def is_operator(token: str | float) -> bool: - """ - Checks whether a given input is one of the valid operators or not. - Valid operators being '-', '+', '*', '^' and '/'. - - Parameters - ---------- - token : str or float - The value that needs to be checked for operator - - Returns - ------- - bool - True if data is an operator else False. - """ - return token in BINARY_OP_SYMBOLS - - def evaluate(post_fix: list[str], verbose: bool = False) -> float: """ Function that evaluates postfix expression using a stack. + >>> evaluate(["0"]) + 0.0 + >>> evaluate(["-0"]) + -0.0 + >>> evaluate(["1"]) + 1.0 + >>> evaluate(["-1"]) + -1.0 + >>> evaluate(["-1.1"]) + -1.1 >>> evaluate(["2", "1", "+", "3", "*"]) 9.0 + >>> evaluate(["2", "1.9", "+", "3", "*"]) + 11.7 + >>> evaluate(["2", "-1.9", "+", "3", "*"]) + 0.30000000000000027 >>> evaluate(["4", "13", "5", "/", "+"]) 6.6 >>> evaluate(["2", "-", "3", "+"]) @@ -106,16 +106,7 @@ def evaluate(post_fix: list[str], verbose: bool = False) -> float: float The evaluated value """ - stack = [] - valid_expression = [] - opr = { - "^": lambda p, q: p**q, - "*": lambda p, q: p * q, - "/": lambda p, q: p / q, - "+": lambda p, q: p + q, - "-": lambda p, q: p - q, - } # operators & their respective operation - if len(post_fix) == 0: + if not post_fix: return 0 # Checking the list to find out whether the postfix expression is valid valid_expression = [parse_token(token) for token in post_fix] @@ -123,14 +114,15 @@ def evaluate(post_fix: list[str], verbose: bool = False) -> float: # print table header print("Symbol".center(8), "Action".center(12), "Stack", sep=" | ") print("-" * (30 + len(post_fix))) + stack = [] for x in valid_expression: - if not is_operator(x): + if x not in OPERATORS: stack.append(x) # append x to stack if verbose: # output in tabular format print( - str(x).rjust(8), - ("push(" + str(x) + ")").ljust(12), + f"{x}".rjust(8), + f"push({x})".ljust(12), stack, sep=" | ", ) @@ -147,13 +139,13 @@ def evaluate(post_fix: list[str], verbose: bool = False) -> float: # output in tabular format print( "".rjust(8), - ("pop(" + str(b) + ")").ljust(12), + f"pop({b})".ljust(12), stack, sep=" | ", ) print( str(x).rjust(8), - ("push(" + str(x) + str(b) + ")").ljust(12), + f"push({x}{b})".ljust(12), stack, sep=" | ", ) @@ -163,7 +155,7 @@ def evaluate(post_fix: list[str], verbose: bool = False) -> float: # output in tabular format print( "".rjust(8), - ("pop(" + str(b) + ")").ljust(12), + f"pop({b})".ljust(12), stack, sep=" | ", ) @@ -173,17 +165,17 @@ def evaluate(post_fix: list[str], verbose: bool = False) -> float: # output in tabular format print( "".rjust(8), - ("pop(" + str(a) + ")").ljust(12), + f"pop({a})".ljust(12), stack, sep=" | ", ) # evaluate the 2 values popped from stack & push result to stack - stack.append(opr[str(x)](a, b)) + stack.append(OPERATORS[x](a, b)) if verbose: # output in tabular format print( str(x).rjust(8), - ("push(" + str(a) + str(x) + str(b) + ")").ljust(12), + f"push({a}{x}{b})".ljust(12), stack, sep=" | ", ) @@ -194,35 +186,16 @@ def evaluate(post_fix: list[str], verbose: bool = False) -> float: return float(stack[0]) -def is_yes(val: str) -> bool: - """ - Function that checks whether a user has entered any representation of a Yes (y, Y). - Any other input is considered as a No. - - Parameters - ----------- - val : str - The value entered by user - - Returns - ------- - bool - True if Yes, otherwise False - """ - return val in ("Y", "y") - - if __name__ == "__main__": - loop = True - # Creating a loop so that user can evaluate postfix expression multiple times + # Create a loop so that the user can evaluate postfix expressions multiple times while True: expression = input("Enter a Postfix Expression (space separated): ").split(" ") - choice = input( + display = input( "Do you want to see stack contents while evaluating? [y/N]: " - ).strip() - display = is_yes(choice) + ).strip().lower() == "y" output = evaluate(expression, display) print("Result = ", output) - choice = input("Do you want to enter another expression? [y/N]: ") - if not is_yes(choice): + if input( + "Do you want to enter another expression? [y/N]: " + ).strip().lower() != "y": break From b0c44a685628dd9986302acadfebeb5ddcf5a151 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Wed, 23 Aug 2023 13:39:52 +0200 Subject: [PATCH 12/15] Update postfix_evaluation.py --- data_structures/stacks/postfix_evaluation.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/data_structures/stacks/postfix_evaluation.py b/data_structures/stacks/postfix_evaluation.py index ea000f79a183..5a604aab8c27 100644 --- a/data_structures/stacks/postfix_evaluation.py +++ b/data_structures/stacks/postfix_evaluation.py @@ -34,7 +34,8 @@ "/": lambda p, q: p / q, "+": lambda p, q: p + q, "-": lambda p, q: p - q, -} +} + def parse_token(token: str | float) -> float | str: """ @@ -190,12 +191,16 @@ def evaluate(post_fix: list[str], verbose: bool = False) -> float: # Create a loop so that the user can evaluate postfix expressions multiple times while True: expression = input("Enter a Postfix Expression (space separated): ").split(" ") - display = input( - "Do you want to see stack contents while evaluating? [y/N]: " - ).strip().lower() == "y" + display = ( + input("Do you want to see stack contents while evaluating? [y/N]: ") + .strip() + .lower() + == "y" + ) output = evaluate(expression, display) print("Result = ", output) - if input( - "Do you want to enter another expression? [y/N]: " - ).strip().lower() != "y": + if ( + input("Do you want to enter another expression? [y/N]: ").strip().lower() + != "y" + ): break From d3f4ee8bbd6d4d9b66dfc73d6ad67c403c5313cd Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Wed, 23 Aug 2023 13:42:32 +0200 Subject: [PATCH 13/15] Update postfix_evaluation.py --- data_structures/stacks/postfix_evaluation.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/data_structures/stacks/postfix_evaluation.py b/data_structures/stacks/postfix_evaluation.py index 5a604aab8c27..c58598a12fcb 100644 --- a/data_structures/stacks/postfix_evaluation.py +++ b/data_structures/stacks/postfix_evaluation.py @@ -191,16 +191,10 @@ def evaluate(post_fix: list[str], verbose: bool = False) -> float: # Create a loop so that the user can evaluate postfix expressions multiple times while True: expression = input("Enter a Postfix Expression (space separated): ").split(" ") - display = ( - input("Do you want to see stack contents while evaluating? [y/N]: ") - .strip() - .lower() - == "y" - ) - output = evaluate(expression, display) + prompt = "Do you want to see stack contents while evaluating? [y/N]: " + verbose = input(prompt).strip().lower() == "y" + output = evaluate(expression, verbose) print("Result = ", output) - if ( - input("Do you want to enter another expression? [y/N]: ").strip().lower() - != "y" - ): + prompt = "Do you want to enter another expression? [y/N]: " + if input(prompt).strip().lower() != "y": break From 0b1627a12d13d6505e02f55b33c713a1914cd9fc Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Wed, 23 Aug 2023 14:25:18 +0200 Subject: [PATCH 14/15] Update postfix_evaluation.py --- data_structures/stacks/postfix_evaluation.py | 26 ++++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/data_structures/stacks/postfix_evaluation.py b/data_structures/stacks/postfix_evaluation.py index c58598a12fcb..79b930b38481 100644 --- a/data_structures/stacks/postfix_evaluation.py +++ b/data_structures/stacks/postfix_evaluation.py @@ -1,5 +1,5 @@ """ -The Reverse Polish Nation also known as Polish postfix notation or simply postfix +Reverse Polish Nation is also known as Polish postfix notation or simply postfix notation. https://en.wikipedia.org/wiki/Reverse_Polish_notation Classic examples of simple stack implementations. @@ -39,13 +39,13 @@ def parse_token(token: str | float) -> float | str: """ - Converts the given data to appropriate number if it is indeed a number, else returns - the data as it is with a False flag. This function also serves as a check of whether - the input is a number or not. + Converts the given data to the appropriate number if it is indeed a number, else + returns the data as it is with a False flag. This function also serves as a check + of whether the input is a number or not. Parameters ---------- - token: The data which needs to be converted to the appropriate operator or number. + token: The data that needs to be converted to the appropriate operator or number. Returns ------- @@ -63,7 +63,7 @@ def parse_token(token: str | float) -> float | str: def evaluate(post_fix: list[str], verbose: bool = False) -> float: """ - Function that evaluates postfix expression using a stack. + Evaluate postfix expression using a stack. >>> evaluate(["0"]) 0.0 >>> evaluate(["-0"]) @@ -95,11 +95,11 @@ def evaluate(post_fix: list[str], verbose: bool = False) -> float: Parameters ---------- - post_fix : list - The postfix expression tokenized into operators and operands and stored as a - python list + post_fix: + The postfix expression is tokenized into operators and operands and stored + as a Python list - verbose : bool + verbose: Display stack contents while evaluating the expression if verbose is True Returns @@ -129,7 +129,7 @@ def evaluate(post_fix: list[str], verbose: bool = False) -> float: ) continue # If x is operator - # If only 1 value is inside stack and + or - is encountered + # If only 1 value is inside the stack and + or - is encountered # then this is unary + or - case if x in UNARY_OP_SYMBOLS and len(stack) < 2: b = stack.pop() # pop stack @@ -175,12 +175,12 @@ def evaluate(post_fix: list[str], verbose: bool = False) -> float: if verbose: # output in tabular format print( - str(x).rjust(8), + f"{x}".rjust(8), f"push({a}{x}{b})".ljust(12), stack, sep=" | ", ) - # If everything executed correctly, the stack will contain + # If everything is executed correctly, the stack will contain # only one element which is the result if len(stack) != 1: raise ArithmeticError("Input is not a valid postfix expression") From 51df05ce11ca03cd0b6f1c0796f469c3fb0e8b93 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Wed, 23 Aug 2023 14:30:48 +0200 Subject: [PATCH 15/15] Update postfix_evaluation.py --- data_structures/stacks/postfix_evaluation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/stacks/postfix_evaluation.py b/data_structures/stacks/postfix_evaluation.py index 79b930b38481..03a87b9e0fa3 100644 --- a/data_structures/stacks/postfix_evaluation.py +++ b/data_structures/stacks/postfix_evaluation.py @@ -171,7 +171,7 @@ def evaluate(post_fix: list[str], verbose: bool = False) -> float: sep=" | ", ) # evaluate the 2 values popped from stack & push result to stack - stack.append(OPERATORS[x](a, b)) + stack.append(OPERATORS[x](a, b)) # type: ignore[index] if verbose: # output in tabular format print(