I am trying to make a nested loop to check if a user's input should be an integer or a float.
In my calculator, rate per compounds is stored in an integer based on text input, however I want to add the functionality for the else statement to check if the input is a whole number or if its decimal. If its a whole number, I want the text to produce the number without a .0, but if its a float, such as 6.5, I want to keep that variable as a float.
rerun = True
while (rerun):
print ("Welcome to the interest calculator")
balance = input ("\nPlease enter your account balance: ")
interest = input ("\nWhat is the interest rate on the account? (decimal): ")
rate = input ("\nWhat is the rate that interest is applied? "
"\n(Monthly, Quarterly, Annually, Biannually): ")
balance = float(balance)
interest = float(interest)
#Convert text to rate variable
if (rate == "Monthly" or rate == "monthly"):
compounds = 12
elif (rate == "Quarterly" or rate == "quarterly"):
compounds = 4
elif (rate == "Annually" or rate == "annually"):
compounds = 1
elif (rate == "Biannually" or rate == "biannually"):
compounds = 2
This is where I think the check should be
else:
compounds = float(rate)
#Display Data
print ('interest = ', type(interest))
print ('balance = ', type(balance))
print ('compounds = ', type(compounds))
if (compounds == 1):
print ("\nYour account has a balance of $" + str(balance), "dollars with an interest rate \n"
"of ", str(interest) + "%", " being applied", str(compounds), "time per year")
else:
print ("\nYour account has a balance of $" + str(balance), "dollars with an interest rate \n"
"of ", str(interest) + "%", " being applied", str(compounds), "times per year")
total = interest * balance * compounds
if (total < 1):
print ("Calculated total = $" + "{:.2f}".format(total) + " cents")
else:
print ("Calculated total = $" + "{:.2f}".format(total) + " dollars")
#while loop to rerun program
answer = input ("\nType (y) to rerun the program: ")
if (answer == "y" or "Y"):
rerun = True
print ("\n")
else:
rerun = False
So if a user inputs 1 for rate, which would fall in the else statement as it is not one of my predefined words, the "Your account balance......" should display compounds as an int.
If a user inputs 1.5 for rate, which would fall in the else statement as it is not one of my predefined words, the "Your account balance......." should display compounds as a float.
Can anyone offer me some input on how I can approach this? I have tried writing it out using remainders, subtracting and adding numbers to check if compounds is > than a whole number, but I cant seem to get it to write correctly.
Just use float initially, then check if is_integer and handle accordingly:
>>> f = float(input())
3
>>> f
3.0
>>> f.is_integer()
True
Or even better, use the g format specifier:
>>> f = 1.000
>>> f
1.0
>>> print("{:g}".format(f))
1
>>> f = 3.14
>>> print("{:g}".format(f))
3.14
General format. For a given precision p >= 1, this rounds the number
to p significant digits and then formats the result in either
fixed-point format or in scientific notation, depending on its
magnitude.
The precise rules are as follows: suppose that the result formatted
with presentation type 'e' and precision p-1 would have exponent exp.
Then if -4 <= exp < p, the number is formatted with presentation type
'f' and precision p-1-exp. Otherwise, the number is formatted with
presentation type 'e' and precision p-1. In both cases insignificant
trailing zeros are removed from the significand, and the decimal point
is also removed if there are no remaining digits following it.
Related
Beginner in python here. I'm trying to create a program that takes the takes the total price of many things and rounds them up or down depending on their last digit. My issue is that my first "if" statement always gets ignored but all my other "elif" statements work just fine
Code:
if str(finalTotalPrice).endswith("1" or "2") :
roundedDown = round(finalTotalPrice, 1)
print("Final Total = $" + str(roundedDown) + str(0))
print()
cashPayment = float( input("How much cash will you pay with? $"))
change = (cashPayment - roundedDown)
change = round(change, 3)
print("Your change is $" + str(change))
elif str(finalTotalPrice).endswith("8" or "9") :
roundedUp = round(finalTotalPrice, 1)
print("Final Total = $" + str(roundedUp) + str(0))
print()
cashPayment = float( input("How much cash will you pay with? $"))
change = (cashPayment - roundedUp)
change = round(change, 3)
print("Your change is $" + str(change))
elif str(finalTotalPrice).endswith("5" or "0") :
print("Final Total = $" + str(finalTotalPrice))
print()
cashPayment = float( input("How much cash will you pay with? $"))
change = (cashPayment - finalTotalPrice)
change = round(change, 3)
print("Your change is $" + str(change))
Python is not natural language. and and or do not behave the way you are used to. Let's look at the documentation:
>>> help(str.endswith)
Help on method_descriptor:
endswith(...)
S.endswith(suffix[, start[, end]]) -> bool
Return True if S ends with the specified suffix, False otherwise.
With optional start, test S beginning at that position.
With optional end, stop comparing S at that position.
suffix can also be a tuple of strings to try.
Your if statements should look like this:
if str(finalTotalPrice).endswith(("1", "2")):
As pointed out by tripleee, you're actually trying to do logically the wrong thing.
roundedDown = round(finalTotalPrice, 1)
This suggests that finalTotalPrice is a float. Never use floats for money. It'll mostly work for small values, but one day things will stop adding up. Instead, use an integer representing the amount of the smallest denomination you have – here, it looks like your dollar is divided into mils (you used round(..., 3)), so a dollar should be represented as 1000.
But can you still use the round function?
>>> help(round)
Help on built-in function round in module builtins:
round(number, ndigits=None)
Round a number to a given precision in decimal digits.
The return value is an integer if ndigits is omitted or None. Otherwise
the return value has the same type as the number. ndigits may be negative.
Yes, you can; just put in -1 to round to the nearest 10, -2 to round to the nearest 100, etc..
str(finalTotalPrice).endswith("1" or "2")
Ignoring the bug for a moment, this is a bad solution. If you're using floats, it will usually give a completely wrong answer, and if you're using ints it's inefficient. Once you're using ints, you can fix this; finalTotalPrice % 10 will get the last digit, finalTotalPrice % 100 will get the last two digits, etc.. Then you can do:
if finalTotalPrice % 10 in (1, 2):
if finalTotalPrice % 10 > 7:
if finalTotalPrice % 5 == 0:
as necessary.
Additionally, your cash payment code is identical in each if branch, so it should be written after them, not in each branch. And, while we're at it, let's make your variable names conform to PEP 8, the Python Style Guide, and improve input handling:
import re
MONEY_REGEX = re.compile(r"[$]?(\d*)(?:\.(\d+))?")
def input_dollars(prompt="", places=3):
"""Input a dollar amount, returned as an integer.
The prompt string, if given, is passed to the input function.
The places argument determines how many decimal places are allowed.
The return value is shifted by that many decimal places,
so that it is an integer.
>>> input_dollars("prompt? ", places=2)
prompt? a
invalid input
prompt?
empty input
prompt? 0.
invalid input
prompt? $32
3200
>>> input_dollars("prompt? ", places=2)
prompt? 32.450
too many decimal places
prompt? 32.4
3240
>>> input_dollars("prompt? ", places=2)
prompt? .6
60
>>> input_dollars("prompt? ", places=4)
prompt? $.472
4720
"""
fix = 10 ** places
while True:
text = input(prompt)
match = MONEY_REGEX.fullmatch(text)
if match is None:
print("invalid input")
continue
integer, fractional = match.groups()
if fractional is None:
if len(integer) == 0:
print("empty input")
continue
return int(integer) * fix
if len(fractional) > places:
print("too many decimal places")
continue
ipart = int(integer) if integer else 0
fpart = int(fractional.ljust(places, '0'))
return ipart * fix + fpart
def format_dollars(dollars, places=3):
fix = 10 ** places
return "${}.{:0>{}}".format(dollars // fix, dollars % fix, places)
def print_final_total(final_total, places=3):
print("Final Total =", format_dollars(final_total, places))
print()
final_total_price = input_dollars("What's the final total price? ")
if final_total_price % 10 in (1, 2, 8, 9):
print_final_total(round(final_total_price, -2))
elif final_total_price % 5 == 0:
print_final_total(final_total_price)
cash_payment = input_dollars("How much cash will you pay with? $")
change = cash_payment - final_total_price
print("Your change is", format_dollars(change))
This code probably doesn't do what you want it to. But, then, neither does your original.
I wish to create a Function in Python to calculate the sum of the individual digits of a given number
passed to it as a parameter.
My code is as follows:
number = int(input("Enter a number: "))
sum = 0
while(number > 0):
remainder = number % 10
sum = sum + remainder
number = number //10
print("The sum of the digits of the number ",number," is: ", sum)
This code works up until the last print command where I need to print the original number + the statement + the sum. The problem is that the original number changes to 0 every time (the sum is correct).
How do I calculate this but also show the original number in the print command?
Keep another variable to store the original number.
number = int(input("Enter a number: "))
original = number
# rest of the code here
Another approach to solve it:
You don't have to parse the number into int, treat it as a str as returned from input() function. Then iterate each character (digit) and add them.
number = input("Enter a number: ")
total = sum(int(d) for d in number)
print(total)
You can do it completely without a conversion to int:
ORD0 = ord('0')
number = input("Enter a number: ")
nsum = sum(ord(ch) - ORD0 for ch in number)
It will compute garbage, it someone enters not a number
number = input("Enter a number: ")
total = sum((int(x) for x in list(number)))
print("The sum of the digits of the number ", number," is: ", total)
As someone else pointed out, the conversion to int isn't even required since we only operate a character at a time.
So I'm writing a basic program, and part of the output is to state the lowest and highest number that the user has entered. For some reason, the min and max are correct some of the time, and not others. And I can't figure out any pattern of when it's right or wrong (not necessarily when lowest number is first, or last, etc). Everything else works perfectly, and the code runs fine every time. Here is the code:
total = 0
count = 0
lst = []
while True:
x = input("Enter a number: ")
if x.lower() == "done":
break
if x.isalpha():
print("invalid input")
continue
lst.append(x)
total = total + int(x)
count = count + 1
avg = total / count
print("The total of all the numbers your entered is: " + str(total))
print("You entered " + str(count) + " numbers.")
print("The average of all your numbers is: " + str(avg))
print("The smallest number was: " + str(min(lst)))
print("The largest number was: " + str(max(lst)))
Any ideas? Keep in mind I'm (obviously) pretty early on in my coding study. Thanks!
If, at the end of your program, you add:
print("Your input, sorted:", sorted(lst))
you should see the lst in the order that Python thinks is sorted.
You'll notice it won't always match what you think is sorted.
That's because you consider lst to be sorted when the elements are in numerical order. However, the elements are not numbers; when you add them to lst, they're strings, and Python treats them as such, even when you call min(), max(), and sorted() on them.
The way to fix your problem is to add ints to the lst list, by changing your line from:
lst.append(x)
to:
lst.append(int(x))
Make those changes, and see if that helps.
P.S.: Instead of calling str() on all those integer values in your print statements, like this:
print("The total of all the numbers your entered is: " + str(total))
print("You entered " + str(count) + " numbers.")
print("The average of all your numbers is: " + str(avg))
print("The smallest number was: " + str(min(lst)))
print("The largest number was: " + str(max(lst)))
you can take advantage of the fact that Python's print() function will print each argument individually (separated by a space by default). So use this instead, which is simpler and a bit easier to read:
print("The total of all the numbers your entered is:", total)
print("You entered", count, "numbers.")
print("The average of all your numbers is:", avg)
print("The smallest number was:", min(lst))
print("The largest number was:", max(lst))
(And if you want to, you can use f-strings. But you can look that up on your own.)
You convert your input to int when you are adding it to the total, but not when you are finding the min and max.
When given strings, min and max return values based on alphabetical order, which may sometimes happen to correspond to numerical size, but in general doesn't.
All you need to do is to append input as ints.
total = 0
count = 0
lst = []
while True:
x = input("Enter a number: ")
if x.lower() == "done":
break
if x.isalpha():
print("invalid input")
continue
lst.append(int(x)) # this should fix it.
total = total + int(x)
count = count + 1
avg = total / count
You might also want to use string formatting to print your answers:
print(f"The total of all the numbers your entered is: {total}")
print(f"You entered {count} numbers.")
print(f"The average of all your numbers is: {avg}")
print(f"The smallest number was: {min(lst)}")
print(f"The largest number was: {max(lst)}")
I'm trying to replicated a program I made on a Scratch-like application. My problem here is I'm trying to display the user with different numerical data (subtotal, tax and total cost), but when it shows the total cost it gives repeating or terminating decimals. I'd like it to be rounded to two decimals. I've tried adding the round() command inside the program but it's difficult because I'm trying to round a variable rather than an actual number. This is my code so far (line 25 and 28 I believe is where I'm suppose to add a round() or on a new line). I'm very new to Python, I'm using version 3.5.0. I also have searched on here, but the answers were too complex for me. In addition, I got this error: typeerror type str doesn't define __round__ method when adding the round() function in places I assume won't work. Thanks. (ignore after the last else: statement)
#This program asks for the size of pizza and how many toppings the customer would like and calculates the subtotal, tax and total cost of the pizza.
largePizza = 'large'
extraLargePizza = 'extra large'
print ('Answer the follwing question in all lowercase letters.')
print ('Would you like a large or an extra large pizza?')
sizeOfPizza = input()
if sizeOfPizza == largePizza:
print('Large pizza. Good choice!')
else:
print('Extra large pizza. Good choice!')
costOfLargePizza = str(6)
costOfExtraLargePizza = str(10)
oneTopping = 'one'
twoToppings = 'two'
threeToppings = 'three'
fourToppings = 'four'
print ('Answer the following question using words. (one, two, three, four)')
print ('How many toppings would you like on your pizza?')
numberOfToppings = input()
tax = '13%'
if numberOfToppings == oneTopping:
print('One topping, okay.')
if sizeOfPizza == largePizza:
subtotalCostOfLargePizza = str(int(costOfLargePizza) + 1)
**totalCostOfLargePizza = str(int(subtotalCostOfLargePizza) * 1.13)**
print('Your subtotal cost is ' + str(subtotalCostOfLargePizza))
print('Your tax is ' + str(tax))
**print('Your total cost is ' + str(totalCostOfLargePizza))**
else:
print('One topping, okay.')
subtotalCostOfExtraLargePizza = str(int(costOfExtraLargePizza) + 1)
totalCostOfExtraLargePizza = str(int(subtotalCostOfExtraLargePizza) * 1.13)
print('Your subtotal cost is ' + str(subtotalCostOfExtraLargePizza))
print('Your tax is ' + str(tax))
print('Your total cost is ' + str(totalCostOfExtraLargePizza))
I was wondering if anyone could help point me in the right direction! I'm a beginner and I'm totally lost. I'm trying to make a Sentinel controlled loop that asks the user to "enter the amount of check" and then ask "how many patrons for this check". After it asks the user then enters it until they type -1.
once user is done inputting it is suppose to calculate the total,tip,tax of each check with an 18% tip for anything under 8 patrons and 20%tip for anything over 9 and a tax rate of 8%.
and then it should add up the Grand totals.
ex: check 1 = 100$
check 2 = 300
check 3 = 20
Total checks = $420
I'm not asking for someone to do it for me but just if you could point me in the right direction, this is all i have so far and im stuck.
As of right now the code is horrible and doesn't really work.
I completed it in Raptor and it worked perfectly I just don't know how to convert it to python
sum1 = 0
sum2 = 0
sum3 = 0
sum4 = 0
sum5 = 0
check = 0
print ("Enter -1 when you are done")
check = int(input('Enter the amount of the check:'))
while check !=(-1):
patron = int(input('Enter the amount of patrons for this check.'))
check = int(input('Enter the amount of the check:'))
tip = 0
tax = 0
if patron <= 8:
tip = (check * .18)
elif patron >= 9:
tip = (check * .20)
total = check + tax + tip
sum1 = sum1 + check
sum2 = sum2 + tip
sum3 = sum3 + patron
sum4 = sum4 + tax
sum5 = sum5 + total
print ("Grand totals:")
print ("Total input check = $" + str(sum1))
print ("Total number of patrons = " + str(sum3))
print ("Total Tip = $" +str(sum2))
print ("Total Tax = $" +str(sum4))
print ("Total Bill = $" +str(sum5))
Your code runs fine, but you have some logic problems.
It appears you're planning to deal with multiple checks at the same time. You'll probably want to use a list for that, and append checks and patrons to it until check is -1 (and don't append the last set of values!).
I think the real issue you're having is that to leave the loop, check must be equal to -1.
If you follow that a bit further down, you continue to work with check, which we now know is -1, regardless of what happened previously in the loop (check is overwritten every time).
When you get to these lines, then you have a real problem:
if patron <= 8:
tip = (check * .18)
elif patron >= 9:
tip = (check * .20)
# This is the same, we know check == -1
if patron <= 8:
tip = (-1 * .18)
elif patron >= 9:
tip = (-1 * .20)
At this point you probably won't be able to do anything interesting with your program.
EDIT: A bit more help
Here's an example of what I'm talking about with appending to a list:
checks = []
while True:
patron = int(input('Enter the amount of patrons for this check.'))
check = int(input('Enter the amount of the check:'))
# here's our sentinal
if check == -1:
break
checks.append((patron, check))
print(checks)
# do something interesting with checks...
EDIT: Dealing with cents
Right now you're parsing input as int's. That's OK, except that an input of "3.10" will be truncated to 3. Probably not what you want.
Float's could be a solution, but can bring in other problems. I'd suggest dealing with cents internally. You might assume the input string is in $ (or € or whatever). To get cents, just multiply by 100 ($3.00 == 300¢). Then internally you can continue to work with ints.
This program should get you started. If you need help, definitely use the comments below the answer.
def main():
amounts, patrons = [], []
print('Enter a negative number when you are done.')
while True:
amount = get_int('Enter the amount of the check: ')
if amount < 0:
break
amounts.append(amount)
patrons.append(get_int('Enter the number of patrons: '))
tips, taxs = [], []
for count, (amount, patron) in enumerate(zip(amounts, patrons), 1):
tips.append(amount * (.20 if patron > 8 else .18))
taxs.append(amount * .08)
print('Event', count)
print('=' * 40)
print(' Amount:', amount)
print(' Patron:', patron)
print(' Tip: ', tips[-1])
print(' Tax: ', taxs[-1])
print()
print('Grand Totals:')
print(' Total amount:', sum(amounts))
print(' Total patron:', sum(patrons))
print(' Total tip: ', sum(tips))
print(' Total tax: ', sum(taxs))
print(' Total bill: ', sum(amounts + tips + taxs))
def get_int(prompt):
while True:
try:
return int(input(prompt))
except (ValueError, EOFError):
print('Please enter a number.')
if __name__ == '__main__':
main()