[Tutor] Multi-Dimensional Dictionary that contains a 12 element list.

Paul Kraus pkraus at pelsupply.com
Fri Dec 30 17:59:29 CET 2005


> That is the approach Paul took originally (see the other fork of this
> thread). He is accumulating a sparse 3d matrix where the keys are year,
> field6 and month. (He hasn't said what field6 represents.) The problem
> is that he wants to print out counts corresponding to all the existing
> year and field6 values and every possible month value. To do this I
> think a two-level data structure is appropriate, such as the dict[
> (year, field6) ][month] approach you outlined.

Field6 is just an arbitrary field that represents some generic key. So for 
clarity lets say in this instance it represents a customer code.

so dict(2005,12130)[0..11]
would hold sales by month for customer number 12130 in 2005.

This problem has evolved since it started and I have created a class that lets 
me build rolling 24 month data structures.I need to create a bunch of reports 
that will be run monthly that will show a rolling 24 month total for 
different things. Sales by customer, sales by vendor, purchases by vendor.

So by making a class that on construction takes the current year and month it 
will build the structure I need. I then have a method that lets me fill the 
monthly buckets. All i do is pass it the arbitrary key (customercode) year, 
month, and amount and it will increment that bucket.

So now for all my reports all I have to write are little 5 or 6 line scripts 
that take a text file split the fields and format them before basing them off 
into my custom object. Very slick and this is my first python project. Its 
cluttered and messy but for about 1 hours worth of work on a brand new 
language I am impressed with the usability of this language.

Now I have to find a way to take the output at the end and pipe it out to an 
external Perl program that creates an excel spreadsheet ( no real clean easy 
way to do this in python but hey each tool has its usefullness). I wish I 
could hide this in the object though so that I could call a "dump" method 
that would then create the spreadsheet. I will have to play with this later. 

Current Script - Critique away! :)
=-=-=-=-=--=-=
#!/usr/bin/python
import string
import re

class Tbred_24Months:
    def __init__(self,currentyear,currentmonth): ### Takes Ending Year and 
Ending Month Inits List
        guide = []
        self.results = {}
        self.guide = {}
        self.end_month = currentmonth
        self.end_year  = currentyear
        self.start_month = currentmonth
        self.start_year = currentyear
        for count in range(24):
            guide.append((self.start_month,self.start_year))
            self.start_month -= 1
            if self.start_month < 1:
                self.start_month = 12
                self.start_year -= 1
        guide.reverse()
        count = 0
        for key in guide:
            self.guide[key[1],key[0]]=count
            count += 1
        self.sortedkeys = self.guide.keys()
        self.sortedkeys.sort()

    def insert(self,key,year,month,number):
        if self.guide.has_key((year,month)):
            if self.results.has_key(key):
                seq = self.guide[(year,month)]
                self.results[key][seq] += number
            else:
                self.results[key] = []
                for x in range(24):self.results[key].append(0)

def splitfields(record):
    fields = []
    datestring=''
    ### Regular Expr.
    re_negnum = re.compile('(\d?)\.(\d+)(-)')
    re_date   = re.compile('(\d\d)/(\d\d)/(\d\d)')
    for element in record.split('|'):
        element=element.strip() # remove leading/trailing whitespace
        ### Move Neg Sign from right to left of number
        negnum_match = re_negnum.search( element )
        if negnum_match: 
            if negnum_match.group(1):element = "%s%d.%02d" 
%(negnum_match.group(3),int(negnum_match.group(1)),int(negnum_match.group(2)))
            else:element = "%s0.%02d" 
%(negnum_match.group(3),int(negnum_match.group(2)))
        ### Format Date
        date_match = re_date.search(element)
        if date_match:
            (month,day,year) = 
(date_match.group(1),date_match.group(2),date_match.group(3))
            ### Convert 2 year date to 4 year
            if int(year) > 80:year = "19%02d" %int(year)
            else:year = "20%02d" %int(year)
            element = (year,month,day)
        if element == '.000': element = 0.00
        fields.append( element )
    return fields

            
### Build Vendor Sales 
sales = Tbred_24Months(2005,11)
vendorsales = open('vendorsales.txt','r')
for line in vendorsales:
    fields = splitfields( line )
    if len(fields) == 7:
        (vendor,otype,oreturn,discountable,discperc,amount,date) = fields
        amount = float(amount);discperc = float(discperc)
        #if discperc and discountable == 'Y': amount = amount - ( amount * 
(discperc/100) )
        if otype == 'C' or oreturn == 'Y':amount = amount * -1
        sales.insert(vendor,int(date[0]),int(date[1]),amount)
result = ''

for key in sales.results:
    sum = float(0)
    result = str(key)
    for amount in sales.results[key]:
        sum += amount
        result += "|" + str(amount)
    print str(key),sum
    #print result,sum


More information about the Tutor mailing list