<?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>puremango.co.uk</title>
	<atom:link href="http://www.puremango.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.puremango.co.uk</link>
	<description>innovative coding, tutorials, web stuff.</description>
	<lastBuildDate>Wed, 17 Feb 2010 17:28:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Break out of infinite alert() popups!</title>
		<link>http://www.puremango.co.uk/2010/02/break-out-of-infinite-alert-popups/</link>
		<comments>http://www.puremango.co.uk/2010/02/break-out-of-infinite-alert-popups/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 08:55:45 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[Firefox]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[alert]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[firebug]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=759</guid>
		<description><![CDATA[How many times have you been developing in javascript and said &#8220;I&#8217;ll just pop it in an alert&#8221;, alt-tab, refresh and then the sudden sinking feeling as you realise that you&#8217;re about to get 300 alert popups?
Damn! Now you have to sit there and press OK a bajillion times, or restart the browser &#8211; which [...]]]></description>
			<content:encoded><![CDATA[<p>How many times have you been developing in javascript and said &#8220;I&#8217;ll just pop it in an alert&#8221;, alt-tab, refresh and then the sudden sinking feeling as you realise that you&#8217;re about to get 300 alert popups?</p>
<p>Damn! Now you have to sit there and press OK a bajillion times, or restart the browser &#8211; which is a pain because you&#8217;ll lose all your tabs, and more importantly you&#8217;ll lose your concentration while you load everything up again.</p>
<p>We&#8217;ve all been there. But recently I found a neat little trick to break out of infinite javascript alert loops in firefox:</p>
<p><span id="more-759"></span>Of course in Chrome it&#8217;s easy, there&#8217;s a tickbox on the alert popup! (and I hope other browsers follow suit)</p>
<p><img class="aligncenter" title="Chrome Rocks" src="http://www.puremango.co.uk/firefox_alerts/chrome_rocks.png" alt="" width="362" height="149" /></p>
<p>But in firefox sadly we have no such luxury:</p>
<p><img class="aligncenter" title="Firefox Alerts" src="http://www.puremango.co.uk/firefox_alerts/firefox_alerts.png" alt="" width="365" height="138" /></p>
<p>So how do you get rid of alert popups in firefox?</p>
<ol style="margin-left: 30px;">
<li><strong>Hold Ctrl</strong></li>
<li><strong>Hold Enter</strong></li>
<li><strong>Press F4 once</strong></li>
</ol>
<p>That&#8217;s it &#8211; the tab will close, you&#8217;ll get one final alert and then you&#8217;ll be free!</p>
<h3 style="text-align: center;"><a href="http://www.puremango.co.uk/firefox_alerts/infinite.html" target="_blank"><strong>Try it out here (in a new tab)</strong></a></h3>
<p><span style="color: white;">spacer</span></p>
<p>Doesn&#8217;t work in MSIE, sadly. Although it did work in <a href="http://www.my-debugbar.com/wiki/IETester/HomePage" target="_blank">IETester</a> when I tried it there. Also I have reports of it not working in firefox under linux or mac.</p>
<p>Of course, the *real* solution is to use console.log(); and <a href="http://getfirebug.com/">firebug </a>instead &#8211; they say if you play with fire you&#8217;ll get burned but in this case fire(bug) can really save your ass.</p>
<p>Repeat after me:</p>
<blockquote>
<p style="padding-left: 30px;"><strong><em>console.log is safer than alert because it doesn&#8217;t lock up the whole browser. I will use console.log instead of alert for debugging in the future. I will now link to puremango.co.uk</em></strong></p>
</blockquote>
<p>Hey thanks for the link, man ;)</p>
<p>For those of you who&#8217;ve never used console.log, you&#8217;re in for a real treat. Compare the difference on an onclick event between alert (which simply calls .toString() on its arguments) and console.log (which dumps the actual object itself):</p>
<p>alert(window.event);</p>
<p><img class="aligncenter" title="Using Alert" src="http://www.puremango.co.uk/firefox_alerts/alert_log.png" alt="" width="400" height="163" />console.log(window.event);</p>
<p><img class="aligncenter" title="Console.log" src="http://www.puremango.co.uk/firefox_alerts/console1.png" alt="" width="269" height="120" />Now that&#8217;s more useful to start with. But we can even click that logged text and it jumps to a tree view of the entire object:</p>
<p><img class="aligncenter" title="Firebug is really nice" src="http://www.puremango.co.uk/firefox_alerts/console2.png" alt="" width="657" height="437" /></p>
<p>I certainly know which I&#8217;d rather be using!</p>
<p>Finally, an additional benefit is that console.log won&#8217;t lock up the GUI; so if you do have your debug call inside a big loop it&#8217;ll merrily log them all; meaning you can close the tab if it&#8217;s infinite, or just wait for the loop to finish if it&#8217;s merely big.</p>
<p>You will however need to have the firebug window open, otherwise your script won&#8217;t execute. And that&#8217;s why we all sometimes resort to the tried and true alert(); method of debugging. And next time your heart sinks because you forgot that your loop has hundreds of iterations, remember the magic incantation: <strong>Ctrl, Enter, F4</strong>.</p>
<p>And happy debugging :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/02/break-out-of-infinite-alert-popups/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>allRGB Entry &#8211; PHP Image Manipulation</title>
		<link>http://www.puremango.co.uk/2010/02/allrgb-entry-php-image-manipulation/</link>
		<comments>http://www.puremango.co.uk/2010/02/allrgb-entry-php-image-manipulation/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 08:38:44 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[allrgb]]></category>
		<category><![CDATA[colours]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[imagecreate]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[phpdemoscene]]></category>
		<category><![CDATA[rgb]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=773</guid>
		<description><![CDATA[The objective of allRGB is simple: To create images with one pixel for every rgb-color (16777216 to be exact); not one color missing, and not one color twice.
What a cool project! As regular readers will know, I love messing about with image manipulation in PHP, so when I heard about the allRGB project I knew [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>The objective of <a href="http://allrgb.com/" target="_blank">allRGB</a> is simple: To create images with one pixel for every <abbr>rgb</abbr>-color (16777216 to be exact); not one color missing, and not one color twice.</p></blockquote>
<p>What a cool project! As regular readers will know, I love messing about with <a href="http://www.puremango.co.uk/tag/imagecreate/" target="_self">image manipulation in PHP</a>, so when I heard about the allRGB project I knew I had to make an entry for it. A few false starts and about half an hour later, I proudly submitted my first entry, a 4096&#215;4096 PNG image containing every single possible RGB colour. As one redditor put it, &#8220;It&#8217;s like poetry, just without words.&#8221;</p>
<p><center><a href="http://www.puremango.co.uk/allrgb/one.png" target="_blank"><img title="All possible colours" src="http://www.puremango.co.uk/allrgb/sm_one.jpg" alt="" width="400" height="400" /></center></a></p>
<p style="text-align: center;"><a href="http://www.puremango.co.uk/allrgb/one.png" target="_blank"><em>Click for the high resolution (only 173Kb)</em></a></p>
<p>And now on to the code:<br />
<span id="more-773"></span><br />
The authors of the allRGB project state that;</p>
<blockquote><p>The most obvious example is a series of 16 by 16 squares, each of which consists of a gradient.</p></blockquote>
<p>But to me the most obvious approach was to simply loop over red (0-255), green (0-255) and blue (0-255) adding a pixel for each colour; as the PHP code below illustrates:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?</span>
&nbsp;
<span style="color: #000088;">$w</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">4096</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$h</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">4096</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$x</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$y</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$im</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ImageCreateTrueColor</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$w</span><span style="color: #339933;">,</span> <span style="color: #000088;">$h</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$r</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$r</span><span style="color: #339933;">&lt;=</span><span style="color: #cc66cc;">255</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$r</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$g</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$g</span><span style="color: #339933;">&lt;=</span><span style="color: #cc66cc;">255</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$g</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$b</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$b</span><span style="color: #339933;">&lt;=</span><span style="color: #cc66cc;">255</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$b</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$col</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ImageColorAllocate</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$im</span><span style="color: #339933;">,</span><span style="color: #000088;">$r</span><span style="color: #339933;">,</span><span style="color: #000088;">$g</span><span style="color: #339933;">,</span><span style="color: #000088;">$b</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #990000;">ImageSetPixel</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$im</span><span style="color: #339933;">,</span> <span style="color: #000088;">$x</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">,</span> <span style="color: #000088;">$col</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$x</span><span style="color: #339933;">&lt;</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$w</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000088;">$x</span><span style="color: #339933;">++;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000088;">$x</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
				<span style="color: #000088;">$y</span><span style="color: #339933;">++;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Content-type: image/png&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">ImagePng</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$im</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">ImageDestroy</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$im</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>You&#8217;ll need to up max_execution_time and memory_limit, but it&#8217;s not as hungry as you might imagine; under a minute of processing time on my meager home server.</p>
<p>My entry, which I&#8217;ve imaginatively entitled &#8220;Grid One&#8221;, is still undergoing review with the folks at allRGB, but I hope to be listed in their hall of fame shortly (<a href="http://allrgb.com/grid-one">now listed</a>) :0) It&#8217;s similar to the existing &#8220;<a href="http://allrgb.com/suave">suave</a>&#8221; and &#8220;<a href="http://allrgb.com/tvlines">tvlines</a>&#8221; entries.</p>
<p>And for my next trick? I&#8217;m working on a script to convert any arbitrary image into an allRGB entry. But loops with 16 million iterations need to be carefully optimised. It&#8217;s a fun challenge, especially in PHP.</p>
<p><strong>Update</strong>: Many thanks to Alexander for pointing out that my first attempt didn&#8217;t actually contain all the colours (*blush*) &#8211; code and images updated now :D</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/02/allrgb-entry-php-image-manipulation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Textpad PHP manual lookup tool</title>
		<link>http://www.puremango.co.uk/2010/02/textpad-php-manual-lookup-tool/</link>
		<comments>http://www.puremango.co.uk/2010/02/textpad-php-manual-lookup-tool/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 19:11:40 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=743</guid>
		<description><![CDATA[A little tip for those of us using textpad to develop in PHP. How often do you find yourself having to go back to PHP.net to check up on a function &#8211; is it ($needle, $haystack) or ($haystack, $needle)? I can never remember! With this tool I just need to highlight the function in textpad, [...]]]></description>
			<content:encoded><![CDATA[<p>A little tip for those of us using <a href="http://www.textpad.com">textpad</a> to develop in PHP. How often do you find yourself having to go back to PHP.net to check up on a function &#8211; is it ($needle, $haystack) or ($haystack, $needle)? I can never remember! With this tool I just need to highlight the function in textpad, press Ctrl-1 and up pops php.net in a new tab, opened on that function&#8217;s manual entry. Neat huh?</p>
<p>Here&#8217;s how:</p>
<p><span id="more-743"></span><strong>1) Go to Configure-&gt;Preferences-&gt;Tools-&gt;Add-&gt;DOS Command:</strong></p>
<p><img class="aligncenter" title="Textpad Tools Menu" src="http://www.puremango.co.uk/images/textpad_tool1.png" alt="" width="632" height="372" /></p>
<p><strong>2) Then enter the following in the popup dialog:</strong></p>
<h3 style="padding-left: 30px;"><strong>start http://php.net/manual-lookup.php?pattern=$Sel</strong></h3>
<p><strong> </strong></p>
<p><strong>3) Then </strong><strong>in the tool&#8217;s preferences, </strong><strong>untick &#8220;Capture Output&#8221; and tick &#8220;Close DOS window on exit&#8221;:</strong></p>
<p><img class="aligncenter" title="Textpad Tools Options" src="http://www.puremango.co.uk/images/textpad_tool2.png" alt="" width="632" height="372" /></p>
<p>Now any time you want to lookup a function in your code, simply highlight or double-click it and press Ctrl-1 to be taken to that function&#8217;s manual page on PHP.net, in a new tab in your default web browser.</p>
<p>While we&#8217;re on the topic of textpad tweaks, did you know you can jump to the matching brace by pressing Ctrl-M? Very handy for spaghetti code. Share your textpad PHP IDE tips below! And if you haven&#8217;t already, why not take this opportunity to, you know, actually buy textpad after all this time? &lt;grin&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/02/textpad-php-manual-lookup-tool/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The K-Means Clustering Machine Learning Algorithm</title>
		<link>http://www.puremango.co.uk/2010/01/k-means-clustering-machine-learning/</link>
		<comments>http://www.puremango.co.uk/2010/01/k-means-clustering-machine-learning/#comments</comments>
		<pubDate>Sun, 24 Jan 2010 20:28:13 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[machine learning]]></category>
		<category><![CDATA[clustering]]></category>
		<category><![CDATA[k-means]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[unsupervised learning]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=714</guid>
		<description><![CDATA[The k-means clustering algorithm is one of the simplest unsupervised machine learning algorithms, which can be used to automatically recognise groups of similar points in data without any human intervention or training.
The first step is to represent the data you want to group as points in an n-dimensional space, where n is the number of [...]]]></description>
			<content:encoded><![CDATA[<p>The k-means clustering algorithm is one of the simplest unsupervised machine learning algorithms, which can be used to automatically recognise groups of similar points in data without any human intervention or training.</p>
<p>The first step is to represent the data you want to group as points in an n-dimensional space, where n is the number of attributes the data have. For simplicity let&#8217;s assume we just want to group the ages of visitors to a website &#8211; a one-dimensional space. Let&#8217;s assume the set of ages is as follows:</p>
<p style="padding-left: 30px;"><em>{15,15,16,19,19,20,20,21,22,28,35,40,41,42,43,44,60,61,65}</em></p>
<p>Now there are a number of ways we could separate these points out; one obvious way that springs to mind is simply to iterate over the set and find the largest gap between adjacent ages. For some sets this can work quite nicely, but in our case it would give us quite unbalanced groups; 15-44 and 60-65, the latter containing just 3 points, and the former being far too broadly distributed.</p>
<p>Using k-means clustering we can obtain more tightly defined groups; consider the set {1,2,3,5,6,9} &#8211; using the simplistic greatest distance technique we gain two sets {1,2,3,5,6} and {9}, while the k-means algorithm produces a grouping of {1,2,3} and {5,6,9} &#8211; more cohesive clusters with less dispersion of points inside the groups &#8211; k-means tries to minimise the sum of squares within a cluster:</p>
<p><img class="aligncenter" title="Splitting Data" src="http://www.puremango.co.uk/images/splits.png" alt="" width="164" height="87" /></p>
<p>Notice how in the first set of clusters the outermost points of the first cluster are quite far away from the middle of the cluster, while in the second set, the points in both clusters are closer the center of their groups; making these clusters more well-defined, less sparsely populated.</p>
<p>Now let&#8217;s have a look at the algorithm and work through the example age data to see if we can get a tighter grouping than 15-44 and 60-65 using clustering:</p>
<p><span id="more-714"></span><strong>The algorithm:</strong></p>
<p>Firstly we pick <em>k</em> random points in the space as initial cluster co-ordinates, where <em>k</em>=the number of clusters you wish to obtain.</p>
<p>Then for each cluster, we work out the average value for that cluster, known as the centroid of the cluster.</p>
<p>Then we iterate over all the points, including those already assigned to clusters, and we assign each point to the cluster with the closest centroid.</p>
<p>We then repeat the process of finding the centroids and assigning points until there is no change between iterations.</p>
<p><strong>Example:</strong></p>
<p>Let&#8217;s say we want two clusters, and initially set cluster one = 16 and cluster two=22. In full, the process of clustering our example data looks like this:</p>
<p style="padding-left: 30px;">Initial Clusters:<br />
centroid 16    [16]<br />
centroid 22    [22]</p>
<p>Now assign all points closer to 16 than 22 to cluster one:</p>
<p style="padding-left: 30px;">Iteration 1 clusters:<br />
centroid 15.33    [15,15,16]<br />
centroid 36.25    [19,19,20,20,21,22,28,35,40,41,42,43,44,60,61,65]</p>
<p>Now assign all points closer to 15.33 than 36.25 to cluster one:</p>
<p style="padding-left: 30px;">Iteration 2 clusters:<br />
centroid 18.56    [15,15,16,19,19,20,20,21,22]<br />
centroid 45.90    [28,35,40,41,42,43,44,60,61,65]</p>
<p>Now assign all points closer to 18.56 than 45.90 to cluster one:</p>
<p style="padding-left: 30px;">Iteration 3 clusters:<br />
centroid 19.50    [15,15,16,19,19,20,20,21,22,28]<br />
centroid 47.89    [35,40,41,42,43,44,60,61,65]</p>
<p>Now assign all points closer to 19.50 than 47.89 to cluster one:</p>
<p style="padding-left: 30px;">Iteration 4 clusters:<br />
centroid 19.50    [15,15,16,19,19,20,20,21,22,28]<br />
centroid 47.89    [35,40,41,42,43,44,60,61,65]</p>
<p>No change between iterations; this is known as convergence and means we can stop running the algorithm. Using clustering, we have gained 15-28 and 35-65, which are much more closely grouped clusters than 15-44 and 60-65.</p>
<p>The initial choice of centroids can affect the output clusters, so the algorithm is often run multiple times with different starting conditions in order to get a fair view of what the clusters should be.</p>
<p>In a multi-dimensional space, we define distance as the Euclidean distance, e.g. if we imagine a 3-d space (your office or bedroom) and two points in it (the light switch and the light bulb), then the distance between the two is simply the shortest straight line between the points. The <a href="http://en.wikipedia.org/wiki/Euclidean_distance" target="_blank">Euclidean distance</a> gives us this measure.</p>
<p>Next time, I&#8217;ll present PHP and javascript implementations of the k-means clustering algorithm for n dimensions so you can see how it works in the code, and have a chance to use clustering in your own applications. Any questions or comments? Chat below!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2010/01/k-means-clustering-machine-learning/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Top 2009 Facebook Status Trends</title>
		<link>http://www.puremango.co.uk/2009/12/2009-facebook-status-trends/</link>
		<comments>http://www.puremango.co.uk/2009/12/2009-facebook-status-trends/#comments</comments>
		<pubDate>Tue, 22 Dec 2009 16:14:29 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[status]]></category>
		<category><![CDATA[trend]]></category>
		<category><![CDATA[zeitgeist]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=682</guid>
		<description><![CDATA[As google release their annual zeitgeist, and many other sites prepare interesting stats on web usage, facebook have today done the same and released an fascinating insight into the top facebook status update topics of 2009:


While they have obviously post-processed the data quite a lot (just as everyone else does), it&#8217;s not clear just how [...]]]></description>
			<content:encoded><![CDATA[<p>As google release their annual <a href="http://www.google.com/intl/en/press/zeitgeist2009/">zeitgeist</a>, and many other sites prepare interesting stats on web usage, facebook have today done the same and released an fascinating insight into the top facebook status update topics of 2009:</p>
<p><img src="http://www.puremango.co.uk/images/fb_status_trends.jpg" alt="Facebook Status Trends" title="Facebook Status Trends" /><br />
<span id="more-682"></span><br />
While they have obviously post-processed the data quite a lot (just as everyone else does), it&#8217;s not clear just how useful this data is; they&#8217;ve separated &#8220;movies&#8221; and &#8220;sports&#8221; into their own categories, but &#8220;Lady Gaga&#8221; gets a whole slot to herself &#8211; why not &#8220;music&#8221; I wonder?</p>
<p>&#8220;Years&#8221; really should be called &#8220;Dates&#8221;, and &#8220;Yard&#8221; &#8211; well, although their blog post claims that yard is incredibly popular due to the &#8220;moms and dads&#8221; of the &#8220;hipsters&#8221; who are tending their yards, a cynic might suggest that facebook is trying to make themselves look more appealing to the more mature adult population who will be happy to spend their cash in a facebook appstore which I have no doubt is on the horizon for FB.</p>
<p>As normal for these yearly glances we are afforded into the inner workings on the biggest sites on the net, the information is fascinating, but ultimately unfulfilling. Here&#8217;s hoping that next year we get a hundred gigabyte download of the top statuses (suitably anonymised of course)!</p>
<p>Read the <a href="http://blog.facebook.com/blog.php?post=215076352130">facebook blog posting</a> for the full details.</p>
<p>via <a href="http://www.techcrunch.com/2009/12/21/facebook-status-trends-2009/">Techcrunch</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2009/12/2009-facebook-status-trends/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Facebook Chat Smilies</title>
		<link>http://www.puremango.co.uk/2009/12/facebook-chat-smilies/</link>
		<comments>http://www.puremango.co.uk/2009/12/facebook-chat-smilies/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 21:46:33 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[chat]]></category>
		<category><![CDATA[emote]]></category>
		<category><![CDATA[emoticon]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[smiley]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=669</guid>
		<description><![CDATA[After the runaway success of my facebook chat history video (45k views, 100 ratings on youtube) I thought I&#8217;d follow up with a video explaining all the chat emotes you can use in facebook. There are some cool emoticons there.


Facebook Chat Smilies
This list includes the facebook robot, the new shark smiley and the new facebook [...]]]></description>
			<content:encoded><![CDATA[<p>After the runaway success of my <a href="http://www.puremango.co.uk/2009/07/facebook-chat-history/">facebook chat history</a> video (45k views, 100 ratings on youtube) I thought I&#8217;d follow up with a video explaining all the chat emotes you can use in facebook. There are some cool emoticons there.<br />
<span id="more-669"></span><br />
<object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/_ibORvWWhfk&#038;hl=en_GB&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/_ibORvWWhfk&#038;hl=en_GB&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object></p>
<h3>Facebook Chat Smilies</h3>
<p>This list includes the facebook robot, the new shark smiley and the new facebook penguin smiley! Woop woop!</p>
<table border="0">
<tbody>
<tr>
<td><img src="/fb_smilies/fb_happy.gif" alt="facebook happy smiley" /></td>
<td>:)</td>
<td><img src="/fb_smilies/fb_sad.gif" alt="facebook sad smiley" /></td>
<td>:(</td>
<td><img src="/fb_smilies/fb_tongue.gif" alt="facebook tongue smiley" /></td>
<td>:P</td>
<td><img src="/fb_smilies/fb_grin.gif" alt="facebook grin smiley" /></td>
<td>:D</td>
</tr>
<tr>
<td><img src="/fb_smilies/fb_shock.gif" alt="facebook shock smiley" /></td>
<td>:o</td>
<td><img src="/fb_smilies/fb_wink.gif" alt="facebook wink smiley" /></td>
<td>;)</td>
<td><img src="/fb_smilies/fb_specs.gif" alt="facebook glasses smiley" /></td>
<td>8)</td>
<td><img src="/fb_smilies/fb_cool.gif" alt="facebook cool smiley" /></td>
<td>8|</td>
</tr>
<tr>
<td><img src="/fb_smilies/fb_grumpy.gif" alt="facebook grumpy smiley" /></td>
<td>&gt;:(</td>
<td><img src="/fb_smilies/fb_erm.gif" alt="facebook erm smiley" /></td>
<td>:/</td>
<td><img src="/fb_smilies/fb_cry.gif" alt="facebook crying smiley" /></td>
<td>:&#8217;(</td>
<td><img src="/fb_smilies/fb_devil.gif" alt="facebook devil smiley" /></td>
<td>3:)</td>
</tr>
<tr>
<td><img src="/fb_smilies/fb_angel.gif" alt="facebook angel smiley" /></td>
<td>O:)</td>
<td><img src="/fb_smilies/fb_kiss.gif" alt="facebook kiss smiley" /></td>
<td>:*</td>
<td><img src="/fb_smilies/fb_heart.gif" alt="facebook love smiley" /></td>
<td>&lt;3</td>
<td><img src="/fb_smilies/fb_jhappy.gif" alt="facebook happy smiley" /></td>
<td>^_^</td>
</tr>
<tr>
<td><img src="/fb_smilies/fb_fhappy.gif" alt="facebook happy smiley" /></td>
<td>-_-</td>
<td><img src="/fb_smilies/fb_oo.gif" alt="facebook confused smiley" /></td>
<td>o.O</td>
<td><img src="/fb_smilies/fb_laugh.gif" alt="facebook laugh smiley" /></td>
<td>&gt;:o</td>
<td><img src="/fb_smilies/fb_pacman.gif" alt="facebook pacman smiley" /></td>
<td>:v</td>
</tr>
<tr>
<td><img src="/fb_smilies/fb_shark.gif" alt="facebook shark smiley" /></td>
<td>(^^^)</td>
<td><img src="/fb_smilies/fb_cat.gif" alt="facebook cat smiley" /></td>
<td>:3</td>
<td><img src="/fb_smilies/fb_robot.gif" alt="facebook robot smiley" /></td>
<td>:|]</td>
<td><img src="/fb_smilies/fb_putnam.gif" alt="facebook putnam smiley" /></td>
<td>:putnam:</td>
</tr>
<tr>
<td><img src="http://static.ak.fbcdn.net/images/emote/penguin.gif" alt="" /></td>
<td>&lt;(&#8220;)</td>
<td colspan="6"></td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2009/12/facebook-chat-smilies/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Wordpress Security Flaw &#8211; Admin Password Reset</title>
		<link>http://www.puremango.co.uk/2009/08/wordpress-security-flaw-admin-password-reset/</link>
		<comments>http://www.puremango.co.uk/2009/08/wordpress-security-flaw-admin-password-reset/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 22:24:01 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[advisory]]></category>
		<category><![CDATA[how to hack]]></category>
		<category><![CDATA[passwords]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=615</guid>
		<description><![CDATA[It is possible to reset the admin password in all versions of wordpress up to and including the most recent version 2.8.3.
This information comes from a milw0rm exploit.

So, the jist is you can simply go to:
http://domain.example/wp-login.php?action=rp&#38;key[]=
and it&#8217;ll reset the admin password. milw0rm didn&#8217;t supply a patch, but thankfully the internet is awesome and pzero from [...]]]></description>
			<content:encoded><![CDATA[<p>It is possible to reset the admin password in all versions of wordpress up to and including the most recent version 2.8.3.</p>
<p>This information comes from a <a href="http://www.milw0rm.com/exploits/9410" target="_blank">milw0rm exploit</a>.<br />
<span id="more-615"></span><br />
So, the jist is you can simply go to:</p>
<blockquote><p>http://domain.example/wp-login.php?action=rp&amp;key[]=</p></blockquote>
<p>and it&#8217;ll reset the admin password. milw0rm didn&#8217;t supply a patch, but thankfully the internet is awesome and <a href="http://www.reddit.com/r/programming/comments/99nep/wordpress_security_flaw_reset_admin_password_of/c0bxbu5" target="_blank">pzero from reddit</a> pointed me to <a href="http://www.programmerfish.com/fix-wordpress-admin-password-reset-exploit/" target="_blank">the fix</a>:</p>
<p>Open wp-login.php and goto line 190 (assuming WP 2.8.3, or for earlier versions line 169) and replace this line:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$key</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span></pre></div></div>

<p>with</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$key</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$key</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span></pre></div></div>

<p>Have fun patching your systems peeps. If (and only if) you&#8217;re running 2.8.3 you can <a href="http://www.puremango.co.uk/wp_pw_reset/wp-login.phps" target="_blank">download a fixed wp-login.php</a>. If you&#8217;re running a lower version, you&#8217;ll have to edit the file manually. Please backup your wp-login.php before changing it, my file might cause unforeseen problems otherwise.</p>
<p><strong>UPDATE: wordpress have now released 2.8.4 which fixes this issue.</strong> Upgrade now.</p>
<p>Here are some screenshots showing exactly how it works:</p>
<div class="wp-caption alignnone" style="width: 609px"><img title="Wordpress password reset - malicious URL" src="/wp_pw_reset/wp_address.png" alt="" width="599" height="143" /><p class="wp-caption-text">Wordpress password reset - malicious URL</p></div>
<p>- just press enter and then&#8230;</p>
<div class="wp-caption alignnone" style="width: 609px"><img title="Wordpress password reset - attack worked" src="/wp_pw_reset/wp_password.png" alt="" width="599" height="464" /><p class="wp-caption-text">Wordpress password reset - attack worked</p></div>
<p>but with the patch in place, wordpress is no longer vulnerable to this password reset attack:</p>
<div class="wp-caption alignnone" style="width: 609px"><img title="Wordpress password reset - Patched!" src="/wp_pw_reset/wp_patched.png" alt="" width="599" height="674" /><p class="wp-caption-text">Wordpress password reset - Patched!</p></div>
<p>To those of you wondering what the consequences are:</p>
<ul>
<li>Annoyance.</li>
<li>Inconvenience.</li>
<li>Admin lock-out, if a script was set up to repeatedly generate new passwords.</li>
<li>Admin lock-out, if admin no longer has access to their &#8220;admin&#8221; email address.</li>
<li>Resource consumption.</li>
<li>Email flood.</li>
</ul>
<p>So, while it&#8217;s not as serious as a revealed password would be, there are some serious potential consequences.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2009/08/wordpress-security-flaw-admin-password-reset/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>GIFexplode &#8211; community powered web development</title>
		<link>http://www.puremango.co.uk/2009/08/gifexplode-community-powered-web-development/</link>
		<comments>http://www.puremango.co.uk/2009/08/gifexplode-community-powered-web-development/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 18:35:00 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=573</guid>
		<description><![CDATA[Let me share with you a very cool story about strangers coming together and building something.
I was browsing reddit yesterday, and I saw a thread entitled &#8220;Someone needs to make a Firefox add-on that lets you step through animated gifs frame by frame&#8220;. I thought &#8220;hey that&#8217;s a nice well defined simple idea&#8221; &#8211; just [...]]]></description>
			<content:encoded><![CDATA[<p>Let me share with you a very cool story about strangers coming together and building something.</p>
<p><a href="http://www.gifexplode.com/c" target="_blank"><img class="alignright" title="I am a tiger" src="http://www.puremango.co.uk/gifexplode/619504tiger.gif" alt="" width="100" height="100" /></a>I was browsing reddit yesterday, and I saw a thread entitled &#8220;<a href="http://www.reddit.com/r/programming/comments/96iok/someone_needs_to_make_a_firefox_addon_that_lets/">Someone needs to make a Firefox add-on that lets you step through animated gifs frame by frame</a>&#8220;. I thought &#8220;hey that&#8217;s a nice well defined simple idea&#8221; &#8211; just the kind of thing I love, so I registered a nice-sounding domain name and started looking at how to use PHP to split an animated gif into its component frames &#8211; I figured it couldn&#8217;t be too hard.<span id="more-573"></span></p>
<p><a href="http://www.gifexplode.com/q" target="_blank"><img class="alignleft" title="Ralph" src="http://www.puremango.co.uk/gifexplode/545934ralph_eats_glue_e0.gif" alt="" width="160" height="120" /></a>It wasn&#8217;t. Less than an hour later, <a href="http://www.gifexplode.com/" target="_blank">GIFexplode.com</a> was up and running with some bare-bones functionality based around some freeware code I&#8217;d found. I posted the link to reddit and thought &#8220;well it&#8217;s not quite a firefox extension but it&#8217;s close enough&#8221; (by the way, click any of the gifs on this page to see how GIFexplode processed them).</p>
<p>Within ten hours, other members of the reddit community had produced a working Firefox extension for GIFexplode, two bookmarklets, a logo, a front-end design and a <a href="http://www.reddit.com/r/programming/comments/96n1x/someone_needs_to_make_a_firefox_addon_that_will/" target="_blank">spoof thread</a>&#8230;</p>
<p>not to mention the <strong>700+ animated gif files</strong> that were uploaded in that first day.</p>
<p><a href="http://www.gifexplode.com/e" target="_blank"><img class="alignright" title="Chimp is not impressed" src="http://www.puremango.co.uk/gifexplode/102664chimpanzee.gif" alt="" /></a>Why did everyone pitch in like that? Well I can&#8217;t speak for anyone else, but I started working on it because I thought it would be an interesting challenge.</p>
<p><strong>Fame?</strong> A little &#8211; but while I got a few upvotes on reddit and earned a little respect, that really doesn&#8217;t go too far online. <strong>Fortune?</strong> Unlikely &#8211; even if GIFexplode became as popular as imageshack or tinyurl (which it won&#8217;t), I&#8217;d still have to work out a good enough revenue model to cover the hosting and bandwidth charges. <strong>Over 1.5GB was uploaded</strong> on that first day, and if GIFexplode carried on at that rate I&#8217;m sure I&#8217;d be asked to upgrade to a private server pretty quickly. <a href="http://www.dreamhost.com/r.cgi?492537" target="_blank">Dreamhost </a>coped excellently with the traffic though.</p>
<p><a href="http://www.gifexplode.com/endless.htm" target="_blank"><img class="alignleft" title="Endless. This one isn't actually processed correctly by GIFexplode.. yet." src="http://www.puremango.co.uk/gifexplode/794844one_1.gif" alt="" width="160" height="120" /></a>So that&#8217;s the story of how GIFexplode was born and, as one commenter aptly phrased it, put in front of &#8220;a live firing squad challenge&#8221;!</p>
<p>As to the future? Well there are a few extra features I want to implement, but I really have <a href="http://www.puremango.co.uk/2009/06/adaptive-web-sites/" target="_blank">more important work</a> to be doing this month. I expect the traffic to drop very sharply and hit around 10 visits per day by the end of September. Perhaps I&#8217;ll post another followup in a few months once we have some more features and the code is a bit more robust.</p>
<p>But in the meantime, <strong>a sincere thankyou</strong> to everyone who chipped in &#8211; if I ever do become a millionaire from this I&#8217;ll make sure you get your slice.</p>
<p><a href="http://www.gifexplode.com/d" target="_blank"><img class="alignright" title="Picard" src="http://www.puremango.co.uk/gifexplode/4290711237976746_picard2.gif" alt="" width="150" height="200" /></a><strong>Some random stats:</strong></p>
<ul>
<li>Around one third of the uploaded files were porn. I am amazed it wasn&#8217;t a higher proportion.</li>
<li>The bouncing gif (you know the one I mean) was uploaded at least 200 times &#8211; at one point I was considering making a static page just for that gif (I still may do)</li>
<li>The largest file uploaded was a 5.14Mb file of a <a href="http://commons.wikimedia.org/wiki/File:Cicada_molting_animated-2.gif" target="_blank">cicada molting</a></li>
<li>The non-porn files consisted mainly of people jumping around, trippy stuff, cartoon clips, cats and other animal antics ;0)</li>
</ul>
<p>I&#8217;ve archived everything that was uploaded to my local machine. Is there anything you&#8217;d like to know? Any ideas or suggested features?</p>
<p>update: For the moment, you can <a href="http://www.gifexplode.com/uploads/" target="_blank">browse what&#8217;s being uploaded</a> (lots NSFW). I will clear the contents of that directory every day or so, so don&#8217;t bother linking to the files there. A better way of sharing these gifs will come in a few months.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2009/08/gifexplode-community-powered-web-development/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>PHP CV &#8211; Howard Yeend &#8211; UK Web Developer</title>
		<link>http://www.puremango.co.uk/2009/08/php-cv/</link>
		<comments>http://www.puremango.co.uk/2009/08/php-cv/#comments</comments>
		<pubDate>Sat, 01 Aug 2009 13:40:52 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[(misc)]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[cv]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[howard]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[programmer]]></category>
		<category><![CDATA[resumé]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=217</guid>
		<description><![CDATA[howard.yeend@gmail.com &#8211; 07790 816291

Availability
Not currently seeking work. Sorry!
Qualifications

Oxford University 2008-2009
Subject: Computer Science MSc
Result: Pass, distinction in dissertation.
My dissertation focused on implementing Adaptive Web Sites using machine learning and Ajax. I passed modules including Object Oriented Programming with JAVA, Information Retrieval, Computational Linguistics and Compilers.
University of Wales Lampeter 2004-2007
Subject: Information Technology and Philosophical Studies BA
Result: First [...]]]></description>
			<content:encoded><![CDATA[<h6><a href="mailto:howard.yeend@gmail.com" target="_self">howard.yeend@gmail.com</a> &#8211; 07790 816291</h6>
<hr />
<p style="margin-top:30px;"><span style="text-decoration: underline;"><strong>Availability</strong></span></p>
<p style="padding-left: 30px;">Not currently seeking work. Sorry!</p>
<p style="margin-top:20px;"><strong><span style="text-decoration: underline;"><span id="more-217"></span>Qualifications</span><br />
</strong></p>
<p style="padding-left: 30px;"><strong>Oxford University <em>2008-2009</em></strong></p>
<p style="padding-left: 60px;"><strong>Subject:</strong><em> Computer Science MSc</em></p>
<p style="padding-left: 60px;"><strong>Result:</strong> <em>Pass, distinction in dissertation.</em></p>
<p style="padding-left: 60px;">My dissertation focused on implementing <a href="http://www.puremango.co.uk/2009/06/adaptive-web-sites/" target="_self">Adaptive Web Sites</a> using machine learning and Ajax. I passed modules including Object Oriented Programming with JAVA, Information Retrieval, Computational Linguistics and Compilers.</p>
<p style="padding-left: 30px;"><strong>University of Wales Lampeter <em>2004-2007</em></strong></p>
<p style="padding-left: 60px;"><strong>Subject:</strong> <em>Information Technology and Philosophical Studies BA</em></p>
<p style="padding-left: 60px;"><strong>Result:</strong> <em>First Class Honours, awarded Lampeter Society Prize for IT</em></p>
<p style="padding-left: 60px;">I undertook modules in Databases, Computer Modelling, Robotics and Ethics. My final project, a game, was written in VB.NET and MSSQL.</p>
<p style="padding-left: 30px;"><strong>Northampton College<em> 1999-2001</em></strong></p>
<p style="padding-left: 60px;">Distinction: City and Guilds &#8220;Computer Programming &#8211; Games &amp; Quizzes&#8221;</p>
<p style="padding-left: 60px;">Pass: City and Guilds &#8220;Computer Programming &#8211; Business Applications&#8221;</p>
<p style="padding-left: 30px;"><strong>Pitsford Independent School<em> 1995-1998</em></strong></p>
<p style="padding-left: 60px;">9 GCSEs: Physics (B), English Lit (B), English Lang (B), German (B), French (B), Maths (C), Chemistry (C), Biology (C), Geography (C).</p>
<p><strong><span style="text-decoration: underline;">Commercial Experience</span></strong></p>
<p style="padding-left: 30px;"><strong>GG.com / Twist Digital Media: <em>Feb 2010-current</em></strong></p>
<p style="padding-left: 60px;"><strong>Job Title:</strong> Web Developer</p>
<p style="padding-left: 60px;">Returning to my previous role as a web developer, I am developing new products in javascript/json/xul, object oriented PHP 5 and mySQL.</p>
<p style="padding-left: 30px;"><strong>Web Office Systems: <em>Oct 2009-Feb 2010</em></strong></p>
<p style="padding-left: 60px;"><strong>Job Title:</strong> Web Developer</p>
<p style="padding-left: 60px;">Here I was responsible for developing and maintaining business oriented web applications and web services (SaaS) using PHP, mySQL, XML-RPC and Ajax, as well as performing routine linux server maintenance.</p>
<p style="padding-left: 30px;"><strong>GG.com / Twist Digital Media: </strong><strong><em>2007-2008 </em><br />
</strong></p>
<p style="padding-left: 60px;"><strong> Job Title:</strong> Web Developer</p>
<p style="padding-left: 60px;">Primarily developing in PHP5/mySQL, this role was split 70/30 between maintaining existing systems and R&amp;D for new business directions. The company was looking to expand its web offerings with new in-browser betting games. I provided extensive input on technical feasibility for new projects, as well as being actively sought for my ideas for new business directions. During my time at GG, I redeveloped a javascript bet calculator which was deemed worthy of spinning off to a standalone website in its own right. I wrote a Firefox extension and Internet Explorer plugin for this calculator which allows people to use their sidebar to calculate bets while on other websites.</p>
<p style="padding-left: 30px;"><strong>Freetimers Ltd / Poulson Enterprises Group: </strong><em><strong>2001-2005</strong></em></p>
<p style="padding-left: 60px;"><strong> Job Titles:</strong> Internet Programmer, Senior Database Programmer</p>
<p style="padding-left: 60px;"><strong> </strong></p>
<p style="padding-left: 60px;">My role at Freetimers progressed rapidly from a junior technical role to being the primary designer and maintainer of the flagship product, Freedom<sup>TM</sup>. At Freetimers, I was instrumental in the design and continued development of all technical products now offered to clients. These products include a multi-lingual, multi-website content management system, a web-managed stock control system including ecommerce, and web-based bulk email software, as well as the multi-user admin shell.</p>
<p style="padding-left: 60px;">When I first started, Freetimers websites were produced from scratch on a per-client basis. My ideas and technical expertise allowed me to create standard, re-usable and upgradable modules that enabled Freetimers to massively reduce development time and continually improve the products offered to clients. I also managed a small number of junior developers, and brought their skill level forwards; under my supervision, a web graphics designer also became a html developer, and a html/PHP developer became a PHP/mySQL developer.</p>
<p><strong><span style="text-decoration: underline;">General IT Skills</span></strong></p>
<ul style="padding-left: 30px;">
<li>Standards-Compliant HTML / JavaScript / jQuery / dHTML / Ajax / JSON / &#8220;web2.0 technologies&#8221;</li>
<li>Object Oriented PHP5, PHP4</li>
<li>MySQL</li>
<li>VBA, VB6, VB.NET</li>
<li>Excellent SEO ability; this PHP resumé is ranked in the top results for &#8220;<a href="http://www.google.com/search?q=php+cv" target="_blank">php CV</a>&#8221; and &#8220;<a href="http://www.google.com/search?q=programmer+cv" target="_blank">programmer CV</a>&#8220;.</li>
<li>Firefox extensions, greasemonkey scripts, MSIE plugins</li>
<li>Apache administration under both Windows and Linux</li>
<li>My work on CAPTCHA security has been cited by <a href="http://www.w3.org/TR/turingtest/" target="_blank">w3.org</a></li>
<li>My GPL PHP CAPTCHA script was used by Apple and Mozilla, among others.</li>
<li>One of my PHP scripts has an average rating of 4½/5 from 100+ reviewers on <a href="http://www.hotscripts.com/listing/easygraph/#PublisherInfo" target="_blank">hotscripts.net</a>.</li>
<li>I have some experience with MSSQL/SQL Server and Linux server administration using putty/SSH.</li>
</ul>
<p><strong><span style="text-decoration: underline;">Personal Statement</span></strong></p>
<p style="padding-left: 30px;">I am a highly motivated individual who thrives on interesting challenges and works best under pressure. I enjoy varied work and am deeply interested in all aspects of computer technology.</p>
<p style="padding-left: 30px;">My interests include machine learning, responsive UI design, and programming involving images. I also enjoy photography and science fiction. I am also a keen swimmer and collect robots and swiss army knives.</p>
<p style="padding-left: 30px;">In addition to <a href="http://www.puremango.co.uk" target="_self">puremango.co.uk</a>, I also maintain <a href="http://www.thingsinbooks.com" target="_self">thingsinbooks.com</a> and <a href="http://www.gifexplode.com" target="_blank">gifexplode.com</a>.</p>
<p><em>References available on request.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2009/08/php-cv/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Facebook Chat History</title>
		<link>http://www.puremango.co.uk/2009/07/facebook-chat-history/</link>
		<comments>http://www.puremango.co.uk/2009/07/facebook-chat-history/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 20:04:33 +0000</pubDate>
		<dc:creator>Howard Yeend</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[chat]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.puremango.co.uk/?p=568</guid>
		<description><![CDATA[
A little video I made with some instructions on how to get facebook chat history, even if your friends are offline.
It&#8217;s always really annoying when you remember that a friend sent you a cool link but they&#8217;re not online any more. With this facebook tweak you can bring up the chat history.
Facebook only stores chat [...]]]></description>
			<content:encoded><![CDATA[<p><object width="640" height="505"><param name="movie" value="http://www.youtube.com/v/hZ9sXvM433U&#038;hl=en_GB&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/hZ9sXvM433U&#038;hl=en_GB&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505"></embed></object></p>
<p>A little video I made with some instructions on how to get facebook chat history, even if your friends are offline.</p>
<p>It&#8217;s always really annoying when you remember that a friend sent you a cool link but they&#8217;re not online any more. With this facebook tweak you can bring up the chat history.</p>
<p>Facebook only stores chat history for a few days though, so there might be no history to retrieve.</p>
<p>This is an extension of my <a href="http://www.puremango.co.uk/2009/05/hacking-facebook/" target="_self">facebook hacks</a> page.</p>
<p>PS: Sorry the text is so small on the vid, put it fullscreen and you can read it better :0)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.puremango.co.uk/2009/07/facebook-chat-history/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 1.130 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2010-03-11 13:18:31 -->
