HW3FINALBEST
py
keyboard_arrow_up
School
Pennsylvania State University *
*We aren’t endorsed by this school
Course
132
Subject
Statistics
Date
Feb 20, 2024
Type
py
Pages
10
Uploaded by MateWasp883
# HW3
# REMINDER: The work in this assignment must be your own original work and must be completed alone.
class Node:
def __init__(self, value):
self.value = value self.next = None def __str__(self):
return "Node({})".format(self.value) __repr__ = __str__
#=============================================== Part I ==============================================
class Stack:
'''
>>> x=Stack()
>>> x.pop()
>>> x.push(2)
>>> x.push(4)
>>> x.push(6)
>>> x
Top:Node(6)
Stack:
6
4
2
>>> x.pop()
6
>>> x
Top:Node(4)
Stack:
4
2
>>> len(x)
2
>>> x.peek()
4
'''
def __init__(self):
self.top = None
def __str__(self):
temp=self.top
out=[]
while temp:
out.append(str(temp.value))
temp=temp.next
out='\n'.join(out)
return ('Top:{}\nStack:\n{}'.format(self.top,out))
__repr__=__str__
def isEmpty(self):
# YOUR CODE STARTS HERE
if self.__len__() != 0:
return False
else:
return True
def __len__(self): # YOUR CODE STARTS HERE
x = self.top
count = 0
while x != None:
x = x.next
count += 1
return count
def push(self,value):
# YOUR CODE STARTS HERE
x = self.top
newNode = Node(value)
if self.isEmpty()== False:
newNode.next = x
self.top = newNode
else:
self.top = newNode
def pop(self):
# YOUR CODE STARTS HERE
if self.isEmpty():
return None
else:
x_value = self.top.value
self.top = self.top.next
return x_value
def peek(self):
# YOUR CODE STARTS HERE
if self.isEmpty():
return None
else:
return self.top.value
#=============================================== Part II ==============================================
class Calculator:
def __init__(self):
self.__expr = None
@property
def getExpr(self):
return self.__expr
def setExpr(self, new_expr):
if isinstance(new_expr, str):
self.__expr=new_expr
else:
print('setExpr error: Invalid expression')
return None
def _isNumber(self, txt):
'''
>>> x=Calculator()
>>> x._isNumber(' 2.560 ')
True
>>> x._isNumber('7 56')
False
>>> x._isNumber('2.56p')
False
'''
# YOUR CODE STARTS HERE
try:
txt = float(txt)
return True
except:
return False
def tocheckInvalidity(self, txt):
x = txt
lst1 = ['^', '*', '/', '+', '-']
lst2 = ['(', ')']
if x[-1] in lst1:
return False
for i in x:
if (i not in lst1) and (self._isNumber(i)!=True) and (i not in lst2):
return False
count = 0
for i in x:
if i == ')':
count -= 1
elif i == '(':
count +=1
if count != 0:
return False
count1 = 0
count2 = 1
for i in range(1, len(x)):
if (self._isNumber(x[count1]) == True) and (self._isNumber(x[count2]) == True) or (self._isNumber(x[count1]) == True) and (x[count2] == '('):
return False
elif (x[count1] in lst1) and (x[count2] in lst1) or (x[count1] == ')') and (x[count2] == '(') :
return False
count1 =count1+1
count2 = count2+1
def _getPostfix(self, txt):
'''
Required: _getPostfix must create and use a Stack for expression processing
>>> x=Calculator()
>>> x._getPostfix(' 2 ^ 4')
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
- Access to all documents
- Unlimited textbook solutions
- 24/7 expert homework help
'2.0 4.0 ^'
>>> x._getPostfix(' 2 ')
'2.0'
>>> x._getPostfix('2.1 * 5 + 3 ^ 2 + 1 + 4.45')
'2.1 5.0 * 3.0 2.0 ^ + 1.0 + 4.45 +'
>>> x._getPostfix('2*5.34+3^2+1+4')
'2.0 5.34 * 3.0 2.0 ^ + 1.0 + 4.0 +'
>>> x._getPostfix('2.1 * 5 + 3 ^ 2 + 1 + 4')
'2.1 5.0 * 3.0 2.0 ^ + 1.0 + 4.0 +'
>>> x._getPostfix('( .5 )')
'0.5'
>>> x._getPostfix ('( ( 2 ) )')
'2.0'
>>> x._getPostfix ('2 * ( ( 5 +-3 ) ^ 2 + (1 + 4 ))')
'2.0 5.0 -3.0 + 2.0 ^ 1.0 4.0 + + *'
>>> x._getPostfix ('(2 * ( ( 5 + 3) ^ 2 + (1 + 4 )))')
'2.0 5.0 3.0 + 2.0 ^ 1.0 4.0 + + *'
>>> x._getPostfix ('((2 *((5 + 3 ) ^ 2 + (1 +4 )) ))')
'2.0 5.0 3.0 + 2.0 ^ 1.0 4.0 + + *'
>>> x._getPostfix('2* ( -5 + 3 ) ^2+ ( 1 +4 )')
'2.0 -5.0 3.0 + 2.0 ^ * 1.0 4.0 + +'
# In invalid expressions, you might print an error message, adjust doctest accordingly
# If you are veryfing the expression in calculate before passing to postfix, this cases are not necessary
>>> x._getPostfix('2 * 5 + 3 ^ + -2 + 1 + 4')
>>> x._getPostfix(' 2 * 5 + 3 ^ * 2 + 1 + 4')
>>> x._getPostfix('2 5')
>>> x._getPostfix('25 +')
>>> x._getPostfix(' 2 * ( 5 + 3 ) ^ 2 + ( 1 +4 ')
>>> x._getPostfix(' 2 * ( 5 + 3 ) ^ 2 + ) 1 + 4 (')
>>> x._getPostfix('2 * 5% + 3 ^ + -2 +1 +4')
'''
# YOUR CODE STARTS HERE
postfixStack = Stack() # method must use postfixStack to compute the postfix expression
txt = txt.strip(' ')
txt=txt+' ' #to avoid going out of bounds
txtmod="" #to store the output with spaces at right places
lst1= ['^', '*', '/', '+', '-']
for i in range(len(txt)-1):
if (txt[i]=='-' and self._isNumber(txt[i+1]) and txt[i-1] in lst1):
txtmod=txtmod+" "+str(txt[i])
elif (txt[i]=='-' and self._isNumber(txt[i+1]) and self._isNumber(txt[i-1])== False):
txtmod=txtmod+str(txt[i])
elif (self._isNumber(txt[i]) and (txt[i+1])=='.') or (txt[i] =='.' and self._isNumber(txt[i+1])) or (self._isNumber(txt[i]) and self._isNumber(txt[i+1])):
txtmod=txtmod+str(txt[i])
elif (txt[i] =='(' and (txt[i+1])=='(') or (txt[i] ==')' and (txt[i+1])==')') or (self._isNumber(txt[i]) and (txt[i+1])==')')or (txt[i]=='(' and
self._isNumber(txt[i+1])):
txtmod=txtmod+str(txt[i])+" "
elif (txt[i] in lst1 and self._isNumber(txt[i+1])) or (txt[i] in lst1 and (txt[i+1])=='(') or (self._isNumber(txt[i]) and (txt[i+1]) in lst1):
txtmod=txtmod+str(txt[i])+" "
else:
txtmod=txtmod+str(txt[i])
txtmod=txtmod.strip(' ')
txtmod = txtmod.split(' ')
txtmod2=[] #to store the output without unnecessary spaces
for i in txtmod:
if i !="":
txtmod2.append(i)
txt=txtmod2
if self.tocheckInvalidity(txt) != False:
postfix = []
precedence = {'(':5, ')':5, '^':4, '*':3, '/':3, '+':2, '-':2} for i in range(0, len(txt)):
next = txt[i]
if self._isNumber(next) == True:
postfix.append(str(float(next)))
else: if postfixStack.isEmpty() != True:
if next == '(':
postfixStack.push(next)
elif next == ')':
while postfixStack.peek()!='(':
postfix.append(postfixStack.pop())
postfixStack.pop()
else:
check = True
while (postfixStack.isEmpty()!=True) and (precedence[next] <= precedence[postfixStack.peek()]) and check == True:
if (precedence[next] == 4 and precedence[postfixStack.peek()] == 4) or postfixStack.peek() == '(':
check = False
else:
postfix.append(postfixStack.pop())
postfixStack.push(next)
else:
postfixStack.push(next) while postfixStack.isEmpty() == False:
if postfixStack.peek() != '(':
postfix.append(postfixStack.pop())
else:
postfixStack.pop()
return (' '.join(postfix))
else:
return None
@property
def calculate(self):
'''
calculate must call _getPostfix
calculate must create and use a Stack to compute the final result as shown in the video lecture
>>> x=Calculator()
>>> x.setExpr('4 + 3 - 2')
>>> x.calculate
5.0
>>> x.setExpr('-2 + 3.5')
>>> x.calculate
1.5
>>> x.setExpr(' 4 + 3.65 - 2 / 2')
>>> x.calculate
6.65
>>> x.setExpr('23 / 12 - 223 + 5.25 * 4 * 3423')
>>> x.calculate
71661.91666666667
>>> x.setExpr('2-3*4')
>>> x.calculate
-10.0
>>> x.setExpr('7^2^3')
>>> x.calculate
5764801.0
>>> x.setExpr(' 3 * ((( 10 - 2*3 )) )')
>>> x.calculate
12.0
>>> x.setExpr(' 8 / 4 * (3 - 2.45 * ( 4 - 2 ^ 3 ) ) + 3')
>>> x.calculate
28.6
>>> x.setExpr('2 * ( 4 + 2 * ( 5 - 3 ^ 2 ) + 1 ) + 4')
>>> x.calculate
-2.0
>>> x.setExpr(' 2.5 + 3 * (2 + ( 3.0) * ( 5^2-2 * 3 ^ ( 2 ) ) * ( 4 ) ) * ( 2 / 8 + 2 * ( 3 - 1 /3 ) ) - 2 / 3^ 2')
>>> x.calculate
1442.7777777777778
# In invalid expressions, you might print an error message, but code must return None, adjust doctest accordingly
>>> x.setExpr(" 4 ++ 3+ 2") >>> x.calculate
>>> x.setExpr("4 3 +2")
>>> x.calculate
>>> x.setExpr('( 2 ) * 10 - 3 *( 2 - 3 * 2 ) )')
>>> x.calculate
>>> x.setExpr('( 2 ) * 10 - 3 * / ( 2 - 3 * 2 )')
>>> x.calculate
>>> x.setExpr(' ) 2 ( *10 - 3 * ( 2 - 3 * 2 ) ')
>>> x.calculate
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
- Access to all documents
- Unlimited textbook solutions
- 24/7 expert homework help
>>> x.setExpr('( 3.5 ) ( 15 )') >>> x.calculate
>>> x.setExpr('3 ( 5) - 15 + 85 ( 12)') >>> x.calculate
>>> x.setExpr("( -2/6) + ( 5 ( ( 9.4 )))") >>> x.calculate
'''
if not isinstance(self.__expr,str) or len(self.__expr)<=0:
print("Argument error in calculate")
return None
calcStack = Stack() # method must use calcStack to compute the expression
# YOUR CODE STARTS HERE
if not isinstance(self.__expr,str) or len(self.__expr)<=0:
print("Argument error in calculate")
return None
calcStack = Stack() # method must use calcStack to compute the expression
# YOUR CODE STARTS HERE
postfix_exp = self._getPostfix(self.__expr)
if postfix_exp != None:
postfix_exp = postfix_exp.split(' ')
operators = ['/','*','+','-','^']
for i in range(0, len(postfix_exp)):
current = postfix_exp[i]
if self._isNumber(current) == True:
calcStack.push(float(current))
else:
x = calcStack.pop()
y = calcStack.pop()
if current == '^':
ans = y**x
elif current == '/':
ans = y/x
elif current == '*':
ans = y*x
elif current == '+':
ans = y+x
elif current == '-':
ans = y-x
calcStack.push((ans))
return (float(calcStack.pop()))
else:
return None
#=============================================== Part III ==============================================
class AdvancedCalculator:
'''
>>> C = AdvancedCalculator()
>>> C.states == {}
True
>>> C.setExpression('a = 5;b = 7 + a;a = 7;c = a + b;c = a * 0;return c')
>>> C.calculateExpressions() == {'a = 5': {'a': 5.0}, 'b = 7 + a': {'a': 5.0, 'b': 12.0}, 'a = 7': {'a': 7.0, 'b': 12.0}, 'c = a + b': {'a': 7.0, 'b': 12.0,
'c': 19.0}, 'c = a * 0': {'a': 7.0, 'b': 12.0, 'c': 0.0}, '_return_': 0.0}
True
>>> C.states == {'a': 7.0, 'b': 12.0, 'c': 0.0}
True
>>> C.setExpression('x1 = 5;x2 = 7 * ( x1 - 1 );x1 = x2 - x1;return x2 + x1
^ 3')
>>> C.states == {}
True
>>> C.calculateExpressions() == {'x1 = 5': {'x1': 5.0}, 'x2 = 7 * ( x1 - 1 )': {'x1': 5.0, 'x2': 28.0}, 'x1 = x2 - x1': {'x1': 23.0, 'x2': 28.0}, '_return_': 12195.0}
True
>>> print(C.calculateExpressions())
{'x1 = 5': {'x1': 5.0}, 'x2 = 7 * ( x1 - 1 )': {'x1': 5.0, 'x2': 28.0}, 'x1
= x2 - x1': {'x1': 23.0, 'x2': 28.0}, '_return_': 12195.0}
>>> C.states == {'x1': 23.0, 'x2': 28.0}
True
>>> C.setExpression('x1 = 5 * 5 + 97;x2 = 7 * ( x1 / 2 );x1 = x2 * 7 / x1;return x1 * ( x2 - 5 )')
>>> C.calculateExpressions() == {'x1 = 5 * 5 + 97': {'x1': 122.0}, 'x2 = 7 * ( x1 / 2 )': {'x1': 122.0, 'x2': 427.0}, 'x1 = x2 * 7 / x1': {'x1': 24.5, 'x2': 427.0}, '_return_': 10339.0}
True
>>> C.states == {'x1': 24.5, 'x2': 427.0}
True
>>> C.setExpression('A = 1;B = A + 9;C = A + B;A = 20;D = A + B + C;return D - A')
>>> C.calculateExpressions() == {'A = 1': {'A': 1.0}, 'B = A + 9': {'A': 1.0, 'B': 10.0}, 'C = A + B': {'A': 1.0, 'B': 10.0, 'C': 11.0}, 'A = 20': {'A': 20.0, 'B': 10.0, 'C': 11.0}, 'D = A + B + C': {'A': 20.0, 'B': 10.0, 'C': 11.0, 'D': 41.0}, '_return_': 21.0}
True
>>> C.states == {'A': 20.0, 'B': 10.0, 'C': 11.0, 'D': 41.0}
True
>>> C.setExpression('A = 1;B = A + 9;2C = A + B;A = 20;D = A + B + C;return
D + A')
>>> C.calculateExpressions() is None
True
>>> C.states == {}
True
'''
def __init__(self):
self.expressions = ''
self.states = {}
def setExpression(self, expression):
self.expressions = expression
self.states = {}
def _isVariable(self, word):
'''
>>> C = AdvancedCalculator()
>>> C._isVariable('volume')
True
>>> C._isVariable('4volume')
False
>>> C._isVariable('volume2')
True
>>> C._isVariable('vol%2')
False
'''
# YOUR CODE STARTS HERE
if (word[0].isalpha() == True) and (word.isalnum() == True):
return True
else:
return False
def _replaceVariables(self, expr):
'''
>>> C = AdvancedCalculator()
>>> C.states = {'x1': 23.0, 'x2': 28.0}
>>> C._replaceVariables('1')
'1'
>>> C._replaceVariables('105 + x')
>>> C._replaceVariables('7 * ( x1 - 1 )')
'7 * ( 23.0 - 1 )'
>>> C._replaceVariables('x2 - x1')
'28.0 - 23.0'
'''
# YOUR CODE STARTS HERE
x = expr.split(" ")
check = True
for i in range(0, len(x)):
if self._isVariable(x[i]) == True:
if x[i] in self.states: x[i] = str(self.states[x[i]])
else:
check = False
if check == True:
return " ".join(x)
def calculateExpressions(self):
self.states = {} calcObj = Calculator() # method must use calcObj to compute each expression
# YOUR CODE STARTS HERE
output = {} exp = self.expressions.split(';')
check = False
for i in exp:
if "=" in i: equation = i.split(" = ") numerical = self._replaceVariables(equation[1]) if numerical != None:
calcObj.setExpr(numerical)
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
- Access to all documents
- Unlimited textbook solutions
- 24/7 expert homework help
self.states[equation[0]] = calcObj.calculate
output[i] = self.states.copy()
else:
self.states = {}
return None
if "return" in i:
a = i.split()[1:] b = " ".join(a) c = self._replaceVariables(b)
if c != None:
calcObj.setExpr(c)
d = calcObj.calculate output["_return_"] = d
check = True
else:
self.states = {}
return None
if len(output) != 0 and check == True:
return output
else:
return None
if __name__=='__main__':
import doctest
doctest.testmod()
# OR
#doctest.run_docstring_examples(AdvancedCalculator, globals(), name='HW3',verbose=True)
Related Documents
Recommended textbooks for you
Algebra & Trigonometry with Analytic Geometry
Algebra
ISBN:9781133382119
Author:Swokowski
Publisher:Cengage
Recommended textbooks for you
- Algebra & Trigonometry with Analytic GeometryAlgebraISBN:9781133382119Author:SwokowskiPublisher:Cengage
Algebra & Trigonometry with Analytic Geometry
Algebra
ISBN:9781133382119
Author:Swokowski
Publisher:Cengage