[Tutor] Organizing my code, should I use functions?

bob gailer bgailer at gmail.com
Wed Apr 22 17:47:00 CEST 2009


Eduardo Vieira wrote:
> Hello! I’m not a programmer 

Do you mean that you were not a programmer and are now becoming one?

> [snip] I wondered how would I save time avoiding repeating code, creating extra
> variables, etc. So, I simply decided to alter the code as little as
> possible and use the import statement. 
> It's working this way. Sounds
> wise? I thought if I converted it to a function or a class would make
> it more flexible, but my understanding of classes are too basic yet,
> and am not sure if it's worth using it.
> I have noticed that in lot's of python code example, people make
> functions out of everything. I'm still too much attached to
> procedural, not functional programming, if I understand the terms
> correctly. I would appreciate any suggestions.
>   

"functional programming" is a pretty specific concept. Using Python functions is not necessarily "functional programming". It is procedural.

IMHO there are reasons for writing functions:
1) modularity - break up a "long" program into relatively independent pieces.
2) factor out common code.
3) package the "main" program so 
  a) it can be conditionally called when the module is run and not when imported
  b) other function definitions can be written following the main program.

Applying 2) to your example I find the following code is duplicated except for variable names. I removed comments and whitespace to make it more readable (to me).

book = xlrd.open_workbook(thisyearFile) 
dayexcel = xlrd.xldate.xldate_from_date_tuple(thisDay, book.datemode)
sh = book.sheet_by_name(thismonth) 
firstCol = sh.col_values(0) 
tperday = firstCol.index('TOTAL Per Day') 
shipindex = tperday + 1 
for valores in sh.col_values(cols):
    if valores == dayexcel: 
        todaysList = sh.col_values(cols)
        totals = sh.row_values(shipindex, end_colx=cols + 1) 
        break
shippedToday = todaysList[shipindex]
totalShipments = sum([a for a in totals if type(a) == type(2.0)])

To convert to a function ask: 
- what are the inputs? 
- what are the outputs?

The input I see is the excel file name. 
The outputs I see are # shipped today and total # shipped.

That leads to a function:

def getShipmentInfo(xlfilename): # specify the input(s) here
    ###### --- Code to find the right cell with today's shipments
    book = xlrd.open_workbook(xlfilename)
    thisDay = time.gmtime()[:3]
    dayexcel = xlrd.xldate.xldate_from_date_tuple(thisDay, book.datemode)
    thismonth = time.strftime('%B', time.gmtime()) 
    sh = book.sheet_by_name(thismonth) 
    firstCol = sh.col_values(0) 
    tperday = firstCol.index('TOTAL Per Day') 
    shipindex = tperday + 1 
    for valores in sh.col_values(cols):
        if valores == dayexcel: 
            todaysList = sh.col_values(cols)
            totals = sh.row_values(shipindex, end_colx=cols + 1) 
            break
    shipped = todaysList[shipindex]
    total = sum([a for a in totals if type(a) == type(2.0)])
    return shipped, total # specify the output(s) here

Eliminate unused statements and whitespace.
Put the main program in a main function (reason 3) above)
The program now looks like:

## This script creates a report of shipments 
## comparing the numbers from the previous year with the current year.
import xlrd # Package to read Excel files 
import time 
import datetime 
def main():
    # Two excel files to process with shipping information
    thisyearFile = r'c:\Shipping Totals - 2009\Shipping Totals 2009 West.xls'
    prevyearFile = r'c:\Shipping Totals\Shipping Totals - 2008\ShippingTotals 2008 West.xls'
    shippedToday, totalShipments = getShipmentInfo(thisyearFile)
    shippedLastYear, OldTotalShipments = getShipmentInfo(prevyearFile)

    # Imports the information from the Eastern division. See code on the bottom
    .... rest of main program
def getShipmentInfo(xlfilename): # specify the input(s) here
    .... rest of function code from above
if __name__ == "__main__":
    main()

This is not the only way to use functions or improve things.

I leave dealing with the east data to someone else, but I think we can apply the same principles.

> Here is the code:
>
> ## This script creates a report of shipments ## comparing the numbers
> from the previous year with the current year.
>
> import xlrd # Package to read Excel files import os import glob import
> time import datetime import dbi import odbc
>
>
>
>
> thismonth = time.strftime('%B', time.gmtime()) # Get's a string with
> the name of the current month
>
> hoje = time.strftime("%a, %b %d, %Y", time.gmtime())
>
>
> # Two excel files to process with shipping information
>
> thisyearFile = r'c:\Shipping Totals - 2009\Shipping Totals 2009 West.xls'
> prevyearFile = r'c:\Shipping Totals\Shipping Totals - 2008\Shipping
> Totals 2008 West.xls'
>
>
>
> thisDay = time.gmtime()[:3]
> prevyear = datetime.datetime.today() - datetime.timedelta(days=365)
> aYearAgo = prevyear.timetuple()[:3]
>
> ###### --- Code to find the right cell with today's shipments
>
> book = xlrd.open_workbook(thisyearFile) # Opens excel file
>
> dayexcel = xlrd.xldate.xldate_from_date_tuple(thisDay, book.datemode)
> #Puts the date in the Excel format, like 3991.0
>
>
> sh = book.sheet_by_name(thismonth) # The sheet which has the name of
> the month: April, May, June, etc.
>
> firstCol = sh.col_values(0) # Retrieves the first column
>
> tperday = firstCol.index('TOTAL Per Day') # Finds the cell 'Total Per Day'
>
> shipindex = tperday + 1 # The next cell after 'TOTAL Per Day', which
> contains the info about shipments
>
> # Looks for the column whose header is today's date for cols in range(sh.ncols):
>    for valores in sh.col_values(cols):
>        if valores == dayexcel: # If it finds the column with today's date
>            todaysList = sh.col_values(cols)
>            totals = sh.row_values(shipindex, end_colx=cols + 1) # sum
> up to the current date
>            break
>
> # Crosses rows with column to find the right cell with the shipments
> of today shippedToday = todaysList[shipindex]
>
> totalShipments = sum([a for a in totals if type(a) == type(2.0)]) #
> Sums all shipments
>
>
> # Check previous year's shipments processing the file with last year's data
>
> booktwo = xlrd.open_workbook(prevyearFile)
>
> dayexcel = xlrd.xldate.xldate_from_date_tuple(aYearAgo, book.datemode)
>
> sh = booktwo.sheet_by_name(thismonth)
>
> firstCol = sh.col_values(0)
>
>
>
> tperday = firstCol.index('TOTAL Per Day')
>
> shipindex = tperday + 1
>
> for cols in range(sh.ncols):
>    for valores in sh.col_values(cols):
>        if valores == dayexcel:
>            lastyearsList = sh.col_values(cols)
>            totals = sh.row_values(shipindex, end_colx=cols + 1) # sum
> up to the current date
>            break
>
>
> shippedLastYear = lastyearsList[shipindex]
>
>
> OldTotalShipments = sum([a for a in totals if type(a) == type(2.0)])
>
>
> # Imports the information from the Eastern division. See code on the bottom
>
> import bizreportereast as bz
>
>
> report = """
>
>
> ===== Shipments Alberta Warehouse =====
>
> - Shipments today: %d
>
> - Shipments this month: %d
>
> - Shipments this day, last year: %d
>
> - Shipments this month, last year: %d
>
>
> ===== Shipments Ontario Warehouse =====
>
> - Shipments today: %d
>
> - Shipments this month: %d
>
> - Shipments this day, last year: %d
>
> - Shipments this month, last year: %d
>
>
> """ % (shippedToday, totalShipments, shippedLastYear,
> OldTotalShipments, bz.shippedToday, bz.totalShipments,
> bz.shippedLastYear, bz.OldTotalShipments)
>
> print report
>
> logfile = open('c:/myscripts/logbizreport.log', 'a')
>
>
> #### Code found in bizreportereast.py #### import xlrd import os
> import glob import time import datetime
>
>
> ###### --- Code to find the right cell with today's shipments
>
> thismonth = time.strftime('%B', time.gmtime())
>
> hoje = time.strftime("%a, %b %d, %Y", time.gmtime())
>
> thisyearFile = r'c:\MS Excel\Shipping Totals\Shipping Totals -
> 2009\Shipping Totals 2009 East.xls'
> prevyearFile = r'c:\MS Excel\Shipping Totals\Shipping Totals -
> 2008\Shipping Totals 2008 East.xls'
>
>
>
> thisDay = time.gmtime()[:3]
> prevyear = datetime.datetime.today() - datetime.timedelta(days=365)
> aYearAgo = prevyear.timetuple()[:3]
>
>
>
> book = xlrd.open_workbook(thisyearFile)
>
> dayexcel = xlrd.xldate.xldate_from_date_tuple(thisDay, book.datemode)
>
>
> sh = book.sheet_by_name(thismonth)
>
> firstCol = sh.col_values(0)
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
>
>   


-- 
Bob Gailer
Chapel Hill NC
919-636-4239


More information about the Tutor mailing list