Python while loop won't end - python

So I have a code that project the user's bill. I put it on a loop so that it keeps repeating itself until the user don't want to continue.
here is my code:
status = True
def kill() :
confirm = input("Again? (Y/N) : ")
if confirm == "n":
status = False
while(status):
plan_option = input("Which plan are using ? (a/b/c/d/e): ").lower()
if plan_option == "a" :
print("Your current bill is : $90")
kill()
else :
data_amount = float(input("How much data have you used? "))
print("===========================")
def plan_b(x) :
if x < 10 :
print("Your current bill is : $60")
elif x > 10 :
total = 60 + x*10
print("Your current bill is : $", total)
def plan_c(x) :
if x < 5 :
print("Your current bill is : $40")
elif x > 5 :
total = 40 + x*12
print("Your current bill is : $", total)
def plan_d(x) :
if x < 2 :
print("Your current bill is : $30")
elif x > 2 :
total = + x*15
print("Your current bill is : $", total)
def plan_e(x) :
total = x*18
print("Your current bill is : $", total)
if plan_option == "b" :
plan_b(data_amount)
elif plan_option == "c" :
plan_c(data_amount)
elif plan_option == "d" :
plan_d(data_amount)
elif plan_option == "e" :
plan_e(data_amount)
kill()
So my questions are :
If I enter "n" when the code prompt me, the script won't stop and kept going back to plan_option.
even though the code stops (eventually), it kept prompting me "Again? (Y/N) : " before it kills itself.
Where did I do wrong?
Also, am I over-engineering here?

You have to declare 'status' as a global variable inorder to update value to
"status = False" in your kill method.
You can do 2 things here:
1. Declare status as global variable
2. Return "status" (which is a local variable) from kill method
You can check the tutorials on how to use global variables. Am not going to provide you the code (for your own good ofcourse).

def kill() :
confirm = input("Again? (Y/N) : ")
if confirm == "n":
status = False
This creates a local variable named status, and sets that. The global variable of the same name is unaffected.
Add global status in the function so that it uses the global one instead:
def kill() :
global status
confirm = input("Again? (Y/N) : ")
if confirm == "n":
status = False

I think that you should use less complicated way:
try this model
===>here your function a()<===
def a():
print("A plan in action")
while True:
===> your loop code <===
your_input = input("> ")
your_input = your_input.upper()
if your_input == 'N':
print("\n** You escaped! **\n")
break
elif your_input == "A":
print("\n** Plan A lunched ! **\n")
a()
===>you can use 'break' to stop the loop here <===
else:
continue

Two revisions:
Use global status in kill()
If you are comparing confirm == "n", then convert n to lower while taking input
Try this:
def kill() :
confirm = input("Again? (Y/N) : ").lower()
if confirm == "n":
global status
status = False

Related

Not sure why my if statements to check the first character of varaible state is only running the first statement

I know my code is a little messy, I am going to clean it up once I can figure out why the if statements to check state[0] is only printing the first statement. I tried moving it around the codeblocks and indentations but still only getting the first if statement to print. Any advice/help would be great. Just came back to python, been learning java/SQL, this class is going back to python, so I'm a little off at then moment. Thanks
ballotLoop = input("Hey there, are you here for the voter ballot? Exit to stop.\n")
while ballotLoop != "exit":
lastName = input("Please enter your last name.\n")
firstName = input("Please enter your first name.\n")
age = int(input("Please enter your age.\n"))
usCit = input("Are you a United States Citizen?\n")
if usCit == "yes":
if age >= 18 and age < 80:
print(firstName, lastName +". Great you are over 18 and a US citizen\nYou may proceed with the form.\n")
elif age > 0 and age < 18:
print("I am sorry you are not old enough to complete this voter form.")
elif age > 80:
print("Error age does not make sense.\n")
elif age < -1:
print("Error age does not make sense.\n")
state = input("What state do you currently reside in?\n")
zipcode = input("What is your current zipcode\n")
print("Alright so to make sure everything is correct we have the following.\n"\
+ firstName, lastName + ", you are "+ str(age) + " years old.\nYou marked " + usCit + \
" for being a US citizen.\nYou currently reside in " + state + " and your zipcode is " + zipcode +"\n")
if state[0] == "a" or "c":
print("You should recieve your ballot in 1 week")
elif state[0] == "t" or "d":
print("You should recieve your ballot in 4 weeks")
elif state[0] == "m" or "l":
print("You should recieve your ballot in 2 weeks")
elif usCit == "no":
print("I am sorry but you may not complete this form, I am going to have to ask you to leave.")
ballotLoop = input("Would you like to fill out another ballot? Exit to stop.\n")
if ballotLoop == "exit":
print("Thank you for you vote today, every little bit makes a difference!!")
Solution
state[0] == "a" or state[0] == "c" instead of
state[0] == "a" or "c"
and so on for next two logics.
Explanation
There are two parts per and / or keywords in python. The left part (any boolean expression) to the keyword is compared with the right part (another boolean expression). And you know that boolean expression is either True or False.
Keeping these in mind let's break down your if statement.
if state[0] == "a" or "c":
print('...')
Here, the boolean expressions are:
state[0] == "a"
Possible results: Either True or False
"c" which is always True in python. Check this.
So under the hood your logical operation in the if statement is state[0] == "a" or True
Which will always return True, satisfying the first if statement everytime.
Long story short, explicitly write:
state[0] == "a" or state[0] == "c"

Question about the while loop for supermarket checkout case

I tried to make simple codes for supermarket checkout, but I have an issue with the while loop statement. Please check the code below and picture I sent.
I don't know why after I input "n", it does not go back to the loop.
def start():
quan = 1
price = 0
end = False
total = 0
while end == False:
food = (input("Enter your food: "))
quan = int(input("Enter quantative: "))
price = float(input("Price of food: "))
disscount = float(input("Do you have disscount? enter '0' for no disccount. "))
end = input("Finish? y or n: ")
sum = price * quan
sub_total = sum - (sum * disscount * 0.01)
total += sub_total
if end == "y":
print("Total price is ", total)
end = True
elif end == "n":
end = False
else:
again = input("Wrong message! Do you want to try again? enter 'y' to try again or 'n' to end: ")
if again == "y":
return start()
elif again == "n":
print("Bye!")
break
start()
The if again block needs to be indented:
else:
again = input("Wrong message! Do you want to try again? enter 'y' to try again or 'n' to end: ")
if again == "y":
return start()
elif again == "n":
print("Bye!")
break
Otherwise, you hit your if statement without necessarily having defined again. If it is not defined, you get the error you cite.

Python - How can I save the player's score as they keep increasing it? Any help is appreciated

to learn Python I'm working on a small terminal upgrade game. The user enters a number that is added to a random integer to get a score (called "Films Produced" in game). The problem I can't seem to fix is every time the player goes to the menu and back then back to entering more numbers the previous number is deleted instead of added on to the new one.
Here is the code:
print("TERMINAL FILM by Dominick")
print("---------------------")
# SCORE
def filmClicker():
global score
user_input = int(input(">> Enter a number: "))
score = user_input
if user_input > 5 or user_input < 0 or user_input == 0:
print(">> Not a valid number.")
filmClicker()
elif score > 0:
score = score + random.randint(1, 50)
print("")
print(">> You produced:", score, "films", "<<")
go_back_or_menu = input(">> Press ENTER to go again. Or type TAB to go back to the menu. ")
if go_back_or_menu == "":
filmClicker()
elif go_back_or_menu == "TAB" or "Tab" or "tab":
game()
def game():
print(">>>>>>>>>>>>> Menu >>>>>>>>>>>>>")
print(">> Type A to go make films. ")
print(">> Type B to see your current balance. ")
print(">> Type C to see the current box office. ")
print(">> Type D for your stats. ")
press_button_menu = input("")
if press_button_menu == "A":
filmClicker()
elif press_button_menu == "B":
print("Current Balance =", score)
press_enter()
game()
else:
filmClicker()
game()
So I want the player to be able to insert a number, the number gets added to another number by the computer, and then a final number is spit out. I got all that working. But it doesn't save when you do that multiple times. Which I don't want, I want it to stack each time you do it.
Sorry if I poorly explained it, I can answer more about it if needed. Any help is appreciated.
UPDATE:
I removed the score = "input" variable and declared it out of any function. But it's still not saving. Here is a better answer as to what I want it to do:
In the picture below I start at the game menu. I then decide to make films, I do it 5 times. But then when I go back to the menu and check my balance, the balance equals the last time I made films and not the TOTAL films. What I want it to do is add up all of the films. So in this case 48 + 49 + 9 + 38 + 25 instead of having just the last set (which is 25 in this case), to get a total balance which can be displayed by going to the menu and typing "B."
Here is the current code:
import random
score = 0
# SCORE
def filmClicker():
global score
user_input = int(input(">> Enter a number: "))
if user_input > 5 or user_input < 0 or user_input == 0:
print(">> Not a valid number.")
filmClicker()
elif score > 0:
score = score + random.randint(1, 50)
print("")
print(">> You produced:", score, "films", "<<")
go_back_or_menu = input(">> Press ENTER to go again. Or type TAB to go back to the menu. ")
print(go_back_or_menu)
if go_back_or_menu == "":
filmClicker()
elif go_back_or_menu == "TAB" or "Tab" or "tab":
game_menu()
# GAME MENU
def game_menu():
print(">>>>>>>>>>>>> Menu >>>>>>>>>>>>>")
print(">> Type A to go make films. ")
print(">> Type B to see your current balance. ")
print(">> Type C to see the current box office. ")
print(">> Type D for your stats. ")
press_button_menu = input("")
if press_button_menu == "A":
filmClicker()
elif press_button_menu == "B":
print("Current Balance =", score)
press_enter()
game_menu()
else:
filmClicker()
game_menu()
SECOND UPDATE:
Updated Code:
import random
score = 0
# PRINT BLANK LINE
def press_enter():
press_enter = print(input(""))
# SCORE
def filmClicker():
global score
user_input = int(input(">> Enter a number: "))
score += user_input
produced = random.randint(1, 50)
if user_input > 5 or user_input < 0 or user_input == 0:
print(">> Not a valid number.")
filmClicker()
elif score > 0:
score += produced
print("")
print(">> You produced:", produced, "films", "<<")
go_back_or_menu = input(">> Press ENTER to go again. Or type TAB to go back to the menu. ")
print(go_back_or_menu)
if go_back_or_menu == "":
filmClicker()
elif go_back_or_menu == "TAB" or "Tab" or "tab":
game_menu()
# GAME MENU
def game_menu():
print(">>>>>>>>>>>>> Menu >>>>>>>>>>>>>")
print(">> Type A to go make films. ")
print(">> Type B to see your current balance. ")
print(">> Type C to see the current box office. ")
print(">> Type D for your stats. ")
press_button_menu = input("")
if press_button_menu == "A":
filmClicker()
elif press_button_menu == "B":
print("Current Balance =", score)
press_enter()
game_menu()
else:
filmClicker()
game_menu()
In the picture below it's printing how much the player is producing from that turn but I also am testing the score (which is what the 6 and 49 stand for). It's scaling weird like that, where it adds a certain amount after every turn. Any way to fix this?
I think you are looking for the += operator.
Keep the score = 0 at the top of the file to initialize the variable, then use score += user_input to keep a running tally. This is the same as writing score = score + user_input.
In your filmClicker function, you should remove the following line:
score = user_input
By assigning to it, you've essentially erased its previous value which is why it doesn't accumulate between rounds.
For saving data, You can Use Files in python
For Saving:
f=open("data_game.txt","w")
f.write(<your score>)
f.close()
For Reading:
f=open("data_game.txt","r")
score=f.read()
print(score)
f.close()

How would I create an object that passes the average as an argument to the function and get the return value to print out? I haven't coded for a bit

Error is saying grade isn't defined and I don't know how to define it. I googled a bunch but I don't think the information helped much. Or at least it didn't click in my brain... I appreciate the help.
class ClassGrader:
earnedTotal = 0.0
Total = 0.0
grade = Grade()
while 'earned' != 'exit':
earned = input("What is the grade earned? or type *exit* to proceed to the next section: ")
if earned == 'exit':
while 'subTotal' != 'exit':
subTotal = input("What is the total of assignment? Enter the next... or type *exit* for the average grade: ")
if subTotal == 'exit':
average = earnedTotal/Total
print("The average of "+str(earnedTotal)+"/"+str(Total)+" is "+str(average*100)) + grade.Grade(average)
exit()
else:
Total=float(subTotal)+Total
print(Total)
else:
earnedTotal=float(earned)+earnedTotal
print(earnedTotal)
def Grade(i):
if i >= 90:
return "A"
elif i >= 80:
return "B"
elif i >= 70:
return "C"
elif i >= 60:
return "D"
else:
return "F"
You did have many, many problems here, not the least of which is unclear requirements. What you have here should be functions, not classes. You are confused between variables and strings. Here is something that mostly does what I THINK you want.
As a user experience thing, it's not fair to require them to type the whole word "exit" to stop the process. One mistake, and this will crash converting the string to float. You should just have them press "enter" and check for an empty string. I haven't done that here.
def Grade(avg):
return "FFFFFFDCBAA"[int(avg*10)]
def ClassGrader():
earnedTotal = 0.0
Total = 0.0
while True:
earned = input("What is the grade earned? or type *exit* to proceed to the next section: ")
if earned == 'exit':
break
earnedTotal+=float(earned)
print(earnedTotal)
while True:
subTotal = input("What is the total of assignment? Enter the next... or type *exit* for the average grade: ")
if subTotal == 'exit':
break
Total+=float(subTotal)
print(Total)
average = earnedTotal/Total
print(f"The average of {earnedTotal}/{Total} is {average*100)", Grade(average))
ClassGrader()

how to congratulate player with using hint and without using it differently

i would like to know how to tell the computer to print different input for player using hint
and for someone who doesn't used it to congratulate them
import random
words = dict(
python = "type of snake",
honda = "type of car",
spanish = "type of language",)
word = list(words)
var = random.choice(word)
score = 0
chance = 5
x = list(var)
random.shuffle(x)
jumble = "".join(x)
print("the jumble word is :", jumble,)
while True:
guess = input(" this is my guess :")
if guess == "hint":
print(words[var])
if guess == var:
print("well done you only used ", score,"to guessed it ")
break
else:
print("try again")
score +=1
if score == chance:
print("better luck next time")
break
What about adding a boolean, say hintUsed, that keeps track of whether or not the user used a hint:
hintUsed = False
while True:
guess = input(" this is my guess :")
if guess == "hint":
hintUsed = True # change hintUsed to True !!
print(words[var])
And then, to congratulate:
if guess == var:
if hintUsed:
#print a message
else:
#print another message
break

Categories

Resources