For those of you who just want to see the code just hit the links.

OK, Real world problem I have a client who does business in the state of Texas. Texas requires that on a monthly basis my client send them a report on pre-printed forms as to the state taxes they have collected. In point of fact they not only have to collect state taxes, but city, county, and various other specialty taxes. Without going into a great deal of detail I collect this information at a detail level on an order by order bases and transfer this detail into a MySQL database. Then through various SQL queries create a summary table of the Texas State, City, County, etc taxes. Each record contains the name of the taxing body, an ID number of the taxing body, the total dollar amount of all sales for the month, the tax percent and tax amount. If you would like to see what this form looks like go to http://www.window.state.tx.us/taxinfo/taxforms/01-forms.html and select form no 01-116.

I wanted to produce this report using python and after some Googling figured Reportlab was the tool to use. After reading the documentation checking a few tutorials and a couple of false starts trying to use Platypus, I finally figured out the I would have to use the low-level functions of Canvas so I could have complete control of field placement on the forms that is what ‘drawString’ and its various incantations do. I played around with the Hello World example and added a second field to the example just to get a feel for how this worked. Figured out that the pagesize needed to be set to ‘letter’ for US and although units (measurements used for X and Y coordinate) could be set to inch or cm using the default point of 1/72 of inch or 72 point per inch gave me greater control especially for accurate vertical spacing.

For you newbie programmers and newbies to python, the code below is the very first draft of the program and is crap. Like you, although I have been programming for years I am new to python and I don’t automatically think in higher concepts of the language yet.

The program creates the following report;

Texas_Tax_Rpt.pdf

Now for the real job of programmer refactoring your code. I actually did this in 5 additional steps to be exact and will list each.

Step 1 was actually writing the first draft above.

Step 2 was to rename my functions to more appropriate names (vestiges of an old Cobol programmer), remove the line computations from the tax_detail function and to make the line computation more compact and non dependent on knowing the number of records in the file thus removing all of the page computation. Also I removed the page summary total from the tax_detail function and gave it its own function.

texas_tax_rpt2.py

Step 3, the only real changes here are I don’t really like using index numbers for obtaining field elements, on a file this small it is probably not that big a deal but when working with file with a larger number of column it can get unruly. In this version I just created my own column name and created a dictionary.

texas_tax_rpt3.py

Step 4 typing all those fields in using dictionary notation such as dict_rec[‘sale_amt’] is just to much strain on my little pinky so I created a class to create variable attributes such as tsr.sale_amt. It also improves code readablity.

texas_tax_rpt4.py

Step 5 next came the realization of why should I create a set of column names when I already have column names in the database so why not use them. So I shifted the col_name list under the SQL that fetched the data records and pulled the column names from the SQL table thus giving more consistance to the link between the MySQL table and report logic.

texas_tax_rpt5.py

Step 6 finally after reviewing the code I noticed that the code for printing the state tax total and the individual tax lines was really identical so I deleted the function for the state tax total and just used the tax detail code.

texas_tax_rpt6.py

Last thoughts for what it is worth, I thought about doing one more round turning the code into a more object oriented program but refrained because this is a very specific report and reuse of the report specifics is highly unlikely.