<?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>Fri, 03 Sep 2010 13:08:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Pyowa &#8211; September 2010 Wrap-Up</title>
		<link>http://www.blog.pythonlibrary.org/2010/09/03/pyowa-september-2010-wrap-up/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/09/03/pyowa-september-2010-wrap-up/#comments</comments>
		<pubDate>Fri, 03 Sep 2010 13:08:57 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Pyowa]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1180</guid>
		<description><![CDATA[This is for all you Pyowa home-boys out there what missed our gathering. We don&#8217;t know why you homebodies didn&#8217;t come and hang out and talk shop wit us, but we think you really truly missed out on our phat gathering. We had around 10 real homies show up to hear the jibber jabber about [...]]]></description>
			<content:encoded><![CDATA[<p>This is for all you Pyowa home-boys out there what missed our gathering. We don&#8217;t know why you homebodies didn&#8217;t come and hang out and talk shop wit us, but we think you really truly missed out on our phat gathering. We had around 10 real homies show up to hear the jibber jabber about South, a Django data migration tool. We were supposed to hear about SWIG too, but ended up swigging pop (or soda for you southerners) and chowing down on free pizza instead. </p>
<p>Next time, we&#8217;ll be booking it at the Ames Public Library in (you guessed it!) Ames, IA on Thursday, October 7th. If you think you got the chops for talking about Python, drop me a line and I&#8217;ll hook you up.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/09/03/pyowa-september-2010-wrap-up/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Another GUI2Exe Tutorial &#8211; Build a Binary Series!</title>
		<link>http://www.blog.pythonlibrary.org/2010/08/31/another-gui2exe-tutorial-build-a-binary-series/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/08/31/another-gui2exe-tutorial-build-a-binary-series/#comments</comments>
		<pubDate>Wed, 01 Sep 2010 00:09:58 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Packaging]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[binaries]]></category>
		<category><![CDATA[Distribution]]></category>
		<category><![CDATA[GUI2Exe]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1163</guid>
		<description><![CDATA[This is the last article of my &#8220;Build a Binary Series&#8221;. If you haven&#8217;t done so already, be sure to check out the others. For our finale, we are to look at Andrea Gavana&#8217;s wxPython-based GUI2Exe, a nice graphical user interface to py2exe, bbfreeze, cx_Freeze, PyInstaller and py2app. The latest release of GUI2Exe is 0.5.0, [...]]]></description>
			<content:encoded><![CDATA[<p>This is the last article of my &#8220;Build a Binary Series&#8221;. If you haven&#8217;t done so already, be sure to check out the others. For our finale, we are to look at Andrea Gavana&#8217;s wxPython-based GUI2Exe, a nice graphical user interface to py2exe, bbfreeze, cx_Freeze, PyInstaller and py2app. The latest release of GUI2Exe is 0.5.0, although the source may be slightly newer. Feel free to run from the tip as well. We&#8217;ll be using the example scripts that we used for several of the previous articles: one console and one GUI script, neither of which do much of anything.<span id="more-1163"></span></p>
<h2>Getting Started with GUI2Exe</h2>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/gui2exe.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/gui2exe-300x217.png" alt="" title="gui2exe.png" width="300" height="217" class="aligncenter size-medium wp-image-1165" /></a></p>
<p>Quite some time ago, I wrote another article on this cool tool. However, the look-and-feel of the application has changed quite a bit, so I felt I should re-write that article in the context of this series. To follow along with this article, you&#8217;ll need to hit <a href="http://code.google.com/p/gui2exe/">Google Code</a> for the source. Let&#8217;s begin, shall we? Here are some step-by-step directions for making the console script using py2exe via GUI2Exe:</p>
<ol>
<li>Download the source and unzip them in a convenient location</li>
<li>Run the &#8220;GUI2Exe.py&#8221; file (you can use your favorite editor, open it via the command line or whatever)</li>
<li>Go to File, New Project. A dialog will appear asking you to name the project. Give it a good name! Then hit OK.</li>
<li>Click in the &#8220;Exe Kind&#8221; column and change it to &#8220;Console&#8221;</li>
<li>Click in the &#8220;Python Main Script&#8221; column and you&#8217;ll see a button appear.</li>
<li>Press the button and use the file dialog to find your main script</li>
<li>Fill out the other optional fields however you like</li>
<li>Hit the compile button on the lower right</li>
<li>Try the result to see if it worked!</li>
</ol>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/gui2exe_options.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/gui2exe_options-300x187.png" alt="" title="gui2exe_options" width="300" height="187" class="aligncenter size-medium wp-image-1170" /></a></p>
<p>If you followed the directions above, you should now have an executable file (and a few dependencies) in a &#8220;dist&#8221; folder at the location of the main script. As you can see in the screenshot above, there are all the typical options that you would set in your setup.py file. You can set your excludes list, the includes, the optimize and compressed settings, whether or not to include a zip, packages and much more! You can tweak to your hearts content and hit the &#8220;Compile&#8221; button whenever you&#8217;re ready to see the result. If I&#8217;m experimenting, I usually change the output directory&#8217;s name so I can compare the results to see which is the most compact.</p>
<p>If you want to use bbfreeze, cx_freeze, PyInstaller or py2app, just click the respective name in the column on the right. This will cause the middle part of the screen to change according to your choice and show the corresponding options for said choice. Let&#8217;s take a quick visual tour!</p>
<h2>GUI2Exe in Pictures!</h2>
<p>The following is a snapshot of the py2app options:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/gui2exe_py2app.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/gui2exe_py2app-300x233.png" alt="" title="gui2exe_py2app" width="300" height="233" class="aligncenter size-medium wp-image-1171" /></a></p>
<p>Next is a shot of the cx_Freeze options:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/gui2exe_cxfreeze.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/gui2exe_cxfreeze-300x229.png" alt="gui2exe_cxfreeze.png" title="gui2exe_cxfreeze.png" width="300" height="229" class="aligncenter size-medium wp-image-1172" /></a></p>
<p>And here is PyInstaller&#8217;s settings:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/gui2exe_pyinst.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/gui2exe_pyinst-300x233.png" alt="gui2exe_pyinst.png" title="gui2exe_pyinst.png" width="300" height="233" class="aligncenter size-medium wp-image-1173" /></a></p>
<p>Finally, we have bbfreeze&#8217;s options:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/gui2exe_bbfreeze.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/gui2exe_bbfreeze-300x229.png" alt="gui2exe_bbfreeze.png" title="gui2exe_bbfreeze.png" width="300" height="229" class="aligncenter size-medium wp-image-1175" /></a></p>
<p>There&#8217;s also a VendorId screen, but I don&#8217;t know much about that one, so we&#8217;ll be skipping it.</p>
<h2>GUI2Exe&#8217;s Menu Options</h2>
<p>As you might guess, all these options work the same way as they do when you do it all yourself in code. If you ever need to check out the setup.py file that GUI2Exe is making for you, just go to the <strong>Builds</strong> menu and choose <strong>View Setup Script</strong>. If you want to see a handy listing of the files it output and where it output the files, go to Build, Explorer and you should see something like the screenshot below:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/gui2exe_explorer.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/gui2exe_explorer-300x294.png" alt="gui2exe_explorer.png" title="gui2exe_explorer.png" width="300" height="294" class="aligncenter size-medium wp-image-1176" /></a></p>
<p>Other handy option in the Builds menu include the Mission Modules and the Binary Dependencies menu items. These show you what may be missing from the dist folder that you may need to include should you distribute your masterpiece.</p>
<p>The <strong>Options </strong>menu controls options for GUI2Exe itself and a few custom items for the build process, like setting the Python version, deleting the build and/or dist folders, set the PyInstaller Path and more. The other menus are pretty self-explanatory and I leave them for the adventurous readers.</p>
<h2>Wrapping Up</h2>
<p>If you&#8217;ve read my other tutorials in the &#8220;Build a Binary Series&#8221; then you should be able to take that knowledge and use it productively with GUI2Exe. I find GUI2Exe to be very helpful when it comes time for me to build an executable and I used it to help me figure out the options for some of the other binary builders in this series. I hope you enjoyed this series and found it helpful. See you next time!</p>
<h2>Further Reading</h2>
<ul>
<li>GUI2Exe Official <a href="http://code.google.com/p/gui2exe/">website</a></li>
<li>Andrea Gavana&#8217;s <a href="http://xoomer.virgilio.it/infinity77/">website</a> and <a href="http://thedoomedcity.blogspot.com/">blog</a></li>
<li><a href="http://www.blog.pythonlibrary.org/tag/binaries/">Build a Binary Series</a></li>
<li>The other <a href="http://www.blog.pythonlibrary.org/2008/08/27/packaging-wxpymail-for-distribution/">GUI2Exe </a>tutorial</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/08/31/another-gui2exe-tutorial-build-a-binary-series/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Book Review: Python 3 Object Oriented Programming</title>
		<link>http://www.blog.pythonlibrary.org/2010/08/22/book-review-python-3-object-oriented-programming/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/08/22/book-review-python-3-object-oriented-programming/#comments</comments>
		<pubDate>Sun, 22 Aug 2010 18:48:23 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Book Review]]></category>
		<category><![CDATA[OOP]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1152</guid>
		<description><![CDATA[Python 3 Object Oriented Programming By Dusty Phillips Amazon Packt A few months ago, I wrote a preview of this book. A little over a week ago, I received my copy of the book. Before we get to the review though, I want to give full disclosure: Packt contacted me to be a &#8220;Reviewer&#8221; (read: [...]]]></description>
			<content:encoded><![CDATA[<table>
<tr>
<td><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/python3_oop.jpg"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/python3_oop-243x300.jpg" alt="" title="python3_oop" width="243" height="300" class="aligncenter size-medium wp-image-1154" /></a></td>
<td>
<h3>Python 3 Object Oriented Programming</h3>
<p><p>By Dusty Phillips</p>
<p><strong><a href="http://www.amazon.com/exec/obidos/ASIN/1849511268/thmovsthpy-20/">Amazon</a></strong></p>
<p><strong><a href="http://www.packtpub.com/python-3-object-oriented-programming/book?utm_source=blog.pythonlibrary.org&#038;utm_medium=bookrev&#038;utm_content=blog&#038;utm_campaign=mdb_004190">Packt</a></strong></br>
</td>
</tr>
</table>
<p><span id="more-1152"></span><br />
A few months ago, I wrote a <a href="http://www.blog.pythonlibrary.org/2010/05/20/book-preview-python-3-object-oriented-programming/">preview </a>of this book. A little over a week ago, I received my copy of the book. Before we get to the review though, I want to give full disclosure: Packt contacted me to be a &#8220;Reviewer&#8221; (read: technical editor) for this book last December. The payment? They gave me a copy of the book, one copy of any other book from their catalog that I wanted and my name appears in the book. If you think that remuneration will cause me to biased, so be it. Everyone is biased in some way or another. I tend to be harsher on things that I&#8217;m involved in though.</p>
<p>Well, enough of the baring of my soul. Let&#8217;s take a look at the book. The author of this book really likes Unified Modeling Language (UML) class diagrams, so if you find those helpful in learning, then you&#8217;ll like this book. The entire first chapter is made up of text and UML diagrams, after all and it gives a brief introduction to the Object Oriented philosophy. Chapter 2 jumps into Python Objects, modules and packages. Chapter 3 digs into inheritance (basic and multiple) and polymorphism. Chapter 4 is all about exceptions in Python. Chapter 5 attempts to explain when to use object oriented programming. I thought that was an interesting chapter because it seems to me that colleges browbeat their students into thinking they should use OOP for everything. Chapters 6 and 7 dig into the Python standard library by covering tuples, lists, dicts, sets, various comprehensions, generators and functions. I learned a lot about comprehensions from these chapters that made me wish I used Python 3 more. Chapters 8 and 9 cover Python Design Patterns. I found these chapters to be the highlight of the book and very interesting. He covers the following patterns: decorator,  observer, strategy, state, singleton, template, adapter, facade, flyweight, command, abstract factory and composite.</p>
<p>Chapter 10 covers the basics of files and strings; chapter 11 goes overs testing with unit tests and py.test. Last, chapter 12 does a quick overview of common Python 3 libraries, like SqlAlchemy, Tkinter, PyQt, lxml and CherryPy.</p>
<p>When I was reviewing the book, Chapters 5 and 8 had some Python Imaging Library examples. The author had noted that PIL hadn&#8217;t been ported to Python 3 at the time, but he thought it would be by publishing. Alas, the people behind PIL still do not have a Python 3 port. So I was curious how the author handled this conundrum. It turns out that he ended up replacing PIL with pygame. An interesting choice that appears to work all right for the examples. I didn&#8217;t re-read the book (although I plan to at some point). Instead, I just did a spot check to see if the author followed any of my suggestions or fixed errors. It appears that he did.</p>
<p>This book was good before he fixed the problems with it. There&#8217;s more theory here than you normally find in Python textbooks, but I found the examples intriguing and he has unusual exercises at the end of the chapters that should keep you thinking. I&#8217;m pretty sure I would have been quite happy if I had purchased this book. If you&#8217;re new to Python 3 and specifically object oriented programming or you want to learn about programming patterns, I recommend this book. If you want a sneak peak, Packt has Chapter 7 available on their website <a href="https://www.packtpub.com/sites/default/files/1261-chapter-7-Python%20object-oriented-shortcuts.pdf">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/08/22/book-review-python-3-object-oriented-programming/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A bbfreeze Tutorial &#8211; Build a Binary Series!</title>
		<link>http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 13:23:23 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Packaging]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[bbfreeze]]></category>
		<category><![CDATA[binaries]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Distribution]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1137</guid>
		<description><![CDATA[The bbfreeze package also allows us to create binaries, but only on Linux and Windows. It&#8217;s just an easy_install away, so if you plan on following along with the examples in the article, you should go get it. The bbfreeze package includes egg support, so it can include egg dependencies in your binary, unlike py2exe. [...]]]></description>
			<content:encoded><![CDATA[<p>The bbfreeze package also allows us to create binaries, but only on Linux and Windows. It&#8217;s just an easy_install away, so if you plan on following along with the examples in the article, you should go get it. The bbfreeze package includes egg support, so it can include egg dependencies in your binary, unlike py2exe. You can also freeze multiple scripts at once, include the Python interpreter and more. According to bbfreeze&#8217;s PyPI entry, it&#8217;s only been tested with Python 2.4-2.5, so keep that in mind. However, I was able to use it with Python 2.6 with no obvious problems.<span id="more-1137"></span></p>
<h2>Getting Started with bbfreeze</h2>
<p>You can use easy_install to download and install bbfreeze or you can just download its source or the egg file directly from the <a href="http://pypi.python.org/pypi/bbfreeze/">Python Package Index</a> (PyPI). In this article, we&#8217;ll try using it on a simple configuration file generator script and we&#8217;ll also try it against a lame wxPython program. My test machine was a Windows 7 Home Edition 32-bit laptop with bbfreeze 0.96.5, and Python 2.6.4. Let&#8217;s start with the configuration script:</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># config_1.py</span>
<span style="color: #ff7700;font-weight:bold;">import</span> configobj
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig<span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Create the configuration file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    inifile = configFile
    config.<span style="color: black;">filename</span> = inifile
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'server'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;http://www.google.com&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'username'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;mike&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'password'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;dingbat&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'update interval'</span><span style="color: black;">&#93;</span> = <span style="color: #ff4500;">2</span>
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> getConfig<span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Open the config file and return a configobj
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig2<span style="color: black;">&#40;</span>path<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Create a config file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    config.<span style="color: black;">filename</span> = path
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;product&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;Sony PS3&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;accessories&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'controller'</span>, <span style="color: #483d8b;">'eye'</span>, <span style="color: #483d8b;">'memory stick'</span><span style="color: black;">&#93;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;retail price&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;$400&quot;</span>
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    createConfig2<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sampleConfig2.ini&quot;</span><span style="color: black;">&#41;</span></pre>
<p>This script has a couple of functions that are pointless, but we&#8217;ll leave them in for illustrative purposes. According to the bbfreeze documentation, we should be able to create a binary with the following string typed into the command line:</p>
<p><code><br />
bb-freeze config_1.py<br />
</code></p>
<p>This assumes that you have &#8220;C:\Python26\Scripts&#8221; on your path. If you don&#8217;t, you&#8217;ll need to type the complete path out (i.e. &#8220;C:\Python26\Scripts\bb-freeze config_1.py&#8221;). When I ran this, I got an error. Here it is:</p>
<pre class="python">Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\S</span>cripts<span style="color: #000099; font-weight: bold;">\b</span>b-freeze-script.py&quot;</span>, line <span style="color: #ff4500;">8</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
    load_entry_point<span style="color: black;">&#40;</span><span style="color: #483d8b;">'bbfreeze==0.96.5'</span>, <span style="color: #483d8b;">'console_scripts'</span>, <span style="color: #483d8b;">'bb-freeze'</span><span style="color: black;">&#41;</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\_</span>_init__.py&quot;</span>, line <span style="color: #ff4500;">18</span>, <span style="color: #ff7700;font-weight:bold;">in</span> main
    f<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\f</span>reezer.py&quot;</span>, line <span style="color: #ff4500;">474</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #0000cd;">__call__</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">addModule</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;encodings.*&quot;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\f</span>reezer.py&quot;</span>, line <span style="color: #ff4500;">411</span>, <span style="color: #ff7700;font-weight:bold;">in</span> addModule
    <span style="color: #008000;">self</span>.<span style="color: black;">mf</span>.<span style="color: black;">import_hook</span><span style="color: black;">&#40;</span>name<span style="color: black;">&#91;</span>:<span style="color: #ff4500;">-2</span><span style="color: black;">&#93;</span>, fromlist=<span style="color: #483d8b;">&quot;*&quot;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\m</span>odulegraph<span style="color: #000099; font-weight: bold;">\m</span>odulegraph.py&quot;</span>, line <span style="color: #ff4500;">256</span>, <span style="color: #ff7700;font-weight:bold;">in</span> import_hook
    modules.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">ensure_fromlist</span><span style="color: black;">&#40;</span>m, fromlist<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\m</span>odulegraph<span style="color: #000099; font-weight: bold;">\m</span>odulegraph.py&quot;</span>, line <span style="color: #ff4500;">345</span>, <span style="color: #ff7700;font-weight:bold;">in</span> ensure_fromlist
    fromlist.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">find_all_submodules</span><span style="color: black;">&#40;</span>m<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  File <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\l</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages<span style="color: #000099; font-weight: bold;">\b</span>bfreeze-0.96.5-py2.6-win32.egg<span style="color: #000099; font-weight: bold;">\b</span>bfreeze<span style="color: #000099; font-weight: bold;">\m</span>odulegraph<span style="color: #000099; font-weight: bold;">\m</span>odulegraph.py&quot;</span>, line <span style="color: #ff4500;">369</span>, <span style="color: #ff7700;font-weight:bold;">in</span> find_all_submodules
    <span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: black;">&#40;</span>path, mode, typ<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">in</span> ifilter<span style="color: black;">&#40;</span><span style="color: #008000;">None</span>, imap<span style="color: black;">&#40;</span>moduleInfoForPath, names<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
<span style="color: #008000;">NameError</span>: <span style="color: #ff7700;font-weight:bold;">global</span> name <span style="color: #483d8b;">'ifilter'</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> defined</pre>
<p>It would seem that the &#8220;modulegraph.py&#8221; file is missing an import from the <a href="http://docs.python.org/library/itertools.html">itertools</a> library, which is included with Python. I edited my copy of &#8220;modulegraph.py&#8221; to include the following line at the top of the file: &#8220;from itertools import ifilter&#8221;. This got rid of that traceback, but it raised another because &#8220;imap&#8221; wasn&#8217;t defined either. To fix the second error, I changed my import to &#8220;from itertools import ifilter,imap&#8221; and then it ran with no problems and produced a binary in a &#8220;dist&#8221; folder along with nine other files (see screenshot below).</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/bbfreeze_dir.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/bbfreeze_dir.png" alt="bbfreeze_dir.png" title="bbfreeze_dir.png" width="599" height="324" class="aligncenter size-full wp-image-1148" /></a></p>
<h2>Using bbfreeze&#8217;s Advanced Configuration</h2>
<p>The PyPI page for bbfreeze (which is also its home page) has very little documentation. However, the page does say that the preferred way to use bbfreeze is with little scripts. We&#8217;re going to try using creating a binary with the lame wxPython, mentioned earlier. Here&#8217;s the wx code:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> wx
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoPanel<span style="color: black;">&#40;</span>wx.<span style="color: black;">Panel</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <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>, parent<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Panel</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>
&nbsp;
        labels = <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Name&quot;</span>, <span style="color: #483d8b;">&quot;Address&quot;</span>, <span style="color: #483d8b;">&quot;City&quot;</span>, <span style="color: #483d8b;">&quot;State&quot;</span>, <span style="color: #483d8b;">&quot;Zip&quot;</span>,
                  <span style="color: #483d8b;">&quot;Phone&quot;</span>, <span style="color: #483d8b;">&quot;Email&quot;</span>, <span style="color: #483d8b;">&quot;Notes&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
        mainSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">VERTICAL</span><span style="color: black;">&#41;</span>
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=<span style="color: #483d8b;">&quot;Please enter your information here:&quot;</span><span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> lbl <span style="color: #ff7700;font-weight:bold;">in</span> labels:
            sizer = <span style="color: #008000;">self</span>.<span style="color: black;">buildControls</span><span style="color: black;">&#40;</span>lbl<span style="color: black;">&#41;</span>
            mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>sizer, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">SetSizer</span><span style="color: black;">&#40;</span>mainSizer<span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Layout</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> buildControls<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        sizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">HORIZONTAL</span><span style="color: black;">&#41;</span>
        size = <span style="color: black;">&#40;</span><span style="color: #ff4500;">80</span>,<span style="color: #ff4500;">40</span><span style="color: black;">&#41;</span>
        font = wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span>
&nbsp;
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=label, size=size<span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>|wx.<span style="color: black;">CENTER</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> label <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;Notes&quot;</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name=label<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, style=wx.<span style="color: black;">TE_MULTILINE</span>, name=label<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>txt, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> sizer
&nbsp;
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoFrame<span style="color: black;">&#40;</span>wx.<span style="color: black;">Frame</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Frame that holds all other widgets
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Frame</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #008000;">None</span>, wx.<span style="color: black;">ID_ANY</span>,
                          <span style="color: #483d8b;">&quot;cxFreeze Tutorial&quot;</span>,
                          size=<span style="color: black;">&#40;</span><span style="color: #ff4500;">600</span>,<span style="color: #ff4500;">400</span><span style="color: black;">&#41;</span>
                          <span style="color: black;">&#41;</span>
        panel = DemoPanel<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">Show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    app = wx.<span style="color: black;">App</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
    frame = DemoFrame<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    app.<span style="color: black;">MainLoop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>Now let&#8217;s create a simple freezing script!</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># bb_setup.py</span>
<span style="color: #ff7700;font-weight:bold;">from</span> bbfreeze <span style="color: #ff7700;font-weight:bold;">import</span> Freezer
&nbsp;
f = Freezer<span style="color: black;">&#40;</span>distdir=<span style="color: #483d8b;">&quot;bb-binary&quot;</span><span style="color: black;">&#41;</span>
f.<span style="color: black;">addScript</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sampleApp.py&quot;</span><span style="color: black;">&#41;</span>
f<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>First off, we import the <em>Freezer</em> class from the bbfreeze package. Freezer accepts three arguments: a destination folder, an includes iterable and an excludes iterable (i.e. a tuple or list). Just to see how well bbfreeze works with only its defaults, we leave out the includes and excludes tuples/lists. Once you have a Freezer object, you can add your script(s) by calling the Freezer object name&#8217;s <em>addScript</em> method. Then you just need to call the object (i.e.  f() ). If you do all that, you should end up with a 14.5 MB folder holding 18 files. When I ran the sampleApp.exe file, it ran just fine and was properly themed, however it also had a console screen. To figure out the correct syntax, I used <a href="http://code.google.com/p/gui2exe/">GUI2Exe</a>. Here&#8217;s the new code:</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># bb_setup2.py</span>
<span style="color: #ff7700;font-weight:bold;">from</span> bbfreeze <span style="color: #ff7700;font-weight:bold;">import</span> Freezer
&nbsp;
includes = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
excludes = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'_gtkagg'</span>, <span style="color: #483d8b;">'_tkagg'</span>, <span style="color: #483d8b;">'bsddb'</span>, <span style="color: #483d8b;">'curses'</span>, <span style="color: #483d8b;">'email'</span>, <span style="color: #483d8b;">'pywin.debugger'</span>,
            <span style="color: #483d8b;">'pywin.debugger.dbgcon'</span>, <span style="color: #483d8b;">'pywin.dialogs'</span>, <span style="color: #483d8b;">'tcl'</span>,
            <span style="color: #483d8b;">'Tkconstants'</span>, <span style="color: #483d8b;">'Tkinter'</span><span style="color: black;">&#93;</span>
&nbsp;
bbFreeze_Class = Freezer<span style="color: black;">&#40;</span><span style="color: #483d8b;">'dist'</span>, includes=includes, excludes=excludes<span style="color: black;">&#41;</span>
&nbsp;
bbFreeze_Class.<span style="color: black;">addScript</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sampleApp.py&quot;</span>, gui_only=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
&nbsp;
bbFreeze_Class.<span style="color: black;">use_compression</span> = <span style="color: #ff4500;">0</span>
bbFreeze_Class.<span style="color: black;">include_py</span> = <span style="color: #008000;">True</span>
bbFreeze_Class<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>If you run this, you should end up with a &#8220;dist&#8221; folder that contains 18 files and is 16.6 MB in size. Notice that we added a second argument to the <em>addScript</em> method: gui_only=True. This makes that annoying console go away. We also set compression to zero (no compression, I think) and include the Python interpreter. Turning on compression only reduced the result down to 14.3 MB though. </p>
<p>The bbfreeze package also handles &#8220;recipes&#8221; and includes several examples, however they are not documented well either and I couldn&#8217;t figure out how to include them with my current examples. Feel free to figure them out on your own!</p>
<h2>Wrapping Up</h2>
<p>Well, now you should know the basics of using bbfreeze to create binaries from your programs. I hope you found this helpful. The last article in this series will be on GUI2Exe. Look for it soon!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/08/19/a-bbfreeze-tutorial-build-a-binary-series/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Book Review: Practical Programming: An Introduction to Computer Science Using Python</title>
		<link>http://www.blog.pythonlibrary.org/2010/08/14/book-review-practical-programming-an-introduction-to-computer-science-using-python/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/08/14/book-review-practical-programming-an-introduction-to-computer-science-using-python/#comments</comments>
		<pubDate>Sat, 14 Aug 2010 13:46:50 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Book Review]]></category>
		<category><![CDATA[Computer Science]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1115</guid>
		<description><![CDATA[Practical Programming: An Introduction to Computer Science Using Python By Jennifer Campbell, Paul Gries, Jason Montojo and Greg Wilson Amazon I received the book, Practical Programming: An Introduction to Computer Science Using Python as a gift last month from a family member. This book is by four authors: Jennifer Campbell, Paul Gries, Jason Montojo and [...]]]></description>
			<content:encoded><![CDATA[<table>
<tr>
<td><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/pragmaticPython.jpg"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/pragmaticPython.jpg" alt="Pragmatic Python Cover  Image" title="pragmaticPython.jpg" width="300" height="300" class="aligncenter size-full wp-image-1126" /></a></td>
<td>
<h3>Practical Programming: An Introduction to Computer Science Using Python</h3>
<p><p>By Jennifer Campbell, Paul Gries, Jason Montojo and Greg Wilson</p>
<p><strong><a href="http://www.amazon.com/exec/obidos/ASIN/1934356271/thmovsthpy-20/7">Amazon</a></strong></p>
</td>
</tr>
</table>
<p>I received the book, <em>Practical Programming: An Introduction to Computer Science Using Python</em> as a gift last month from a family member. This book is by four authors: Jennifer Campbell, Paul Gries, Jason Montojo and Greg Wilson. I&#8217;d been interested in reading another Python-related textbook for a while, and this happens to be one of the few out there. The only other Python textbook I&#8217;ve read is <em><a href="http://www.amazon.com/exec/obidos/ASIN/1590282418/thmovsthpy-20/">Python Programming: An Introduction to Computer Science</a></em> by John Zelle. I&#8217;m aware of one or two others, but those books are beyond what I&#8217;m willing to pay.<span id="more-1115"></span></p>
<p>Normally when I see something that required multiple authors, the results are less than stellar. However, this book does a pretty good job of introducing students to computer science using Python. Of course, when I was taking classes in computer science, we spent multiple classes on just theory. Most of this book is on learning the basics of Python, such as how to use strings, lists, dicts, tuples, etc. So if you were hoping to learn algorithms and data structures using Python, you won&#8217;t be finding much of that here. There is one chapter on algorithms that covers sorts and search algorithms though, and I thought that was one of the highlights of the book.</p>
<p>On the other hand, you will get a nice introduction to one of the easiest and most fun to use programming languages ever created. Not only do you get a nice introduction, but each chapter ends with a series of exercises based on the text of the chapter. I like having review questions or problems to solve that make what I learned stick in my brain. I mostly skimmed the exercises though because the chapters were designed for college Freshmen with no programming experience.</p>
<p>This book covers basic testing in two places. It&#8217;s not thorough, but it does give the reader a taste and I think it conveys the reasoning behind testing fairly well. At the end of the book, they get a little more topical on us. The book gives an overview of the following topics: debugging, the object-oriented philosophy (classes, inheritance, polymorphism), graphical user interfaces using Tkinter, and databases (sqlite). </p>
<p>After reading Dusty Phillips&#8217; <a href="http://www.amazon.com/exec/obidos/ASIN/1849511268/thmovsthpy-20/">book </a>on Object Oriented Programming with Python, I found the one chapter in this book lacking. However, it is typical of an introduction, so I can&#8217;t knock it too much. The Tkinter chapter was fun as I have been planning on brushing up on that for other articles on this blog. The authors even spend some time on the Model-Viewer-Controller paradigm. I didn&#8217;t really like how they laid out the code though since it was hard to tell which code fit where in the whole MVC schema. The database section was almost straight-up SQL code using Python 2.5&#8242;s sqlite module. While there&#8217;s nothing particularly bad with that approach, I know I would have been a little confused by it because of all the new syntax that doesn&#8217;t match anything I had learned previously in the book.</p>
<p>There are some instances of weird or poor grammar, but I didn&#8217;t find any obvious coding errors that weren&#8217;t there on purpose. The book is priced reasonably, especially considering that it&#8217;s supposed to be a college textbook. If you are new to computer science or to Python, I think you&#8217;ll find this book helpful. If you&#8217;re an experienced programmer or you&#8217;ve already had several courses in computer science, than you&#8217;ll probably want to skip this book (unless you&#8217;re looking to learn Python).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/08/14/book-review-practical-programming-an-introduction-to-computer-science-using-python/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A cx_Freeze Tutorial &#8211; Build a Binary Series!</title>
		<link>http://www.blog.pythonlibrary.org/2010/08/12/a-cx_freeze-tutorial-build-a-binary-series/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/08/12/a-cx_freeze-tutorial-build-a-binary-series/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 00:40:32 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Packaging]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[binaries]]></category>
		<category><![CDATA[cx_freeze]]></category>
		<category><![CDATA[Distribution]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1112</guid>
		<description><![CDATA[In this article, we will be learning about cx_Freeze, a cross-platform set of scripts designed to &#8220;freeze&#8221; Python scripts into executables in a manner similar to py2exe, PyInstaller, etc. We will freeze one console script and one window (i.e GUI) script, using the examples from the previous article in this series. If you haven&#8217;t done [...]]]></description>
			<content:encoded><![CDATA[<p>In this article, we will be learning about cx_Freeze, a cross-platform set of scripts designed to &#8220;freeze&#8221; Python scripts into executables in a manner similar to py2exe, PyInstaller, etc. We will freeze one console script and one window (i.e GUI) script, using the examples from the previous article in this series. If you haven&#8217;t done so already, you can get cx_Freeze <a href="http://cx-freeze.sourceforge.net/">here</a>. Let&#8217;s get this party started, shall we?<span id="more-1112"></span></p>
<h2>Getting Started with cx_Freeze</h2>
<p>As mentioned on the cx_Freeze website, there are three ways to use this script. The first is to just use the included cxfreeze script; the second is to create a distutils setup script (think py2exe) which you can save for future use; and the third is to work with the internals of cxfreeze. We will focus on the first two ways of using cx_Freeze. We&#8217;ll begin with the console script:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> configobj
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig<span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Create the configuration file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    inifile = configFile
    config.<span style="color: black;">filename</span> = inifile
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'server'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;http://www.google.com&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'username'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;mike&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'password'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;dingbat&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'update interval'</span><span style="color: black;">&#93;</span> = <span style="color: #ff4500;">2</span>
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> getConfig<span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Open the config file and return a configobj
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig2<span style="color: black;">&#40;</span>path<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Create a config file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    config.<span style="color: black;">filename</span> = path
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;product&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;Sony PS3&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;accessories&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'controller'</span>, <span style="color: #483d8b;">'eye'</span>, <span style="color: #483d8b;">'memory stick'</span><span style="color: black;">&#93;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;retail price&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;$400&quot;</span>
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    createConfig2<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sampleConfig2.ini&quot;</span><span style="color: black;">&#41;</span></pre>
<p>All this script does is create a really simple configuration file using Michael Foord&#8217;s <a href="http://www.voidspace.org.uk/python/configobj.html">configobj</a> module. You can set it up to read the config too, but for this example, we&#8217;ll skip that. Let&#8217;s find out how to build a binary with cx_Freeze! According to the documentation, all it should take is the following string on the command line (assuming you are in the correct directory):</p>
<p><code><br />
cxfreeze config_1.py --target-dir dirName<br />
</code></p>
<p>This assumes that you have &#8220;C:\PythonXX\Scripts&#8221; on your path. If not, you&#8217;ll either have to fix that or type out the fully qualified path. Anyway, if the cxfreeze script run correctly, you should have a folder with the following contents:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/cx_freeze_dir.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/08/cx_freeze_dir.png" alt="cx_freeze_dir.png" title="cx_freeze_dir.png" width="587" height="244" class="aligncenter size-full wp-image-1118" /></a></p>
<p>As you can see, the total file size should be 4.81 MB or almost 5 megabytes. That was pretty easy. It even picked up the configobj module without our having to tell it to, something that PyInstaller failed to do. There are 18 command line arguments you can pass to cx_Freeze to control how it does things. These range from what modules to include or exclude, optimization, compression, include a zip file, path manipulation and more. Now let&#8217;s try something a little more advanced.</p>
<h2>&#8220;Advanced&#8221; cx_Freeze &#8211; Using a setup.py File</h2>
<p>First off we need a script to use. For this one, we&#8217;ll use that simple wxPython script from the PyInstaller article:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> wx
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoPanel<span style="color: black;">&#40;</span>wx.<span style="color: black;">Panel</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <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>, parent<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Panel</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>
&nbsp;
        labels = <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Name&quot;</span>, <span style="color: #483d8b;">&quot;Address&quot;</span>, <span style="color: #483d8b;">&quot;City&quot;</span>, <span style="color: #483d8b;">&quot;State&quot;</span>, <span style="color: #483d8b;">&quot;Zip&quot;</span>,
                  <span style="color: #483d8b;">&quot;Phone&quot;</span>, <span style="color: #483d8b;">&quot;Email&quot;</span>, <span style="color: #483d8b;">&quot;Notes&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
        mainSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">VERTICAL</span><span style="color: black;">&#41;</span>
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=<span style="color: #483d8b;">&quot;Please enter your information here:&quot;</span><span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> lbl <span style="color: #ff7700;font-weight:bold;">in</span> labels:
            sizer = <span style="color: #008000;">self</span>.<span style="color: black;">buildControls</span><span style="color: black;">&#40;</span>lbl<span style="color: black;">&#41;</span>
            mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>sizer, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">SetSizer</span><span style="color: black;">&#40;</span>mainSizer<span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Layout</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> buildControls<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        sizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">HORIZONTAL</span><span style="color: black;">&#41;</span>
        size = <span style="color: black;">&#40;</span><span style="color: #ff4500;">80</span>,<span style="color: #ff4500;">40</span><span style="color: black;">&#41;</span>
        font = wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span>
&nbsp;
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=label, size=size<span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>|wx.<span style="color: black;">CENTER</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> label <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;Notes&quot;</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name=label<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, style=wx.<span style="color: black;">TE_MULTILINE</span>, name=label<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>txt, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> sizer
&nbsp;
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoFrame<span style="color: black;">&#40;</span>wx.<span style="color: black;">Frame</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Frame that holds all other widgets
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Frame</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #008000;">None</span>, wx.<span style="color: black;">ID_ANY</span>,
                          <span style="color: #483d8b;">&quot;cxFreeze Tutorial&quot;</span>,
                          size=<span style="color: black;">&#40;</span><span style="color: #ff4500;">600</span>,<span style="color: #ff4500;">400</span><span style="color: black;">&#41;</span>
                          <span style="color: black;">&#41;</span>
        panel = DemoPanel<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">Show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    app = wx.<span style="color: black;">App</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
    frame = DemoFrame<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    app.<span style="color: black;">MainLoop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>Now let&#8217;s create a <strong>setup.py</strong> file in the cx_Freeze style:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> cx_Freeze <span style="color: #ff7700;font-weight:bold;">import</span> setup, Executable
&nbsp;
setup<span style="color: black;">&#40;</span>
    name = <span style="color: #483d8b;">&quot;wxSampleApp&quot;</span>,
    version = <span style="color: #483d8b;">&quot;0.1&quot;</span>,
    description = <span style="color: #483d8b;">&quot;An example wxPython script&quot;</span>,
    executables = <span style="color: black;">&#91;</span>Executable<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sampleApp.pyw&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
    <span style="color: black;">&#41;</span></pre>
<p>As you can see, this is a pretty simple one. We import a couple classes from cx_Freeze and pass some parameters into them. In this case, we give the <em>setup</em> class a name, version, description and and <em>Executable </em>class. The Executable class also gets one parameter, the script name that it will use to create the binary from. To get this to build the binary, you need to do the following on the command line:</p>
<p><code><br />
python setup.py build<br />
</code></p>
<p>After running this, you should end up with the following folders: &#8220;build\exe.win32-2.6&#8243;. Inside that last folder are 17 files that total 15.3 MB. When you run the sampleApp.exe file, you will notice that we&#8217;ve screwed something up. There&#8217;s a console window loading in addition to our GUI!!! To rectify this, we&#8217;ll need to change our setup file slightly. Take a look at our new one:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> cx_Freeze <span style="color: #ff7700;font-weight:bold;">import</span> setup, Executable
&nbsp;
exe = Executable<span style="color: black;">&#40;</span>
    script=<span style="color: #483d8b;">&quot;sampleApp.pyw&quot;</span>,
    base=<span style="color: #483d8b;">&quot;Win32GUI&quot;</span>,
    <span style="color: black;">&#41;</span>
&nbsp;
setup<span style="color: black;">&#40;</span>
    name = <span style="color: #483d8b;">&quot;wxSampleApp&quot;</span>,
    version = <span style="color: #483d8b;">&quot;0.1&quot;</span>,
    description = <span style="color: #483d8b;">&quot;An example wxPython script&quot;</span>,
    executables = <span style="color: black;">&#91;</span>exe<span style="color: black;">&#93;</span>
    <span style="color: black;">&#41;</span></pre>
<p>First off, we separated the <em>Executable</em> class from the <em>setup</em> class and assigned the Executable class to a variable. We also added a second parameter to the Executable class that is key. That parameter is called &#8220;base&#8221;. By setting <strong>base=&#8221;Win32GUI&#8221;</strong>, we are able to suppress the console window. A good way to learn the many other options that we can use with cx_Freeze is to use GUI2Exe to generate the setup.py files for us. The documentation on the cx_Freeze website shows the many other options that the Executable class takes. Oddly enough, I couldn&#8217;t find any information about what the <em>setup</em> class takes for arguments other than just the source itself, which has very little comments. Good luck figuring that bit out.</p>
<h2>Wrapping Up</h2>
<p>Now you should know how to create binaries with cx_Freeze. It&#8217;s pretty easy to do and it&#8217;s nice that they&#8217;ve created a method to create binaries in a cross-platform way. Have fun!</p>
<h2>Further Reading</h2>
<ul>
<li><a href="http://stackoverflow.com/questions/2880316/hide-console-window-with-wxpython-and-cxfreeze">Stackoverflow</a></li>
<li>cx_Freeze <a href="http://cx-freeze.sourceforge.net/">official site</a>, <a href="https://lists.sourceforge.net/lists/listinfo/cx-freeze-users">mailing list</a></li>
<li>GUI2Exe <a href="http://code.google.com/p/gui2exe/">website</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/08/12/a-cx_freeze-tutorial-build-a-binary-series/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A PyInstaller Tutorial &#8211; Build a Binary Series!</title>
		<link>http://www.blog.pythonlibrary.org/2010/08/10/a-pyinstaller-tutorial-build-a-binary-series/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/08/10/a-pyinstaller-tutorial-build-a-binary-series/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 01:36:13 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Packaging]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[binaries]]></category>
		<category><![CDATA[Distribution]]></category>
		<category><![CDATA[PyInstaller]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1102</guid>
		<description><![CDATA[In our previous article on building binaries, we learned a little about py2exe. This time around, we will be focusing our collective attention on the ins and outs of PyInstaller. We&#8217;ll use the same lame wxPython script from the last article for one of our examples, but we&#8217;ll also try a normal console script to [...]]]></description>
			<content:encoded><![CDATA[<p>In our previous article on building binaries, we learned a little about py2exe. This time around, we will be focusing our collective attention on the ins and outs of PyInstaller. We&#8217;ll use the same lame wxPython script from the last article for one of our examples, but we&#8217;ll also try a normal console script to see what the differences are, if any. In case you didn&#8217;t know, PyInstaller works on Linux, Windows and Mac (experimental) and works with Python 1.5-2.6 (except on Windows, where there&#8217;s a caveat for 2.6 &#8211; see below). PyInstaller supports code-signing (Windows), eggs, hidden imports, single executable, single directory, and lots more!<span id="more-1102"></span></p>
<h2>Getting Started with PyInstaller</h2>
<p><strong>Note on Python 2.6 on Windows: </strong>If you read the PyInstaller <a href="http://www.pyinstaller.org/wiki/Python26Win">website </a>closely, you will see a warning about Python 2.6+ not being fully supported. The note says that you will currently need to have the Microsoft CRT installed for your executable to work. What this is probably referring to is the side-by-side assemblies / manifest issues that were introduced with Python 2.6 vis-a-vis Microsoft Visual Studio 2008. We already mentioned this problem in the first article. If you don&#8217;t know anything about it, please check out the py2exe website, the wxPython wiki or Google for the issue.</p>
<p>Anyway, let&#8217;s get on with the show. After you download PyInstaller, you just unzip the archive somewhere convenient. The follow these three simple steps:</p>
<ol>
<li>Run <strong>Configure.py</strong> to save some basic configuration data to a &#8220;.dat&#8221; file. This saves some time since PyInstaller won&#8217;t have to recalculate the configuration on the fly.</li>
<li>Run the following command on the command line:  <em>python Makespec.py [opts] <scriptname></em> where scriptname is the name of the main Python file you use to run your program.</li>
<li>Finally, run the following command via the command line:  <em>python Build.py specfile</em> to build your executable.</li>
</ol>
<p>Let&#8217;s run through this with a real script now. We&#8217;ll start with a simple console script that creates a faux configuration file. Here&#8217;s the code:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> configobj
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig<span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Create the configuration file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    inifile = configFile
    config.<span style="color: black;">filename</span> = inifile
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'server'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;http://www.google.com&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'username'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;mike&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'password'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;dingbat&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'update interval'</span><span style="color: black;">&#93;</span> = <span style="color: #ff4500;">2</span>
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> getConfig<span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Open the config file and return a configobj
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span>configFile<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> createConfig2<span style="color: black;">&#40;</span>path<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Create a config file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    config = configobj.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    config.<span style="color: black;">filename</span> = path
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;product&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;Sony PS3&quot;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;accessories&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'controller'</span>, <span style="color: #483d8b;">'eye'</span>, <span style="color: #483d8b;">'memory stick'</span><span style="color: black;">&#93;</span>
    config<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sony&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;retail price&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;$400&quot;</span>
    config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    createConfig2<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;sampleConfig.ini&quot;</span><span style="color: black;">&#41;</span></pre>
<p>Now let&#8217;s make a spec file:</p>
<p><code><br />
c:\Python25\python c:\Users\Mike\Desktop\pyinstaller-1.4\Makespec.py config_1.py<br />
</code></p>
<p>On my test machine, I have 3 different Python versions installed, so I had to specify the Python 2.5 path explicitly (or set Python 2.5 as the default). Anyway, this should create a file similar to the following (which was named &#8220;config_1.spec&#8221;):</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># -*- mode: python -*-</span>
a = Analysis<span style="color: black;">&#40;</span><span style="color: black;">&#91;</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>HOMEPATH,<span style="color: #483d8b;">'support<span style="color: #000099; font-weight: bold;">\\</span>_mountzlib.py'</span><span style="color: black;">&#41;</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>HOMEPATH,<span style="color: #483d8b;">'support<span style="color: #000099; font-weight: bold;">\\</span>useUnicode.py'</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">'config_1.py'</span><span style="color: black;">&#93;</span>,
             pathex=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'C:<span style="color: #000099; font-weight: bold;">\\</span>Users<span style="color: #000099; font-weight: bold;">\\</span>Mike<span style="color: #000099; font-weight: bold;">\\</span>Desktop<span style="color: #000099; font-weight: bold;">\\</span>py2exe_ex'</span>, r<span style="color: #483d8b;">'C:<span style="color: #000099; font-weight: bold;">\P</span>ython26<span style="color: #000099; font-weight: bold;">\L</span>ib<span style="color: #000099; font-weight: bold;">\s</span>ite-packages'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
pyz = PYZ<span style="color: black;">&#40;</span>a.<span style="color: black;">pure</span><span style="color: black;">&#41;</span>
exe = EXE<span style="color: black;">&#40;</span>pyz,
          a.<span style="color: black;">scripts</span>,
          exclude_binaries=<span style="color: #ff4500;">1</span>,
          name=<span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'build<span style="color: #000099; font-weight: bold;">\\</span>pyi.win32<span style="color: #000099; font-weight: bold;">\\</span>config_1'</span>, <span style="color: #483d8b;">'config_1.exe'</span><span style="color: black;">&#41;</span>,
          debug=<span style="color: #008000;">False</span>,
          strip=<span style="color: #008000;">False</span>,
          upx=<span style="color: #008000;">True</span>,
          console=<span style="color: #008000;">True</span> <span style="color: black;">&#41;</span>
coll = COLLECT<span style="color: black;">&#40;</span> exe,
               a.<span style="color: black;">binaries</span>,
               a.<span style="color: black;">zipfiles</span>,
               a.<span style="color: black;">datas</span>,
               strip=<span style="color: #008000;">False</span>,
               upx=<span style="color: #008000;">True</span>,
               name=<span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'pyInstDist2'</span>, <span style="color: #483d8b;">'config_1'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre>
<p>For the Python script we&#8217;re using, we need to add an explicit path to the location of <em>configobj.py</em> in the <em>Analysis </em>section of the spec file in the <em>pathex</em> parameter. If you do not do this, when you run the resulting executable, it will open and close a console window really fast and you won&#8217;t be able to tell what it says unless you run the exe from the command line. I did the latter to find out what was wrong and discovered it could not find the configobj module. You can also specify the output path for your exe in the COLLECT function&#8217;s name parameter. In this case, we put PyInstaller&#8217;s output in the &#8220;config_1&#8243; subfolder of &#8220;pyInstDist2&#8243;, which should be a folder alongside your original script. There are a ton of options when configuring your spec file, which you can read about <a href="http://www.pyinstaller.org/export/latest/tags/1.4/doc/Manual.html?format=raw#configuring-your-pyinstaller-setup">here</a>.</p>
<p>To build the executable based on the spec file, do the following on the command line:</p>
<p><code><br />
c:\Python25\python c:\Users\Mike\Desktop\pyinstaller-1.4\Build.py config_1.spec<br />
</code></p>
<p>On my machine, I ended up with a folder that had 25 files in it that totaled 6.7 MB. You should be able to reduce the size using the Analysis section&#8217;s <em>excludes</em> parameter and/or compression.</p>
<h2>PyInstaller and wxPython</h2>
<p>Now let&#8217;s try creating a binary from a simple wxPython script. Here&#8217;s the Python script:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> wx
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoPanel<span style="color: black;">&#40;</span>wx.<span style="color: black;">Panel</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <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>, parent<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Panel</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>
&nbsp;
        labels = <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Name&quot;</span>, <span style="color: #483d8b;">&quot;Address&quot;</span>, <span style="color: #483d8b;">&quot;City&quot;</span>, <span style="color: #483d8b;">&quot;State&quot;</span>, <span style="color: #483d8b;">&quot;Zip&quot;</span>,
                  <span style="color: #483d8b;">&quot;Phone&quot;</span>, <span style="color: #483d8b;">&quot;Email&quot;</span>, <span style="color: #483d8b;">&quot;Notes&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
        mainSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">VERTICAL</span><span style="color: black;">&#41;</span>
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=<span style="color: #483d8b;">&quot;Please enter your information here:&quot;</span><span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> lbl <span style="color: #ff7700;font-weight:bold;">in</span> labels:
            sizer = <span style="color: #008000;">self</span>.<span style="color: black;">buildControls</span><span style="color: black;">&#40;</span>lbl<span style="color: black;">&#41;</span>
            mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>sizer, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">SetSizer</span><span style="color: black;">&#40;</span>mainSizer<span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Layout</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> buildControls<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        sizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">HORIZONTAL</span><span style="color: black;">&#41;</span>
        size = <span style="color: black;">&#40;</span><span style="color: #ff4500;">80</span>,<span style="color: #ff4500;">40</span><span style="color: black;">&#41;</span>
        font = wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span>
&nbsp;
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=label, size=size<span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>|wx.<span style="color: black;">CENTER</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> label <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;Notes&quot;</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name=label<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, style=wx.<span style="color: black;">TE_MULTILINE</span>, name=label<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>txt, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> sizer
&nbsp;
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoFrame<span style="color: black;">&#40;</span>wx.<span style="color: black;">Frame</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Frame that holds all other widgets
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Frame</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #008000;">None</span>, wx.<span style="color: black;">ID_ANY</span>,
                          <span style="color: #483d8b;">&quot;PyInstaller Tutorial&quot;</span>,
                          size=<span style="color: black;">&#40;</span><span style="color: #ff4500;">600</span>,<span style="color: #ff4500;">400</span><span style="color: black;">&#41;</span>
                          <span style="color: black;">&#41;</span>
        panel = DemoPanel<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">Show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    app = wx.<span style="color: black;">App</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
    frame = DemoFrame<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    app.<span style="color: black;">MainLoop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>Since this is a GUI, we&#8217;ll create our spec file slightly differently:</p>
<p><code><br />
c:\Python25\python c:\Users\Mike\Desktop\pyinstaller-1.4\Makespec.py -F -w sampleApp.py<br />
</code></p>
<p>Note the -F and -w parameters. The -F command tells PyInstaller to create just one executable whereas the -w tells PyInstaller to hide the console window. Here&#8217;s the resulting spec file:</p>
<pre class="python"><span style="color: #808080; font-style: italic;"># -*- mode: python -*-</span>
a = Analysis<span style="color: black;">&#40;</span><span style="color: black;">&#91;</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>HOMEPATH,<span style="color: #483d8b;">'support<span style="color: #000099; font-weight: bold;">\\</span>_mountzlib.py'</span><span style="color: black;">&#41;</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>HOMEPATH,<span style="color: #483d8b;">'support<span style="color: #000099; font-weight: bold;">\\</span>useUnicode.py'</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">'sampleApp.py'</span><span style="color: black;">&#93;</span>,
             pathex=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'C:<span style="color: #000099; font-weight: bold;">\\</span>Users<span style="color: #000099; font-weight: bold;">\\</span>Mike<span style="color: #000099; font-weight: bold;">\\</span>Desktop<span style="color: #000099; font-weight: bold;">\\</span>py2exe_ex'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
pyz = PYZ<span style="color: black;">&#40;</span>a.<span style="color: black;">pure</span><span style="color: black;">&#41;</span>
exe = EXE<span style="color: black;">&#40;</span> pyz,
          a.<span style="color: black;">scripts</span>,
          a.<span style="color: black;">binaries</span>,
          a.<span style="color: black;">zipfiles</span>,
          a.<span style="color: black;">datas</span>,
          name=<span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'pyInstDist'</span>, <span style="color: #483d8b;">'sampleApp.exe'</span><span style="color: black;">&#41;</span>,
          debug=<span style="color: #008000;">False</span>,
          strip=<span style="color: #008000;">False</span>,
          upx=<span style="color: #008000;">True</span>,
          console=<span style="color: #008000;">False</span> <span style="color: black;">&#41;</span></pre>
<p>Note that the last line has the &#8220;console&#8221; parameter set to &#8220;False&#8221;. If you build this like you did with the console script you should end up with one file in the &#8220;pyInstDist&#8221; folder that is approximately 7.1 MB in size. </p>
<h2>Wrapping Up</h2>
<p>This ends our quick tour of PyInstaller. I hope you found this helpful in your Python binary-making endeavors. There is much more information on the PyInstaller website and it&#8217;s pretty well documented, although the website is pretty plain. Be sure to give it a try and see just how much easy PyInstaller is to use!</p>
<p><em>Note: I tested all this using PyInstaller 1.4 and Python 2.5 on Windows 7 Home Premium (32-bit).</em></p>
<h2>Further Reading</h2>
<ul>
<li>PyInstaller Official <a href="http://www.pyinstaller.org">Website</a>, <a href="http://www.pyinstaller.org/export/latest/tags/1.4/doc/Manual.html?format=raw">Manual</a>, <a href="http://groups-beta.google.com/group/PyInstaller?pli=1">Mailing List</a></li>
<li>First <a href="http://www.blog.pythonlibrary.org/2010/07/31/a-py2exe-tutorial-build-a-binary-series/">article </a>in the &#8220;Build a Binary Series&#8221;</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/08/10/a-pyinstaller-tutorial-build-a-binary-series/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>August Pyowa Meeting Wrapup</title>
		<link>http://www.blog.pythonlibrary.org/2010/08/06/august-pyowa-meeting-wrapup/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/08/06/august-pyowa-meeting-wrapup/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 13:19:25 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Pyowa]]></category>
		<category><![CDATA[local user groups]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1098</guid>
		<description><![CDATA[We had our August 2010 Pyowa meeting last night in Ames at the Ames Public Library. Seven people attended the meeting, most of whom were regulars. I think we had one new guy or maybe he&#8217;s only been to one. Anyway, Scott presented on SqlAlchemy. He walked us through the basics using a movies example [...]]]></description>
			<content:encoded><![CDATA[<p>We had our August 2010 Pyowa meeting last night in Ames at the Ames Public Library. Seven people attended the meeting, most of whom were regulars. I think we had one new guy or maybe he&#8217;s only been to one. Anyway, Scott presented on <a href="http://www.sqlalchemy.org">SqlAlchemy</a>. He walked us through the basics using a movies example that I think get found on Jonathan Ellis&#8217;s <a href="http://spyced.blogspot.com/">site</a>. He also talked about SqlSoup, Migrate, a couple other extensions and SqlAlchemy&#8217;s TurboGears 2 integration. In fact, he demoed a couple TurboGears applications as well.</p>
<p>Our next meeting will be in Des Moines at the IMT Group building.  We are currently getting all the details nailed down for that, so be sure to check out the Pyowa <a href="http://www.pyowa.org">website </a>for updates or join our <a href="http://pyowalist.pythonlibrary.org/listinfo.cgi/pyowa-pythonlibrary.org">mailing list</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/08/06/august-pyowa-meeting-wrapup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A py2exe tutorial &#8211; Build a Binary Series!</title>
		<link>http://www.blog.pythonlibrary.org/2010/07/31/a-py2exe-tutorial-build-a-binary-series/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/07/31/a-py2exe-tutorial-build-a-binary-series/#comments</comments>
		<pubDate>Sat, 31 Jul 2010 19:52:09 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Packaging]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[binaries]]></category>
		<category><![CDATA[py2exe]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[wxPython]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1080</guid>
		<description><![CDATA[I received a request to create an article on how to use py2exe and wxPython to create an executable. I d, ecided to do a series on packaging instead. It is my intention to go over the major Windows binary building utilities and show you, dear reader, how to use them to create a binary [...]]]></description>
			<content:encoded><![CDATA[<p>I received a request to create an article on how to use py2exe and wxPython to create an executable. I d, ecided to do a series on packaging instead. It is my intention to go over the major Windows binary building utilities and show you, dear reader, how to use them to create a binary that you can distribute. Once those articles are done, I&#8217;ll show how to use Inno and NSIS. To kick things off, we&#8217;ll go over how to use py2exe, probably the most popular of the Windows executable packages.<span id="more-1080"></span></p>
<h2>Let&#8217;s Get Started</h2>
<p>For this tutorial, we&#8217;re going to use a wxPython script that doesn&#8217;t do anything. This is a contrived example, but we&#8217;re using wx to make it more visually interesting than just doing a console &#8220;Hello World&#8221; program. Note also that I am using py2exe 0.6.9, wxPython 2.8.11.0 and Python 2.6. Here&#8217;s what the end product should look like when run:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/07/py2exe_wx.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/07/py2exe_wx.png" alt="" title="py2exe_wx.png" width="496" height="400" class="aligncenter size-full wp-image-1084" /></a></p>
<p>Now that we know what it looks like, here&#8217;s a look at the code:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> wx
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoPanel<span style="color: black;">&#40;</span>wx.<span style="color: black;">Panel</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <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>, parent<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Panel</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, parent<span style="color: black;">&#41;</span>
&nbsp;
        labels = <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Name&quot;</span>, <span style="color: #483d8b;">&quot;Address&quot;</span>, <span style="color: #483d8b;">&quot;City&quot;</span>, <span style="color: #483d8b;">&quot;State&quot;</span>, <span style="color: #483d8b;">&quot;Zip&quot;</span>,
                  <span style="color: #483d8b;">&quot;Phone&quot;</span>, <span style="color: #483d8b;">&quot;Email&quot;</span>, <span style="color: #483d8b;">&quot;Notes&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
        mainSizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">VERTICAL</span><span style="color: black;">&#41;</span>
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=<span style="color: #483d8b;">&quot;Please enter your information here:&quot;</span><span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> lbl <span style="color: #ff7700;font-weight:bold;">in</span> labels:
            sizer = <span style="color: #008000;">self</span>.<span style="color: black;">buildControls</span><span style="color: black;">&#40;</span>lbl<span style="color: black;">&#41;</span>
            mainSizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>sizer, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">EXPAND</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">SetSizer</span><span style="color: black;">&#40;</span>mainSizer<span style="color: black;">&#41;</span>
        mainSizer.<span style="color: black;">Layout</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> buildControls<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        sizer = wx.<span style="color: black;">BoxSizer</span><span style="color: black;">&#40;</span>wx.<span style="color: black;">HORIZONTAL</span><span style="color: black;">&#41;</span>
        size = <span style="color: black;">&#40;</span><span style="color: #ff4500;">80</span>,<span style="color: #ff4500;">40</span><span style="color: black;">&#41;</span>
        font = wx.<span style="color: black;">Font</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">12</span>, wx.<span style="color: black;">SWISS</span>, wx.<span style="color: black;">NORMAL</span>, wx.<span style="color: black;">BOLD</span><span style="color: black;">&#41;</span>
&nbsp;
        lbl = wx.<span style="color: black;">StaticText</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, label=label, size=size<span style="color: black;">&#41;</span>
        lbl.<span style="color: black;">SetFont</span><span style="color: black;">&#40;</span>font<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>lbl, <span style="color: #ff4500;">0</span>, wx.<span style="color: black;">ALL</span>|wx.<span style="color: black;">CENTER</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> label <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;Notes&quot;</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name=label<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            txt = wx.<span style="color: black;">TextCtrl</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, style=wx.<span style="color: black;">TE_MULTILINE</span>, name=label<span style="color: black;">&#41;</span>
        sizer.<span style="color: black;">Add</span><span style="color: black;">&#40;</span>txt, <span style="color: #ff4500;">1</span>, wx.<span style="color: black;">ALL</span>, <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> sizer
&nbsp;
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">########################################################################</span>
<span style="color: #ff7700;font-weight:bold;">class</span> DemoFrame<span style="color: black;">&#40;</span>wx.<span style="color: black;">Frame</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Frame that holds all other widgets
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructor&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        wx.<span style="color: black;">Frame</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #008000;">None</span>, wx.<span style="color: black;">ID_ANY</span>,
                          <span style="color: #483d8b;">&quot;Py2Exe Tutorial&quot;</span>,
                          size=<span style="color: black;">&#40;</span><span style="color: #ff4500;">600</span>,<span style="color: #ff4500;">400</span><span style="color: black;">&#41;</span>
                          <span style="color: black;">&#41;</span>
        panel = DemoPanel<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">Show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    app = wx.<span style="color: black;">App</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
    frame = DemoFrame<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    app.<span style="color: black;">MainLoop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>
<p>This is fairly straightforward, so I&#8217;ll leave it the reader to figure out. This article is about py2exe after all.</p>
<h2>The py2exe setup.py file</h2>
<p>The key to any py2exe script is the <em>setup.py</em> file. This file controls what gets included or excluded, how much we compress and bundle, and much more! Here is the simplest setup that we can use with the wx script above:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">distutils</span>.<span style="color: black;">core</span> <span style="color: #ff7700;font-weight:bold;">import</span> setup
<span style="color: #ff7700;font-weight:bold;">import</span> py2exe
&nbsp;
setup<span style="color: black;">&#40;</span>windows=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'sampleApp.py'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre>
<p>As you can see, we import the <em>setup</em> method from <em>distutils.core</em> and then we import <em>py2exe</em>. Next we call setup with a <em>windows</em> keyword parameter and pass it the name of the main file inside a python list object. If you were creating a non-GUI project, than you would use the <em>console </em> key instead of <em>windows</em>. To run this, open up a command prompt and navigate to the appropriate location. Then type &#8220;python setup.py py2exe&#8221; to run it. This is what I got when I first ran it:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/07/py2exe_firstrun.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/07/py2exe_firstrun.png" alt="" title="py2exe_firstrun.png" width="450" height="325" class="aligncenter size-full wp-image-1085" /></a></p>
<p>It looks like wxPython requires the &#8220;MSVCP90.dll&#8221; and Windows can&#8217;t find it. A quick Google search yielded the consensus that I needed the &#8220;Microsoft Visual C++ 2008 Redistributable Package&#8221;, found <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=9b2da534-3e03-4391-8a4d-074b9f2bc1bf&#038;displaylang=en">here</a>. I downloaded it, installed it and tried py2exe again. Same error. This would have probably worked had I been using Visual Studio to create an exe of a C# program. Anyway, the trick was to search the hard drive for the file and then copy it to Python&#8217;s DLL folder, which on my machine was found at the following location: C:\Python26\DLLs (adjust as necessary on your machine). Once the DLL was in the proper place, the setup.py file ran just fine. The result was put into a &#8220;dist&#8221; folder which contains 17 files and weighs in at 15.3 MB. I double-clicked the &#8220;sampleApp.exe&#8221; file to see if my shiny new binary would work and it did! In older versions of wxPython, you would have needed to include a manifest file to get the right look and feel (i.e the themes), but that was taken care of in 2.8.10 (I think) as was the side-by-side (SxS) assembly manifest file that used to be required.</p>
<p>Note that for non-wxPython scripts, you will probably still need to mess with the SxS manifests and all the hoops that includes. You can read more about that in the <a href="http://py2exe.org/index.cgi/Tutorial">py2exe tutorial</a>.</p>
<h2>Creating an Advanced setup.py File</h2>
<p>Let&#8217;s see what other options py2exe gives us for creating binaries by creating a more complex setup.py file. </p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">distutils</span>.<span style="color: black;">core</span> <span style="color: #ff7700;font-weight:bold;">import</span> setup
<span style="color: #ff7700;font-weight:bold;">import</span> py2exe
&nbsp;
includes = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
excludes = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'_gtkagg'</span>, <span style="color: #483d8b;">'_tkagg'</span>, <span style="color: #483d8b;">'bsddb'</span>, <span style="color: #483d8b;">'curses'</span>, <span style="color: #483d8b;">'email'</span>, <span style="color: #483d8b;">'pywin.debugger'</span>,
            <span style="color: #483d8b;">'pywin.debugger.dbgcon'</span>, <span style="color: #483d8b;">'pywin.dialogs'</span>, <span style="color: #483d8b;">'tcl'</span>,
            <span style="color: #483d8b;">'Tkconstants'</span>, <span style="color: #483d8b;">'Tkinter'</span><span style="color: black;">&#93;</span>
packages = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
dll_excludes = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'libgdk-win32-2.0-0.dll'</span>, <span style="color: #483d8b;">'libgobject-2.0-0.dll'</span>, <span style="color: #483d8b;">'tcl84.dll'</span>,
                <span style="color: #483d8b;">'tk84.dll'</span><span style="color: black;">&#93;</span>
&nbsp;
setup<span style="color: black;">&#40;</span>
    options = <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;py2exe&quot;</span>: <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;compressed&quot;</span>: <span style="color: #ff4500;">2</span>,
                          <span style="color: #483d8b;">&quot;optimize&quot;</span>: <span style="color: #ff4500;">2</span>,
                          <span style="color: #483d8b;">&quot;includes&quot;</span>: includes,
                          <span style="color: #483d8b;">&quot;excludes&quot;</span>: excludes,
                          <span style="color: #483d8b;">&quot;packages&quot;</span>: packages,
                          <span style="color: #483d8b;">&quot;dll_excludes&quot;</span>: dll_excludes,
                          <span style="color: #483d8b;">&quot;bundle_files&quot;</span>: <span style="color: #ff4500;">3</span>,
                          <span style="color: #483d8b;">&quot;dist_dir&quot;</span>: <span style="color: #483d8b;">&quot;dist&quot;</span>,
                          <span style="color: #483d8b;">&quot;xref&quot;</span>: <span style="color: #008000;">False</span>,
                          <span style="color: #483d8b;">&quot;skip_archive&quot;</span>: <span style="color: #008000;">False</span>,
                          <span style="color: #483d8b;">&quot;ascii&quot;</span>: <span style="color: #008000;">False</span>,
                          <span style="color: #483d8b;">&quot;custom_boot_script&quot;</span>: <span style="color: #483d8b;">''</span>,
                         <span style="color: black;">&#125;</span>
              <span style="color: black;">&#125;</span>,
    windows=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'sampleApp.py'</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#41;</span></pre>
<p>This is pretty self-explanatory, but let&#8217;s unpack it anyway. First we set up a few lists that we pass to the options parameter of the setup function. </p>
<ul>
<li>The <em>includes</em> list is for special modules that you need to specifically include. Sometimes py2exe can&#8217;t find certain modules, so you get to manually specify them here. </li>
<li>The <em>excludes</em> list is a list of which modules to exclude from your program. In this case, we don&#8217;t need Tkinter since we&#8217;re using wxPython. This list of excludes is what GUI2Exe will exclude by default.</li>
<li>The <em>packages</em> list is a list of specific packages to include. Again, sometimes py2exe just can&#8217;t find something. I&#8217;ve had to include email, PyCrypto, or lxml here before. Note that if the excludes list contains something you&#8217;re trying to include in the packages or includes lists, py2exe may continue to exclude them.</li>
<li><em>dll_excludes</em> &#8211; excludes dlls that we don&#8217;t need in our project.</li>
</ul>
<p>In the <em>options</em> dictionary, we have a few other options to look at. The <em>compressed</em> key tells py2exe whether or not to compress the zipfile, if it&#8217;s set. The <em>optimize</em> key sets the optimization level. Zero is no optimization and 2 is the highest. The <em>bundle_files</em> key bundles dlls in the zipfile or the exe. Valid values for <em>bundle_files</em> are: 3 = don&#8217;t bundle (default) 2 = bundle everything but the Python interpreter 1 = bundle everything, including the Python interpreter. A couple of years ago, when I was first learning py2exe, I asked on their mailing list what the best option was because I was having issues with bundle option 1. I was told that 3 was probably the most stable. I went with that and stopped having random problems, so that&#8217;s what I currently recommend. If you don&#8217;t like distributing more than one file, zip them up or create an installer. The only other option I use in this list is the <em>dist_dir</em> one. I use it to experiment with different built options or to create custom builds when I don&#8217;t want to overwrite my main good build. You can read about all the other options (including ones not even listed here) on the <a href="http://py2exe.org/index.cgi/ListOfOptions">py2exe website</a>. By setting optimize to 2, we can reduce the size of folder by about one megabyte. </p>
<h2>Reducing a wxPython Script&#8217;s Binary Size</h2>
<p>There&#8217;s a <a href="http://bit.ly/bwIDNd">thread </a>on the wxPython mailing list about reducing the size of the binary. I contacted Steven Sproat, one of the people in the thread, about what he did and here&#8217;s the trick: Set the &#8220;bundle_files&#8221; option to 1 and the the zipfile to None. The result will be three files in your dist folder: MSVCR71.dll, sampleApp.exe and w9xpopen.exe. The size of the folder is 5.94 MB on my machine (Tested on a Windows XP machine). As I mentioned earlier, setting bundle_files to 1 can cause some users to experience issues when running your application, but this may have been fixed with the newer versions of py2exe. Here&#8217;s what the setup.py file looks like with the new options set:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">distutils</span>.<span style="color: black;">core</span> <span style="color: #ff7700;font-weight:bold;">import</span> setup
<span style="color: #ff7700;font-weight:bold;">import</span> py2exe
&nbsp;
includes = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
excludes = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'_gtkagg'</span>, <span style="color: #483d8b;">'_tkagg'</span>, <span style="color: #483d8b;">'bsddb'</span>, <span style="color: #483d8b;">'curses'</span>, <span style="color: #483d8b;">'email'</span>, <span style="color: #483d8b;">'pywin.debugger'</span>,
            <span style="color: #483d8b;">'pywin.debugger.dbgcon'</span>, <span style="color: #483d8b;">'pywin.dialogs'</span>, <span style="color: #483d8b;">'tcl'</span>,
            <span style="color: #483d8b;">'Tkconstants'</span>, <span style="color: #483d8b;">'Tkinter'</span><span style="color: black;">&#93;</span>
packages = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
dll_excludes = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'libgdk-win32-2.0-0.dll'</span>, <span style="color: #483d8b;">'libgobject-2.0-0.dll'</span>, <span style="color: #483d8b;">'tcl84.dll'</span>,
                <span style="color: #483d8b;">'tk84.dll'</span><span style="color: black;">&#93;</span>
&nbsp;
setup<span style="color: black;">&#40;</span>
    options = <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;py2exe&quot;</span>: <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;compressed&quot;</span>: <span style="color: #ff4500;">2</span>,
                          <span style="color: #483d8b;">&quot;optimize&quot;</span>: <span style="color: #ff4500;">2</span>,
                          <span style="color: #483d8b;">&quot;includes&quot;</span>: includes,
                          <span style="color: #483d8b;">&quot;excludes&quot;</span>: excludes,
                          <span style="color: #483d8b;">&quot;packages&quot;</span>: packages,
                          <span style="color: #483d8b;">&quot;dll_excludes&quot;</span>: dll_excludes,
                          <span style="color: #483d8b;">&quot;bundle_files&quot;</span>: <span style="color: #ff4500;">1</span>,
                          <span style="color: #483d8b;">&quot;dist_dir&quot;</span>: <span style="color: #483d8b;">&quot;dist&quot;</span>,
                          <span style="color: #483d8b;">&quot;xref&quot;</span>: <span style="color: #008000;">False</span>,
                          <span style="color: #483d8b;">&quot;skip_archive&quot;</span>: <span style="color: #008000;">False</span>,
                          <span style="color: #483d8b;">&quot;ascii&quot;</span>: <span style="color: #008000;">False</span>,
                          <span style="color: #483d8b;">&quot;custom_boot_script&quot;</span>: <span style="color: #483d8b;">''</span>,
                         <span style="color: black;">&#125;</span>
              <span style="color: black;">&#125;</span>,
    <span style="color: #dc143c;">zipfile</span> = <span style="color: #008000;">None</span>,
    windows=<span style="color: black;">&#91;</span><span style="color: #483d8b;">'sampleApp.py'</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#41;</span></pre>
<p>Another way to reduce the size of the folder is to use compression programs as one of my readers, ProgMan, pointed out. Here are his results:</p>
<p><a href="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/07/sampleapps.png"><img src="http://www.blog.pythonlibrary.org/wp-content/uploads/2010/07/sampleapps.png" alt="" title="sampleapps" width="496" height="315" class="aligncenter size-full wp-image-1096" /></a></p>
<h2>Wrapping Up</h2>
<p>You now know the basics for creating binaries with py2exe. I hope you have found this helpful for your current or future projects. If so, let me know in the comments!</p>
<h2>Further Reading</h2>
<ul>
<li>The py2exe <a href="http://py2exe.org/index.cgi/Tutorial">Tutorial</a></li>
<li><a href="http://www.blog.pythonlibrary.org/2008/08/27/packaging-wxpymail-for-distribution/">Packaging wxPyMail for Distribution</a></li>
<li><a href="http://code.google.com/p/gui2exe/">GUI2Exe</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/07/31/a-py2exe-tutorial-build-a-binary-series/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PyWin32: Getting Windows Event Logs</title>
		<link>http://www.blog.pythonlibrary.org/2010/07/27/pywin32-getting-windows-event-logs/</link>
		<comments>http://www.blog.pythonlibrary.org/2010/07/27/pywin32-getting-windows-event-logs/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 12:14:28 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[PyWin32]]></category>
		<category><![CDATA[System Admin]]></category>

		<guid isPermaLink="false">http://www.blog.pythonlibrary.org/?p=1071</guid>
		<description><![CDATA[The other day, there was a post on one of the mailing lists that I follow about accessing the Windows Event Logs. I thought that was an interesting topic, so I went looking for examples and found a pretty nice example on ActiveState. In this article, you&#8217;ll find out what I discovered. It&#8217;s probably easiest [...]]]></description>
			<content:encoded><![CDATA[<p>The  other day, there was a post on one of the mailing lists that I follow about accessing the Windows Event Logs. I thought that was an interesting topic, so I went looking for examples and found a pretty nice example on <a href="http://docs.activestate.com/activepython/2.5/pywin32/Windows_NT_Eventlog.html">ActiveState</a>. In this article, you&#8217;ll find out what I discovered.<span id="more-1071"></span></p>
<p>It&#8217;s probably easiest to just jump right into the code. Note that the only thing other than Python that you will need is the PyWin32 package. Once you&#8217;ve got that, then you can follow along:</p>
<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">codecs</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</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> win32con
<span style="color: #ff7700;font-weight:bold;">import</span> win32evtlog
<span style="color: #ff7700;font-weight:bold;">import</span> win32evtlogutil
<span style="color: #ff7700;font-weight:bold;">import</span> winerror
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> getAllEvents<span style="color: black;">&#40;</span>server, logtypes, basePath<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> server:
        serverName = <span style="color: #483d8b;">&quot;localhost&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        serverName = server
    <span style="color: #ff7700;font-weight:bold;">for</span> logtype <span style="color: #ff7700;font-weight:bold;">in</span> logtypes:
        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>basePath, <span style="color: #483d8b;">&quot;%s_%s_log.log&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>serverName, logtype<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        getEventLogs<span style="color: black;">&#40;</span>server, logtype, path<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#----------------------------------------------------------------------</span>
<span style="color: #ff7700;font-weight:bold;">def</span> getEventLogs<span style="color: black;">&#40;</span>server, logtype, logPath<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Get the event logs from the specified machine according to the
    logtype (Example: Application) and save it to the appropriately
    named log file
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Logging %s events&quot;</span> <span style="color: #66cc66;">%</span> logtype
    log = <span style="color: #dc143c;">codecs</span>.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span>logPath, encoding=<span style="color: #483d8b;">'utf-8'</span>, mode=<span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
    line_break = <span style="color: #483d8b;">'-'</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">80</span>
&nbsp;
    log.<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>%s Log of %s Events<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>server, logtype<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    log.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Created: %s<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: #dc143c;">time</span>.<span style="color: black;">ctime</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    log.<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>&quot;</span> + line_break + <span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
    hand = win32evtlog.<span style="color: black;">OpenEventLog</span><span style="color: black;">&#40;</span>server,logtype<span style="color: black;">&#41;</span>
    total = win32evtlog.<span style="color: black;">GetNumberOfEventLogRecords</span><span style="color: black;">&#40;</span>hand<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Total events in %s = %s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>logtype, total<span style="color: black;">&#41;</span>
    flags = win32evtlog.<span style="color: black;">EVENTLOG_BACKWARDS_READ</span>|win32evtlog.<span style="color: black;">EVENTLOG_SEQUENTIAL_READ</span>
    events = win32evtlog.<span style="color: black;">ReadEventLog</span><span style="color: black;">&#40;</span>hand,flags,<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
    evt_dict=<span style="color: black;">&#123;</span>win32con.<span style="color: black;">EVENTLOG_AUDIT_FAILURE</span>:<span style="color: #483d8b;">'EVENTLOG_AUDIT_FAILURE'</span>,
              win32con.<span style="color: black;">EVENTLOG_AUDIT_SUCCESS</span>:<span style="color: #483d8b;">'EVENTLOG_AUDIT_SUCCESS'</span>,
              win32con.<span style="color: black;">EVENTLOG_INFORMATION_TYPE</span>:<span style="color: #483d8b;">'EVENTLOG_INFORMATION_TYPE'</span>,
              win32con.<span style="color: black;">EVENTLOG_WARNING_TYPE</span>:<span style="color: #483d8b;">'EVENTLOG_WARNING_TYPE'</span>,
              win32con.<span style="color: black;">EVENTLOG_ERROR_TYPE</span>:<span style="color: #483d8b;">'EVENTLOG_ERROR_TYPE'</span><span style="color: black;">&#125;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        events=<span style="color: #ff4500;">1</span>
        <span style="color: #ff7700;font-weight:bold;">while</span> events:
            events=win32evtlog.<span style="color: black;">ReadEventLog</span><span style="color: black;">&#40;</span>hand,flags,<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
&nbsp;
            <span style="color: #ff7700;font-weight:bold;">for</span> ev_obj <span style="color: #ff7700;font-weight:bold;">in</span> events:
                the_time = ev_obj.<span style="color: black;">TimeGenerated</span>.<span style="color: black;">Format</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;">#'12/23/99 15:54:09'</span>
                evt_id = <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>winerror.<span style="color: black;">HRESULT_CODE</span><span style="color: black;">&#40;</span>ev_obj.<span style="color: black;">EventID</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
                computer = <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>ev_obj.<span style="color: black;">ComputerName</span><span style="color: black;">&#41;</span>
                cat = ev_obj.<span style="color: black;">EventCategory</span>
        <span style="color: #808080; font-style: italic;">##        seconds=date2sec(the_time)</span>
                record = ev_obj.<span style="color: black;">RecordNumber</span>
                msg = win32evtlogutil.<span style="color: black;">SafeFormatMessage</span><span style="color: black;">&#40;</span>ev_obj, logtype<span style="color: black;">&#41;</span>
&nbsp;
                source = <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>ev_obj.<span style="color: black;">SourceName</span><span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> ev_obj.<span style="color: black;">EventType</span> <span style="color: #ff7700;font-weight:bold;">in</span> evt_dict.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
                    evt_type = <span style="color: #483d8b;">&quot;unknown&quot;</span>
                <span style="color: #ff7700;font-weight:bold;">else</span>:
                    evt_type = <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>evt_dict<span style="color: black;">&#91;</span>ev_obj.<span style="color: black;">EventType</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
                log.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Event Date/Time: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> the_time<span style="color: black;">&#41;</span>
                log.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Event ID / Type: %s / %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>evt_id, evt_type<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
                log.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Record #%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> record<span style="color: black;">&#41;</span>
                log.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Source: %s<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> source<span style="color: black;">&#41;</span>
                log.<span style="color: black;">write</span><span style="color: black;">&#40;</span>msg<span style="color: black;">&#41;</span>
                log.<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>
                log.<span style="color: black;">write</span><span style="color: black;">&#40;</span>line_break<span style="color: black;">&#41;</span>
                log.<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>
    <span style="color: #ff7700;font-weight:bold;">except</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">traceback</span>.<span style="color: black;">print_exc</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">exc_info</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Log creation finished. Location of log is %s&quot;</span> <span style="color: #66cc66;">%</span> logPath
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    server = <span style="color: #008000;">None</span>  <span style="color: #808080; font-style: italic;"># None = local machine</span>
    logTypes = <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;System&quot;</span>, <span style="color: #483d8b;">&quot;Application&quot;</span>, <span style="color: #483d8b;">&quot;Security&quot;</span><span style="color: black;">&#93;</span>
    getAllEvents<span style="color: black;">&#40;</span>server, logTypes, <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\d</span>ownloads&quot;</span><span style="color: black;">&#41;</span></pre>
<p>There are a couple potential caveats to this type of scripting. I tested this code as an Administrator on my PCs and as a Domain Administrator at work. I did not test it as any other type of user. So if you have problems getting this code to run, check your permissions. I tested this from Windows XP  and Windows 7. The UAC doesn&#8217;t appear to block this activity on Windows 7, so that made it just as easy to use as XP did. However, Windows 7&#8242;s events had some unicode in the message portion of the code whereas XP did not. Watch out for that and handle it accordingly.</p>
<p>Anyway, let&#8217;s unpack this script and see how it works. First we have a number of imports. We use the <em>codecs</em> modules to encode the log file in utf-8 just in case there&#8217;s some sneaky unicode in the message. We use PyWin32&#8242;s <em>win32evtlog</em> module to open the event log and pull information out of it. According to the article I mentioned at the beginning, to get all the events from the log, you need to call <em>win32evtlog.ReadEventLog</em> repeatedly until it stops returning events. Thus, we use <em>while </em>loop. Inside the while loop, we use a <em>for</em> loop to iterate over the events and extract the event ID, record number, event message, event source and a few other tidbits. We log it and then we exit the <em>for</em> loop and the <em>while</em> loop calls the <em>win32evtlog.ReadEventLog</em> again.</p>
<p>We use the <em>traceback</em> module to print out any errors that occur during the script&#8217;s run. And that&#8217;s all there is to it!</p>
<h2>Wrapping Up</h2>
<p>As you can see, using the PyWin32 package is easy. If you get stuck, it has some great documentation. If that documentation isn&#8217;t good enough though, you can fall back on MSDN instead. PyWin32 is a light wrapper around Windows&#8217; API, so using MSDN&#8217;s instructions is fairly simple. Anyway, I hope you learned a lot and will find it helpful.</p>
<h2>Further Reading</h2>
<ul>
<li><a href="http://docs.python.org/howto/unicode.html">Python and Unicode</a></li>
<li><a href="http://sourceforge.net/projects/pywin32/">PyWin32</a></li>
<li>PyWin32 <a href="http://docs.activestate.com/activepython/2.5/pywin32/PyWin32.HTML">Documentation </a>from ActiveState</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.pythonlibrary.org/2010/07/27/pywin32-getting-windows-event-logs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 2.771 seconds -->
<!-- Cached page served by WP-Cache -->
