Closing a program when a condition is met - python

I am just starting out and can't figure this one out.
I am writing a program to do some simple calculations for me at school.
Different calculations will be accessible through input of simple numbers from 1 to X. Every number will call a function just for that calculation.
My problem is this:
I want that if the user enters an empty string when prompted for a number, the program will ask the user to re enter a number for a certain amount of times before closing. Here's my code:
def pick_procedure():
procedure = raw_input("> ")
if not procedure:
counter = 0
print "Enter a value. "
while counter <4:
counter = counter + 1
main()
if counter == 4:
break
def main():
print "\nStudy helper 1.0.\n"
print """Procedure list:
1.Area of circle.
2. Circumference of a circle.
Please pick a procedure: """
pick_procedure()
main()
No matter how many times an empty string is entered, the program does not close.
How to do it correctly and cleaner?

As you say, you need to reorganise your code:
def pick_procedure(valid_choices):
print "Enter a value. "
for _ in range(4): # prompt for a choice up to 4 times
choice = raw_input("> ")
if choice in valid_choices:
return choice
return None # A valid choice was not entered
def main():
print "\nStudy helper 1.0.\n"
choice = 1
while choice:
print """Procedure list:
1. Area of circle.
2. Circumference of a circle.
Please pick a procedure: """
choice = pick_procedure(["1", "2"])
if choice:
print "Doing choice", choice
main()
The following approach makes use of a while choice loop to keep prompting if a valid choice is entered. If no choice is entered 4 times, the pick_procedure() function returns None causing the while loop to exit cleanly. If a valid choice is entered, it returns that choice.
I also pass the list of valid responses to the function, that way the function can be used for other questions simply by passing a different list of valid responses.

You created a vicious circle.
First time that procedure is false, pick_procedure calls main and then main calls again pick_procedure. It continues recursively.
If you just want to finish the program when an event is fired, you can use sys.exit(0) and your problems are solved.

Related

Name Error in python from function

I have a code here that uses functions to draw outputs. I keep getting "prompt" is not defined but isn't it already stated in the function filterer?
[enter image description here][1]
def menu():
print ("[1] Compute Area of a Circle")
print ("[2] Compute Perimeter of a Rectangle")
print ("[3] Compute Volume of a Cone")
print ("[4] Compute Slope of a Straight Line")
print ("[5] Exit")
#Determining the input of the user
choice = filterer("Choose from the menu:")
#function for the filter
def filterer(prompt):
while True:
choice = float(input(prompt))
if choice > 5 or choice < 1:
print ("Must input integer between 1 and 5. Input again")
elif choice.is_integer == False:
print ("Must put an integer. Input again.")
else:
return prompt
filterer(choice)
#Hamms and #stybl both answered this in the comments, however, just to be clear, you need to change
filterer(prompt)
into
filterer("do some amazing thing or something")
Except with the quote you want to use as a prompt instead of "do some amazing thing or something."
The key to this is to think about the scope of the code. filterer(prompt) assumes prompt is defined by the time it's called. But you're calling it without ever defining a prompt. You could define the prompt if you wanted to, for example,
prompt = "do something super groovy"
filterer(prompt)
Others have pointed out the main issue, which is that you're trying to reference a variable (prompt) which doesn't exist in that scope.
That said, I don't think you want to call filterer twice, and I don't think you want it to return the prompt, but rather the choice made. Also, your integer testing wasn't right.
Here's full working code:
def filterer(prompt):
while True:
try:
choice = int(input(prompt))
except ValueError:
# Value couldn't be parsed as an integer
print("You must enter an integer. Try again.")
else:
# Value was successfully parsed
if choice > 5 or choice < 1:
print("Must input integer between 1 and 5. Input again")
else:
return choice # <-- changed from prompt
def menu():
print("[1] Compute Area of a Circle")
print("[2] Compute Perimeter of a Rectangle")
print("[3] Compute Volume of a Cone")
print("[4] Compute Slope of a Straight Line")
print("[5] Exit")
# Determining the input of the user
choice = filterer("Choose from the menu: ")
print("You chose: {}".format(choice))
menu()
prompt is defined within the scope of the function filterer, so it cannot be accessed outside the function. The line:
filterer(prompt)
Should be changed to something like:
foo=filterer(bar)
The variable bar has to be defined before doing this.

I need to figure out how to make my program repeat. (Python coding class)

I am a beginner student in a python coding class. I have the majority of the done and the program itself works, however I need to figure out a way to make the program ask if wants a subtraction or an adding problem, and if the user would like another question. I asked my teacher for assistance and he hasn't gotten back to me, so I'm simply trying to figure out and understand what exactly I need to do.
import random
x = int(input("Please enter an integer: "))
if x < 0:
x = 0
print('Negative changed to zero')
elif x == 0:
print('Zero')
elif x == 1:
print('Single')
else:
print('More')
maximum = 10 ** x;
maximum += 1
firstnum = random.randrange(1,maximum) # return an int from 1 to 100
secondnum = random.randrange(1, maximum)
compsum = firstnum + secondnum # adds the 2 random numbers together
# print (compsum) # print for troubleshooting
print("What is the sum of", firstnum, " +", secondnum, "?") # presents problem to user
added = int(input("Your answer is: ")) # gets user input
if added == compsum: # compares user input to real answer
print("You are correct!!!")
else:
print ("Sorry, you are incorrect")
You'll want to do something like this:
def foo():
print("Doing good work...")
while True:
foo()
if input("Want to do more good work? [y/n] ").strip().lower() == 'n':
break
I've seen this construct (i.e., using a break) used more often than using a sentinel in Python, but either will work. The sentinel version looks like this:
do_good_work = True
while do_good_work:
foo()
do_good_work = input("Want to do more good work? [y/n] ").strip().lower() != 'n'
You'll want to do more error checking than me in your code, too.
Asking users for input is straightforward, you just need to use the python built-in input() function. You then compare the stored answer to some possible outcomes. In your case this would work fine:
print('Would you like to test your adding or subtracting skills?')
user_choice = input('Answer A for adding or S for subtracting: ')
if user_choice.upper() == 'A':
# ask adding question
elif user_choice.upper() == 'S':
# ask substracting question
else:
print('Sorry I did not understand your choice')
For repeating the code While loops are your choice, they will repeatedly execute a statement in them while the starting condition is true.
while True: # Condition is always satisfied code will run forever
# put your program logic here
if input('Would you like another test? [Y/N]').upper() == 'N':
break # Break statement exits the loop
The result of using input() function is always a string. We use a .upper() method on it which converts it to UPPERCASE. If you write it like this, it doesn't matter whether someone will answer N or n the loop will still terminate.
If you want the possibility to have another question asked use a while loop and ask the user for an input. If you want the user to input whether (s)he want an addition or substraction you already used the tools to ask for such an input. Just ask the user for a string.

issues with looping, calling functions to loop

I have to write a program that performs Egyptian type of multiplication. I have the math correct(for the most part) But I've searched and searched and searched and can't really pin point down a correct loop.
I need the program to loop the calculation part, ending with it asking if you want to loop it again to put in different numbers. I also need a negative section, to calculate the outcome if using negative numbers, which I am completely drawing a blank to do.
What I've got so far:
import math
def egyptian(positive):
a,b = raw_input('Please input the two numbers separated by a space').split()
a = int(a)
b = int(b)
answer = 0
while b != 0:
if (a%2 != 0):
print "B was odd, we add A to make the product: ", (a)
answer = answer+a
a = a*2
b = b//2
if (b%2 == 0):
a = A*2
b = b//2
print "The product of the two numbers is", (answer)
choice = ""
if choice != "y" or "Y":
choice = raw_input("Do you want to continue?(y/n)")
if choice == "Y" or "y":
goto NO idea what to put here to get it to loop.
if choice != "Y" or "y":
print "Quitting"
I understand the choice part at the bottom is probably way off for what I want it to do.
Any help is greatly appreciated
I don't see where you are calling your egyptian function? But what you can do is you can put all of the code inside of the egyptian function, and then you can have the function call itself to make it loop again.
Also the line choice = "" should be choice = raw_input("Do you want to continue?(y/n)"). You need to ask for the input first, and then once you have their input you add the correct logic to determine if they would like to loop again.
There is another way you could solve this issue, but it's not as good of a solution because it's always better to break your code down into smaller function, but you could also have a loop inside of a loop. The outer loop would decide if you should loop again, the inner loop does the egyptian multiplication code.

How to Go Back to an Original Prompt in Python

I am trying to create a basic calculator that takes the first number, takes the operation(+,-,*,/), and second number. If a person puts in a zero for the first number and/or the second number my program is supposed to go back to the number it was at and ask again for a number other than 0. So if a person puts in 0 for number 2 then my program will take the person back to number two. I am also supposed to do the same concept for the operation but have the person start over if they do not put in the operation available to use which includes the ones previously shown in parentheses. Below is the code I have so far. Any help would be appreciated. My class is currently on while loops and breaks among other things, but I am wondering if those two would be beneficial in my code.
#Programming Fundamentals Assignment Unit 5
#Create a basic calculator function
while True:
#Num1 will require user input
num1 = input ("Enter the first number\n")
#Operation will require user input
operation = raw_input("Enter the operation(+,-,*,/)\n")
#Num2 will require user input
num2 = input("Enter the second number\n")
#Now to define how the operation will be used
if operation == "+":
print num1+num2
elif operation == "-":
print num1-num2
elif operation == "*":
print num1*num2
elif operation == "/":
print num1/num2
else:
print "Please enter an operation"
#Exit will end the calculation from going into a loop
exit()
Put loops around your various inputs to ensure proper checking. So for the first number, you could have:
num1 = 0
while num1 == 0:
num1 = input ("Enter the first number\n")
This'll keep asking till they input something that isn't a 0.
For the second issue (starting over if they enter an invalid operation), you want to immediately check if the operation is valid and if it isn't, then you need to re-loop (which is just by skipping the remaining parts of the current loop).
So to easily check if it's valid:
operation not in ["+","-","*","/"]
which will return false if they enter invalid, and then the second part (skipping the rest of the loop) can easily be accomplished with the "continue" keyword.
if operation not in ["+","-","*","/"]:
continue
This will take you back to the beginning of the loop, asking for new number first number.
When you want to stop execution, you'll need to implement "break" which will break out of the inner most loop that it's a part of.

python checking user input for number in a while loop

I have a function below which is part of my big main function, what I want this function to do is that whenever called, I want the function to check if the user input is
a number or not. If it is a number it will return the number and break.
But if it is not a number I want it to loop again and again.when I try to
run it, it gives me unexpected an error:
unexpected eof while parsing
can any body help me what I am missing or how I should rearrange my code? thank you!
def getnumber():
keepgoing==True
while keepgoing:
number = input("input number: ")
result1 = number.isdigit()
if result1 == 1:
return number
break
elif keepgoing==True:
A neater and clearer what to do what you are already doing:
def getnumber():
while True:
number = input("Input number: ")
if number.isdigit():
return number
That's all you need, the extra variables are superfluous and the elif at the end makes no sense. You don't need to check booleans with == True or == 1, you just do if condition:. And nothing happens after return, your break will never be reached.
You don't need the last line:
elif keepgoing==True:
It's waiting for the rest of the file after the :.
Side note, it should be a single = in the first part, and can just be written simpler as well.
def getnumber():
while True:
number = input("input number: ")
result1 = number.isdigit()
if result1:
return number
Since you're inside the while loop, it'll keep executing. Using return will end the while loop, as will breaking and exiting the program. It will wait for input as well each time, though.
While assigning you have used keepgoing == True, I think it should be keepgoing=True
The following solution works on my machine, although I am running Python 2.7
def get_num():
while True: #Loop forever
number_str = raw_input("> Input a number: ") #Get the user input
if number_str.isdigit(): #They entered a number!
return int(number_str) #Cast the string to an integer and return it
I used raw_input rather than input, because raw_input gives you the exact string the user entered, rather than trying to evaluate the text, like input does. (If you pass the 12 to input, you'll get the number 12, but if you pass "12", you'll get the string '12'. And, if you pass my_var, you'll get whatever value was in my_var).
Anyway, you should also know that isdigit() returns whether or not the string has only digits in it and at least one character - that is not the same thing as isNumber(). For instance, "123".isdigit() is True, but "123.0".isdigit() is False. I also simplified your loop logic a bit.

Categories