<?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>JoeJag :: Tech</title>
	<atom:link href="http://code.joejag.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://code.joejag.com</link>
	<description>Joe Wright&#039;s technology blog</description>
	<lastBuildDate>Thu, 11 Apr 2013 22:11:44 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>What&#8217;s your problem?</title>
		<link>http://code.joejag.com/2013/considerations-when-adopting-a-new-tool-or-practice/</link>
		<comments>http://code.joejag.com/2013/considerations-when-adopting-a-new-tool-or-practice/#comments</comments>
		<pubDate>Mon, 01 Apr 2013 23:30:40 +0000</pubDate>
		<dc:creator>Joe Wright</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://code.joejag.com/?p=949</guid>
		<description><![CDATA[Google don&#8217;t do Test Driven Development, so I don&#8217;t see why I should either Countless software devs We live in a world where people love to apply quick fix solutions to problems. Lose 10kg in 2 weeks! No cash until payday? Borrow £100 at 30000% APR! We crave these simple solutions, and deeply want to [...]]]></description>
				<content:encoded><![CDATA[<blockquote><p>
Google don&#8217;t do Test Driven Development, so I don&#8217;t see why I should either<br />
<small>Countless software devs</small>
</p></blockquote>
<p>We live in a world where people love to apply quick fix solutions to problems. Lose 10kg in 2 weeks! No cash until payday? Borrow £100 at 30000% APR! We crave these simple solutions, and deeply want to believe that they can make our lives better.</p>
<p>It&#8217;s a good idea to look at the context we are in, then work on a way to change the system that governs that context. Once we understand the system we can then look at adopting tools to help us. </p>
<p>For both of the examples I gave in the introduction a good question would be: What&#8217;s your food intake and exercise like? How are you spending your money currently? But people don&#8217;t do this. They are far more interested in the next miracle fix.  Sadly in the IT world we are just as susceptible to quickly grabbing a new tool that worked for someone else, then either blindly going with it or quitting in absolute disgust.</p>
<p>We can improve the process we use to select tools to remedy our problems. The key to this is to stop only focusing on how a tool works and its benefits and <strong>start by asking what problem the tool solves</strong>. The first two parts are important, but useless without knowing if it&#8217;s solving a problem you have.</p>
<p>I suggest we use this checklist when considering any new tool or practice:</p>
<ul>
<li>What problem does it solve?
<li>How does it work?
<li>What are the benefits?
<li>Will this work in my context?
</ul>
<p>A lot of people have a strong reaction to BDD and <a href="http://cukes.info/">Cucumber</a> so let&#8217;s use that as an example. We&#8217;ll use a shortened summary of the checklist items then consider a recommendation for two different personas.</p>
<h3>Cucumber checklist summary</h3>
<p>Cucumber solves a number of problems often seen in software development where misunderstandings are rife. In particular it solves the problem of the business speaking a different domain language from the development team by asking them to collaborate on acceptance tests together in a simple natural language script.</p>
<p>Its benefits include living documentation, automated acceptance tests, and encouraging an outside in view of software development.</p>
<h4>Is Cucumber right for Angus?</h4>
<p>Our first persona will be Angus. Angus had an idea for a mobile app and hired two people he trusts to help him build it. Angus has heard great things about Cucumber at conferences and wants to try it out with his team.</p>
<p>Angus doesn&#8217;t have a major problem with miscommunication within his team. If he tries Cucumber he&#8217;ll probably decide that he doesn&#8217;t like &#8220;<a href="http://stackoverflow.com/questions/4183160/does-bdd-pay-off">the extra layer of indirection</a>&#8221; Cucumber introduces. As the readers of the tests are all technical, he could get the same benefit from just writing outside-in integration tests in the testing framework he&#8217;s already using.</p>
<p>Angus should look for other methods, or invent his own, that can give him some of the other benefits that Cucumber brings. </p>
<h4>Is Cucumber right for Bruce?</h4>
<p>Bruce works for a medium sized digital agency who specialise in online shopping sites for a wide variety of clients. His customers like to run discount campaigns during different seasons. Currently he gets the client to write the pricing rules down in an email which he turns into code.</p>
<p>The product owner for Bruce&#8217;s project is not part of the team. By using Cucumber&#8217;s acceptance criteria with the client he could quickly discover problems with his understanding of the pricing code and also open up other conversations with his client.</p>
<p>Bruce should look into adopting Cucumber.</p>
<h3>Context is king</h3>
<p>When you hear about a tool you need to look at the problem it solves, the other benefits it brings and consider if this makes sense in your own context. The misapplication of tools leads to pessimism and waste. We should be optimistic about new tools, but grounded in our current context. Context is king.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.joejag.com/2013/considerations-when-adopting-a-new-tool-or-practice/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Everyday Git Aliases</title>
		<link>http://code.joejag.com/2013/everyday-git-aliases/</link>
		<comments>http://code.joejag.com/2013/everyday-git-aliases/#comments</comments>
		<pubDate>Mon, 01 Apr 2013 10:12:18 +0000</pubDate>
		<dc:creator>Joe Wright</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://code.joejag.com/?p=903</guid>
		<description><![CDATA[Git gives you as much flexibility in how you construct your VCS workflow as it does for the commands you use on your local repo. In your gitconfig file you can add alises for your favourite commands, in this article I&#8217;ll talk about mine. You can see my gitconfig on github. git standup alias for [...]]]></description>
				<content:encoded><![CDATA[<p>Git gives you as much flexibility in how you construct your VCS workflow as it does for the commands you use on your local repo. In your gitconfig file you can add alises for your favourite commands, in this article I&#8217;ll talk about mine. You can see my gitconfig on <a href="https://github.com/joejag/dotfiles/blob/master/git/gitconfig">github</a>.</p>
<h3>git standup</h3>
<p><em>alias for git log &ndash;&ndash;since yesterday &ndash;&ndash;author joe</em></p>
<p>Just about to head to a standup but you can&#8217;t remember everything that you did yesterday? This command will come to your rescue. It only lists what you did in the last 24 hours.</p>
<pre class="sh_sh sh_sourceCode">
3400455 - fixed the whizzbang (Mon, 1 Apr 2013 13:57:37 +0100) <Joe Wright>
5dae0a0 - whizzbang feature (Mon, 1 Apr 2013 13:57:32 +0100) <Joe Wright>
</pre>
<h3>git purr</h3>
<p><em>alias for git pull &ndash;&ndash;rebase</em></p>
<p>In Git you have public and private branches, public branches are the ones on github (or your own git host), private branches are in your local git repo and are setup to be tracking or topic. A tracking branch is linked to a public branch and a topic is only in your local git repo.</p>
<p>You have two options when you want to integrate changes between branches, either you <strong>merge</strong> or <strong>rebase</strong>. By default when you do a <strong>pull</strong> on a tracked branch it performs a <strong>fetch</strong> then a <strong>merge</strong>. If you&#8217;ve made changes locally and someone else has pushed changes to your git host then git will automatically merge these together with a merge commit.</p>
<pre class="sh_sh sh_sourceCode">
4ffe733 - Merge branch 'development' of github.com:YourCompany/project into master
</pre>
<p>On an active project with other colleagues using <strong>pull</strong> will generate a load of these noisy commits in your projects history. I only like merge commits to be in the history when a topic branch has been reintegrated. Tracking branches should have a linear history.</p>
<p>When you do a <strong>git pull &ndash;&ndash;rebase</strong>, git fetches the changes from your remote repo and then perform a rebase rather than the default merge. A rebase resets the HEAD of your local branch to be the same as the remote HEAD, then replays your local commits back into repo. This means you don&#8217;t get any noisy merge messages in your history. As well as giving a linear history, this also helps when using <strong>bisect</strong>.</p>
<h3>git st</h3>
<p><em>alias for git status -sb</em></p>
<p>Git gives a verbose output when you perform a <strong>status</strong> which is excellent when you are getting started with git. As you become used to the output you want a shorter version. The output of this alias shows a single letter that represents the change type and reports how far ahead of the remote branch you are.</p>
<pre class="sh_sh sh_sourceCode">
## master...origin/master [ahead 2]
A  g
D  gitignore
</pre>
<h3>git ready</h3>
<p><em>alias for git rebase -i @{u}</em></p>
<p>Once you&#8217;ve committed a few local changes you&#8217;ll want to share them with your team by pushing to your git host. Before I push I always run the <strong>git ready</strong> alias to see what&#8217;s going to be pushed so I can reword commit messages and squash related commits together. <strong>git ready</strong> performs an interactive rebase on your unpushed commits.</p>
<p>Let&#8217;s say I&#8217;ve pushed two commits that are related to a new feature and I have another where I made a spelling mistake in the commit message. When I run <strong>git ready</strong> I get dropped into vim with this input.</p>
<pre class="sh_sh sh_sourceCode">
pick 7f06d36 whizzbang feature - adding fizzbuzz
pick ad544d0 whizzbang feature - minor refactoring to fizzbuzz
pick de3083a spelling mizzztake
</pre>
<p>I want to squash the two whizzbang feature commits together. So I change <strong>pick</strong> to say <strong>s</strong> to squash the two together into a single commit. I also want to reword the commit with the spelling mistake. To do this I make the file look like:</p>
<pre class="sh_sh sh_sourceCode">
pick 7f06d36 whizzbang feature - adding fizzbuzz
s ad544d0 whizzbang feature - minor refactoring to fizzbuzz
r de3083a spelling mizzztake
</pre>
<p>This gives me two new commit messages to edit, which I update. Now when I push the remote repo host receives two commits</p>
<pre class="sh_sh sh_sourceCode">
3400455 - spelling mistake
5dae0a0 - whizzbang feature 
</pre>
<h3>git lg</h3>
<p><em>alias for git log &ndash;&ndash;pretty=format:&#8217;%Cred%h%Creset -%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset&#8217;</em></p>
<p>When I&#8217;m viewing history I just want to see the SHA, the commit message, who made the commit and how long ago. This custom log output gives me:</p>
<pre class="sh_sh sh_sourceCode">
3400455 - spelling mistake (20 minutes ago) <Joe Wright>
5dae0a0 - whizzbang feature (28 minutes ago) <Joe Wright>
efaea80 - Removing trailing space on save (4 days ago) <Another Guy>
c351700 - Copying to system clipboard in vim (5 days ago) <Joe Wright>
</pre>
<p>I&#8217;d be interested to hear about your favourite git aliases too.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.joejag.com/2013/everyday-git-aliases/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>An example driven guide to regular expressions</title>
		<link>http://code.joejag.com/2013/practical-regex/</link>
		<comments>http://code.joejag.com/2013/practical-regex/#comments</comments>
		<pubDate>Mon, 25 Mar 2013 15:42:38 +0000</pubDate>
		<dc:creator>Joe Wright</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://code.joejag.com/?p=897</guid>
		<description><![CDATA[The problem You have a string of text that needs to be checked to see if it fits a validation pattern or to extract information from it. In the case of validation you might want to know if a given input is a valid currency amount like £100, so you can prompt the user to [...]]]></description>
				<content:encoded><![CDATA[<h3>The problem</h3>
<p>You have a string of text that needs to be checked to see if it fits a validation pattern or to extract information from it. </p>
<p>In the case of validation you might want to know if a given input is a valid currency amount like £100, so you can prompt the user to enter a valid amount before you process a transaction.</p>
<p>For parsing you might want to get the version of a users web browser given from a User Agent string like these:</p>
<pre>
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0
</pre>
<p>To solve both problems we either need to either split the text and manually check for conditions in our code or we can use a regular expression.</p>
<h3>What is a regular expression?</h3>
<p>Regular expressions are a DSL which consist of two parts, a <strong>target string</strong> and the <strong>regular expression</strong> itself. The regular expression part is kind of like the patterns you use to search for files with wildcards. They look very scary at first but you only need to know a few rules to get the most out of them.</p>
<p>Given a target string of <em>&#8216;Mississippi&#8217;</em> and a regular expression of <strong>/s/</strong> we would get a match back as the target string contains at least one &#8216;s&#8217;. Though this is a quite simple example, usually they use a number of regular expression features like: <strong>/^d\w[uiop](in|vi)[^a-f]*$/</strong> which matches <em>&#8216;driving&#8217;</em>.</p>
<h3>How does it work?</h3>
<p>A regular expression is made up of <strong>literal characters</strong>, <strong>metacharacters</strong> and <strong>escape sequences</strong>. </p>
<p>A <strong>literal</strong> is like in the Mississippi example above, the <strong>/m/</strong> literally means this contains an &#8216;m&#8217; anywhere in the target string. </p>
<p>A <strong>metacharacter</strong> is used within a regular expression for special characters that don&#8217;t have a literal meaning, for example a caret sign indicates this regular expression must match from the start of the line. Meaning <strong>/^s/</strong> would no longer match Mississippi but <strong>/^m/</strong> would.</p>
<p>Finally, an <strong>escape sequence</strong> is used to convert a metacharacter into a literal for when the need arrises. For example the dollar sign &#8216;$&#8217; has a special meaning so to literally search for it we&#8217;d escape it by putting a slash at the front like <strong>/\$/</strong>. </p>
<h4>Capture groups</h4>
<p>The first metacharacter we&#8217;ll get to know properly is the capture group, as this is what allows you to extract a substring of text from a target string. </p>
<p>Let&#8217;s say we wanted to find the version of the IE web browser a visitor was using which has a target string of <em>&#8216;Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0&#8242;</em>. In here we are looking for the <em>&#8217;8.0&#8242;</em> following the MSIE. A simple way to achieve this would be to do <strong>/MSIE (8.0)/</strong></p>
<p><a href="http://rubular.com/r/yNFui6IklJ">See this in action</a></p>
<h4>Boolean &#8216;or&#8217;</h4>
<p>If you wanted to search for one string or an alternative. You could do this with a pipe sign allowing you to match two different versions of IE: <strong>/MSIE (8.0|9.0)/</strong></p>
<p><a href="http://rubular.com/r/yNFui6IklJ">See this in action</a></p>
<h4>Matching any single character</h4>
<p>Searching for just 8.0 or 9.0 is quite limiting though, so let&#8217;s use the dot &#8216;.&#8217; metacharcter to search for any version number with a length of three characters with <strong>/MSIE (&#8230;)/</strong></p>
<p><a href="http://rubular.com/r/I3SILqtd7P">See this in action</a></p>
<h4>Iteration metacharacters</h4>
<p>Matching on exactly three characters using the dot is working well for us here, but we know IE 10.0 is coming soon and many later versions after that. What we want is a variable amount of matching characters. To do this regular expressions allow us to put an iteration metacharacter right after a literal or other metacharacter to say how many times we&#8217;d like it to match.</p>
<p>Regular expressions give us curly brackets to do this. Say we expect exactly three occurrences of the previous pattern we could do: <strong>/MSIE (.{3})/</strong></p>
<p><a href="http://rubular.com/r/8wgZVpfry6">See this in action</a></p>
<p>The curly brackets also allow us to use a range to match a minimum or maximum amount using <strong>/MSIE (.{3,4});/</strong>. In this example we&#8217;ve added the literal semi-colon to indicate the end of the version in the target string.</p>
<p><a href="http://rubular.com/r/Kp6KJfi5TM">See this in action</a></p>
<p>In we wanted to future proof to even larger version numbers of IE we could leave the second value blank: <strong>/MSIE (.{3,});/</strong>.</p>
<p><a href="http://rubular.com/r/91WJ05oMJb">See this in action</a></p>
<p>The regular expression creators realised this is quite a common task, so they made metacharacters to support the common ranges:</p>
<ul>
<li>? : Zero or one {0,1}</li>
<li>+ : 1 or more {1,}</li>
<li>* : Zero or more {0,}</li>
</ul>
<p>The question mark is particularly useful when dealing with pluralization. So you could match a target string of &#8216;game&#8217; or &#8216;games&#8217; with <strong>/games?/</strong>.</p>
<p><a href="http://rubular.com/r/EmN0WWbkhc">See this in action</a></p>
<h4>Positioning</h4>
<p>We&#8217;ve been looking for regular expressions that occur anywhere within a string so far. When you want your expression to match an entire line you use the $ and ^ signs. ^ means from the start of the line and $ means from the end of the line. This prevents your expression matching characters you don&#8217;t want it to.</p>
<p>For example <strong>/^brown fox$/</strong> matches &#8216;brown fox&#8217; but not &#8216;brown fox jumps away&#8217;.</p>
<p><a href="http://rubular.com/r/SNItDaTIFR">See this in action</a></p>
<h4>Character classes</h4>
<p>Up to now we&#8217;ve searched for literal matches or used the dot wildcard. Sometimes you want to search for a string that matches a list of possibilites. Square brackets allow you to do this <strong>/[01234556789]/</strong>.</p>
<p><a href="http://rubular.com/r/pYrfgL5QM0">See this in action</a></p>
<p>Within a range the hypen, &#8216;-&#8217;, becomes a metacharacter that allows you to specify a range. So the previous example can become <strong>/[0-9]/</strong></p>
<p><a href="http://rubular.com/r/KE3uuhCpWD">See this in action</a></p>
<p>As well as numbers you can do the same with letters with <strong>/[A-Z]/</strong> for uppercase letters and <strong>/[a-z]/</strong> for lower case.</p>
<p><a href="http://rubular.com/r/sStpeDTk80">See this in action</a></p>
<p>These ranges can be combined to search for alpha numeric characters with <strong>/[A-Za-z0-9]+/</strong></p>
<p><a href="http://rubular.com/r/SRMtxCIypf">See this in action</a></p>
<p>Finally, you can invert the selection by placing a caret at the start of the range to search for the opposite <strong>/[^0-9]/</strong></p>
<p><a href="http://rubular.com/r/Hje64BNc3n">See this in action</a></p>
<h4>Shorthand character classes</h4>
<p>Just like with the range shorthands, the regular expression creators realised that character classes are a common occurance as well. To help with this they added some shorthand versions of popular tasks:</p>
<ul>
<li>\d : digits [0-9]
<li>\w : alpha numeric search for [0-9A-Za-z]
<li>\s : searches for spaces, tabs, and other whitespace
</ul>
<p>All of these letters can be made upper case to search for the opposite, just like the caret did previously with ranges. So <strong>\D</strong> means not a number.</p>
<h4>Capture groups extended</h4>
<p>If you don&#8217;t want to capture the contents of a group you can put a question mark and a colon at the start of the group. This is useful when you need to use groups but don&#8217;t care what their contents are. For example <strong>/the cost of the (?:grey|gray) sofa is £(\d+)/</strong> will handle the different spellings of the colour grey, but only capture the price.</p>
<p><a href="http://rubular.com/r/Gd6XMuWURl">See this in action</a></p>
<p>If you&#8217;d like to add text into the capture group to make it readable, called a <strong>named group</strong>, you can use angle brackets within the group. For example to extract a date naming each part you could use <strong>/(?&lt;month&gt;\d{1,2})\/(?&lt;day&gt;\d{1,2})\/(?&lt;year&gt;\d{4})/</strong> on the target string &#8216;Today&#8217;s date is: 10/23/2012&#8242; to get &#8216;month 10, day 23, year 2012&#8242;</p>
<p><a href="http://rubular.com/r/xfQHocREGj">See this in action</a></p>
<p>You can also reuse a capture group using <strong>\1</strong> to search for the same pattern again, this is called a <strong>backreference</strong>. For example with html tags you&#8217;d want to make sure that the closing tag matches exactly the same element name as the opening tag with <strong>/<(em|strong)>.*<\/(\1)>/</strong> which makes sure a &lt;/strong&gt; or &lt;/em&gt; matches it&#8217;s opening tag.</p>
<p><a href="http://rubular.com/r/uGYC5JJjhZ">See this in action</a></p>
<h4>/^d\w[uiop](in|vi)[^a-f]*$/</h4>
<p>Earlier on I said this regular expression can match the target string &#8216;driving&#8217;.</p>
<p><a href="http://rubular.com/r/Hc8vIdCC6T">See this in action</a></p>
<p>Let&#8217;s break down what&#8217;s happening here. We&#8217;ve got positional anchors with the ^ and $ that let us know the entire contents of the string are within the regular expression. Let&#8217;s remove them to give us: <strong>d\w[uiop](in|vi)[^a-f]*</strong></p>
<p>The first letter is a literal &#8216;d&#8217;. Followed by a single alphanumeric &#8216;\w&#8217;. Then we have a range of possible single characters [uiop], followed by a boolean or &#8216;(in|vi)&#8217; and finally a range between 0 or infinite characters that doesn&#8217;t contain any letters between a-f. One word which matches these conditions is &#8216;driving&#8217;.</p>
<p>If you come across such crazy regular expressions I&#8217;d encourage you to put them into <a href="http://www.regexper.com/">Regexper</a> which will explain them for you. For this expression Regexper gives us this diagram:</p>
<p><img src="http://code.joejag.com/wp-content/uploads/2013/03/driving_regex.png" alt="driving_regex" class="alignnone" /></p>
<p>Why would someone make this regular expression?</p>
<p>I&#8217;ve given you a crash course in what you need to know to solve most problems with regular expressions. Now see if you can put your knowledge to test by solving this <a href="http://mariolurig.com/crossword/">regular expression crossword puzzle</a>.</p>
<h4>Resources</h4>
<ul>
<li><a href="http://rubular.com/">Rubular</a> is a great testing tool for creating regex
<li>For converting a regular expression into a human readable form use <a href="http://www.regexper.com/">Regexper</a>
<ul>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://code.joejag.com/2013/practical-regex/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A compassionate approach to the Pycon incident</title>
		<link>http://code.joejag.com/2013/compassion-and-pycon/</link>
		<comments>http://code.joejag.com/2013/compassion-and-pycon/#comments</comments>
		<pubDate>Sun, 24 Mar 2013 00:22:05 +0000</pubDate>
		<dc:creator>Joe Wright</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://code.joejag.com/?p=888</guid>
		<description><![CDATA[You&#8217;ve no doubt heard about the recent incident at Pycon where Adria Richards attempted to correct the behaviour of some other participants of the conference by publicly shaming them. This resulted in a dire consequences for both sides with job losses and groups with agendas online battling against both sides. It&#8217;s a sad story for [...]]]></description>
				<content:encoded><![CDATA[<p>You&#8217;ve no doubt heard about the <a href="http://arstechnica.com/tech-policy/2013/03/how-dongle-jokes-got-two-people-fired-and-led-to-ddos-attacks/">recent incident at Pycon</a> where Adria Richards attempted to correct the behaviour of some other participants of the conference by publicly shaming them. This resulted in a dire consequences for both sides with job losses and groups with agendas online battling against both sides. It&#8217;s a sad story for everyone involved.</p>
<p>A <a href="http://subfictional.com/2013/03/22/bold-ideas-uttered-publicly/">few</a> <a href="http://www.forbes.com/sites/deannazandt/2013/03/22/why-asking-what-adria-richards-could-have-done-differently-is-the-wrong-question/">commentators</a> online have been saying the approach to how Adria reported this incident was <em>the only option available to be heard</em>. I find this depressing as it&#8217;s encouraging people to use fear of public shaming to change behaviour rather than through compassion.</p>
<p>When realising her feelings and needs weren&#8217;t met I wish someone in the same situation would&#8217;ve confronted the people responsible and said:</p>
<blockquote><p>
When I hear you making sexual innuendos about dongles and forking people, I feel incensed and disheartened because I need this community to be inclusive and considerate for myself and others like me. Would you be willing to stop making these type of jokes while at community events?
</p></blockquote>
<p>How would you react to someone requesting you change your behaviour in this way? I feel this makes an emotional connection that properly expresses the needs that aren&#8217;t being met by the requestor.</p>
<p>It&#8217;s making an appeal to the compassion of the people involved. It isn&#8217;t trying to coerce people through fear, guilt or shame. It&#8217;s letting other people know about specific behaviours that are hurting your feelings and needs, coupled with a request for change.</p>
<p><b>Update</b>: I would encourage people in this situation to blog / tweet / talk about their experience in this style so more people can hear about their needs that aren&#8217;t being met by community events.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.joejag.com/2013/compassion-and-pycon/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Agile is more about efficiency then effectiveness</title>
		<link>http://code.joejag.com/2013/agile-is-more-about-efficiency-than-effectiveness/</link>
		<comments>http://code.joejag.com/2013/agile-is-more-about-efficiency-than-effectiveness/#comments</comments>
		<pubDate>Sat, 16 Feb 2013 16:56:12 +0000</pubDate>
		<dc:creator>Joe Wright</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://code.joejag.com/?p=840</guid>
		<description><![CDATA[At Lean Agile Glasgow on Wednesday we were discussing a recent event in London where a bunch of agile luminaries got together to discuss &#8220;How to build the right thing&#8221;. The author of the article starts by saying (emphasis mine): Agile basically solved the problem of how to deliver software. Most any company that applies [...]]]></description>
				<content:encoded><![CDATA[<p>At <a href="https://twitter.com/LeanAgileGLA">Lean Agile Glasgow</a> on Wednesday we were discussing a recent event in London where a bunch of agile luminaries got together to discuss <a href="http://blog.crisp.se/2013/02/12/henrikkniberg/how-to-build-the-right-thing">&#8220;How to build the right thing&#8221;</a>.</p>
<p>The author of the article starts by saying (emphasis mine):</p>
<blockquote><p>
Agile basically <strong>solved the problem of how to deliver software</strong>. Most any company that applies an agile method and mindset can get working software out the door. Now, <b>the biggest waste in software development seems to be building the wrong product</b>, or the wrong features.<br />
<small>Henrik Kniberg</small>
</p></blockquote>
<p>I&#8217;m interpreting this as the author saying that we&#8217;ve figured out how to <em>efficiently</em> create software with agile, but we are still working out  how to <em>effectively</em> deliver it.</p>
<p>Reading over the headline statements on the agile manifesto and focusing on the items on the left you will have an efficient system for developing software. But are they focusing on effectiveness?</p>
<blockquote><p>Individuals and interactions over processes and tools</p></blockquote>
<p><em>Waste reduction by encouraging conversation over heavy process or tools</em></p>
<blockquote><p>Working software over comprehensive documentation</p></blockquote>
<p><em>Waste reduction by building something usable first</em></p>
<blockquote><p>Customer collaboration over contract negotiation</p></blockquote>
<p><em>More effectiveness focused than the others here, though also the least adhered too</em></p>
<blockquote><p>Responding to change over following a plan</p></blockquote>
<p><em>Waste reduction by removing detailed future plans that&#8217;ll be wrong or unwanted</em></p>
<p>Seeing three out of four items as efficiency focused is what leads me to think that agile is more about efficiently than effectiveness. The hope is that by being more effiecient you get more time building valuable and effective software, rather than just doing the wrong thing righter. The area of building the right thing is where we should now focus our efforts.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.joejag.com/2013/agile-is-more-about-efficiency-than-effectiveness/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Host a static web site on Dropbox for free</title>
		<link>http://code.joejag.com/2013/host-a-static-web-site-on-dropbox-for-free/</link>
		<comments>http://code.joejag.com/2013/host-a-static-web-site-on-dropbox-for-free/#comments</comments>
		<pubDate>Sun, 27 Jan 2013 12:18:14 +0000</pubDate>
		<dc:creator>Joe Wright</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://code.joejag.com/?p=826</guid>
		<description><![CDATA[While at a local CoderDojo helping kids age 10-18 learn to program, I was asked how they could upload their work onto the Internet to show their parents. In this case it was html pages with css and images. Assuming you already have a Dropbox account: Make a folder under your Public folder on Dropbox [...]]]></description>
				<content:encoded><![CDATA[<p>While at a local <a href="http://coderdojo.com/">CoderDojo</a> helping kids age 10-18 learn to program, I was asked how they could upload their work onto the Internet to show their parents. In this case it was html pages with css and images.</p>
<p>Assuming you already have a <a href="https://www.dropbox.com/home">Dropbox</a> account:</p>
<ol>
<li>Make a folder under your Public folder on Dropbox</li>
<li>Copy your web site files there</li>
<li>Log in to your Dropbox account online, navigate to the folder under Public</li>
<li>Find your starting html page (probably index.htm) in the Dropbox UI</li>
<li>Right click on the file and select &#8220;Copy Public Link&#8221;</li>
<li>Check out the link, share it with your friends</li>
</ol>
<p>Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://code.joejag.com/2013/host-a-static-web-site-on-dropbox-for-free/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speaking at Lean Agile Scotland 2012</title>
		<link>http://code.joejag.com/2012/speaking-at-lean-agile-scotland-2012/</link>
		<comments>http://code.joejag.com/2012/speaking-at-lean-agile-scotland-2012/#comments</comments>
		<pubDate>Wed, 29 Aug 2012 21:40:26 +0000</pubDate>
		<dc:creator>Joe Wright</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://code.joejag.com/?p=809</guid>
		<description><![CDATA[Hello dear readers, I&#8217;m delighted to say that I will be speaking at the inaugural Lean Agile Scotland conference in September. I&#8217;ll be evangelising about Continuous Delivery to the best and brightest in the industry and I would encourage you to get a ticket while they are available. If you send me a mail/tweet I&#8217;ll [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.leanagilescotland.com/" target="_blank"><img src="http://goo.gl/CIqJb"></a></p>
<p>Hello dear readers,</p>
<p>I&#8217;m delighted to say that I will be speaking at the inaugural <a href="http://www.leanagilescotland.com/">Lean Agile Scotland</a> conference in September. I&#8217;ll be evangelising about <a href="http://en.wikipedia.org/wiki/Continuous_delivery">Continuous Delivery</a> to the best and brightest in the industry and I would encourage you to get a ticket while they are available.</p>
<p>If you send me a mail/tweet I&#8217;ll send you a 10% discount code I have to further entice you.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.joejag.com/2012/speaking-at-lean-agile-scotland-2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to send a raw HTTP request via Java</title>
		<link>http://code.joejag.com/2012/how-to-send-a-raw-http-request-via-java/</link>
		<comments>http://code.joejag.com/2012/how-to-send-a-raw-http-request-via-java/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 22:06:32 +0000</pubDate>
		<dc:creator>Joe Wright</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://code.joejag.com/?p=702</guid>
		<description><![CDATA[While trying to figure out how a service worked I recently had to put together a Java class that let you easily replay a http conversation which had been sniffed. I got bored of using telnet while making small changes to the payload and curl wants requests converted into an XML format it appears. This [...]]]></description>
				<content:encoded><![CDATA[<p>While trying to figure out how a service worked I recently had to put together a Java class that let you easily replay a http conversation which had been sniffed.</p>
<p>I got bored of using telnet while making small changes to the payload and curl wants requests converted into an XML format it appears.</p>
<p>This simple socket based class lets you send a captured http request to a service.  I&#8217;ve removed the exception handling for brevity.</p>
<pre class="sh_java sh_sourceCode">
import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class Client {

    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(args[0], 80);

        BufferedWriter out = new BufferedWriter(
                new OutputStreamWriter(socket.getOutputStream(), "UTF8"));
        BufferedReader in = new BufferedReader(
                new InputStreamReader(socket.getInputStream()));

        sendMessage(out, new File(args[1]));
        readResponse(in);

        out.close();
        in.close();
    }

    private static void sendMessage(BufferedWriter out, File request) throws IOException {
        System.out.println(" * Request");

        for (String line : getContents(request)) {
            System.out.println(line);
            out.write(line + "\r\n");
        }

        out.write("\r\n");
        out.flush();
    }

    private static void readResponse(BufferedReader in) throws IOException {
        System.out.println("\n * Response");

        String line;
        while ((line = in.readLine()) != null) {
            System.out.println(line);
        }
    }

    private static List<String> getContents(File file) throws IOException {
        List<String> contents = new ArrayList<String>();

        BufferedReader input = new BufferedReader(new FileReader(file));
        String line;
        while ((line = input.readLine()) != null) {
            contents.add(line);
        }
        input.close();

        return contents;
    }
}
</pre>
<p>For example.  Running this class with the parameters: &#8220;google.co.uk /path/to/stored/file&#8221; with the stored file being just:</p>
<pre class="sh_sh sh_sourceCode">
GET /intl/en/policies/privacy/ HTTP/1.1
</pre>
<p>Will give you this output:</p>
<pre class="sh_sh sh_sourceCode">
 * Sending
GET /intl/en/policies/privacy/ HTTP/1.1

 * Response
HTTP/1.1 200 OK
Vary: Accept-Encoding
Content-Type: text/html
Last-Modified: Fri, 27 Jan 2012 17:53:03 GMT
Date: Tue, 07 Feb 2012 21:40:30 GMT
Expires: Tue, 07 Feb 2012 21:40:30 GMT
Cache-Control: private, max-age=0
X-Content-Type-Options: nosniff
Server: sffe
X-XSS-Protection: 1; mode=block
Transfer-Encoding: chunked

// Body content of web page
<!DOCTYPE html>
</pre>
<p>For capturing payloads I recommend using <a href="http://afflib.org/software/tcpflow">tcpflow</a> running on the target host as &#8220;tcpflow port 80&#8243;</p>
]]></content:encoded>
			<wfw:commentRss>http://code.joejag.com/2012/how-to-send-a-raw-http-request-via-java/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Checking JMX with JRuby</title>
		<link>http://code.joejag.com/2011/checking-jmx-with-jruby/</link>
		<comments>http://code.joejag.com/2011/checking-jmx-with-jruby/#comments</comments>
		<pubDate>Tue, 01 Nov 2011 11:02:33 +0000</pubDate>
		<dc:creator>Joe Wright</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://code.joejag.com/?p=669</guid>
		<description><![CDATA[I&#8217;ve recently been playing around with JRuby and found the switch from MRI to be hassle free. One of the advantages of JRuby is it&#8217;s portability. You can use nearly all Ruby code straight away on the JVM without having to do any code changes, you just include the jruby jar in your classpath. Another [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve recently been playing around with <a href="http://jruby.org/">JRuby</a> and found the switch from MRI to be hassle free.  One of the advantages of JRuby is it&#8217;s portability.  You can use nearly all Ruby code straight away on the JVM without having to do any code changes, you just include the jruby jar in your classpath.</p>
<p>Another advantage is Java interoperability from JRuby (just <i>require &#8216;java&#8217;</i>).  I&#8217;ve found this useful when using JMX to check certain conditions are in place while performing releases and for general monitoring.  </p>
<p>The following script uses JRuby&#8217;s Java integration to walk a given ObjectName&#8217;s attributes within JMX.</p>
<pre class="sh_ruby">
require 'java'

# Return a JMX Connection
def connect_to_jmx service_url, credentials
	jmxUrl = javax.management.remote.JMXServiceURL.new(service_url)

	environment = java.util.HashMap.new
	environment.put(javax.management.remote.JMXConnector.CREDENTIALS, 
                              credentials.to_java(:string))

	jmxCon = javax.management.remote.JMXConnectorFactory.connect(jmxUrl, 
                                                                                              environment)
	return jmxCon.getMBeanServerConnection
end

# Walk the JMX tree and return the attributes.  Optionally limit to a single ObjectName
def walk_tree jmx_connection, limited_to=''
	names = jmx_connection.queryNames(
                                           javax.management.ObjectName.new(limited_to), nil)

	cached = Hash.new([])

	names.each do |name|
	   info = jmx_connection.getMBeanInfo(name)
	   info.getAttributes.each do | mbi|
		   attr = jmx_connection.getAttribute(name, mbi.getName)
		   cached.store(name.getCanonicalName, 
                          cached[name.getCanonicalName] << { mbi.getName  => attr })
	   end     
	end
	
	return cached
end

service_url = 'host:port'
credentials = ['username', 'password']
jmx_connection = connect_to_jmx(service_url, credentials)

results = walk_tree(jmx_connection, 'java.lang:type=OperatingSystem')

results.each do | key, attributes |
  puts ' * ' + key
  attributes.each do | attr |
	puts " ** #{attr.first[0]} :: #{attr.first[1]}"
  end
  puts
end
</pre>
<p>When invoked against a running JMX instance this will return something similar to:</p>
<pre class="sh_sh sh_sourceCode"> 
> jruby jmx_walker.rb
 * java.lang:type=OperatingSystem
 ** FreePhysicalMemorySize :: 51955511296
 ** TotalPhysicalMemorySize :: 151873998848
 ** Name :: Linux
 ** Arch :: amd64
 ** Version :: 2.6.18-194.11.4.el5
 ** AvailableProcessors :: 24
 ** SystemLoadAverage :: 0.49
</pre>
<p>Hopefully this is of use to you, or inspires you to investigate JRuby a bit further.  I&#8217;d highly recommend it for Java shops who want to take advantage of Ruby&#8217;s scripting ability.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.joejag.com/2011/checking-jmx-with-jruby/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A DSL for collections in Java</title>
		<link>http://code.joejag.com/2011/a-dsl-for-collections-in-java/</link>
		<comments>http://code.joejag.com/2011/a-dsl-for-collections-in-java/#comments</comments>
		<pubDate>Fri, 04 Mar 2011 15:50:24 +0000</pubDate>
		<dc:creator>Joe Wright</dc:creator>
				<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://code.joejag.com/?p=541</guid>
		<description><![CDATA[When writing Java code I often find it laborious to create collections using the java.util.* collection classes. To avoid this, I&#8217;ve been using a mini-DSL to reduce my collections code. import static com.joejag.common.collections.Dsl.*; // A list List list = list("abc", "def"); // A set Set set = set("Sleepy", "Sneezy", "Dozy"); // A Map Map map [...]]]></description>
				<content:encoded><![CDATA[<p>When writing Java code I often find it laborious to create collections using the <i>java.util.*</i> collection classes.  To avoid this, I&#8217;ve been using a mini-DSL to reduce my collections code.</p>
<pre class="sh_java sh_sourceCode">
import static com.joejag.common.collections.Dsl.*;

// A list
List<String> list = list("abc", "def");
      
// A set
Set<String> set = set("Sleepy", "Sneezy", "Dozy");
      
// A Map
Map<String, Integer> map = map(entry("Joe", 28), entry("Gerry", 39));
</pre>
<p>Here is the underlying code.</p>
<pre class="sh_java sh_sourceCode">
package com.joejag.common.collections;


import java.util.*;

public class Dsl {
    public static &lt;T&gt; List&lt;T&gt; list(T... args) {
        return Arrays.asList(args);
    }

    public static &lt;T&gt; Set&lt;T&gt; set(T... args) {
        Set&lt;T&gt; result = new HashSet&lt;T&gt;(args.length);
        result.addAll(Arrays.asList(args));
        return result;
    }

    public static &lt;K, V&gt; Map&lt;K, V&gt; map(Entry&lt;? extends K, ? extends V&gt;... entries) {
        Map&lt;K, V&gt; result = new HashMap&lt;K, V&gt;(entries.length);

        for (Entry&lt;? extends K, ? extends V&gt; entry : entries)
            if (entry.value != null)
                result.put(entry.key, entry.value);

        return result;
    }

    public static &lt;K, V&gt; Entry&lt;K, V&gt; entry(K key, V value) {
        return new Entry&lt;K, V&gt;(key, value);
    }

    public static class Entry&lt;K, V&gt; {
        K key;
        V value;

        public Entry(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }

    public static void main(String args[]) {
        List&lt;String&gt; list = list(&quot;abc&quot;, &quot;def&quot;);
        System.out.println(list);

        Set&lt;String&gt; set = set(&quot;Sleepy&quot;, &quot;Sneezy&quot;, &quot;Dozy&quot;);
        System.out.println(set);

        Map&lt;String, Integer&gt; map = map(entry(&quot;Joe&quot;, 28), entry(&quot;Gerry&quot;, 39));
        System.out.println(map);
    }
}
</pre>
<p>I&#8217;ve noticed that the Google Collections project has morphed into <a href="http://code.google.com/p/guava-libraries/">Guava</a> which has great reusable code for collections and a lot of other common Java tasks.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.joejag.com/2011/a-dsl-for-collections-in-java/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
