On Tue, Feb 17, 2009 at 7:09 PM, Wayne Watson <sierra_mtnv...@sbcglobal.net>wrote:
I have a few notes, but first I just have to say: you're working very hard to implement an ordered dictionary, and you really, really don't need to. Python's (unordered) dictionaries work just fine for reading and writing configurations; you just need to rethink a little. Or, try ConfigObj, which reads and writes your config files exactly according to your specification with very little fuss and minimal wheel-reinvention. 'Nuff said. Ok, let's see how this works. I've defined this function and the > config_var_list. stop time is the last entry shown. It is part of the > constructor for mainloop, Sentinel_GUI. and loads sdict as shown. > def Set_ConfigDictionary(): > > *config_var_list* = (['config_file_name', ['Initial.sen', > STR]], > ['mask_file_name', ['xyz', STR]], > ... > ['stop_time', ['datetime.time(6, 0, 0)', DAT]], > ... > ) > # load sdict > *sdict* = {} > for j in range(0, len(config_var_list)): > # print "j: ", j, "str part: ", str(config_var_list[j][0]), > config_var_list[j][1] > sdict[str(config_var_list[j][0])] = > config_var_list[j][1][0] > ... > These two lines are unnecessary: *self.sdict = sdict* *self.config_var_list* = config_var_list You don't need to create and load "sdict" and "config_var_list" before assigning them to self - you could start out with *self.sdict* = {} and *self.config_var_list* = etc. and work from there. ... > sdict and config_var_list become global to Sentinel_GUI. The first index of > conf_var_list maintains order for sdict. That is, when I want to output the > config file, I use to to fetch from sdict what I need, which is a value and > the "user" type, i.e., STR, DAT, BOO, etc. > I don't understand the need for STR, DAT, BOO - if you're type-checking, you don't need to create your own types to do it, and if they're informational only, you could just give your variables descriptive names. Relax and learn to love Python's iterators. You don't need an index to step through the members of a list or tuple - Python is happy to give them to you one at a time and in order! Instead of: for j in range(0, len(config_var_list)): sdict[str(config_var_list[j][0])] = config_var_list[j][1][0] try this: for var in config_var_list: sdict[var[0]] = var[1][0] Also - config_var_list is a tuple of lists. (I'm guessing you intended to make it a list of lists - that's what the name indicates, after all - but putting it between "( )" makes it a tuple.) Myself, I'd make it either a list of dictionaries (preserves ordering), or a dictionary of dictionaries. Here's what I'm talking about - *config_var_list* = [{"name":"config_file_name", "value":"Initial.sen", "type": "STR"}, {"name":"mask_file_name", "value":"xyz", "type":"STR"}, ... {"name":"stop_time", "value":"datetime.time(6, 0, 0)", "type":"DAT"}, ... ] # load sdict *sdict* = {} for var in config_var_list: sdict[var["name"]] = var["value"] I just find it much, much easier to understand what's going on - with [0] and [1][0] I had to read the code four or five times to grok it. I haven't benchmarked the two approaches - it's possible that access by list indices is faster - but it's hard to overestimate the importance of clarity. Now in SaveConfigFile, I go merrily along thusly: > > ... > # SAVE CONFIG FILE > items = self.sdict.keys() > items.sort() > for (j, conf_entry) in enumerate(self.config_var_list): > varName = conf_entry[0] > varType = self.config_var_list[j][1][1] > # Note, date-time vars are in hh:mm:ss > varValue = eval('self.' + varName) > var_assignment = varName + "=" + str(varValue) <<--- Beep, > beep > config_file.write(var_assignment + "\n") > ... > Don't work so hard! You're using enumerate() to get both the index and the item - but you don't need to, and it's easier to use and to read if you don't. In other words, varType = self.config_var_list[j][1][1] could be shortened to varType = conf_entry[1][1] You already did that for varName - just take it the rest of the way. Next, that eval() - better this way: varValue = getattr(self, varName) There _are_ some valid use cases for eval() - but getting and setting attributes ain't it. So, taking just this section in isolation (assuming you don't implement any of my other suggestions) - for conf_entry in enumerate(self.config_var_list): varName = conf_entry[0] varType = conf_entry[1][1] varValue = getattr(self, varName) var_assignment = varName + "=" + str(varValue) + "\n" config_file.write(var_assignment) > "Beep, beep" shows the likely problem. > You haven't actually explained what the "problem" is, but I'm going to take a stab at it... datetime objects are not strings. They are - how shall I put this - datetime objects. You can't actually write them to a configuration file (you could pickle/shelve them, but that's a topic for another time) - you can only write a string representation to the file. When you want to read them back, you need to convert them back from a string into a datetime.time; this is called "round-tripping". The complementary function to strftime() is called strptime(): >>>tstTime = datetime.time(9,10,11) >>>outStr = tstTime.strftime("%H:%M:%S") # produces a string >>>print outStr '09:10:11' >>>inTime = datetime.datetime.strptime(outStr, "%H:%M:%S") # creates a datetime object from our string >>>print inTime 1900-01-01 09:10:11 # if no date is specified, datetime objects default to 1 Jan 1900 (on Windows XP, anyway) >>>print inTime.time() # just the time portion 09:10:11 > Here, I suspect that I should put out something like datetime.time(11, 20, > 10). The time being 11:00:10. Instead I chose, to put 11:00:10 in the file. > Please, please, please don't put "datetime.time(11, 20, 10)" in your config file. Apart from being hard on the eyes, it pretty much requires that you use eval() - a terrible, terrible idea. If somebody edits your config file by hand, and either intentionally or accidentally puts something funky in there, you want the worst possible consequence to be an error message, not disaster. You could store "(11,20,10)", but it's probably clearer to store the time in a human-readable format and convert it back with strptime() as above. Hope that helps... -- www.fsrtechnologies.com
_______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor