<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description> 
 
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-1136525-6']);
  _gaq.push(['_trackPageview']);
 
  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
  })();
 

A blog about the development and usage of GarlicSim, the open-source Pythonic framework for computer simulations.
Written by Ram Rachum, developer of GarlicSim.</description><title>GarlicSim blog</title><generator>Tumblr (3.0; @garlicsim)</generator><link>http://blog.garlicsim.org/</link><item><title>Silly Python riddle</title><description>&lt;p&gt;Here&amp;#8217;s a silly Python riddle for you.&lt;/p&gt;
&lt;p&gt;Today I opened up a Python 2.7 shell, and ran two commands in it.&lt;/p&gt;
&lt;p&gt;&lt;code&gt; &lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; f = lambda: g(&lt;strong&gt;???&lt;/strong&gt;)
&amp;gt;&amp;gt;&amp;gt; f()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt; &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;(Note that these are the only commands that I ran. You&amp;#8217;re not allowed to run any other commands before them.)&lt;/p&gt;
&lt;p&gt;The riddle: What&amp;#8217;s the &lt;em&gt;shortest&lt;/em&gt; thing you can put instead of &lt;strong&gt;???&lt;/strong&gt; so my second command would not raise an exception?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Edit:&lt;/strong&gt; I just posted it and people are already coming up with creative solutions! So now it&amp;#8217;s time to say: The winning solution is &lt;strong&gt;7 characters&lt;/strong&gt; long. Try to match that!&lt;/p&gt;
&lt;p&gt;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; An anonymous commenter on Hacker News &lt;a href="http://news.ycombinator.com/item?id=3373280"&gt;solved it&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;The solution:&lt;/p&gt;
&lt;p&gt;(Scroll down&amp;#8230;) &lt;/p&gt;
&lt;p&gt;(Scroll down&amp;#8230;) &lt;/p&gt;
&lt;p&gt;(Scroll down&amp;#8230;) &lt;/p&gt;
&lt;p&gt;(Scroll down&amp;#8230;) &lt;/p&gt;
&lt;p&gt;(Scroll down&amp;#8230;) &lt;/p&gt;
&lt;p&gt;(Scroll down&amp;#8230;) &lt;/p&gt;
&lt;p&gt;(Scroll down&amp;#8230;) &lt;/p&gt;
&lt;p&gt;(Scroll down&amp;#8230;) &lt;/p&gt;
&lt;p&gt;(Scroll down&amp;#8230;) &lt;/p&gt;
&lt;p&gt;(Scroll down&amp;#8230;) &lt;/p&gt;
&lt;p&gt;(Scroll down&amp;#8230;) &lt;/p&gt;
&lt;p&gt;(Scroll down&amp;#8230;) &lt;/p&gt;
&lt;p&gt;(Scroll down&amp;#8230;) &lt;/p&gt;
&lt;p&gt;(Scroll down&amp;#8230;) &lt;/p&gt;
&lt;p&gt;The solution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; f = lambda: g(&lt;strong&gt;(yield)&lt;/strong&gt;)
&amp;gt;&amp;gt;&amp;gt; f()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Funny, isn&amp;#8217;t it? I was surprised to see that the &lt;code&gt;yield&lt;/code&gt; keyword can be used in a lambda function. &lt;/p&gt;
&lt;p&gt;So when you type &lt;code&gt;f()&lt;/code&gt;, it just returns a generator. If you&amp;#8217;ll try to exhaust it, an exception will be raised because &lt;code&gt;g&lt;/code&gt; doesn&amp;#8217;t exist, but that&amp;#8217;s a new line :)&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s funny that in this case, Python seems to throw away the value of the lambda function! As we know, the &lt;code&gt;yield&lt;/code&gt; keyword actually forms an expression whose value is &lt;code&gt;None&lt;/code&gt;, unless you used the generator&amp;#8217;s &lt;code&gt;.send&lt;/code&gt; instead of &lt;code&gt;.next&lt;/code&gt;. So you could also use &lt;code&gt;.send&lt;/code&gt; to send in whatever value you want into the lambda function, and Python will just throw it away. Unless I&amp;#8217;m missing something.&lt;/p&gt;
&lt;p&gt;So that&amp;#8217;s the only case I can think of where Python completely throws away the value of a lambda function.&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/14506657016</link><guid>http://blog.garlicsim.org/post/14506657016</guid><pubDate>Tue, 20 Dec 2011 14:16:00 +0200</pubDate></item><item><title>The `coverage` module celebrates 10 years today!</title><description>&lt;p&gt;Today, December 4&lt;sup&gt;th&lt;/sup&gt; 2011, marks the tenth birthday of &lt;a href="http://pypi.python.org/pypi/coverage"&gt;the excellent &lt;code&gt;coverage&lt;/code&gt; module&lt;/a&gt;! Here is the &lt;a href="https://bitbucket.org/ned/coveragepy/src/740b68eb8fc5/CHANGES.txt#cl-580"&gt;changelog entry&lt;/a&gt; showing it was created exactly ten years ago, on December 4&lt;sup&gt;th&lt;/sup&gt;, 2001 by &lt;a href="http://garethrees.org/"&gt;Gareth Rees&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;coverage&lt;/code&gt; module is one of the most sturdy and reliable pillars of my development toolset. It&amp;#8217;s a hallmark of a great tool that you never have to spend too much with it&amp;#8212; When I want to check the statement-coverage of my tests, I just use &lt;code&gt;coverage&lt;/code&gt; (invoked via its Nose plugin), it just works, and then I can go back to writing my tests and ensuring they cover a big part of my code. You don&amp;#8217;t have to spend too much time with it for the simple reason that it very rarely breaks&amp;#8212; Which is not a trivial accomplishment for a tool that acts on every, single, line of code in your project.&lt;/p&gt;
&lt;p&gt;Kudos to &lt;a href="http://nedbatchelder.com/"&gt;Ned Batchelder&lt;/a&gt; for his excellent maintenance of the &lt;code&gt;coverage&lt;/code&gt; module! I&amp;#8217;m a relatively new user of &lt;code&gt;coverage&lt;/code&gt;, having used it only for about 2 years, if I remember correctly. So long-time users of &lt;code&gt;coverage&lt;/code&gt; may have a bigger perspective on this module than I do. But in the relatively short time that I&amp;#8217;ve been using it, Ned has been an exemplary maintainer, and the few tickets that I created on the bug tracker received his attention. Ned also made sure that &lt;code&gt;coverage&lt;/code&gt; supported Python 3.x &lt;em&gt;before it was cool&lt;/em&gt;, and on every release he takes the time to create Windows binaries of &lt;code&gt;coverage&lt;/code&gt; to help Windows users avoid having to compile it themselves.&lt;/p&gt;
&lt;p&gt;If every maintainer was as dedicated as Ned, the Python community would be in a better place today, and we would have probably already seen Python 3.x going into mainstream.&lt;/p&gt;
&lt;p&gt;Thank you, Gareth and Ned, for this wonderful module!&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/13739362516</link><guid>http://blog.garlicsim.org/post/13739362516</guid><pubDate>Sun, 04 Dec 2011 21:28:00 +0200</pubDate></item><item><title>Deadline for GarlicSim 0.7 cancelled</title><description>&lt;p&gt;Just when I finished one contract job and thought that I finally had time for some serious work on GarlicSim, I got a new contract job.&lt;/p&gt;
&lt;p&gt;Since the deadline for the GarlicSim 0.7 release has been postponed so many times, I&amp;#8217;m just going to cancel the deadline altogether. Sorry for the disappointment.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m angry at myself for not making the deadlines, but on the other hand I&amp;#8217;m happy about having a bunch of contract jobs. This will allow me to spend a lot of time on GarlicSim later on. My contract jobs have already allowed me to do a bunch of upgrades and improvements of my work environment (from hardware upgrades, through time-saving AutoHotKey scripts, to ergonomic upgrades), and that really helps me be more productive, both in my contract work and my open-source work.&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/11269744385</link><guid>http://blog.garlicsim.org/post/11269744385</guid><pubDate>Mon, 10 Oct 2011 13:30:35 +0200</pubDate></item><item><title>GUIs kick CLIs' asses</title><description>&lt;p&gt;Or, &lt;strong&gt;&amp;#8220;Hey programmers, did you know you can use a GUI with the keyboard?&amp;#8221;&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;This post is &lt;strong&gt;part 1&lt;/strong&gt; of the &lt;strong&gt;Unpopular Opinions&lt;/strong&gt; series. In this series I will present a few opinions of mine that go against what most other software developers think. If you disagree any of these posts, you know they&amp;#8217;re working. Please stay civil in the comments&amp;#8212; Criticizing my opinions is encouraged, as long as it&amp;#8217;s done in a &lt;a href="http://www.paulgraham.com/disagree.html"&gt;constructive and respectful manner&lt;/a&gt;.&lt;/blockquote&gt;
&lt;p&gt;One of the big things that have been bugging me ever since I became a professional developer is that &lt;strong&gt;most developers shun GUIs.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As a developer, I often get to hang out with other developers and see their tools and work processes— Sometimes in person, and sometimes online. I quickly found that almost all of them hate GUIs (&lt;a href="http://en.wikipedia.org/wiki/Graphical_user_interface"&gt;Graphical User Interfaces&lt;/a&gt;, i.e. visual programs with windows, buttons, menus, dialogs, etc.) Most programmers much prefer working with CLIs (&lt;a href="http://en.wikipedia.org/wiki/Command-line_interface"&gt;Command Line Interfaces&lt;/a&gt;, i.e. a textual shell.)&lt;a href="#note1"&gt;[1]&lt;!-- more --&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://garlicsim.org/images/complex_gui.png" align="right"/&gt;I found this baffling. Why would anyone enjoy working in front of a command-line interface, where you can&amp;#8217;t see shit and have to remember a ton of commands and flags by heart? Surely the programmer community is intelligent and passionate enough to pick the very best possible tools, so perhaps they have good reasons for preferring CLIs?&lt;/p&gt;
&lt;p&gt;After thinking about it for a while, my conclusion is that there are two main reasons that most programmers prefer CLIs to GUIs:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;
&lt;p&gt;Most GUIs suck. And when it comes to proper keyboard support, most GUIs suck &lt;em&gt;terribly&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Most programmers are ignorant about good GUIs.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;But before we get to that:&lt;/p&gt;
&lt;h2&gt;Let&amp;#8217;s compare GUIs and CLIs&lt;/h2&gt;
&lt;p&gt;There are a bunch of parameters that we can measure GUIs against CLIs on. The two parameters that are the most important for heavy computer users are &lt;strong&gt;Visibility&lt;/strong&gt; and &lt;strong&gt;Speed&lt;/strong&gt;.&lt;a href="#note2"&gt;[2]&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Visibility&lt;/h2&gt;
&lt;p&gt;The first parameter we&amp;#8217;re going to look at is &lt;strong&gt;visibility&lt;/strong&gt;. This is the 800-pound gorilla that most programmers seem to ignore.&lt;/p&gt;
&lt;p&gt;For the sake of an example, let&amp;#8217;s take a simple everyday task: Say you want to copy a bunch of files from one folder on your computer to another.&lt;/p&gt;
&lt;p&gt;If you were to do this with a CLI, you would do something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    cd ~/source_dir
    cp file_1 file_2 file_3 ~/target_dir&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the other side of the ring, if you were to do this with a GUI, you would navigate to the source folder in your explorer/nautilus/whatever, select the three files, copy them to the clipboard, navigate to the the target folder and hit paste.&lt;/p&gt;
&lt;p&gt;&lt;img height="266" width="400" title="Alex E. Proimos on flickr.com" alt="Alex E. Proimos on flickr.com" src="http://garlicsim.org/images/horse_blinders.png" align="right"/&gt;When you take the GUI route to copying files, you get to see a lot of stuff. Some of it may not be relevant to your current needs, but some of it might be. You will get to see all the other files in the source and target folders. You will get to see how much disk space all these files take. You will get to see any sibling folders that the source/target folder might have. You will get to see the file size of each of the files you&amp;#8217;re copying.&lt;/p&gt;
&lt;p&gt;When you take the CLI route to copying files, you&amp;#8217;re not seeing anything except the next shell prompt waiting for your next command. Sure, if you got everything right, you wouldn&amp;#8217;t really &lt;em&gt;need&lt;/em&gt; to see anything, because your 3 files just got copied and you completed the task. So what do you care about seeing all the data you would have seen in the GUI route?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Because keeping your eyes open is important.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Maybe when looking around the source folder, you&amp;#8217;d see that there was another file that you forgot to copy? Maybe you&amp;#8217;ll see that for some reason the target folder has more files that it should, which might indicate a problem with your system? Maybe you&amp;#8217;ll see that some impolite package-management tool that you previously ran left a bunch of &lt;code&gt;build&lt;/code&gt; folders that you should delete?&lt;/p&gt;
&lt;p&gt;When you take the GUI route, you&amp;#8217;re exposed to all of that stuff. You&amp;#8217;re more likely to catch possible problems, or have ideas about how to improve the system.&lt;/p&gt;
&lt;p&gt;So the scoreboard for &lt;strong&gt;Visibility&lt;/strong&gt; is:&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;GUI - Medium to High&lt;/strong&gt; (depending on GUI quality)&lt;br/&gt;&lt;strong&gt;CLI - Low to Medium&lt;/strong&gt; (depending on CLI quality)&lt;/blockquote&gt;
&lt;p&gt;And when our task isn&amp;#8217;t to copy files, but to write or debug a computer program, this point becomes &lt;em&gt;crucial&lt;/em&gt;. There&amp;#8217;s so much shit that&amp;#8217;s helpful to see when you&amp;#8217;re developing! If you just got an exception, you should see the running code, the entire stack, the values of all variables, documentation for the currently selected function, system I/O, and on and on. Each of these pieces of data might help you solve your problem in seconds instead of hours.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://garlicsim.org/images/zork.gif" align="right"/&gt;Now sure, you can obtain all of that data on the shell too. But having to explicitly ask for it by running a command is such a chore! And what more, every time you ask for more data, it pushes the previous data up and away, as if that data wasn&amp;#8217;t important anymore!&lt;/p&gt;
&lt;p&gt;Do you know what this reminds me of? It reminds me of old text-based games, where you would tell the computer &amp;#8220;Go west&amp;#8221;, &amp;#8220;Look around&amp;#8221;, &amp;#8220;Fight monster&amp;#8221; etc., and it would tell you things like &amp;#8220;You have killed the monster&amp;#8221; or &amp;#8220;You are in a room with exits to the north and east.&amp;#8221; Aside from the nostalgic feelings, playing a game like this totally sucks! You want to &lt;em&gt;see&lt;/em&gt; how many exits the room has! You want to &lt;em&gt;see&lt;/em&gt; the monster you&amp;#8217;re killing, in all its gory detail! And this is true whether that monster is a grue or a segfault.&lt;/p&gt;
&lt;h2&gt;Speed&lt;/h2&gt;
&lt;p&gt;Now we&amp;#8217;re getting to our second parameter: &lt;strong&gt;Speed&lt;/strong&gt;. The opposite of speed, when it comes to computing tasks, can be called &lt;strong&gt;friction&lt;/strong&gt;. If you have to click in seven different places to finish a task, then that&amp;#8217;s a lot of friction, and that makes for a slow process and a sad user.&lt;/p&gt;
&lt;p&gt;Speed is obviously a crucially important parameter. When you spend 8 hours a day doing tasks on the computer, the speed with which you do the tasks makes for a night-and-day difference. Sometimes you manage to shorten a 10-second task to a 2-second task, which is nothing short of an orgasm for a productivity-minded developer. But even cutting a task down from 3 seconds to 2 seconds is a considerable improvement. Remember— We&amp;#8217;re sitting in front of that freaking computer &lt;em&gt;all day long.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s important to note that speed is important &lt;em&gt;not only&lt;/em&gt; because of the time you save, but because computer tasks are usually done in order to achieve some greater goal. That greater goal often requires a bunch of subtasks, and as each of these subtasks becomes more complicated and slow, you lose sight of your original goal. Doing tasks fast allows your train of thought to go faster.&lt;/p&gt;
&lt;p&gt;Okay, so how do CLIs fare against GUIs in the parameter of speed?&lt;/p&gt;
&lt;p&gt;Speed is the old standby of CLI-loving programmers. &amp;#8220;CLIs are so must faster than GUIs! A GUI is so cumbersome, you have to click here and click there, navigate through menus&amp;#8230; With a CLI, you just press a few keys, hit enter, and presto, it&amp;#8217;s done!&amp;#8221;&lt;/p&gt;
&lt;p&gt;I beg to differ.&lt;/p&gt;
&lt;p&gt;The scoreboard for &lt;strong&gt;Speed&lt;/strong&gt;, which I will promptly explain, is:&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;GUI - Low to High&lt;/strong&gt; (depending on GUI quality)&lt;br/&gt;&lt;strong&gt;CLI - Medium to High&lt;/strong&gt; (depending on CLI quality)&lt;/blockquote&gt;
&lt;p&gt;The CLIs&amp;#8217; score of &amp;#8220;Medium to High&amp;#8221; is, on average, better than the GUIs&amp;#8217; score of &amp;#8220;Low to High&amp;#8221;; but when it comes to software, where copying costs are minimal, the best program tends to make all the other alternatives extinct. So in the long run we care more about the best program rather than the average program, so GUIs and CLIs end up pretty close to each other on the all-important &lt;strong&gt;speed&lt;/strong&gt; parameter.&lt;/p&gt;
&lt;p&gt;&amp;#8220;But wait,&amp;#8221; the Vim fanboy cries, &amp;#8220;how the hell could a GUI have anything close to a &amp;#8220;high&amp;#8221; speed rating?&amp;#8221;&lt;/p&gt;
&lt;p&gt;If you don&amp;#8217;t know the answer to that question, I want you to really listen to what I&amp;#8217;m about to say next, and try hard to remember it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Because GUIs can be controlled with the keyboard!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Phew, that felt good! Now let&amp;#8217;s explain.&lt;/p&gt;
&lt;p&gt;The reason that programmers see GUIs as so much slower and more cumbersome than CLIs is that they try to operate them with the mouse. Working with the mouse is terribly, terribly slow. When you&amp;#8217;re working with the mouse, you don&amp;#8217;t have muscle memory. You always have to look at the screen for the next button or next menu item that you want to click. Not to mention that the mouse is more conducive to RSI than the keyboard, and this can be a serious health problem for heavy computer users.&lt;/p&gt;
&lt;p&gt;To take a simple example: After you&amp;#8217;ve learned to copy-paste by pressing &lt;code&gt;Ctrl-C&lt;/code&gt; and &lt;code&gt;Ctrl-V&lt;/code&gt;, you don&amp;#8217;t need to think about them anymore; those movements become second nature. Your body and mind are good at memorizing these kinds of tasks, and before you know it you&amp;#8217;ll be &lt;code&gt;Ctrl-C&lt;/code&gt;&amp;#8216;ing and &lt;code&gt;Ctrl-V&lt;/code&gt;&amp;#8216;ing without even thinking about it, like a pianist doesn&amp;#8217;t even think about which piano keys he&amp;#8217;s hitting. But if you were to try this with the mouse, it won&amp;#8217;t work: You&amp;#8217;ll always have to be on the lookout for the context menu after right-clicking, and then visually search for the &amp;#8220;copy&amp;#8221; item and click it&amp;#8230; &lt;em&gt;Friction friction friction.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Not to mention that when you&amp;#8217;re using the mouse, you constantly have to move your right hand from the mouse to the keyboard and back, and that sucks.&lt;/p&gt;
&lt;p&gt;And programmers often do tasks much more complicated than copy-pasting, making this point so much stronger.&lt;/p&gt;
&lt;p&gt;So we all agree: Mice suck, keyboards rock!&lt;/p&gt;
&lt;p&gt;But, but, but&amp;#8230; A good GUI can be controlled with the keyboard! A good GUI can be operated completely with the keyboard, and has good keyboard shortcuts for the most common tasks.&lt;/p&gt;
&lt;p&gt;&lt;img align="right" src="http://garlicsim.org/images/git_checkout.jpg" width="326" height="422"/&gt;For example, let&amp;#8217;s look at a program I use everyday and has both a GUI and CLI interface: &lt;a href="http://en.wikipedia.org/wiki/Git_(software)"&gt;Git&lt;/a&gt;. Say I want to check-out a branch, something I do dozens of times a day. If I&amp;#8217;d want to do that with the CLI, I&amp;#8217;d type &lt;code&gt;git checkout master&lt;/code&gt;. With autocompletion in place, I will have to make exactly 12 keypresses (namely, &lt;code&gt;git chec{TAB}m{Tab}{Enter}&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;What about the GUI? Sure, if I&amp;#8217;ll try using a mouse it will be an epic fail, but with the keyboard I can do &lt;code&gt;{Ctrl-O}ma{Enter}{Enter}&lt;/code&gt;, which makes for exactly 6 keypresses. &lt;strong&gt;It&amp;#8217;s twice as fast at the CLI version, i.e. half of the friction!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now sure, some tasks can turn out to be faster on a GUI and others can be faster on a CLI, but when you pit the best GUIs against the best CLIs, they&amp;#8217;re in the same league.&lt;/p&gt;
&lt;h2&gt;So why do programmers still prefer CLIs?&lt;/h2&gt;
&lt;p&gt;Now we can get back to the two items I mentioned at the beginning of the article, and expand on them. Those are the two main reasons that programmers prefer CLIs to GUIs:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Most GUIs suck. And when it comes to proper keyboard support, most GUIs suck &lt;em&gt;terribly&lt;/em&gt;.&lt;/strong&gt; It seems that most developers of GUI apps don&amp;#8217;t care so much about keyboard-accessibility. It&amp;#8217;s all too common to see desktop apps that simply cannot be controlled with the keyboard. Buttons that cannot be pressed, menus that cannot be opened, scrollbars that cannot be moved with the arrow keys.&lt;/p&gt;
&lt;p&gt;This is annoying enough in mainstream software that&amp;#8217;s mostly intended for non-technical people, but the astounding thing is that &lt;strong&gt;many open-source programs that are made &lt;em&gt;for&lt;/em&gt; developers &lt;em&gt;by&lt;/em&gt; developers are not keyboard-usable!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I find this completely shocking. The same programmers that preach about how Vim is so much more productive than an IDE because you get to use the keyboard, suddenly put on a different face when it&amp;#8217;s time for them to make GUIs, for other programmers no less!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Most programmers are ignorant about good GUIs.&lt;/strong&gt; Because some GUIs are good. Some GUIs have great keyboard support. Microsoft is one company that really shines in this regard. I challenge you to find one action in Windows, or in any other Microsoft product, that can be done with the mouse but not with the keyboard.&lt;/p&gt;
&lt;p&gt;So good GUIs exist. They can be hard to find, but hey, a lot of good software is. Google Chrome has good keyboard support. Mac and Ubuntu have okay keyboard support. Wing IDE has good keyboard support. PuTTY has great keyboard support.&lt;/p&gt;
&lt;p&gt;And of course, these GUI programs usually have much better visibility than their CLI counterparts, making them more productive programs overall.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;h2&gt;Final words&lt;/h2&gt;
&lt;p&gt;I want to stress out that what I did here is a comparison between the &lt;em&gt;very best&lt;/em&gt; GUIs and the &lt;em&gt;very best&lt;/em&gt; CLIs. It takes time to find good GUI programs that can be operated with the keyboard. That&amp;#8217;s tough. It takes time before you can surround yourself in excellent GUI tools to help you do your job. But it&amp;#8217;s possible, and eventually, it&amp;#8217;s the optimal way to work.&lt;/p&gt;
&lt;p&gt;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&lt;/p&gt;
&lt;p&gt;&lt;a name="note1" id="note1"&gt;[1]&lt;/a&gt; - Actually there are some communities of programmers where most of the members like GUIs, but these are usually communities of developers that work in environments like Dot-Net and Java.&lt;/p&gt;
&lt;p&gt;&lt;a name="note2" id="note2"&gt;[2]&lt;/a&gt; - One parameter that is very important for non-hardcore users, and still somewhat important even for hardcore users, is &lt;strong&gt;Discoverability&lt;/strong&gt;, i.e. being able to easily see all the different options and commands that a program gives you. GUIs obviously beat CLIs big-time in this parameter.&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/9875143930</link><guid>http://blog.garlicsim.org/post/9875143930</guid><pubDate>Tue, 06 Sep 2011 15:17:00 +0300</pubDate></item><item><title>Quick riddle</title><description>&lt;p&gt;Here&amp;#8217;s a quick riddle:&lt;/p&gt;
&lt;p&gt;You owe your friend two Dollars. You have a $5 bill, but your friend has only a $1 coin for change.&lt;/p&gt;
&lt;p&gt;What would be a fair way to settle your debt that would not require you to get more change?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Answer:&lt;/strong&gt; You toss the coin. If you win, you don&amp;#8217;t give your friend anything. If your friend wins, you give him the $5 and he gives you back $1, so he gets $4. His expectation is $4 * 1/2 = $2, which is exactly fair.&lt;/p&gt;
&lt;p&gt;Thanks for all the people who posted their answers in the comments!&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/9799355938</link><guid>http://blog.garlicsim.org/post/9799355938</guid><pubDate>Sun, 04 Sep 2011 22:12:00 +0300</pubDate></item><item><title>A Git user's first (and hopefully last) foray into SVN-land</title><description>&lt;p&gt;&lt;img align="right" src="http://garlicsim.org/images/jump_fail.jpg" alt="By Asthma Helper at flickr.com" width="213" height="237"/&gt;I belong to a rare breed of programmers: I was born and raised on Git. It&amp;#8217;s the only version-control system that I&amp;#8217;ve ever used. This is my personal story of how I had to use SVN temporarily for a contract project.&lt;/p&gt;
&lt;p&gt;Now, I know there are a million of blog posts out there saying &amp;#8220;Ooh, look how much better Git is than SVN!&amp;#8221; I&amp;#8217;m not trying to tell people something they don&amp;#8217;t already know about Git, SVN, and the difference between them&amp;#8212; I&amp;#8217;ll just be telling my own personal story and my own impressions of SVN.&lt;!-- more --&gt;&lt;/p&gt;
&lt;h2&gt;Beginnings&lt;/h2&gt;
&lt;p&gt;I started my programming comeback about 3 years ago. When I was a child, I programmed a lot&amp;#8212; I was taught Basic in third grade, and I spent a lot of time of my elementary school and junior high making various little programs in C and Pascal. But I took a long hiatus from programming starting at about 10th grade, because I was frustrated with how many stupid technical details were involved in programming.&lt;/p&gt;
&lt;p&gt;That hiatus ended about 3 years ago as I started learning Python, programming computer simulations for my Physics research, and about a year after that became a professional programmer. By the way, the main reason I chose Python is because &lt;a href="http://paulgraham.com"&gt;Paul Graham&lt;/a&gt; mentioned it favorably in one of his essays.&lt;/p&gt;
&lt;h2&gt;Starting out with Git&lt;/h2&gt;
&lt;p&gt;How did I start out with version control? I saw the term &amp;#8220;GitHub&amp;#8221; being thrown around a lot on &lt;a href="http://news.ycombinator.com/"&gt;Hacker News&lt;/a&gt;. It seemed to be something everyone liked, so I figured I&amp;#8217;ll try putting my project &lt;a href="http://garlicsim.org"&gt;GarlicSim&lt;/a&gt; there. I learned Git. It took a while, because I was still not very technical, but eventually I got the hang of it enough to work in a single branch.&lt;/p&gt;
&lt;p&gt;After a while, I understood what branches meant. I understood that I was able to create alternate versions of my code, work on them as much as I want, and decide at my leisure whether they should be merged into &lt;code&gt;master&lt;/code&gt; and become an official part of my project.&lt;/p&gt;
&lt;p&gt;I was happy. Branches are awesome.&lt;/p&gt;
&lt;h2&gt;I heard about SVN&amp;#8230;&lt;/h2&gt;
&lt;p&gt;At some point I heard about SVN. I heard that it was something like a predecessor to Git.&lt;/p&gt;
&lt;p&gt;What I imagined in my mind was that SVN was to Git what Windows 98 was to Windows XP. I imagined that SVN was just a crappier version of Git. Like, same idea, same workflow, just with more annoyances and less polish.&lt;/p&gt;
&lt;p&gt;That perception changed when I got my first programming job.&lt;/p&gt;
&lt;h2&gt;First contact with SVN&lt;/h2&gt;
&lt;p&gt;Then I started programming professionally. I was hired by an Israeli startup to work on a Django project. I was kinda surprised to learn that they were using SVN. I figured that a technology startup would, you know, &lt;em&gt;care about technology&lt;/em&gt;. But I said, &amp;#8220;Meh, so I&amp;#8217;ll just have to use Windows 98 for a while instead of XP, I could live with that.&amp;#8221;&lt;/p&gt;
&lt;p&gt;Oh boy.&lt;/p&gt;
&lt;p&gt;So I was just about to learn SVN. This is a dramatization of the conversation I had with that company&amp;#8217;s chief developer: (I ask you to read the text in &lt;em&gt;italics&lt;/em&gt; in John Cleese&amp;#8217;s famous &lt;a href="http://youtu.be/sFBOQzSk14c?t=59s"&gt;surprised voice&lt;/a&gt;.)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Me: Hey man, I wanna make a small change to the code to add [Feature X], I&amp;#8217;ll just make a little branch, alright?&lt;/p&gt;
&lt;p&gt;Chief developer: &lt;em&gt;What?!&lt;/em&gt; You&amp;#8217;re gonna make a &lt;em&gt;branch&lt;/em&gt;?!&lt;/p&gt;
&lt;p&gt;Me (taken back): Eh, yeah, a branch. So, you know, I could make changes in it without affecting our &lt;code&gt;master&lt;/code&gt;, or &lt;code&gt;trunk&lt;/code&gt;, or whatever?&lt;/p&gt;
&lt;p&gt;Chief developer: And how are we supposed to put the changes back into our &lt;code&gt;trunk&lt;/code&gt;?!&lt;/p&gt;
&lt;p&gt;Me (totally freaked out at this point): Eh, merge them back?&lt;/p&gt;
&lt;p&gt;Chief developer: &lt;em&gt;Merge? MERGE?!&lt;/em&gt; That&amp;#8217;s a mighty big word for someone your size!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And then followed a conversation in which he explained to me that branching-n-merging in SVN is really fucking complicated. I don&amp;#8217;t remember exactly what he said was required, but it changed my perception of SVN from:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;#8220;SVN is a slightly crappier version of Git.&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;#8220;SVN is a version of Git in which every time you want to start a branch or merge it back, you have to sacrifice a young virgin to the source-control gods.&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I was not happy.&lt;/p&gt;
&lt;p&gt;Luckily, the chief developer was considerate of me, and the company was small enough (only a handful of people), so he agreed that we&amp;#8217;ll just move our entire product to Git.&lt;/p&gt;
&lt;p&gt;I was saved at last moment from the atrocities of SVN.&lt;/p&gt;
&lt;p&gt;Until now.&lt;/p&gt;
&lt;h2&gt;SVN strikes back&lt;/h2&gt;
&lt;p&gt;Recently I got a nice contract job. And, like any other contract job after my initial trauma with SVN, I made sure to ask that the job was in Git &lt;em&gt;before&lt;/em&gt; I started the job. Unfortunately, despite being told that the job was in Git, it turned out that the job was in SVN, and that we&amp;#8217;d move to Git &amp;#8220;after the deadline.&amp;#8221;&lt;/p&gt;
&lt;p&gt;I was not happy. It turned out that I had to learn SVN after all.&lt;/p&gt;
&lt;p&gt;I had my brother give me a crash course on SVN via phone. My brother&amp;#8217;s a C++/Java programmer, and he had to use SVN for a while, so he agreed to help me with it. He has experience with Git so he was in a good position to explain the differences between the two. I primarily remember him explaining to me about branches.&lt;/p&gt;
&lt;p&gt;Now, I remember seeing the &amp;#8220;branches&amp;#8221; folder in the SVN repo. I thought it was pretty weird to keep branches in a folder, but whatever. I assumed that the stuff in the &amp;#8220;branches&amp;#8221; folder was like the stuff in the &amp;#8220;.git&amp;#8221; folder in Git: Magic data that contains all your branches and allows you to switch to them at will.&lt;/p&gt;
&lt;p&gt;Then my brother explained to me that this is not the case. I remember this part of our phone conversation pretty well, because at that point I was sitting on my knees on the carpet, with my head in my hands, looking down into the seat of my office chair. He explained that SVN doesn&amp;#8217;t &lt;em&gt;really&lt;/em&gt; have branches, it&amp;#8217;s just a folder called &amp;#8220;branches&amp;#8221; that you manually copy your code into.&lt;/p&gt;
&lt;p&gt;I was not happy.&lt;/p&gt;
&lt;p&gt;Though, on the other hand, it was kind of a relief; it was relieving to know that SVN doesn&amp;#8217;t even &lt;em&gt;try&lt;/em&gt; to do branches. Because God knows how badly they would fuck it up if they would have tried to. Copy-pasting folders is major bullshit, but at the very least it&amp;#8217;s predictable; when you use &lt;code&gt;mv&lt;/code&gt; or &lt;code&gt;cp&lt;/code&gt;, you know exactly what you&amp;#8217;re getting, which is something you can&amp;#8217;t say about &lt;code&gt;svn&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;That partial relief nonwithstanding, the whole &amp;#8220;branches&amp;#8221; thing in SVN is utterly ridiculous. In the past when people told me &amp;#8220;SVN has branches too!&amp;#8221; I knew that something wasn&amp;#8217;t right and I just assumed that SVN branches suck, but now with this new knowledge I can answer in confidence, &amp;#8220;No, SVN does &lt;em&gt;not&lt;/em&gt; have branches, it merely has a folder called &amp;#8220;branches&amp;#8221;, which is a far cry from having actual branches.&amp;#8221;&lt;/p&gt;
&lt;p&gt;You know what SVN&amp;#8217;s &amp;#8220;branches&amp;#8221; folder is like? It&amp;#8217;s like taking an A4 paper from your printer, drawing a &lt;a href="http://en.wikipedia.org/wiki/DeLorean_time_machine#Flux_capacitor"&gt;Flux Capacitor&lt;/a&gt; on it, hanging it in your car and declaring with a satisfied grin, &amp;#8220;My car&amp;#8217;s a DeLorean time machine! I can go back in time!&amp;#8221;&lt;/p&gt;
&lt;h2&gt;SVN Ignore&lt;/h2&gt;
&lt;p&gt;One other thing I had to deal with in SVN was doing &amp;#8220;SVN ignore&amp;#8221; (I don&amp;#8217;t know the SVN jargon for it.) Basically I was looking for the SVN equivalent of &lt;code&gt;.gitignore&lt;/code&gt;: A list of file patterns that do not get source-controlled, ever. This is very useful for build products, files containing passwords, user-uploaded static content, etc.&lt;/p&gt;
&lt;p&gt;Now in Git, you just have a file called &lt;code&gt;.gitignore&lt;/code&gt; in the root of your repo, and in that file you write the file patterns that should be git-ignored, like &lt;code&gt;*.pyc&lt;/code&gt; or &lt;code&gt;build&lt;/code&gt;. You save the file, and that&amp;#8217;s it. I assumed that there would be a similar mechanism in SVN.&lt;/p&gt;
&lt;p&gt;You can probably guess where this is going by now.&lt;/p&gt;
&lt;p&gt;It turned out that SVN&amp;#8217;s ignoring mechanism is far more complicated than that. It basically holds a list of SVN-ignored file for &lt;em&gt;every&lt;/em&gt;, &lt;em&gt;single&lt;/em&gt;, &lt;em&gt;folder&lt;/em&gt; in your repo, and there is no convenient way to edit all these rules for the enitre repo, or even just view them. You have to run &lt;a href="http://stackoverflow.com/questions/1252270/how-do-i-view-all-ignored-patterns-set-with-svnignore-recursively-in-an-svn-repo/1252303#1252303"&gt;this baffling command&lt;/a&gt; in order to even &lt;em&gt;view&lt;/em&gt; the ignore rules. Also, when you edit the ignore rules for a folder, you&amp;#8217;re not just editing a text file like in Git, you have to actually set the rules using &lt;code&gt;svn&lt;/code&gt;. I tried actually going into the dreaded &lt;code&gt;.svn&lt;/code&gt; folder and edit the text file that holds the ignore rules myself, but it was encoded in a really stupid encoding, and in order to write rules there manually I would have had to count the number of characters in my ruleset and type it as part of the text file.&lt;/p&gt;
&lt;h2&gt;Back to Git&lt;/h2&gt;
&lt;p&gt;Eventually my new client saw how bad of an effect SVN was having on me, and he let me move us to Git. So over the weekend I used &lt;a href="https://github.com/nirvdrum/svn2git"&gt;svn2git&lt;/a&gt; to convert our repo to Git and now we manage all our code in Git. Uninstalling TortoiseSVN from my machine was quite a happy moment.&lt;/p&gt;
&lt;p&gt;Goodbye SVN, may we never meet again.&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/9583964892</link><guid>http://blog.garlicsim.org/post/9583964892</guid><pubDate>Tue, 30 Aug 2011 14:36:00 +0300</pubDate></item><item><title>Postponing GarlicSim 0.7 yet again</title><description>&lt;p&gt;Yeah, the deadline for GarlicSim 0.7 has been an epic fail. &lt;a href="http://blog.garlicsim.org/post/7849706187/postponing-garlicsim-0-7-again"&gt;A couple of weeks ago&lt;/a&gt; I thought I had it under control, but then I got a contract job that&amp;#8217;s been taking all my time. Good news for mah bank account, bad news for mah open-source project.&lt;/p&gt;
&lt;p&gt;So I&amp;#8217;m postponing the 0.7 release to &lt;strong&gt;November 1st, 2011&lt;/strong&gt;. See you then.&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/8656451924</link><guid>http://blog.garlicsim.org/post/8656451924</guid><pubDate>Mon, 08 Aug 2011 23:23:31 +0300</pubDate></item><item><title>Postponing GarlicSim 0.7 again</title><description>&lt;p&gt;I&amp;#8217;m postponing the deadline of GarlicSim 0.7 again, this time to &lt;strong&gt;August 20th&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This is fucked up and I feel really bad about this. I should have been more realistic about my deadlines, but I&amp;#8217;ve let my optimism have the better of me. I&amp;#8217;ll try to be more accurate in future deadlines.&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/7849706187</link><guid>http://blog.garlicsim.org/post/7849706187</guid><pubDate>Wed, 20 Jul 2011 20:43:57 +0300</pubDate></item><item><title>Why making a cool project is a good idea for an aspiring software developer</title><description>&lt;p&gt;As a software developer, I get to know a lot of other software developers. Many of the software developers I know are either running a startup, working as an early employee for a startup, doing contract jobs for a startup, or dreaming of one day starting a startup. My point is that software developers are very interested in startups, either starting them or working for them.&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/jmpk/3420499644"&gt;&lt;img height="487" width="323" align="right" src="http://garlicsim.org/images/man_juggling.png"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My advice to anyone who&amp;#8217;s interested in startups: &lt;strong&gt;Before you ever start a startup, try to make at least one cool and useful project.&lt;/strong&gt; It doesn&amp;#8217;t have to make money; in fact, it&amp;#8217;s better if your project doesn&amp;#8217;t even try to make any kind of profit.&lt;/p&gt;
&lt;h2&gt;Why is making a cool project important?&lt;/h2&gt;
&lt;p&gt;When you&amp;#8217;re doing a startup, you essentially have to do two things at once:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Create some kind of &lt;strong&gt;product&lt;/strong&gt; or solution that answers your users&amp;#8217; needs; this is usually the software ingredient of your startup; and&lt;/li&gt;
&lt;li&gt;Create a &lt;strong&gt;business&lt;/strong&gt; around that product that brings in money for your company.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Both of these things are difficult. Really difficult. It&amp;#8217;s easy to mess either of these up. And you have to do them both &lt;em&gt;at the same time&lt;/em&gt;. Get one right but mess the other one up, and you still failed.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s a metaphor: &lt;strong&gt;Starting a startup is like juggling while riding a unicycle.&lt;/strong&gt; Riding a unicycle is &lt;em&gt;hard&lt;/em&gt;. Juggling is &lt;em&gt;hard&lt;/em&gt;. Doing them both at the same time? &lt;em&gt;Really freaking hard.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If your goal in life was to juggle while riding a unicycle, would you get on the unicycle while holding a few juggling clubs and try to juggle while riding the unicycle? Not if you have any common sense. You would first try to ride the unicycle. You&amp;#8217;d take your time until you&amp;#8217;re sufficiently skilled with that. Ditto for juggling. Then you&amp;#8217;d carefully try to do both of them at once.&lt;/p&gt;
&lt;p&gt;The same applies to startups. Making a successful product is hard enough; it&amp;#8217;s all too common for companies to invest a lot of resources in making an ambitious product, and when it&amp;#8217;s launched it&amp;#8217;s just &amp;#8220;meh&amp;#8221;. &lt;/p&gt;
&lt;p&gt;Building a business on top of a product is hard as well. There are many places where you can screw it up, both by making technical mistakes or strategic ones.&lt;/p&gt;
&lt;p&gt;As you can guess, the chance of you messing &lt;em&gt;either&lt;/em&gt; the software side &lt;em&gt;or&lt;/em&gt; the business side is very big.&lt;/p&gt;
&lt;h2&gt;Start a project, don&amp;#8217;t try to make money.&lt;/h2&gt;
&lt;p&gt;That&amp;#8217;s the essence of my advice. Start a project which is free of the burden of profit. Sure, you won&amp;#8217;t get rich off of it, and you&amp;#8217;re gonna have to support yourself financially while you work on it, but it&amp;#8217;s your best chance at learning how to make a successful product&amp;#8212; It definitely has a much better ROI than going to college.&lt;/p&gt;
&lt;p&gt;Not being burdened with having to make a profit will make it easier for you to build a successful product. &lt;strong&gt;You&amp;#8217;d never have to think about limiting or exploiting your users&lt;/strong&gt;, which is something that many software businesses have to do. Think about those crippled &amp;#8220;starter&amp;#8221; versions of Windows that sell for cheap, or DRM, or annoying ads on websites, or desktop software that installs annoying toolbars and spyware. These are all attempts to make money by limiting or exploiting users. &lt;a href="http://blog.garlicsim.org/post/1388741380/thinking-of-your-software-as-a-butler-is-difficult-but"&gt;Software needs to act like a butler&lt;/a&gt;, which is difficult enough; imagine how hard it is to have a good butler who also tries to upsell you some crap as he serves you.&lt;/p&gt;
&lt;p&gt;As a person who&amp;#8217;s making a project that doesn&amp;#8217;t aim to make money, you&amp;#8217;ll be free from all of those dangerous practices.&lt;/p&gt;
&lt;p&gt;Making a useful product is still hard, mind you, and you still have a good chance of failing; but at least when you crash from the unicycle and try to pick yourself up, you won&amp;#8217;t have juggling clubs falling on your head.&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/7699968171</link><guid>http://blog.garlicsim.org/post/7699968171</guid><pubDate>Sun, 17 Jul 2011 00:34:31 +0300</pubDate></item><item><title>`SimpackSelectionDialog` almost done</title><description>&lt;p&gt;Hey, only a few weeks remain until the release of GarlicSim 0.7. I just wanted to give you a sneak peak of the new &lt;code&gt;SimpackSelectionDialog&lt;/code&gt;, incidentally on a Mac:&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://garlicsim.org/images/simpack_selection_widget_teaser.png"&gt;&lt;img height="384" width="512" alt="Teaser of `SimpackSelectionDialog`" src="http://garlicsim.org/images/simpack_selection_widget_teaser_thumbnail.png" align="middle"/&gt;&lt;br/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://garlicsim.org/images/simpack_selection_widget_teaser.png"&gt;(Click to enlarge.)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m quite pleased with this widget. It&amp;#8217;s almost finished, I might put in a few more touches before the release. The above screenshot shows it on a Mac, but as always, it&amp;#8217;s completely cross-platform and works on Windows XP, Windows 7 and Linux as well.&lt;/p&gt;
&lt;p&gt;This time I put in more emphasis on keyboard-accessibility, including accelerators for as many buttons as possible. The widget is not 100% keyboard accessible, but I&amp;#8217;d say around 90%, and it will get to 100% in a couple of years as the underlying &lt;a href="http://wxpython.org"&gt;wxPython framework&lt;/a&gt; evolves. I also went through all the other dialogs in GarlicSim and gave them as many accelerators as possible.&lt;/p&gt;
&lt;p&gt;Going back to work on 0.7!&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/7508116562</link><guid>http://blog.garlicsim.org/post/7508116562</guid><pubDate>Tue, 12 Jul 2011 01:13:00 +0300</pubDate></item><item><title>DreamPie: My favorite Python shell</title><description>&lt;p&gt;If you&amp;#8217;re not familiar with it, you should really check out &lt;a href="http://dreampie.sourceforge.net/"&gt;DreamPie&lt;/a&gt;, which is a graphical Python shell.&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s a really well-done GUI shell, with great keyboard support to boot. Its most unique feature is the separation of the &amp;#8220;history area&amp;#8221; from the &amp;#8220;current command area&amp;#8221;. I think this design makes more sense than the traditional approach of having them together. It&amp;#8217;s also notable that the &amp;#8221;current command area&amp;#8221; can be used to enter multi-line Python commands (like defining a function or a class) and it&amp;#8217;s very easy to move between lines to edit them. (This sounds obvious but many other shells make this kind of editing cumbersome.) The autocompletion is also well done; for example, DreamPie is able to autocomplete modules even if they haven&amp;#8217;t been imported yet.&lt;/p&gt;
&lt;p&gt;On top of that, I was delighted to find that it works on PyPy out of the box! Check it out:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_lmn8op5dMS1qzywlj.png"/&gt;&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/6429754567</link><guid>http://blog.garlicsim.org/post/6429754567</guid><pubDate>Sat, 11 Jun 2011 23:56:00 +0300</pubDate></item><item><title>Why don't people use enum in Python?</title><description>&lt;p&gt;A while ago I was introduced to the concept of &lt;a href="http://en.wikipedia.org/wiki/Enumerated_type"&gt;enum&lt;/a&gt; in Java. I never programmed Java, but this looks like &lt;em&gt;the&lt;/em&gt; solution for when you want a variable to hold a value from a limited set of possible values. What is usually done in Python is either using a string or an index number, both of which are less elegant solutions in my opinion.&lt;/p&gt;
&lt;p&gt;Python doesn&amp;#8217;t provide a built-in enum type, but I found a few third-party modules, out of which I chose &lt;code&gt;flufl.enum&lt;/code&gt; as being the most promising:&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://packages.python.org/flufl.enum/docs/using.html#creating-an-enum"&gt;&lt;a href="http://packages.python.org/flufl.enum/docs/using.html#creating-an-enum"&gt;http://packages.python.org/flufl.enum/docs/using.html#creating-an-enum&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This looks like a pretty good solution. A tad less native than in Java, but still much better than strings or ints.&lt;/p&gt;
&lt;p&gt;So I wonder: Why do I never see Python code that uses &lt;code&gt;flufl.enum&lt;/code&gt;, or any other enum package for that matter? Is there some reason not to use enums in Python? Perhaps a large portion of Python programmers are ignorant about enums, (as I was before I saw it recently?) Or perhaps people just don&amp;#8217;t really care about making their code elegant?&lt;/p&gt;
&lt;p&gt;Anyway I&amp;#8217;ll try to start using &lt;code&gt;flufl.enum&lt;/code&gt; soon. One awesome application that this could have is to make a Django &lt;code&gt;EnumField&lt;/code&gt; (or &lt;code&gt;ChoiceField&lt;/code&gt; or whatever you want to call it) instead of the current ugly way of making an &lt;code&gt;IntegerField&lt;/code&gt; and defining &lt;code&gt;CHOICES&lt;/code&gt; separately.&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/6388800336</link><guid>http://blog.garlicsim.org/post/6388800336</guid><pubDate>Fri, 10 Jun 2011 20:25:00 +0300</pubDate></item><item><title>Nullege: Search engine for Python source code</title><description>&lt;p&gt;&lt;a href="http://nullege.com/"&gt;Nullege&lt;/a&gt; is a service I&amp;#8217;ve been using for a while. It&amp;#8217;s a search engine for Python code. I&amp;#8217;m quite surprised that I don&amp;#8217;t hear much talk about it in Python-related blogs; it&amp;#8217;s a pretty useful tool:&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://garlicsim.org/images/nullege.png" alt="Nullege in action" width="771" height="648"/&gt;&lt;/p&gt;
&lt;p&gt;It shows you info about the class/function/whatever else you were searching for, and also places where it&amp;#8217;s used in various Python projects found on the web.&lt;/p&gt;
&lt;p&gt;Check it out: &lt;a href="http://nullege.com"&gt;&lt;a href="http://nullege.com"&gt;http://nullege.com&lt;/a&gt;&lt;/a&gt;.&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/5586105105</link><guid>http://blog.garlicsim.org/post/5586105105</guid><pubDate>Wed, 18 May 2011 00:41:00 +0300</pubDate></item><item><title>Is something blocking you from moving to Python 2.7?</title><description>&lt;p&gt;I didn&amp;#8217;t move to Python 2.7 yet. That is, I don&amp;#8217;t consider it my main Python version. My main version is Python 2.6. I consider Python 2.5 the past, Python 2.6 the present, Python 2.7 the future, and Python 3.x the distant future. When I package GarlicSim for end-user distribution I do it with Python 2.6.&lt;/p&gt;
&lt;p&gt;Now, I&amp;#8217;m a big fan of using the latest version of Python, in order to both take advantage of new features and bugfixes, and also to help advance the entire Python community to more advanced versions. If we all adopted new versions of Python as soon as possible, and ensured our packages and services support them, it would be much easier for our fellow Python developers to upgrade as well. This is especially true for Python 2.7 which serves as a bridge to the holy grail, Python 3.x.&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;I try to do my part: GarlicSim supports Python 2.5, 2.6, 2.7, 3.1 and 3.2. But unfortunately it&amp;#8217;s sometimes hard to move to new versions because existing technologies don&amp;#8217;t support them yet.&lt;/p&gt;
&lt;p&gt;For me the blocker is &lt;a href="http://psyco.org"&gt;Psyco&lt;/a&gt;. Psyco&amp;#8217;s JIT compiler speeds up my code by several times. It&amp;#8217;s really awesome. But Psyco doesn&amp;#8217;t support Python 2.7, and it&amp;#8217;s pretty much the reason that I don&amp;#8217;t move to Python 2.7. It seems that all development effort is focused on PyPy, and while PyPy is a super-awesome project, you can&amp;#8217;t really use it if you use C extensions. (Unless you&amp;#8217;re willing to dig into &lt;code&gt;cpyext&lt;/code&gt;.) The cool thing about Psyco is that you just &lt;code&gt;import psyco; psyco.full()&lt;/code&gt; and your code becomes faster, regardless of which third-party packages you use. So for me upgrading to Python 2.7 means making my program several times slower, which is a price I&amp;#8217;m not willing to pay.&lt;/p&gt;
&lt;p&gt;So Psyco is what&amp;#8217;s blocking me from using Python 2.7. What&amp;#8217;s blocking you?&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/5541441091</link><guid>http://blog.garlicsim.org/post/5541441091</guid><pubDate>Mon, 16 May 2011 13:45:00 +0300</pubDate></item><item><title>GarlicSim 0.7 release's scope expanded, deadline postponed</title><description>&lt;p&gt;Yeah, I&amp;#8217;m postponing the deadline for GarlicSim 0.7&amp;#160;&lt;em&gt;again&lt;/em&gt;. The new deadline for GarlicSim 0.7 is &lt;strong&gt;August 1st, 2011&lt;/strong&gt;. (The old deadline was &lt;strike&gt;June 1st, 2011&lt;/strike&gt;.)&lt;/p&gt;
&lt;p&gt;The good news is that I&amp;#8217;m adding a few more features besides those I promised in my original plans:&lt;!-- more --&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;I&amp;#8217;m vastly improving the &lt;code&gt;SimpackSelectionDialog&lt;/code&gt; widget. This is what I&amp;#8217;m trying to do with it:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://garlicsim.org/images/SimpackSelectionDialog_mockup.png"/&gt;&lt;/p&gt;
&lt;p&gt;(Thanks for the awesome mockup tool, &lt;a href="http://balsamiq.com/products/mockups"&gt;Balsamiq&lt;/a&gt;!)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;GarlicSim 0.7 is going to be &lt;a href="http://pypy.org/"&gt;PyPy&lt;/a&gt;-compatible! PyPy is a very exciting Python implementation project and it has a good chance of becoming the future of Python. And I want to be sure from the start that GarlicSim can be part of that future. (Do note that there is no wxPython installer available for PyPy yet, so I wasn&amp;#8217;t able to ensure that the GarlicSim GUI works on PyPy; I only ensured the core logic does and that all its tests pass.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Despite these added features, I feel kind of bad about postponing the release. I should have been more conservative with the deadline. This will definitely be a lesson for future GarlicSim releases. I&amp;#8217;ll try to set more realistic deadlines from now on.&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/5446622629</link><guid>http://blog.garlicsim.org/post/5446622629</guid><pubDate>Fri, 13 May 2011 12:51:00 +0300</pubDate></item><item><title>GarlicSim continuous-integration website, managed by ShiningPanda</title><description>&lt;p&gt;Check out the new &amp;#8220;GarlicSim status&amp;#8221; website:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://status.garlicsim.org"&gt;&lt;a href="http://status.garlicsim.org"&gt;http://status.garlicsim.org&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s a Jenkins continuous-integration server which automatically pulls the most recent version of GarlicSim from the GitHub repo, runs the tests, measures line coverage, and displays all the results on the web.&lt;/p&gt;
&lt;p&gt;It runs on &lt;a href="http://www.shiningpanda.com/"&gt;ShiningPanda&lt;/a&gt;, which abstracts away a lot of the technical work involved in running a Jenkins server. ShiningPanda is still in beta, but it&amp;#8217;s already useful for me; this has been a lot easier than my previous attempt at running Jenkins on EC2. I also love the fact that ShiningPanda is focused on Python and Python-related tools; to contrast, I remember how frustrated I was when I was trying to use CloudBees for the same task and discovered that they don&amp;#8217;t even have &lt;a href="http://pypi.python.org/pypi/nose"&gt;nose&lt;/a&gt; installed&amp;#8230;&lt;/p&gt;
&lt;p&gt;Anyway, enjoy the new CI server!&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/4985077369</link><guid>http://blog.garlicsim.org/post/4985077369</guid><pubDate>Wed, 27 Apr 2011 17:54:00 +0300</pubDate></item><item><title>New Wing 4 script: `instantiate`</title><description>&lt;p&gt;Hey, I made a new script for &lt;a href="http://wingware.com/"&gt;Wing IDE 4&lt;/a&gt;. Users of Wing may want to check it out.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s called &lt;strong&gt;&lt;code&gt;instantiate&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;What it does is simple. Often you want to instantiate an object from a class like this:&lt;/p&gt;
&lt;pre&gt;cat_nip = CatNip()&lt;/pre&gt;
&lt;p&gt;The annoying thing about typing this is that you don&amp;#8217;t get autocompletion for &lt;code&gt;cat_nip&lt;/code&gt; because it doesn&amp;#8217;t exist yet. But you do usually get autocompletion for &lt;code&gt;CatNip&lt;/code&gt;. Hence this script: You type &lt;code&gt;CatNip&lt;/code&gt;, execute the script, and then automatically get this line:&lt;/p&gt;
&lt;pre&gt;cat_nip = CatNip()&lt;/pre&gt;
&lt;p&gt;With the cursor already placed inside the parentheses for you to type the arguments.&lt;/p&gt;
&lt;p&gt;The source is on GitHub:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/cool-RR/cute-wing-stuff"&gt;&lt;a href="https://github.com/cool-RR/cute-wing-stuff"&gt;https://github.com/cool-RR/cute-wing-stuff&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/4955147760</link><guid>http://blog.garlicsim.org/post/4955147760</guid><pubDate>Tue, 26 Apr 2011 15:47:57 +0300</pubDate></item><item><title>2 out of 3 GitHub forks are completely empty</title><description>&lt;p&gt;About 2 years ago I started &lt;a href="http://github.com/cool-RR/GarlicSim"&gt;the GarlicSim project on GitHub&lt;/a&gt;. GitHub&amp;#8217;s most famous feature is &amp;#8220;forking&amp;#8221;: When another person forks your code, they create their own copy which they may work on and change the code, and later show you their changes (a.k.a. &amp;#8220;pull request&amp;#8221;) so you could merge those changes into your own repo. True open-source spirit.&lt;/p&gt;
&lt;p&gt;GarlicSim was forked 4 times in the 2 years of its existence. I remember the first time someone forked GarlicSim. I was very excited. I thought someone was going to help me work on it. I asked that person what he was thinking of adding. He didn&amp;#8217;t respond to my messages. He didn&amp;#8217;t add any code to his fork. Neither did the 3 other forks of GarlicSim that followed.&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;Then it became clear to me that GitHub forks don&amp;#8217;t mean much. I guess most people just click &amp;#8220;fork&amp;#8221; because they think it&amp;#8217;s cool, or because they would like to imagine themselves working on the project. But they don&amp;#8217;t actually do any development on their forks.&lt;/p&gt;
&lt;p&gt;I wanted to check whether this phenomenon happens on other peoples&amp;#8217; repos too; maybe I was just unlucky with GarlicSim? Apparently not. My small research showed that &lt;strong&gt;2 out of 3 GitHub forks are completely empty.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;My modest research&lt;/h2&gt;
&lt;p&gt;I checked 12 random GitHub projects which have at least one fork, not including the original repo. I used GitHub&amp;#8217;s own &amp;#8220;Random repository&amp;#8221; link to find them, and pruned through all the fork-less repos (more than a hundred) until I got my 12. Then I counted how many forks each of these repos had; the smallest had just one fork, the biggest had 8 forks. (Again, not including the original repo.) The median number of forks was 1. The total number of forks across the 12 projects was 27.&lt;/p&gt;
&lt;p&gt;Then I used Github&amp;#8217;s excellent &amp;#8220;Network&amp;#8221; view to see how many of these repositories actually had any commits not present in the original repo. Only 8 out of the 27 forks had any content in them.&lt;/p&gt;
&lt;p&gt;To put it simply: &lt;strong&gt;2 out of every 3 forks in GitHub are completely empty. &lt;/strong&gt;Their owners did not add even a single trivial line of code to the project, not even just for playing around in their own fork.&lt;/p&gt;
&lt;p&gt;And of course, regarding those ~33% of forks which actually contains code, I did not check how many of these have trivial code and how many have substantial code. It&amp;#8217;s quite possible that a big share of them just add a few trivial lines that never get merged into the original project.&lt;/p&gt;
&lt;p&gt;So keep that in mind next time you browse Github and see a project with 20 forks. There aren&amp;#8217;t really 20 active forks, there are perhaps 7 active forks, and even that is being optimistic.&lt;/p&gt;
&lt;p&gt;(And I&amp;#8217;d like to note: I love GitHub with all my heart. It&amp;#8217;s a great tool and I use it both in my OSS work and my job. I just want people to have a realistic view of what a GitHub fork means.)&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/4472104984</link><guid>http://blog.garlicsim.org/post/4472104984</guid><pubDate>Sat, 09 Apr 2011 21:25:00 +0300</pubDate></item><item><title>GarlicSim 0.6.3 released, becomes fully open-source!</title><description>&lt;p&gt;I have big news. I&amp;#8217;ve decided to release the entire code of GarlicSim as open-source under the &lt;a href="http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License"&gt;LGPL license&lt;/a&gt;. Previously, only &lt;code&gt;garlicsim&lt;/code&gt; and &lt;code&gt;garlicsim_lib&lt;/code&gt; were released under the LGPL, and the &lt;code&gt;garlicsim_wx&lt;/code&gt; GUI was closed-source. Now I&amp;#8217;ve released &lt;code&gt;garlicsim_wx&lt;/code&gt; under the LGPL as well, so &lt;strong&gt;the GarlicSim project is &lt;em&gt;completely&lt;/em&gt; open source&lt;/strong&gt;. Yay!&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve made a new release, &lt;a href="http://docs.garlicsim.org/intro/installation/index.html"&gt;GarlicSim 0.6.3&lt;/a&gt;, which clearly states that &lt;code&gt;garlicsim_wx&lt;/code&gt; is now released under the LGPL. I also made a few minor additions in this release:&lt;/p&gt;
&lt;h2&gt;What&amp;#8217;s new in GarlicSim 0.6.3&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;code&gt;garlicsim_wx&lt;/code&gt; gets released as open-source under the LGPL license.&lt;/li&gt;
&lt;li&gt;Most of the sample simpacks in &lt;code&gt;garlicsim_lib&lt;/code&gt; have been rewritten to be more elegant and well-documented.&lt;/li&gt;
&lt;li&gt;NumPy is no longer needed in order to run the &lt;code&gt;garlicsim_lib.simpacks.queue&lt;/code&gt; simpack.&lt;/li&gt;
&lt;li&gt;A class &lt;code&gt;garlicsim.general_misc.identities.HasIdentity&lt;/code&gt; was added, to be used as a base class for every object that needs to maintain its identity across simulation states.&lt;/li&gt;
&lt;li&gt;A bunch of fixes, more tests, and more documentation.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Go on and &lt;a href="http://docs.garlicsim.org/intro/installation/index.html"&gt;install the new version!&lt;/a&gt;&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/4425132633</link><guid>http://blog.garlicsim.org/post/4425132633</guid><pubDate>Fri, 08 Apr 2011 01:27:49 +0300</pubDate></item><item><title>The next revolution after Git</title><description>&lt;p&gt;(Note: I talk a lot about Git in this essay, but the same thing can probably be said about Mercurial, Bazaar, et al. I simply use Git because that&amp;#8217;s the system that I&amp;#8217;m personally familiar with.)&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve been a &lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt; user for a few years now. I love it. Being able to branch-n-merge freely is a very powerful tool for anyone who needs to manage a codebase. But I find that there is one area where Git falls short; in this essay I will make a humble first attempt at designing a system that tries to solve this problem. I hope that someone will pick up the glove and create this project. If anyone implements this well, &lt;strong&gt;I would personally consider it to be the next revolution after Git;&lt;/strong&gt; i.e., The difference in productivity between this system and Git would be on the same scale as the difference between Git and SVN.&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;The missing feature is: &lt;strong&gt;Templating.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;The problem&lt;/h2&gt;
&lt;p&gt;In a codebase you often have code snippets that repeat themselves a few times in different places. For example you have a code file &lt;code&gt;chair.py&lt;/code&gt; that defines a class &lt;code&gt;Chair&lt;/code&gt;, and another file &lt;code&gt;bar_stool.py&lt;/code&gt; that defines a class &lt;code&gt;BarStool&lt;/code&gt;, and they share a lot of code, but they have a few small differences between them. You don&amp;#8217;t want your source-control to store two copies of the same code; not because you&amp;#8217;re cheap on hard-disk space, but because every time you&amp;#8217;ll want to change the shared code, you&amp;#8217;ll have to change it in two (or more) places. This is called the &lt;a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself"&gt;DRY principle&lt;/a&gt;, &amp;#8220;Don&amp;#8217;t repeat yourself&amp;#8221;, and it&amp;#8217;s a very good principle.&lt;/p&gt;
&lt;p&gt;I know what you&amp;#8217;re thinking. &amp;#8220;You should refactor the &lt;code&gt;Chair&lt;/code&gt; and &lt;code&gt;BarStool&lt;/code&gt; classes so that the shared code will be put in a base class!&amp;#8221; Sure, if you can. I&amp;#8217;m personally a refactoring fanatic. I refactor everything that moves. &lt;strong&gt;But sometimes you just can&amp;#8217;t refactor.&lt;/strong&gt; Sometimes you&amp;#8217;re completely unable to refactor, and sometimes you are able to refactor but it&amp;#8217;s just not practical, because it will make your code too dynamic and introduce too much indirection.&lt;a href="#note1"&gt;[1]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;GarlicSim has several examples of situations in which you have repeating code that would be impractical to refactor. A good one is the &lt;code&gt;setup.py&lt;/code&gt; files. GarlicSim is comprised of three Python packages: &lt;code&gt;garlicsim&lt;/code&gt;, &lt;code&gt;garlicsim_lib&lt;/code&gt; and &lt;code&gt;garlicsim_wx&lt;/code&gt;. Like all Python packages, they each have a &lt;code&gt;setup.py&lt;/code&gt; file: &lt;a href="https://github.com/cool-RR/GarlicSim/blob/master/garlicsim/setup.py"&gt;&lt;code&gt;garlicsim/setup.py&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://github.com/cool-RR/GarlicSim/blob/master/garlicsim_lib/setup.py"&gt;&lt;code&gt;garlicsim_lib/setup.py&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://github.com/cool-RR/GarlicSim/blob/master/garlicsim_wx/setup.py"&gt;&lt;code&gt;garlicsim_wx/setup.py&lt;/code&gt;&lt;/a&gt;. As you can see, these files have many lines in common with each other. But there is no practical way to refactor those identical parts away.&lt;/p&gt;
&lt;h2&gt;The solution, in the abstract&lt;/h2&gt;
&lt;p&gt;The solution is templating. Instead of manipulating the code files directly, you manipulate succinct descriptions of the code files. So instead of maintaining three &lt;code&gt;setup.py&lt;/code&gt; files, I would have to maintain one generic &lt;code&gt;setup.py&lt;/code&gt; template, and then describe each of the three actual &lt;code&gt;setup.py&lt;/code&gt; files as deviations from that template.&lt;/p&gt;
&lt;p&gt;Any programmer worth his salt would feel in his guts that templating is &amp;#8220;the correct solution,&amp;#8221; that it&amp;#8217;s the way things should be. But then, almost no open-source project uses such a templating scheme to maintain their code. Why?&lt;/p&gt;
&lt;h2&gt;The solution needs to be comfortable to work with&lt;/h2&gt;
&lt;p&gt;There&amp;#8217;s a big difference between solving a problem in the abstract and solving it in practice. A templating system is indeed &amp;#8220;the correct solution,&amp;#8221; but that&amp;#8217;s not enough to make it a solution worthy of being used.&lt;/p&gt;
&lt;p&gt;Imagine if I tried to use a templating system, say &lt;a href="http://jinja.pocoo.org/"&gt;Jinja&lt;/a&gt;, to produce my &lt;code&gt;setup.py&lt;/code&gt; files. I would have a general template, and then three descriptions of how each &lt;code&gt;setup.py&lt;/code&gt; file deviates from the templates. And then I would have to generate the actual &lt;code&gt;setup.py&lt;/code&gt; files from the templates.&lt;/p&gt;
&lt;p&gt;That would be annoying. One of the big issues is that you can&amp;#8217;t edit the generated code. I&amp;#8217;ve often seen messages like:&lt;/p&gt;
&lt;pre&gt;# This file was created automatically by the templating system.
# Don't modify this file, modify the templating interface instead.
&lt;/pre&gt;
&lt;p&gt;That really sucks. It sucks to be forced to edit your template files instead of the code files. Your IDE just can&amp;#8217;t grok the template as a source file, so it loses all intelligence features. The same thing can be said about the developer himself, actually&amp;#8230; You always want to be able to view and edit your source files directly.&lt;/p&gt;
&lt;h2&gt;A design that might work&lt;/h2&gt;
&lt;p&gt;Here&amp;#8217;s a design that might work. Let&amp;#8217;s codename it &amp;#8220;Leapfrog&amp;#8221;, just for the sake of easy reference.&lt;/p&gt;
&lt;p&gt;This is a design that works &lt;em&gt;on top&lt;/em&gt; of Git, or on top of any other source-control system. Now, when you have a Git repo, Git saves all its data in a hidden &lt;code&gt;.git&lt;/code&gt; folder in your project&amp;#8217;s root folder. We are going to do something similar; we&amp;#8217;ll save all of our data in a &lt;code&gt;.leapfrog&lt;/code&gt; folder that will sit in the root folder alongside the &lt;code&gt;.git&lt;/code&gt; folder.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;.leapfrog&lt;/code&gt; folder will contain all the templates and all the data needed to generate your project&amp;#8217;s source files. The &lt;code&gt;.leapfrog&lt;/code&gt; folder will be the only thing tracked by Git; your actual source files will be git-ignored.&lt;/p&gt;
&lt;p&gt;So the contents of your &lt;code&gt;.leapfrog&lt;/code&gt; folder may look like this:&lt;/p&gt;
&lt;pre&gt;.leapfrog/
    setup.py.abstract
	garlicsim/
	    setup.py
	garlicsim_lib/
	    setup.py
	garlicsim_wx/
	    setup.py
&lt;/pre&gt;
&lt;p&gt;Where &lt;code&gt;setup.py.abstract&lt;/code&gt; is a template, and each &lt;code&gt;setup.py&lt;/code&gt; file extends that template. This is all the information that is needed to generate the actual &lt;code&gt;setup.py&lt;/code&gt; files in the so-called &amp;#8220;working directory.&amp;#8221; (The template format can be in Jinja or whatever.)&lt;/p&gt;
&lt;p&gt;Now, in order to synchronize the working directory with the &lt;code&gt;.leapfrog&lt;/code&gt; directory, you&amp;#8217;ll have an interface quite similar to Git. A &lt;code&gt;leapfrog checkout&lt;/code&gt; action would generate the code files from the templates. But the powerful feature would be that you could go the other way too; you could edit the code files and then &amp;#8220;stage&amp;#8221; that to the templates.&lt;/p&gt;
&lt;p&gt;For example, you could edit &lt;code&gt;garlicim_lib/setup.py&lt;/code&gt; and add a bunch of lines. Then you would run &lt;code&gt;leapfrog add .&lt;/code&gt; to stage, just like you do in Git. The changes will be added to the &lt;code&gt;.leapfrog/garlicim_lib/setup.py&lt;/code&gt; template. Then you could use &lt;code&gt;git add .&lt;/code&gt; and &lt;code&gt;git commit&lt;/code&gt; to stage and commit the changes to the template to Git.&lt;/p&gt;
&lt;h2&gt;Pre-rebuttal&lt;/h2&gt;
&lt;p&gt;Probably some people will say, &amp;#8220;there are many existing templating systems out there that you can use!&amp;#8221; To which I can give the Drew Houston reply:&lt;/p&gt;
&lt;blockquote&gt;You: There are a million of templating systems out there!&lt;br/&gt; Me: Do you use any of them to manage your codebase?&lt;br/&gt; You: No.&lt;br/&gt; Me: &amp;#8230;&lt;br/&gt;&lt;/blockquote&gt;
&lt;h2&gt;Final words&lt;/h2&gt;
&lt;p&gt;There are probably mistakes in my design. There are probably problems I didn&amp;#8217;t think of. Good chances are that the eventual implementation will look nothing like the design I described. That&amp;#8217;s okay, this is how these things work. I just hope to get the ball rolling for people to start thinking about this problem and come up with solutions.&lt;/p&gt;
&lt;p&gt;I really hope that some open-source developer out there will read this essay and implement it, or implement his own take on it, so we could all benefit from this tool.&lt;/p&gt;
&lt;p&gt;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&lt;/p&gt;
&lt;h3&gt;Notes&lt;/h3&gt;
&lt;p&gt;&lt;a name="note1" id="note1"&gt;[1]&lt;/a&gt; I personally remember one contract Django job in which I had a few repeating code segments in a few classes. I refactored them into one base class. But that architecture was just not meant to be. It was too dynamic; I was creating class attributes dynamically and doing other nasty stuff. Maybe in &lt;a href="http://en.wikipedia.org/wiki/Lisp_(programming_language)"&gt;LISP&lt;/a&gt; one would be able to come up with an elegant refactoring for that specific problem, but not in Python. That refactoring was a mistake on my part that cost my client a bit of money.&lt;/p&gt;
&lt;p&gt;Thanks to Amir Rachum for helping me brainstorm on this idea.&lt;/p&gt;</description><link>http://blog.garlicsim.org/post/4362874439</link><guid>http://blog.garlicsim.org/post/4362874439</guid><pubDate>Tue, 05 Apr 2011 13:29:00 +0300</pubDate></item></channel></rss>

