[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