I'm trying to have a program return the luminance of a light based on user given values, but the while loop is what's getting me confused.
def Brightness(r,g,b):
value = 0.2126 * r + 0.7152 * g + 0.0722 * b
return value
while True:
r = int(raw_input("Enter in the value for red: "))
g = int(raw_input("Enter in the value for green: "))
b = int(raw_input("Enter in the value for blue: "))
result = Brightness(r,g,b)
print result
if ((r == "quit") or (g == "quit") or (b == "quit")):
break
result = Brightness(r,g,b)
I feel like the answer is staring me right in the face, but I can't put my finger on it.
First of all, notice that you're doing int(raw_input()) everywhere. This means that when you try to enter quit as input, the program will raise a ValueError exception and quit abnormally.
My suggestion is to modify a little bit the input loop:
while True:
i1 = raw_input("Enter in the value for red: ")
i2 = raw_input("Enter in the value for green: ")
i3 = raw_input("Enter in the value for blue: ")
if ((i1 == "quit") or (i2 == "quit") or (i3 == "quit")):
break
r = int(i1)
g = int(i2)
b = int(i3)
result = Brightness(r,g,b)
print result
result = Brightness(r,g,b)
Also I don't understand what the last line result = Brightness(r,g,b) is for? It seems to me you're outputting the result in the last two lines in the loop.
Hope this helps!
The problem is that you typecast all your user input to an int without validating the input. When the input is a string, python will throw an error, because a string cannot be converted to an integer.
Best would be to store the raw input as raw data into the variables r, g, and b and check whether the user wants to quit first. If not, you should do a sanity check on your input values. If they are integers, you can typecast them as such. Otherwise, print an error message or start at the beginning of the loop.
This code can't possibly work correctly. If the user enters quit, then when you pass that input string to int() you will get an exception, because quit doesn't work as an integer.
Then, if the user does enter quit, you can break out of the loop without setting all of r, g, and b, so the last line where you call Brightness(r,g,b) will raise an exception.
Also, this doesn't check to see if the user entered quit until after the user has been prompted three times. This will annoy a user who wanted to quit at the first number.
So, don't convert the user's input to integer without checking for quit; check after each time you prompt the user; and either have default values for r,g, and b or else don't have the last call to Brightness() if the user quit.
QUIT = "quit"
got_input = False
while True:
r = raw_input("Enter in the value for red: ")
if r == QUIT:
break
r = int(r)
g = raw_input("Enter in the value for green: ")
if g == QUIT:
break
g = int(g)
b = raw_input("Enter in the value for blue: ")
if b == QUIT:
break
b = int(b)
got_input = True
result = Brightness(r,g,b)
print result
if got_input:
result = Brightness(r,g,b)
Note that there is a lot of repetition in this loop. Perhaps we could write a function to clean it up?
def get_user_input(question)
answer = raw_input(question)
if answer == QUIT:
return False, None
else:
return True, int(answer)
got_input = False
while True:
quit, r = get_user_input("Enter in the value for red: ")
if quit:
break
quit, g = get_user_input("Enter in the value for green: ")
if quit:
break
b = get_user_input("Enter in the value for blue: ")
if quit:
break
got_input = True
result = Brightness(r,g,b)
print result
if got_input:
result = Brightness(r,g,b)
It's a little better. Maybe we can make it cleaner? Let's use Python exceptions. We can just write the code to assume that things are going as planned, but when the user enters quit we can raise an exception. Let's define our own exception to make this clear.
import sys
QUIT = "quit"
class UserHasQuit(Exception):
pass
def get_user_input(question)
answer = raw_input(question)
if answer == QUIT:
raise UserHasQuit
return int(answer)
try:
r = get_user_input("Enter in the value for red: ")
g = get_user_input("Enter in the value for green: ")
b = get_user_input("Enter in the value for blue: ")
result = Brightness(r,g,b)
print result
except UserHasQuit:
sys.exit(0)
Instead of raise UserHasQuit we could call sys.exit() when getting user input. But when you are debugging, an exception gives you a stack backtrace that shows you where the exception came from, while sys.exit() just makes the program stop. So if you have an unexpected sys.exit() it can be a bit hard to find it, but exceptions are easy to find. So it's best to keep calls to sys.exit() at the outer layer and use exceptions for internal code.
Related
lst = []
while True:
try:
arr = int(input("Enter number of elements: "))
if arr == "Quit":
break
except ValueError:
print("Invalid Input")
continue
else:
break
while True:
try:
for i in range(0, arr):
ele = int(input("Enter the elements:"))
lst.append(ele)
print(lst)
except ValueError:
print("Invalid Input")
continue
else:
break
How can I create a condition to exit the program at any point in the loop by specifically entering the conditioned term?
Like when it asks me to enter an element, but i want to break the program right at that point by entering
"Quit".
How to do that in this code?
(Learner)
Use sys.exit() to exit the program completely. Use break to exit the specific loop you're in (which you've used).
Other notes:
You're doing arr = int(input(...)) but you want to accept the input of "Quit" which is a string. So if the user enters "Quit", it raise ValueError and the loop continues. So check for "Quit" first and if it's not quit, then convert to int with the try-block
Same applies for the 2nd loop where you ask the user for the elements in the list
Btw, your second loop's while True loop should be inside the for-loop which gets each element.
lst = []
while True:
arr = input("Enter number of elements: ")
if arr == "Quit":
sys.exit() # will exit completely
try:
arr = int(arr) # check for int in the try-block, error raised here, if not int
break # can put break here instead of in else, any is okay
except ValueError:
print("Invalid Input")
# continue not needed here, since it loops infinitely by default
for i in range(0, arr):
while True:
ele = input("Enter the elements:")
if ele == "Quit":
sys.exit() # will exit completely
try:
ele = int(ele) # check for int in the try-block, error raised here, if not int
lst.append(ele)
break # breaks out of `while` loop, not `for` loop; good
except ValueError:
print("Invalid Input")
# continue not needed here, since it loops infinitely by default
print(lst) # print the full list after all the inputs
The pattern for your input is repeated:
Ask user for input
if input is "Quit", then exit completely
otherwise, convert the input to an int
So this can put into a function, which you call in both places:
def int_or_quit(msg):
"""`msg` is the message you want to show at input"""
while True:
item = input(msg)
if item == "Quit":
sys.quit() # will exit completely
try:
return int(item) # try converting to int and return
except ValueError:
print("Invalid Input")
# repeats by default
# use the function above in your two code blocks, which are now simplified:
lst = []
arr = int_or_quit("Enter number of elements: ")
# program exits before if user "Quit", next part won't execute
for i in range(0, arr):
ele = int_or_quit("Enter an element:")
lst.append(ele)
print(lst)
I can see that there're 2 blocks in your code snippet. I'd suggest organising them in distinct functions, where function name infers a function goal (instead of comments):
def get_list_size():...
def fill_list():...
Next thing to do is deciding about function's return values:
from typing import List, Optional
def get_list_size() -> Optional[int]:
"""
:returns: number of desired elements of list or None, if "Quit" was pressed
:raises: ValueError exception, if non integer value was pressed
"""
def fill_list(lst_size: int) -> List[int]:
"""
returns: filled list
throws: ValueError exception, if non integer value was pressed
"""
Here you can see, how Optional type hint is used to add condition logic into the program.
Lats thing to do is to fill your functions with lightweight code:
def get_list_size() -> Optional[int]:
"""
:returns: number of desired elements of list or None, if "Quit" was pressed
:raises: ValueError exception, if non integer value was pressed
"""
while True:
try:
input_value = input("Enter number of elements: ")
# Pay attention: you have to check string input_value, not int(input_value).
# Checking int(input_value) would raise exception before 'Quit' validation.
if input_value == "Quit":
return None
return int(input_value)
# Could be rewritten as trinary if
# return None if input_value == "Quit" else int(input_value)
except ValueError:
print("Invalid Input")
# continue <- Not needed here
def fill_list(lst_size: int) -> List[int]:
"""
returns: filled list
throws: ValueError exception, if non integer value was pressed
"""
lst = []
while len(lst) < lst_size:
try:
ele = int(input("Enter the elements:"))
lst.append(ele)
print(lst)
except ValueError:
print("Invalid Input")
return lst
Pay attention: in fill_list function you have to try/except each element, so while loop was moved outside.
Last thing to do is running these functions:
desired_list = []
desired_list_size = get_list_size()
if desired_list_size is not None:
desired_list = fill_list(desired_list_size)
def one():
message = ""
while message != "Quit":
message = input("Type in Order > ")
if message == "Run":
print("Run some Code")
message = input("What do u want to run ? > ")
if message == "Exel":
print("Runing Exel")
else:
pass
else:
pass
while True:
one()
Here you can pass in funktions that will run when you call it by its Name. If u write Quit it will start over again. It starts over again if you write something wrong. U could do an FailExeption for that if u want to.
I keep getting an error when I run this functions. Everything goes through and then it shows this error. I have tried adding .items() to the end when I print the dictionary and still throws this error.
CLARIFICATION just realized. Not getting any type errors or anything. It prints fine but when doesn't add the second variable to the dictionary. Instead it prints this..
{'Frappe': ('small', function type_of_milk at 0x000002BE2BCD2F78>)}
def order():
ready_to_order = True
while ready_to_order != False:
ordering_q = input(
"""Do you know what you would like to order or do you need to see the menu?
[M]enu or [R]eady to order or [Q]uit: """)
if ordering_q.upper() == "Q":
sys.exit()
elif ordering_q.upper() == "M":
print(Menu())
elif ordering_q.upper() == "R":
ready_to_order = False
else:
print("Please enter valid letters only, try again.")
print(" ")
print(" ")
add_cart = True
while add_cart != False:
order1 = input("What would you like to order?")
if order1.upper() == "Done":
add_cart = False
elif order1 == 'a1':
print("Frappe added to cart")
global total_order
total_order += 3
drink_size()
type_of_milk()
order_dict['Frappe'] = (drink_sizes, type_of_milk)
add_cart = False
print(order_dict)
This line:
order_dict['Frappe'] = (drink_sizes, type_of_milk)
is adding the function type_of_milk to your dict, which is why you see function type_of_milk at 0x000002BE2BCD2F78> when you print the dict out. Maybe you meant to say type_of_milk()?
I'm new to programming, and I was wondering how I can repeat an input section, if the user types in invalid data.
I want the application to just repeat the input section, instead of having to run the function all over again and making the user type everything all over again.
My guess is that I would have to change the "return main()" into something else.
condition = input("What is the condition of the phone(New or Used)?")
if condition not in ["New", "new", "Used", "used"]:
print("Invalid input")
return main()
gps = input("Does the phone have gps(Yes or No)?")
if gps not in ["Yes", "yes", "No", "no"]:
print("Invalid input")
return main()
You can make a method to check it in a loop:
def check_input(values, message):
while True:
x = input(message)
if x in values:
return x
print "invalid values, options are " + str(values)
You can generalise the code to use a message prompt and a validating function:
def validated_input(prompt, validate):
valid_input = False
while not valid_input:
value = input(prompt)
valid_input = validate(value)
return value
eg:
>>> def new_or_used(value):
... return value.lower() in {"new", "used"}
>>> validate_input("New, or used?", new_or_used)
Or, simpler, but less flexible, pass in the valid values:
def validated_input(prompt, valid_values):
valid_input = False
while not valid_input:
value = input(prompt)
valid_input = value.lower() in valid_values
return value
And use:
>>> validate_input("New, or used?", {"new", "used"})
You could even use the valid values to create the input prompt:
def validated_input(prompt, valid_values):
valid_input = False
while not valid_input:
value = input(prompt + ': ' + '/'.join(valid_values))
valid_input = value.lower() in valid_values
return value
Which gives a prompt:
>>> validate_input("What is the condition of the phone?", {"new", "used"})
What is the condition of the phone?: new/used
Here is a good reading about Control Flows.
Also in your case, you can use strip() and lower() for user inputs.
>>> 'HeLLo'.lower()
'hello'
>>> ' hello '.strip()
'hello'
Here is the solution for Python 3:
while True:
condition=input("What is the condition of the phone(New or Used)?")
if condition.strip().lower() in ['new', 'used']:
break
print("Invalid input")
while True:
gps=input("Does the phone have gps(Yes or No)?")
if gps.strip().lower() in ['yes','no']:
break
print("Invalid input")
I'm working on a school project and I have a problem. I have to write code for apothecary where clients can buy medicine. So, I need to make restrictions, which one doesn't go with others and etc. Here is the code:
def prodajLek():
lekovi = Fajl1.UcitavanjeLekova()
lekoviRed = []
brojacZaForPetlju = 1
n = 0
cena = 0
kolicina = []
korpa = []
rednibrojevilekova = []
ukupnacena = 0
print(" Fabricki naziv Genericki naziv Serijski broj Kolicina Cena \n")
for i in lekovi:
x = i.strip().split("|")
lekoviRed.append(x)
if lekoviRed[n][5] == "False":
print(brojacZaForPetlju,"\t {:10} \t {:10} \t\t\t {:3} \t\t\t {:4} \t\t {:5}".format(x[0],x[1],x[2],x[3],x[4]))
brojacZaForPetlju = brojacZaForPetlju + 1
n = n + 1
print("\n\n\n\n")
rednibrleka = input("Izaberite redni broj leka koji zelite da prodate:\n>>\t")
rednibrleka = int(rednibrleka)
rednibrleka = rednibrleka - 1
rednibrojevilekova.append(rednibrleka)
kolicinaZahteva = input("Koju kolicinu zelite da prodate?\n>>\t")
kolicinaZahteva = int(kolicinaZahteva)
if kolicinaZahteva > int(lekoviRed[rednibrleka][3]):
print("Nema toliko na lageru!\n")
Fajl1.LekarMenu()
kolicina.append(kolicinaZahteva)
cena = int(lekoviRed[rednibrleka][4])
korpa.append(cena)
print("Da li zelite da kupite jos lekova?\n1.Da\n2.Ne\n")
nastavakKupovine = input(">>")
if nastavakKupovine == "1":
prodajLek()
elif nastavakKupovine == "2":
Fajl1.LekarMenu()
So, when I get to the nastavakKupovine input, when I press 1, I need to continue shopping and store my row numbers, my price and quantity in arrays rednibrojlekova = [] , korpa = [] and kolicina = []. But I have a problem, because I dont know how to continue this without reseting these arrays to empty.
The standard idiom for what you want to do is a while True loop. Rather than show how to change your (rather long) function, here's a very simple one which hopefully shows the principle in a straightforward way:
def ask():
answers = []
while True:
response = input("What do you have to say? ")
answers.append(response)
check = input("Type 'q' to quit, anything else to repeat: ")
if check == "q":
break
else:
continue
return answers
For this simple function, the else: continue part isn't necessary, because the loop will continue anyway, but I've included it so you can see how to use it.
Here's an example of the function in action:
>>> ask()
What do you have to say? Something
Type 'q' to quit, anything else to repeat:
What do you have to say? Another thing
Type 'q' to quit, anything else to repeat:
What do you have to say? Ok, done
Type 'q' to quit, anything else to repeat: q
['Something', 'Another thing', 'Ok, done']
>>>
You can find out more about while, break and continue by reading the More Control Flow Tools chapter of the official Python tutorial.
While working on my program I have run into a problem where the information stored in Menu option 1 is not being transferred to Menu option 2. As you can see it is correctly stored when in menu one. When it returns to go to menu option 2 its like it never went to option 1.
update #1:
some suggestions I've had is to understand scope? from what I can tell the program is not passing the data along to its parent program even though I've typed out return in each of the definitions.
#Must be able to store at least 4 grades
#Each class can have up to 6 tests and 8 hw's
#Weighted 40%*testavg 40% hw average attendance is 20%
#User must be able to input a minimum grade warning
#after each test the your program must calculate the students average and issue warning if necessary
##Define the Modules##
import math
def menu (a): #2nd thing to happen
menuend = 'a'
while menuend not in 'e':
menuend = raw_input("Type anything other then 'e' to continue:\n")
print "What would you like to do ?"
menudo = 0
print "1 - Enter Courses\n2 - Select Course to Edit\n3 - Save File\n4 - Load File\n5 - Exit\n"
menudo = input("Enter Selection:")
if (menudo == 1):
menuchck = 0
menuchck = raw_input("\nYou have entered #1 (y/n)?:\n")
if menuchck in ["Yes","yes","y","Y"]:
x = m1()
else:
print "I'm sorry,",nam,",for the confusion, lets try again\n"
menu()
elif (menudo == 2):
menuchck1 = 0
menuchck1 = raw_input("\nYou have entered #2 (y/n)?:\n")
if menuchck1 in ["Yes","yes","y","Y"]:
x = m2()
else:
print "I'm sorry,",nam,",for the confusion, lets try again\n"
menu()
elif (menudo == 3):
print "Entered 3"
elif (menudo == 4):
print "Entered 4"
else:
print "Anything Else Entered"
def course(): #3rd thing to happen
b = {}
while True:
while True:
print "\n",name,", please enter your courses below ('e' to end):"
coursename = raw_input("Course Name:")
if (coursename == 'e'):
break
will = None
while will not in ('y','n'):
will = raw_input('Ok for this name : %s ? (y/n)' % coursename)
if will=='y':
b[coursename] = {}
print "\n",name,", current course load:\n",b
coursechck = None
while coursechck not in ('y','n'):
coursechck = raw_input("Are your courses correct (y/n)")
if coursechck =='y':
return b
else:
b = {}
print
##Menu Options##
def m1():
a = course()
return a
def m2():
print "Excellent",name,"lets see what courses your enrolled in\n"
print x
return x
###User Input Section###
name = raw_input("Enter Students Name:\n")
a = {}
menu(a)
raw_input("This is the end, my only friend the end")
In your if-elif blocks in the do==1 case, you write m1(), but for the last case, you write x=m1(). You should have the latter everywhere (by typing m1() you only run the function, but do not store the returned x anywhere).
By the way, you can avoid this if-elif confusion using if chck in ["Yes","yes","Y","y"]: