[Tutor] I have a small project I want to work on..
Erik Price
erikprice@mac.com
Tue Mar 4 08:01:16 2003
On Tuesday, March 4, 2003, at 03:33 AM, Darren Munsell wrote:
> Its for my work.=A0 I work in a school where we punch in and out on a=20=
> time card, however we are also required to=A0 write out a time sheet =
to=20
> go along with this. Since I'm no wizz at math, I want to make this=20
> time consuming adding hours and minutes from my time card into a=20
> simple program that's there when we need it.
> The only bad news is that my school probably will not allow the Python=20=
> program to sit on any of the computers (security reasons), so I was=20
> hoping that maybe I could embed it into a Html or have it as an=20
> excutable, all our mechines are Windows98, so there is no=20
> cross-operating system to worry about.
> I'm very new to python and I understand the basics. But what would you=20=
> suggest for me to get started ?
Well, I've been working on a somewhat similar utility for my own use. =20=
One night out of the week I wait tables at a restaurant and up till=20
lately I've been keeping all my income records in a spreadsheet, but=20
since I don't have any spreadsheet software on my main computer it=20
requires that I go to another computer just to enter in this data. =20
Plus, I honestly never really bothered to learn how to do any=20
calculations with spreadsheet software, so although I can see all the=20
income on the sheet, I'd far prefer to just whip up some code to=20
generate a report (such as avg tips per hour, avg income per month,=20
etc) in python.
It's really simple. I have created a Shift class which tracks the=20
start and end time, the pay rate, the amount of tips earned and the=20
amount of tips paid out to the bartenders. The time is stored as a=20
Unix timestamp (seconds since 1970-01-01) for ease of calculation. =20
This class sits in its own file, shift.py, and is imported by the main=20=
script, TipTracker.py. I've copied the very basic parts of what I have=20=
into this email so you can see how I went about it for ideas (I removed=20=
the tip parts since it doesn't sound like you need this, and it is=20
actually pretty long with all the tip calculations). My favorite parts=20=
are the functions that get user input -- they are recursive, so if the=20=
user enters invalid data, an exception is raised and then immediately=20
caught, calling the function again so that the entire script doesn't=20
have to be re-executed.
It's not done yet -- specifically, I haven't yet written the=20
persistence part, where I write the user input (my input) to a file=20
that is read on successive uses of the program to build up a list of=20
Shift instances which can then be reported against. And I haven't=20
written the report-generating (output-generating) part either. (I just=20=
started this the other day.) But hopefully this will get you started.
#!/usr/bin/python
# shift.py -- a file containing just the Shift class:
# Class to represent a Shift worked by an Employee
class Shift:
"Represents a Shift worked by an Employee"
# static class vars
pay_rates =3D {} # cents per hour
pay_rates['bar'] =3D 235
pay_rates['server'] =3D 235
pay_rates['host'] =3D 800
pay_rates['bus'] =3D 0
def __init__(self, shift_type, shift_start, shift_stop):
if not Shift.pay_rates.has_key(shift_type):
raise KeyError
if shift_start > shift_stop:
raise ValueError
self.shift_type =3D shift_type
self.shift_start =3D shift_start
self.shift_stop =3D shift_stop
def hours_worked(self):
'Returns the duration of the shift in hours.'
totalseconds =3D self.shift_stop - self.shift_start
return totalseconds / 3600
def wages(self):
'Returns the wages earned in the shift before taxes.'
return float(self.hours_worked() *
Shift.pay_rates[self.shift_type]) / 100
#!/usr/bin/python
# TipTracker.py - a file containing the actual executed script
# Driver script for TipTracker
import sys
import time
from shift import Shift
def fetch_shift_types():
'create a list of the different shift types'
output =3D ''
keys =3D Shift.pay_rates.keys()
num_key =3D 0
for key in keys:
num_key +=3D 1
output +=3D key
if num_key < len(keys): output +=3D ', '
else: output +=3D ''
return output
def timestr_to_timestamp(timestr):
'parse a time string entered by the user to a timestamp number'
format =3D '%Y-%m-%d %H:%M'
return time.strptime(timestr, format)
def shift_type_input():
'get user input for type of shift'
shift_type =3D raw_input('Shift type (%s): ' % fetch_shift_types())
if not Shift.pay_rates.has_key(shift_type):
print 'Invalid shift type "' + shift_type + '"'
shift_type =3D shift_type_input()
return shift_type
def shift_start_input():
'get user input for start of shift'
tstart =3D raw_input('Start time (YYYY-MM-DD HH:MM): ')
try:
start =3D timestr_to_timestamp(tstart)
except ValueError:
print 'Invalid start time "' + tstart + '"'
start =3D shift_start_input()
return time.mktime(start)
def shift_stop_input():
'get user input for end of shift'
tstop =3D raw_input('Stop time (YYYY-MM-DD HH:MM): ')
try:
stop =3D timestr_to_timestamp(tstop)
except ValueError:
print 'Invalid end time "' + tstop + '"'
stop =3D shift_stop_input()
return time.mktime(stop)
def main():
'Get user input, process, echo, and write to file'
# user input
shift_type =3D shift_type_input()
shift_start =3D shift_start_input()
shift_stop =3D shift_stop_input()
# catch invalid data early
while (shift_start > shift_stop):
print 'Shift start time must precede shift end time'
shift_start =3D shift_start_input()
shift_stop =3D shift_stop_input()
try:
usershift =3D Shift(shift_type, shift_start, shift_stop)
except KeyError:
print 'Invalid shift type "' + shift_type + '"'
sys.exit(0)
except ValueError:
print 'Shift start time must precede shift end time'
sys.exit(0)
# echo
print "Hours worked: " + str(usershift.hours_worked())
print "Wages: " + str(usershift.wages())
# write to file
# not done yet
if __name__ =3D=3D '__main__':
try:
main()
except EOFError: # exit script if user hits Ctrl-D
print '\n'
sys.exit(0)
--=20
Erik Price
email: erikprice@mac.com
jabber: erikprice@jabber.org