Calculator that takes 3 user inputs: operation signs and numbers 1-5 spelled out. Then it converts them to numbers and symbols. Users can input them in any order. The problem is in my for loops in functions i(1-3) the only input that works is one any other doesn't convert to a number or symbol.
dictt = {
'one': 1,
'two': 2,
'three': 3,
'four': 4,
'five': 5,
'add': r" ",
'subtract': r"-",
'multiply': r"*",
'divide': r"/"
}
def i1():
i1 = (input("Please input 'add', 'subtract', 'multiply', 'divide', 'one', 'two', 'three' , 'four', or 'five': "))
num1=0
for k,v in dictt.items():
if i1 == k:
num1 = dictt[k]
return num1
def i2():
i2 = (input("Please input 'add', 'subtract', 'multiply', 'divide', 'one', 'two', 'three' , 'four', or 'five': "))
num2=0
for k,v in dictt.items():
if i2 == k:
num2 = dictt[k]
return num2
def i3():
i3 = (input("Please input 'add', 'subtract', 'multiply', 'divide', 'one', 'two', 'three' , 'four', or 'five': "))
num3=0
for k,v in dictt.items():
if i3 == k:
num3 = dictt[k]
return num3
def main():
x=i1()
y=i2()
z=i3()
listo=[x,y,z]
listn=[]
for i in listo:
if i == int:
listn.append(i)
listo.remove(i)
else:
pass
if len(listn) == 2:
if listo[0] == "add":
result=listn[0] listn[1]
return f"{listn[0]} {listn[1]} = {result}"
elif listo[0] == "subtract":
result = listn[0] - listn[1]
return f"{listn[0]} - {listn[1]} = {result}"
elif listo[0] == "multiply":
result=listn[0] * listn[1]
return f"{listn[0]} * {listn[1]} = {result}"
elif listo[0] == "divide":
result=listn[0] / listn[1]
return f"{listn[0]} / {listn[1]} = {result}"
elif len(listn) < 2:
return "not enough numbers"
elif len(listo) != 1:
return "just one operator"
CodePudding user response:
Your iteration is broken because you return too early, but you don't need to iterate through a dictionary to look up an item in it in the first place. Instead of:
def i1():
i1 = (input("Please input 'add', 'subtract', 'multiply', 'divide', 'one', 'two', 'three' , 'four', or 'five': "))
num1=0
for k,v in dictt.items():
if i1 == k:
num1 = dictt[k]
return num1
do:
def i1():
i1 = input("Please input 'add', 'subtract', 'multiply', 'divide', 'one', 'two', 'three' , 'four', or 'five': ")
return dictt.get(i1, 0)
You also don't need i2
and i3
, because all of these functions do exactly the same thing, just with different names. Instead of:
x=i1()
y=i2()
z=i3()
listo=[x,y,z]
you could just do:
listo = [i1(), i1(), i1()]
or:
listo = [i1() for _ in range(3)]
I might suggest simplifying the overall code by putting all the inputs in a list, sorting them into numbers and functions, and then applying them, rather than having a bunch of if
statements:
ops = {
'one': 1,
'two': 2,
'three': 3,
'four': 4,
'five': 5,
'add': (" ", int.__add__),
'subtract': ("-", int.__sub__),
'multiply': ("*", int.__mul__),
'divide': ("/", int.__truediv__),
}
def get_op():
while True:
try:
return ops[input(
"Please input 'add', 'subtract', 'multiply', 'divide', "
"'one', 'two', 'three' , 'four', or 'five': "
)]
except KeyError:
print("Not a valid input.")
def main():
while True:
ops = [get_op() for _ in range(3)]
nums = [n for n in ops if isinstance(n, int)]
f = [f for f in ops if isinstance(f, tuple)]
if len(f) == 1 and len(nums) == 2:
break
else:
print("Must enter exactly two numbers and one operation.")
symbol, func = f.pop()
expr = f" {symbol} ".join(str(n) for n in nums)
return f"{expr} = {func(*nums)}"
if __name__ == '__main__':
print(main())
CodePudding user response:
I think you make your codes a little bit complicated, which will be difficult to maintain, this can be simple if using operator
from operator import add, sub, mul, truediv
from typing import Callable
dictt = {
'one': 1,
'two': 2,
'three': 3,
'four': 4,
'five': 5,
'add': add,
'subtract': sub,
'multiply': mul,
'divide': truediv,
}
def main():
input_msg = "Please input 'add', 'subtract', 'multiply', 'divide', 'one', 'two', 'three' , 'four', or 'five': "
v1 = dictt.get(input(input_msg).strip())
v2 = dictt.get(input(input_msg).strip())
v3 = dictt.get(input(input_msg).strip())
if isinstance(v2, Callable) and v1 and not isinstance(v1, Callable) and v3 and not isinstance(v3, Callable)::
return v2(v1, v3)
else:
return 'Invalid input'
if __name__ == '__main__':
res = main()
print(res)