I have been tasked with creating a python program that will ask for user inputs and calculate monthly loan repayments, this is the formula I have to work off: Formula. Doing this was not too difficult, however the tutor asked as a bonus to try to make the user inputs 'unbreakable', meaning if any value other than the expected were input it wouldn't break the program. I thought this can easily be done with Try Except, and that's what I did, however I believe my code can be written in a much more concise manner, instead of a Try Except for every input as below:
err = "Please enter a number only!!"
while True:
try:
A = int(input("How much were you loaned? "))
except ValueError:
print(err)
continue
else:
break
while True:
try:
R = float(input("At what monthly rate interest? ")) / 100
except ValueError:
print(err)
continue
else:
break
while True:
try:
N = int(input("And how many years is the loan for? "))
except ValueError:
print(err)
continue
else:
break
RA = R * A
RN = 1 - (1 + R) ** -N
P = RA / RN
print("You will pay £", P, "yearly", "or, £", P / 12, "monthly")
I feel as if perhaps the user inputs could be put into a For Loop, or perhaps all of this into one Try Except block? After thinking about it, I put all the inputs into one Try Except block, however as soon as you fail to correctly input the expected data for the user input, it goes right back to the beginning, not to the question you were on. This is not what I want. Have a look:
err = "Please enter a number only!!"
while True:
try:
A = int(input("How much were you loaned? "))
R = float(input("At what monthly rate interest? ")) / 100
N = int(input("And how many years is the loan for? "))
except ValueError:
print(err)
continue
else:
break
RA = R * A
RN = 1 - (1 + R) ** -N
P = RA / RN
print("You will pay £", P, "yearly", "or, £", P / 12, "monthly")
How do you think I can modify this code to make it more concise, shorter, and efficient without having a Try Except for every user input?
Modularise it, and use a generic function that handles input and loops until the user enters what is asked.
def get_num(prompt="Enter number: "):
"""
(str) -> num
Outputs a prompt and loops until a valid number is
entered by the user, at which point that value is
returned and the function terminates
"""
while True:
num = input(prompt)
try:
num = float(num)
return num
except:
print("Must enter a valid number")
def do_calc():
"""(None) -> None
Get user input, perform calculations and output results
"""
A = int(get_num("How much were you loaned? "))
R = get_num("At what monthly rate interest? ") / 100
N = int(get_num("And how many years is the loan for? "))
RA = R * A
RN = 1 - (1 + R) ** -N
P = RA / RN
print(f"You will pay £{round(P, 2)} yearly or £{P/12:.2f} monthly")
do_calc()
Using the f-string from Python 3 is really nice and elegant- just plug in the values or calculations inside the curly braces. As per suggestion in comment, you may wish to show to two decimal places using either the round function or the formatting option as shown.
A more pythonic way to name your variables would be
amount rather than A
rate rather than R
num_years rather than N
and so on.
Extract the repeated procedure in a function, with all the relevant inputs.
I have added some formatting to the final output to avoid too many decimals
def get_value(message, func, denominator = 1):
try_again = True
v = None
while try_again:
try:
v = func(input(message))/denominator
except ValueError:
print("Please enter a number only!!")
else:
try_again= False
return v
A = get_value("How much were you loaned? ", int)
R = get_value("At what monthly rate interest? ", float, denominator=100.0)
N = get_value("And how many years is the loan for? ", int)
RA = R * A
RN = 1 - (1 + R) ** -N
P = RA / RN
print("You will pay £ {:.2f} yearly or £ {:.2f} monthly".format(P, P / 12))
Related
I am a beginner programmer, working on a project for an online course. I am trying to build a tip calculator. I want it to take input from the user for three values: Bill total, how many are splitting the bill, and the percent they would wish to tip. My conditional statement only has one if:
if meal_price >= 0.01:
example(example)
else:
example(example)
There are no elifs, only an else clause, stating to the user to enter only a numerical value. The program is designed to loop if the else clause runs, or continue if the 'if' condition is met. I would like this program to be completely user-friendly and run regardless of what is typed in. But instead of the else clause being ran when a user enters a string value, the terminal returns an error. How would I check the datatype the user enters, and run my conditional statement based off of that instead of the literal user response?
Note, I've tried:
if isinstance(meal_price, float):
Converting the user input into a string, but then the conditional statement becomes the problem
Thank you all for the help. I started my coding journey about 3 months ago and I am trying to learn as much as I can. Any feedback or criticism is GREATLY appreciated.
enter image description here
def calculation():
tip_percent = percentage / 100
tip_amount = meal_price * tip_percent
meal_and_tip = tip_amount + meal_price
total_to_return = meal_and_tip / to_split
return total_to_return
print("\nWelcome to the \"Bill Tip Calculator\"!")
print("All you need to do is enter the bill, the amount of people splitting it, and the percent you would like to tip.\n")
while True:
print("First, what was the total for the bill?")
meal_price = float(input("Bill (Numerical values only): "))
if meal_price >= 0.01:
meal_price2 = str(meal_price)
print("\nPerfect. The total is " + "$" + meal_price2 + ".")
while True:
print("\nHow many people are splitting the bill?")
to_split = int(input("People: "))
if to_split >= 1:
to_split2 = str(to_split)
print("\nAwesome, there is", "\"" + to_split2 + "\"", "person(s) paying.")
while True:
print("\nWhat percent would you like to tip?")
percentage = float(input("Percentage (Numerical values only, include decimals): "))
if percentage >= 0:
percentage2 = str(percentage)
print("\nGot it.", percentage2 + '%.')
calculation()
total = str(calculation())
#total2 = str(total)
print("\n\nEach person pays", "$" + total + ".")
exit()
else:
print("\nPlease enter only a numerical value. No decimals or special characters.")
else:
print("\nPlease respond with a numerical value greater than 0.\n")
else:
print("Please remember to enter only a numerical value.\n")
Included image snapshot in case copy & paste isn't accurate.
The user's input will be a string, so you need to check if the parse to the float was successful. You can do that with a try/except, and then loop back over asking for more input:
print("First, what was the total for the bill?")
meal_price = None
while meal_price == None:
try:
meal_price = float(input("Bill (Numerical values only):"))
except ValueError:
print("That didn't look like a number, please try again")
print(meal_price)
Adding on to #OliverRadini's answer, you use the same structure a lot for each of your inputs that could be generalized into a single function like so
def get_input(prompt, datatype):
value = input(prompt)
try:
a = datatype(value)
return a
except:
print("Input failed, please use {:s}".format(str(datatype)))
return get_input(prompt, datatype)
a = get_input("Bill total: ", float)
print(a)
Perhaps the main point of confusion is that input() will always return what the user enters as a string.
Therefore trying to check whether meal_price is something other than a string will always fail.
Only some strings can be converted into floats - if you try on an inappropriate string, an exception (specifically, a ValueError) will be raised.
So this is where you need to learn a bit about exception handling. Try opening with this block:
meal_price = None
while meal_price is None:
try:
meal_price = float(input("Bill (Numerical values only): "))
except ValueError:
print("Please remember to enter only a numerical value.\n")
This will try to execute your statement, but in the event it encounters a value error, you tell it not to raise the exception, but to instead print a message (and the loop restarts until they get it right, or a different kind of error that you haven't handled occurs).
Thank you all! After looking into your comments and making the amendments, my program works perfectly! You lot rock!!
def calculation():
tip_percent = tip / 100
tip_amount = bill * tip_percent
meal_and_tip = tip_amount + bill
total_to_return = meal_and_tip / to_split
return total_to_return
def user_input(prompt, datatype):
value = input(prompt)
try:
input_to_return = datatype(value)
return input_to_return
except ValueError:
print("Input failed, please use {:s}".format(str(datatype)))
return user_input(prompt, datatype)
print("\nWelcome to the \"Bill Tip Calculator\"!")
print("\nAll you need to do is:\n1.) Enter your bill\n2.) Enter the amount of
people (if bill is being split)\n3.) Enter the amount you would like to
tip.")
print("\n\n1.) What was the total for the bill?")
bill = user_input("Total Bill: ", float)
print("\nAwesome, the total for your meal was " + "$" + str(bill) + ".")
print("\n\n2.) How many people are splitting the bill?")
to_split = user_input("Number of People: ", int)
print("\nSo the bill is divided", str(to_split), "way(s).")
print("\n\n3.) What percent of the bill would you like to leave as a tip?
(Enter a numeral value only. No special characters.)")
tip = user_input("Tip: ", int)
print("\nYou would like to tip", str(tip) + "%! Nice!")
total = calculation()
print("\n\n\n\nYour total is " + "$" + str(total), "each! Thank you for using
the \"Bill Tip Calculator\"!")
my problem is i have to calculate the the sum of digits of given number and that no is between 100 to 999 where 100 and 999 can also be include
output is coming in this pattern
if i take a=123 then out put is coming total=3,total=5 and total=6 i only want output total=6
this is the problem
there is logical error in program .Help in resolving it`
this is the complete detail of my program
i have tried it in this way
**********python**********
while(1):
a=int(input("Enter any three digit no"))
if(a<100 or a>999):
print("enter no again")
else:
s = 0
while(a>0):
k = a%10
a = a // 10
s = s + k
print("total",s)
there is no error message in the program because it has logical error in the program like i need output on giving the value of a=123
total=6 but i m getting total=3 then total=5 and in last total=6 one line of output is coming in three lines
If you need to ensure the verification of a 3 digit value and perform that validation, it may be useful to employ Regular Expressions.
import re
while True:
num = input("Enter number: ")
match = re.match(r"^\d{3}$, num)
if match:
numList = list(num)
sum = 0
for each_number in numList:
sum += int(each_number)
print("Total:", sum)
else:
print("Invalid input!")
Additionally, you can verify via exception handling, and implementing that math you had instead.
while True:
try:
num = int(input("Enter number: "))
if num in range(100, 1000):
firstDigit = num // 10
secondDigit = (num // 10) % 10
thirdDigit = num % 10
sum = firstDigit + secondDigit + thirdDigit
print("Total:", sum)
else:
print("Invalid number!")
except ValueError:
print("Invalid input!")
Method two utilizes a range() function to check, rather than the RegEx.
Indentation problem dude, remove a tab from last line.
Also, a bit of python hint/tip. Try it. :)
a=123
print(sum([int(x) for x in str(a)]))
Python 2.7. I am new to Python and I am stuck with while True loop. Simple program to calculate salary. When 'standard' entered as a letter, it catches the error and jumps again to the line 'Enter your rate'. I want it to be repeated only where the error was captured and not starting to input all info all over again. Can someone help please?
while True:
try:
rate = float(raw_input("Enter your rate: "))
error = float(rate)
standard = float(raw_input("Enter total standard hours 100%: "))
error = float(standart)
except:
print 'Not a number'
continue
else:
sum = standard * rate
print sum
Thank you in advance.
while True:
try:
rate = float(raw_input("Enter your rate: "))
standard = float(raw_input("Enter total standard hours 100%: "))
except ValueError:
print 'Not a number'
else:
sum = standard * rate
print sum
break
You need to add a break at the end. Also you dont need to write error = float(..) when you are already trying to typecaste it in the input step.
Also, there is a typo in the line error = float(standart) . This will cause it to give exceptions forever.
Another good practice is to specify the type of error you expect ( ValueError ). This would help prevent things like typos.
Try splitting standard and rate out of the same loop, like so.
def get_input(text):
while 1:
try:
value = float(raw_input(text))
break
except:
print 'Not a Number'
return value
rate = get_input("Enter your rate: ")
standard = get_input("Enter total standard hours 100%: ")
sum = standard * rate
print(sum)
This way only the value that failed will be re-queried.
In your code continue instruction is not needed, as else
instruction is executed only if no exception has been thrown.
But to exit the loop in the "positive" case, add break instruction
after print sum.
And one more remark: Change standart to standard.
while True:
try:
rate = float(raw_input("Enter your rate: "))
standard = float(raw_input("Enter total standard hours 100%: "))
except ValueError:
print( 'Not a number' )
else:
sum = standard * rate
print(sum)
break
Trying to do a Boolean test loop where the user needs to enter a number between 10 and 1000 including 10 and 1000, they need to stay in this loop until they enter the correct number once they do then I will finish the else statement.
I tried this:
while (num_years < 10) and (num_years > 1000): # boolean test , note == (= will give you an error!)
print("Your input must be 10 and 1000")
input("Enter number of years to simulate (currently " + str(num_years) + "): ")
else:
print()
AND this:
while (num_years == range(10, 1000)): # boolean test , note == (= will give you an error!)
print("Your input must be 10 and 1000")
input("Enter number of years to simulate (currently " + str(num_years) + "): ")
else:
print()
You could try something like this as it also checks if the user inputs a valid number:
while True:
number = input("Enter number of years to simulate (10-1000): ")
try:
years = int(number)
if years >= 10 and years <= 1000:
break
else:
print("Your input must be between 10 and 1000 inclusive")
except ValueError:
print("That's not an int!")
print("Simulating %d years..." % years)
Example Usage:
Enter number of years to simulate (10-1000): asd
That's not an int!
Enter number of years to simulate (10-1000): 5
Your input must be between 10 and 1000 inclusive
Enter number of years to simulate (10-1000): 245
Simulating 245 years...
Try it here!
You are never changing the value of num_years so the condition will never change. Fixing your boolean logic:
num_years = 0
while (num_years < 10) or (num_years > 1000):
print("Your input must be 10 and 1000")
num_years = int(input("Enter number of years to simulate (currently {}): ".format(num_years)))
else:
print()
However, this assumes someone is entering a number if you need to cover a non-numeric value then use a try: except: pass block:
try:
num_years = int(input("Enter number of years to simulate (currently {}): ".format(num_years)))
except ValueError:
pass
Note: = is assignment not an equality test. Use in to test if a value is in a list or range.
Okay, first of all:
(num_years < 10) and (num_years > 1000)
this is always False since one number cannot be less than 10 and more than 1000 at the same time.
Second of all
num_years == range(10, 1000)
will never work since you have (probably) integer on the left and generator on the right.
However you might try something like that:
possible_years = range(10,101)
num_years = 50
while num_years in possible_years: # or 9 < num_years < 100
print("Your input must be 10 and 1000")
entered_years = input("Enter number of years to simulate (currently " + str(num_years) + "): ")
num_years = int(entered_years) # remeber to check if entered_years is int before this line!
else:
print()
However there is still a catch, you need to check if user entered an integer.
What you need to do is a while loop to check whether the input is valid. If it's not, it will loop again. Also you never assign the input to a variable.
n = None
while n is None or not 10 <= n <= 1000:
if n is not None: # Only happens if it's not the first input
print('Invalid number, please try again')
try:
n = int( input('Enter number of years to simulate (10-1000): ') ) # Convert the
# string to an int
except:
pass
print( 'Simulating {} years...'.format(n) )
It will continue and say simulating once a valid number is input because
not 10 <= n <= 1000
will evaluate to false.
You can try it at this link: https://repl.it/FftK/0
n = None
while n is None or not 10 <= n <= 1000:
if n is not None: # Only happens if it's not the first input
print('Invalid number, please try again')
try:
n = int( input('Enter number of years to simulate (10-1000): ') ) # Convert the
# string to an int
except:
pass
print( 'Simulating {} years...'.format(n) )
I have the following which should return a value of the interest where it should be divided by 100. How do I implement this?
import math
p = int(raw_input("Please enter deposit amount: \n"))
r = float(raw_input("Please input interest rate: \n")) /100
t = int(raw_input("Please insert number of years of the investment: \n"))
interest = raw_input("Do you want a simple or compound interest ? \n")
A = p*(1+r*t)
B = p*(1+r)^t
if interest == "simple":
print (float(A))
else:
print(float(B))
Try something like this (Hint you don't need to import math for something like this):
from decimal import *
p = Decimal(raw_input("Please enter deposit amount:"))
r = Decimal(raw_input("Please input interest rate as a percentage:")) /100
t = int(raw_input("Please insert number of years of the investment:"))
n = 1 # You should really be asking how many times is the interest compounded per year? If the user chooses compound...
A = p*(1 + r)**t
B = p*(1 + r)**(n*t)
while(True):
interest = raw_input("Do you want simple or compound interest?")
if(interest.lower() == "simple"):
print(A)
break
elif(interest.lower() == "compound"):
print(B)
break
Try it here!