<?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>The Mouse Vs. The Python</title>
	<atom:link href="http://www.blog.pythonlibrary.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.blog.pythonlibrary.org</link>
	<description>Python Programming from the Frontlines</description>
	<lastBuildDate>Tue, 09 Mar 2010 15:23:59 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>A Simple Step-by-Step Reportlab Tutorial</title>
		<link>http://www.blog.pythonlibrary.org/2010/03/08/a-simple-step-by-step-reportlab-tutorial/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/03/08/a-simple-step-by-step-reportlab-tutorial/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 01:03:23 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Python PDF Series]]></category>
		<category><![CDATA[Reportlab]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=668</guid>
		<description><![CDATA[The subtitle for this article could easily be &#8220;How To Create PDFs with Python&#8221;, but WordPress doesn&#8217;t support that. Anyway, the premier PDF library in Python is Reportlab. It is not distributed with that standard library, so you&#8217;ll need to download it if you want to run the examples in this tutorial. There will also [...]]]></description>
			<content:encoded><![CDATA[<p>The subtitle for this article could easily be &#8220;How To Create PDFs with Python&#8221;, but WordPress doesn&#8217;t support that. Anyway, the premier PDF library in Python is <a href="http://www.reportlab.com/software/opensource/rl-toolkit/download/">Reportlab</a>. It is not distributed with that standard library, so you&#8217;ll need to download it if you want to run the examples in this tutorial. There will also be at least one example of how to put an image into a PDF, which means you&#8217;ll also need the <a href="http://www.pythonware.com/products/pil/">Python Image Library</a> (PIL). As I understand it, Reportlab is compatible with Python 2.x, <a href="http://ironpython.net/">IronPython</a> and <a href="http://www.jython.org/">Jython</a>. They are currently working on a port for Python 3.x (or will be soon).<span id="more-668"></span></p>
<h2>Installation</h2>
<p>Reportlab supports most of the normal Python installation methods. You have the option of downloading the source and running &#8220;python setup.py install&#8221; or running a binary installer (on Windows). There was a recent thread on their mailing list that seemed to indicate that they may also support <a href="http://pypi.python.org/pypi/pip">pip</a> soon. The threads I&#8217;ve read about Reportlab&#8217;s support of easy_install are confusing, so I&#8217;m not sure if they already support that method or not.</p>
<h2>Creating a Simple PDF</h2>
<p>Reportlab has decent documentation. What I mean by that is that the documentation gives you just enough to get started, but when you find something slightly complex to do, you get to figure it out on your own. Just recently, they added a <a href="http://www.reportlab.com/snippets/">Code Snippets</a> section to their website that will hopefully become a recipe book of cool tips and tricks and also help ameliorate this issue. But enough about that. Let&#8217;s see how to actually create something!</p>
<p>In Reportlab, the lowest-level component that&#8217;s used regularly is the <em>canvas</em> object from the <em>pdfgen</em> package. The functions in this package allow you to &#8220;paint&#8221; a document with your text, images, lines or whatever. I&#8217;ve heard some people describe this as writing in PostScript. I doubt it&#8217;s really that bad. In my experience, it&#8217;s actually a lot like using a GUI toolkit to layout widgets in specific locations. Let&#8217;s see how the canvas object works:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> reportlab.<span style="color: black;">pdfgen</span> <span style="color: #ff7700;font-weight:bold;">import</span> canvas
&nbsp;
c = canvas.<span style="color: black;">Canvas</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;hello.pdf&quot;</span><span style="color: black;">&#41;</span>
c.<span style="color: black;">drawString</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">100</span>,<span style="color: #ff4500;">750</span>,<span style="color: #483d8b;">&quot;Welcome to Reportlab!&quot;</span><span style="color: black;">&#41;</span>
c.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>You should end up with a PDF that looks something like this:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/03/hello-pdf-screenshot.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/03/hello-pdf-screenshot-300x184.png" alt="" title="hello-pdf-screenshot" width="300" height="184" class="aligncenter size-medium wp-image-672" /></a></p>
<p>The first thing to notice about this code is that if we want to save the PDF, we need to supply a file name to the Canvas object. This can be an absolute path or a relative path. In this example, it should create the PDF in the same location that you run the script from. The next piece of the puzzle is the <em>drawString</em> method. This will draw text wherever you tell it to. When using the canvas object, it starts at the bottom left of the page, so for this example, we told it to draw the string 100 points from the left margin and 750 points from the bottom of the page (1 point = 1/72 inch). You can change this default in the Canvas constructor by passing a zero to the <em>bottomup </em>keyword argument. However, I&#8217;m not exactly sure what will happen if you do that as the Reportlab user guide isn&#8217;t clear on this topic. I think it will change the start point to the top left though. The final piece in the code above is to save your PDF.</p>
<p>That was easy! You&#8217;ve just created a really simple PDF! Note that the default Canvas size is A4, so if you happen to be American, you&#8217;ll probably want to change that to letter size. This is easy to do in Reportlab. All you need to do is the following:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> reportlab.<span style="color: black;">lib</span>.<span style="color: black;">pagesizes</span> <span style="color: #ff7700;font-weight:bold;">import</span> letter
<span style="color: #ff7700;font-weight:bold;">from</span> reportlab.<span style="color: black;">pdfgen</span> <span style="color: #ff7700;font-weight:bold;">import</span> canvas
&nbsp;
canvas = canvas.<span style="color: black;">Canvas</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'myfile.pdf'</span>, pagesize=letter<span style="color: black;">&#41;</span>
width, height = letter</pre>
<p>The main reason to grab the width and height is that you can use them for calculations to decide when to add a page break or help define margins. Let&#8217;s take a quick look at the constructor for the Canvas object to see what other options we have:</p>
<pre class="python"><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>,filename,
    pagesize=letter,
    bottomup = <span style="color: #ff4500;">1</span>,
    pageCompression=<span style="color: #ff4500;">0</span>,
    encoding=rl_config.<span style="color: black;">defaultEncoding</span>,
    verbosity=<span style="color: #ff4500;">0</span>
    encrypt=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:</pre>
<p>The above was pulled directly from the <a href="http://www.reportlab.com/docs/reportlab-userguide.pdf">Reportlab User Guide</a>, page 11. You can read about the other options in their guide if you want the full details. </p>
<p>Now let&#8217;s do something a little more complicated and useful.</p>
<h2>A Little Form, Little Function</h2>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/03/pdf-partial-form.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/03/pdf-partial-form-300x88.png" alt="" title="pdf-partial-form" width="300" height="88" class="aligncenter size-medium wp-image-677" /></a></p>
<p>In this example, we&#8217;ll create a partial printable form. As far as I can tell, Reportlab doesn&#8217;t support the fillable forms that were added to Adobe products a few years ago. Anyway, let&#8217;s take a look at some code!</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> reportlab.<span style="color: black;">lib</span>.<span style="color: black;">pagesizes</span> <span style="color: #ff7700;font-weight:bold;">import</span> letter
<span style="color: #ff7700;font-weight:bold;">from</span> reportlab.<span style="color: black;">pdfgen</span> <span style="color: #ff7700;font-weight:bold;">import</span> canvas
&nbsp;
canvas = canvas.<span style="color: black;">Canvas</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;form.pdf&quot;</span>, pagesize=letter<span style="color: black;">&#41;</span>
canvas.<span style="color: black;">setLineWidth</span><span style="color: black;">&#40;</span>.<span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
canvas.<span style="color: black;">setFont</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Helvetica'</span>, <span style="color: #ff4500;">12</span><span style="color: black;">&#41;</span>
&nbsp;
canvas.<span style="color: black;">drawString</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">30</span>,<span style="color: #ff4500;">750</span>,<span style="color: #483d8b;">'OFFICIAL COMMUNIQUE'</span><span style="color: black;">&#41;</span>
canvas.<span style="color: black;">drawString</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">30</span>,<span style="color: #ff4500;">735</span>,<span style="color: #483d8b;">'OF ACME INDUSTRIES'</span><span style="color: black;">&#41;</span>
canvas.<span style="color: black;">drawString</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">500</span>,<span style="color: #ff4500;">750</span>,<span style="color: #483d8b;">&quot;12/12/2010&quot;</span><span style="color: black;">&#41;</span>
canvas.<span style="color: black;">line</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">480</span>,<span style="color: #ff4500;">747</span>,<span style="color: #ff4500;">580</span>,<span style="color: #ff4500;">747</span><span style="color: black;">&#41;</span>
&nbsp;
canvas.<span style="color: black;">drawString</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">275</span>,<span style="color: #ff4500;">725</span>,<span style="color: #483d8b;">'AMOUNT OWED:'</span><span style="color: black;">&#41;</span>
canvas.<span style="color: black;">drawString</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">500</span>,<span style="color: #ff4500;">725</span>,<span style="color: #483d8b;">&quot;$1,000.00&quot;</span><span style="color: black;">&#41;</span>
canvas.<span style="color: black;">line</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">378</span>,<span style="color: #ff4500;">723</span>,<span style="color: #ff4500;">580</span>,<span style="color: #ff4500;">723</span><span style="color: black;">&#41;</span>
&nbsp;
canvas.<span style="color: black;">drawString</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">30</span>,<span style="color: #ff4500;">703</span>,<span style="color: #483d8b;">'RECEIVED BY:'</span><span style="color: black;">&#41;</span>
canvas.<span style="color: black;">line</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">120</span>,<span style="color: #ff4500;">700</span>,<span style="color: #ff4500;">580</span>,<span style="color: #ff4500;">700</span><span style="color: black;">&#41;</span>
canvas.<span style="color: black;">drawString</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">120</span>,<span style="color: #ff4500;">703</span>,<span style="color: #483d8b;">&quot;JOHN DOE&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
canvas.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>This is based on an actual receipt I created at work. The main difference between this one and the previous example is the <em>canvas.line</em> code. You can use it to draw lines on your documents by passing two X/Y pairs. I&#8217;ve used this functionality to create grids, although it&#8217;s pretty tedious. Other points of interest in this code include the setLineWidth(.3) command, which tells Reportlab how thick or thin the line should be; and the setFont(&#8216;Helvetica&#8217;, 12) command, which allows us to specify a specific font and point size. </p>
<p>Our next example will build on what we&#8217;ve learned so far, but also introduce us to the concept of &#8220;flowables&#8221;.</p>
<h2>Going with the Flow</h2>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/03/pdf-form-letter.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/03/pdf-form-letter-300x246.png" alt="" title="pdf-form-letter" width="300" height="246" class="aligncenter size-medium wp-image-678" /></a></p>
<p>If you&#8217;re in advertising or do any kind of work with form letters, then Reportlab makes for an excellent addition to your arsenal. We use it to create form letters for people who have overdue parking tickets. The following example is based on some code I wrote for that application, although the letter is quite a bit different. (Note that the code below will not run without the Python Image Library)</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
<span style="color: #ff7700;font-weight:bold;">from</span> reportlab.<span style="color: black;">lib</span>.<span style="color: black;">enums</span> <span style="color: #ff7700;font-weight:bold;">import</span> TA_JUSTIFY
<span style="color: #ff7700;font-weight:bold;">from</span> reportlab.<span style="color: black;">lib</span>.<span style="color: black;">pagesizes</span> <span style="color: #ff7700;font-weight:bold;">import</span> letter
<span style="color: #ff7700;font-weight:bold;">from</span> reportlab.<span style="color: black;">platypus</span> <span style="color: #ff7700;font-weight:bold;">import</span> SimpleDocTemplate, Paragraph, Spacer, Image
<span style="color: #ff7700;font-weight:bold;">from</span> reportlab.<span style="color: black;">lib</span>.<span style="color: black;">styles</span> <span style="color: #ff7700;font-weight:bold;">import</span> getSampleStyleSheet, ParagraphStyle
<span style="color: #ff7700;font-weight:bold;">from</span> reportlab.<span style="color: black;">lib</span>.<span style="color: black;">units</span> <span style="color: #ff7700;font-weight:bold;">import</span> inch
&nbsp;
doc = SimpleDocTemplate<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;form_letter.pdf&quot;</span>,pagesize=letter,
                        rightMargin=<span style="color: #ff4500;">72</span>,leftMargin=<span style="color: #ff4500;">72</span>,
                        topMargin=<span style="color: #ff4500;">72</span>,bottomMargin=<span style="color: #ff4500;">18</span><span style="color: black;">&#41;</span>
Story=<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
logo = <span style="color: #483d8b;">&quot;python_logo.png&quot;</span>
magName = <span style="color: #483d8b;">&quot;Pythonista&quot;</span>
issueNum = <span style="color: #ff4500;">12</span>
subPrice = <span style="color: #483d8b;">&quot;99.00&quot;</span>
limitedDate = <span style="color: #483d8b;">&quot;03/05/2010&quot;</span>
freeGift = <span style="color: #483d8b;">&quot;tin foil hat&quot;</span>
&nbsp;
formatted_time = <span style="color: #dc143c;">time</span>.<span style="color: black;">ctime</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
full_name = <span style="color: #483d8b;">&quot;Mike Driscoll&quot;</span>
address_parts = <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;411 State St.&quot;</span>, <span style="color: #483d8b;">&quot;Marshalltown, IA 50158&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
im = Image<span style="color: black;">&#40;</span>logo, <span style="color: #ff4500;">2</span><span style="color: #66cc66;">*</span>inch, <span style="color: #ff4500;">2</span><span style="color: #66cc66;">*</span>inch<span style="color: black;">&#41;</span>
Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>im<span style="color: black;">&#41;</span>
&nbsp;
styles=getSampleStyleSheet<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
styles.<span style="color: black;">add</span><span style="color: black;">&#40;</span>ParagraphStyle<span style="color: black;">&#40;</span>name=<span style="color: #483d8b;">'Justify'</span>, alignment=TA_JUSTIFY<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
ptext = <span style="color: #483d8b;">'&lt;font size=12&gt;%s&lt;/font&gt;'</span> <span style="color: #66cc66;">%</span> formatted_time
&nbsp;
Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Paragraph<span style="color: black;">&#40;</span>ptext, styles<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Normal&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Spacer<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">12</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Create return address</span>
ptext = <span style="color: #483d8b;">'&lt;font size=12&gt;%s&lt;/font&gt;'</span> <span style="color: #66cc66;">%</span> full_name
Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Paragraph<span style="color: black;">&#40;</span>ptext, styles<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Normal&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> part <span style="color: #ff7700;font-weight:bold;">in</span> address_parts:
    ptext = <span style="color: #483d8b;">'&lt;font size=12&gt;%s&lt;/font&gt;'</span> <span style="color: #66cc66;">%</span> part.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Paragraph<span style="color: black;">&#40;</span>ptext, styles<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Normal&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Spacer<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">12</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
ptext = <span style="color: #483d8b;">'&lt;font size=12&gt;Dear %s:&lt;/font&gt;'</span> <span style="color: #66cc66;">%</span> full_name.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Paragraph<span style="color: black;">&#40;</span>ptext, styles<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Normal&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Spacer<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">12</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
ptext = <span style="color: #483d8b;">'&lt;font size=12&gt;We would like to welcome you to our subscriber base for %s Magazine! <span style="color: #000099; font-weight: bold;">\</span>
        You will receive %s issues at the excellent introductory price of $%s. Please respond by<span style="color: #000099; font-weight: bold;">\</span>
        %s to start receiving your subscription and get the following free gift: %s.&lt;/font&gt;'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>magName,
                                                                                                issueNum,
                                                                                                subPrice,
                                                                                                limitedDate,
                                                                                                freeGift<span style="color: black;">&#41;</span>
Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Paragraph<span style="color: black;">&#40;</span>ptext, styles<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Justify&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Spacer<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">12</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
ptext = <span style="color: #483d8b;">'&lt;font size=12&gt;Thank you very much and we look forward to serving you.&lt;/font&gt;'</span>
Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Paragraph<span style="color: black;">&#40;</span>ptext, styles<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Justify&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Spacer<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">12</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
ptext = <span style="color: #483d8b;">'&lt;font size=12&gt;Sincerely,&lt;/font&gt;'</span>
Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Paragraph<span style="color: black;">&#40;</span>ptext, styles<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Normal&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Spacer<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">48</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
ptext = <span style="color: #483d8b;">'&lt;font size=12&gt;Ima Sucker&lt;/font&gt;'</span>
Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Paragraph<span style="color: black;">&#40;</span>ptext, styles<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Normal&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Spacer<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">12</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
doc.<span style="color: black;">build</span><span style="color: black;">&#40;</span>Story<span style="color: black;">&#41;</span></pre>
<p>Well, that&#8217;s a lot more code than our previous examples contained. We&#8217;ll need to look over it slowly to understand everything that&#8217;s going on. When you&#8217;re ready, just continue reading.</p>
<p>The first part that we need to look at are the new imports:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> reportlab.<span style="color: black;">lib</span>.<span style="color: black;">enums</span> <span style="color: #ff7700;font-weight:bold;">import</span> TA_JUSTIFY
<span style="color: #ff7700;font-weight:bold;">from</span> reportlab.<span style="color: black;">platypus</span> <span style="color: #ff7700;font-weight:bold;">import</span> SimpleDocTemplate, Paragraph, Spacer, Image
<span style="color: #ff7700;font-weight:bold;">from</span> reportlab.<span style="color: black;">lib</span>.<span style="color: black;">styles</span> <span style="color: #ff7700;font-weight:bold;">import</span> getSampleStyleSheet, ParagraphStyle
<span style="color: #ff7700;font-weight:bold;">from</span> reportlab.<span style="color: black;">lib</span>.<span style="color: black;">units</span> <span style="color: #ff7700;font-weight:bold;">import</span> inch</pre>
<p>From enums, we import &#8220;TA_JUSTIFY&#8221;, which allows our strings to have the <em>justified </em>format. There are a number of other constants we could import that would allow us to right or left justify our text and do other fun things. Next is the platypus (which stands for Page Layout and Typography Using Scripts) module. It contains lots of modules, but probably the most important of them are the flowables, such as Paragraph. A flowable typically has the following abilities: <em>wrap</em>, <em>draw</em> and sometimes <em>split</em>. They are used to make writing paragraphs, tables and other constructs over multiple pages easier to do.</p>
<p>The SimpleDocTemplate class allows us to set up margins, page size, filename and a bunch of other settings for our document all in one place. A Spacer is good for adding a line of blank space, like a paragraph break. The Image class utilizes the Python Image Library to allow easy insertion and manipulation of images in your PDF. </p>
<p>The getSampleStyleSheet gets a set of default styles that we can use in our PDF. ParagraphStyle is used to set our paragraph&#8217;s text alignment in this example, but it can do much more than that (see page 67 of the user guide). Finally, the <em>inch</em> is a unit of measurement to help in positioning items on your PDF. You can see this in action where we position the logo: Image(logo, 2*inch, 2*inch). This means that the logo will be two inches from the top and two inches from the left.</p>
<p>I don&#8217;t recall the reason why Reportlab&#8217;s examples use a Story list, but that&#8217;s how we&#8217;ll do it here as well. Basically you create a line of text, a table, and image or whatever and append it to the Story list. You&#8217;ll see that throughout the entire example. The first time we use it is when we add the image. Before we look at the next instance, we&#8217;ll need to look at how we add a style to our styles object:</p>
<pre class="python">styles.<span style="color: black;">add</span><span style="color: black;">&#40;</span>ParagraphStyle<span style="color: black;">&#40;</span>name=<span style="color: #483d8b;">'Justify'</span>, alignment=TA_JUSTIFY<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre>
<p>The reason this is important is because you can use the style list to apply various paragraph alignment settings (and more) to text in your document. In the code above, we create a ParagraphStyle called &#8220;Justify&#8221;. All it does is justify our text. You&#8217;ll see an example of this later in the text. For now, let&#8217;s look at a quick example:</p>
<pre class="python">ptext = <span style="color: #483d8b;">'&lt;font size=12&gt;%s&lt;/font&gt;'</span> <span style="color: #66cc66;">%</span> formatted_time
Story.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Paragraph<span style="color: black;">&#40;</span>ptext, styles<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Normal&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre>
<p>For our first line of text, we use the Paragraph class. As you can see, the Paragraph class accepts some HTML-like tags. In this instance, we set the font&#8217;s point size to 12 and use the normal style (which is left aligned, among other things). The rest of the example is pretty much the same, just with Spacers thrown in here and there. At the end, we call <em>doc.build</em> to create the document.</p>
<h2>Wrapping Up</h2>
<p>Now you know the basics for creating PDFs in Python using Reportlab. We didn&#8217;t even scratch the surface of what all you can do with Reportlab though. Some examples include tables, graphs, paginating, color overprinting, hyperlinks, graphics and much more. I highly recommend that you download the module along with its user guide and give it a try!</p>
<p><b>Further Reading</b></p>
<ul>
<li><a href="http://www.reportlab.com/software/opensource/">Reportlab Home Page</a></li>
<li><a href="http://www.protocolostomy.com/2008/10/22/generating-reports-with-charts-using-python-reportlab/">Generating Reports with Charts</a></li>
<li><a href="http://stochasticgeometry.wordpress.com/2009/01/06/reportlab/">A series on Reportlab</a></li>
</ul>
<li><a href="http://www.magitech.org/2006/05/05/getting-started-with-reportlab/">Getting Started with Reportlab</a></li>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/03/08/a-simple-step-by-step-reportlab-tutorial/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Book Review: Python Testing</title>
		<link>http://www.blog.pythonlibrary.org/2010/03/06/book-review-python-testing/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/03/06/book-review-python-testing/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 16:01:08 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Book Review]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=663</guid>
		<description><![CDATA[Before PyCon, I was approached by a representative from Packt Publishing to review one of their books. They wanted me to read Daniel Arbuckle&#8217;s Python Testing: Beginner&#8217;s Guide. I&#8217;m not really into testing frameworks or test driven development and thought this would be a good excuse to learn the methodology and see if it was [...]]]></description>
			<content:encoded><![CDATA[<p>Before PyCon, I was approached by a representative from Packt Publishing to review one of their books. They wanted me to read Daniel Arbuckle&#8217;s <em><a href="http://www.amazon.com/Python-Testing-Beginners-Daniel-Arbuckle/dp/1847198848/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1267883216&#038;sr=8-1">Python Testing: Beginner&#8217;s Guide</a></em>. I&#8217;m not really into testing frameworks or test driven development and thought this would be a good excuse to learn the methodology and see if it was something that was actually valuable or just a lot of hype. The book is only 256 pages long, so I told the Packt contact that it would probably take me a week or so to review. After a week, she seemed kind of anxious that I wasn&#8217;t done. Thus, this is a partial review. I don&#8217;t like being pressured to review something fast. I want my reviews to be thorough and of the best quality I can make them. You will get a thorough review of the chapters that I did manage to finish. If you want a full review, I&#8217;m pretty sure someone else on Python Planet said they were doing one.<span id="more-663"></span></p>
<p>I read chapters 1-6 and then skimmed 7-10. The author writes in an engaging manner and the chapters are broken up into sections, which makes it easy to pick up, do a section, and put it back down without losing your place. The primary reason that I was slow to review this book is that it has lots of code examples and it takes quite a while to re-type them all. I hate technical books that are riddled with broken code, so I wanted to make sure that this book&#8217;s code and tests worked. If I review a book with lots of code in the future, I will insist on lots of time or an e-book copy so I can just copy and paste the code. </p>
<p>Anyway, the first couple of chapters went by with only minor errors in the text itself. The content was pretty good, but the editors missed simple stuff where the author used &#8220;white&#8221; instead of &#8220;write&#8221;. There are silly mistakes like this in most chapters. The real problems don&#8217;t happen until chapter 3, which is about creating unit tests with doctest. On page 45, there&#8217;s a code example that includes the following line:</p>
<pre class="python"><span style="color: #008000;">self</span>.<span style="color: black;">integrated_error</span> +q= err <span style="color: #66cc66;">*</span> delta</pre>
<p>Since the author recommends using Python 2.6, I thought that &#8220;+q=&#8221; might be some kind of new format that I was unaware of. But it&#8217;s just a typo. On page 48-50, he has a revised test from earlier in the chapter. The text clearly states that all revisions will be clearly marked. They are not and I was unable to find all the revisions to make the new version work. I didn&#8217;t want to re-type the entire thing in again, so I skipped it and decided to download the author&#8217;s code bundle from the publisher&#8217;s website.</p>
<p>Here is where things really went downhill for me. After getting the code, I noticed that the files and folders were not arranged by chapter, but by some other method. This made it very difficult to find what I was looking for. I eventually did find a chapters sub-folder in the &#8220;tests&#8221; folder (I think). My plan was to do a diff on that code versus mine. When I opened the book code though, I noticed that the author had included a bunch of mock tests in it. He doesn&#8217;t cover mock until chapter 4. I considered stopping here and just telling everyone I knew to avoid this book, but since I got it for free, I decided to soldier on.</p>
<p>Chapter 4 is on the <a href="http://labix.org/mocker">Python Mocker</a> package by Labix. This chapter was quite good and I think I learned a lot from it. The only downer was that the author mentioned that you could use easy_install to install this module and that by so doing, <a href="http://pypi.python.org/pypi/nose/0.11.3">Nose</a> would be ready to run. That was just plain dumb. Other than that, I thought this was a good chapter.</p>
<p>Chapter 5 introduced the reader to Python&#8217;s <a href="http://docs.python.org/library/unittest.html">unittest library</a>. I don&#8217;t recall if I tested all the code in this chapter or not, but I didn&#8217;t note anything that was wrong. I thought this was a good introduction to unittest, especially for a beginner. </p>
<p>For chapter 6, the topic is changed to Nose. As you may have noticed from my descriptions so far, the author is quite gradual in how he went through the topics. He started with doctests, moved to mock, then unittests and then Nose, which is kind of a test runner and enhancer. I had weird issues with Nose when I tried to easy_install it. For some reason, I ended up with the 0.10.1 version which didn&#8217;t work with all the commands in this book. Once I got the current version, everything worked better. I should note that I was unable to get the example on page 112 to pass nosetests. I have no idea what the problem is, although it has to do with the Python Mocker module. It may be that I mistyped something, but I couldn&#8217;t figure it out.</p>
<p>The author covers Nose&#8217;s configuration file briefly and goes over a few command line flags for nosetests. He also covers fixtures and how to use them to enhance your tests. Finally he shows how to use Nose&#8217;s pattern matching abilities to run tests that match a certain naming convention. Pretty cool stuff!</p>
<p>I started to skim in earnest after this chapter though. In seven, he does a step-by-step walk-through depicting how to test and create a personal scheduling program. I look forward to reading this section and seeing how complex or simple this is. There is certainly code aplenty in this section and lots of tests (or he may just be re-printing some of the examples in smaller parts for commentary). I have no idea if any of it is functional though.</p>
<p>In chapter 8, the book moves on to Web Testing with <a href="http://twill.idyll.org/">Twill</a>. I thought this was an interesting choice since Twill&#8217;s website says that it hasn&#8217;t been updated in over 3 years. I tested a few of the examples in this chapter and they worked as advertised. Much of this section is made up of explanations of Twill commands though. The last section purportedly shows how to integrate Twill tests with unittest tests. I didn&#8217;t do that part though.</p>
<p>Chapter 9 talks about Integration and System testing. I thought the idea of drawing concentric circles in a diagram to figure out how to create integrated units for testing was a good concept. That will probably appeal to the readers who like visuals. Alas, I didn&#8217;t really read anything more than the first couple of pages, but it looks like he uses his schedule planner example here as well.</p>
<p>The final chapter entitled &#8220;Other Testing Tools and Techniques&#8221;. I think this chapter looks fairly interesting, but didn&#8217;t get a chance to read it. Looking at the text now, it would seem to briefly cover the following: <a href="http://nedbatchelder.com/code/coverage/">coverage.py</a>, version control hooks (Bazaar,  Mercurial, Darcs, Subversion), and buildbot.</p>
<p>There is also an appendix with Pop Quiz answers.</p>
<p>Overall, I think the chapters that I read had a lot of good information and that is was very well organized. Unfortunately, the good was pretty badly marred by minor grammatical or sentence structure issues and the occasionally larger issue of broken code/tests. If it happens once, then I expect that there probably other code or tests that are broken as well. If this is the case, then I recommend buying it used or wait for a Packt sale of some sort. On the other hand, if the book is pristine after chapter 6&#8230;well, I guess that really doesn&#8217;t matter since that would mean that over half the book had problems.</p>
<p>Okay. Here&#8217;s a better recommendation: Find a Borders or Barnes &#038; Nobles near you that has the book and free wi-fi. Go there, find the book, and read it and mess around with the examples BEFORE you buy it. </p>
<p><strong>Rating Scale: 1 (low) &#8211; 5 (high)</strong></p>
<p>Code rating = 3<br />
Writing = 4<br />
Organization = 5</p>
<p>Average Score = 4  (take a point or two off if broken code annoys you)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/03/06/book-review-python-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python: Finding the Commit Charge Values in Windows</title>
		<link>http://www.blog.pythonlibrary.org/2010/03/05/python-finding-the-commit-charge-values-in-windows/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/03/05/python-finding-the-commit-charge-values-in-windows/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 14:24:38 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[ctypes]]></category>
		<category><![CDATA[System Admin]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=656</guid>
		<description><![CDATA[This week I was tasked with trying to find a way to find out what the Peak Commit value was on our virtual workstations. The reason being that we are trying to save money and were wondering if we were allocating too much memory or not. We didn&#8217;t need the Total Commit Charge or the [...]]]></description>
			<content:encoded><![CDATA[<p>This week I was tasked with trying to find a way to find out what the Peak Commit value was on our virtual workstations. The reason being that we are trying to save money and were wondering if we were allocating too much memory or not. We didn&#8217;t need the Total Commit Charge or the Limit Commit Charge values, but since I figured out how to get those during my research, I&#8217;ll show how to get those as well.<span id="more-656"></span></p>
<p>When I first started searching on this topic, I tried such search terms as &#8220;python peak commit value&#8221; and variations thereof. That got me nowhere, so I replaced &#8220;oython&#8221; with &#8220;wmi&#8221; and found the <a href="http://msdn.microsoft.com/en-us/library/aa394268%28VS.85%29.aspx">Win32_PerfFormattedData_PerfOS_Memory</a> Class on MSDN. I thought this was it, but it only gave me the Commit Charge Limit and the Total Commit Charge. Here&#8217;s how I got those values using Tim Golden&#8217;s WMI module:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> wmi
&nbsp;
c = wmi.<span style="color: black;">WMI</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> item <span style="color: #ff7700;font-weight:bold;">in</span> c.<span style="color: black;">Win32_PerfFormattedData_PerfOS_Memory</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    commitChargeLimit = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>item.<span style="color: black;">CommitLimit</span><span style="color: black;">&#41;</span> / <span style="color: #ff4500;">1024</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> item <span style="color: #ff7700;font-weight:bold;">in</span> c.<span style="color: black;">Win32_PerfFormattedData_PerfOS_Memory</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    commitChargeTotal = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>item.<span style="color: black;">CommittedBytes</span><span style="color: black;">&#41;</span> / <span style="color: #ff4500;">1024</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Commit Charge Limit: &quot;</span>, commitChargeLimit
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Commit Charge Total: &quot;</span>, commitChargeTotal</pre>
<p>This is neat stuff and shows how easy it is to take the documentation at MSDN and translate it into something usable in Python. Unfortunately, it just didn&#8217;t give me the information I needed. My next stop was the <a href="http://mail.python.org/mailman/listinfo/python-win32">PyWin32 mailing list</a> where Mark Hammond informed me of the win32pdh and win32pdhutil modules. These expose performance counters, but I couldn&#8217;t find a way to use it to get this information either. Fortunately, I found an old post on the <a href="http://forum.sysinternals.com/forum_posts.asp?TID=15540&#038;PID=75852">sysinternals forum </a> that gave me a clue. Here is what it said:</p>
<p><quote><br />
The only way I&#8217;m aware of that one can get this detail is from the uMmPeakCommitLimit member of the SYSTEM_PERFORMANCE_INFORMATION structure one passes to NtQuerySystemInformation when calling it with the SystemPerformanceInformation type.<br />
</quote></p>
<p>I asked Mr. Hammond if that meant that I would need to use <a href="http://python.net/crew/theller/ctypes/">ctypes</a> since the <a href="http://msdn.microsoft.com/en-us/library/ms724509%28VS.85%29.aspx">NtQuerySystemInformation</a> class isn&#8217;t exposed by PyWin32 and he said &#8220;probably&#8221;. The ctypes module is pretty low-level and not something I&#8217;ve used except when I&#8217;ve copied a script from ActiveState. It&#8217;s a pretty handy module though and was added to the <a href="http://docs.python.org/library/ctypes.html">standard library</a> in version 2.5. From what I can tell, it was created by Thomas Heller.</p>
<p>Anyway, ctypes has its own <a href="https://lists.sourceforge.net/lists/listinfo/ctypes-users">mailing list</a>, so I decided to try there. I received two replies, one of which was from the man himself (Heller). He gave me a script that didn&#8217;t appear to work at first, but after a little back and forth with him, he got me straightened out. Here&#8217;s the result:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> ctypes <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
SystemBasicInformation = <span style="color: #ff4500;">0</span>
SystemPerformanceInformation = <span style="color: #ff4500;">2</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> SYSTEM_BASIC_INFORMATION<span style="color: black;">&#40;</span>Structure<span style="color: black;">&#41;</span>:
    _fields_ = <span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Reserved1&quot;</span>, c_long <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;NumberOfProcessors&quot;</span>, c_byte<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;bUnknown2&quot;</span>, c_byte<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;bUnknown3&quot;</span>, c_short<span style="color: black;">&#41;</span>
                <span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> SYSTEM_PERFORMANCE_INFORMATION<span style="color: black;">&#40;</span>Structure<span style="color: black;">&#41;</span>:
    _fields_ = <span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;IdleTime&quot;</span>, c_int64<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;ReadTransferCount&quot;</span>, c_int64<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;WriteTransferCount&quot;</span>, c_int64<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;OtherTransferCount&quot;</span>, c_int64<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;ReadOperationCount&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;WriteOperationCount&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;OtherOperationCount&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;AvailablePages&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;TotalCommittedPages&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;TotalCommitLimit&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PeakCommitment&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PageFaults&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;WriteCopyFaults&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;TransitionFaults&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Reserved1&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;DemandZeroFaults&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PagesRead&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PageReadIos&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Reserved2&quot;</span>, c_ulong <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PagefilePagesWritten&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PagefilePageWriteIos&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;MappedFilePagesWritten&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;MappedFilePageWriteIos&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PagedPoolUsage&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;NonPagedPoolUsage&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PagedPoolAllocs&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PagedPoolFrees&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;NonPagedPoolAllocs&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;NonPagedPoolFrees&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;TotalFreeSystemPtes&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SystemCodePage&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;TotalSystemDriverPages&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;TotalSystemCodePages&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SmallNonPagedLookasideListAllocateHits&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SmallPagedLookasideListAllocateHits&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Reserved3&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;MmSystemCachePage&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PagedPoolPage&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SystemDriverPage&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;FastReadNoWait&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;FastReadWait&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;FastReadResourceMiss&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;FastReadNotPossible&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;FastMdlReadNoWait&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;FastMdlReadWait&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;FastMdlReadResourceMiss&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;FastMdlReadNotPossible&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;MapDataNoWait&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;MapDataWait&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;MapDataNoWaitMiss&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;MapDataWaitMiss&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PinMappedDataCount&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PinReadNoWait&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PinReadWait&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PinReadNoWaitMiss&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;PinReadWaitMiss&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;CopyReadNoWait&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;CopyReadWait&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;CopyReadNoWaitMiss&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;CopyReadWaitMiss&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;MdlReadNoWait&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;MdlReadWait&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;MdlReadNoWaitMiss&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;MdlReadWaitMiss&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;ReadAheadIos&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;LazyWriteIos&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;LazyWritePages&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;DataFlushes&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;DataPages&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;ContextSwitches&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;FirstLevelTbFills&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SecondLevelTbFills&quot;</span>, c_ulong<span style="color: black;">&#41;</span>,
                <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SystemCalls&quot;</span>, c_ulong<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
&nbsp;
sbi = SYSTEM_BASIC_INFORMATION<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
retlen = c_ulong<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
res = windll.<span style="color: black;">ntdll</span>.<span style="color: black;">NtQuerySystemInformation</span><span style="color: black;">&#40;</span>SystemBasicInformation,
                                            byref<span style="color: black;">&#40;</span>sbi<span style="color: black;">&#41;</span>,
                                            sizeof<span style="color: black;">&#40;</span>sbi<span style="color: black;">&#41;</span>,
                                            byref<span style="color: black;">&#40;</span>retlen<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> res, retlen
<span style="color: #ff7700;font-weight:bold;">print</span> sbi.<span style="color: black;">NumberOfProcessors</span>
&nbsp;
&nbsp;
spi = SYSTEM_PERFORMANCE_INFORMATION<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
retlen = c_ulong<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
res = windll.<span style="color: black;">ntdll</span>.<span style="color: black;">NtQuerySystemInformation</span><span style="color: black;">&#40;</span>SystemPerformanceInformation,
                                            byref<span style="color: black;">&#40;</span>spi<span style="color: black;">&#41;</span>,
                                            sizeof<span style="color: black;">&#40;</span>spi<span style="color: black;">&#41;</span>,
                                            byref<span style="color: black;">&#40;</span>retlen<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> res, retlen
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Peak commit: &quot;</span>,
<span style="color: #ff7700;font-weight:bold;">print</span> spi.<span style="color: black;">PeakCommitment</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">4096</span> / <span style="color: #ff4500;">1024</span></pre>
<p>I don&#8217;t really understand everything that&#8217;s going on here, but I&#8217;m glad it works. Well, I should say that it works on Windows XP Professional, 32-bit with Python 2.5. I tried it on Windows 7 64-bit as well and while the script ran, it returned &#8220;0L&#8221;. I&#8217;m guessing that 64-bit operating systems need a slightly different script, but since all our workstations currently use 32-bit, it doesn&#8217;t really matter at this point. Once again, the Python community came through for me and showed me just how amazing they are!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/03/05/python-finding-the-commit-charge-values-in-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finding Installed Software using Python</title>
		<link>http://www.blog.pythonlibrary.org/2010/03/03/finding-installed-software-using-python/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/03/03/finding-installed-software-using-python/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 04:11:02 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=652</guid>
		<description><![CDATA[Have you ever wondered what software was installed on your PC? Most people who use Windows would probably go to Add/Remove Programs to find out this information, but they&#8217;re not programmers. No, programmers have to script it because it&#8217;s just in our blood to do so. I actually had another reason to do so: my [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever wondered what software was installed on your PC? Most people who use Windows would probably go to Add/Remove Programs to find out this information, but they&#8217;re not programmers. No, programmers have to script it because it&#8217;s just in our blood to do so. I actually had another reason to do so: my boss wanted me to log what was installed on our user&#8217;s PCs so we&#8217;d know if our users were installing unauthorized software. Thus, there&#8217;s also a practical reason to attempt this.<span id="more-652"></span></p>
<p>After some research, I discovered that most well-behaved software will store various pieces of information about themselves in the Windows Registry. Specifically, they usually store this information in the following location: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall</p>
<p>It should be noted that not all programs that you install will put that information in the Registry. We have vendors who don&#8217;t use the Registry at all, for example. Also, nefarious programs like malware probably won&#8217;t put anything there either. However, well over 90% do so this is a good way to get the information. To get more, you&#8217;d probably need to do some directory walking with Python&#8217;s os module using it&#8217;s &#8220;walk&#8221; methods and look for mismatches from that compared to what&#8217;s in the Registry or maybe from some stored image that you&#8217;ve kept from a virgin base machine.</p>
<p>Anyway, enough talk. Let&#8217;s take a look at the code! Note: if you&#8217;d like to follow along then you&#8217;ll need to download and install Tim Golden&#8217;s <a href="http://timgolden.me.uk/python/wmi/index.html">WMI module</a>.</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">StringIO</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">traceback</span>
<span style="color: #ff7700;font-weight:bold;">import</span> wmi
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">_winreg</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: black;">&#40;</span>HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS,
                     OpenKey, EnumValue, QueryValueEx<span style="color: black;">&#41;</span>
&nbsp;
softFile = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'softLog.log'</span>, <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
errorLog = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'errors.log'</span>, <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
&nbsp;
r = wmi.<span style="color: black;">Registry</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
result, names = r.<span style="color: black;">EnumKey</span> <span style="color: black;">&#40;</span>hDefKey=HKEY_LOCAL_MACHINE, sSubKeyName=r<span style="color: #483d8b;">&quot;Software<span style="color: #000099; font-weight: bold;">\M</span>icrosoft<span style="color: #000099; font-weight: bold;">\W</span>indows<span style="color: #000099; font-weight: bold;">\C</span>urrentVersion<span style="color: #000099; font-weight: bold;">\U</span>ninstall&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
softFile.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'These subkeys are found under &quot;HKEY_LOCAL_MACHINE<span style="color: #000099; font-weight: bold;">\S</span>oftware<span style="color: #000099; font-weight: bold;">\M</span>icrosoft<span style="color: #000099; font-weight: bold;">\W</span>indows<span style="color: #000099; font-weight: bold;">\C</span>urrentVersion<span style="color: #000099; font-weight: bold;">\U</span>ninstall&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
errorLog.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Errors<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
separator = <span style="color: #483d8b;">&quot;*&quot;</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">80</span>
keyPath = r<span style="color: #483d8b;">&quot;Software<span style="color: #000099; font-weight: bold;">\M</span>icrosoft<span style="color: #000099; font-weight: bold;">\W</span>indows<span style="color: #000099; font-weight: bold;">\C</span>urrentVersion<span style="color: #000099; font-weight: bold;">\U</span>ninstall&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> subkey <span style="color: #ff7700;font-weight:bold;">in</span> names:
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        softFile.<span style="color: black;">write</span><span style="color: black;">&#40;</span>separator + <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
        path = keyPath + <span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>&quot;</span> + subkey
        key = OpenKey<span style="color: black;">&#40;</span>HKEY_LOCAL_MACHINE, path, <span style="color: #ff4500;">0</span>, KEY_ALL_ACCESS<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            temp = QueryValueEx<span style="color: black;">&#40;</span>key, <span style="color: #483d8b;">'DisplayName'</span><span style="color: black;">&#41;</span>
            display = <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>temp<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
            softFile.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Display Name: '</span> + display + <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\n</span>Regkey: '</span> + subkey + <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span>:
            softFile.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Regkey: '</span> + subkey + <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">except</span>:
        fp = <span style="color: #dc143c;">StringIO</span>.<span style="color: #dc143c;">StringIO</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #dc143c;">traceback</span>.<span style="color: black;">print_exc</span><span style="color: black;">&#40;</span><span style="color: #008000;">file</span>=fp<span style="color: black;">&#41;</span>
        errorMessage = fp.<span style="color: black;">getvalue</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        error = <span style="color: #483d8b;">'Error for '</span> + key + <span style="color: #483d8b;">'. Message follows:<span style="color: #000099; font-weight: bold;">\n</span>'</span> + errorMessage
        errorLog.<span style="color: black;">write</span><span style="color: black;">&#40;</span>error<span style="color: black;">&#41;</span>
        errorLog.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
softFile.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
errorLog.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>This is a pretty short snippet, but there&#8217;s a lot going on here. Let&#8217;s unpack it. First we import the modules we need and then open a couple of files: <em>softFile </em>will store all the software our script finds in &#8220;softLog.log&#8221; whereas our <em>errorLog</em> variable will store any errors we encounter in &#8220;errors.log&#8221;. Next we use WMI to enumerate over the subkeys in the &#8220;Uninstall&#8221; key. After that, we write a some title info to each log file to make them easier to read.</p>
<p>The last important piece occurs in the loop structure. Here we loop over the results returned from our WMI call. In our loop, we try to pull out two pieces of information: the Display Name of the software and the key that it&#8217;s associated with. There is lots of other information to be had, but there doesn&#8217;t seem to be any standards that are adhered to, so I didn&#8217;t grab any of that. You would need more complex error handling to extract it nicely (or maybe use generators some how). Anyway, if either of the pieces that we try to pull out fails, we catch the error and keep going. The nested exception handing catches the error related to getting the display name whereas the outer exception handler catches errors related to accessing the Registry. We should probably make these exceptions explicit (for example, the latter should be WindowsError, I think), but this is just a quick and dirty script. Feel free to extend it as much as you deem necessary.</p>
<p>If we encounter an error in either location, we log something. In the nested case, we just log the Regkey&#8217;s name to &#8220;softLog.log&#8221;, whereas in the outer case, we just log an error to &#8220;errors.log&#8221;. At the end, we clean up by closing the files.</p>
<p>Here&#8217;s a partial sample of what I get when I run this script on my Windows XP machine:</p>
<p><code><br />
These subkeys are found under &quot;HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall&quot;</p>
<p>********************************************************************************</p>
<p>Display Name: Windows Driver Package - Garmin (grmnusb) GARMIN Devices  (03/08/2007 2.2.1.0)<br />
Regkey: 45A7283175C62FAC673F913C1F532C5361F97841<br />
********************************************************************************</p>
<p>Regkey: AddressBook<br />
********************************************************************************</p>
<p>Display Name: Adobe Flash Player 10 ActiveX<br />
Regkey: Adobe Flash Player ActiveX<br />
********************************************************************************</p>
<p>Display Name: Adobe Flash Player 10 Plugin<br />
Regkey: Adobe Flash Player Plugin<br />
********************************************************************************</p>
<p>Display Name: Python 2.4 adodb-2.00<br />
Regkey: adodb-py2.4<br />
********************************************************************************</p>
<p>Display Name: Agent Ransack<br />
Regkey: Agent Ransack<br />
********************************************************************************</p>
<p>Display Name: Amazon Games &amp; Software Downloader<br />
Regkey: Amazon Games &amp; Software Downloader_is1<br />
********************************************************************************</p>
<p>Display Name: Amazon MP3 Downloader 1.0.3<br />
Regkey: Amazon MP3 Downloader<br />
********************************************************************************</p>
<p>Display Name: ZoneAlarm Spy Blocker Toolbar<br />
Regkey: Ask Toolbar_is1<br />
********************************************************************************</p>
<p>Display Name: Aspell English Dictionary-0.50-2<br />
Regkey: Aspell English Dictionary_is1<br />
********************************************************************************<br />
</code></p>
<p>Now you know how to extract most of the software installed on your Windows box. I&#8217;ve tested this primarily on Windows XP with Python 2.5, but it should work on Windows Vista and 7 too. Windows 7 and Vista usually forces the default user to run with lower privileges that XP, so you may be required to run this script as Administrator or impersonate the Administrator. Have fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/03/03/finding-installed-software-using-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PyCon 2010 and Volunteering</title>
		<link>http://www.blog.pythonlibrary.org/2010/02/28/pycon-2010-and-volunteering/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/02/28/pycon-2010-and-volunteering/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 19:43:16 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[PyCon]]></category>
		<category><![CDATA[PyCon 2010]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=630</guid>
		<description><![CDATA[This year, I decided to volunteer at PyCon. At both my previous PyCons, I had planned to help, but wasn&#8217;t sure how to join in. The evening before the tutorials started in 2009, I wandered all over the hotel looking for PyCon staff and found no one. Once the tutorials started, I felt pretty drained [...]]]></description>
			<content:encoded><![CDATA[<p>This year, I decided to volunteer at PyCon. At both my previous PyCons, I had planned to help, but wasn&#8217;t sure how to join in. The evening before the tutorials started in 2009, I wandered all over the hotel looking for PyCon staff and found no one. Once the tutorials started, I felt pretty drained in the evenings because I was taking the maximum number of tutorials and that&#8217;s a lot of information to soak up. But back to this year. I volunteered to be a Session Chair for one session. It was an interesting experience. I got to meet a fair number of cool Python people, although the only ones that I really saw after the session were Stani and Nadia. <span id="more-630"></span></p>
<p>The first evening I was at PyCon, I was approached by some guy who wanted to know if I would do some data entry. He had a bunch of tutorial surveys that needed to be entered for Greg Lindstrom, founder (I think) of Elegant Stitches (AKA: WearPython). So I ended up doing some of that once I actually found a location where the PyCon wireless worked.</p>
<p>My next act of good will occurred Friday morning. I had just found a place a sit near an access point when this fellow came up to me and asked if I could help put the power strips under the tables. This was in the main auditorium. I ended up doing about half the room. Sometime during that, another fellow started helping me. The objective was to plug them all together from the front to the back, usually in two series. The biggest drawback to this method is that if anyone in the back bumped their power strip&#8217;s switch, then all the people who were feeding off that one would lose power. I never heard if this was an issue or not.</p>
<p>My final volunteering activity was being a Session Chair. I actually talked about that in <a href="http://www.blog.pythonlibrary.org/2010/02/19/pycon-2010-friday-session-2/">another post</a>, so I won&#8217;t repeat myself here. I&#8217;ll just say that it was a mostly good experience other than some minor audio issues and some butterflies.</p>
<p>I was kind of hoping to get an awesome staff tee, but the main staff tees were lame. They&#8217;re just black with some white lettering and the PyCon logo. If you were paying attention at the conference, then you&#8217;d know that the only differences between the staff and the conference tees were slightly different verbiage and the fact that one was black and the other blue. Oh well. I do like the PyCon logo, but it would have been cooler if they had a large logo on the back too or something.</p>
<p>Next year, I encourage you all to get out there and volunteer to make PyCon 2011 even better!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/02/28/pycon-2010-and-volunteering/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Creating Windows Shortcuts with Python (Part II)</title>
		<link>http://www.blog.pythonlibrary.org/2010/02/25/creating-windows-shortcuts-with-python-part-ii/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/02/25/creating-windows-shortcuts-with-python-part-ii/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 00:57:23 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[PyWin32]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[System Admin]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=640</guid>
		<description><![CDATA[Back when I first wrote about creating shortcuts with Python last month, I kept thinking to myself that I had a 3rd way of doing it. Today, I had to maintain some of my shortcut code and I stumbled upon it once more. I also noticed that my post had received a comment from Tim [...]]]></description>
			<content:encoded><![CDATA[<p>Back when I first wrote about <a href="http://www.blog.pythonlibrary.org/2010/01/23/using-python-to-create-shortcuts/">creating shortcuts</a> with Python last month, I kept thinking to myself that I had a 3rd way of doing it. Today, I had to maintain some of my shortcut code and I stumbled upon it once more. I also noticed that my post had received a comment from Tim Golden on yet another way to create shortcuts, so I&#8217;ll include that in this post as well.<span id="more-640"></span></p>
<p>Oddly enough, my other method happened to use something of Tim Golden&#8217;s; namely, his <a href="http://timgolden.me.uk/python/winshell.html">winshell module</a>. Check it out below:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> winshell
&nbsp;
program_files = winshell.<span style="color: black;">programs</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
winshell.<span style="color: black;">CreateShortcut</span> <span style="color: black;">&#40;</span>
               Path=<span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span> <span style="color: black;">&#40;</span>program_files, <span style="color: #483d8b;">'My Shortcut.lnk'</span><span style="color: black;">&#41;</span>,
               Target=r<span style="color: #483d8b;">'C:<span style="color: #000099; font-weight: bold;">\P</span>rogram Files<span style="color: #000099; font-weight: bold;">\S</span>omeCoolProgram<span style="color: #000099; font-weight: bold;">\p</span>rog.exe'</span><span style="color: black;">&#41;</span></pre>
<p>Let&#8217;s unpack this so you know what&#8217;s going on. First, we use winshell to find the user&#8217;s &#8220;Programs&#8221; folder, which is a sub-folder of the user&#8217;s &#8220;Startup&#8221; folder. Then we use winshell&#8217;s <em>CreateShortcut </em> method to actually create the shortcut. If you look at the CreateShortcut&#8217;s docstring, you&#8217;ll discover that it can also accept the following keyword arguments: Arguments, StartIn, Icon, and Description.</p>
<p>Oddly enough, this wasn&#8217;t the method that Golden was suggesting in his comment. He had another <a href="http://timgolden.me.uk/python/win32_how_do_i/create-a-shortcut.html">idea </a>that is quite a bit more complicated. Let&#8217;s take a quick look:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>, <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> pythoncom
<span style="color: #ff7700;font-weight:bold;">from</span> win32com.<span style="color: black;">shell</span> <span style="color: #ff7700;font-weight:bold;">import</span> shell, shellcon
&nbsp;
shortcut = pythoncom.<span style="color: black;">CoCreateInstance</span> <span style="color: black;">&#40;</span>
  shell.<span style="color: black;">CLSID_ShellLink</span>,
  <span style="color: #008000;">None</span>,
  pythoncom.<span style="color: black;">CLSCTX_INPROC_SERVER</span>,
  shell.<span style="color: black;">IID_IShellLink</span>
<span style="color: black;">&#41;</span>
program_location = r<span style="color: #483d8b;">'C:<span style="color: #000099; font-weight: bold;">\P</span>rogram Files<span style="color: #000099; font-weight: bold;">\S</span>omeCoolProgram<span style="color: #000099; font-weight: bold;">\p</span>rog.exe'</span>
shortcut.<span style="color: black;">SetPath</span> <span style="color: black;">&#40;</span>program_location<span style="color: black;">&#41;</span>
shortcut.<span style="color: black;">SetDescription</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;My Program Does Something Really Cool!&quot;</span><span style="color: black;">&#41;</span>
shortcut.<span style="color: black;">SetIconLocation</span> <span style="color: black;">&#40;</span>program_location, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
&nbsp;
desktop_path = shell.<span style="color: black;">SHGetFolderPath</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, shellcon.<span style="color: black;">CSIDL_DESKTOP</span>, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
persist_file = shortcut.<span style="color: black;">QueryInterface</span> <span style="color: black;">&#40;</span>pythoncom.<span style="color: black;">IID_IPersistFile</span><span style="color: black;">&#41;</span>
persist_file.<span style="color: black;">Save</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span> <span style="color: black;">&#40;</span>desktop_path, <span style="color: #483d8b;">&quot;My Shortcut.lnk&quot;</span><span style="color: black;">&#41;</span>, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span></pre>
<p>In my opinion, this is getting a little too low-level for my taste. However, it is also really cool that you can do it this way. If you look at Tim Golden&#8217;s <a href="http://timgolden.me.uk/python/win32_how_do_i/create-a-shortcut.html">linked page</a>, you&#8217;ll see that this example is practically just a copy and paste job. I think winshell&#8217;s <em>desktop</em> method does the same thing as &#8220;shell.SHGetFolderPath (0, shellcon.CSIDL_DESKTOP, 0, 0)&#8221; and it&#8217;s easier to read. Anyway, the code above does the same thing that the previous code does, only it puts the shortcut on the user&#8217;s desktop. I don&#8217;t really understand what Golden is doing in the &#8220;pythoncom.CoCreateInstance&#8221; part other than creating an object that we can use to create our shortcut.</p>
<p>Also note that Tim Golden talks about creating a URL shortcut using a method that is quite similar to the one detailed above. You can go to his <a href="http://timgolden.me.uk/python/win32_how_do_i/create-a-url-shortcut.html">website</a> and learn all the juicy details.</p>
<p>Anyway, I felt that to be complete, I&#8217;d better write up these other two methods of creating shortcuts in Windows. Hopefully you found this interesting and maybe even educational.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/02/25/creating-windows-shortcuts-with-python-part-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PyCon 2010: Sunday Plenaries</title>
		<link>http://www.blog.pythonlibrary.org/2010/02/22/pycon-2010-sunday-plenaries/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/02/22/pycon-2010-sunday-plenaries/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 04:05:20 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[PyCon]]></category>
		<category><![CDATA[Plenary]]></category>
		<category><![CDATA[PyCon 2010]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=620</guid>
		<description><![CDATA[The last plenary session for PyCon 2010 was on Sunday. In it, Van Lindberg told us that if we included all the vendors, our conference had hit over 1100 people. What that meant is that for PyCon 2011, they would probably have to put an attendance cap of 1500 so that we wouldn&#8217;t run out [...]]]></description>
			<content:encoded><![CDATA[<p>The last plenary session for <a href="http://us.pycon.org/2010/about/">PyCon 2010</a> was on Sunday. In it, Van Lindberg told us that if we included all the vendors, our conference had hit over 1100 people. What that meant is that for PyCon 2011, they would probably have to put an attendance cap of 1500 so that we wouldn&#8217;t run out of room at the current venue. Is this good? I don&#8217;t really know. Sometimes it felt like it was already too big. Time will tell.<span id="more-620"></span></p>
<p>The first Plenary of the morning was given by <a href="http://fwierzbicki.blogspot.com/">Frank Wierzbicki</a> of <a href="http://saucelabs.com/">Sauce Labs</a> and he talked about the &#8220;State of Jython&#8221;, the Java implementation of Python. It turns out that version 2.5.1 has really good compatibility with the normal Python implementation such that <a href="http://www.jython.org/">Jython</a> passes almost all of CPython&#8217;s test suite. Jython also work with most Java libraries and applications, so you can get the best of both worlds. </p>
<p>Wierzbicki went on to say that any pure Python code should work in Jython. He gave examples of SqlAlchemy, Django, Pylons, pip, web2py and distribute as working in Jython. The current plan for Jython is to shoot for a 2.6 release this summer to get Jython to Python&#8217;s 2.6 status and then, depending on how far along Python developers are in porting their applications to Python 3, he would like to have Jython start porting to 3.x as well.</p>
<p>He put a call out for assistance on the Jython project as they no longer have sponsors. He then wrapped it up with a demo using the <a href="http://sikuli.csail.mit.edu/">Sikuli</a> script by Joseph Chang from MIT that used Jython to play Bejeweled. Weird, but cool!</p>
<p>The second plenary was on the &#8220;State of <a href="http://code.google.com/p/unladen-swallow/">Unladen Swallow</a>&#8221; and given by <a href="http://oakwinter.com/code/">Collin Winter</a> who works for Google. He didn&#8217;t use slides since he said that we could refer to a talk he&#8217;d given on Saturday if we needed visuals. Winter told us how their interpreter was faster than Jython and <a href="http://codespeak.net/pypy/dist/pypy/doc/">PyPy</a>, but that it could be optimized up the wazoo. He announced that Guido had approved the merging of Unladen Swallow into the Python 3.x code base, hopefully in time for 3.3. Winter said that he hoped that by merging the code, they would gain many more developers who could get the optimizing process up to warp speed and make a really fast interpreter. Finally, Winter noted that Unladen Swallow has 100% compatibility with all current Python code and gave the example that Unladen Swallow made Django run 20% faster.</p>
<p>The final plenary was given by the entrepreneur Antonio Rodriguez, founder of <a href="http://www.tabblo.com/studio">tabblo</a> (which he subsequently sold to HP). Here are a few of my notes from the talk:</p>
<ul>
<li>success = [e.hack() for e in employees]</li>
<li>Every machine can run the full stack. Anyone can check out the full tree and build the full product. Anyone can make a change to any part of the source tree. Everyone has commit bits. Anyone can push to production.</li>
<li>98% of companies start with around 10 people</li>
<li>Business vs. tech is a false dichotomy</li>
<li>The lean startup should be the emaciated startup</li>
</ul>
<p>The challenges that he saw for Python were getting people to commit to porting to 3.x so the split wouldn&#8217;t continue, need more batteries in the standard library and the packaging problem. I highly recommend waiting for the video and watching it as I am not explaining his talk very well and I thought he gave the best talk that I attended.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/02/22/pycon-2010-sunday-plenaries/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>PyCon 2010: Sunday Morning Lightning Talks</title>
		<link>http://www.blog.pythonlibrary.org/2010/02/22/pycon-2010-sunday-morning-lightning-talks/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/02/22/pycon-2010-sunday-morning-lightning-talks/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 03:42:14 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[PyCon]]></category>
		<category><![CDATA[PyCon 2010]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=618</guid>
		<description><![CDATA[The last morning Lightning talks were on Sunday. I wasn&#8217;t able to stay for the Lightning talks that were given in the afternoon. Here&#8217;s a quick run-down (note that I wasn&#8217;t able to get the presenter&#8217;s name on a lot of these because they would show their first slide for just a few scant seconds):



 [...]]]></description>
			<content:encoded><![CDATA[<p>The last morning Lightning talks were on Sunday. I wasn&#8217;t able to stay for the Lightning talks that were given in the afternoon. Here&#8217;s a quick run-down (note that I wasn&#8217;t able to get the presenter&#8217;s name on a lot of these because they would show their first slide for just a few scant seconds):</p>
<link rel="File-List" href="file:///C:%5CUsers%5CMike%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml"><!--[if gte mso 9]><xml>           </xml><![endif]-->
<link rel="themeData" href="file:///C:%5CUsers%5CMike%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx">
<link rel="colorSchemeMapping" href="file:///C:%5CUsers%5CMike%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml"><!--[if gte mso 9]><xml>     Normal    0                false    false    false       EN-US    X-NONE    X-NONE                                                                                                        <!--[endif]--><!--[if gte mso 9]><xml>                                                                                                                                                                                                                                                                                                                                                                                                                                </xml><![endif]--><br />
<style> <!-- /* Font Definitions */ @font-face 	{font-family:"Cambria Math"; 	panose-1:0 0 0 0 0 0 0 0 0 0; 	mso-font-charset:1; 	mso-generic-font-family:roman; 	mso-font-format:other; 	mso-font-pitch:variable; 	mso-font-signature:0 0 0 0 0 0;} @font-face 	{font-family:Calibri; 	panose-1:2 15 5 2 2 2 4 3 2 4; 	mso-font-charset:0; 	mso-generic-font-family:swiss; 	mso-font-pitch:variable; 	mso-font-signature:-520092929 1073786111 9 0 415 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-unhide:no; 	mso-style-qformat:yes; 	mso-style-parent:""; 	margin-top:0in; 	margin-right:0in; 	margin-bottom:10.0pt; 	margin-left:0in; 	line-height:115%; 	mso-pagination:widow-orphan; 	font-size:11.0pt; 	font-family:"Calibri","sans-serif"; 	mso-ascii-font-family:Calibri; 	mso-ascii-theme-font:minor-latin; 	mso-fareast-font-family:Calibri; 	mso-fareast-theme-font:minor-latin; 	mso-hansi-font-family:Calibri; 	mso-hansi-theme-font:minor-latin; 	mso-bidi-font-family:"Times New Roman"; 	mso-bidi-theme-font:minor-bidi;} .MsoChpDefault 	{mso-style-type:export-only; 	mso-default-props:yes; 	mso-ascii-font-family:Calibri; 	mso-ascii-theme-font:minor-latin; 	mso-fareast-font-family:Calibri; 	mso-fareast-theme-font:minor-latin; 	mso-hansi-font-family:Calibri; 	mso-hansi-theme-font:minor-latin; 	mso-bidi-font-family:"Times New Roman"; 	mso-bidi-theme-font:minor-bidi;} .MsoPapDefault 	{mso-style-type:export-only; 	margin-bottom:10.0pt; 	line-height:115%;} @page Section1 	{size:8.5in 11.0in; 	margin:1.0in 1.0in 1.0in 1.0in; 	mso-header-margin:.5in; 	mso-footer-margin:.5in; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --> </style>
<p><!--[if gte mso 10]><br />
<style> /* Style Definitions */ table.MsoNormalTable 	{mso-style-name:"Table Normal"; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-priority:99; 	mso-style-qformat:yes; 	mso-style-parent:""; 	mso-padding-alt:0in 5.4pt 0in 5.4pt; 	mso-para-margin-top:0in; 	mso-para-margin-right:0in; 	mso-para-margin-bottom:10.0pt; 	mso-para-margin-left:0in; 	line-height:115%; 	mso-pagination:widow-orphan; 	font-size:11.0pt; 	font-family:"Calibri","sans-serif"; 	mso-ascii-font-family:Calibri; 	mso-ascii-theme-font:minor-latin; 	mso-fareast-font-family:"Times New Roman"; 	mso-fareast-theme-font:minor-fareast; 	mso-hansi-font-family:Calibri; 	mso-hansi-theme-font:minor-latin; 	mso-bidi-font-family:"Times New Roman"; 	mso-bidi-theme-font:minor-bidi;} </style>
<p> <![endif]-->
<ul>
<li>Please Pirate &#8211; This one was given over half an hour BEFORE lightning talks were scheduled. I don&#8217;t know why. His talk&#8217;s website is <a href="http://www.pleasepirate.com">www.pleasepirate.com</a>. His premise was that people should encourage others to pirate their intellectual property. It was pretty confusing, actually. He doesn&#8217;t think Creative Commons goes far enough either.</li>
</ul>
<ul>
<li>You can write stored procedures in postgres &#8211; This was like a 60 second advertisement.</li>
</ul>
<ul>
<li><a href="http://python.org.ar/pyar/">PyAr</a> – Natalia from the Argentina Python Users group spoke on how their group started and its mission / vision. It has 650+ members with a mailing list of 11000+ messages per month. She also talked about what they do as a group, such as PyCamps and sprints (cocos2d, lalita, CDPedia)</li>
</ul>
<ul>
<li>Python Spring Cleanup &#8211; go home, figure out how to contribute to python, demo your stuff at a Python Users Group, get others to do it too</li>
</ul>
<ul>
<li>You got your <a href="http://www.cython.org/">Cython</a> in my <a href="http://numpy.scipy.org/">NumPy</a> – by D. Huggins – Went through a bunch of iterations of k-means code to show how Cython could make Python code much faster. He messed up at the end, so we never got to see how fast it really was.</li>
</ul>
<ul>
<li><a href="http://www.picloud.com/">PiCloud </a>– inspiration was facebook photo-tagging assistant but it turned into some kind of cloud-computing program. I didn&#8217;t really follow this very well, but they seem to have created a &#8220;cloud&#8221; module/package that allows you to utilize Amazon&#8217;s resources (EC2?) to do calculations.</li>
</ul>
<ul>
<li>Mox – Mobile web in <a href="http://www.djangoproject.com/">Django</a>, presented by Tim Fernando from Oxford, UK – Molly is a soon-to-be open source project that focuses on providing web content to mobile devices. Example (I think) is m.ox.ac.uk. It also does maps and it’s RESTful</li>
</ul>
<ul>
<li><a href="http://www.ccpgames.com/">CCP Games</a> guy – custom <a href="http://www.stackless.com/">stackless </a>or socket api (accent is hard to understand), used cherrypy’s thread test to compare against his program to show that his version was super fast. I couldn&#8217;t read the screen, so I don&#8217;t know if he proved anything or not.</li>
</ul>
<div class="zemanta-pixie"><img class="zemanta-pixie-img" alt="" src="http://img.zemanta.com/pixy.gif?x-id=abf08f9a-2560-8bd8-9944-02e757d35014" /></div>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/02/22/pycon-2010-sunday-morning-lightning-talks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PyCon 2010 Open Spaces</title>
		<link>http://www.blog.pythonlibrary.org/2010/02/21/pycon-2010-open-spaces/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/02/21/pycon-2010-open-spaces/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 03:51:40 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[PyCon]]></category>
		<category><![CDATA[PyCon 2010]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=624</guid>
		<description><![CDATA[PyCon 2010 continued the practice of Open Spaces (if you don&#8217;t know what those are, click here). I really enjoyed the Open Space track last year and greatly looked forward to it this year. Unfortunately, I only managed to get to one and that was the wxPython BoF that I had posted on the board. [...]]]></description>
			<content:encoded><![CDATA[<p>PyCon 2010 continued the practice of Open Spaces (if you don&#8217;t know what those are, click <a href="http://us.pycon.org/2009/openspace/">here</a>). I really enjoyed the Open Space track last year and greatly looked forward to it this year. Unfortunately, I only managed to get to one and that was the wxPython BoF that I had posted on the board. The major flaw that I saw this year was that there were two contradictory Open Space boards. There was one outside the doors into the Open Space corridor that had blocks given using the 24-hour time format (i.e. 1300 hours) and then was another board just inside the doorway with the same room letters and most of the same times, but in normal U.S. format (i.e. 1 p.m., 2 p.m., etc). Thus, it was very hard to know which board to follow.</p>
<p>For example, I wanted to go to the Python Authors BoF (BoF = Birds of a Feather). When I went down there, the outside board said it was in so-and-so and the inside board was blank. I went looking for this room, but found other people instead (I think they were the django folk). I don&#8217;t know where the authors thing was or if it even happened. </p>
<p>My wxPython BoF fared no better. I had put down my time slot on both boards in hopes of mitigating the confusion, but there was some huge group in the room I had reserved anyway. They left about 5-10 minutes after my BoF was supposed to start, which I think caused us to lose participants. We only had 6 people show up whereas last year it was closer to triple that amount. </p>
<p>All in all though, I think the wxPython BoF was alright because I got to meet the two major developers behind <a href="http://dabodev.com/">Dabo</a>, Ed Leafe and Paul McNett. And <a href="http://pythonide.blogspot.com/">Stani</a> showed up too, so I was able to rub shoulders with a few of the cool people of the wxPython niche. We discussed various projects we were working on and helped a wxPython newbie. </p>
<p>Another annoyance was that there never seemed to be any cards handy to fill out to post on the board(s)!. If I&#8217;m able to attend PyCon next year, I hope that this area of the conference is shown more love.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/02/21/pycon-2010-open-spaces/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>PyCon 2010: Saturday Session 3 (late afternoon) &#8211; Think Globally, Hack Locally</title>
		<link>http://www.blog.pythonlibrary.org/2010/02/20/pycon-2010-saturday-session-3-late-afternoon-think-globally-hack-locally/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/02/20/pycon-2010-saturday-session-3-late-afternoon-think-globally-hack-locally/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 00:07:53 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[PyCon]]></category>
		<category><![CDATA[PyCon 2010]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/2010/02/20/pycon-2010-saturday-session-3-late-afternoon-think-globally-hack-locally/</guid>
		<description><![CDATA[I only attended one of the two talks in the last session of the day. It was presented by Ms. Leigh Honeywell and called Think Globally, Hack Locally &#8211; Teaching Python in Your Community.
She started &#8220;Python Newbie Night&#8221; in Toronto, Canada. It was an informal, peer-taught class which often put code up on the wall [...]]]></description>
			<content:encoded><![CDATA[<p>I only attended one of the two talks in the last session of the day. It was presented by Ms. <a href="http://twitter.com/Hypatiadotca" target="_blank">Leigh Honeywell</a> and called <a href="http://us.pycon.org/2010/conference/schedule/event/111/" target="_blank">Think Globally, Hack Locally &#8211; Teaching Python in Your Community</a>.</p>
<p>She started &#8220;Python Newbie Night&#8221; in Toronto, Canada. It was an informal, peer-taught class which often put code up on the wall with a projector. They would work through the Python book, &#8220;How to Think Like a Computer Scientist&#8221; which has chapter exercises (the book is online for free at http://thinkpython.com). She was in a hackerspace (her local one was <a href="http://hacklab.to/" target="_blank">hacklab.co</a>) and seemed to recommend them. She gave a list of venues for teaching programming such as Community centres, churches, retirement homes, schools, jails and more. She also mentioned that the University of Toronto has switched to teaching Python from Java (I think).</p>
<p>She spoke on what worked for these classes and what didn&#8217;t work so well. For the most part, the talk was just general purpose tips for teaching Python. I do most of the stuff that she talks about for Pyowa (local python users group) and completely agree that doing it alone sucks. I also agree that teaching others about Python can be very rewarding. I thought this was a nice informal talk that would be informative to people who have never done this before. If you plan to start a user&#8217;s group, watching her talk or reading her slides would be a step in the right direction.</p>
<div class="zemanta-pixie"><img class="zemanta-pixie-img" alt="" src="http://img.zemanta.com/pixy.gif?x-id=444a18bc-4274-89c2-97f3-ad2fe575fcc5" /></div>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/02/20/pycon-2010-saturday-session-3-late-afternoon-think-globally-hack-locally/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 3.097 seconds -->
