tag:blogger.com,1999:blog-48966474424825256962009-05-27T10:48:52.218-07:00approaching infinitysporadic writings from aaron maxwellHilomathhttp://www.blogger.com/profile/12381955713518103519noreply@blogger.comBlogger9125tag:blogger.com,1999:blog-4896647442482525696.post-28393692078998662009-05-20T10:49:00.000-07:002009-05-27T10:48:10.638-07:00Dealing with multiple Django versions<p>More than a few Django websites I built in the past two years are still live and active. And because they were made at different times, they were built against different Django versions.</p> <p>If a (virtual) web host accidentally imports a different version of django, the site will completely break at best... or exhibit subtle, hard-to-discover runtime errors at worst. Guard against this by placing a version check in settings.py:</p> <pre style="text-indent: 0;"> from django import VERSION as DJANGO_VERSION assert (1,1) == DJANGO_VERSION[:2], DJANGO_VERSION </pre> <p>(If, for example, this web site is built for version 1.1. Change the tuple in the assert statement to match whatever version is required.)</p> <p>This will cause the host start-up to immediately fail, loudly and visibly, if the incorrect Django version has been imported.</p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4896647442482525696-2839369207899866?l=ai.redsymbol.net'/></div>Hilomathhttp://www.blogger.com/profile/12381955713518103519noreply@blogger.com0tag:blogger.com,1999:blog-4896647442482525696.post-64513587572582801922009-04-07T19:18:00.001-07:002009-05-27T10:48:37.591-07:00Django: AttributeError: 'str' object has no attribute 'resolve'<p>Here is today's obscure error message and its solution.</p> <p>Say you are working on a Django project, using its development web server, and you get this exception when you try to load a page in the browser:</p> <pre> AttributeError: 'str' object has no attribute 'resolve' </pre> <p>It's because you forgot to type the word "patterns".</p> <p>Specifically, in some url.py, you typed something like this:</p> <pre> urlpatterns = ('', (r'^$', direct_to_template, {'template' : 'a.html'}), # ... </pre> <p>when you should have typed this:</p> <pre> urlpatterns = patterns('', (r'^$', direct_to_template, {'template' : 'a.html'}), # ... </pre> <p>See the difference? In the first one, I'm incorrectly assigning urlpatterns to be a tuple. In the second, I'm correctly using the <code>django.conf.urls.defaults.patterns</code> function.</p> <p>File this under "issues that cost me an annoying amount of time to solve, and which I'm documenting so it doesn't have to happen to anyone else."</p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4896647442482525696-6451358757258280192?l=ai.redsymbol.net'/></div>Hilomathhttp://www.blogger.com/profile/12381955713518103519noreply@blogger.com0tag:blogger.com,1999:blog-4896647442482525696.post-40455362824110361262009-04-04T22:42:00.000-07:002009-04-04T22:45:38.422-07:00How To Build an Automated Testing System<p>What is the value of automating your software testing as much as possible?</p> <p>At a talk I gave once to a large room of software engineers, I asked for a show of hands: how many write unit tests all the time? And, how many use version control for nearly all their code? Almost every hand went up on both counts. I was proud of them for this, and told them so!</p> <p>A little later in the same talk, I asked how many had use a code coverage tool on their code in the past week. Only fifteen percent! A tiny fraction. And these were undeniably excellent engineers. What would the ratio have been for a more mediocre group?</p> <p><strong>Automation is a form of leverage.</strong> If each attendee's organization had an automated QA system that simply did a source checkout each night, and executed all tests within a code coverage tool while everyone slept, then everyone would have been able to raise their hands... even if they did not know how to invoke the tool! </p> <p>This situation demonstrates why an automated testing system is important. By silently working for you and your team, all measurable metrics are just there and available. You won't use them all the time. That's fine. They are there when you need them, without distracting you from more important matters.</p> <p>A great automated quality assurance system will have a number of good ingredients. Let's look at them.</p> <p>(And by the way, this list is unapologetically opinionated. It's not necessary to agree with each item. But everything is there for a reason. I urge you to at least understand the rationale behind it. Then you are well equipped to decide whether to do it this way or another way. Send questions and/or criticisms to amax@redsymbol.net.) </p> <p><strong>Read the full version of <a href="http://redsymbol.net/articles/build-test-automation-system/">Building an Automated Testing/Quality Assurance System</a></strong></p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4896647442482525696-4045536282411036126?l=ai.redsymbol.net'/></div>Hilomathhttp://www.blogger.com/profile/12381955713518103519noreply@blogger.com0tag:blogger.com,1999:blog-4896647442482525696.post-5244712335832472462008-11-14T19:43:00.000-08:002008-11-14T21:20:22.300-08:00Does it take money to make money?<a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=Does%20it%20take%20money%20to%20make%20money%3F&amp;linkurl=http%3A%2F%2Fai.redsymbol.net%2F2008%2F11%2Fdoes-it-take-money-to-make-money.html"><img src="http://static.addtoany.com/buttons/share_save_171_16.gif" width="171" height="16" border="0" alt="Share/Save/Bookmark"/></a><script type="text/javascript">a2a_linkname="Does it take money to make money?";a2a_linkurl="http://ai.redsymbol.net/2008/11/does-it-take-money-to-make-money.html";</script><script type="text/javascript" src="http://static.addtoany.com/menu/page.js"></script> <p>Let's talk about a phrase you have heard before:</p> <blockquote>"It takes money to make money."</blockquote> <p>Like many aphorisms, it must be handled with great care. It can be amazing that the words you listen to can affect what you believe, and thus how you act.</p> <p>"It takes money to make money." One could use this idea to keep themselves poor, reasoning that they can never afford to become wealthier than they are now.</p> <p>I would prefer that this not happen to you. So let me suggest a different wording that may be more profitable.</p> <blockquote>"It takes SOME money to make MORE money."</blockquote> <p>And very importantly,</p> <blockquote>"You can create SOME money out of nothing."</blockquote> <p>Is this dual aphorism true? Just as true as the original, perhaps more.</p> <p>If you have money, can you utilize it to create even more? Yes, absolutely. Can you create money out of thin air? Yes, there are many ways. One way is to sell your time and labor to those who will pay for it. There are other ways.</p> <p>Some recommended reading: <ul> <li><a href="http://marshallbrain.com/million.htm">How To Make a Million Dollars</a></li> <li><a href="http://www.37signals.com/svn/posts/1256-making-money-twice">Making Money Twice</a></li> <li><a href="http://sethgodin.typepad.com/seths_blog/2008/10/is-effort-a-myt.html">Is effort a myth?</a></li> </ul> </p> <a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=Does%20it%20take%20money%20to%20make%20money%3F&amp;linkurl=http%3A%2F%2Fai.redsymbol.net%2F2008%2F11%2Fdoes-it-take-money-to-make-money.html"><img src="http://static.addtoany.com/buttons/share_save_171_16.gif" width="171" height="16" border="0" alt="Share/Save/Bookmark"/></a><script type="text/javascript">a2a_linkname="Does it take money to make money?";a2a_linkurl="http://ai.redsymbol.net/2008/11/does-it-take-money-to-make-money.html";</script><script type="text/javascript" src="http://static.addtoany.com/menu/page.js"></script><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4896647442482525696-524471233583247246?l=ai.redsymbol.net'/></div>Hilomathhttp://www.blogger.com/profile/12381955713518103519noreply@blogger.com0tag:blogger.com,1999:blog-4896647442482525696.post-71541182895214586232008-10-03T12:06:00.000-07:002009-05-27T10:48:52.230-07:00Django and Lighttpd: one niggling fastCGI detail<p>If you are setting up a <a href="http://djangoproject.com/">Django</a> website using the <a href="http://www.lighttpd.net/">lighttpd</a> web server, one of the easiest ways to configure it is via fastcgi, which lighttpd has built-in support for. As I write this, the <a href="http://docs.djangoproject.com/en/dev/howto/deployment/fastcgi/">official Django FastCGI docs</a> do a very good job of explaining everything, provided you read the whole document. (Don't just skip to the lighttpd section - relevant info is contained earlier, perhaps even in the Apache sections.)</p> <p>The docs skimp over one detail that happened to affect me, however, which I'd like to document here in hopes that it will save you some time: the <a href="http://docs.djangoproject.com/en/dev/ref/settings/#force-script-name">FORCE_SCRIPT_NAME</a> setting. At first, when I called up the admin site and clicked the submit button to log in, I got a 404 error, for a url like "/mysite.fcgi/admin/". mysite.fcgi (not its real name :) is the url prefix I configured for the fastcgi rewrite rule in the lighttpd configuration.</p> <p>After much research and fruitless tweaking of the config files, I thought to look at the HTML source of the admin login page (which served just fine). Turns out the action attribute of the login form element was set to "/mysite.fcgi/admin/", not "/admin/" or ".", like it should be. At <a href="http://docs.djangoproject.com/en/dev/howto/deployment/fastcgi/#forcing-the-url-prefix-to-a-particular-value">the tail end of the above docs</a>, I got a clue as to the cause. Long story short, defining FORCE_SCRIPT_NAME to the empty string in settings.py solved the problem.</p> <p>There... hope this saves someone an hour or two!</p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4896647442482525696-7154118289521458623?l=ai.redsymbol.net'/></div>Hilomathhttp://www.blogger.com/profile/12381955713518103519noreply@blogger.com4tag:blogger.com,1999:blog-4896647442482525696.post-1886402537894010482008-07-15T18:59:00.000-07:002009-01-21T10:29:48.767-08:00Crash course in Applied Functional Programming<p>If you're a software developer, something interesting has been happening in your field lately. Mainstream programming languages are starting to gain features from what used to be a decidedly academic domain: so-called <strong>functional programming</strong>.</p> <p>Now, I'm sure you are a programmer just like me, who works in C or C++ or Java or Python or Ruby or Javascript or, God help you, PHP. And also just like me, you probably spend much of your free time reading math books.</p> <p>What? Oh, right, that's not normal - I keep forgetting. The point is, more and more, languages that <em>you actually use</em> are picking up some rather theoretical ideas from computer science, and incorporating them very directly into the syntax of the language... </p> <p><strong><em>Read full version of</em> <a href="http://redsymbol.net/articles/crash-course-applied-functional-programming/">Crash course in Applied Functional Programming</a></strong></p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4896647442482525696-188640253789401048?l=ai.redsymbol.net'/></div>Hilomathhttp://www.blogger.com/profile/12381955713518103519noreply@blogger.com0tag:blogger.com,1999:blog-4896647442482525696.post-22103933446667403772008-04-23T16:40:00.000-07:002009-01-21T10:35:36.174-08:00Three Things I Love About Git<h2>git-commit --amend</h2> <p>One of the benefits of using version control is organization. When you commit a set of changes, you are implicitly marking that set as defining a certain feature set, or otherwise having something in common.</p> <p>Have you ever committed something, then realized you forgot to include something with it? Maybe it's a new file, or maybe it's an extra small change you forgot to make.</p> <p>Enter <code>git-commit --amend</code>. The amend option adds to the tip of the current branch, and actually <em>replaces the last commit</em> with the combined change! It even seeds the message editor with the last commit's description, so you don't have to type it in again.</p> <p><strong><em>Find out two other lovable git qualities in the full version of </em><a href="http://redsymbol.net/articles/three-things-love-about-git/">Three Things I Love About Git</a></strong></p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4896647442482525696-2210393344666740377?l=ai.redsymbol.net'/></div>Hilomathhttp://www.blogger.com/profile/12381955713518103519noreply@blogger.com2tag:blogger.com,1999:blog-4896647442482525696.post-71222083174735389672008-01-16T21:16:00.001-08:002009-01-21T10:33:07.660-08:00High-level Language Features and Testing<p>When I first started doing test-driven development as a PHP coder, our <a href="http://radicalfusion.net">development shop</a> used Marcus Baker's excellent <a href="http://www.lastcraft.com/simple_test.php">SimpleTest</a> framework. I liked it a lot. Since then I've used unit test frameworks in C, Perl, Java, and Python, and SimpleTest is still my overall favorite in any language.</p> <p>As I became more <strike>obsessed with</strike> interested in automated testing, however &mdash; reading books and blog articles, experimenting with new testing patterns, getting xUnit tattoos &mdash; I sometimes felt frustrated. Often I would want to write some kind of test in the framework and language, but one or both was just not powerful enough to express the idea cleanly.</p> <p>It wasn't until I started coding a lot in Python that the cause hit me. Most xUnit <em>frameworks</em>, particularly if they provide good <a href="http://en.wikipedia.org/wiki/Mock_object">mock objects</a>, are more than adequate in themselves to support any testing pattern I could come up with. SimpleTest certainly is. The problems I ran into came from <em>the language itself</em>...</p> <p><strong><em>Read more about how a language's features affect the tests you write in the full version of</em> <a href="http://redsymbol.net/articles/high-level-lang-features-and-testing/">High-level Language Features and Testing</a></strong></p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4896647442482525696-7122208317473538967?l=ai.redsymbol.net'/></div>Hilomathhttp://www.blogger.com/profile/12381955713518103519noreply@blogger.com4tag:blogger.com,1999:blog-4896647442482525696.post-46708328163890019962007-06-15T01:17:00.000-07:002007-06-30T20:52:16.732-07:00Using Gnu Emacs With SCMUtilsIf you are interested in both physics and computer science, there is a real treasure of a book you owe it to yourself to check out. It's called <a href="http://mitpress.mit.edu/SICM/">Structure and Interpretation of Classical Mechanics</a>. The full text is online at that link, and you can also <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FStructure-Interpretation-Classical-Mechanics-Sussman%2Fdp%2F0262194554%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1181895701%26sr%3D8-1&tag=aaronscashfl1-20&linkCode=ur2&camp=1789&creative=9325">buy a physical copy</a>. I won't describe it further in this post; good summaries can be found in the <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FStructure-Interpretation-Classical-Mechanics-Sussman%2Fdp%2F0262194554%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1181895701%26sr%3D8-1&tag=aaronscashfl1-20&linkCode=ur2&camp=1789&creative=9325">reviews on Amazon.</a> Accompanying the text is an open-source numerical and symbolic math library called "scmutils", meant to be run in MIT's version of Scheme. (<a href="http://www-swiss.ai.mit.edu/~gjs/6946/linux-install.htm">download and install instructions</a>) MIT Scheme includes an Emacs-like editor and execution environment called "Edwin", which acts as an interface to the whole system. Edwin has some nice features, including a user-friendly debugger and symbol completion. Most of the time, however, I prefer to use full-fledged Gnu Emacs as the interface. Setting this up is actually pretty simple, once you have downloaded and installed scmutils. Just include the following in your .emacs file: <pre> (defun mechanics () (interactive) (run-scheme "ROOT/mit-scheme/bin/scheme --library ROOT/mit-scheme/lib" )) </pre> Replace ROOT with the directory in which you installed the scmutils software. (Remember to replace it in both places. If it is installed differently on your system, just make sure the string has the form "/path/to/mit-scheme --library /path/to/scmutils-library".) Restart emacs (or use C-x C-e to evaluate the mechanics defun), and launch the environment with the command M-x mechanics. There are a few nice Emacs and scheme-mode features you can use. A handy way to work in the environment is with two buffers open at once. One buffer will be in the mechanics enviroment (i.e. scheme interpreter) launched with the mechanics command; we'll refer to this as the "mechanics" buffer. The other buffer will be open to a file containing Scheme/Scmutils code. The idea is that you write your code in the file, save it, then tell the scheme process to load the file. You do this by switching to the mechanics buffer, then typing C-c C-l. (That's "L", not "one"). You will be asked for, and must specify, the file to load the first time. It is remembered on subsequent invokations, so after making a change to the file and saving, you can just switch to the mechanics buffer and type C-c C-l [ENTER] to reload. It's very simple and fast. In the mechanics buffer - which happens to be in the normal Emacs scheme interaction mode - a command history is kept. You can cycle up and down through the command history with C-up and C-down. If you make a mistake and get to the error prompt, or start a calculation that is taking too long, you can abort and return to the normal prompt by typing C-c C-c. Other useful commands can be found from M-x describe-mode .<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4896647442482525696-4670832816389001996?l=ai.redsymbol.net'/></div>Hilomathhttp://www.blogger.com/profile/12381955713518103519noreply@blogger.com1