A simple program to help me calculate costs for some new flooring, but my final outputs are not what i expect.
In particular, when underlay is "No", the variable for underlayarea is still picking up a value and being printed at the end.
If it isn't painfully obvious, this is my first crack at it. Ever.
I was expecting that while the variables for 'edging' and 'underlay' remained "No" that no values would be stored in that while loop.
underlay='No'
edging=input('Are you ordering Edging?').title()
underlay=input('Are you ordering underlay?').title()
roomsize=input('How many square meters is the room?')
roomflt=float(roomsize)
while edging =='Yes':
#ask for user inputs
edgeprice=input("How much is the edging per meter?")
edgeperim=input('What is the perimeter of the room?')
#convert to float for calculation
one=float(edgeperim)
two=float(edgeprice)
#calculate
edgearea=one*two
#reset flag
edging='No'
while underlay=='Yes':
#ask for user input
underlayprice=input('How much per square meter for the Underlay?')
#convert to float for calculation
three=float(underlayprice)
four=float(roomflt)
#calculate
underlayarea=three*four
#reset flag
underlay='No'
#set the floor price
floorprice=input("How much is the floor per square meter?")
#convert to float for calculation
five=float(floorprice)
six=float(roomflt)
#calculate
area=five*six
#get the cost
addemup=(edgearea+underlayarea+area)
print("\n----------------------------------------------\nThe total is £{0:.2f} to purchase the flooring.".format(addemup))
print("This is made up of £{0:.2f} for the floor itself,".format(area))
print("This is made up of £{0:.2f} for the edging,".format(edgearea))
print("and £{0:.2f} for the underlay".format(underlayarea))
You should use simple if-statements instead of using a while-loop and "resetting the flag" at the bottom of the loop. I also improved readability of your code by giving the variables telling names (never give variables names such as one, two and so on). You also have to define edgearea and underlayarea, because else a NameError would be raised in case the user does enter "No" in at least one of the inputs.
edgearea = 0
underlayarea = 0
edging = input('Are you ordering Edging?').title()
underlay = input('Are you ordering underlay?').title()
roomsize = input('How many square meters is the room?')
roomsize = float(roomsize)
if edging == 'Yes':
edgeprice = float(input("How much is the edging per meter?"))
edgeperim = float(input('What is the perimeter of the room?'))
edgearea = edgeperim * edgeprice
if underlay == 'Yes':
underlayprice = float(input('How much per square meter for the Underlay?'))
underlayarea = underlayprice * roomsize
floorprice = float(input("How much is the floor per square meter?"))
area = floorprice * roomsize
total_price = edgearea + underlayarea + area
print(f"\n----------------------------------------------\nThe total is {total} to purchase the flooring.")
print(f"This is made up of {area} for the floor itself,")
if edgearea:
print(f"This is made up of {edgearea} for the edging,")
if underlayarea:
print(f"and {underlayarea} for the underlay")
I would also like to recommend having a look at the DRY principle, aka "Don't repeat yourself". The three calculations have basically the same form. That's why it would be better code style to define a function for these calculations which takes the necessary parameters. A DRY solution could look similar to the following:
def calculate(
name: str,
dimension: str,
unit: str,
mandatory: bool = True,
) -> float:
mandatory = mandatory or input(f"Do you order {name}?") == "Yes"
if mandatory:
relative_price = float(input(f"How much is the {name} per {unit}?"))
size = float(input(f"How much {dimension} is the room?"))
return size * relative_price
return 0
floor_price = calculate("floor", "area", "squaremeters")
edging_price = calculate("edging", "perimeter", "meters", False)
underlay_price = calculate("underlay", "area", "squaremeters", False)
total_price = floor_price + edging_price + underlay_price
Related
I am trying to calculate the cost each person will have to pay daily on a trip. I can get the prompts to work, but not the math. I have no idea on how to do the math with the lists. Anyone got any ideas?
Here is what I have so far:
def main():
morepeople = True
NumPPL = list()
Days = list()
Gas = list()
Food = list ()
Nopeople = 0
while(morepeople):
Numppl = (input('Enter the amount of people traveling: '))
if(Numppl == Nopeople):
morepeople = False
else:
NumPPL.append(Numppl)
Days.append(input('Enter the amount of predicted days traveling: '))
Gas.append(input('Enter gas cost per day: '))
Food.append(input('Enter food cost per day: '))
break
Cost = sum(Gas) and sum(Food)/ sum(NumPPL)
print('Everyones daily share is: ', Cost)
main()
welcome to these boards.
This is a curious approach and interesting question.
Couple things to help you...
1> Input() passes a string regardless of the value actually input. You should convert it to an integer or float before using it in a mathematical operation.
2> As dea87 called out, aggregations on list objects require sum() or len() to get the total of values or count of entries, respectively.
This question already has answers here:
How can I read inputs as numbers?
(10 answers)
Closed 1 year ago.
I'm new to functions and arguments (actually new to python in general) and I'm having a bit of a problem making this program multiply the unit given by the user and output it. It just keeps coming up as whatever the variable is up top, and if I don't include that it says it isn't defined. May someone help, please?
# Variables
inches = 0
item_length = 0
unit_value = 0
# Your unit (smooots for general purposes) function
def inches_to_smoots(inches):
## inches = item x unit value
inches = item_length * unit_value
## return the number of inches
return inches
## main function
def main():
unit = input("What is the name of your unit? ")
unit_value = input (str("What is the length of your unit in inches? "))
item = input("What is the name of the object you'd like to convert to your unit? ")
item_length = input ("What is the length of your item in inches? ") # Is there a way to print a variable inside an input statement?
answer = inches_to_smoots(item_length)
## print the answer
print(item_length,'inches is', inches, unit, 's!')
## call main
main()
Instead of declaring the variables up at the top, your function should take the necessary inputs as arguments. Since you're doing unit conversion, it's very helpful to give each variable a name that indicates what units it's in! For example, your inches_to_smoots function is presumably (according to its name) supposed to take an inch measurement and return a smoot measurement, but you're returning a value called inches. It would make more sense for one of its arguments to be inches and for it to return something that's in smoots. When your code itself makes sense, you'll find that it's not necessary to comment each individual line to explain it.
Make sure to keep the Python types straight as well -- input() gives you a str, but for any kind of mathematical operation you want values to be int or float.
def inches_to_smoots(inches: float, smoots_per_inch: float) -> float:
smoots = inches * smoots_per_inch
return smoots
def main():
smoot = input("What is the name of your unit? ")
inches_per_smoot = float(input(
f"What is the length of one {smoot} in inches? "
))
item_name = input(
f"What is the name of the object you'd like to convert to {smoot}s? "
)
item_inches = float(input(f"What is the length of your {item_name} in inches? "))
item_smoots = inches_to_smoots(item_inches, 1 / inches_per_smoot)
print(f"{item_inches} inches is {item_smoots} {smoot}s!")
if __name__ == '__main__':
main()
Note that your function inches_to_smoots expects to be told how many smoots are in an inch, but you asked the user for the number of inches in a smoot -- hence you want to take the reciprocal! smoots_per_inch == 1 / inches_per_smoot.
Example output:
What is the name of your unit? finger
What is the length of one finger in inches? 4.5
What is the name of the object you'd like to convert to fingers? hand
What is the length of your hand in inches? 7
7.0 inches is 1.5555555555555554 fingers!
To make math with elements inputed by the user, you need to convert it to int or float using the int() or float() methods.
unit = input("What is the name of your unit? ")
unit_value = int(input (str("What is the length of your unit in inches? ")))
item = int(input("What is the name of the object you'd like to convert to your unit? "))
item_length = int(input ("What is the length of your item in inches? ") # Is there a way to print a variable inside an input statement?)
That is because it is seeing inputs as strings and python does not know how to properly multiply those together.
I am about a week into Python. I have looked at various other questions regarding this, and have grown fairly frustrated that my attempts to implement those suggestions are falling flat.
I have tried a few means of passing variables through, based on things I have read. For example (this isn't necessarily representative of a coherent attempt... I have tried many variations and have had to walk back to get code worth posting):
def verify_nums():
globhours = hours
globrate = rate
try:
globhours = float(globhours)
globrate = float(globrate)
return globhours,globrate
except:
print("You must provide numbers")
def calc():
globhours = globhours
globrate = globrate
if globhours > 40:
base = 40 * globrate
ot = (globhours - 40) * (globrate * 1.5)
pay = base + ot
print(pay)
else:
pay = globrate * globhours
print(pay)
hours = input("Enter hours worked: ")
rate = input("Enter hourly rate: ")
verify_nums()
calc()
I am supremely confused on how to transfer the hours and rate variables over to the calc() function.
I eventually figured out I could just merge these into one function...
def paycalc(hours,rate):
etc.
etc.
hours = input("Enter hours: ")
hours = input("Enter hours: ")
paycalc(hours,rate)
But for the sake of learning, I really want to get this global/local thing figured out.
Thanks for the help!
You seem to be trying to get Python to guess which functions are supposed to be global and which local based on their names. Python doesn't do that. If you assign to a variable in a function, and you want that assignment to be global, you need a global statement at the top of the function:
def verify_nums():
global globhours
global blograte
globhours = hours
globrate = rate
# ...
Also, globhours = globhours doesn't do anything useful—and, in fact, it causes a problem. If you global globhours in that function as well, the statement is meaningless. Without that, you're creating a local variable, and assigning it… the value of that local variable that doesn't exist yet.
Anyway, if you add the right global declarations to all of your functions, they will work, but it won't be a great design.
You really don't need any global variables here. If you think about values rather than variables, everything gets a lot easier.
Your verify_nums function needs to work on two values. So just pass those values in as parameters. And it needs to return two values—that's easy, you already did that part.
Now the caller has to store those two values that it returned, so it can pass them to the calc function. Which can also take two values as parameters.
Putting that all together:
def verify_nums(hours, rate):
try:
numhours = float(hours)
numrate = float(rate)
return numhours, numrate
except:
print("You must provide numbers")
def calc(hours, rate):
if hours > 40:
base = 40 * rate
ot = (hours - 40) * (rate * 1.5)
pay = base + ot
print(pay)
else:
pay = rate * hours
print(pay)
globhours = input("Enter hours worked: ")
globrate = input("Enter hourly rate: ")
hours, rate = verify_nums(globhours, globrate)
calc(hours, rate)
One problem left: what happens if there's an error with the user's input? Inside verify_nums, you handle the error with an except:, then you print a message and do nothing. That means you return None. So, when the caller tries to do hours, rate = None, it's going to get an error, which you're not handling. And you can't just carry on without values. What can you do?
More generally "return a pair of numbers, or return None" is a confusing contract for a function to fulfill. How do you use that function? With a whole lot of ugly type-checking. But "return a pair of numbers, or raise an exception" is a perfectly good contract. How do you use that function? With a simple try.
That's why it's better to put the exception handling in exactly the right place where you can deal with it. You want to skip calling calc if there's an error, so the except has to be where you call calc.
def verify_nums(hours, rate):
numhours = float(hours)
numrate = float(rate)
return numhours, numrate
def calc(hours, rate):
if hours > 40:
base = 40 * rate
ot = (hours - 40) * (rate * 1.5)
pay = base + ot
print(pay)
else:
pay = rate * hours
print(pay)
try:
globhours = input("Enter hours worked: ")
globrate = input("Enter hourly rate: ")
hours, rate = verify_nums(globhours, globrate)
except ValueError:
print("You must provide numbers")
else:
calc(hours, rate)
Another improvement you might want to consider: Have calc return the pay, instead of printing it, and make the caller print the value it returns.
I am a novice python code writer and i am starting small with a fuel conversion program. The program asks for your name and then converts a miles per gallon rate or a kilometers per litre rate. Currently, the program runs fine until it gets to the convert to MPG line. then once you press y, it does nothing. funny thing is, no syntax error has been returned. please help as i cannot find anything on it :(
import time
y = 'y', 'yes', 'yep', 'yea', 'ye'
n = 'n', 'no', 'nup', 'nay'
name = str(input("Hey, User, whats your name? "))
time.sleep(1.5)
print("Alright", name, "Welcome the the *gravynet* Fuel Efficiency Converter!")
time.sleep(1.5)
str(input("Would you like to convert the fuel efficiency of your motor vehcile? (Miles Per Gallon) (y/n): "))
if y is True:
miles = int(input("How far did you travel (in miles): "))
galls = int(input("How much fuel did you consume (in gallons): "))
mpgc = (galls/miles)
print("The MPG Rate is: ", int(mpgc))
time.sleep(2)
print("test print")
if y is (not True):
input(str("Would you like to convert KPL instead? (y/n): "))
time.sleep(1.5)
if y is True:
kilometers = int(input("How far did you travel (in kilometers): "))
litres = int(input("How much fuel did you consume (in litres): "))
kplc = ( litres / kilometers )
print("The KPL Rate is: ", int(kplc))
time.sleep(3)
exit()
if y is not True:
print("No worries")
time.sleep(1.5)
print("Thanks", name, "for using *gravynet* Fuel Efficiency Coverter")
time.sleep(1.5)
print("Have a good day!")
time.sleep(1.5)
exit()
else :
print("Sorry, invalid response. Try again")
exit()
elif not y:
print("Please use y/n to answer" )
time.sleep(2)
elif not n:
print("Please use y/n to answer" )
time.sleep(2)
sorry if you think that is bad but i just started python and i need some help :)
Severely trimmed down and indentation fixed (I think....)
if y is True and similarly if y is not True make no sense here.
Also, speaking of is.. is and == may be work as equivalent expressions sometimes for checking for "equality", but not necessarily. == checks for equality whereas is checks for object identity. You should use == for checking for equality between two objects. Except for None in which case it's generally preferred to use is instead of == for this.
You're converting to str in a bunch of places unnecessarily. They're already strings.
In your mpg conversion you already have a floating point number (possibly an int). There's no need to convert to an int here. Suppose mpg is < 1. Then int casting will make this return zero
Your math is also backwards. miles per gallon. Similarly, kilometers per gallon.
name = input("Hey, User, whats your name? ")
print("Alright", name, "Welcome the the *gravynet* Fuel Efficiency Converter!")
mpg = input("Would you like to convert the fuel efficiency of your motor vehcile? (Miles Per Gallon) (y/n): ")
if mpg in y:
miles = int(input("How far did you travel (in miles): "))
galls = int(input("How much fuel did you consume (in gallons): "))
mpgc = miles / galls
print("The MPG Rate is: ", mpgc)
else:
kpl = input("Would you like to convert KPL instead? (y/n): ")
if kpl in y:
kilometers = int(input("How far did you travel (in kilometers): "))
litres = int(input("How much fuel did you consume (in litres): "))
kplc = kilometers / litres
print("The KPL Rate is: ", kplc)
else:
print("No worries")
print("Thanks", name, "for using *gravynet* Fuel Efficiency Coverter")
print("Have a good day!")
The is keyword in python checks if two variables point to the same location in memory. y will never point to the same memory location as the singleton True because it's value is a string. I suspect what you mean to do is something like
inp = str(input("Would you like to convert the fuel efficiency of your motor vehcile? (Miles Per Gallon) (y/n): "))
if inp in y:
...
You cannot directly take y as pressed from the keyboard, you have to take it as an input(Pressing enter would be required), store it, check if it satisfies the conditions, then apply the logic.
I see you tried to define y and n as a tuple (deliberately or not), In that case I assume you also want to take those other words as yes or or too.
In that case you can apply this logic;
inp = input("Would you like to convert the fuel efficiency of your motor vehcile? (Miles Per Gallon) (y/n): ")
if inp in y: # Check if inp corresponds any of the words defined in y
# Things to do if `yes` or anything similar entered.
Some notes:
You don't need to use str() after you take input if you are using
Python3 (Which seems you are). Because input() returns string.
In somewhere you did something like this:
input(str("Would you like to convert KPL instead? (y/n): "))
Which is even more reduntant because the value you entered is already
a string.
You also didn't assign some inputs to any variable throughout the
code. You should assign them If you are to use them later.
Please take care of these issues.
I'm using python for the very first time and I am stuck on this stinking problem and cant for the life of me figure out why its not working. When I try and run my program I can get an answer for the yearly cost without the modification (even though its wrong and I dont know why) but not the yearly cost with the modification.
I've tried rewriting it in case I missed a colon/parenthesis/ect but that didnt work, I tried renaming it. And I tried taking it completely out (this is the only way I could get rid of that annoying error message)
payoff file
from mpg import *
def main():
driven,costg,costm,mpgbm,mpgam = getInfo(1,2,3,4,5)
print("The number of miles driven in a year is",driven)
print("The cost of gas is",costg)
print("The cost of the modification is",costm)
print("The MPG of the car before the modification is",mpgbm)
print("The MPG of the car afrer the modification is",mpgam)
costWithout = getYearlyCost(1,2)
print("Yearly cost without the modification:", costWithout)
costWith = getYearlyCost2()
print("Yearly cost with the modification:", costWith)
While I know there is an error (most likely a lot of errors) in this I cant see it. Could someone please point it out to me and help me fix it?
Also I added my mpg.py in case the error is in there and not the payoff file.
def getInfo(driven,costg,costm,mpgbm,mpgam):
driven = eval(input("enter number of miles driven per year: "))
costg = eval(input("enter cost of a gallon of gas: "))
costm = eval(input("enter the cost of modification: "))
mpgbm = eval(input("eneter MPG of the car before the modification: "))
mpgam = eval(input("enter MPG of the car after the modification: "))
return driven,costg,costm,mpgbm,mpgam
def getYearlyCost(driven,costg):
getYearlyCost = (driven / costg*12)
def getYealyCost2(driven,costm):
getYearlyCost2 = (driven / costm*12)
return getYearlyCost,getYearlyCost2
def gallons(x,y,z,x2,y2,z2):
x = (driven/mpgbm) # x= how many gallons are used in a year
y = costg
z = (x*y) # z = how much money is spent on gas in year
print("money spent on gas in year ",z)
x2 = (driven/mpgam) # x2 = how much money is spent with mod.
z2 = (x2*y)
y2 = (costm + z2)
1,1 Top
Here's your immediate problem:
costWith = getYearlyCost2()
The function you're trying to call is named getYealyCost2() (no "r").
There are other problems that you'll find as soon as you fix that, such as no return statement in getYearlyCost() and trying to return the function getYearlyCost() in getYearlyCost2() and calling getYearlyCost2() without any arguments.
On top of that, import * is frowned upon, and then there's the use of eval()... but that'll do for starters.