<?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>DaleR</title>
	<atom:link href="http://blog.dalereidy.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.dalereidy.co.uk</link>
	<description>Programming, mostly.</description>
	<lastBuildDate>Wed, 03 Aug 2011 19:14:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Pre-multiplied alpha</title>
		<link>http://blog.dalereidy.co.uk/2011/06/22/pre-multiplied-alpha/</link>
		<comments>http://blog.dalereidy.co.uk/2011/06/22/pre-multiplied-alpha/#comments</comments>
		<pubDate>Wed, 22 Jun 2011 01:00:36 +0000</pubDate>
		<dc:creator>Dale</dc:creator>
				<category><![CDATA[Game Development]]></category>
		<category><![CDATA[alphablending]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[slimdx]]></category>

		<guid isPermaLink="false">http://blog.dalereidy.co.uk/?p=118</guid>
		<description><![CDATA[Pre-multiplied alpha is alpha blending done correctly. It involves changing your alpha blending states, and ensuring your texture colour channels (R, G, B) are pre-multiplied (hence the name) with the alpha channel (A). Firstly the alpha blending operations will have to be changed: Set your source alpha blend to ONE (probably instead of SRCALPHA) &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>Pre-multiplied alpha is alpha blending done correctly. It involves changing your alpha blending states, and ensuring your texture colour channels (R, G, B) are pre-multiplied (hence the name) with the alpha channel (A).</p>
<p>Firstly the alpha blending operations will have to be changed:</p>
<ul>
<li>Set your source alpha blend to ONE (probably instead of SRCALPHA) &#8211; How solid our source texture appears depends on our alpha value alone (pre-multiplied colour channels at work here).</li>
<li>Set your destination blend to INVSRCALPHA &#8211; The more solid our texture appears, the less light we should let through from behind</li>
</ul>
<pre class="brush: csharp; title: ; notranslate">
// Standard fare alpha texture operations
Device.SetTextureStageState(0, TextureStage.AlphaArg1, TextureArgument.Texture);
Device.SetTextureStageState(0, TextureStage.AlphaArg2, TextureArgument.Diffuse);
Device.SetTextureStageState(0, TextureStage.AlphaOperation, TextureOperation.Modulate);

// Important
Device.SetRenderState(RenderState.AlphaBlendEnable, True);

// New alpha blending render states
Device.SetRenderState(RenderState.SourceBlend, Blend.One);
Device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);
</pre>
<p>The next part is loading the texture data and calculating the new colour channel values &#8211; below is a C# snippet for reading a 32-bit bitmap and performing this calculation. We take a bitmap that has been loaded into memory, iterate over each pixel in the image, calculate our new R, G and B values and save them back into the bitmap. Using SetPixel and GetPixel would be far too slow so this example locks the bitmap data and accesses the colour values directly.</p>
<pre class="brush: csharp; title: ; notranslate">[StructLayout(LayoutKind.Sequential, Pack=1)]
struct RgbaColor
{
    // Huh?! turns out PixelFormat.Format32bppArgb should
    // actually be called Format32bppBgra.
    public byte Blue;
    public byte Green;
    public byte Red;
    public byte Alpha;
}

public unsafe static class DangerousTextureLoader
{
    private static Texture LoadFromBitmap(Bitmap bitmap)
    {
        // Lock the entire bitmap for Read/Write access as we'll be reading the pixel
        // colour values and altering them in-place.
        var bmlock = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
                                     ImageLockMode.ReadWrite, bitmap.PixelFormat);

        // This code only works with 32bit argb images
        Debug.Assert(bmlock.PixelFormat == PixelFormat.Format32bppArgb);

        var ptr = (byte*) bmlock.Scan0.ToPointer();

        for (var y = 0; y &lt; bmlock.Height; y++)
        {
            for (var x = 0; x &lt; bmlock.Width; x++)
            {
                // Obtain the memory location where our pixel data resides and cast it
                // into a struct to improve sanity.
                var color = (RgbaColor*)(ptr + (y * bmlock.Stride) + (x * sizeof(RgbaColor)));

                var alphaFloat = (*color).Alpha/255.0f;

                (*color).Red = Convert.ToByte(alphaFloat * (*color).Red);
                (*color).Green = Convert.ToByte(alphaFloat * (*color).Green);
                (*color).Blue = Convert.ToByte(alphaFloat * (*color).Blue);
            }
        }

        // SlimDX specific stuff here
        var newTexture = new Texture(_device, bitmap.Width, bitmap.Height, 0,
            Usage.None, GetD3DFormat(bitmap.PixelFormat), Pool.Managed);

        // SlimDX specific stuff
        var textureLock = newTexture.LockRectangle(0, LockFlags.None);
        textureLock.Data.WriteRange(bmlock.Scan0, bmlock.Height * bmlock.Stride);

        // The bitmap lock is freed here
        bitmap.UnlockBits(bmlock);

        // SlimDX specific stuff
        newTexture.UnlockRectangle(0);
        newTexture.FilterTexture(0, Filter.Default);

        return newTexture;
    }
}
</pre>
<p>You can read a better explanation and a link to a research paper at <a href="http://home.comcast.net/~tom_forsyth/blog.wiki.html#%5B%5BPremultiplied%20alpha%5D%5D">TomF&#8217;s tech blog</a>. He also highlights how pre-multiplied alpha will help compress your textures using DXTn formats.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dalereidy.co.uk/2011/06/22/pre-multiplied-alpha/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Daybreak</title>
		<link>http://blog.dalereidy.co.uk/2011/06/02/daybreak/</link>
		<comments>http://blog.dalereidy.co.uk/2011/06/02/daybreak/#comments</comments>
		<pubDate>Thu, 02 Jun 2011 22:28:21 +0000</pubDate>
		<dc:creator>Dale</dc:creator>
				<category><![CDATA[Daybreak]]></category>

		<guid isPermaLink="false">http://blog.dalereidy.co.uk/?p=107</guid>
		<description><![CDATA[I&#8217;ve been spending the past few months working on a top-down zombie survival co-op game, it&#8217;s still very much still in the workshed, but there&#8217;s plenty of screenshots over  at the zombie hq. This game, whilst rather rudimentary in it&#8217;s presentation, is actually designed to be a realistic zombie apocalypse survival simulator. We used a [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been spending the past few months working on a top-down zombie survival co-op game, it&#8217;s still very much still in the workshed, but there&#8217;s plenty of screenshots over  <a href="http://www.dalereidy.co.uk/daybreak/" target="_blank">at the zombie hq</a>.</p>
<p>This game, whilst rather rudimentary in it&#8217;s presentation, is actually designed to be a realistic zombie apocalypse survival simulator. We used a team of zombie survival experts* to plan situations that would call for coordination, teamwork and an assortment of firearms and melee weapons.</p>
<p>* they watched Dawn of the Dead once or twice. We did try and use somebody who&#8217;d watched Resident Evil 2, but he was past saving.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dalereidy.co.uk/2011/06/02/daybreak/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Microsoft certification</title>
		<link>http://blog.dalereidy.co.uk/2010/09/23/microsoft-certification/</link>
		<comments>http://blog.dalereidy.co.uk/2010/09/23/microsoft-certification/#comments</comments>
		<pubDate>Thu, 23 Sep 2010 17:42:46 +0000</pubDate>
		<dc:creator>Dale</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[daybreak]]></category>
		<category><![CDATA[exams]]></category>
		<category><![CDATA[legume]]></category>
		<category><![CDATA[mcts]]></category>

		<guid isPermaLink="false">http://blog.dalereidy.co.uk/?p=90</guid>
		<description><![CDATA[Last month I finished my second exam [70-562] &#8211; this means I&#8217;m now an MCTS in developing ASP.net Web Applications(hurrah!), unfortunately I have to print my own certificate (boo!). I got quite a lot out of reading through the self paced training kits &#8211; though they&#8217;re DULL AS HELL, and full of errata. Lots of [...]]]></description>
			<content:encoded><![CDATA[<p>Last month I finished my second exam [70-562] &#8211; this means I&#8217;m now an MCTS in developing ASP.net Web Applications(hurrah!), unfortunately I have to print my own certificate (boo!).</p>
<p>I got quite a lot out of reading through the self paced training kits &#8211; though they&#8217;re DULL AS HELL, and <a href="http://support.microsoft.com/kb/971804">full </a>of <a href="http://support.microsoft.com/kb/959409">errata</a>. Lots of little unknown unknowns in my knowledge of C# and ASP.net got patched, and I learnt quite a bit about stuff I have never come across in my job or in my spare time.</p>
<p>The big downside to taking the examinations is the interface you&#8217;re forced with using &#8211; it&#8217;s bloody awful. Lack of mouse-wheel enabled scrolling of the question and answers, 800&#215;600 resolution, no option to switch mouse buttons for lefties (minor point but still, it was a bit frustrating), and a strange UI behaviour where, if you click a radio button of a selected answer, it deselects it! &#8211; so my belt&amp;braces OCD make-sure-I&#8217;ve-clicked-my-correct-answer method caught me out a few times. Despite the unnecessary hurdles, I made it through &#8211; seriously Microsoft, fix the interface.</p>
<p>Project-wise, I&#8217;m currently working on a top-down multiplay zombie shooter &#8211; Its in it&#8217;s infancy at the moment but you can find some early screen-shots on the <a href="http://www.dalereidy.co.uk/daybreak/">Daybreak</a> project webpage.</p>
<p>Legume is on hold for the meantime &#8211; it&#8217;s not dead &#8211; unlike zombies &#8211; which are.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dalereidy.co.uk/2010/09/23/microsoft-certification/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Legume 0.2</title>
		<link>http://blog.dalereidy.co.uk/2010/06/26/legume-0-2/</link>
		<comments>http://blog.dalereidy.co.uk/2010/06/26/legume-0-2/#comments</comments>
		<pubDate>Sat, 26 Jun 2010 17:04:49 +0000</pubDate>
		<dc:creator>Dale</dc:creator>
				<category><![CDATA[Legume]]></category>

		<guid isPermaLink="false">http://blog.dalereidy.co.uk/2010/06/26/legume-0-2/</guid>
		<description><![CDATA[Yup version 0.2 is available &#8211; obtain it via googlecode or pypi. I&#8217;ve made substantial changes to the API and the guts so it&#8217;s completely incompatible with version 0.1.]]></description>
			<content:encoded><![CDATA[<p>Yup version 0.2 is available &#8211; obtain it via googlecode or pypi. I&#8217;ve made substantial changes to the API and the guts so it&#8217;s completely incompatible with version 0.1.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dalereidy.co.uk/2010/06/26/legume-0-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Legume &#8211; documentation</title>
		<link>http://blog.dalereidy.co.uk/2009/12/15/legume-documentation/</link>
		<comments>http://blog.dalereidy.co.uk/2009/12/15/legume-documentation/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 22:51:58 +0000</pubDate>
		<dc:creator>Dale</dc:creator>
				<category><![CDATA[Legume]]></category>

		<guid isPermaLink="false">http://blog.dalereidy.co.uk/?p=78</guid>
		<description><![CDATA[The API documentation for Legume 0.1 is now available, and will be updated regularly as more is added. Version 0.2? The work on the documentation and removing the bugs listed on the google-code page is towards the next release of Legume, which in all probability will be in the new-year. Stay tuned]]></description>
			<content:encoded><![CDATA[<p><b><a href="http://www.dalereidy.co.uk/legume-docs/">The API documentation for Legume 0.1 is now available</a></b>, and will be updated regularly as more is added.</p>
<h2>Version 0.2?</h2>
<p>The work on the documentation and removing the bugs listed on the google-code page is towards the next release of Legume, which in all probability will be in the new-year. Stay tuned <img src='http://blog.dalereidy.co.uk/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dalereidy.co.uk/2009/12/15/legume-documentation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Backing up a Subversion repository to Amazon&#8217;s S3</title>
		<link>http://blog.dalereidy.co.uk/2009/12/11/backing-up-a-subversion-repository-to-amazons-s3/</link>
		<comments>http://blog.dalereidy.co.uk/2009/12/11/backing-up-a-subversion-repository-to-amazons-s3/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 19:51:18 +0000</pubDate>
		<dc:creator>Dale</dc:creator>
				<category><![CDATA[Subversion]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[backups]]></category>
		<category><![CDATA[s3cmd]]></category>

		<guid isPermaLink="false">http://blog.dalereidy.co.uk/?p=65</guid>
		<description><![CDATA[I&#8217;m currently working through the process of re-building my development server and have got to the stage of configuring the backup of my subversion repository to Amazon&#8217;s S3 storage &#8216;cloud&#8217;. Due to the inevitability of having to do it again in the near future I&#8217;m going to document how I keep my repository backed up, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently working through the process of re-building my development server and have got to the stage of configuring the backup of my subversion repository to Amazon&#8217;s S3 storage &#8216;cloud&#8217;. Due to the inevitability of having to do it again in the near future I&#8217;m going to document how I keep my repository backed up, for myself, and for everyone else:</p>
<p>(This guide is assuming a freshly-squeezed Ubuntu 9.04 server install)</p>
<p>0. Obtain an <a href="http://aws.amazon.com/">AWS account</a> if you haven&#8217;t already &#8211; making note of the Access key and Secret key, you&#8217;ll need them in step 2.</p>
<p>1. Install <a href="http://s3tools.org/s3cmd/">s3cmd</a></p>
<pre>
root@trogdor:~# <strong>sudo apt-get install s3cmd</strong>
</pre>
<p>2. Configure s3cmd and follow the onscreen instructions</p>
<pre>
root@trogdor:~# <strong>s3cmd --configure</strong>
</pre>
<p>3. Create the backup location</p>
<pre>
root@trogdor:~# <strong>mkdir /var/nightly_backup</strong>
</pre>
<p>4. Create the backup script (/var/nightly_backup/backup.sh)</p>
<pre>
#!/bin/bash
svnadmin dump --quiet /var/svn/repos | gzip > /var/nightly_backup/svn.gz
s3cmd sync /var/nightly_backup s3://backup_bucket/nightly_backup/
</pre>
<p>5. Make the backup script executable</p>
<pre>
root@trogdor:~# <strong>chmod +x /var/nightly_backup</strong>
</pre>
<p>6. Amend /etc&nbsp;/crontab to run the backup at a suitable time (3am in this case)</p>
<pre>
... contents of /etc&nbsp;/crontab ...
0 3 * * * root /var/nightly_backup/backup.sh
</pre>
<p>7. Wait until 3am, or run /var/nightly_backup/backup.sh.</p>
<p>8. Download an S3 browser such as <a href="http://s3browser.com/">S3 Browser (Windows)</a> or <a href="https://jets3t.dev.java.net/">Jets3t (Java)</a></p>
<p>9. Configure your S3 browser of choice to point to your AWS account to confim that the backup completed successfully.</p>
<p>10. ?</p>
<p>11. Profit.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dalereidy.co.uk/2009/12/11/backing-up-a-subversion-repository-to-amazons-s3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>legume 0.1 released: easy_install &#8216;legume&#8217;</title>
		<link>http://blog.dalereidy.co.uk/2009/10/10/legume-0-1-released-easy_install-legume/</link>
		<comments>http://blog.dalereidy.co.uk/2009/10/10/legume-0-1-released-easy_install-legume/#comments</comments>
		<pubDate>Sat, 10 Oct 2009 13:59:31 +0000</pubDate>
		<dc:creator>Dale</dc:creator>
				<category><![CDATA[Legume]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[legume]]></category>

		<guid isPermaLink="false">http://blog.dalereidy.co.uk/?p=52</guid>
		<description><![CDATA[It&#8217;s been a few months in the making, but now legume has gotten to a point that I thought it worthy of a 0.1 release. The basic feature-set is complete, so it&#8217;s in a usable state, that is if anybody can be be faced with using it yet, as at the moment there&#8217;s very little [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a few months in the making, but now legume has gotten to a point that I thought it worthy of a 0.1 release. The basic feature-set is complete, so it&#8217;s in a usable state, that is if anybody can be be faced with using it yet, as at the moment there&#8217;s very little (read: nothing) in the way of documentation or user guides.</p>
<p>The release is available via pypi or <a href="http://code.google.com/p/legume/">google code</a>, and I think that softpedia has already snapped it up.</p>
<p>As for the name: &#8220;It&#8217;s not a nut, it&#8217;s a legume! phew!&#8221; (Ricky Gervais, Animals).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dalereidy.co.uk/2009/10/10/legume-0-1-released-easy_install-legume/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python distutils</title>
		<link>http://blog.dalereidy.co.uk/2009/10/05/python-distutils/</link>
		<comments>http://blog.dalereidy.co.uk/2009/10/05/python-distutils/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 20:26:16 +0000</pubDate>
		<dc:creator>Dale</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[distutils]]></category>
		<category><![CDATA[installers]]></category>
		<category><![CDATA[setuptools]]></category>

		<guid isPermaLink="false">http://blog.dalereidy.co.uk/?p=39</guid>
		<description><![CDATA[A guide to creating a simplistic .exe python package installer: Create a setup.py file in the directory above your package directory: MyPythonPackage setup.py Copy the following in setup.py: from distutils.core import setup import setuptools import sys setup(name='MyAmazingLibrary', version='0.1', description='My Amazing Library', author='My Name', url='http://code.google.com/p/MyAmazingLibrary/', packages=setuptools.find_packages('.'), package_dir = {'':'.'}, ) Open a command prompt in the [...]]]></description>
			<content:encoded><![CDATA[<p>A guide to creating a simplistic .exe python package installer:</p>
<ol>
<li> Create a <strong>setup.py</strong> file in the directory above your package directory:
<pre>
MyPythonPackage
setup.py
</pre>
<li> Copy the following in setup.py:
<pre name="code" class="python">
from distutils.core import setup
import setuptools
import sys

setup(name='MyAmazingLibrary',
    version='0.1',
    description='My Amazing Library',
    author='My Name',
    url='http://code.google.com/p/MyAmazingLibrary/',
    packages=setuptools.find_packages('.'),
    package_dir = {'':'.'},
)</pre>
<li> Open a command prompt in the directory containing the setup.py and execute
<pre>
python setup.py bdist_wininst
</pre>
<li> Observe how the installer appears in the newly created <code>dist</code> directory.
</ol>
<h4>Additional Notes</h4>
<ul>
<li>To specify that the installer is only for a specific Python install use the <strong>&#8211;target-version</strong> option with setup.py, eg:
<pre>
python setup.py bdist_wininst --target-version=2.5
</pre>
<li>Swap <strong>bdist_wininst</strong> to <strong>bdist_msi</strong> to create a Windows Installer for your python package.
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.dalereidy.co.uk/2009/10/05/python-distutils/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Event handling in python</title>
		<link>http://blog.dalereidy.co.uk/2009/09/17/event-handling-in-python/</link>
		<comments>http://blog.dalereidy.co.uk/2009/09/17/event-handling-in-python/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 19:44:43 +0000</pubDate>
		<dc:creator>Dale</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[event-handling]]></category>

		<guid isPermaLink="false">http://blog.dalereidy.co.uk/?p=31</guid>
		<description><![CDATA[Update: for the latest code please check nevent.py in the legume google code repository Typically, event handling in python either involves storing a function pointer and invoking it at some pointer later-on, or inheriting a base-class and overriding event handler stubs. Storing a single function pointer does not permit event handler chaining, but is the [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update: for the latest code please check <a href="https://code.google.com/p/legume/source/browse/legume/nevent.py">nevent.py in the legume google code repository</a></strong></p>
<p>Typically, event handling in python either involves storing a function pointer and invoking it at some pointer later-on, or inheriting a base-class and overriding event handler stubs. Storing a single function pointer does not permit event handler chaining, but is the easiest method to expand upon, and acts as a replacement for event handler stubs in classes.</p>
<p><strong>Expected usage of the Event handler:</strong></p>
<pre class="python">def example_handler(param):
    print "1", param

example_event= Event()
example_event += example_handler
example_event('Hello!')</pre>
<p>And the output:</p>
<pre>1 Hello!
2 Hello!</pre>
<p>A basic structure to the event handler class is shown below:</p>
<pre name="code" class="python">class EventError(Exception): pass

class Event(object):
    def __init__(self):
        self._handlers = []

    def __iadd__(self, other):
        if other not in self._handlers:
            self._handlers.append(other)
        else:
            raise EventError, \
                   'Event %s error: Handler %s is already bound' \
                   % (self, other)
        return self

    def __isub__(self, other):
        try:
            self._handlers.remove(other)
        except IndexError, e:
            raise EventError, \
                   'Event %s error: Handler %s is not bound' \
                   % (self, other)
        return self

    def __call__(self, sender, args):
        result = None
        for handler in self._handlers:
            result = handler(sender, args)
        return result

    def is_handled_by(self, handler):
        return handler in self._handlers</pre>
<p>Note how overriding __iadd__ provides a syntax identical to C# for adding extra handlers onto the event handler chain &#8211; marvelous.</p>
<p>This code is actually based off the event handling used in the legume network library, see<br />
<a href="https://code.google.com/p/legume/source/browse/legume/nevent.py">nevent.py in the legume google code repository</a> for the code in use, and to see any further changes.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dalereidy.co.uk/2009/09/17/event-handling-in-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A unittest green bar for the console</title>
		<link>http://blog.dalereidy.co.uk/2009/07/26/a-unittest-green-bar-for-the-console/</link>
		<comments>http://blog.dalereidy.co.uk/2009/07/26/a-unittest-green-bar-for-the-console/#comments</comments>
		<pubDate>Sun, 26 Jul 2009 16:33:22 +0000</pubDate>
		<dc:creator>Dale</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[console]]></category>
		<category><![CDATA[unittest]]></category>

		<guid isPermaLink="false">http://blog.dalereidy.co.uk/?p=16</guid>
		<description><![CDATA[One thing the unittest module is missing for me is a green bar of success (or a red bar of fail), so here&#8217;s one I cooked up to scratch my itch (windows only at the mo&#8217;, sorry): import sys import ctypes import unittest class GreenBarRunner(unittest.TextTestRunner): FOREGROUND_GREEN= 0x0A FOREGROUND_RED = 0x0C FOREGROUND_WHITE= 0x0F FOREGROUND_YELLOW=0x0E def __init__(self, [...]]]></description>
			<content:encoded><![CDATA[<p>One thing the unittest module is missing for me is a green bar of success (or a red bar of fail), so here&#8217;s one I cooked up to scratch my itch (windows only at the mo&#8217;, sorry):</p>
<pre name="code" class="python">
import sys
import ctypes
import unittest

class GreenBarRunner(unittest.TextTestRunner):
    FOREGROUND_GREEN= 0x0A
    FOREGROUND_RED  = 0x0C
    FOREGROUND_WHITE= 0x0F
    FOREGROUND_YELLOW=0x0E

    def __init__(self, verbosity=2):
        unittest.TextTestRunner.__init__(self, verbosity=verbosity)
        STD_OUTPUT_HANDLE = -11
        self.std_out_handle = ctypes.windll.kernel32.GetStdHandle(
            STD_OUTPUT_HANDLE)

    def set_color(self, color):
        bool = ctypes.windll.kernel32.SetConsoleTextAttribute(
            self.std_out_handle, color)
        return bool

    def run(self, test):
        r = unittest.TextTestRunner.run(self, test)

        failed_count = len(r.failures)
        errored_count = len(r.errors)
        total = r.testsRun
        ok_count = total - (failed_count + errored_count)

        sys.stdout.write('\n[')
        self.set_color(self.FOREGROUND_RED)
        sys.stdout.write('#' * errored_count)
        self.set_color(self.FOREGROUND_YELLOW)
        sys.stdout.write('#' * failed_count)
        self.set_color(self.FOREGROUND_GREEN)
        sys.stdout.write('#' * ok_count)
        self.set_color(self.FOREGROUND_WHITE)
        sys.stdout.write(']\n')</pre>
<p>Usage:</p>
<pre name="code" class="python">
suite = unittest.TestLoader().loadTestsFromModule(example_module)
GreenBarRunner(verbosity=2).run(suite)
</pre>
<p>It&#8217;ll execute the TextTestRunner so you won&#8217;t lose the test names and stack traces and afterwards display a red/yellow/green bar:</p>
<p><img class="alignnone size-full wp-image-20" title="GreenBarTestRunner" src="http://blog.dalereidy.co.uk/wp-content/uploads/GreenBarTestRunner.png" alt="GreenBarTestRunner" width="231" height="94" /></p>
<p>Ta-da.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dalereidy.co.uk/2009/07/26/a-unittest-green-bar-for-the-console/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

