<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Musings of an Anonymous Geek &#187; Web Services</title>
	<atom:link href="http://www.protocolostomy.com/category/web-services/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.protocolostomy.com</link>
	<description>Made with only the finest 1's and 0's</description>
	<lastBuildDate>Thu, 03 Nov 2011 04:08:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Thoughts on Python and Python Cookbook Recipes to Whet Your Appetite</title>
		<link>http://www.protocolostomy.com/2011/06/09/thoughts-on-python-and-python-cookbook-recipes-to-whet-your-appetite/</link>
		<comments>http://www.protocolostomy.com/2011/06/09/thoughts-on-python-and-python-cookbook-recipes-to-whet-your-appetite/#comments</comments>
		<pubDate>Fri, 10 Jun 2011 03:33:42 +0000</pubDate>
		<dc:creator>bkjones</dc:creator>
				<category><![CDATA[Big Ideas]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://www.protocolostomy.com/?p=934</guid>
		<description><![CDATA[Dave Beazley and myself are, at this point, waist deep into producing Python Cookbook 3rd Edition. We haven&#8217;t really taken the approach of going chapter by chapter, in order. Rather, we&#8217;ve hopped around to tackle chapters one or the other finds interesting or in-line with what either of us happens to be working with a [...]]]></description>
			<content:encoded><![CDATA[<p>Dave Beazley and myself are, at this point, waist deep into producing Python Cookbook 3rd Edition. We haven&#8217;t really taken the approach of going chapter by chapter, in order. Rather, we&#8217;ve hopped around to tackle chapters one or the other finds interesting or in-line with what either of us happens to be working with a lot currently.</p>
<p>For me, it&#8217;s testing (chapter 8, for those following along with the 2nd edition), and for Dave, well, I secretly think Dave touches every aspect of Python at least every two weeks whether he needs to or not. He&#8217;s just diabolical that way. He&#8217;s working on processes and threads at the moment, though (chapter 9 as luck would have it).</p>
<p>In both chapters (also a complete coincidence), we&#8217;ve decided to toss every scrap of content and start from scratch.</p>
<h2>Why on Earth Would You Do That?</h2>
<p>Consider this: when the last edition (2nd ed) of the Python Cookbook was released, it went up to Python 2.4. Here&#8217;s a woefully incomplete list of the superamazing awesomeness that didn&#8217;t even exist when the 2nd Edition was released:</p>
<ul>
<li>Modules:
<ul>
<li>ElementTree</li>
<li>ctypes</li>
<li>sqlite3</li>
<li>functools</li>
<li>cProfile</li>
<li>spwd</li>
<li>uuid</li>
<li>hashlib</li>
<li>wsgiref</li>
<li>json</li>
<li>multiprocessing</li>
<li>fractions</li>
<li>plistlib</li>
<li>argparse</li>
<li>importlib</li>
<li>sysconfig</li>
</ul>
</li>
<li>Other Stuff
<ul>
<li>The &#8216;with&#8217; statement and context managers*</li>
<li>The &#8216;any&#8217; and &#8216;all&#8217; built-in functions</li>
<li>collections.defaultdict</li>
<li>advanced string formatting (the &#8216;format()&#8217; method)</li>
<li>class decorators</li>
<li>collections.OrderedDict</li>
<li>collections.Counter</li>
<li>collections.namedtuple()</li>
<li>the ability to send data *into* a generator (yield as an expression)</li>
<li>heapq.merge()</li>
<li>itertools.combinations</li>
<li>itertools.permutations</li>
<li>operator.methodcaller()</li>
</ul>
</li>
</ul>
<p>* If memory serves, the &#8216;with&#8217; statement was available in 2.4 via future import.</p>
<p>Again, woefully incomplete, and that&#8217;s only the stuff that&#8217;s in the 2.x version! I don&#8217;t even mention 3.x-only things like concurrent.futures. From this list alone, though, you can probably discern that the way we think about solving problems in Python, and what our code looks like these days, is fundamentally altered forever in comparison to the 2.4 days.</p>
<p>To give a little more perspective: Python core development moved from CVS to Subversion well after the 2nd edition of the book hit the shelves. They&#8217;re now on Mercurial. We skipped the entire Subversion era of Python development.</p>
<p>The addition of any() and all() to the language by themselves made at least 3-4 recipes in chapter 1 (strings) one-liners. I had to throw at least one recipe away because people just don&#8217;t need three recipes on how to use any() and all(). The idea that you have a chapter covering processes and threads without a multiprocessing module is just weird to think about these days. The with statement, context managers, class decorators, and enhanced generators have fundamentally changed how we think about certain operations.</p>
<p>Also something to consider: I haven&#8217;t mentioned a single third-party module! Mock, tox, and nosetests all support Python 3. At least Mock and tox didn&#8217;t exist in the old days (I don&#8217;t know about nose off-hand). Virtualenv and pip didn&#8217;t exist (both also support Python 3). So, not only has our <em>code</em> changed, but <em>how</em> we code, test, deploy, and generally do our jobs with Python has also changed.</p>
<p>Event-based frameworks aside from Twisted are not covered in the 2nd edition if they existed at all, and Twisted does not support Python 3.</p>
<p>WSGI, and all it brought with it, did not exist to my knowledge in the 2.4 days.</p>
<p>We need a <a href="http://www.beloit.edu/mindset/">Mindset List</a> for Python programmers!</p>
<h2>So, What&#8217;s Your Point</h2>
<p>My point is that I suspect some people have been put off of submitting Python 3 recipes, because they don&#8217;t program in Python 3, and if you&#8217;re one of them, you need to know that there&#8217;s a lot of ground to cover between the 2nd and 3rd editions of the book. If you have a recipe that happens to be written in Python 2.6 using features of the language that didn&#8217;t exist in Python 2.4, submit it. You don&#8217;t even have to port it to Python 3 if you don&#8217;t want to or don&#8217;t have the time or aren&#8217;t interested or whatever.</p>
<h2>Are You Desperate for Recipes or Something?</h2>
<p>Well, not really. I mean, if you all want to wait around while Dave and I crank out recipe after recipe, the book will still kick ass, but it&#8217;ll take longer, and the book&#8217;s world view will be pretty much limited to how Dave and I see things. I think everyone loses if that&#8217;s the case. Having been an editor of a couple of different technical publications, I can say that my two favorite things about tech magazines are A) The timeliness of the articles (if Python Magazine were still around, we would&#8217;ve covered tox by now), and B) The broad perspective it offers by harvesting the wisdom and experiences of a vast sea of craftspeople.</p>
<h2>What Other Areas Are In Need?</h2>
<p>Network programming and system administration. For whatever reason, the 2nd edition&#8217;s view of system administration is stuff like checking your Windows sound system and spawning an editor from a script. I guess you can argue that these are tasks for a sysadmin, but it&#8217;s just not the meat of what sysadmins do for a living. I&#8217;ll admit to being frustrated by this because I spent some time searching around for Python 3-compatible modules for SNMP and LDAP and came up dry, but there&#8217;s still all of that sar data sitting around that nobody ever seems to use and is amazing, and is easy to parse with Python. There are also terminal logging scripts that would be good.</p>
<p>Web programming and fat client GUIs also need some love. The GUI recipes that don&#8217;t use tkinter mostly use wxPython, which isn&#8217;t Python 3-compatible. Web programming is CGI in the 2nd edition, along with RSS feed aggregation, Nevow, etc. I&#8217;d love to see someone write a stdlib-only recipe for posting an image to a web server, and then maybe more than one recipe on how to easily implement a server that accepts them.</p>
<p>Obviously, any recipes that solve a problem that others are likely to have that use any of the aforementioned modules &amp; stuff that didn&#8217;t exist in the last edition would really rock.</p>
<h2>How Do I Submit?</h2>
<ol>
<li>Post the code and an explanation of the problem it solves somewhere on the internet, or send it (or a link to it) via email to PythonCookbook@oreilly.com or to @bkjones on Twitter.</li>
<li>That&#8217;s it.</li>
</ol>
<p>We&#8217;ll take care of the rest. &#8220;The rest&#8221; is basically us pinging O&#8217;Reilly, who will contact you to sign something that says it&#8217;s cool if we use your code in the book. You&#8217;ll be listed in the credits for that recipe, following the same pattern as previous editions. If it goes in relatively untouched, you&#8217;ll be the only name in the credits (also following the pattern of previous editions).</p>
<h2>What Makes a Good Recipe?</h2>
<p>A perfect recipe that is almost sure to make it into the cookbook would ideally meet most of the criteria set out in my <a href="http://www.protocolostomy.com/2010/12/20/the-makings-of-a-great-python-cookbook-recipe/">earlier blog post on that very topic</a>. Keep in mind that the ability to illustrate a language feature in code takes precedence over the eloquence of any surrounding prose.</p>
<h2>What If&#8230;</h2>
<p>I sort of doubt this will come up, but if we&#8217;ve already covered whatever is in your recipe, we&#8217;ll weigh that out based on the merits of the recipes. I want to say we&#8217;ll give new authors an edge in the decision, but for an authoritative work, a meritocracy seems the only valid methodology.</p>
<p>If you think you&#8217;re not a good writer, then write the code, and a 2-line description of the problem it solves, and a 2-line description of how it works. We&#8217;ll flesh out the text if need be.</p>
<p>If you just can&#8217;t think of a good recipe, grep your code tree(s) for just the import statements, and look for ideas by answering questions on Stackoverflow or the various mailing lists.</p>
<p>If you think whatever you&#8217;re doing with the language isn&#8217;t very cool, then stop thinking that a cookbook is about being cool. It&#8217;s about being practical, and showing programmers possibly less senior than yourself an approach to a problem that isn&#8217;t completely insane or covered in warts, even if the problem is relatively simple.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.protocolostomy.com/2011/06/09/thoughts-on-python-and-python-cookbook-recipes-to-whet-your-appetite/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Slides, an App, a Meetup, and More On the Way</title>
		<link>http://www.protocolostomy.com/2011/06/02/slides-an-app-a-meetup-and-more-on-the-way/</link>
		<comments>http://www.protocolostomy.com/2011/06/02/slides-an-app-a-meetup-and-more-on-the-way/#comments</comments>
		<pubDate>Fri, 03 Jun 2011 03:27:44 +0000</pubDate>
		<dc:creator>bkjones</dc:creator>
				<category><![CDATA[Big Ideas]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Me stuff]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://www.protocolostomy.com/?p=922</guid>
		<description><![CDATA[I&#8217;ve been busy. Seriously. Here&#8217;s a short dump of what I&#8217;ve been up to with links and stuff. Hopefully it&#8217;ll do until I can get back to my regular blogging routine. PICC &#8217;11 Slides Posted I gave a Python talk at PICC &#8217;11. If you were there, then you have a suboptimal version of the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been busy. Seriously. Here&#8217;s a short dump of what I&#8217;ve been up to with links and stuff. Hopefully it&#8217;ll do until I can get back to my regular blogging routine.</p>
<h2>PICC &#8217;11 Slides Posted</h2>
<p>I gave a Python talk at PICC &#8217;11. If you were there, then you have a suboptimal version of the slides, both because I caught a few bugs, and also because they&#8217;re in a flattened, lifeless PDF file, which sort of mangles anything even slightly fancy. I&#8217;m not sure how much value you&#8217;ll get out of these because my presentation slides tend to present code that I then explain, and you won&#8217;t have the explanation, but people are asking, <a href="http://public.iwork.com/document/?d=PythonPICC11.key&amp;a=p55961227">so here they are in all their glory</a>. Enjoy!</p>
<h2>I Made a Webapp Designed To Fail</h2>
<p>No really, I did. <a href="http://webstatuscodes.appspot.com" target="_blank">WebStatusCodes</a> is the product of necessity. I&#8217;m writing a Python module that provides an easy way for people to talk to a web API. I test my code, and for some of the tests I want to make sure my code reacts properly to certain HTTP errors (or in some cases, to *any* HTTP status code that&#8217;s not 200). In unit tests this isn&#8217;t hard, but when you&#8217;re starting to test the network layers and beyond, you need something on the network to provide the errors. That&#8217;s what <a href="http://webstatuscodes.appspot.com" target="_blank">WebStatusCodes</a> does. It&#8217;s also a simple-but-handy reference for HTTP status codes, though it is incomplete (418 I&#8217;m a teapot is not supported). Still, worth checking out.</p>
<p>Interesting to note, this is my first AppEngine application, and I believe it took me 20 minutes to download the SDK, get something working, and get it deployed. It was like one of those &#8216;build a blog in -15 minutes&#8217; moments. Empowering the speed at which you can create things on AppEngine, though I&#8217;d be slow to consider it for anything much more complex.</p>
<h2>Systems and Devops People, Hack With Me!</h2>
<p>I like systems-land, and a while back I was stuck writing some reporting code, which I really don&#8217;t like, so I started a side project to see just how much cool stuff I could do using the /proc filesystem and nothing but pure Python. I didn&#8217;t get too far because the reporting project ended and I jumped back into all kinds of other goodness, but there&#8217;s a <a href="http://github.com/bkjones/pyproc" target="_blank">github project called pyproc</a> that&#8217;s just a single file with a few functions in it right now, and I&#8217;d like to see it grow, so fork it and send me pull requests. If you know Linux systems pretty well but are relatively new to Python, I&#8217;ll lend you a hand where I can, though time will be a little limited until the book is done (see further down).</p>
<p>The other projects I&#8217;m working on are sort of in pursuit of larger fish in the Devops waters, too, so be sure to check out the other projects I mention later in this post, and <a href="https://github.com/bkjones/" target="_blank">follow me on github</a>.</p>
<h2>Python Meetup Group in Princeton NJ</h2>
<p>I started a <a href="http://meetup.com/pug-ip" target="_blank">Meetup group for Pythonistas that probably work in NYC or PA, but live in NJ</a>. I work in PA, and before this group existed, the closest group was in Philly, an hour from home. I put my feelers out on Twitter, found some interest, put up a quick Meetup site, and we had 13 people at the first meetup (more than had RSVP&#8217;d). It&#8217;s a great group of folks, but more is always better, so check it out if you&#8217;re in the area. We hold meetings at the beautiful <a href="http://www.princeton.lib.nj.us/" target="_blank">Princeton Public Library </a>(who <a href="http://twitter.com/pugip" target="_blank">found us</a> <a href="http://twitter.com/princetonpl" target="_blank">on twitter</a> and now sponsors the group!), which is just a block or so from Triumph, the local microbrewery. I&#8217;m hoping to have a post-meeting impromptu happy hour there at some point.</p>
<h2>Python Cookbook Progress</h2>
<p>The Python Cookbook continues its march toward production. Lots of work has been done, lots of lessons have been learned, lots of teeth have been gnashed. The book is gonna rock, though. I had the great pleasure of porting all of the existing recipes that are likely to be kept over to Python 3. Great fun. It&#8217;s really amazing to see just how it happens that a 20-line recipe is completely obviated by the addition of a single, simple language feature. It&#8217;s happened in almost every chapter I&#8217;ve looked at so far.</p>
<p>If you have a recipe, or stumble upon a good example of some language feature, module, or other useful tidbit, whether it runs in Python 3 or not, let me know (see &#8216;Contact Me&#8217;). The book is 100% Python 3, but I&#8217;ve gotten fairly adept at porting things over by now <img src='http://www.protocolostomy.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Send me your links, your code, or whatever. If we use the recipe, the author will be credited in the book, of course.</p>
<h2>PyRabbit is Coming</h2>
<p>In the next few days I&#8217;ll be releasing a Python module on github that will let you easily work with RabbitMQ servers using that product&#8217;s HTTP management API. It&#8217;s not nearly complete, which is why I&#8217;m releasing it. It does some cool stuff already, but I need another helper or two to add new features and help do some research into how RabbitMQ broker configuration affects JSON responses from the API.<a href="https://github.com/bkjones" target="_blank"> Follow me on github</a> if you want to be the first to know when I get it released. You probably also want to <a href="https://github.com/myyearbook" target="_blank">follow myYearbook on github</a> since that&#8217;s where I work, and I might release it through the myYearbook github organization (where we also release lots of other cool open source stuff).</p>
<h2>Python Asynchronous AMQP Consumer Module</h2>
<p>I&#8217;m also about 1/3 of the way through a project that lets you write AMQP consumers using the same basic model as you&#8217;d write a Tornado application: write your handler, import the server, link the two (like, one line of code), and call consume(). In fact, it uses the Tornado IOLoop, as well as <a href="https://github.com/pika/pika" target="_blank">Pika</a>, which is an asynchronous AMQP module in Python (maintained by none other than <a href="https://github.com/gmr" target="_blank">my boss</a> and myYearbook CTO,  <a href="http://twitter.com/#!/crad" target="_blank">@crad</a>), which also happens to support the Tornado IOLoop directly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.protocolostomy.com/2011/06/02/slides-an-app-a-meetup-and-more-on-the-way/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why Open Shop In California?</title>
		<link>http://www.protocolostomy.com/2010/06/03/why-open-shop-in-california/</link>
		<comments>http://www.protocolostomy.com/2010/06/03/why-open-shop-in-california/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 12:44:00 +0000</pubDate>
		<dc:creator>bkjones</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://www.protocolostomy.com/?p=795</guid>
		<description><![CDATA[DISCLAIMER: I live on the East Coast, so these are perceptions and opinions that I don&#8217;t put forth as facts. I&#8217;m more asking a question to start a dialog than professing knowledge. So, I just heard a report claiming that there are more IT jobs than techs to fill them in Southern California. Anyone who [...]]]></description>
			<content:encoded><![CDATA[<p>DISCLAIMER: I live on the East Coast, so these are perceptions and opinions that I don&#8217;t put forth as facts. I&#8217;m more asking a question to start a dialog than professing knowledge.</p>
<p>So, I just heard a report claiming that there are more IT jobs than techs to fill them in Southern California. Anyone who ever reads a tech job board and/or TechCrunch has also no doubt taken note that a vast majority of startups seem to be starting up there, and that there are just a metric asston of jobs there anyway. </p>
<p>This boggles my mind. This is a place with an extremely high cost of living, making labor more expensive. At the same time, aren&#8217;t there rolling power outages in CA? Does that not effect corporations or something? Do they just move their datacenters across the border to another state? </p>
<p>Between what I would think is an amazingly high labor cost and what I would think is an unfavorable place in terms of simple things like availability of power, I would think more places would look elsewhere for expansion or startups. </p>
<p>I live within spitting distance of at least 5 universities with engineering departments that I think would rate at the very least &#8220;solid&#8221;, many would rate better. I would guess that I could get to any Ivy League school in 6 hours or less, driving (3 are within an hour of my NJ home). MIT and Stevens are very good non-Ivy schools, and lots of other ones like Rutgers, NJIT, Penn State, NYU, and lots more are here, and those are just a few of the ones between NYC and Philadelphia, which are less than 2 hours apart. So&#8230;. there&#8217;s a labor pool here. </p>
<p>Is it tax breaks? Some aspect of the political atmosphere? Transportation? Is San Francisco such a clean, safe, friendly city that you just deal with the nonsense to live there? </p>
<p>What&#8217;s your take on this? </p>
]]></content:encoded>
			<wfw:commentRss>http://www.protocolostomy.com/2010/06/03/why-open-shop-in-california/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Head first into javascript (and jQuery)</title>
		<link>http://www.protocolostomy.com/2010/01/12/head-first-into-javascript-and-jquery/</link>
		<comments>http://www.protocolostomy.com/2010/01/12/head-first-into-javascript-and-jquery/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 01:56:12 +0000</pubDate>
		<dc:creator>bkjones</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://www.protocolostomy.com/?p=695</guid>
		<description><![CDATA[So, I had to take a break from doing the Code Katas just as I was getting to the really cool one about Bloom Filters. The reason for the unexpected break from kata-ing was that I had a project thrown into my lap. I say &#8220;project&#8221; not because it was some huge thing that needed [...]]]></description>
			<content:encoded><![CDATA[<p>So, I had to take a break from doing the Code Katas just as I was getting to the really cool one about <a href="http://codekata.pragprog.com/2007/01/kata_five_bloom.html">Bloom Filters</a>. The reason for the unexpected break from kata-ing was that I had a project thrown into my lap. I say &#8220;project&#8221; not because it was some huge thing that needed doing &#8212; lots of people reading this could probably have done it in a matter of a few hours &#8212; but because it involved two things I&#8217;ve never done any real work with: javascript, and jQuery.</p>
<p>My task? Well, first I had to recreate a page from a graphic designer&#8217;s mockup. So, take a JPEG image and create the CSS and stuff to make that happen. Already I&#8217;m out of my comfort zone, because historically I&#8217;m a back-end developer more comfortable with threading than CSS (95% of my code is written in Python and is daemonized/threaded/multiprocess/all-of-the-above or worse), but at least I&#8217;ve done enough CSS to get by.</p>
<p>Once the CSS was done, I was informed that I&#8217;d now need to take the tabular reporting table I just created and make it sort on any of the columns, get the data via AJAX calls to a flat file that would store the JSON for the dummy data, create nice drop-down date pickers so date ranges in the report could be chosen by the end user, page the data using a flickr-style pager so only 20 lines would show up on a page, and alternate the row colors in the table (and make sure that doesn&#8217;t break when you sort!).</p>
<h2>How to learn javascript and/or jQuery REALLY fast</h2>
<p>How exactly do you learn enough javascript and jQuery to get this done in a matter of a few days (counting from *after* the CSS part was done)? Here are some links you should keep handy if you have a situation like this arise:</p>
<ul>
<li>If Douglas Crockford says it, listen. I&#8217;d advise you start <a href="http://video.yahoo.com/watch/111593/1710507">here</a> (part I of a 4-part intro to javascript). That site also has his &#8216;Advanced Javascript&#8217; series. He also wrote a <a href="http://www.amazon.com/gp/product/0596517742/ref=s9_k2a_gw_ir01?pf_rd_m=ATVPDKIKX0DER&amp;pf_rd_s=center-2&amp;pf_rd_r=187J8VKKRM59PEZBF159&amp;pf_rd_t=101&amp;pf_rd_p=470938631&amp;pf_rd_i=507846">book</a>, which is small enough to read quickly, and well done.</li>
<li>Packt has a lot of decent resources for jQuery. Specifically, <a href="http://www.packtpub.com/article/jquery-table-manipulation-part1">this article</a> helped me organize what I was doing in my head. The code itself had some rather glaring issues &#8212; you&#8217;re not going to cut-n-paste this code and deploy it to production, but coming from scorched earth, I really learned a lot.</li>
<li>After the project was already over I found <a href="http://www.webdesignerwall.com/tutorials/jquery-tutorials-for-designers/">this nice writeup</a> that covers quick code snippets and demos illustrating some niceties like sliding panels and disappearing table rows and how to do them with jQuery.</li>
<li>jQuery itself has some pretty decent <a href="http://api.jquery.com/">documentation</a> for those times when your cut-n-pasted code looks a little suspect or you&#8217;re just sure there&#8217;s a better way. Easy to read and concise.</li>
</ul>
<h2>Why I Wrote My Own Sorting/Paging in jQuery</h2>
<p>Inevitably, someone out there is wondering why I didn&#8217;t just use tablesorter and tablesorter.pager, or Flexigrid, or something like that. The answer, in a nutshell, is paging. Sorting and paging operations, I learned both by experience and in my reading, *NEED* to know about each other. If they don&#8217;t, you&#8217;ll get lots of weird results, like sorting on just one page (or, sorting on just one page until you click to another page, which will look as expected, and then click back), or pages with rows on them that are just plain wrong, or&#8230; the list goes on. This is precisely the problem that the integrated &#8220;all-sorting-all-paging&#8221; tools like tablesorter try to solve. The issue is that I could not find a SINGLE ONE that did not have a narrow definition of what a pager was, and what it looked like.</p>
<p>I wanted (well, I was required to mimic the mockup, so &#8220;needed&#8221;) a flickr-style pager &#8212; modified. I needed to have each page of the report represented at the bottom of the report table by a block with the proper number in the block. The block would be clickable, and clicking it would show the corresponding page of data. This is more or less what Flickr does, but I didn&#8217;t need the &#8220;previous&#8221; and &#8220;next&#8221; buttons, and I didn&#8217;t need the &#8220;&#8230;&#8221; they use (rather effectively) to cut down on the number of required pager elements. So&#8230; just some blocks with page numbers. That&#8217;s it.</p>
<p>I started out using tablesorter for jQuery, and it worked great &#8212; it does the sorting for you, manages the alternating row colors, and is a pretty flexible sorter. Then I got to the paging part, and things went South pretty fast. While tablesorter.pager has a &#8216;moveToPage&#8217; function, it&#8217;s not exposed so you can bind it to a CSS selector like the &#8216;moveToPrevious&#8217;, &#8216;moveToLast&#8217;, &#8216;moveToNext&#8217; and other functions are. So, I tried to hack it into the pager code myself. I got weird results (though I feel more confident about approaching that now than I did even three days ago). There wasn&#8217;t any obvious way to do anything but give the user *only* first/last/previous/next buttons to control the paging. I moved on. I googled, I asked on jQuery IRC, I even wrote the developer of tablesorter. I got nothing.</p>
<p>I looked at 4 or 5 different tools, and was shocked to find the same thing! I didn&#8217;t go digging into the code of all of them, but their documentation all seemed to be in some kind of weird denial about the existence of flickr-style paging altogether!</p>
<p>So, I wrote my own. It wasn&#8217;t all that difficult, really. The code that worked was only slightly different from the code I&#8217;d fought with early on in the process. It just took some reading to get some of the basic tricks of the trade under my belt, and I got a tip or two from one of the gurus at work as well, and I was off to the races!</p>
<h2>Lessons Learned</h2>
<p>So, one thing I have to say for my boss is that he knows better than to throw *all* of those things at me at once. Had he come to me and said he wanted an uber-ajaxian reporting interface from outer space from the get-go, I might not have responded even as positively as I did (and I would rate my response as &#8216;tepid, but attempting a positive outlook&#8217;) . It&#8217;s best to draw me in slowly, a task at a time, so I can get some sense of accomplishment and some feedback along the way instead of feeling like I still have this mountain to climb before it&#8217;s over.</p>
<p>I certainly learned that this javascript and jQuery (and AJAX) stuff isn&#8217;t really black magic. Once you get your hands dirty with it it&#8217;s kinda fun. I still don&#8217;t ever want to become a front end developer on a full-time basis (browser testing is where I *really* have zero patience, either for myself or the browsers), but this experience will serve me well in making my own projects a little prettier and slicker, and nicer to use. It&#8217;ll also help me understand more about what the front end folks are dealing with, since there&#8217;s tons of javascript at myYearbook.</p>
<p>So, I hope this post keeps some back end scalability engineer&#8217;s face from turning white when they&#8217;re given a front-end AJAX project to do. If you&#8217;ve ever had a similar situation happen to you (not necessarily related to javascript, but other technologies you didn&#8217;t know until you were thrown into a project), let&#8217;s hear the war stories!!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.protocolostomy.com/2010/01/12/head-first-into-javascript-and-jquery/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Python, Creating XML, Recursion, and Order</title>
		<link>http://www.protocolostomy.com/2009/11/04/python-creating-xml-recursion-and-order/</link>
		<comments>http://www.protocolostomy.com/2009/11/04/python-creating-xml-recursion-and-order/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 02:05:00 +0000</pubDate>
		<dc:creator>bkjones</dc:creator>
				<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://www.protocolostomy.com/?p=644</guid>
		<description><![CDATA[I love being challenged every day. Today I ran across a challenge that has several solutions. However, most of them are hacks, and I never feel like I really solved the problem when I implement a hack. There&#8217;s also that eerie feeling that this hack is going to bite me later. I have an API [...]]]></description>
			<content:encoded><![CDATA[<p>I love being challenged every day. Today I ran across a challenge that has several solutions. However, most of them are hacks, and I never feel like I really solved the problem when I implement a hack. There&#8217;s also that eerie feeling that this hack is going to bite me later.</p>
<p>I have an API I need to talk to. It&#8217;s pure XML-over-HTTP (henceforth XHTTP). Actually, the first issue I had was just dealing with XHTTP. All of the APIs I&#8217;ve dealt with in the past were either XMLRPC, SOAP, which have ready-made libraries ready to use, or they used GET parameters and the like, which are pretty simple to deal with. I&#8217;ve never had to actually construct an HTTP request and just POST raw XML.</p>
<p>It&#8217;s as easy as it should be, really. I code in Python, so once you actually have an XML message ready to send, you can use urllib2 to send it in about 2 lines of code.</p>
<p>The more interesting part is putting the request together. I thought I had this beat. I decided to use the xml.dom.minidom module and create my Document object by going through the DOMImplementation object, because it was the only thing I found that allowed me to actually specify a DTD programmatically instead of hackishly tacking on hard-coded text. No big deal.</p>
<p>Now that I had a document, I needed to add elements to it. Some of these XML queries I&#8217;m sending can get too long to write a function that manually creates all the elements, then adds them to the document, then creates the text nodes, then adds them to the proper element&#8230; it&#8217;s amazingly tedious to do. I really wish Python had something like PHP&#8217;s XMLWriter, which lets you create an element and its text in one line of code.</p>
<p>Tedium drives me nuts, so rather than code this all out, I decided to create a dictionary that mirrored the structure of my query, with the data for the text nodes filled in by variables.</p>
<pre class="brush: python; title: ; notranslate">
query_params = {'super_special_query':
                   {
                      'credentials': {'username': user, 'password': password, 'data_realm': realm},
                      'result_params': {'num_results': setsize, 'order_by': order_by},
                       query_type: query_dict
                    }
                }

def makeDoc():
    impl = getDOMImplementation()
    dt = impl.createDocumentType(&quot;super_special&quot;, None, 'super_special.dtd')
    doc = impl.createDocument(None, &quot;super_special&quot;, dt)
    return doc

def makeQuery(doc, query_params, tag=None):
    &quot;&quot;&quot;
        @doc is an xml.minidom.Document object
        @query_params is a dictionary structure that mirrors the structure of the xml.
        @tag used in recursion to keep track of the node to append things to next time through.

    &quot;&quot;&quot;

    if tag is None:
        root = doc.documentElement
    else:
        root = tag

    for key, value in query_params.iteritems():
        tag = doc.createElement(key)
        root.appendChild(tag)
        if isinstance(value, dict):
            makeQuery(doc, value, tag)
        else:
            root.appendChild(tag)
            tag_txt = doc.createTextNode(value)
            tag.appendChild(tag_txt)

    return doc.toxml()

doc = makeDoc()
qxml = makeQuery(doc, query_params)
</pre>
<p>This is simplistic, really. I don&#8217;t need to deal with attributes in my queries, for example. But it is generic enough that if I need to send different types of queries, all that&#8217;s required is creating another dictionary to represent it, and passing that through the same makeQuery function to create the query.</p>
<p>Initial testing indicated success, but that&#8217;s why you can&#8217;t rely on only simple initial tests. Switching things up immediately exposed a problem: The API server validated my query against a DTD that enforced strict ordering of the elements, and Python dictionaries do not have the same notion of &#8220;order&#8221; that you and I do.</p>
<p>So there&#8217;s the code. If nothing else, it&#8217;s a less-contrived example of what you might actually use recursion for. Tomorrow I have to figure out how to enforce the ordering. One idea is to have a separate list to consult for the ordering of the elements. It requires an extra outer loop to go through the list, get the name of the next tag, then use that value to ask the dictionary for any related values. Seemed like a good way to go, but I had a bit of difficulty figuring out how to make that work at all. Maybe with fresh eyes in the AM it&#8217;ll be more obvious &#8212; that happens a lot, and is always a nice surprise.</p>
<p>Ideas, as always, are hereby solicited!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.protocolostomy.com/2009/11/04/python-creating-xml-recursion-and-order/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

