<?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 “Invent with Python” Blog &#187; Uncategorized</title>
	<atom:link href="http://inventwithpython.com/blog/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://inventwithpython.com/blog</link>
	<description>News about Al Sweigart’s programming books.</description>
	<lastBuildDate>Wed, 16 May 2012 20:59:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Stop Using &#8220;print&#8221; for Debugging: A 5 Minute Quickstart Guide to Python’s logging Module</title>
		<link>http://inventwithpython.com/blog/2012/04/06/stop-using-print-for-debugging-a-5-minute-quickstart-guide-to-pythons-logging-module/</link>
		<comments>http://inventwithpython.com/blog/2012/04/06/stop-using-print-for-debugging-a-5-minute-quickstart-guide-to-pythons-logging-module/#comments</comments>
		<pubDate>Fri, 06 Apr 2012 17:15:35 +0000</pubDate>
		<dc:creator>Al Sweigart</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://inventwithpython.com/blog/?p=675</guid>
		<description><![CDATA[This tutorial is short. To figure out bugs in your code, you might put in print statements/print() calls to display the value of variables. Don’t do this. Use the Python logging module. The logging is better than printing because: It&#8217;s easy to put a timestamp in each message, which is very handy. You can have [...]]]></description>
			<content:encoded><![CDATA[<ul>
<li>This tutorial is short.</li>
<li>To figure out bugs in your code, you might put in <code>print</code> statements/<code>print()</code> calls to display the value of variables.</li>
<li>Don’t do this. Use the Python <code>logging</code> module.</li>
</ul>
<p>The <code>logging</code> is better than printing because:</p>
<ul>
<li>It&#8217;s easy to put a timestamp in each message, which is very handy.</li>
<li>You can have different levels of urgency for messages, and filter how less urgent messages.</li>
<li>When you want to later find/remove log messages, you won&#8217;t get them confused for real <code>print()</code> calls.</li>
<li>If you just print to a log file, it&#8217;s easy to leave the log function calls in and just ignore them when you don&#8217;t need them. (You don&#8217;t have to constantly pull out print() calls.)</li>
</ul>
<p>Using print is for coders with too much time on their hands. Use logging instead. Also, learn to use <a href="http://mihirknows.blogspot.com/2007/10/debugging-with-python-pdb-quick-and.html">the Python debugger</a> to debug bugs and <a href="http://www.logilab.org/857">Pylint</a> to prevent bugs and make your code readable.</p>
<p>To <strong>print log messages to the screen</strong>, copy and paste this code:</p>
<blockquote><p><code>import logging<br />
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')<br />
logging.debug('This is a log message.')</code></p></blockquote>
<p>To <strong>write log messages to a file</strong>, you can copy and paste this code (the only difference is <strong>in bold</strong>):</p>
<blockquote><p><code>import logging<br />
logging.basicConfig(<strong>filename='log_filename.txt', </strong>level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')<br />
logging.debug('This is a log message.')</code></p></blockquote>
<p>Later runs of the program will append to the end of the log file, rather than overwrite the file.</p>
<p>To log messages to a file <strong>AND</strong> printed to the screen, copy and paste the following:<br />
<span id="more-675"></span></p>
<blockquote><p><code>import logging<br />
logger = logging.getLogger()<br />
logger.setLevel(logging.DEBUG)</p>
<p>formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')</p>
<p>fh = logging.FileHandler('log_filename.txt')<br />
fh.setLevel(logging.DEBUG)<br />
fh.setFormatter(formatter)<br />
logger.addHandler(fh)</p>
<p>ch = logging.StreamHandler()<br />
ch.setLevel(logging.DEBUG)<br />
ch.setFormatter(formatter)<br />
logger.addHandler(ch)</p>
<p>logger.debug('This is a test log message.')</code></p></blockquote>
<p>Make sure that the <code>logger</code> variable is global, so that you can use it in functions. (You don&#8217;t need the &#8220;<code>global logger</code>&#8221; at the top of the function, because the <code>logger</code> variable is only read, not modified.)</p>
<hr />
<p>The different levels of logging, from highest urgency to lowest urgency, are:</p>
<ol>
<li>CRITICAL</li>
<li>ERROR</li>
<li>WARNING</li>
<li>INFO</li>
<li>DEBUG</li>
</ol>
<p>The <code>setLevel()</code> call sets the minimum log level of messages it actually logs. So if you <code>fh.setLevel(logging.ERROR)</code>, then WARNING, INFO, and DEBUG log messages will not be written to the log file (since <code>fh</code> is the log handler for the log file, as opposed to <code>ch</code> which is the handler for the console screen.)</p>
<p>To write a log message in one of these five levels, use the following functions:</p>
<ol>
<li><code>logger.critical('This is a critical message.')</code></li>
<li><code>logger.error('This is an error message.')</code></li>
<li><code>logger.warning('This is a warning message.')</code></li>
<li><code>logger.info('This is an informative message.')</code></li>
<li><code>logger.debug('This is a low-level debug message.')</code></li>
</ol>
<p>There&#8217;s plenty more you can do, but this all you need to know to never again use <code>print()</code> calls to do your debugging work.</p>
<p>The <a href="http://docs.python.org/library/logging.html">Python documentation</a> has more info, including a <a href="http://docs.python.org/howto/logging.html#logging-basic-tutorial">Basic Tutorial</a>, an <a href="http://docs.python.org/howto/logging.html#logging-advanced-tutorial">Advanced Tutorial</a>, and a <a href="http://docs.python.org/howto/logging-cookbook.html#logging-cookbook">Logging Cookbook</a>.</p>
<p>Also, the <a href="http://docs.python.org/library/pprint.html#pprint.pprint">pprint.pprint() function</a> is great for &#8220;pretty printing&#8221; dictionaries and lists that have nested dictionaries and lists in them. The <a href="http://docs.python.org/library/pprint.html#pprint.pformat">pprint.pformat() function</a> returns the string of this content, rather than printing it to the screen.</p>
<hr />
<p>One final tip: You can use the <code>tail -f logfile.txt</code> command to show a file as it is being written to. The -f stands for &#8220;follow&#8221;. Just leave a terminal/console window open with this command running, and new text in the log file will appear as it is written. This way, you don&#8217;t have to keep opening/reloading a text editor to view the latest text in the log file.</p>
<p>The tail command comes on Mac OS X and Linux OSes. On Windows, you can download the <a href="http://www.cygwin.com/install.html">Cygwin project</a> to get the tail command.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Finventwithpython.com%2Fblog%2F2012%2F04%2F06%2Fstop-using-print-for-debugging-a-5-minute-quickstart-guide-to-pythons-logging-module%2F&amp;title=Stop%20Using%20%E2%80%9Cprint%E2%80%9D%20for%20Debugging%3A%20A%205%20Minute%20Quickstart%20Guide%20to%20Python%E2%80%99s%20logging%20Module" id="wpa2a_2"><img src="http://inventwithpython.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://inventwithpython.com/blog/2012/04/06/stop-using-print-for-debugging-a-5-minute-quickstart-guide-to-pythons-logging-module/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>My awesome exciting indie Pygame games: &#8220;Look At This Rock&#8221; and &#8220;Look At This Rock 2: A Different Rock&#8221;</title>
		<link>http://inventwithpython.com/blog/2011/10/21/my-awesome-exciting-indie-games-look-at-this-rock-and-look-at-this-rock-2-a-different-rock/</link>
		<comments>http://inventwithpython.com/blog/2011/10/21/my-awesome-exciting-indie-games-look-at-this-rock-and-look-at-this-rock-2-a-different-rock/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 19:03:29 +0000</pubDate>
		<dc:creator>Al Sweigart</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://inventwithpython.com/blog/?p=489</guid>
		<description><![CDATA[Here are a couple games I wrote. The first was so popular that I made a sequel: Win32 EXEs and source: Look At This Rock Look At This Rock 2: A Different Rock Source (requires Pygame to be installed along with Python): Source: LookAtThisRock.py and PNG Source: LookAtThisRock2.py and PNG Screenshots:]]></description>
			<content:encoded><![CDATA[<p>Here are a couple games I wrote. The first was so popular that I made a sequel:</p>
<p>Win32 EXEs and source:</p>
<p><a href="http://inventwithpython.com/LookAtThisRock.zip">Look At This Rock</a></p>
<p><a href="http://inventwithpython.com/LookAtThisRock2.zip">Look At This Rock 2: A Different Rock</a></p>
<p>Source (requires <a href="http://pygame.org">Pygame</a> to be installed along with Python):</p>
<p><a href="http://inventwithpython.com/LookAtThisRock.py">Source: LookAtThisRock.py</a> and <a href="http://inventwithpython.com/rock1.png">PNG</a></p>
<p><a href="http://inventwithpython.com/LookAtThisRock2.py">Source: LookAtThisRock2.py</a> and <a href="http://inventwithpython.com/rock2.png">PNG</a></p>
<p>Screenshots:</p>
<p><img src="http://inventwithpython.com/screenshot_rock.png" /></p>
<p><img src="http://inventwithpython.com/screenshot_rock2.png" /></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Finventwithpython.com%2Fblog%2F2011%2F10%2F21%2Fmy-awesome-exciting-indie-games-look-at-this-rock-and-look-at-this-rock-2-a-different-rock%2F&amp;title=My%20awesome%20exciting%20indie%20Pygame%20games%3A%20%E2%80%9CLook%20At%20This%20Rock%E2%80%9D%20and%20%E2%80%9CLook%20At%20This%20Rock%202%3A%20A%20Different%20Rock%E2%80%9D" id="wpa2a_4"><img src="http://inventwithpython.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://inventwithpython.com/blog/2011/10/21/my-awesome-exciting-indie-games-look-at-this-rock-and-look-at-this-rock-2-a-different-rock/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>JavaScript Cipher Wheel</title>
		<link>http://inventwithpython.com/blog/2011/09/20/javascript-cipher-wheel/</link>
		<comments>http://inventwithpython.com/blog/2011/09/20/javascript-cipher-wheel/#comments</comments>
		<pubDate>Wed, 21 Sep 2011 05:19:40 +0000</pubDate>
		<dc:creator>Al Sweigart</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://inventwithpython.com/blog/?p=434</guid>
		<description><![CDATA[I&#8217;ve created a web version of the Caesar Cipher wheel using JQuery and CSS sprites. JavaScript Cipher Wheel I also have a Pygame version and Windows executable of this.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve created a web version of the Caesar Cipher wheel using JQuery and CSS sprites.</p>
<p><strong><a href="http://inventwithpython.com/cipherwheel">JavaScript Cipher Wheel</a></strong></p>
<p><a href="http://inventwithpython.com/cipherwheel"><img src="http://inventwithpython.com/cipherwheel/js_cipherwheel.png"></a></p>
<p>I also have a <a href="http://inventwithpython.com/blog/2011/09/18/virtual-caesar-cipher-wheel-program/">Pygame version and Windows executable</a> of this.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Finventwithpython.com%2Fblog%2F2011%2F09%2F20%2Fjavascript-cipher-wheel%2F&amp;title=JavaScript%20Cipher%20Wheel" id="wpa2a_6"><img src="http://inventwithpython.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://inventwithpython.com/blog/2011/09/20/javascript-cipher-wheel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Great Pygame Example Site</title>
		<link>http://inventwithpython.com/blog/2011/05/16/great-pygame-example-site/</link>
		<comments>http://inventwithpython.com/blog/2011/05/16/great-pygame-example-site/#comments</comments>
		<pubDate>Mon, 16 May 2011 17:10:00 +0000</pubDate>
		<dc:creator>Al Sweigart</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://inventwithpython.com/blog/?p=288</guid>
		<description><![CDATA[I wanted to share this link to a great site with some simple Pygame examples: Python and Pygame Examples There is also a textbook draft called &#8220;Introduction to Computer Science Using Python and Pygame&#8221; by Paul Vincent Craven.]]></description>
			<content:encoded><![CDATA[<p>I wanted to share this link to a great site with some simple Pygame examples:</p>
<p><a href="http://cs.simpson.edu/?q=python_pygame_examples">Python and Pygame Examples</a></p>
<p>There is also a textbook draft called <a href="http://cs.simpson.edu/files/CS_Intro_Book.pdf">&#8220;Introduction to Computer Science Using Python and Pygame&#8221;</a> by Paul Vincent Craven.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Finventwithpython.com%2Fblog%2F2011%2F05%2F16%2Fgreat-pygame-example-site%2F&amp;title=Great%20Pygame%20Example%20Site" id="wpa2a_8"><img src="http://inventwithpython.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://inventwithpython.com/blog/2011/05/16/great-pygame-example-site/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;MooseGesture&#8221; &#8211; Python Mouse Gestures Module</title>
		<link>http://inventwithpython.com/blog/2011/05/09/moosegesture-python-mouse-gestures-module/</link>
		<comments>http://inventwithpython.com/blog/2011/05/09/moosegesture-python-mouse-gestures-module/#comments</comments>
		<pubDate>Mon, 09 May 2011 22:13:35 +0000</pubDate>
		<dc:creator>Al Sweigart</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://inventwithpython.com/blog/?p=272</guid>
		<description><![CDATA[&#8220;MooseGesture&#8221; is a Python module that implements a basic mouse gesture recognition system. It can identify gestures made up of strokes in the eight cardinal and diagonal directions. A mouse gesture is holding down the mouse button and moving the mouse cursor in a specific pattern to issue a command. Mouse gestures are a way [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;MooseGesture&#8221; is a Python module that implements a basic mouse gesture recognition system. It can identify gestures made up of strokes in the eight cardinal and diagonal directions.</p>
<p>A mouse gesture is holding down the mouse button and moving the mouse cursor in a specific pattern to issue a command.<br />
Mouse gestures are a way of dragging with the mouse in order to draw out a certain pattern. The most mainstream uses of mouse gestures in computer software are for web browsers. (<a href="http://www.chromeplugins.org/extensions/chrome-gestures-google-chrome-mouse-gestures-extension/">Chrome</a>, <a href="https://addons.mozilla.org/en-us/firefox/addon/mouse-gestures-redox/">Firefox</a>, <a href="http://www.opera.com/">Opera</a>, <a href="http://www.codeproject.com/KB/shell/MouseGestures.aspx">Internet Explorer</a>)</p>
<p>Mouse gestures can provide an interesting game mechanic that you can add to your own programs (similar to what the Wiimote does in a few games).</p>
<p>You can download the module (and a simple Pygame test script that uses it) here:</p>
<p><strong><a href="http://coffeeghost.net/src/moosegesture.zip">MooseGestures &#038; Test App (zipped)</a></strong></p>
<p><a href="http://coffeeghost.net/src/moosegesture.py">moosegesture.py</a></p>
<p><a href="http://coffeeghost.net/src/moosegesturetest.py">moosegesturetest.py</a></p>
<p><a href="http://inventwithpython.com/simongesture.zip">Simon Gesture</a> &#8211; A game that uses the MooseGesture module.</p>
<p><img src="http://coffeeghost.net/images/moosegesturescreenshot.png" alt="" /></p>
<p>(The screenshot above shows the test app after entering a mouse gesture. It correctly identifies the gesture as Down Right Up.)</p>
<p><img src="http://coffeeghost.net/images/moosegesturescreenshot2.png" alt="" /></p>
<p>(The above screenshot shows a more complicated gesture: Down, Up, Down, Right, Left, Right.)<br />
<span id="more-272"></span><br />
Description of the Algorithm</p>
<p>First, some nomenclature (at least how I use it):</p>
<ul>
<li>A &#8220;point&#8221; is a 2D tuple of x, y values. These values can be ints or floats, MooseGesture supports both.</li>
<li>A &#8220;point pair&#8221; is a point and its immediately subsequent point, i.e. two points that are next to each other.</li>
<li>A &#8220;segment&#8221; is two or more ordered points forming a series of lines.</li>
<li>A &#8220;stroke&#8221; is a segment with all its point pairs going in a single direction (one of the 8 cardinal or diagonal directions: up, upright, left, etc.)</li>
<li>A &#8220;gesture&#8221; is one or more strokes in a specific pattern, e.g. up then right then down then left.</li>
</ul>
<p>The identification of strokes is based on a simple slope calculation between two points. MooseGesture can identify several strokes in a row in the eight cardinal and diagonal directions (up, down, left, right, and the four diagonals in between). MooseGesture does not recognize two strokes in the same direction performed in succession, but sees it as just one stroke in that direction. So up, up, down, down, left, right, left right would be identified as just up, down, left, right.</p>
<p>A slope is calculated between two XY coordinates with the basic &#8220;rise over run&#8221; calculation: (y2 &#8211; y1) / (x2 &#8211; x1)</p>
<p>The slope is then categorized into one of the eight directions by checking which &#8220;zone&#8221; it falls into. Each of the eight zones spans 45 degrees. To make it easier to remember, I&#8217;ve numbered them according to the same directions the numbers on your keyboard&#8217;s number pads align to:</p>
<p><img src="http://coffeeghost.net/images/moosegesture_zones.png" alt="" /></p>
<p>The key is to know when one stroke ends and another begins, and to allow for some inaccuracy and imperfection from the user. MooseGesture does this by breaking up the user&#8217;s gesture into overlapping &#8220;segments&#8221; and testing for a consistent direction on all point pairs in that segment.</p>
<p>Here&#8217;s what I mean. Say the user&#8217;s gesture (which is just an ordered list of XY points) looks like this:</p>
<p><img src="http://coffeeghost.net/images/moosegesture_segments.png" alt="" /></p>
<p>The user intends to just have a simple to-the-right gesture, but because of some natural shaky mouse movement there is a little deviation in it. We want this deviation to be ignored, and not identified as an additional upright stroke. The segment consistency checks in our algorithm will ignore these little bumps.</p>
<p>A &#8220;segment&#8221; has a starting point, and then continues to include subsequent points until it meets a minimum segment length (and no longer). (The minimum segment length is adjustable. A smaller minimum segment length lets strokes be shorter but increases the odds of misidentified strokes.) So say the gesture has 10 points (which we&#8217;ll call 0 to 9) altogether. The first segment starts at point 0 and goes on for some number of points until it is at least the minimum segment length. The second segment starts at point 1. This means that the second segment overlaps the first for a bit. (This depends on the lengths of the segments, which depends on how close together/far apart the points are.)</p>
<p>The last segment will start at the latest point that we can get a segment that meets the minimum segment length. So if the distance between points 7 to 8 to 9 is less than the minimum segment length, there won&#8217;t be a segment that starts at point 7 (or, logically, at point 8).</p>
<p>Note that the length of a segment is the sum of lengths of its point pairs, not the distance between the first and last points in the segment. For example, the distance between points 0 and 1, 1 and 2, and 2 and 3. It would not be the distance between points 0 and 3.</p>
<p>Here&#8217;s an animated gif that shows a gesture with 8 points (0 to 7), with the segments highlighted in turn:</p>
<p><img src="http://coffeeghost.net/images/moosegesture_segments_anim.gif" alt="" /></p>
<p>The Algorithm:</p>
<ol>
<li>Split up the gesture&#8217;s points into segments that meet the minimum segment length.</li>
<li>For each segment: Calculate the slope of each point pair and categorize them into one of the eight directions based which &#8220;zone&#8221; the slope falls in.</li>
<li>If all of the point pairs in the segment agree on the direction, then this segment is considered consistent and the direction is added to the list of identified strokes. See the animated gif below for an example of consistent/inconsistent segments, the R stands for &#8220;right direction point pair&#8221; and the UR for &#8220;upright direction point pair&#8221;.</li>
<li>The list of identified strokes is returned as the identified gesture.</li>
</ol>
<p><img src="http://coffeeghost.net/images/moosegesture_segments_anim2.gif" alt="" /></p>
<p>(There is one exception to adding a consistent segment: if the previously identified stroke is in the same direction as this one, then we don&#8217;t add the direction. This prevents multiple sequential strokes in the same direction, i.e. up-up-up-left-left is just considering up-left.)</p>
<p>This algorithm lets us ignore tiny deviations because they will create an inconsistent segment (i.e. a segment wit pair points going in different directions. So we drop that segment from being considered an identified stroke. But there is bound to be some segments before and after it that are consistent.</p>
<p>One limitation is that MooseGesture can only identify direction. It can&#8217;t identify lengths or specific shapes. So these two paths are both interpreted as the same gesture by MooseGesture (upright, downright, left):</p>
<p><img src="http://coffeeghost.net/images/moosegesture_samegesture.png" alt="" /></p>
<p>This is just an algorithm that I came up with literally over a weekend. Even for gestures with an absurd number of points in them, it seems to run in a couple milliseconds. It can probably be improved, but will work just fine for most Python games. I&#8217;ll be converting the module to JavaScript in the future. Email me any questions you might have. Enjoy!</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Finventwithpython.com%2Fblog%2F2011%2F05%2F09%2Fmoosegesture-python-mouse-gestures-module%2F&amp;title=%E2%80%9CMooseGesture%E2%80%9D%20%E2%80%93%20Python%20Mouse%20Gestures%20Module" id="wpa2a_10"><img src="http://inventwithpython.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://inventwithpython.com/blog/2011/05/09/moosegesture-python-mouse-gestures-module/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Free Cipher Disk Cutout</title>
		<link>http://inventwithpython.com/blog/2011/02/09/free-cipherdisk-cutout/</link>
		<comments>http://inventwithpython.com/blog/2011/02/09/free-cipherdisk-cutout/#comments</comments>
		<pubDate>Wed, 09 Feb 2011 20:26:14 +0000</pubDate>
		<dc:creator>Al Sweigart</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://inventwithpython.com/blog/?p=242</guid>
		<description><![CDATA[Here&#8217;s a cipher disk that you can print and cutout to help you manually implement the Caesar Cipher. A program to implement this cipher (and break the cipher) is available in Chapter 14 of the free programming book &#8220;Invent Your Own Computer Games with Python&#8221; at http://inventwithpython.com/chapter14.html Simply download and printout the PDF and cut [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://coffeeghost.net/images/cipherdisk_thumb.png" style="border: 1px solid black;" /></p>
<p>Here&#8217;s a cipher disk that you can print and cutout to help you manually implement the Caesar Cipher. A program to implement this cipher (and break the cipher) is available in Chapter 14 of the free programming book &#8220;Invent Your Own Computer Games with Python&#8221; at <a href="http://inventwithpython.com/chapter14.html">http://inventwithpython.com/chapter14.html</a></p>
<p>Simply download and printout the PDF and cut out the two circles and place them on top of each other. The key number is whichever one is opposite the outer &#8220;A&#8221; letter.</p>
<p><a href="http://coffeeghost.net/files/cipherdisk.pdf"><strong>Download the PDF</strong></a></p>
<p>If you would like to change around the font or the logo, you can also <a href="http://coffeeghost.net/files/cipherdisk_orig.psd">download the original Photoshop file</a>.</p>
<p>High resolution PNG files of the <a href="http://coffeeghost.net/files/cipherdisk_inner.png">inner</a> and <a href="http://coffeeghost.net/files/cipherdisk_outer.png">outer</a> circles are also available for download.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Finventwithpython.com%2Fblog%2F2011%2F02%2F09%2Ffree-cipherdisk-cutout%2F&amp;title=Free%20Cipher%20Disk%20Cutout" id="wpa2a_12"><img src="http://inventwithpython.com/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://inventwithpython.com/blog/2011/02/09/free-cipherdisk-cutout/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

