tag:blogger.com,1999:blog-3362951070793682452024-03-13T08:31:54.979-04:00Real Ultimate ProgrammingThe Home for People Who Like to Flip Out and Write CodeHank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.comBlogger121125tag:blogger.com,1999:blog-336295107079368245.post-69160180300329870162012-01-18T09:10:00.004-05:002012-01-18T09:22:45.860-05:00How to enable `git grep -P` on OS X using Homebrew<p>
If you're using <a href="http://mxcl.github.com/homebrew/" title="Homebrew's Home Page">Homebrew</a> to manage software on your OS X Lion box, and using the version of <a href="http://git-scm.com/" title="Git's Home Page"><kbd>git</kbd></a> it provides, you may have noticed that you can't use the <kbd>-P</kbd> flag to <kbd>git grep</kbd> to enable Perl-compatible regular expressions (<acronym title="Perl-compatible regular expressions">PCRE</acronym>). It turns out the default formula doesn't enable that option when building <kbd>git</kbd>. Rather than have to override this every single time you upgrade <kbd>git</kbd>, it's far easier to add this line to your <kbd>.bashrc</kbd> (or <kbd>.zshrc</kbd>):
</p>
<pre><code>
export USE_LIBPCRE=yes
</code></pre>
<p>
After you do that, you <em>also</em> need to <kbd>brew install pcre</kbd>, because if you don't you'll get a build error when you next attempt to build <kbd>git</kbd>. It will look something like:
</p>
<pre><code>
==> Upgrading git
==> Downloading http://git-core.googlecode.com/files/git-1.7.8.3.tar.gz
File already downloaded in /Users/hank/Library/Caches/Homebrew
==> make prefix=/usr/local/Cellar/git/1.7.8.3 install
GIT_VERSION = 1.7.8.3
* new build flags or prefix
* new link flags
./generate-cmdlist.sh > common-cmds.h+ && mv common-cmds.h+ common-cmds.h
/usr/bin/llvm-gcc -o hex.o -c -MF ./.depend/hex.o.d -MMD -MP -O3 -w -pipe -march=core2 -msse4.1 -I. -DUSE_LIBPCRE -DUSE_ST_TIMESPEC -DSHA1_HEADER='<openssl/sha.h>' -DNO_MEMMEM hex.c
/usr/bin/llvm-gcc -o ident.o -c -MF ./.depend/ident.o.d -MMD -MP -O3 -w -pipe -march=core2 -msse4.1 -I. -DUSE_LIBPCRE -DUSE_ST_TIMESPEC -DSHA1_HEADER='<openssl/sha.h>' -DNO_MEMMEM ident.c
/usr/bin/llvm-gcc -o kwset.o -c -MF ./.depend/kwset.o.d -MMD -MP -O3 -w -pipe -march=core2 -msse4.1 -I. -DUSE_LIBPCRE -DUSE_ST_TIMESPEC -DSHA1_HEADER='<openssl/sha.h>' -DNO_MEMMEM kwset.c
/usr/bin/llvm-gcc -o levenshtein.o -c -MF ./.depend/levenshtein.o.d -MMD -MP -O3 -w -pipe -march=core2 -msse4.1 -I. -DUSE_LIBPCRE -DUSE_ST_TIMESPEC -DSHA1_HEADER='<openssl/sha.h>' -DNO_MEMMEM levenshtein.c
/usr/bin/llvm-gcc -o list-objects.o -c -MF ./.depend/list-objects.o.d -MMD -MP -O3 -w -pipe -march=core2 -msse4.1 -I. -DUSE_LIBPCRE -DUSE_ST_TIMESPEC -DSHA1_HEADER='<openssl/sha.h>' -DNO_MEMMEM list-objects.c
/usr/bin/llvm-gcc -o ll-merge.o -c -MF ./.depend/ll-merge.o.d -MMD -MP -O3 -w -pipe -march=core2 -msse4.1 -I. -DUSE_LIBPCRE -DUSE_ST_TIMESPEC -DSHA1_HEADER='<openssl/sha.h>' -DNO_MEMMEM ll-merge.c
In file included from revision.h:5,
from list-objects.c:8:
grep.h:43: error: expected specifier-qualifier-list before ‘pcre’
make: *** [list-objects.o] Error 1
make: *** Waiting for unfinished jobs....
==> Exit Status: 2
http://github.com/mxcl/homebrew/blob/master/Library/Formula/git.rb#L51
==> Environment
HOMEBREW_VERSION: 0.8.1
HEAD: 730f9b7fbc30a74348223fa78e1ede295dc73340
HOMEBREW_PREFIX: /usr/local
HOMEBREW_CELLAR: /usr/local/Cellar
Hardware: dual-core 64-bit penryn
OS X: 10.7.2
Kernel Architecture: x86_64
Ruby: 1.8.7-249
/usr/bin/ruby => /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
Xcode: 4.2.1
GCC-4.0: N/A
GCC-4.2: N/A
LLVM: build 2336
Clang: 3.0 build 211
MacPorts or Fink? false
X11 installed? true
==> Build Flags
CC: /usr/bin/llvm-gcc => /usr/llvm-gcc-4.2/bin/llvm-gcc-4.2
CXX: /usr/bin/llvm-g++ => /usr/llvm-gcc-4.2/bin/llvm-g++-4.2
LD: /usr/bin/llvm-gcc => /usr/llvm-gcc-4.2/bin/llvm-gcc-4.2
CFLAGS: -O3 -w -pipe -march=core2 -msse4.1
CXXFLAGS: -O3 -w -pipe -march=core2 -msse4.1
MAKEFLAGS: -j2
Error: Failed executing: make prefix=/usr/local/Cellar/git/1.7.8.3 install
These existing issues may help you:
https://github.com/mxcl/homebrew/issues/6820
https://github.com/mxcl/homebrew/issues/6971
https://github.com/mxcl/homebrew/issues/7462
https://github.com/mxcl/homebrew/issues/8030
https://github.com/mxcl/homebrew/issues/8913
https://github.com/mxcl/homebrew/issues/8977
https://github.com/mxcl/homebrew/issues/9017
https://github.com/mxcl/homebrew/issues/9023
https://github.com/mxcl/homebrew/issues/9435
https://github.com/mxcl/homebrew/issues/9538
https://github.com/mxcl/homebrew/issues/9574
https://github.com/mxcl/homebrew/issues/9618
Otherwise, please report the bug:
https://github.com/mxcl/homebrew/wiki/checklist-before-filing-a-new-issue
</code></pre>
<p>
It's that little line <q><code>grep.h:43: error: expected specifier-qualifier-list before ‘pcre’</code></q> that clues you in that you have a PCRE problem.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-77160577007450525652011-08-30T21:21:00.008-04:002011-08-30T21:28:35.052-04:00Book Review: Python 3 Web Development Beginner's Guide<p>I recently received a free review copy (eBook version) of
<br/>
<a href="http://www.packtpub.com/python-3-web-development-beginners-guide/book" title="Packt Publishing page for Python 3 Web Development Beginner's Guide"><img src="http://www.packtpub.com/sites/default/files/3746OS_Python%203%20Web%20Development%20Beginner’s%20Guide_0.jpg" alt="Cover art for Python 3 Web Development Beginner's Guide" width="320" height="400"/></a>
<br /> from Packt Publishing. I was looking forward to this book, because I haven't really done much Python 3 work yet, and I wanted to see how it could make my life as a web developer better. However, the book wasn't what I expected. Instead of covering the basics of web development and how Python 3 applies, it is more of an introduction to the sorts of concerns that come up when you build a web framework on top of <a href="http://www.cherrypy.org/">CherryPy</a>. The sample code just happens to be in Python 3.</p>
<h2>The Good</h2>
<p>The two best parts of the book, to me, were the coverage of writing a <a href="http://jquery.com/">jQuery</a> plugin, and growing an <abbr title="Object-Relational Mapper">ORM</abbr> that uses metaclasses to provide a compact, readable way to define the models.</p>
<h2>The Bad</h2>
<p>I have a rather long list of things I didn't like about the book, some of which are a function of the title setting misleading expectations, and some of which I think are just problematic in general.</p>
<p>In general, I didn't care for the examples. Some of this is personal preference: I find that many people (myself included) learn better when they must type in the examples instead of opening up the code and reading through a completed solution. While the book sometimes indicated that something had been left as an exercise to the reader, opening up the sample code showed that the exercise actually <em>had not</em> been left to the reader. This mismatch between what the text of the book <em>says</em> will be in the sample code and what is <em>actually in</em> the sample code occurs in multiple places throughout the book, and gives a sense that the book was sloppily edited.</p>
<p>I also felt the examples in general were too complicated. It's fine to build up a complicated example over the course of a book, but instead we got a task list, a wiki, a Customer Relationship Management (<abbr title="Customer Relationship Management">CRM</abbr>) tool, a spreadsheet, and more. That's an awful lot to distract you from the beginner's principles that you would expect in a book with this title.</p>
<p>I also didn't care for many of the shortcuts taken in the book. In most instances, the book did acknowledge that the approach taken was not appropriate in the real world, but then proceeded with little or no justification for why it was done the way it was. The two examples that really leap out in this category are the password hashing scheme and the
failure to use a template engine.</p>
<p>When the book first introduces authentication, it explains that you should never store passwords in plaintext. This is absolutely correct, but the book then goes on to demonstrate a completely insecure password hashing scheme: <strong>UNSALTED</strong> <a href="http://en.wikipedia.org/wiki/SHA-1"><abbr title="Secure Hash Algorithm">SHA1</abbr></a>. The author only provides a cursory link to explain what you should actually be doing. In this day and age, demonstrating anything less than a <a href="http://www.usenix.org/events/usenix99/provos/provos_html/index.html"><code>bcrypt</code></a>-based solution is wrong. Read <a href="http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html">Enough With The Rainbow Tables</a> and <a href="http://codahale.com/how-to-safely-store-a-password/">How To Safely Store A Password</a> for a far better explanation than I can provide. There's really no excuse for
this: the added complexity of using <a href="http://code.google.com/p/py-bcrypt/"><code>py-bcrypt</code></a> instead of writing your own (insecure) <abbr title="Secure Hash Algorithm">SHA1</abbr>-based solution is trivial at worst; there's a strong case to be made that it would actually be simpler.</p>
<p>The failure to use a template engine (also a weakness acknowledged by the book) really makes the code harder to follow than it should be. Virtually any serious web development effort is going to take advantage of a template engine, and for good reason. This code gives me flashbacks to my days of writing Java servlets before the advent of <abbr title="Java Server Pages">JSP</abbr>, and I saw where one other reviewer invoked the specter of PHP. The fact that this style of coding draws such comparisons should give you an idea of just how unpythonic it is. I would be sympathetic to claims of not wanting to add too many external dependencies if the book did not already rely significantly on the magic of <a href="http://jqueryui.com/">jQuery UI</a>.</p>
<p>My last major complaint is simply one of focus: the book spends substantial amounts of time growing an <abbr title="Object-Relational Mapper">ORM</abbr> and teaching Python metaclasses (and doing a good job of it), but spends little
more than the bare minimum required on CherryPy (which is at the core of the code), and essentially none on understanding <abbr title="HyperText Transfer Protocol">HTTP</abbr>. In fact, the few times it comes up is usually in relation to <code>GET</code> vs. <code>POST</code>, where the decision is usually made based on inane implementation details such as whether request arguments are logged by default instead of <abbr title="HyperText Transfer Protocol">HTTP</abbr> fundamentals such as idempotency, safety, or cacheability (although caching <em>is</em> mentioned elsewhere, in the context of how to prevent it). Also, the book does mention security, but it does not give it the sort of omnipresent emphasis that is necessary to write good web applications, given the hostile nature of the domain. <abbr title="Cross-site Scripting">XSS</abbr>, <abbr title="Cross-Site Request Forgery">CSRF</abbr>, and SQL injection attacks all deserve much more attention than they were given.</p>
<h2>The Summary</h2>
<p>The book has some good content mixed in with the stuff I didn't like. Unfortunately, the good content is rarely specific to web development. For example, the chapter that uses metaclasses to clean up the <abbr title="Object-Relational Mapper">ORM</abbr> is one of the better resources on metaclasses that I've seen, but metaclasses are clearly not specific to web development. Furthermore, the impression of sloppy editing makes it hard to put as much faith in the content as it probably deserves. Given these flaws, I really don't think I'd recommend this book to a friend who was looking to get started with web development.</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-14652962241767032202011-08-06T10:48:00.011-04:002011-08-06T10:58:27.789-04:00Now Reading: Python 3 Web Development Beginner's Guide<p>
Packt Publishing has kindly given me a free review copy of the eBook edition of<br/>
<a href="http://www.packtpub.com/python-3-web-development-beginners-guide/book" title="Packt Publishing page for Python 3 Web Development Beginner's Guide"><img src="http://www.packtpub.com/sites/default/files/3746OS_Python%203%20Web%20Development%20Beginner’s%20Guide_0.jpg" alt="Cover art for Python 3 Web Development Beginner's Guide" width="320" height="400"/></a>
<br />
I'll be reading it and publishing my review here and on the <a href="http://pyatl.blogspot.com/" title="Homepage for the PyATL Book Club's blog">PyATL Book Club blog</a>.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com1tag:blogger.com,1999:blog-336295107079368245.post-10285447076433385152011-06-09T21:21:00.004-04:002011-06-09T21:23:58.945-04:00Announcing My First Real Open Source Project<p>
I ported the dark-background variant of the <a href="http://ethanschoonover.com/solarized" title="Homepage for the Solarized project">Solarized project</a> to <a href="http://pygments.org/" title="Hompage for Pygments">Pygments</a>. You can see the results <a href="http://gthank.github.com/solarized-dark-pygments/" title="GitHub page for my project">here</a>.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-60383283320554648192011-02-16T06:27:00.007-05:002011-02-16T06:34:35.715-05:00Note to Self: A NetBSD domU Doesn't Have An Entropy Source By Default<p>
I discovered this after a <a href="http://unix.stackexchange.com/questions/7358/how-long-should-it-take-to-generate-300-bytes-of-entropy-on-a-vps" title="Unix StackExchange: question about a symptom of this 'feature'">curious problem</a> led me to email my VPS provider and get back a pointer to <a href="http://mail-index.netbsd.org/netbsd-bugs/2009/02/24/msg009501.html" title="NetBSD mailing list exchange about this 'feature'">mailing list exchange</a>. Possibly more interesting than the original problem, I also learned that <a href="http://www.daemon-systems.org/man/rndctl.8.html" title="man page for NetBSD's rndctl">this exists</a>.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-22660759366715981182010-12-29T22:16:00.006-05:002010-12-29T22:23:10.442-05:00Note to Self: Source Django's bash Completion Automatically<p>
If you're using Doug Hellman's awesome <a href="http://www.doughellmann.com/projects/virtualenvwrapper/" title="virtualenvwrapper Home Page"><kbd>virtualenvwrapper</kbd></a> to manage your Django projects—and you really should be—try adding the following line to your <kbd>$VIRTUAL_ENV/bin/postactivate</kbd> script:
</p>
<pre><code>
source "$VIRTUAL_ENV/build/Django/extras/django_bash_completion"
</code></pre>
<p>
If you used the <kbd>--no-site-packages</kbd> option to create the virtualenv, that should automatically source the Django <kbd>bash</kbd> completion script everytime you <kbd>workon</kbd> into your project. If you didn't, you just need to figure out where the Django <kbd>bash</kbd> completion script is squirreled away on your system and use that path instead. BTW, <kbd>--no-site-packages</kbd> should really be the default.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com4tag:blogger.com,1999:blog-336295107079368245.post-42297519785494591842010-11-22T10:28:00.004-05:002010-11-22T10:46:43.910-05:00Note to Self: Changing info for the postgres system user<p>
Do you use MacPorts? Ever switch from one version of PostgresQL to another, e.g., 8.4 to 9.0? Did you notice that it started complaining about a non-existent home directory for the <kbd>postgres</kbd> system user? Me, too.
</p>
<p>
My first instinct was to edit the user, but there is no entry for <kbd>postgres</kbd> in <kbd>/etc/passwd</kbd>. That led me to this <a href="http://girders.org/changing-postgres-user-info-on-os-x-106" title="Changing postgres user info on OS X 10.6">excellent article</a>. Using that info, I cooked up the following command:
</p>
<pre><code>
sudo dscl localhost change /Local/Default/Users/postgres NFSHomeDirectory /opt/local/var/db/postgresql84 /opt/local/var/db/postgresql90
</code></pre>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-19907769555285280812010-08-11T07:40:00.003-04:002010-08-11T07:41:15.124-04:00Sneak Attack: The Smell of Hell<p>
Excellent <a href="http://www.dadhacker.com/blog/?p=1274" title="The Smell of Hell">article on code smells</a>.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-4946266216118149212010-08-05T08:37:00.002-04:002010-08-05T08:39:36.674-04:00Sneak Attack: Oops, I forgot to sudo in Vim<p>
Ever forget to <kbd>sudo</kbd> before you started editing that file in <kbd>vim</kbd>? Here's a <a href="http://al3k.net/2010/08/vim-forget-sud/" title="Oops, I forgot to sudo in Vim">nifty, <kbd>tee</kbd>-based trick</a> to save you some hassle.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-27195173133671840162010-07-23T16:28:00.001-04:002010-07-23T16:29:59.936-04:00Sneak Attack: Will it Optimize?<p>
<a href="http://ridiculousfish.com/blog/archives/2010/07/23/will-it-optimize/" title="An interesting article on what optimizations GCC can/will perform">Fun with optimizing compilers</a>.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com1tag:blogger.com,1999:blog-336295107079368245.post-1448466720939128812010-07-20T23:37:00.002-04:002010-07-20T23:42:13.314-04:00Sneak Attack: TEMPORARY (Tablespace) Insanity<p>
If you ever find yourself cursing about an <code>ORA-01652: unable to extend temp segment by 128 in tablespace TEMP</code> at 11 PM on your birthday, this <a href="http://oratips-ddf.blogspot.com/2008/02/temporary-tablespace-insanity.html" title="Handy article that teaches you tons about monitoring and administering Oracle tablespaces">article</a> might be just the thing for you.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-76342486875038365162010-07-19T11:28:00.004-04:002010-07-19T11:30:31.328-04:00Sneak Attack: GNU Screen and the Scrollback<p>
Handy <a href="http://www.samsarin.com/blog/2007/03/11/gnu-screen-working-with-the-scrollback-buffer/" title="GNU Screen: Working with the Scrollback Buffer">article on scrolling with <kbd>screen</kbd></a>, which I use rarely enough that I always need to look this up.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-37189511123555810832009-12-09T10:58:00.003-05:002009-12-09T11:03:36.570-05:00Sneak Attack: Fixing Django Management Commands<p>
Nifty post on <a href="http://blog.zacharyvoase.com/post/275566873" title="'Fixing Django Management Commands' by Zachary Voase'">reducing boilerplate and improving argument parsing in Django management commands</a>.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-61005262914664425982009-11-27T13:53:00.017-05:002009-11-27T17:59:08.362-05:00Getting Started with distutils<p>
If you've seen some of the discussions surrounding <a href="http://pypi.python.org/pypi/distribute" title="The distribute page at PyPI"><code>Distribute</code></a> (a fork of <abbr title="Phillip J. Eby">PJE</abbr>'s <a href="http://pypi.python.org/pypi/setuptools" title="The setuptools page at PyPI"><code>Setuptools</code></a>), you may be wondering about <code>distutils</code>, the backbone of both <code>Distribute</code> and <code>Setuptools</code>. If you are, then you may have noticed that it's easier to find details on the various tools built on top of it than it is to find info on the basics, even though <code>distutils</code> is in the standard library.</p>
<h4>Helpful Resources</h4>
<p>Here are some of the resources I found useful:</p>
<ul>
<li>the <a href="http://docs.python.org/distutils/introduction.html" title="The standard docs covering distutils">standard docs for distutils</a>. These are a good start, as they outlines the basics of <code>distutils</code> as it currently stands, without any of the various <abbr title="Python Enhancement Proposal">PEP</abbr>s that have been discussed/proposed.</li>
<li>the <a href="http://docs.python.org/distutils/apiref.html" title="The API docs from the standard library for distutils">API reference</a>, since it helps cover the <em>numerous</em> keyword arguments to the <a href="http://docs.python.org/distutils/apiref.html#distutils.core.setup" title="Direct link to the API docs for the setup function, since I'm using it a LOT"><code>setup</code></a> function.</li>
<li>the <a href="http://pypi.python.org/pypi?:action=list_classifiers" title="List of classifiers, hosted by PyPI">list of classifiers</a> at PyPI; this is handy to make sure you're using actual classifiers that other Python developers are likely to understand instead of ones you just make up</li>
<li>this <a href="http://wiki.python.org/moin/Distutils/Tutorial" title="Tutorial on distutils hosted at the Python wiki"><code>distutils</code> tutorial</a> on the Python wiki</li>
<li>the <a href="http://wiki.python.org/moin/Distutils/Cookbook" title="The Distutils Cookbook on the Python Wiki">Distutils Cookbook</a>; I particularly enjoy the <a href="http://wiki.python.org/moin/Distutils/Cookbook/AutoPackageDiscovery" title="The AutoPackageDiscovery Recipe from the Distutils Cookbook">AutoPackageDiscovery recipe</a></li>
</ul>
<h4>Miscellaneous</h4>
<p>One thing to remember: the <code>package_data</code> and <code>data_files</code> keyword arguments to <code>setup</code> in <kbd>setup.py</kbd> tell the installer what to install, <kbd>MANIFEST.in</kbd> tells the packager what to include in the distribution file. Even if it seems duplicative, you need to make sure your resources show up in both places if you want to be able to use <kbd>python setup.py install</kbd> using the distribution you build using <kbd>python setup.py sdist</kbd>.</p>
<h4>Testing It All Out</h4>
<p>After you package up your program, you can see if your <kbd>setup.py</kbd> is correct by doing a test install in a <a href="http://pypi.python.org/pypi/virtualenv" title="The virtualenv page at PyPI"><code>virtualenv</code></a>. This let's you make sure you can <kbd>python setup.py install</kbd> etc. without contaminating your global site packages. If you haven't heard about <code>virtualenv</code>, I recommend reading up on it; it's really handy. The <a href="http://www.google.com/search?q=virtualenv" title="Google results for a search for virtualenv">first page of Google results</a> is a good starting point.</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-4958740883543603162009-11-18T15:49:00.002-05:002009-11-18T15:50:54.279-05:00Sneak Attack: Debugging in Python<p>
Nice <a href="http://pythonconquerstheuniverse.wordpress.com/2009/09/10/debugging-in-python/" title="stephenferg's excellent introduction to pdb">intro to debugging in Python using pdb</a>.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-20611899943265327922009-11-03T17:34:00.007-05:002009-11-04T12:16:37.482-05:00Setting up gitosis on OS X<h4>
What is <kbd>gitosis</kbd>?
</h4>
<p>
<kbd>gitosis</kbd> is a wrapper around <kbd>git</kbd> that makes it easier share repositories, especially as it relates to managing access rights.
</p>
<h4>
Why Should I Care?
</h4>
<p>
The benefit that made me check it out is that I don't have to create an account on my dev machine for every single developer to whom I'd like to give access to some of my <kbd>git</kbd> repos.
</p>
<h4>
Assumptions
</h4>
<ul class="simple">
<li>You installed <kbd>git</kbd> and <kbd>python</kbd> from <a class="reference external" href="http://www.macports.org/">MacPorts</a>.
</li>
<li>You have enabled "Remote Login" in the "Sharing" Preferences pane.
</li>
<li>You have a public key (typically generated via <kbd>ssh-keygen</kbd>); see the <a class="reference external" href="http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man1/ssh-keygen.1.html">man pages</a> for more details.
</li>
</ul>
<h4>
Installation
</h4>
<h5>
Preliminary Steps
</h5>
<ol class="arabic simple">
<li>Create a <kbd>git</kbd> user
</li>
<li>Add <kbd>git</kbd> to the list of users who can <kbd>ssh</kbd> in
</li>
<li>Configure <kbd>git</kbd>'s <kbd>.bashrc</kbd> (<strong>NOT</strong> <kbd>.bash_profile</kbd>) so <kbd>port</kbd>-installed apps are on the <kbd>PATH</kbd>. Mine looks like
</li>
</ol>
<pre>
<code language="shell"> export PATH=/opt/local/bin:/opt/local/sbin:/opt/local/Library/Frameworks/Python.framework/Versions/Current/bin/:$PATH
export MANPATH=/opt/local/share/man:$MANPATH
</code>
</pre>
<h5>
Installing <kbd>gitosis</kbd>
</h5>
<ol class="arabic simple">
<li>
<kbd>cd /tmp</kbd>
</li>
<li>
<kbd>mkdir src</kbd>
</li>
<li>
<kbd>cd src</kbd>
</li>
<li>
<kbd>git clone git://eagain.net/gitosis.git</kbd>
</li>
<li>
<kbd>cd gitosis</kbd>
</li>
<li>
<kbd>python setup.py install</kbd>
</li>
<li>
<kbd>sudo chmod 755 /Users/git/repositories/gitosis-admin.git/hooks/post-update</kbd>
</li>
</ol>
<h4>
Configuration
</h4>
<h5>
Setting up Admin Access
</h5>
<p>
Add yourself as an admin (member of the <var>gitosis-admin</var> group) by executing <kbd>sudo -H -u git gitosis-init < ~/.ssh/id_dsa.pub</kbd>. This will use your public key as input into <kbd>gitosis-init</kbd> and set you up as an admin.
</p>
<h5>
Cloning the Admin Repo
</h5>
<p>
Try <kbd>git clone git@`$HOST`:gitosis-admin.git</kbd>. It should work. If it doesn't, and complains about the other end unexpectedly hanging up, the <var>$PATH</var> for <kbd>git</kbd> is probably misconfigured. Make sure you configured <kbd>.bashrc</kbd>, because <kbd>.bash_profile</kbd> won't stick around.
</p>
<h5>
Configuring a New Repo
</h5>
<p>
You make configuration changes to <kbd>gitosis</kbd> by editing your local clone of <kbd>gitosis-admin</kbd> and FIXME kbd pushing them back. Let's add a new repo.
</p>
<ol class="arabic simple">
<li>Open up <kbd>gitosis.conf</kbd> in your editor of choice
</li>
<li>Add an entry like the one below
</li>
<li>Save
</li>
<li>
<kbd>git push</kbd>
</li>
</ol>
<pre>
<code> [group fabfour]
members = john paul george ringo
writable = the_monkeys_are_hacks
</code>
</pre>
<h6>
Breaking It Down
</h6>
<pre>
<code> [group fabfour]
</code>
</pre>
<p>
We're defining a new group, named <var>fabfour</var>.
</p>
<pre>
<code> members = john paul george ringo
</code>
</pre>
<p>
Adding <var>john</var>, <var>paul</var>, <var>george</var>, <var>ringo</var> as members of the <var>fabfour</var> group.
</p>
<pre>
<code> writable = the_monkeys_are_hacks
</code>
</pre>
<p>
Listing <var>the_monkeys_are_hacks</var> as the only writable repo for the <var>fabfour</var> group. In case you're saying "Wait, I don't have a <var>the_monkeys_are_hacks</var> repo!" don't worry, that's coming next. You have to do all of this <em>before</em> you try to <kbd>push</kbd> anything to <kbd>gitosis</kbd>.
</p>
<h5>
Populating Your New Repo
</h5>
<ol class="arabic">
<li>
<dl class="first docutils">
<dt>
If the repo doesn't exist, create it
</dt>
<dd>
<ol class="first last arabic simple">
<li>
<kbd>mkdir the_monkeys_are_hacks</kbd>
</li>
<li>
<kbd>cd the_monkeys_are_hacks</kbd>
</li>
<li>
<kbd>git init</kbd>
</li>
<li>Do Work Here and Commit It
</li>
</ol>
</dd>
</dl>
</li>
<li>
<p class="first">
Add your new <kbd>gitosis</kbd>-managed repo as a <var>remote</var>; inside your repo, execute <kbd>git remote add origin git@`$HOST`:the_monkeys_are_hacks.git</kbd>
</p>
</li>
<li>
<p class="first">
Push to it; inside your repo, execute <kbd>git push origin master:refs/heads/master</kbd>
</p>
</li>
</ol>
<p>
If the last step fails with an inscrutable error, there's a good chance you forgot to <kbd>chmod</kbd> the <kbd>post-update</kbd> hook.
</p>
<h5>
Actually Letting John and the Gang Access the Repo
</h5>
<p>
Before <var>john</var>, <var>paul</var>, <var>george</var>, or <var>ringo</var> can actually get into the server, you need to add their public keys under <kbd>gitosis-admin/keydir</kbd>. I'm going to wave my hands concerning how you get the public keys, but they need to be added to <kbd>gitosis-admin/keydir</kbd> and they need to be named using the convention <var>username.pub</var>, so we'd have:
</p>
<ol class="arabic simple">
<li>
<kbd>cd gitosis-admin</kbd>
</li>
<li>
<kbd>cp /tmp/john.pub keydir/</kbd>
</li>
<li>
<kbd>cp /tmp/paul.pub keydir/</kbd>
</li>
<li>
<kbd>cp /tmp/george.pub keydir/</kbd>
</li>
<li>
<kbd>cp /tmp/ringo.pub keydir/</kbd>
</li>
<li>
<kbd>git add keydir/john.pub keydir/paul.pub keydir/george.pub keydir/ringo.pub</kbd>
</li>
<li>
<kbd>git ci -m "Adding the keys for the Fab Four"</kbd>
</li>
<li>
<kbd>git push</kbd>
</li>
</ol>
<h4>
Want More?
</h4>
<ul class="simple">
<li>Check out this extremely detailed (non-Mac-specific) <a class="reference external" href="http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way">guide</a>.
</li>
</ul>
<p>
Back to flipping out...
</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-4734836325558525022009-10-14T22:40:00.003-04:002009-10-14T22:45:03.942-04:00Note to Self: apropos finds man entries<p>
Ever get that feeling that there just <em>has</em> to be something built right into the shell that will solve the problem you're facing, but have no idea what that something might be? Enter <a href="http://unixhelp.ed.ac.uk/CGI/man-cgi?apropos" title="man page for apropos"><kbd>apropos</kbd></a>. It searches the <kbd>man</kbd> page blurbs for entries that match your keywords, which can be regular expressions. How is it that more people don't talk about features like this?
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-36789803597185244742009-09-28T15:17:00.004-04:002009-10-05T13:05:39.609-04:00Sneak Attack: Functional Java<p>
How is this the first time I've heard of <a href="http://functionaljava.org/" title="The Functional Java home page">Functional Java</a>?
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-59692845838798500062009-09-25T15:25:00.004-04:002009-09-25T15:31:10.955-04:00Note to Self: nohup a Running Process<p>
<kbd>nohup -p <var>pid</var></kbd>
</p>
<p>
<a href="http://publib.boulder.ibm.com/infocenter/systems/topic/com.ibm.aix.cmds/doc/aixcmds4/nohup.htm#nohup_flags_p">see also</a>
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-35279800371304572932009-09-24T13:45:00.004-04:002009-09-24T13:48:14.237-04:00Sneak Attack: 10 Useful Usability Findings and Guidelines<p>
I wish more people would pay attention to things like <a href="http://www.smashingmagazine.com/2009/09/24/10-useful-usability-findings-and-guidelines/" title="Summary of important web page usability findings">this</a>. It's not like most of that information is new, but it still gets ignored far too often.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-2037915847420555662009-09-22T08:04:00.003-04:002009-09-22T08:07:16.700-04:00Sneak Attack: Python is not Java<p>
One of the (in Internet time, at least) <a href="http://dirtsimple.org/2004/12/python-is-not-java.html" title="A rundown of things you get wrong when coming to Python from Java">golden oldies</a>. Re-reading this makes me cringe when I think back.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-48127830230904970952009-09-22T07:59:00.002-04:002009-09-22T08:01:16.013-04:00Sneak Attack: Why I Like pip<p>
The <a href="http://www.b-list.org/weblog/2008/dec/15/pip/" title="James Bennett on why he likes pip">most concise description I've found of really <em>using</em> <kbd>pip</kbd></a>.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-3803137743232295612009-09-15T09:39:00.002-04:002009-09-15T09:44:58.535-04:00Sneak Attack: Sacrificing Quality—Part II—Kaizen<p>
Interesting post about <a href="http://chrismelinn.wordpress.com/2009/09/15/sacrificing-quality-and-kaizen/">negative hiring impacts</a> caused by sacrificing quality. I also recommend the <a href="http://chrismelinn.wordpress.com/2009/07/21/sacrificing-quality-costs-more-than-you-think/">first post in the series</a>, which focuses on the psychological impacts of sacrificing quality.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-72184188449419371332009-08-29T09:30:00.002-04:002009-08-29T09:32:24.653-04:00Sneak Attack: Co-routines as an alternative to state machines<p>
<a href="http://eli.thegreenplace.net/2009/08/29/co-routines-as-an-alternative-to-state-machines/#id3" title="Excellent article about/using coroutines">Co-routines as an alternative to state machines</a>. And the money quote: <q>Co-routines are to state machines what recursion is to stacks</q>.
</p>
<p>Back to flipping out...</p>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0tag:blogger.com,1999:blog-336295107079368245.post-76570536860039213172009-08-25T06:53:00.007-04:002009-08-29T09:03:54.337-04:00PyAtl Notes—2009-08-20<p>What follows is essentially a stream-of-consciousness dump from the <a class="reference external" href="http://pyatl.org/">PyATL</a> meeting on August 20.</p>
<h4>Introduction to Python and Sqlite3</h4>
<div style="font-size:small">Presented by Alfredo Deza</div>
<ul class="simple">
<li>For simple things, it's blazing fast</li>
<li>It's local, so no network necessary</li>
<li>Serializes to a single file</li>
<li>Uses DB-API 2.0 (see <a class="reference external" href="http://www.python.org/dev/peps/pep-0249">PEP 249</a>). Once you have your <tt class="docutils literal"><span class="pre">cursor</span></tt>, you can start running SQL.</li>
<li>NOTE: Use <tt class="docutils literal"><span class="pre">sqlite3.connect(':memory:',</span> <span class="pre">isolation_level='exclusive')</span></tt> to use an in-memory DB</li>
<li>The <tt class="docutils literal"><span class="pre">iterdump()</span></tt> method of the sqlite3 connection gives you an iterable that lets you export the in-memory database. This is handy if you want to write them all to a file.</li>
<li>Although the sqlite3 docs claim that the concurrency situation has improved, the Internet at large seems to indicate that problems still abound.</li>
</ul>
<h4>GeoDjango</h4>
<div style="font-size:small">Presented by Skylar Saveland</div>
<ul class="simple">
<li>Recommend you use PostGIS w/ PostgresQL</li>
<li><a class="reference external" href="http://openlayers.org/">OpenLayers</a> is a nice library for embedding map widgets on any webpage.</li>
<li>Core team is available on IRC (<tt class="docutils literal"><span class="pre">#geodjango</span></tt> on Freenode)</li>
<li>They make it fairly easy to integrate with Google Maps</li>
<li>Instead of standard Django <tt class="docutils literal"><span class="pre">models</span></tt>, you use the one from GeoDjango and then you get the <tt class="docutils literal"><span class="pre">Point</span></tt>, <tt class="docutils literal"><span class="pre">Polygon</span></tt> etc. so that you can store GIS data right with your Django models</li>
<li>You can do distance, intersection, touches, etc. queries right in the ORM</li>
</ul>
<h4>Nuts & Bolts</h4>
<div style="font-size:small">Presented by Brandon Rhodes</div>
<ul>
<li><p class="first">PyCon is 6 months away</p></li>
<li>String formatting</li>
<ul>
<li>New in 2.6</li>
<li><tt class="docutils literal"><span class="pre">str</span></tt> and <tt class="docutils literal"><span class="pre">unicode</span></tt> objects now have a <tt class="docutils literal"><span class="pre">format()</span></tt> method, and <em>that's</em> the encouraged way to do string formatting; <tt class="docutils literal"><span class="pre">%</span></tt> is right out.</li>
<li>At least one of the benefits of the new method is that it's easier to read the name-based format</li>
<li>It lets you use dot-notation to access attributes of parameters</li>
<li>Also supports indexing into lists, etc.</li>
<li>I need to look this up, pronto. It's covered briefly in the sequence types in the standard docs and links to a dedicated page for the new syntax.</li>
</ul>
<li><a class="reference external" href="http://codespeak.net/lxml/">lxml</a> != <a class="reference external" href="http://effbot.org/zone/element-index.htm">ElementTree</a></li>
<ul>
<li>The goal of ElementTree is to be a Pythonic XML library</li>
<li>It's probably a dead project, since the current version is 2 years old</li>
<li>lxml uses the "ElementTree" object model, but it's built on top of <a class="reference external" href="http://xmlsoft.org/">libxml2</a> and <a class="reference external" href="http://xmlsoft.org/XSLT/">libxslt</a> so it's blazing fast.</li>
<li>Remember these two imports:</li>
<ul>
<li><tt class="docutils literal"><span class="pre">from</span> <span class="pre">lxml</span> <span class="pre">import</span> <span class="pre">etree</span></tt></li>
<li><tt class="docutils literal"><span class="pre">from</span> <span class="pre">lxml.cssselect</span> <span class="pre">import</span> <span class="pre">CSSSelector</span> <span class="pre">as</span> <span class="pre">css</span></tt></li>
</ul>
<li>lxml also supports CSS selectors</li>
<li>Don't forget the default for lxml is an XML parser; you want the HTML parser</li>
<li><a href="http://blog.ianbicking.org/2008/12/10/lxml-an-underappreciated-web-scraping-library/" title="Ian Bicking's blog post on lxml's usefulness for web scraping">Ian Bicking says lxml is better</a> than <a class="reference external" href="http://www.crummy.com/software/BeautifulSoup/">BeautifulSoup</a></li>
</ul>
</ul>
<h4>Making Code More Testable</h4>
<div style="font-size:small">Presented by Brandon Rhodes</div>
<ul class="simple">
<li>Based on <a class="reference external" href="http://googletesting.blogspot.com/2008/08/by-miko-hevery-so-you-decided-to.html">Writing Testable Code</a>; showing Python examples of how some of these actually look when you put them in action</li>
</ul>
<h5>Don't Mix Object Graph Construction with Application Logic</h5>
<ul class="simple">
<li>This one makes it <em>really</em> hard to test classes in isolation, because instantiating one starts instantiating a bunch of objects we <em>don't</em> want to test.</li>
<li>On a side note, nose handily shows you captured <tt class="docutils literal"><span class="pre">stdout</span></tt> when a test fails, and doesn't show you when the test is successful. That way you can you leave your debugging print statements. It does <em>not</em> capture <tt class="docutils literal"><span class="pre">stderr</span></tt>.</li>
<li>The simple fix for this in Python is to accept dependencies in the <tt class="docutils literal"><span class="pre">__init__</span></tt> method. You might recognize this as constructor-based dependency injection. In Java, mutator-based dependency injection is more common.</li>
</ul>
<h5>Avoid "Global State"</h5>
<ul class="simple">
<li>Even though every programmer (should) know global state is evil, you still see this quite often in web apps where the global state is something like the request and/or session.</li>
<li>The breakage is quite often far more extensive than you would expect, e.g., a test in one file that doesn't handle global state well can break tests in other files, even if they <em>are</em> doing a good job of handling the global state.</li>
<li>The fix is to pass the state explicitly, even if the state has to be passed to a lot of functions. This is inconvenient at times, but is usually worth it.</li>
</ul>Hank Gayhttp://www.blogger.com/profile/13405417651021620361noreply@blogger.com0