While loop in function not working (Python 3.5.0) - python

I am doing a piece of code for a school with 7-10 year old students which will test their basic arithmetic skills. The program is fully functional and should allows the teacher to see the scores in text files afterwards. However, it's currently 556 lines long. I have shortened it as much as possible but I can't seem to get this one piece of code to work:
def Repeat(repeat_q, option_right, t_class_right):
repeat_q = input("\n\nWould you like to see any other class details? ")
if repeat_q == "Yes" or repeat_q == "yes":
option_right = False
t_class_right = False
repeat_question = True
repeat_q = " "
elif repeat_q == "No" or repeat_q == "no":
print("Okay...")
repeat = False
T_Exit()
else:
print("Please only write 'yes' or 'no'")
return repeat_question
This function is called later on like this:
elif test == 2:
OP_2(list_counter, repeat_question)
while repeat_question != True:
Repeat(repeat_q, option_right, t_class_right)
All it does like this is repeat the 'repeat_q' variable. I have tried changing the value of the variable after it but nothing seems to work.I can get it to work if I take it out of the function, like this:
elif test == 3:
OP_3(list_counter, repeat_question)
while repeat_question != True:
repeat_q = input("\n\nWould you like to see any other class details? ")
if repeat_q == "Yes" or repeat_q == "yes":
option_right = False
t_class_right = False
repeat_question = True
elif repeat_q == "No" or repeat_q == "no":
print("Okay...")
repeat = False
T_Exit()
else:
print("Please only write 'yes' or 'no'")
This is what happens to the code:
Hello and welcome to my quiz.
Please write your name: teacher
Write the number of the class you would like to see (1, 2 or 3): 1
Opening Class 1
_________________________________________
| |
| 1) Alphabetical with highest score |
| 2) Highest score, highest to lowest |
| 3) Average score, highest to lowest |
|_________________________________________|
Choose one of the options above (1, 2 or 3): 2
Sorting by highest score, from highest to lowest
['Lol: 10', 'Zaid: 9', 'Abdul: 8', 'Hello: 5', 'Bruno: 5']
Would you like to see any other class details? yes
Would you like to see any other class details? yes
Would you like to see any other class details? yes
Would you like to see any other class details? yes
Would you like to see any other class details? no
Okay...
You have now finished viewing class details
Thank you for using this program
>>> # Exits the program
As opposed to this (The working but inefficient version):
Hello and welcome to my quiz.
Please write your name: teacher
Write the number of the class you would like to see (1, 2 or 3): 1
Opening Class 1
_________________________________________
| |
| 1) Alphabetical with highest score |
| 2) Highest score, highest to lowest |
| 3) Average score, highest to lowest |
|_________________________________________|
Choose one of the options above (1, 2 or 3): 1
Sorting alphabetically...
['Abdul: 8', 'Bruno: 5', 'Hello: 5', 'Lol: 10', 'Zaid: 9']
Would you like to see any other class details? yes
Write the number of the class you would like to see (1, 2 or 3): 1
Opening Class 1
_________________________________________
| |
| 1) Alphabetical with highest score |
| 2) Highest score, highest to lowest |
| 3) Average score, highest to lowest |
|_________________________________________|
Choose one of the options above (1, 2 or 3): 3
Sorting by average score, from highest to lowest
['Lol: 10.0', 'Zaid: 8.333333333333334', 'Abdul: 5.333333333333333', 'Hello: 3.3333333333333335', 'Bruno: 3.0']
Would you like to see any other class details? no
Okay...
You have now finished viewing class details
Thank you for using this program
>>>
Can anyone please help me. A full version of my code is available if anyone wants to check that out: http://www.filedropper.com/teacherprogramtask3-annotated

When you have the chunk of code inside of the Repeat() function, repeat_question = True is creating a local variable called repeat_question. This variable is a different variable to the one outside of the function that the while loop is checking.
This issue is to do with variable scope, this website explains it quite well: http://gettingstartedwithpython.blogspot.com.au/2012/05/variable-scope.html
There is a simple solution however, you just need to use the return repeat_question at the end of your function by setting repeat_question to the result of the function:
while repeat_question != True:
repeat_question = Repeat(repeat_q, option_right, t_class_right)
Also inside the function's elif...: and else: statements you may have to set repeat_question to False.
That should fix it.
EDIT: I think that it isn't working as when it is inside the function, the option_right and t_class_right variables are also only local variables and don't affect the option_right and t_class_right that are outside of the function.
It's a bit of a messy workaround but it should work.
OK I got it working!
Repeat function:
def Repeat(repeat_q, option_right, t_class_right):
repeat_q = input("\n\nWould you like to see any other class details? ")
if repeat_q == "Yes" or repeat_q == "yes":
option_right = False
t_class_right = False
repeat_question = True
repeat_q = " "
elif repeat_q == "No" or repeat_q == "no":
print("Okay...")
repeat = False
t_class_right = True
repeat_question = False
T_Exit()
else:
print("Please only write 'yes' or 'no'")
return repeat_question, t_class_right, repeat_question
And in the code:
if test == 1:
OP_1(list_counter, repeat_question)
while repeat_question != True:
repeat_question, t_class_right, repeat_question = Repeat(repeat_question, option_right, t_class_right)
elif test == 2:
OP_2(list_counter, repeat_question)
while repeat_question != True:
repeat_question, t_class_right, repeat_question = Repeat(repeat_question, option_right, t_class_right)
elif test == 3:
OP_3(list_counter, repeat_question)
while repeat_question != True:
repeat_question, t_class_right, repeat_question = Repeat(repeat_question, option_right, t_class_right)
else:
T_Broke()
You have to name repeat_q to repeat_question in the function call, as it is in the above code. That may have caused it to crash and stop working or it could have closed since option_right and t_class_right weren't being updated, or a combination of the two.

Related

Can I add two VALUES to a dictionary from user input?

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()?

Variables not gaining value in subroutines

The total cost wont print or gain value. I've tried running the subroutines separately but that didn't work. It will not print totalcost at all:
#coffee maker program
print("Welcome to the BartSucks Coffee App")
print("We will guide you through the ordering process")
print("And our amazing Barista 'Simpson' will then serve you")
name = input("Please type in your name: ")
print("Would you like small, medium or large?")
size = input("Type s for small\nType m for medium\nType l for large\n")
while size.upper() not in ("S","M","L"):
print("You must enter s, m or l")
size = input("Please try again\n")
print("Would you like zero,one, two or three spoons of sugar?")
sugars = input("Type 0 for none\nType 1 for one\nType 2 for two\nType 3 for three\n")
while sugars not in ("0","1","2","3"):
print("You must enter 0, 1, 2 or 3")
sugars = input("Please try again\n")
print("Would you like no syrup flavouring?")
print ("Or would you like almond, vanilla or butterscotch syrup?")
flavour = input("n = none\na = almond\nv = vanilla\nb = butterscotch\n")
while flavour.upper() not in ("N","A","V","B"):
print("You must enter n, a, v or b")
flavour = input("Please try again\n")
totalcost=0
def CoffeeSize(cs):
cs=cs.upper()
global totalcost
if size =="S" or size=="s":
totalcost+= 2.5
elif size=="M" or size=="m":
totalcost+=3.0
elif size=="L" or size=="l":
totalcost+= 3.5
def SugarAmount(sa):
sa=sa.upper()
global totalcost
if sugars=="0":
totalcost+= 0
elif sugars=="1":
totalcost+= 0.5
elif sugars=="2":
totalcost+= 1.0
elif sugars=="3":
totalcost+= 1.5
def flavour(fl):
fl=fl.upper()
global totalcost
if flavour=="NONE" or flavour=="none":
totalcost+= 0
elif flavour=="BS" or flavour=="bs":
totalcost+= 1.6
elif flavour=="V" or flavour=="v":
totalcost+= 0.75
elif flavour=="A" or flavour=="a":
totalcost+= 1.0
CoffeeSize(cs)
SugarAmount(sa)
flavour(fl)
print(totalcost)
sorry im quite new to this so correct me if im wrong but i think the problem is that you are calling the functions inside a function which isnt being executed?
Also, everything apart from anything under 'if','def'... etc statements should be on the first indentation level
Your code:
totalcost=0
def flavour(fl):
...
...
CoffeeSize(cs)
SugarAmount(sa)
flavour(fl)
print(totalcost)
In Python, indentations are important and define under what statement it runs over.
As you can see, you are calling the functions on the same indentation level as the code underneath the function 'flavour', therefore it wont get executed as there isnt any other place that calls that function. Try and put this at the end of your program instead:
Code:
if __name__ == '__main__':
CoffeeSize(cs)
SugarAmount(sa)
flavour(fl)
print(totalcost)
What this does is checks to see if the program is the main program instead of being imported by something else. If it is the main/'_ main _' program, it will go from the start, ask the users what they want and then check to see if this program is the main one, then executes all the functions that are listed under the if statement.
Sorry if i misinterpreted your problem but i think that's what the problem is from my perspective :)
Thanks!

How to patch multiple repeated inputs in python unit test?

I'm trying to unit test a function that can have multiple repeated inputs from within a while statement:
def ask_yes_or_no(prompt):
while True:
answer = input(prompt)
if answer.capitalize()[0] == 'Y':
return True
elif answer.capitalize()[0] == 'N':
return False
def human_move(computer_score, human_score):
total = 0
roll_again = True
while roll_again:
if ask_yes_or_no('Roll again? '):
points = roll()
print('You rolled a ' + str(points))
if points == 1:
total = 0
roll_again = False
else:
total += points
else:
roll_again = False
So far I've used the mock module with a with statement to simulate the input. e.g.:
def test_human_move(self):
random.seed(900)
with unittest.mock.patch('builtins.input', return_value = 'N'):
self.assertEqual(human_move(0,0), 0)
However this only works for a single one time input. Is there a way to simulate a repeated input> For instance if the user input ('Y', 'Y', 'Y', 'N')?
Sorry if that's not a very clear explanation.
Thanks.

Problems transferring information from one part of a function to another

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"]:

Loop issue with python3

I'm struggeling a bit with a part of code for a little program I'm writing. Have in mind I'm very new with this.
Heres the code:
def sell():
sell = input("\nGreetings! What would you like to do today?\nPress 1 to sell an animal\nPress 2 to buy an animal\nPress 3 If you want to see all the farms and their animals first\n")
if sell == "1":
whichs = input("Which animal do you want to sell?\nPress 1 for pig\nPress 2 for horse\nPress 3 for cow\nPress 4 for bull\n")
if whichs == "1":
print ("\nYou just sold\n",p[0])
print ("\nYou now have 350gold")
print ("\nThese are the animals you have left:")
print (p[1], p[2], p[3]) #Prints the animals you have left from p list.
elif whichs == "2":
print ("\nYou just sold\n",p[1])
print ("\nYou now have 350gold")
print ("\nThese are the animals you have left:")
print (p[0], p[2], p[3])
elif whichs == "3":
print ("\nYou just sold\n",p[2])
print ("\nYou now have 360gold.")
print ("\nThese are the animals you have left:")
print (p[0], p[1], p[3])
elif whichs == "4":
print ("\nYou just sold\n",p[3])
print ("\nYou now have 350gold.")
print ("\nThese are the animals you have left:")
print (p[0], p[1], p[2])
else:
print ("Error")
I want this to loop so when the user has sold one animal, they start over with the:
sell = input("\nGreetings! What would you like to do today?\nPress 1 to sell an animal\nPress 2 to buy an animal\nPress 3 If you want to see all the farms and their animals first\n")
And I'm struggeling with how this is done.
The other two answers are right in telling you to use a while loop but fail to address a more general problem: the loop shouldn't be inside of the sell function but outside of it, as your text indicates that the user can also buy stuff or look at his stats. You should create individual functions for all of these actions and then create a loop that checks for the action and calls the appropriate functions:
def buy():
#...
def sell():
#...
def stats():
#...
while True:
choice = input("1: Buy 2:Sell 3:Stats - press any other key to exit")
if choice == "1": buy()
elif choice == "2": sell()
elif choice == "3": stats()
else: break
The loop could be optimized by using more pythonic approaches like mapping the choices to the functions in a dictionary, but I've written it with a simple if for clarity.
Also, if you don't choose to hold all your state in global variables (which you shouldn't), it would make sense to put the functions into a class which also holds the current balance, stock and other game parameters.
def sell():
looping = True
while looping:
sell = input("\nGreetings! ... Press Q for quit")
if sell == "1":
#rest of your code
elif sell == "Q":
looping = False
Try using a while loop:
def sell_function():
while True:
sell = input("\nGreetings! What would you like to do today?\nPress 1 to sell an animal\nPress 2 to buy an animal\nPress 3 If you want to see all the farms and their animals first\n")
# ...
else:
print("Error")
break # Stop looping on error
We could have also set a variable to True, done while variable and then variable = False instead of break for the same effect (in this instance).
I renamed your function, as you used a variable called sell and had a function with the same name which could cause problems. Also, you'll no doubt later find the break and continue statements useful.

Categories