Python parking rate - python

def cal_parking_fee (parking_duration):
if parking_duration< 60:
fee = 2.5
else:
fee = 1.80 + 2.50
return(fee)
hours = int(input("Enter minutes "))
total_fee = cal_parking_fee(hours)
print(total_fee)
Hi I'm trying to practice my python programming and I am stuck with this particular question. It says to Write/define a function called cal_parking_fee that takes in one parameter parking_duration in
minutes and return the fee payable based on the duration and parking rate. The rate is first hour of parking is $2.50 and every 30 min of parking thereafter is $1.80. I cant seems to make my code to work with the every 30 mins part.

def cal_parking_fee (parking_duration):
duration_mins = parking_duration
# duration_mins = parking_duration * 60
if duration_mins < 60:
fee = 2.5
else:
duration = duration_mins - 60
fee = 2.5
while duration > 0:
duration = duration - 30
fee = fee + 1.80
return(fee)
hours = int(input("Enter hours "))
total_fee = cal_parking_fee(hours)
print(total_fee)

Here's another approach
def cal_parking_fee (parking_duration):
fee = 2.5
if parking_duration > 60:
# Here I subtract 2 because the 1st two 30 minutes
# have a fixed fee of 2.5 that we've already set
if (parking_duration / 30 - 2) == 0:
periods_to_pay = 1
else:
periods_to_pay = (parking_duration / 30 - 2)
fee += periods_to_pay * 1.8
return(fee)
hours = int(input("Enter minutes "))
total_fee = cal_parking_fee(hours)
print(total_fee)

Related

bisection search causes infinite loop

I want to use bisection search to find out how much monthly payment should be in order to pay the full amount of balance within 12 months which user will input. However, this code I write goes into the infinite loop,showing "low, high, montlyPayment infinite times." I don't know which code causes this problem since conditional statement seems right to me .
initialBalance = float(raw_input('Enter the outstanding balance on your credit card'))
annualInterestrate = float(raw_input('Enter the annual credit card interest rate as a decimal'))
monthlyInterestrate = round(annualInterestrate, 2)
balance = initialBalance
while balance > 0:
numMonth = 0
balance = initialBalance
low = balance/12.0
high = (balance*(1+(annualInterestrate/12.0))**12.0)/12.0
epsilon = 0.01
monthlyPayment = round((high + low)/2.0, 2)
while abs(monthlyPayment*12.0 - initialBalance) >= epsilon:
print 'low =', low, 'high =', high, 'monthlyPayment =', round(monthlyPayment,2)
if monthlyPayment*12.0 < balance:
low = monthlyPayment
else:
high = monthlyPayment
monthlyPayment = round((high + low)/2.0, 2)
while balance > 0 and numMonth < 12:
numMonth += 1
interest = monthlyInterestrate * balance
balance -= monthlyPayment
balance += interest
balance = round(balance, 2)
print 'RESULT'
print 'monthly payment to pay off debt in 1 year:', monthlyPayment
print 'Number of months needed:', numMonth
print 'Balance:',balance
I have re-coded the above problem as
balance = 120000
annualInterestRate = 0.1
rate=annualInterestRate/12.0
high=(balance * (1 + rate)**12) / 12.0
low=balance/12.0
payment=0
bal_ref=balance
unpaid=balance
N=0
while (abs(unpaid) > .01):
month=0
pay=(high+low)/2
balance=bal_ref
while(month < 12):
unpaid=balance-pay
balance=unpaid + (unpaid * rate)
month +=1
if (abs(unpaid) < .01):
payment=pay
break
elif (unpaid > .01):
low=pay
elif (unpaid < -.01):
high=pay
N+=1
print("Payment:",round(pay,2))

Regarding not changing value of N

The question is to find the fixed amount you need to pay to a credit card company when -
bal= the amount you need to pay at the beginning of 0th month
N = it is the monthly fixed amount to be to paid to the credit card company such that at the end of the year, you will have paid the total amount
int = interest rate of the credit card company
bal = int(raw_input("Enter balance"))
rate = int(raw_input("enter rate"))
lower_b = bal/12
upper_b = (bal + ((rate*bal)/1200))/12
N= (lower_b+upper_b)/2
def Credit(bal,rate,N):
global upper_b
global lower_b
i=1
k=bal
while (i<13):
print(N)
paid = N
bal = bal - paid
print("Balance remains to be paid is %s" %(round(bal,2)))
Interest = rate * bal /1200
print("The interest added on is %s" %(round(Interest,2)))
bal=bal+Interest
print ("The amount that needs to be payed is %s " %(round(bal,2)))
i=i+1
if bal==0:
return N
elif 50 < bal < 2000 :
lower_b = N
upper_b = upper_b
N = (upper_b +lower_b)/2
return Credit(k,rate,N)
elif -2000<bal< -50:
upper_b = N
lower_b = lower_b
N = (lower_b +upper_b)/2
return Credit(k,rate,N)
elif -50 < bal < 50:
return N
else:
return bal
result=Credit(bal,rate,N)
print(result)
My code never terminates. The problem is the value of N defined in the code is not changing. It remains fixed N = upper_b +lower_b)/2
Using recursion would not be the ideal approach, you also have logic errors including needing to get the interest rate for the month, your initial upper bound should be greater than the principal plus the interest. You can use a while loop with an inner for loop resetting the balance after each unsuccessful inner loop:
balance = int(raw_input("Enter balance"))
int_rate = float(raw_input("enter rate"))
int_rate /= 100
lower_b = balance / 12.
upper_b = ((balance * (1 + (int_rate / 12.0)) ** 12) / 12.0)
payment = (lower_b + upper_b) / 2
def Credit(bal, rate, low, high, pay):
new_b = bal
# calculate monthly interest rate
month_int = rate / 12
while abs(new_b) > 0.001: # use epsilon
# always reset balance
new_b = bal
for _ in range(12): # loop over 12 month range
new_b -= pay # deduct pay
new_b += month_int * new_b
# if we still have a balance we need to take more so set low to current payment
if new_b > 0:
low = pay
# else we took to much so set high to current payment
else:
high = pay
pay = (low + high) / 2.0
return "Lowest monthly payment over 12 months: {}".format(pay)
print(Credit(balance, int_rate, lower_b, upper_b, payment))

Finding overall time

Trying to find the total time worked in this. Cant seem to figure out what I have wrong.
#Problem 3, Python, Extra Credit
hourStart = int(input("Please enter the hour that Jimmy started work."))
minStart = int(input("Please enter the minute on the hour that Jimmy started work."))
hourEnd = int(input("Please enter the hour that Jimmy ended work."))
minEnd = int(input("Please enter the minute on the hour that Jimmy ended work."))
lunchHourStart = int(input("Please enter that hour that Jimmy started lunch."))
lunchMinStart = int(input("Please enter the minute on the hour that Jimmy started lunch."))
lunchHourEnd = int(input("Please enter the hour that Jimmy ended his lunch break."))
lunchMinEnd =int(input("Please enter the minute on the hour that Jimmy ended his lunch break."))
start = hourStart * 60 + minStart
end = hourEnd * 60 + minEnd
totalTime = end + start
lunchStart = lunchHourStart * 60 + lunchMinStart
lunchEnd = lunchHourEnd * 60 + lunchMinEnd
lunchTime = lunchEnd - lunchStart
timeWorked = (totalTime - lunchTime) * 60
hoursWorked = int(timeWorked)
min = (timeWorked - hoursWorked) * 60
print (min)
Total time should be calculated as
totalTime = end - start
All durations are in minutes, so the following is already in minutes, and does not need to be multiplied by 60:
timeWorked = (totalTime - lunchTime)
Now you have timeWorked in minutes, so in hours that is:
hoursWorked = int(timeWorked / 60)
and the minutes would be the remainder:
minutesWorked = timeWorked % 60
The last 2 statements could be replaced with divmod():
hoursWorked, minutesWorked = divmod(timeWorked, 60)

NameError: global name 'totaloverpay' is not defined

I just started college and I am writing this code out for my college class and it keeps sending an error. Any enlightenment will help, maybe the problem is that I'm half asleep.
here is the code
def main():
overtime = int(0)
totaloverpay = float(0)
hours = int(input('How many hours did you work? NOTE** Hours can not exceed 86 or be less than 8 '))
while hours > 86 or hours < 8:
print('ERROR: Insufficient input. Try again')
hours = int(input('How many hours did you work? NOTE** Hours can not exceed 86 or be less than 8 '))
payrate = float(input('What is the payrate per hour for this employee? NOTE** Payrate can not exceed $50.00 or be less than $7.00 '))
while payrate > 50.00 or payrate < 7.00:
print('ERROR: Insufficient input. Try again')
payrate = float(input('What is the payrate per hour for this employee? NOTE** Payrate can not exceed $50.00 or be less than $7.00 '))
workhours(hours, payrate, overtime)
def workhours(hours, payrate, overtime):
if hours > 40:
overtime = (hours - 40) * -1
else:
regtime = hours + 0
paydistribution(hours, payrate, regtime, overtime)
def paydistribution(hours, payrate, regtime, overtime):
if hours >= 40:
halfrate = float(payrate * 0.5)
overpay = halfrate + payrate
totaloverpay = float(overpay * hours)
if hours < 40:
regpay = hours * payrate
display(hours, payrate, regpay, regtime, overtime)
def display(hours, payrate, regpay, regtime, overtime):
total = float(regpay + totaloverpay)
print(' Payroll Information')
print('Payrate :', format(payrate, '0.2f'))
print('Regular Hours :', format(regtime))
print('Overtime Hours:', format(overtime))
print('Regular Pay :', format(regpay, '6.2f'))
print('Overtime Pay :', format(totaloverpay, '7.2f'))
print('Total Pay :', format(total, '7.2f'))
main()
totaloverplay is not defined in any function below main in which it is referred to, or as a global variable. If you want it to be global, define it outside of the main function's scope.
This looks like a great use-case for a class rather than relying on functional programming.
from decimal import Decimal # more precision than floating point
MINIMUM_WAGE = Decimal("7.25")
OVERTIME_RATE = Decimal("1.5")
class Employee(object):
def __init__(self,first,last,MI="",payrate=MINIMUM_WAGE):
self.first = first.capitalize()
self.last = last.capitalize()
self.MI = MI.upper()
if not MI.endswith("."): self.MI += "."
self.payrate = payrate
self.hours = 0
#property
def name(self, reversed_=False):
return "{} {} {}".format(self.first,self.MI,self.last)
#property
def alphabetize(self):
return "{}, {}".format(self.last, self.first)
def payroll(self,numweeks=1):
regularhours = min(40*numweeks,self.hours)
OThours = max(0,self.hours-regularhours)
regularpay = regularhours * self.payrate
OTpay = round(OThours * self.payrate * OVERTIME_RATE,2)
return {"reghours":regularhours,
"overtime":OThours,
"regpay":regularpay,
"OTpay":OTpay,
"total":regularpay + OTpay}
def sethoursworked(self,amt):
self.hours = amt
def display(employee):
payrollinfo = employee.payroll()
print("{:^30}".format("Payroll Information"))
print("{:>30}".format(employee.name))
print("Payrate:{:>22}".format(employee.payrate))
print("Hours:{:>24}".format(payrollinfo['reghours']))
print("Overtime Hours:{:>15}".format(payrollinfo['overtime']))
print("Regular Pay:{:>18}".format(payrollinfo['regpay']))
print("Overtime Pay:{:>17}".format(payrollinfo['OTpay']))
print("-"*30)
print("Total Pay:{:>20}".format(payrollinfo['total']))
Adam = Employee("Adam","Smith","D")
Adam.sethoursworked(51)
display(Adam)
OUTPUT:
Payroll Information
Adam D. Smith
Payrate: 7.25
Hours: 40
Overtime Hours: 11
Regular Pay: 290.00
Overtime Pay: 119.62
------------------------------
Total Pay: 409.62
You should not get in the habit of using global; it's usually a sign that you're heading in the wrong direction. Instead, pass the variables you need around explicitly, using function arguments and return statements. Also, don't pass functions arguments they don't need to do their job, and prefer default arguments or explicit constants to "magic numbers". For example:
def workhours(hours, threshold=40):
if hours > threshold:
overtime = hours - threshold
regtime = threshold
else:
overtime = 0
regtime = hours
return regtime, overtime
def paydistribution(payrate, regtime, overtime, otrate=1.5):
regpay = regtime * payrate
overpay = overtime * payrate * otrate
return regpay, overpay
Now main can call:
regtime, overtime = workhours(hours)
regpay, overpay = paydistribution(payrate, regtime, overtime)
display(hours, payrate, regpay, regtime, overtime)
This keeps the flow mostly in main while letting the other functions do just their specific bits of the task.
In your position, I would also consider having a separate function to take user input, which loops until they provide something acceptable. An appropriate definition, for example:
def user_input(prompt, min_, max_):
Here is another cleaned-up version:
from textwrap import dedent
import sys
if sys.hexversion < 0x3000000:
# Python 2.x
inp = raw_input
else:
# Python 3.x
inp = input
MIN_HOURS = 8.
MAX_HOURS = 86.
MIN_RATE = 7.
MAX_RATE = 50.
OVERTIME_CUTOFF = 40.
OVERTIME_BONUS = 0.5
def get_float(prompt, lo=None, hi=None):
while True:
try:
val = float(inp(prompt))
if lo is not None and val < lo:
print("Value must be >= {}".format(lo))
elif hi is not None and val > hi:
print("Value must be <= {}".format(hi))
else:
return val
except ValueError:
print("Please enter a number")
def main():
hours = get_float("How many hours did you work? ", MIN_HOURS, MAX_HOURS)
rate = get_float("What is the hourly payrate? ", MIN_RATE, MAX_RATE)
time = min(hours, OVERTIME_CUTOFF)
pay = time * rate
overtime = max(0., hours - OVERTIME_CUTOFF)
overpay = overtime * rate * (1. + OVERTIME_BONUS)
print(dedent("""
Payroll Information
Payrate : $ {rate:>7.2f}
Regular Hours : {time:>4.0f} h
Regular Pay : $ {pay:>7.2f}
Overtime Hours: {overtime:>4.0f} h
Overtime Pay : $ {overpay:>7.2f}
Total Pay : $ {total:>7.2f}
""").format(rate=rate, time=time, pay=pay, overtime=overtime, overpay=overpay, total=pay+overpay))
if __name__=="__main__":
main()
which runs like
How many hours did you work? 46
What is the hourly payrate? 11
Payroll Information
Payrate : $ 11.00
Regular Hours : 40 h
Regular Pay : $ 440.00
Overtime Hours: 6 h
Overtime Pay : $ 99.00
Total Pay : $ 539.00

Using a loop with counters

Here's my program. There are seven employees for which I am creating a paystub. I am trying to achieve a loop where it starts at num = 1 and go all the way through num = 7. When I run the program, however, nothing gets printed. Thoughts?
#initalize all variables
medPremiere = 400
fedRate = .20
stateRate = .05
FICA = .08
retirement = .06
**Tax rates and such**
#the processing module
num = 1
while num < 8:
if num ==1:
empNum = 1
empName = 'billybob'
hours = 40
rate = 50
num = num + 1
if num ==2:
empNum = 2
empName = 'superman'
hours = 55
rate = 40
num = num + 1
if num ==3:
empNum = 3
empName = 'hulk'
hours = 60
rate = 60
num = num + 1
if num ==4:
empNum = 4
empName = 'scoobie'
hours = 45
rate = 80
num = num + 1
if num ==5:
empNum = 5
empName = 'Sherry'
hours = 66
rate = 30
num = num + 1
if num ==6:
empNum = 6
empName = 'doctor'
hours = 88
rate = 90
num = num + 1
if num ==7:
empNum = 7
empName = 'ironman'
hours = 77
rate = 70
num = num + 1
These are 7 different employees for which I have to create paystubs for
#the calc module
#calculate gross pay
num ==1
while num < 8:
They get payed overtime and double overtime so I have to account for how many hours each employee has worked. Less than 41 hours they get payed regular, 41-60 hours they get paid overtime and more than 61 hours they get payed double overtime.
if hours <41:
gross = rate*hours
fedTax = gross*fedRate
stateTax = gross*stateRate
F = gross*FICA
K = gross*retirement
netPay = gross - fedTax - stateTax - F - K - medPremiere
print('Gross pay: ', gross)
print('Federal tax # 20%: ', fedTax)
print('State tax # 5%: ', stateTax)
print('FICA # 8%: ', F)
print('401K # 6%: ', K)
print('Net pay: $', netPay)
num = num + 1
Here I'm trying to make it go back to the list of numbers at the top and pull the information for the next employee.
if hours < 61:
gross = (40*hours) + (hours - 40)(1.5)(rate)
fedTax = gross*fedRate
stateTax = gross*stateRate
F = gross*FICA
K = gross*retirement
netPay = gross - fedTax - stateTax - F - K - medPremiere
print('Gross pay: ', gross)
print('Federal tax # 20%: ', fedTax)
print('State tax # 5%: ', stateTax)
print('FICA # 8%: ', F)
print('401K # 6%: ', K)
print('Net pay: $', netPay)
num = num + 1
if hours > 61:
gross = 40*hours + (hours-40)(1.5)(rate) + (hours - 60)(2)(rate)
fedTax = gross*fedRate
stateTax = gross*stateRate
F = gross*FICA
K = gross*retirement
netPay = gross - fedTax - stateTax - F - K - medPremiere
print('Gross pay: ', gross)
print('Federal tax # 20%: ', fedTax)
print('State tax # 5%: ', stateTax)
print('FICA # 8%: ', F)
print('401K # 6%: ', K)
print('Net pay: $', netPay)
num = num + 1
break
Is the calc module properly formatted, or is there a better way to go about this?
Above the line with while num < 8: you say num ==1. This instead should be num = 1, and should be put inline with the while statement like so:
num = 1
while num < 8:
That's why none of the print statements execute; because num is not being reset to be less than 8.
Also, a stylistic point that can help you avoid errors (and it does the dirty work of initializing and incrementing counter vars for you), you can do this:
for num in range(1,8):
...
print num
...
This code can't possibly work as intended. You go over the first loop 7 times, rebinding the same variables and doing nothing else. At the end of that, you've got employee 7's values. Then you go over the second loop 7 times, using employee 7's values each time. (Then, because your indentation is incorrect, you don't do anything for an employee with >= 41 hours, so you do nothing 7 times.)
This is a very awkward way to structure your program, and it will be a lot easier to fix it if you restructure it.
First, if you want to loop over all of the numbers in [1, 8), use a for loop:
for num in range(1, 8):
This removes a whole lot of lines of extra code where you could get things wrong—including the one you actually did get wrong.
Next, you need to actually do something for each employee. While you could move the first loop into a function and put a yield empNum, empName, hours, rate, num after each one, this is making things far more complicated than they need to be. What you want is a function that can be called with a number and just return the right values for that number. Then you don't need a loop here at all.
But that function is already written for you, if you use the right data structure: it's just indexing.
For example, if you replace the first loop with this:
employees = {}
employees[1] = dict(empNum = 1,
empName = 'billybob',
hours = 40,
rate = 50)
employees[2] = dict(empNum = 2,
# etc.
… then the second loop can just do this:
for employee in employees.values():
if employee['hours'] < 41:
gross = employee['rate'] * employee['hours']
fedTax = gross*fedRate
stateTax = gross*stateRate
F = gross*FICA
K = gross*retirement
netPay = gross - fedTax - stateTax - F - K - medPremiere
print('Gross pay: ', gross)
print('Federal tax # 20%: ', fedTax)
print('State tax # 5%: ', stateTax)
print('FICA # 8%: ', F)
print('401K # 6%: ', K)
print('Net pay: $', netPay)
if employee['hours'] < 61:
# ...
But note that you're not actually using the keys for anything, so you must as well just use a list instead of a dict. (That way you also guarantee that you always iterate the employees in the same order you create them.) For example:
employees = [
dict(empNum = 1,
empName = 'billybob',
hours = 40,
rate = 50),
dict(empNum = 2,
# etc.
And now, you don't need for employee in employees.values():, just for employee in employees:.
Meanwhile, the indentation problem wouldn't be possible if you used elif and else. In this code:
if employee['hours'] < 41:
gross = employee['rate'] * employee['hours']
# ... a bunch more code
if employee['hours'] < 61:
gross = employee['rate'] * employee['hours']
# ... a bunch more code
if employee['hours'] > 61:
gross = employee['rate'] * employee['hours']
… everything compiles and runs, but you can never get into the last block, because hours can't be less than 41 and also be more than 60. But in this code:
if employee['hours'] < 41:
gross = employee['rate'] * employee['hours']
# ... a bunch more code
elif employee['hours'] < 61:
gross = employee['rate'] * employee['hours']
# ... a bunch more code
elif employee['hours'] > 61:
gross = employee['rate'] * employee['hours']
You will get a SyntaxError if you get the indentation wrong, because there's no if at the same level as the elif, which is easier to debug.
Next, note that 61 is not less than 41, or less than 61, or greater than 61, so nothing will happen for anyone who works 61 hours. You could fix that by using >= 61 for the last check. Or, even more simply, just using else instead of elif.
Next, whenever you write the same line of code more than twice, you should look for a way to refactor it. Almost all of the details are identical between the three cases; only the first line is different. Besides being harder to read, repetitive code is also harder to get right, and harder to maintain. For example, at some point, you're going to have a bug, and fix it in one copy but not the other two.
Also, you can't multiply two numbers in Python by adjoining them; you need to use the * operator, like this:
gross = 40*hours + (hours - 40) * 1.5 * rate + (hours - 60) * 2 * rate
Finally, your equations are wrong. If someone works 50 hours, you're going to pay them 40 hours at $1/hour because you forgot to multiply the first term by rate, and then you're going to pay them an extra 150% for the next 15 hours instead of an extra 50%.
Putting it all together, replace the first loop with the list of dictionaries above, then replace the second loop with this:
for employee in employees:
gross = rate * hours
if hours > 40:
gross += rate * (hours - 40) * 0.5 * rate
if hours > 60:
gross += rate * (hours - 60) * 0.5 * rate
fedTax = gross*fedRate
stateTax = gross*stateRate
F = gross*FICA
K = gross*retirement
netPay = gross - fedTax - stateTax - F - K - medPremiere
print('Gross pay: ', gross)
print('Federal tax # 20%: ', fedTax)
print('State tax # 5%: ', stateTax)
print('FICA # 8%: ', F)
print('401K # 6%: ', K)
print('Net pay: $', netPay)
And that's your whole program.

Categories