<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5772872</id><updated>2023-07-24T06:30:52.979-05:00</updated><category term="programming"/><category term="design"/><category term="smalltalk"/><category term="java"/><category term="ruby"/><category term="dynamic languages"/><category term="javascript"/><category term="rant"/><category term="squeak"/><category term="Python"/><category term="inspiration"/><category term="misc"/><category term="lisp"/><category term="presentation"/><category term="music"/><category term="seaside"/><category term="agile"/><category term="conference"/><category term="groovy"/><category term="metal"/><category term="travel"/><category term="XP"/><category term="analysis"/><category term="business"/><category term="emacs"/><category term="functional programming"/><category term="mac"/><category term="prototypes"/><category term="Objective C"/><category term="bar camp"/><category term="funny"/><category term="html"/><category term="javvascript"/><category term="marketing"/><category term="quote"/><category term="self"/><category term="test"/><category term="twitter"/><category term="use cases"/><title type='text'>Fanciful Magic</title><subtitle type='html'>Readable Code By Doing</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>982</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5772872.post-5701020232191110982</id><published>2015-05-24T18:02:00.001-05:00</published><updated>2015-05-24T18:02:46.500-05:00</updated><title type='text'>Getting a USB sound card configured for Raspberry Pi 2</title><content type='html'>I recently tried to get a USB sound card working on a Raspberry Pi 2. My motivation was to start working on audio applications like writing my own synth. It&#39;s something I&#39;ve wanted to do for a long time, but some odd reason never got around to it. At first, I simply tried to output sound via the built-in sound card. This experiment was successful of course, but there was a lot of noise in the output. I tested using the SonicPi program that comes with the Pi.&lt;br /&gt;
&lt;br /&gt;
My next experiment was to use a USB sound card that I had gotten for cheap. Apparently, these are hit and miss and if I were to do it over again, I would get one from &lt;a href=&quot;http://adafruit.com/&quot; target=&quot;_blank&quot;&gt;Adafruit&lt;/a&gt;&amp;nbsp;where they sell ones that have been tested for the Pi. Everything worked out so I lucked out, but the path to success was not obvious. For your information, I used the CMedia HS100 from NRGtech. I also used the latest version of &lt;a href=&quot;https://www.raspberrypi.org/downloads/&quot; target=&quot;_blank&quot;&gt;Raspbian (Debian Wheezy)&lt;/a&gt;&amp;nbsp;and updated my pi firmware with &quot;sudo rpi-update&quot; before I even started since most guides mentioned to do this for latency.&lt;br /&gt;
&lt;br /&gt;
Before I begin, I was repeatedly given the &lt;a href=&quot;https://wiki.archlinux.org/index.php/Advanced_Linux_Sound_Architecture#In_User_Space&quot; target=&quot;_blank&quot;&gt;ALSA (Advanced Linux Sournd Architecture) document&lt;/a&gt;. There&#39;s a lot of information in there. I hope to spend sometime read it more thoroughly, but when you&#39;re trying to get something simple working, it&#39;s like drinking from a fire hose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Plugin the USB sound card.&lt;/li&gt;
&lt;li&gt;Navigate to the Menu&amp;gt;Preferences&amp;gt;Audio Device Settings.&lt;/li&gt;
&lt;li&gt;At the top of the dialog, there is a drop down for the sound card. Mine displayed &quot;bcm2835 ALSA mixer) (Default)&quot;. Click it and you should see your new USB sound card. Again, mine displayed &quot;USB PnP Sound Device (Alsa Mixer)&quot;.&lt;/li&gt;
&lt;li&gt;Select the USB sound card.&lt;/li&gt;
&lt;li&gt;Click &quot;Make Default&quot; button.&lt;/li&gt;
&lt;li&gt;You can click &quot;Select Controls...&quot; which brings up a dialog for you to be able to select things it can use to change settings on your sound card. I selected everything.&lt;/li&gt;
&lt;li&gt;Make sure volume is up and USB soundcard is connected to either headphones or speakers. To verify, my speaker setup, I used the built-in audio output first before connecting USB sound card.&lt;/li&gt;
&lt;li&gt;Edit /etc/modprobe.d/alsa-base.conf with your favorite editor (sudo vi&amp;nbsp;/etc/modprobe.d/alsa-base.conf). I strongly recommend making a backup of this file. You can also follow this from an &lt;a href=&quot;https://learn.adafruit.com/usb-audio-cards-with-a-raspberry-pi/updating-alsa-config&quot; target=&quot;_blank&quot;&gt;Adafruit article &lt;/a&gt;as well.&lt;/li&gt;
&lt;li&gt;Find the line &quot;options snd-usb-audio index=-2&quot; and change it to &quot;options snd-usb-audio index=0&quot;.&lt;/li&gt;
&lt;li&gt;Add another line below the edited line: &quot;options snd_bcm2835 index=1&quot;&lt;/li&gt;
&lt;li&gt;Save the alsa-base.conf and reboot the pi (sudo reboot).&lt;/li&gt;
&lt;li&gt;speaker-test -c2 -D hw:0,0. This should work. You will hear white noise from left to right on your speakers.&lt;/li&gt;
&lt;li&gt;aplay -D hw:0,0 /usr/share/sounds/alsa/Front_Center.wav&lt;/li&gt;
&lt;li&gt;Success? Or did you get &quot;Channels count non available&quot;. If success, you can stop now and celebrate. Have some fun with SonicPi!&lt;/li&gt;
&lt;li&gt;sudo aplay -D hw:0,0 /usr/share/sounds/alsa/Front_Center.wav&lt;/li&gt;
&lt;li&gt;This probably worked. If so, the answer is simple. Edit the $HOME/.asoundrc (vi $/.asoundrc). Back up the original is again strongly recommended.&lt;/li&gt;
&lt;li&gt;Clear the existing contents of the .asoundrc.&lt;/li&gt;
&lt;li&gt;Add &quot;defaults.ctl.card 0&quot;&lt;/li&gt;
&lt;li&gt;Add &quot;defaults.pcm.card 0&quot;&lt;/li&gt;
&lt;li&gt;Add &quot;defaults.pcm.device 0&quot;&lt;/li&gt;
&lt;li&gt;Save .asoundsrc. Try &quot;aplay -D hw:0,0 /usr/share/sounds/alsa/Front_Center.wav&quot; again.&lt;/li&gt;
&lt;li&gt;Success? Excellent. Glad this guide can help. If you are still having issues: &lt;a href=&quot;http://archlinuxarm.org/forum/viewtopic.php?f=31&amp;amp;t=6392&quot; target=&quot;_blank&quot;&gt;this article&lt;/a&gt; and &lt;a href=&quot;https://bbs.archlinux.org/viewtopic.php?id=137026&quot; target=&quot;_blank&quot;&gt;this one too&lt;/a&gt; helped me figure out what was going.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
I wrote this guide up mainly for myself so I don&#39;t forget it and to use again. Hope it helps you as well.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/5701020232191110982/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=5701020232191110982' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/5701020232191110982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/5701020232191110982'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2015/05/getting-usb-sound-card-configured-for.html' title='Getting a USB sound card configured for Raspberry Pi 2'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-2756925457932696510</id><published>2015-02-02T21:21:00.000-05:00</published><updated>2015-02-02T21:21:14.473-05:00</updated><title type='text'>Why Smalltalk is the productivity king</title><content type='html'>I&#39;ve been thinking about why I&#39;m so much more productive in Smalltalk than any other language. The reason is because I&#39;m curious if you could bring some of it to other languages. So, what makes Smalltalk so special?&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Incremental compilation. &lt;/b&gt;There is no cognitive drift. Compilation happens at the method level when one saves the code. It&#39;s automatically linked in and can be executed. Smalltalkers enjoy programming in the debugger and changing code in a running program. The concept of having to restart an entire application is foreign to a Smalltalker. The application is always alive and running. In other languages, you code while the application is not running. Programming a live application is an amazing experience. I&#39;m shocked that it&#39;s hard to find a language that supports it. Java running the OSGi framework is the only example I can think of. But, one still has to compile a bundle (which is larger than a method).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Stored application state. &lt;/b&gt;Smalltalkers call it the image. At any point in time, you can save the entire state of the application even with a debugger open. I&#39;ve saved my image at the end of the day so that I could be at that exact moment the next morning. I&#39;ve also used it to share a problem that I&#39;m having with another developer so they can see the exact state. It takes less than a second to bring up an image. It has the current running state and compiled code. One never spends time waiting for compiles or applications to start up.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Self contained.&lt;/b&gt;&amp;nbsp;All of the source code is accessible inside the image. One can change any of it at any time. Every tool is written in Smalltalk. If one doesn&#39;t like how something works, one can change it. If one wants to add a feature, one is empowered to. Since everything is open, one can even change how the language works. It&#39;s programming without constraints.&amp;nbsp;The original refactoring tools were written in Smalltalk.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Freedom from files.&lt;/b&gt;&amp;nbsp;Allows Smalltalk to store the code in its own database. The shackles of the file system makes compilation and version control trickier. Smalltalk can incrementally index code to make searches quick and efficient. The structure of the code is not forced to fit into the file system mold.&lt;/li&gt;
&lt;/ul&gt;
Now, the question one has to ask is why don&#39;t we have these features in languages that we use now? Personally, I would love to be able to keep my application running and change the code as it runs. I just want to end productivity lost to application restarts and compilations.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/2756925457932696510/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=2756925457932696510' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/2756925457932696510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/2756925457932696510'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2015/02/why-smalltalk-is-productivity-king.html' title='Why Smalltalk is the productivity king'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-5950883906647500266</id><published>2014-05-02T12:58:00.002-05:00</published><updated>2014-05-02T12:58:35.026-05:00</updated><title type='text'>Pharo 3.0 Projects - JavaLoader and iTunes Parser</title><content type='html'>I&#39;ve been inspired recently with the new release of &lt;a href=&quot;http://pharo.org/&quot; target=&quot;_blank&quot;&gt;Pharo 3.0&lt;/a&gt;. I updated my &lt;a href=&quot;http://smalltalkhub.com/#!/~blabux/JavaLoader/&quot; target=&quot;_blank&quot;&gt;JavaLoader&lt;/a&gt; project and added a brand new project called &lt;a href=&quot;http://smalltalkhub.com/#!/~blabux/ITunesParser&quot; target=&quot;_blank&quot;&gt;iTunes Parser&lt;/a&gt;. The JavaLoader project is an old project that can load serialized java objects and Java classes. The iTunes Parser can load the xml iTunes library file. Check them out if you use Pharo 3.0 and give me any feedback.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/5950883906647500266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=5950883906647500266' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/5950883906647500266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/5950883906647500266'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2014/05/pharo-30-projects-javaloader-and-itunes.html' title='Pharo 3.0 Projects - JavaLoader and iTunes Parser'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-2147892704713773338</id><published>2013-11-17T11:00:00.002-05:00</published><updated>2013-11-17T11:00:38.584-05:00</updated><title type='text'>One Year Of Pomodoro</title><content type='html'>I gave my first Pomodoro talk this year at the Tampa Bar Camp. Needless to say, I&#39;m still a firm believer and practitioner of the technique. I&#39;ve spent this year experimenting with what works best and makes me more productive. It has been invaluable. Now, I do it slightly different than what is discussed in the &lt;a href=&quot;http://pomodorotechnique.com/&quot; target=&quot;_blank&quot;&gt;book&lt;/a&gt;, but I find productivity to be personal: do what works for you. For the most part though, I follow the technique strictly.&lt;br /&gt;
&lt;br /&gt;
Let me begin by describing my use of pomodoros. I begin every morning with a blank sheet of paper. I draw a line down the middle and on the top left write the date and &quot;Unplanned&quot; on the right. I then write every task that I need/want to accomplish today. I write left over work from the day before first. I put estimates next to each item by placing empty boxes for each pomodoro. &amp;nbsp;I then prioritize each task by placing numbers to each one based on urgency. With coffee in hand, I begin my day.&lt;br /&gt;
&lt;br /&gt;
I set my timer for 10 minutes and go through my email. Any requests get written down in unplanned and I put estimates on the task. I then determine urgency for each one and update my priorities accordingly. I try to keep my urgent unplanned work to a minimum. If any email needs a reply, I will try to respond immediately. If it will take more than the 10 minutes to respond, I will star the email to get back to it later. The point of the first 10 minutes is to get through my inbox. It&#39;s about minimizing distractions. If I have enough starred emails, I make an email task to get to in the afternoon. I don&#39;t prioritize this task. I want to use my productive morning time to do real work.&lt;br /&gt;
&lt;br /&gt;
For the rest of day, I work in 25 minute chunks with 5 minute breaks. I try to do 3-4 pomodoros followed by a longer 10 minute break, but most of my days get broken up with meetings anyway. I try to get in as many pomodoros as I can. For each one accomplished, I check off a box next to a task and put a mark on top of the page. The marks at the top allow me to see how productive I&#39;ve been that day. The marks on the boxes allow me to see how well I&#39;m estimating. If a task takes longer than what I have estimated, I draw a circle to notate that I under estimated. This is valuable data for learning.&lt;br /&gt;
&lt;br /&gt;
At the end of the day, I look back at what I accomplished and make some notes for what I need to do the next day. The day sheets are invaluable for determining productivity. When I first started the technique, I was shocked that I was finishing only 3-4 pomodoros a day. This means I was doing only 1.5-2 hours of productive work a day! This evidence allowed me to have direct and frank discussions with my management. This meant moving meetings around and minimizing which ones were really needed. It also forced me to manage my emails accordingly. Now, I get 6-8 pomodoros per 8 hour work day. It&#39;s still not to the level I would like, but I&#39;m constantly trying to figure out how to be more productive. I would like to get to 12 pomodoros per day eventually.&lt;br /&gt;
&lt;br /&gt;
That&#39;s the basics, but the most powerful part of the pomodoro is handling interruptions. This is what keeps me doing pomodoros. At work, I bought a children&#39;s timer that has a huge light on it. I got it as a huge visual clue for my co-workers . Now instead of interrupting, they will send me an IM or email. They know if it&#39;s urgent to send an IM and I will get back to them after my current pomodoro, otherwise send an email. I try to only check my emails twice a day.&lt;br /&gt;
&lt;br /&gt;
I use pomodoros on my off-time projects as well. It allows me to time box all the things that I want to do. I used pomodoros to write this blog post (it took 3). I love it for its simplicity and allows me to concentrate on all the things that I want to accomplish. It might not work for everyone, but I encourage you to least try it. After a year, pomodoros are an integral part of my work and I can&#39;t see myself abandoning them anytime in the future. It&#39;s the best technique for managing interruptions, estimating, and measuring productivity.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/2147892704713773338/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=2147892704713773338' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/2147892704713773338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/2147892704713773338'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2013/11/one-year-of-pomodoro.html' title='One Year Of Pomodoro'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-3934555553699805733</id><published>2013-02-18T10:19:00.004-05:00</published><updated>2013-02-18T10:19:35.648-05:00</updated><title type='text'>Java Reader Update</title><content type='html'>I just updated my old Java Squeak project to &lt;a href=&quot;http://ss3.gemstone.com/&quot; target=&quot;_blank&quot;&gt;SS3&lt;/a&gt; and &lt;a href=&quot;http://pharo-project.org/&quot; target=&quot;_blank&quot;&gt;Pharo&lt;/a&gt;. It now works with &lt;a href=&quot;http://www.pharo-project.org/pharo-download/beta-2-0&quot; target=&quot;_blank&quot;&gt;Pharo 2.0&lt;/a&gt;. You can find it &lt;a href=&quot;http://ss3.gemstone.com/ss/JavaReader.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. If you find any bugs, let me know. I plan on doing more with it in the future. Stay tuned. For &amp;nbsp;a quick reminder, it allows you to load Java class files and read in serialized streams. The only drawback right now is if the Java objects have customized read/write methods. But, I&#39;m working on a solution for that. There are tests to make sure all major functionality works.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/3934555553699805733/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=3934555553699805733' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/3934555553699805733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/3934555553699805733'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2013/02/java-reader-update.html' title='Java Reader Update'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-3578650733294850609</id><published>2012-06-22T10:29:00.000-05:00</published><updated>2012-06-22T10:29:46.448-05:00</updated><title type='text'>Pomodoro Technique</title><content type='html'>I was reading &lt;a href=&quot;http://www.amazon.com/The-Clean-Coder-Professional-Programmers/dp/0137081073/ref=sr_1_1?s=books&amp;amp;ie=UTF8&amp;amp;qid=1340377795&amp;amp;sr=1-1&amp;amp;keywords=clean+coder&quot;&gt;Robert Martin&#39;s excellent &quot;Clean Coder&quot;&lt;/a&gt; and he mentions a productivity tool called the &lt;a href=&quot;http://pomodorotechnique.com/&quot;&gt;&quot;Pomodoro Technique&quot;&lt;/a&gt;. The premise is simple. Work for 25 minutes, then take a 5 minute break. During a 25 minute period (called a Pomodoro), you concentrate on one and only one task. If you are interrupted, you deal with it once the 25 minutes is up. Sounded simple and I was looking for a way to increase my productivity.&lt;br /&gt;
&lt;br /&gt;
The first day that I tried it, I was enlightened and shocked. First, I was amazed how much progress I could make on a task in 25 minutes. I loved the 5 minute breaks for short walks. But, I was shocked how little productive time I got done in that first day. I only got through four Pomodoros. The rest of my day was meetings and helping my team mates. But, in that time, I got more accomplished than the previous day.&lt;br /&gt;
&lt;br /&gt;
I kept doing my work for the rest week using this simple technique. I discovered that I loved working this way. First, it was an effective way to manage interruptions. Instead of addressing an interruption immediately, I would simply delay until the end of the current Pomodoro. After a few days, everyone got the swing of it and supported me. Another one was taking the break in the middle of a task that spanned multiple Pomodoros. At first, it was hard and wanted to keep on working. But, I decided to stick with the program. What I found was that a lot of times, just the 5 minutes to walk away when I came back, my work would take surprising turns. It forced me to evaluate where I wanted to go at the beginning of the next Pomodoro. By the end of the week, I was getting more work done, tracking better on my estimates, and felt better about the work I was getting done even the number of Pomodoros was low. I was marking more tasks off my to do list than ever before.&lt;br /&gt;
&lt;br /&gt;
The next week I decided to read&amp;nbsp;&lt;a href=&quot;http://www.amazon.com/Pomodoro-Technique-Illustrated-Minutes-Pragmatic/dp/1934356506/ref=sr_1_1?ie=UTF8&amp;amp;qid=1340377701&amp;amp;sr=8-1&amp;amp;keywords=pomodoro+technique&quot;&gt;Pomodoro Technique Illustrated&lt;/a&gt; and the free &lt;a href=&quot;http://www.pomodorotechnique.com/&quot;&gt;ebook&lt;/a&gt;. And I made adjustments to how I was doing it based on what was in those books. When I got in the morning, I looked at my to do list and prioritized what I needed to get done that day. Next, I estimated how many Pomodoros it would take to complete the task. If the task was longer than 4 Pomodoros, I broke it up into smaller tasks. What I found out by doing this is that I could make head ways via 25 minute chunks on multiple projects. I could spend a Pomodoro on a bug as a break if I wanted to to help break up the monotony of a long task. I also noticed that I was getting more Pomodoros done because I wasn&#39;t jumping up at every interruption.&lt;br /&gt;
&lt;br /&gt;
Every day I&#39;m tweaking how I work within such a simple constraint of working for 25, break for 5.

In conclusion, the Pomodoro Technique will forever be something that I do to track work. I&#39;ve been amazed how much it has helped me thus far. I love that it&#39;s easy to track time on my projects, forces me to take mental breaks and exercise, breaks my flow in a good way, gives a graceful way to handle interruptions, allows me to&amp;nbsp;reassess&amp;nbsp;my work, and is simple. I&#39;ve even started to using it on my spare time projects, so I can better allocate time to the things that matter to me. I&#39;ve even playing around with the 30/30 off-shoot as well to handle free time and working on household chores. But, that is another blog post.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/3578650733294850609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=3578650733294850609' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/3578650733294850609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/3578650733294850609'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2012/06/pomodoro-technique.html' title='Pomodoro Technique'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-4270719035659251522</id><published>2011-10-26T21:26:00.001-05:00</published><updated>2011-11-19T08:49:47.314-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="inspiration"/><title type='text'>Lost two of my heros</title><content type='html'>This month I lost two of my heros: Steve Jobs and John McCarthy. As a child, I dreamed of being Steve Jobs. I admired him for what he accomplished and his impeccable showmanship. I learned so much from him and his vision. I&#39;m sad that I will never be able to meet him. &lt;br /&gt;
&lt;br /&gt;
When I got older and learned about how Xerox Parc and John Engelbart inspired the Mac, I found Lisp. My love affair with Lisp goes back to college when I didn&#39;t quite understand it, but thought it was strange yet elegant. The light eventually went on and the true power of macros and functional programming was eventually revealed. To this day, there is a source of amazement that comes with Lisp and I thank John McCarthy for that. I wish I could have met him as well. &lt;br /&gt;
&lt;br /&gt;
I can&#39;t express how I much these men touched my life without ever meeting them. They both hit the ball so far out of the park that they will be revered for generations to come. The bar has been set and I plan on standing on their shoulders. Thank you.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/4270719035659251522/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=4270719035659251522' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/4270719035659251522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/4270719035659251522'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2011/10/lost-two-of-my-heros.html' title='Lost two of my heros'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-8471312834123798783</id><published>2011-06-04T08:30:00.000-05:00</published><updated>2011-06-04T08:30:16.436-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="design"/><category scheme="http://www.blogger.com/atom/ns#" term="html"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><title type='text'>The days of templates are over</title><content type='html'>When I first started to work with web applications, it was just servlets and then came JSPs. At the time, I didn&#39;t like JSPs (and to this day I still don&#39;t). They seemed like a necessary evil that got the job done. The thing I found repulsive about them was the mix of server and client code together. The switching of contexts just made both look ugly and hard to maintain. But, it was easier than generating pages directly from servlets by hand. Of course, there were other solutions that I looked for, but nothing got away from the horrid markup. Then, I fell in love with Seaside which did away with markup and generated content through a custom DSL. It felt better to me and loved it until I realized that it was only for the developer, not the web page designer. It made their life harder. Now, we all know we should use minimal content and have CSS do the layout. But, in this modern world, you need folks who are experts at web page design. You can not and should not alienate them.&lt;br /&gt;
&lt;br /&gt;
Fast forward to now. Currently, I&#39;ve been using Javascript frameworks and working mainly from the front-end. The project I&#39;m currently working on is pure HTML/Javascript/CSS for the front-end with RESTful calls to the backend. I must admit, I had my reservations about this arrangement, but after working with it; it is the right thing to do. No more ugly markup. The separation of concerns is well in place. And finally, the web designer is allowed to concentrate on making a rich user experience and the developer to concentrate on business logic. Perfect.&lt;br /&gt;
&lt;br /&gt;
My feeling is that the days of template engines are over. It&#39;s a waste of time and all of them are a pain to debug. A pure Web 2.0 AJAX solution allows each to utilize their tools and do things separately. To me that is exciting and I will gladly leave ugly code behind.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/8471312834123798783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=8471312834123798783' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/8471312834123798783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/8471312834123798783'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2011/06/days-of-templates-are-over.html' title='The days of templates are over'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-8217092248247134439</id><published>2011-06-04T08:13:00.000-05:00</published><updated>2011-06-04T08:13:12.563-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="business"/><title type='text'>App Dev Today</title><content type='html'>I&#39;m pleased to announce the start of a new &lt;a href=&quot;http://appdevtoday.com&quot;&gt;venture&lt;/a&gt;. It&#39;s a new company to launch new mobile applications. The ball is just starting to roll and exciting times are ahead. We have some cool stuff up our sleeves and will be showing soon.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/8217092248247134439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=8217092248247134439' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/8217092248247134439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/8217092248247134439'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2011/06/app-dev-today.html' title='App Dev Today'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-6395796510261297454</id><published>2011-04-04T15:10:00.000-05:00</published><updated>2011-04-04T15:10:38.238-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Objective C"/><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><title type='text'>Easier Memory Release In Objective C with Blocks</title><content type='html'>I&#39;ve been getting my head around Objective C recently and remembering all that is great about about manual memory management. I found myself repeating code that either a) autoreleased or b) released with try finally loops. The autorelease puts a drag on your pool so you want to use it sparingly (with APIs where you don&#39;t know who will be calling it) and it&#39;s mentioned in several places in the Apple documentation to favor &quot;release&quot; over &quot;autorelease&quot;. So, that leaves me with option b in most of my code with a lot of boilerplate code. And I hate boilerplate code. Well, did some more reading and found out that blocks are a new thing in Objective C and I quickly whipped this up:&lt;br /&gt;
&lt;pre&gt;typedef void (^Monadic)(id value);
typedef id (^Niladic)();

-(void)use: (Niladic)calc during:(Monadic)monadic {
    id toUse = calc();
    @try {
        monadic(toUse);
    }
    @finally {
        [toUse release];
    }
}
&lt;/pre&gt;Basically, it allows you to send in one block to get the allocated object and then use it in a try finally. It automatically cleans up after itself! I then decided to try it out on some code:&lt;br /&gt;
&lt;pre&gt;-(IBAction)calculateClicked:(id) sender {
    [self 
     use: ^() { return [[Cents alloc] initWithString: [startView text]]; } 
     during: ^(id startAmount) {
         [self 
          use: ^() { return [[Cents alloc] initWithString: [eachYearAmountView text]]; }
          during: ^(id eachYearAmount) {
              [self
               use: ^() { return [[NSDecimalNumber alloc] initWithString: [interestView text]]; }
               during: ^(id years) {
                   Cents *answer = [startAmount
                          atRetirementAdd: eachYearAmount 
                          earning: years 
                          for: [[yearsView text] intValue]];
                   [resultView setText: [answer description]];
               } ];
          } ];
     } ];
}
&lt;/pre&gt;I think I made it too generic in that I now have to type &quot;^() { return [blah blah blah]; } every time. I realized I could get rid of those blocks and just pass in the object I want to clean up. Remove Niladic block and take two looks like this:&lt;br /&gt;
&lt;pre&gt;typedef void (^Monadic)(id value);
-(void)use:(id)toUse during:(Monadic)monadic {
    @try {
        monadic(toUse);
    }
    @finally {
        [toUse release];
    }
}
&lt;/pre&gt;And this is what it looks like when you use it:&lt;br /&gt;
&lt;pre&gt;-(IBAction)calculateClicked:(id) sender {
    [self 
     use: [[Cents alloc] initWithString: [startView text]]
     during: ^(id startAmount) {
         [self 
          use: [[Cents alloc] initWithString: [eachYearAmountView text]]
          during: ^(id eachYearAmount) {
              [self
               use: [[NSDecimalNumber alloc] initWithString: [interestView text]]
               during: ^(id years) {
                   Cents *answer = [startAmount
                          atRetirementAdd: eachYearAmount 
                          earning: years 
                          for: [[yearsView text] intValue]];
                   [resultView setText: [answer description]];
               } ];
          } ];
     } ];
}
&lt;/pre&gt;As long as the Monadic blocks stay on the stack we don&#39;t need to do the copy autorelease business on block objects. I like this code better than nested try finally code because I&#39;m not repeating the name of my variable to release in the clean up code. I&#39;m still not 100% happy with the code, but I&#39;ll keep playing around with other things until then. I do like the fact that it is simple. Just something I wanted to share as I learn Objective C.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/6395796510261297454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=6395796510261297454' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/6395796510261297454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/6395796510261297454'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2011/04/easier-memory-release-in-objective-c.html' title='Easier Memory Release In Objective C with Blocks'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-1593724462718627864</id><published>2011-03-11T19:19:00.000-05:00</published><updated>2011-03-11T19:19:45.866-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><title type='text'>Singleton Pattern in Dojo</title><content type='html'>Recently, I needed to have a singleton object. So, I came up with the following implementation to give me just that.&lt;br /&gt;
&lt;pre&gt;var makeSingleton = function (aClass) {
    aClass.singleton = function () {
        var localScope = arguments.callee;
        localScope.instance = localScope.instance || new aClass();
        return localScope.instance;
    };
    return aClass;
};
&lt;/pre&gt;&lt;br /&gt;
When declaring my class in Dojo, I did the following:&lt;br /&gt;
&lt;pre&gt;makeSingleton(dojo.declare(...));
&lt;/pre&gt;Then, to use it:&lt;br /&gt;
&lt;pre&gt;var instance = myClass.singleton();
&lt;/pre&gt;I like the fact with this implementation that it&#39;s obvious that I&#39;m creating a singleton object up front around the dojo.declare. Of course, there&#39;s nothing preventing someone from creating the class with new, but we could easily get around that with throwing an exception in our constructor after our singleton has been initialized.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/1593724462718627864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=1593724462718627864' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/1593724462718627864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/1593724462718627864'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2011/03/singleton-pattern-in-dojo.html' title='Singleton Pattern in Dojo'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-4779128830862386552</id><published>2011-01-22T10:55:00.001-05:00</published><updated>2011-01-24T10:29:05.316-05:00</updated><title type='text'>Functional Programming In Python 2</title><content type='html'>I gave a talk this month to the Tampa Bay Python User Group on functional programming in Python. It&#39;s actually the second part of the talk. I&#39;ve put the slides up for all to enjoy &lt;a href=&quot;http://www.blainebuxton.com/presentations/index.html&quot;&gt;here&lt;/a&gt;. If you have any questions or complaints, feel free to contact me. I welcome all comments.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/4779128830862386552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=4779128830862386552' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/4779128830862386552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/4779128830862386552'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2011/01/functional-programming-in-python-2.html' title='Functional Programming In Python 2'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-3517976467408025298</id><published>2011-01-22T10:28:00.000-05:00</published><updated>2011-01-22T10:28:54.267-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="agile"/><title type='text'>Collaboration Not Pairing</title><content type='html'>One of the tenants of Extreme Programming is pairing on all production code. At first, it seems to make perfect sense. Four eyes on all code is better than two, right? There is another partner to help solve issues, take over when one is tired, and to keep each other honest. What could be wrong with that? Plenty. I feel that pairing is good in spurts of time or as I like to say, &quot;Collaborate not pair&quot;. &lt;br /&gt;
&lt;br /&gt;
I want someone to help me on the hard problems. I don&#39;t need someone peering over my shoulder to make sure I&#39;m coding a for loop correctly. I think big picture. I want a pair to help with the design and make sure it is sound. The physical act of coding might have some hard problems too and I would like a pair for that as well. But, for the mundane boilerplate code, I don&#39;t need to watch someone type that.&lt;br /&gt;
&lt;br /&gt;
I believe you need a mix of alone time on a problem and together time to exchange ideas. Pairing constantly stops that and it&#39;s easy to fall prey to a stronger partner&#39;s ideas even if those ideas are bad. The stronger personality wins. This should not be the case. But, I&#39;ve seen it many times on XP projects.  A pair put into production code that was clearly not good and hard to maintain. The very thing pairing is supposed to prevent.&lt;br /&gt;
&lt;br /&gt;
This doesn&#39;t mean I don&#39;t want four eyes on all code either. I think a collaborator should read over every line of code that is written in isolation and ask questions. This is where time away is helpful. The partner brings an outside perspective than if the pair was sitting side by side. This prevents group think or one partner overbearing another. There&#39;s also the case where some developers are intimidated working with someone all of the time. They need to have space to properly think. These developers can be prone to letting a stronger partner always have their way. Again, not what we want.&lt;br /&gt;
&lt;br /&gt;
As you can see, I&#39;m not against pairing, but against constant pairing. Collaborate when necessary and make sure to leave time to think in isolation. You need both. You can&#39;t be all one side or the other. Either one all of the time is not healthy. But, how much collaboration versus alone time is needed? This is where you have to use your best judgement. Agility is about thinking and finding the right solution for the right situation. It&#39;s not a one size fits all world.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/3517976467408025298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=3517976467408025298' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/3517976467408025298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/3517976467408025298'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2011/01/collaboration-not-pairing.html' title='Collaboration Not Pairing'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-6098913205205081597</id><published>2011-01-21T08:14:00.002-05:00</published><updated>2011-01-21T10:49:03.388-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="design"/><title type='text'>Domain Driven Design Immersion</title><content type='html'>I&#39;ve been meaning to write about my experience at the Domain Driven Design Immersion training that I took back in November. But, I&#39;ve been so busy that I haven&#39;t had the time to put down my thoughts on it properly until today. First off, I had a great time; met many wonderful and intelligent people; and learned quite a few new techniques. Just given that, it was well worth the time. The course was simply fantastic.&lt;br /&gt;
&lt;br /&gt;
I read &lt;a target=&quot;_blank&quot;  href=&quot;http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215?ie=UTF8&amp;tag=wwwblainebuxt-20&amp;link_code=btl&amp;camp=213689&amp;creative=392969&quot;&gt;Domain-Driven Design&lt;/a&gt;&lt;img src=&quot;http://www.assoc-amazon.com/e/ir?t=wwwblainebuxt-20&amp;l=btl&amp;camp=213689&amp;creative=392969&amp;o=1&amp;a=0321125215&quot; width=&quot;1&quot; height=&quot;1&quot; border=&quot;0&quot; alt=&quot;&quot; style=&quot;border:none !important; margin:0px !important; padding: 0px !important&quot; /&gt; when it first came and fell in love with it. I&#39;ve read it several times and consider it one of the greatest books on design. It&#39;s a tome of knowledge on being practical in design and getting closer to mapping user language to code. There are no silver bullets, just great advice and a road map of thought to get there. Despite the book being well-written, there were questions I&#39;ve had when applying DDD throughout the years. I jumped at the chance to spend a week immersed in DDD and learn a few more tricks.&lt;br /&gt;
&lt;br /&gt;
The training was excellent: well-paced, interactive, and loads of discussion. DDD is something that you must practice and the training provides a lot of it. From hands on coding to white board design sessions, you get your mind in the middle of the whole process. The trainers guided discussion and encouraged us to be creative in our solutions: messy whiteboards are good! I&#39;ve been to a lot of training and seminars. Normally, little thought was given to pacing of the material. This was not the case with DDD Immersion. I felt there was an excellent mix of lecture, hands-on, and discussions. Each day felt like it went by too fast. Four days is not a lot of time to cram the amount of material that the DDD book covers, but the course materials provided abbreviated documents to bullet point the important ideas. I personally thought the materials made the course all worth it.&lt;br /&gt;
&lt;br /&gt;
Even if you have read the DDD book, I still think the training is worth it&#39;s weight in gold. I work with Eric on his &lt;a href=&quot;http://sourceforge.net/projects/timeandmoney/&quot;&gt;Time and Money library&lt;/a&gt; and I still got new ideas out of it. The training does add new material to the book and expands on Eric&#39;s new ideas concerning DDD. &lt;br /&gt;
&lt;br /&gt;
The one thing that I took from the training is it&#39;s all about practicing to get better at design. Eric has laid out a path of thought on design. It still takes ingenuity and playing around with ideas to be successful. Design is a creative process and it takes hard thinking to match the language of users into code. The training brings that home. I whole heartily recommend the training and would go again given the chance. The real world keep giving me problems where questions arise to the best way to tackle them. You can never stop learning.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/6098913205205081597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=6098913205205081597' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/6098913205205081597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/6098913205205081597'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2011/01/domain-driven-design-immersion.html' title='Domain Driven Design Immersion'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-4524569173963463725</id><published>2010-10-14T08:41:00.000-05:00</published><updated>2010-10-14T08:41:51.370-05:00</updated><title type='text'>Functional Python Talk In Tampa</title><content type='html'>Here&#39;s my presentation from last night for anyone that missed it.&lt;br /&gt;
&lt;iframe src=&quot;https://docs.google.com/present/embed?id=ddxg6bkv_20g893j6dg&quot; frameborder=&quot;0&quot; width=&quot;410&quot; height=&quot;342&quot;&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
I mentioned several books and articles as well.&lt;br /&gt;
&lt;a href=&quot;http://norvig.com/luv-slides.ps&quot;&gt;Peter Norvig&#39;s &quot;Tutorial On Good Lisp Programming Style&quot;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.freetechbooks.com/a-functional-pattern-system-for-object-oriented-design-t417.html&quot;&gt;Thomas Kuhne&#39;s &quot;Functional Pattern System For Object-Oriented Style&quot;&lt;/a&gt;&lt;br /&gt;
&lt;iframe src=&quot;http://rcm.amazon.com/e/cm?t=wwwblainebuxt-20&amp;o=1&amp;p=8&amp;l=bpl&amp;asins=0262011530&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr&quot; style=&quot;align:left;padding-top:5px;width:131px;height:245px;padding-right:10px;&quot;align=&quot;left&quot; scrolling=&quot;no&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;&lt;iframe src=&quot;http://rcm.amazon.com/e/cm?t=wwwblainebuxt-20&amp;o=1&amp;p=8&amp;l=bpl&amp;asins=0321112547&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr&quot; style=&quot;align:left;padding-top:5px;width:131px;height:245px;padding-right:10px;&quot;align=&quot;left&quot; scrolling=&quot;no&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;&lt;iframe src=&quot;http://rcm.amazon.com/e/cm?t=wwwblainebuxt-20&amp;o=1&amp;p=8&amp;l=bpl&amp;asins=0262560992&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr&quot; style=&quot;align:left;padding-top:5px;width:131px;height:245px;padding-right:10px;&quot;align=&quot;left&quot; scrolling=&quot;no&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;&lt;iframe src=&quot;http://rcm.amazon.com/e/cm?t=wwwblainebuxt-20&amp;o=1&amp;p=8&amp;l=bpl&amp;asins=026256100X&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr&quot; style=&quot;align:left;padding-top:5px;width:131px;height:245px;padding-right:10px;&quot;align=&quot;left&quot; scrolling=&quot;no&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;&lt;iframe src=&quot;http://rcm.amazon.com/e/cm?t=wwwblainebuxt-20&amp;o=1&amp;p=8&amp;l=bpl&amp;asins=0262562146&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr&quot; style=&quot;align:left;padding-top:5px;width:131px;height:245px;padding-right:10px;&quot;align=&quot;left&quot; scrolling=&quot;no&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;&lt;iframe src=&quot;http://rcm.amazon.com/e/cm?t=wwwblainebuxt-20&amp;o=1&amp;p=8&amp;l=bpl&amp;asins=0321125215&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr&quot; style=&quot;align:left;padding-top:5px;width:131px;height:245px;padding-right:10px;&quot;align=&quot;left&quot; scrolling=&quot;no&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/4524569173963463725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=4524569173963463725' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/4524569173963463725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/4524569173963463725'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2010/10/functional-python-talk-in-tampa.html' title='Functional Python Talk In Tampa'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-1398534689133712377</id><published>2010-08-29T12:20:00.000-05:00</published><updated>2010-08-29T12:20:45.864-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="design"/><category scheme="http://www.blogger.com/atom/ns#" term="inspiration"/><title type='text'>Imitation and Repetition</title><content type='html'>I was recently reading &lt;a target=&quot;_blank&quot;  href=&quot;http://www.amazon.com/Alice-Cooper-Golf-Monster-Becoming/dp/B002GJU2JW?ie=UTF8&amp;tag=wwwblainebuxt-20&amp;link_code=btl&amp;camp=213689&amp;creative=392969&quot;&gt;Alice Cooper, Golf Monster: A Rock &amp;#39;n&amp;#39; Roller&amp;#39;s 12 Steps to Becoming a Golf Addict&lt;/a&gt;&lt;img src=&quot;http://www.assoc-amazon.com/e/ir?t=wwwblainebuxt-20&amp;l=btl&amp;camp=213689&amp;creative=392969&amp;o=1&amp;a=B002GJU2JW&quot; width=&quot;1&quot; height=&quot;1&quot; border=&quot;0&quot; alt=&quot;&quot; style=&quot;border:none !important; margin:0px !important; padding: 0px !important&quot; /&gt; and had an epiphany. In one of the chapters Alice talks about the way to be great at anything. He explains one should mimic the greats by watching and then repeat what they do until it&#39;s natural. I immediately started to think about programming, of course. We all have programmers that we admire. For me, most of my admired heros are great writers. It&#39;s their advice that I adore. I soak their words in and then practice what they talk about. But, it&#39;s not the same as reading code. What Alice was talking about was studying what the greats do and repeating it until it&#39;s as natural as the way you breathe. Where can we find great code? I always felt my programming took a huge leap forward with Smalltalk. The reason I think that is now crystal clear: Smalltalk encourages you to read other people&#39;s code. All of the tools embrace reading code. If you don&#39;t know how to do something, you can search via the tools to find something similar and then repeat what they did. There is a plethora of patterns and good programming in any Smalltalk system. All of the GoF patterns came from Smalltalk originally.&lt;br /&gt;
&lt;br /&gt;
That&#39;s fine and dandy, but what about Java, Python, Ruby, or other developers? It&#39;s just as easy as finding an open source framework you love and diving head first into the code. Study it, practice writing in that style, and repeat until it feels natural. Open source gives us opportunities that only Smalltalk and Lisp did in the past: a limitless supply of software to study in any language we choose. But, this begs the question: How do I know I&#39;m studying good code? Alice touches on this in his book by saying that as you pass milestones in competence, you know what the next level looks like. Start with code that looks good to you now and keep practicing. For me, I strive for readability. How can I remove all noise until the code I write is nothing but the language of the problem I&#39;m trying to solve. I&#39;m always reading code to find new techniques for removing noise. I study code written in different languages and see how I can apply any new techniques in the language I am currently using. I&#39;ve found a lot of gems by studying from functional programming and applying them to object-oriented languages.&lt;br /&gt;
&lt;br /&gt;
This brings up another interesting observation. If it&#39;s good to read code and practice writing it, when should you use a new technique? For me, I always practice a new technique a lot before I apply it to production code. Normally, once a technique feels natural and I know it like the back of my hand. Most of the open source libraries I&#39;ve written have been to explore an idea that I saw somewhere else to play around with it. There&#39;s nothing worse than not having mastery and immediately applying it because it was new at the time. Be patient. Read, code, repeat. Always be reading and practicing. It&#39;s the only way to get better.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/1398534689133712377/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=1398534689133712377' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/1398534689133712377'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/1398534689133712377'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2010/08/imitation-and-repetition.html' title='Imitation and Repetition'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-5863889600808966165</id><published>2010-05-13T18:10:00.000-05:00</published><updated>2010-05-13T18:10:08.572-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Partial With Frozen Arguments In Any Position</title><content type='html'>Recently, I was working on a problem where I wish I could have frozen arguments using a partial, but could not. The reason was that I needed to freeze the last argument instead of the first. Here&#39;s a simple example of what I wanted my function to behave like:&lt;br /&gt;
&lt;pre&gt;def contains_three(string):
  return &#39;3&#39; in string&lt;/pre&gt;But, I wanted to define it like so:&lt;br /&gt;
&lt;pre&gt;contains_three = functools.partial(operator.__contains__, &#39;3&#39;)&lt;/pre&gt;But, partial only freezes the first arguments and you can&#39;t mix and match. I&#39;ve ran into this before and I thought it would be nice to define a partial function that would allow you to freeze arguments in any position. Here&#39;s my implementation:&lt;br /&gt;
&lt;pre&gt;def custom_partial(func, *const_args, **const_kwds):
    def result(*args,**kwds):
        args_iter=iter(args)
        def convert(value):
            if value is None:
                return args_iter.next()
            else:
                return value
        to_call = map(convert, const_args)
        new_kwds = const_kwds.copy()
        new_kwds.update(kwds)
        return func(*(to_call + list(args_iter)), **new_kwds)
    return result&lt;/pre&gt;Is there a test? Of course, there is...&lt;br /&gt;
&lt;pre&gt;from operator import __contains__
import unittest
class Test(unittest.TestCase):
    def testContains(self):
        has_three = custom_partial(__contains__, None, &#39;3&#39;)
        self.assertTrue(has_three(&#39;1234&#39;))
        self.assertFalse(has_three(&#39;124&#39;))&lt;/pre&gt;By looking at the test and code, the implementation I chose was to have the value of None to denote any argument I don&#39;t want to freeze. I could have created a placeholder value for it, but decided since I haven&#39;t had a need to freeze an argument with None to just leave it.&lt;br /&gt;
&lt;br /&gt;
Now, I&#39;m not excited about the implementation, but it satisfies my initial requirements. I&#39;m going to continue to work on this to come up with something more elegant, but for now it works.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/5863889600808966165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=5863889600808966165' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/5863889600808966165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/5863889600808966165'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2010/05/partial-with-frozen-arguments-in-any.html' title='Partial With Frozen Arguments In Any Position'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-8980114474671708568</id><published>2009-10-17T20:17:00.004-05:00</published><updated>2009-10-17T21:10:58.989-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="design"/><category scheme="http://www.blogger.com/atom/ns#" term="functional programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Devilishly Clever</title><content type='html'>I was doing my usual research on Python when I ran across this recipe to make tail recursive calls not blow the stack in Python: &lt;a href=&quot;http://code.activestate.com/recipes/474088/&quot;&gt;Tail Call Optimization Decorator&lt;/a&gt;. I read through the code and thought, &quot;Wow! This is devilishly clever!&quot; As a thought exercise, I think it&#39;s awesome. But, it got me thinking about clever and production code. In my opinion, clever is never good or wanted in production code. It&#39;s great to learn and understand clever code though. It&#39;s a great mental workout to keep you sharp.&lt;br /&gt;&lt;br /&gt;So, what&#39;s my point with all of this besides to say that clever is bad? The example in the above link is factorial (which as everyone knows is hated by me, but that&#39;s another story). But, the amazing thing about factorial examples are that they are dead simple, yet there&#39;s several ways to get the answer. Here&#39;s a few that I came up with:&lt;br /&gt;&lt;pre&gt;def reg_fact(x):&lt;br /&gt;    if x is 1:&lt;br /&gt;        return 1&lt;br /&gt;    return reg_fact(x - 1) * x&lt;br /&gt;&lt;br /&gt;def tail_fact(x):&lt;br /&gt;    def func(acc, x):&lt;br /&gt;        if x is 1:&lt;br /&gt;            return acc&lt;br /&gt;        return func(acc * x, x - 1)&lt;br /&gt;    return func(1, x)&lt;br /&gt;&lt;br /&gt;def not_rec_fact(x):&lt;br /&gt;    result = 1&lt;br /&gt;    for each in range(2, x + 1):&lt;br /&gt;        result *= each&lt;br /&gt;    return result&lt;br /&gt;&lt;br /&gt;def not_rec_fact_fancy(x):&lt;br /&gt;    return reduce(lambda result, each: result * each, range(1, x + 1))&lt;br /&gt;&lt;br /&gt;import operator&lt;br /&gt;def not_rec_fact_super_fancy(x):&lt;br /&gt;    return reduce(operator.mul, range(1, x + 1))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Each of these compute factorial. Amazingly, there&#39;s even more ways than what I listed (the math wizards in the audience know what they are). Now, think about this: Computing factorial is dead simple. What happens when we get to harder problems? Being clever can actually get in the way of making the code easy to understand. It might even kill performance. Let&#39;s think back to the devilishly clever code. The performance of making Python tail recursive is awful. Sure, it&#39;s pure and tail recursive, but in production code that is deadly. What we want is simple and to the point. It&#39;s why I generally like solutions that need less code. There&#39;s less noise to get in the way of understanding and generally can mean better performance as well.&lt;br /&gt;&lt;br /&gt;Real world problems are hardly ever as straightforward as factorial. The balancing act comes when you drop a solution because it&#39;s not working for whatever reason. Raising and catching exceptions so you can have a tail recursive factorial is overkill. It took more code than the non-recursive version. It begs for the programmer to know their tool set and to know how to solve problems in that tool set that are straightforward. Tail recursion is powerful in languages like Haskell and Erlang. But, there&#39;s always another way of doing things that can make more sense in the language you are using. In our case, the other ways were just as easy yet more scalable for our tool set. Food for thought the next time you go down the path of clever and end up writing more noise than solution.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/8980114474671708568/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=8980114474671708568' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/8980114474671708568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/8980114474671708568'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2009/10/devilishly-clever.html' title='Devilishly Clever'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-850214506054851332</id><published>2009-10-10T20:45:00.000-05:00</published><updated>2009-10-12T19:46:11.718-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Freezing Objects in Python</title><content type='html'>Someone stop me. I like freezing simple objects or what Eric Evans calls &quot;Value Objects&quot; in his excellent &quot;Domain Driven Design&quot; book. Python doesn&#39;t have immutable objects (ala freeze in Ruby) explicitly, but we can easily create it. Python gives us the power to get under its covers. Here&#39;s my implementation:&lt;br /&gt;&lt;pre&gt;class ValueObject(object):&lt;br /&gt;    def __setattr__(self, name, value):&lt;br /&gt;        if name == &#39;value&#39; and hasattr(self, &#39;value&#39;):&lt;br /&gt;            raise AttributeError(&quot;Can not change value attribute&quot;)&lt;br /&gt;        else:&lt;br /&gt;            self.__dict__[name] = value&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Do you have to ask? Yes, I made a test. Here they are:&lt;br /&gt;&lt;pre&gt;import unittest&lt;br /&gt;class Test(unittest.TestCase):&lt;br /&gt;&lt;br /&gt;    def testSimple(self):&lt;br /&gt;        class Cents(ValueObject):&lt;br /&gt;            def __init__(self, value):&lt;br /&gt;                self.value = value&lt;br /&gt;            def __str__(self):&lt;br /&gt;                return str(self.value) + &quot; cents&quot;&lt;br /&gt;        subject = Cents(5)&lt;br /&gt;        self.assertEquals(5, subject.value)&lt;br /&gt;        def set_value():&lt;br /&gt;            subject.value = 6&lt;br /&gt;        self.failUnlessRaises(AttributeError, set_value)&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/850214506054851332/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=850214506054851332' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/850214506054851332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/850214506054851332'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2009/10/freezing-objects-in-python.html' title='Freezing Objects in Python'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-2941573612963136192</id><published>2009-10-05T21:40:00.000-05:00</published><updated>2009-10-05T20:41:00.322-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>method_missing in Python</title><content type='html'>OK, I know there is a few implementations of this knocking around on the net already, but I&#39;m in learning mode. So, here&#39;s my implementation of Ruby&#39;s method_missing:&lt;br /&gt;&lt;pre&gt;class PossibleMissingAttribute(object):&lt;br /&gt;    def __init__(self, object, name):&lt;br /&gt;        self._object = object&lt;br /&gt;        self._name = name&lt;br /&gt;&lt;br /&gt;    def __call__(self, *args, **kwargs):&lt;br /&gt;        return self._object._method_missing(self._name, *args, **kwargs)&lt;br /&gt;    &lt;br /&gt;    def __str__(self):&lt;br /&gt;        return self.__class__.__name__ + &quot;: &quot; + str(self._object) + &quot;.&quot; + self._name&lt;br /&gt;    &lt;br /&gt;    def __getattr__(self, name):&lt;br /&gt;        return None&lt;br /&gt;    &lt;br /&gt;    def __nonzero__(self):&lt;br /&gt;        return False&lt;br /&gt;    &lt;br /&gt;class MethodMissingError(Exception):&lt;br /&gt;    def __init__(self, object, name, *args, **kwargs):&lt;br /&gt;        self.object = object&lt;br /&gt;        self.name = name&lt;br /&gt;        self.args = args&lt;br /&gt;        self.kwargs = kwargs&lt;br /&gt;&lt;br /&gt;    def __str__(self):&lt;br /&gt;        return repr(str(self.object) + &quot;.&quot; + self.name)&lt;br /&gt;&lt;br /&gt;class Missing(object):&lt;br /&gt;    def __getattr__(self, name):&lt;br /&gt;        return PossibleMissingAttribute(self, name)&lt;br /&gt;    def _method_missing(self, name, *args, **kwargs):&lt;br /&gt;        raise MethodMissingError(self, name, *args, **kwargs)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Three objects and that&#39;s it! One to be a placeholder when an argument is missing. One object to represent the MethodMissingError and the last to be an abstract class to inherit from. But, you could easily just put these methods anywhere. Here&#39;s my tests:&lt;br /&gt;&lt;pre&gt;import unittest&lt;br /&gt;&lt;br /&gt;class TestMissing(unittest.TestCase):&lt;br /&gt;    def test_missing(self):&lt;br /&gt;       class TestClass(Missing):&lt;br /&gt;           def __str__(self):&lt;br /&gt;               return self.__class__.__name__&lt;br /&gt;           def existing(self):&lt;br /&gt;               return &quot;i am&quot;&lt;br /&gt;           def _method_missing(self, name, *args, **kwargs):&lt;br /&gt;               return args[0]&lt;br /&gt;       self.assertEquals(&quot;am not&quot;, TestClass().missing(&quot;am not&quot;))&lt;br /&gt;       self.assertEquals(&quot;i am&quot;, TestClass().existing())&lt;br /&gt;       self.assertEquals(None, TestClass().missing.something_else_missing)&lt;br /&gt;       self.assertFalse(TestClass().missing)&lt;br /&gt;       self.assertEquals(&quot;PossibleMissingAttribute: TestClass.missing&quot;, str(TestClass().missing))&lt;br /&gt;       &lt;br /&gt;    def test_exception(self):&lt;br /&gt;        class TestClass(Missing):&lt;br /&gt;           def __str__(self):&lt;br /&gt;               return self.__class__.__name__&lt;br /&gt;        self.failUnlessRaises(MethodMissingError, lambda: TestClass().missing())&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You&#39;ve seen my implementation. Here&#39;s another one that I found on the net: &lt;a href=&quot;http://log.chemica.co.uk/?p=13&quot;&gt;method_missing in Python&lt;/a&gt;&lt;br /&gt;&lt;pre&gt;class MethodMissing(object):&lt;br /&gt;    def method_missing(self, attr, *args, **kwargs):&lt;br /&gt;        “”&quot; Stub: override this function “”&quot;&lt;br /&gt;        raise AttributeError(”Missing method %s called.”%attr)&lt;br /&gt;&lt;br /&gt;    def __getattr__(self, attr):&lt;br /&gt;        def callable(*args, **kwargs):&lt;br /&gt;            return self.method_missing(attr, *args, **kwargs)&lt;br /&gt;        return callable&lt;/pre&gt;&lt;br /&gt;Um, this version is much shorter than mine. It gets the same job done and is more obvious of what it is doing. Simply returning a function on __getattr__ is the best way to go. It&#39;s what my PossibleArgumentMissing was doing. But, where I tried to get all fancy using __call__ to mimic a function which caused my version to be longer. I was also trying to get the argument to come back to return false in if conditions and be almost like None (again, I&#39;m learning and was looking at what was possible). Simplest is best.&lt;br /&gt;&lt;br /&gt;This was a fun thought exercise. I love all the hooks Python provides to allow you to get underneath the hood if need be. I will be soon doing a post on descriptors and even decorators. I find Python tends to sway heavier on the functional side of programming versus object-oriented. I&#39;m loving the succinct, yet readable code. Too many languages get into the being so terse that they sacrifice readability or debugability (is that a word? Is now!).</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/2941573612963136192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=2941573612963136192' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/2941573612963136192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/2941573612963136192'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2009/09/methodmissing-in-python.html' title='method_missing in Python'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-8351826223694012036</id><published>2009-09-29T18:54:00.003-05:00</published><updated>2009-09-29T19:26:58.600-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="prototypes"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Prototypes in Python</title><content type='html'>I&#39;m in love with prototype-based languages, but there only a few to play with ECMAScript (Javascript) and Self. Since I&#39;m learning Python, I thought it would be a good experiment to implement prototypes in Python. For one thing, I would get to learn some of the meta capabilities and other advanced features. A pure thought experiment just for learning and seeing how far I could push another paradigm onto Python. Here is what I came up with:&lt;br /&gt;&lt;pre&gt;class Prototype(object):&lt;br /&gt;    def __init__(self, *args):&lt;br /&gt;        self._parents = []&lt;br /&gt;        for each in args:&lt;br /&gt;            self._parents.append(each)&lt;br /&gt;        &lt;br /&gt;    def clone(self, *args):&lt;br /&gt;        return self.__class__(self, *args)&lt;br /&gt;    &lt;br /&gt;    def __getattr__(self, name):&lt;br /&gt;        for each in self._parents:&lt;br /&gt;            try:&lt;br /&gt;                return getattr(each, name)&lt;br /&gt;            except AttributeError:&lt;br /&gt;                pass&lt;br /&gt;        raise AttributeError(name)&lt;/pre&gt;&lt;br /&gt;The implementation is suprisingly simple: three methods! &lt;br /&gt;&lt;br /&gt;The first is the initialize method for new instances. It takes a list of objects that we will use as the parents of our new object. Of course, by simply calling Prototype&#39;s constructor with no arguments, we get a clean object. I made the ability to have multiple inheritance simple because of Self.&lt;br /&gt;&lt;br /&gt;The second method is the clone method and it simply calls the constructor for another object makes itself the first parent with the rest of the arguments becoming the other parents. Nothing to it!&lt;br /&gt;&lt;br /&gt;The last method is the real meat. It only get called by the Python engine when an attribute fails to be looked up. All I do is call each parent and if one succeeds, it returns the answer. This is a depth first search of the parent hierarchy. Simple.&lt;br /&gt;&lt;br /&gt;And that&#39;s all we need to implement prototypes in Python. Now, I just need to explain some practical uses of this in some later blog entries.&lt;br /&gt;&lt;br /&gt;How do I know all of this works? Here&#39;s my tests:&lt;br /&gt;&lt;pre&gt;import unittest&lt;br /&gt;class Test(unittest.TestCase):&lt;br /&gt;&lt;br /&gt;    def testSimple(self):&lt;br /&gt;        parent = Prototype()&lt;br /&gt;        child = parent.clone()&lt;br /&gt;        &lt;br /&gt;        parent.value = 0&lt;br /&gt;        self.assertEquals(0, child.value)&lt;br /&gt;        child.value = 1&lt;br /&gt;        &lt;br /&gt;        self.assertEquals(1, child.value)&lt;br /&gt;        self.assertEquals(0, parent.value)&lt;br /&gt;        &lt;br /&gt;        self.failUnlessRaises(AttributeError, lambda:parent.unknown)&lt;br /&gt;    &lt;br /&gt;    def testMultipleParents(self):&lt;br /&gt;        parent1 = Prototype()&lt;br /&gt;        parent2 = Prototype()&lt;br /&gt;        child = parent1.clone(parent2)&lt;br /&gt;        &lt;br /&gt;        parent2.value = 2&lt;br /&gt;        self.failUnlessRaises(AttributeError, lambda:parent1.value)&lt;br /&gt;        self.assertEquals(2, child.value)&lt;/pre&gt;&lt;br /&gt;If anyone sees anything wrong in my implementation or un-Pythonic let me know. I&#39;m still learning, but I thought it would be cool to show my progress.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/8351826223694012036/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=8351826223694012036' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/8351826223694012036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/8351826223694012036'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2009/09/prototypes-in-python.html' title='Prototypes in Python'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-1492978342642582106</id><published>2009-09-13T14:55:00.006-05:00</published><updated>2009-09-13T19:28:43.278-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Constraints in Python</title><content type='html'>With every language that I learn, I pay close attention to my work flow. I take note of anything that gets in the way of getting my task accomplished. In a perfect language, I should never have to worry about the language ever. A free flow of ideas should come out. Whenever I find myself totally immersed in a problem, I keep track of what made it so. Recently, the one feature that surprised me the most was Python&#39;s forced indention. At first I thought, how nice not to use curly brackets to denote scope, but what about that white space? But, I put my best foot forward and worked on some code. I must admit that I love it now! It makes code more readable by keeping the rules consistent (you have to be or your code will have bugs). Formatting my code is now one less worry I have. I am forced to indent as I go along. This constraint is liberating in the fact that it allows me concentrate on the problem at hand and is one less thing to worry about. No more worrying about if the curly braces go on the same line or not depending on local coding standards. It makes code easier to read across Python programmers. In fact, I have yet to meet a Python program that I could not understand easily from first glance which is a rare accomplishment in other languages.&lt;br /&gt;&lt;br /&gt;I also love the constraint about one line lambdas. I thought it was going to drive me crazy, but I have embraced completely. It keeps your lambda functions short and sweet like they really should be. But, the best side effect is that if that lambda needs to grow, you simply move it out to a named function automatically making your code more readable. Excellent.&lt;br /&gt;&lt;br /&gt;Both of the features that I just mentioned are merely constraints that take away thinking about the language and force you to write readable code. I always like and embrace the design decisions to constrain the coder to make more maintainable code. The less I have to think about the language, the more time I spend on the problem I am trying to solve and that&#39;s the way it should be. It just amazed me that sometimes I find them in the strangest of ways. I would have never thought that forced indention or one lined lambdas would bring me so much coding pleasure.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/1492978342642582106/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=1492978342642582106' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/1492978342642582106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/1492978342642582106'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2009/09/constraints-in-python.html' title='Constraints in Python'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-8555391352317992865</id><published>2009-09-12T07:48:00.003-05:00</published><updated>2009-09-12T08:00:15.510-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="misc"/><title type='text'>The Dead Year</title><content type='html'>This blog has been dead for a year and it&#39;s not been a lack of passion. I had some rather large life changing events to deal with. I have emerged stronger than ever before and I plan to start posting regularly here again. To let you know what to expect, I hope to do some new articles on my exploration of Python and Django. I&#39;ve been enjoying my time with Python quite a bit. I also hope to spend some time digging into Google&#39;s V8 ECMAScript. It&#39;s time for me to kick this blog back into gear. Hold on!</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/8555391352317992865/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=8555391352317992865' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/8555391352317992865'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/8555391352317992865'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2009/09/dead-year.html' title='The Dead Year'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-5342945128336325010</id><published>2009-01-04T13:21:00.004-05:00</published><updated>2009-01-04T18:30:15.083-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="misc"/><title type='text'>Domain Change</title><content type='html'>Update your bookmarks from &lt;a href=&quot;http://www.blainebuxton.net&quot;&gt;blainebuxton.com&lt;/a&gt; to &lt;a href=&quot;http://www.blainebuxton.net&quot;&gt;blainebuxton.net&lt;/a&gt;. The new blog address is: &lt;a href=&quot;http://blog.blainebuxton.net&quot;&gt;blog.blainebuxton.net&lt;/a&gt;. I plan on to start blogging again soon in the next year. Things are going on that I&#39;d rather not discuss in a public forum. But, I will be back soon!</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/5342945128336325010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=5342945128336325010' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/5342945128336325010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/5342945128336325010'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2009/01/domain-change.html' title='Domain Change'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5772872.post-754245571082525377</id><published>2008-10-11T18:34:00.004-05:00</published><updated>2008-10-11T19:12:55.144-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="agile"/><category scheme="http://www.blogger.com/atom/ns#" term="XP"/><title type='text'>Forced Pairing</title><content type='html'>Let&#39;s be honest. I&#39;m not a big fan of &quot;forced&quot; pairing. I believe in active collaboration between cooperating team members. In other words, two people should pair if they want to. The energy of pairing is incredible when both partners are engaged and having fun. The code is better and so is the resultant design. It&#39;s the other side of the coin that I don&#39;t like and think the results are worse, even if the two programmers were working separately. A good pairing starts with the pair liking to work with one another. They don&#39;t have to see eye to eye, but they must enjoy the journey of working on code together. They will push and encourage each other to do better. A fun competition that will result in another problem being pushed past and the winner being a well-maintained system.&lt;br /&gt;&lt;br /&gt;&quot;Forced&quot; pairing is what XP advocates and I see a huge problem with it. The reason is if the pair doesn&#39;t like or respect one another, the code quality will be on par with that of the worst of the pair. When pairs don&#39;t get along, one side will disengage. When this happens, you get none of the benefits. The team still thinks its safe from doing code reviews because they had four eyes on all code. Not so. To ignore the effects of &quot;forced&quot; pairing is to ignore that the team is human.</content><link rel='replies' type='application/atom+xml' href='http://blog.blainebuxton.com/feeds/754245571082525377/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5772872&amp;postID=754245571082525377' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/754245571082525377'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5772872/posts/default/754245571082525377'/><link rel='alternate' type='text/html' href='http://blog.blainebuxton.com/2008/10/forced-pairing.html' title='Forced Pairing'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry></feed>