<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:georss="http://www.georss.org/georss" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><id>tag:blogger.com,1999:blog-18697241</id><updated>2009-06-30T18:32:36.608-07:00</updated><title type="text">Darrell Hawley: Home Page</title><subtitle type="html" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/default.html" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default?start-index=26&amp;max-results=25" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.darrellhawley.com/atom.xml" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>92</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/darrellhawley" type="application/atom+xml" /><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><entry><id>tag:blogger.com,1999:blog-18697241.post-7690627568813053910</id><published>2009-06-28T09:01:00.001-07:00</published><updated>2009-06-30T18:32:36.613-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title type="text">Note to Self 10 – JQuery Selectors and Custom Functions and a thought on JQuery</title><content type="html">&lt;p&gt;After using &lt;a href="http://www.python.org"&gt;Python&lt;/a&gt;, diving into &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; has proven exceptionally difficult. Even though it solves the not-so-small problem of commonizing the DOM across multiple browsers, I find it very difficult to read. I know with time I’ll get used to it and maybe even find some beauty in my jQuery code, but it will never stop me from wishing for a cleaner syntax like that of Python or &lt;a href="http://www.ruby-lang.org/en/"&gt;Ruby&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;With that said, here’s a bit of what I learned about jQuery recently.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Selectors in jQuery are a syntax for selecting an html element. Selectors can return a single element or several (or none if nothing matching is found). &lt;/li&gt;    &lt;li&gt;$(“#[elementID]”) – finds an element with an &lt;em&gt;id&lt;/em&gt; attribute equal to “elementID”. &lt;/li&gt;    &lt;li&gt;$(“[name=’elementName’]”) – gets all elements with a &lt;em&gt;name&lt;/em&gt; attribute equal to “&lt;em&gt;elementName”&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;$(“[name^=’element’]”) – gets all elements with a &lt;em&gt;name&lt;/em&gt; attribute that begins with “&lt;em&gt;element”&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;$(“[name$=’Name’]”) – gets all elements with a &lt;em&gt;name&lt;/em&gt; attribute that ends with “&lt;em&gt;Name”&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;$(“input:checkbox”) – gets all checkboxes &lt;/li&gt;    &lt;li&gt;$(“#blah &amp;gt; input:checkbox”) – gets all checkboxes within a parent element of id &lt;em&gt;“blah”&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;Creating a custom function in jQuery: &lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strike&gt;$.fn.CustomFunctionName({function()({        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; //code here         &lt;br /&gt;})&lt;/strike&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#ff0000"&gt;$.fn.exclaim = function(message){       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; alert(message)        &lt;br /&gt;}        &lt;br /&gt;$.fn.exclaim(&amp;quot;hello, world&amp;quot;)&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-7690627568813053910?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/7690627568813053910/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=7690627568813053910" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/7690627568813053910" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/7690627568813053910" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2009/06/note-to-self-10-jquery-selectors-and_28.html" title="Note to Self 10 – JQuery Selectors and Custom Functions and a thought on JQuery" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-4175159309556728108</id><published>2009-05-29T07:05:00.001-07:00</published><updated>2009-05-29T07:05:29.665-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="SharpDevelop" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="IronPython" /><title type="text">Note to Self 9 – Exploring SharpDevelop and Going off Topic</title><content type="html">&lt;p&gt;It’s been too long since I last blogged which typically means I have too many competing ideas to settle on just one. So welcome to Note to Self 9!&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://icsharpcode.net/OpenSource/SD/Default.aspx"&gt;SharpDevelop&lt;/a&gt; is an open source IDE for the .NET platform. Is it new? Hardly. Based on the &lt;a href="http://icsharpcode.net/OpenSource/SD/NewsHistory.aspx"&gt;history of news releases&lt;/a&gt; from their website, It’s been around since December of 2000. Considering that the .NET platform was publicly announced only 6 months earlier, SharpDevelop seems only that much more mature.&lt;/li&gt;    &lt;li&gt;If you’re comfortable with the basics of Visual Studio, SharpDevelop should feel like home to you. In fact, the best way to describe SharpDevelop is “Visual Studio without a lot of stuff I don’t want and a few thid-party items I do”.&lt;/li&gt;    &lt;li&gt;SharpDevelop uses NUnit instead of MSTest. That’s right. No third party plugins to make your IDE work with NUnit. It simply works.&lt;/li&gt;    &lt;li&gt;It’s time for me to confess. It’s all about IronPython. The reason I started investigating SharpDevelop is because of my frustration with Visual Studio’s lack of support for the language. Specifically, I want Intellisense when I write IronPython. To be sure, you only get Intellisense for “non-DLR code”, but surprisingly that doesn’t seem to be as much of a handicap as you might think.&lt;/li&gt;    &lt;li&gt;Speaking of first class citizens, SharpDevelop comes stock with C#, Visual Basic, Boo (I can hear Jay Wren cheering now), IronPython and F# (now a number of SRT folks are cheering).&lt;/li&gt;    &lt;li&gt;If you’re frightened of the consequences that may come from changing your development environment, don’t be. You can open one of your existing Visual Studio solutions with SharpDevelop and start coding. Switching back is as simple as opening up your now modified project/solution in Visual Studio.&lt;/li&gt;    &lt;li&gt;For clarity, SharpDevelop is new to me. I haven’t used SharpDevelop for any projects yet so I can’t tell you about any of its nuances. I plan on putting it to the test, however, over the next several weeks. I’ll be posting about my experiences.&lt;/li&gt;    &lt;li&gt;Now for the off-topic part. I’ve been listening to &lt;a href="http://thehistoryofrome.typepad.com/"&gt;The History of Rome&lt;/a&gt;, a FANTASTIC podcast series on, well, the history of Rome. Mike Duncan, creator and narrator, is not only an engaging story teller, but also has the technical savvy to put together a professional podcast. Though it’s not the sort of podcast typically on a geek’s menu, I think there are enough parallels to some of the challenges we are facing in the software industry to make it worthwhile.&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-4175159309556728108?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/4175159309556728108/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=4175159309556728108" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/4175159309556728108" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/4175159309556728108" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2009/05/note-to-self-9-exploring-sharpdevelop.html" title="Note to Self 9 – Exploring SharpDevelop and Going off Topic" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-5933719459525401431</id><published>2009-04-07T20:00:00.001-07:00</published><updated>2009-04-07T20:00:35.184-07:00</updated><title type="text">Anatomy of an IronPython Application at AADND</title><content type="html">&lt;p&gt;I'm going to be talking IronPython at the &lt;a href="http://www.aadnd.org" target="_blank"&gt;Ann Arbor .NET Developers Group&lt;/a&gt; at &lt;a href="http://srtsolutions.com/" target="_blank"&gt;SRT Solutions&lt;/a&gt; tomorrow night (April 8) at 6:00. I'll be showing you how you might introduce IronPython into your existing .NET environment through a lot of sample code and very few PowerPoint slides. I hope to see you there.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Anatomy of an IronPython Application&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;You've heard about IronPython and maybe have even taken the time to write the obligatory &amp;quot;Hello, World&amp;quot; application. Now what? The buzz around IronPython continues but there's still little guidance on tools and development processes.&amp;#160; This presentation focuses on the basics of interacting with C# and VB.NET libraries using IronPython while introducing useful tools and techniques to get you started. Though experience with .NET is necessary, the samples and discussions are understandable to even beginning Python developers.&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-5933719459525401431?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/5933719459525401431/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=5933719459525401431" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/5933719459525401431" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/5933719459525401431" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2009/04/anatomy-of-ironpython-application-at.html" title="Anatomy of an IronPython Application at AADND" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-8027568377207805970</id><published>2009-03-15T06:19:00.001-07:00</published><updated>2009-03-15T06:19:18.921-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="IronPython" /><category scheme="http://www.blogger.com/atom/ns#" term="WCF" /><title type="text">Writing an IronPython WCF Host</title><content type="html">&lt;p&gt;This is a simple WCF host written in IronPython that consumes a library I wrote in C#.&lt;/p&gt;  &lt;p&gt;import clr   &lt;br /&gt;clr.AddReferenceByPartialName(&amp;quot;System.ServiceModel&amp;quot;)    &lt;br /&gt;clr.AddReferenceByPartialName(&amp;quot;CSharpClass&amp;quot;) &lt;/p&gt;  &lt;p&gt;from System.ServiceModel import ServiceHost, BasicHttpBinding   &lt;br /&gt;from System.ServiceModel.Description import ServiceMetadataBehavior    &lt;br /&gt;from CSharpClass import PersonService, IPersonService    &lt;br /&gt;from System import Array, Uri &lt;/p&gt;  &lt;p&gt;uri = Uri(&amp;quot;&lt;a href="http://localhost:1234/people")"&gt;http://localhost:1234/people&amp;quot;)&lt;/a&gt;    &lt;br /&gt;uriArray = Array[Uri]([uri]) # creates a generic array of type Uri    &lt;br /&gt;serviceHost = ServiceHost(PersonService, uriArray) &lt;/p&gt;  &lt;p&gt;binding = BasicHttpBinding() &lt;/p&gt;  &lt;p&gt;serviceHost.AddServiceEndpoint(IPersonService, binding, &amp;quot;&lt;a href="http://localhost:1234/people")"&gt;http://localhost:1234/people&amp;quot;)&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;behavior = ServiceMetadataBehavior()   &lt;br /&gt;behavior.HttpGetEnabled = True    &lt;br /&gt;serviceHost.Description.Behaviors.Add(behavior) &lt;/p&gt;  &lt;p&gt;serviceHost.Open() &lt;/p&gt;  &lt;p&gt;raw_input(&amp;quot;Service has been started. Press Enter to exit...&amp;quot;)&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-8027568377207805970?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/8027568377207805970/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=8027568377207805970" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/8027568377207805970" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/8027568377207805970" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2009/03/writing-ironpython-wcf-host.html" title="Writing an IronPython WCF Host" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-8265670058660956714</id><published>2009-03-06T11:28:00.001-08:00</published><updated>2009-03-06T11:29:25.131-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><category scheme="http://www.blogger.com/atom/ns#" term="IronPython" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><title type="text">Running nose with IronPython</title><content type="html">&lt;p&gt;I just spent the past week at the 2009 Microsoft MVP Summit where I got a chance to talk to the some of the crew behind the dynamic languages at Microsoft. When I mentioned that I had gotten nose, a Python unit testing framework, working with IronPython, I was strongly encouraged to blog about it. Without further adieu, here's my code.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;import sys      &lt;br /&gt;sys.path.append(r&amp;quot;C:\Python25\Lib\site-packages\nose-0.10.4-py2.5.egg&amp;quot;)       &lt;br /&gt;sys.path.append(r&amp;quot;C:\python25\lib&amp;quot;)       &lt;br /&gt;sys.path.append(r&amp;quot;C:\Python25\Lib\email&amp;quot;)       &lt;br /&gt;sys.path.append(r&amp;quot;C:\Python25\Scripts&amp;quot;)       &lt;br /&gt;import nose       &lt;br /&gt;nose.main()&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I dropped this script into a directory with a couple of bogus unit tests and ran it with Python 2.5.4. Results were consistent with my expectations - successful tests passed and failing tests threw exceptions. When I ran the same suite against IronPython 2.0.0, I still received the correct results but the script took 1 minute and 20 seconds to complete. Compare that to less than a second (estimated) for CPython. For the sake of completeness, I ran the same test with IronPython 2.0.1 and received the same result.&lt;/p&gt;  &lt;p&gt;The root of the problem appears to be the large number of GeneratorExitExceptions being thrown. I'm not sure why they're being thrown, but I'll continue to investigate and report my findings. If you're interested in the gory details, here's the stack trace of the first exception:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;at IronPython.Runtime.PythonGenerator.ThrowThrowable()      &lt;br /&gt;at IronPython.Runtime.PythonGenerator.CheckThrowable()       &lt;br /&gt;at IronPython.Runtime.PythonGenerator.       &lt;br /&gt;CheckThrowableAndReturnSendValue()       &lt;br /&gt;at IronPython.Runtime.Operations.PythonOps.       &lt;br /&gt;GeneratorCheckThrowableAndReturnSendValue(Object self)       &lt;br /&gt;at S$11.lambda_method$312(Closure , Int32&amp;amp; state, Object&amp;amp; current) in C:\python25\lib\types.py:line 52       &lt;br /&gt;at Microsoft.Scripting.Runtime.GeneratorEnumerator`1.       &lt;br /&gt;System.Collections.IEnumerator.MoveNext()       &lt;br /&gt;at IronPython.Runtime.PythonGenerator.MoveNextWorker()       &lt;br /&gt;at IronPython.Runtime.PythonGenerator.System.       &lt;br /&gt;Collections.IEnumerator.MoveNext()       &lt;br /&gt;at IronPython.Runtime.PythonGenerator.throw(Object type, Object value, Object traceback)       &lt;br /&gt;at IronPython.Runtime.PythonGenerator.throw(Object type)       &lt;br /&gt;at IronPython.Runtime.PythonGenerator.close()&lt;/p&gt;&lt;/blockquote&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-8265670058660956714?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/8265670058660956714/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=8265670058660956714" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/8265670058660956714" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/8265670058660956714" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2009/03/running-nose-with-ironpython.html" title="Running nose with IronPython" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-9136387387445195503</id><published>2009-02-20T12:54:00.001-08:00</published><updated>2009-02-20T12:54:52.298-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Hosting" /><category scheme="http://www.blogger.com/atom/ns#" term="IronPython" /><title type="text">IronPython Exception: [A]Person cannot be cast to [B]Person</title><content type="html">&lt;p&gt;Had an interesting problem while using the Hosting API the other day. Here's the exception message.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;[A]CSharpClass.Person cannot be cast to [B]CSharpClass.Person. Type A originates from 'CSharpClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'LoadNeither' at location '[project directory]\bin\Debug\CSharpClass.dll'. Type B originates from 'CSharpClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location '[temp directory]\CSharpClass.DLL'.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I was struggling with this for a while until I found this &lt;a href="http://www.nabble.com/Question-on-instantiating-a-.NET-class-in-Python-and-pass-the-instantiated-object-back-to-C--td21608470.html" target="_blank"&gt;link&lt;/a&gt;. In order to get my IronPython scripts to communicate with my CLR-based code, I was using the clr module's AddReference methods. These methods require you to point at the appropriate &lt;em&gt;copy&lt;/em&gt; of the library you want to consume. I do stress &amp;quot;&lt;em&gt;copy&lt;/em&gt;&amp;quot;. Let's say you point your IronPython script at the bin\debug folder of a C# library project you're consuming in a console application. When you run the application, you'll get the exception message above. To make this example work, you'd have to point your IronPython script at the bin\Debug folder of your console application instead. Clearly, this is a maintenance nightmare. Instead, insert the following chunk of code into your hosting application (in the example described above, your console application) to avoid the problem all together.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Assembly assembly = typeof (CSharpClass.Person).Assembly;     &lt;br /&gt;runtime.LoadAssembly(assembly);&lt;/p&gt;&lt;/blockquote&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-9136387387445195503?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/9136387387445195503/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=9136387387445195503" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/9136387387445195503" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/9136387387445195503" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2009/02/ironpython-exception-aperson-cannot-be.html" title="IronPython Exception: [A]Person cannot be cast to [B]Person" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-4045338151122134543</id><published>2009-02-04T19:03:00.001-08:00</published><updated>2009-02-04T19:03:27.096-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Hosting" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="IronPython" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><title type="text">Note to Self 8 - IronPython2, Hosting, DLR</title><content type="html">&lt;ul&gt;   &lt;li&gt;The latest DLR code and documentation can be found at &lt;a href="http://www.codeplex.com/dlr"&gt;www.codeplex.com/dlr&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;For the examples below, here is the Python script I'm using     &lt;br /&gt;&lt;/li&gt;    &lt;blockquote&gt;     &lt;p&gt;class Person(object):       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; def __init__(self, name, phone):        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; self.name = name        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; self.phone = phone        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; def TalkToCSharp(self):        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; val = {&amp;quot;name&amp;quot;:self.name, &amp;quot;phone&amp;quot;:self.phone}        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return val &lt;/p&gt;      &lt;p&gt;&amp;#160;&lt;/p&gt;      &lt;p&gt;def GetPerson():       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; person = Person(&amp;quot;darrell&amp;quot;, &amp;quot;555-4321&amp;quot;)        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return person.TalkToCSharp()        &lt;br /&gt;&lt;/p&gt;      &lt;p&gt;def GetPersonWithParams(name, phone):       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; person = Person(name, phone)        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return person.TalkToCSharp() &lt;/p&gt;      &lt;p&gt;theNumberFive = 5       &lt;br /&gt;myPerson = GetPerson()&lt;/p&gt;   &lt;/blockquote&gt;    &lt;li&gt;Simplest thing you can do is execute a Python script.     &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;blockquote&gt;     &lt;p&gt;static void ExecutePythonScript(string path)       &lt;br /&gt;{        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ScriptRuntime runtime = Python.CreateRuntime();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; runtime.ExecuteFile(path);        &lt;br /&gt;}&lt;/p&gt;   &lt;/blockquote&gt;    &lt;li&gt;Sometimes you need to get a variable after a script has run.     &lt;br /&gt;&lt;/li&gt;    &lt;blockquote&gt;     &lt;p&gt;static void GetDoubleVariable(string path)       &lt;br /&gt;{        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ScriptRuntime runtime = Python.CreateRuntime();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ScriptScope scope = runtime.ExecuteFile(path);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; object x = scope.GetVariable(&amp;quot;theNumberFive&amp;quot;);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(x);        &lt;br /&gt;}&lt;/p&gt;   &lt;/blockquote&gt;    &lt;li&gt;What happens if you're trying to return a custom class defined in the script? The easiest - and IMHO the best - way to go about this is to convert the object to a dictionary before passing it to your C# code.     &lt;br /&gt;&lt;/li&gt;    &lt;blockquote&gt;     &lt;p&gt;static void GetInstanceCustomClass(string path)       &lt;br /&gt;{        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ScriptRuntime runtime = Python.CreateRuntime();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ScriptScope scope = runtime.ExecuteFile(path);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; PythonDictionary dictionary =         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; scope.GetVariable(&amp;quot;myPerson&amp;quot;)         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; as PythonDictionary;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; foreach (var property in dictionary)        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(property.Key +         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot; == &amp;quot; + property.Value);        &lt;br /&gt;}&lt;/p&gt;   &lt;/blockquote&gt;    &lt;li&gt;Getting properties is definitely useful, but you'll probably want to call a function.     &lt;br /&gt;&lt;/li&gt;    &lt;blockquote&gt;     &lt;p&gt;static void CallingAFunction(string path)       &lt;br /&gt;{        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ScriptRuntime runtime = Python.CreateRuntime();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ScriptScope scope = runtime.ExecuteFile(path);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ObjectOperations op =         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; scope.Engine.CreateOperations();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ObjectHandle handle =         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; scope.GetVariableHandle(&amp;quot;GetPerson&amp;quot;);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var x = op.Call(handle, new object[0]);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; PythonDictionary dictionary =         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; x.Unwrap() as PythonDictionary;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; foreach (var property in dictionary)        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(property.Key +        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot; == &amp;quot; + property.Value);        &lt;br /&gt;}&lt;/p&gt;   &lt;/blockquote&gt;    &lt;li&gt;Here's an example of passing parameters to a Python function.     &lt;br /&gt;&lt;/li&gt;    &lt;blockquote&gt;     &lt;p&gt;static void CallingAFunctionWithParameters(string path)       &lt;br /&gt;{        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ScriptRuntime runtime = Python.CreateRuntime();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ScriptScope scope = runtime.ExecuteFile(path);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ObjectOperations op =         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; scope.Engine.CreateOperations();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ObjectHandle handle =         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; scope.GetVariableHandle(&amp;quot;GetPersonWithParams&amp;quot;);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var x = op.Call(handle, &amp;quot;Larry&amp;quot;, &amp;quot;555-1234&amp;quot;);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; PythonDictionary dictionary =        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; x.Unwrap() as PythonDictionary;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; foreach (var property in dictionary)        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(property.Key +        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot; == &amp;quot; + property.Value);        &lt;br /&gt;}        &lt;br /&gt;&lt;/p&gt;   &lt;/blockquote&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-4045338151122134543?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/4045338151122134543/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=4045338151122134543" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/4045338151122134543" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/4045338151122134543" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2009/02/note-to-self-8-ironpython2-hosting-dlr.html" title="Note to Self 8 - IronPython2, Hosting, DLR" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-716965728420404397</id><published>2009-01-29T08:14:00.001-08:00</published><updated>2009-02-01T06:37:01.747-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="SciTE" /><category scheme="http://www.blogger.com/atom/ns#" term="IronPython" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><title type="text">Note to Self 7 - Naming Python Modules, SciTE, IronPython and __name__</title><content type="html">&lt;ul&gt;   &lt;li&gt;Be careful naming your Python modules. If you name a Python file the same as an existing file in your Python install directory, you may get the following exception message: &lt;em&gt;&amp;quot;'module' object has no attribute '[some-attribute-name]'&amp;quot;&lt;/em&gt;. &lt;/li&gt;    &lt;li&gt;I'm really loving SciTE. It's a dead simple code editor that offers syntax highlighting for an impressive number of languages and displays the results of the run in it's own output window. &lt;/li&gt;    &lt;li&gt;More SciTE: If you decide to use SciTE, you'll probably want to customize how it works. Here's a nice &lt;a href="http://novicenotes.com/software/scite-quick-reference/" target="_blank"&gt;quick reference&lt;/a&gt; to supplement the &lt;a href="http://www.scintilla.org/SciTEDoc.html" target="_blank"&gt;SciTE documentation&lt;/a&gt; to help guide you through the config files. &lt;/li&gt;    &lt;li&gt;If you want to use SciTE as your IronPython editor, you'll need to modify the existing python.properties file. Select &amp;quot;Open python.properties&amp;quot; from the &amp;quot;Options&amp;quot; menu. Search for &amp;quot;command.go&amp;quot; and modify the value so that it points at your IronPython directory. &lt;/li&gt;    &lt;li&gt;All Python modules have a special variable called &amp;quot;__name__&amp;quot;. When the code in your module is executed with CPython, __name__ is set to the file name of your module minus the &amp;quot;py&amp;quot; extension (&amp;quot;mymodule&amp;quot; if the file name of your module is &amp;quot;mymodule.py&amp;quot;, for example), except when the module is executed directly. If that's the case, __name__ is equal to &amp;quot;__main__&amp;quot;. Unfortunately, this is not the case if you execute it with IronPython. The special variable __name__ will always be based on the file name. &lt;em&gt;UPDATE: The above is true only when you compile your IronPython code. If you launch a *.py file with ipy.exe, the __name__ variable will be &amp;quot;__main__&amp;quot;.&lt;/em&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-716965728420404397?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/716965728420404397/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=716965728420404397" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/716965728420404397" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/716965728420404397" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2009/01/note-to-self-7-naming-python-modules.html" title="Note to Self 7 - Naming Python Modules, SciTE, IronPython and __name__" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-7083510773503905421</id><published>2009-01-19T20:09:00.001-08:00</published><updated>2009-01-19T20:09:24.851-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="IronPython" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><title type="text">Note to Self 6 - IronPython, pyc.py and SciTE</title><content type="html">&lt;ul&gt;   &lt;li&gt;The pyc.py file can compile you IronPython code into .NET executables. &lt;/li&gt;    &lt;li&gt;The pyc.py file is part of the sample code released with IronPython. It can be found &lt;a href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=8365" target="_blank"&gt;here&lt;/a&gt;. Look for the &amp;quot;IronPython-2.0-Samples.zip&amp;quot; link. &lt;/li&gt;    &lt;li&gt;Typing out &amp;quot;[IP directory]\ipy [code directory]pyc.py&amp;quot; explicitly everytime you want to use the tool is somewhat annoying. Consider creating a script to do this for you. Here's a simple batch file.      &lt;br /&gt;      &lt;br /&gt;      &lt;blockquote&gt;cd C:\data\FeClass        &lt;br /&gt;c:\fepython\ipy.exe pyc.py class.py /main:main.py &lt;/blockquote&gt;      &lt;br /&gt;Note that you'll have to copy the pyc.py file to the same directory as your code for this to work. &lt;/li&gt;    &lt;li&gt;IronPython Studio just isn't up to snuff. You're better off to use a text editor and a build script &lt;/li&gt;    &lt;li&gt;I like SciTE as my IronPython editor even more so than Notepad++. I really like that I can run my Python or IronPython script from SciTE and the output the normally would be displayed in the command window is captured in SciTE. &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-7083510773503905421?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/7083510773503905421/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=7083510773503905421" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/7083510773503905421" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/7083510773503905421" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2009/01/note-to-self-6-ironpython-pycpy-and.html" title="Note to Self 6 - IronPython, pyc.py and SciTE" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-5803143768554273096</id><published>2009-01-11T20:25:00.001-08:00</published><updated>2009-01-11T20:25:54.344-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="SQL Alchemy" /><title type="text">SQL Alchemy ORM Basics</title><content type="html">&lt;p&gt;In my previous post, &lt;a href="http://www.darrellhawley.com/2009/01/learning-sql-alchemy.html" target="_blank"&gt;Learning SQL Alchemy&lt;/a&gt;, I focused on the SQL-like aspect of SQL Alchemy. You'll need to review the sample code in that post before understanding the code below. On with the code.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;class User(object): pass      &lt;br /&gt;mapper(User, user_table)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Believe it or not, we just created a class with an ID, Name and Password. Simply create an empty class and pass it to the the mapper along with the user_table we had created. How do we use it? First off we have to create a Session object. Note that when we call the sessionmaker, it returns a Session class which you use to create the session.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Session = sqlalchemy.orm.sessionmaker()      &lt;br /&gt;session = Session()&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;All have we to do now is create a new User object, set the appropriate fields and pass it to the &amp;quot;save&amp;quot; method.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;user = User()      &lt;br /&gt;user.name = &amp;quot;Fred Flintstone&amp;quot;       &lt;br /&gt;user.password = &amp;quot;yaba daba doo&amp;quot;       &lt;br /&gt;session.save(user)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;But how do we get our user back from the database?&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;query = session.query(User)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We can now iterate through the query like any list.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;for user in query:      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; print user.id, user.name, user.password&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You can see the new record we inserted along with the other records in the table.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;2 angie password2      &lt;br /&gt;3 nate awesomeness       &lt;br /&gt;4 Fred Flintstone yaba daba doo&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The important thing to note is that the query object is actually a list of the very same User type I defined at the beginning of this post. Of course we probably don't want everything in the table, so here's an example of getting back a single object.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;for user in query.filter_by(name = &amp;quot;angie&amp;quot;):      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; print user.id, user.name, user.password&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The result is just what we would expect.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;2 angie password2&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;But let's say I want to change Angie's password.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;user.password = &amp;quot;a much more secure passphrase&amp;quot; &lt;/p&gt;    &lt;p&gt;for user in query.filter_by(name = &amp;quot;angie&amp;quot;):     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; print user.id, user.name, user.password&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The result?&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;2 angie a much more secure passphrase&lt;/p&gt;&lt;/blockquote&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-5803143768554273096?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/5803143768554273096/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=5803143768554273096" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/5803143768554273096" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/5803143768554273096" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2009/01/sql-alchemy-orm-basics.html" title="SQL Alchemy ORM Basics" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-3340216019905635562</id><published>2009-01-07T17:58:00.001-08:00</published><updated>2009-01-07T18:00:30.797-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="SQL Alchemy" /><title type="text">Learning SQL Alchemy</title><content type="html">&lt;p&gt;I spent a portion of my holidays studying the basics of SQL Alchemy. My first lesson is that SQL Alchemy is NOT an ORM for Python but instead a SQL abstraction tool with an ORM built-into it. At first I was having trouble understanding what this really meant, but after seeing an example it sunk in. Let's start by building a table.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;from sqlalchemy import&amp;#160; Table, Column, Integer, String&lt;/p&gt;    &lt;p&gt;meta = sqlalchemy.MetaData(&amp;quot;sqlite:///&amp;quot;) &lt;/p&gt;    &lt;p&gt;user_table = Table('userTable', meta,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Column('id', Integer, primary_key=True),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Column('name', String, unique=True, nullable=False),       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Column('password', String, nullable=False)) &lt;/p&gt;    &lt;p&gt;meta.create_all()&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;First thing we need is a MetaData object which holds all of our database schema information as well as our engine for executing queries. By passing &amp;quot;sqlite:///&amp;quot; in the MetData constructor we create an engine pointing at an in-memory SQLite database. To create a table, we just declare an instance of the Table object and pass in the necessary parameters: table name, our MetData instance and whatever columns we need in the table. The constructor for the Column class not only takes the column name and type, but constraints as well. Then all we have to do is execute the statement by using the create_all() method of the MetaData class.&lt;/p&gt;  &lt;p&gt;Did you note the user_table variable we created? That comes in really handy when we want to start manipulating our new table.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;insert = user_table.insert()      &lt;br /&gt;insert.execute(name='darrell', password='password1')       &lt;br /&gt;insert.execute(name='angie', password='password2')       &lt;br /&gt;insert.execute(name='nate', password='password3')       &lt;br /&gt;insert.execute(name='drew', password='password4')&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;See how easy inserting data is? There are methods just like the insert method above for select, insert and delete. Let's take a look at the select method.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;select = user_table.select()      &lt;br /&gt;results = select.execute() &lt;/p&gt;    &lt;p&gt;for row in results:      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; print row.name, row.password&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The result are just as you would expect.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;darrell password1      &lt;br /&gt;angie password2       &lt;br /&gt;nate password3       &lt;br /&gt;drew password4&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;That's great, but how do we change Nate's password and then return only his record?&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;update = user_table.update(user_table.c.name=='nate')      &lt;br /&gt;update.execute(password='awesomeness') &lt;/p&gt;    &lt;p&gt;select = user_table.select(user_table.c.name=='nate')      &lt;br /&gt;results = select.execute() &lt;/p&gt;    &lt;p&gt;for row in results:      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; print row.name, row.password&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;It's very simple and readable code with one caveat: what is &amp;quot;user_table.c.name&amp;quot;? It's a convenience attribute containing a collection of all the columns in userTable. So what our update statement is saying in terms of SQL is &amp;quot;UPDATE userTable SET ????? WHERE name = 'nate'&amp;quot;. The only thing we don't know at this point is what to change. That happens when we execute the statement on the next line. If you understand the update statement above, the select statement works exactly the same way. Our result is below.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;nate awesomeness&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We've seen select, update and insert, but what about delete?&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;delete = user_table.delete(user_table.c.name.like(&amp;quot;d%&amp;quot;))     &lt;br /&gt;delete.execute()      &lt;br /&gt;select = user_table.select()      &lt;br /&gt;results = select.execute()&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I couldn't help myself - I &lt;em&gt;had&lt;/em&gt; to confuse the issue by using &amp;quot;LIKE&amp;quot;. In my defense, now you know how to introduce a &amp;quot;LIKE&amp;quot; comparison into your code AND that the &amp;quot;c&amp;quot; attribute is more than just a collection of strings. Beyond that, the delete works exactly the way you would expect it to work: call the delete method by passing the constraining expression as a parameter and then execute the result.&lt;/p&gt;  &lt;p&gt;Now I understand why SQL Alchemy is an SQL abstration tool. All I did in the examples above were execute very basic SQL statements; the ORM was never used. Why is this so powerful? Imagine being able to write the same code for a SQL Server database as you did for a MySQL server and having the confidence that it's going to work. That's the power of SQL Alchemy.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-3340216019905635562?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/3340216019905635562/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=3340216019905635562" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/3340216019905635562" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/3340216019905635562" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2009/01/learning-sql-alchemy.html" title="Learning SQL Alchemy" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-261405553121119225</id><published>2009-01-02T06:26:00.001-08:00</published><updated>2009-01-02T06:28:44.663-08:00</updated><title type="text">Congratulations 2009 Microsoft MVP!</title><content type="html">&lt;p&gt;That's the subject line of an email I received yesterday. No one is more surprised than me. Considering who the other MVPs are, I'm honored to be among them. I'm not entirely sure what I did to deserve this, but I'm grateful all the same. Thank you, Microsoft, for noticing me and here's to a productive 2009. Cheers!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-261405553121119225?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/261405553121119225/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=261405553121119225" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/261405553121119225" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/261405553121119225" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2009/01/congratulations-2009-microsoft-mvp.html" title="Congratulations 2009 Microsoft MVP!" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-2336433541660932514</id><published>2008-12-27T08:37:00.001-08:00</published><updated>2008-12-27T08:37:07.711-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Testing" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><title type="text">Note to Self 5 - Inherit and Override</title><content type="html">&lt;p&gt;I've been reading &lt;em&gt;Working Effectively with Legacy Code&lt;/em&gt; by Michael C. Feathers. It's a trove of useful information for turning your unreadable and unreliable code into the complete opposite.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Here's a useful technique for dealing with dependencies that have problematic methods for testing. Mark the offending method as virtual and inherit from the class. Now you can use this new derivative class in your test methods in place of the original. Here's an example in C#.      &lt;br /&gt;      &lt;br /&gt;      &lt;blockquote&gt;       &lt;p&gt;public class MyClass          &lt;br /&gt;{           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public MyClass()           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(&amp;quot;MyClass has been initialized&amp;quot;);           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;        &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; public virtual void DifficultMethod()          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;Difficult method makes testing difficult.&amp;quot;);           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }           &lt;br /&gt;} &lt;/p&gt;        &lt;p&gt;public class MyClassDerived : MyClass          &lt;br /&gt;{           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public MyClassDerived() : base()           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;        &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; public override void DifficultMethod()          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(&amp;quot;It's testable!&amp;quot;);           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;        &lt;p&gt;} &lt;/p&gt;        &lt;p&gt;public class ClassToTest          &lt;br /&gt;{           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public ClassToTest(MyClass myclass)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(&amp;quot;Initializing ClassToTest&amp;quot;);           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; myclass.DifficultMethod();           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }           &lt;br /&gt;}&lt;/p&gt;        &lt;br /&gt;&lt;/blockquote&gt;      &lt;p&gt;The ClassToTest has a constructor that takes a MyClass parameter. Unfortunately, MyClass has the DifficultMethod which is a very...well, difficult method. By marking DifficultMethod as virtual we can override it in a derived class which can then be used to pass into the ClassToTest constructor. Handy.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;Here's the same idea in Python      &lt;br /&gt;      &lt;blockquote&gt;       &lt;p&gt;class MyClass(object):          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; def __init__(self):           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; print &amp;quot;MyClass Initialized&amp;quot;           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; def difficult_method(self):           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; print &amp;quot;this makes things hard&amp;quot;           &lt;br /&gt;&lt;/p&gt;        &lt;p&gt;class MyClassDerivative(MyClass):          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; def __init__(self):           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; MyClass.__init__(self)           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; def difficult_method(self):           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; print &amp;quot;MUCH better&amp;quot;           &lt;br /&gt;&lt;/p&gt;        &lt;p&gt;class ClassToTest(object):          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; def __init__(self, myClass):           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; print &amp;quot;ClassToTest has been initialized&amp;quot;           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; myClass.difficult_method()          &lt;br /&gt;          &lt;br /&gt;&lt;/p&gt;     &lt;/blockquote&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-2336433541660932514?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/2336433541660932514/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=2336433541660932514" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/2336433541660932514" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/2336433541660932514" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2008/12/note-to-self-5-inherit-and-override.html" title="Note to Self 5 - Inherit and Override" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-8333166480642852034</id><published>2008-12-16T20:20:00.001-08:00</published><updated>2008-12-16T20:20:23.561-08:00</updated><title type="text">Using Lambdas to Avoid Gnarly IF Statements</title><content type="html">&lt;p&gt;Do you have a function in your C# code somewhere that takes a parameter - the type doesn't matter - and then executes another function based on that parameter's value?&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;public void what_to_do(string param)     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (param == &amp;quot;this&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DoThis();      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; else if (param == &amp;quot;that&amp;quot;)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DoThat();      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; else      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DoSomethingElse();      &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Whenever I see &amp;quot;else if&amp;quot;, my spider-sense starts tingling. Adding another &amp;quot;else if&amp;quot; is just too easy and the result can be cumbersome. I do use &amp;quot;else if&amp;quot; (and &amp;quot;switch&amp;quot; - it's just as vulnerable to this idea), but I don't always like it. The good news is that there is a fix - if you're willing to think &amp;quot;functionally&amp;quot;. The bad news is it took me so long to piece it all together.&lt;/p&gt;  &lt;p&gt;When did this epiphany come? At the latest &lt;a href="http://groups.google.com/group/michipug/web/index-2?pli=1" target="_blank"&gt;MichiPUG&lt;/a&gt; meeting, while &lt;a href="http://compoundthinking.com/blog/" target="_blank"&gt;Mark Ramm&lt;/a&gt; was demonstrating a Python library for implementing generics, he displayed an interesting technique for avoiding the Python version of the above code. Here's my rendition of what he showed us:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;whatToDoDictionary = {'this':do_this, 'that':do_that} &lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;def what_to_do(param):     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if param in whatToDoDictionary:      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; whatToDoDictionary[param]();      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; else:      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; do_something_else();&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The key to this bit of Python is the values in the&amp;#160; whatToDoDictionary. Instead of your standard string or integers, the values are functions. When we call the what_to_do method, we look to see if the parameter is present as a key in the dictionary. If it is, we simple execute the value portion of the key/value pair. Voil&amp;#224;! No more &amp;quot;else if&amp;quot;!&lt;/p&gt;  &lt;p&gt;Can we do this in C#? Sure. Let's do it using lambdas.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Dictionary&amp;lt;string, Action&amp;gt; dict = &lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new Dictionary&amp;lt;string, Action&amp;gt;(); &lt;/p&gt;    &lt;p&gt;public Lambda()     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dict.Add(&amp;quot;this&amp;quot;, () =&amp;gt; do_this());      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dict.Add(&amp;quot;that&amp;quot;, () =&amp;gt; do_that());      &lt;br /&gt;} &lt;/p&gt;    &lt;p&gt;public void WhatToDo(string param)     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (dict.ContainsKey(param))      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; dict[param]();      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; else      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; do_something_else();      &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The concept is exactly the same. Build a dictionary of lambdas (functions in Python), see if the parameter passed to the WhatToDo(string) is in the dictionary and then execute the lambda if it is. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-8333166480642852034?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/8333166480642852034/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=8333166480642852034" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/8333166480642852034" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/8333166480642852034" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2008/12/using-lambdas-to-avoid-gnarly-if.html" title="Using Lambdas to Avoid Gnarly IF Statements" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-1106972138331870081</id><published>2008-12-13T13:11:00.001-08:00</published><updated>2008-12-13T13:11:20.224-08:00</updated><title type="text">Note to Self 4 - Python Editors, Debuggers, stdout and stderr</title><content type="html">&lt;ul&gt;   &lt;li&gt;PyScripter has been IDE of choice for Python, but I've run into some problems with it. I would have continued to use it, but I noticed that the latest anyone did any work on it was October of 2006 - or at least that's what I thought. It turns out that early this year PyScripter is now maintained in Google Code and supports Python 2.6. You can download it &lt;a href="http://code.google.com/p/pyscripter/" target="_blank"&gt;here&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;I've started using &lt;a href="http://notepad-plus.sourceforge.net/uk/site.htm" target="_blank"&gt;Notepad++&lt;/a&gt; for editing my Python. Though it's only an editor, it uses syntax highlighting, supports macros and allows me to define hot keys to run external programs. This last point makes it possible for me to launch my code in Python with a simple keypress. &lt;/li&gt;    &lt;li&gt;Want to know how to use Notepad++ to launch the file you're currently editing in Python? Type &amp;quot;[%Python directory%]\python.exe &amp;quot;$(FULL_CURRENT_PATH)&amp;quot; into the Notepad++ Run dialog and then save it to the keystroke combination of you choice. &lt;/li&gt;    &lt;li&gt;If you took my previous bullet point to heart, you'll find that Python launches in a command window and then promptly closes after your tests run losing any output you may have had. The only way that I've been able to solve this is by pointing the stdout and stderr to a file. I would prefer to override the these when I launch Python, but instead I have to put some addtional code into my application. Bummer. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://winpdb.org/" target="_blank"&gt;WinPDB&lt;/a&gt; is a debugging tool for Python. The only tool I'd used for debugging in the past is the one embedded into &lt;a href="http://code.google.com/p/pyscripter/" target="_blank"&gt;PyScripter&lt;/a&gt;. When I started using Notepad++ as my editor, I started trying to debug from the command line using the PDB module. No fun. That's when I came across WinPDB. It's worked well for the past few days that I've been using it, but it still isn't as nice as having your debugger integrated into your environment. &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-1106972138331870081?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/1106972138331870081/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=1106972138331870081" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/1106972138331870081" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/1106972138331870081" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2008/12/note-to-self-4-python-editors-debuggers.html" title="Note to Self 4 - Python Editors, Debuggers, stdout and stderr" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-6979377162939117941</id><published>2008-11-17T10:41:00.001-08:00</published><updated>2008-11-17T10:41:54.353-08:00</updated><title type="text">Note to Self 3 - CodeMash Screen Casting Options</title><content type="html">&lt;p&gt;I've been learning a lot about Screencasting this week...&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;I've updated my podcasting links at &lt;a title="http://delicious.com/dwhawley/podcasting" href="http://delicious.com/dwhawley/podcasting"&gt;http://delicious.com/dwhawley/podcasting&lt;/a&gt; with a couple of new items.&lt;/li&gt;    &lt;li&gt;I reviewed a couple of USB devices to capture video and audio (&lt;a href="http://www.amazon.com/review/product/B000234SMQ/ref=cm_cr_pr_hist_5?_encoding=UTF8&amp;amp;showViewpoints=0&amp;amp;filterBy=addFiveStar" target="_blank"&gt;USB 28000D DVD Maker&lt;/a&gt; and the &lt;a href="http://www.amazon.com/Diamond-VC500-Touch-Capture-Device/dp/B000VM60I8/ref=pd_cp_e_0?pf_rd_p=413863501&amp;amp;pf_rd_s=center-41&amp;amp;pf_rd_t=201&amp;amp;pf_rd_i=B000234SMQ&amp;amp;pf_rd_m=ATVPDKIKX0DER&amp;amp;pf_rd_r=0VJFAC945FBNH58A11D8" target="_blank"&gt;Diamond VC500 One Touch Video Capture Device&lt;/a&gt;) and I wasn't happy with any of the reviews. This really seemed to be the simplest avenue but seems to be a dead-end.&lt;/li&gt;    &lt;li&gt;The solution I'm searching for assumes that I'll only have laptops available. There are a lot of video capture cards out there for a desktop machine but I'm avoiding this one for now.&lt;/li&gt;    &lt;li&gt;I like the VNC option the best, but a major problem with this is that we'll need to rely on speakers installing something on their machine. &lt;a href="http://jasonfollas.com/blog/" target="_blank"&gt;Jason Follas&lt;/a&gt; pointed this out to me and he's right. I think the only way to resolve this is ask the community. If they don't like the solution I'll know to keep looking. Besides, someone might have a really good idea.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.jingproject.com/" target="_blank"&gt;Jing&lt;/a&gt; is cool. &lt;a href="http://srtsolutions.com/blogs/jaywren/default.aspx" target="_blank"&gt;Jay Wren&lt;/a&gt; gave me quick demo earlier today and I was impressed with it's simplicity. One of the things that I really like about &lt;a href="http://www.jingproject.com/" target="_blank"&gt;Jing&lt;/a&gt; is it's social spirit. I was looking at &lt;a href="http://www.techsmith.com/camtasia.asp" target="_blank"&gt;Camtasia&lt;/a&gt;, another offering by &lt;a href="http://www.techsmith.com/" target="_blank"&gt;TechSmith&lt;/a&gt; , but I think &lt;a href="http://www.jingproject.com/" target="_blank"&gt;Jing&lt;/a&gt; may be a better fit.&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-6979377162939117941?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/6979377162939117941/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=6979377162939117941" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/6979377162939117941" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/6979377162939117941" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2008/11/note-to-self-3-codemash-screen-casting.html" title="Note to Self 3 - CodeMash Screen Casting Options" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-451118641904661188</id><published>2008-11-04T11:00:00.001-08:00</published><updated>2008-11-04T11:01:40.718-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="VNC" /><category scheme="http://www.blogger.com/atom/ns#" term="screencasts" /><title type="text">Note to Self 2 - Capturing Multiple Conference Sessions Simultaneously</title><content type="html">&lt;p&gt;I'm the A/V Coordinator for &lt;a href="http://www.codemash.org/" target="_blank"&gt;CodeMash 2009&lt;/a&gt; and as such I have a lot of sessions to capture. Here are some notes.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;I'm storing links related to podcasting at &lt;a title="http://delicious.com/dwhawley/podcasting" href="http://delicious.com/dwhawley/podcasting"&gt;http://delicious.com/dwhawley/podcasting&lt;/a&gt;.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Vnc" target="_blank"&gt;According to Wikipedia&lt;/a&gt;, &amp;quot;&lt;b&gt;Virtual Network Computing&lt;/b&gt; (&lt;b&gt;VNC&lt;/b&gt;) is a graphical &lt;a href="http://en.wikipedia.org/wiki/Desktop_sharing"&gt;desktop sharing&lt;/a&gt; system which uses the &lt;a href="http://en.wikipedia.org/wiki/RFB_protocol"&gt;RFB protocol&lt;/a&gt; to remotely control another &lt;a href="http://en.wikipedia.org/wiki/Computer"&gt;computer&lt;/a&gt;. It transmits the &lt;a href="http://en.wikipedia.org/wiki/Computer_keyboard"&gt;keyboard&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Computer_mouse"&gt;mouse&lt;/a&gt; events from one computer to another, relaying the graphical &lt;a href="http://en.wikipedia.org/wiki/Computer_screen"&gt;screen&lt;/a&gt; updates back in the other direction, over a &lt;a href="http://en.wikipedia.org/wiki/Computer_network"&gt;network&lt;/a&gt;.&amp;quot; In short, the VNC server displays what's on the screen of the VNC client.&lt;/li&gt;    &lt;li&gt;Every presenter will require a VNC client of some sort on their machine. The client will connect to a VNC server where the actual video capturing will take place. I'm assuming one server per client with each hard-wired to a switch, but I'm hoping for more 2 or more clients per server.&lt;/li&gt;    &lt;li&gt;Without knowing much about it, I had been using VNC for quite some time. I've used both GoToMeeting and NetMeeting with excellent results.&lt;/li&gt;    &lt;li&gt;Because this is &lt;a href="http://www.codemash.org/" target="_blank"&gt;CodeMash&lt;/a&gt;, there will be three different families of Operating Systems represented: Windows, Mac and Linux. Theoretically, my Windows based VNC Server should have no problems seeing a Linux- or Mac-based client, but I've heard this sort of thing before. I will be setting up a test network in the very near future.&lt;/li&gt;    &lt;li&gt;Audio will have to be recorded separately since it isn't part of the RFB spec (communications protocol between VNC client and server). I know some tools cover this for you, but I can't count on it in platform agnostic environment.&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-451118641904661188?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/451118641904661188/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=451118641904661188" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/451118641904661188" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/451118641904661188" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2008/11/note-to-self-2-capturing-multiple.html" title="Note to Self 2 - Capturing Multiple Conference Sessions Simultaneously" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-5400092419446305111</id><published>2008-11-03T13:57:00.001-08:00</published><updated>2008-11-03T13:57:36.342-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Virtualization" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><category scheme="http://www.blogger.com/atom/ns#" term="SQL Alchemy" /><title type="text">Note to Self 1</title><content type="html">&lt;p&gt;I haven't been blogging much lately, which is no surprise to anyone who follows my blog. To those three readers, I'd like to tell you that writing - to me - is a very much a love/hate relationship. When I'm inspired, writing becomes an obsession I can't possibly put aside. Even if what I produce is not noteworthy among my colleagues, the process of putting my thoughts into words helps me clarify personal thoughts like no other learning experience could. It confirms truths. It tears-down misconceptions. It's the highest form of human expression. It's REALLY exhausting. So If I don't have the time or energy to write, how do I effectively maintain a blog?&lt;/p&gt;  &lt;p&gt;The title of this post sums up my solution. If I don't have the time or energy to write the kind of post I want, just write short bullet points on the things that I've been exploring. What I really like about this approach is that I do a lot more in the course of a day than I could possibly convey through my blog. For example, since I last blogged, I've experimented with jQuery, VMWare Player, Virtual PC, Python and SQL Alchemy. Even at the best of times, there is no way that I'm going to cover all of those topics before forgetting one or more of them. With that said, time to write some notes.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;jQuery rules, though I've had problems debugging using FireBug. Apparently it requires a bookmarklet though that still doesn't seem to work for me. &lt;/li&gt;    &lt;li&gt;The mapper class in SQL Alchemy - Python ORM - gets rid of having to manually set properties of derived classes when the corresponding base class is already known (i.e., Employee.Name = Person.Name). This is the sort of code that really annoys me and I'm glad there's a way to avoid it. &lt;/li&gt;    &lt;li&gt;Virtualization rocks, but it gets tough on a laptop. My host machine is Vista and my guests are all XP. I've tried Vista as guest before, but it was so slow I couldn't really do anything with it. Some of my virtualization links can be found at &lt;a title="http://delicious.com/dwhawley/virtual" href="http://delicious.com/dwhawley/virtual"&gt;http://delicious.com/dwhawley/virtual&lt;/a&gt;.&lt;/li&gt;    &lt;li&gt;I've been using both VMWare Player and Virtual PC. VMWare Player works with more than just Windows allowing me to periodically play with Linux, but doesn't have the really cool pause feature that Virtual PC has. Virtual PC seems a bit snappier to me, but it lacks support for USB. No excuses for that.&lt;/li&gt;    &lt;li&gt;Azure is really cool though you should keep in mind that this is in direct competition with Google Apps. Either way, I'll be using both.&lt;/li&gt;    &lt;li&gt;Of all of the features I've heard about Windows 7, I'm most excited about it's smaller footprint. &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-5400092419446305111?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/5400092419446305111/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=5400092419446305111" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/5400092419446305111" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/5400092419446305111" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2008/11/note-to-self-1.html" title="Note to Self 1" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-5472603715331487719</id><published>2008-10-27T13:54:00.001-07:00</published><updated>2008-10-27T13:54:51.675-07:00</updated><title type="text">A Visit from Redmond - Catching up on Visual Studio Team Edition with Mark Mydland</title><content type="html">&lt;p&gt;On November 12th, Mark Mydland, Group Manager for the Visual Studio Team Edition for Software Testers, will be speaking at the &lt;a href="http://www.aadnd.org" target="_blank"&gt;Ann Arbor .NET Developers Group&lt;/a&gt;. This is your opportunity to glimpse the future of - possibly even influence - the tool you spend the most time using, so clear you calendar!&amp;#160; &lt;/p&gt;  &lt;p&gt;The phrase &amp;#8220;drive quality upstream&amp;#8221; has been abused so badly by ALM software vendors that it has to be relegated to the platitude junk pile along with such all time favorites as &amp;#8220;work smarter not harder,&amp;#8221; &amp;#8220;think outside the box,&amp;#8221; and &amp;#8220;synergistic leveraging of code reuse.&amp;#8221; Before we drive quality anywhere, we need to give quality a seat at the table. VSTS Rosario release will do this by automatically gathering critical information about the project and code and making that data available when, where and to whom it is needed. During this discussion we will examine how Rosario impacts quality across the application lifecycle by:    &lt;br /&gt;* Allowing testers to provide developers with details about what the code did instead of just providing the details about what the tester did.     &lt;br /&gt;* Allowing development leads and architects to visualize and understand their current code (not the code they wish they had, but the code they really have) so that they can minimize the impact of changes; and     &lt;br /&gt;* Allowing developers to understand the impact of their changes in terms of affected tests, concurrency and bounds checking.     &lt;br /&gt;The Rosario release of VSTS will bring all project stakeholders together to allow richer information to be shared across every role to make software quality accessible and achievable.&lt;/p&gt;  &lt;p&gt;&lt;font color="#800040"&gt;About Mark&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/hawley.darrell/SQYqlaxGe_I/AAAAAAAAARA/zSrkMiEvvfM/s1600-h/image%5B3%5D.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="image" src="http://lh4.ggpht.com/hawley.darrell/SQYqmdGkLII/AAAAAAAAARE/HiLM-NjwroM/image_thumb%5B1%5D.png?imgmax=800" width="198" align="left" border="0" /&gt;&lt;/a&gt;Mark Mydland is a Group Manager for the Visual Studio Team Edition for Software Testers product at Microsoft.&amp;#160; In the past 12 years, Mark has worked as a developer and consultant across a wide variety of applications and industries.&amp;#160; Mark first joined Microsoft in 2001 working as a member of the Natural Interactive Services Division (NISD).&amp;#160; During his time in that group, Mark was the development manager for a team focused on analytics for assessing the efficacy of natural language interpreters with a particular emphasis on driving authoring simplification and relevance quality for user assistance.&amp;#160; Based on this work, Mark filed numerous patents and coauthored a paper for the SIGIR journal.&amp;#160; In 2004, Mark left Microsoft to work as a Director of Development at Getty Images where he led a change in process from a traditional waterfall methodology to a scrum-based agile approach which brought the release frequency from 12-18 months down to 1 month.&amp;#160; Since Getty made extensive use of VSTS, it seemed a natural fit for Mark to join VSTS on his return to Microsoft in 2006.&amp;#160; Mark received his B.S. from West Point in 1991.&amp;#160; He has also held positions with USWeb/marchFirst and Andersen Consulting/Accenture.&amp;#160; &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-5472603715331487719?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/5472603715331487719/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=5472603715331487719" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/5472603715331487719" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/5472603715331487719" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2008/10/visit-from-redmond-catching-up-on.html" title="A Visit from Redmond - Catching up on Visual Studio Team Edition with Mark Mydland" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-4263509553683055665</id><published>2008-09-05T08:39:00.001-07:00</published><updated>2008-09-05T08:39:35.603-07:00</updated><title type="text">Class Variables versus Instance Variables in Python</title><content type="html">&lt;p&gt;While writing some Python, I ran into a behavior that I didn't expect. Check out the following chunk of code:&lt;/p&gt;  &lt;p&gt;import unittest &lt;/p&gt;  &lt;p&gt;class Task(object):    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; keywords = [] &lt;/p&gt;  &lt;p&gt;class TestClass(unittest.TestCase):    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; def test_keywords(self):     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mytask = Task()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mytask.keywords.append(&amp;quot;one&amp;quot;) &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mytask2 = Task()    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mytask2.keywords.append(&amp;quot;two&amp;quot;)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; self.assertEqual(mytask2.keywords[0], &amp;quot;two&amp;quot;)&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;When I ran the test, it failed with the following exception: &amp;quot;AssertionError: 'one' != 'two'&amp;quot;. As I dug into the code I found that the mytask and mytask2 instances had received both of the keywords, not just one a piece. My initial reaction was that this must be some sort of Python bug. But as I investigated I found that I had actually created a Class Variable - Python's way of saying &amp;quot;static&amp;quot;. What I really wanted was an Instance Variable.&lt;/p&gt;  &lt;p&gt;class Task(object):    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; def __init__(self):     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; self.keywords = []&lt;/p&gt;  &lt;p&gt;By declaring &amp;quot;keywords&amp;quot; inside the constructor it is now guaranteed to be unique to each instance of the class allowing my test to pass. This &lt;a href="http://www.python.org/doc/2.5.1/ref/class.html" target="_blank"&gt;link&lt;/a&gt; in the &lt;a href="http://www.python.org/doc/2.5.1/ref/" target="_blank"&gt;Python Reference Manual&lt;/a&gt; explains it much more clearly. Note that &lt;a href="http://www.codeplex.com/IronPython" target="_blank"&gt;IronPython&lt;/a&gt; behaves in the same manner.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-4263509553683055665?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/4263509553683055665/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=4263509553683055665" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/4263509553683055665" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/4263509553683055665" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2008/09/class-variables-versus-instance.html" title="Class Variables versus Instance Variables in Python" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-3859767395556796416</id><published>2008-08-29T08:10:00.001-07:00</published><updated>2008-08-29T08:10:57.253-07:00</updated><title type="text">More Lessons from Project Management in the Physical World</title><content type="html">&lt;p&gt;&lt;em&gt;This post is a continuation of &lt;/em&gt;&lt;a href="http://www.darrellhawley.com/2008/07/lessons-from-project-management-in_30.html" target="_blank"&gt;&lt;em&gt;my post from July 30&lt;/em&gt;&lt;/a&gt;&lt;em&gt; on some project management lessons I learned while roofing my garage.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;I had all of my roofing supplies, my work force was in place and the big day had arrived. Everything was just as I had envisioned it. Then my first volunteer arrived and told me he wasn't sure how long he was going to be able to help. His wife had gotten sick the day before and it didn't appear she was going to be in any shape to watch their children. If he would have been the only person I recruited to help, I may have been hard-pressed to accomplish my goal of completing the roof by Sunday evening. But he wasn't. I still had one other person to help that day and I could have probably found additional help the following day if necessary. Crisis averted.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Lesson 4: Mitigating risk is time well spent especially when risk becomes reality.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I had researched getting a dumpster and instead found a company that would load your garbage in a truck with their own work force. They had a nice website that detailed their costs - or so I thought. It turns out that they had a special pricing for roofing which I didn't learn about until 3 hours prior to pick-up. The additional cost was excessive and there was no way I was going to pay for it. I had no backup plan aside from just leaving a pile of roofing in my driveway until I found alternative. Fortunately, my friend let me borrow his truck and I was able to dispose of the old roofing for a fraction of the cost. I was lucky. In retrospect, having a dumpster on site ahead of time would have completely eliminated this risk. Instead, I knowingly introduced a number of unnecessary variables into my project (reliability of the company schedule, truck and web site pricing for example).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Lesson 5: You may not know ALL of the risks ahead of time, but you CAN minimize them by limiting your unknowns.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;When Sunday evening did come, I could say that I had met my goal of having a roof in place. Unfortunately, the job was far from done. The rain storm that had hit meant I had to clean out the garage and I still had a truck load of roofing to take to the landfill. It turns out &amp;quot;done&amp;quot; really meant that the only change to my property was a new garage roof - definitely not the case on Sunday evening. I could have blamed the rain for not meeting my goal but that would have done nothing but assuage the problem. The rain had only changed the actions necessary to attain my goal not change the goal itself.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Lesson 6: Make sure that everyone on the team clearly understands what &amp;quot;done&amp;quot; means.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;When the rain started coming down, I looked at it as a bad thing. But it forced me to go through the &amp;quot;features&amp;quot; of my garage - spare sheets of drywall and scrap lumber for example - and make some decisions on them. Removing these features made my garage a more useable space. The irony of course, was that I considered rain a risk not an opportunity.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Lesson 7: Beware of bloat&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Lesson 8: Look for the opportunities in setbacks. Sometimes they can contribute to the success of the project.&lt;/strong&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-3859767395556796416?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/3859767395556796416/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=3859767395556796416" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/3859767395556796416" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/3859767395556796416" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2008/08/more-lessons-from-project-management-in.html" title="More Lessons from Project Management in the Physical World" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-891211124540815536</id><published>2008-08-19T18:30:00.001-07:00</published><updated>2008-08-19T18:30:07.571-07:00</updated><title type="text">Speaking at GANG on Wednesday Night</title><content type="html">&lt;p&gt;Just a note that I'll be doing my &amp;quot;Getting Started with IronPython&amp;quot; talk at the &lt;a href="http://www.migang.org" target="_blank"&gt;Great Lakes Area .NET User Group&lt;/a&gt; in Southfield, MI tomorrow night. I'm always glad to go back to GANG since this is where my User Group career started before I moved over to the &lt;a href="http://www.aadnd.org" target="_blank"&gt;Ann Arbor .NET Developers Group&lt;/a&gt;. Come out and learn about one of the new .NET languages while networking with local community leaders. I Hope to see you there.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-891211124540815536?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/891211124540815536/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=891211124540815536" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/891211124540815536" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/891211124540815536" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2008/08/speaking-at-gang-on-wednesday-night.html" title="Speaking at GANG on Wednesday Night" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-4119478245564542960</id><published>2008-07-30T20:27:00.001-07:00</published><updated>2008-07-30T20:27:51.133-07:00</updated><title type="text">Lessons from Project Management in the Physical World</title><content type="html">&lt;p&gt;When developers talk about projects, they probably are talking about software. But however hard they try, they cannot completely escape &amp;quot;real&amp;quot; world projects. This is especially true when it comes to home ownership. When my wife and I noticed our garage roof deteriorating, I realized I was going to be confronted with an especially nasty real-world undertaking. By looking at it through the eyes of a project manager however, I was able to take an unpleasant task and turn it into a successful learning experience.&lt;/p&gt;  &lt;p&gt;Like any project, replacing a roof requires planning and my plan focused on a single goal: there will be a new roof on my garage come Sunday night. The five basic items on my task list - schedule a weekend, purchase supplies, order a dumpster, remove the old roof and install the new roof - were all focused toward achieving that goal. I was concerned about inclement weather, unforeseen repairs and lack of personnel, so I created a plan for each risk and a trigger for implementing it. What I did not plan was HOW to roof the garage. I simply had to be confident that the implementation team could do the work using pre-defined best practices.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Lesson 1: Planning is about achieving a goal, identifying general tasks and knowing how to deal with risks. Planning is NOT about implementation details.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I felt the project could be completed quickly though I didn't have the experience to say for certain. I contacted someone with more experience (my dad) and he confirmed that one day should be enough time for a 2-man crew to roof a one-car garage. My experience however, told me to include extra time and any additional personnel I felt I could keep consistently busy. In the end, myself and 2 people were able to replace the roof in one very long Saturday. If additional time was required, we still had Sunday as a buffer.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Lesson 2: Experience is invaluable. If you don't have it, find it.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Risk exists. Acknowledge it up front or spend your life being constantly surprised by it's consequences. When I chose my weekend to roof, I knew three days in advance that rain was a possibility. I knew that afternoon thunderstorms were a certainty the night before. To mitigate the rain risk, I bought a tarp large enough cover only a portion of my garage. I felt that the extra $80 was not worth protecting things that I could either handle the wet or that I could live without. With plan in place and thunderstorms in the forecast, I pressed forward. Guess what? We had a two hour downpour in the morning almost immediately after we had finished removing the old roof. Critical items were protected, but I still suffered some minimal damage. When I cleaned out my garage, the only things I had lost were time and expendable items. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Lesson 3: Just because you mitigate risk doesn't mean you completely avoid it's consequences. Take a moment to imagine handling the consequences before committing to anything.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;As this could turn into such a large blog post, I thought I'd break it up into a couple of chunks. I'll post part two sometime in the next week. &lt;/em&gt;&lt;a href="http://www.dotnetrockstar.com/2008/07/21/ThisBlogEntryInspiredBy.aspx" target="_blank"&gt;&lt;em&gt;John Hopkins&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, I acknowledge that you've called me out and I owe a post on who inspires me.&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-4119478245564542960?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/4119478245564542960/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=4119478245564542960" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/4119478245564542960" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/4119478245564542960" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2008/07/lessons-from-project-management-in_30.html" title="Lessons from Project Management in the Physical World" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-3678568488034258395</id><published>2008-06-19T05:58:00.001-07:00</published><updated>2008-06-19T05:58:31.157-07:00</updated><title type="text">Speaking at GLUG.Net Tonight</title><content type="html">&lt;p&gt;I'll be giving my now re-tooled introduction to IronPython this evening at the &lt;a href="http://portal.artemis-solutions.com/glugnet/" target="_blank"&gt;Greater Lansing User Group .Net&lt;/a&gt; meeting. Entitled &amp;quot;Getting Started with IronPython&amp;quot;, I'll be focusing on the syntax, rules and &amp;quot;gotchas&amp;quot; of IronPython by making comparisons to C# as well as writing lots of code. My end point - if there's enough time -&amp;#160; is to get started on a very simple windows application. Hope to see you there.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-3678568488034258395?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/3678568488034258395/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=3678568488034258395" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/3678568488034258395" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/3678568488034258395" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2008/06/speaking-at-glugnet-tonight.html" title="Speaking at GLUG.Net Tonight" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18697241.post-216871644631168032</id><published>2008-06-12T07:19:00.001-07:00</published><updated>2008-06-12T07:19:16.258-07:00</updated><title type="text">AADND and Lessons Learned on Speaking</title><content type="html">&lt;p&gt;I gave my &lt;em&gt;Looking Out For IronPython&lt;/em&gt; talk at AADND last night which went really well. People were asking questions and genuinely seemed engaged. But as far as knowledge gained is concerned, I think I was the big winner last night. After the meeting had cleared out, &lt;a href="http://srtsolutions.com/blogs/billwagner" target="_blank"&gt;Bill Wagner&lt;/a&gt; gave me the most in-depth speaking critique I have ever gotten. Typically, the only feedback a speaker gets is a stack of evaluation forms with a bunch of numbers circled and an occasional useful comment. Bill's comments focused not only content, but also pace and physical movement. His comments in summary...&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Only move to different locations in the room if there is a purpose in doing so. I have a tendency to pace which only distracts the audience from your point. Check out &lt;a href="http://www.joshholmes.com/2008/04/28/PublicSpeakingAndMovementOnstage.aspx" target="_blank"&gt;this post&lt;/a&gt; by &lt;a href="http://www.joshholmes.com/default.aspx" target="_blank"&gt;Josh Holmes&lt;/a&gt; to hammer home the point. If you have the time, browse his blog in it's entirety. He has a lot to say about public speaking. &lt;/li&gt;    &lt;li&gt;Posture is important. It magnifies your presence and conveys confidence. Putting your hands in your pockets kills your posture and thus your presence. Even worse, you loose credibility with your audience. Stand tall, keep your hands out of your pockets and use hand gestures only if necessary. &lt;/li&gt;    &lt;li&gt;It's OK to say, &amp;quot;I don't know,&amp;quot; but it's not OK to advertise it (yes, there is irony in this post). When you speak, you become the self-professed expert in the room. In this context, I viewed any question from the audience that I couldn't answer as a failure. Now that I've learned differently, I seemed to have gone too far. I LIKE to talk about the issues I'm trying to solve. Great for personal growth, not so much for presentations. I need to focus on what I know. &lt;/li&gt;    &lt;li&gt;&lt;em&gt;Looking out for IronPython &lt;/em&gt;was intended to be an introductory talk. People are showing-up to learn the basics of IronPython, not to be wowed by what IronPython can do. I spent too too much time on complex examples that had little value to the audience. &lt;/li&gt;    &lt;li&gt;My talk was structured so that the first half was entirely PowerPoint and the second half was entirely code. This sort of thing can be taxing on an audience's attention span. Do a few slides, show a demo, do some more slides, then do another demo. This breaks things up into smaller, more digestable chunks. &lt;/li&gt;    &lt;li&gt;Showing an audience something they already know and then morphing it into something new is an effective teaching technique. I did it in &lt;em&gt;Looking out for IronPython &lt;/em&gt;and I should consider it for future talks. &lt;/li&gt;    &lt;li&gt;Humor is risky which is why I have made the conscious decision to stay away from a lot of jokes in my presentations. I did insert one slide that last nights audience found entertaining (earlier audiences did not), but it was directly relevant to my point. My lesson here? Don't plan a joke. If the opportunity comes, jump on it. Otherwise, just be yourself. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Bill's comments were a nudge in the right direction. If I'm really serious about improving though, I need to find the nearest &lt;a href="http://www.toastmasters.org/" target="_blank"&gt;Toastmasters&lt;/a&gt; group. All I have to do is find the time!&lt;/p&gt;  &lt;p&gt;I know I promised a post of IronPython resources. I'm still compiling my list and hope to have those posted by this weekend.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18697241-216871644631168032?l=www.darrellhawley.com%2Fdefault.html'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/216871644631168032/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=18697241&amp;postID=216871644631168032" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/216871644631168032" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/18697241/posts/default/216871644631168032" /><link rel="alternate" type="text/html" href="http://www.darrellhawley.com/2008/06/aadnd-and-lessons-learned-on-speaking.html" title="AADND and Lessons Learned on Speaking" /><author><name>Darrell Hawley</name><uri>http://www.blogger.com/profile/13626445665115916691</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="03881874778058834600" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry></feed>
