<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-11802292</id><updated>2012-01-12T07:48:00.533-08:00</updated><category term='cmd2'/><category term='linux'/><category term='women'/><category term='postgresql'/><category term='mysql'/><category term='ohio'/><category term='web'/><category term='geekeventaggregator'/><category term='talk'/><category term='python group'/><category term='dayo'/><category term='usergroup'/><category term='meeting'/><category term='conference'/><category term='pythonic-plsql'/><category term='pycon'/><category term='oracle'/><category term='microformats'/><category term='sqlpython'/><category term='pyohio python conference ohio'/><category term='python'/><category term='turbogears'/><category term='gender'/><category term='pyohio'/><category term='htsql'/><category term='dayoug'/><title type='text'>Catherine: pyOraGeek</title><subtitle type='html'>Databases taste better with Python.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default?start-index=101&amp;max-results=100'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>310</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-11802292.post-374629124243647766</id><published>2012-01-12T07:13:00.000-08:00</published><updated>2012-01-12T07:48:00.565-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='usergroup'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Movie Night at the user group</title><content type='html'>At &lt;a href="http://www.dma.org/sigs.shtml#Dynamic"&gt;Dayton Dynamic Languages&lt;/a&gt; last night, we watched a great video, &lt;a href="http://2010.osdc.com.au/proposal/196/git-ages-4-and"&gt;"Git for Ages 4 and Up"&lt;/a&gt;.  ("WARNING: CHOKING HAZARD - Small Parts. Not For Children Under 4 Years.")  We had a great time, and I learned a bunch of things that I literally put to use for work on the bus home that night.&lt;br /&gt;&lt;br /&gt;So, what's the difference between watching a video at home and watching it at a user group meeting?  The all-important &lt;span style="font-style:italic;"&gt;pause key&lt;/span&gt;.  Every couple minutes, one of us would say, "Wait, what?"; we'd pause and discuss.  Discussion is always the best part of a user event; anytime I help organize an event where the attendees don't start talking to each other, I'm disappointed.  DDL never has a problem with discussion, but the video acts as a great tool to help seed and drive the conversation.&lt;br /&gt;&lt;br /&gt;Now I'm thinking that all sorts of groups may want to add an occasional Movie Night to their regular meeting schedule.  There are plenty of great video sources like &lt;a href="http://python.mirocommunity.org/"&gt;Python Miro Community&lt;/a&gt;, but watching with your friends adds enormously to the experience.&lt;br /&gt;&lt;br /&gt;[Hi to all my friends at CodeMash!  Sorry I'm not there... next year in Sanduskalem, right?]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-374629124243647766?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/374629124243647766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=374629124243647766' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/374629124243647766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/374629124243647766'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2012/01/movie-night-at-user-group.html' title='Movie Night at the user group'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-3920603609615597199</id><published>2011-10-27T14:10:00.000-07:00</published><updated>2011-10-27T14:17:50.339-07:00</updated><title type='text'>MySQL Bizarro World</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-ym93EasTKSs/TqnKJGhzFZI/AAAAAAAAAHs/UI0LuPxc11g/s1600/bworld.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 347px; height: 400px;" src="http://3.bp.blogspot.com/-ym93EasTKSs/TqnKJGhzFZI/AAAAAAAAAHs/UI0LuPxc11g/s400/bworld.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5668283863742485906" /&gt;&lt;/a&gt;&lt;br /&gt;Getting used to MySQL has been a real challenge for me.  Most everything I know about databases is backward in this MySQL world.&lt;br /&gt;&lt;br /&gt;In the REAL WORLD,&lt;br /&gt;  table names are case-insensitive.&lt;br /&gt;  &lt;br /&gt;In MySQL WORLD,&lt;br /&gt;  table names are case-sensitive.  Maybe.  Depending on what platform you're running on.&lt;br /&gt;  &lt;br /&gt;in the REAL WORLD,&lt;br /&gt;  queries against VARCHAR data are case-sensitive.&lt;br /&gt;  &lt;br /&gt;in the MySQL WORLD,&lt;br /&gt;  queries against VARCHAR data are case-insensitive.  (So is every other use of the data.  Which can cause immeasurable pain w/r/t UNIQUE constraints if you weren't prepared for it.)&lt;br /&gt;  &lt;br /&gt;in the REAL WORLD,&lt;br /&gt;  database connections are expensive, and complex queries are optimized well.  If you can connect to the database once and issue a single complex query, you'll get much better performance than if you make repeated connections and issue large numbers of simple queries.&lt;br /&gt;  &lt;br /&gt;in the MySQL WORLD,&lt;br /&gt;  database connections are cheap, and complex queries are optimized badly.  If you make repeated connections and issue large numbers of simple queries, you'll get much better performance than if you connect to the database once and issue a single complex query.&lt;br /&gt;  &lt;br /&gt;I think the conclusion is obvious: MySQL was written by programmers from Superman's &lt;a href="http://tvtropes.org/pmwiki/pmwiki.php/Main/BizarroUniverse"&gt;Bizarro World&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Incidentally, the &lt;a href="http://daytonoracle.org/"&gt;Dayton Oracle User Group&lt;/a&gt; is planning a MySQL-themed meeting in the mid-term future.  If you'd like to get involved - as an attendee or a speaker - let me know!&lt;br /&gt;&lt;br /&gt;Hello!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-3920603609615597199?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/3920603609615597199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=3920603609615597199' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3920603609615597199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3920603609615597199'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2011/10/mysql-bizarro-world.html' title='MySQL Bizarro World'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-ym93EasTKSs/TqnKJGhzFZI/AAAAAAAAAHs/UI0LuPxc11g/s72-c/bworld.gif' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-1547053980742461885</id><published>2011-10-20T15:31:00.000-07:00</published><updated>2011-10-20T15:38:28.557-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='htsql'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='ohio'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>HTSQL answers</title><content type='html'>&lt;a href="http://catherinedevlin.pythoneers.com/presentations/htsql-olf/"&gt;HTSQL slides&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Thanks to the great audiences at my HTSQL talks at Ohio Linuxfest and Dayton IEEE!  (And to the folks who will come see me at Columbus Code Camp on Saturday.)  I've promised you answers to some of your questions that stumped me, and (for OLF people) been criminally slow at getting them to you.  So here you are!  Some of the answers come from my own research, but I've also inserted quotes directly from the creator of HTSQL, Clark Evans... the embedded quotes are from Clark.&lt;br /&gt;&lt;br /&gt;1. How do you restrict access via HTSQL?&lt;br /&gt;&lt;br /&gt;&lt;a href="http://htsql.org/doc/install.html#security"&gt;http://htsql.org/doc/install.html#security&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;First, consider carefully which database user account you use to run htsql-ctl serve, and assign only the rights that user (representing your HTSQL users) should legitimately have.&lt;br /&gt;&lt;br /&gt;Second, you can (and probably should) close down port 8080 (or whatever port you're serving HTSQL on) on your machine's firewall, and route all traffic through a webserver like Apache.  (&lt;a href="http://catherinedevlin.blogspot.com/2011/09/htraf-setup-from-zero.html"&gt;My HTRAF directions&lt;/a&gt; tell how to do that.)  Then you can apply whatever authentication, IP limits, etc. you need at the webserver level.&lt;br /&gt;&lt;br /&gt;If you need multiple groups to access your data with varying levels of permission, it's easy to run multiple instances of HTSQL as multiple&lt;br /&gt;database users, route those instances through Apache, and restrict them at the Apache level appropriately.&lt;br /&gt;&lt;blockquote&gt;This is a great answer.  A few more items:&lt;br /&gt;&lt;br /&gt;If the database is static (updated periodically), want to put varnish or something on the front.  When you make another "data push" you could run though common queries to warm the cache.  This is what we do for demo.htsql.org so that queries in our tutorial don't even hit the server.&lt;br /&gt;&lt;br /&gt;For PostgreSQL, there is also a ``select timeout`` you can set using the "tweak.timeout" plugin, it can help a little bit with accidental denial of service.  Basically, it cancels a query if your query runs over a particular number of seconds.  If other databases have this ability, we could add a similar feature.  &lt;br /&gt;&lt;br /&gt;There is a also a ``autolimit`` that you can apply, this adds a LIMIT X to every query.  In the current HTSQL implementation, all the results have to fit into memory: so, you can kill the backend process by creating a large result set.   We'll fix this problem sometime next year... if you have a friendly audience, this generally isn't a problem.  This plugin helps ensure users don't "accidently" create a big result though.&lt;br /&gt;&lt;br /&gt;Even with these two enabled, you can still make queries that bring down either the HTSQL server (via memory exhaustion on big result) or the Database (via memory or cpu denial).  So, some caution is advised if you give *direct* HTSQL access since you're letting arbitrary queries be created and such.&lt;br /&gt;  &lt;br /&gt;One solid way to handle this is separate the "trusted" users who need to create queries from "untrusted" users who are just running canned reports and dashboards.   There's a "ssi" demo for doing this and we'll improve on it later.  Basically, you have .htsql files server side with canned queries in them.  You then limit users to only access .htsql saved queries.  It'd be great to have this more automated... the demo code is just that: a proof of concept.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;2. How can you paginate results?&lt;br /&gt;&lt;br /&gt;You can request a "page" of results with HTSQL's limit() function.  The optional second argument is an offset:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://demo.htsql.org/course.limit(10)"&gt;http://demo.htsql.org/course.limit(10)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://demo.htsql.org/course.limit(10,10)"&gt;http://demo.htsql.org/course.limit(10,10)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://demo.htsql.org/course.limit(10,20)"&gt;http://demo.htsql.org/course.limit(10,20)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There is a &lt;a href="http://htsql.org/blog/htsql-2.1-beta2.html?highlight=autolimit"&gt;tweak.autolimit&lt;/a&gt; available to keep users from killing off their browsers with mistakenly broad queries.  For example:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;htsql-ctl -E tweak.autolimit:limit=10 serve pgsql://user:pwd@host/database&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Users may also want to consider a browser like Chrome, where a runaway tab won't lock up the entire browser.&lt;br /&gt;&lt;br /&gt;There's no way currently to have HTML results automatically insert "Next Page"-type links.  Keep in mind that users aren't likely to genuinely want to page manually through very long result sets anyway; they'd probably be better off narrowing their queries rather than searching long lists by eyeball.&lt;br /&gt;&lt;br /&gt;There are plans for HTRAF to generate automatically paginated tables at some point in the future.&lt;br /&gt;&lt;br /&gt;3. Performance-wise, how does HTSQL respond under intense loads?&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;The best way to perform under intense loads is to not perform at all (see varnish above).  The HTSQL server is also stateless: you can load balance as many copies as you need to meet demand.&lt;br /&gt;&lt;br /&gt;As far as a single-process goes, the time spent converting HTSQL-to-SQL isn't really that significant compared to the query execution.  The result handling isn't bad... although we've not done any load testing.&lt;br /&gt;&lt;br /&gt;The SQL generation is probably the most important part.  I think HTSQL generates quite clear/clean SQL, although your mileage may vary.  To make any real judgments you need test queries and test data and profile it.   Often times a 30 line SQL query that looks a bit ugly/repetitive will outperform a "hand-optimized" SQL query that is 12 lines.&lt;br /&gt;&lt;br /&gt;We &lt;a href="http://www.htsql.com/"&gt;(Prometheus Research)&lt;/a&gt; [would] be delighted to help figure out why HTSQL performs badly if you have a specific query and test data set for us!&lt;br /&gt;&lt;br /&gt;Anecdotally, for big (1-3 page) queries we have converted from SQL to HTSQL, the HTSQL equivalent is ~40% less source code and an order of magnitude more readable and maintainable.  The SQL we then generate is typically bigger, sometimes 2x the size, but so far, the performance in the samples we have has been as-good-if-not-better than the original.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;4. What about outer joins in HTSQL?&lt;br /&gt;&lt;br /&gt;All HTSQL joins are LEFT OUTER joins - rows from the "driving" table are always included in the results, whether or not there are also records in the joined tables... it's a natural consequence of the driving table always determining the size of the result set.  (If you specifically want to exclude rows that don't have counterparts in the joined tables, you can use &lt;a href="http://htsql.org/doc/ref/functions.html#aggregate-functions"&gt;?exists(joined-table)&lt;/a&gt;.  More about that &lt;a href="http://www.htsql.com/htsql_blog_tips_cardinality"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-1547053980742461885?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/1547053980742461885/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=1547053980742461885' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1547053980742461885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1547053980742461885'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2011/10/htsql-answers.html' title='HTSQL answers'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-2384401491003979773</id><published>2011-10-19T20:18:00.000-07:00</published><updated>2011-10-20T15:31:42.185-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='htsql'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='ohio'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Columbus Code Camp</title><content type='html'>I'll be speaking on HTSQL this Saturday at &lt;a href="http://columbuscodecamp.com/"&gt;Columbus Code Camp&lt;/a&gt;.  It was a great event last year, and I'm expecting even better this year.  Check out the schedule - it's an excellent set of "I gotta see that!" topics.&lt;br /&gt;&lt;br /&gt;Hope to see you there!  (Unless you're at &lt;a href="http://southwestohiogivecamp.org/"&gt;Southwest Ohio GiveCamp&lt;/a&gt;, of course - sorry I have to miss my GiveCamp friends this year.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-2384401491003979773?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/2384401491003979773/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=2384401491003979773' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/2384401491003979773'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/2384401491003979773'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2011/10/columbus-code-camp.html' title='Columbus Code Camp'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-1703018261947191793</id><published>2011-09-11T09:59:00.000-07:00</published><updated>2011-09-12T05:57:36.814-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>HTRAF setup, from zero</title><content type='html'>As I mentioned in my OLF talk, setting up HTSQL is crazy-easy.&lt;br /&gt;&lt;br /&gt;HTRAF, however - the library that lets you do the gorgeous graphics - takes a few more steps.  &lt;a href="http://htsql.org/htraf/"&gt;The documentation&lt;/a&gt; doesn't spell out the webserver-specific aspects of the setup, which may confuse you if you aren't an experienced webserver admin.  So, here's my expanded version "getting started with HTRAF".  My directions assume an Ubuntu machine.&lt;br /&gt;&lt;br /&gt;1. &lt;/code&gt;&lt;pre&gt;sudo easy_install htsql&lt;/pre&gt;&lt;/code&gt;  It doesn't have to be on the same machine you use for HTRAF, just a machine that your HTRAF machine can contact.  &lt;br /&gt;&lt;br /&gt;2. Start up HTSQL: &lt;/code&gt;&lt;pre&gt;htsql-ctl serve postgres://username:password@hostname/databasename&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;3. On your HTRAF machine, install a web server.  &lt;/code&gt;&lt;pre&gt;sudo apt-get install apache2&lt;/pre&gt;&lt;/code&gt;  &lt;br /&gt;4. Get the HTRAF library.  The simplest thing is to put it right under your Apache DocumentRoot:&lt;br /&gt;&lt;/code&gt;&lt;pre&gt;&lt;br /&gt;sudo su - www-data&lt;br /&gt;cd /var/www/&lt;br /&gt;wget http://htsql.org/download/HTRAF-latest.zip&lt;br /&gt;unzip HTRAF-latest.zip&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;5. You need to handle HTSQL requests via your Apache server.  (If you try contacting the HTSQL server directly from your webpages, users' browsers are likely to block you, thinking that the site includes a cross-site scripting attack.)  &lt;br /&gt;&lt;br /&gt;So you'll need to change your Apache server configuration by adding ProxyPass and ProxyPassReverse directives.  Apache configuration files are structured differently on different distributions; on mine, I used &lt;/code&gt;&lt;pre&gt;gksudo gedit /etc/apache2/sites-enabled/000-default&lt;/pre&gt;&lt;/code&gt; to add&lt;br /&gt;&lt;/code&gt;&lt;pre&gt;&lt;br /&gt;    ProxyPass /htsql/ http://localhost:8080/&lt;br /&gt;    ProxyPassReverse /htsql/ http://localhost:8080/&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;just within the &lt;var&gt;&amp;lt;VirtualHost *:80&amp;gt;&lt;/var&gt; directive.&lt;br /&gt;&lt;br /&gt;6. Next, you need to enable mod_proxy on your Apache, so that it knows what to do with a ProxyPass.  &lt;/code&gt;&lt;pre&gt;&lt;br /&gt;cd /etc/apache2&lt;br /&gt;sudo cp mods-available/proxy_*.* mods-enabled/&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;7. Now restart Apache so that the new settings will take effect.  &lt;/code&gt;&lt;pre&gt;sudo service apache2 restart&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;8. Test it out!  Hit this with your web browser:&lt;br /&gt;&lt;a href="http://localhost:8080/htsql/a_table_from_your_database"&gt;http://localhost:8080/htsql/a_table_from_your_database&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;9. Now write a webpage that includes HTRAF elements calling HTSQL!  Here's a minimal example.  &lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;     &amp;lt;script type="text/javascript"&lt;br /&gt;     src="HTRAF-2.0.0b1/htraf/htraf.js"&lt;br /&gt;     data-htsql-version="2"&lt;br /&gt;     data-htsql-prefix="/htsql"&amp;gt;&lt;br /&gt;     &amp;lt;/script&amp;gt;&lt;br /&gt;    &amp;lt;link rel="stylesheet" type="text/css" &lt;br /&gt;        href="HTRAF-2.0.0b1/htraf/htraf-02.css"/&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;select id="school"&lt;br /&gt;    data-htsql="/school{code, name}?exists(department)"&amp;gt;&lt;br /&gt;    &amp;lt;/select&amp;gt;&lt;br /&gt;&amp;lt;h3&amp;gt;Departments&amp;lt;/h3&amp;gt;&lt;br /&gt;&amp;lt;table id="department" data-hide-column-0="yes"&lt;br /&gt;    data-htsql="/department{code, name,&lt;br /&gt;                     count(course) :as '%23 of courses'}&lt;br /&gt;         ?school_code=$school&amp;name~$department_name"&lt;br /&gt;    data-ref="school department_name"&amp;gt;&lt;br /&gt;&amp;lt;/table&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Save it as /var/www/minimal.html and view it at &lt;a href="http://localhost/minimal.html"&gt;http://localhost/minimal.html&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;8. Hey, that table looks bland!  If you preferred the colors I showed in my talk, you can use &lt;a href="http://catherinedevlin.pythoneers.com/presentations/htsql-olf/htraf-02.css"&gt;this CSS&lt;/a&gt;, which I copied from HTRAF's demo a few months ago.  Save it to /var/www/HTRAF-2.0.0b1/htraf/htraf-02.css and change the stylesheet in your &amp;lt;head&amp;gt; to &lt;/code&gt;&lt;pre&gt;&lt;br /&gt;    &amp;lt;link rel="stylesheet" type="text/css" &lt;br /&gt;    href="HTRAF-2.0.0b1/htraf/htraf-02.css"/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-1703018261947191793?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/1703018261947191793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=1703018261947191793' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1703018261947191793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1703018261947191793'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2011/09/htraf-setup-from-zero.html' title='HTRAF setup, from zero'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-3645121093933090553</id><published>2011-09-11T09:05:00.000-07:00</published><updated>2011-09-11T09:08:38.238-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>HTSQL slides posted</title><content type='html'>Thanks to my &lt;a href="https://ohiolinux.org/"&gt;Ohio Linuxfest&lt;/a&gt; audience for your attention and interest!  My slides from yesterday are posted:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://catherinedevlin.pythoneers.com/presentations/htsql-olf/"&gt;Your Database, Exposed: HTSQL&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Shortly, I'll also post a summary of the questions I was asked that I didn't have firm answers for.  &lt;br /&gt;&lt;br /&gt;As usual, I had great time at OLF.  As usual, I brought my voice to its knees by talking to awesome people in the noisy exhibit hall before my talk... I'm going to ask for a morning speaking slot next time I speak!  Thanks, everybody!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-3645121093933090553?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/3645121093933090553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=3645121093933090553' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3645121093933090553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3645121093933090553'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2011/09/htsql-slides-posted.html' title='HTSQL slides posted'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-4680281354621728186</id><published>2011-09-07T07:06:00.001-07:00</published><updated>2011-09-07T07:16:13.007-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pyohio'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Ohio LinuxFest</title><content type='html'>I feel bad for not blogging after PyOhio.  I just have trouble finding words.  Along with PyCon, it's a sort of family reunion for me.&lt;br /&gt;&lt;br /&gt;But anyway - next conference: &lt;a href="https://ohiolinux.org/"&gt;Ohio LinuxFest&lt;/a&gt;.  This weekend, so sign up &lt;span style="font-style:italic;"&gt;now now now move move move&lt;/span&gt; - I think today is the pre-reg deadline.  It's always a great event, draws people from all over the East and sometimes further.  Look for our PyOhio table to have a Python chat (or help staff the table, and introduce other attendees to Python joy).  OLF is one of the best places in the region for midway mingling.&lt;br /&gt;&lt;br /&gt;I'm speaking on &lt;a href="http://htsql.org/"&gt;HTSQL&lt;/a&gt;.  I spoke on it at Indiana LinuxFest in the spring, too, only this time it follows several months of using it seriously at work.  The experience has only made me more enthusiastic about HTSQL.  Check it out... there's still time to be an early adopter and sneer at everybody else after it becomes famous.&lt;br /&gt;&lt;br /&gt;See you in Columbus!  Register now!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-4680281354621728186?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/4680281354621728186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=4680281354621728186' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4680281354621728186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4680281354621728186'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2011/09/ohio-linuxfest.html' title='Ohio LinuxFest'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-7202050485612322030</id><published>2011-08-08T08:31:00.000-07:00</published><updated>2011-08-11T16:25:52.934-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>MSSQL to CSV</title><content type='html'>Searching for ways to dump CSV from a MS SQL Server brings up recommendations to buy various third-party tools.&lt;br /&gt;&lt;br /&gt;Excuse me?  Buy tools for something any Pythonista can do in seventeen lines?&lt;br /&gt;&lt;br /&gt;You'll need the &lt;a href="https://code.google.com/p/pyodbc/"&gt;pyodbc&lt;/a&gt; module, which you should have anyway because it rocks.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;import csv&lt;br /&gt;import pyodbc&lt;br /&gt;&lt;br /&gt;cnxn = pyodbc.connect(&lt;br /&gt;       '''DRIVER={SQL Server};&lt;br /&gt;          SERVER=localhost;&lt;br /&gt;          DATABASE=mydb;&lt;br /&gt;          UID=myname;&lt;br /&gt;          PWD=mypwd''')&lt;br /&gt;curs = cnxn.cursor()&lt;br /&gt;&lt;br /&gt;def write_table(tblname):&lt;br /&gt;    with open(tblname+'.csv', 'wb') as outfile:&lt;br /&gt;        writer = csv.writer(outfile)&lt;br /&gt;        curs.execute('SELECT * FROM %s' % tblname)&lt;br /&gt;        writer.writerows(curs.fetchall())&lt;br /&gt;&lt;br /&gt;curs.execute('SELECT name FROM sys.tables')&lt;br /&gt;table_names = curs.fetchall()&lt;br /&gt;for table_name in table_names:&lt;br /&gt;    write_table(table_name.name)&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Go on, get more sophisticated with the hardcoded connect string, etc.&lt;br /&gt;&lt;br /&gt;AND A NOTE: If the ultimate destination of your .csv is to be imported into another database, you'd better distinguish between empty strings and NULLS.  To do that, replace&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;        writer.writerows(curs.fetchall())&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;with&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;        for row in curs:&lt;br /&gt;            writer.writerow(['NULL' if r is None else r &lt;br /&gt;                             for r in row])&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;AND, if you end up importing this .csv into MySQL, you'll want to set ESCAPED BY '' in your LOAD DATA statement, or else backslashes will start mucking up your field boundaries.  (Thanks to &lt;a href="http://jjinux.blogspot.com/2008/08/python-csv-module-and-mysqlimport.html"&gt;Shannon -jj Behrens&lt;/a&gt; for saving my sanity on that one).  Here's my script to consume the files:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;for fn in `ls *.csv`&lt;br /&gt;do&lt;br /&gt;  tbl=${fn%.*}&lt;br /&gt;  mysql myinst -e  "SET FOREIGN_KEY_CHECKS=0; &lt;br /&gt;                    DELETE FROM $tbl; &lt;br /&gt;                    LOAD DATA LOCAL INFILE '$fn' &lt;br /&gt;                      INTO TABLE $tbl &lt;br /&gt;                      COLUMNS TERMINATED BY ',' &lt;br /&gt;                      OPTIONALLY ENCLOSED BY '\"' &lt;br /&gt;                      ESCAPED BY '';"&lt;br /&gt;done&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-7202050485612322030?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/7202050485612322030/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=7202050485612322030' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7202050485612322030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7202050485612322030'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2011/08/mssql-to-csv.html' title='MSSQL to CSV'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6457282290954974586</id><published>2011-07-27T16:08:00.000-07:00</published><updated>2011-07-27T17:02:06.012-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Analytic functions</title><content type='html'>A life history of unforgettable moments of clarity:&lt;br /&gt;&lt;br /&gt;1983: Jesus&lt;br /&gt;1994: Special relativity&lt;br /&gt;2011: Analytic functions&lt;br /&gt;&lt;br /&gt;I've known for a long time that I really should make use of analytic database functions.  I think I've RTFMed a half-dozen times over the years, sometimes fumbling through an example or two, but never really &lt;span style="font-style:italic;"&gt;getting&lt;/span&gt; them.  &lt;a href="http://catherinedevlin.blogspot.com/2011/07/tom-kyte-in-dayton.html"&gt;Tom Kyte's appearance at the Dayton-Oracle User Group&lt;/a&gt; finally made it clear to me. &lt;br /&gt;&lt;br /&gt;Fortunately, (a different delivery of) &lt;a href="http://www.ustream.tv/recorded/15813909"&gt;Tom's talk was recorded&lt;/a&gt;.  Go, watch it!  You don't have to live without analytic functions one more day!&lt;br /&gt;&lt;br /&gt;In my case, I'd been tormented by questions about "the most recent record where..." in a MySQL database; the complex classic SQL queries I was using performed &lt;span style="font-style:italic;"&gt;horribly&lt;/span&gt; in MySQL.  MySQL doesn't have analytic functions, so I converted the reporting database to PostgreSQL.  It paid off enormously; analytic functions cut several queries from multiple days to a few minutes.  I am a Believer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6457282290954974586?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6457282290954974586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6457282290954974586' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6457282290954974586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6457282290954974586'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2011/07/analytic-functions.html' title='Analytic functions'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-1335119057308709091</id><published>2011-07-14T05:50:00.000-07:00</published><updated>2011-07-14T07:14:04.723-07:00</updated><title type='text'>KACE M300</title><content type='html'>We interrupt this blog with a message from &lt;span style="font-style:italic;"&gt;my&lt;/span&gt; sponsor.&lt;br /&gt;&lt;br /&gt;One of the cool things about working at &lt;a href="http://www.kace.com/"&gt;KACE&lt;/a&gt; is helping make a product that people genuinely need and want.  The job of keeping up with an organization's computers, networks, software, licenses, patches, security exposure, etc. is growing to near hopelessness for IT pros without good tools.  KACE appliances are effective, affordable, and simple for medium and larger enterprises.&lt;br /&gt;&lt;br /&gt;Small operations have different standards of what's "affordable" and "simple", though - so today &lt;a href="http://www.kace.com/products/asset-management-appliance/videos.php#video-m300-product-overview"&gt;KACE introduces the M300&lt;/a&gt;, a systems management appliance cheap and simple enough for virtually anybody.  &lt;br /&gt;&lt;br /&gt;I've only had a tiny, peripheral role in bringing out the M300, but it still feels really good.  Better systems management is something the world truly needs - too many human souls pour way too many hours into the scutwork part of IT.  I hope the M300 can get a lot more people get free from that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-1335119057308709091?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/1335119057308709091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=1335119057308709091' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1335119057308709091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1335119057308709091'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2011/07/kace-m300.html' title='KACE M300'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6243294194712528425</id><published>2011-07-06T19:25:00.000-07:00</published><updated>2011-07-06T19:29:16.081-07:00</updated><title type='text'>Tom Kyte in Dayton</title><content type='html'>&lt;a href="http://daytonoracle.org/"&gt;Tom Kyte of asktom.oracle.com is coming to Dayton on July 14!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is crazy-big for Dayton.  Tom is one of the most amazing Oracle experts out there, with an immense knowledge of Oracle and a gift for getting straight to the heart of questions and problems; you really need to see him in action.&lt;br /&gt;&lt;br /&gt;Thanks so much to &lt;a href="http://www.linkedin.com/profile/view?id=22817909"&gt;Vicki Blommel&lt;/a&gt; for bringing this huge win to Dayton - when I was leading the Dayton Oracle User Group, I never even dreamed of bringing somebody this big to town.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6243294194712528425?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6243294194712528425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6243294194712528425' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6243294194712528425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6243294194712528425'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2011/07/tom-kyte-in-dayton.html' title='Tom Kyte in Dayton'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-5135922373494716532</id><published>2011-03-28T10:44:00.000-07:00</published><updated>2011-03-28T11:06:24.503-07:00</updated><title type='text'>HTSQL and Indiana LinuxFest</title><content type='html'>Thanks and congratulations to Lord Drachenblut and the rest of the volunteer crew for putting on &lt;a href="http://www.indianalinux.org/"&gt;Indiana LinuxFest&lt;/a&gt;!  They did a great job.  I thought the participation was really impressive, looking and feeling more like a well-established conference than a brand-new one.  Nothing will displace &lt;a href="http://ohiolinux.org/"&gt;Ohio LinuxFest&lt;/a&gt; in my heart, naturally, but it looks like the community in this region can support and be bolstered by two annual conferences.  It's almost enough to blunt the pain of missing &lt;a href="http://us.pycon.org/"&gt;PyCon&lt;/a&gt;... well, OK, not really.  But it was still great.  I got a chance to see Tarus Balog again, who's so gracious it's crazy, and meet &lt;a href="http://www.indianalinux.org/cms/speakers2011"&gt;a whole mess of FLOSS's other heroes&lt;/a&gt;... Thanks to all of them for making the trip to Indiana!&lt;br /&gt;&lt;br /&gt;As a result of ILF, my determination to immerse myself in &lt;a href="http://docs.puppetlabs.com/"&gt;Puppet&lt;/a&gt; reached new heights.  Earlier, I'd assumed it was only for people who administer servers by the dozens or hundreds, but now I see how much even my small server admin tasks need the sort of order and repeatability that Puppet can help give me.&lt;br /&gt;&lt;br /&gt;I also got a chance to present on &lt;a href="http://htsql.org/"&gt;HTSQL&lt;/a&gt;, a new passion of mine since I first saw Clark Evan's submission for his PyCon talk.  &lt;a href="http://catherinedevlin.pythoneers.com/presentations/htsql/"&gt;My slides are here&lt;/a&gt; (and, for once, they actually cover the bulk of what I said).  However, you'll probably want to watch &lt;a href="http://pycon.blip.tv/file/4883320/"&gt;video from the PyCon talk by Clark Evans himself&lt;/a&gt;; he goes into much more detail than I did.&lt;br /&gt;&lt;br /&gt;In a word, HTSQL is a gorgeously simple approach to database reporting.  How gorgeous?  Take a look at &lt;a href="http://htraf.htsql.org/"&gt;this dashboard&lt;/a&gt;.  How simple?  Go back to that dashboard and hit View Source.  It's absurdly concise and comprehensible thanks to the HTRAF JavaScript library and HTSQL queries that fit comfortably and clearly into a URL, like &lt;a href="http://demo.htsql.org/department?school={%27eng%27,%27ns%27}"&gt;this&lt;/a&gt;.  Go spend some time playing with HTSQL if you care about data at all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-5135922373494716532?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/5135922373494716532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=5135922373494716532' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5135922373494716532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5135922373494716532'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2011/03/htsql-and-indiana-linuxfest.html' title='HTSQL and Indiana LinuxFest'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6845903069064549661</id><published>2011-03-22T07:00:00.001-07:00</published><updated>2011-03-22T07:34:21.489-07:00</updated><title type='text'>Indiana LinuxFest</title><content type='html'>First off, thanks to everybody who was at my Python intro at Millenicon.  You can find the talk materials at &lt;a href="http://catherinedevlin.pythoneers.com/"&gt;http://catherinedevlin.pythoneers.com/&lt;/a&gt; under "Talks".&lt;br /&gt;&lt;br /&gt;Second, have you seen the great schedule at &lt;a href="http://www.indianalinux.org/"&gt;Indiana LinuxFest&lt;/a&gt; this weekend?  They've really put together a lot of great material.  (And I don't just say that because I'll be presenting on HTSQL.)  I'm especially pleased that they have talks that will cater to my new love affair with &lt;a href="http://www.puppetlabs.com/"&gt;Puppet&lt;/a&gt;.  There's still time to sign up... hope to see you there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6845903069064549661?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6845903069064549661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6845903069064549661' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6845903069064549661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6845903069064549661'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2011/03/indiana-linuxfest.html' title='Indiana LinuxFest'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-7250635300410619366</id><published>2011-03-18T11:35:00.000-07:00</published><updated>2011-03-18T11:44:28.491-07:00</updated><title type='text'>Amateur Computer Programming</title><content type='html'>It's true: I missed PyCon 2011.  Unbelievable.  We have a sick horse who can't be left alone even for six hours, and our last-ditch scheme to get him to the OSU veterinary hospital, just before we were to leave for PyCon, foundered (ha!) with a broken-down truck and trailer on a small rural road.  In the dark.  And snow.  Wasn't a good night.  (Sigh)  Next year, with feeling!&lt;br /&gt;&lt;br /&gt;Anyway, onward.  Tonight I'm on a panel at Millennicon (a straight-up SF con) titled "Amateur Computer Programming".  I wanted to gather links to some short screencasts to give people an idea of some of the interesting tools out there.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.resolversystems.com/screencasts/resolver-one-in-one/"&gt;resolverone.com&lt;/a&gt; lets you program spreadsheets&lt;/li&gt;&lt;li&gt;&lt;a href="http://sikuli.org/"&gt;sikuli.org&lt;/a&gt; drives your whole system by a script&lt;/li&gt; &lt;li&gt;&lt;a href=""&gt;greasespot.net&lt;/a&gt; lets you reprogram somebody else's web app&lt;/li&gt;&lt;li&gt;&lt;a href="http://seleniumhq.org/"&gt; seleniumhq.org&lt;/a&gt;, a web testing framework&lt;/li&gt;&lt;li&gt;&lt;a href="http://renpy.org"&gt;renpy.org&lt;/a&gt; - easy visual novel authoring&lt;/li&gt; &lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=1hYv54euXVQ"&gt;pygame.org&lt;/a&gt; - game writing&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-7250635300410619366?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/7250635300410619366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=7250635300410619366' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7250635300410619366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7250635300410619366'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2011/03/amateur-computer-programming.html' title='Amateur Computer Programming'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-4572093923737557980</id><published>2011-02-21T08:13:00.000-08:00</published><updated>2011-02-21T08:31:48.697-08:00</updated><title type='text'>mysql rocks</title><content type='html'>No, I don't mean the MySQL server, about which my feelings are still &lt;span style="font-style:italic;"&gt;very&lt;/span&gt; mixed.  I'm still very keenly looking forward to moving to PostgreSQL.  I mean &lt;span style="font-style:italic;"&gt;mysql&lt;/span&gt;, the command-line client.&lt;br /&gt;&lt;br /&gt;It's awesome!  All those features that I've been gradually adding to &lt;a href="http://pypi.python.org/pypi/sqlpython"&gt;sqlpython&lt;/a&gt; - at the cost of slow execution, and with my personal late-night bad quality control - most of them have been in mysql for &lt;span style="font-style:italic;"&gt;years&lt;/span&gt;.  Flexible output formats, easy interaction with the OS environment, and so forth.  A fat toolbox of goodies.&lt;br /&gt;&lt;br /&gt;So, how about this, Oracle?  Oracle &lt;span style="font-style:italic;"&gt;SQL*Plus&lt;/span&gt; has been neglected and underpowered for ages.  It can't hold a candle to the &lt;span style="font-style:italic;"&gt;mysql&lt;/span&gt; client for features.  Why not assign a few programmers to extend the mysql client so that it works with Oracle as well as MySQL?  Why should the world have to deal with a different client program for every database back-end?  I can really imagine &lt;span style="font-style:italic;"&gt;mysql&lt;/span&gt; evolving into the One True SQL Client.&lt;br /&gt;&lt;br /&gt;Finally, I have to praise the &lt;a href="http://oreilly.com/catalog/9780596527082/"&gt;MySQL Cookbook&lt;/a&gt; from O'Reilly.  For somebody moving to MySQL from another database, it's the only way to fly.  Almost all MySQL books I've seen assume that it's your first database, and spend 90% of the text explaining SQL fundamentals.  Based on my happy experience with the &lt;a href="http://oreilly.com/catalog/9780596007973/"&gt;Python Cookbook&lt;/a&gt;, I thought the MySQL Cookbook would do better, and I was right.  It cuts straight to the stuff that isn't obvious but is very, very useful.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="&lt;br /&gt;http://oreilly.com/catalog/9780596527082/"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 180px; height: 236px;" src="http://covers.oreilly.com/images/9780596527082/cat.gif" border="0" alt="MySQL Cookbook cover" /&gt;&lt;/a&gt;&lt;br /&gt;(Hi.  Yes, I've been quiet.  Yes, I love the new job.  Yes, it's a lot of work, particularly during this learning-the-ropes phase.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-4572093923737557980?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/4572093923737557980/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=4572093923737557980' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4572093923737557980'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4572093923737557980'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2011/02/mysql-rocks.html' title='mysql rocks'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-3659992918248072535</id><published>2010-11-10T10:34:00.000-08:00</published><updated>2010-11-10T10:59:25.382-08:00</updated><title type='text'>Have you seen the elephant?</title><content type='html'>In case you're wondering, my upcoming work for KACE doesn't imply that I'm leaving Dayton.  Like most of my coworkers, I'll work for KACE by telecommute.  It's enormously flattering to be offered a position when the competitors for the job are potentially anybody on the surface of the earth.  (Anybody who's interested in a Dayton &lt;a href="http://www.workatjelly.com/"&gt;jelly&lt;/a&gt; or telecommuters' club, let me know.)&lt;br /&gt;&lt;br /&gt;That's good, but honestly, it's not the aspect of the new job I'm most excited about.  It's this.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://marakana.com/static/images/logos/course/PostgreSQL.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 220px; height: 170px;" src="http://marakana.com/static/images/logos/course/PostgreSQL.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'll migrate an important MySQL database to PostgreSQL and become its caretaker.  I don't expect to use Oracle at all in the new job (though I'll stay active in the local Oracle community, and do some personal Oracle projects just for fun).  Basically, I'll be a full-fledged PostgreSQL DBA.&lt;br /&gt;&lt;br /&gt;Oracle has been practically a part of my identity for years, but those who have paid close attention have noticed me sighing in longing for PostgreSQL for years, too; I've said more than once that I'd drop everything to work full-time with PostgreSQL.  I didn't think it would ever happen, since Dayton's main employer (the Air Force) has a strong prejudice for proprietary software.  But, thanks to KACE, the impossible finally happened.&lt;br /&gt;&lt;br /&gt;It's a funny coincidence - but yes, a coincidence - that this happens during a downswing in relations between Oracle and open-source communities; many F/OSS lovers are upset about Oracle's decisions since acquiring Sun.  For me, though, it's not a matter of techie politics; PostgreSQL is simply a wonderfully-written database and a joy to work with.&lt;br /&gt;&lt;br /&gt;As my relationship with PostgreSQL matures from a clandestine affair conducted at night to a full-time committed relationship, I'm sure we'll get past the honeymoon period and have some arguments, like any couple.  Even the best software is still software, after all, and human-software relationships always have their difficult moments.  Still, I'm enormously excited to begin this new phase in my love of free software.&lt;br /&gt;&lt;br /&gt;Hmm.  "PyOraGeek" might not be the most accurate subtitle anymore, but "PyPostgreSQL geek" violates uniqueness constraints in a big way.  The rebranding is the hardest part...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-3659992918248072535?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/3659992918248072535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=3659992918248072535' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3659992918248072535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3659992918248072535'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/11/have-you-seen-elephant.html' title='Have you seen the elephant?'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-3455653918898749649</id><published>2010-11-10T10:25:00.000-08:00</published><updated>2010-11-10T10:31:47.452-08:00</updated><title type='text'>sqlpython 1.7.2</title><content type='html'>&lt;a href="http://pypi.python.org/pypi/sqlpython"&gt;sqlpython&lt;/a&gt; 1.7.2 has been released!  Install it, pretend that your Oracle/PostgreSQL/MySQL database is a UNIX filesystem, and have a blast.&lt;br /&gt;&lt;br /&gt;This release doesn't really add any new features.  However, it does clean up the sluggishness in metadata operations (like &lt;span style="font-style:italic;"&gt;ls&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;desc&lt;/span&gt;) and the major outright bugs that were making sqlpython frankly unusable for an embarrassing number of months.&lt;br /&gt;&lt;br /&gt;Sorry for the wait!  Hope you'll find the new sqlpython worth it.  Functionality for PostgreSQL and MySQL are now fully-fledged, with some relatively minor exceptions (like image BLOB displays).  Furthermore, my upcoming position guarantees that the sqlpython/PostgreSQL will get lots of love in coming months.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-3455653918898749649?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/3455653918898749649/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=3455653918898749649' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3455653918898749649'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3455653918898749649'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/11/sqlpython-172.html' title='sqlpython 1.7.2'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-9033824919469664705</id><published>2010-11-08T06:17:00.000-08:00</published><updated>2010-11-08T09:50:56.805-08:00</updated><title type='text'>Moving to KACE</title><content type='html'>For almost ten years, I've worked for IntelliTech on contract at Wright-Patterson Air Force base.  IntelliTech has been a very supportive employer, and my government boss at WPAFB (Ralph Ranard) has been an absolutely amazing supervisor; that's why I've been there so long.&lt;br /&gt;&lt;br /&gt;This month, though, an opportunity has come up that I absolutely can't resist.  I met Mike Gray and Tyler Gingrich of &lt;a href="http://www.kace.com/"&gt;Dell KACE&lt;/a&gt; at &lt;a href="http://"&gt;Columbus Code Camp&lt;/a&gt;, which KACE sponsored partially to make contact with potential employees.  (This, incidentally, shows excellent management right there.  If you want skilled and passionate geeks, do you hire a recruiter to try to read the tea leaves of the self-promoting buzzwords of a huge stack of resumes?  Or do you go to where the most passionate geeks congregate all on their own?)&lt;br /&gt;&lt;br /&gt;Everything I've seen about KACE delights me so far.  It's a subsidiary of Dell that has intentionally retained its startup spirit since its acquisition.  Technical decisions are made by technical people for technical reasons - in other words, people are allowed to use the expertise they were hired for.  (I know, that &lt;span style="font-style:italic;"&gt;shouldn't&lt;/span&gt; be exceptional.)  It's got a developer-centered culture that is a huge breath of fresh air.  It's friendly to newer technologies and &lt;span style="font-style:italic;"&gt;very&lt;/span&gt; friendly to open source.  For example, I'll be taking over an important database currently in MySQL and migrating it to PostgreSQL.  (Getting somebody to pay me for working with PostgreSQL has been a dream of mine for years...)  And &lt;span style="font-style:italic;"&gt;of course&lt;/span&gt; I'll be using Python.  I'd wait tables before taking a job with no Python.&lt;br /&gt;&lt;br /&gt;During my entire process of interviewing with KACE, it never felt like "job interviews" - those nerve-wracking, superficial, semi-adversarial dances described so depressingly in career publications.  Rather, it felt like some long conference-hallway conversations between geeks - very real and very techie.&lt;br /&gt;&lt;br /&gt;So... hello KACE!  I'm delighted to join you!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-9033824919469664705?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/9033824919469664705/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=9033824919469664705' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/9033824919469664705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/9033824919469664705'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/11/moving-to-kace.html' title='Moving to KACE'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6456844492436557774</id><published>2010-10-18T07:29:00.001-07:00</published><updated>2010-10-18T08:06:57.348-07:00</updated><title type='text'>Camping in Ohio</title><content type='html'>This Saturday was the &lt;a href="http://columbuscodecamp.com/"&gt;Columbus Code Camp&lt;/a&gt;, and I have to say I was &lt;span style="font-style:italic;"&gt;really&lt;/span&gt; impressed.  The quality of the talks - and the audiences - was excellent, and it was a nice broad set of interesting topics.  &lt;a href="http://michaelreed.org/"&gt;Mike Reed&lt;/a&gt; and the other organizers should feel great about putting together such a good event, especially for its maiden voyage.  I look forward to it as a regular event.&lt;br /&gt;&lt;br /&gt;My talk &lt;a href="http://catherinedevlin.pythoneers.com/presentations/sikuli/sikuli.html"&gt;slides&lt;/a&gt; and &lt;a href="http://catherinedevlin.pythoneers.com/presentations/sikuli.tar.gz"&gt;materials&lt;/a&gt; are the same as the Ohio LinuxFest versions.  Thanks to my audience for the great questions!&lt;br /&gt;&lt;br /&gt;Next weekend comes the &lt;a href="http://southwestohiogivecamp.org/"&gt;Southwest Ohio GiveCamp&lt;/a&gt;, a big hackfest to rapidly produce software for area nonprofits.  I've never been to a GiveCamp before, and I'm really looking forward to it; I've heard great things from people who have participated before.  Python folks, step forward - I want to make sure there are enough of us to form at least one strong team writing Python-based software.&lt;br /&gt;&lt;br /&gt;Scheduling of tech events is an interesting topic.  If it's held on a weekend, you know you're getting genuinely passionate professionals, people who want to spend their own time learning new things and improving their skills.  If it's held on a weekday, you know you're getting people who work for smart companies that value their employees' skill and know that user-driven events are a great (and cheap) form of training... as well as a few attendees who are &lt;span style="font-style:italic;"&gt;so&lt;/span&gt; hard-core that they'll actually take their own vacation time for learning.  Either way, it reveals a lot about which people and employers are really dedicated to being and staying sharp.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6456844492436557774?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6456844492436557774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6456844492436557774' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6456844492436557774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6456844492436557774'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/10/camping-in-ohio.html' title='Camping in Ohio'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-4400937243262638128</id><published>2010-09-13T13:13:00.000-07:00</published><updated>2010-09-13T13:20:47.570-07:00</updated><title type='text'>pdb with Sikuli</title><content type='html'>As I mentioned in &lt;a href="http://catherinedevlin.blogspot.com/2010/09/sikuli-talk-follow-up.html"&gt;my last post&lt;/a&gt;, the big barrier to debugging a Sikuli script with &lt;kbd&gt;&lt;a href="http://docs.python.org/release/2.5.4/lib/module-pdb.html"&gt;pdb&lt;/a&gt;&lt;/kbd&gt; is that, when you enter a debugging command like "next", "continue", etc. that is supposed to allow program flow to continue, you are &lt;span style="font-style:italic;"&gt;in the debugging console window&lt;/span&gt;, and your Sikuli script will send the keyclicks and mouse actions into the debugging console window instead of the application your script was supposed to be driving.&lt;br /&gt;&lt;br /&gt;Here's a minor modification to &lt;kbd&gt;pdb&lt;/kbd&gt; that can change that by using Alt-TAB to switch back to the application window every time program flow moves from the debugger to the application.  Save this code as &lt;kbd&gt;sikpdb.py&lt;/kbd&gt; in the &lt;kbd&gt;Lib&lt;/kbd&gt; directory that you unzipped Sikuli into, for example, &lt;kbd&gt;~/Sikuli-IDE/Lib&lt;/kbd&gt;.  (&lt;kbd&gt;/Lib&lt;/kbd&gt; is not created by default, but it &lt;span style="font-style:italic;"&gt;is&lt;/span&gt; the first item in sys.path.)&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#! /usr/bin/env python&lt;br /&gt;&lt;br /&gt;"""A Python debugger.&lt;br /&gt;&lt;br /&gt;   A slight modification of ``pdb``; attempts to switch&lt;br /&gt;   screen focus back to the invoking app before running commands&lt;br /&gt;   in the program being debugged.  This should prevent Sikuli&lt;br /&gt;   commands from being "typed" or "clicked" into the debugger&lt;br /&gt;   window when they should go into the window of the app being&lt;br /&gt;   debugged."""  &lt;br /&gt;# catherinedevlin.blogspot.com&lt;br /&gt;# (See pdb.doc for documentation.)&lt;br /&gt;&lt;br /&gt;import pdb&lt;br /&gt;import sys&lt;br /&gt;&lt;br /&gt;class Pdb(pdb.Pdb):&lt;br /&gt;    def _to_running_window(self):&lt;br /&gt;        """Moves focus to the window a Sikuli script was running&lt;br /&gt;           before the debugger was invoked, so that subsequent commands&lt;br /&gt;           will act in the app instead of the debugger."""&lt;br /&gt;        self.onecmd("SCREEN.type(Key.TAB, KEY_ALT)")&lt;br /&gt;        &lt;br /&gt;    def do_step(self, arg):&lt;br /&gt;        self._to_running_window()&lt;br /&gt;        return pdb.Pdb.do_step(self, arg)&lt;br /&gt;    do_s = do_step&lt;br /&gt;&lt;br /&gt;    def do_next(self, arg):&lt;br /&gt;        self._to_running_window()&lt;br /&gt;        return pdb.Pdb.do_next(self, arg)&lt;br /&gt;    do_n = do_next&lt;br /&gt;&lt;br /&gt;    def do_return(self, arg):&lt;br /&gt;        self._to_running_window()&lt;br /&gt;        return pdb.Pdb.do_return(self, arg)&lt;br /&gt;    do_r = do_return&lt;br /&gt;&lt;br /&gt;    def do_continue(self, arg):&lt;br /&gt;        self._to_running_window()&lt;br /&gt;        return pdb.Pdb.do_continue(self, arg)&lt;br /&gt;    do_c = do_cont = do_continue&lt;br /&gt;&lt;br /&gt;def set_trace():&lt;br /&gt;    Pdb().set_trace(sys._getframe().f_back)&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Now, at the point in your Sikuli script where you want to enter the debugger, insert&lt;br /&gt;&lt;code&gt;import sikpdb; sikpdb.set_trace()&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Also remember that you need to add &lt;kbd&gt;-Dsikuli.console=false&lt;/kbd&gt; to your &lt;kbd&gt;.sh&lt;/kbd&gt; or &lt;kbd&gt;.bat&lt;/kbd&gt; script in order to allow pdb input/output to appear in the console window you used to invoke Sikuli.  Otherwise, Sikuli will just hang when you attempt to enter the debugger (it's waiting for your input - in some nonexistant interactive session).  For instance:&lt;br /&gt;&lt;code&gt;$ cat sikuli-ide.sh&lt;br /&gt;#!/bin/sh&lt;br /&gt;DIR=`dirname $0`&lt;br /&gt;java -Xms64M -Dsikuli.console=false -Xmx512M -Dfile.encoding=UTF-8 -jar $DIR/sikuli-ide.jar $*&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The remaining problem is that sikpdb.py depends on the notion that ALT-TAB will reliably return you to the application's window.  This is true, but only if you do not browse around among your open windows while in the debugger; if you do, you'll change the z-ordering of the windows.  It would be more reliable to call switchApp() with the title of the application's window, but I don't know of a cross-platform way to automatically detect it - the best I can think of would be to manually pass it as an argument to set_trace, have set_trace store it in an instance variable like &lt;kbd&gt;self._application_window_title&lt;/kbd&gt;, then call &lt;code&gt;self.onecmd("switchApp('%s')" % self._application_window_title)&lt;/code&gt; in place of &lt;code&gt;self.onecmd("SCREEN.type(Key.TAB, KEY_ALT)") &lt;/code&gt;.  It's more complex to use, but more reliable... feel free to use that approach if you prefer it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-4400937243262638128?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/4400937243262638128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=4400937243262638128' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4400937243262638128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4400937243262638128'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/09/pdb-with-sikuli.html' title='pdb with Sikuli'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-1019187870432998149</id><published>2010-09-12T17:05:00.000-07:00</published><updated>2010-09-13T01:04:17.024-07:00</updated><title type='text'>Sikuli talk follow-up</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Thanks&lt;/span&gt; to everybody who made time in a busy &lt;a href="http://ohiolinux.org/"&gt;Ohio LinuxFest&lt;/a&gt; schedule to make it to my talk on Project Sikuli!  I appreciated your attention and your questions.&lt;br /&gt;&lt;br /&gt;You can browse my slides at &lt;a href="http://catherinedevlin.pythoneers.com/presentations/sikuli/sikuli.html"&gt;http://catherinedevlin.pythoneers.com/presentations/sikuli/sikuli.html&lt;/a&gt;, and/or download a tarball with all the code demonstrated at &lt;a href="http://catherinedevlin.pythoneers.com/presentations/sikuli.tar.gz"&gt;http://catherinedevlin.pythoneers.com/presentations/sikuli.tar.gz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I promised to follow up on the questions that stumped me, so here are the first couple answers...&lt;br /&gt;&lt;br /&gt;- I mentioned how debugging with &lt;a href="http://docs.python.org/release/2.5.4/lib/module-pdb.html"&gt;pdb&lt;/a&gt; is difficult because switching to the command-line window to interact with pdb interrupts the program flow, and when you issue a "continue" in the debugger, your Sikuli script will barrel along &lt;span style="font-style:italic;"&gt;in the command-line window with the debugger&lt;/span&gt; instead of in the application you wanted Sikuli to drive.  A couple people suggested debugging the script from a remote machine, connecting with pdb and attaching the debug process to the Sikuli process.  I still don't know whether that's possible - definitely maybe - but I realized that there's a very simple remedy that I feel silly for not suggesting before.  &lt;br /&gt;&lt;br /&gt;In your Sikuli script at the point you want to enter the interactive debugger, instead of simply inserting &lt;code&gt;import pdb; pdb.set_trace()&lt;/code&gt;, insert &lt;code&gt;import pdb; pdb.set_trace(); switchApp('Window Title Of The App I Am Debugging')&lt;/code&gt; - that should put the script you're debugging back on track.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;EDIT: &lt;/span&gt;WAIT - I got this wrong - this doesn't make sense.  You do need to switchApp() back to the window your script was running in, but not immediately after invoking pdb.set_trace(); rather, it needs to be invoked just before running pdb.next, pdb.continue, etc.  I think the right way to do this is to subclass pdb; give me a bit to produce and test something like that.&lt;br /&gt;&lt;br /&gt;- I confirmed that there isn't yet a "Recording" mode, or anything to automatically translate your actions into Sikuli commands.  Really, though, I'm not sure how much that would help - writing the Sikuli commands is actually the easy part of the automation.  The hard part is figuring out precisely which actions to take to get the effects you want most reliably.&lt;br /&gt;&lt;br /&gt;OLF was really good this year.  I especially enjoyed the hallway track - met lots of really interesting people that I need to follow through with on some neat ideas.  The exhibit hall was a great place for PyOhio folks to meet new people and connect them with the Python community - thanks so much for all the PyOhio crew who came out to staff the booth!  Thanks to the organizers for all their work!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-1019187870432998149?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/1019187870432998149/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=1019187870432998149' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1019187870432998149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1019187870432998149'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/09/sikuli-talk-follow-up.html' title='Sikuli talk follow-up'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-8583241156650076582</id><published>2010-09-09T14:37:00.000-07:00</published><updated>2010-09-09T14:41:23.389-07:00</updated><title type='text'>Quran troll</title><content type='html'>&lt;a href=" http://www.google.com/buzz/104537541227697934010/Bu5okDe9YWH/This-whole-Koran-burning-church-event-is-trolling"&gt;Ian Bicking hit it right on the nose&lt;/a&gt;: this Quran-burning pastor is a troll, no more.&lt;br /&gt;&lt;br /&gt;Arguably, I shouldn't even be posting this.  Trolls should be ignored.  The trouble is, even internet-savvy people have trouble living up to that prescription.  The world as a whole definitely doesn't know what to do about trolls.  There are already people in Afghanistan holding demonstrations because of this troll... so I feel like "just ignore it" maybe isn't enough right now.&lt;br /&gt;&lt;blockquote&gt;John Shimek: The best suggestion I have heard it to ignore it and donate towards the Pakistan flood relief.&lt;/blockquote&gt;Very good.  But I'm wondering if one step further would be a good idea: an explicit linkage.  You know, "I pledge a $x donation for Pakistan flood relief for every copy of the Quran burned."  Isn't there a webservice out there that facilitates making this sort of pledge?  Help me out, lazyweb - this should happen fast if it's going to happen.&lt;br /&gt;&lt;br /&gt;Granted, Pakistan flood relief shouldn't be an issue of the victims' religion one way or the other, so there's something a little odd about using it as an anti-bigotry statement.  And maybe this does amount to feeding the troll.  But at least it would feed some real-live human beings at the same time.  It's the only way I can think of to turn this stupidity into something good.&lt;br /&gt;&lt;br /&gt;And, if you can permit me just one little troll-foodish comment...&lt;br /&gt;&lt;br /&gt;To be an a**hole is one thing.  (I really struggled to find another word here.  This time, though, it really is the only word.)  But to say, "It's not me - it's God who's the a**hole, and I'm just obeying him"...  I don't understand how anybody can say that without being 100% flat-out certain that there is no God.  Why would anybody take the slightest chance of ever standing before God and having Him say, "Could you repeat that to My face, please?"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-8583241156650076582?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/8583241156650076582/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=8583241156650076582' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8583241156650076582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8583241156650076582'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/09/quran-troll.html' title='Quran troll'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-4119994581791802245</id><published>2010-08-21T04:23:00.000-07:00</published><updated>2010-08-21T05:10:07.509-07:00</updated><title type='text'>Setting the turtle free with Sikuli</title><content type='html'>Have you played with turtle graphics?  I enjoyed Logo ages and ages ago.  Nowadays there's a &lt;kbd&gt;turtle&lt;/kbd&gt; module in Python's standard library, plus several other implementations.&lt;br /&gt;&lt;br /&gt;But all the implementations I know of keep the poor little turtle stuck inside a dull little window.  Last night I realized that, with &lt;a href="http://groups.csail.mit.edu/uid/sikuli/"&gt;Sikuli&lt;/a&gt;, I can &lt;span style="font-style:italic;"&gt;set the turtle free!&lt;/span&gt;  It can roam freely beyond one little window and have adventures in the big, wide world.  Here it is marching right past the edge of TuxPaint and onto GNU Paint.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_HR7nVcfhs_s/TG-49R2WupI/AAAAAAAAAFg/6GYvpsFXQZs/s1600/zigzag.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 333px;" src="http://1.bp.blogspot.com/_HR7nVcfhs_s/TG-49R2WupI/AAAAAAAAAFg/6GYvpsFXQZs/s400/zigzag.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5507824232200321682" /&gt;&lt;/a&gt;&lt;br /&gt;Note that this is an invisible turtle.  But you can see its effects.&lt;br /&gt;&lt;br /&gt;For the new free-range turtle, "penDown" and "penUp" are actually "mouse button down" and "mouse button up".  If it's walking across a drawing program with a paintbrush turned on, it will paint a line like a traditional Logo turtle.  Otherwise, it will click and drag its way across your desktop and your other applications.  This turtle can be mischievous!&lt;br /&gt;&lt;br /&gt;What really pleased me was just how easy it was to implement with Sikuli.  &lt;a href="http://catherinedevlin.pythoneers.com/sikuli/turtle.skl"&gt;Here's the code&lt;/a&gt; in an .skl bundle - it's a zipfile that Sikuli can use directly.&lt;pre class="sikuli-code"&gt;&lt;br /&gt;&lt;span class="kw"&gt;import&lt;/span&gt; math&lt;br /&gt;&lt;br /&gt;&lt;span class="kw"&gt;class&lt;/span&gt; Turtle(object):&lt;br /&gt;    &lt;span class="kw"&gt;def&lt;/span&gt; __init__(self):&lt;br /&gt;        self.heading = &lt;span class="dig"&gt;0&lt;/span&gt;&lt;br /&gt;        self.penDown()&lt;br /&gt;        self.loc = Env.getMouseLocation()&lt;br /&gt;    &lt;span class="kw"&gt;def&lt;/span&gt; forward(self, distance):&lt;br /&gt;        sin = math.sin(math.radians(self.heading))&lt;br /&gt;        cos = math.cos(math.radians(self.heading))&lt;br /&gt;        endpoint = (int(self.loc.x + cos * distance),&lt;br /&gt;                          int(self.loc.y + sin * distance))&lt;br /&gt;        &lt;span class="kw"&gt;if&lt;/span&gt; self.down:&lt;br /&gt;            &lt;span class="skw"&gt;dragDrop&lt;/span&gt;(self.loc, endpoint)&lt;br /&gt;        &lt;span class="kw"&gt;else&lt;/span&gt;:&lt;br /&gt;            mouseMove(endpoint)&lt;br /&gt;        self.loc = Location(*endpoint)&lt;br /&gt;    &lt;span class="kw"&gt;def&lt;/span&gt; backward(self, distance):&lt;br /&gt;        self.forward(distance * -&lt;span class="dig"&gt;1&lt;/span&gt;)&lt;br /&gt;    &lt;span class="kw"&gt;def&lt;/span&gt; right(self, degrees):&lt;br /&gt;        self.heading = (self.heading + degrees) % &lt;span class="dig"&gt;360&lt;/span&gt;&lt;br /&gt;    &lt;span class="kw"&gt;def&lt;/span&gt; left(self, degrees):&lt;br /&gt;        self.right(-&lt;span class="dig"&gt;1&lt;/span&gt; * degrees)&lt;br /&gt;    &lt;span class="kw"&gt;def&lt;/span&gt; penUp(self):&lt;br /&gt;        self.down = False&lt;br /&gt;    &lt;span class="kw"&gt;def&lt;/span&gt; penDown(self):&lt;br /&gt;        self.down = True&lt;br /&gt;    &lt;span class="kw"&gt;def&lt;/span&gt; circle(self, radius, extent=&lt;span class="dig"&gt;360.&lt;/span&gt;, steps=&lt;span class="dig"&gt;20&lt;/span&gt;):&lt;br /&gt;        circ = &lt;span class="dig"&gt;2&lt;/span&gt; * math.pi * radius&lt;br /&gt;        fraction = extent / &lt;span class="dig"&gt;360.&lt;/span&gt;&lt;br /&gt;        step_length = (circ * fraction) / steps&lt;br /&gt;        &lt;span class="kw"&gt;for&lt;/span&gt; i &lt;span class="kw"&gt;in&lt;/span&gt; range(steps):&lt;br /&gt;            self.forward(step_length)&lt;br /&gt;            self.left(&lt;span class="dig"&gt;360.&lt;/span&gt; * fraction / steps)&lt;br /&gt;&lt;br /&gt;&lt;span class="kw"&gt;def&lt;/span&gt; zigzag(startHeading, size, angle, steps):&lt;br /&gt;    t = Turtle()&lt;br /&gt;    t.heading = startHeading&lt;br /&gt;    t.left(angle * &lt;span class="dig"&gt;0.5&lt;/span&gt;)&lt;br /&gt;    &lt;span class="kw"&gt;for&lt;/span&gt; i &lt;span class="kw"&gt;in&lt;/span&gt; range(steps):&lt;br /&gt;        t.forward(size)&lt;br /&gt;        t.right(angle)&lt;br /&gt;        t.forward(size)&lt;br /&gt;        t.left(angle)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-4119994581791802245?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/4119994581791802245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=4119994581791802245' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4119994581791802245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4119994581791802245'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/08/setting-turtle-free-with-sikuli.html' title='Setting the turtle free with Sikuli'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_HR7nVcfhs_s/TG-49R2WupI/AAAAAAAAAFg/6GYvpsFXQZs/s72-c/zigzag.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-2109336692816048656</id><published>2010-08-17T09:00:00.000-07:00</published><updated>2010-08-17T13:09:14.887-07:00</updated><title type='text'>gmail filter appender with Sikuli</title><content type='html'>Gmail filters are great, but I've got some filters that apply to a hundred different senders - and I'm always adding new senders to them.  I've wished for an automated way to add the sender of the message I'm currently viewing to one of my filters.&lt;br /&gt;&lt;br /&gt;I'm sure this &lt;span style="font-style:italic;"&gt;could&lt;/span&gt; be done in Greasemonkey, Selenium, etc., but Sikuli is my tool of interest for the moment - and, after some fumbling, I'm really happy with it.&lt;br /&gt;&lt;br /&gt;A partial screenshot, just to give you the idea:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_HR7nVcfhs_s/TGrsK_uuohI/AAAAAAAAAFY/JBuh19oFydE/s1600/sikuli.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 307px;" src="http://2.bp.blogspot.com/_HR7nVcfhs_s/TGrsK_uuohI/AAAAAAAAAFY/JBuh19oFydE/s400/sikuli.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5506473168064127506" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://catherinedevlin.pythoneers.com/sikuli/despam.sikuli/despam.html"&gt;View the Sikuli code&lt;/a&gt;, or &lt;a href="http://catherinedevlin.pythoneers.com/sikuli/spammy.skl"&gt;download it&lt;/a&gt; and run it with &lt;kbd&gt;/path/to/your/sikuli-ide.sh spammy.skl&lt;/kbd&gt; - except you'll probably want to edit the keywords identifying your filter, and possibly recreate the graphics to match your own Firefox theme.  Mostly, it's there as an example to learn from.&lt;br /&gt;&lt;br /&gt;I'm learning plenty that will go into my Ohio LinuxFest talk, but the big lesson for today is to rely on keyboard-based and text-based techniques rather than picture-finding whenever they're available.  For instance, how should I click a button that might have scrolled off the bottom of the screen?  There are lots of ways - I could embed &lt;kbd&gt;find()&lt;/kbd&gt; in a loop with &lt;kbd&gt;type(Key.PAGE_DOWN)&lt;/kbd&gt;, for example - but it's more reliable to piggyback off Firefox's "Find" to zoom in on the text on (or near) the button and &lt;span style="font-style:italic;"&gt;then&lt;/span&gt; find it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-2109336692816048656?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/2109336692816048656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=2109336692816048656' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/2109336692816048656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/2109336692816048656'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/08/gmail-filter-appender-with-sikuli.html' title='gmail filter appender with Sikuli'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_HR7nVcfhs_s/TGrsK_uuohI/AAAAAAAAAFY/JBuh19oFydE/s72-c/sikuli.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-3077444469400421697</id><published>2010-08-11T10:07:00.000-07:00</published><updated>2010-08-11T10:19:25.974-07:00</updated><title type='text'>Sikuli at Ohio LinuxFest</title><content type='html'>And now, for my next trick, &lt;span style="font-style:italic;"&gt;one month from today, &lt;/span&gt;I shall demonstrate how to script virtually any program with a GUI... &lt;span style="font-style:italic;"&gt;without touching an API!&lt;/span&gt;  (audience gasps)&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;If You Can See It, You Can Automate It:  &lt;a href="http://sikuli.org"&gt;Sikuli&lt;/a&gt; &lt;/span&gt;&lt;br /&gt;Your computer should save you from doing tedious and repetitive tasks yourself, but automation programming has been too difficult for casual uses. MIT's Project Sikuli changes that. It fuses traditional text-base scripts with actual screenshots of targets on your screen, making programming simple, versatile, and useful. If you've ever told a friend, "Go here, now click on this, then on that", you know enough to start using Sikuli. Let Project Sikuli shake up your notions of what programming is like. &lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;I'll be spending most of this month using Sikuli to build a test suite for a complex GUI app at work, recording the pain points as I go.  I'd also appreciate your questions and comments about Sikuli - I may be able to work them into my talk (or at least be prepared when they're asked from the audience.)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ohiolinux.org"&gt;Ohio Linux Fest&lt;/a&gt;, Sep. 10 - 12.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-3077444469400421697?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/3077444469400421697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=3077444469400421697' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3077444469400421697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3077444469400421697'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/08/sikuli-at-ohio-linuxfest.html' title='Sikuli at Ohio LinuxFest'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-3140919566949811791</id><published>2010-08-08T06:55:00.000-07:00</published><updated>2010-08-08T09:16:47.341-07:00</updated><title type='text'>"Many Eyeballs" - HA!</title><content type='html'>Oh, yes, I feel I should record this little incident from PyOhio 2010, for the sake of evidence during Nick's trial.&lt;br /&gt;&lt;br /&gt;I used PyOhio's Lightning Talks to give away our swag prizes; and, in the spirit of open-source, I put the code on the projector for everyone to see.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;import csv&lt;br /&gt;import random&lt;br /&gt;&lt;br /&gt;regfile = open('registrations.csv')&lt;br /&gt;reader = csv.DictReader(regfile)&lt;br /&gt;registrants = list(reader)&lt;br /&gt;&lt;br /&gt;def pick():&lt;br /&gt;    winner = random.choice(registrants)&lt;br /&gt;    return '%s %s' % (winner['First Name'], &lt;br /&gt;                      winner['Last Name'])&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Then I realized that I didn't have the Lightning Talk sign-up board, so I went out into the hall to get it.  I was gone maybe 60 seconds.  When I got back, I called &lt;code&gt;pick()&lt;/code&gt; and got... Nick Bastin!&lt;br /&gt;&lt;br /&gt;The room giggled.  Nick said, "Wow, that's the first time I've written bug-free code on the first try!"  I didn't get it, so he said, "Why don't you pick another winner?"&lt;br /&gt;&lt;br /&gt;Nick Bastin!&lt;br /&gt;&lt;br /&gt;The nice thing is, my code was intact.  However, this was lurking in my directory.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;$ cat random.py&lt;br /&gt;def choice(foo):&lt;br /&gt; return {"First Name" : "Nick", "Last Name" : "Bastin"}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;The lesson here is: Many eyeballs can help protect you from malicious code... &lt;span style="font-style:italic;"&gt;unless they're all in on it!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-3140919566949811791?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/3140919566949811791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=3140919566949811791' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3140919566949811791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3140919566949811791'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/08/many-eyeballs-ha.html' title='&quot;Many Eyeballs&quot; - HA!'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-8375834521121704455</id><published>2010-08-08T06:29:00.000-07:00</published><updated>2010-08-08T06:55:29.128-07:00</updated><title type='text'>PyOhio 2010 review</title><content type='html'>My own PyOhio 2010 wrap-up post is highly suspect, because I'm probably not one to deliver an unbiased opinion.  So, when I say that &lt;br /&gt;&lt;br /&gt;IT WAS AWESOME&lt;br /&gt;&lt;br /&gt;you can be forgiven for being a little skeptical.  In fact, one of my few regrets is that I didn't collect firm, objective data on just how awesome it was.  I don't have accurate numbers on attendance yet - our sign in sheets are, um, somewhere around here.  We had 179 pre-registrations; subtract some no-shows, add some walk-ins, and you get... I don't know.  But the place was bustling!&lt;br /&gt;&lt;br /&gt;The talks were good, and more importantly, they stimulated some excellent informal activity.  The Open Space activity was stronger than ever this year; some of them packed our Open Space rooms to the walls.  There were a fair number of Python newcomers there - yay! - and I was glad that we had a good Beginners' Track for them. An After-Hours Board helped people coordinate some evening fun together.  Overall, it was not at all just "a place to see talks", but a full immersion in the awesomeness of Python people.  Of course, the sprints were the big after-hours event, but they deserve their own post (soon to follow).&lt;br /&gt;&lt;br /&gt;OSU's new Ohio Union was a great locale.  It helps a lot that it has a design and a staff specialized in holding meetings and conferences, and it's just fantastic that the OSU Open Source club was able to provide the space at incredibly good rates.  We look forward to using virtually the same space next year, with just some minor tweaks.&lt;br /&gt;&lt;br /&gt;And, for everybody who wondered how we put on a great show at no charge... thank our sponsors!&lt;ul&gt;&lt;li&gt;Microsoft&lt;/li&gt;&lt;li&gt;Intellovations&lt;/li&gt;&lt;li&gt;AGInteractive&lt;/li&gt;&lt;li&gt;Dayton Microcomputer Association&lt;/li&gt;&lt;/ul&gt;Anyway, I'm delighted.  I had fun and learned a ton.  I hope you did, too!  Thanks so much to everybody who took part!&lt;br /&gt;&lt;br /&gt;Here are a couple other wrap-up posts I've happened across.  Let me know about others you find.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://morepypy.blogspot.com/2010/08/pyohio.html"&gt;Alex Gaynor&lt;/a&gt;&lt;br /&gt;&lt;a href="http://bioselement.com/2010/08/pyohio-day-1/"&gt;William Chambers&lt;/a&gt; &lt;br /&gt;&lt;a href="http://blog.mitechie.com/2010/08/02/insert-giant-pyohio-2010-recap-here/"&gt;Richard Harding&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-8375834521121704455?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/8375834521121704455/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=8375834521121704455' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8375834521121704455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8375834521121704455'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/08/pyohio-2010-review.html' title='PyOhio 2010 review'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-8978413568791298082</id><published>2010-07-28T15:14:00.000-07:00</published><updated>2010-07-28T15:15:19.744-07:00</updated><title type='text'>PyOhio: photos plz</title><content type='html'>We have 138 &lt;a href="http://pyohio.org"&gt;PyOhio&lt;/a&gt; registrants so far - that's greater than the total number of attendees last year.  I'm excited!&lt;br /&gt;&lt;br /&gt;Is there a shutterbug in the house?  I'm always envious of the photos taken at some conferences, like &lt;a href="http://pythonsprints.com/2010/07/27/europython-2010-core-sprint-report/"&gt;this one&lt;/a&gt; of Python core sprinters at EuroPython.  (Hi, guys!  Our &lt;a href="http://www.pyohio.org/Contribute"&gt;contribu-palooza&lt;/a&gt;-ers will be joining you soon!)  I want to join the fun.  Our PyOhio attendees are just as pretty as any of them!&lt;br /&gt;&lt;br /&gt;So if you enjoy taking pictures, and you're coming to PyOhio (and who wouldn't?), please don't forget your camera!  Get some group shots, and let me know about them afterward.  Thanks!&lt;br /&gt;&lt;br /&gt;See you Saturday!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-8978413568791298082?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/8978413568791298082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=8978413568791298082' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8978413568791298082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8978413568791298082'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/07/pyohio-photos-plz.html' title='PyOhio: photos plz'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6010489049294621006</id><published>2010-07-16T01:56:00.000-07:00</published><updated>2010-07-16T02:14:06.534-07:00</updated><title type='text'>PyOhio</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://pyohio.org"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 340px; height: 196px;" src="http://www.codinggeekette.com/PyOhio/Badges/StaffBadge.JPG" border="0" alt="PyOhio staff badge" /&gt;&lt;/a&gt;&lt;br /&gt;We are 15 days from the third &lt;a href="http://pyohio.org"&gt;PyOhio&lt;/a&gt;, and I am so excited...  My first hope for PyOhio was that it would become a little slice of PyCon-ish goodness in our region... we've definitely accomplished that.  This year we're adding on some very serious sprinting that, I think, will make PyOhio an important part of the Python scene not just here, but worldwide.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.pyohio.org/Sprints2010"&gt;The Android Scripting Workshop&lt;/a&gt; has the potential to make Python-lovers of a whole new class of people who wouldn't even call themselves programmers (yet)... people who love their powerful Android phones and will love them even more once they learn the power of scripting on them.  One question I'd like your advice on: how do we let these people know about the workshop?  They're not reading my blog, after all...&lt;/li&gt;&lt;li&gt;The &lt;a href="http://www.pyohio.org/Contribute"&gt;Contribu-palooza&lt;/a&gt; is a set of linked events (a classic talk, a "Teach Me" talk, and a big fat sprint) designed to make &lt;span style="font-style:italic;"&gt;you &lt;/span&gt;into a contributor to the Python language, starting from nothing - we supply the motivation, the skills, and then the hands-on practice.  I'd like to see this produce both an immediate new set of Python contributors (including me) and a new way of bringing contributors in.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;I hope to see you there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6010489049294621006?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6010489049294621006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6010489049294621006' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6010489049294621006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6010489049294621006'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/07/pyohio.html' title='PyOhio'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-8338391730689068302</id><published>2010-07-02T07:02:00.000-07:00</published><updated>2010-07-02T07:38:02.250-07:00</updated><title type='text'>talking with women</title><content type='html'>A man at a conference I was at a couple months ago approached me to talk about databases.&lt;br /&gt;&lt;br /&gt;It was, in all ways, a good and appropriate conversation, and an example of the reason I go to conferences like that in the first place.  But he later confessed to me that he'd been very hesitant to speak to me because he was afraid it would come across as cover for some kind of flirtation.  It seemed ridiculous, because he was &lt;em&gt;so far&lt;/em&gt; from anything inappropriate, but his uncertainty came a hair's breadth from actually diminishing the conference's benefit to both of us.&lt;br /&gt;&lt;br /&gt;You see the big fat irony.  Avoiding sexualizing a woman's professional environment is an absolutely appropriate and important goal.  But sidelining women from a professional community's social aspects is genuinely harmful.&lt;br /&gt;&lt;br /&gt;Most men can easily judge for themselves the difference between friendly and creepy, but geekdom is infamous for its high proportion of the awkward.*  I'd love it if there were a really clear and well-known rule of thumb that would assure even the most shy and awkward guys about where "the line" is.  The hard part is that men differ so widely in their judgements and self-judgements.  Some will be critical or suspicious of themselves at virtually anything, and some find excuses for even the most egregious of their own behavior.  It's hard to know how to encourage the former but not the latter.&lt;br /&gt;&lt;br /&gt;My first thoughts - &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Imagine that she were a man.  Would you still do or say what you're doing or saying now, or would it feel too awkward?**&lt;/li&gt;&lt;li&gt;If you're genuinely worried about it, you're probably not a problem guy in the first place.&lt;/li&gt;&lt;/ul&gt;What are your thoughts?&lt;br /&gt;&lt;font size=-2&gt;&lt;br /&gt;* - Understand that, when I say this, it's with affection.  I love the socially awkward!  I find communities where everybody adheres smoothly to a single social standard to be boring and uncreative.  I hope geekdom will always be a haven for the awkward.&lt;br /&gt;** - Obviously not a very useful standard for bisexual people.&lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-8338391730689068302?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/8338391730689068302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=8338391730689068302' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8338391730689068302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8338391730689068302'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/07/talking-with-women.html' title='talking with women'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6450821475815592725</id><published>2010-06-10T07:59:00.002-07:00</published><updated>2010-06-11T06:50:34.510-07:00</updated><title type='text'>Dayton Dynamic Languages User Group</title><content type='html'>In Dayton, we don't have a dedicated Python user group; instead, we have the &lt;a href="http://www.dma.org/sigs.shtml#Dynamic"&gt;Dynamic Languages User Group&lt;/a&gt;.  I always struggle to explain why I enjoy this group so much, because a quick description doesn't sound that impressive.  Each meeting is 5-10 people scattered across the entire dynamic language landscape: Python, Ruby, Perl, JavaScript, PHP... now and then somebody will throw in some LISP or whatnot.  There's only occasionally a formal presentation.&lt;br /&gt;&lt;br /&gt;Instead, there are people who are very open about sharing both what they know (which is impressive) and what they &lt;span style="font-style:italic;"&gt;don't&lt;/span&gt; know (which is more important).  I've never been in a group where people are more uninhibited about saying, "Wait -- I don't get it."  As a result, everything we do gets enriched by some extremely good discussion.  &lt;br /&gt;&lt;br /&gt;When we don't have a formal presentation, we sometimes walk through a code project somebody's working on, or research a programming topic together (like dependency injection).  Recently we've started publishing a simple programming problem and asking the members to bring a solution in their favorite language - reviewing the various solutions is a nice exercise in both language details and programming approaches.&lt;br /&gt;&lt;br /&gt;Come see us sometime.  We meet the second Wednesday of the month at 7:00 PM at the &lt;a href="http://www.daytonchessclub.com/"&gt;Dayton Chess Club&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6450821475815592725?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6450821475815592725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6450821475815592725' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6450821475815592725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6450821475815592725'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/06/dayton-dynamic-languages-user-group.html' title='Dayton Dynamic Languages User Group'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-7101645190667453386</id><published>2010-06-09T13:21:00.000-07:00</published><updated>2010-06-09T13:51:15.176-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>On the error message soapbox again</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Q&lt;/span&gt;. What's wrong with this message?&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_HR7nVcfhs_s/TA_41MRE4HI/AAAAAAAAAFI/AeC9mjMwkLE/s1600/errormsg.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 223px;" src="http://2.bp.blogspot.com/_HR7nVcfhs_s/TA_41MRE4HI/AAAAAAAAAFI/AeC9mjMwkLE/s400/errormsg.png" border="0" alt="Database Configuration Assistant: Info - There is an error in creating the following process: /data/ora/oracle/product/11.2.0/dbhome_1/bin/sqlplus -s -N /NOLOG  The error is: /data/ora/oracle/product/11.2.0/dbhome_1/bin/sqlplus: error while loading shared libraries: /data/ora/oracle/product/11.2.0/dbhome_1/lib/libclntsh.so.11.1: cannot restore segment prot after reloc: Permission denied" id="BLOGGER_PHOTO_ID_5480872864242786418" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;A&lt;/span&gt;. The window that it pops up in doesn't support copy-and-paste (on Fedora 13, at least).  If you want to websearch for this message, you have to type it in by hand.  &lt;br /&gt;&lt;br /&gt;Hey, Oracle - fix it, please?  It's the sort of usability problem that I wouldn't nag you about if you were a little FOSS project or a mom-and-pop software shop, but you're a big company with fifty &lt;span style="font-style:italic;"&gt;bazillion&lt;/span&gt; programmers and entire committees on usability, so I know you can do it.  &lt;br /&gt;&lt;br /&gt;I'm sure that's the fault of whatever Java GUI library underlies your graphical tools like dbca... so go on and fix the library, and the whole world will benefit!  &lt;br /&gt;&lt;br /&gt;Also, in keeping with my fixation with good error messages, I implore you to think about error message usability ahead of time.  I suspect that error messages get the short end of developer attention because they never appear in sales presentations.  Well, actually, they &lt;span style="font-style:italic;"&gt;do&lt;/span&gt; appear in sales presentations, they're just not supposed to... (although, frankly, watching somebody work through an error is a million times more interesting than watching a polished sales pitch)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Q&lt;/span&gt;. What else is wrong?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;A&lt;/span&gt;. The workaround to this error is to disable SELinux.  For the ultimate bestest securest database EVAR, doesn't that seem a little cheesy?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Q&lt;/span&gt;. Anything else?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;A&lt;/span&gt;. Until you actually achieve SELinux compatibility, how about trapping the error with a message that describes the workaround?  Failing that, mentioning in the Installation Guide that SELinux should be turned off is a next-best solution... no, come to think of it, forget I said that.  "It's on page 732 of the docs" is actually a terrible excuse for leaving a bug unfixed.  I don't know how "document it" became an acceptable alternative to "fix it".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Q&lt;/span&gt;. Are you finished yet?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;A&lt;/span&gt;. Almost.  After more than 10 years of DBA work, I actually don't know what the proper channel is for making suggestions to Oracle Corp.  I end up ranting about it on my blog, approximately the equivalent of wandering into the street and yelling about it.  Is that silly or what?&lt;br /&gt;&lt;br /&gt;I'm Catherine Devlin, and I approved this message.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-7101645190667453386?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/7101645190667453386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=7101645190667453386' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7101645190667453386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7101645190667453386'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/06/on-error-message-soapbox-again.html' title='On the error message soapbox again'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_HR7nVcfhs_s/TA_41MRE4HI/AAAAAAAAAFI/AeC9mjMwkLE/s72-c/errormsg.png' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6526097442071359949</id><published>2010-05-27T02:34:00.001-07:00</published><updated>2010-05-27T18:04:12.737-07:00</updated><title type='text'>templating engine cookoff updated</title><content type='html'>Ian &lt;a href="http://catherinedevlin.blogspot.com/2010/04/templating-engine-cookoff.html"&gt;wished for loop syntax examples&lt;/a&gt; in the &lt;a href="http://catherinedevlin.pythoneers.com/cookoff.html"&gt;Templating Engine Cookoff&lt;/a&gt;, so I just added them.&lt;br /&gt;&lt;br /&gt;And none of you Django programmers have given me code to include Django templates in the cookoff.  You can't throw an exception in this town without hitting a Django programmer, so what's up?  C'mon, it's easy - I just need something analogous to this:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;The answer to the Ultimate&lt;br /&gt;Question is ${everything['universe'].answer}.&lt;br /&gt;&lt;br /&gt;Among our weapons are: &lt;br /&gt;  % for weapon in weapons:&lt;br /&gt;  ${weapon}              &lt;br /&gt;  % endfor&lt;br /&gt;&lt;br /&gt;import mako&lt;br /&gt;import mako.template&lt;br /&gt;class MakoDemo(Demo):&lt;br /&gt;    name = 'mako'&lt;br /&gt;    version = mako.__version__&lt;br /&gt;    def demo(self, vars):&lt;br /&gt;        self.template_name = 'mako.txt'&lt;br /&gt;        template = mako.template.Template(filename=self.template_name)&lt;br /&gt;        return template.render(**vars)&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;[EDIT: Well done, Django folks!  Django is in the cookoff now.  Except... hmm... it reacts to missing variables by leaving blanks instead of throwing an exception... so I need a new trick if I want to actually see the Django error stack.]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6526097442071359949?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6526097442071359949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6526097442071359949' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6526097442071359949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6526097442071359949'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/05/templating-engine-cookoff-updated.html' title='templating engine cookoff updated'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-2379856468475182328</id><published>2010-05-25T12:13:00.000-07:00</published><updated>2010-05-25T13:17:06.173-07:00</updated><title type='text'>dbapiext.py</title><content type='html'>&lt;a href="http://bitofcheese.blogspot.com/2010/04/dpapiextpy-making-dealing-with-sql.html"&gt;Richard Jones&lt;/a&gt; alerted me to Martin Blais' &lt;a href="http://furius.ca/pubcode/pub/antiorm/lib/python/dbapiext.py.html"&gt;dbapiext.py&lt;/a&gt;, and I like it very much.&lt;br /&gt;&lt;br /&gt;Richard's post focuses on the improvements to bind variable handling.  I love dbapiext.py for another reason: it provides query results as &lt;a href="http://docs.python.org/library/collections.html#collections.namedtuple"&gt;namedtuples&lt;/a&gt;, a class so perfect for database resultsets that they make me sob with relief.&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;&gt;&gt;&gt; import cx_Oracle, dbapiext&lt;br /&gt;&gt;&gt;&gt; connection = cx_Oracle.connect('username/password@SID')&lt;br /&gt;&gt;&gt;&gt; results = dbapiext.execute_obj(connection, 'SELECT * FROM crew')&lt;br /&gt;&gt;&gt;&gt; row = results.next()&lt;br /&gt;&gt;&gt;&gt; row&lt;br /&gt;Row(ID=1, NAME='Kaylee Frye', ROLE='Mechanic')&lt;br /&gt;&gt;&gt;&gt; row[1]&lt;br /&gt;'Kaylee Frye'&lt;br /&gt;&gt;&gt;&gt; row.ROLE&lt;br /&gt;'Mechanic'&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;When memory isn't an issue, I like to transform the result into a list and tack on a simple equality filter method for convenience.&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;class Filterable(list):&lt;br /&gt;    def filter(self, **kw):&lt;br /&gt;        for itm in self:&lt;br /&gt;            for k in kw:&lt;br /&gt;                if not (getattr(itm, k) == kw[k]):&lt;br /&gt;                    break&lt;br /&gt;            else:&lt;br /&gt;                yield itm    &lt;br /&gt;        yield StopIteration     &lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;&gt;&gt;&gt; result = Filterable(dbapiext.execute_obj(connection, 'SELECT * FROM crew')) &lt;br /&gt;&gt;&gt;&gt; result.filter(NAME='Jayne Cobb').next()&lt;br /&gt;Row(ID=5, NAME='Jayne Cobb', ROLE='Public Relations')&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;It is, of course, no SQLAlchemy, and isn't meant to be.  It's meant to be a roadmap toward a less awful DB-API for Python.  (I still wake up in the middle of the night, gasping, "Five incompatible bind variable formats!  It's &lt;a href="http://www.python.org/dev/peps/pep-0020/"&gt;heresy&lt;/a&gt;!")  In the meantime, dbapiext.py is a nice lightweight layer for times when SQLAlchemy is too much.  For instance, I write lots of database administration tools that poke around in lots of different views of Oracle's data dictionary, and setting up SQLAlchemy mappings for each of them is a pain.  dbapiext.py is perfect for that.  Thanks, Martin!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-2379856468475182328?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/2379856468475182328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=2379856468475182328' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/2379856468475182328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/2379856468475182328'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/05/dbapiextpy.html' title='dbapiext.py'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6251092610718980043</id><published>2010-05-03T18:26:00.000-07:00</published><updated>2010-05-04T13:45:22.148-07:00</updated><title type='text'>Penguicon wrap-up</title><content type='html'>Thanks to the wonderful audience at my Ren'Py talk.  Your patience and your questions got us through the painful time of waiting for the projector to work... bless you all!  I hope you have fun with Ren'Py.  I've posted my slides and sample game in the Ren'Py forum &lt;a href="http://lemmasoft.renai.us/forums/viewtopic.php?f=8&amp;t=6765&amp;p=92382&amp;hilit=penguicon#p92382"&gt;* here *&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Oh, and I saw a flashbulb during the talk... if you're reading this, could you send me a copy of the photo?  I don't have a good recent photo of myself presenting.  Unless it sucks, that is.  :)&lt;br /&gt;&lt;br /&gt;Some of Penguicon's other highlights, from my POV:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.irongeek.com/"&gt;Adrian Crenshaw&lt;/a&gt;'s talk on &lt;a href="http://www.irongeek.com/i.php?page=security/mutillidae-deliberately-vulnerable-php-owasp-top-10"&gt;Mutillidae&lt;/a&gt; was delightful.  I am so tempted to quit my job and become a security researcher; they have all the fun.  He tipped us off to some Firefox extensions for conveniently testing websites for some common vulnerabilities, too.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://nemorathwald.com/"&gt;Matt Arnold&lt;/a&gt;'s talk on &lt;a href="http://inform7.com/"&gt;Inform7&lt;/a&gt;, which showed me wonderful tools the Inform IDE comes with.  It's amazing to see how much work has gone into a language that has such a specialty purpose.  I hope I'll find time to put some more work into Inform7 games.  I loved this exchange:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-style:italic;"&gt;Attendee&lt;/span&gt;: Is there a limit to how many [options] there can be?&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Matt&lt;/span&gt;: No!  The limit is &lt;span style="font-style:italic;"&gt;your sanity&lt;/span&gt;!&lt;/blockquote&gt;&lt;br /&gt;The dance.  I love dancing with nerds.  It's so much more fun when the cool kids aren't there.  I miss the good old days, though, when we danced to songs, instead of to interminable dance beats.  Ah well.&lt;br /&gt;&lt;br /&gt;During &lt;a href="http://compoundthinking.com/blog/"&gt;Mark Ramm&lt;/a&gt;'s talk about implementing Sourceforge's new TurboGears/MongoDB infrastructure, a questioner invited him to complain about strict schedules for completing a job.  Instead, he said that he likes demanding, inflexible deadlines; having flexibility on a project's scope is how you get things done.  I thought that was a wondefully wise point of view.  A flexible timetable can be an excuse for not triaging a project's scope; a firm deadline helps you make those necessary decisions and actually get something done.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6251092610718980043?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6251092610718980043/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6251092610718980043' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6251092610718980043'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6251092610718980043'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/05/penguicon-wrap-up.html' title='Penguicon wrap-up'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-3854765811359168340</id><published>2010-04-23T10:23:00.001-07:00</published><updated>2010-04-23T10:33:36.441-07:00</updated><title type='text'>Dayton Oracle meeting</title><content type='html'>DAY-O, the Dayton Oracle user group, is meeting May 4 - a week from this Tuesday.  We've got a full-day meeting planned with lots of great content... see &lt;a href="http://daytonoracle.org/"&gt;daytonoracle.org&lt;/a&gt; for full details.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;09:00 AM - 09:30 AM Meeting Registration / Door Prize Raffle Registration&lt;br /&gt;09:30 AM - 10:00 AM Sun / Oracle Merger Update - Gary Hall (Sun / Oracle Corp.)&lt;br /&gt;10:00 AM - 10:30 AM Leading Spaces and Their Diagnosis with Toad for Oracle, A Toad® for Oracle Case Study - Michael Allen (SmartDBA.com)&lt;br /&gt;10:30 AM - 10:45 AM Break&lt;br /&gt;10:45 AM - 11:45 AM Oracle Fusion Middleware 11g Update / Roadmap - Eric Rudie (Oracle Corp.)&lt;br /&gt;11:45 AM - 12:40 PM Lunch - Pizza&lt;br /&gt;12:40 PM - 01:25 PM Exadata 2 Database Machine - Gary Hall (Sun / Oracle Corp.)&lt;br /&gt;01:25 PM - 01:30 PM Break&lt;br /&gt;01:30 PM - 02:30 PM Security and Compliance with Oracle Database 11g Release 2 - Eric Rudie (Oracle Corp.)&lt;br /&gt;02:30 PM - 02:45 PM Announcements / Raffle &lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Thanks to Matt Morrisey and Vicki Blommel for their organizational work, and to Oracle for being our meeting sponsor!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-3854765811359168340?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/3854765811359168340/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=3854765811359168340' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3854765811359168340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3854765811359168340'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/04/dayton-oracle-meeting.html' title='Dayton Oracle meeting'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-7460453015164880074</id><published>2010-04-22T13:01:00.000-07:00</published><updated>2010-04-22T13:14:09.877-07:00</updated><title type='text'>Bugfixing at PyOhio</title><content type='html'>&lt;a href="http://jessenoller.com/2010/04/22/why-arent-you-contributing-to-python/"&gt;Jesse Noller wants to know what's holding you back from working on Python.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;He's looking to make the process of contributing to Python more smooth and self-explanatory, less intimidating.  That's a good discussion, and I'm not sure what to tell him right now, but it does bring to mind something I really want to see.&lt;br /&gt;&lt;h3&gt;Let's have a Python Bug Fixing Tutorial at &lt;a href="http://www.pyohio.org/"&gt;PyOhio&lt;/a&gt;!&lt;/h3&gt;&lt;br /&gt;Walk everybody nice and slooooowly through the process of browsing through the Python bug tracker (for bugs in Python itself, in its standard library, etc.), checking out code, fixing and testing, making a diff file, submitting the fix.  Don't assume that people are familiar with VCS, diff files, the test suite, etc. - all those tools and jargon that separate veterans from intimidated users.  Let's break down that separation.&lt;br /&gt;&lt;br /&gt;Our &lt;a href="http://www.pyohio.org/CallForProposals"&gt;Call for Proposals&lt;/a&gt; is open right now (through May 10).  What a coincidence!  I'm not actually on the program committee, so I can't promise that such a proposal would be accepted, but let's just say that the committee will give it serious consideration if they know what's good for them.  :)&lt;br /&gt;&lt;br /&gt;I'm asking you to propose this, not me, because I am not crazy enough to think that I can lead such a tutorial while chairing the conference; especially since I've never actually done it before myself.  Actually, maybe there's one way I could do it: taking the role of the leader/learner in a "Teach Me Twisted"-style you-teach-me session.  In that case, I'd want commitments from... hmm... let me say 3+ experienced bugfixers to talk me through it in front of a live audience.&lt;br /&gt;&lt;br /&gt;One way or the other, let's see to it that PyOhio transforms some Python users into contributors!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-7460453015164880074?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/7460453015164880074/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=7460453015164880074' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7460453015164880074'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7460453015164880074'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/04/bugfixing-at-pyohio.html' title='Bugfixing at PyOhio'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-7314993188003926260</id><published>2010-04-22T10:50:00.000-07:00</published><updated>2010-04-22T12:05:20.836-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pythonic-plsql'/><title type='text'>Pythonic PL/SQL</title><content type='html'>Pythonic PL/SQL exists!  &lt;br /&gt;&lt;br /&gt;&lt;a href="https://code.launchpad.net/~catherine-devlin/pythonic-plsql/trunk"&gt;https://code.launchpad.net/~catherine-devlin/pythonic-plsql/trunk&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I imagine it will grow in fits and starts as my job needs dictate, but it shouldn't ever be abandoned, since I'm incorporating it gleefully into my own production code.&lt;br /&gt;&lt;br /&gt;So far, &lt;code&gt;format&lt;/code&gt; (Python 3-style string formatting) and &lt;code&gt;join&lt;/code&gt; are available.  I'm not using object-oriented PL/SQL at all (I find it very unsatisfactory), so instead of&lt;br /&gt;&lt;code&gt;','.join(mylist)&lt;/code&gt;, you use &lt;code&gt;pythonic.join(',', mylist)&lt;/code&gt;.&lt;br /&gt; &lt;br /&gt;I'm very open to contributions from others!  There's plenty of room to participate, since implementation has barely begun.&lt;br /&gt;&lt;br /&gt;There are &lt;a href="http://www.quest.com/code-tester-for-oracle/"&gt;Quest Code Tester&lt;/a&gt; tests for it, too, but unfortunately that's a closed-source project and I have to check on what the rules are for releasing tests produced with it.&lt;br /&gt;&lt;br /&gt;Of course, most hard-core PL/SQL developers will already have written or found code to handle basic, common operations like this.  But, by sticking close to names and APIs we're familiar with from another increasingly well-known language, I hope to reduce the amount of brainspace you need to remember how to do it all.&lt;br /&gt;&lt;br /&gt;Usage samples::&lt;code&gt;&lt;pre&gt;   &lt;br /&gt;    DECLARE&lt;br /&gt;       crewlist pythonic.string_list&lt;br /&gt;             := pythonic.string_list ('Wash', 'Kaylee', 'Mal');&lt;br /&gt;       crewdictionary   pythonic.string_dictionary;&lt;br /&gt;       curs             SYS_REFCURSOR;&lt;br /&gt;       template         VARCHAR2 (100);&lt;br /&gt;    BEGIN&lt;br /&gt;       DBMS_OUTPUT.PUT_LINE (pythonic.join ('; ', crewlist));&lt;br /&gt;       -- output: "Wash; Kaylee; Mal"&lt;br /&gt;       OPEN curs FOR&lt;br /&gt;            SELECT name FROM crew ORDER BY name;&lt;br /&gt;       DBMS_OUTPUT.PUT_LINE (pythonic.join (' *** ', curs));&lt;br /&gt;       -- output: "Kaylee *** Mal *** Wash"&lt;br /&gt;       template := '{2}!  {1} says we''d better replace that catalyzer!';&lt;br /&gt;       DBMS_OUTPUT.PUT_LINE (pythonic.format (template, NULL, 'Kaylee', 'Captain'));&lt;br /&gt;       -- output: "Captain!  Kaylee says we'd better replace that catalyzer!"&lt;br /&gt;       DBMS_OUTPUT.PUT_LINE (pythonic.format (template, crewlist));&lt;br /&gt;       -- output: "Mal!  Kaylee says we'd better replace that catalyzer!"&lt;br /&gt;       crewdictionary ('First Officer') := 'Zoe';&lt;br /&gt;       crewdictionary ('Public Relations') := 'Jayne';&lt;br /&gt;       template := '{First Officer}: (to {Public Relations})  "I can hurt you."';&lt;br /&gt;       DBMS_OUTPUT.PUT_LINE (pythonic.format (template, crewdictionary));&lt;br /&gt;    -- output: Zoe: (to Jayne)  "I can hurt you."&lt;br /&gt;    END;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-7314993188003926260?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/7314993188003926260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=7314993188003926260' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7314993188003926260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7314993188003926260'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/04/pythonic-plsql.html' title='Pythonic PL/SQL'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-1729366434549170242</id><published>2010-04-19T12:02:00.000-07:00</published><updated>2010-04-22T10:54:20.811-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pythonic-plsql'/><title type='text'>P(ythonic)L/SQL?</title><content type='html'>I'm itching to begin creating a bunch of PL/SQL packages that will emulate certain handy Python features.  Before I sink too much time into it, does the LazyWeb have anything to recommend?  Or, perhaps, volunteers to help make the dream come true?&lt;br /&gt;&lt;br /&gt;I want to start with a package for Pythonic string manipulation:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;'The {0} brown fox jumped over the {1} dog'.format('quick','lazy')&lt;br /&gt;.join()&lt;br /&gt;.split()&lt;br /&gt;.splitlines()&lt;/code&gt;&lt;br /&gt;... and so forth&lt;br /&gt;&lt;br /&gt;I think this package would not just implement the ones that don't exist in SQL or PL/SQL, it will provide Pythonically familiar names and interfaces to the ones that do exist.&lt;br /&gt;&lt;br /&gt;Granted, there's only so Pythonic you can get in PL/SQL.  A perfect set of packages would be a heroic task.  Still, it's easy to imagine helping PL/SQL to suck less...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-1729366434549170242?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/1729366434549170242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=1729366434549170242' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1729366434549170242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1729366434549170242'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/04/pythoniclsql.html' title='P(ythonic)L/SQL?'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-3338236004628724892</id><published>2010-04-18T06:31:00.000-07:00</published><updated>2010-04-19T06:28:05.454-07:00</updated><title type='text'>templating engine cookoff</title><content type='html'>There are more Python string templating engines in the world than homemade chili recipes.  Which is tastiest?  &lt;a href="http://catherinedevlin.pythoneers.com/cookoff.html"&gt;Let's have a cookoff!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We all have different criteria, of course.  The only organized comparisons I've seen between them are based mostly on measuring speed of rendering.  Huh?  I have never said to myself, "Wow, I'm wasting so much time because these templating engines aren't rendering fast enough.  If only they would finish in 0.4 seconds each instead of 0.6!"&lt;br /&gt;&lt;br /&gt;I &lt;em&gt;have&lt;/em&gt; said to myself, "Wow, I'm wasting so much time because there are errors in my templates, and my templating engine isn't helping me find them."  Writing templates is tricky.  Errors are common.  So, for me, clear error messages are the key virtue.  My cookoff focuses on recognizing the engines that report the filename and the offending string when a rendering failure occurs.  It also displays a typical simple syntax for writing and using each type of template (so it can serve as a cheatsheet as well).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://catherinedevlin.pythoneers.com/cookoff.html"&gt;My results&lt;/a&gt;?  So far, only jinja2 and genshi report both filename and the error-causing string.  The jinja2 error stack is more concise overall, so I award it the prize by a nose.  &lt;br /&gt;&lt;br /&gt;I'm really happy with the framework I wrote for doing the cookoff, too, so I &lt;a href="https://code.launchpad.net/~catherine-devlin/templatecookoff/trunk"&gt; posted it on Launchpad&lt;/a&gt;.  It is really, really easy to add new engines for comparison - feel free to suggest or submit them!  In fact, I hope that others can adapt my cookoff framework to other situations that call for side-by-side package comparisons.&lt;br /&gt;&lt;br /&gt;Incidentally, why are comparisons like this usually styled "smackdowns" or "shootouts"?  What's up with that?  We're not trying to put anybody in the hospital!  We're just trying to select our favorite from a banquet of delicious offerings.  Eat up!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-3338236004628724892?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/3338236004628724892/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=3338236004628724892' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3338236004628724892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3338236004628724892'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/04/templating-engine-cookoff.html' title='templating engine cookoff'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-5795120090363031612</id><published>2010-04-12T14:04:00.001-07:00</published><updated>2010-04-12T14:58:29.982-07:00</updated><title type='text'>I'm speaking at Penguicon</title><content type='html'>&lt;blockquote&gt;&lt;div class="vevent"&gt;&lt;h3 class="summary"&gt;&lt;a href="http://penguicon.org/events.php" class="url"&gt;Ren'Py: A Visual Novel Engine&lt;/a&gt;&lt;/h3&gt;&lt;div class="description"&gt;Computer gaming, anime/manga, Python programming, fiction writing: &lt;a href="http://renpy.org/"&gt;Ren'Py&lt;/a&gt; is everything you love about Penguicon rolled up into one. It's an open-source visual novel engine that lets you program graphical games and stories with the greatest of ease. Creating basic linear or branched stories is almost as easy as writing them on paper - yet Ren'Py is also a full-fledged Python environment, so there's no limit to what you can program as you learn. This intro will show you everything you need to start creating your own masterpiece. Ikimashou, otaku-san! &lt;/div&gt;&lt;br /&gt;&lt;abbr title="2010-05-01T12:00-0400" class="dtstart"&gt;May 1, 2010, 12 noon&lt;/abbr&gt; - &lt;abbr title="2010-05-01T13:00-0400" class="dtend"&gt;1 PM&lt;/abbr&gt;&lt;div class="location"&gt;&lt;a href="http://www.marriott.com/hotels/travel/dtttt?groupCode=pgupgua&amp;app=resvlink&amp;fromDate=4/30/10&amp;toDate=5/2/10"&gt;Detroit Marriott Troy&lt;/a&gt; &lt;div class="adr"&gt;&lt;div class="street-address"&gt;200 W. Big Beaver Rd.&lt;/div&gt; &lt;span class="locality"&gt;Detroit&lt;/span&gt; &lt;span class="region"&gt;MI&lt;/span&gt; &lt;span class="postal-code"&gt;48084&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;YOU:&lt;/span&gt; Okay... but will you give the presentation wearing a homemade Elizabethan-era dress?&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;ME:&lt;/span&gt;  Yes!&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;YOU:&lt;/span&gt; Cool!  Um... why?&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;ME:&lt;/span&gt;  Because this is &lt;span style="font-style:italic;"&gt;Penguicon&lt;/span&gt;!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;What's &lt;a href="http://penguicon.org/"&gt;Penguicon&lt;/a&gt;&lt;/span&gt;?  It's an open-source software conference... it's a science fiction fandom conference... it's an awesome hybrid of the two!  Super-sharp technical people come for some awesome knowledge sharing, and the SF fans help make the atmosphere even more relaxed and imaginative than at a normal FOSS con.  I love both sides of the con and especially the ways they mix together, which is why I wanted to give a talk this time that would really encompass it all.  (Costumes are totally optional, by the way.  But they sure are fun!)&lt;br /&gt;&lt;br /&gt;(Psst - if you install &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/4106"&gt;Operator&lt;/a&gt;, you'll be able to automatically process the &lt;a href="http://microformats.org/"&gt;microformatted&lt;/a&gt; data in this post and add it to your calendar.  Cool, huh?)&lt;br /&gt;&lt;br /&gt;See you in Detroit!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-5795120090363031612?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/5795120090363031612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=5795120090363031612' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5795120090363031612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5795120090363031612'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/04/im-speaking-at-penguicon.html' title='I&apos;m speaking at Penguicon'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-9136025750866620785</id><published>2010-04-12T13:58:00.001-07:00</published><updated>2010-04-12T14:00:19.779-07:00</updated><title type='text'>PyOhio Call for Proposals</title><content type='html'>PyOhio's &lt;a href="http://www.pyohio.org/CallForProposals"&gt;http://www.pyohio.org/CallForProposals&lt;/a&gt; is out, due May 10.  Let your imagination run wild; PyOhio is what we make it, no more and no less.  Help us make this year's &lt;a href="http://www.pyohio.org/"&gt;PyOhio&lt;/a&gt; the best yet!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-9136025750866620785?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/9136025750866620785/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=9136025750866620785' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/9136025750866620785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/9136025750866620785'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/04/pyohio-call-for-proposals.html' title='PyOhio Call for Proposals'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6865573310261374040</id><published>2010-04-09T10:08:00.000-07:00</published><updated>2010-04-09T10:19:55.965-07:00</updated><title type='text'>daytontechevents</title><content type='html'>&lt;h2&gt;&lt;a href="http://daytontechevents.com/"&gt;daytontechevents.com&lt;/a&gt;&lt;/h2&gt;&lt;h3&gt;A free service aggregating information about tech events in Dayton&lt;/h3&gt;There's too much geeky awesomeness going on in town to track with your brain alone.  &lt;a href="http://daytontechevents.com/"&gt;daytontechevents&lt;/a&gt; fixes that.  If you're in or near Dayton, keep an eye on it so that you don't miss something fantastic!  If you know of a group or event around here that isn't yet on daytontechevents, &lt;a href="http://daytontechevents.com/index.php?view=article&amp;id=49"&gt;add it&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;Thanks to &lt;a href="http://www.codinggeekette.com/"&gt;Sarah Dutkiewicz&lt;/a&gt;, who got the idea and put the infrastructure in place not just for Dayton, but also for &lt;a href="http://columbustechevents.com/"&gt;Columbus&lt;/a&gt; and her hometown &lt;a href="http://clevelandtechevents.com/"&gt;Cleveland&lt;/a&gt;.  Ohio thanks you, Sarah!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6865573310261374040?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6865573310261374040/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6865573310261374040' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6865573310261374040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6865573310261374040'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/04/daytontechevents.html' title='daytontechevents'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6188439551919304542</id><published>2010-04-08T11:09:00.000-07:00</published><updated>2010-04-08T11:27:30.284-07:00</updated><title type='text'>Pooled nonprofit IT</title><content type='html'>File this one under "Daydreaming".&lt;br /&gt;&lt;br /&gt;There are lots of small, local nonprofit organizations that really can't afford to do their IT well.  They can't afford a full-time professional, so they make do with unskilled labor, plus a smattering of donated services and what short-term contractual help they can afford.  Each time, the solutions implemented depend on the skills and tastes of the implementor, and rarely build usefully on what has been implemented before.&lt;br /&gt;&lt;br /&gt;Imagine the efficiencies if many organizations could share a small, full-time IT staff dedicated to their needs.  Most organizations share many of the same needs, and &lt;span style="font-style:italic;"&gt;could&lt;/span&gt; share the same set of solutions.  A full-time pro would become familiar with those needs and could efficiently apply a well-known solution to each group.  (S)he would provide continuity, well-informed decisionmaking, and perfectly specialized skills.&lt;br /&gt;&lt;br /&gt;Providing this would seem like a natural role for, say, an organization like the United Way; or perhaps for a small meta-charity created for the purpose.  I'm sure private firms have attempted to set themselves up in this role, but anything that demands a steady funding &lt;span style="font-style:italic;"&gt;outflow&lt;/span&gt; from the benefiting agencies is a tough sell, no matter how beneficial it would be in the long run.&lt;br /&gt;&lt;br /&gt;I'm just daydreaming, but I'm interested in people's comments.  Has anybody heard of something like this being done?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6188439551919304542?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6188439551919304542/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6188439551919304542' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6188439551919304542'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6188439551919304542'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/04/pooled-nonprofit-it.html' title='Pooled nonprofit IT'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-8061427117953894486</id><published>2010-03-24T11:46:00.001-07:00</published><updated>2010-03-24T12:00:08.160-07:00</updated><title type='text'>Community Service Award</title><content type='html'>&lt;a href="http://www.taniquetil.com.ar/plog/"&gt;Facundo Batista&lt;/a&gt; and I received the &lt;a href="http://pyfound.blogspot.com/2010/03/final-2009-community-service-awards.html"&gt;4th-quarter Python Software Foundation Community Service Awards!&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;I actually heard about it several days ago, and have been tongue-tied (keyboard-tied?) since then.  I'm mostly seen in and around Ohio these days, but I grew up thoroughly Minnesotan.  If you pay Minnesotans a really extravagant compliment, you'll send them into a kind of blushing panic.  All of our ancestors who enjoyed the limelight were found and eaten by bears, you see, so we evolved a genetic terror of having attention called to us.&lt;br /&gt;&lt;br /&gt;Anyway, this is one of the most flattering honors I've ever received.  &lt;span style="font-weight:bold;"&gt;THANK&lt;/span&gt; you, PSF!  I hope I'll always be one of the Python world's many valuable contributors.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-8061427117953894486?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/8061427117953894486/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=8061427117953894486' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8061427117953894486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8061427117953894486'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/03/community-service-award.html' title='Community Service Award'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-180556102791403936</id><published>2010-03-03T07:44:00.000-08:00</published><updated>2010-03-03T10:40:55.612-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sqlpython'/><category scheme='http://www.blogger.com/atom/ns#' term='cmd2'/><title type='text'>cmd2 0.6.1</title><content type='html'>Many thanks to the audience at &lt;a href="http://us.pycon.org/2010/conference/talks/#proposal_link_153"&gt;my PyCon cmd/cmd2 talk&lt;/a&gt; for your interest and enthusiasm!  It was my first full-scale PyCon presentation and I absolutely loved it.&lt;br /&gt;&lt;br /&gt;I need to follow up on three things I claimed in my talk:&lt;br /&gt;&lt;br /&gt;1. "My presentation is already online at &lt;a href="http://pypi.python.org/pypi/cmd2"&gt;http://pypi.python.org/pypi/cmd2&lt;/a&gt;".  &lt;span style="font-weight:bold;"&gt;FALSE&lt;/span&gt; (at the time I said it, and for several days afterward).  I actually had posted the docs and edited the PyPI page to point to them, but forgot to update &lt;var&gt;url&lt;/var&gt; in setup.py, so it overwrote the link when I registered cmd2's 0.6.0 release.&lt;br /&gt;&lt;br /&gt;It's fixed now, though.  The &lt;a href="http://pypi.python.org/pypi/cmd2"&gt;cmd2 PyPI page&lt;/a&gt; has a link to the &lt;a href="http://packages.python.org/cmd2/"&gt;cmd2 documentation&lt;/a&gt;, which in turn links to &lt;a href="http://catherinedevlin.pythoneers.com/presentations/cmd_cmd2/pycon2010.html"&gt;my talk slides&lt;/a&gt;.  You can also &lt;a href="http://python.mirocommunity.com/video/1533/easy-command-line-applications"&gt;watch the talk&lt;/a&gt; thanks to the fantastic PyCon video crew!&lt;br /&gt;&lt;br /&gt;2. "A more stable version will be out within a couple weeks of PyCon."  &lt;span style="font-weight:bold;"&gt;TRUE.&lt;/span&gt;  0.6.1 is not exactly &lt;span style="font-style:italic;"&gt;stable&lt;/span&gt; stable, but I think I've smoothed out bugs that snuck in while I was pushing to release 0.6.0 for PyCon.  &lt;br /&gt;&lt;br /&gt;3. "sqlpython will be more presentable in a couple weeks, too."  &lt;span style="font-weight:bold;"&gt;TRUE.&lt;/span&gt;  The new &lt;a href="http://pypi.python.org/pypi/sqlpython"&gt;sqlpython&lt;/a&gt; 1.7.1 brings the postgreSQL functionality (&lt;a href="http://pypi.python.org/pypi/gerald/"&gt;thanks Andy!&lt;/a&gt;) to pretty near 100% (except for the can't-see-other's-schemas problem, which should be fixed for 1.7.2.)  I believe that MySQL should be fully functional, too, but that's very lightly tested because I barely use MySQL and don't know much about how to test it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-180556102791403936?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/180556102791403936/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=180556102791403936' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/180556102791403936'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/180556102791403936'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/03/cmd2-061.html' title='cmd2 0.6.1'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-733037444731420361</id><published>2010-02-16T17:23:00.001-08:00</published><updated>2010-02-16T17:39:42.806-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gender'/><title type='text'>Computer Engineer Barbie</title><content type='html'>I'm happy about &lt;a href="http://www.barbie.com/vote/"&gt;Computer Engineer Barbie&lt;/a&gt;.  No doll will save the world, but every little bit helps.&lt;br /&gt;&lt;br /&gt;It's annoying, though, that &lt;a href="http://news.bbc.co.uk/2/hi/uk_news/magazine/8517097.stm"&gt;some people&lt;/a&gt; only see one more opportunity to trot out this classic:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;def belittle(geek):&lt;br /&gt;    prejudice = "Well, then, she's not much of a {0}, is she?"&lt;br /&gt;    if geek.is_femme:&lt;br /&gt;        excuse = 'geek'&lt;br /&gt;    else:&lt;br /&gt;        excuse = 'woman'&lt;br /&gt;    return prejudice.format(excuse)&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-733037444731420361?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/733037444731420361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=733037444731420361' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/733037444731420361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/733037444731420361'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/02/computer-engineer-barbie.html' title='Computer Engineer Barbie'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-4286645746347278139</id><published>2010-02-10T10:42:00.001-08:00</published><updated>2010-02-10T10:48:52.873-08:00</updated><title type='text'>sqlpython 1.7 pre-release</title><content type='html'>First off: &lt;a href="http://us.pycon.org/2010/registration/"&gt;PyCon online registration&lt;/a&gt; ends TODAY.  Go do it NOW.&lt;br /&gt;&lt;br /&gt;I intend to show off &lt;a href="http://packages.python.org/sqlpython"&gt;sqlpython&lt;/a&gt; at PyCon.  Version 1.7 works with postgreSQL and MySQL as well as Oracle.  (In fact, a single sqlpython session can keep connections to all three types of databases open at once!)&lt;br /&gt;&lt;br /&gt;1.7 isn't quite ready for PyPI yet; I've just posted an &lt;a href="http://groups.google.com/group/sqlpython/browse_thread/thread/5c3e9891d597d2d4"&gt;appeal for sqlpython testing&lt;/a&gt;, with instructions for getting the development version, to the sqlpython google group.  If you'd like to take the new-and-improved sqlpython for a spin around your databases, I would hugely appreciate it.  Anticipate a PyPI release just before PyCon, once the ugliest of the bugs are worked out.&lt;br /&gt;&lt;br /&gt;See you in Atlanta!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-4286645746347278139?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/4286645746347278139/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=4286645746347278139' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4286645746347278139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4286645746347278139'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/02/sqlpython-17-pre-release.html' title='sqlpython 1.7 pre-release'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-2070728534145779678</id><published>2010-02-02T12:55:00.001-08:00</published><updated>2010-02-02T13:16:24.046-08:00</updated><title type='text'>Hey, Oracle!</title><content type='html'>You're scaring me!&lt;br /&gt;&lt;br /&gt;In the last couple months, we've learned that the new Sun will be going forward &lt;a href="http://fwierzbicki.blogspot.com/2009/11/leaving-sun.html"&gt;without Frank Wierzbicki&lt;/a&gt;, the Jython project lead, and now &lt;a href="http://www.sauria.com/blog/2010/02/02/the-sun-sets-on-me/"&gt;without Ted Leung&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The Oracle Technology Network is working hard to foster dynamic language use with Oracle.  It's got &lt;a href="http://www.oracle.com/technology/tech/scripting-languages/index.html"&gt;publications&lt;/a&gt;, PyCon sponsorship, &lt;a href="http://wiki.oracle.com/page/Python"&gt;resources&lt;/a&gt;, and so forth.  OTN delights me.  &lt;br /&gt;&lt;br /&gt;I'm afraid, though, that the larger Oracle corporation doesn't share OTN's interest.  Oracle's absorption of Sun is proceeding without any apparent interest in dynamic languages.  Oracle is discarding some of the finest talent it could possibly acquire, people who could have helped bring on a real flowering of dynamic language use in Oracle environments.  &lt;br /&gt;&lt;br /&gt;I, for one, would have loved to see Jython harnessed on Oracle's many Java-based tools and even the JVM in the Oracle database - imagine the wonders Frank and Ted could have worked with that, had Oracle assigned them to!  Instead... there will be nothing Oracle-related from them.  Meanwhile, Microsoft funds development of several dynamic languages, including IronPython, which integrate to SQL Server through .NET.  &lt;br /&gt;&lt;br /&gt;I don't know.  I just dread the thought that, five years from now, SQL Server will be the proprietary database of choice for any environment where dynamic languages are used... which will soon be &lt;span style="font-style:italic;"&gt;most environments&lt;/span&gt;.  Oracle, you really want to give this market away?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-2070728534145779678?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/2070728534145779678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=2070728534145779678' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/2070728534145779678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/2070728534145779678'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/02/hey-oracle.html' title='Hey, Oracle!'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-986093396404370109</id><published>2010-01-20T13:52:00.000-08:00</published><updated>2010-01-20T14:19:58.888-08:00</updated><title type='text'>How to write a bad abstract</title><content type='html'>Ironically, the only talk that disappointed me at all at CodeMash was... &lt;a href="http://catherinedevlin.pythoneers.com/#other-talks"&gt;mine&lt;/a&gt;.  I thought my delivery was a little rough - pretty much because it's a really bad time of year for me to practice a talk.&lt;br /&gt;&lt;br /&gt;I had a (great, attentive, but) smallish audience, too.  One of the reasons was simple scheduling - there were some amazing talks opposite me.  I was tempted to slip out and watch one myself!  The biggest problem, though, was me.  I wrote a bad title and abstract for the program guide.&lt;br /&gt;&lt;blockquote&gt;reStructuredText: Plain Text Gets Superpowers&lt;br /&gt;Technology/Platform: Python&lt;br /&gt;Difficulty Level: Beginner&lt;br /&gt;&lt;br /&gt;Abstract: Write a document, just once, in plain text. Enjoy all plain text's benefits - speed, simplicity, scriptability, version control. Now, from this single plain text source, automatically generate beautifully-formatted webpages, presentations, .PDFs, auto-indexed documentation trees, and more. It's time to quit slacking on documenting your software. reStructuredText will make you actually enjoy writing docs!&lt;/blockquote&gt;What's wrong with this?  It's a nice narrative that fits together and builds to a nice little conclusion... but it's bad for a program guide.&lt;br /&gt;&lt;br /&gt;I assumed attendees would read the whole abstract carefully.  Then, when I got to CodeMash, what did I do to select sessions &lt;span style="font-style:italic;"&gt;I&lt;/span&gt; would attend?  I quickly scanned over the list of titles, and based on that, hastily read some of the abstracts.  I forgot that geeks are pressed for time, especially at conferences!&lt;br /&gt;&lt;br /&gt;There were three important messages for attendees to know to decide whether to come:&lt;br /&gt;&lt;br /&gt;1. This is a talk about writing documentation&lt;br /&gt;2. It is independent of what programming language you use&lt;br /&gt;3. This talk provides a helpful tool (i.e., it's not just a preachy sermon)&lt;br /&gt;&lt;br /&gt;You have to read all the way to the end of my abstract to get messages #1 and #3, and #2 is never communicated clearly at all.  So, what would a &lt;span style="font-style:italic;"&gt;good&lt;/span&gt; title and abstract have looked like?&lt;br /&gt;&lt;blockquote&gt;Your Docs Won't Suck Anymore&lt;br /&gt;Technology/Platform: Other *&lt;br /&gt;Difficulty Level: Beginner&lt;br /&gt;&lt;br /&gt;Abstract: No matter what programming language you write in, it's the English language that's killing you - your lack of good documentation is driving potential users away.  reStructuredText is a technology and a family of tools that will make writing documentation easy, powerful, and satisfying.  We'll introduce reStructuredText and get you started on writing beautiful documentation for any program or language.&lt;/blockquote&gt;&lt;span style="font-style:italic; font-size:0.6em;"&gt;* - "platform-independent" would have been the best choice for "Technology", but it wasn't in the dropdown.  I worried that choosing "Other" would imply reST was implemented in Scala or something.  I should have done it anyway, though, because most CodeMash attendees don't know Python and probably read "Python" as "not for me".&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The take-home lesson here: when writing titles and abstracts, be very mindful of the divided and rushed attention of the typical geek.  Don't be coy and save the good stuff for the fine print.  Get your message across up front.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-986093396404370109?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/986093396404370109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=986093396404370109' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/986093396404370109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/986093396404370109'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/01/how-to-write-bad-abstract.html' title='How to write a bad abstract'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-4026579979228861887</id><published>2010-01-18T05:50:00.000-08:00</published><updated>2010-01-18T06:12:42.058-08:00</updated><title type='text'>Fear is not a virtue</title><content type='html'>I know there have been a million news items like this, but this is the one that puts me over the edge.&lt;a href="http://www.signonsandiego.com/news/2010/jan/15/students-evacuated-school-chollas-view/"&gt;&lt;br /&gt;&lt;blockquote&gt;SAN DIEGO — Students were evacuated from Millennial Tech Magnet Middle School in the Chollas View neighborhood Friday afternoon after an 11-year-old student brought a personal science project that he had been making at home to school, authorities said.&lt;br /&gt;&lt;br /&gt;Maurice Luque, spokesman for the San Diego Fire-Rescue Department, said the student had been making the device in his home garage. A vice principal saw the student showing it to other students at school about 11:40 a.m. Friday and was concerned that it might be harmful, and San Diego police were notified.&lt;br /&gt;&lt;br /&gt;The school, which has about 440 students in grades 6 to 8 and emphasizes technology skills, was initially put on lockdown while authorities responded.&lt;br /&gt;&lt;br /&gt;Luque said the project was made of an empty half-liter Gatorade bottle with some wires and other electrical components attached. There was no substance inside.&lt;br /&gt;... &lt;br /&gt;Luque said the project was intended to be a type of motion-detector device.&lt;br /&gt;...&lt;br /&gt;Both the student and his parents were "very cooperative" with authorities, Luque said. He said fire officials also went to the student's home and checked the garage to make sure items there were neither harmful nor explosive.&lt;br /&gt;&lt;br /&gt;"There was nothing hazardous at the house," Luque said.&lt;br /&gt;&lt;br /&gt;The student will not be prosecuted, but authorities were recommending that he and his parents get counseling, the spokesman said. The student violated school policies, but there was no criminal intent, Luque said.&lt;br /&gt;&lt;/blockquote&gt;&lt;/a&gt;&lt;br /&gt;I finally understand Al-Qaeda's master plan, and it's freaking &lt;span style="font-style:italic;"&gt;brilliant&lt;/span&gt;.  Resenting American technological dominance, they have found a way to end it, convincing us to semi-criminalize technical curiosity and thus lobotomize our culture.  I'm just surprised that we're choosing to participate in the plan.  I thought we were on opposite sides?...&lt;br /&gt;&lt;br /&gt;Is there a political movement or group I can join to fight this?  Common-sense people grousing about how stupid each incident is is failing to hold back the tide.  Something vaguely like the EFF but with a broader scope - because all science and technology is under attack now.&lt;br /&gt;&lt;br /&gt;Fear is not patriotic.  Fear is not a public service.  Fear is not a virtue.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-4026579979228861887?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/4026579979228861887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=4026579979228861887' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4026579979228861887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4026579979228861887'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/01/fear-is-not-virtue.html' title='Fear is not a virtue'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-684011485833212903</id><published>2010-01-17T19:43:00.000-08:00</published><updated>2010-01-18T06:59:50.265-08:00</updated><title type='text'>MongoDB</title><content type='html'>Gloria Jacobs told me about &lt;a href="http://www.mongodb.org/"&gt;MongoDB&lt;/a&gt; at &lt;a href="http://www.pyohio.org/"&gt;PyOhio&lt;/a&gt;, but I was too busy conference-chairing to see her talk, and time has flown by.  Her enthusiasm prompted me to see &lt;a href="http://www.slideshare.net/mdirolf/codemash-2010"&gt;Mike Dirolf's MongoDB talk at CodeMash&lt;/a&gt;, though, and &lt;span style="font-weight:bold;"&gt;wow&lt;/span&gt;.  Thanks, Gloria and Mike!  I like it, I really like it!&lt;br /&gt;&lt;br /&gt;My &lt;a href="http://catherinedevlin.blogspot.com/2008/09/bigtable-blues.html"&gt;frustrating experience with BigTable&lt;/a&gt; had given me a "Bah, humbug!" attitude toward the NoSQL fad, but it really looks like MongoDB is the cure for that.  It surrenders much less query capability than the other NoSQL contenders do.  The simplest of those are useful only if you already have the key for your desired record in hand, and BigTable's limitations make it feel only moderately better to me.  But MongoDB's query capabilities are really rich, good enough for many (though of course not all) real query needs.&lt;br /&gt;&lt;br /&gt;Now, don't get me wrong; there are a *whole lot* of tasks for which an RDMBS is still very much the answer.  When you need transactions, or child items that aren't tucked neatly under single parents, or complex queries - and how often do you really *know* that you'll never need complex queries? - it's safer to use an RDMBS.&lt;br /&gt;&lt;br /&gt;I think that, when the database is an enduring construct, important in itself - when multiple applications may be written against it, and new applications yet unforeseen may appear in the future - then a good RDBMS is the only way to go.  In such cases, it's just impossible to safely predict what you'll need to do with the data one day, so you need database software that can do virtually anything.&lt;br /&gt;&lt;br /&gt;But when the database will play a supporting role to a single, well-defined application, and will not outlive the application. then a non-relational database could be very convenient, and MongoDB looks to me like a fantastic choice.&lt;br /&gt;&lt;br /&gt;Let's call this Devlin's Doggy Directive of Databases:&lt;br /&gt;&lt;blockquote&gt;If the application is the dog, and the database is the tail, consider a non-relational database.&lt;br /&gt;If the database is the dog, and the application is the tail, stick with a relational database.&lt;br /&gt;&lt;/blockquote&gt;If you doubt that I'm qualified to go naming rules of thumb after myself, let me remind you that have ten years of relational database experience, a sparse smattering of non-relational experience along the way, and that my parents owned a boarding kennel when I was young.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-684011485833212903?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/684011485833212903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=684011485833212903' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/684011485833212903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/684011485833212903'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/01/mongodb.html' title='MongoDB'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6387057293686525876</id><published>2010-01-17T17:41:00.000-08:00</published><updated>2010-01-17T17:44:40.217-08:00</updated><title type='text'>CodeMash general recap</title><content type='html'>Believe the hype.  &lt;a href="http://codemash.org"&gt;CodeMash&lt;/a&gt; is all that.  It's people from all over the region and beyond whose enthusiasm and intelligence is too much to stay channelled in one technology.  There are consistent preferences - for agile methods, open-source code, etc. - and a majority user community - .NET - but it's full of people who know that cross-pollination and cross-training are where it's at.&lt;br /&gt;&lt;br /&gt;The one problem is the same one that all big conferences have: the scheduled talk track is so rich that it's almost impossible to pull yourself away to the Open Spaces.  As next year's planning begins, I'll agitate for a schedule that somehow makes some Open Space time that doesn't run parallel to sponsored talks; I actually think Open Spaces on the precompiler day (maybe as the entire content of the precompiler day) would be a great idea.  Except that it's probably best to let the regular conference content prime the pump first... hmm...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6387057293686525876?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6387057293686525876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6387057293686525876' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6387057293686525876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6387057293686525876'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/01/codemash-general-recap.html' title='CodeMash general recap'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-5032690946163373964</id><published>2010-01-16T05:16:00.000-08:00</published><updated>2010-01-16T05:21:44.414-08:00</updated><title type='text'>reStructuredText talk follow-up</title><content type='html'>Thanks to everybody who saw my reStructuredText talk at &lt;a href="http://codemash.org/"&gt;CodeMash&lt;/a&gt; 2010!  My slides are at the end of &lt;a href="http://catherinedevlin.pythoneers.com/"&gt;catherinedevlin.pythoneers.com&lt;/a&gt;.  Those who asked questions I couldn't answer - thank you!  I'll be researching the ones I remember so that I can post on them; commenting or emailing me reminders of your questions - or new ones - would be much appreciated.&lt;br /&gt;&lt;br /&gt;I had a great time at CodeMash; the organizers deserve a huge round of applause.  I'll post more extensively with some of what I learned... after catching up on sleep.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-5032690946163373964?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/5032690946163373964/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=5032690946163373964' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5032690946163373964'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5032690946163373964'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/01/restructuredtext-talk-follow-up.html' title='reStructuredText talk follow-up'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-8993478476462671914</id><published>2010-01-14T06:50:00.000-08:00</published><updated>2010-01-14T07:02:12.021-08:00</updated><title type='text'>Codemash - day 0 (precompiler) report</title><content type='html'>A good start to &lt;a href="http://codemash.org/"&gt;CodeMash&lt;/a&gt;.  I started with a session on the &lt;a href="http://github.com/edgecase/ruby_koans"&gt;Ruby Koans&lt;/a&gt;, a very nice way of teaching; it tempts me to join the crew building a corresponding set of Python Koans.  In fact, it would be really interesting to host Python Koans on Google App Engine... Hmm...&lt;br /&gt;&lt;br /&gt;Next I went to Mary Poppendieck's session on leadership in software; alas, for me, it was as much frustrating as inspiring.  She described techniques proven to produce good software consistently, and I see very few of them in use in the Air Force.  Worse, the Air Force is driving hard to make the problem worse: centralizing, centralizing, centralizing - building up the separation between decisionmakers and IT professionals and IT users with thicker and thicker walls made of miles, layers of management, internal organziational boundaries, and government:contractor barriers.  *sigh*&lt;br /&gt;&lt;br /&gt;She did, however, make me realize that my employer - a small contractor that sends IT professionals in ones and twos to work on projects as our customers need - can do a lot more to improve skills among our employees.  We could get together occasionally from our various customer sites to work together on our skills, or at least have a mailing list for technical chat among our employees.&lt;br /&gt;&lt;br /&gt;But here's a question - from a purely selfish point of view, is this the right way to spend my energy?  After all, there are already plenty of groups of professionals dedicated to mutual skill improvement.  They're called user groups, and the time I spent on internal skill development could just as well be spent deepening my involvement in local user groups; the payoff may be bigger, because I'd be involved with a self-selecting group, with people who already believe it's worth going out of their way to hone their own skills and others'.  User group members have an attitude, a hunger and thirst and personal committment to excellence, and trying to create that attitude among my company coworkers may be a lot less fruitful than taking advantage of people who alreay have it.&lt;br /&gt;&lt;br /&gt;Your thoughts?&lt;br /&gt;&lt;br /&gt;Anyway, today begins CodeMash in earnest, and I'm loving it.  Most of all, I like meeting up with old friends and meeting new ones.  Geeks - particularly geeks who are active in the user community - are just fun, interesting people to be around!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-8993478476462671914?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/8993478476462671914/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=8993478476462671914' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8993478476462671914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8993478476462671914'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/01/codemash-day-0-precompiler-report.html' title='Codemash - day 0 (precompiler) report'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-5163536954411569608</id><published>2010-01-05T07:31:00.000-08:00</published><updated>2010-01-05T07:32:47.021-08:00</updated><title type='text'>PyCon early-bird deadline TOMORROW</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_HR7nVcfhs_s/S0NbgJN2yYI/AAAAAAAAAE8/XloWod9fo54/s1600-h/earlybird.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 291px;" src="http://4.bp.blogspot.com/_HR7nVcfhs_s/S0NbgJN2yYI/AAAAAAAAAE8/XloWod9fo54/s400/earlybird.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5423278984072186242" /&gt;&lt;/a&gt;Time to &lt;a href="http://us.pycon.org/2010/registration/"&gt;register&lt;/a&gt;.  Srsly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-5163536954411569608?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/5163536954411569608/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=5163536954411569608' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5163536954411569608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5163536954411569608'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2010/01/pycon-early-bird-deadline-tomorrow.html' title='PyCon early-bird deadline TOMORROW'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_HR7nVcfhs_s/S0NbgJN2yYI/AAAAAAAAAE8/XloWod9fo54/s72-c/earlybird.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-7673193903399924622</id><published>2009-12-10T19:41:00.001-08:00</published><updated>2009-12-10T19:53:23.476-08:00</updated><title type='text'>microfinance gift</title><content type='html'>Cash is almost always the most practical gift you can get somebody.  I have trouble not feeling that it's too crass, though.  Here's one possible solution.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://www.microplace.com/"&gt;Microplace&lt;/a&gt;, my favorite microcredit site, recently introduced a Gift feature where you can give an investment to somebody else.  You pay the money, it goes to the developing world as a loan, and the interest and eventual repayment go to your gift recipient.  Everybody wins!&lt;br /&gt;&lt;br /&gt;This makes the most sense when you know somebody will need the money more later than they do now; it's a nice way to put the money "in transit" to them - and it does some good on the way.  For instance, my sister is facing a gap in her income for maternity leave this spring; I chose a gift that would mature then.  It was a perfect solution!  Future students are other obvious recipients.  Seasonally employed people... people planning an upcoming major trip... etc.&lt;br /&gt;&lt;br /&gt;(Incidentally, another great microfinance site is Kiva, and there's actually a &lt;a href="http://www.kiva.org/team/pythonistas"&gt;Pythonistas' lending team&lt;/a&gt;.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-7673193903399924622?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/7673193903399924622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=7673193903399924622' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7673193903399924622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7673193903399924622'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/12/microfinance-gift.html' title='microfinance gift'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-5939623958821500979</id><published>2009-12-02T07:29:00.001-08:00</published><updated>2009-12-02T07:50:29.283-08:00</updated><title type='text'>Windows vs. Linux for Oracle</title><content type='html'>I found myself fielding a "Windows vs. Linux for Oracle" question on StackOverflow, and realized that my answer was detailed enough to deserve a blog entry... my humble contribution to the great war.  (I know most experienced Oracle DBAs are chuckling, because "Which OS is best?" is more likely to make them think "Linux or commercial UNIX?")&lt;br /&gt;&lt;br /&gt;Note that I'm speaking here of my preference strictly for Oracle-hosting purposes, and that everything I say about "Linux" really applies to all POSIX-based systems (like Solaris, which I started on as a DBA).&lt;br /&gt;&lt;br /&gt;I've used Oracle on Windows and Linux for many years, and on Solaris many years ago. I prefer Linux because:&lt;br /&gt;&lt;br /&gt;   1. Oracle releases patches, new versions, and sometimes security updates for Linux significantly before they are available for Windows - there's usually about a two month lag for Windows (one month for Critical Patch Updates).&lt;br /&gt;   2. Our Windows servers have crashed or locked up occasionally, and very frequently require reboots for patch installation. Oracle itself stays up very nicely, but Oracle can't keep running on a machine that is down. This hasn't been a problem for me on Linux.&lt;br /&gt;   3. Oracle's interaction with Vista's User Access Control is a nightmare. I'm constantly finding that the dedicated Oracle user account, which was used to install Oracle, nonetheless lacks permission to edit or even see Oracle-generated files - like newly generated logfiles. It could be that I'm making some mistake, but permissions shouldn't be confusing; and on Linux, they aren't. (Most servers don't run Vista, but I'm afraid of what this forebodes for future versions of Windows Server.)&lt;br /&gt;   4. Thanks to the Windows Registry, cleanly removing an installation of Oracle from Windows is tricky and tedious. The Oracle Installer has gotten better at this since version 10g, though.&lt;br /&gt;   5. Better tools. Linux &lt;span style="font-style:italic;"&gt;find&lt;/span&gt; is infinitely better than any native Windows search tool.  It can take you minutes on Windows to track down what Linux &lt;span style="font-style:italic;"&gt;which&lt;/span&gt; tells you in an instant.  Also, Oracle uses and generates plenty of plain-text files, and Linux comes with better tools for handling text files - good text editors (unlike Notepad), shell commands like head, tail, grep, etc. You can try to catch Windows up by installing Geanie, Cygwin, Google Desktop, etc. on a Windows machine, but it's better not to have to (especially since Cygwin installation is not completely newbie-friendly).&lt;br /&gt;&lt;br /&gt;I can only think of two Windows advantages over Linux:&lt;br /&gt;&lt;br /&gt;   1. In Oracle's command-line tools like sqlplus, rman, etc., you can scroll through and re-run past commands using the up- and down- arrow keys - but only on Windows. You can fix this on Linux by installing rlwrap and always invoking the Oracle tools under rlwrap: &lt;code&gt;rlwrap sqlplus me@myinstance&lt;/code&gt;&lt;br /&gt;   2. Quest's TOAD is only available for Windows, and it is an infamously useful tool.  It doesn't need to be on the database server, though, just on a machine that can connect to the database.  Also, Oracle's free sqldeveloper is one among several viable alternatives; it will probably never catch up to TOAD completely, but it's good for the bulk of what most people use TOAD for.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;In general&lt;/span&gt;, however, I should emphasis that Oracle's ancient boast of running on everything really is true.  As a DBA, I prefer Linux for the reasons listed above, but to my database users, it's absolutely irrelevant (downtime aside).  I could move my production databases to a different OS overnight, and tomorrow, my users would have no idea that there had been a change.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-5939623958821500979?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/5939623958821500979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=5939623958821500979' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5939623958821500979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5939623958821500979'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/12/windows-vs-linux-for-oracle.html' title='Windows vs. Linux for Oracle'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6059972531702955784</id><published>2009-11-22T06:22:00.000-08:00</published><updated>2009-11-23T13:07:54.282-08:00</updated><title type='text'>Viva Tortuga</title><content type='html'>&lt;a href="http://www.blogger.com/profile/07097826327266682983"&gt;Joseph Lisee&lt;/a&gt;, author of the upcoming &lt;a href="http://us.pycon.org/2010/conference/talks/#proposal_link_175"&gt;Python submarine robot PyCon talk&lt;/a&gt;, left a comment on my last post.  I think he was a little shy about me highlighting him.&lt;br /&gt;&lt;br /&gt;I'm sorry, Joseph.  You really left me no choice.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Completely Unfounded Rumors About &lt;span style="font-style:italic;"&gt;&lt;a href="http://us.pycon.org/2010/conference/talks/#proposal_link_175"&gt;"An Underwater Python: Tortuga the Python Powered Robot"&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Roll 1d6 for each hour spent in the Atlanta Hyatt bar.&lt;ol&gt;&lt;li&gt;1. Joseph will announce the release of &lt;em&gt;asimov.py&lt;/em&gt;, a pure-Python implementation of the Three Laws of Robotics.&lt;/li&gt;&lt;li&gt;2. Bring a swimsuit and snorkel.  One lucky audience member will be picked to join Tortuga in the hotel pool, where Tortuga will take a fish from their hand.*&lt;/li&gt;&lt;li&gt;3. Jozeph 'az been practeeseeng 'eez reedeeculous Jacques Cousteau accent for months and weel uze eet to deeleever zee eentire talk.&lt;/li&gt;&lt;li&gt;4. Several minutes into the presentation, Tortuga will overpower Joseph, throw him from the stage, and announce that humankind is obsolete and has been deprecated.&lt;/li&gt;&lt;li&gt;5. Attendees will be asked to pour out a libation to Poseidon.  Any caffeinated beverage may be used.&lt;/li&gt;&lt;li&gt;6. There will be a sprint to construct a tall, dapper companion to Tortuga for communication and protocol purposes.&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-style:italic;"&gt;* - No, Tortuga won't be physically present at PyCon.  It's not that portable.  Believe me, the program committee asked!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;P. S. Blogger, don't you know what an &amp;lt;ol&amp;gt; is?  You know, like an &amp;lt;ul&amp;gt with numbers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6059972531702955784?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6059972531702955784/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6059972531702955784' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6059972531702955784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6059972531702955784'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/11/joseph-lisee-author-of-upcoming-python.html' title='Viva Tortuga'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-7739797831900664217</id><published>2009-11-20T03:03:00.000-08:00</published><updated>2009-11-20T03:44:37.796-08:00</updated><title type='text'>PyCon pre-favorites</title><content type='html'>When I look over the &lt;a href="http://us.pycon.org/2010/conference/talks/"&gt;PyCon 2010 talk list&lt;/a&gt;, I'd like to be at about half of them (a physical impossibility, until I master self-multiplexing).  Still, these are the ones that I'll move heaven and earth to be at.  What about you - what are your favorites?&lt;dl&gt;&lt;dt&gt;&lt;a href="http://us.pycon.org/2010/conference/talks#proposal_link_65"&gt;Extending Java Applications with Jython &lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;I'm hopeful that this can really move Jython from my "stuff I think is cool" box to my "stuff I use every day" box.&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://us.pycon.org/2010/conference/talks#proposal_link_67"&gt;IronPython Tooling&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;This is going to cover development environments and tools for debugging and profiling... pretty much a necessity in the .NET world.  I also hope to use the video of this talk in the future in talking to the hordes of programmers around here who live and breathe Visual Studio.&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://us.pycon.org/2010/conference/talks#proposal_link_71"&gt;Python in the Browser &lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;Silverlight is way too cool to leave to the C# kids.&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://us.pycon.org/2010/conference/talks#proposal_link_122"&gt;Think Globally, Hack Locally - Teaching Python in Your Community &lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;As a local group-leader type geek, I'd love to start some of these Hack Nights.&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://us.pycon.org/2010/conference/talks#proposal_link_133"&gt;Dude, Where's My Database?&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;There were &lt;span style="font-style:italic;"&gt;so many&lt;/span&gt; proposals for descriptions of non-relational databases - but this one really stands out because it looks at the huge picture, classifying databases by their broad category and highlighting what makes each category beneficial for particular purposes.&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://us.pycon.org/2010/conference/talks#proposal_link_137"&gt;Sprox: data driven web development &lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;I confess - I've fallen behind the TurboGears world lately.  Nobody's demanded a dynamic web app of me for a while, and TG has moved too fast for me to keep track of it.  When last I was involved, Sprox was just emerging.  I hope this talk will help me catch up.&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://us.pycon.org/2010/conference/talks#proposal_link_86"&gt;Revisioned Databases for MultiUser Editing &lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;Revisioned databases are an interesting concept, and seeing how one was actually developed should warm my datageek heart.&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://us.pycon.org/2010/conference/talks#proposal_link_153"&gt;Easy command-line applications with cmd and cmd2&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;Interactive command-line interfaces were good enough for ZORK, and they're good enough for you!  cmd and cmd2 make them crazy-easy.  (I'll get in trouble if I don't go to this one, since I'm the speaker.)&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://us.pycon.org/2010/conference/talks#proposal_link_156"&gt;Dealing with unsightly data in the real world&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;Gathering data from disparate, chaotic sources is a big part of pretty much everybody's life.  I'm eager for any new insights.&lt;/dd&gt;&lt;dt&gt;&lt;a href="http://us.pycon.org/2010/conference/talks#proposal_link_175"&gt;An Underwater Python: Tortuga the Python Powered Robot&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;because, deep down inside, people everywhere are the same; we all want to be loved, &lt;span style="font-style:italic;"&gt;and Python-powered robot submarines&lt;/span&gt;.&lt;/dd&gt;&lt;/dl&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-7739797831900664217?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/7739797831900664217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=7739797831900664217' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7739797831900664217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7739797831900664217'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/11/pycon-pre-favorites.html' title='PyCon pre-favorites'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-4866392375555319086</id><published>2009-11-18T12:47:00.000-08:00</published><updated>2009-11-18T12:52:05.253-08:00</updated><title type='text'>Configuring Oracle Data Guard</title><content type='html'>&lt;a href="http://www.oracle.com/pls/db112/portal.portal_db?selected=14&amp;frame=#data_guard"&gt;The official Oracle Data Guard docs&lt;/a&gt; are, of course, the most complete and accurate source of information about setting up Data Guard.&lt;br /&gt;&lt;br /&gt;They're not very easy to use, though.  They don't provide a walk-through of the entire process, for example, instead branching the discussion at every possible decision point.&lt;br /&gt;&lt;br /&gt;I just fought my way through the process, with help from Chris Ruel of &lt;a href="http://perptech.com/"&gt;Perpetual Technologies&lt;/a&gt;, and thought I'd record my steps for the benefit of humankind.  OK, that's not true - it's actually because the Internet is the only place I can leave myself notes and be certain to find them again later.&lt;br /&gt;&lt;br /&gt;It's too bulky for a blog post, so here: &lt;a href="http://catherinedevlin.pythoneers.com/dg.html"&gt;Oracle Data Guard Configuration Walk-Through&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-4866392375555319086?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/4866392375555319086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=4866392375555319086' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4866392375555319086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4866392375555319086'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/11/configuring-oracle-data-guard.html' title='Configuring Oracle Data Guard'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-7453620171955511211</id><published>2009-11-05T07:00:00.001-08:00</published><updated>2009-11-18T12:58:28.647-08:00</updated><title type='text'>pernicious python.org proxy problem</title><content type='html'>For the past few weeks, I haven't been able to access python.org or any of its pages through a proxy server.  My workplace has one standard proxy server, and I also use a personal machine as a SOCKS proxy for an SSH tunnel - and both of them have been getting name resolution errors for all python.org sites.  I haven't seen it for any other sites, or when using no proxy.&lt;br /&gt;&lt;br /&gt;Does anybody know what's going on?  Is there something about python.org that would make name resolution work differently for it?&lt;br /&gt;&lt;br /&gt;[EDIT: Friends from the &lt;a href="http://www.dma.org/sigs.shtml#Dynamic"&gt;Dayton Dynamic Languages SIG&lt;/a&gt; figured this one out.  My primary workplace proxy server is blocking DNS lookup on the python.org domain.  Trying to use a different proxy through a SOCKS/SSH tunnel produced the same DNS failure, because - to my surprise - by default, Firefox does &lt;span style="font-style:italic;"&gt;not&lt;/span&gt; make its DNS requests through the SSH tunnel even when all other traffic &lt;span style="font-style:italic;"&gt;is&lt;/span&gt; tunneled.  The network.proxy.socks_remote_dns preference must be set to change this.  See "&lt;a href="https://calomel.org/firefox_ssh_proxy.html"&gt;Proxy Firefox through a SSH tunnel&lt;/a&gt;".]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-7453620171955511211?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/7453620171955511211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=7453620171955511211' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7453620171955511211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7453620171955511211'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/11/pernicious-pythonorg-proxy-problem.html' title='pernicious python.org proxy problem'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-8445481670856757570</id><published>2009-11-03T09:19:00.000-08:00</published><updated>2009-11-03T09:37:35.389-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='pycon'/><title type='text'>A PyCon program committee volunteer reflects</title><content type='html'>The &lt;a href="http://us.pycon.org"&gt;PyCon&lt;/a&gt; program committee has finished its work.  All submissions have been reviewed, debated, argued on, and voted - often through several cycles.  Emails accepting and declining talks have gone out.&lt;br /&gt;&lt;br /&gt;I wanted to blog about my impressions as a program committee volunteer.  Note that this is totally unofficial, and I'm not speaking on behalf of the committee, PyCon, etc.&lt;br /&gt;&lt;h2&gt;It was wonderful&lt;/h2&gt;Just reviewing the talks was a great experience.  Some of the talks were fun just to visualize; watching them will be even better.  I learned lots about what is going on in the Python community.  The program committee is a smart and fun crowd to work with, too.&lt;br /&gt;&lt;h2&gt;It was horrible&lt;/h2&gt;The problem with a programming language that can do pretty much anything is that three days of scheduled talks are nowhere near enough to see everything that's going on.  I wish we could have five days of talks, but there are too many people who wouldn't have the time or money for such a conference.&lt;br /&gt;&lt;br /&gt;With room to accept fewer than half of our submissions, we had to turn away talks that would have been great.  For instance, the one talk I most wanted to see - the proposal I would have walked barefoot to Atlanta for - got declined.  What can you do?  Often "pretty much everybody was pretty excited about this" talks had to be sacrificed for the sake of "virtually everybody was dying to see this" talks.&lt;br /&gt;&lt;h2&gt;But wait, there's more&lt;/h2&gt;Fortunately, scheduled talks are only the tip of the PyCon iceberg.  We have Lightning Talks, Open Spaces, and (new this year) &lt;a href="http://us.pycon.org/2010/conference/posters/"&gt;poster board sessions&lt;/a&gt;!  I hope all declined speakers will consider taking their material to one or more of those formats!&lt;br /&gt;&lt;h2&gt;PyCon is going to be wonderful&lt;/h2&gt;I think we have the best crop of presentations we've ever had.  If you can look through the list of accepted talks and not start making Atlanta travel plans, then you are already dead.&lt;br /&gt;&lt;h2&gt;PyCon is going to be horrible&lt;/h2&gt;... because, with five simultaneous tracks packed with the very best of material, I promise you will face multiple can't-miss talks going on at the same time, all day, every day.  The painful decisions of the program committee are really only a preview of the difficult decisions every attendee will have to make at the conference itself.&lt;br /&gt;&lt;h2&gt;For 2011: increasing your chances&lt;/h2&gt;If you want to make your future PyCon proposal more appealing to the committee (making our decisions even harder - thanks a lot), here are some of the things I saw that helped talks make the cut.&lt;ul&gt;&lt;li&gt;The basics: a clear talk description, orderly-looking outline, plausible-looking timings.  If reviewers ask questions, answer them.  Give every impression that you're prepared to put serious effort into your talk.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Broad appeal.  It's OK to present on specialty topics, of course, but if you can point out ways that even people outside the specialty will also want to see it, it will help.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Unusual topic.  Every year, there are some hot topics that everybody in the community seems to be talking about... and submitting talks on.  Since we're not going to accept a dozen talks on any topic, no matter how hot, these talks need to prevail over a lot of competitors.  On the other hand, if you've got a topic that makes the committee say, "HUH?  Wow, I'd never heard of anything like that!", it really helps you stand out.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;We always get more intermediate-level submissions than for beginner or advanced, so the competition was fiercest there.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;What will attendees get from your talk that they couldn't get simply from reading the docs?  Make sure we can tell.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Evidence of preparation and skill.  Some speakers had established reputations as skillful, engaging presenters; some provided links to their slide decks from earlier versions of their talks given at local groups or regional conferences; a few linked to actual recordings of earlier versions of their talks.  Give your talk at a nearby usergroup, then convince one of your group members to volunteer for the program committee.  :)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Scratch the itch.  When committee members say, "Ah, yes, I've been puzzled by that and dying for a proper explanation!" - or, "I personally understand it, but I see misunderstanding of it throughout the community and wish somebody would help clear  it up", that is a big plus.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Keep the Py in PyCon.  If the topic is one of general IT interest - database technology or rich web client programming, for instance - then make sure to emphasize the Python angle of your talk.  How do you work the problem from Python specifically?  What do Python users need to know about the problem that they won't learn from materials aimed at the IT community overall?&lt;/li&gt;&lt;/ul&gt;Anyway, my personal thanks to everyone who submitted, and I really hope to see you all at PyCon!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-8445481670856757570?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/8445481670856757570/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=8445481670856757570' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8445481670856757570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8445481670856757570'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/11/pycon-program-committee-volunteer.html' title='A PyCon program committee volunteer reflects'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-5433430923462444737</id><published>2009-10-07T06:22:00.000-07:00</published><updated>2009-10-07T06:55:08.061-07:00</updated><title type='text'>Stop!  Drop that field!</title><content type='html'>For &lt;a href="http://www.pyohio.org/"&gt;PyOhio&lt;/a&gt; registration, we used a nice service called &lt;a href="http://www.eventbrite.com/"&gt;eventbrite&lt;/a&gt;.  It worked great, but I have one big problem with it: it collected way too much data from registrants.  It got us the data we needed, but it also asked for home addresses, gender, job title, company... all data we had no legitimate need for or plans to use, probably just because the fields are in the eventbrite form template.  Entering it was pointless nuisance for our attendees, and maybe some were actually put off by the length or intrusiveness of the registration form.  (Dave Stanek, if you're reading this, let's see if we can change that for next year.)&lt;br /&gt;&lt;br /&gt;We are &lt;span style="font-style:italic;"&gt;so&lt;/span&gt; not the only offenders in this department.  It's everywhere, it's endemic.  At website after website, we're asked to provide information of no apparent relevance to the sites' purposes.  It's so easy to throw field after field into a data collection form; templates are provided with every conceivable field already in place; and - well, why not?  Isn't more data better?&lt;br /&gt;&lt;br /&gt;No.  No, it's not.  Excess data takes time, clutters databases, obscures important data, increases risks of data leakage.  In interpersonal interactions, we always have the option of asking "Why do you need to know that?", or just giving people that funny look that tells them they're going out of bounds.  On paper forms, we can leave fields blank.  Automated forms with field validation cut those safeguards off and open the door to compulsive collection syndrome.  The one defense people do have against intrusive electronic forms - lying - ruins data quality, and false data is much worse than no data at all.&lt;br /&gt;&lt;br /&gt;We need a ethos of restraint in data collection, of always asking, "Why am I collecting this field?"  Data collection needs to be seen as something that is not pure good, but something that has a cost to weigh against the benefit.  &lt;span style="font-style:italic;"&gt;Not&lt;/span&gt; collecting data is often the responsible choice, and we need to teach each other that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-5433430923462444737?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/5433430923462444737/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=5433430923462444737' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5433430923462444737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5433430923462444737'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/10/stop-drop-that-field.html' title='Stop!  Drop that field!'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-7359139683091666347</id><published>2009-10-05T11:43:00.001-07:00</published><updated>2009-10-05T11:49:31.279-07:00</updated><title type='text'>PyCon talk review</title><content type='html'>We've got a record number of volunteers working on PyCon's Program Committee - the group that reviews talk proposals and decides which ones go on the schedule.  And it's a good thing, because we've also got a record number of proposals - 179!  (For comparison, PyCon 2008 got 118.)&lt;br /&gt;&lt;br /&gt;Right now, we're in the fun part - going through the proposed talks and yelling, "Oooh!  Ooooh!  I want that one!"  Just looking through the proposed talks is a great Python education all by itself - you find out about useful packages and techniques you'd never known were out there.  &lt;br /&gt;&lt;br /&gt;The tough part comes later - when we have to winnow the list down.  Without exception, there are talks I want to see that won't make the cut.  Accepting all the good talks would be great, but we'd need a week of PyCon, and three days for the core conference are all we figure most attendees can spare.  (My proposal for a round-the-clock talk schedule met only chuckles.  Then again, with late-night Open Spaces, we already come dangerously close to a round-the-clock schedule...)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-7359139683091666347?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/7359139683091666347/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=7359139683091666347' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7359139683091666347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7359139683091666347'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/10/pycon-talk-review.html' title='PyCon talk review'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-4576206123806792726</id><published>2009-09-29T08:44:00.001-07:00</published><updated>2009-10-02T10:37:55.524-07:00</updated><title type='text'>Ohio LinuxFest</title><content type='html'>Wooo, Ohio LinuxFest!&lt;br /&gt;&lt;br /&gt;My reStructuredText slides are at &lt;a href="http://catherinedevlin.pythoneers.com/"&gt;catherinedevlin.pythoneers.com&lt;/a&gt;, down at the bottom of the page.  Thanks to everybody who attended and gave great feedback!&lt;br /&gt;&lt;br /&gt;I arrived Friday morning this time and spent a good chunk of the day at the Hackathon, working with Mark Borgerding on his idea for a new educational game for Childsplay.  We made some good progress, especially since we were both 100% newbies to pygame!  I enjoyed myself and learned a thing or two.  Hopefully we'll be able to finish the game up remotely over the next several weeks.  &lt;br /&gt;&lt;br /&gt;Next came an impromptu lightning talk session (I looooove lightning talks) where I gave an extremely badly-organized (but well-received) glimpse at sqlpython.  &lt;br /&gt;&lt;br /&gt;I helped Todd Trichler from Oracle Technology Network with his demonstration of Oracle's free offerings.  We had a good group, and the next morning Todd gave away his ENORMOUS box of Oracle software in about an hour.&lt;br /&gt;&lt;br /&gt;The hallway track was, as usual, excellent.  William McVey and Eric Floehr used the PyOhio table to stir up interest in CincyPy and Central Ohio Pythonistas, and Monday's inaugural COPy meeting had 27 attendees!  Score!  I enjoyed talking with people so much that I found myself on the verge of going hoarse just 90 minutes before my talk.  Eek!&lt;br /&gt;&lt;br /&gt;I had a great time.  Congratulations and thank you to the OLF organizers and sponsors.  Once a year, you make Ohio feel like anything but a technology backwater!&lt;br /&gt;&lt;br /&gt;Sunday was the Diversity in Open Source workshop, which deserves its own post.  To be continued...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-4576206123806792726?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/4576206123806792726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=4576206123806792726' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4576206123806792726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4576206123806792726'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/09/ohio-linuxfest.html' title='Ohio LinuxFest'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6140429737074408223</id><published>2009-09-24T06:47:00.001-07:00</published><updated>2009-09-24T06:56:16.549-07:00</updated><title type='text'>Python at Ohio LinuxFest</title><content type='html'>The &lt;a href="http://ohiolinux.org/"&gt;Ohio LinuxFest&lt;/a&gt; fun starts tomorrow!  Here are the Python-related activities there that I know of.&lt;br /&gt;&lt;br /&gt;Of the Friday hackathon projects, I believe that &lt;a href="http://sourceforge.net/projects/schoolsplay/"&gt;schoolsplay&lt;/a&gt; and &lt;a href="http://sourceforge.net/projects/sendoff/"&gt;sendoff&lt;/a&gt; are Python-based.&lt;br /&gt;&lt;a href="http://www.ohiolinux.org/hackathon.html"&gt;http://www.ohiolinux.org/hackathon.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Zenoss Community day on Friday (Zenoss is a Python product):&lt;br /&gt;&lt;a href="http://www.ohiolinux.org/zenoss.html"&gt;http://www.ohiolinux.org/zenoss.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Python for Linux System Administration - Vern Ceder&lt;br /&gt;10 AM Saturday&lt;br /&gt;&lt;a href="http://www.ohiolinux.org/talks.html#PYTHON"&gt;http://www.ohiolinux.org/talks.html#PYTHON&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;reStructuredText - Plain Text gets Superpowers - me&lt;br /&gt;5 PM Saturday&lt;br /&gt;&lt;a href="http://www.ohiolinux.org/talks.html#TEXT"&gt;http://www.ohiolinux.org/talks.html#TEXT&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pyohio.org"&gt;PyOhio&lt;/a&gt; booth - all day Saturday (though not always staffed).  All Python groups should take advantage of it shamelessly - bring your literature! - and anybody who wants to hang around there and have Python-related conversations with people, that's fantastic.&lt;br /&gt;&lt;br /&gt;And, of course, don't forget &lt;a href="http://catherinedevlin.blogspot.com/2009/08/oracle-at-ohio-linuxfest.html"&gt;Oracle's event at OLF&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;See you there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6140429737074408223?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6140429737074408223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6140429737074408223' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6140429737074408223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6140429737074408223'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/09/python-at-ohio-linuxfest.html' title='Python at Ohio LinuxFest'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-1301155174063836618</id><published>2009-09-17T10:46:00.001-07:00</published><updated>2009-09-17T11:01:19.326-07:00</updated><title type='text'>easy_install no longer easy on Vista</title><content type='html'>Since my Windows machine was upgraded from XP to Vista, managing Python packages has become absolutely horrible.  Here's what I've puzzled out so far, with much wailing and gnashing of teeth:&lt;br /&gt;&lt;br /&gt;1. No matter what rights your primary account has, you need to run easy_install from a &lt;span style="font-style:italic;"&gt;Run as Administrator&lt;/span&gt; window - otherwise, easy_install runs in a separate window which pops up, flashes some feedback at you for a microsecond or so, then disappears, leaving you with absolutely no record of whether the install works and why.  There doesn't seem to be any way to log the results to a file.&lt;br /&gt;&lt;br /&gt;2. After installing any module that is deployed as an .egg into &lt;span style="font-style:italic;"&gt;site-packages&lt;/span&gt;, you need to go and edit its permissions manually to give your account read privileges on the egg.  (Giving your account privileges on the whole site-packages directory does not help.)  Until you do, &lt;span style="font-style:italic;"&gt;import newmodule&lt;/span&gt; will fail with &lt;span style="font-style:italic;"&gt;ImportError: no module named newmodule&lt;/span&gt; on your account - but will succeed when run from a Run as Administrator window.&lt;br /&gt;&lt;br /&gt;This is bad news.  I fought my way through because I'm a dedicated Pythonista; how many Vista-using Py-curious are going to give up on Python because module installation now requires such hacks?&lt;br /&gt;&lt;br /&gt;(Don't forget - Ohio LinuxFest registration ends tomorrow at noon!  Move, move, move!  You'll hurt my feelings if you don't go.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-1301155174063836618?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/1301155174063836618/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=1301155174063836618' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1301155174063836618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1301155174063836618'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/09/easyinstall-no-longer-easy-on-vista.html' title='easy_install no longer easy on Vista'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-3542451930785650633</id><published>2009-08-28T11:57:00.001-07:00</published><updated>2009-08-28T17:08:09.539-07:00</updated><title type='text'>Enthought's reStructuredText editor</title><content type='html'>Enthought has produced a wonderful tool for getting into reStructuredText: a side-by-side WYSIWYG rST editor.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_HR7nVcfhs_s/SpgowhBw8vI/AAAAAAAAAEY/1AzCTiiHvI8/s1600-h/rsted.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 169px;" src="http://1.bp.blogspot.com/_HR7nVcfhs_s/SpgowhBw8vI/AAAAAAAAAEY/1AzCTiiHvI8/s400/rsted.png" border="0" alt="Screenshot of editor session" id="BLOGGER_PHOTO_ID_5375090969231291122" /&gt;&lt;/a&gt;&lt;br /&gt;Getting it installed, however, just about killed me.  Here are the steps I finally puzzled out for Ubuntu 9.04.  Miss any steps - or even change the order - and you'll get error messages that don't help even slightly.&lt;blockquote&gt;&lt;code&gt;sudo apt-get update&lt;br /&gt;sudo apt-get install python-setuptools python-vtk&lt;br /&gt;sudo easy_install -U numpy&lt;br /&gt;sudo easy_install -U docutils sphinx TraitsBackendQt[nonets] AppTools[nonets]&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;[EDIT] If you're not on 9.04, or you just want to be on the safe side, it doesn't hurt to &lt;code&gt;sudo apt-get install python-dev python-qt4&lt;/code&gt; at the beginning of the whole process.&lt;br /&gt;&lt;br /&gt;The other odd thing is that this lovely editor apparently has no name, and certainly no handy start script or presence in any menu.  Mine got installed at &lt;code&gt;/usr/local/lib/python2.6/dist-packages/AppTools-3.3.0-py2.6.egg/enthought/rst/app.py&lt;/code&gt;; your best bet to find yours is probably &lt;code&gt;sudo updatedb; locate -r rst/app.py$&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Then, set up a bash script to make it usable.  I'm calling it "rsted".  &lt;code&gt;sudo nano /usr/local/bin/rsted&lt;/code&gt; and fill it with:&lt;blockquote&gt;&lt;code&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;python /usr/local/lib/python2.6/dist-packages/AppTools-3.3.0-py2.6.egg/enthought/rst/app.py $*&lt;br /&gt;&lt;/code&gt;&lt;/blockquote&gt;    &lt;br /&gt;... &lt;code&gt;sudo chmod +x /usr/local/bin/rsted&lt;/code&gt;, and live happily ever after.&lt;br /&gt;  &lt;br /&gt;(The $* in /usr/local/bin/rsted doesn't actually do anything - the editor doesn't seem to accept arguments like a filename - but I'm being hopeful for the future.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-3542451930785650633?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/3542451930785650633/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=3542451930785650633' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3542451930785650633'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3542451930785650633'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/08/enthoughts-restructuredtext-editor.html' title='Enthought&apos;s reStructuredText editor'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_HR7nVcfhs_s/SpgowhBw8vI/AAAAAAAAAEY/1AzCTiiHvI8/s72-c/rsted.png' height='72' width='72'/><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-1203966398207791005</id><published>2009-08-14T09:30:00.000-07:00</published><updated>2009-08-14T09:32:16.358-07:00</updated><title type='text'>PyCon 2010: Call for Proposals</title><content type='html'>In the opinion of most attendees I talked to, PyCon 2009 was the best one yet.  If you need an excuse to come to PyCon 2010... well, what better excuse could there be than, "I'm speaking"?&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;Call for proposals — PyCon 2010 — &lt;a href="http://us.pycon.org/2010/"&gt;http://us.pycon.org/2010/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Due date: October 1st, 2009&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Want to showcase your skills as a Python Hacker? Want to have hundreds of people see your talk on the subject of your choice? Have some hot button issue you think the community needs to address, or have some package, code or project you simply love talking about? Want to launch your master plan to take over the world with python?&lt;br /&gt;&lt;br /&gt;PyCon is your platform for getting the word out and teaching something new to hundreds of people, face to face.&lt;br /&gt;&lt;br /&gt;Previous PyCon conferences have had a broad range of presentations, from reports on academic and commercial projects, tutorials on a broad range of subjects and case studies. All conference speakers are volunteers and come from a myriad of backgrounds. Some are new speakers, some are old speakers. Everyone is welcome so bring your passion and your code! We’re looking to you to help us top the previous years of success PyCon has had.&lt;br /&gt;&lt;br /&gt;PyCon 2010 is looking for proposals to fill the formal presentation tracks.  The PyCon conference days will be February 19-22, 2010 in Atlanta, Georgia, preceded by the tutorial days (February 17-18), and followed by four days of development sprints (February 22-25).&lt;br /&gt;&lt;br /&gt;Online proposal submission is open now! Proposals will be accepted through October 1st, with acceptance notifications coming out on November 15th. For the detailed call for proposals, please see:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://us.pycon.org/2010/conference/proposals/"&gt;http://us.pycon.org/2010/conference/proposals/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For videos of talks from previous years – check out:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pycon.blip.tv"&gt;http://pycon.blip.tv&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We look forward to seeing you in Atlanta!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-1203966398207791005?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/1203966398207791005/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=1203966398207791005' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1203966398207791005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1203966398207791005'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/08/pycon-2010-call-for-proposals.html' title='PyCon 2010: Call for Proposals'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-1969804732010891995</id><published>2009-08-11T12:27:00.000-07:00</published><updated>2009-08-11T12:40:46.506-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sqlpython'/><title type='text'>BLOBs in sqlpython</title><content type='html'>Obviously, you can't query BLOBs in a command-line SQL tool.&lt;br /&gt;&lt;br /&gt;Unless, of course, that tool is &lt;a href="http://pypi.python.org/pypi/sqlpython"&gt;sqlpython&lt;/a&gt;.  Bwa ha ha ha.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_HR7nVcfhs_s/SoHI_gavjdI/AAAAAAAAAEQ/g2JRfj8zqNA/s1600-h/Screenshot.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 267px;" src="http://1.bp.blogspot.com/_HR7nVcfhs_s/SoHI_gavjdI/AAAAAAAAAEQ/g2JRfj8zqNA/s400/Screenshot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5368793224161758674" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-1969804732010891995?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/1969804732010891995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=1969804732010891995' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1969804732010891995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1969804732010891995'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/08/blobs-in-sqlpython.html' title='BLOBs in sqlpython'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_HR7nVcfhs_s/SoHI_gavjdI/AAAAAAAAAEQ/g2JRfj8zqNA/s72-c/Screenshot.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-8792871705199232499</id><published>2009-08-11T10:10:00.000-07:00</published><updated>2009-08-11T10:45:58.640-07:00</updated><title type='text'>reStructuredText talk at OLF</title><content type='html'>It's official - I'm on the schedule!&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.ohiolinux.org/"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 151px; height: 98px;" src="http://www.ohiolinux.org/files/images/151x49.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;div id="hcalendar-reStructuredText:-Plain-Text-Gets-Superpowers" class="vevent"&gt;&lt;br /&gt;&lt;a href="http://www.ohiolinux.org/talks.html#TEXT" class="url summary"&gt;reStructuredText: Plain Text Gets Superpowers&lt;/a&gt;&lt;br /&gt;&lt;abbr title="2009-09-26T17:00-04:0000" class="dtstart"&gt;September 26, 2009, 5&lt;/abbr&gt; - &lt;abbr title="2009-09-26T18:00-04:00" class="dtend"&gt;6pm&lt;/abbr&gt;&lt;br /&gt;at &lt;a href="http://www.ohiolinux.org/"&gt;Ohio LinuxFest&lt;/a&gt;&lt;br /&gt;&lt;div id="hcard-Greater-Columbus-Convention-Center" class="vcard location"&gt;&lt;br /&gt;  &lt;a class="url fn n" href="http://www.columbusconventions.com/"&gt;Greater Columbus Convention Center&lt;/a&gt;  &lt;div class="adr"&gt;    &lt;div class="street-address"&gt;400 North High Street&lt;/div&gt;    &lt;span class="locality"&gt;Columbus&lt;/span&gt;, &lt;span class="region"&gt;OH&lt;/span&gt; &lt;span class="postal-code"&gt;43215&lt;/span&gt; &lt;span class="country-name"&gt;USA&lt;/span&gt;  &lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="description"&gt;Introduction to reStructuredText, a simple single-source format that can generate documents in HTML, PDF, .odt, and many other formats.&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;I also see tasty-looking talks on "Python for Linux System Administration", a "Sysadmins' Rosetta Stone" talk that should help me port my Ubuntu skills to Red Hat, and gobs more - plus the Diversity in Open Source workshop.  This will be a great year!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-8792871705199232499?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/8792871705199232499/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=8792871705199232499' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8792871705199232499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8792871705199232499'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/08/restructuredtext-talk-at-olf.html' title='reStructuredText talk at OLF'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-3411929164831267033</id><published>2009-08-11T07:31:00.000-07:00</published><updated>2009-08-11T07:52:24.557-07:00</updated><title type='text'>Spend Like a Pirate Day</title><content type='html'>Why do we Americans continue to carry around drab $1 bills, struggling to cram mushy, wrinkled paper into vending machine readers, when we could carry gleaming, clinking, golden doubloons?&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.usmint.gov/images/mint_programs/firstSpouse/AbigailAdamsObv.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 200px;" src="http://www.usmint.gov/images/mint_programs/firstSpouse/AbigailAdamsObv.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;Admire the gleam and the weight.  This is the proper sensory experience for money!&lt;br /&gt;&lt;br /&gt;I just found out &lt;a href="http://www.usmint.gov/mint_programs/$1coin/?action=directShip"&gt;you can buy boxes of 250 coins directly from the mint&lt;/a&gt;.  Granted, there's $5 shipping, so you're paying $255 to get $250, but your credit card kickback should cover that.  Then you can eschew that lame ATM for months!  Let's face it, you only use cash for little purchases these days anyway.  Make every cash transaction enjoyable!&lt;br /&gt;&lt;br /&gt;When you receive your coins, feel free to run your hands through them several times, purring, "Arrrrrr!  Thar's treasure for ye, me mateys!"  Do &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt;, however, bury them in a sturdy wooden chest and draw a map with a dotted line and an X.  I know it's tempting!  I want to do it, too!  But the point is to get more of these beauties into circulation.&lt;br /&gt;&lt;br /&gt;Arrrrrr!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-3411929164831267033?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/3411929164831267033/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=3411929164831267033' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3411929164831267033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3411929164831267033'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/08/spend-like-pirate-day.html' title='Spend Like a Pirate Day'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6003702903652314483</id><published>2009-08-10T14:03:00.001-07:00</published><updated>2009-08-10T14:23:09.934-07:00</updated><title type='text'>workaround: easy_install windows vanish</title><content type='html'>My employer-mandated Vista machine has gone almost unused for months because of an infuriating quirk in Vista's command-prompt operation.  I've come as close to completely forgetting how to use Windows as I've ever been.  Giles Thomas (of &lt;a href="http://www.resolversystems.com/"&gt;Resolver Systems&lt;/a&gt;) saved me.&lt;br /&gt;&lt;br /&gt;The problem: Vista runs programs like easy_install in a new cmd window, separate from the one they were invoked in.  The instant the program terminates, the new window is closed, and any messages it returned - like error messages - are lost.  No, redirecting the messages with &gt; and 2&gt; does not work.  &lt;span style="font-style:italic;"&gt;"Why would you want to see error messages, anyway?  They're so geeky and depressing!"  *gum snap*&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Thus, I was unable to install cx_Oracle, and had to turn to my trusty Ubuntu machine for absolutely every pyOraGeekish task.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.gilesthomas.com/?p=51"&gt;Giles blogged a lifesaver workaround&lt;/a&gt;.  If you can run the cmd window as Administrator in the first place, you are entrusted with the awesome power and responsibility of being allowed to view your own error messages.&lt;br /&gt;&lt;br /&gt;So, now I can blow the dust off my Vista machine.  Wow, controlling the font size of a cmd window is absolutely as primitive as it was in Windows 3.1.  Giles, got a workaround for this, too?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6003702903652314483?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6003702903652314483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6003702903652314483' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6003702903652314483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6003702903652314483'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/08/workaround-easyinstall-windows-vanish.html' title='workaround: easy_install windows vanish'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-7554462012284871977</id><published>2009-08-04T15:06:00.000-07:00</published><updated>2009-08-04T15:13:31.365-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Oracle at Ohio LinuxFest</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.ohiolinux.org/"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 600px; height: 143px;" src="http://www.ohiolinux.org/files/images/iamgoing.png" border="0" alt="I'm going to Ohio LinuxFest 2009" /&gt;&lt;/a&gt;&lt;br /&gt;It's not official yet - so you can't find it at the &lt;a href="http://ohiolinux.org/"&gt;Ohio LinuxFest website&lt;/a&gt; - but it looks like Oracle will be a sponsor and exhibitor this year.  They're planning to do an Oracle-on-Linux installfest.  If you'd like to get your first taste of Oracle on Linux, sign up for LinuxFest (it's free) and prepare to have a blast.&lt;br /&gt;&lt;br /&gt;If you're already pretty good at Oracle-on-Linux and would like to help others get started, &lt;a href="mailto:sam18xgy4fz@liquidid.net"&gt;send me email&lt;/a&gt;!  I hope to gather a small group of volunteers to help out at the installfest.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-7554462012284871977?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/7554462012284871977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=7554462012284871977' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7554462012284871977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7554462012284871977'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/08/oracle-at-ohio-linuxfest.html' title='Oracle at Ohio LinuxFest'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-3711736633417106400</id><published>2009-08-04T07:41:00.000-07:00</published><updated>2009-08-04T07:55:46.709-07:00</updated><title type='text'>bug reports from the public</title><content type='html'>From &lt;a href="http://en.wikipedia.org/wiki/Smith_&amp;_Dale#Early_life_and_work"&gt;"Dr. Kronkheit and His Only Living Patient"&lt;/a&gt;:&lt;blockquote&gt;SMITH: Doctor, it hurts when I do this.&lt;br /&gt;DALE: Don't do that.&lt;/blockquote&gt;Dear &lt;a href="http://www.enterprise.com/" rel="nofollow"&gt;Enterprise Rent-A-Car&lt;/a&gt;,&lt;br /&gt;&lt;br /&gt;That was called a "bug report".  It was not actually a request for a condescending message about how I can still rent a car by navigating the website in a different way.  I knew that.  &lt;br /&gt;&lt;br /&gt;I took the time to write up detailed instructions for reproducing the bug as a professional courtesy to your developers.  Unfortunately, they will never see my message, since your customer service is managed strictly from a "deal with nuisance customers" point of view.  Looks like I wasted a couple seconds of your time as well as several minutes of my own.&lt;br /&gt;&lt;br /&gt;RESOLVED: If I ever work on a project large enough to have a customer service department separate from development, I will insist upon bridging this gap.  I will make sure customer service has the access, knowledge, and encouragement to communicate constantly with me.  I will regard customer service as a valuable conduit for end-user feedback rather than a distant, uninteresting group of non-colleagues.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-3711736633417106400?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/3711736633417106400/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=3711736633417106400' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3711736633417106400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3711736633417106400'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/08/bug-reports-from-public.html' title='bug reports from the public'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6803550807107306175</id><published>2009-08-04T04:35:00.000-07:00</published><updated>2009-08-04T13:23:42.072-07:00</updated><title type='text'>logging is ugly</title><content type='html'>Instrumenting your code - whether with a PL/SQL package like &lt;a href="http://www.toadworld.com/Experts/StevenFeuersteinsPLSQLObsession/MyPetProjectsandContributions/QuestErrorManagerQEM/tabid/210/Default.aspx"&gt;Quest Error Manager&lt;/a&gt; as Steven Feuerstein suggests, &lt;a href="http://docs.python.org/library/logging.html#module-logging"&gt;Python's logging module&lt;/a&gt;, or whatever - is an important part of writing good code.&lt;br /&gt;&lt;br /&gt;I don't.  Not very often, anyway.  When I do, I often delete the logging calls as soon as the code is more or less working.  The biggest reason is the ugliness.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;def days_ago (ndays):&lt;br /&gt;    logging.info('days_ago called with arg %s' % str(ndays))&lt;br /&gt;    logging.info('arg type %s' % type(ndays))&lt;br /&gt;    try:&lt;br /&gt;        ndays = int(ndays)&lt;br /&gt;        logging.info('argument converted to integer %d' % ndays)&lt;br /&gt;        current_date = datetime.datetime.now()&lt;br /&gt;        logging.info('current date is %s' % str(current_date))&lt;br /&gt;        result = current_date - datetime.timedelta(ndays)&lt;br /&gt;    except ValueError, e:&lt;br /&gt;        logging.error('Error converting ndays to integer:')&lt;br /&gt;        logging.error(str(e))&lt;br /&gt;        result = None&lt;br /&gt;    logging.info('returning from days_ago: %s' % str(result))&lt;br /&gt;    return result&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;EWWWWWW!  That is &lt;span style="font-weight:bold;"&gt;ugly&lt;/span&gt;!  It completely disrupts the comfortable reading of the code.  It buries the actual purpose and actions of the function under a steaming heap of chatter.  It offends everything that I value in beauty and readability.  What to do?&lt;br /&gt;&lt;br /&gt;One solution might be a code editor that would toggle the visibility of all logging calls in a program.  You could leave them invisible most of the time, and only look at the logging statements when you have a specific reason to.  I can see two problems with that, though.&lt;ul&gt;&lt;li&gt;The logging calls themselves could get out of synch with the functioning code.  This could be partially addressed by having logging calls become visible automatically whenever code adjacent to them is changed.&lt;/li&gt;&lt;li&gt;This would create code which is readable and beautiful in my editor, but ugly when somebody else tries to read it.  Perhaps if we cooked up a convention whereby a header comment could define the suggested hiding of logging calls for each program, and most editors could be trained to recognize and respect these suggestions?&lt;/li&gt;&lt;/ul&gt;I don't have the answer for this.  I'd love to hear ideas.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;EDIT&lt;/span&gt;: &lt;a href="http://blog.extracheese.org/"&gt;Gary Bernhardt&lt;/a&gt; tweets, "Anything that you want your editor to to be able to hide (comments, setters/getters, logging) shouldn't exist".  &lt;br /&gt;&lt;br /&gt;An interesting idea... how to eliminate logging?  A good logging decorator could log arguments, return values, and error messages to any decorated function - and that level of information could suffice, if the functions are very fine-grained.  Having to write fine-grained functions is the sort of constraint that might improve programming style, too, much the way unit testing demands well-defined functions.  I think I'll try this philosophy and see if I can make it work. &lt;br /&gt;&lt;br /&gt;It's not much help for the PL/SQL side of things, though.  I'm trying to imagine if there's some way to make an analog to Python's decorators in PL/SQL.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6803550807107306175?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6803550807107306175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6803550807107306175' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6803550807107306175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6803550807107306175'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/08/logging-is-ugly.html' title='logging is ugly'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-2204117308578388873</id><published>2009-07-28T11:58:00.000-07:00</published><updated>2009-07-28T12:05:09.933-07:00</updated><title type='text'>Database comics</title><content type='html'>Clearly, it's somebody's responsibility to create a Hall of Fame for database-related comic strips.  I may as well start gethering them here.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://imgs.xkcd.com/comics/exploits_of_a_mom.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; " src="http://imgs.xkcd.com/comics/exploits_of_a_mom.png" border="0" alt="xkcd comic: Exploits of a Mom" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://browsertoolkit.com/fault-tolerance.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; " src="http://browsertoolkit.com/fault-tolerance.png" border="0" alt="Fault-tolerance comic on key-value stores" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;What else is out there?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-2204117308578388873?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/2204117308578388873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=2204117308578388873' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/2204117308578388873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/2204117308578388873'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/07/database-comics.html' title='Database comics'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-8557784824493373533</id><published>2009-07-26T19:14:00.000-07:00</published><updated>2009-08-10T03:02:46.881-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pyohio'/><category scheme='http://www.blogger.com/atom/ns#' term='pyohio python conference ohio'/><title type='text'>now that's agile</title><content type='html'>My favorite anecdote from PyOhio 2009:&lt;br /&gt;&lt;a href="http://www.linkedin.com/in/williammcvey"&gt;&lt;br /&gt;William McVey&lt;/a&gt; prepared slides for his Sunday PyOhio presentation using reStructuredText and rst2s5, but he wasn't satisfied with S5's presentation quality.  He tried rst2odp to generate an OpenOffice Impress document instead, but it failed him.&lt;br /&gt;&lt;br /&gt;So he convened a Saturday night sprint on rst2odp at PyOhio.  Working past midnight, a small team fixed the rst2odp flaws.  William regenerated his slides and presented successfully on Sunday.&lt;br /&gt;&lt;br /&gt;Finally, in a mighty feat of recursion, he described the feat in a lightning talk Sunday evening, using slides generated by rst2odp, including a slide that contained the source code of the lightning talk he was giving, including the slide with the source code...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-8557784824493373533?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/8557784824493373533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=8557784824493373533' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8557784824493373533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8557784824493373533'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/07/now-thats-agile.html' title='now that&apos;s agile'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-544942399630086473</id><published>2009-07-26T07:19:00.000-07:00</published><updated>2009-07-26T07:23:32.345-07:00</updated><title type='text'>Oracle - Linux - Python tutorial slides (PyOhio)</title><content type='html'>Todd Trichler from OTN is beginning his half of our presentation while I post... my half's materials are &lt;a href="http://catherinedevlin.pythoneers.com/pyora_tutorial.tar.gz"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-544942399630086473?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/544942399630086473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=544942399630086473' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/544942399630086473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/544942399630086473'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/07/oracle-linux-python-tutorial-slides.html' title='Oracle - Linux - Python tutorial slides (PyOhio)'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-7316972539313500681</id><published>2009-07-23T14:27:00.000-07:00</published><updated>2009-08-10T06:47:00.005-07:00</updated><title type='text'>doubleplus PyOhio</title><content type='html'>&lt;code&gt;&lt;br /&gt;&gt;&gt;&gt; 2009 &gt; (2 * 2008)&lt;br /&gt;True&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;PyOhio 2008 had 93 registrants.  &lt;a href="http://www.pyohio.org/"&gt;PyOhio 2009&lt;/a&gt; has more than doubled that number already.  Hooray!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-7316972539313500681?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/7316972539313500681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=7316972539313500681' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7316972539313500681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/7316972539313500681'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/07/doubleplus-pyohio.html' title='doubleplus PyOhio'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-546436867588040845</id><published>2009-07-02T13:34:00.000-07:00</published><updated>2009-07-02T14:09:28.955-07:00</updated><title type='text'>PyOhio registration, schedule, sponsors...</title><content type='html'>Things are really coming together!&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://pyohio.org"&gt;&lt;img src="http://66.35.48.8/catherine/blogbadge.png" alt="PyOhio" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;PyOhio registration is open.  38 people have signed up in just over a day!&lt;/li&gt;&lt;li&gt;The talk schedule is up.  25 talks, my goodness.&lt;/li&gt;&lt;li&gt;Oracle Technology Network and Intellovations have stepped forward as sponsors.&lt;/li&gt;&lt;li&gt;Oracle is also sending Todd Trichler to cooperate with me on a two-hour tutorial on Oracle/Python/Linux.  I'm enjoying the preparations so far - I think you'll like it if you have any interest in databases.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-546436867588040845?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/546436867588040845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=546436867588040845' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/546436867588040845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/546436867588040845'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/07/pyohio-registration-schedule-sponsors.html' title='PyOhio registration, schedule, sponsors...'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6364275055431209314</id><published>2009-06-24T14:19:00.000-07:00</published><updated>2009-06-25T09:38:06.339-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>don't need no stinking rules engine</title><content type='html'>There's a whole class of programs called &amp;quot;rules engines&amp;quot;.  The idea is to remove the details of a process from the hard-code of the program, store them externally, and view/modify them easily.  The engine then converts the rules, stored in some sort of custom format, back into an executable form at runtime.&lt;br /&gt;&lt;br /&gt;In my experience, Python &lt;em&gt;is&lt;/em&gt; an effective rule engine.  Thanks to Python's readability, you can store business rules as snippets of Python code - in textfiles, a database table, or wherever you prefer - and business users should be able to read them comfortably.  After that, a very lightweight Python program can load the rules and the relevant data and use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;exec()&lt;/span&gt;&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;eval()&lt;/span&gt;&lt;/tt&gt; to apply the rules to it.&lt;br /&gt;&lt;br /&gt;One of my main projects is an example of this.  It's program that synchronizes data between two Oracle databases.  That sounds easy, but business details complicate it enormously:&lt;ul class="simple"&gt;&lt;br /&gt;&lt;li&gt;Table and column naming, structure, and normalization differ&lt;/li&gt;&lt;li&gt;Only some rows are transferred, according to a complex set of business rules&lt;/li&gt;&lt;li&gt;Only some columns are transferred.  Column values are combined, split, truncated, have functions applied, etc.  Again, governed by a jungle of business rules&lt;/li&gt;&lt;li&gt;The business rules change continually&lt;/li&lt;li&gt;Rules must be documented.  Letting documentation get out of synch with implemented rules is very bad.&lt;/li&gt;&lt;li&gt;Users may demand explanations for each decision made by the program, down to the row and column level&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;My first take on the problem was a large hard-coded PL/SQL procedure.  What a nightmare!&lt;br /&gt;&lt;br /&gt;Later, I rewrote the rules as snippets of Python.  Each rule is stored a database table along with the dates it takes effect and expires, the person authorizing the rule, and a justification.  This readable, self-documenting set of rules can also answer questions like, &amp;quot;Why did things change since last month?&amp;quot;.&lt;br /&gt;&lt;br /&gt;Unfortunately, I didn't know much about object-relational mappers when I wrote it, so the program has clunky data-fetching code.  I'm currently working on a third version of the program that uses SQLAlchemy; the resulting program is &lt;em&gt;very&lt;/em&gt; short.  Broadly, here's what it does:&lt;br /&gt;&lt;br /&gt;- Queries the row-level and column-level rules from their respective tables&lt;br /&gt;&lt;br /&gt;- Fetches a row from the local database (&lt;cite&gt;ours&lt;/cite&gt;) and the corresponding row from the remote database (&lt;cite&gt;theirs&lt;/cite&gt;)&lt;br /&gt;&lt;br /&gt;- The heart of the engine:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;data = {'ours': ours, 'theirs': theirs}&lt;br /&gt;for row_rule in row_rules:&lt;br /&gt;    if not eval(row_rule, data):&lt;br /&gt;        return&lt;br /&gt;for column_rule in column_rules:&lt;br /&gt;    exec(column_rule, data)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Actually, the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;data&lt;/span&gt;&lt;/tt&gt; dict also includes definitions of a few functions that some of the rules invoke.  The function names are chosen to be self-explanatory to business users.  For example:&lt;br /&gt;&lt;pre class="literal-block"&gt;&lt;br /&gt;def fiscalYear(inDate):&lt;br /&gt;    if inDate.month &amp;gt; 9:&lt;br /&gt;        result = inDate.year + 1&lt;br /&gt;    else:&lt;br /&gt;        result = inDate.year&lt;br /&gt;    return result&lt;br /&gt;&lt;br /&gt;data = {'ours': ours, 'theirs': theirs, 'fiscalYear': fiscalYear}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I suppose it wouldn't be too hard to put the function definitions themselves in among the rules, then include &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;locals()&lt;/span&gt;&lt;/tt&gt; in with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;data&lt;/span&gt;&lt;/tt&gt;, as long as execution order is controlled (easily done by putting execution_order columns in the rules tables).  It hasn't been necessary for my project.&lt;br /&gt;&lt;br /&gt;- Now &lt;var&gt;row_rules&lt;/var&gt; has &lt;var&gt;eval()&lt;/var&gt;-able entries like::&lt;pre&gt;&lt;br /&gt;  id  start   end     code                      authorized   reason&lt;br /&gt;   1  1/1/06  7/1/09  ours.funded == "Y"        Bob          I said so&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and &lt;var&gt;column_rules&lt;/var&gt; has &lt;var&gt;exec()&lt;/var&gt;-able entries like::&lt;pre&gt;&lt;br /&gt;  id  start   end     code                           authorized   reason&lt;br /&gt;   1  2/2/08          if (ours.value &gt; 1000):        Steve        to annoy Bob&lt;br /&gt;                          theirs.value = ours.value&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;- Add some logging and a &amp;quot;test-run&amp;quot; capacity which reports on the changes without actually performing them.  (It uses &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;sqlalchemy.orm.attributes.get_history()&lt;/span&gt;&lt;/tt&gt; for this; make sure to set &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;autoflush=False&lt;/span&gt;&lt;/tt&gt; if you use this, or intermediate flushes might clear the history.)&lt;br /&gt;&lt;br /&gt;I suppose I could try writing a sample rules-engine implementation in simple, general terms, that people could crib from for their own &amp;quot;rules engine&amp;quot; applications.  I wonder if that would be helpful, or if just the general idea is enough guidance.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6364275055431209314?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6364275055431209314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6364275055431209314' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6364275055431209314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6364275055431209314'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/06/dont-need-no-stinking-rules-engine.html' title='don&apos;t need no stinking rules engine'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-553035376723864323</id><published>2009-06-19T06:35:00.000-07:00</published><updated>2009-06-19T07:08:57.637-07:00</updated><title type='text'>Python for Secretaries</title><content type='html'>As if I need a new ambition, I've got an itch to create and teach a course called "Computer Programming for Secretaries".  Since I got into IT via the secretarial pool, I think I'm the perfect one to do it.&lt;br /&gt;&lt;br /&gt;To outsiders, programming has this horribly intimidating aura.  You've got enterprisey Software Architects trying to sound professional, academic Computer Scientists telling you that you're oversimplifying the problem, fearsome Hacker Gods strutting their skillz.  Lots of people want to make sure you know how smart they are, and that nothing could happen without their planet-sized brains.&lt;br /&gt;&lt;br /&gt;but &lt;span style="font-weight:bold;"&gt;programming is not rocket science&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you want to launch satellites into space, you need to invest your life in the field and be part of a large, well-funded institution.  Yes, you can have lots of fun with model rocketry, but you're just playing.  You're not actually going to get anything into orbit.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;programming is more like cooking&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;My friend James is a professional chef.  Everything he makes involves a bunch of French words, ingredients I've never heard of, and turns out eyes-roll-back delicious.  I don't have the ambition to invest the time and effort to cook that well... &lt;span style="font-style:italic;"&gt;but I can still roast a turkey&lt;/span&gt;.  That's what programming is like, especially dynamic language programming.  With a lot of skill, you can work miracles - but with a little skill, you can work little miracles.  You don't need to go in for the whole hog.&lt;br /&gt;&lt;br /&gt;That's what I'd like a class to address.  There are programming books aimed at kids, but none that I know of aimed at adult business users.  There are people who could write themselves small, useful programs, but who will flee in well-justified terror if you start talking about overriding import hooks.  There are people spending hours cutting-and-pasting from one file to another because they don't know how to write a six-line script.  There are people could replace some of their daily tedium with just a little dose of Python.  There is Resolver One, which is a fantastic way to integrate tiny dashes of Python with everyday spreadsheet work, but it's being used by thousands instead of by millions.&lt;br /&gt;&lt;br /&gt;So... yeah.  What should such a class include?  More importantly, once I'm ready to teach such a class, where do I teach it?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-553035376723864323?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/553035376723864323/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=553035376723864323' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/553035376723864323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/553035376723864323'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/06/python-for-secretaries.html' title='Python for Secretaries'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-1207650926204333252</id><published>2009-06-15T07:56:00.000-07:00</published><updated>2009-06-15T08:12:11.114-07:00</updated><title type='text'>how to tell a geek</title><content type='html'>Given a choice between spending an hour doing a task manually, or spending three hours writing a program to do it automatically... a geek will write the program, &lt;span style="font-style:italic;"&gt;every single time&lt;/span&gt;.  And, if not given the choice, if explicitly ordered to do the job manually, we'll disobey and write the program anyway.  I've heard it said that a good geek is lazy, but I think it's more precise to say that a geek dreads &lt;span style="font-style:italic;"&gt;boredom&lt;/span&gt; above all else.  We'll move mountains to accomplish a task, as long as it's interesting.&lt;br /&gt;&lt;br /&gt;This is not nearly as crazy as it sounds, because after we've "finished" a task, without fail, the requestor will return and say, "I know I said that would just be a one-time change, but...", or, "Actually, it turns out we don't need A B C D, we need A B Q D C", or whatever.  You &lt;span style="font-style:italic;"&gt;will&lt;/span&gt; reuse that program, no matter what they say; never throw it away!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-1207650926204333252?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/1207650926204333252/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=1207650926204333252' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1207650926204333252'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1207650926204333252'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/06/how-to-tell-geek.html' title='how to tell a geek'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-4487005247595426371</id><published>2009-06-09T13:31:00.000-07:00</published><updated>2009-06-09T14:02:44.106-07:00</updated><title type='text'>NCR</title><content type='html'>Pardon, oh Citizens of the World who read this, while I go regional for a moment and speak as a Dayton-area resident on news almost certainly irrelevant to you.&lt;br /&gt;&lt;br /&gt;The big news here last week was NCR's decision to leave Dayton.  Basically, three reasons have been given:&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.daytondailynews.com/business/ncrs-blunt-words-add-urgency-to-concerns-151458.html"&gt;"the high availability of a skilled work force"&lt;/a&gt;&lt;/li&gt;&lt;li&gt;More direct international flights from Atlanta than from Dayton&lt;/li&gt;&lt;li&gt;$60 to $80 million in incentives from Georgia&lt;/li&gt;&lt;/ul&gt;The funny thing about the first reason is... &lt;span style="font-style:italic;"&gt;NCR doesn't hire people&lt;/span&gt;.  (Their manufacturing plants may hire, but I'm speaking of their HQ here in Dayton).  Since I came to the Dayton area, I've had IT friends in NCR and have tried to keep up with them.  The news from them has always been the same: "We just went through another round of downsizing.  We keep wondering when our turn will come."  For a company in continual contraction, the benefit of a larger pool of people to not hire seems... um, not clear.&lt;br /&gt;&lt;br /&gt;That leaves shorter plane flights for those who fly to Europe - seems a strange reason to move 1,300 people - and a large amount of cash.  Many people think Ohio should have tried to outbid Georgia, but that would have to come at the expense of companies that &lt;span style="font-style:italic;"&gt;don't&lt;/span&gt; threaten relocation - and it begins to blur the line between "private company" and "state-funded entity", anyway.&lt;br /&gt;&lt;br /&gt;Moving itself, of course, gets rid of those employees who choose not to relocate.  I predict that most Ohioans who choose not to move with NCR will not be replaced; the company will use the natural contraction in place of one of its periodic downsizings.&lt;br /&gt;&lt;br /&gt;Anyway, it's sad for Dayton, since the company had such a history here, but that's pretty much what NCR has been about here for years - history.  For decades now, growth for Dayton - as for most cities - hasn't come from big, stable, traditional companies but from small companies, appearing and disappearing quickly as new opportunities appear and change and dry up.  It's a less predictable business world, but that's the century we're in.  No amount of sighing will prolong the 20th century&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-4487005247595426371?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/4487005247595426371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=4487005247595426371' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4487005247595426371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/4487005247595426371'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/06/ncr.html' title='NCR'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-1545135082055083391</id><published>2009-06-05T09:51:00.001-07:00</published><updated>2009-06-05T11:35:52.849-07:00</updated><title type='text'>Python Magazine article</title><content type='html'>I've got an article in &lt;a href="http://pymag.phparch.com/c/issue/view/98"&gt;this month's Python Magazine&lt;/a&gt;: &lt;span style="font-style:italic;"&gt;PyOhio: Planning and Running a Regional Python Miniconference&lt;/span&gt;.  I try to cover some of the stuff we learned in the course of doing the first &lt;a href="http://pyohio.org"&gt;PyOhio&lt;/a&gt;, for the benefit of people considering staging similar conferences of their own.  I feel a little silly impersonating an expert on the topic, since I'm near the beginning of a learning process that never ends - but in the open-source world, it's not being the ultimate guru that's important, it's taking the time to share whatever you can.&lt;br /&gt;&lt;br /&gt;Python Magazine is a great publication, by the way - with all the good stuff about Python on the net, you might wonder what's the point of buying a magazine, but their articles are very well-chosen and there's a real advantage to being able to read it away from the computer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-1545135082055083391?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/1545135082055083391/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=1545135082055083391' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1545135082055083391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/1545135082055083391'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/06/python-magazine-article.html' title='Python Magazine article'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-3458630092525170051</id><published>2009-05-29T07:14:00.001-07:00</published><updated>2009-05-29T07:57:43.971-07:00</updated><title type='text'>Where did you hear about... ?</title><content type='html'>I've served as &lt;a href="http://us.pycon.org"&gt;PyCon&lt;/a&gt;'s volunteer publicity chair the past two years.  This year, at my request, the attendee survey had the question, "How did you hear about PyCon?"&lt;br /&gt;&lt;br /&gt;Thanks to everybody who took the survey and answered that annoying question.  Of course, most answers were along the lines of, "Duh, I've always known about PyCon!"  &lt;br /&gt;&lt;br /&gt;Basically, the answers helped to confirm that community buzz is what brings most people.  (My favorite answer: "Birds.")  Problem: not everybody is plugged into the buzz.  I know lots of programmers who never read blogs or attend groups, and there are lots more that I don't know &lt;span style="font-style:italic;"&gt;because&lt;/span&gt; they don't do blogs or groups, or otherwise plug themselves into the community.  &lt;br /&gt;&lt;br /&gt;What I most need is for everybody who &lt;span style="font-style:italic;"&gt;didn't&lt;/span&gt; hear about PyCon to answer this question: "Why didn't you hear about PyCon?  Where would you have seen a PyCon announcement?"  The logistics of doing that survey are tricky, however.&lt;br /&gt;&lt;br /&gt;How do you think word spreads among geeks, in this day and age?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-3458630092525170051?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/3458630092525170051/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=3458630092525170051' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3458630092525170051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/3458630092525170051'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/05/where-did-you-hear-about.html' title='Where did you hear about... ?'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6245574592003375901</id><published>2009-05-22T05:55:00.000-07:00</published><updated>2009-05-22T06:02:51.616-07:00</updated><title type='text'>Wanted: pictoral Field Guide to Nerds</title><content type='html'>My grandfather was an amazing man.  He seemed to know every living soul in Duluth, Minnesota.  He never forgot a face.&lt;br /&gt;&lt;br /&gt;I didn't inherit that gene.  Remembering faces and names is a huge challenge for me.  &lt;span style="font-style:italic;"&gt;"Very nice to meet you, Mrs. - wait, have we met before?  Oh, Mom!  I'm sorry."&lt;/span&gt;  I can spend fifteen minutes in conversation with someone, and five minutes later be unable to bring their face into my mind.  It's frustrating and humiliating.  I need technological help.&lt;br /&gt;&lt;br /&gt;I'd love a website full of labelled and indexed photos of the inhabitants of geekland, something I could brush up on before a conference, or study afterward to cement the new acquaintances into my memory.&lt;br /&gt;&lt;br /&gt;Does something like this exist?  Failing that, does anybody have some good ideas for how it could be made?  At present, my best idea is for some sort of Flickr mashup.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6245574592003375901?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6245574592003375901/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6245574592003375901' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6245574592003375901'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6245574592003375901'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/05/wanted-pictoral-field-guide-to-nerds.html' title='Wanted: pictoral Field Guide to Nerds'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6545325202002935959</id><published>2009-05-15T07:52:00.000-07:00</published><updated>2009-05-15T09:27:41.241-07:00</updated><title type='text'>documentation rant</title><content type='html'>Everybody knows that open-source software documentation sucks.  &lt;br /&gt;&lt;br /&gt;It doesn't, however, suck nearly as much as big-company proprietary software documentation, which &lt;a href="http://holdenweb.blogspot.com/2009/05/help-files-should-help-right.html"&gt;Steve Holden characterizes as&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;    Threep Nardling&lt;br /&gt;    To nardle threeps, select the Threep tab and check the Nardling checkbox.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;... and so forth... a beautifully-typeset waste of electrons.&lt;br /&gt;&lt;br /&gt;The questions we go to docs for are: &lt;span style="font-style:italic;"&gt;Can I nardle a threep via SSH?  I tried it, but my threep still isn't nardled.  I got an "ERROR: Threep nardling failure" message.  What now? &lt;/span&gt;  If those questions aren't addressed, there's really no point.&lt;br /&gt;&lt;br /&gt;These days, I do sometimes see open-source docs that address these questions.  Most often, of course, you find answers to these questions in the user community.&lt;br /&gt;&lt;br /&gt;Anyway, I suggest that, when users run into trouble, this is the preferable order of responses:&lt;br /&gt;&lt;br /&gt;1. Change the program so that it acts as the users expected in the first place.&lt;br /&gt;2. Use program interaction and informative error messages to guide users through problems without having to look outside the program.&lt;br /&gt;3. Put the answer in the documentation - and &lt;span style="font-style:italic;"&gt;make it easy to find&lt;/span&gt; or it doesn't count!  Expecting users to comb painstakingly through 400 pages is not realistic.&lt;br /&gt;4. Respond to individual questions via some sort of support process.&lt;br /&gt;&lt;br /&gt;Small-to-medium FOSS projects are the best at responding in this order, probably because the same people - or at least people who know each other - are responsible for writing the program, documenting it, and answering user questions.  At Big Software Corp., on the other hand, Support, Documentation, and Development are likely to be completely separate groups.  The professionalization of documentation is deadly, because you get reams of nearly identical manuals that are pleasantly laid-out and nicely proofread, but completely unaware of realistic user problems.  Support is painfully aware of user problems, but they have no process to tell Documentation and Development, "Hey, users keep getting confused here.  Can we change the program and the docs to help them?  Please?  Because we'd really like to quit getting these questions?"  (Perhaps some companies do have processes; I can only speculate, but I do know that I don't see evidence of it.)&lt;br /&gt;&lt;br /&gt;Oracle, incidentally, only about halfway sucks in these matters, which is pretty good for a company so large.  Their docs generally have some good, non-obvious substance, and &lt;span style="font-style:italic;"&gt;sometimes&lt;/span&gt; - but, alas, only sometimes - troubleshooting information.&lt;br /&gt;&lt;br /&gt;In short, I think you need users' pain to efficiently and accurately become developers' and documenters' pain, so that the causes will get fixed.  Small FOSS projects have this kind of pain transfer built-in (when the authors publish their email addresses and invite questions).  Everybody else should think about how to make it happen for their product.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6545325202002935959?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6545325202002935959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6545325202002935959' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6545325202002935959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6545325202002935959'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/05/documentation-rant.html' title='documentation rant'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-5504990546703101487</id><published>2009-05-12T12:29:00.000-07:00</published><updated>2009-05-15T13:19:34.991-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sqlpython'/><title type='text'>managing installation requirements by Python version</title><content type='html'>I always feel guilty using this blog as my LazyWeb, but it works really well, so here we go again...&lt;br /&gt;&lt;br /&gt;I'm trying out Oracle Enterprise Linux 5 - basically a clone of RHEL - and trying to get sqlpython installed on it.  OEL5 comes with Python 2.4; sqlpython 1.6.5.1 needs Python 2.5.  I could take out the 2.5 dependency in sqlpython, but it uses pyparsing.  Pyparsing dropped 2.4 compatibility as of 1.5.2.  &lt;br /&gt;&lt;br /&gt;[EDIT: It turns out that pyparsing 1.5.2 still works on Python 2.4.  It emits a scary error message, during easy_install under Python 2.4 - &lt;br /&gt;&lt;blockquote&gt;except ParseException as err:&lt;br /&gt;^&lt;br /&gt;SyntaxError: invalid syntax&lt;/blockquote&gt;&lt;br /&gt;but it &lt;span style="font-style:italic;"&gt;installs successfully nonetheless&lt;/span&gt;.  Thanks to Paul McGuire to pointing that out.  So my job in this case is simply to release a 2.4-compatible sqlpython 1.6.5.2.]&lt;br /&gt;&lt;br /&gt;I could change &lt;code&gt;install_requires=['pyparsing&gt;=1.5.1']&lt;/code&gt; to &lt;code&gt;install_requires=['pyparsing==1.5.1']&lt;/code&gt; in setup.py, but that locks everybody into an obsolete pyparsing whether they need it or not.  &lt;br /&gt;&lt;br /&gt;I'd like to &lt;code&gt;install_requires=(['pyparsing&gt;=1.5.1'] if python.version &gt;= '2.5' else ['pyparsing==1.5.1'])&lt;/code&gt;, but that's absolutely imaginary syntax.&lt;br /&gt;&lt;br /&gt;Obviously, I could just download a newer Python and install it on my machine, but I'm trying to make sqlpython usable for DBAs who don't have that kind of authority, or who fear to muck around with their environment that way.&lt;br /&gt;&lt;br /&gt;I wonder what the smart people do in situations like this?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-5504990546703101487?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/5504990546703101487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=5504990546703101487' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5504990546703101487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5504990546703101487'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/05/managing-installation-requirements-by.html' title='managing installation requirements by Python version'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-211379843740469623</id><published>2009-04-30T11:42:00.001-07:00</published><updated>2009-04-30T11:53:02.846-07:00</updated><title type='text'>SpeakerRate</title><content type='html'>I've created a page at speakerrate.com for myself:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.speakerrate.com/catherinedevlin"&gt;SpeakerRate profile&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;... and populated it with my two upcoming talks.&lt;br /&gt;&lt;br /&gt;If you want to use SpeakerRate to give feedback to a speaker, you don't actually have to wait for them to create their own profile - you can enter it yourself.&lt;br /&gt;&lt;br /&gt;I don't know if SpeakerRate will grow into the ultimate connecting-to-speakers webtool, but it might.  I do know that they support microformats, which is a big plus in my book.&lt;br /&gt;&lt;br /&gt;Hope to see some of you at Penguicon (this weekend) or IOUG Collaborate (next week)!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-211379843740469623?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/211379843740469623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=211379843740469623' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/211379843740469623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/211379843740469623'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/04/speakerrate.html' title='SpeakerRate'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-5445677857033840681</id><published>2009-04-29T10:45:00.000-07:00</published><updated>2009-04-29T11:03:24.247-07:00</updated><title type='text'>right to complaint</title><content type='html'>(prompted by discussion of porn use at GoGaRuCo - see &lt;a href="http://www.sarahmei.com/blog/?p=46"&gt;here&lt;/a&gt;, &lt;a href="http://merbist.com/2009/04/28/on-engendering-strong-reactions/"&gt;here&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Quick thought: It's not that the community needs to ensure offensive content never happens, or that the community needs to find a single standard of what is appropriate.&lt;br /&gt;&lt;br /&gt;The key is the &lt;span style="font-style:italic;"&gt;right to complain safely&lt;/span&gt;.  When complaints are predictably met with accusations of "overreacting", "political correctness", and "intolerance", the resulting message is: &lt;span style="font-style:italic;"&gt;Be like us, be silent, or leave.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you reject the criticism, then try something like, "I think you're wrong, but I accept your right to complain."  Complaint is &lt;span style="font-style:italic;"&gt;feedback&lt;/span&gt;, it's a legitimate part of a community's communication.&lt;br /&gt;&lt;br /&gt;(Let me clarify that I've had mostly really good experiences in the software communities I participate in!)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-5445677857033840681?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/5445677857033840681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=5445677857033840681' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5445677857033840681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5445677857033840681'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/04/right-to-complaint.html' title='right to complaint'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-8184668713663826658</id><published>2009-04-23T07:09:00.001-07:00</published><updated>2009-04-30T11:54:27.944-07:00</updated><title type='text'>the expanding reStructuredTextiverse</title><content type='html'>It seems I'm always coming across new uses for &lt;a href="http://docutils.sourceforge.net/rst.html"&gt;reStructuredText&lt;/a&gt;, the plaintext format that goes everywhere.  (Really, more of a "set of plaintext conventions" than a format as such.)  I'm beginning to imagine a talk reviewing them all for next Fall's Ohio LinuxFest, or maybe a magazine article.  &lt;br /&gt;&lt;br /&gt;The places you can go with reStructuredText - am I missing any?  (I haven't checked these all for viability)&lt;ul&gt;&lt;li&gt;HTML, XML, pseudo-XML, LaTeX, and &lt;a href="http://meyerweb.com/eric/tools/s5/"&gt;S5&lt;/a&gt; (PowerPoint-like presentations), with the conversion utilities in docutils&lt;/li&gt;&lt;li&gt;&lt;a href="http://rst2a.com/"&gt;rst2a - reStructuredText 2 Anything&lt;/a&gt; - docutils conversion utilities, online&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/rst2pdf/"&gt;rst2pdf&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.voidspace.org.uk/python/rest2web/"&gt;rest2web&lt;/a&gt; - webpages with templates, navigation structure, etc.&lt;/li&gt;&lt;li&gt;&lt;a href="http://packages.ubuntu.com/jaunty/rst2man"&gt;rst2man&lt;/a&gt; - Unix man pages&lt;/li&gt;&lt;li&gt;&lt;a href="http://sphinx.pocoo.org/"&gt;Sphinx&lt;/a&gt; - easy, multi-page sites for docs or other static content&lt;/li&gt;&lt;li&gt;&lt;a href="http://epydoc.sourceforge.net/manual-othermarkup.html"&gt;epydoc&lt;/a&gt; - Automated API documentation&lt;/li&gt;&lt;li&gt;&lt;a href="http://furius.ca/nabu/"&gt;nabu&lt;/a&gt; - ReStructured Text to RDBMS&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.rexx.com/~dkuhlman/odtwriter.html"&gt;rst2odt&lt;/a&gt; - Produce files for OpenOffice Writer.&lt;/li&gt;&lt;li&gt;&lt;a href="http://docutils.sourceforge.net/FAQ.html#are-there-any-wikis-that-use-restructuredtext-syntax"&gt;wiki pages&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://docutils.sourceforge.net/FAQ.html#are-there-any-weblog-blog-projects-that-use-restructuredtext-syntax"&gt;Blog clients&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/django-rstify/"&gt;django-rstify&lt;/a&gt; - ReStructuredText in Django templates&lt;li&gt;&lt;a href="http://docutils.sourceforge.net/tools/editors/README.html"&gt;Editor support&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Not everything has been done yet, however.  Here are a couple projects yet undone - so far as I know.  Comment with your own ideas... or take this as a challenge and implement something!&lt;ul&gt;&lt;li&gt;rst2word - this would really be the holy grail, for communicating to the unwashed masses.  (We in the know can use rst2odt and convert within OpenOffice, but rst2word would get &lt;span style="font-style:italic;"&gt;my boss&lt;/span&gt; on board.)&lt;/li&gt;&lt;li&gt;Fuse more templating engines to rst (perhaps not a good idea, violate the readability principle?)&lt;/li&gt;&lt;li&gt;ReST lexer for &lt;a href="http://scintilla.org/"&gt;Scintilla&lt;/a&gt; - &lt;a href="http://wingware.com/pipermail/wingide-users/2005-June/002420.html"&gt;this would allow ReST support in WingIDE, too&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;[EDIT: Thanks &lt;a href="http://www.voidspace.org.uk/"&gt;Michael Foord&lt;/a&gt; for info about rest2web, rst2pdf.]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-8184668713663826658?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/8184668713663826658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=8184668713663826658' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8184668713663826658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8184668713663826658'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/04/expanding-restructured-textiverse.html' title='the expanding reStructuredTextiverse'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-8348867104849364636</id><published>2009-04-21T19:15:00.000-07:00</published><updated>2009-04-21T19:53:51.516-07:00</updated><title type='text'>chocolate</title><content type='html'>We interrupt this blog with a special message from our sponsor.&lt;br /&gt;&lt;br /&gt;My friend James has a new business, &lt;a href="http://www.twobearschocolates.com/"&gt;Two Bears Chocolates&lt;/a&gt;, handmaking organic chocolates.  They are crazy-good... I've never been a food snob, but James's chocolates have spoiled me to the point where even "gourmet" mass-produced chocolates seem waxy and bland by comparison.  They're a diet aid!  I have to eat these chocolates so that I won't be tempted by lesser chocolates!&lt;br /&gt;&lt;br /&gt;Anyway, they're expensive, but worth it, and a good gift (see: Mother's Day)... or a good way to maximize your yummy-per-calorie ratio.&lt;br /&gt;&lt;br /&gt;He's particularly gung-ho to do custom orders.  Go ahead, ask him to make a gooseberry-chocolate truffle in the shape of the state of Michigan.  He'll love you for the challenge.&lt;br /&gt;&lt;br /&gt;So, as James says, "If you love someone, send Two Bears chocolates.  If not, bummer."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-8348867104849364636?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/8348867104849364636/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=8348867104849364636' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8348867104849364636'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8348867104849364636'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/04/chocolate.html' title='chocolate'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-6288765340910381422</id><published>2009-04-20T09:54:00.000-07:00</published><updated>2009-04-20T10:12:09.117-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>calm down</title><content type='html'>Yes, yes.  Oracle is buying Sun, which owns MySQL and Java.  No, this is not the end of MySQL.  You're being silly.&lt;br /&gt;&lt;br /&gt;Oracle is about as open-source friendly as a huge proprietary software company can be, and has been since before it was cool.  Oracle adores Linux, and started pushing it vigorously since about, hm, 2002?  Oracle has been Java-crazy since that time, too.  Oracle's marketing strategy has long been against lock-in - it wants to plug easily into a thriving open-standards economy, not to enclose and lock a walled garden.  It's also been very easygoing about licensing, eager to see casual, non-paying users gaining familiarity with its products, knowing that those are the seeds that later big-money sales will come from.  It doesn't try to catch and squeeze little fish, it feeds them fish food and waits for them to grow into whales.  In short, you over there, slapping MySQL on your Linux box for your brother's home business?  Oracle doesn't want to shut you down.  Oracle loves you, has always loved you, and wants your love and trust for when you get big.&lt;br /&gt;&lt;br /&gt;In fact, if anything, I'm a little disappointed that Oracle's (superb) marketing power, name recognition, and corporate respect will all benefit MySQL and Java... which is all fine and good, except that I'd rather see that gust of wind behind PostgreSQL and Python.  (&lt;a href="http://us.pycon.org/2009/about/"&gt;OTN's PyCon sponsorship&lt;/a&gt; warmed my heart, to be sure, but I wish there was a way to make ORACLE + PYTHON stop-the-presses news all around techland.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-6288765340910381422?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/6288765340910381422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=6288765340910381422' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6288765340910381422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/6288765340910381422'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/04/calm-down.html' title='calm down'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-8980281352564993776</id><published>2009-04-13T08:02:00.000-07:00</published><updated>2009-04-13T18:39:56.972-07:00</updated><title type='text'>#amazonfail</title><content type='html'>If you haven't heard about #amazonfail, &lt;a href="http://www.guardian.co.uk/culture/2009/apr/13/amazon-gay-writers"&gt;this article&lt;/a&gt; will catch you up quickly.&lt;br /&gt;&lt;br /&gt;1. It's a good reminder that giving market dominance to one company in a crucial role in steering our culture is probably unwise.  Let's not have a market where a single company can relegate books to obscurity, intentionally or not.  Patronize a variety of booksellers.&lt;br /&gt;&lt;br /&gt;2. A proper apology would look something like, "Mr. Doofus Middle Manager didn't think through what he was doing, and company management failed to supervise it properly.  We feel humiliated and commit to new efforts to keep book culture diverse and uncensored."  Amazon's lame, mealy-mouthed "glitch" non-apology suggests that it has fallen prey to Big Corporatosis.  Unless, of course, Amazon really has discovered a &lt;span style="font-style:italic;"&gt;homophobic&lt;/span&gt; computer glitch, in which case this is &lt;span style="font-style:italic;"&gt;huge&lt;/span&gt; news for artificial intelligence researchers.&lt;br /&gt;&lt;br /&gt;3. This is not the only case where the label "adult content" has had a strangling effect.  Actions taken under the justification of "adult content" should never be blandly accepted, but should be carefully examined for accuracy, necessity, and bias.&lt;br /&gt;&lt;br /&gt;[ EDIT: A final complaint: Labelling a bad policy, sloppily implemented and poorly supervised, as a "glitch", is blaming the company's &lt;span style="font-style:italic;"&gt;technologists&lt;/span&gt; for a mistake of its &lt;span style="font-style:italic;"&gt;management&lt;/span&gt;.  It says that Amazon's management does not trust, understand, or respect its technologists.  In a &lt;span style="font-style:italic;"&gt;technology&lt;/span&gt; company, this is a strong signal of decline.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-8980281352564993776?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/8980281352564993776/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=8980281352564993776' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8980281352564993776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/8980281352564993776'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/04/amazonfail.html' title='#amazonfail'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-5956263561012232645</id><published>2009-04-10T10:20:00.001-07:00</published><updated>2009-04-10T10:37:05.296-07:00</updated><title type='text'>Penguicon 7.0</title><content type='html'>&lt;a href="http://penguicon.org/"&gt;&lt;img src="http://penguicon.org/images/banner2.jpg" width="450"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you're anywhere near Michigan, you need to consider Penguicon.  It's an open-source software conference!  It's a science-fiction con!  It's two great tastes that really do taste great together.  There's always a great deal of excellent technical content, and the SF people lend a really healthy sense of relaxation and creativity to the whole thing.  Where else can you learn CSS and belly dancing in one weekend?&lt;br /&gt;&lt;br /&gt;I'm giving a talk at Penguicon this year: "sqlpython: SQL is fun again".  It's sort of a preview of my upcoming &lt;a href="http://catherinedevlin.blogspot.com/2008/12/speaking-at-ioug.html"&gt;SQL*Plus Alternatives talk&lt;/a&gt; at &lt;a href="http://www.ioug.org/collaborate09/"&gt;IOUG Collaborate&lt;/a&gt;... but without the stuff about Oracle-only tools, and with more focus on sqlpython's rapidly developing cross-RDBMS powers, and a healthy plug to pull more people into the project.&lt;br /&gt;&lt;br /&gt;In fact, I'm leaving directly from Penguicon to Collaborate.  Yikes!  It'll be a fun week.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-5956263561012232645?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/5956263561012232645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=5956263561012232645' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5956263561012232645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/5956263561012232645'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/04/penguicon-70.html' title='Penguicon 7.0'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-2311140553865414689</id><published>2009-04-09T14:25:00.001-07:00</published><updated>2009-04-09T14:25:15.271-07:00</updated><title type='text'>PyOhio: Call for Proposals</title><content type='html'>The &lt;a href="http://wiki.python.org/moin/PyOhio/CallForProposals"&gt;PyOhio Call for Proposals&lt;/a&gt; has been issued!&lt;br /&gt;&lt;center&gt;&lt;a href="http://pyohio.org"&gt;&lt;img src="http://66.35.48.8/catherine/blogbadge.png" alt="PyOhio" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;  &lt;a href="http://pyohio.org "&gt;PyOhio 2009&lt;/a&gt; takes place &lt;a href="http://www.google.com/calendar/event?action=TEMPLATE&amp;amp;tmeid=YTkwbjJlcjRjNGFsNzhvMmhxN2VxajVxZW8gY2F0aGVyaW5lLmRldmxpbkBt&amp;amp;tmsrc=Y2F0aGVyaW5lLmRldmxpbkBnbWFpbC5jb20"&gt;July 25-26, 2009&lt;/a&gt; at the Ohio State University &lt;a href="http://maps.google.com/maps?f=q&amp;source=s_q&amp;hl=en&amp;geocode=&amp;q=275+W+Woodruff+Ave,+Columbus,+OH&amp;sll=40.013515,-83.014455&amp;sspn=0.022811,0.04755&amp;ie=UTF8&amp;ll=40.002372,-83.012695&amp;spn=5.839762,12.172852&amp;z=7&amp;iwloc=A"&gt;in Columbus, Ohio&lt;/a&gt;.  Much like a mini-PyCon, it includes scheduled talks, tutorials, Lightning Talks, Open Spaces, and room for your own unique ideas.  If you can make it to Ohio this summer, please consider participating.&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;a target="_blank" href="http://www.google.com/calendar/event?action=TEMPLATE&amp;amp;tmeid=YTkwbjJlcjRjNGFsNzhvMmhxN2VxajVxZW8gY2F0aGVyaW5lLmRldmxpbkBt&amp;amp;tmsrc=Y2F0aGVyaW5lLmRldmxpbkBnbWFpbC5jb20"&gt;&lt;img border=0 src="http://www.google.com/calendar/images/ext/gc_button1_en.gif"&gt;&lt;/a&gt;&lt;br /&gt;&lt;/center&gt;&lt;br /&gt;PyOhio 2009, the second annual Python programming mini-conference for Ohio and surrounding areas, will take place Saturday-Sunday, July 25-26, 2009 at the Ohio State University in Columbus, Ohio. A variety of activities are planned, including tutorials, scheduled talks, Lightning Talks, and Open Spaces.&lt;br /&gt;&lt;br /&gt;PyOhio invites all interested people to submit proposals for scheduled talks and tutorials. PyOhio will accept abstracts on any topics of interest to Python programmers.&lt;br /&gt;&lt;br /&gt;Standard presentations are expected to last 40 minutes with a 10 minute question-and-answer period. Other talk formats will also be considered, however; please indicate your preferred format in your proposal. Hands-on tutorial sessions are also welcomed. Tutorial instructors should indicate the expected length&lt;br /&gt;&lt;br /&gt;PyOhio is especially interested in hosting a Beginners' Track for those new to Python or new to programming in general. If your proposal would be suitable for inclusion in the Beginners' Track, please indicate so. Organizers will work with speakers and instructors in the Beginners' Track to help them coordinate their talks/tutorials into a smooth, coherent learning curve for new Python users.&lt;br /&gt;&lt;br /&gt;All proposals should include abstracts no longer than 500 words in length. Abstracts must include the title, summary of the presentation, the expertise level targeted, and a brief description of the area of Python programming it relates to.&lt;br /&gt;&lt;br /&gt;All proposals should be emailed to cfp@pyohio.org for review. Please submit proposals by May 15, 2009. Accepted speakers will be notified by June 1.&lt;br /&gt;&lt;br /&gt;You can read more about the conference at http://pyohio.org&lt;br /&gt;&lt;br /&gt;If you have questions about proposals, please email cfp@pyohio.org. You can also contact the PyOhio organizers at pyohio-organizers@python.org.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-2311140553865414689?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/2311140553865414689/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=2311140553865414689' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/2311140553865414689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/2311140553865414689'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/04/pyohio-call-for-proposals.html' title='PyOhio: Call for Proposals'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11802292.post-290863720331935201</id><published>2009-04-06T14:58:00.000-07:00</published><updated>2009-04-06T15:49:23.021-07:00</updated><title type='text'>geekspeakr.com</title><content type='html'>&lt;a href="http://www.geekspeakr.com/"&gt;geekspeakr.com: connecting tech women speakers with event organizers&lt;/a&gt;&lt;blockquote&gt;Many organisers of technical conferences, meetups, and dinners want to have more gender-balance in their lineups, but they don't know where to find technical women speakers.&lt;br /&gt;&lt;br /&gt;Enter geekspeakr.com, a simple directory and connections system to help technical women speakers and event organisers to find each other.&lt;/blockquote&gt;I'm really glad to see this.  I'm even more glad to see, browsing through speakers, that they really are &lt;span style="font-style:italic;"&gt;technical&lt;/span&gt; women.  I've... um, there's no good way to say this... seen other "tech women" groups that quickly became dominated by women networking for their multilevel marketing careers.  It's pretty understandable, since they have a much more obvious need to network than us geeks - but, you know, it's really not the purpose.&lt;br /&gt;&lt;br /&gt;Anyway.  geekspeakr's are the real deal.  w00t!  Need more Python and Oracle speakers there, though.&lt;br /&gt;&lt;br /&gt;Note to self: just as soon as the &lt;a href="http://www.pyohio.org/"&gt;PyOhio&lt;/a&gt; CFP is out (very soon), &lt;span style="font-style:italic;"&gt;do not neglect&lt;/span&gt; to spam Pythonistas on geekspeakr!  At least, the ones vaguely near Ohio.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11802292-290863720331935201?l=catherinedevlin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://catherinedevlin.blogspot.com/feeds/290863720331935201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11802292&amp;postID=290863720331935201' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/290863720331935201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11802292/posts/default/290863720331935201'/><link rel='alternate' type='text/html' href='http://catherinedevlin.blogspot.com/2009/04/geekspeakrcom.html' title='geekspeakr.com'/><author><name>Catherine</name><uri>http://www.blogger.com/profile/12229578427522022392</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://photos1.blogger.com/img/93/6310/320/shoulders4_zoom.jpg'/></author><thr:total>0</thr:total></entry></feed>
