3

I'm writing a program that requires lots of Date lookups (Fiscal Year, Month, Week). To simplify the lookups I created a Dictionary where the Key is a date (used for the lookup) and the Value is a Class Object. I put the class def and the code to read the dates data (a .txt file) in separate file, not the main file. BTW, this is not a question about Date objects. The code is:

# filename: MYDATES
class cMyDates:
    def __init__(self, myList):
        self.Week_Start  = myList[1]
        self.Week_End    = myList[2]
        self.Week_Num    = myList[3]
        self.Month_Num   = myList[4]
        self.Month       = myList[5]
        self.Year        = myList[6]
        self.Day_Num     = myList[7]

d_Date = {} # <-- this is the dictionary of Class Objects
# open the file with all the Dates Data
myDateFile = "myDates.log"
f = open(myDateFile, "rb")
# parse the Data and add it to the Dictionary
for line in f:
    myList = line.replace(' ','').split(',')
    k = myList[0]
    val = cMarsDates(myList)
    d_Date[k] = val

The actual dates data, from the text file, are just long strings separated by a comma: (also these strings are reduced in size for clarity, as-is the class def init)

2012-12-30, 2012-12-30, 2013-01-05, 1, 12, Dec, 2012, 30, Sun
2012-12-31, 2012-12-30, 2013-01-05, 1, 12, Dec, 2012, 31, Mon

In my main program I import this data:

import MYDATES as myDate

From here I can access my dictionary object like this:

myDate.d_Date

Everything works fine. My question: Is there a way to store this data inside the python code somehow, instead of in a separate text file? The program will always require this same information and it will never change. It's like a glorified static variable. I figured if I could keep this inside a .pyc file then perhaps it would run faster. Ok, before you jump on me about 'faster' or the amount of time it takes to read the external data and create the dictionary... It doesn't take long (about 0.00999 sec on average, I benchmarked it). The question is just for my edification - in case I need to do something like this again, but on a much larger scale where the time "might" matter.

I thought of storing the dates data in an array (coming from VB thinking) or List (Python) and just feeding it to the dictionary object, but it seems as though you can only .append to a List instead of giving it a predetermined size. Then I thought about creating a dictionary, or dictionaries, but that just seemed overwhelming considering the amount of data I have and the fact I would have to read thru these dictionaries to create another dictionary of Class Objects. It didn't seem right.

Can anybody suggest a different way to populate my dictionary of class objects besides storing the data in a separate text file and reading thru it in the code?

twegner
  • 443
  • 1
  • 5
  • 21
  • You can have dictionary literals. If you print (or [pretty print](https://docs.python.org/2/library/pprint.html)) your dictionary, you should be able to embed it in your code as is. – Peter Wood Jan 10 '16 at 23:12

2 Answers2

2

You can have list literals:

values = [1, 2, 3, 4]

Also a dictionary literal:

d = {'2012-12-30': cMyDates(['2012-12-30', '2012-12-30', '2013-01-05', 1, 12, 'Dec', 2012, 30, 'Sun']),
     '2012-12-31': cMyDates(['2012-12-31', '2012-12-30', '2013-01-05', 1, 12, 'Dec', 2012, 31, 'Mon'])}

You probably want a proper constructor for your class instead of passing a list:

class cMyDates:
    def __init__(self, Week_Start, Week_End, Week_Num, Month_Num, Month, Year, Day_Num):
        self.Week_Start  = Week_Start
        self.Week_End    = Week_End
        self.Week_Num    = Week_Num
        self.Month_Num   = Month_Num
        self.Month       = Month
        self.Year        = Year
        self.Day_Num     = Day_Num

Then your literal can look like this, which is a lot nicer:

d = {'2012-12-30': cMyDates(Week_Start='2012-12-30',
                            Week_End='2013-01-05',
                            Week_Num=1,
                            Month_Num=12,
                            Month='Dec',
                            Year=2012,
                            Day=30,
                            Day_Num='Sun'),
     '2012-12-31': cMyDates(Week_Start='2012-12-31',
                            Week_End='2013-01-05',
                            Week_Num=1,
                            Month_Num=12,
                            Month='Dec',
                            Year=2012,
                            Day=31,
                            Day_Num='Mon'))}
Peter Wood
  • 23,859
  • 5
  • 60
  • 99
1

Sure - put the text in a longstring, denoted by starting with either ''' or """ and finishing with the same sequence on an empty line.

I use this mostly where I have some literal xml I want to parse, where xml is the original format so I don't want to parse-then-print-then-paste-into-python-file whenever it changes. Just doing a paste to replace the xml is much easier.

Longstring looks ike this:

dates='''2012-12-30, 2012-12-30, 2013-01-05, 1, 12, Dec, 2012, 30, Sun
2012-12-31, 2012-12-30, 2013-01-05, 1, 12, Dec, 2012, 31, Mon
'''

Obviously you will have to parse this out - if you use StringIO to open the string with a file-like interface, your parsing of it should be unchanged.

BTW if instead of doing a separate open, you use the with statement, closing the file is neatly handled, regardless of exceptions. BTW2, not sure why you are opening your text file "rb" - you should use "rt". Revised code looks like this:

with open(myDateFile, "rt") as f:
    # parse the Data and add it to the Dictionary
    for line in f:
        myList = line.replace(' ','').split(',')
        k = myList[0]
        val = cMarsDates(myList)
        d_Date[k] = val

or, I think this should work (untested, it's late):

import io.StringIO as StringIO
with StringIO.StringIO(dates) as f:
    # parse the Data and add it to the Dictionary
    for line in f:
        myList = line.replace(' ','').split(',')
        k = myList[0]
        val = cMarsDates(myList)
        d_Date[k] = val