This question already has answers here:
Python: How to keep repeating a program until a specific input is obtained? [duplicate]
(4 answers)
Closed 5 years ago.
I am fairly new to Python and I'm trying to create a simple program to calculate, then print, how much a vacation rental is based on the number of weeks a user has inputted (so long as the number of weeks is greater than 4, but less than 16). I have that part of the code down just fine, but what I am having trouble with is getting the program to repeat the question if a user does enter a number that is not in range. Any help would be greatly appreciated. Here is my code:
weeks = 0
total = 0
while True:
try:
weeks = int(input("How many weeks do you plan on vacationing? "))
break
except ValueError:
print("Please enter a number.")
if weeks < 4:
print("Not in range.")
elif weeks <= 6:
total = weeks*3080
print("Rental cost: $",total)
elif weeks <= 10:
total = weeks*2650
print("Rental cost: $", total)
elif weeks <=16:
total = weeks*2090
print("Rental cost: $", total)
else:
print("Not in range.")
Update:
weeks = 0
total = 0
while True:
try:
weeks = int(input("How many weeks do you plan on vacationing? "))
if weeks < 4:
print("Not in range.")
continue
elif weeks <= 6:
total = weeks*3080
print("Rental cost: $",total)
break
elif weeks <= 10:
total = weeks*2650
print("Rental cost: $", total)
break
elif weeks <=16:
total = weeks*2090
print("Rental cost: $", total)
break
else:
print("Not in range.")
except ValueError:
print("Please enter a number.")
Validate weeks in the try block and raise ValueError before the break if out of range.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 months ago.
Improve this question
I want to write a script that will return the Gregorian epact.
The program asks the user to provids a year.
It checks if the input is correct (i.e. number).
It determines the number of digits of the given number (4 here).
If the user fails five to provides a correct input the scripts terminates.
Here is my script.
I think it is rather complicated. How could I simplify it?
# Program for the calculation of the Gregorian epact
import math as m # Python's basic mathematical library
print("This program calculates the Gregorian epact value of a given year.")
print("See https://fr.wikipedia.org/wiki/%C3%89pacte for further details.")
is_year_correct = False
n = 0
while (not is_year_correct) and n<=4:
year = input("Enter the year (e.g. 2020): ") # User provides a year
try:
year = int(year)
digits = int(m.log10(year))+1 # number of digits in year
except ValueError:
print("Please, try again by entering a year!")
if digits == 4:
is_year_correct = True
else:
print("Please enter a four digit number.")
n = n+1
if n<=4:
c = year // 100
epact = (8+(c//4) - c + ((8*c + 13)//25) + 11 * (year % 19)) % 30
print("The epact value is", epact, "days.")
else:
print('No more attempts!')
Wow learning about epact led me on a rabbit hole
I have minimized the code a bit however I lost some functionality...
I have a way to make sure the functionality is ensured and I will share the piece of code in a sec:
Code with comments:
# Program for the calculation of the Gregorian epact
print("This program calculates the Gregorian epact value of a given year.")
print("See https://fr.wikipedia.org/wiki/%C3%89pacte for further details.")
# Infinite loop
while True:
# Tries to convert the user's input into a number
try:
year = int(input("Enter the year (e.g. 2020): ")) # User provides a year
# All code under this will NOT be executed if user doesn't enter a number
# as the code above will raise an exception causing us to go to the
# exception area
# If year is less than 1000 we warn else we leave infinite loop
if year < 1000: print("Please enter a four digit number.")
else: break
# If user enters a letter
except ValueError:
print("Please, try again by entering a year!")
# Epact calculations
c = year // 100
epact = (8+(c//4) - c + ((8*c + 13)//25) + 11 * (year % 19)) % 30
print(f"The epact value is {epact} days.")
Code without Comments:
# Program for the calculation of the Gregorian epact
print("This program calculates the Gregorian epact value of a given year.")
print("See https://fr.wikipedia.org/wiki/%C3%89pacte for further details.")
while True:
try:
year = int(input("Enter the year (e.g. 2020): ")) # User provides a year
if year < 1000: print("Please enter a four digit number.")
else: break
except ValueError:
print("Please, try again by entering a year!")
c = year // 100
epact = (8+(c//4) - c + ((8*c + 13)//25) + 11 * (year % 19)) % 30
print(f"The epact value is {epact} days.")
All functionality
# Program for the calculation of the Gregorian epact
print("This program calculates the Gregorian epact value of a given year.")
print("See https://fr.wikipedia.org/wiki/%C3%89pacte for further details.")
for _ in range(5):
try:
year = int(input("Enter the year (e.g. 2020): ")) # User provides a year
if year < 1000: print("Please enter a four digit number.")
else: break
except ValueError:
print("Please, try again by entering a year!")
try:
c = year // 100
epact = (8+(c//4) - c + ((8*c + 13)//25) + 11 * (year % 19)) % 30
print(f"The epact value is {epact} days.")
except: print("No more tries!")
I need the loop to stop at 12 months and not count all the way up to how many months it takes to reach the goal. I just need it to print how many months it takes to reach the goal but not count all the way to it. I only need it to go up to 12 months. For example if I input an original deposit for 1000, 4.5 interest rate, 12 months, and 1200 goal amount then I want it to only show it counting to 12 months not 49. I still need it to print out how many months it takes to reach the goal at the end but I do not need it to show it counting all the way up to 49. I am sorry if this sounds confusing.
#Keep asking until the user puts in a positive numeric value using loops
fDeposit = 0
while fDeposit <= 0:
try:
fDeposit = float(input('What is the original deposit (positive value): '))
if fDeposit <= 0:
print("Input must be a positive numerical value: ")
except ValueError:
print("Input must be a numeric value")
fInterest = 0
while fInterest <= 0:
try:
fInterest = float(input('What is the Interest Rate (positive value): '))
if fInterest <= 0:
print("Input must be a positive numerical value: ")
except ValueError:
print("Input must be a numeric value")
iMonths = 0
while iMonths <= 0:
try:
iMonths = int(input('What is the number of months (positive value): '))
if iMonths <= 0:
print("Input must be a positive numerical value: ")
except ValueError:
print("Input must be a numeric value")
fGoal = None
while fGoal == None:
try:
fGoal = float(input('What is the goal amount (Can enter 0 but not negative): '))
if fGoal < 0:
print("Input must be a positive numerical value: ")
fGoal = None
except ValueError:
print("Input must be a numeric value")
# Calculate Interest. First convert the variable to a decimal by dividing by 100 then divide
that by 12
fMonthlyInterest= (fInterest/100/12)
#Output the number of months the user has supplied and get account balance
i = 1
fAccountBalance = fDeposit
while i <= fAccountBalance:
if fAccountBalance >= fGoal:
break
fInterestForMonth = (fAccountBalance * fMonthlyInterest)
#Add the interest for the month to the deposit to get the new Account Balance
fAccountBalance += fInterestForMonth
print('Month: ',i, 'Account Balance is: $',format(fAccountBalance, ",.2f"))
i += 1
# Calculate how many months it will take of compounding to reach the goal amount
GoalFormatted = "{:.2f}".format(fGoal)
CompoundedSavingsAccountBalance = fMonthlyInterest + fAccountBalance
while CompoundedSavingsAccountBalance < fGoal:
iMonths += 1
print('It will take: ',i-1, 'months to reach the goal of $', GoalFormatted)
to solve your problem, add "if i < 12:" after line 52, and indent the next line where you printing the month & the account balance. The completed section is below.
i = 1
fAccountBalance = fDeposit
while i <= fAccountBalance:
if fAccountBalance >= fGoal:
break
fInterestForMonth = (fAccountBalance * fMonthlyInterest)
#Add the interest for the month to the deposit to get the new Account Balance
fAccountBalance += fInterestForMonth
if i <= 12:
print('Month: ',i, 'Account Balance is: $',format(fAccountBalance, ",.2f"))
i += 1
Asked a question earlier today, but managed to figure out my answer from earlier after some goofing around. I have a new question though. I'm still really new to python, and I'm working on my first mid-term project. My code currently runs exactly to the specifications the instructor has asked for, however I would like to add a little extra by making sure that the only input the code will accept from the user is an integer. I've looked at a posts and seen how it can be done, but I don't quite understand yet. Can someone show me how I would be able to write an exception handler into my code that continues to loop properly?
#will be used later to generate a random guess
import random
#Welcome Greeting
print("----------------------------------------------------")
print("Hello, and welcome to my Fall 2021 Mid-term Project.")
print("----------------------------------------------------\n\n")
#collect data for group size, give user the option to exit
groupSize = int(input("How many people are there in your group today? Or enter 0 to exit: "))
while groupSize != 0:
eachAge = 0
#prep user to enter values
print("\nWhy don't you tell me how old each person is?\n")
for eachLoop in range (1, groupSize+1):
age = int(input("# "+str(eachLoop)+" : "))
#make sure to add the ages of the group to each other to update the eachAge variable
eachAge += age
#divide the total age by the groupSize variable and round to 3 decimals
averageAge = round(eachAge/groupSize,3)
print("\nThe average age for this group is",str(averageAge)+".\n")
#generate a random guess between 1-100
randNum=random.randint(1,100)
print("I was going to guess %0.3f"%randNum)
if randNum < averageAge:
#i'm creating variables to make the fomatting in my string simpler
guessLow = float(averageAge-randNum)
print("\nI seem to have guessed too low, short by %0.3f" % guessLow)
elif randNum > averageAge:
guessHigh = float(randNum-averageAge)
print("\nIt looks like I guessed too high, over shot it by %0.3f" % guessHigh)
#this is extremely unlikely with the random guessing, I just thought it might be fun
else:
print("\nOh man, I guessed right on the money!")
#time to categorize our averaged age groups
if averageAge <= 19:
print ("\nYou have a group of very young people.\n\n")
elif averageAge >= 20 and averageAge <= 44:
print ("\nYou have a group of young people.\n\n")
elif averageAge >= 45 and averageAge <= 59:
print ("\nYou have a group of middle aged people.\n\n")
elif averageAge >= 60 and averageAge <= 74:
print ("\nYou have a group of young elderly people.\n\n")
elif averageAge >= 75 and averageAge <= 90:
print ("\nYou have a group of elderly people.\n\n")
else:
print ("\nYou have a group of long-lived people.\n\n")
print("----------------------------------------------------")
print("Why don't we give it another shot? Let's start over.")
print("----------------------------------------------------\n\n")
#reinitialize value back to 0 so that the program can run again from the beginning
groupSize = int(input("How many people are there in your group this time? Or enter 0 to exit: "))
if groupSize <= 0:
print("\n\n\n-`-`-`-`-`-`-`-`-`-`Thanks for trying out my program!`-`-`-`-`-`-`-`-`-`-")
Here is one way to continuously prompt the user until they enter an integer (or an exception is thrown, like KeyboardInterrupt if they press ctrl C):
def read_int(msg):
while True:
val_str = input(msg)
try:
return int(val_str)
except ValueError:
print('%r is not a valid integer' % val_str)
x = read_int('Please enter an integer')
print('user entered %d' % x)
The way it works is by calling input and converting it to an int, like you are doing. But using try/except, it handles the case where int(val_str) throws an exception if the input is not a valid integer. Normally the program would end and print the stack trace in that case, but if we catch it then we can do whatever we want: in this case, loop and call input again.
The loop ends when we return. You could also break if this is not inside its own function.
Without functions or try/except
For the purposes of learning, one way of doing it without functions or try except could involve manually checking if the string is a valid integer (but thanks to #chepner for pointing out that I first missed negative numbers, and that the python int() can handle far more than ascii 0-9 with an optional negative):
val_int = None
while True:
val_str = input(msg)
# Below is a crude way to implement
# the regex '[+-]?[0-9]+'
# make a copy of the string so that we can modify it
val_str_test = val_str
is_valid_int = True
# allow negative numbers in subsequent checks
# by removing the leading unary negative/positive if it exists
if len(val_str_test) > 0 and val_str_test[0] in [ '-', '+' ]:
val_str_test = val_str_test[1:]
# check if all characters in the string
# are between 0 and 9, to ensure this is a valid integer
for c in val_str_test:
if not('0' <= c <= '9'):
is_valid_int = False
break
# empty strings are also not valid integers, but wouldn't
# be caught by the above loop
if len(val_str_test) == 0:
is_valid_int = False
# if the user's string is not a valid integer,
# then loop to the beginning where we prompt the user to
# enter a string
if not is_valid_int:
continue
# I am pretty sure that in this case, int(val_str)
# can't throw an exception, besides maybe
# running out of memory or something outside the scope
# of this question
val_int = int(val_str)
break
Set a function to reprompt the person for a number:
def get_number(question):
value = input(question)
while 1:
try:
value = int(value)
break
except:
value = input(f'(must be a number) {question}')
return value
groupSize = get_number("How many people are there in your group this time? Or enter 0 to exit: ")
#or
age = get_number("# " + str(eachLoop) + " : ")
Your entire code would look like this:
# will be used later to generate a random guess
import random
# Welcome Greeting
print("----------------------------------------------------")
print("Hello, and welcome to my Fall 2021 Mid-term Project.")
print("----------------------------------------------------\n\n")
# collect data for group size, give user the option to exit
def get_number(question):
value = input(question)
while 1:
try:
value = int(value)
break
except:
value = input(f'(must be a number) {question}')
return value
while 1:
groupSize = get_number("How many people are there in your group this time? Or enter 0 to exit: ")
if groupSize == 0:
break
eachAge = 0
# prep user to enter values
print("\nWhy don't you tell me how old each person is?\n")
for eachLoop in range(1, groupSize + 1):
age = get_number("# " + str(eachLoop) + " : ")
# make sure to add the ages of the group to each other to update the eachAge variable
eachAge += age
# divide the total age by the groupSize variable and round to 3 decimals
averageAge = round(eachAge / groupSize, 3)
print("\nThe average age for this group is", str(averageAge) + ".\n")
# generate a random guess between 1-100
randNum = random.randint(1, 100)
print("I was going to guess %0.3f" % randNum)
if randNum < averageAge:
# i'm creating variables to make the fomatting in my string simpler
guessLow = float(averageAge - randNum)
print("\nI seem to have guessed too low, short by %0.3f" % guessLow)
elif randNum > averageAge:
guessHigh = float(randNum - averageAge)
print("\nIt looks like I guessed too high, over shot it by %0.3f" % guessHigh)
# this is extremely unlikely with the random guessing, I just thought it might be fun
else:
print("\nOh man, I guessed right on the money!")
# time to categorize our averaged age groups
if averageAge <= 19:
print("\nYou have a group of very young people.\n\n")
elif averageAge >= 20 and averageAge <= 44:
print("\nYou have a group of young people.\n\n")
elif averageAge >= 45 and averageAge <= 59:
print("\nYou have a group of middle aged people.\n\n")
elif averageAge >= 60 and averageAge <= 74:
print("\nYou have a group of young elderly people.\n\n")
elif averageAge >= 75 and averageAge <= 90:
print("\nYou have a group of elderly people.\n\n")
else:
print("\nYou have a group of long-lived people.\n\n")
print("----------------------------------------------------")
print("Why don't we give it another shot? Let's start over.")
print("----------------------------------------------------\n\n")
if groupSize <= 0:
print("\n\n\n-`-`-`-`-`-`-`-`-`-`Thanks for trying out my program!`-`-`-`-`-`-`-`-`-`-")
So I read a bit about using Try and Except and came up with this:
while True:
try:
groupSize = int(input("How many people are there in your group? Or enter 0 to exit. "))
break
except ValueError:
print("\n**Please enter an integer value only.\n**")
while groupSize != 0:
eachAge = 0
The rest of the code remains unchanged from what I did earlier until the end of the loop when I basically redo the same try/except handler to re-initialize the groupSize variable back to a user input.
What i'm trying to do is have an initial input take a number, then proceed to take numbers that are entered afterwards until the loop is closed by entering 0. The output should be the Initial input, the amount entered added up, then subtracted from the Initial number.
I want to change the overall structure of the program as little as possible.
budget = float(input('Enter amount budgeted for the month: '))
spent = 0
total = 0
while spent >= 0:
spent = float(input('Enter an amount spent(0 to quit): '))
total += spent
print ('Budgeted: $', format(budget, '.2f'))
print ('Spent: $', format(total, '.2f'))
if budget > total:
difference = budget - total
print ('You are $', format(difference, '.2f'), \
'under budget. WELL DONE!')
elif budget < total:
difference = total - budget
print ('You are $', format(difference, '.2f'), \
'over budget. PLAN BETTER NEXT TIME!')
elif budget == total:
print ('Spending matches budget. GOOD PLANNING!')
First, you need to loop until user enters 0. You can use a loop that breaks on 0:
while True:
spent = float(input('Enter an amount spent(0 to quit): '))
if spent == 0: break
total += spent
Or loop until spent is 0. This means initializing it to some non-zero value.
spent = -1
while spent != 0:
spent = float(input('Enter an amount spent(0 to quit): '))
total += spent
Also, all the other code should be outside the loop:
budget = float(input('Enter amount budgeted for the month: '))
spent = -1
total = 0
while spent != 0:
spent = float(input('Enter an amount spent(0 to quit): '))
total += spent
print ('Budgeted: $', format(budget, '.2f'))
print ('Spent: $', format(total, '.2f'))
if budget > total:
difference = budget - total
print ('You are $', format(difference, '.2f'), \
'under budget. WELL DONE!')
elif budget < total:
difference = total - budget
print ('You are $', format(difference, '.2f'), \
'over budget. PLAN BETTER NEXT TIME!')
else:
print ('Spending matches budget. GOOD PLANNING!')
I am writing a program that prompts the user to input some information to output the pay amount. After displaying the amount, the program asks the user whether the user wants to repeat it using the while loop. After the definition of the program that calculates the pay amount, there is a while loop to repeat the questions for the inputs. The problem is that I cannot find a way to exit the loop.
Here is what I have so far:
def CalPay(hrs,rate):
print('Please enter number of hours worked for this week:', hrs)
print('What is hourly rate?', rate)
try:
hrs = float(hrs)
except:
print('You entered wrong information for hours.')
return
try:
rate=float(rate)
except:
print('You entered wrong rate information.')
return
if hrs < 0:
print('You entered wrong information for hours.')
elif rate < 0:
print('You entered wrong rate information.')
else:
if hrs > 60:
pay=((hrs-60)*2*rate)+(20*rate*1.5)+(rate*40)
print('Your pay for this week is:', '$'+str(pay))
elif hrs > 40:
pay=((hrs-40)*1.5*rate)+(rate*40)
print('Your pay for this week is:', '$'+str(pay))
else:
pay=rate*hrs
print('Your pay for this week is:', '$'+str(pay))
repeat=input('Do you want another pay calculation?(y or n)')
while repeat == 'y' or 'Y':
while True:
try:
hrs = float(input('Please enter number of hours worked for this week:'))
except:
print('You entered wrong information for hours.')
continue
else:
break
while True:
try:
rate=float(input('What is hourly rate?'))
except:
print('You entered wrong rate information.')
continue
else:
break
if hrs < 0:
print('You entered wrong information for hours.')
elif rate < 0:
print('You entered wrong rate information.')
else:
if hrs > 60:
pay=((hrs-60)*2*rate)+(20*rate*1.5)+(rate*40)
print('Your pay for this week is:', '$'+str(pay))
elif hrs > 40:
pay=((hrs-40)*1.5*rate)+(rate*40)
print('Your pay for this week is:', '$'+str(pay))
else:
pay=rate*hrs
print('Your pay for this week is:', '$'+str(pay))
repeat=input('Do you want another pay calculation?(y or n)')
print('Good Bye!')
I think your problem is, every time after calculation it is asking you question "'Do you want another pay calculation?(y or n)'" and if you answer n, still execution is going inside loop.
you are using below condition in while
while repeat == 'y' or 'Y': #this is wrong
when you write above condition it actually resolves to
while (repeat == 'y') or ('Y'):
here first condition is false but 2nd is true. So execution will go inside while.
Instead use 'in' keyword as below.
while repeat in ['y', 'Y']: #I will prefer this.
or
while repeat == 'y' or repeat=='Y':
or
while repeat == ('y' or 'Y'):
Hope this will help you.
You have nested while loops. You'll need to break out of both of them.