<?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>A Little Off &#187; Code</title>
	<atom:link href="http://www.bemasher.net/archives/category/technology/code/feed" rel="self" type="application/rss+xml" />
	<link>http://www.bemasher.net</link>
	<description>Code, Computers, Photography and Guns</description>
	<lastBuildDate>Mon, 30 Aug 2010 16:42:17 +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>Choosing an SSD</title>
		<link>http://www.bemasher.net/archives/836</link>
		<comments>http://www.bemasher.net/archives/836#comments</comments>
		<pubDate>Thu, 12 Aug 2010 06:02:27 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Computers]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[A-Data]]></category>
		<category><![CDATA[G.SKILL]]></category>
		<category><![CDATA[matplotlib]]></category>
		<category><![CDATA[Newegg]]></category>
		<category><![CDATA[Patriot]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Read]]></category>
		<category><![CDATA[Sequential]]></category>
		<category><![CDATA[SSD]]></category>
		<category><![CDATA[Western Digital]]></category>
		<category><![CDATA[Write]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=836</guid>
		<description><![CDATA[Before I started my new job I had an inordinate amount of free time and for a majority of that time, nothing to spend it doing[1]. I was still thinking about my desktop wishlist[2] and about choosing a better SSD than the one I had previously selected[3]. A long time ago when I was following [...]]]></description>
			<content:encoded><![CDATA[<p>Before I started my new job I had an inordinate amount of free time and for a majority of that time, nothing to spend it doing<sup>[<a href="http://www.bemasher.net/archives/836#footnote_0_836" id="identifier_0_836" class="footnote-link footnote-identifier-link" title="Nothing worth-while anyway">1</a>]</sup>. I was still thinking about my desktop wishlist<sup>[<a href="http://www.bemasher.net/archives/836#footnote_1_836" id="identifier_1_836" class="footnote-link footnote-identifier-link" title="See previous post: Wishlist.">2</a>]</sup> and about choosing a better SSD than the one I had previously selected<sup>[<a href="http://www.bemasher.net/archives/836#footnote_2_836" id="identifier_2_836" class="footnote-link footnote-identifier-link" title="Western Digital SiliconEdge 128GB SSD">3</a>]</sup>.</p>
<p>A long time ago when I was following the HDD market since I was looking to buy some bulk storage I wrote a php script which loaded newegg's product list based on some search parameters you provided newegg's productlist.xml<sup>[<a href="http://www.bemasher.net/archives/836#footnote_3_836" id="identifier_3_836" class="footnote-link footnote-identifier-link" title="Which no longer exists in it&#039;s original form.">4</a>]</sup>. The script would then parse the list and produce a list sorted based on price per gigabyte. Which is useful when you're in the market for capacity<sup>[<a href="http://www.bemasher.net/archives/836#footnote_4_836" id="identifier_4_836" class="footnote-link footnote-identifier-link" title="Which I was.">5</a>]</sup>.</p>
<p>I decided to do more or less the same thing with SSD's except this time I did it in python since I'm rusty on PHP and I didn't want to mess with setting up a web server to test on. So I got started by doing a power search on newegg for the specific flavor of SSD I was looking for.</p>
<p>The search parameters are as follows:</p>
<ul>
<li>2.5" Form Factor</li>
<li>SATA II/III</li>
<li>120GB or Greater</li>
<li>Less than $300</li>
<li>Retail or OEM</li>
<li>Support TRIM Command</li>
</ul>
<p>As of this writing those particular search parameters narrows the result to 17 SSD's. Now comes the code. Before I started coding I needed some way to sort them according to what I thought was important. The metric is as follows:</p>
<p><center><img src="http://l.wordpress.com/latex.php?latex=%5Cfrac%7B%5Ctext%7BRead%7D%20%5Ctimes%20%5Ctext%7BWrite%7D%20%5Ctimes%20%5Ctext%7BCapacity%7D%7D%7B%7C%5Ctext%7BRead%7D%20-%20%5Ctext%7BWrite%7D%7C%20%5Ctimes%20%5Ctext%7BPrice%7D%7D&#038;bg=FFFFFF&#038;fg=2C2C29&#038;s=2" title="\frac{\text{Read} \times \text{Write} \times \text{Capacity}}{|\text{Read} - \text{Write}| \times \text{Price}}" style="vertical-align:-20%;" class="tex" alt="\frac{\text{Read} \times \text{Write} \times \text{Capacity}}{|\text{Read} - \text{Write}| \times \text{Price}}" /></center></p>
<p>After looking closer at the scores this produces I noticed that it <em>heavily</em> penalizes drives with huge differences between read and write speeds which effectively weeds out drives that still have acceptable read//write speeds. So I removed that section of the metric producing:</p>
<p><center><img src="http://l.wordpress.com/latex.php?latex=%5Cfrac%7B%5Ctext%7BRead%7D%20%5Ctimes%20%5Ctext%7BWrite%7D%20%5Ctimes%20%5Ctext%7BCapacity%7D%7D%7B%5Ctext%7BPrice%7D%7D&#038;bg=FFFFFF&#038;fg=2C2C29&#038;s=2" title="\frac{\text{Read} \times \text{Write} \times \text{Capacity}}{\text{Price}}" style="vertical-align:-20%;" class="tex" alt="\frac{\text{Read} \times \text{Write} \times \text{Capacity}}{\text{Price}}" /></center></p>
<p>The basic idea behind this scoring measure is that sequential read and write speeds are important, as well as capacity. Price and difference between sequential read//write are considered bad<sup>[<a href="http://www.bemasher.net/archives/836#footnote_5_836" id="identifier_5_836" class="footnote-link footnote-identifier-link" title="Although we&#039;re excluding read//write speed difference.">6</a>]</sup>. In the equation read and write refer to sequential read and write speeds. The ratio of these will produce a score of the SSD's overall performance for capacity, read//write speeds and price.</p>
<p>The code is relatively simple in purpose. Load the data and parse it into a dictionary then sort based on the metric above.</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib2</span>, <span style="color: #dc143c;">re</span><br />
<br />
<span style="color: #808080; font-style: italic;"># url = &quot;</span><br />
<span style="color: #808080; font-style: italic;"># http://www.newegg.com/Product/ProductList.aspx?Submit=Property&amp;Subcatego </span><br />
<span style="color: #808080; font-style: italic;"># ry=636&amp;Description=&amp;Type=&amp;N=100008120&amp;IsNodeId=1&amp;srchInDesc=&amp;MinPrice=&amp;M </span><br />
<span style="color: #808080; font-style: italic;"># axPrice=&amp;OEMMark=1&amp;OEMMark=0&amp;PropertyCodeValue=4213:30854&amp;PropertyCodeVa </span><br />
<span style="color: #808080; font-style: italic;"># lue=4214:30848&amp;PropertyCodeValue=4214:39416&amp;PropertyCodeValue=4214:30849 </span><br />
<span style="color: #808080; font-style: italic;"># &amp;PropertyCodeValue=4214:39415&amp;PropertyCodeValue=4215:55552&amp;PropertyCodeV </span><br />
<span style="color: #808080; font-style: italic;"># alue=4215:41071&amp;PropertyCodeValue=4215:46319&quot;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># data = open(&quot;temp.html&quot;, &quot;w&quot;)</span><br />
<span style="color: #808080; font-style: italic;"># data.write(urllib2.urlopen(url).read())</span><br />
<span style="color: #808080; font-style: italic;"># data.close()</span><br />
raw = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;temp.html&quot;</span><span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
item_re = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'&lt;div class=&quot;itemCell&quot;.*?&gt;(.*?)&lt;br class=&quot;clear&quot;.*?&lt;/div&gt;'</span><span style="color: black;">&#41;</span><br />
feature_re = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;&lt;li&gt;&amp;nbsp;(.*?)&lt;/li&gt;&quot;</span><span style="color: black;">&#41;</span><br />
feature_list_re = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'&lt;b&gt;(.*?)<span style="color: #000099; font-weight: bold;">\s</span>?<span style="color: #000099; font-weight: bold;">\#</span>?<span style="color: #000099; font-weight: bold;">\s</span>?:<span style="color: #000099; font-weight: bold;">\s</span>?&lt;/b&gt;<span style="color: #000099; font-weight: bold;">\s</span>?(.*?)&lt;/li&gt;'</span><span style="color: black;">&#41;</span><br />
speed_re = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;(up to )?(<span style="color: #000099; font-weight: bold;">\d</span>+).*?MB/s&quot;</span><span style="color: black;">&#41;</span><br />
capacity_re = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;(<span style="color: #000099; font-weight: bold;">\d</span>+)GB&quot;</span><span style="color: black;">&#41;</span><br />
price_re = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">&quot;&lt;/span&gt;<span style="color: #000099; font-weight: bold;">\$</span>&lt;strong&gt;(<span style="color: #000099; font-weight: bold;">\d</span>+)&lt;/strong&gt;&lt;sup&gt;.(<span style="color: #000099; font-weight: bold;">\d</span>+)&lt;/sup&gt;&quot;</span><span style="color: black;">&#41;</span><br />
<br />
item_list = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
valid = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'Read'</span>, <span style="color: #483d8b;">'Item'</span>, <span style="color: #483d8b;">'Interface'</span>, <span style="color: #483d8b;">'Capacity'</span>, <span style="color: #483d8b;">'Model'</span>, <span style="color: #483d8b;">'Write'</span>, <span style="color: #483d8b;">'Size'</span><span style="color: black;">&#93;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">for</span> item <span style="color: #ff7700;font-weight:bold;">in</span> item_re.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>raw<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; current = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><br />
&nbsp; &nbsp; no_label = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; features = feature_re.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>item<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Size&quot;</span><span style="color: black;">&#93;</span> = features<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Capacity&quot;</span><span style="color: black;">&#93;</span> = features<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Interface&quot;</span><span style="color: black;">&#93;</span> = features<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> feature <span style="color: #ff7700;font-weight:bold;">in</span> feature_list_re.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>item<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> feature<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\r</span>&quot;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= -<span style="color: #ff4500;">1</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current<span style="color: black;">&#91;</span>feature<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span> = feature<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\r</span>&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current<span style="color: black;">&#91;</span>feature<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span> = feature<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Read&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>speed_re.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sequential Access - Read&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Write&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>speed_re.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Sequential Access - Write&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Capacity&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>capacity_re.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Capacity&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> feature <span style="color: #ff7700;font-weight:bold;">in</span> current.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> feature <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #ff7700;font-weight:bold;">in</span> valid:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">del</span> current<span style="color: black;">&#91;</span>feature<span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Price&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">float</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'.'</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>price_re.<span style="color: black;">findall</span><span style="color: black;">&#40;</span>item<span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Item&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;http://www.newegg.com/Product/Product.aspx?Item=%s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>current<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Item&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; item_list.<span style="color: black;">append</span><span style="color: black;">&#40;</span>current<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
<span style="color: #008000;">sorted</span> = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> item <span style="color: #ff7700;font-weight:bold;">in</span> item_list:<br />
&nbsp; &nbsp; ratio = <span style="color: black;">&#40;</span>item<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Read&quot;</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">*</span> item<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Write&quot;</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">*</span> item<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Capacity&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> / <span style="color: black;">&#40;</span>item<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Price&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">sorted</span><span style="color: black;">&#91;</span>ratio<span style="color: black;">&#93;</span> = item<br />
&nbsp; &nbsp; <br />
sort_order = <span style="color: #008000;">sorted</span>.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
sort_order.<span style="color: black;">sort</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
sort_order.<span style="color: black;">reverse</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> key <span style="color: #ff7700;font-weight:bold;">in</span> sort_order:<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#print '\t'.join(map(lambda x: str(x), sorted[key].keys()))</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\t</span>'</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #008000;">map</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x: <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>, <span style="color: #008000;">sorted</span><span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span>.<span style="color: black;">values</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Now given that there is quite a lot of data to present and analyze all at once I've decided it would be easiest to just provide you with a pretty graph<sup>[<a href="http://www.bemasher.net/archives/836#footnote_6_836" id="identifier_6_836" class="footnote-link footnote-identifier-link" title="Scores have been normalized to 100%.">7</a>]</sup>:<br />
<center><img src="http://lh5.ggpht.com/_67X_BsG0Kiw/TGOKY0sqJKI/AAAAAAAAHyQ/nAVB8GIDJXQ/s800/Output.png"></img></center><br />
If you look closely at the scores of all the disks in the query, you'll notice that this is a noticeable gap between the top 3 and the rest. They are as follows:<br />
<center><br />
<table>
<tr>
<td>Manufacturer:</td>
<td>A-DATA</td>
<td>Patriot</td>
<td>G.Skill</td>
</tr>
<tr>
<td>Series:</td>
<td>S599</td>
<td>Inferno</td>
<td>Phoenix Series</td>
</tr>
<tr>
<td>Capacity:</td>
<td>128GB</td>
<td>120GB</td>
<td>120GB</td>
</tr>
<tr>
<td>Read:</td>
<td>280MB/s</td>
<td>285MB/s</td>
<td>285MB/s</td>
</tr>
<tr>
<td>Write:</td>
<td>270MB/s</td>
<td>275MB/s</td>
<td>275MB/s</td>
</tr>
<tr>
<td>Item:</td>
<td>N82E16820211471<sup>[<a href="http://www.bemasher.net/archives/836#footnote_7_836" id="identifier_7_836" class="footnote-link footnote-identifier-link" title="A-Data S599">8</a>]</sup></td>
<td>N82E16820220510<sup>[<a href="http://www.bemasher.net/archives/836#footnote_8_836" id="identifier_8_836" class="footnote-link footnote-identifier-link" title="Patriot Inferno">9</a>]</sup></td>
<td>N82E16820231372<sup>[<a href="http://www.bemasher.net/archives/836#footnote_9_836" id="identifier_9_836" class="footnote-link footnote-identifier-link" title="G.Skill Phoenix Series">10</a>]</sup></td>
</tr>
<tr>
<td>Price:</td>
<td>$295.99</td>
<td>$289.99</td>
<td>$299.00</td>
</tr>
</table>
<p></center><br />
I noticed that if you ignore capacity in the metric then the Patriot Inferno is the clear winner here. So as it turns out the Western Digital SiliconEdge I had selected when I first wrote the wishlist wasn't the best drive for my needs. But then I've always had a soft-spot for Western Digital. But now I'm convinced that the Patriot Inferno is the SSD I'll be getting unless by the time I get around to buying one there are better options<sup>[<a href="http://www.bemasher.net/archives/836#footnote_10_836" id="identifier_10_836" class="footnote-link footnote-identifier-link" title="Which there probably will be.">11</a>]</sup>.</p>
<ol class="footnotes"><li id="footnote_0_836" class="footnote">Nothing worth-while anyway</li><li id="footnote_1_836" class="footnote">See previous post: <a href="http://www.bemasher.net/archives/804">Wishlist</a>.</li><li id="footnote_2_836" class="footnote"><a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820250002&#038;cm_re=Western_Digital_Silicon_Edge-_-20-250-002-_-Product">Western Digital SiliconEdge 128GB SSD</a></li><li id="footnote_3_836" class="footnote">Which no longer exists in it's original form.</li><li id="footnote_4_836" class="footnote">Which I was.</li><li id="footnote_5_836" class="footnote">Although we're excluding read//write speed difference.</li><li id="footnote_6_836" class="footnote">Scores have been normalized to 100%.</li><li id="footnote_7_836" class="footnote"><a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820211471">A-Data S599</a></li><li id="footnote_8_836" class="footnote"><a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820220510">Patriot Inferno</a></li><li id="footnote_9_836" class="footnote"><a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820231372">G.Skill Phoenix Series</a></li><li id="footnote_10_836" class="footnote">Which there probably will be.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/836/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Matplotlib and Live Data: A Tale of Two Technologies</title>
		<link>http://www.bemasher.net/archives/813</link>
		<comments>http://www.bemasher.net/archives/813#comments</comments>
		<pubDate>Thu, 29 Jul 2010 04:46:53 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[DS18B20]]></category>
		<category><![CDATA[DS18S20]]></category>
		<category><![CDATA[DS18X20]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[Live]]></category>
		<category><![CDATA[matplotlib]]></category>
		<category><![CDATA[OneWire]]></category>
		<category><![CDATA[pySerial]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[temperature]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=813</guid>
		<description><![CDATA[Being unemployed over the summer is never usually a good thing for me. I get bored very easily if I don't have something to occupy myself with. This last bout of boredom led me to unpack some of my electronics. Dusted off my multimeter, Arduino and a digital thermometer I bought a little while ago. [...]]]></description>
			<content:encoded><![CDATA[<p>Being unemployed over the summer is never usually a good thing for me. I get bored very easily if I don't have something to occupy myself with. This last bout of boredom led me to unpack some of my electronics. Dusted off my multimeter, Arduino and a digital thermometer I bought a little while ago. Figured I could use these to solve one of my current problems.</p>
<p>Living in Laramie usually subjects people to harsh winters which leaves most housing developments without central air conditioning installed since, well it's never really needed except maybe one or two days over the summer where it gets above 85 <sup>o</sup>F. This summer has apparently been hotter than previous summers and It's left my condo in an "uncomfortable state". Mind you I'm used to living in hot weather so this isn't such a terrible thing to me, I'm used to it. </p>
<p>What I'm not used to is not having AC and it cooling off enough at night that it's worthwhile to open a few windows and stick a fan in one of them. Which leaves me with this problem: When is the optimal time to open the windows and turn on the fan to get my condo cooled off earliest//fastest?</p>
<p>In comes my Arduino + digital thermometer<sup>[<a href="http://www.bemasher.net/archives/813#footnote_0_813" id="identifier_0_813" class="footnote-link footnote-identifier-link" title="DS18S20 Digital Thermometer Datasheet">1</a>]</sup>. Once I rigged up the proper power//data connections on a breadboard for my Arduino I set out to find code for the thermometer. I've setup the thermometer with a sketch on my Arduino before I just didn't feel like wasting a few hours trying to do it from scratch again. Soon enough I found some code<sup>[<a href="http://www.bemasher.net/archives/813#footnote_1_813" id="identifier_1_813" class="footnote-link footnote-identifier-link" title="Temperature Measurement using the Dallas DS18B20 by Peter H. Anderson">2</a>]</sup> that worked perfectly. So I trimmed out some code I didn't need for the project and set it up to just write the temperature as fast as possible<sup>[<a href="http://www.bemasher.net/archives/813#footnote_2_813" id="identifier_2_813" class="footnote-link footnote-identifier-link" title="Somewhere in the range of 750ms between readings since it is in parasite mode, may change this later to run in non-parasite mode.">3</a>]</sup> to the serial port it's connected to.</p>
<p>After that I wrote a logging program on my desktop in Python to record temperatures sent via serial to my desktop. The program is incredibly simple and uses the pySerial library<sup>[<a href="http://www.bemasher.net/archives/813#footnote_3_813" id="identifier_3_813" class="footnote-link footnote-identifier-link" title="pySerial Python Library">4</a>]</sup> to read temperatures from the serial port of my desktop and append them to a temperature log. I used a simple windows command to do this since it wouldn't lock the file so I could read data from it simultaneously. There are still occasionally collisions with the processing program locking the file and the logger not being able to write the data to the file but these are rare enough that it's negligible in my situation.</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> serial, <span style="color: #dc143c;">os</span><br />
<br />
ser = serial.<span style="color: black;">Serial</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:<br />
&nbsp; &nbsp; <span style="color: #dc143c;">os</span>.<span style="color: black;">system</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;echo %s&gt;&gt;out.txt&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>ser.<span style="color: #dc143c;">readline</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">strip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>The next step in this project was visualizing the data. I've used matplotlib<sup>[<a href="http://www.bemasher.net/archives/813#footnote_4_813" id="identifier_4_813" class="footnote-link footnote-identifier-link" title="matplotlib Python Library">5</a>]</sup> before and I was thinking this time I would like to see if I could write the program to update data live as it recieves it. My first foray into this goal was a miserable disaster. Most of the solutions I could find involved just setting up an infinite loop with a short time delay in it. Which works great except that it sleeps the thread running the plot which makes it impossible to resize the plot or do anything at all with the GUI for that matter. So obviosly this wouldn't work at all.</p>
<p>After poking around for different solutions to this and crashing my computer once from spawning an infinite number of instances of the plot I gave up for a bit, only to discover that there was an example in the documentation which wasn't obviously named. I quickly discovered the best way to do this. I even added some pretty annotations and such.</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> gobject<br />
<span style="color: #ff7700;font-weight:bold;">import</span> matplotlib<br />
matplotlib.<span style="color: black;">use</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'GTKAgg'</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">import</span> matplotlib.<span style="color: black;">pyplot</span> <span style="color: #ff7700;font-weight:bold;">as</span> plt<br />
<br />
current_pos = <span style="color: #ff4500;">0</span><br />
temps = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
pad = <span style="color: #ff4500;">5.0</span><br />
<br />
f = plt.<span style="color: black;">figure</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> update<span style="color: black;">&#40;</span><span style="color: #008000;">vars</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Unpack variables that need to be persistent between</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># executions of this method.</span><br />
&nbsp; &nbsp; temps = <span style="color: #008000;">vars</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; current_pos = <span style="color: #008000;">vars</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; pad = <span style="color: #008000;">vars</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Open the data file and get any new data points since</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># the last time we read from this file</span><br />
&nbsp; &nbsp; data = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;out.txt&quot;</span>, <span style="color: #483d8b;">&quot;r&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; data.<span style="color: black;">seek</span><span style="color: black;">&#40;</span>current_pos<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; new_temps = <span style="color: #008000;">map</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span> + <span style="color: #ff4500;">4.0</span>/<span style="color: #ff4500;">5.0</span><span style="color: black;">&#41;</span> + <span style="color: #ff4500;">32.0</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; data.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>:-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; current_pos = data.<span style="color: black;">tell</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; data.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># If we got new data then append it to the list of</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># temperatures and trim to 750 points</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>new_temps<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">0</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; temps.<span style="color: black;">extend</span><span style="color: black;">&#40;</span>new_temps<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; temps = temps<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">750</span>:<span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; f.<span style="color: black;">clear</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; f.<span style="color: black;">suptitle</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Live Temperature&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; a = f.<span style="color: black;">add_subplot</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">111</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; a.<span style="color: black;">grid</span><span style="color: black;">&#40;</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; l, = a.<span style="color: black;">plot</span><span style="color: black;">&#40;</span>temps<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; plt.<span style="color: black;">xlabel</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Time (Seconds)&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; plt.<span style="color: black;">ylabel</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'Temperature $^{<span style="color: #000099; font-weight: bold;">\c</span>irc}$F'</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Get the minimum and maximum temperatures these are</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># used for annotations and scaling the plot of data</span><br />
&nbsp; &nbsp; min_t = <span style="color: #008000;">min</span><span style="color: black;">&#40;</span>temps<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; max_t = <span style="color: #008000;">max</span><span style="color: black;">&#40;</span>temps<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Add annotations for minimum and maximum temperatures</span><br />
&nbsp; &nbsp; a.<span style="color: black;">annotate</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'Min: %0.2f$^{<span style="color: #000099; font-weight: bold;">\c</span>irc}$F'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>min_t<span style="color: black;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; xy=<span style="color: black;">&#40;</span>temps.<span style="color: black;">index</span><span style="color: black;">&#40;</span>min_t<span style="color: black;">&#41;</span>, min_t<span style="color: black;">&#41;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; xycoords=<span style="color: #483d8b;">'data'</span>, xytext=<span style="color: black;">&#40;</span><span style="color: #ff4500;">20</span>, -<span style="color: #ff4500;">20</span><span style="color: black;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; textcoords=<span style="color: #483d8b;">'offset points'</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; bbox=<span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>boxstyle=<span style="color: #483d8b;">&quot;round&quot;</span>, fc=<span style="color: #483d8b;">&quot;0.8&quot;</span><span style="color: black;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; arrowprops=<span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>arrowstyle=<span style="color: #483d8b;">&quot;-&gt;&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; shrinkA=<span style="color: #ff4500;">0</span>, shrinkB=<span style="color: #ff4500;">1</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; connectionstyle=<span style="color: #483d8b;">&quot;angle,angleA=0,angleB=90,rad=10&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; a.<span style="color: black;">annotate</span><span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'Max: %0.2f$^{<span style="color: #000099; font-weight: bold;">\c</span>irc}$F'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>max_t<span style="color: black;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; xy=<span style="color: black;">&#40;</span>temps.<span style="color: black;">index</span><span style="color: black;">&#40;</span>max_t<span style="color: black;">&#41;</span>, max_t<span style="color: black;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; xycoords=<span style="color: #483d8b;">'data'</span>, xytext=<span style="color: black;">&#40;</span><span style="color: #ff4500;">20</span>, <span style="color: #ff4500;">20</span><span style="color: black;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; textcoords=<span style="color: #483d8b;">'offset points'</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; bbox=<span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>boxstyle=<span style="color: #483d8b;">&quot;round&quot;</span>, fc=<span style="color: #483d8b;">&quot;0.8&quot;</span><span style="color: black;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; arrowprops=<span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>arrowstyle=<span style="color: #483d8b;">&quot;-&gt;&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; shrinkA=<span style="color: #ff4500;">0</span>, shrinkB=<span style="color: #ff4500;">1</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; connectionstyle=<span style="color: #483d8b;">&quot;angle,angleA=0,angleB=90,rad=10&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Set the axis limits to make the data more readable</span><br />
&nbsp; &nbsp; a.<span style="color: black;">axis</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span>,<span style="color: #008000;">len</span><span style="color: black;">&#40;</span>temps<span style="color: black;">&#41;</span>, min_t - pad,max_t + pad<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; f.<span style="color: black;">canvas</span>.<span style="color: black;">draw_idle</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Repack variables that need to be persistent between</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># executions of this method</span><br />
&nbsp; &nbsp; <span style="color: #008000;">vars</span> = <span style="color: black;">&#123;</span><span style="color: #ff4500;">0</span>: temps, <span style="color: #ff4500;">1</span>: current_pos, <span style="color: #ff4500;">2</span>: pad<span style="color: black;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">True</span><br />
<br />
<span style="color: #008000;">vars</span> = <span style="color: black;">&#123;</span><span style="color: #ff4500;">0</span>: temps, <span style="color: #ff4500;">1</span>: current_pos, <span style="color: #ff4500;">2</span>: pad<span style="color: black;">&#125;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Execute update method every 500ms</span><br />
gobject.<span style="color: black;">timeout_add</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">500</span>, update, <span style="color: #008000;">vars</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Display the plot</span><br />
plt.<span style="color: black;">show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>This code generates a plot which updates every 500ms. This is based on an example in the matplotlib examples<sup>[<a href="http://www.bemasher.net/archives/813#footnote_5_813" id="identifier_5_813" class="footnote-link footnote-identifier-link" title="Animation example code: simple_anim_gtk.py">6</a>]</sup>. An example of the program's output can be seen below.</p>
<p><center><img src="http://lh4.ggpht.com/_67X_BsG0Kiw/TFEFttg0AlI/AAAAAAAAHxk/mwXxOtaC_tQ/s800/Output.png" /></center></p>
<p>I imagine that I could have made this simpler by not using the GTK libraries which are a pain to install since there are 3 or 4 modules you have to install in order to make all this work including the GTK+ runtime. I may come back later and post a version written using TK since it can be used without installing extra modules and stuff.</p>
<ol class="footnotes"><li id="footnote_0_813" class="footnote"><a href="http://datasheets.maxim-ic.com/en/ds/DS18S20.pdf">DS18S20 Digital Thermometer Datasheet</a></li><li id="footnote_1_813" class="footnote"><a href="http://www.phanderson.com/arduino/ds18b20_1.html">Temperature Measurement using the Dallas DS18B20 by Peter H. Anderson</a></li><li id="footnote_2_813" class="footnote">Somewhere in the range of 750ms between readings since it is in parasite mode, may change this later to run in non-parasite mode.</li><li id="footnote_3_813" class="footnote"><a href="http://pyserial.sourceforge.net/">pySerial Python Library</a></li><li id="footnote_4_813" class="footnote"><a href="http://matplotlib.sourceforge.net/">matplotlib Python Library</a></li><li id="footnote_5_813" class="footnote"><a href="http://matplotlib.sourceforge.net/examples/animation/simple_anim_gtk.html">Animation example code: simple_anim_gtk.py</a></li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/813/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WriteMonkey and Markdown</title>
		<link>http://www.bemasher.net/archives/781</link>
		<comments>http://www.bemasher.net/archives/781#comments</comments>
		<pubDate>Mon, 28 Jun 2010 03:14:01 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Download Squad]]></category>
		<category><![CDATA[Markdown]]></category>
		<category><![CDATA[WriteMonkey]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=781</guid>
		<description><![CDATA[Recently Download Squad had a post[1] about a practical way to get features and support for open-source programs, specifically through donations. The post was about a program called WriteMonkey which is a minimalistic writing program that the author had originally written about previously[2]. Think of the best code editing program you know of, mine is [...]]]></description>
			<content:encoded><![CDATA[<p>Recently Download Squad had a post<sup>[<a href="http://www.bemasher.net/archives/781#footnote_0_781" id="identifier_0_781" class="footnote-link footnote-identifier-link" title="Download Squad: Amazing software tip: Pay free software developers to get stuff fixed!">1</a>]</sup> about a practical way to get features and support for open-source programs, specifically through donations. The post was about a program called WriteMonkey which is a minimalistic writing program that the author had originally written about previously<sup>[<a href="http://www.bemasher.net/archives/781#footnote_1_781" id="identifier_1_781" class="footnote-link footnote-identifier-link" title="Download Squad: WriteMonkey is an unbelievable full-screen text editor">2</a>]</sup>. Think of the best code editing program you know of, mine is Notepad++<sup>[<a href="http://www.bemasher.net/archives/781#footnote_2_781" id="identifier_2_781" class="footnote-link footnote-identifier-link" title="Notepad++">3</a>]</sup>. Now take that program and refactor it specifically for writing articles or blog posts, you've just created WriteMonkey<sup>[<a href="http://www.bemasher.net/archives/781#footnote_3_781" id="identifier_3_781" class="footnote-link footnote-identifier-link" title="WriteMonkey">4</a>]</sup>.</p>
<p>Something that interested me about WriteMonkey was the Download Squad author's post specifically mentioned writing posts using Markdown<sup>[<a href="http://www.bemasher.net/archives/781#footnote_4_781" id="identifier_4_781" class="footnote-link footnote-identifier-link" title="Markdown">5</a>]</sup> syntax. Markdown is a simple plain-text syntax which is parsed into html removing the need to tediously enter html<sup>[<a href="http://www.bemasher.net/archives/781#footnote_5_781" id="identifier_5_781" class="footnote-link footnote-identifier-link" title="HTML: HyperText Markup Language, is the predominant markup language for web pages.">6</a>]</sup> as  you write. At first glance it didn't really seem like it would really help all that much when it came to writing blog posts. But I was completely wrong and am better off for it. Now the especially useful part is that WriteMonkey supports this completely as well as having a very useful shortcut for parsing and copying html straight from Markdown source. This is incredibly useful since I can then just go to my website and paste the resulting html into a blog post and hit save and be done with it.</p>
<p>As I looked through the program I realized, this is much much more than just a Markdown IDE. It includes all sorts of useful features like a "progress bar" which tells you how far along you are in a certain quota you specify in the preferences. This led me to write a little bit of SQL<sup>[<a href="http://www.bemasher.net/archives/781#footnote_6_781" id="identifier_6_781" class="footnote-link footnote-identifier-link" title="SQL: Structured Query Language">7</a>]</sup> to calculate the average word-count of posts in my blog. Excluding the outliers it came out to ~350 words per post. So I just set the quota to 350 words and it displays a bar at the top or bottom of the screen depending on what you choose showing your current progress on the quota.</p>
<p>It also does several other useful things like displaying current battery life as a percentage in the progress bar, showing the file you're writing in. There's also this feature called repository//main. This allows you to store text clippings in repository and then write the blog post in main. When exported as html the repository is ignored and only main is copied. Makes it useful to write notes and such in the middle of authoring a post to keep with everything you write and it's easy enough to switch between the two to make it useful. For this post I just made a list of points I wanted to cover.</p>
<p>After using WriteMonkey for an hour or so I think I've found the new environment I'll be writing all my posts in for the foreseeable future.</p>
<ol class="footnotes"><li id="footnote_0_781" class="footnote"><a href="http://www.downloadsquad.com/2010/06/25/amazing-software-tip-pay-free-software-developers-to-get-stuff/">Download Squad</a>: Amazing software tip: Pay free software developers to get stuff fixed!</li><li id="footnote_1_781" class="footnote"><a href="http://www.downloadsquad.com/2010/04/21/writemonkey-is-an-unbelievable-full-screen-text-editor/">Download Squad</a>: WriteMonkey is an unbelievable full-screen text editor</li><li id="footnote_2_781" class="footnote"><a href="http://notepad-plus-plus.org/">Notepad++</a></li><li id="footnote_3_781" class="footnote"><a href="http://writemonkey.com/">WriteMonkey</a></li><li id="footnote_4_781" class="footnote"><a href="http://daringfireball.net/projects/markdown/">Markdown</a></li><li id="footnote_5_781" class="footnote"><a href="http://en.wikipedia.org/wiki/Html">HTML</a>: HyperText Markup Language, is the predominant markup language for web pages.</li><li id="footnote_6_781" class="footnote"><a href="http://en.wikipedia.org/wiki/Sql">SQL</a>: Structured Query Language</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/781/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FreeNAS Users Rejoice!</title>
		<link>http://www.bemasher.net/archives/735</link>
		<comments>http://www.bemasher.net/archives/735#comments</comments>
		<pubDate>Tue, 04 May 2010 06:06:10 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[freenas]]></category>
		<category><![CDATA[install]]></category>
		<category><![CDATA[Live]]></category>
		<category><![CDATA[Stick]]></category>
		<category><![CDATA[syslinux]]></category>
		<category><![CDATA[Thumbdrive]]></category>
		<category><![CDATA[unetbootin]]></category>
		<category><![CDATA[USB]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=735</guid>
		<description><![CDATA[Unetbootin[1] now supports FreeNAS! Take a look at these awesome little snippets of code: 1234567891011121314//distrolst.cpp if &#40;nameDistro == &#34;FreeNAS&#34;&#41; &#123; &#160; &#160; if &#40;isarch64&#41; &#123; &#160; &#160; &#160; &#160; cpuarch = &#34;amd64&#34;; &#160; &#160; &#125; else &#123; &#160; &#160; &#160; &#160; cpuarch = &#34;i386&#34;; &#160; &#160; &#125; &#160; &#160; instIndvfl&#40;&#34;memdisk&#34;, QString&#40;&#34;%1ubnkern&#34;&#41;.arg&#40;targetPath&#41;&#41;; &#160; &#160; if &#40;islivecd&#41; [...]]]></description>
			<content:encoded><![CDATA[<p>Unetbootin<sup>[<a href="http://www.bemasher.net/archives/735#footnote_0_735" id="identifier_0_735" class="footnote-link footnote-identifier-link" title="http://unetbootin.sourceforge.net/">1</a>]</sup> now supports FreeNAS! Take a look at these awesome little snippets of code:</p>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">//distrolst.cpp</span><br />
<span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>nameDistro <span style="color: #000080;">==</span> <span style="color: #FF0000;">&quot;FreeNAS&quot;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>isarch64<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; cpuarch <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;amd64&quot;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; cpuarch <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;i386&quot;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; instIndvfl<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;memdisk&quot;</span>, QString<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%1ubnkern&quot;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">arg</span><span style="color: #008000;">&#40;</span>targetPath<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>islivecd<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; downloadfile<span style="color: #008000;">&#40;</span>QString<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;http://downloads.sourceforge.net/sourceforge/lubi/FreeNAS-%1-LiveCD-%2.img.gz&quot;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">arg</span><span style="color: #008000;">&#40;</span>cpuarch, relname<span style="color: #008000;">&#41;</span>, QString<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%1ubninit&quot;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">arg</span><span style="color: #008000;">&#40;</span>targetPath<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; downloadfile<span style="color: #008000;">&#40;</span>QString<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;http://sourceforge.net/projects/freenas/files/stable/0.7/FreeNAS-%1-embedded-%2.img/download&quot;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">arg</span><span style="color: #008000;">&#40;</span>cpuarch, relname<span style="color: #008000;">&#41;</span>, QString<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%1ubninit&quot;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">arg</span><span style="color: #008000;">&#40;</span>targetPath<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<div class="codecolorer-container cpp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">//distrover.cpp</span><br />
distroselect<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>addItem<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;FreeNAS&quot;</span>, <span style="color: #008000;">&#40;</span>QStringList<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;0.7.4919&quot;</span> <span style="color: #000080;">&lt;&lt;</span><br />
unetbootin<span style="color: #008080;">::</span><span style="color: #007788;">tr</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;&lt;b&gt;Homepage:&lt;/b&gt; &lt;a href=<span style="color: #000099; font-weight: bold;">\&quot;</span>http://freenas.org/<span style="color: #000099; font-weight: bold;">\&quot;</span>&gt;http://www.freenas.org&lt;/a&gt;&lt;br/&gt;&quot;</span><br />
&nbsp; &nbsp; <span style="color: #FF0000;">&quot;&lt;b&gt;Description:&lt;/b&gt; FreeNAS is an embedded open source NAS (Network-Attached Storage) distribution based on FreeBSD.&lt;br/&gt;&quot;</span><br />
&nbsp; &nbsp; <span style="color: #FF0000;">&quot;&lt;b&gt;Install Notes:&lt;/b&gt; The LiveCD version creates a RAM drive for FreeNAS, and uses a FAT formatted floppy disk or USB key for saving the configuration file. The embedded version allows installation to hard disk.&quot;</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;&lt;</span><br />
<span style="color: #FF0000;">&quot;0.7.4919&quot;</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;0.7.4919_x64&quot;</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;0.7.1.5024_Live&quot;</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;0.7.1.4997_Live_x64&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></td></tr></tbody></table></div>
<p>Segue:<br />
I'm actually considering forking the unetbootin project to add support for a master distro list which can be updated remotely eliminating the requirement for users to download a new copy of the program if they wish to get the latest version of the list of pre-configured distros.</p>
<p>This has a little bit to do with the fact that I'll be required to take a few C++ courses at the University of Wyoming since Java is the standard language taught at the University of Arizona while I was there and I've never used C++ before. Can't be that hard right?</p>
<ol class="footnotes"><li id="footnote_0_735" class="footnote"><a href="http://unetbootin.sourceforge.net/">http://unetbootin.sourceforge.net/</a></li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/735/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quote of the Day and Something Cool</title>
		<link>http://www.bemasher.net/archives/654</link>
		<comments>http://www.bemasher.net/archives/654#comments</comments>
		<pubDate>Fri, 11 Sep 2009 03:19:47 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[1911]]></category>
		<category><![CDATA[college]]></category>
		<category><![CDATA[discrete structures]]></category>
		<category><![CDATA[grey area]]></category>
		<category><![CDATA[gun]]></category>
		<category><![CDATA[pornography]]></category>
		<category><![CDATA[pro-gun]]></category>
		<category><![CDATA[professor]]></category>
		<category><![CDATA[pseudo-code]]></category>
		<category><![CDATA[student]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=654</guid>
		<description><![CDATA[So I was sitting in my discrete structures analysis class today when a student asked a question about the homework. It went a little like this: Student: How should we format pseudo-code in the homework? Professor: Ah see pseudo-code is in that grey area. It's somewhere in between code and english. Professor: You see me [...]]]></description>
			<content:encoded><![CDATA[<p>So I was sitting in my discrete structures analysis class today when a student asked a question about the homework. It went a little like this:</p>
<blockquote><p>
Student: How should we format pseudo-code in the homework?<br />
Professor: Ah see pseudo-code is in that grey area. It's somewhere in between code and english.<br />
Professor: You see me do it one way in class, the book does it another way and the homework assignment does it an even different way.<br />
Professor: Think of it this way, pseudo-code is a lot like pornography: you'll know it when you see it.<br />
Professor: So I'm not very worried about how you do your pseudo-code as long as I understand it.
</p></blockquote>
<p>The other cool thing that happened today was that I found out the owner of my favorite coffee shop is a pro-gun person. Apparently some of his relatives own a gun shop and he's done some shooting competitions. All very cool. It definitely explains why none of the employees ever freak out about me carrying my 1911 which looks giant on my hip compared to others. I'm a tall skinny guy if you didn't already know.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/654/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Computer Science Professor</title>
		<link>http://www.bemasher.net/archives/652</link>
		<comments>http://www.bemasher.net/archives/652#comments</comments>
		<pubDate>Tue, 01 Sep 2009 21:14:47 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Computers]]></category>
		<category><![CDATA[beer]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[college]]></category>
		<category><![CDATA[professor]]></category>
		<category><![CDATA[pub]]></category>
		<category><![CDATA[school]]></category>
		<category><![CDATA[university]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=652</guid>
		<description><![CDATA[I think I may have found my new favorite professor. After having 3 lectures total with him I've noticed that he rates cleverness of his proofs//examples in terms of how much beer you could win by betting others at a pub on the outcomes.]]></description>
			<content:encoded><![CDATA[<p>I think I may have found my new favorite professor. After having 3 lectures total with him I've noticed that he rates cleverness of his proofs//examples in terms of how much beer you could win by betting others at a pub on the outcomes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/652/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Second More Useless Plugin</title>
		<link>http://www.bemasher.net/archives/594</link>
		<comments>http://www.bemasher.net/archives/594#comments</comments>
		<pubDate>Wed, 08 Jul 2009 11:08:24 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[censor]]></category>
		<category><![CDATA[joke]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=594</guid>
		<description><![CDATA[Bored again which seems to be the usual for the summer I sat down with one purpose in mind: To write another plugin. Didn't really matter to me if it was useful or not I just wanted to write another one. I decided to ask my friend Pete who snarkily replied "Write one that randomly [...]]]></description>
			<content:encoded><![CDATA[<p>Bored again which seems to be the usual for the summer I sat down with one purpose in mind: To write another plugin. Didn't really matter to me if it was useful or not I just wanted to write another one. I decided to ask my friend Pete who snarkily replied "Write one that randomly inserts horse pr0n<sup>[<a href="http://www.bemasher.net/archives/594#footnote_0_594" id="identifier_0_594" class="footnote-link footnote-identifier-link" title="Mind you this is a joke, relating to the fact that horse pr0n happens to rank pretty high on the list of strange things on the internet.">1</a>]</sup> in your blog." to which I immediately replied "not horse pr0n, ASCII pr0n!" which probably made him choke on his drink and immediately remember rule 34. But this made me think to myself: Why not a random plugin?</p>
<p>So I did just that, I wrote a random plugin. One so useless that I don't think I'm even going to activate it on my blog save for days like April Fools Day. The plugin chooses at random a word from each post using the <em>the_content</em> hook and censors it out with <em>&lt;censored&gt;</em>. Funny huh? This will ignore html tags so it won't break links and things like that. The code is as follows:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">/*<br />
&nbsp; &nbsp; &nbsp; &nbsp; Plugin Name: Random Censor<br />
&nbsp; &nbsp; &nbsp; &nbsp; Plugin URI: http://www.bemasher.net/<br />
&nbsp; &nbsp; &nbsp; &nbsp; Description: Picks a common word at random from posts at display<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; and replaces with &amp;lt;censor&amp;gt;. Ignores urls and other<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; semi-important things.<br />
&nbsp; &nbsp; &nbsp; &nbsp; Version: 0.01<br />
&nbsp; &nbsp; &nbsp; &nbsp; Author: BeMasher<br />
&nbsp; &nbsp; &nbsp; &nbsp; Author URI: http://www.bemasher.net/<br />
&nbsp; &nbsp; */</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">function</span> random_censor<span style="color: #009900;">&#40;</span><span style="color: #000088;">$content</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$oldcontent</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$content</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$content</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/preg_replace"><span style="color: #990000;">preg_replace</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/&lt;[^&lt;]+?&gt;/&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$content</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/preg_match_all"><span style="color: #990000;">preg_match_all</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/\b\w+\b/&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$content</span><span style="color: #339933;">,</span> <span style="color: #000088;">$words</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$word</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$words</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><a href="http://www.php.net/rand"><span style="color: #990000;">rand</span></a><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <a href="http://www.php.net/sizeof"><span style="color: #990000;">sizeof</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$words</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000088;">$oldcontent</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/preg_replace"><span style="color: #990000;">preg_replace</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/\b<span style="color: #006699; font-weight: bold;">$word</span>\b/i&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot; &amp;lt;censored&amp;gt; &quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$oldcontent</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #000088;">$oldcontent</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; add_filter<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;the_content&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;random_censor&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></tbody></table></div>
<ol class="footnotes"><li id="footnote_0_594" class="footnote">Mind you this is a joke, relating to the fact that horse pr0n happens to rank pretty high on the list of strange things on the internet.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/594/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My First WordPress Plugin</title>
		<link>http://www.bemasher.net/archives/534</link>
		<comments>http://www.bemasher.net/archives/534#comments</comments>
		<pubDate>Tue, 07 Jul 2009 02:09:33 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[filters]]></category>
		<category><![CDATA[hooks]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[replace]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=534</guid>
		<description><![CDATA[I've been meaning to do this for a while, I'm writing a plugin for wordpress to automatically capitalize the right letter in the words I'm generally lazy about typing. Things like I, I'm, I've and the like[1]. Took me a little while but I did finally find some documentation on all the different hooks wordpress [...]]]></description>
			<content:encoded><![CDATA[<p>I've been meaning to do this for a while, I'm writing a plugin for wordpress to automatically capitalize the right letter in the words I'm generally lazy about typing. Things like I, I'm, I've and the like<sup>[<a href="http://www.bemasher.net/archives/534#footnote_0_534" id="identifier_0_534" class="footnote-link footnote-identifier-link" title="Notice they look normal to you because I&#039;ve gotten my script working.">1</a>]</sup>.</p>
<p>Took me a little while but I did finally find some documentation on all the different hooks wordpress has for filters. I found one in particular that does what I want called <em>content_save_pre</em> which applies a particular filter to the content of a post any time I save or edit it. So for things like drafts and actual posting and updating posts it would fire the function I registered as a filter.</p>
<p>The first problem I ran into is that for some strange reason it didn't seem to want to replace contractions with the single quote character. I later found out that when displaying the single-quote it converts it to the html entity <em>&amp;#8217;</em> which shows up as an apostrophe. So I tried working around that but that dIdn't seem to work either. Eventually I just setup a small test post and modified the function to email me the plain-text contents of the post that the filter would receIve, I noticed that it escaped single quotes probably through the use of the php function <em>mysql_escape_string</em><sup>[<a href="http://www.bemasher.net/archives/534#footnote_1_534" id="identifier_1_534" class="footnote-link footnote-identifier-link" title="http://www.php.net/manual/en/function.mysql-escape-string.php">2</a>]</sup>. So anything with an single-quote would show up with a backslash just before the single-quote. This of course broke the regular expression I was using and I couldn't seem to figure out how to get it to check for that character so I gave up and just used the negated word-character class <em>\W</em>.</p>
<p>Anyway after fiddling around with it a little more and adding a few new cases to the regex I arrived at this code:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">/*<br />
&nbsp; &nbsp; &nbsp; &nbsp; Plugin Name: Lazy Errors<br />
&nbsp; &nbsp; &nbsp; &nbsp; Plugin URI: http://www.bemasher.net/<br />
&nbsp; &nbsp; &nbsp; &nbsp; Description: Replaces errors from lazy typing, things like:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; I, I'd, I've, I'm will be replaced with proper case.<br />
&nbsp; &nbsp; &nbsp; &nbsp; Version: 0.02<br />
&nbsp; &nbsp; &nbsp; &nbsp; Author: BeMasher<br />
&nbsp; &nbsp; &nbsp; &nbsp; Author URI: http://www.bemasher.net/<br />
&nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">function</span> lazy_errors<span style="color: #009900;">&#40;</span><span style="color: #000088;">$content</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> <a href="http://www.php.net/preg_replace"><span style="color: #990000;">preg_replace</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/I(?(?=\W')(\W')(ve|m|d|)|(\b))/&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;I<span style="color: #006699; font-weight: bold;">$1</span><span style="color: #006699; font-weight: bold;">$2</span><span style="color: #006699; font-weight: bold;">$3</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$content</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; add_filter<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;content_save_pre&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;lazy_errors&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></tbody></table></div>
<p>The regular expression reads like so: If there's an I followed by any non-word character and a single-quote then make sure it's got a proper contraction following the single-quote. Else make sure there's a space, period, comma, colon or semI-colon following the I. Then replace with capitalized I and the matching group from the conditional.</p>
<p>I should probably work out some code to make it ignore sections of text I don't want it to filter. A prime example of this would be in the comments of the plugin and especially in any code as code examples copied from my site would then be broken if the regex I wrote matched anything in the code.</p>
<ol class="footnotes"><li id="footnote_0_534" class="footnote">Notice they look normal to you because I've gotten my script working.</li><li id="footnote_1_534" class="footnote"><a href="http://www.php.net/manual/en/function.mysql-escape-string.php">http://www.php.net/manual/en/function.mysql-escape-string.php</a></li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/534/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing MikTeX on Windows 7</title>
		<link>http://www.bemasher.net/archives/443</link>
		<comments>http://www.bemasher.net/archives/443#comments</comments>
		<pubDate>Tue, 23 Jun 2009 10:18:12 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Computers]]></category>
		<category><![CDATA[BSOD]]></category>
		<category><![CDATA[install]]></category>
		<category><![CDATA[Latex]]></category>
		<category><![CDATA[MikTeX]]></category>
		<category><![CDATA[TeX]]></category>
		<category><![CDATA[Windows 7]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=443</guid>
		<description><![CDATA[One of the only things that kept me from installing Windows 7 permanently during the school year was that the few times I tried, I had never gotten MikTeX[1] to work. This of course was a major problem since nearly all of my assignments are done with MikTeX now. When installing MikTeX I always ran [...]]]></description>
			<content:encoded><![CDATA[<p>One of the only things that kept me from installing Windows 7 permanently during the school year was that the few times I tried, I had never gotten MikTeX<sup>[<a href="http://www.bemasher.net/archives/443#footnote_0_443" id="identifier_0_443" class="footnote-link footnote-identifier-link" title="MiKTeX (pronounced mick-tech) is an up-to-date implementation of TeX and related programs for Windows (all current variants).">1</a>]</sup> to work. This of course was a major problem since nearly all of my assignments are done with MikTeX now. When installing MikTeX I always ran into a BSOD that I ignored because I figured that it was only because Windows 7 was only an RC<sup>[<a href="http://www.bemasher.net/archives/443#footnote_1_443" id="identifier_1_443" class="footnote-link footnote-identifier-link" title="Release Candidate">2</a>]</sup>.</p>
<p>I've had Windows 7 on my desktop now for about 2 weeks and up until this point I've been making due with the MikTeX Portable Edition which is pretty buggy to say the least. More than half of the time it would hang on compiling a document to pdf at something due to it not thinking initexmf.exe was an operable program. And of course upon googling this problem, nothing of use could be found.</p>
<p>Well tonight I decided I'd give the install another go to see if either Windows 7 had been patched to fix this issue, or if MikTeX had fixed the problem. On my first try, it did exactly as it had always done before BSOD'd. Since I had never set windows to not automatically restart upon catastrophic system failure<sup>[<a href="http://www.bemasher.net/archives/443#footnote_2_443" id="identifier_2_443" class="footnote-link footnote-identifier-link" title="Read: Blue Screen Of Death">3</a>]</sup> it would just instantly restart without giving me enough time to read the type of error. I fixed this and ran the installer once more. The BSOD was a PAGE_FAULT_IN_NON_PAGED_AREA error, which was pretty vague as usual but I figured it had to do with system paging, so I disabled the Virtual Memory restarted and ran the installer once more. This time it worked exactly as it should.</p>
<p>On another interesting note, I discovered that pdflatex is significantly faster than texify. I found this out when I was trying different methods of compiling my TeX documents into pdf's using the MikTeX Portable Edition which was giving me fits with my old method.</p>
<p>I used to use the following in NotePad++'s NppExec plugin to compile a pdf and view in Adobe Reader:</p>
<div class="codecolorer-container dos default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="dos codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">C:\Program Files\MiKTeX <span style="color: #cc66cc;">2.7</span>\miktex\bin\texify.exe -c -p &quot;$<span style="color: #66cc66;">&#40;</span>FULL_CURRENT_PATH<span style="color: #66cc66;">&#41;</span>&quot; &quot;$<span style="color: #66cc66;">&#40;</span>NAME_PART<span style="color: #66cc66;">&#41;</span>.pdf&quot;<br />
C:\Program Files\Adobe\Reader <span style="color: #cc66cc;">9.0</span>\Reader\AcroRd32.exe &quot;$<span style="color: #66cc66;">&#40;</span>CURRENT_DIRECTORY<span style="color: #66cc66;">&#41;</span>\$<span style="color: #66cc66;">&#40;</span>NAME_PART<span style="color: #66cc66;">&#41;</span>.pdf&quot;</div></td></tr></tbody></table></div>
<p>Now I use pdflatex:</p>
<div class="codecolorer-container dos default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="dos codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">C:\Program Files\MiKTeX <span style="color: #cc66cc;">2.7</span>\miktex\bin\pdflatex.exe &quot;$<span style="color: #66cc66;">&#40;</span>FULL_CURRENT_PATH<span style="color: #66cc66;">&#41;</span>&quot;<br />
C:\Program Files\Adobe\Reader <span style="color: #cc66cc;">9.0</span>\Reader\AcroRd32.exe &quot;$<span style="color: #66cc66;">&#40;</span>CURRENT_DIRECTORY<span style="color: #66cc66;">&#41;</span>\$<span style="color: #66cc66;">&#40;</span>NAME_PART<span style="color: #66cc66;">&#41;</span>.pdf&quot;</div></td></tr></tbody></table></div>
<ol class="footnotes"><li id="footnote_0_443" class="footnote"><a href="http://miktex.org/">MiKTeX</a> (pronounced mick-tech) is an up-to-date implementation of TeX and related programs for Windows (all current variants).</li><li id="footnote_1_443" class="footnote">Release Candidate</li><li id="footnote_2_443" class="footnote">Read: Blue Screen Of Death</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/443/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>LCD Hello World!</title>
		<link>http://www.bemasher.net/archives/363</link>
		<comments>http://www.bemasher.net/archives/363#comments</comments>
		<pubDate>Mon, 11 May 2009 07:30:46 +0000</pubDate>
		<dc:creator>bemasher</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Computers]]></category>
		<category><![CDATA[20x4 LCD]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[HD44780]]></category>
		<category><![CDATA[LCD]]></category>
		<category><![CDATA[LiquidCrystal]]></category>

		<guid isPermaLink="false">http://www.bemasher.net/?p=363</guid>
		<description><![CDATA[I finally got impatient with my progress on the LCD Shield I'm designing and decided to solder the headers onto the LCD and give it a try on the breadboard, which has turned out to be a good idea. The original pin-mapping I setup in the design wouldn't have worked and I would have been [...]]]></description>
			<content:encoded><![CDATA[<p><a title="DSC_4108" href="http://picasaweb.google.com/BeMasher/ALittleOff#5334432879950732770"><img class="pie-img alignleft" src="http://lh4.ggpht.com/_67X_BsG0Kiw/Sge2cPegneI/AAAAAAAAEcQ/tfCNJZ2uTrY/DSC_4108.jpg?imgmax=160" alt="DSC_4108" width="160" height="106" /></a></p>
<p>I finally got impatient with my progress on the LCD Shield I'm designing and decided to solder the headers onto the LCD and give it a try on the breadboard, which has turned out to be a good idea. The original pin-mapping I setup in the design wouldn't have worked and I would have been very frustrated at my wasting ~$20 on getting a PCB printed. I got a lot of great help from <a href="http://www.alfonsomartone.itb.it/kwztcq.html">http://www.alfonsomartone.itb.it/kwztcq.html</a> which almost problem-for-problem outlined the same order of issues I had excluding problems #2, #4 and #8.</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">#define RS 11</span><br />
<span style="color: #339933;">#define RW 2</span><br />
<span style="color: #339933;">#define E &nbsp;3</span><br />
<span style="color: #339933;">#define D0 4</span><br />
<span style="color: #339933;">#define D1 5</span><br />
<span style="color: #339933;">#define D2 6</span><br />
<span style="color: #339933;">#define D3 7</span><br />
<span style="color: #339933;">#define D4 14</span><br />
<span style="color: #339933;">#define D5 15</span><br />
<span style="color: #339933;">#define D6 16</span><br />
<span style="color: #339933;">#define D7 17</span><br />
<br />
LiquidCrystal lcd<span style="color: #009900;">&#40;</span>RS<span style="color: #339933;">,</span>RW<span style="color: #339933;">,</span>E<span style="color: #339933;">,</span>D0<span style="color: #339933;">,</span>D1<span style="color: #339933;">,</span>D2<span style="color: #339933;">,</span>D3<span style="color: #339933;">,</span>D4<span style="color: #339933;">,</span>D5<span style="color: #339933;">,</span>D6<span style="color: #339933;">,</span>D7<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Above is what the pin-mapping ended up being. I also discovered I had no pots to use for the contrast pin on the LCD at all so that's going to have to be fixed in the future. So for the time being the contrast is a little out of whack. But I was able to get it to print the traditional "Hello World!" string as you can see in the photo. Also you'll note that I used pins 14 through 17 and you're probably scratching your head as to which pins those are. They're actually the row of pins marked as analog in, analog in 0 is 14 and can actually be used as a digital IO pin as well.</p>
<p>Something else that I've also noticed that I'll need to fix is that the rows seem to be written to out of order. Writing order is as follows: Row 1, Row 3, Row 2, Row 4. Which I'm sure I can fix somehow but I don't know exactly why it's doing that just yet.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bemasher.net/archives/363/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
