Comparing Dictionaries
Hello, I am new to Python, but not programming. I would like to start my Python career by developing programs according to the "best practices" of the industry. Right now, that appears to be unit tests, patterns, and source code control. So, I am trying to write a unit test for some code that reads a Windows style INI file and stores the section, key, and values in a dictionary (recipe originally found on ASPN, but heavily modified for my needs). -- class LoadIni(unittest.TestCase): knownDefault = { "database$dbms":"mysql", "database$name":"thelarch", "database$user":"nobody", "database$password":"special", "database$host":"127.0.0.1" } def testNoIniFilename(self): """A default configuration list should be returned.""" result = ini.load() # These next two print statement show the same key/value pairs, # but in a different order. #print knownDefault #print result self.assertEqual(result, self.knownDefault) # does not work --- In this case, I need to compare the returned dictionary (result) with the known default dictionary (knownDefault). This needs to be a comparison of the dictionary key/value pairs. If all of the key/value pairs are an exact match and no extra key/value pairs are in either dictionary then I consider the two dictionaries to be equivalent. In other words, I consider these two dictionaries to be equivalent: { 'dog' : 'bone', 'cat' : 'fever', 'mouse' : 'mickey' } { 'mouse' : 'mickey', 'dog' : 'bone', 'cat' : 'fever' } while these two are not: { 'dog' : 'bone', 'cat' : 'fever', 'mouse' : 'mickey' } { 'dog' : 'bone', 'cat' : 'fever', 'mouse' : 'michael' } Any suggestions on how to compare these via some assert statement? Am I even on the right track with the INI file storing results in a dictionary? When I found the code, it just "felt right". NOTE: The code works, I can load the INI file, programmatically change a few settings, save the results to a new INI file, and manually compare the resulting files. I get the expected results. It is the automation of this testing process that appears to be the stumbling block. adTHANKSvance, Kenneth Love -- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Kenneth Love | Oklahoma Tax Commission DP Programmer/Analyst | Information Technology (405) 522 - 5864 | http://www.tax.ok.gov/ -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -- http://mail.python.org/mailman/listinfo/python-list
Re: Comparing Dictionaries
At 09:55 PM 7/26/2007, Ben Finney wrote: >Kenneth Love <[EMAIL PROTECTED]> writes: > > > In other words, I consider these two dictionaries to be equivalent: > > > > { 'dog' : 'bone', 'cat' : 'fever', 'mouse' : 'mickey' } > > { 'mouse' : 'mickey', 'dog' : 'bone', 'cat' : 'fever' } > > > > while these two are not: > > > > { 'dog' : 'bone', 'cat' : 'fever', 'mouse' : 'mickey' } > > { 'dog' : 'bone', 'cat' : 'fever', 'mouse' : 'michael' } > > > > Any suggestions on how to compare these via some assert statement? > >Dictionaries already know how to compare themselves to each other. > > >>> {'dog': 'bone', 'cat': 'fever', 'mouse': 'mickey'} == {'mouse': > 'mickey', 'dog': 'bone', 'cat': 'fever'} > True > >>> {'dog': 'bone', 'cat': 'fever', 'mouse': 'mickey'} == {'mouse': > 'michael', 'dog': 'bone', 'cat': 'fever'} > False After verifying this myself, I double checked my code. It turns out, the changes I made to get rid of the "import string" from the original recipe were the problem. Leaving the parenthesis off lower() and strip() in the following code causes all sorts of problems: config["%s$%s" % (name, key.lower())] = cp.get(sec, key).strip() That should teach me not to change working code at the same time I am writing unit tests. Even so, I realize it won't be the last time I do something so silly. Yes, I know about TDD's "write the test first", but I'm not comfortable with the philosophy of these new fangled unit tests yet. Thanks for the help! Sincerely, Kenneth Love -- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Kenneth Love | Oklahoma Tax Commission DP Programmer/Analyst | Information Technology (405) 522 - 5864 | http://www.tax.ok.gov/ -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -- http://mail.python.org/mailman/listinfo/python-list
Re: Comparing Dictionaries
At 04:42 AM 7/27/2007, Ali wrote: >On Jul 26, 10:18 pm, Kenneth Love <[EMAIL PROTECTED]> wrote: > > Hello, > > > > I am new to Python, but not programming. I would like to start my > > Python career by developing programs according to the "best practices" > > of the industry. Right now, that appears to be unit tests, patterns, > > and source code control. > >I am not sure about "best", but one of my "favourite practices" is to >not re-write code that other people have written, and have released >under licenses that allow you to do anything with it. > > > So, I am trying to write a unit test for some code that reads a Windows > > style INI file and stores the section, key, and values in a dictionary > >So, in the standard library: >http://docs.python.org/lib/module-ConfigParser.html >And if you want a more involved approach: >http://www.voidspace.org.uk/python/configobj.html > >Ali The published recipe (based on ConfigParser) did not handle my INI files. I have periods in both the section names and the key names. The INI files contents were developed according to an internally defined process that other non-Python programs rely on. The published recipe *did not work* with this scenario. Believe me, not modifying 3rd-party code is something I prefer and already practice. The code has to work first. In case anyone is curious, here is a link to the original: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65334 I combined the load/save routines, slogged through the unfamiliar syntax, changed the section/key separator to '$', and started writing unit tests. Sincerely, Kenneth Love -- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Kenneth Love | Oklahoma Tax Commission DP Programmer/Analyst | Information Technology (405) 522 - 5864 | http://www.tax.ok.gov/ -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -- http://mail.python.org/mailman/listinfo/python-list
Fwd: Re: Comparing Dictionaries
>From: "Steven D'Aprano" <[EMAIL PROTECTED]> >Newsgroups: comp.lang.python >Subject: Re: Comparing Dictionaries >Date: Sat, 28 Jul 2007 10:21:14 +1000 >To: python-list@python.org > >On Fri, 27 Jul 2007 14:11:02 -0500, Kenneth Love wrote: > > > The published recipe (based on ConfigParser) did not handle my INI > > files. I have periods in both the section names and the key names. > > The INI files contents were developed according to an internally > > defined process that other non-Python programs rely on. The published > > recipe *did not work* with this scenario. > >I think you have made a mistake. ConfigParser as published certainly DOES >accept periods in section and option names. It just *works*. The recipe I'm using is based upon ConfigParser and creates a dictionary that is based on the contents of the INI file. The dictionary's key is based on the section name and the key name from the INI file. The two are concatenated with a separator. In the original recipe, the separator is a period. To use your example (deleted as an attempt at brevity), the dictionary would be: { "SECTION.FRED.option.wilma" : "45" } As originally written, the section name is now "SECTION" when you write the INI file back out. The key is "FRED.option.wilma". Here is the original recipe: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65334 My version replaces the period with a dollar sign giving: { "SECTION.FRED$option.wilma" : "45" } I also removed the "import string" and put both the load() and save() functions in a file with proper comments and the Python equivalent of Javadoc comments. >Even if the existing ConfigParser doesn't do what you want, the right way >to fix the problem is not to recreate the entire module from scratch, but >to subclass it: >[snip] In no way did I rewrite ConfigParser. I have a real job with time pressures and I'm not so arrogant as to think I could whip something up in an hour that would be anywhere close to correct. I see that I wasn't as clear as I thought I was in my original post as you are second person to think I was developing my own INI solution. All I wanted to know was "How do I compare two dictionaries to see if they are equal?". It turns out that this functionality is built-in and it is my own stupid fault that my unit test was failing (modifying working code and writing a unit test at the same time is a recipe for failure). Oh well. Next time I'll spend two hours trying to figure it out instead of one before I post. :-\ >-- >Steven. > >-- >http://mail.python.org/mailman/listinfo/python-list -- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Kenneth Love | Oklahoma Tax Commission DP Programmer/Analyst | Information Technology (405) 522 - 5864 | http://www.tax.ok.gov/ -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -- http://mail.python.org/mailman/listinfo/python-list
Re: Comparing Dictionaries
At 03:23 AM 7/28/2007, you wrote: >Hi Kenneth, being new to Python i wondered if you at least considered >Doctests as part of your testing solution. >Other languages don't have Doctest. > >- Paddy. Until I read your post, I had never even heard of Doctest. I will look into it. Here is the list of online sources I've found: http://www.ibiblio.org/obp/thinkCSpy/index.html http://www.diveintopython.org/toc/index.html http://aspn.activestate.com/ASPN/Cookbook/Python Here are the O'Reilly books I purchased from Barnes & Noble: Python in a Nutshell (2nd ed.) Python Cookbook (2nd ed.) Programming Python (3rd ed.) I am a slow reader. So, if Doctests are mentioned in any of the above, I haven't encountered it yet. Specifically, my information on unit testing comes from reading about half of this online chapter: http://www.diveintopython.org/unit_testing/index.html I will search on Google for more info on Doctest. Thanks! Sincerely, Kenneth Love -- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Kenneth Love | Oklahoma Tax Commission DP Programmer/Analyst | Information Technology (405) 522 - 5864 | http://www.tax.ok.gov/ -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -- http://mail.python.org/mailman/listinfo/python-list
Accessing docstrings at runtime?
How do I print the docstring for a class property? When I run the code below, I get the docstring for the string module and not the one I set for the property. - # NOTE: Found in Python docs defining built-in functions (such as # property()). FIXED: Bug in getx, setx, and delx where "__x" # was misreferenced as "_x". class C(object): def __init__(self): self.__x = None def getx(self): return self.__x def setx(self, value): self.__x = value def delx(self): del self.__x x = property(getx, setx, delx, "I'm the 'x' property.") if __name__ == "__main__" y = C() y.x = 'test' print y.x print y.x.__doc__ - I get the following output: - test str(object) -> string Return a nice string representation of the object. If the argument is a string, the return value is the same object. --------- What am I doing wrong? adTHANKSvance, Kenneth Love P.S. If I want a docstring and I do not want a delete function, do I just pass 'None' (minus quotes) for that parameter? -- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Kenneth Love | Oklahoma Tax Commission DP Programmer/Analyst | Information Technology (405) 522 - 5864 | http://www.tax.ok.gov/ -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -- http://mail.python.org/mailman/listinfo/python-list
Re: Accessing docstrings at runtime?
On 08/29/07, Chris Mellon <[EMAIL PROTECTED]> wrote: > On 8/29/07, Kenneth Love <[EMAIL PROTECTED]> wrote: >> How do I print the docstring for a class property? >> >> [[[ SNIP EXAMPLE ]]] >> >> What am I doing wrong? >> > > You're looking at an instance, not at the class. y.x is going through > the descriptor lookup and is returning the string, so the __doc__ is > the the __doc__ of the string object, as you see. > > If you want to look at the property directly, look it up in the class > object: > > C.x.__doc__ That worked. Thanks! Kenneth -- http://mail.python.org/mailman/listinfo/python-list
Overriding Logging Config FileHandler Filename
I have a Python logging config file that contains a RotatingFileHandler handler. In the args key, I have hard-coded the log filename. Everything works great. However, I find that I now need to override this filename at application runtime. Is there a good way to do this? Here is a bit of sample code that (hopefully) clarifies my question. --- log.ini - [loggers] keys=root,processor ; Lots more stuff here: handlers, formatters, and loggers... [handlers] keys=consoleHandler,fileHandler [handler_fileHandler] class=handlers.RotatingFileHandler level=DEBUG formatter=standard args=('D:\Projects\Python\src\log.log', 'a', 9, 10) -- mymain.py - import logging.config logging.config.fileConfig('log.ini') # TODO: Override log filename with new name (e.g. 'd:\\logs\\mymain.py.log') log = logging.getLogger('mymain') log.info('START: mymain.py') log.info('FINISH: mymain.py') -- adTHANKSvance, Kenneth Love -- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Kenneth Love | Oklahoma Tax Commission DP Programmer/Analyst | Information Technology (405) 522 - 5864 | http://www.tax.ok.gov/ -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -- http://mail.python.org/mailman/listinfo/python-list
Re: Overriding Logging Config FileHandler Filename
> On Sep 26, 1:07 am, "Vinay Sajip" <[EMAIL PROTECTED]> wrote: >> On Sep 25, 9:15 pm, "Kenneth Love" <[EMAIL PROTECTED]> wrote: >> I have a Pythonloggingconfig file that contains a RotatingFileHandler >> handler. In the args key, I have hard-coded the log filename. >> Everything >> works great. >> >> However, I find that I now need to override this filename at application >> runtime. Is there a good way to do this? >> > > Are you using the original file name mentioned in the config file at > all? Why and under what conditions do you need to switch? You could > easily do this programmatically - have two handlers and when you need > to, remove one from the logger and add the other. I see you are using > a rotating handler, which itself does rollover to new log files every > so often. > > Regards, > > Vinay Sajip Sorry for the delay in my response. This post is a little long. Just bear with me and remember... You did ask. :-) We want to move all of my logging, command line processing, and other generic application initialization to a module (or set of modules) that can be used in roughly 90% of our processing tasks. In other words, we are developing a framework that is highly tailored to our needs. We have most of what we need already done. Logging is one of the last steps to be completed because of this issue. One of the requirements for our processing is a log file name that is specific to each task. The format and behavior must be the same across all tasks. We determined that using a common logging configuration would be the most expedient way of implementing this. This method has the added benefit of being easily modifiable outside of code (when our needs change). The logging filename follows a specific behavior by "falling back" to a less desirable method when the current one fails. This determination is made ONLY at application initialization. In order of most to least desirable, below is a list of the desired behavior: 1) Retrieve a predetermined key that is stored in an INI file passed via the command line. The fully qualified path should be specified in the INI file, but it could be relative. 2) The name of the INI file passed via the command line with ".log" appended. Preferably stored in the same location as the INI file. The INI file will not be stored in the same location as the Python script. 3) The name of the original calling script with ".log" appeneded (from the example in my original post this would be "mymain.py.log"). Submodules do not override this name (e.g. "mymain.py" calls "mysub01.py" and the log filename used is still "mymain.py.log"). This log file would be stored in the same directory as the main script. 4) Use the default log name stored in the INI file. Again this should be the fully qualified path, but could be relative. 5) Raise an error (resulting in a message being sent to the console and via an e-mail). My (probably erroneous) speculation is that I can retrieve a handler specified in the INI file and dynamically change the filename argument to the desired value. So far, I have been unable to figure out how to do this. In summary, we need a way to override, at runtime, the filename stored in the logging configuration file. adTHANKSvance, Kenneth Love -- http://mail.python.org/mailman/listinfo/python-list