Im a total python noob and Im trying to figure out why my program doesn't end when I input "0". It just starts the menu over again.
def menu():
print('\n\n\n\n')
print('List Processing Program Menu')
print('0 to exit')
print('1 to view data')
print('2 to append data')
while(1):
try:
choice = -1
while(choice < 0 or choice > 2):
choice = int(input('Please enter a valid number choice '))
break
except ValueError:
print('Enter an integer number for your menu selection')
return choice
def main():
while(1):
choice = menu()
if(choice == 0):
break
main()
while(choice < 0 or choice > 2):
choice = int(input('Please enter a valid number choice '))
break
Your problem is here. The while loop is broken out of and None is always returned (there is an implicit return of None at the end of every Python function).
You can clean up your code as follows:
def menu():
print('\n\n\n\n')
print('List Processing Program Menu')
print('0 to exit')
print('1 to view data')
print('2 to append data')
choice = None
while choice not in [0, 1, 2]:
try:
choice = int(input('Please enter a valid number choice '))
except ValueError:
print('Enter an integer number for your menu selection')
return choice
No value is ever returned from menu because your return statement is inside of the while loop that you break out of before you get to it. Hence, inside of your main, choice is always None.
If you de-indent the return statement this will work as you expect.
def menu():
print('\n\n\n\n')
print('List Processing Program Menu')
print('0 to exit')
print('1 to view data')
print('2 to append data')
while(1):
try:
choice = -1
while(choice < 0 or choice > 2):
choice = int(input('Please enter a valid number choice '))
break
except ValueError:
print('Enter an integer number for your menu selection')
return choice
def main():
while(1):
choice = menu()
if(choice == 0):
break
main()
If you want to be concise, you can remove all of your try/except statements because you never actually need to execute those anyhow.
def menu():
choice = -1
while choice < 0 or choice > 2:
choice = int(input('Please enter a valid number choice'))
return choice
def main():
choice = -1
while choice != 0:
choice = menu()
Right after the while (choice < 0 or choice > 2): loop you say break, but the return choice is inside of the while(1) loop. That means that your function will by implication return None, not choice. You just need to un-indent the return choice line.
Your menu() function returns None because your return statement is inside your while loop, which you break out of when the entry is valid.
Unindent your return statement so it lines up with while, or better yet, just return from inside the loop instead of using break.
You are never returning choice, because it is inside your first while loop. When you break out of that while loop, you just return None since there is no specific return specified. You have two options here:
Move the return outside of the while loop, or do something like this:
try:
choice = -1
while(choice < 0 or choice > 2):
return int(input('Please enter a valid number choice '))
except ValueError:
print('Enter an integer number for your menu selection')
You need to indent the break when you are reading the choice, or else your menu function will always return None.
try:
choice = -1
while(choice < 0 or choice > 2):
choice = int(input('Please enter a valid number choice '))
break
except ValueError:
print('Enter an integer number for your menu selection')
Related
I'm guessing there is a quite simple solution to this. How do I get the user input to be validated and then continue on to be used within another function?
When I run this code, it will just insist that the "Invalid option" has been selected. Is there a way to solve this?
Example:
def user_input():
while True:
try:
option = int(input("Enter an option: "))
break
except ValueError:
print("Invalid input. Please enter a number between 1 and 3.")
if option < 1:
print("Invalid value. Please enter a non-negative integer.")
if option > 3:
print("Please enter an integer between 1 and 3.")
if option >= 1 and option <= 3:
return option
else:
user_input()
def main():
option = user_input()
if option == 1:
print("Option 1 Selected")
elif option == 2:
print("Option 2 Selected")
elif option == 3:
print("Option 3 Selected")
else:
print("Invalid option")
if __name__ == "__main__":
main()
You failed to return the result of the recursive user_input() call, so anytime it recurses, you end up returning None. Using return user_input() instead fixes it, sort of, but it's a bad solution. Just incorporate the range tests into the existing loop. You get rid of the early break, and just continue any time a condition is invalid, then unconditionally return the value if no tests failed:
def user_input():
while True:
try:
option = int(input("Enter an option: "))
except ValueError:
print("Invalid input. Please enter a number between 1 and 3.")
continue
if option < 1:
print("Invalid value. Please enter a non-negative integer.")
continue
if option > 3:
print("Please enter an integer between 1 and 3.")
continue
# No need to test option >= 1 and option <= 3, the prior tests
# would continue if it wasn't valid
return option
Alternatively, you can replace a few of those continues with elif or elses, e.g.:
def user_input():
while True:
try:
option = int(input("Enter an option: "))
except ValueError:
print("Invalid input. Please enter a number between 1 and 3.")
continue # This continue still needed
# Continues below this line replaced with exclusive tests via elif/else
if option < 1:
print("Invalid value. Please enter a non-negative integer.")
elif option > 3:
print("Please enter an integer between 1 and 3.")
else:
# Still no need to test option >= 1 and option <= 3, the prior tests
# would exclude running the else if either passed
return option
I'm trying to make a program in python so that when I input a number from 1 to 10, a specific set of program goes on and asks for another number from 1 to 10 and runs another program, until I enter 0(zero) and the program stops.
So my guess was using a while loop but it didn't quite work out.
user_input = input()
user_input = int(user_input)
while user_input != 0:
(program)
else:
quit()
Try this:
user_input = int(input())
while user_input != 0:
(program)
user_input = int(input())
quit()
With your current code you only ask for input once so the loop won't end. This way you can input a new number after every iteration.
Your current program only asks once and then the loop keeps repeating. You need to keep asking for input inside the loop.
def program():
print("Executing Task....")
user_input = int(input())
while user_input != 0:
program()
user_input = int(input())
printf("Program Terminated")
Here it is:
def program():
pass
user_input = int(input())
while user_input:
program()
user_input = int(input())
quit(0)
A different way using iter with a sentinel:
def program(number):
if number < 0 or number > 10:
print('Invalid number:', number)
else:
print('Valid number:', number)
def quit():
print('quitting')
def get_number():
return int(input('Enter a number from 1 to 10: '))
for number in iter(get_number, 0):
program(number)
else:
quit()
not_zero = True
while not_zero:
num = int(input("Enter a number: "))
if num == 0:
not_zero = False
you can stop your loop using a boolean value.
I wrote a program that draws a convex regular polygon in turtle (given no. of sides and length). I also wanted it to check for invalid inputs, such that it would immediately ask if the user would like to try a different one. Is there a way to check both input's validity in less code, while also accounting for ValueError?
Also, a Terminator error occurs after every successful run. What might be causing it, and is there even a way to fix it when using this import command?
from turtle import *
def inp():
while True:
try:
n = int(input("Enter the number of sides of the polygon: "))
except ValueError:
y_n = input("Invalid input, type \"y\" if you'd like to try again: ")
if y_n == "y":
continue
else:
print("Goodbye!")
break
if n >= 3:
pass
else:
y_n = input("Invalid input, type \"y\" if you'd like to try again: ")
if y_n == "y":
inp()
else:
print("Goodbye!")
break
try:
l = float(input("Enter the length of the side in pixels: "))
except ValueError:
y_n = input("Invalid input, type \"y\" if you'd like to try again: ")
if y_n == "y":
continue
else:
print("Goodbye!")
break
if l > 0:
for i in range(1, n + 1):
forward(l)
left(360/n)
exitonclick()
break
else:
y_n = input("Invalid input, type \"y\" if you'd like to try again: ")
if y_n == "y":
inp()
else:
print("Goodbye!")
break
inp()
For efficient parameter inputs, here are some steps:
Start with the value as something invalid
Using a while loop, ask the user for valid input
If valid input, exit the loop
In you're code, both parameters have the the same validation check, so you can use a function to check both.
Try this code:
from turtle import *
def validnum(nm):
return str(nm).isdigit() and int(nm) > 0 # integer and greater than zero
def inp():
n = l = '' # both invalid
while not validnum(n): # loop first entry until valid
n = input("Enter the number of sides of the polygon or 'q' to quit: ")
if n == 'q':
print("Goodbye!")
exit()
if not validnum(n):
print("Invalid entry")
while not validnum(l): # loop second entry until valid
l = input("Enter the length of the side in pixels or 'q' to quit: ")
if l == 'q':
print("Goodbye!")
exit()
if not validnum(l):
print("Invalid entry")
n, l = int(n), int(l) # convert entries to integers
for i in range(1, n + 1):
forward(l)
left(360/n)
exitonclick()
inp()
Since both parameters have the same validation and only differ in the message prompt, you can make your code even more compact by putting the prompts in a list.
from turtle import *
def validnum(nm):
return str(nm).isdigit() and int(nm) > 0 # integer and greater than zero
def inp():
lstinp = ['',''] # both invalid
lstmsg = ['Enter the number of sides of the polygon', 'Enter the length of the side in pixels'] # both msgs
for i in range(len(lstinp)): # each input value
while not validnum(lstinp[i]): # loop until valid entry
lstinp[i] = input(lstmsg[i] + " or 'q' to quit: ") # msg
if lstinp[i] == 'q':
print("Goodbye!")
exit()
if not validnum(lstinp[i]):
print("Invalid entry")
n, l = int(lstinp[0]), int(lstinp[1]) # convert entries to integers
for i in range(1, n + 1):
forward(l)
left(360/n)
exitonclick()
inp()
I did not receive any errors when running the code.
I have a menu function and choice function that both worked. There are 3 menu choices. 1 and 3 worked properly at one point. 2 never has. I don't know what I did to mess it up, but when I run the module to test through IDLE, it doesn't ever work past the first prompting to enter my menu choice number. It should complete an if statement, then restart.
I don't know what else to try. I wish I knew what I changed to mess it up.
tribbles = 1
modulus = 2
closer= 3
def menu():
print(' -MENU-')
print('1: Tribbles Exchange')
print('2: Odd or Even?')
print("3: I'm not in the mood...")
menu()
def choice():
choice = int(input('\n Enter the number of your menu choice: ')
if choice == tribbles:
bars = int(input('\n How many bars of gold-pressed latinum do you have? '))
print('\n You can buy ',bars * 5000 / 1000,' Tribbles.')
menu()
choice()
elif choice == modulus:
num = int(input('\n Enter any number:'))
o_e = num % 2
if num == 0:
print(num,' is an even number')
elif num == 1:
print(num,' is an odd number')
menu()
choice()
elif choice == closer:
print('\n Thanks for playing!')
exit()
else:
print('Invalid entry. Please try again...')
menu()
choice()
print(' ')
choice = int(input('\n Enter the number of your menu choice: '))
I expect it to return with the string plus all formula results, then asking again, unless option 3 was selected and exit() is performed. However it returns with "Enter the number of your menu choice: " after the first input, then it returns blank after choosing any other choice on the second prompt.f
First things first!
It's good practice to define all functions at the top of the file, and call those functions at the bottom! Second your indenting is incorrect, i'm going to assume that happened after you pasted it here. Finally, you never actually call the function choice() you instead overwrite it with the result of a prompt.
Below i'm going to correct these issues.
tribbles = 1
modulus = 2
closer= 3
def menu():
print(' -MENU-')
print('1: Tribbles Exchange')
print('2: Odd or Even?')
print("3: I'm not in the mood...")
choice() #added call to choice here because you always call choice after menu
def choice():
my_choice = int(raw_input('\nEnter the number of your menu choice: ')) #you were missing a ) here! and you were overwriting the function choice again
#changed choice var to my_choice everywhere
if my_choice == tribbles:
bars = int(raw_input('\nHow many bars of gold-pressed latinum do you have? '))
print('\n You can buy ',bars * 5000 / 1000,' Tribbles.')
menu()
elif my_choice == modulus:
num = int(raw_input('\n Enter any number:'))
o_e = num % 2
if num == 0:
print(num,' is an even number')
elif num == 1:
print(num,' is an odd number')
menu()
elif choice == closer:
print('\n Thanks for playing!')
exit()
else:
print('Invalid entry. Please try again...')
menu()
print(' ')
if __name__ == "__main__": #standard way to begin. This makes sure this is being called from this file and not when being imported. And it looks pretty!
menu()
Before you check the value of choice, the variable choice is not declared. You have to catch your input before the line: if choice == tribbles:. Your are only defining a function which even don't return the value of your choice or set a global variable.
Try this:
def menu():
print(' -MENU-')
print('1: Tribbles Exchange')
print('2: Odd or Even?')
print("3: I'm not in the mood...")
menu()
choice = int(input('\n Enter the number of your menu choice: '))
if choice == tribbles:
...
I'm working on part of a program which presents a menu of 3 options to the user. I want to allow the user to enter their menu choice (1-3) after which the menu appears again and allows the user to enter another choice and repeats this process for a total of n times which the user also inputs prior to the menu.
The program is just printing the menu 3 times in a row rather than in n separate iterations but I'm not sure how to fix this.
n = int(input('Please enter the number of iterations:'))
for i in range(0,n):
print('Enter 1 for choice 1\n')
print('Enter 2 for choice 2\n')
print('Enter 3 for choice 3\n')
choice = int(input('Enter your choice:'))
if (choice == 1):
....
....
else:
print('Invalid choice')
Put your code to handle the choice inside the loop:
n = int(input('Please enter the number of iterations:'))
for i in range(0,n):
print('Enter 1 for choice 1\n')
print('Enter 2 for choice 2\n')
print('Enter 3 for choice 3\n')
choice = int(input('Enter your choice:'))
if (choice == 1):
....
....
else:
print('Invalid choice')
Indent the following piece of code, 4 spaces to the right:
if (choice == 1):
...
...
else:
print('Invalid choice')
But if I may suggest a better implementation of what you are trying to do, then define a function which can handle a non-numeric user input, and in addition, take those prints outside the for loop:
def getUserInput(msg):
while True:
print msg
try:
return int(input(msg))
except Exception,error:
print error
n = getUserInput('Please enter the number of iterations:')
print 'Enter 1 for choice 1'
print 'Enter 2 for choice 2'
print 'Enter 3 for choice 3'
while n > 0:
choice = getUserInput('Enter your choice:')
if choice == 1:
...
n -= 1
elif choice == 2:
...
n -= 1
elif choice == 3:
...
n -= 1
else:
print 'Invalid choice'
Just for fun: I've rewritten this to introduce some more advanced ideas (program structure, use of enumerate(), first-class functions, etc).
# assumes Python 3.x
from collections import namedtuple
def get_int(prompt, lo=None, hi=None):
while True:
try:
val = int(input(prompt))
if (lo is None or lo <= val) and (hi is None or val <= hi):
return val
except ValueError: # input string could not be converted to int
pass
def do_menu(options):
print("\nWhich do you want to do?")
for num,option in enumerate(options, 1):
print("{num}: {label}".format(num=num, label=option.label))
prompt = "Please enter the number of your choice (1-{max}): ".format(max=len(options))
choice = get_int(prompt, 1, len(options)) - 1
options[choice].fn() # call the requested function
def kick_goat():
print("\nBAM! The goat didn't like that.")
def kiss_duck():
print("\nOOH! The duck liked that a lot!")
def call_moose():
print("\nYour trombone sounds rusty.")
Option = namedtuple("Option", ["label", "fn"])
options = [
Option("Kick a goat", kick_goat),
Option("Kiss a duck", kiss_duck),
Option("Call a moose", call_moose)
]
def main():
num = get_int("Please enter the number of iterations: ")
for i in range(num):
do_menu(options)
if __name__=="__main__":
main()
You need to develop a python program that asks several intervals of integer numbers to the user
(negative or positive numbers). Each time, the user should have an option to either provide a new
interval or quit the program. The intervals will form lists of numbers and have a limit of -999 or 999.
An interval is defined as a continuous sequence of integer numbers. For every break in the continuity
of the integer numbers, you assume a new interval.