patternpythonMinor
Simple calculator which can operate on more than two numbers
Viewed 0 times
cansimplethanoperatemorenumberstwowhichcalculator
Problem
All the calculator programs I have seen so far seem long, complicated and they can only operate on two numbers. Mine is simple, short, and it can operate on as many numbers as you want. Please tell me if there is another way to improve this section of code.
x=[]
amount=int(input("How many numbers?"))
operation=input("(*), (/), (+), (-)")
previous1 = 0
previous2=1
for i in range(amount):
number=int(input("Number: "))
x.append(number)
if operation == "+":
for i in range(amount):
previous1=x[i]+previous1
elif operation == "*":
for i in range(amount):
previous2=x[i]*previous2
elif operation == "-":
for i in range(amount):
previous1=x[i]-previous1
elif operation == "/":
for i in range(amount):
previous2=x[i]/previous2
if operation == "+" or operation == "-":
print(previous1)
else:
print(previous2)Solution
reduce
Whenever you need to fold an operation across a list, like you're doing, you want to use
is equivalent to:
This is precisely what we want. The
Simplifying the logic
We could directly translate the above into a dictionary of operators and a dictionary of initializers:
This will additionally fix your bug where for subtraction you're really adding.
List Comprehensions
It's more direct to simply initialize your numbers directly:
Note that
Division
All of your numbers are
Whenever you need to fold an operation across a list, like you're doing, you want to use
reduce(). That takes a function, an iterable, and an optional initializer, and performs the operation across all of them. So:reduce(f, [x, y, z])is equivalent to:
f(f(x, y), z)This is precisely what we want. The
operator library additionally gives us all the mathematical operators, so we don't have to write them ourselves. So the various operations are:+: reduce(operator.add, numbers) # or just sum(numbers)
-: reduce(operator.sub, numbers, 0)
*: reduce(operator.mul, numbers)
/: reduce(operator.floordiv, numbers, 1)Simplifying the logic
We could directly translate the above into a dictionary of operators and a dictionary of initializers:
operators = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'/': operator.floordiv
}
initializers = {
'-': 0,
'/': 1
}
result = reduce(operators[operation],
numbers,
initializers.get(operation, None))This will additionally fix your bug where for subtraction you're really adding.
List Comprehensions
It's more direct to simply initialize your numbers directly:
numbers = [int(input("Number: ")) for _ in range(amount)]Note that
x is not a good name. Prefer more descriptive names. Division
All of your numbers are
ints. Which means that when you divide, you're going to end up with 0 as soon as you have any number that isn't 1. That isn't particularly interesting, so I'd suggest using floating point numbers instead.Code Snippets
reduce(f, [x, y, z])f(f(x, y), z)+: reduce(operator.add, numbers) # or just sum(numbers)
-: reduce(operator.sub, numbers, 0)
*: reduce(operator.mul, numbers)
/: reduce(operator.floordiv, numbers, 1)operators = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'/': operator.floordiv
}
initializers = {
'-': 0,
'/': 1
}
result = reduce(operators[operation],
numbers,
initializers.get(operation, None))numbers = [int(input("Number: ")) for _ in range(amount)]Context
StackExchange Code Review Q#113302, answer score: 7
Revisions (0)
No revisions yet.