Python - looping - python

I am trying to build a simple calculator. I just want the user to enter two numbers and an operation, then for the calculation to be shown, then to loop back to entering two numbers again. If the user enters an operation that is not recognized I want to loop back to 'enter operation'.
Why is this not working:
def add (a,b):
return a + b
def minus (a,b):
return a - b
def multi (a,b):
return a * b
def div (a,b):
return a / b
def numPic():
num1 = int(input("Type a number: "))
num2 = int(input("Type another number: "))
def opPic():
op = input("Type an operation (add,minus,multi,div):" )
if op == "add":
print (add (num1,num2))
elif (op == "minus"):
print (minus(num1,num2))
elif (op == "multi"):
print (mulit(num1,num2))
elif (op == "div"):
print (div(num1,num2))
else :
print ("operation not recognised")
opPic ()
print ("Hello User")
numPic()
opPic()

You have a few bugs. First, num1 and num2 are local to numPic--not
global. So you need to return them to the caller, and the caller has to pass
them to opPic():
def numPic():
num1 = int(input("Type a number: "))
num2 = int(input("Type another number: "))
return num1, num2
def opPic(num1, num2):
op = input("Type an operation (add,minus,multi,div):" )
if op == "add":
print (add (num1,num2))
elif (op == "minus"):
print (minus(num1,num2))
elif (op == "multi"):
print (mulit(num1,num2))
elif (op == "div"):
print (div(num1,num2))
else :
print ("operation not recognised")
opPic (num1, num2)
num1, num2 = numPic()
opPic (num1, num2)
To make it loop-based, you could do something like:
def opPic(num1, num2):
while True:
op = input("Type an operation (add,minus,multi,div):" )
if op == "add":
print (add (num1,num2))
elif (op == "minus"):
print (minus(num1,num2))
elif (op == "multi"):
print (mulit(num1,num2))
elif (op == "div"):
print (div(num1,num2))
else :
print ("operation not recognised")
continue
break
Hopefully, you can figure out the other bit on your own, as this looks like a school assignment.

The num1 and num2 you define in numPic are local to that function. You need to return them and pass them to the opPic function for them to be used.
def numPic():
num1 = int(input("Type a number: "))
num2 = int(input("Type another number: "))
return num1, num2
def opPic(num1, num2):
#the same code as before
#except changing opPic() to opPic(num1, num2)
print ("Hello User")
num1, num2 = numPic()
opPic(num1, num2)
There are better ways of doing what you seem to be aiming for though. You haven't actually used a loop and have used recursion instead.

Related

Save and display calculation history of the python calculator

I need to extend the given calculator program to record the calculations, and recall them as a list using an additional command '?'.
Things to do:
Declare a list to store the previous operations
Save the operator, operands, and the results as a single string, for each operation after each calculation
implement a history() function to handle the operation '?'
Display the complete saved list of operations (in the order of execution) using a new command ‘?’
If there are no previous calculations when the history '?' command is used, you can display the following message "No past calculations to show"
Can someone help me, please?
return a+b
def subtract(a,b):
return a-b
def multiply (a,b):
return a*b
def divide(a,b):
try:
return a/b
except Exception as e:
print(e)
def power(a,b):
return a**b
def remainder(a,b):
return a%b
def select_op(choice):
if (choice == '#'):
return -1
elif (choice == '$'):
return 0
elif (choice in ('+','-','*','/','^','%')):
while (True):
num1s = str(input("Enter first number: "))
print(num1s)
if num1s.endswith('$'):
return 0
if num1s.endswith('#'):
return -1
try:
num1 = float(num1s)
break
except:
print("Not a valid number,please enter again")
continue
while (True):
num2s = str(input("Enter second number: "))
print(num2s)
if num2s.endswith('$'):
return 0
if num2s.endswith('#'):
return -1
try:
num2 = float(num2s)
break
except:
print("Not a valid number,please enter again")
continue
if choice == '+':
result = add(num1, num2)
elif choice == '-':
result = subtract(num1, num2)
elif choice == '*':
result = multiply(num1, num2)
elif choice == '/':
result = divide(num1, num2)
elif choice == '^':
result = power(num1, num2)
elif choice == '%':
result = remainder(num1, num2)
else:
print("Something Went Wrong")
else:
print("Unrecognized operation")
while True:
print("Select operation.")
print("1.Add : + ")
print("2.Subtract : - ")
print("3.Multiply : * ")
print("4.Divide : / ")
print("5.Power : ^ ")
print("6.Remainder: % ")
print("7.Terminate: # ")
print("8.Reset : $ ")
print("8.History : ? ")
# take input from the user
choice = input("Enter choice(+,-,*,/,^,%,#,$,?): ")
print(choice)
if(select_op(choice) == -1):
#program ends here
print("Done. Terminating")
exit()```
You need to declare function history() and list,
last_calculation = []
def history():
global last_calculation
if last_calculation == []:
print("No past calculations to show")
else:
for i in last_calculation:
print(*i) #for single line
Then in the if loop add below code to end of the operations,
last_calculation.append(result)
Then trigger history() function, use 'continue' to make operation after the call history()
if choice=='?':
history()
continue
To save the history, you can add a global variable which is an empty list. Like this:
history = []
...
def record_history(*args):
history.append(args)
def select_op(choice):
...
record_history(choice, num1, num2, result)
...
This is not the most cleanest solution, but the simplest one since you are only using functions. Ideally functions should not have any side effects and should not depend on the "state" of the program. To save any kind of "state" refactoring this implementation into classes would make things more clean. Something like
class Calculator:
def __init__(self):
self.history = []
def record_history(self, *args):
self.history.append(args)
def select_op(self, choice):
...
self.record_history(choice, num1, num2, result)
...
Tips
Make your life simpler by using the standard library
The operator library provides functions like add, sub, mul etc.
The cmd.Cmd class can be used to build interactive consoles easily.
This is my answer to the problem you face. I have created this and checked it.
calculations = []
def record_history(args):
calculations.append(args)
def history():
if calculations == []:
print("No past calculations to show")
else:
for i in calculations:
print(i)
def add(a,b):
return a+b
def subtract(a,b):
return a-b
def multiply (a,b):
return a*b
def divide(a,b):
try:
return a/b
except Exception as e:
print(e)
def power(a,b):
return a**b
def remainder(a,b):
return a%b
def select_op(choice):
if choice == '#':
return -1
elif choice == '$':
return 0
elif choice in ('+', '-', '*', '/', '^', '%'):
while True:
num1s = input("Enter first number: ")
print(num1s)
if num1s.endswith('$'):
return 0
if num1s.endswith('#'):
return -1
try:
num1 = float(num1s)
break
except:
print("Not a valid number, please enter again")
continue
while True:
num2s = input("Enter second number: ")
print(num2s)
if num2s.endswith('$'):
return 0
if num2s.endswith('#'):
return -1
try:
num2 = float(num2s)
break
except:
print("Not a valid number, please enter again")
continue
result = 0.0
last_calculation = ""
if choice == '+':
result = add(num1, num2)
elif choice == '-':
result = subtract(num1, num2)
elif choice == '*':
result = multiply(num1, num2)
elif choice == '/':
result = divide(num1, num2)
elif choice == '^':
result = power(num1, num2)
elif choice == '%':
result = remainder(num1, num2)
else:
print("Something Went Wrong")
last_calculation = "{0} {1} {2} = {3}".format(num1, choice, num2, result)
print(last_calculation)
record_history(last_calculation)
elif choice == '?':
history()
else:
print("Unrecognized operation")
while True:
print("Select operation.")
print("1.Add : + ")
print("2.Subtract : - ")
print("3.Multiply : * ")
print("4.Divide : / ")
print("5.Power : ^ ")
print("6.Remainder: % ")
print("7.Terminate: # ")
print("8.Reset : $ ")
print("8.History : ? ")
# take input from the user
choice = input("Enter choice(+,-,*,/,^,%,#,$,?): ")
print(choice)
if select_op(choice) == -1:
#program ends here
print("Done. Terminating")
break

how to make a calculator with a loop until I choose to break

I'm trying to build a calculator with a loop until I choose to break it or end it.
Can you please suggest?
Thank you in advance,
Max
new_operation = input("press enter to make a new operation or type the word exit to finish")
num1 = int(input("Enter a number: "))
op = input("Enter the operator: ")
num2 = int(input("Enter a second number: "))
while new_operation != ("no"):
if op == ("+"):
print (num1 + num2)
elif op == ("-"):
print (num1 - num2)
elif op == ("*"):
print (num1 * num2)
elif op == ("/"):\
print (num1 / num2)
else:
print ("Invalid operation")
new_operation = input("make a new operation")
Your code looks good, but need some tweak to make it "do while" loop kind of implementation.
while True:
num1 = int(input("Enter a number: "))
op = input("Enter the operator: ")
num2 = int(input("Enter a second number: "))
if op == ("+"):
print (num1 + num2)
elif op == ("-"):
print (num1 - num2)
elif op == ("*"):
print (num1 * num2)
elif op == ("/"):\
print (num1 / num2)
else:
print ("Invalid operation")
new_operation = input("press enter to make a new operation or type the word exit to finish")
if(new_operation == ("no")):
break
Some suggestions:
Check your indentation, as commented above. Python is sensitive to that.
Make sure your inputs and outputs are more consistent and useful. Your prompt says I should type exit, but your code requires them to type no...
Your looping structure is a bit broken. This is to be expected for somebody new to coding. One of my favorites for this case is:
print('Welcome to the calculator!')
do_run = True
while do_run:
...
do_run = input('Would you like to continue [y/n]: ')[0].lower() == 'y'

How to input string to function?

Here are the instructions I received for my assignment:
4) Add the following function into Mylib
scalc(p1)
p1 will be a string like this "N1, N2, operator"
examples
scalc("20,30,*")
the result will be 600
scalc("50,20,+")
the result will be 70
scalc("50,20,-")
the result will be 30
scalc("60,20,/")
the result will be 30
use string functions to parse the first number, the second number, and the operator from the input string.
use the prior functions (add, subtract, divide and multiply ) to do the calculations.
And here is my attempt that is not working. I have the add() sub() mult() div() functions, I'm just not showing them here.
I know it's something very simple that likely has to do with where I call the function scalc(p1). What is the proper way to do that?
def scalc(p1):
astring = p1.split(",")
num1 = float(astring[0])
num2 = float(astring[1])
if astring[3] == "+":
add()
elif astring[3] == "-":
sub()
elif astring[3] == "*":
mult()
elif astring[3] == "/":
div()
return num1, num2
p1 = input("Enter two numbers and an operator, each separated by a comma: ")
scalc(p1)
EDIT: Here is the Answer. I did not have arguments being passed to my functions. By adding num1 and num2 to every instance of my arithmetic functions, they were able to receive the new variable values.
#Define the main program function
def main():
#Define input function
def float_input(msg):
while True:
try:
return float(input(msg))
except ValueError:
print("You must enter a number!")
else:
break
#Declare variables
rangeLower = float_input("Enter your Lower range: ")
rangeHigher = float_input("Enter your Higher range: ")
num1 = float_input("Enter your First number: ")
num2 = float_input("Enter your Second number: ")
#Define formula functions
def add(num1, num2):
sum = num1 + num2
print("The Result of",num1,"+",num2,"=", sum)
def sub(num1, num2):
diff = num1 - num2
print("The Result of",num1,"-",num2,"=", diff)
def mult(num1, num2):
product = num1 * num2
print("The Result of",num1,"*",num2,"=", product)
def div(num1, num2):
if num2 == 0:
print("The Result of",num1,"/",num2,"= You cannot divide by Zero")
else:
quotient = num1 / num2
print("The Result of",num1,"/",num2,"=", quotient)
#If-else
if num1 < rangeLower or num1 > rangeHigher or num2 < rangeLower or num2 > rangeHigher:
print("The input values are outside the input ranges.")
print("Please check the number and try again.")
print("Thanks for using our calculator")
else:
#Call functions
add(num1, num2)
sub(num1, num2)
mult(num1, num2)
div(num1, num2)
print("Thanks for using this calculator!")
def scalc(p1):
astring = p1.split(",")
num1 = float(astring[0])
num2 = float(astring[1])
if astring[2] == "+":
add(num1, num2)
elif astring[2] == "-":
sub(num1, num2)
elif astring[2] == "*":
mult(num1, num2)
elif astring[2] == "/":
div(num1, num2)
return num1, num2
p1 = input("Enter two numbers and an operator, each separated by a comma: ")
scalc(p1)
This does it. There were a couple errors. First, in Python you start counting at 0, so you wanted to use astring[2] instead of astring[3]. Also you needed a value to be returned:
def scalc(p1):
astring = p1.split(",")
print(astring)
num1 = float(astring[0])
num2 = float(astring[1])
if astring[2] == "+":
add(num1,num2)
elif astring[2] == "-":
sub(num1,num2)
elif astring[2] == "*":
mult(num1,num2)
elif astring[2] == "/":
div(num1,num2)
return value
p1 = input("Enter two numbers and an operator, each separated by a comma: ")
scalc(p1)
Example:
input: "20,30,+"
Out[2]: 50.0

NameError: name '' is not defined with multiple define functions

I just want to start off by saying I know this code is wrong, I'm just testing
this is meant to be a calculator, as you may be able to see from the code I am trying to make the number they end with e.g.
10 + 10 = 20, they will keep the number 20 and can carry on with 20, I want to keep repeating that option
Code:
def add(num1, num2):
return num1 + num2
def mul(num1, num2):
return num1 * num2
def sub(num1, num2):
return num1 - num2
def div(num1, num2):
return num1 / num2
def main():
operation = input("Do you want to(+,-,*,/): ")
if(operation != "+" and operation != "-" and operation != "*" and operation != "/"):
print("That is an invalid operation")
else:
num1 = float(input("choose a number: "))
num2 = float(input("Choose another number: "))
if(operation == "+"):
answer = (add(num1, num2))
print(answer)
elif(operation == "-"):
answer = (sub(num1, num2))
print(answer)
elif(operation == "*"):
answer = (mul(num1, num2))
print(answer)
elif(operation == "/"):
answer = (div(num1, num2))
print(answer)
else:
print("Syntax error!")
def multiple(multiple):
multiple = input("would you like to carry the number(Y or N): ")
if(multiple == "Y" or multiple == "y"):
carry = input("(+,-,*,/): ")
num3 = int(input("choose a number: "))
if(carry == "+"):
print(answer + num3)
elif(carry == "-"):
print(answer - num3)
elif(carry == "*"):
print(answer * num3)
elif(carry == "/"):
print(answer / num3)
else:
print("Syntax Error!")
multiple = True
while multiple == True:
multiple()
choice = input("would you like multiple calculations? (Y or N): ")
while(choice == "y" or choice == "Y"):
main()
multiple()
multiple()
main()
error message:
line 56, in <module>
multiple()
NameError: name 'multiple' is not defined
p.s There may be some indentation errors in this as it pasted strange
You're trying to call the function multiple outside of the scope of the main function while it is only defined in it. Assuming that your indentation is as presented here, you need to move the definition of multiple outside of main so that it can be called.
Additionally, you're defining a variable named multiple which might create some problems. You should change it to something else.
I optimized your code a little and fixed it. It works fine so take a look at it.
def add(num1, num2):
return num1 + num2
def mul(num1, num2):
return num1 * num2
def sub(num1, num2):
return num1 - num2
def div(num1, num2):
return num1 / num2
def main(carry):
operation = input("Do you want to (+,-,*,/): ")
if(operation != "+" and operation != "-" and operation != "*" and operation != "/"):
print("That is an invalid operation")
else:
num1 = float(input("choose a number: "))
if carry == None:
num2 = float(input("Choose another number: "))
else:
num2 = carry
if(operation == "+"):
answer = add(num1, num2)
elif(operation == "-"):
answer = sub(num1, num2)
elif(operation == "*"):
answer = mul(num1, num2)
elif(operation == "/"):
answer = div(num1, num2)
print(answer)
return answer
if input("would you like multiple calculations? (Y or N): ") in ("y", "Y"):
domultiple = True
else:
domultiple = False
carry = None
while 1:
carry = main(carry)
if domultiple:
if input("would you like to carry the number (Y or N): ") in ("n", "N"):
break
else:
break

Repeating code 3 times, and making sure input is only a number in Python 2.7

I am trying to find out how to make my code repeat its self 3 times at the end of the set of questions and also I'm trying to make sure my validation is correct so that the input to the questions is only a number.
This is my code...
import random
correct = 0
name = raw_input("Please enter your name: ")
print 'ok',name, 'I need you to answer these 10 math simple maths questions'
for counter in range(10):
num1 = float(random.randint(1, 10))
num2 = float(random.randint(1, 10))
Math = random.choice(["+", "-", "*","/"])
print("Please solve:", num1, Math, num2)
user = int(input(""))
if Math == "+":
answer = num1 + num2
elif Math == "-":
answer = num1 - num2
elif Math == "*":
answer = num1 * num2
elif Math == "/":
answer = num1 / num2
if answer!= int:
print ("Please reenter a number")
if user == answer:
print("Correct!")
correct = correct + 1
else:
print("Incorrect")
print(name, " You Got", correct, "Out Of 10")
Your answer != int should be if not isinstance(answer, int)
Furthermore, you will get ValueError each time user tries to insert characters.
Because of this, you should edit your code to look like this:
from __future__ import division
import random
for i in xrange(3):
correct = 0
name = raw_input("Please enter your name: ")
print 'ok',name, 'I need you to answer these 10 math simple maths questions'
for counter in xrange(3):
num1 = random.randint(1, 10)
num2 = random.randint(1, 10)
Math = random.choice(["+", "-", "*","/"])
print("Please solve: {} {} {}".format(num1, Math, num2))
while True:
try:
user = int(raw_input(""))
except ValueError:
print ("Please reenter a number")
continue
break
if Math == "+":
answer = num1 + num2
elif Math == "-":
answer = num1 - num2
elif Math == "*":
answer = num1 * num2
elif Math == "/":
answer = round(num1 / num2, 1)
if user == answer:
print("Correct!")
correct = correct + 1
else:
print("Incorrect")
print("{} You Got {} Out Of 10".format(name, correct))
As you can see there was a lot things that you needed to change.

Categories