Beginner question regarding if-elif-if-if chain - python

Very recently started to learn Python (2 weeks ago) and have been enjoying working through the Python Crash Course book. I've written some code for an exercise in the book. The code works as I expected it to but I don't quite understand why.
Exercise: Write a program for a cinema that asks the user for inputs of their age and then tells them what price their ticket will be, using a while loop.
Here is the code I first wrote:
print("Welcome to Cathrine's Cinema!\n")
no_tickets = 0
total_cost = 0
while True:
if no_tickets == 0:
ticket = input("Would you like to buy a ticket? (Yes/No) ")
if ticket.lower() == 'yes':
no_tickets += 1
age = input("Great! How old is the person that this ticket is "
"for? ")
age = int(age)
if age < 3:
print("The ticket is free, enjoy!")
continue
elif age <= 12:
print("That'll be £10 please.")
total_cost += 10
continue
elif age > 12:
print("That'll be £15 please.")
total_cost += 15
continue
elif ticket.lower() == 'no':
print("Ok, thanks for coming by!")
break
else:
print("Please answer 'Yes' or 'No'")
continue
if no_tickets > 0:
ticket = input("Would you like to buy another ticket? (Yes/No) ")
if ticket.lower() == 'yes':
no_tickets += 1
age = input("Great! How old is the person that this ticket is "
"for? ")
age = int(age)
if age < 3:
print("The ticket is free, enjoy!")
continue
elif age <= 12:
print("That'll be £10 please.")
total_cost += 10
continue
elif age > 12:
print("That'll be £15 please.")
total_cost += 15
continue
elif ticket.lower() == 'no':
print(f"Cool, you have purchased {no_tickets} tickets for a total"
f" cost of £{total_cost}.")
break
else:
print("Please answer 'Yes' or 'No'")
continue
I thought it was quite awkward having two big almost identical if statements just so the initial message (Would you like to buy a/another ...) and the goodbye message was right, so I wrote it again a bit differently.
print("Welcome to Cathrine's Cinema!\n")
no_tickets = 0
total_cost = 0
while True:
if no_tickets == 0:
message = "Would you like to buy a ticket? (Yes/No) "
bye_message = "Ok, thanks for coming by."
elif no_tickets > 0:
message = "Would you like to buy another ticket? (Yes/No) "
bye_message = (f"Cool, you have purchased {no_tickets} tickets for a "
f"total cost of £{total_cost}.")
ticket = input(message)
if ticket.lower() == 'yes':
no_tickets += 1
age = input("Great! How old is the person that this ticket is "
"for? ")
age = int(age)
if age < 3:
print("The ticket is free, enjoy!")
continue
elif age <= 12:
print("That'll be £10 please.")
total_cost += 10
continue
elif age > 12:
print("That'll be £15 please.")
total_cost += 15
continue
elif ticket.lower() == 'no':
print(bye_message)
break
else:
print("Please answer 'Yes' or 'No'")
continue
Now this seems to work exactly the same as the previous program, but I'm confused about the if-elif chain. I thought that python executes only one block in an if-elif chain. So if the customer orders 1 ticket, then no_tickets > 0 and so we enter the second elif statement. Why then don't we go back to the start of the while loop and loop infinitely? Why instead do we continue to the other if statements below (testing if ticket.lower() == 'yes' or 'no')?
Thanks for reading all of this! Sorry if this seems like a pointless question as my code is working as intended, I just want to properly understand everything that's going on.

This has to do with indentation. Languages like java enclose if/else statements in parenthesis {}, but python depends on indentation.
Notice that the testing if ticket.lower() == 'yes' or 'no' has the same indentation as if no_tickets == 0: and if no_tickets > 0: therefore it is considered to be outside of the first if/else block.
This might be helpful: https://www.w3schools.in/python-tutorial/concept-of-indentation-in-python/

if your if statement condition is fulfilled, say age<3 is true then statement for that condition are processed/executed and then your program will not see anything in if..elif..else code block, it will go for the next code block(part of code after if..elif..else statement).
why we continue to other if statement, because in your code there are two code section for if statement and they processed one by one unless no break/exit statement didn't occur which cause them to go out of the while loop or exit the program

Related

ValueError exception in python3?

I'm a python beginner and i was making a simple number guessing game, but every time i accidently type in a letter or a symbol instead of a number, i get the ValueError. How do I pass this error throughout the entire program? i know the code is messy, and I'm sorry for that but I'm just trying to have some fun with it.
import random
tries = 15
money = 0
cheat = 0
run = True
random_number = random.randint(1, 20)
while run:
if cheat >= 1:
print(random_number)
cheat -= 1
guess = input("Pick a number from 1-20! You have " + str(tries) + " tries")
guess = int(guess)
if guess == random_number:
money += 5
print("You got it right! You got it with " + str(tries) + " tries left", "your balance is", + money)
again = input("Play again? yes/no")
if again == "yes":
random_number = random.randint(1, 20)
else:
break
#store system
shop = input("Would you like to access the shop? yes/no")
if shop == "yes":
try_cost = 10
cheat_cost = 20
#if player has enough money
buy_try = input("Would you like to purchase more tries? price is 10 dollars for 5 tries. yes/no")
if buy_try == "yes" and money >= 10:
tries += 5
money -= 10
print("You have", tries, "tries", "and", money, "money", "and", cheat, "cheats")
buy_cheat = input("Would you like to purchase a cheat? price is 20 dollars for 2 cheats")
if buy_cheat == "yes" and money >= 20:
cheat += 2
money -= 20
print("You have", tries, "tries", "and", money, "money", "and", cheat, "cheats")
# if player doesn't have enough money
elif buy_try == "yes" and money != 10:
print("You don't have enough for that, you have", money, "dollars")
elif buy_cheat == "yes" and money != 20:
print("You don't have enough for that, you have", money, "dollars")
elif guess > random_number:
print("Try a little lower!")
tries -= 1
elif guess < random_number:
print("Try a little higher!")
tries -= 1
if tries == 0:
print("you ran out of tries!")
run = False
Pick a number from 1-20! You have 15 triess
Traceback (most recent call last):
File "C:\Users\bashr\PycharmProjects\pythonProject1\main.py", line 15, in
guess = int(guess)
ValueError: invalid literal for int() with base 10: 's'
In this situation, use a try and except clause.
Documentation: https://docs.python.org/3/tutorial/errors.html#handling-exceptions
assuming you want to access that error inside this whole file then you can use global variable or you can use class concept
I think the fastest way to solve that is a while: while the input Is not a digit ask again the input.
So, in your case, every time you use the input function you should use something likes this:
guess = input("Pick a number from 1-20! You have " + str(tries) + " tries")
while not guess.isdigit():
print("the input Is not a digit, please retry")
guess = input("Pick a number from 1-20! You have...")
Or you can use you can use try and except

Is it possible to end a while loop with a try/except statement?

So the goal here is to end my while loop, or my script really if a user's bank amount reaches 0 (zero) or if the user inputs a 0 (zero) for bet amount to terminate the script. THE PROBLEM is that I am NOT allowed to use a break statement, and though the program works perfectly with exit(), I cannot use that either because we haven't "gotten there yet" via the book (the instructor wants us to use what we are learning in the book and not what we already know).
I am just really stumped. Part of it is because I struggle a lot with the try/except statements so maybe I am just doing something wrong there, or maybe I need to try a different loop. Maybe you guys can help?
Gonna post my code below. As far as I am concerned, everything works perfectly fine, but I cannot use exit() or break so I need some advice on another python basics-orientated method...
So can I use try/except? If so, how?
I need the program to continue looping unless banking reaches 0 (zero) or user input is equal to 0 (zero), it's why I chose the while loop. Do I need to use a different loop method?
The help will be GREATLY appreciated and I thank everyone in advance.
import random
def rollDice(cnt):
die1 = random.randint(1,6)
die2 = random.randint(1,6)
x = int(die1 + die2)
print('Roll #', cnt, 'was', x)
return x
def total_bank(bank):
bet = 0
while bet <= 0 or bet > min([500,bank]):
print(f'You have ${bank} in your bank.')
get_bet = input('Enter your bet (or 0 to quit): ')
if get_bet == '0':
print('Thanks for playing!')
exit()
bet = int(get_bet)
return bank,bet
def get_guess():
guess = 0
while (guess < 2 or guess > 12):
try:
guess = int(input('Choose a number between 2 and 12: '))
except ValueError:
guess = 0
return guess
bank = 500
guess = get_guess
rcnt = 1
while rcnt < 4:
rcnt = 0
bank,bet = total_bank(bank)
guess = get_guess()
if guess == rollDice(rcnt+1):
bank += bet * 2
elif guess == rollDice(rcnt+2):
bank += bet * .5
elif guess == rollDice(rcnt+3):
bank = bank
else:
bank = bank - bet
if bank == 0:
print(f'You have ${bank} in your bank.')
print('Thanks for playing!')
exit()
You can certainly exit the loop using an exception; just raise an exception inside your while loop, and catch it outside the loop:
def total_bank(bank):
bet = 0
try:
while bet <= 0 or bet > min([500,bank]):
print(f'You have ${bank} in your bank.')
get_bet = input('Enter your bet (or 0 to quit): ')
if get_bet == '0':
print('Thanks for playing!')
raise StopIteration()
bet = int(get_bet)
except StopIteration:
pass
return bank,bet
But even easier is just to return from inside the loop:
def total_bank(bank):
bet = 0
while bet <= 0 or bet > min([500,bank]):
print(f'You have ${bank} in your bank.')
get_bet = input('Enter your bet (or 0 to quit): ')
bet = int(get_bet)
if get_bet == '0':
print('Thanks for playing!')
return bank, bet
return bank, bet
I'm not super knowledgable with the try and except functions but with the try block you could raise an error and end the program like that.

How to stop code running when if statement is not fulfilled

I am doing a school project and what i want to add is a line of code that would stop the code from running if age < 15 or if age > 100
I tried break but it would continue to the next line.
while True:
try:
age = int(input("How old are you? "))
except ValueError:
print("Please enter a valid age!")
continue
if age < 15:
print("sorry you are too young to enter the store!")
break
if age > 100:
print("Please come back in the next life")
break
else:
break
print("")
print("Welcome to Jim's Computer Store", name)
print("") while True:
try:
cash = int(input("How much cash do you currently have? $"))
except ValueError:
print("Please enter a valid value! ")
continue
else:
break
I would advise you to proceed step by step. The code in the question is too long for the purpose. When the first step behaves like you want, you can do another step.
Is is this working like you want ?
name = "John"
while True:
try:
age = int(input("How old are you? "))
except ValueError:
print("Please enter a valid age!")
continue
break
# Here, we can assume that 'age' is an integer
if age < 15:
print("sorry you are too young to enter the store!")
exit()
if age > 100:
print("Please come back in the next life")
exit()
print("")
print("Welcome to Jim's Computer Store", name)
# When the code above will be validated, the next step will be easy
The while loop is to assure that age is an integer when he breaks the loop (if age is not an integer, the program will execute the continue instruction and go back to the start of the loop).
Just adding a exit() after the if condition will do the job.
An example would be:
x = 5
if x < 2:
print "It works"
else:
exit()
Or without the else statement:
x = 5
if x < 2:
print "It works"
exit()

Having user input take string and int? (Python)

prompt = "Enter your age for ticket price"
prompt += "\nEnter quit to exit: "
active = True
while active:
age = input(prompt)
age = int(age)
if age == 'quit':
active = False
elif age < 3:
print("Your ticket is $5")
elif age >= 3 and age < 12:
print("Your ticket is $10")
elif age >= 12:
print("Your ticket is $15")
This is some fairly simple code but I am having one issue. The problem is, for the code to run age has to be converted into an int. However, the program is also supposed to exit when you type in "quit". You can always have another prompt along the lines of "Would you like to add more people?". However, is there a way to make it run without having to prompt another question?
I would suggest getting rid of the active flag, and just breaking when "quit" is entered, like so, then you can safely convert to int, because the code will not reach that point if "quit" was entered:
while True:
age = input(prompt)
if age == "quit":
break
age = int(age)
if age < 3:
print("Your ticket is $5")
elif age < 12:
print("Your ticket is $10")
else:
print("Your ticket is $15")
Note that the age >= 3 and age >= 12 checks are unnecessary, because you have already guaranteed them with the earlier checks.
If you want to add another prompt, you can ask the first prompt before the loop and the other one at the end of it. And if you want to add the prices, you need a variable for it. If you dont want to prompt another question but want more user input, leave the prompt empty.
prompt = "Enter your age for ticket price"
prompt += "\nEnter 'quit' to exit: "
price = 0
user_input = input(prompt)
while True:
if user_input == 'quit':
break
age = int(user_input)
if age < 3:
price += 5
elif age < 12:
price += 10
else:
price += 15
print(f"Your ticket is ${price}")
user_input = input("You can add an age to add another ticket, or enter 'quit' to exit. ")

Getting error message when trying to break out of a while loop in Python

I'm trying to write code that includes the following:
1) Uses a conditional test in the while statement to stop the loop.
2) Uses an active variable to control how long the loop runs.
3) Use a break statement to exit the loop when the user enters a 'quit' value.
Here is my code:
prompt = "What is your age?"
prompt += "\nEnter 'quit' to exit: "
while True:
age = input(prompt)
age = int(age)
if age == 'quit':
break
elif age < 3:
print("Your ticket is free.")
elif 3 <= age <=12:
print("Your ticket is $10.")
elif 12 < age:
print("Your ticket is $15.")
else:
print("Please enter a valid age.")
I believe I've answered part 1 and 2 correctly but whenever I enter 'quit' or any other word to test for part 3, I get an error message that states: "ValueError: invalid literal for int() with base 10: 'quit'"
Does anyone have any suggestions of what I may be doing wrong in my code? Thank you for your time.
You are converting the user's input to a number before checking if that input is actually a number. Go from this:
age = input(prompt)
age = int(age)
if age == 'quit':
break
elif age < 3:
print("Your ticket is free.")
To this:
age = input(prompt)
if age == 'quit':
break
age = int(age)
if age < 3:
print("Your ticket is free.")
This will check for a request to exit before assuming that the user entered a number.
You convert age to an integer with int() so it will never equal 'quit'. Do the quit check first, then convert to integer:
age = input(prompt)
if age == 'quit':
break;
age = int(age)
...
This now checks if it's equal to a string literal first, so that in the case it is, it breaks correctly. If not, then continue on as usual.
You are casting the string "quit" to integer, and python tells you it's wrong.
This will work :
prompt = "What is your age?"
prompt += "\nEnter 'quit' to exit: "
while True:
age = input(prompt)
if age == 'quit':
break
age = int(age)
if age < 3:
print("Your ticket is free.")
elif 3 <= age <=12:
print("Your ticket is $10.")
elif 12 < age:
print("Your ticket is $15.")
else:
print("Please enter a valid age.")
Just for the sake of showing something different, you can actually make use of a try/except here for catching a ValueError and in your exception block, you can check for quit and break accordingly. Furthermore, you can slightly simplify your input prompt to save a couple of lines.
You can also force the casing of quit to lowercase so that you allow it to be written in any casing and just force it to a single case and check for quit (if someone happens to write QuIt or QUIT it will still work).
while True:
age = input("What is your age?\nEnter 'quit' to exit: ")
try:
age = int(age)
if age < 3:
print("Your ticket is free.")
elif 3 <= age <=12:
print("Your ticket is $10.")
elif 12 < age:
print("Your ticket is $15.")
else:
print("Please enter a valid age.")
except ValueError:
if age.lower() == 'quit':
break
As proposed in a comment above you should use raw_input() instead of input in order to handle the user input as a string so that you can check for the 'quit' string. If the user input is not equal to 'quit' then you can try to manage the input string as integer numbers. In case the user passes an invalid string (e.g. something like 'hgkjhfdjghd') you can handle it as an exception.
Find below a piece of code that demonstrates what I described above:
prompt = "What is your age?"
prompt += "\nEnter 'quit' to exit: "
while True:
age = raw_input(prompt)
if age == 'quit':
break
try:
age = int(age)
if age < 3:
print("Your ticket is free.")
elif 3 <= age <=12:
print("Your ticket is $10.")
elif 12 < age:
print("Your ticket is $15.")
except Exception as e:
print 'ERROR:', e
print("Please enter a valid age.")

Categories