<?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>Curia &#187; Python</title>
	<atom:link href="http://blog.curiasolutions.com/category/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.curiasolutions.com</link>
	<description>Technology thoughts and ideas</description>
	<lastBuildDate>Wed, 16 Dec 2009 01:38:40 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Python as a PHP replacement?</title>
		<link>http://blog.curiasolutions.com/2009/11/python-as-a-php-replacement/</link>
		<comments>http://blog.curiasolutions.com/2009/11/python-as-a-php-replacement/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 18:11:50 +0000</pubDate>
		<dc:creator>Seth</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.curiasolutions.com/?p=637</guid>
		<description><![CDATA[I recently sat down to coffee with a new acquaintance of mine who spends much of his time implementing F/OSS projects at non-profit organizations, and who had just stepped into a lead web developer position using PHP. After sharing pleasantries we began trading stories and talking about each of our &#8220;tools of the trade.&#8221; When [...]]]></description>
			<content:encoded><![CDATA[<p>I recently sat down to coffee with a new acquaintance of mine who spends much of his time implementing F/OSS projects at non-profit organizations, and who had just stepped into a lead web developer position using PHP. After sharing pleasantries we began trading stories and talking about each of our &#8220;tools of the trade.&#8221; When I mentioned that I used to do most of my web development in PHP, but have spent the past year or so trying to move as completely as possible to Python, his response was: &#8220;Huh, I have never really thought of Python as a PHP replacement.&#8221;</p>
<p>Now, this guy hasn&#8217;t exactly been living under a rock for the past 10 years—his resume was quite impressive and included projects in a number of different programming languages; But as you can imagine, I was rather surprised by his response, and it made me wonder: Has the Python community really been that bad at promoting the strengths of Python for web development? Or, does the nirvana experienced by switching from a language like PHP to Python just make us so at peace with the world that we forget the hordes of developers still stuck with C-style syntax? Either way, it got me thinking about a few of the reasons why <em>I</em> decided to switch from PHP to Python; and why I not only see Python as an excellent PHP replacement, but am surprised it is such a &#8220;best-kept secret&#8221; for web development.</p>
<p>There are already plenty of pages out there discussing <a href="http://wiki.python.org/moin/PythonVsPhp" target="_blank">Python vs. PHP as a language</a>, so I probably won&#8217;t get too technical here. I also want to try avoid turning this into a &#8220;Python is better than PHP because&#8230;&#8221; rant (for more on that, please see the end of this post), so I will simply share with you a few of the main reasons why <em>I</em> decided to replace PHP with Python as <em>my</em> primary language for web development:</p>
<p><span id="more-637"></span></p>
<h4>» Python is more flexible than PHP</h4>
<p>Python was engineered from the beginning to be a general purpose programming language. PHP on the other hand was written to overcome many of the &#8220;limitations&#8221; of the <a href="http://en.wikipedia.org/wiki/Cgi-bin" target="_blank">cgi-bin</a>. This should say a lot about the &#8220;soul&#8221; of each language, but the conclusion I have come to is:</p>
<ul>
<li>PHP is meant to do web things really well</li>
<li>Python is meant to do most things really well</li>
</ul>
<p>Sure, these days you <em>could</em> write a desktop GUI in PHP, but it would most likely <em>not</em> be the right tool for the job (and you&#8217;d probably get laughed at). On a somewhat related note: many PHP developers I know find themselves switching between PHP for their website tasks, and a variety of other languages for other tasks (Shell Scripting for command-line scripts, Perl for text processing, etc.). As a Python programmer, I can typically stick to <em>one programming language</em> no matter what the task at hand requires (especially when armed with <a href="http://ipython.scipy.org/" target="_blank">iPython</a>).</p>
<p>Now, the obvious argument for PHP at this point is: &#8220;But wait, since PHP was written specifically for the web, shouldn&#8217;t that actually give it <em>more</em> credibility as the right tool for the web job?&#8221; Well, 5 or 10 years ago I might have agreed with you, but web development has changed a lot in the past few years (not to mention the introduction of Python&#8217;s <a href="http://en.wikipedia.org/wiki/Web_Server_Gateway_Interface" target="_blank">WSGI spec</a>).</p>
<p>The internet as a platform has grown and mutated drastically and now requires much more than &#8220;a server-side extension to HTML.&#8221; We are now in an age of full-blown internet <em>applications</em>, which require a true &#8220;application-level&#8221; language. In my opinion, PHP has only recently begun to move in that direction with the v5.3 release (as well as updates expected in PHP 6). That alone should give you pause when pondering PHP&#8217;s ability to &#8220;keep up&#8221; with the growth of the web.</p>
<p>In short, the internet continues to transform into an arena that is much less of a website platform, and much more of an application platform. To me, this makes a general purpose language such as Python the obvious choice for &#8220;future-proof&#8221; internet development.</p>
<h4>» Python is typically faster than PHP, <span style="text-decoration: line-through;">even</span> especially on the web</h4>
<p>You might find PHP beating out Python in a simple &#8220;hello world&#8221;-type test, but &#8220;real-world&#8221; applications will typically run much faster in Python. In a Web 2.0 world where everyone has broadband, speed is now an important factor in keeping your visitors happy.</p>
<p>In addition to &#8220;raw, under-the-hood&#8221; speed, Python&#8217;s language philosophy means it will typically <a href="http://groups.google.com/group/comp.lang.python/msg/83907b65bdee30f6" target="_blank">scale better than PHP</a> (although this can be argued a million different ways, since scalability usually involves much more than the language).</p>
<p>I&#8217;ve already done <a href="http://blog.curiasolutions.com/2009/09/the-great-web-development-shootout/" target="_blank">benchmarks</a> comparing a few popular web frameworks, but if you&#8217;re still curious I&#8217;d suggest you <a href="http://www.google.com/search?q=is+python+or+php+faster%3F" target="_blank">dig around with Google</a> for a while.</p>
<h4>» Python is easier to read and maintain than PHP</h4>
<p>Any veteran programmer will tell you that code <em>readability</em> plays a huge factor in code <em>maintainability</em>. With that in mind, Python was designed with some pretty strict syntax rules in regards to code-blocks and whitespace. While this may initially frustrate programmers who are used to a looser &#8220;bracket-encapsulated&#8221; language, it actually forces you to write more readable (and therefore, more maintainable) code.</p>
<p>Other than readability, Python&#8217;s clean syntax also means:</p>
<ul>
<li>You can write more code with less errors (because they&#8217;re so easy to spot). This often comes as a pleasant surprise to programmers migrating from C-style languages (take <a href="http://www.python.org/about/success/esr/" target="_blank">Eric Raymond</a> for example).</li>
<li>You end up typing less — No more semicolons or brackets, and fewer parentheses.</li>
<li>Your eyes don&#8217;t have to move around as much to figure out what&#8217;s going on.</li>
<li>Your first guess about what&#8217;s happening in a code-block is usually correct.</li>
</ul>
<p>When you have time to kill, I&#8217;d recommend a stroll through <a href="http://rosettacode.org/wiki/Main_Page" target="_blank">Rosetta Code</a> to compare how different languages &#8220;look&#8221; when tackling the same problem. Unless you just love brackets, I think you&#8217;ll find the non C-style syntaxes much easier to read.</p>
<h4>» Python is more consistent than PHP</h4>
<p>Continuing somewhat in the vein of readability is the topic of consistency. Since PHP&#8217;s lack of consistency has already been studied exhaustively by the Perl folks, I will spare you my rant and suggest you <a href="http://tnx.nl/php.html" target="_blank">read theirs</a>.</p>
<p>As a side note on this topic: I often hear PHP programmers talk about how awesome PHP&#8217;s documentation is in that you can open a web browser and just type &#8220;php.net/some_function&#8221; to get help. Well, documentation recall usually isn&#8217;t that big of a deal for me (because I have a somewhat photographic memory), but I will say that after switching to Python I found myself turning to its documentation <em>significantly</em> less than I had with PHP, simply because I didn&#8217;t have to keep reminding myself whether that infrequently used function was named some_function or somefunction. With Python, the function/method I need is usually named <em>exactly</em> what I expect it to be named, and returns <em>exactly</em> what I expect it to return.</p>
<p>Oh, and don&#8217;t even get me started on PHP&#8217;s recent <a href="http://blog.fedecarg.com/2008/10/28/php-namespaces-controversy/" target="_blank">namespace</a> <a href="http://michaelkimsal.com/blog/disappointed-with-php-namespace-seperator-decision/" target="_blank">decision</a>.</p>
<p>&nbsp;</p>
<h4 style="text-align: center;">» However, PHP still excels in a few areas «</h4>
<p>Having said all of that, there are a few areas where I believe PHP may still shine brighter than Python:</p>
<h4>» PHP hosting support <span style="text-decoration: line-through;">is</span> may be more prevalent than Python</h4>
<p>It&#8217;s practically unheard of to find yourself on a web host that doesn&#8217;t support PHP out of the box. However, this is becoming less and less of an issue since most Python web applications can now be deployed using tools such as FastCGI or mod_proxy (as opposed to the popular <a href="http://code.google.com/p/modwsgi/" target="_blank">mod_wsgi</a> setup, which often requires root access to configure). These days any &#8220;reputable&#8221; web host is probably going to support some sort of strategy for deploying Python web applications. Of course, this only really applies to shared hosting environments without root access. If you&#8217;ve got a VPS or dedicated server you&#8217;re fine.</p>
<h4>» PHP is arguably &#8220;more seasoned&#8221; on the web than Python</h4>
<p>The communities behind projects like Drupal and WordPress really stand out to me as examples of the maturity of PHP on the web. Although similar Python web projects have been slowly emerging (and <a href="http://plone.org/" target="_blank">Plone</a> has been around for years, if that&#8217;s your cup of tea), they don&#8217;t really compete yet in my opinion.</p>
<p>Of course, I am only talking about specific web projects here. Language wise, Python has been around longer than PHP. Web 2.0 framework wise, Python&#8217;s offerings have been around about as long as PHP&#8217;s (pretty much every language had its own answer to Ruby on Rails in 2005).</p>
<h4>» PHP <em>seems</em> easier than Python at first (and might be for simple deployments)</h4>
<p>There&#8217;s something magical about throwing together a few quick index.php/about.php/contact.php files and uploading them to the httpdocs directory of your webserver and it &#8220;just working.&#8221; A lot of simple websites have no need for acronyms like MVC, ORM, and DRY, and in those cases PHP is an excellent &#8220;server-side extension&#8221; to HTML. However, if and when you begin to scale, you&#8217;ll either find yourself switching to a full-blown framework, or throwing one together to help facilitate your growth. At that point, you&#8217;ll probably begin discovering the &#8220;dark corners&#8221; of PHP, and may find yourself wishing you had &#8220;done it right&#8221; the first time.</p>
<p>&nbsp;</p>
<h4 style="text-align: center;">» So, which is better? «</h4>
<p>Remember, the point of this post is to solidify the fact that Python can be an excellent PHP <em>replacement</em>. When it comes to programming languages, &#8220;better&#8221; is often more a case of personal preference than anything else. However, to <em>me</em> the points discussed above make Python the better choice when it comes to what <em>I</em> like in a web development language.</p>
<p>So, is Python a better web development language than PHP?<br />
Well, does Nike make a better shoe than Adidas?</p>
<p>The most honest answer is probably: &#8220;It depends.&#8221; Python definitely has some significant advantages over PHP in certain circumstances, but the same could probably be said of PHP in other circumstances (although limited to the web I imagine).</p>
<p>&nbsp;</p>
<p>I hope this post has encouraged you PHP programmers out there to take another look at Python. It may take some getting used to (Python&#8217;s way of doing things is inherently quite different than PHP&#8217;s), but you will probably find yourself thanking me later.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.curiasolutions.com/2009/11/python-as-a-php-replacement/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Reorganizing data with list &amp; dict comprehensions</title>
		<link>http://blog.curiasolutions.com/2009/10/reorganizing-data-with-list-dict-comprehensions/</link>
		<comments>http://blog.curiasolutions.com/2009/10/reorganizing-data-with-list-dict-comprehensions/#comments</comments>
		<pubDate>Sat, 31 Oct 2009 03:58:59 +0000</pubDate>
		<dc:creator>Seth</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.curiasolutions.com/?p=538</guid>
		<description><![CDATA[While writing scripts, I frequently run into the issue of needing to re-arrange sets of data into a more &#8220;process friendly&#8221; format. A common issue I encounter is needing to turn a list (array) into a dictionary (associative array) or vice versa. More often than not, I find myself needing to be able to access [...]]]></description>
			<content:encoded><![CDATA[<p>While writing scripts, I frequently run into the issue of needing to re-arrange sets of data into a more &#8220;process friendly&#8221; format. A common issue I encounter is needing to turn a list (array) into a dictionary (associative array) or vice versa. More often than not, I find myself needing to be able to access list elements by a key, but since they aren&#8217;t setup in a dictionary I have to pull out a looping technique to reorganize the data for this to be possible.</p>
<p>Take the following set of data for example:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: black;">&#91;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'John Smith'</span>, <span style="color: #483d8b;">'admin'</span><span style="color: black;">&#93;</span>,
 <span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span>, <span style="color: #483d8b;">'Jane Doe'</span>, <span style="color: #483d8b;">'superuser'</span><span style="color: black;">&#93;</span>,
 <span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span>, <span style="color: #483d8b;">'Sam Jones'</span>, <span style="color: #483d8b;">'user'</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span></pre></div></div>

<p>What we have here is a few rows of user data. In this example, the data is in a Python list (which in PHP would be an array).</p>
<p>In PHP, this would look something like (using print_r):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">Array</span> <span style="color: #009900;">&#40;</span>
    <span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">Array</span> <span style="color: #009900;">&#40;</span>
        <span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span>
        <span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> John Smith
        <span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> admin
    <span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">Array</span> <span style="color: #009900;">&#40;</span>
        <span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">2</span>
        <span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=&gt;</span> Jane Doe
<span style="color: #666666; font-style: italic;"># (...etc...)</span></pre></div></div>

<p>So, what if I found myself writing some code that needed to be able to access each record by its first value, which in this case would be the user_id? <span id="more-538"></span></p>
<p>Well, in PHP the easiest way to make this happen would be a good-old-fashioned <em>foreach</em> loop:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$val</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$out</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$val</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$val</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Not very &#8220;sexy&#8221; for something I find myself having to more often than I would like, but it works nonetheless.</p>
<p>Now, here&#8217;s where the beauty of Python kicks in. Python has a built-in feature called &#8220;comprehension&#8221; which allows you to modify and/or convert sets of data quickly and easily.</p>
<p>Remember what our original data set looks like? Here&#8217;s a refresher:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span> row
<span style="color: black;">&#91;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'John Smith'</span>, <span style="color: #483d8b;">'admin'</span><span style="color: black;">&#93;</span>,
 <span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span>, <span style="color: #483d8b;">'Jane Doe'</span>, <span style="color: #483d8b;">'superuser'</span><span style="color: black;">&#93;</span>,
 <span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span>, <span style="color: #483d8b;">'Sam Jones'</span>, <span style="color: #483d8b;">'user'</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span></pre></div></div>

<p>Now, in Python all we need to do is use the dictionary comprehension:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> out = <span style="color: black;">&#123;</span>val<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>: val <span style="color: #ff7700;font-weight:bold;">for</span> val <span style="color: #ff7700;font-weight:bold;">in</span> row<span style="color: black;">&#125;</span> <span style="color: #808080; font-style: italic;"># Python 3.X</span>
<span style="color: #808080; font-style: italic;"># (or, for Python 2.X)</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> out = <span style="color: #008000;">dict</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>val<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, val<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> val <span style="color: #ff7700;font-weight:bold;">in</span> row<span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># Python 2.4+</span>
&nbsp;
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span> out
<span style="color: black;">&#123;</span><span style="color: #ff4500;">1</span>: <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'John Smith'</span>, <span style="color: #483d8b;">'admin'</span><span style="color: black;">&#93;</span>,
 <span style="color: #ff4500;">2</span>: <span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span>, <span style="color: #483d8b;">'Jane Doe'</span>, <span style="color: #483d8b;">'superuser'</span><span style="color: black;">&#93;</span>,
 <span style="color: #ff4500;">3</span>: <span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span>, <span style="color: #483d8b;">'Sam Jones'</span>, <span style="color: #483d8b;">'user'</span><span style="color: black;">&#93;</span><span style="color: black;">&#125;</span></pre></div></div>

<p>See how easy that was?</p>
<p>And what if I had a dictionary in the above format, and needed to turn it into the type of list I had previously? Well, I could simply use the list comprehension to re-generate this set of data as a list:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: black;">&#91;</span>val <span style="color: #ff7700;font-weight:bold;">for</span> val <span style="color: #ff7700;font-weight:bold;">in</span> out.<span style="color: black;">values</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'John Smith'</span>, <span style="color: #483d8b;">'admin'</span><span style="color: black;">&#93;</span>,
 <span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span>, <span style="color: #483d8b;">'Jane Doe'</span>, <span style="color: #483d8b;">'superuser'</span><span style="color: black;">&#93;</span>,
 <span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span>, <span style="color: #483d8b;">'Sam Jones'</span>, <span style="color: #483d8b;">'user'</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span></pre></div></div>

<p>This is an extremely simple comprehension example. For a deeper look, check out Wikipedia&#8217;s <a href="http://en.wikipedia.org/wiki/Python_syntax_and_semantics#Functional_programming" target="_blank">Python syntax page</a> or the <a href="http://docs.python.org/3.1/tutorial/datastructures.html" target="_blank">official Python documentation</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.curiasolutions.com/2009/10/reorganizing-data-with-list-dict-comprehensions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to use multiple databases in TurboGears 2.0</title>
		<link>http://blog.curiasolutions.com/2009/07/multiple-databases-in-turbogears-2/</link>
		<comments>http://blog.curiasolutions.com/2009/07/multiple-databases-in-turbogears-2/#comments</comments>
		<pubDate>Fri, 31 Jul 2009 01:46:08 +0000</pubDate>
		<dc:creator>Seth</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[turbogears]]></category>

		<guid isPermaLink="false">http://blog.curiasolutions.com/?p=87</guid>
		<description><![CDATA[I recently had to setup a special marketing web-portal for a client of mine that would collect some basic information and throw it into a database to be retrieved later. Since I&#8217;ve already got most of the client&#8217;s web-stuff on TG2 (and in an effort to keep things DRY), I decided I&#8217;d just add a [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had to setup a special marketing web-portal for a client of mine that would collect some basic information and throw it into a database to be retrieved later. Since I&#8217;ve already got most of the client&#8217;s web-stuff on TG2 (and in an effort to keep things DRY), I decided I&#8217;d just add a controller for the new pages to TG and use some mod_proxy kung-fu to make it look like it all lived autonomously. Easy enough, right?</p>
<p>Well, about halfway through this process I decided I wanted to have the collected information dump into its own SQLite DB, keeping it safely away from the rest of my client&#8217;s data. I had heard that setting up multiple databases in TG2 was supposed to be easy, and with some help from Google I soon ran across <a href="http://groups.google.com/group/turbogears/browse_thread/thread/70c14ac308563af5" target="_blank">this thread on the ML</a>. In it, Chris supplies some <a href="http://groups.google.com/group/turbogears/msg/dec19abfaa503bbc" target="_blank">very helpful example code</a> which Mike subsequently posted on his blog as <a href="http://www.blog.pythonlibrary.org/?p=210" target="_blank">a nice tutorial</a>. However, neither of these resources were exhaustive enough to achieve what I was looking for without a bit of &#8220;stumbling around&#8221;, so in an effort to be overly verbose (and perhaps unnecessarily repetitive) I&#8217;ve decided to post what I hope will be a more comprehensive run-down of how to accomplish this task.</p>
<p>Disclaimer: I am in no way a TurboGears or SQLAlchemy expert. There&#8217;s probably an easier/better way to do this, but since there&#8217;s no &#8220;official&#8221; TurboGears tutorial on this topic yet I&#8217;m afraid this is the best method I&#8217;ve found so far. If anyone reading this knows a better way to implement this kind of thing, please leave a comment and I will update this post as the suggestions come in.</p>
<blockquote><p>Step 1: Define your database urls in the [app:main] section of your .ini file(s)</p></blockquote>
<p>This is where the magic begins. Instead of one simple <em>sqlalchemy.url =</em> assignment, you&#8217;ve got to create assignments for each of the databases you want to use:<span id="more-87"></span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># in myapp/development.ini (or production.ini, or whatever.ini you are using)</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#sqlalchemy.url = sqlite:///%(here)s/devdata.db</span>
sqlalchemy.<span style="color: black;">first</span>.<span style="color: black;">url</span> = sqlite:///<span style="color: #66cc66;">%</span><span style="color: black;">&#40;</span>here<span style="color: black;">&#41;</span>s/database_1.<span style="color: black;">db</span>
sqlalchemy.<span style="color: black;">second</span>.<span style="color: black;">url</span> = sqlite:///<span style="color: #66cc66;">%</span><span style="color: black;">&#40;</span>here<span style="color: black;">&#41;</span>s/database_2.<span style="color: black;">db</span></pre></div></div>

<blockquote><p>Step 2: Change the way your app loads the databases</p></blockquote>
<p>Now we need to instruct the app to load the multiple databases correctly. This requires telling base_config (in app_cfg.py) to load our own custom AppConfig with the proper multi-db assignments and a call to the model&#8217;s init_model method (more on that in Step 3):</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># in myapp/config/app_cfg.py</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># make sure these imports are added to the top</span>
<span style="color: #ff7700;font-weight:bold;">from</span> tg.<span style="color: black;">configuration</span> <span style="color: #ff7700;font-weight:bold;">import</span> AppConfig, config
<span style="color: #ff7700;font-weight:bold;">from</span> pylons <span style="color: #ff7700;font-weight:bold;">import</span> config <span style="color: #ff7700;font-weight:bold;">as</span> pylons_config
<span style="color: #ff7700;font-weight:bold;">from</span> myapp.<span style="color: black;">model</span> <span style="color: #ff7700;font-weight:bold;">import</span> init_model
&nbsp;
<span style="color: #808080; font-style: italic;"># add this before base_config =</span>
<span style="color: #ff7700;font-weight:bold;">class</span> MultiDBAppConfig<span style="color: black;">&#40;</span>AppConfig<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> setup_sqlalchemy<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Setup SQLAlchemy database engine(s)&quot;&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">from</span> sqlalchemy <span style="color: #ff7700;font-weight:bold;">import</span> engine_from_config
        engine1 = engine_from_config<span style="color: black;">&#40;</span>pylons_config, <span style="color: #483d8b;">'sqlalchemy.first.'</span><span style="color: black;">&#41;</span>
        engine2 = engine_from_config<span style="color: black;">&#40;</span>pylons_config, <span style="color: #483d8b;">'sqlalchemy.second.'</span><span style="color: black;">&#41;</span>
        <span style="color: #808080; font-style: italic;"># engine1 should be assigned to sa_engine as well as your first engine's name</span>
        config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'pylons.app_globals'</span><span style="color: black;">&#93;</span>.<span style="color: black;">sa_engine</span> = engine1
        config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'pylons.app_globals'</span><span style="color: black;">&#93;</span>.<span style="color: black;">sa_engine_first</span> = engine1
        config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'pylons.app_globals'</span><span style="color: black;">&#93;</span>.<span style="color: black;">sa_engine_second</span> = engine2
        <span style="color: #808080; font-style: italic;"># Pass the engine to init_model, to be able to introspect tables</span>
        init_model<span style="color: black;">&#40;</span>engine1, engine2<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#base_config = AppConfig()</span>
base_config = MultiDBAppConfig<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<blockquote><p>Step 3: Update your model&#8217;s __init__ to handle multiple sessions and metadata</p></blockquote>
<p>Switching the model&#8217;s init from a single-db config to a multi-db simply means we have to duplicate our DBSession and metata assignments, and then update the init_model method to assign/configure each engine correctly:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># in myapp/model/__init__.py</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># after the first maker/DBSession assignment, add a 2nd one</span>
maker2 = sessionmaker<span style="color: black;">&#40;</span>autoflush=<span style="color: #008000;">True</span>, autocommit=<span style="color: #008000;">False</span>,
                     extension=ZopeTransactionExtension<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
DBSession2 = scoped_session<span style="color: black;">&#40;</span>maker2<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># after the first DeclarativeBase assignment, add a 2nd one</span>
DeclarativeBase2 = declarative_base<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># uncomment the metadata2 line and assign it to DeclarativeBase2.metadata</span>
metadata2 = DeclarativeBase2.<span style="color: black;">metadata</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># finally, modify the init_model method to allow both engines to be passed (see step 2) and</span>
<span style="color: #808080; font-style: italic;"># assign the sessions and metadata to each engine</span>
<span style="color: #ff7700;font-weight:bold;">def</span> init_model<span style="color: black;">&#40;</span>engine1, engine2<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Call me before using any of the tables or classes in the model.&quot;&quot;&quot;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#    DBSession.configure(bind=engine)</span>
    DBSession.<span style="color: black;">configure</span><span style="color: black;">&#40;</span>bind=engine1<span style="color: black;">&#41;</span>
    DBSession2.<span style="color: black;">configure</span><span style="color: black;">&#40;</span>bind=engine2<span style="color: black;">&#41;</span>
&nbsp;
    metadata.<span style="color: black;">bind</span> = engine1
    metadata2.<span style="color: black;">bind</span> = engine2</pre></div></div>

<blockquote><p>Step 4: Have your model classes inherit from either DeclarativeBase or DeclarativeBase2, and use DBSession or DBSession2 as your database session handler</p></blockquote>
<p>Now that the configuration has all been taken care of, you can instruct your models to use either the first or second DeclarativeBase and DBSession based on what DB engine you want it to access:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># myapp/model/spam.py (uses engine1)</span>
<span style="color: #ff7700;font-weight:bold;">from</span> sqlalchemy <span style="color: #ff7700;font-weight:bold;">import</span> Table, ForeignKey, Column
<span style="color: #ff7700;font-weight:bold;">from</span> sqlalchemy.<span style="color: #dc143c;">types</span> <span style="color: #ff7700;font-weight:bold;">import</span> Integer, Unicode, Boolean
<span style="color: #ff7700;font-weight:bold;">from</span> myapp.<span style="color: black;">model</span> <span style="color: #ff7700;font-weight:bold;">import</span> DeclarativeBase
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Spam<span style="color: black;">&#40;</span>DeclarativeBase<span style="color: black;">&#41;</span>:
    __tablename__ = <span style="color: #483d8b;">'spam'</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: #008000;">id</span> = <span style="color: #008000;">id</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">variety</span> = variety
&nbsp;
    <span style="color: #008000;">id</span> = Column<span style="color: black;">&#40;</span>Integer, autoincrement=<span style="color: #008000;">True</span>, primary_key=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
    variety = Column<span style="color: black;">&#40;</span>Unicode<span style="color: black;">&#40;</span><span style="color: #ff4500;">50</span><span style="color: black;">&#41;</span>, nullable=<span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#---------------------------------------------------------------------#</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># myapp/model/eggs.py (uses engine2)</span>
<span style="color: #ff7700;font-weight:bold;">from</span> sqlalchemy <span style="color: #ff7700;font-weight:bold;">import</span> Table, ForeignKey, Column
<span style="color: #ff7700;font-weight:bold;">from</span> sqlalchemy.<span style="color: #dc143c;">types</span> <span style="color: #ff7700;font-weight:bold;">import</span> Integer, Unicode, Boolean
<span style="color: #ff7700;font-weight:bold;">from</span> myapp.<span style="color: black;">model</span> <span style="color: #ff7700;font-weight:bold;">import</span> DeclarativeBase2
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Eggs<span style="color: black;">&#40;</span>DeclarativeBase2<span style="color: black;">&#41;</span>:
    __tablename__ = <span style="color: #483d8b;">'eggs'</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #008000;">id</span>, pkg_qty<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: #008000;">id</span> = <span style="color: #008000;">id</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">pkg_qty</span> = pkg_qty
&nbsp;
    <span style="color: #008000;">id</span> = Column<span style="color: black;">&#40;</span>Integer, autoincrement=<span style="color: #008000;">True</span>, primary_key=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
    pkg_qty = Column<span style="color: black;">&#40;</span>Integer, default=<span style="color: #ff4500;">12</span><span style="color: black;">&#41;</span></pre></div></div>

<blockquote><p>Optional: Create and populate each database in websetup.py</p></blockquote>
<p>If you want your setup_app method to populate each database with data, simply use the appropriate metadata/DBSession objects as you would in a single-db setup:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># in myapp/websetup.py</span>
<span style="color: #ff7700;font-weight:bold;">def</span> setup_app<span style="color: black;">&#40;</span>command, conf, <span style="color: #008000;">vars</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Place any commands to setup myapp here&quot;&quot;&quot;</span>
    load_environment<span style="color: black;">&#40;</span>conf.<span style="color: black;">global_conf</span>, conf.<span style="color: black;">local_conf</span><span style="color: black;">&#41;</span>
    <span style="color: #808080; font-style: italic;"># Load the models</span>
    <span style="color: #ff7700;font-weight:bold;">from</span> myapp <span style="color: #ff7700;font-weight:bold;">import</span> model
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Creating tables for engine1&quot;</span>
    model.<span style="color: black;">metadata</span>.<span style="color: black;">create_all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Creating tables for engine2&quot;</span>
    model.<span style="color: black;">metadata2</span>.<span style="color: black;">create_all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># populate spam table</span>
    spam = <span style="color: black;">&#91;</span>
        model.<span style="color: black;">Spam</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, u<span style="color: #483d8b;">'Classic'</span><span style="color: black;">&#41;</span>,
        model.<span style="color: black;">Spam</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span>, u<span style="color: #483d8b;">'Golden Honey Grail'</span><span style="color: black;">&#41;</span>,
    <span style="color: black;">&#93;</span>
    <span style="color: #808080; font-style: italic;"># DBSession is bound to the spam table</span>
    model.<span style="color: black;">DBSession</span>.<span style="color: black;">add_all</span><span style="color: black;">&#40;</span>spam<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># populate eggs table</span>
    eggs = <span style="color: black;">&#91;</span>
        model.<span style="color: black;">Eggs</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">12</span><span style="color: black;">&#41;</span>,
        model.<span style="color: black;">Eggs</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">6</span><span style="color: black;">&#41;</span>,
    <span style="color: black;">&#93;</span>
    <span style="color: #808080; font-style: italic;"># DBSession2 is bound to the eggs table</span>
    model.<span style="color: black;">DBSession2</span>.<span style="color: black;">add_all</span><span style="color: black;">&#40;</span>eggs<span style="color: black;">&#41;</span>
&nbsp;
    model.<span style="color: black;">DBSession</span>.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    model.<span style="color: black;">DBSession2</span>.<span style="color: black;">flush</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    transaction.<span style="color: black;">commit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Successfully setup&quot;</span></pre></div></div>

<p>Hope this helps! If you have any questions or suggestions please leave a comment below.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.curiasolutions.com/2009/07/multiple-databases-in-turbogears-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why I&#8217;ve fallen in love with Python</title>
		<link>http://blog.curiasolutions.com/2009/07/why-ive-fallen-in-love-with-python/</link>
		<comments>http://blog.curiasolutions.com/2009/07/why-ive-fallen-in-love-with-python/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 07:05:20 +0000</pubDate>
		<dc:creator>Seth</dc:creator>
				<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.curiasolutions.com/?p=38</guid>
		<description><![CDATA[In a previous post, I briefly mentioned falling in love with Python. Now that I&#8217;m finally using Python for a large percentage of my development and am more than &#8220;casually acquainted&#8221; with its toolset, I thought it would be fun to highlight a few reasons why Python has become my new language of choice.
In an [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://blog.curiasolutions.com/?p=3" title="Introducing TurboGears 2">previous post</a>, I briefly mentioned falling in love with Python. Now that I&#8217;m finally using Python for a large percentage of my development and am more than &#8220;casually acquainted&#8221; with its toolset, I thought it would be fun to highlight a few reasons why Python has become my new language of choice.</p>
<p>In an effort to help you understand where I&#8217;m coming from, let me (briefly) rehash some of my programming history: I spent much of the 90&#8217;s doing dynamic web development using Perl (weren&#8217;t <em>those</em> the days!). I eventually migrated to PHP which usually made things much easier on the web; and subsequently replaced most of my console scripting with BASH [shell scripting]. However, I&#8217;m kind of a hack and love languages so I have occasionally been known to write something in C; and although I&#8217;m not a complete stranger to Java and Ruby, I never really felt like I &#8220;clicked&#8221; with either of those languages.</p>
<p>Ok, now that I&#8217;ve hopefully convinced you that I&#8217;m not just a fly-by-night programmer, let me show you some Python code. Brace yourself, as this article is bound to get lengthy&#8230; <span id="more-38"></span></p>
<blockquote><p>Reason #1: &#8220;Whitespace done right&#8221; is actually a good thing</p></blockquote>
<p>The first thing that people either absolutely love or adamantly hate about Python is the fact that code blocks are heavily tied to proper usage of whitespace. At first glance, this causes many curious onlookers from other languages to shy away from Python and continue in their bracket-encapsulated bondage. I&#8217;ll admit, at first I wasn&#8217;t too wild about these new restrictions either (I&#8217;m a programmer—I should be able to do my code how I want!); but the first time I had to go back to doing something in PHP for a client, I quickly realized I didn&#8217;t ever want to put anything inside brackets again:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># A sample function that's free from brackets, parenthesis, and semicolons!</span>
<span style="color: #ff7700;font-weight:bold;">def</span> check_number<span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">type</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= <span style="color: #008000;">type</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;That isn't a number!&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">elif</span> x <span style="color: #66cc66;">%</span> <span style="color: #ff4500;">2</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;This number is odd&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;This number is even&quot;</span></pre></div></div>

<p>Not only does this make Python source code incredibly readable, but you also end up typing less!</p>
<blockquote><p>Reason #2: I almost always know what type of object I&#8217;m working with</p></blockquote>
<p>One thing that always annoyed me about Perl was that you set an array or hash using the &#8216;@&#8217; or &#8216;%&#8217; sigils, but typically accessed them using the &#8216;$&#8217; sigil. PHP simplified this a bit, but &#8220;$array = array();&#8221; could be a simple list or an associative array (known as a dictionary in Python). With Python on the other hand, the enclosure defines the type (for most built-in types at least), and since everything is an object there&#8217;s no need for silly sigils:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># the type of enclosure makes a distinction between a string , a list, and a dictionary</span>
<span style="color: #dc143c;">string</span> = <span style="color: #483d8b;">'This is a string'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">string</span> <span style="color: #808080; font-style: italic;"># prints 'This is a string'</span>
&nbsp;
<span style="color: #008000;">list</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'This'</span>, <span style="color: #483d8b;">'is'</span>, <span style="color: #483d8b;">'a'</span>, <span style="color: #483d8b;">'list'</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">list</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 'This'</span>
&nbsp;
<span style="color: #008000;">dict</span> = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'first_key'</span>: <span style="color: #483d8b;">'This'</span>, <span style="color: #483d8b;">'second_key'</span>: <span style="color: #483d8b;">'is'</span>, <span style="color: #483d8b;">'third_key'</span>: <span style="color: #483d8b;">'a'</span>, <span style="color: #483d8b;">'fourth_key'</span>: <span style="color: #483d8b;">'dictionary'</span><span style="color: black;">&#125;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">dict</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'fourth_key'</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 'dictionary'</span></pre></div></div>

<p>On a somewhat related note, you can use these objects on-the-fly in your scripts without even having to assign them to a name. This isn&#8217;t usually practical of course (and may not be recommended), but it is possible:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">'This'</span>, <span style="color: #483d8b;">'is'</span>, <span style="color: #483d8b;">'a'</span>, <span style="color: #483d8b;">'list'</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 'is'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'first_key'</span>: <span style="color: #483d8b;">'This'</span>, <span style="color: #483d8b;">'second_key'</span>: <span style="color: #483d8b;">'is'</span>, <span style="color: #483d8b;">'third_key'</span>: <span style="color: #483d8b;">'a'</span>, <span style="color: #483d8b;">'fourth_key'</span>: <span style="color: #483d8b;">'dictionary'</span><span style="color: black;">&#125;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'first_key'</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 'This'</span></pre></div></div>

<blockquote><p>Reason #3: I can throw practically any type of object almost anywhere I want</p></blockquote>
<p>Ok, so that might be a slight exaggeration; but the truth is that since Python treats everything as an object, you&#8217;re free to pack things away in the strangest places. A great way of demonstrating the power and flexibility of Python is in an example showing a few ways different types of objects can be stored and accessed:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># create a function</span>
<span style="color: #ff7700;font-weight:bold;">def</span> hello_function<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">'Hello world!'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># create a file handle</span>
hello_file = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'~/hello.txt'</span>, <span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># create a list with the function, the file handle, and a string</span>
<span style="color: #008000;">list</span> = <span style="color: black;">&#91;</span>hello_function, hello_file, <span style="color: #483d8b;">'Hello world!'</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">list</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># prints 'Hello world!'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">list</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># prints 'Hello world!\n'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">list</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 'Hello world!'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># or how about a dictionary?</span>
<span style="color: #008000;">dict</span> = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'function'</span>: hello_function, <span style="color: #483d8b;">'file_object'</span>: hello_file, <span style="color: #483d8b;">'string'</span>: <span style="color: #483d8b;">'Hello world!'</span><span style="color: black;">&#125;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">dict</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'function'</span><span style="color: black;">&#93;</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># prints 'Hello world!'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">dict</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'file_object'</span><span style="color: black;">&#93;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># prints 'Hello world!\n'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">dict</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'string'</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 'Hello world!'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># print types</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">type</span><span style="color: black;">&#40;</span><span style="color: #008000;">list</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># prints &lt;type 'function'&gt;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">type</span><span style="color: black;">&#40;</span><span style="color: #008000;">dict</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'file_object'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># prints &lt;type 'file'&gt;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">type</span><span style="color: black;">&#40;</span><span style="color: #008000;">list</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># prints &lt;type 'str'&gt; (str for string)</span></pre></div></div>

<p>The <em>shelve</em> and <em>pickle</em> modules are also work a look if you like what you&#8217;ve just seen here.</p>
<blockquote><p>Reason #4: The &#8220;in&#8221; operator simplifies sequences and makes membership testing a breeze</p></blockquote>
<p>To explain the power of &#8220;in&#8221;, it&#8217;s probably easier to just show you a few examples:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #483d8b;">'p'</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #483d8b;">&quot;spam&quot;</span> <span style="color: #808080; font-style: italic;"># == True</span>
<span style="color: #483d8b;">'item1'</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">'item1'</span>, <span style="color: #483d8b;">'item2'</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># == True</span>
<span style="color: #483d8b;">'key'</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;key&quot;</span>: <span style="color: #483d8b;">'value'</span><span style="color: black;">&#125;</span> <span style="color: #808080; font-style: italic;"># == True</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># prints anchor tags for a navigation</span>
<span style="color: #ff7700;font-weight:bold;">for</span> title, link <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'Home'</span>: <span style="color: #483d8b;">'index.html'</span>, <span style="color: #483d8b;">'About'</span>: <span style="color: #483d8b;">'about.html'</span>, <span style="color: #483d8b;">'Contact'</span>: <span style="color: #483d8b;">'contact.html'</span><span style="color: black;">&#125;</span>.<span style="color: black;">iteritems</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'&lt;a href=&quot;%s&quot;&gt;%s&lt;/a&gt;'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>link, title<span style="color: black;">&#41;</span></pre></div></div>

<blockquote><p>Reason #5: Slicing, stepping, and striding are a walk in the park</p></blockquote>
<p>Probably my most-hated function in PHP is the substr() function. It should just be easier to access a parts of a string. Thankfully, in Python it&#8217;s a piece of cake:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#string slices and stepping/striding</span>
<span style="color: #dc143c;">string</span> = <span style="color: #483d8b;">'This is a string'</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">string</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 's'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">string</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">5</span>:<span style="color: #ff4500;">9</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 'is a'</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">string</span><span style="color: black;">&#91;</span>::<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints 'Ti sasrn' (a stride of 2 means print every other item)</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># works on lists and dictionaries as well</span>
<span style="color: #008000;">list</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'This'</span>, <span style="color: #483d8b;">'is'</span>, <span style="color: #483d8b;">'a'</span>, <span style="color: #483d8b;">'list'</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">list</span><span style="color: black;">&#91;</span>::<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># prints ['This', 'a']</span></pre></div></div>

<blockquote><p>Reason #6-XX: Python makes programming fun again!</p></blockquote>
<p>I could go on and on, but this post would be endless. As you can see, Python is a flexible, powerful, and fun programming language. For more Python concepts (I didn&#8217;t have time here to go into list comprehensions, generators, decorators, etc), I&#8217;d suggest you take a gander at Wikipedia&#8217;s page on <a href="http://en.wikipedia.org/wiki/Python_syntax_and_semantics" target="_blank">Python syntax and semantics</a>.</p>
<p>Finally, I&#8217;ll leave you with a few relevant links that are worth taking the time to check out:</p>
<ul>
<li>Bruce Eckel&#8217;s slides: <a href="http://www.mindviewinc.com/downloads/pub/eckel/LovePython.zip" target="_blank">Why I Love Python</a></li>
<li><a href="http://docs.python.org/tutorial/" target="_blank">Python&#8217;s official tutorial</a> (by Guido&mdash;Python&#8217;s creator)</li>
<li><a href="http://diveintopython.org/" target="_blank">Dive Into Python</a> &#8211; Free online book</li>
<li><a href="http://xkcd.com/353/" target="_blank">xkcd&#8217;s famous Python comic</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.curiasolutions.com/2009/07/why-ive-fallen-in-love-with-python/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Making TurboGears and Authorize.net play nice together</title>
		<link>http://blog.curiasolutions.com/2009/07/making-turbogears-and-authorize-net-play-nice-together/</link>
		<comments>http://blog.curiasolutions.com/2009/07/making-turbogears-and-authorize-net-play-nice-together/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 19:18:49 +0000</pubDate>
		<dc:creator>Seth</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[turbogears]]></category>

		<guid isPermaLink="false">http://blog.curiasolutions.com/?p=40</guid>
		<description><![CDATA[I recently had to wire up an Authorize.net form for a TurboGears project I&#8217;m building, and since I&#8217;m a bit new to custom form validation in TG I had quite a bit of trouble figuring out the &#8220;right&#8221; way to do it.
The goal was to get the form to go through two layers of validation [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had to wire up an Authorize.net form for a TurboGears project I&#8217;m building, and since I&#8217;m a bit new to custom form validation in TG I had quite a bit of trouble figuring out the &#8220;right&#8221; way to do it.</p>
<p>The goal was to get the form to go through two layers of validation before passing:</p>
<ol>
<li>Use the validation packages provided by TG (<a href="http://toscawidgets.org/" target="_blank">tw.forms</a> and <a href="http://www.formencode.org/" target="_blank">formencode</a>)</li>
<li>If the first layer of validation passes, try to run the authorize.net charge. If this returns a response code of 1 (approved) then all validation has passed. Otherwise, invalidate the form and flash the authorize.net error.</li>
</ol>
<p>tw.forms and formencode are awesome packages, but at first glance there didn&#8217;t seem to be &#8220;one obvious way&#8221; to do things. I found the documentation and tutorials to be scant at best, and eventually went to the <a href="http://groups.google.com/group/turbogears" target="_blank">TurboGears mailing list</a> for help. In spite of the fact that I&#8217;d probably give TurboGears a &#8220;C&#8221; <em>at best</em> for its documentation (not to mention the availability of &#8220;verbose&#8221; tutorials), the folks on the mailing list and IRC channel (when it&#8217;s actually active) seem to be quite helpful.</p>
<p>Eventually (and with additional help from Google&#8217;s <a href="http://www.google.com/codesearch" target="_blank">source code search</a>) I was able to hack together something that worked as planned, and was overjoyed to observe chained validators in action. Below is some example code provided for your hacking pleasure. To download the full example file, see the links at the bottom of the post.<span id="more-40"></span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># FancyValidator to process the Credit Card using the authorize package</span>
<span style="color: #ff7700;font-weight:bold;">class</span> ProcessCard<span style="color: black;">&#40;</span>validators.<span style="color: black;">FancyValidator</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> _to_python<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, value, state<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">from</span> authorize <span style="color: #ff7700;font-weight:bold;">import</span> aim <span style="color: #ff7700;font-weight:bold;">as</span> aim_api
&nbsp;
        <span style="color: #808080; font-style: italic;"># Setup the aim Api object.</span>
        aim = aim_api.<span style="color: black;">Api</span><span style="color: black;">&#40;</span>AUTHNET_LOGIN, AUTHNET_KEY, is_test=<span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Create a transaction against a credit card</span>
        result_dict = aim.<span style="color: black;">transaction</span><span style="color: black;">&#40;</span>
            amount=u<span style="color: #483d8b;">&quot;16.00&quot;</span>,
            card_num=<span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#91;</span><span style="color: #483d8b;">'card_number'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>,
            exp_date=<span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#91;</span><span style="color: #483d8b;">'card_expiry'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>,
            <span style="color: #808080; font-style: italic;"># ...and others...</span>
            <span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">if</span> result_dict<span style="color: black;">&#91;</span><span style="color: #483d8b;">'code'</span><span style="color: black;">&#93;</span> == <span style="color: #483d8b;">'1'</span>:
            <span style="color: #808080; font-style: italic;"># success</span>
            <span style="color: #ff7700;font-weight:bold;">return</span> value
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #808080; font-style: italic;"># failure</span>
            <span style="color: #ff7700;font-weight:bold;">raise</span> validators.<span style="color: black;">Invalid</span><span style="color: black;">&#40;</span>result_dict<span style="color: black;">&#91;</span><span style="color: #483d8b;">'reason_text'</span><span style="color: black;">&#93;</span>, value, state<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> AuthnetForm<span style="color: black;">&#40;</span>TableForm<span style="color: black;">&#41;</span>:
    submit_text=<span style="color: #483d8b;">'Process Card'</span>
&nbsp;
    validator = validators.<span style="color: black;">Schema</span><span style="color: black;">&#40;</span>
        chained_validators = <span style="color: black;">&#91;</span>
            validators.<span style="color: black;">CreditCardValidator</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'card_type'</span>,<span style="color: #483d8b;">'card_number'</span><span style="color: black;">&#41;</span>,
            validators.<span style="color: black;">CreditCardSecurityCode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'card_type'</span>,<span style="color: #483d8b;">'card_cvv'</span><span style="color: black;">&#41;</span>,
            <span style="color: #808080; font-style: italic;"># you could also add an expiry validator, but authnet will handle this for you</span>
            ProcessCard<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: black;">&#93;</span>
    <span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">class</span> fields<span style="color: black;">&#40;</span>WidgetsList<span style="color: black;">&#41;</span>:
        name = TextField<span style="color: black;">&#40;</span>validator=validators.<span style="color: black;">String</span><span style="color: black;">&#40;</span>not_empty=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #808080; font-style: italic;"># ...and others like address, city, state, zip...</span>
        spacer = Spacer<span style="color: black;">&#40;</span>suppress_label=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
        card_type = SingleSelectField<span style="color: black;">&#40;</span>options=<span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'visa'</span>, <span style="color: #483d8b;">'Visa'</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #483d8b;">'mastercard'</span>, <span style="color: #483d8b;">'Master Card'</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #483d8b;">'discover'</span>, <span style="color: #483d8b;">'Discover'</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #483d8b;">'amex'</span>, <span style="color: #483d8b;">'American Express'</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>, validator=validators.<span style="color: black;">NotEmpty</span><span style="color: black;">&#41;</span>
        card_expiry = CalendarDatePicker<span style="color: black;">&#40;</span>date_format=<span style="color: #483d8b;">&quot;%m/%Y&quot;</span>, validator=validators.<span style="color: black;">NotEmpty</span><span style="color: black;">&#41;</span>
        card_number = TextField<span style="color: black;">&#40;</span>label_text=<span style="color: #483d8b;">'Card #'</span>, validator=validators.<span style="color: black;">NotEmpty</span><span style="color: black;">&#41;</span>
        card_cvv = TextField<span style="color: black;">&#40;</span>label_text=<span style="color: #483d8b;">'CVV Code'</span>, validator=validators.<span style="color: black;">NotEmpty</span><span style="color: black;">&#41;</span>
&nbsp;
authnet_form = AuthnetForm<span style="color: black;">&#40;</span><span style="color: #483d8b;">'authnet_form'</span>, action=url<span style="color: black;">&#40;</span><span style="color: #483d8b;">'/authnet/process/'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Links of interest:</p>
<ul>
<li><a href="http://blog.curiasolutions.com/wp-content/uploads/2009/07/authnet.py">Download the authnet.py file</a></li>
<li><a href="http://groups.google.com/group/turbogears/t/c721e2d15bb2c134" target="_blank">This post&#8217;s original Google group thread</a></li>
<li><a href="http://www.adroll.com/labs" target="_blank">The Authorize package</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.curiasolutions.com/2009/07/making-turbogears-and-authorize-net-play-nice-together/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing TurboGears 2</title>
		<link>http://blog.curiasolutions.com/2009/06/turbogears-2/</link>
		<comments>http://blog.curiasolutions.com/2009/06/turbogears-2/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 02:43:00 +0000</pubDate>
		<dc:creator>Seth</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[turbogears]]></category>

		<guid isPermaLink="false">http://blog.curiasolutions.com/?p=3</guid>
		<description><![CDATA[I&#8217;m the type of person who is a bit anal about trying to use what I think is &#8220;the right tool for the job.&#8221; This is something I think my Dad passed down to me (I can&#8217;t tell you how many times I was scolded with that phrase as a kid—usually having something to do [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m the type of person who is a bit anal about trying to use what I think is &#8220;the right tool for the job.&#8221; This is something I think my Dad passed down to me (I can&#8217;t tell you how many times I was scolded with that phrase as a kid—usually having something to do with me trying to hammer an object with anything but a hammer); and it influences my world of development heavily. Because of this, I often find myself using a number of different programming languages and technologies at any given time for various projects. A shell script is perfect when you need something quick &amp; dirty. PHP makes adding logic to HTML a piece of cake. And then there&#8217;s my new personal favorite: Python.</p>
<p>Ok, let me back up before I get ahead of myself&#8230;<span id="more-3"></span></p>
<p>I&#8217;ve been a web developer for over 10 years now. When it comes to web programming languages and platforms, I&#8217;ve been around the block a bit: Back in the 90s I was building shopping carts from scratch using Perl (ouch!). From Perl, I eventually migrated to PHP which usually made things much easier. From time to time I would play around with Rails; but I never could stomach Ruby&#8217;s syntax (I think it reminded me too much of Perl). Even though I never felt like I really &#8220;clicked&#8221; with PHP, I eventually settled into a few PHP frameworks I liked and finally called myself a PHP developer.</p>
<p>Then one day I stumbled across Python, and it was love at first sight. I quickly vowed that I would soon be doing 99% of my web development in my newfound favorite language, but was disappointed to discover that (at that time) the available web frameworks were either ugly or poorly documented/supported. Reluctantly I returned to PHP, unable to justify moving away from the &#8220;quick &amp; simple&#8221; nature of what I was used to with PHP and the frameworks I was used to.</p>
<p>I&#8217;m not one to give up easily though, and on a recent &#8220;re-visit&#8221; of the Python web framework scene I was excited to see that things had changed dramatically: Django&#8217;s community had exploded and its documentation looked rock-solid. Pylons had cropped up as a serious WSGI-based contender (and modeling quite a bit of it&#8217;s functionality after Rails). But what really caught my attention was the (at the time) upcoming TurboGears v2.0 release.</p>
<p>What made TG2 stand out to me was its attempt to build a &#8220;best-of-breed&#8221; module-set on top of Pylons. Mark Ramm (the current leader of TG development) has been quoted as comparing TG2 to Ubuntu in that  &#8220;TG 2 is to Pylons as Ubuntu is to Debian.&#8221; The sound of that intrigued me, and I started playing around with the TG 2 Betas (and liking what I was seeing!).</p>
<p>Recently one of my clients asked me to whip up a medium-sized project with various amounts of CRUD and Ajax. Ironically, that very same day TurboGears&#8217; v2.0 release went gold. Seeing this as my opportunity to finally begin transitioning into the Python world with a stable &#8220;next-generation&#8221; Python web-development framework, I have decided to implement my latest project using TurboGears 2. Could this be the beginning of the rest of my life?</p>
<p>I will keep you posted on my progress and what I encounter along the way (good, bad, and ugly). Keep it here for what will likely be an interesting adventure.</p>
<p>&nbsp;</p>
<p>Related links of interest:</p>
<ul>
<li><a href="http://www.turbogears.com/2.0" target="_blank">TurboGears</a></li>
<li><a href="http://www.linuxjournal.com/content/introducing-three-python-web-frameworks" target="_blank">Introducing Three Python Web Frameworks</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.curiasolutions.com/2009/06/turbogears-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
