Answered step by step
Verified Expert Solution
Question
1 Approved Answer
Im trying to build a calculator using these two python programs (PYTHON ONLY) This is the base Calculator Code: # Name : # Project: Calculator
Im trying to build a calculator using these two python programs (PYTHON ONLY)
This is the base Calculator Code:
# Name : # Project: Calculator pt.2 """Reverse Polish calculator. This RPN calculator creates an expression tree from the input. It prints the expression in algebraic notation and then prints the result of evaluating it. """ import lex import expr import io from typing import List BINOPS = {lex.TokenCat.PLUS: expr.Plus, lex.TokenCat.TIMES: expr.Times, lex.TokenCat.DIV: expr.Div, lex.TokenCat.MINUS: expr.Minus } UNOPS = {lex.TokenCat.ABS: expr.Abs, lex.TokenCat.NEG: expr.Neg} def rpn_parse(text: str) -> List[expr.Expr]: """Parse text in reverse Polish notation into a list of expressions (exactly one if the expression is balanced).""" stack = [] tokens = lex.TokenStream(io.StringIO(text)) while tokens.has_more(): tok = tokens.take() if tok.kind == lex.TokenCat.INT: stack.append(expr.IntConst(int(tok.value))) elif tok.kind in BINOPS: binop_class = BINOPS[tok.kind] right = stack.pop() left = stack.pop() stack.append(binop_class(left, right)) elif tok.kind in UNOPS: unop_class = UNOPS[tok.kind] left = stack.pop() stack.append(unop_class(left)) elif tok.kind == lex.TokenCat.VAR: stack.append(expr.Var(tok.value)) elif tok.kind == lex.TokenCat.ASSIGN: assign_class = expr.Assign right = stack.pop() left = stack.pop() # Trying to reverse right and left stack.append(assign_class(right, left)) return stack def calc(text: str): """Read and evaluate a single line formula.""" try: tokens = lex.TokenStream(io.StringIO(text)) stack = [ ] while tokens.has_more(): tok = tokens.take() if tok.kind == lex.TokenCat.INT: stack.append(expr.IntConst(int(tok.value))) elif tok.kind == lex.TokenCat.PLUS: right = stack.pop() left = stack.pop() stack.append(expr.Plus(left, right)) except lex.LexicalError as e: raise ValueError(f"Lexical error {e}") return except IndexError: # Stack underflow means the expression was imbalanced raise ValueError(f"Imbalanced RPN expression, missing operand at {tok.value}") return if len(stack) == 0: print("(No expression)") else: # For a balanced expression there will be one Expr object # on the stack, but if there are more we'll just evaluate # and print each of them for exp in stack: print(f"{exp} => {exp.eval()}") def rpn_calc(): txt = input("Expression (return to quit):") while len(txt.strip()) > 0: calc(txt) txt = input("Expression (return to quit):") print("Bye! Thanks for the math!") if __name__ == "__main__": """RPN Calculator as main program""" rpn_calc()
((This is the code for the operations but when I run the first code it just comes out as 3 => 3. PLease help))
# Name: # Project: Calculator # One global environment (scope) for # the calculator ENV = dict() def env_clear(): """Clear all variables in calculator memory""" global ENV ENV = dict() class Expr(object): """ This will be the Abstract base class of all expressions.""" # def __init__(self): # raise NotImplementedError("Each concrete Expr") def eval(self) -> "IntConst": """Implementations of eval should be returning an integer constant.""" raise NotImplementedError("Each concrete Expr class must define 'eval' ") def __str__(self) -> str: """__str__ Implementation should return the expression in algebraic notation. """ raise NotImplementedError("Concrete Expr class must define __str__") def __repr__(self) -> str: """__repr__ Implements should return a string that looks like the constructer """ raise NotImplementedError("Concrete Expr classes must define __repr__") class IntConst(Expr): def __init__(self, value: int): self.value = value # Probs wrong Tbh def eval(self) -> "IntConst": return IntConst(self.value) def __str__(self): return f"{self.value}" def __repr__(self): return f"IntConst({self.value})" def __eq__(self, other: Expr): return isinstance(other, IntConst) and self.value == other.value class BinOp(Expr): def __init__(self): raise NotImplementedError("Do not instantiate BinOp") def _binop_init(self, left: Expr, right: Expr, op_sym: str, op_name: str): self.left = left self.right = right self.op_sym = op_sym self.op_name = op_name def __str__(self) -> str: """Implementing of __str__ should return the expression in algebraic notation""" return f"({self.left} {self.op_sym} {self.right})" def __repr__(self) -> str: """__repr__ Implements should return a string that looks like the constructor """ return f"{self.op_name}({repr(self.left)}, {repr(self.right)})" def eval(self) -> "IntConst": """Implementing of eval should return an int constant.""" left_val = self.left.eval() right_val = self.right.eval() return IntConst(self._apply(left_val.value, right_val.value)) class UnOp(Expr): def __init__(self): raise NotImplementedError("Do not instantiate UnOp") def _unop_init(self, left: Expr, opsym_unO: str, opname_unO: str): self.left = left self.opsym_unO = opsym_unO self.opname_unO = opname_unO def __str__(self) -> str: return f"{self.opsym_unO}{self.left}" def __repr__(self) -> str: return f"{self.opname_unO}({repr(self.left)})" def eval(self) -> "IntConst": """Each concrete subclass must define _apply(int, int)->int""" left_val = self.left.eval() return IntConst(self._apply(left_val.value)) class Plus(BinOp): """Expr + Expr""" def __init__(self, left: Expr, right: Expr): self._binop_init(left, right, "+", "Plus") def _apply(self, left: int, right: int) -> int: return left + right class Times(BinOp): """left * right""" def __init__(self, left: Expr, right: Expr): self._binop_init(left, right, "*", "Times") def _apply(self, left: int, right: int) -> int: return left * right class Minus(BinOp): """left - right""" def __init__(self, left: Expr, right: Expr): self._binop_init(left, right, "-", "Minus") def _apply(self, left: int, right: int) -> int: return left - right class Div(BinOp): """ left // right""" def __init__(self, left: Expr, right: Expr): self._binop_init(left, right, "/", "Div") def _apply(self, left: int, right: int) -> int: return left // right class Abs(UnOp): """ @ Expr""" def __init__(self, left: Expr): self._unop_init(left, "@ ", "Abs") def _apply(self, left: int): return abs(left) def _apply(left: int) -> int: return 0 - left class Neg(UnOp): def __init__(self, left: Expr): self._unop_init(left, "~ ", "Neg") class UndefinedVariable(Exception): pass class Var(Expr): def __init__(self, name: str): self.name = name def __str__(self): return self.name def __repr__(self): return f"Var({self.name})" def eval(self): global ENV if self.name in ENV: return ENV[self.name] else: raise UndefinedVariable(f"{self.name} has not been assigned a value") def assign(self, val: IntConst): global ENV ENV[self.name] = val class Assign(Expr): """Assignment: x = E represented as Assign(x, E)""" def __init__(self, left: Var, right: Expr): assert isinstance(left, Var) self.left = left self.right = right def eval(self) -> IntConst: r_val = self.right.eval() self.left.assign(r_val) return r_val def __str__(self): return f"{self.left} = {self.right}" def __repr__(self): return f"{repr(self.left)} = Var{repr(self.right)}"
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started