""" This is problem 7.7 on page 229 of Zelle's 'Python Programming...' text, namely : Write a program that accepts starting time and ending time in hours and minutes, and calculates the resulting bill. The rate is $2.50/hr until 9:00pm and $1.75/hr after that. What I've done here is overkill, but it does show the level of detail you may need to conver all the contingencies. Note the use of functions to accomplish specific smaller tasks, such as turning "7:30pm" into 19.0 (24 hour clock). $ python babysit.py -- problem 7.7 on page 229 -- Starting time? [7:00pm] 7:30pm Ending time? [10:00pm] 1:00am The bill is $10.75. Jim M | Oct 2013 | MIT License """ def time2hrmin(time_string): """Convert a string like '7:23pm' to an (hour, min) tuple using a 24-hour clock. >>> time2hrmin('7:23pm') (19, 23) >>> time2hrmin('11:01am') (11, 1) >>> time2hrmin('12:03pm') (12, 3) >>> time2hrmin('1:43') (13, 43) >>> time2hrmin('4 pm') (16, 0) """ if time_string.endswith('am'): time_string = time_string[0:-2] afternoon = False elif time_string.endswith('pm'): time_string = time_string[0:-2] afternoon = True else: # assume pm if am or pm isn't given. afternoon = True hour, minutes = 0, 0 times = time_string.split(':') if len(times) == 1: hour = eval(times[0]) elif len(times) == 2: hour = eval(times[0]) minutes = eval(times[1]) if (hour == 12 and not afternoon): hour = 0 elif (hour != 12 and afternoon): hour = hour + 12 return (hour, minutes) def hrmin2hour(hour_minutes): """Convert (hour, minutes) to fractional hours. >>> hrmin2hour((14, 30)) 14.5 """ return hour_minutes[0] + hour_minutes[1]/60.0 def get_user_time(prompt=" What is the time?", default="5:00pm"): """Prompt user for a time, and return (hour, minutes).""" prompt_string = prompt + " [" + str(default) + "] " while True: try: response = raw_input(prompt_string) except: print "\nBye..." import sys sys.exit(0) if not response: response = default try: answer = time2hrmin(response) return answer except: print "OOPS: that didn't look like a time; please try again." def calculate_bill(start, end): """Return money owed (bill) given the times 'start' and 'end', both in fractional hours on 24-hour clock. >>> calculate_bill(19.5, 20.5) # 7:30pm to 8:30pm 2.5 >>> calculate_bill(22.25, 23.25) # 10:15pm to 11:15pm 1.75 >>> calculate_bill(20.0, 21.0) # 8pm to 9pm 2.5 >>> calculate_bill(21.0, 22.0) # 9pm to 10pm 1.75 >>> calculate_bill(20.0, 22.0) # 8pm to 10pm 4.25 >>> calculate_bill(19.5, 1.0) # 7:30pm to 1am = 1.5*2.50 + 4*1.75 = 10.75 10.75 """ before_rate = 2.50 # in $, before 9pm after_rate = 1.75 # in $, after 9pm nine_pm = 21.00 # 9pm on a 24-hour clock midnight = 24.00 if start > end: # times wrap past midnight ? return calculate_bill(start, midnight) + end * after_rate else: if start < nine_pm and end <= nine_pm: return before_rate * (end - start) elif start < nine_pm and end > nine_pm: return before_rate * (nine_pm - start) + after_rate * (end - nine_pm) else: return after_rate * (end - start) def main(): print "-- problem 7.7 on page 229 --" start = get_user_time(" Starting time?", "7:00pm") # e.g. start = (19, 0) end = get_user_time(" Ending time?", "10:00pm") bill = calculate_bill(hrmin2hour(start), hrmin2hour(end)) print " The bill is ${:.2f}.".format(bill) if __name__ == "__main__": import doctest doctest.testmod() main()