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.
Related
I wrote this simple calculator program to ask for two numbers and then perform a certain action on them like dividing the first by the second etc. I implemented it in a big while loop that is repeated if the user chooses to repeat it after a calculation. However, after the user enters the operation they want to perform the program does not give the answer but asks the user if they want to repeat. What did I do wrong?
import random, time
valid_operations = ("/", "*", "+", "-")
valid = 3
repeat = "y"
while repeat == "y":
number_1 = input('Enter first number \n')
if number_1.isdigit() == True:
num_1 = number_1
else:
print("that is not a valid integer")
exit()
number_2 = input('Enter second number \n')
if number_2.isdigit() == True:
num_2 = number_2
else:
print("that is not a valid integer")
exit()
operation = input("what operation would you like? \nvalid operations include:\n/ - divide\n* - multiply\n+ - add\n- - subtract\n")
while valid > 0:
if operation in valid_operations:
if operation == "/":
print(f"Answer = {int(num_1) / int(num_2)}")
valid -= 3
elif operation == "*":
print(f"Answer = {int(num_1) * int(num_2)}")
valid -= 3
elif operation == "+":
print(f"Answer = {int(num_1) + int(num_2)}")
valid -= 3
elif operation == "-":
print(f"Answer = {int(num_1) - int(num_2)}")
valid -= 3
else:
print(f"that is not a valid operation you have {valid} more attmepts to type a valid operation")
valid -= 1
time.sleep(2)
want_rep = input("would you like to do another calculation? y/n\n")
if want_rep == "y":
repeat = "y"
elif want_rep == "n":
repeat = "n"
else:
print("that is not a valid response, please choose either yes - y or no - n")
exit()
Problem lies in the valid variable.
You define it as 3 before the first iteration.
Then, inside the second while loop, it is reduced to 0 by
valid -= 3
And you never restore the starting value. So, the program comes back to the operation input, reads the loop condition:
while valid > 0:
And omits it, as valid equals 0.
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'm a step away from completing my binary converter, though it keeps on repeating, it's and endless loop.
def repeat1():
if choice == 'B' or choice == 'b':
while True:
x = input("Go on and enter a binary value: ")
try:
y = int(x, 2)
except ValueError:
print("Please enter a binary value, a binary value only consists of 1s and 0s")
print("")
else:
if len(x) > 50:
print("The number of characters that you have entered is", len(x))
print("Please enter a binary value within 50 characters")
z = len(x)
diff = z - 50
print("Please remove", diff, "characters")
print(" ")
else:
print(x, "in octal is", oct(y)[2:])
print(x, "in decimal is", y)
print(x, "in hexidecimal is", hex(y)[2:])
print(" ")
def tryagain1():
print("Type '1' to convert from the same number base")
print("Type '2' to convert from a different number base")
print("Type '3' to stop")
r = input("Would you like to try again? ")
print("")
if r == '1':
repeat1()
print("")
elif r == '2':
loop()
print("")
elif r == '3':
print("Thank you for using the BraCaLdOmbayNo Calculator!")
else:
print("You didn't enter any of the choices! Try again!")
tryagain1()
print("")
tryagain1()
I'm looking for a way to break the loop specifically on the line of code "elif r== '3':. I already tried putting 'break', but it doesn't seem to work. It keeps on asking the user to input a binary value even though they already want to stop. How do I break the loop?
elif r == '3':
print("Thank you for using the BraCaLdOmbayNo Calculator!")
return 0
else:
print("You didn't enter any of the choices! Try again!")
choice = try again()
if choice == 0:
return 0
print("")
tryagain1()
return is suppose to be used at the end of the Function or code when you have nothing else to do
I'm a newbie in Python3 coding and I have a problem here.
In line 14, I intended to end this program by printing "Thank you! Goodbye" at the part where you answer "n" to "try again?". However, it turned out that I would start all over again even if I've inserted "break" under it. Now, the only solution I can come up is to end the whole program with sys.exit(0), but I don't consider it an ideal solution since it just closes the whole program down.
import sys
while True:
x=int(input("Enter the coins you expected="))
f=int(input("Enter first coin="))
while f!=1 and f!=5 and f!=10 and f!=25:
print("invalid number")
f=int(input("Enter first coin="))
if x>f:
while x>f:
n=input("Enter next coin=")
if not n:
print("Sorry-you only entered",f,"cents")
again=input("Try again (y/n)?=")
if again=="y":
True
elif again=="n":
print("Thank you, goodbye!")
sys.exit(0)
break
while int(n)!=1 and int(n)!=5 and int(n)!=10 and int(n)!=25:
print("invalid number")
n=input("Enter next coin=")
f=f+int(n)
Replace your whole code with this:
import sys
Stay = True
while Stay:
x = int(input("Enter the coins you expected = "))
f = int(input("Enter first coin = "))
while f != 1 and f != 5 and f != 10 and f != 25:
f = int(input("Invalid number entered./nEnter first coin = "))
while x > f and Stay:
n = input("Enter next coin = ")
if not n:
print("Sorry, you only entered " + str(f) + " cents")
again = input("Try again (y/n)?=")
if again == "n":
print("Thank you, goodbye!")
Stay = False
if Stay:
n = int(n)
while n != 1 and n != 5 and n != 10 and n != 25:
print("Invalid number entered.")
n = int(input("Enter next coin = "))
f += n
I made your code more readable and fixed your problem by using a Boolean flag (Stay). This basically means that the program runs while Stay is True, and Stay becomes False when the user enters 'n'.
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')