<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><description></description><title>AsciiArmor</title><generator>Tumblr (3.0; @asciiarmor-blog)</generator><link>https://www.asciiarmor.com/</link><item><title>Building Go Applications for ARM Single Board Computers</title><description>&lt;p&gt;Last week &lt;a href="https://github.com/chrissnell"&gt;Chris Snell&lt;/a&gt; and I co-presented at the &lt;a href="http://www.meetup.com/golang/"&gt;Seattle Go Meetup&lt;/a&gt;. Here are the slides to both presentations and a quick photo.&lt;/p&gt;

&lt;figure class="tmblr-full" data-orig-height="500" data-orig-width="500" data-orig-src="https://64.media.tumblr.com/5b8c697d891ba9974997080e2f9cf94f/tumblr_inline_ne6tezPVoP1qz9mkv.jpg"&gt;&lt;img src="https://64.media.tumblr.com/807285d6a9faa282d0fed0fa7326dcda/tumblr_inline_pjzrq4jchk1qz9mkv_540.jpg" alt="image" data-orig-height="500" data-orig-width="500" data-orig-src="https://64.media.tumblr.com/5b8c697d891ba9974997080e2f9cf94f/tumblr_inline_ne6tezPVoP1qz9mkv.jpg"/&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;


&lt;iframe src="//www.slideshare.net/slideshow/embed_code/key/KQhYWSKh5L9brl" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen&gt; &lt;/iframe&gt; &lt;div style="margin-bottom:5px"&gt; &lt;strong&gt; &lt;a href="//www.slideshare.net/ryancox/developing-applications-for-beagle-bone-black-raspberry-pi-and-soc-single-board-arm-computers-with-go" title="Developing Applications for Beagle Bone Black, Raspberry Pi and SoC Single Board ARM Computers with Go" target="_blank"&gt;Developing Applications for Beagle Bone Black, Raspberry Pi and SoC Single Board ARM Computers with Go&lt;/a&gt; &lt;/strong&gt; from &lt;strong&gt;&lt;a target="_blank" href="//www.slideshare.net/ryancox"&gt;ryancox&lt;/a&gt;&lt;/strong&gt; &lt;/div&gt;


&lt;script async class="speakerdeck-embed" data-id="bc329f0040ee0132e592723ed83df33f" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"&gt;&lt;/script&gt;&lt;p&gt;Solid Run generously sent us a dual core &lt;a href="http://www.solid-run.com/products/hummingboard/"&gt;HummingBoard&lt;/a&gt; which we gave away to one of the attendees.&lt;/p&gt;</description><link>https://www.asciiarmor.com/post/101231662971</link><guid>https://www.asciiarmor.com/post/101231662971</guid><pubDate>Tue, 28 Oct 2014 20:58:00 -0700</pubDate><category>go</category><category>golang</category><category>meetup</category><category>raspberry pi</category><category>beagle bone black</category><category>arm</category></item><item><title>Jenkins: Now with more Gopher</title><description>&lt;p&gt;&lt;figure class="tmblr-full" data-orig-height="297" data-orig-width="500" data-orig-src="https://64.media.tumblr.com/b2af928872ed6017865b4ce871647064/tumblr_inline_nczta68vfL1qz9mkv.png"&gt;&lt;img alt="image" src="https://64.media.tumblr.com/68f3267f870d965034e5b5b1a2a7cc0f/tumblr_inline_pjzsu9LtnI1qz9mkv_540.png" data-orig-height="297" data-orig-width="500" data-orig-src="https://64.media.tumblr.com/b2af928872ed6017865b4ce871647064/tumblr_inline_nczta68vfL1qz9mkv.png"/&gt;&lt;/figure&gt;&lt;/p&gt;

&lt;p&gt;At the last &lt;a href="http://www.meetup.com/golang/"&gt;Seattle Go Programmers Meetup&lt;/a&gt; there was some interest expressed in work I had done using Jenkins to handle continuous integration for a couple of projects. I&amp;rsquo;ve captured details below along with a Dockerfile that lets you get up and running quickly with a worked example that builds the &lt;a href="https://github.com/spf13/hugo"&gt;Hugo&lt;/a&gt; project.&lt;/p&gt;
&lt;h3&gt;Setting up the demo within Docker&lt;/h3&gt;
&lt;p&gt;A &lt;a href="https://github.com/ryancox/go-jenkins-setup"&gt;docker file and job config&lt;/a&gt; is checked into GitHub that shows these ideas in action.&lt;/p&gt;
&lt;p&gt;On a 64 bit Linux system running a recent version of docker perform the following steps.&lt;/p&gt;
&lt;script src="https://gist.github.com/ryancox/622f568e3c6ec60d2bda.js" type="text/javascript"&gt;&lt;/script&gt;&lt;h3&gt;Workspace Setup&lt;/h3&gt;
&lt;p&gt;Jenkins creates a workspace directory for each job that contains all source and generated artifacts. This makes a convenient GOPATH root; ensuring that all dependencies are known and accounted for.&lt;/p&gt;

&lt;p&gt;&lt;figure class="tmblr-full" data-orig-height="203" data-orig-width="378" data-orig-src="https://64.media.tumblr.com/f953e02639e1d44918b001774ac37250/tumblr_inline_ncztainIcx1qz9mkv.png"&gt;&lt;img alt="image" src="https://64.media.tumblr.com/f953e02639e1d44918b001774ac37250/tumblr_inline_pjzsu90UhA1qz9mkv_540.png" data-orig-height="203" data-orig-width="378" data-orig-src="https://64.media.tumblr.com/f953e02639e1d44918b001774ac37250/tumblr_inline_ncztainIcx1qz9mkv.png"/&gt;&lt;/figure&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Install the &lt;a href="https://wiki.jenkins-ci.org/display/JENKINS/EnvInject+Plugin"&gt;EnvInject&lt;/a&gt; Jenkins plugins&lt;/li&gt;
&lt;li&gt;Under Build Environment, select &amp;lsquo;Inject environment variables to the build process&amp;rsquo; and enter 'GOPATH=$WORKSPACE&amp;rsquo; under Properties Contents&lt;/li&gt;
&lt;li&gt;All subsequent 'go get&amp;rsquo; or other go tools calls will operate within the context of the Jenkins workspace directory for this job.&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Git configuration&lt;/h3&gt;
&lt;p&gt;A useful configuration option when building projects from a Git repository is adding a &lt;a href="http://git-scm.com/book/en/Git-Internals-Git-References"&gt;Git reference&lt;/a&gt; that specifies the commit to be built by the job. The value can be defaulted to 'refs/heads/master&amp;rsquo; which will build from master during automatic or ad-hoc execution if not overridden. However, if a one-off job run is desired for a particular tag, branch or commit; this can easily be specified as a parameter. This also makes it very easy to go back and run prior versions of a project, in order to see historical trends for test pass rates, benchmarks and warnings counts.&lt;/p&gt;
&lt;p&gt; &lt;figure class="tmblr-full" data-orig-height="340" data-orig-width="500" data-orig-src="https://64.media.tumblr.com/ba5ce1146074b5c2ec3477026ff3f080/tumblr_inline_ncztnqMZoD1qz9mkv.png"&gt;&lt;img alt="image" src="https://64.media.tumblr.com/d8f10291d3c8d6c29f3bf845aedddf33/tumblr_inline_pjzsu94Fyg1qz9mkv_540.png" data-orig-height="340" data-orig-width="500" data-orig-src="https://64.media.tumblr.com/ba5ce1146074b5c2ec3477026ff3f080/tumblr_inline_ncztnqMZoD1qz9mkv.png"/&gt;&lt;/figure&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Install the &lt;a href="https://wiki.jenkins-ci.org/display/JENKINS/Git+Client+Plugin"&gt;Git Client&lt;/a&gt; Jenkins plugin&lt;/li&gt;
&lt;li&gt;Configure a job parameter of COMMIT that defaults to 'refs/heads/master&amp;rsquo;&lt;/li&gt;
&lt;li&gt;In the job&amp;rsquo;s Git Client setup, set the 'Branch Specifier&amp;rsquo; to $COMMIT&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Running Tests&lt;/h3&gt;
&lt;p&gt;While there is no native support for ingesting 'go test&amp;rsquo; output, Jenkins does have excellent handling of JUnit output. With the &lt;a href="https://bitbucket.org/tebeka/go2xunit"&gt;go2xunit&lt;/a&gt; utility, output from 'go test&amp;rsquo; and go check can be transformed into a format that the JUnit Jenkins plugin can process. This makes possible capture and visualization of test output.&lt;/p&gt;
&lt;p&gt;&lt;figure class="tmblr-full" data-orig-height="237" data-orig-width="500" data-orig-src="https://64.media.tumblr.com/a60f2ea175d70ef98163111c0b81ef6a/tumblr_inline_ncztb0uY4n1qz9mkv.png"&gt;&lt;img alt="image" src="https://64.media.tumblr.com/c16208236f85d1fb983c835af9d155e9/tumblr_inline_pjzsu9tQ6H1qz9mkv_540.png" data-orig-height="237" data-orig-width="500" data-orig-src="https://64.media.tumblr.com/a60f2ea175d70ef98163111c0b81ef6a/tumblr_inline_ncztb0uY4n1qz9mkv.png"/&gt;&lt;/figure&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Add a job step that installs go2xunit: 'go get bitbucket.org/tebeka/go2xunit&amp;rsquo;&lt;/li&gt;
&lt;li&gt;Add a job step that runs tests with the &amp;rsquo;-v&amp;rsquo; option and capture the output to a file: 'go test -v github.com/spf13/hugo/&amp;hellip; &amp;gt; test.output&amp;rsquo;&lt;/li&gt;
&lt;li&gt;Add a job step that converts the go test output to JUnit xml: 'cat test.output | &amp;ldquo;./bin/go2xunit&amp;rdquo; -output tests.xml&amp;rsquo;&lt;/li&gt;
&lt;li&gt;Add a Post Build Action to Publish JUnit test results and specify 'tests.xml&amp;rsquo;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Visualizing Benchmarks&lt;/h3&gt;
&lt;p&gt;Go has great support for adding &lt;a href="http://dave.cheney.net/2013/06/30/how-to-write-benchmarks-in-go"&gt;benchmarks&lt;/a&gt;. I&amp;rsquo;ve written a tiny utility &lt;a href="https://github.com/ryancox/gobench2plot"&gt;gobench2plot&lt;/a&gt; that extracts benchmark output and transforms it into an XML format that can be plotted. This format can then be the existing &lt;a href="https://wiki.jenkins-ci.org/display/JENKINS/Plot+Plugin"&gt;Plot&lt;/a&gt; Jenkins plugin.&lt;/p&gt;
&lt;p&gt;&lt;figure class="tmblr-full" data-orig-height="300" data-orig-width="500" data-orig-src="https://64.media.tumblr.com/23aa26033c44dae124bf49a62354860b/tumblr_inline_ncztb9CqyA1qz9mkv.png"&gt;&lt;img alt="image" src="https://64.media.tumblr.com/62e85e1fca4d625570eb1a9691cfbd96/tumblr_inline_pjzsuachTj1qz9mkv_540.png" data-orig-height="300" data-orig-width="500" data-orig-src="https://64.media.tumblr.com/23aa26033c44dae124bf49a62354860b/tumblr_inline_ncztb9CqyA1qz9mkv.png"/&gt;&lt;/figure&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Install the &lt;a href="https://wiki.jenkins-ci.org/display/JENKINS/Plot+Plugin"&gt;Plot&lt;/a&gt; Jenkins plugin&lt;/li&gt;
&lt;li&gt;Add a job step that installs gobench2plot: 'go get github.com/ryancox/gobench2plot&amp;rsquo;&lt;/li&gt;
&lt;li&gt;Add a job step that runs tests and benchmarks: 'go test -bench=Bench* -test.benchmem -v github.com/spf13/hugo/&amp;hellip; &amp;gt; ${WORKSPACE}/test.output&amp;rsquo;&lt;/li&gt;
&lt;li&gt;Add a job step that transforms benchmark values in test output to xml: 'cat test.output | gobench2plot &amp;gt; benchmarks.xml&amp;rsquo;&lt;/li&gt;
&lt;li&gt;Add a post build job step that does a line style plot of the values; specifying benchmarks.xml and an appropriate XPath query: &amp;rsquo;/Benchmarks/AllocsPerOp/*&amp;rsquo;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Static Analysis&lt;/h3&gt;
&lt;p&gt;The popular Jenkin plugin 'warnings&amp;rsquo; parses and captures output of static analysis tools like lint and findbugs. There was no support for Golint and Go vet. So I added this capability and submitted a pull request to the project. &lt;a href="https://github.com/jenkinsci/warnings-plugin/pull/45"&gt;This PR&lt;/a&gt; has been merged into master.&lt;/p&gt;

&lt;p&gt;Note: At the time of writing, a new release has not been created for 'warnings&amp;rsquo; and pushed to the Jenkins plugin server. So until then, you will need to build from source or use the binary in the example project by manually uploading the HPI file into Jenkins via the UI or just copying it to your plugins directory.&lt;/p&gt;
&lt;p&gt;&lt;figure class="tmblr-full" data-orig-height="177" data-orig-width="500" data-orig-src="https://64.media.tumblr.com/ee6c558d0765bc641260615799ff49a5/tumblr_inline_ncztblMGkO1qz9mkv.png"&gt;&lt;img alt="image" src="https://64.media.tumblr.com/b02fde36cd254ee20d29ce9fc0752cf8/tumblr_inline_pjzsuab7BK1qz9mkv_540.png" data-orig-height="177" data-orig-width="500" data-orig-src="https://64.media.tumblr.com/ee6c558d0765bc641260615799ff49a5/tumblr_inline_ncztblMGkO1qz9mkv.png"/&gt;&lt;/figure&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Install the &lt;a href="https://wiki.jenkins-ci.org/display/JENKINS/Warnings+Plugin"&gt;Warnings&lt;/a&gt; Jenkins plugin&lt;/li&gt;
&lt;li&gt;Add build step that installs glint or go vet: 'go get github.com/golang/lint/golint&amp;rsquo;&lt;/li&gt;
&lt;li&gt;Add build step that runs glint or go vet and saves output: &amp;rsquo;./bin/golint github.com/spf13/hugo/&amp;hellip; &amp;gt; lint.txt&amp;rsquo;&lt;/li&gt;
&lt;li&gt;Add a 'Scan for Compiler Warnings&amp;rsquo; post build action that specifies the output file and Go Lint or Go Vet Parser.&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Testing Multiple Go Versions&lt;/h3&gt;
&lt;p&gt;Package owners may want to test support and performance across several different versions of the Go. This can be accomplished using the Jenkins multi-configuration job type. This job type allow for various 'axis&amp;rsquo; of execution to be defined. A new Jenkins build is created for each axis combination. A single axis named GOVERSION, for example, can be created that contains values such as 'go1.1.2 go1.2 go1.3 go tip&amp;rsquo;. In the shell execute steps, $GOVERSION would be used in place of the normal 'go&amp;rsquo; command. This scheme requires that the system upon which Jenkins is executing has multiple Go. This can be accomplished by installing the binaries in a location that is accessible system wide ( e.g. /usr/local/go-1.1.2 and /usr/local/go-1.3 ), then creating symlinks in /usr/local/bin/go-1.1.2 and /usr/local/go-1.3 that point back to the binaries in these locations ). It can be useful to keep a current build from the tip of master installed and accessible as 'gotip&amp;rsquo;. This allows for testing of packages against the most recent changes to Go. TODO: Do I need the matrix plugin for this?&lt;/p&gt;
&lt;p&gt; &lt;figure class="tmblr-full" data-orig-height="189" data-orig-width="500" data-orig-src="https://64.media.tumblr.com/2e5a888a05dfa26822d293b862ec00c4/tumblr_inline_ncztn7gH1z1qz9mkv.png"&gt;&lt;img alt="image" src="https://64.media.tumblr.com/8110d5dc741ddb38efc586fd354c0111/tumblr_inline_pjzsuaoSaZ1qz9mkv_540.png" data-orig-height="189" data-orig-width="500" data-orig-src="https://64.media.tumblr.com/2e5a888a05dfa26822d293b862ec00c4/tumblr_inline_ncztn7gH1z1qz9mkv.png"/&gt;&lt;/figure&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Create build job as 'Build multi-configuration project&amp;rsquo; rather than a 'Freestyle&amp;rsquo; job type&lt;/li&gt;
&lt;li&gt;Under Configuration Matrix, define a User defined Axis of 'GOVERSION&amp;rsquo; containing values 'go1.1.2 go1.2 go1.3&amp;rsquo;&lt;/li&gt;
&lt;li&gt;Replace calls to 'go&amp;rsquo; command with $GOVERSION&lt;/li&gt;
&lt;li&gt;Configure host system with multiple versions of Go such that 'go1.1.2, go1.2 and go1.3 map to the respective versions of the tools&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Note: To keep the example simple, this is not included in the accompanying Dockerfile&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Special thanks to &lt;a href="https://github.com/dylanmei"&gt;Dylan Meissner&lt;/a&gt; for his review of this post&lt;/em&gt;&lt;/p&gt;</description><link>https://www.asciiarmor.com/post/99010893761</link><guid>https://www.asciiarmor.com/post/99010893761</guid><pubDate>Thu, 02 Oct 2014 17:03:00 -0700</pubDate><category>jenkins</category><category>go</category><category>golang</category><category>continuous integration</category></item><item><title>motionless: taking the pain out of Google Static Maps</title><description>&lt;p&gt;I have found myself needing to generate several map visualizations lately. Creating complex URLs for &lt;a href="http://code.google.com/apis/maps/documentation/staticmaps/"&gt;Google Static Maps&lt;/a&gt; can be time consuming and error prone. To make this process more civilized, I&amp;rsquo;ve put together a simple python library. It supports markers, paths as well as simple centered maps. All the details can be found on &lt;a href="http://github.com/ryancox/motionless"&gt;github&lt;/a&gt;. In brief, install with pip:&lt;/p&gt;
&lt;pre&gt;pip install motionless
&lt;/pre&gt;
&lt;p&gt;Simple map centered on the Eiffel Tour:&lt;/p&gt;
&lt;hr&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; motionless import CenterMap 
cmap = CenterMap(lat=48.858278,lon=2.294489,maptype='satellite') 
print cmap.generate_url()
&lt;/pre&gt;
&lt;hr&gt;&lt;p&gt;&lt;img src="http://maps.google.com/maps/api/staticmap?maptype=satellite&amp;amp;format=png&amp;amp;center=48.858278,2.294489&amp;amp;zoom=17&amp;amp;size=400x400&amp;amp;sensor=false"/&gt;&lt;/p&gt;
&lt;p&gt;Slightly more complex example generated from a GPX file on my Garmin device illustrating how to plot paths and add markers. Code is in the &lt;a href="http://github.com/ryancox/motionless/blob/master/examples/munich.py"&gt;examples&lt;/a&gt; directory&lt;/p&gt;
&lt;p&gt;&lt;img src="http://maps.google.com/maps/api/staticmap?maptype=roadmap&amp;amp;format=png&amp;amp;size=640x640&amp;amp;sensor=false&amp;amp;markers=%7Ccolor:green%7Clabel:S%7C48.167051,11.565088&amp;amp;markers=%7Ccolor:red%7Clabel:E%7C48.351883,11.791474&amp;amp;path=enc:as~dHwxqeAc@VPL_@M%7DCOuBBgGn@qDX%7BFmAoHyBcGaDeCwC%7BDwAeBwHaCcNK_AKcBD%7BBC_FEcAnCasA~DcOXNp@Et@DXCf@IRSR%5DL%5DJgABe@?i@QwAa@mAy@_AcN%7DKmHoGmGiGwHiKmEmLwBsK%7DByO%7BC%7DK_FoK_HsI_JoGgJcEeJsD%7BUaJge@aRko@oWiQ_Hym@qVuf@yRc%5C_Ncp@gW%7D%7B@w%5Dqd@%7BPwP_CgPHyQnC%7Bz@dSwo@%60PwSjHek@jVm%5BpN_k@vX_HjDiK%60FuLnGiIlDoGjDcJhCkGm@cIaEeFeGyEkLqIqTmIcUsJyVkFyQyFkUcJmc@aHwd@sEsd@sDkj@qA_e@Ye%60@Kad@_Amf@cC_%5CgDwTiHaX_KeU%7DKmPmOiQkNuRgJoRiGiRgJySuBwKYsJv@mWa@oUiCkv@mAq%60@aAqX%7D@eZo@%7B%5Dg@mZHiFRmBNu@Nq@l@%7BAVm@rA%7BB%60AaAb@WrBq@xJyBx@%5Bn@i@%7C@yAN%5Df@mBNoA?mCm@aPI%7DRc@cPq@qS%5DiA?q@COGMGIM?OJENq@TmHTgDNW%5CA%7D@KsA_@a@c@B"/&gt;&lt;/p&gt;</description><link>https://www.asciiarmor.com/post/902634084</link><guid>https://www.asciiarmor.com/post/902634084</guid><pubDate>Wed, 04 Aug 2010 04:46:00 -0700</pubDate><category>python</category></item><item><title>Tips for Computer Book Authors</title><description>&lt;p&gt;Over the last 18 months or so I’ve had the great experience of reviewing a handful of books in various stages of development. In doing so I noted several patterns that emerged and captured them here. &lt;em&gt;Enjoy!&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Make sample code stand-alone test cases&lt;/h2&gt;
&lt;p&gt;Whether you are developing Python or PowerBuilder, chances are there is a unit-test framework available. Leverage these frameworks in creating your samples. It forces discipline upon the author to keep examples small and self-contained. More significantly, it provides code that will compile and be immediately useful to readers.&lt;/p&gt;
&lt;p&gt;Never underestimate the power of copy and paste.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/1932394281/"&gt;Lucene in Action&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://c2.com/cgi/wiki?TestingFramework"&gt;Testing Frameworks&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Develop reader personas&lt;/h2&gt;
&lt;p&gt;Writers face the challenge of crystallizing target readers. What is their level of education? What is their experience with the subject being presented? More importantly, writers face the less obvious question: Who are they not writing for? Poor attention to these questions manifests itself in the form of inconsistencies like: assuming the reader understands the quicksort algorithm but in the previous chapter explaining how to download and unzip a file.&lt;/p&gt;
&lt;p&gt;Borrow a technique from the design world to mitigate this challenge: Develop full-blown personas of your readers. Include photos. Include a work-history. Is this the type of person who wants to go home at 5PM or understand the subject from the inside out? What is their reading style? Make a few copies. Hang them on the wall where you write. Send them to your editors.&lt;/p&gt;
&lt;p&gt;Mercilessly challenge yourself: Is this something the readers already know? Is this something readers need additional foundation on?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.cooper.com/newsletters/2001_07/perfecting_your_personas.htm"&gt;Perfecting Personas&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Define your value proposition&lt;/h2&gt;
&lt;p&gt;Odds are, your book is not the only one on the subject. In the planning stages of the book define your value proposition in clear terms. Send it to your editors. What does your book bring to the party that no other does? Does it consider common pitfalls? Does it describe internal implementation details? Is it aimed specifically at beginners or advanced readers? Is it a comprehensive treatise on a subject?&lt;/p&gt;
&lt;p&gt;Struggling to come up with your value proposition? Maybe the project isn&amp;rsquo;t such a great idea.&lt;/p&gt;
&lt;h2&gt;Consider various styles of reading&lt;/h2&gt;
&lt;p&gt;A small minority of your readers will make a front-to-back consideration of your manuscript. More readers look for answers to a specific problem. Still more read in an exploratory style, seeking an overall survey or looking for topics that interest them. Ask yourself: How do I serve these various types of readers? Devices such as “Best Practices” or “Pitfalls” beak-out boxes help capture the attention of explorers. A topical Q&amp;amp;A summary can serve the answer seekers.&lt;/p&gt;
&lt;p&gt;Think about the guy at Borders flipping through your book on a rainy afternoon. Remember the frantic developer spilling cold coffee on your book as he works on solving a problem with a production system.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/1930110995/"&gt;JUnit In Action&lt;/a&gt;&lt;br/&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0596007124/"&gt;Head First Design Patterns&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;“Don’t be too pleased with yourself.”&lt;/h2&gt;
&lt;p&gt;This one is borrowed from the style guide provided to writers of the Economist magazine. The idea&amp;rsquo;s relevance to programmers is emphasized in Larry Wall&amp;rsquo;s consideration of great virtues a programmer. In it he defines “Hubris” as:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;“Excessive pride, the sort of thing Zeus zaps you for. Also the quality that makes you write (and maintain) programs that other people won’t want to say bad things about. Hence, the third great virtue of a programmer. See also laziness and impatience. (p.607)”&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Self-confidence is a good thing; leave it unchecked and you will endear yourself to few readers. For whatever reasons, the industry breeds excessive self-assurance. Challenge yourself: Can use of the first person singular be reduced? Better yet, eliminated entirely? Do you see phrases like: “A naive programmer would…” or “Inexperienced users might…”?&lt;/p&gt;
&lt;p&gt;Respect your reader; they could probably teach you a thing or two.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://c2.com/cgi/wiki?LazinessImpatienceHubris"&gt;3 Traits&lt;/a&gt;&lt;br/&gt;&lt;a href="http://www.economist.com/research/styleGuide/index.cfm?page=673927"&gt;Economist Style Guide&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Leave your fingerprints on the manuscript&lt;/h2&gt;
&lt;p&gt;This is the corollary to “Don&amp;rsquo;t be too pleased with yourself”. Without being self-serving let your unique voice be heard. You represent a unique intersection of experience, education and ideas. Let this individuality come through. Have you been consulting for years and seen techniques succeed or fail. Tell readers about it! Have a relevant war story? Share it! Inject some personality; relentlessly combat a dry documentary style.&lt;/p&gt;
&lt;p&gt;If you are not consciously battling tedium, you have ceded to it.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0764558315/"&gt;Enterprise Java w/o EJB&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Use a single problem domain for sample code&lt;/h2&gt;
&lt;p&gt;Don&amp;rsquo;t be seduced by metasyntactic variables. Pick a realistic problem domain and stick to it. Don’t switch from stock quotes in the first chapter to class scheduling in the second. Let your reader reap the benefits of investing time in understanding the problem domain. Note: This is not to say examples should be cumulative and dependent on prior chapters.&lt;/p&gt;
&lt;p&gt;Allow them to focus on the message and not the means to convey it.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0596006969/"&gt;Hibernate: A Developer’s Notebook&lt;/a&gt;&lt;br/&gt;&lt;a href="http://en.wikipedia.org/wiki/Metasyntactic_variable"&gt;Metasyntactic Variables&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Say more by saying less&lt;/h2&gt;
&lt;p&gt;Keep your language simple and eliminate digressions. Simple words are the most powerful. “It was the best times, it was the worst of times…”. “In the beginning…”.  “We didn&amp;rsquo;t land on Plymouth Rock…” Unsparingly revise long and wordy sentences. Watch some DVD commentaries and listen to directors wax-nostalgic about scenes they deleted in the interest of producing a better film. Learn from them. Don&amp;rsquo;t make your book the next Ishtar. Unsympathetically delete sentences, paragraphs and chapters.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ve got work to do if you can&amp;rsquo;t remember the last time you simplified a sentence or deleted a portion of your manuscript.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0201616475/"&gt;Cryptography Decrypted&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Cite other works&lt;/h2&gt;
&lt;p&gt;Citations reinforce the hard work that went into the manuscript. More importantly they show readers where more can be learned on a specific topic. Subscribe to O'Reilly&amp;rsquo;s Safari service. Spend some time at a good book store. Work with your publisher to get copies of books they publish on related topics.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0130206016/"&gt;Unix System Administration Book&lt;/a&gt;&lt;br/&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0735619670/"&gt;Code Complete&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Communicate compromises&lt;/h2&gt;
&lt;p&gt;Every technology represents a series of compromises. Communicate these to the reader. Don&amp;rsquo;t make them learn the hard way. This isn&amp;rsquo;t a hammer for every nail. This isn&amp;rsquo;t a solution to every problem. Challenge yourself when outlining a topic: What are the relative merits the implementation? What were the alternatives? When should this technology not be employed? What would my readers benefit most for knowing?&lt;/p&gt;
&lt;p&gt;Prove to your reader you&amp;rsquo;re not a zealot.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0321150406/"&gt;Effective XML&lt;/a&gt; ( particularly items 24,25,41 )&lt;/p&gt;</description><link>https://www.asciiarmor.com/post/33736614</link><guid>https://www.asciiarmor.com/post/33736614</guid><pubDate>Fri, 14 Jan 2005 18:09:16 -0800</pubDate></item><item><title>java.util.UUID mini-FAQ</title><description>&lt;p&gt;J2SE 1.5 gives us a new class to generate identifiers. Here are some details I found after writing a bit of code and doing some reading.&lt;/p&gt;
&lt;h3&gt;What is a UUID?&lt;/h3&gt;
&lt;p&gt;According to Wikipedia:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“…an identifier standard used in software construction, standardized by the Open Software Foundation (OSF) as part of the Distributed Computing Environment (DCE). The intent of UUIDs is to enable distributed systems to uniquely identify information without significant central coordination. Thus, anyone can create a UUID and use it to identify something with reasonable confidence that that identifier will never be unintentionally used by anyone for anything else. Information labelled with UUIDs can therefore be later combined into a single database without need to resolve name conflicts. The most widespread use of this standard is in Microsoft’s Globally Unique Identifiers (GUIDs) which implement this standard.&lt;/p&gt;
&lt;p&gt;A UUID is essentially a 16-byte number and in its canonical form a UUID may look like this:&lt;/p&gt;
&lt;p&gt;550E8400-E29B-11D4-A716-446655440000&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;How do I generate a new UUID?&lt;/h3&gt;
&lt;p&gt;Calling the randomUUID() factory method will give you a fresh instance. Calling toString() will provide a spec-compliant canonical string representation. See the testRandom method in the source below.&lt;/p&gt;
&lt;h3&gt;I thought these were called GUIDs. What is a UUID?&lt;/h3&gt;
&lt;p&gt;Per the draft spec referenced below these are synonymous:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;…UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally&lt;br/&gt; Unique IDentifier).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;I’m a Windows guy. Is this the same thing as CoCreateGuid?&lt;/h3&gt;
&lt;p&gt;According to MSDN the current version of CoCreateGuid also generates a ‘version 4′ random number based UUID.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The CoCreateGuid function calls the RPC function UuidCreate, which creates a GUID, a globally unique 128-bit integer. Use the CoCreateGuid function when you need an absolutely unique number that you will use as a persistent identifier in a distributed environment.To a very high degree of certainty, this function returns a unique value no other invocation, on the same or any other system (networked or not), should return the same value.&lt;/p&gt;
&lt;p&gt;For security reasons, it is often desirable to keep ethernet/token ring addresses on networks from becoming available outside a company or organization. In Windows XP/2000, the UuidCreate function generates a UUID that cannot be traced to the ethernet/token ring address of the computer on which it was generated. It also cannot be associated with other UUIDs created on the same computer. If you do not need this level of security, your application can use the UuidCreateSequential function, which behaves exactly as the UuidCreate function does on all other versions of the operating system.&lt;/p&gt;
&lt;p&gt;In Windows NT 4.0, Windows 95, DCOM release, and Windows 98, UuidCreate returns RPC_S_UUID_LOCAL_ONLY when the originating computer does not have an ethernet/token ring (IEEE 802.x) address. In this case, the generated UUID is a valid identifier, and is guaranteed to be unique among all UUIDs generated on the computer. However, the possibility exists that another computer without an ethernet/token ring address generated the identical UUID. Therefore you should never use this UUID to identify an object that is not strictly local to your computer. Computers with ethernet/token ring addresses generate UUIDs that are guaranteed to be globally unique.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;I thought UUIDs used the MAC address to guarantee uniqueness&lt;/h3&gt;
&lt;p&gt;The specification defines multiple types of UUIDs. Version 1 UUIDs include a MAC address. Version 4 UUIDs are generated from a large random number and do not include the MAC address. The implementation of java.util.UUID creates version 4 UUIDs. See the testVersion method in the source below.&lt;/p&gt;
&lt;h3&gt;So java.util.UUID can only generate version 4 UUIDs. Can it parse and handle the other types?&lt;/h3&gt;
&lt;p&gt;Yes. Using the fromString method you can instantiate and interrogate a UUID of version 1,2,3 or 4. See the testFromString method in the source below; note it’s a version 1 UUID.&lt;/p&gt;
&lt;h3&gt;The draft spec talks about multiple variant types of UUIDs. Which variant types are supported by java.util.UUID?&lt;/h3&gt;
&lt;p&gt;As indicated by the javadoc for getVariant(), java.util.UUID only supports variant type 2.&lt;/p&gt;
&lt;h3&gt;I like the idea of using the MAC address. What makes version 4 UUIDs better?&lt;/h3&gt;
&lt;p&gt;Using a version 4 UUID could save you &lt;a href="http://www.theregister.co.uk/2002/05/01/melissa_virus_author_jailed/"&gt; 20 months in a United States Federal Prison&lt;/a&gt;. Evidently the writer of the Melissa worm was tracked down in part by the MAC address in a UUID.&lt;/p&gt;
&lt;h3&gt;So these version 4 UUIDs are basically random numbers. Won’t my UUID collide with someone elses?&lt;/h3&gt;
&lt;p&gt;There are 122 significant bits in a type 4 UUID. 2&lt;sup&gt;122&lt;/sup&gt; is a *very* large number. Assuming a random distribution of these bits, the probability of collission is *very* low. How is the “randomness” determined?&lt;/p&gt;
&lt;p&gt;Under the hood java.util.UUID is creating an instance of SecureRandom and using that to generate new UUIDs. If you are using the default Sun provider and default java.security file, you are using a SHA1PRNG ( Pseudo Random Number Generator based on Secure Hash Algorigthm 1 ) seeded from the operating system.&lt;/p&gt;
&lt;p&gt;java.security&lt;/p&gt;
&lt;pre&gt;#
# Select the source of seed data for SecureRandom. By default an
# attempt is made to use the entropy gathering device specified by
# the securerandom.source property. If an exception occurs when
# accessing the URL then the traditional system/thread activity
# algorithm is used.
#
# On Solaris and Linux systems, if file:/dev/urandom is specified and it
# exists, a special SecureRandom implementation is activated by default.
# This "NativePRNG" reads random bytes directly from /dev/urandom.
#
# On Windows systems, the URLs file:/dev/random and file:/dev/urandom
# enables use of the Microsoft CryptoAPI seed functionality.
#
securerandom.source=file:/dev/urandom&lt;/pre&gt;
&lt;p&gt;On WinTel platforms this may map down to &lt;a href="http://blogs.msdn.com/fvicaria/archive/2004/10/06/238862.aspx"&gt;hardware&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;More on &lt;a href="http://triumvir.org/rng/"&gt;randomness&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;I want to preserve backward JDK compatibilty. I’ll just use java.rmi.server.UID. Cool?&lt;/h3&gt;
&lt;p&gt;Probably a bad idea. Per the docs this gives you 2&lt;sup&gt;16&lt;/sup&gt; significant digits. It is also makes no provision for the system clock being set backward.&lt;/p&gt;
&lt;h3&gt;What other options do I have?&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://jakarta.apache.org/commons/sandbox/id/"&gt;commons-id&lt;/a&gt; is a general purpose identifier generator capable of generating UUIDs.&lt;/p&gt;
&lt;h3&gt;Where can I read more about UUIDs?&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.ietf.org/internet-drafts/draft-mealling-uuid-urn-04.txt"&gt;Current Draft Specification&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Sample Code&lt;/h2&gt;
&lt;pre&gt;import java.util.UUID;
  import junit.framework.TestCase;
public class UUIDTest extends TestCase {  	
	public void testRandom() { 		
		UUID a = UUID.randomUUID();
		UUID b = UUID.randomUUID();
		assertFalse(a.equals(b));
	}  	

	public void testVariant() { 		
		UUID a = UUID.randomUUID();
		assertEquals(a.variant(), 2);
	}  	

	public void testVersion() { 		
		UUID a1 = UUID.randomUUID();
		assertEquals(a1.version(), 4);
		// here is a version 1 UUID plucked from my own HKLMSoftwareClasses 		
		// for history of UUIDs ending in 444553540000 		
		// &lt;a href="http://blogs.msdn.com/oldnewthing/archive/2004/02/11/71307.aspx#71356"&gt;http://blogs.msdn.com/oldnewthing/archive/2004/02/11/71307.aspx#71356&lt;/a&gt; 		
		UUID a2 = UUID.fromString("d27cdb6e-ae6d-11cf-96b8-444553540000");
		assertEquals(a2.variant(), 2);
		assertEquals(a2.version(), 1);
	}  	

	public void testFromString() { 		
		String s = "d27cdb6e-ae6d-11cf-96b8-444553540000";
		UUID a = UUID.fromString(s);
		assertEquals(a.toString(), s);
	}  	

	public void testVersionFromCommonsTestCase() {  		
		// these UUIDs are from commons-id 		
		UUID v1 = UUID.fromString("3051a8d7-aea7-1801-e0bf-bc539dd60cf3");
		UUID v2 = UUID.fromString("3051a8d7-aea7-2801-e0bf-bc539dd60cf3");
		UUID v3 = UUID.fromString("3051a8d7-aea7-3801-e0bf-bc539dd60cf3");
		UUID v4 = UUID.fromString("3051a8d7-aea7-4801-e0bf-bc539dd60cf3");

		//UUID v5 = UUID.fromString("3051a8d7-aea7-3801-e0bf-bc539dd60cf3");
		assertEquals(1, v1.version());
		assertEquals(2, v2.version());
		assertEquals(3, v3.version());
		assertEquals(4, v4.version());

		// java.util.UUID doesn't support version 5 UUIDs while commons-id does 		
		//assertEquals(5, v5.version());
	} 
}
&lt;/pre&gt;</description><link>https://www.asciiarmor.com/post/33736615</link><guid>https://www.asciiarmor.com/post/33736615</guid><pubDate>Mon, 03 Jan 2005 23:15:00 -0800</pubDate></item></channel></rss>
