Calculator output wrong answer - python

import math
def findNextOpr(txt):
if len(txt)<=0 or not isinstance(txt,str):
return "type error: findNextOpr"
# --- YOU CODE STARTS HERE
if type(txt) == str:
opr_list = ["+", "-", "*", "/", '^']
for i in range(len(txt)):
if txt[i] in opr_list:
return(i)
return(-1)
# --- CODE ENDS HERE
def isNumber(txt):
if not isinstance(txt, str):
return "type error: isNumber"
if len(txt)==0:
return False
# --- YOU CODE STARTS HERE
if type(txt) == str:
try:
float(txt)
return True
except ValueError:
return False
def getNextNumber(expr, pos):
if len(expr)==0 or not isinstance(expr, str) or pos<0 or pos>=len(expr) or not isinstance(pos, int):
return None, None, "type error: getNextNumber"
# --- YOU CODE STARTS HERE
txt = expr[pos:]
oprPos = findNextOpr(txt)
if oprPos != -1:
if isNumber(txt[:oprPos]) == True:
return float(txt[:oprPos]), txt[oprPos], oprPos+pos
else:
return None, txt[oprPos], oprPos+pos
else:
if isNumber(txt):
return float(txt), None, None
else:
return None,None,None
# --- CODE ENDS HERE
def exeOpr(num1, opr, num2):
#This function is just an utility function for calculator(expr). It is skipping type check
if opr=="+":
return num1+num2
elif opr=="-":
return num1-num2
elif opr=="*":
return num1*num2
elif opr=="/":
return num1/num2
elif opr=="^":
return num1**num2
else:
return "error in exeOpr"
def calculator(expr):
if len(expr)<=0 or not isinstance(expr,str):
return "error"
expr = expr.strip()
if expr[0]!="-":
newNumber, newOpr, oprPos = getNextNumber(expr, 0)
else:
newNumber, newOpr, oprPos = getNextNumber(expr, 1)
newNumber *= -1
if newNumber is None:
return "error"
elif newOpr is None:
return newNumber
elif newOpr=="+" or newOpr=="-":
mode="add"
addResult=newNumber
mulResult=None
expResult=None
elif newOpr=="*" or newOpr=="/":
mode="mul"
addResult=0
mulResult=newNumber
expResult=None
elif newOpr=="^":
mode="exp"
expResult=newNumber
addResult=0
mulResult=None
pos=oprPos+1
opr=newOpr
oldopr=None
while True:
newNumber, newOpr, oprPos = getNextNumber(expr, pos)
if newNumber is None:
return "input error: line B in calculator"
elif newOpr is None:
if mode=='add':
if opr=='*':
return exeOpr(addResult, oldopr, mulResult*newNumber)
elif opr=='/':
return exeOpr(addResult, oldopr, mulResult/newNumber)
else:
return exeOpr(addResult, opr, newNumber)
elif mode=='mul':
if expResult==None:
expResult=0
if mulResult==None:
mulResult=0
return addResult + exeOpr(mulResult, opr, newNumber)
elif mode=="exp":
if expResult<0:
expResult=exeOpr(expResult,opr,newNumber)
if expResult>0:
expResult=-1*expResult
else:
expResult=exeOpr(expResult,opr,newNumber)
if mulResult!=0 and (oldopr=='*' or oldopr=='/'):
mulResult=exeOpr(mulResult,oldopr,expResult)
expResult=0
elif newOpr=='+' or newOpr=='-':
if expResult==None:
expResult=0
if mulResult==None:
mulResult=0
if mode=='add':
addResult = exeOpr(addResult, opr, newNumber)
mulResult = 0
expResult= 0
elif mode=='mul':
addResult += exeOpr(mulResult, opr, newNumber)
mulResult = 0
expResult= 0
elif mode=='exp':
if expResult<0:
expResult=exeOpr(expResult,opr,newNumber)
if expResult>0:
expResult=-1*expResult
addResult+=expResult
else:
addResult+=exeOpr(expResult,opr,newNumber)
if oldopr=='*' or oldopr=='/':
expResult=exeOpr(expResult,opr,newNumber)
mulResult=exeOpr(mulResult,oldopr,expResult)
addResult+=mulResult
mulResult = 0
expResult = 0
mode='add'
elif newOpr=="*" or newOpr=="/":
if mode=='add':
if opr=='-':
oldopr='-'
mulResult = newNumber
elif opr=='+':
#print('here1')
oldopr='+'
mulResult = newNumber
mode='mul'
else:
mulResult = newNumber
elif mode=='mul':
mulResult = exeOpr(mulResult, opr, newNumber)
elif mode=='exp':
if expResult<0:
expResult=exeOpr(expResult,opr,newNumber)
if expResult>0:
expResult=-1*expResult
else:
expResult=exeOpr(expResult,opr,newNumber)
if mulResult !=0 and (oldopr=='*' or oldopr=='/'):
mulResult=exeOpr(mulResult,oldopr,expResult)
expResult=0
else:
mulResult=expResult
expResult=0
mode='mul'
elif newOpr=='^':
if mode=='add':
if expResult==None:
expResult=0
if mulResult==None:
mulResult=0
if opr=='-':
expResult = -newNumber
else:
expResult = newNumber
oldopr=opr
elif mode=='mul':
expResult=newNumber
oldopr=opr
mode='exp'
if oprPos==None:
break
pos=oprPos + 1
opr=newOpr
if mulResult== None:
mulResult=0
if expResult==None:
expResult=0
return addResult+mulResult+expResult
Above is my code for a functional calculator no errors at all but when I run the code and try
calculator('-5 + 60 / 3^3 * 4 - 2 * 4^2')
I get 35.888888888888886 but the answer should be -28.11111111111111
Is there a mistake someone in my code that I cannot find?
I think it might be in the calculator section since everything else works perfectly fine with tests but I just can't find where.
I was told that one way to solve in class was that maybe using a node/stack class might help but is there any other solution than creating another class

In the calculator big loop, when opr is -, you forgot to change the sign of mulResult.
In order to debug it, I added a print statement to the exeOpr function, so that we could see what the calculator is doing at each step. Then it was easy to determine by looking at the partial results.
The full new code is like this:
import math
def findNextOpr(txt):
if len(txt) <= 0 or not isinstance(txt, str):
return "type error: findNextOpr"
# --- YOU CODE STARTS HERE
if type(txt) == str:
opr_list = ["+", "-", "*", "/", '^']
for i in range(len(txt)):
if txt[i] in opr_list:
return (i)
return (-1)
# --- CODE ENDS HERE
def isNumber(txt):
if not isinstance(txt, str):
return "type error: isNumber"
if len(txt) == 0:
return False
# --- YOU CODE STARTS HERE
if type(txt) == str:
try:
float(txt)
return True
except ValueError:
return False
def getNextNumber(expr, pos):
if len(expr) == 0 or not isinstance(expr, str) or pos < 0 or pos >= len(expr) or not isinstance(pos, int):
return None, None, "type error: getNextNumber"
# --- YOU CODE STARTS HERE
txt = expr[pos:]
oprPos = findNextOpr(txt)
if oprPos != -1:
if isNumber(txt[:oprPos]):
return float(txt[:oprPos]), txt[oprPos], oprPos + pos
else:
return None, txt[oprPos], oprPos + pos
else:
if isNumber(txt):
return float(txt), None, None
else:
return None, None, None
# --- CODE ENDS HERE
def exeOpr(num1, opr, num2):
# This function is just an utility function for calculator(expr). It is skipping type check
print("%s %s %s" % (num1, opr, num2)) # <==== DEBUGGING PRINT
if opr == "+":
return num1 + num2
elif opr == "-":
return num1 - num2
elif opr == "*":
return num1 * num2
elif opr == "/":
return num1 / num2
elif opr == "^":
return num1 ** num2
else:
return "error in exeOpr"
def calculator(expr):
if len(expr) <= 0 or not isinstance(expr, str):
return "error"
expr = expr.strip()
if expr[0] != "-":
newNumber, newOpr, oprPos = getNextNumber(expr, 0)
else:
newNumber, newOpr, oprPos = getNextNumber(expr, 1)
newNumber *= -1
if newNumber is None:
return "error"
elif newOpr is None:
return newNumber
elif newOpr == "+" or newOpr == "-":
mode = "add"
addResult = newNumber
mulResult = None
expResult = None
elif newOpr == "*" or newOpr == "/":
mode = "mul"
addResult = 0
mulResult = newNumber
expResult = None
elif newOpr == "^":
mode = "exp"
expResult = newNumber
addResult = 0
mulResult = None
pos = oprPos + 1
opr = newOpr
oldopr = None
while True:
newNumber, newOpr, oprPos = getNextNumber(expr, pos)
if newNumber is None:
return "input error: line B in calculator"
elif newOpr is None:
if mode == 'add':
if opr == '*':
return exeOpr(addResult, oldopr, mulResult * newNumber)
elif opr == '/':
return exeOpr(addResult, oldopr, mulResult / newNumber)
else:
return exeOpr(addResult, opr, newNumber)
elif mode == 'mul':
if expResult == None:
expResult = 0
if mulResult == None:
mulResult = 0
return addResult + exeOpr(mulResult, opr, newNumber)
elif mode == "exp":
if expResult < 0:
expResult = exeOpr(expResult, opr, newNumber)
if expResult > 0:
expResult = -1 * expResult
else:
expResult = exeOpr(expResult, opr, newNumber)
if mulResult != 0 and (oldopr == '*' or oldopr == '/'):
mulResult = exeOpr(mulResult, oldopr, expResult)
expResult = 0
elif newOpr == '+' or newOpr == '-':
if expResult == None:
expResult = 0
if mulResult == None:
mulResult = 0
if mode == 'add':
addResult = exeOpr(addResult, opr, newNumber)
mulResult = 0
expResult = 0
elif mode == 'mul':
addResult += exeOpr(mulResult, opr, newNumber)
mulResult = 0
expResult = 0
elif mode == 'exp':
if expResult < 0:
expResult = exeOpr(expResult, opr, newNumber)
if expResult > 0:
expResult = -1 * expResult
addResult += expResult
else:
addResult += exeOpr(expResult, opr, newNumber)
if oldopr == '*' or oldopr == '/':
expResult = exeOpr(expResult, opr, newNumber)
mulResult = exeOpr(mulResult, oldopr, expResult)
addResult += mulResult
mulResult = 0
expResult = 0
mode = 'add'
elif newOpr == "*" or newOpr == "/":
if mode == 'add':
if opr == '-':
oldopr = '-'
mulResult = -newNumber # <====== THIS IS THE PLACE I CHANGED
elif opr == '+':
# print('here1')
oldopr = '+'
mulResult = newNumber
mode = 'mul'
else:
mulResult = newNumber
elif mode == 'mul':
mulResult = exeOpr(mulResult, opr, newNumber)
elif mode == 'exp':
if expResult < 0:
expResult = exeOpr(expResult, opr, newNumber)
if expResult > 0:
expResult = -1 * expResult
else:
expResult = exeOpr(expResult, opr, newNumber)
if mulResult != 0 and (oldopr == '*' or oldopr == '/'):
mulResult = exeOpr(mulResult, oldopr, expResult)
expResult = 0
else:
mulResult = expResult
expResult = 0
mode = 'mul'
elif newOpr == '^':
if mode == 'add':
if expResult == None:
expResult = 0
if mulResult == None:
mulResult = 0
if opr == '-':
expResult = -newNumber
else:
expResult = newNumber
oldopr = opr
elif mode == 'mul':
expResult = newNumber
oldopr = opr
mode = 'exp'
if oprPos == None:
break
pos = oprPos + 1
opr = newOpr
if mulResult == None:
mulResult = 0
if expResult == None:
expResult = 0
return addResult + mulResult + expResult
x = calculator('-5 + 60 / 3^3 * 4 - 2 * 4^2')
print(x)

Related

Tic Tac Toe stopping and not sure why. Very new to Python and have not looked at any code examples for Tic Tac Toe

This is a very early project in my Python career. Only watched a few tutorials and then jumped in so ELI5 please.
It runs a couple of turns but then it just freezes and im not sure why. It takes turns and then says when there is a winner. There is a bot with real bot logic.
The game starts by defining a spots array which is what the users see. There is 10 spots so it was easier for me to use the array spots 1 for the 1st spot (bad use of arrays, i know). There is a similar thing with spotBooleans which is used for checking whether a spot is taken. The numbers in the 90's are defaults. When a player places a spot, it turns that into an int 1, and enemy will be an int 2.
Most of the action is at the bottom with the while playing loop where it prints most of the data and asks you where to go. Then it checks for winners after you go, and goes to trigger the bot which uses basic algorithms and logic to try to win like a human would. Currently has nothing for stopping human moves. Then it checks if the bot is the winner.
Somewhere here it just stops in its tracks and I can not find why.
Again, I know this is poor code. I know some Java but I am not good at Python so far. Just trying to get the logic right and then the clean code will come up next along with simplifying things.
import random
import time
spots = ["", "-", "-", "-", "-", "-", "-", "-", "-", "-"]
spotBooleans = [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
start = False
whosturn = 1
while True:
spots = ["", "-", "-", "-", "-", "-", "-", "-", "-", "-"]
spotBooleans = [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
start = False
whosturn = 1
while start == False:
playerchoice = input("Would you like to be 'x' or 'o'")
x = False
o = False
if playerchoice == "x" or playerchoice == "X":
x = True
print("Player is X")
start = True
elif playerchoice == "o" or playerchoice == "O" or playerchoice == "0":
o = True
print("Player is O")
start = True
else:
print("Try again.\n\n")
start = False
print("Starting: ")
playing = True
def gorobot(whosturn):
global x
global spots
global spotBooleans
global playing
global start
if x:
robotsymbol = "o"
else:
robotsymbol = "x"
while whosturn == 2:
if spotBooleans[1] == spotBooleans[2] == 2:
if spots[3] == "-":
spots[3] = robotsymbol
spotBooleans[3] = 2
whosturn = 1
elif spotBooleans[3] == spotBooleans[2] == 2:
if spots[1] == "-":
spots[1] = robotsymbol
spotBooleans[1] = 2
whosturn = 1
elif spotBooleans[1] == spotBooleans[3] == 2:
if spots[2] == "-":
spots[2] = robotsymbol
spotBooleans[2] = 2
whosturn = 1
elif spotBooleans[4] == spotBooleans[5] == 2:
if spots[6] == "-":
spots[6] = robotsymbol
spotBooleans[6] = 2
whosturn = 1
elif spotBooleans[4] == spotBooleans[6] == 2:
if spots[5] == "-":
spots[5] = robotsymbol
spotBooleans[5] = 2
whosturn = 1
elif spotBooleans[5] == spotBooleans[6] == 2:
if spots[4] == "-":
spots[4] = robotsymbol
spotBooleans[4] = 2
whosturn = 1
elif spotBooleans[7] == spotBooleans[8] == 2:
if spots[9] == "-":
spots[9] = robotsymbol
spotBooleans[9] = 2
whosturn = 1
elif spotBooleans[7] == spotBooleans[9] == 2:
if spots[8] == "-":
spots[8] = robotsymbol
spotBooleans[8] = 2
whosturn = 1
elif spotBooleans[8] == spotBooleans[9] == 2:
if spots[7] == "-":
spots[7] = robotsymbol
spotBooleans[7] = 2
whosturn = 1
elif spotBooleans[1] == spotBooleans[5] == 2:
if spots[9] == "-":
spots[9] = robotsymbol
spotBooleans[9] = 2
whosturn = 1
elif spotBooleans[9] == spotBooleans[5] == 2:
if spots[1] == "-":
spots[1] = robotsymbol
spotBooleans[1] = 2
whosturn = 1
elif spotBooleans[9] == spotBooleans[1] == 2:
if spots[5] == "-":
spots[5] = robotsymbol
spotBooleans[5] = 2
whosturn = 1
elif spotBooleans[3] == spotBooleans[5] == 2:
if spots[7] == "-":
spots[7] = robotsymbol
spotBooleans[7] = 2
whosturn = 1
elif spotBooleans[7] == spotBooleans[5] == 2:
if spots[3] == "-":
spots[3] = robotsymbol
spotBooleans[3] = 2
whosturn = 1
elif spotBooleans[7] == spotBooleans[3] == 2:
if spots[5] == "-":
spots[5] = robotsymbol
spotBooleans[5] = 2
whosturn = 1
elif spotBooleans[3] == spotBooleans[6] == 2:
if spots[9] == "-":
spots[9] = robotsymbol
spotBooleans[9] = 2
whosturn = 1
elif spotBooleans[3] == spotBooleans[9] == 2:
if spots[6] == "-":
spots[6] = robotsymbol
spotBooleans[6] = 2
whosturn = 1
elif spotBooleans[6] == spotBooleans[9] == 2:
if spots[3] == "-":
spots[3] = robotsymbol
spotBooleans[3] = 2
whosturn = 1
elif spotBooleans[1] == spotBooleans[4] == 2:
if spots[7] == "-":
spots[7] = robotsymbol
spotBooleans[7] = 2
whosturn = 1
elif spotBooleans[1] == spotBooleans[7] == 2:
if spots[4] == "-":
spots[4] = robotsymbol
spotBooleans[4] = 2
whosturn = 1
elif spotBooleans[4] == spotBooleans[7] == 2:
if spots[1] == "-":
spots[1] = robotsymbol
spotBooleans[1] = 2
whosturn = 1
elif spotBooleans[2] == spotBooleans[5] == 2:
if spots[8] == "-":
spots[8] = robotsymbol
spotBooleans[8] = 2
whosturn = 1
elif spotBooleans[2] == spotBooleans[8] == 2:
if spots[5] == "-":
spots[5] = robotsymbol
spotBooleans[5] = 2
whosturn = 1
elif spotBooleans[5] == spotBooleans[8] == 2:
if spots[2] == "-":
spots[2] = robotsymbol
spotBooleans[2] = 2
whosturn = 1
else:
botMove = random.randint(0, 9)
if spots[botMove] == "-":
spots[botMove] = robotsymbol
spotBooleans[botMove] = 2
whosturn = 1
else:
print("The Bot is a moron! " + str(botMove))
def checkforwinners():
if spotBooleans[1] == spotBooleans[2] == spotBooleans[3]:
print("Winner!")
return True
elif spotBooleans[4] == spotBooleans[5] == spotBooleans[6]:
print("Winner!")
return True
elif spotBooleans[7] == spotBooleans[8] == spotBooleans[9]:
print("Winner!")
return True
elif spotBooleans[1] == spotBooleans[4] == spotBooleans[7]:
print("Winner!")
return True
elif spotBooleans[2] == spotBooleans[5] == spotBooleans[8]:
print("Winner!")
return True
elif spotBooleans[3] == spotBooleans[6] == spotBooleans[9]:
print("Winner!")
return True
elif spotBooleans[1] == spotBooleans[5] == spotBooleans[9]:
print("Winner!")
return True
elif spotBooleans[3] == spotBooleans[5] == spotBooleans[7]:
print("Winner!")
return True
else:
print("No Winners!")
print(spots)
print(spotBooleans)
return False
while playing:
print(str(spots[1]) + " " + str(spots[2]) + " " + str(spots[3]))
print(str(spots[4]) + " " + str(spots[5]) + " " + str(spots[6]))
print(str(spots[7]) + " " + str(spots[8]) + " " + str(spots[9]))
print("\n")
spotChoice = input("Where would you like to place your " + playerchoice + "?")
spot = int(spotChoice)
if spots[spot] == "-":
if x:
spots[spot] = "x"
spotBooleans[spot] = 1
if checkforwinners():
playing = False
start = False
break
whosturn = 2
gorobot(2)
else:
spots[spot] = "o"
spotBooleans[spot] = 1
if checkforwinners():
playing = False
start = False
break
whosturn = 2
gorobot(2)
if checkforwinners():
playing = False
start = False
Under certain conditions, your code causes an infinite loop inside the gorobot function.
For example, after a few tries, I got a spotBooleans list that looks like this:
[90, 1, 1, 93, 2, 1, 2, 97, 98, 99]
And a spots list that looks like this:
['', 'x', 'x', '-', 'o', 'x', 'o', '-', '-', '-']
In that state, when the code enters the while loop inside gorobot, it goes through this code path.
elif spotBooleans[4] == spotBooleans[6] == 2:
if spots[5] == "-":
spots[5] = robotsymbol
spotBooleans[5] = 2
whosturn = 1
spotBooleans[4] and spotBooleans[6] are both 2, so it enters the elif block, but spots[5] is "x", so it doesn't enter the inner if block. This means the whosturn variable is not updated, so the code doesn't exit the while whosturn == 2: loop. And the spotBooleans and spots lists are not updated, so on the next loop round the program follows the exact same code path.

Separating out 'While' function

I currently have defined my object (is_matched) that contains a while loop and also the checking of a string. I am trying to pull out the while loop into it's own object but am having trouble completing the coding. I also need the while loop to continue running until a user enters 'q' into the input.
def is_matched():
while True:
expr = input("Enter string (q to quit): ")
if expr == "q":
break
stack = Stack()
for i in expr:
if i == '{' or i == '(' or i == '[':
stack.push(i)
elif i == '}':
if len(expr) != 0:
c = stack.top()
if c == '{':
stack.pop()
else:
return "Unbalanced"
elif i == ')':
if len(expr) != 0:
c = stack.top()
if c == '(':
stack.pop()
else:
return "Unbalanced"
elif i == ']':
if len(expr) != 0:
c = stack.top()
if c == '[':
stack.pop()
else:
return "Unbalanced"
else:
return "Unbalanced"
if len(stack) != 0:
return "Unblanced"
return "Balanced"
result = is_matched()
print(result)
I am trying to pull out the while loop from above and enter into its own object as follows:
def main():
while True:
expr = input("Enter string (q to quit): ")
if expr == "q":
break
else:
return is_matched()
your is_matched function will take one argument which will be the expression to evaluate.
def is_matched(expr):
stack = Stack()
for i in expr:
if i == '{' or i == '(' or i == '[':
stack.push(i)
elif i == '}':
if len(expr) != 0:
c = stack.top()
if c == '{':
stack.pop()
else:
return "Unbalanced"
elif i == ')':
if len(expr) != 0:
c = stack.top()
if c == '(':
stack.pop()
else:
return "Unbalanced"
elif i == ']':
if len(expr) != 0:
c = stack.top()
if c == '[':
stack.pop()
else:
return "Unbalanced"
else:
return "Unbalanced"
if len(stack) != 0:
return "Unblanced"
return "Balanced"
main function.
def main():
while True:
expr = input("Enter string (q to quit): ")
if expr == "q":
break
else:
print(is_matched(expr))

Python Calculator, specifically getNextNumber function not working properly

I tried to work out a simple python calculator using stacks and it works only on situations where a negative number is first and when there isn't a negative number but when a situation arises such as 4*-2 for example, it gives an error (my eyes are on getNextNumber and isNumber and findNextOpr. Is there a way to fix this? Here's the code:
import pdb
class Stack:
def __init__(self):
self.container = []
def isEmpty(self):
return self.size() == 0
def push(self, item):
self.container.append(item)
def pop(self):
return self.container.pop()
def size(self):
return len(self.container)
class stack:
class node:
def __init__(self, value, nextNode):
self.value = value
self.nextNode = nextNode
def __init__(self):
self.top = None
self.last = None
self.size = 0
def __len__(self):
return self.size
def isEmpty(self):
return self.size == 0
def push(self, value):
if self.size == 0:
self.top = self.last = self.node(value, None)
else:
newNode = self.node(value, None)
newNode.nextNode = self.top
self.top = newNode
self.size += 1
def pop(self):
if self.size == 0:
return 'Error: stack.pop'
elif self.size == 1:
value = self.top.value
self.top = self.last = None
self.size -= 1
return value
else:
value = self.top.value
self.top = self.top.nextNode
self.size -= 1
return value
def findNextOpr(s):
if len(s) <= 0 or not isinstance(s, str):
print('Type mismatch error: findNextOpr')
return 'Type mismatch error: findNextOpr'
for n in range(len(s)):
if ord(s[n]) == 42 or ord(s[n]) == 43 or ord(s[n]) == 45 or ord(s[n]) == 47 or ord(s[n]) == 94:
return n
else:
continue
return -1
def isNumber(s):
if len(s) == 0 or not isinstance(s, str):
print('Type mismatch error: isNumber')
return 'Type mismatch error: isNumber'
try:
float(s)
return True
except:
return False
def getNextNumber(expr, pos):
#pdb.set_trace()
if len(expr) == 0 or not isinstance(expr, str) or pos < 0 or pos >= len(expr) or not isinstance(pos, int):
print('Type mismatch error: getNextNumber')
return None, None, 'Type mismatch error: getNextNumber'
m = findNextOpr(expr[pos:])
if m != -1:
opr = expr[m]
if isNumber(expr[pos: m + pos]) is True:
return float(expr[pos: m + pos]), expr[pos + m], m
elif isNumber(expr[pos:m+pos]) is False:
if expr[m+1] == '-':
pos = m+1
num=getNextNumber(expr,pos)
return -float(num),None,None
else:
return None, None, None
elif m == -1:
if isNumber(expr[pos:]) is True:
return float(expr[pos:]), None, None
else:
return None, None, None
def exeOpr(num1, opr, num2):
if opr == '+':
return num1 + num2
elif opr == '-':
return num1 - num2
elif opr == '*':
return num1 * num2
elif opr == '/':
if num2 == 0:
print('Zero division error: exeOpr')
return 'Zero division error: exeOpr'
else:
return num1 / num2
elif opr == '^':
return num1 ** num2
else:
print('Fatal internal error in exeOpr')
return 'Fatal internal error in exeOpr'
def _calc(expr):
if not isinstance(expr, str) or len(expr) <= 0:
print('Argument error: Line A in eval_expr')
return 'Argument error: Line A in eval_expr'
newNumber, newOpr, oprPos = getNextNumber(expr, 0)
if newNumber is None:
print('Input formula error: Line B in eval_expr')
return 'Input formula error: Line B in eval_expr'
elif newOpr is None:
return newNumber
elif newOpr == '+' or newOpr == '-':
mode = 'add'
addResult = newNumber
mulResult = 1
expResult = 0
elif newOpr == '*' or newOpr == '/':
mode = 'mul'
addResult = 0
mulResult = newNumber
expResult = 1
elif newOpr == '^':
mode = 'exp'
addResult = 0
mulResult = 1
expResult = newNumber
pos = oprPos + 1
opr = newOpr
while True:
nextNumber, newOpr, oprPos = getNextNumber(expr, pos)
if nextNumber is None or pos >= len(expr):
print('Input formula error: Line C in calc')
return 'Input formula error: Line C in calc'
elif newOpr is None:
if mode == 'add':
return exeOpr(addResult, opr, nextNumber)
elif mode == 'mul':
return exeOpr(mulResult, opr, nextNumber) + addResult
elif mode == 'exp':
return exeOpr(expResult, opr, nextNumber) * mulResult + addResult
oprPos += pos
pos = oprPos + 1
if mode == 'add':
if newOpr == '+' or newOpr == '-':
addResult = exeOpr(addResult, opr, nextNumber)
mode = 'add'
elif newOpr == '*' or newOpr == '/':
if opr == '+':
mulResult = nextNumber
elif opr == '-':
mulResult = -nextNumber
mode = 'mul'
elif newOpr == '^':
if opr == '+':
expResult = nextNumber
elif opr == '-':
expResult = - nextNumber
mode = 'exp'
elif mode == 'mul':
if newOpr == '*' or newOpr == '/':
mulResult = exeOpr(mulResult, opr, nextNumber)
mode = 'mul'
elif newOpr == '+' or newOpr == '-':
addResult += exeOpr(mulResult, opr, nextNumber)
elif newOpr == '^':
if opr == '*':
expResult = 1 / nextNumber
mode = 'exp'
elif mode == 'exp':
if newOpr == '^':
expResult = exeOpr(expResult, opr, nextNumber)
mode = 'exp'
elif newOpr == '+' or newOpr == '-':
addResult = exeOpr(expResult, opr, nextNumber) * mulResult + addResult
mode = 'add'
elif newOpr == '*' or newOpr == '/':
mulResult = exeOpr(expResult, opr, nextNumber) * mulResult
mode = 'mul'
opr = newOpr
def icheck(expr):
d = None
if expr[0] == '-':
expr = '0' + expr
for i in range(len(expr)):
if expr[i] == '(':
d = i
elif expr[i] == '':
continue
elif d is not None and expr[i] == '-':
for j in range(i + 1, len(expr)):
if expr[j] == '':
continue
else:
expr = expr[0: d + 1] + '0' + expr[d+1:]
d = None
break
else:
d = None
return expr
def pcheck(expr):
expr = expr.replace(' ', '')
per = Stack()
for i in range(len(expr)):
if expr[i] == '(':
if i != 0 and isNumber(expr[i - 1]) == True:
print('Omitting Operator')
return False
per.push(i)
elif expr[i] == ')':
if i != (len(expr) - 1) and isNumber(expr[i + 1]) == True:
print('Omitting Operator')
return False
try:
per.pop()
except IndexError:
print('Parenthesis are unbalanced')
return False
return per.isEmpty()
def calc(e, u=None):
if len(e) == 0:
return 'Empty String'
e = e.replace(' ', '')
if u is None:
e = icheck(e)
tf = pcheck(e)
if tf is False:
return IndexError
st = Stack()
b = None
for i in range(len(e)):
pos = i
if e[i] == '(':
st.push(i)
elif e[i] == ')':
b = st.pop()
c = i
break
if b is None:
return _calc(e)
if st.size() == 0 and (pos == len(e) - 1):
res = _calc(e[b+1:c])
if len(e) > c:
e = e[:b] + str(res) + e[c + 1:]
else:
e = e[:b] + str(res)
return _calc(e)
else:
res = _calc(e[b + 1: c])
e = e[:b] + str(res) + e[c + 1:]
return calc(e, u=1)
print(calc('2.0*-2+5'))
print(calc('-2.0+1'))
print(calc('4*-2'))
print(calc('2+3*(-2 +(-3)*(5^2-2*3^(-2))*(-4))*(2/8+2*(3–1/3))-2/3^2'))
print(calc('1+3-2/30^2/5-1*5*3*4/3-1^2/6/7/8+3-1/2^2*3/2+3+1^2^2+3/3^2'))
This is an expected issue. To overcome this, electronic calculators usually use minus and negative signs seperately (which are the same in Python, causing your problem). You can apply this by creating an operator classes for these, assign them spesific purposes.
Alternatively, you can enforce the correct usage of paranthesis when the input is taken, or pre-check the input and convert it without bothering the user, make it a computer usable format (add paranthesis or whatsoever).

Turning a string to an integer - TypeError: '>' not supported between instances of 'str' and 'int'

I am having the error come up as the >not supported between instances of 'str' and 'int'. This is at the part where it says 'if guess[1] in secretNum > 1'. I realise that this is comparing a string to an integer but i don't know how to change that. Any Help?
clue0 = []
clue1 = []
clue2 = []
clue3 = []
if guess[0] in secretNum:
clue0 = ['Pico']
if guess[0] == secretNum[0]:
clue0 = ['Fermi']
if guess[1] in secretNum or guess[1] == guess[0]:
if guess[1] == guess[0]:
if guess[1] in secretNum > 1:
clue1 == ['Pico']
else:
clue1 == []
else:
clue1 = ['Pico']
if guess[1] == secretNum[1]:
clue1 == ['Fermi']
if guess[2] in secretNum or guess[2] == guess[0] or guess[2] == guess[1]:
if guess[2] == guess[1] or guess[2] == guess[0]:
if guess[2] in secretNum > 2:
clue2 == ['Pico']
else:
clue2 == []
else:
clue2 = ['Pico']
if guess[2] == secretNum[2]:
clue2 == ['Fermi']
if guess[3] in secretNum or guess[3] == guess[0] or guess[3] == guess[1] or guess[3] == guess[2]:
if guess[3] == guess[1] or guess[3] == guess[0] or guess[3] == guess[2]:
if guess[3] in secretNum > 3:
clue3 == ['Pico']
else:
clue3 == []
else:
clue3 = ['Pico']
if guess[3] == secretNum[3]:
clue3 == ['Fermi']
clue = clue0 + clue1 + clue2 + clue3
if len(clue) == 0:
return 'Bagels'
clue.sort()
return ' '.join(clue)
guess[1] in secretNum > 1 equals to guess[1] in secretNum and secretNum > 1, secretNum seems to be string so the comparison after and is invalid (str > int)
if you want to count how many times guess[1] is in secretNumber you should use secretNumber.count(guess[1])

Solitaire python

I have code here for moving a card from the deck to the foundation pile. I've imported the necessary details, etc. My problem is, it's too long. Is there any way to make it shorter? How? Thanks :)
def dtof():
suit = raw_input("enter suit: ")
v = trash.pop()
if suit == "D":
if card.suitNumber[v.suit] == 1:
if card.rankNumber[v.rank] == 0:
Diamond.append(v)
elif card.rankNumber[v.rank] == card.rankNumber[Diamond[-1].rank] + 1:
Diamond.append(v)
else:
trash.append(v)
return Diamond[-1]
else:
trash.append(v)
elif suit == "H":
if card.suitNumber[v.suit] == 2:
if card.rankNumber[v.rank] == 0:
Heart.append(v)
elif card.rankNumber[v.rank] == card.rankNumber[Heart[-1].rank] + 1:
Heart.append(v)
else:
trash.append(v)
return Heart[-1]
else:
trash.append(v)
elif suit == "C":
if card.suitNumber[v.suit] == 4:
if card.rankNumber[v.rank] == 0:
Clubs.append(v)
elif card.rankNumber[v.rank] == card.rankNumber[Clubs[-1].rank] + 1:
Clubs.append(v)
else:
trash.append(v)
return Clubs[-1]
else:
trash.append(v)
elif suit == "S":
if card.suitNumber[v.suit] == 3:
if card.rankNumber[v.rank] == 0:
Spade.append(v)
elif card.rankNumber[v.rank] == card.rankNumber[Spade[-1].rank] + 1:
Spade.append(v)
else:
trash.append(v)
return Spade[-1]
else:
trash.append(v)
else:
trash.append(v)
Consider merging Diamond, Heart, Clubs and Spade into a single dictionary, with the key being suit.

Categories

Resources