Rounding a float that is an str and used in int - python

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))

Related

Trying to change my code to include loops and listed variables to make more streamline and expandable code

I made a prior discussion where I was unable to properly explain myself. This is my most up to date code that does what I want with 3 items. I would like to turn this into a function using a list so that it can ask how many items you want to use and then run the code that I have so it is not manually inputted 3 separate times but is instead expandable to however many items are needed.
unit = "pounds"
pounds = 0.00220462
weightA = float(input("What is the weight of Specimen A? "))
converted_weightA = float(weightA * pounds)
formatted_floatA = "{:.2f}".format(converted_weightA)
#print('Specimen A is ' + formatted_floatA + ' ' + unit)
weightB = float(input("What is the weight of Specimen B? "))
converted_weightB = float(weightB * pounds)
formatted_floatB = "{:.2f}".format(converted_weightB)
#print('Specimen B is ' + formatted_floatB + ' ' + unit)
weightC = float(input("What is the weight of Specimen C? "))
converted_weightC = float(weightC * pounds)
formatted_floatC = "{:.2f}".format(converted_weightC)
#print('Specimen C is ' + formatted_floatC + ' ' + unit)
totalcost = float(input("What is the total price of the lot?: "))
totalweight = converted_weightA + converted_weightB + converted_weightC
IndividualPriceA = (converted_weightA / totalweight) * (totalcost * 3)
IndividualPriceB = (converted_weightB / totalweight) * (totalcost * 3)
IndividualPriceC = (converted_weightC / totalweight) * (totalcost * 3)
print('Specimen A is ' + formatted_floatA + ' ' + unit + ' and is worth $',IndividualPriceA)
print('Specimen B is ' + formatted_floatB + ' ' + unit + ' and is worth $', IndividualPriceB)
print('Specimen C is ' + formatted_floatC + ' ' + unit + ' and is worth $', IndividualPriceC)
input()
Strock, glad your here. I created a solution for you (below) but I wanted to offer some key advice you would benefit from first.
Your question isn't a hard one, but it's almost asking for someone to turn your code into a usable, repeatable script (your asking for loops, a function, etc.). In other words, it comes across as more of a 'will someone do this for me' vice 'How do I do [A] with Python'.
I'm not sure what your profession or intention is regarding python, but if you are seeking to gain more competence with the programming language, the following tips are much more important for you than the solution below.
Break down your script into small parts, i.e., you know you need loops, so start by creating a very simple loop, understanding it's syntax (https://www.freecodecamp.org/news/python-for-loop-example-and-tutorial/). After you build a loop. Add another piece (like appending items to a list like I did below), and so on. Continue with some patience, and you will be rewarded with better python skills.
I'm still fairly new to the stack overflow community, but here are some tips for getting good responses to questions:
make your question as specific as possible, i.e., 'what's the proper syntax for defining a function in python' is better than 'I need a function and some loops and other things to make this script better'
then before you post it, search to see if someone else already asked/answered your question
if there is no answer, ask it here and provide the code involved (which you did nicely)
Best of luck!
Note: the calculations you did (which I copied exactly) didn't make much sense to me, but I also don't know exactly what this is for. Anyways, feel free to comment if you have any questions!
#create wt_convert function which has two required parameters: list of weights and total cost
def wt_convert(list_of_weights, total_cost):
unit = "pounds"
pounds = 0.00220462
#create empty list to hold converted weights
converted_weights = []
#loop through the list of weights, convert them, add them to 'converted_weights' list
for wt in list_of_weights:
conversion = float(wt * pounds)
converted_weights.append(conversion)
#calculate total weight by using sum function and passing list of 'converted_weights'
totalweight = sum(converted_weights)
#loop through 'converted_weights', calculate price, print result for each
i = 1
n = 0
for wt in converted_weights:
price = (wt / totalweight) * (total_cost * 3)
print('Specimen {} is {} {} and is worth $ {}'.format(
i,
converted_weights[n],
unit,
price
))
i += 1
n += 1
#now function (above) is ready, prepare the needed parameters to use it
specimen_weights = []
#used 'while loop' to enable user to make as many inputs as desired
keep_going = "y"
i = 1
while keep_going == "y":
wt = int(input("What is the weight of specimen {}: ".format(i)))
specimen_weights.append(wt)
i += 1
keep_going = input("To add another specimen, input 'y'. Otherwise press enter: ")
#ask user for total cost
totalcost = float(input("What is the total price of the lot?: "))
#now call function and pass list of specimen weights and totalcost
wt_convert(specimen_weights, totalcost)
example output:

First if statement being ignored by python but not elif's

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.

Python function returning a weird string

I've been working through a book called Exercises for Programmers as I am trying to learn Python.
https://pragprog.com/book/bhwb/exercises-for-programmers
At exercise 8 I ran into some trouble; I am meant to write code that prompts for how many people wanna order pizza, how many slices each and then it must calculate how many pizzas must be ordered (1 pizza = 8 slices) according to the total number of slices (persons * slices each) and the number of leftover slices (if there are any).
I think I've managed to suss it out except that once executed the method that calculates the number of leftover slices prints a weird string (it also contains a hex value?).
I've modulated everything into two files (trying to build good habits);
file 01:
main.py
import pizza as p
while True:
number_of_people = input("How many people are hungry for pizza? ")
number_of_slices_per_person = input("And how many slices per person? ")
try:
val = int(number_of_people) or int(number_of_slices_per_person)
print("\n" + number_of_people + " people have ordered " +
str(p.number_of_pizzas(number_of_people, number_of_slices_per_person)) + " pizzas.")
if int(number_of_slices_per_person) == 1:
print("Each person would like just a " + number_of_slices_per_person + " slice of pizza.")
else:
print("Each person would like " + number_of_slices_per_person + " slices of pizza.")
print("There are " + str(p.number_of_leftover_slices) + " pizza slices left over.")
break
except ValueError:
print("Please enter a valid number")
file 02:
pizza.py
def number_of_pizzas(p1, s1):
"""Calculates the number of pizzas according to the specified
requirements"""
total_pizzas = 0
total_slices = int(p1) * int(s1)
for s2 in range(0, total_slices):
if s2 % 8 == 0:
total_pizzas = total_pizzas + 1
return total_pizzas
def number_of_leftover_slices(total_pizzas):
"""Calculate the number of leftover slices of pizza"""
import main as m
total_pizzas = total_pizzas
leftover_slices = (int(total_pizzas) * 8) %
int(m.number_of_slices_per_person)
return leftover_slices
And this is the output I get;
'4 people have ordered 2 pizzas.'
'Each person would like 3 slices of pizza.'
'There are < function number_of_leftover_slices at 0x7f0a95e2c7b8 > pizza slices left over.'
My issue is the string that gets printed instead of the number I am expected to have calculated. Any thoughts on what I might have done wrong?
Thanks.
You have two problems. Firstly, you need to indent the return line at the end of number_of_leftover_slices
Next, when you call print on an object, Python will try to use either the _repr_ or _str_ method of that object to get a string representation of that object. What you're seeing is the string representation of your number_of_leftover_slices function. What you want to print is actually the output of that function.
n = p.number_of_pizzas(number_of_people, number_of_slices_per_person)
remain = p.number_of_leftover_slices(n)
print(remain)

how to check for float

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.

Puzzled about why I can't add strings together

I am trying to write a program that gets user information and adds it to a list and then I want to total how many user inputs there were, but I can't do it. I have tried running an accumulator, but I get TypeError: unsupported operand type(s) for +: 'int' and 'str'.
def main():
#total = 0
cel_list = []
another_celeb = 'y'
while another_celeb == 'y' or another_celeb == 'Y':
celeb = input('Enter a favorite celebrity: ')
cel_list.append(celeb)
print('Would you like to add another celebrity?')
another_celeb = input('y = yes, done = no: ')
print()
print('These are the celebrities you added to the list:')
for celeb in cel_list:
print(celeb)
#total = total + celeb
#print('The number of celebrities you have added is:', total)
main()
Here is the output as desired without the accumulator, but I still need to add the input together. I have commented out the accumulator.
Enter a favorite celebrity: Brad Pitt
Would you like to add another celebrity?
y = yes, done = no: y
Enter a favorite celebrity: Jennifer Anniston
Would you like to add another celebrity?
y = yes, done = no: done
These are the celebrities you added to the list:
Brad Pitt
Jennifer Anniston
>>>
Thanks in advance for any suggestions.
Total is an integer ( declared earlier on as )
total = 0
As the error code suggest, you are trying to join an integer with a string. That is not allowed. To get pass this error, you may :
## convert total from int to str
output = str(total) + celeb
print(" the number of celebrities you have added is', output)
or even better you can try using string formatting
##output = str(total) + celeb
## using string formatting instead
print(" the number of celebrities you have added is %s %s', % (total, celeb))
I hope this will work for you
Python is a dynamically typed language. So, when you type total = 0, the variable total becomes an integer i.e Python assigns a type to a variable depending on the value it contains.
You can check the type of any variable in python using type(variable_name).
len(object) returns integer value.
for celeb in cel_list:
print(celeb)
#end of for loop
total = 0
total = total + len(cel_list) # int + int
print('The number of celebrities you have added is:', total)
You can get the number of entries in a Python list by using the len() function. So, just use the following:
print('These are the celebrities you added to the list:')
for celeb in cel_list:
print(celeb)
total = len(cel_list)
print('The number of celebrities you have added is: ' + str(total))
Note the decreased indentation of the last two lines - you only need to run them once, after you've finished printing out the celeb's names.

Categories

Resources