Recent TweetsMy XBox Live Gamer Card |
Friday, October 17. 2008RadioChoice: Update
I have made some minor changes to RadioChoice.py, my widget that allows the creation of wx.Choice objects that function in groups like wx.RadioButtons.
It has been somewhat PEP 08'ified. Though the CamelCase of wxPython seems to always result in a few compromises. In general I try to make "public" methods CamelCase and "private" methods match PEP-08. As you can see I'm also torn on the subject of module names. I initially renamed the module "radiochoice", but from an aesthetic standpoint I hated the way it looked. You may eventually see the module name change though. Monday, September 22. 2008RadioChoice: Update
As I have been working to divorce my GUI from my model while building Rollem, I came upon a situation where I couldn't fully instantiate my RadioChoice widgets, and had to update the list of available choices after creating the widgets.
In it's original incarnation that was an impossible task. So I added a ResetItems() method which takes a new list of choices and replaces the original list. It can be called on any widget in the group and will replace the choice list across all widgets in the group. The new choice list must follow all the rules of the original choice list (i.e., have a "NULL" choice at the beginning of the list). Here is some sample code showing how it all works:
After seeing how Wizards of the Coast handle the problem I was solving for in their online app, I am more convinced than ever that I took the correct route. RadioChoice.py Wednesday, August 27. 2008Unit Testing with py.test and wx.lib.pubsubI'm a freak about unit tests. In fact I often enjoy writing the tests more than I enjoy writing the actual production code. Seven years ago when first learning about unit tests in my day job (coding in perl with a home grown test framework). I decided to experiment with them in python. Starting with the built in unit test framework, I quickly found that I didn't like it. It didn't work the way I thought it should work and for me, made testing more difficult than it should be. I went in search of something that worked more like I do. That search led to Codespeak's py.test. It works the way I do, no setup required, no test frameworks required, no big fixtures to build up or tear down. Write a test... In the file test_my_module.py
In the file my_module.py
I can now run py.testand it will find my test and run it for me reporting any errors. As I started using PubSub, I ran into some new test issues for me, just how do you effectively test that messages were being sent or received when you believed they should be. I tinkered with it for a while, and eventually came up with the following template for my tests...
This test method is part of a test class that handles all the setup and teardown functionality, setting the initial state for each one of the test methods in the class. One question you might ask about the above is why do I assert that attribute set on line 10 has the correct value on line 11. I do it because MsgObject doesn't just set the attribute, it does other things and since it does other things, it is quite likely that at some point in my code's life I will accidentally delete the line that actually sets the attribute, and I'd like to have my tests fail if I do so. Automatically Generating wx.lib.pubsub Messages When an Attribute is Set
I like to think I write reasonably good code. I think everyone likes to think that they write good code. Of course I've always thought I wrote good code and I look at some of the stuff I wrote several years ago and cringe. Sometimes that happens when I look at code I wrote a month or so ago. Such is the case for me and GUI code I wrote prior to my learning about PubSub.
I had my View in one module and my Model in another (not quite sure where that pesky Controller got to). Yet my code had the two inextricably linked. Everyone one of my main GUI classes had references to the two main objects in the Model. Every one of those classes called methods directly on the Model and while it worked, it was becoming very difficult to maintain. Then there was a discussion about this very subject on the wxPython mailing list and I heard about PubSub for the first time (thanks Chris!). I started messing around with it and had the View communicating with the Model in no time. The problem was the Model wasn't communicating back. Then there was another discussion on the mailing list and someone (thanks Josiah!) said doing a tiny bit of meta-programming to make an object automatically send a message when one of its attributes was set would make message passing even easier. I thought that was a wonderful idea and came up with the following class to help me do that.
All my classes that have attributes that need to be reflected in the View inherit from MsgObject and then the View simply subscribes to the topic '<classname>.update.<attribute_name>', and update themselves. RadioChoice a wx.Choice Widget that Behaves Similarly to a RadioButton
I decided to write my own Dungeons & Dragons character generator when the ones I found either looked clunky, or didn't run on OSX, or lacked functionality I believed was required in such a tool. Since I had a bit of experience with wxPython creating my Conway's Life toy, I decided to try it on a larger toy.
If you're not familiar with character creation for D & D one of the earliest steps is to generate your character's ability scores. There are six scores with a theoretical range of 3 to 18 (think of rolling four dice, discarding the lowest number and summing the points shown on the remaining three). Those scores are then assigned to your character's abilities of Strength, Dexterity, Constitution, Intelligence, Wisdom and Charisma. The problem I faced is that you can pick and choose which ability goes with which score and how do you present this in a usable and attractive UI? I had seen some interfaces using Radio Buttons, but they were bulky and cumbersome, so I decided to use the wx.Choice widget. The problem was that you could not disable an item in item list for a choice, and a user can only select each ability one time so what to do. My solution to that problem is the RadioChoice widget. It allows you to create a group of wx.Choice widgets, each one starting with the same available choices, but when you make a choice on one of the widgets, that choice is removed from all of the other widgets. This is my first "useful" widget. Who knows, it may only be useful for matching D&D abilities to scores, but then again you might find some other use for it. The code and demo are available here... RadioChoice.py Constructive criticism is always welcome. Sunday, August 24. 2008Conway's Life
I touched my first computer on the end of a 300 baud acoustic coupled modem at Benson Polytechnic High School in 1977. I wrote horrible code in horrible BASIC, but it was when my love of programming began. In 1982 I was a CS major at Oregon State University. I spent far too much time goofing off and far too little time studying and the CS department gave me a very polite invitation to not be a CS major any longer. My father was an itinerant Preacher, and in the winter of 1982 he was planning trip around the world to minister in various and sundry places for about six months. My parents asked if I would tag along. I did.
On that trip I read about Conway's cellular automaton simulation and was fascinated by it. It just so happened that at one of our stops in the UK there was a computer available to me (I can't remember what it was, but it did have a BASIC interpreter) and it was there that I first attempted to write my own version of life. It was not good, not very functional, but I did move my skills at writing code forward just a bit. Several months ago, I decided I wanted to do a bit of GUI programming. I'd tinkered with PyQt, but it's support on Apple didn't "feel" as good as wxPython's support on Apple, so I started teaching myself wxPython. My first project was Conway's Life. The code is not brilliant, it is somewhat slow if the grid gets too large, but it does work, and it was a very good educational experience for me. Are there better ways to do it? I'm sure there are. I'd love to hear that feedback. life.py rudimentary unit tests for life.py (using py.test)
(Page 1 of 1, totaling 6 entries)
|
QuicksearchTagsapple applestore blackberry books civics concert d&d dvd editors faith family fanboy firefly food food grilling and recipes friends gti halo hobbies honorharrington humour hyperlinq iPod ipr law linux motorcycles movies music onmyipod oop os/x pets politics priceless programming pubsub python rant recipes religion review riding ridinggear salad society sports support technology travel unittest video games widget writing wxpython xbox360
Syndicate This BlogStatisticsLast entry: 2010-03-04 12:39
166 entries written
12 comments have been made
|
