I'm super new to Python and programming in general. I am following an example off of youtube on how to make a simple calculator but I wanted to add my ideas and functionalities. More or less I want to make it very versatile.
This is the part that is not working out for me. I don't know how to make it work using the two methods I created
def main():
while True:
Num1()
num1 = int.num1()
Num2()
num2 = int.num2()
# Executing the specified calculations with the 'Operation' function (row 13)
Operation(num1, num2)
# --> followed by another nested while asking if the user wants to make another calculation
I want the app to read everywhere that if the user types "exit" it will exit, even if it's asking for a number so I created 2 methods to do so because it wasn't working dealing with the loops and user input directly from main()
def Num1():
while True:
num1 = input("What is the first number? ")
if num1.isdigit():
break
elif num1 == 'exit':
print("Thank you using the SimpleCalculator. Bye!")
time.sleep(3)
exit()
else:
print("I don't understand. Please input a valid number")
continue
def Num2():
while True:
num2 = input("What is the second number? ")
if num2.isdigit():
break
elif num2 == "exit":
print("Thank you using the SimpleCalculator. Bye!")
time.sleep(3)
exit()
else:
print("I don't understand. Please input a valid number")
continue
The problem is that I get this error and I get it but I just don't know how to go about it.
Traceback (most recent call last):
File "C:/Users/Albert/PycharmProjects/HelloWorld - First Py'
Apps/SimpleCalculator.py", line 131, in <module>
main()
File "C:/Users/Albert/PycharmProjects/HelloWorld - First Py'
Apps/SimpleCalculator.py", line 109, in main
Operation(num1, num2)
NameError: name 'num1' is not defined
I see few general errors in your code:
You call function Num1() for entering num1, but num1 is the local
variable. So you can see and use it only in Num1() function. Same
with num2. So, I suggest to use Num1 and Num2 but to return the num1
and num2.
I recommend to use 1 function, there is no need to use 2.
Looks like with num1 = int.num1() you want to convert num1() to int. This is wrong. Correct will be something like num1 = int(num1).
This will convert num1 from string to int and save it to num1. But
better to use different names for strings and int's: num1 =
int(num1_str). And when you use bracket num1(), this means you call
num1 function to complete. But num1 is not a function, so it's not
callable.
You use converting strings to int two times. In programming, when you see two code, which is just copy/paste, you better to make a
function for it. Here we have the function, so just insert
converting to int in function.
Don't forget about indentation. This is the most important thing in Python. In other languages, you use something like {} to define
the beginning and the end of some logical block. But in Python, it
all depends on indentation.
So, using this, it can look like this way:
def main():
while True:
# just call NumEntering - one general function for entering numbers,
# and give to it attribute - message for user.
num1 = int(NumEntering("What is the first number? "))
num2 = int(NumEntering("What is the second number? "))
# Executing the specified calculations with the 'Operation' function (row 13)
Operation(num1, num2)
And the function:
def NumEntering(message): # message - this what function get from outer function.
while True:
num_str = input(message) # show given message
if num_str.isdigit():
return int(num_str) # convert to int and return to outer function
elif num_str == 'exit':
print("Thank you using the SimpleCalculator. Bye!")
time.sleep(3)
exit()
else:
print("I don't understand. Please input a valid number")
continue
case sensitivity, you defined Num1() & Num2() not num1() & num2()
There's plenty wrong with your code.
DRY Do not Repeat Yourself. There's no need to have two functions when they do the same thing. Delete Num2 in its entirety. It's useless.
Num1 isn't returning a value. We want the function to ask the user for a number (which it does), exit if the user inputs "exit" (also done) and return the number entered by the user (not done).
Function names start with a lowercase letter and are descriptive. Num1 does neither, so let's change it to ask_number.
All the problems identified above can be fixed by replacing Num1 and Num2 with the following ask_number function.
def ask_number():
while True:
num = input("What is the first number? ")
if num.isdigit():
return int(num) #This line fixes problem 2
elif num == 'exit':
print("Thank you using the SimpleCalculator. Bye!")
time.sleep(3)
exit()
else:
print("I don't understand. Please input a valid number")
Your main method isn't assigning the return value of your function into the variables.
Fix it by replacing your old code
Num1()
num1 = int.num1()
Num2()
num2 = int.num2()
with
num1 = ask_number()
num2 = ask_number()
We're calling the ask_number function twice and assigning its return value to num1 and num2.
The problem was that Num1() and Num2() asked the questions, but didn't do anything with them. Also, the num1 and num2 that were defined were variables local to the function, so you couldn't access them from the main() function. You should have added "return numX" instead of break and assigned Num1() to num1, which allows you to capture the user's input in a variable accessible by the main() function.
This is what your code should have looked like:
import time
def Num1():
while True:
num1=input("What is the first number? ")
if num1.isdigit():
return int(num1)
elif num1 == 'exit':
print("Thank you using the SimpleCalculator. Bye!")
time.sleep(3)
exit()
else:
print("I don't understand. Please input a valid number")
def Num2():
while True:
num2=input("What is the first number? ")
if num2.isdigit():
return int(num2)
elif num2 == 'exit':
print("Thank you using the SimpleCalculator. Bye!")
time.sleep(3)
exit()
else:
print("I don't understand. Please input a valid number")
def Operation(num_1, num_2):
# code for Operation function
pass
def main():
while True:
num1=Num1()
num2=Num2()
Operation(num1, num2)
if __name__=="__main__": main()
Disclaimer: I'd ask for some clarification, but I don't have the SO privileges yet.
Can you make sure your indentation is correct when you're running the program? For instance, your while loops shouldn't be on the same indentation level as your function definitions.
Also, are you functions all in this file SimpleCalculator.py? If so, you will need to have an additional line to call your methods, since right now they're only being declared.
if __name__ == '__main__':
# And the following line will call your main function which you defined previously
main()
Better yet, just remove your main() function and replace it with the more Pythonic syntax:
if __name__ == '__main__':
while True:
Num1()
Num2()
Also, since you're calling Num1() and Num2() and they're handling the inputs, you don't need to set num1 = int.num1() or num = int.num2() (which both give me errors) or the like. If you want to have the values to be returned to the main method for handling, you'll need to do return num1 when you check if num1.isdigit():, and in your main method set firstNumberInput = Num1()
Hope this helps!
It may just be that you have posted your code with omissions but there are several points to address.
The functions Num1 and Num2 do not return anything. Although the value num1 is assigned within the function, it is not accessible outside that function's scope.
int does not have a method "num1" so calling int.num1() should be replaced with int(num1())
Creating 2 nearly identical functions creates a lot more work for yourself and makes the code hard to change, you could create a more general function.
def getnum():
while True:
mynum = input("What is the first number? ")
if mynum.isdigit():
break
elif mynum == 'exit':
print("Thank you using the SimpleCalculator. Bye!")
time.sleep(3)
exit()
else:
print("I don't understand. Please input a valid number")
return mynum
def main():
while True:
num1 = int(getnum())
num2 = int(getnum())
Related
I am upskilling a bit with my Python and have a passing values question (Got the task off an online python task website).
Call 'UserInput' twice and assign it to two different variables.
Pass the results of this to the Adder function.
Output the result of the Adder function as part of a sentence.
I am unsure about running the same function twice and setting them as separate variables, and running it in main.
This is mine so far:
def Adder(n1,n2):
ans = n1+n2
#print(ans)
print(n1)
def userinput():
try:
n1 = int(input("Please enter an integer!: "))
except:
print("that is not an integer try again!")
else:
print("thank you for this integer")
print(n1)
return(n1)
def main():
userinput()
Adder(n1,n2)
main();
Expecting two numbers in the main and then pass them to "Adder"
I have worked on many projects (school projects, I'm not too advanced), and have found that in many programs where I require the user to input a value that is an integer, or decimal(float), I need to use a "try-except" statement, within a while loop, in order to make certain that the user inputs the required value type.
For example:
def main():
userValue = input("Please enter an integer: ")
while(True):
try:
userValue = int(userValue)
break
except:
userValue = input("That is not an integer, try again: ")
print("The integer you entered is: " + str(userValue))
main()
# Input: SADASD (A non-integer value)
# Output: "That is not an integer, try again: "
# Second-Input: 3
# Second-Output: "The integer you entered is: 3"
Understandably, typing out this entire section of code repeatedly, in a program that requires user input multiple times, is not really efficient. So understanding, that user-defined functions help when I need to perform one action, multiple times. With this in mind, I defined my own function with that same try-except statement in a while loop. However, now, when I use the function, instead of printing the same output previously, rather, it prints out the first value the user had input.
For example:
def valueCheck_Integer(userInput):
while(True):
try:
userInput= int(userInput)
break
except:
userInput = input("That is not an integer, try again: ")
def main():
userValue = input("Please enter an integer: ")
valueCheck_Integer(userValue)
print("The integer you entered is: " + str(userValue))
main()
# Input: SADASD (A non-integer value)
# Output: "That is not an integer, try again: "
# Second-Input: SASASD
# Second-Output: "That is not an integer, try again: "
# Third-Input: 3
# Third-Output: SADASD (The first value that the user Input, instead of 3)
Can someone please explain to me why this happens, and some suggestions on how to fix it?
Thank you!
It's probably going to be easier to expect the function to get/check/return the integer rather than check input you already have. You can pass it the string to use for asking for the value (you could also pass the error string). It will keep asking until it's successful and then return the number you want:
def get_integer(question):
while(True):
try:
return int(input(question))
except ValueError:
question = "That is not an integer, try again:"
def main():
userValue = get_integer("Please enter an integer: ")
print("The integer you entered is: " + str(userValue))
main()
It is because of you are printing userValue instead of userInput.
I used return make it easier. So the code will be like this
def valueCheck_Integer(userInput):
while(True):
try:
userInput= int(userInput)
break
except:
userInput = input("That is not an integer, try again: ")
return userInput
def main():
userValue = input("Please enter an integer: ")
print("The integer you entered is: " + str(valueCheck_Integer(userValue)))
main()
You can make your code smaller like this:
def valueCheck_Integer(userInput):
while not(userInput.isdigit()):
userInput = input("That is not an integer, try again: ")
return userInput
def main():
userValue = input("Please enter an integer: ")
print("The integer you entered is: " + str(valueCheck_Integer(userValue)))
main()
First off, Good Question.
To understand what is going on, we first have to talk about scope of a variable.
When you define a variable outside a function, it becomes something called a global variable. This basically means that you can access it from anywhere in your code. When you define the variable within a function, it becomes a local variable. This means that it is only accessible from within your function. Finally, when a function gets passed in a variable, it gets its own local copy of the variable to work with.
Now let's look at your code.
when you call valueCheck_Integer(userInput): the function gets its own copy of userInput to work with. thus all the changes that the function does modifies the local userInput while the global userInput stays the same. As such, when the user enters a correct answer, the global userInput is the one that gets printed and the changes the function makes to local userInput is lost.
So, how can we fix this?
There are two main methods:
1)Using the global keyword
def valueCheck_Integer(userInput):
global userInput
while(True):
try:
userInput= int(userInput)
break
except:
userInput = input("That is not an integer, try again: ")
This keyword asks the function to modify the global userInput
2)Returning a value
def valueCheck_Integer(userInput):
while(True):
try:
userInput= int(userInput)
break
except:
userInput = input("That is not an integer, try again: ")
return userInput
def main():
userValue = input("Please enter an integer: ")
print("The integer you entered is: " + str(valueCheck_Integer(userValue)))
main()
This works by returning the local copy of userInput and modifying global userInput to equal local userInput
The second code I used was from
Osadhi Virochana Jayasinghe Si's answer.
It's because, if you see your line of code where you print the final output -:
print("The integer you entered is: " + str(userValue))
you will realise that the value you are printing is the one you take the first time from the input function. But this is not the value you have been working on to achieve in your other function.
So for you to rather get that value, the function in some way has to return it back to you.
For this you should allow the function to return the value in the last line.
like so -:
return userInput
and then change the line where you call function so it saves the value returned.
like so -:
userValue = valueCheck_Integer(userValue)
Also as mentioned by others using the global keyword you can define the variable in global scope.
But this is really not a good practice until really needed as it can increase the amount of space that the var is taking, before the variable only took the space for a limited time for when the function is called, but now the variable takes space throughout the time the program runs.
While return will not do so as it will only return the value and once assigned to the already defined variable it will remove the returned value from space.
This should hopefully fix your problem.
I hope this helps.
And also hope that you're safe during the time of this ongoing pandemic.
This question already has answers here:
Class return statement not printing any output
(1 answer)
Why doesn't Python print return values?
(3 answers)
Closed 3 years ago.
I am a beginner with Python and am trying to write my first calculator program. However, the test that I set up for it did not work. It asked me for the operation and the numbers, but it didn't print the result. Why not?
I have tried rewriting it in different ways, but it still doesn't work.
def add(num1, num2):
print(str(num1+num2))
def sub(num1, num2):
return str(num1-num2)
def mul(num1, num2):
return str(num1*num2)
def div(num1, num2):
return str(float(num1)/float(num2))
def main():
operation = input("What operation would you like to perform? add, sub, mul or div: ")
num1 = input("What is number 1? ")
num2 = input("What is number 2? ")
if (operation == 'add'):
add(num1, num2)
main()
I expected it to ask what the operation I wanted to perform was, then to ask what the numbers were, and then to print the result. Instead, it does all of those, except print the result. Please could somebody point out where I have gone wrong. NB: I only put in a case for 'add' because I was just testing it.
it does all of those, except print the result
The simplest answer is that it's because you didn't tell it to. Python only prints things out that you tell it to when you write print(<something>) in your code.
When you write add(num1, num2), it is computing the result, but then you aren't doing anything with that result. You could, for instance, do this:
answer = add(num1, num2)
print(answer)
This declares a variable to store the result, so that it isn't lost. And then prints it.
Beyond the immediate question you have about printing the result, you will find that the value you get from input() is a string, not a number. Your add() function will do num1 + num2 but since these are strings, it is actually concatenating (joining) them, like "3" + "4" = "34" which is not what you want.
You should make be sure to convert your inputs to numbers with int() or float(). And I would recommend not having the str() call inside add(). The print() function can print numbers just fine.
num1 = input("What is number 1? ")
input() returns a string, so you need to convert both inputs to int()s so they can have mathematical operations performed.
Here is a working example of your calculator:
def add(num1, num2):
return num1+num2
def sub(num1, num2):
return num1-num
def mul(num1, num2):
return num1*num2
def div(num1, num2):
return num1/num2
def main():
operation = raw_input("What operation would you like to perform? add, sub, mul or div: ")
num1 = float(input("What is number 1? "))
num2 = float(input("What is number 2? "))
if (operation == 'add'):
print(add(num1, num2))
elif (operation == 'sub'):
print(sub(num1, num2))
elif (operation == 'mul'):
print(mul(num1, num2))
elif (operation == 'div'):
print(div(num1, num2))
else:
print("Error: no such operation")
main()
Note: for your operation, you have to use raw_input instead of input.
#This part of the code will only get numbers from user
while True:
#Using while True will allow me to loop and renter if user input is wrong. While True will go above Try Catch
try:
# Using try: and except: will allow to end the program without crash however then need to be indented
# Try goes before the def name
def getNumbers():
num1=int(input("Enter 1st number: "))
num2=int(input("Enter 2nd number: "))
getNumbers()
break# the while will stop when both values are numbers
except:
print("Incorrect input detected, try again")
#This part of the code will add the 2 numbers
def addNums():
What do I put here so that I can use num1+num2
addNums()
def subNums():
What do I put here so that I can use num1-num2
addNums()
I wrote a Calculator program but over there I declared those num1 and num2 as global variables in side getNumbers def. Someone mentioned that is not a good/ideal way which is why I wanted to try this approach.
Thanks in advance.
In order to use global variables inside of a function, use the global keyword:
x = 1
y = 2
def add() :
global x, y
return x + y
EDIT
Actually, your "question" is really unclear. You say you are not willing to use global-variables in your code, but you wrote:
def addNums():
What do I put here so that I can use num1+num2
addNums()
The problem is that num1 and num2 don't exist at this place. If you want to use them, then they are global variables.
As far as I understand, what you want is just a function:
def addNums(x, y):
return x+y
addNums(num1, num2)
I don't know what's your doubt, it's not clear in your post.
Why can't you do in this way (just for e.g, you can make it better):--
Blockquote
def subNums(a, b):
return (a - b)
def addNums(a, b):
return (a + b)
def getNumbers():
while True:
try:
num1 = int(input("Enter 1st number: "))
num2 = int(input("Enter 2nd number: "))
return (num1, num2)
except:
print("Incorrect input detected, try again")
a, b = getNumbers()
print ("sum of %d and %d : %d" % (a, b, addNums(a, b)))
print ("difference of %d and %d : %d" % (a, b, subNums(a, b)))
Hope this will help.
I'm new to stack overflow this is my second question so please bear with me. I'm creating a simple calculator program. Here's the code:
def add(x, y):
return x + y
def subtract(x, y):
return x - y
def multiply(x, y):
return x * y
def divide(x, y):
return x / y
print("what do you want to do?")
print("1.Add:")
print("2.Subtract:")
print("3.Multiply:")
print("4.Divide:")
choice = input("Enter a number 1-4 for your operation: ")
def operation():
if choice == '1':
print(num1,"+",num2,"=", add(num1, num2))
elif choice == '2':
print(num1,"-",num2,"=", subtract(num1, num2))
elif choice == '3':
print(num1,"*",num2,"=", multiply(num1, num2))
elif choice == '4':
print(num1,"/",num2,"=", divide(num1, num2))
else:
print("I SAID A NUMBER 1-4 YOU DUMBASS!")
return(operation(), input())
operation()
num1 = int(input("Enter a number: "))
num2 = int(input("Enter another one: "))
whenever I put a number greater than 5 it uses the else statement and loops the print statement over and over for a couple of seconds then print "recursion error: maximum recursion depth exceeded. I know that by putting the return statement inside the function, the function then loops itself over and over. I then tried to add the input to prompt the user for another input but I guess this isn't the right syntax. Can someone post the right syntax for this code or is there a more concise way of doing this? Thank you any help is appreciated.
The problem is in your else clause:
else:
print("I SAID A NUMBER 1-4 YOU DUMBASS!")
return(operation(), input())
Notice that you call operation again, but you haven't changed the choice at all, so operation will run again with the same choice you had before (over and over until you hit the recursion limit).
At this point, you're probably tempted to do:
choice = input(...)
return operation()
However, that won't work either as choice is a global variable and if you try to modify it in the function, you'll get an UnboundLocalError.
You could declare global choice within operation, but that's suboptimal. A better design would be to pass the choice as an argument to operation:
choice = int(input("Enter a number 1-4 for your operation: "))
def operation(choice):
if choice == 1:
print(num1,"+",num2,"=", add(num1, num2))
elif choice == 2:
print(num1,"-",num2,"=", subtract(num1, num2))
elif choice == 3:
print(num1,"*",num2,"=", multiply(num1, num2))
elif choice == 4:
print(num1,"/",num2,"=", divide(num1, num2))
else:
print("I SAID A NUMBER 1-4 YOU DUMBASS!")
choice = int(input())
return operation(choice)
operation(choice)
Finally, even once you get this part working, you'll have additional problems depending on python2.x or 3.x. On python2.x, input will be returning numbers, not strings, so your equality tests (choice == '1') will never pass. On python3.x, the equality tests will work out just fine (because your choice will be a string), but the math equations will break (you can't multiply 2 strings together).
I've fixed that in the example above -- But remember not to use input in production code for python2.x as it's a huge security risk.
That call is before input so it is calling and calling and calling again. This menu with choices is usually placed inside a while loop.
There are two problems in your code, one is you are comparing a string with integer and the next one with out changing the value of option you are calling the same function, so it keeps on calling itself never ending, so the compiler giving you recursion error.