<?xml version="1.0" encoding="UTF-8"?>
<rss 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/" version="2.0">

<channel>
	<title>NicholasArmstrong.com</title>
	
	<link>http://nicholasarmstrong.com</link>
	<description />
	<lastBuildDate>Tue, 17 Jan 2012 02:06:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/NicholasArmstrong" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="nicholasarmstrong" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>2012 Mobile Outlook</title>
		<link>http://nicholasarmstrong.com/2012/01/2012-mobile-outlook/</link>
		<comments>http://nicholasarmstrong.com/2012/01/2012-mobile-outlook/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 02:05:50 +0000</pubDate>
		<dc:creator>Nicholas Armstrong</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://nicholasarmstrong.com/?p=326</guid>
		<description><![CDATA[2011 was an active year for mobile platforms - new versions of the major smartphone operating systems were released, Android tablet manufacturers responded en masse to the iPad, and partnerships, acquisitions, and new players that will shape the space in the coming year all came about.

What does that mean for 2012?]]></description>
			<content:encoded><![CDATA[<p>2011 was an active year for mobile platforms &#8211; new versions of the major smartphone operating systems were released, Android tablet manufacturers responded en masse to the iPad, and partnerships, acquisitions, and new players that will shape the space in the coming year all came about.</p>
<p>What does that mean for 2012? I&#8217;ve got a couple ideas.</p>
<h2>iOS (Apple)</h2>
<p>Apple leaves 2011 in a comfortable position &#8211; they aren&#8217;t the largest smartphone vendor any more, but they still have the most widely distributed handset and a sizable amount of the profit. Though Android is applying significant pressure, consumers still seek out Apple&#8217;s mobile products, which should maintain their control &#8211; if not dominance &#8211; of the mobile space through 2012.</p>
<p>Look for Apple to continue to iterate on its mobile products, incorporating popular features from other platforms (with the usual Apple polish) while introducing new features that are unique to their platform, some of which will go on to define what it means to be a smartphone. Given Android&#8217;s increasing sales, also look for Apple to bend to the desires of the carriers somewhat more than in the past; core areas (UI, battery life) will be unaffected, but carrier apps that provide features unavailable to regular App Store developers are likely.</p>
<h2>Android (Google)</h2>
<p>2011 was a massive year for Android &#8211; two big releases (Gingerbread, Honeycomb), a big push into the tablet space, and a large number of innovative phones across all price ranges were released. 2011 was a bit rocky, too &#8211; Android faces some serious patent challenges from Microsoft and others, and consumers are starting to see the downside to Android&#8217;s customizability, especially when it comes to updates.</p>
<p>2012 will be a good year for Android on inertia alone, but Google needs to use the time to position themselves well for the future. Google&#8217;s purchase of Motorola and the increase patent litigation will put pressure on Android manufacturers to think twice about betting their future solely on Android, a fear that Google will have to calm. Furthermore, Android isn&#8217;t looked to for new ideas &#8211; it&#8217;s looked to for common features, cheaply. For them them to gain mindshare (and, eventually, marketshare), they will have to invest resources in making Android a truly excellent platform to use, not just a platform with impressive technical qualifications.</p>
<h2>Windows Phone 7 (Microsoft)</h2>
<p>2011 was a year that really didn&#8217;t happen for Windows Phone. The one big release saw much love from owners but little attention from the market, and the Nokia partnership did not impact consumers until the last quarter of the year (and not at all in North America). Even Microsoft&#8217;s already miniscule marketing campaign for the platform petered out, with no major ad campaigns that caught my eye (at least in Canada).</p>
<p>Microsoft&#8217;s challenge for 2012 isn&#8217;t technical &#8211; it&#8217;s marketing. They have a very capable platform with competitive &#8211; and in my personal opinion, compelling &#8211; features that don&#8217;t try to play the &#8216;me too!&#8217; game with Apple. Furthermore, the introduction of the Metro design language to the Xbox and in Windows 8 could introduce users to a new way of thinking about computing. That&#8217;s not going to happen if Microsoft doesn&#8217;t step up to the plate and aggressively market Windows Phone as compelling alternative to the other phones in the space.</p>
<h2>BlackBerry (RIM)</h2>
<p>Any way you slice it, 2011 was a bad year for RIM. Despite increased sales, and layoffs designed to appease the markets, RIM saw a continually declining stock price, constant takeover rumours, and calls for its executives to resign. Even their flagship product release for the year, the PlayBook, saw massively underwhelming demand and markdowns in excess of $200 in the latter portions of the year.</p>
<p>To top it off, 2012 looks to be even worse for RIM, with little hope for recovery. Their much-heralded &#8220;new OS&#8221;, BB10, won&#8217;t arrive until the fourth quarter.  There may be new devices running old software, but savvy consumers will be cautious when purchasing the last of a dead technology. No exciting new features for BB10 have been announced, either &#8211; it will do email, show videos, and surf the web in a new way, but one that is unlikely to be much different from the old way and certainly not enough to reverse the trend away from BlackBerrys to more engaging platforms. A takeover is possible, though there aren&#8217;t many companies up to the task &#8211; others in this space have already made their purchases, and RIM has been quick to spurn recent pursuers.</p>
<h2>&#8230;and some broad themes</h2>
<p>There are a few themes that, in my opinion, will come to define the year 2012 in the mobile space. The first of these is that 2012 will be the year that smartphones will become the primary units sold by carriers. Carriers today have a large user base on so-called feature phones, and still sell a large number of these low-cost phones. However, with the potential for new revenue through data add-ons, a general decline in traditional (voice) revenue, and the availability of low-cost smartphones (less than $200 off-contract), I expect carriers to aggressively reduce feature phone selection in their product offerings.</p>
<p>A second theme I expect for 2012 is a general decline in native mobile applications. HTML 5 gives developers incredible flexibility to build good applications with web technologies, applications that will work across devices. Maintaining three separate codebases &#8211; one for iOS, one for Android, and one for the web (covering desktops and other phones) &#8211; is time-consuming and expensive.  Using the &#8220;same&#8221; application everywhere will allow companies to put more effort into core features over pure platform parity. Now, that doesn&#8217;t mean that apps won&#8217;t be available through the App Store/Android Marketplace &#8211; they will &#8211; or that we won&#8217;t see separate versions of an app for iPhone and Android &#8211; we will. Rather, what we&#8217;ll see is that the technologies new apps are built with will shift from platform-specific to platform-independent HTML and Javascript, allowing developers to re-use core logic while maintaining device-appropriate visuals.</p>
<p>Finally, I expect that we will see the importance of cloud-based services to the smartphone ecosystem play a more visible role. Consumers don&#8217;t choose smartphones for their hardware, their fancy looks, or their enterprise-grade reliability; they choose them for what they allow them to do, and how they allow them to communicate. That means these devices must support the services they already use, and the communities they are already a part of. If I&#8217;m a Facebook/Dropbox/Instagram user, then my device must support that combination. Platforms that allow user combinations to happen &#8211; iOS through its strong developer base and simple cloud services, Google through the introduction of apps for its services (which many already use), and Microsoft through first-party support for third party services (Facebook chat, the People hub) &#8211; will have a significant edge on those who dont (RIM).</p>
]]></content:encoded>
			<wfw:commentRss>http://nicholasarmstrong.com/2012/01/2012-mobile-outlook/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>EXIF Quick Reference</title>
		<link>http://nicholasarmstrong.com/2010/02/exif-quick-reference/</link>
		<comments>http://nicholasarmstrong.com/2010/02/exif-quick-reference/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 02:41:04 +0000</pubDate>
		<dc:creator>Nicholas Armstrong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[code sample]]></category>
		<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://nicholasarmstrong.com/?p=278</guid>
		<description><![CDATA[Over the past few years, I've used the EXIF data stored by modern digital cameras in a couple of programs I've worked on.  Having access to the date the photo was taken - or which way the camera was rotated when it was - is useful information to have.  Even though it's relatively easy to do, finding the right identifier for the information you want is much harder than it should be.  This page fills that niche - the most useful/popular EXIF properties in an easy-to-find format.]]></description>
			<content:encoded><![CDATA[<p>Over the past few years, I&#8217;ve used the EXIF data stored by modern digital cameras in a couple of programs I&#8217;ve worked on.  Having access to the date the photo was taken &#8211; or which way the camera was rotated when it was &#8211; is useful information to have.  Even though it&#8217;s relatively easy to do, finding the right identifier for the information you want is much harder than it should be.  This page fills that niche &#8211; the most useful/popular EXIF properties in an easy-to-find format.</p>
<p><span id="more-278"></span></p>
<style>#secondary { display: none; } #container {width: 920px; } #content {width: 910px; }</style>
<h2>EXIF in .NET</h2>
<p>The .NET framework provides two ways of accessing EXIF data; functions in the <a title="System.Drawing Namespace" href="http://msdn.microsoft.com/en-us/library/system.drawing.aspx">System.Drawing</a> namespace, and functions in the <a title="System.Windows.Media.Imaging Namespace" href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.aspx">System.Windows.Media.Imaging</a> namespace.  There are also a number of libraries available to read EXIF data in .NET &#8211; which are generally easier to use than the built-in classes &#8211; but I&#8217;ve found that costs associated with loading and deploying an extra library are not worth it for the simpler programming interface.  Most of the time I&#8217;m only reading a couple properties, so doing it directly isn&#8217;t that difficult.</p>
<p>Given those two namespaces each provide a way of reading EXIF data, which one is better?  In my view, <strong>neither</strong>.  Each provides the same functionality, and though the System.Windows.Media.Imaging namespace does provide properties to allow reading some values directly &#8211; like the camera&#8217;s manufacturer or the date the photo was taken &#8211; they are limited enough in practice that you&#8217;ll end up using the tag values anyway.</p>
<p>So which one should we choose?  It&#8217;s actually quite simple; if you are using <strong>Windows Forms</strong>, use the <strong>System.Drawing</strong> version, since you&#8217;ve already loaded the appropriate DLL.  Likewise, if you are using <strong>WPF</strong>, use the <strong>System.Windows.Media.Imaging</strong> version.  And if your application doesn&#8217;t have a UI (or is using an alternate framework), then the choice is up to you &#8211; though I&#8217;d suggest using the <strong>System.Drawing</strong> version.  The System.Drawing namespace resides in System.Drawing.dll, which weighs in at 612 KB on my system, while System.Windows.Media.Imaging resides in PresentationCore.dll, which weighs in at 4112 KB (PresentationCore contains the majority of WPF).  The increased size of the latter DLL results in a slightly slower first-image processing time, as the framework loads the DLL into memory.</p>
<h3>Accessing EXIF data with C#</h3>
<p>Using the System.Drawing/Windows Forms version of accessing EXIF data is relatively straight forward: load the image, request a property by number, and then parse the property bytes into the desired format (string or integer).  Let&#8217;s have a look:</p>
<pre class="brush:c-sharp">using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;

class EXIF
{
    static void Main()
    {
		// Create an Image object
		using (Image photo = Image.FromFile(filename))
		{
			// Read out the date taken property (string)
			PropertyItem dateProperty = photo.GetPropertyItem(0x9003);
			string dateTaken = (new UTF8Encoding()).GetString(dateProperty.Value);

			// And the ISO (unsigned short integer)
			PropertyItem isoProperty = photo.GetPropertyItem(0x8827);
			ushort iso = BitConverter.ToUInt16(isoProperty.Value, 0);

			// other properties can be read using similar methods...
		}
    }
}</pre>
<p>Like the previous version, accessing the EXIF data with System.Windows.Media.Imaging/WPF is relatively easy and follows a similar pattern.  However, in this case the BitmapMetadata class exposes some of the EXIF values through properties on the <a title="BitmapMetadata Properties (System.Windows.Media.Imaging)" href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapmetadata_properties.aspx">BitmapMetadata</a> object.  The rest must be accessed using the <a title="BitmapMetadata.GetQuery Method (System.Windows.Media.Imaging)" href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapmetadata.getquery.aspx">GetQuery</a> method, using the WIC <a title="Metadata Query Language Overview (Windows)" href="http://msdn.microsoft.com/en-us/library/ee719796%28VS.85%29.aspx">Metadata Query Language</a>.  This query language unifies the types of embedded information that can be accessed (EXIF, XMP, IPTC, ID3, etc.) into a general-purpose syntax.  We&#8217;re only concerned with the EXIF ones here, which have the form <code>/app1/ifd/exif:{uint=999}</code> or <code>/app1/ifd/exif/subifd:{uint=99999}</code>, depending on the tag you&#8217;re accessing.  In general, tags less than 1000 (decimal) are accessed using the former syntax, those greater using the latter syntax.</p>
<pre class="brush:c-sharp">using System;
using System.IO;
using System.Windows.Media.Imaging;

class EXIF
{
    static void Main()
    {
		// Load and decode the photo
		using (FileStream stream = new FileStream(filename, FileMode.Open))
		{
			JpegBitmapDecoder decoder = new JpegBitmapDecoder(stream,
										BitmapCreateOptions.PreservePixelFormat,
										BitmapCacheOption.None);

			// Extract the photo's metadata
			BitmapMetadata metadata = (BitmapMetadata)decoder.Frames[0].Metadata;

			// Read out the date taken property...
            // ...  via the built-in property (as a System.DateTime)
			DateTime dateTaken1 = DateTime.Parse(metadata.DateTaken);

			// ... or via a query (as a string)
			string dateTaken2 = (string)metadata.GetQuery("/app1/ifd/exif/subifd:{uint=36867}");

			// And the ISO (unsigned short integer)
			ushort iso = (ushort)metadata.GetQuery("/app1/ifd/exif/subifd:{uint=34855}");

			// other properties can be read using similar methods...
		}
    }
}</pre>
<h3>Accessing EXIF data with Powershell</h3>
<p>Since PowerShell has easy access to the .NET framework, grabbing metadata from a photo using PowerShell is just as easy as doing it in C#, which makes it great for scripting photo tasks.  First up is the System.Drawing/Windows Forms version:</p>
<pre class="brush:plain"># Load the System.Drawing DLL before doing any operations
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") > $null

# And System.Text if reading any of the string fields
[System.Reflection.Assembly]::LoadWithPartialName("System.Text") > $null

# Create an Image object
$photo = [System.Drawing.Image]::FromFile($filename)

# Read out the date taken property (string)
$dateProperty = $photo.GetPropertyItem(0x9003)
$dateTaken = (new-object System.Text.UTF8Encoding).GetString($dateProperty.Value)

# And the ISO (unsigned short integer)
$isoProperty = $photo.GetPropertyItem(0x8827)
$iso = [System.BitConverter]::ToUInt16($isoProperty.Value, 0)

# other properties can be read using similar methods...

# Dispose of the Image once we're done using it
$photo.Dispose()</pre>
<p>We can also use the System.Windows.Media.Imaging/WPF version from PowerShell.  Like the C# version, some values are exposed through properties on the <a title="BitmapMetadata Properties (System.Windows.Media.Imaging)" href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapmetadata_properties.aspx">BitmapMetadata</a> object directly; the rest must be accessed using the <a title="BitmapMetadata.GetQuery Method (System.Windows.Media.Imaging)" href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapmetadata.getquery.aspx">GetQuery</a> method.  Queries take the form <code>/app1/ifd/exif:{uint=999}</code> or <code>/app1/ifd/exif/subifd:{uint=99999}</code>, depending on the tag you&#8217;re accessing.  In general, tags less than 1000 (decimal) are accessed using the former syntax, those greater using the latter syntax.</p>
<pre class="brush:plain"># Load the System.Windows.Media.Imaging DLL before doing any operations
[System.Reflection.Assembly]::LoadWithPartialName("PresentationCore") > $null

# Load and decode the photo
$stream = new-object System.IO.FileStream($filename, [System.IO.FileMode]::Open)
$decoder = new-object System.Windows.Media.Imaging.JpegBitmapDecoder($stream,
           [System.Windows.Media.Imaging.BitmapCreateOptions]::PreservePixelFormat,
           [System.Windows.Media.Imaging.BitmapCacheOption]::None)

# Extract the photo's metadata
$metadata = $decoder.Frames[0].Metadata

# Read out the date taken property...
# ...  via the built-in property (as a System.DateTime)
$dateTaken1 = $metadata.DateTaken
# ... or via a query (as a string)
$dateTaken2 = $metadata.GetQuery("/app1/ifd/exif/subifd:{uint=36867}")

# And the ISO (unsigned short integer)
$iso = $metadata.GetQuery("/app1/ifd/exif/subifd:{uint=34855}")

# other properties can be read using similar methods...

# Dispose of the FileStream once we're done using it
$stream.Dispose()</pre>
<h2>EXIF Tag Reference</h2>
<p>The numbers used in the examples above can be found in the table below.  This table is not intended to be comprehensive &#8211; there is <em>far</em> too much complexity in the EXIF format for that.  Most manufacturers add their own information in proprietary formats (you can usually decode this, but you need to support each manufacturer separately &#8211; Canon camera&#8217;s don&#8217;t write the Nikon fields), and not all cameras write all fields, and there are non-EXIF storage formats that are used as well (XMP, IPTC, ID3, and more).  If you  are looking for comprehensive, I&#8217;d recommend <a title="EXIF Tags" href="http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html">this page</a> on Phil Harvey&#8217;s ExifTool site; otherwise, here&#8217;s a list of the most common, relatively standard ones.  All integers are 32 bits in length, except those with the notation &#8216;short&#8217;; they are 16 bits in length.  Integer rationals are stored XY, where the value is equal to X/Y; most are 64 bits in length (two 32 bit integers back-to-back).</p>
<table border="0" cellspacing="0" cellpadding="0" width="99%">
<thead>
<tr>
<td>Decimal Value</td>
<td>Hex Value</td>
<td style="min-width:123px;">Data Type</td>
<td>Tag Name</td>
<td>Notes</td>
</tr>
</thead>
<tbody>
<tr>
<td>271</td>
<td>0x010f</td>
<td>ASCII string</td>
<td>Equipment Maker</td>
<td>‘Canon&#8217;, &#8216;Nikon&#8217;, etc.</td>
</tr>
<tr class="odd">
<td>272</td>
<td>0&#215;0110</td>
<td>ASCII string</td>
<td>Equipment Model</td>
<td>‘Canon PowerShot S5 IS&#8217;, etc.</td>
</tr>
<tr>
<td>274</td>
<td>0&#215;0112</td>
<td>integer<br />(unsigned short)</td>
<td>Orientation</td>
<td>1 = Horizontal<br />3 = Rotate 180 degrees<br />6 = Rotate 90 degrees clockwise<br />8 = Rotate 270 degrees clockwise</td>
</tr>
<tr class="odd">
<td>282</td>
<td>0x011a</td>
<td>integer<br />(unsigned short)</td>
<td>X Resolution</td>
<td>Unit in Resolution Unit field (for pixels, see Pixel X Dimension field)</td>
</tr>
<tr>
<td>283</td>
<td>0x011b</td>
<td>integer<br />(unsigned short)</td>
<td>Y Resolution</td>
<td>Unit in Resolution Unit field (for pixels, see Pixel Y Dimension field)</td>
</tr>
<tr class="odd">
<td>296</td>
<td>0&#215;0128</td>
<td>integer<br />(unsigned short)</td>
<td>Resolution Unit</td>
<td>1 = None<br />2 = Inches<br />3 = Centimetres</td>
</tr>
<tr>
<td>306</td>
<td>0&#215;0132</td>
<td>ASCII string</td>
<td>Modified Date Time</td>
<td>YYYY:MM:DD HH:MM:SS</td>
</tr>
<tr class="odd">
<td>33434</td>
<td>0x829a</td>
<td>integer rational<br />(unsigned)</td>
<td>Exposure Time</td>
<td>First integer divided by the second integer produces the exposure time in seconds; for example, a value of &#8217;1&#8242; followed by a value of &#8217;50&#8242; is an exposure time of 1/50th of a second.</td>
</tr>
<tr>
<td>33437</td>
<td>0x829d</td>
<td>integer rational<br />(unsigned)</td>
<td>F Number</td>
<td>First integer divided by the second integer produces the F number; for example, a value of &#8217;35&#8242; followed by a value of &#8217;10&#8242; is F/3.5.</td>
</tr>
<tr class="odd">
<td>34855</td>
<td>0&#215;8827</td>
<td>integer<br />(unsigned short)</td>
<td>ISO Speed</td>
<td>100, 200, 400, etc.</td>
</tr>
<tr>
<td>36867</td>
<td>0&#215;9003</td>
<td>ASCII string</td>
<td>Date Taken</td>
<td>YYYY:MM:DD HH:MM:SS</td>
</tr>
<tr class="odd">
<td>36868</td>
<td>0&#215;9004</td>
<td>ASCII string</td>
<td>Date Created</td>
<td>YYYY:MM:DD HH:MM:SS</td>
</tr>
<tr>
<td>37377</td>
<td>0&#215;9201</td>
<td>integer rational (signed)</td>
<td>Shutter Speed</td>
<td>&#160;</td>
</tr>
<tr class="odd">
<td>37378</td>
<td>0&#215;9202</td>
<td>integer rational (unsigned)</td>
<td>Aperture</td>
<td>&#160;</td>
</tr>
<tr>
<td>37380</td>
<td>0&#215;9204</td>
<td>integer rational (signed)</td>
<td>Exposure Compensation</td>
<td>First integer divided by the second integer produces the exposure compensation; for example, a value of &#8217;2&#8242; followed by a value of &#8217;3&#8242; is +2/3</td>
</tr>
<tr class="odd">
<td>37381</td>
<td>0&#215;9205</td>
<td>integer rational (unsigned)</td>
<td>Maximum Aperature</td>
<td>&#160;</td>
</tr>
<tr>
<td>37383</td>
<td>0&#215;9207</td>
<td>integer<br />(unsigned short)</td>
<td>Metering Mode</td>
<td>0 = Unknown<br />1 = Average<br />2 = Center-weighted average<br />3 = Spot<br />4 = Multi-spot<br />5 = Multi-segment<br />6 = Partial<br />255 = Unknown</td>
</tr>
<tr class="odd">
<td>37385</td>
<td>0&#215;9209</td>
<td>integer<br />(unsigned short)</td>
<td>Flash</td>
<td>0 = No Flash<br />LSB (8th bit) set = Flash Fired<br />bits 4&amp;5, L-R:<br />10 = Flash off<br />01 = Flash on<br />11 = Flash auto</td>
</tr>
<tr>
<td>37386</td>
<td>0x920a</td>
<td>integer rational<br />(unsigned)</td>
<td>Focal Length</td>
<td>&#160;</td>
</tr>
<tr class="odd">
<td>37500</td>
<td>0x927c</td>
<td>N/A</td>
<td>Equipment Maker Note</td>
<td>Camera Maker specific information</td>
</tr>
<tr>
<td>37510</td>
<td>0&#215;9286</td>
<td>integer (signed)</td>
<td>User Comment</td>
<td>&#160;</td>
</tr>
<tr class="odd">
<td>40961</td>
<td>0xa001</td>
<td>integer<br />(unsigned short)</td>
<td>Color Space</td>
<td>1 = sRGB</td>
</tr>
<tr>
<td>40962</td>
<td>0xa002</td>
<td>integer<br />(unsigned short)</td>
<td>Pixel X Dimension</td>
<td>In pixels</td>
</tr>
<tr class="odd">
<td>40963</td>
<td>0xa003</td>
<td>integer<br />(unsigned short)</td>
<td>Pixel Y Dimension</td>
<td>In pixels</td>
</tr>
<tr>
<td>41486</td>
<td>0xa20e</td>
<td>integer<br />(unsigned short)</td>
<td>Focal Plane X Resolution</td>
<td>&#160;</td>
</tr>
<tr class="odd">
<td>41487</td>
<td>0xa20f</td>
<td>integer<br />(unsigned short)</td>
<td>Focal Plane Y Resolution</td>
<td>&#160;</td>
</tr>
<tr>
<td>41488</td>
<td>0xa210</td>
<td>integer<br />(unsigned short)</td>
<td>Focal Plane Resolution Unit</td>
<td>1 = None<br />2 = Inches<br />3 = Centimetres<br />4 = Millimetres<br />5 = Micrometres</td>
</tr>
<tr class="odd">
<td>41495</td>
<td>0xa217</td>
<td>integer<br />(unsigned short)</td>
<td>Sensing Method</td>
<td>1 = Not defined<br />2 = One-chip colour area<br />3 = Two-chip colour area<br />4 = Three-chip colour area<br />5 = Colour sequential area<br />7 = Trilinear<br />8 = Colour sequential linear</td>
</tr>
<tr>
<td>41728</td>
<td>0xa300</td>
<td>integer (signed)</td>
<td>File Source</td>
<td>1 = Film scanner<br />2 = Reflection print scanner<br />3 = Digital camera</td>
</tr>
<tr class="odd">
<td>41985</td>
<td>0xa401</td>
<td>integer<br />(unsigned short)</td>
<td>Custom Rendered</td>
<td>0 = Normal<br />1 = Custom</td>
</tr>
<tr>
<td>41986</td>
<td>0xa402</td>
<td>integer<br />(unsigned short)</td>
<td>Exposure Mode</td>
<td>0 = Auto<br />1 = Manual<br />2 = Auto Bracket</td>
</tr>
<tr class="odd">
<td>41987</td>
<td>0xa403</td>
<td>integer<br />(unsigned short)</td>
<td>White Balance</td>
<td>0 = Auto<br />1 = Manual</td>
</tr>
<tr>
<td>41988</td>
<td>0xa404</td>
<td>integer rational<br />(unsigned)</td>
<td>Digital Zoom Ratio</td>
<td>&#160;</td>
</tr>
<tr class="odd">
<td>41989</td>
<td>0xa405</td>
<td>integer<br />(unsigned short)</td>
<td>Focal Length in 35 mm Format</td>
<td>&#160;</td>
</tr>
<tr>
<td>41990</td>
<td>0xa406</td>
<td>integer<br />(unsigned short)</td>
<td>Scene Capture Type</td>
<td>0 = Standard<br />1 = Landscape<br />2 = Portrait<br />3 = Night</td>
</tr>
<tr class="odd">
<td>41991</td>
<td>0xa407</td>
<td>integer<br />(unsigned short)</td>
<td>Gain Control</td>
<td>0 = None<br />1 =Low gain up<br />2 = High gain up<br />3 = Low gain down<br />4 = High gain down</td>
</tr>
<tr>
<td>41992</td>
<td>0xa408</td>
<td>integer<br />(unsigned short)</td>
<td>Contrast</td>
<td>0 = Normal<br />1 = Low<br />2 = High</td>
</tr>
<tr class="odd">
<td>41993</td>
<td>0xa409</td>
<td>integer<br />(unsigned short)</td>
<td>Saturation</td>
<td>0 = Normal<br />1 = Low<br />2 = High</td>
</tr>
<tr>
<td>41994</td>
<td>0xa40a</td>
<td>integer<br />(unsigned short)</td>
<td>Sharpness</td>
<td>0 = Normal<br />1 = Soft<br />2 = Hard</td>
</tr>
<tr class="odd">
<td>41996</td>
<td>0xa40c</td>
<td>integer (unsigned short)</td>
<td>Subject Distance Range</td>
<td>0 = Unknown<br />1 = Macro<br />2 = Close<br />3 = Distant</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://nicholasarmstrong.com/2010/02/exif-quick-reference/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Better Printed Photos: Naming with Date Taken</title>
		<link>http://nicholasarmstrong.com/2010/01/better-printed-photos-naming-with-date-taken/</link>
		<comments>http://nicholasarmstrong.com/2010/01/better-printed-photos-naming-with-date-taken/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 17:32:47 +0000</pubDate>
		<dc:creator>Nicholas Armstrong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[code sample]]></category>
		<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://nicholasarmstrong.com/?p=275</guid>
		<description><![CDATA[Whenever I’ve needed to print digital photos, I’ve found that Photolab – the photo processing arm of the Canadian grocery chain Loblaws – has always done a great job.  Photos are typically printed in a day or less, are easy to pick up – just stop by your local supermarket! – and have always turned [...]]]></description>
			<content:encoded><![CDATA[<p>Whenever I’ve needed to print digital photos, I’ve found that <a href="http://photolab.ca/">Photolab</a> – the photo processing arm of the Canadian grocery chain Loblaws – has always done a great job.  Photos are typically printed in a day or less, are easy to pick up – just stop by your local supermarket! – and have always turned out excellently.  And they are reasonably inexpensive, too.</p>
<p>For as long as I can remember, my parents have been labelling the back of the photos in their photo albums with the month they were taken.  That way, when browsing an album years in the future it is easy to see exactly when something happened and how old I was at the time (they sometimes label the people and the places as well, depending on how non-obvious these attributes are in the photo itself).  Though it takes a bit of work to make all these annotations, the outcome is well worth it in the end.</p>
<p>With traditional film, there are few alternatives to manually annotating photos; ‘burning’ the date into the photo itself is one technique, but obscures some of the image as a result.  But with digital photos, this information – and much more – is stored alongside the photo by the digital camera.  And on the back of the prints we get back from Photolab/Zehrs, they conveniently print the photo filename on the back of the photos.  Wouldn’t it be nice if we could put the date into the filename to make annotating our photos easier?</p>
<h2>Naming photos for printing with PowerShell</h2>
<p>With my <a href="http://nicholasarmstrong.com/2009/12/sending-email-with-powershell-implicit-and-explicit-ssl/">new-found interest</a> in scripting with PowerShell, I figured that there must be a way to automatically name files based on the date they were taken.  Sure enough, there was – the <a title="Image Class (System.Drawing)" href="http://msdn.microsoft.com/en-us/library/system.drawing.image.aspx">Image</a> class, part of the System.Drawing namespace, allows reading of the EXIF data stored by the camera in the photo.</p>
<pre class="brush:plain"># Load image and get EXIF date
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") &gt; $null
$photo = [System.Drawing.Image]::FromFile($file)
try
{
	$dateProp = $photo.GetPropertyItem(36867)
}
catch
{
	try
	{
		$dateProp = $photo.GetPropertyItem(306)
	}
	catch
	{
		continue
	}
}
$photo.Dispose()</pre>
<p>While it is rather straightforward to get EXIF metadata in general from a photo, it takes a bit more work to get the precise data you want.  EXIF data is stored as key:value pairs in the image, with the keys being standardized numerical identifiers.  Here, we first try to access the ‘Date Taken’ value with key 36867, and should that fail, the ‘Date Time’ value with key 306.  These numbers are completely unintuitive, but can be found at various places on the web; an extensive list (if you already know what you are looking for) is in enumeration format <a title="Using Properties from within GDI+, for now a basic enumeration - Justin Rogers" href="http://weblogs.asp.net/justin_rogers/pages/108237.aspx">here</a>.  If neither can be accessed, we skip renaming the file; this is likely the result editing the photo with a program that does not preserve this data.</p>
<p>Once we’ve retrieved the date the photo was taken from the EXIF metadata, we still have to parse it into a string that we can use for our filename.  The data is stored using UTF8 encoding, so we first transform the raw bytes into a string, and then pull the useful parts of the date out into separate variables.</p>
<pre class="brush:plain"># Convert date taken metadata to appropriate fields
[System.Reflection.Assembly]::LoadWithPartialName("System.Text") &gt; $null
$encoding = New-Object System.Text.UTF8Encoding
$date = $encoding.GetString($dateProp.Value).Trim()
$year = $date.Substring(0,4)
$month = $date.Substring(5,2)
$day = $date.Substring(8,2)</pre>
<p>With that data (and a simple regex), I finished the script by renaming the file into the form ‘YYYY.MM.DD.iNNNN.jpg’, where NNNN is the four-digit image number of the original file (my parent’s camera, a Canon, names files IMG_NNNN.jpg; other manufactures use similar formats).  Now when we print our photos, we don’t need to add the date by hand – the script ensures that a string like ‘2010.01.05.i1234.jpg’ is printed on the back of our photo, which tells us the date (January 5th, 2010) as well as what to search for if we need to print another copy (‘1234’, which finds the original image ‘IMG_1234.jpg’ (again, this example is for Canon cameras)).</p>
<h2>Renaming Files with Date Taken: The Full Script</h2>
<p>The next time you need to send photos for printing, give the script a try.  Running the script is easy; simply make a copy of all the photos you want to print into a new folder, and save the following PowerShell script into the directory with the photos for printing.  Then, right-click on the script and select ‘Run with PowerShell’.  The script scans the directory, finds all of the images, and then renames them based on the ‘Date Taken’ EXIF field.</p>
<p><a href="http://code.nicholasarmstrong.com/posts/blog/NameForPrinting/NameForPrinting.ps1">PowerShell Date Taken Naming Script</a> [ps1, 6.7K]</p>
]]></content:encoded>
			<wfw:commentRss>http://nicholasarmstrong.com/2010/01/better-printed-photos-naming-with-date-taken/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sending Email with PowerShell: Implicit and Explicit SSL</title>
		<link>http://nicholasarmstrong.com/2009/12/sending-email-with-powershell-implicit-and-explicit-ssl/</link>
		<comments>http://nicholasarmstrong.com/2009/12/sending-email-with-powershell-implicit-and-explicit-ssl/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 21:44:54 +0000</pubDate>
		<dc:creator>Nicholas Armstrong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[code sample]]></category>
		<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://nicholasarmstrong.com/?p=268</guid>
		<description><![CDATA[I never quite understood the attraction of scripting; sure, not having to set up the scaffolding code of a more formal language is nice, but the limitations of the environment just seemed too great.&#160; The Unix community has it far better than the Windows community in this regard; shell scripting can accomplish amazing feats – [...]]]></description>
			<content:encoded><![CDATA[<p>I never quite understood the attraction of scripting; sure, not having to set up the scaffolding code of a more formal language is nice, but the limitations of the environment just seemed too great.&#160; The Unix community has it far better than the Windows community in this regard; shell scripting can accomplish amazing feats – as long as all of the appropriate utilities are strung together in the right configuration, that is.&#160; And though scripting languages like Python and Ruby do hold some allure, it’s one more thing to install on my Windows box and learn the syntax for.&#160; So for most tasks that needed scripting, C# filled the bill – when I could justify the start-up cost.</p>
<p>Enter PowerShell, the Windows scripting language that purportedly brings together the power of Unix shell scripts with the flexibility of the .NET framework. And it’s installed by default on Windows 7, to boot.&#160; I’d seen an interesting demo of how WPF and PowerShell worked together, so when I recently found the need to send a bunch of mark reports out, I figured it was time to give it a whirl.&#160; There were a couple of tricky problems I encountered while I was throwing the script together; here’s a quick overview of sending email with PowerShell.</p>
<h2>The Basics</h2>
<p>First, we need an email to send.&#160; This should do:</p>
<pre class="brush:plain"># Mail Message
$from = &quot;user@domain.com&quot;
$to = &quot;user@domain.com&quot;
$subject = &quot;Hello from PowerShell&quot;
$body = &quot;This is a message saying hello from PowerShell.&quot;
$hasAttachment = $false
$attachmentPath = &quot;attachmentPath.txt&quot;</pre>
<p>The primary requirement for sending email is access to an SMTP server; it needn’t be on the local machine.&#160; We’ll use Gmail’s SMTP server:</p>
<pre class="brush:plain"># Mail Server Settings
$server = &quot;smtp.gmail.com&quot;
$serverPort = 587
$timeout = 30000          # timeout in milliseconds
$enableSSL = $true
$implicitSSL = $false</pre>
<p>Pretty basic stuff; here we’re using smtp.gmail.com on port 587, and we’re using an SSL-encrypted connection.&#160; We’re also <em>not</em> using implicit SSL, and instead using explicit SSL; wait, <strong>what’s the difference?</strong></p>
<h4>Explicit SSL</h4>
<p>Explicit SSL, as described <a title="Explicit versus implict SSL" href="http://help.globalscape.com/help/secureserver2/Explicit_versus_implicit_SS.htm">here</a>, means that the client first connects to the server using an unsecure channel, requests that conversations be moved to a secure channel, and then both server and client switch to a secure connection and the rest of the communication is encrypted.&#160; Though this sounds somewhat lengthy, it’s the standard procedure for setting up an SSL connection (see <a title="FTP Security Extensions" href="http://www.ietf.org/rfc/rfc2228.txt">RFC 2228</a>).&#160; Gmail handles explicit SSL without any difficulties, as do many other mail servers; Gmail’s explicit SSL server runs on port 587.</p>
<h4>Implicit SSL</h4>
<p>In contrast, implicit SSL drops the SSL negotiation and jumps right into the SSL connection to begin with. Often, this is done through a connection to a specific port that only accepts secure connections.&#160; There is no official standard for this mode of communication, though it’s widely implemented; Gmail also handles implicit SSL, this time on port 465.</p>
<h2>The Catch</h2>
<p>My local university SMTP server <em>only</em> handles implicit SSL, so I needed to find a way to work with this variant.&#160; Unfortunately, the standard .NET library for sending mail, System.Net.Mail – the one often used from PowerShell to send mail – don’t support implicit SSL.&#160; Luckily, System.Web.Mail – an older, now obsolete mail sending library residing in System.Web.dll – does support implicit SSL.&#160; </p>
<h2>Putting it all Together</h2>
<p>Now that we’ve got a strategy for handling implicit and explicit SSL, let’s code up a section of our script to handle each of these servers so we can switch back and forth easily.</p>
<p>We’re also going to need a set of credentials if we’re logging into a secure server; the <a title="Get-Credential" href="http://technet.microsoft.com/en-us/library/dd315327.aspx">Get-Credential</a> cmdlet is just the ticket:</p>
<pre class="brush:plain"># Get user credentials if required
if ($enableSSL)
{
    $credentials = [Net.NetworkCredential](Get-Credential)
}</pre>
<p>We could also prompt at the command line for a username/password combo or just hardcode these values into the script, but the Get-Credential cmdlet is an easy way to get and store just the information we need. </p>
<h3>Explicit SSL with System.Net.Mail</h3>
<p>We’ll be using the <a title="System.Net.Mail Namespace" href="http://msdn.microsoft.com/en-us/library/system.net.mail.aspx">System.Net.Mail</a> namespace to send email to servers using explicit SSL, or to servers that do not require SSL connections.</p>
<pre class="brush:plain">if (!$enableSSL -or !$implicitSSL)
{
    # Set up server connection
    $smtpClient = New-Object System.Net.Mail.SmtpClient $server, $serverPort
    $smtpClient.EnableSsl = $enableSSL
    $smtpClient.Timeout = $timeout

    if ($enableSSL)
    {
        $smtpClient.UseDefaultCredentials = $false;
        $smtpClient.Credentials = $credentials
    }

    # Create mail message
    $message = New-Object System.Net.Mail.MailMessage $from, $to, $subject, $body

    if ($hasAttachment)
    {
        $attachment = New-Object System.Net.Mail.Attachment $attachmentPath
        $message.Attachments.Add($attachment)
    }

    # Send the message
    Write-Output &quot;Sending email to $to...&quot;
    try
    {
        $smtpClient.Send($message)
        Write-Output &quot;Message sent.&quot;
    }
    catch
    {
        Write-Error $_
        Write-Output &quot;Message send failed.&quot;
    }

}</pre>
<p>Using System.Net.Mail is pretty straightforward – we create an <a title="SmtpClient Class (System.Net.Mail)" href="http://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.aspx">SmtpClient</a> to connect to the mail server with, and make the appropriate settings.&#160; Setting Timeout isn’t necessary, but since the default is really high (something like 100,000 milliseconds) and most servers respond quickly, setting it to 30 seconds ensures that the script will fail in reasonably short order if it cannot connect.</p>
<p>Creating a message is easy too – we just create a new <a title="MailMessage Class (System.Net.Mail)" href="http://msdn.microsoft.com/en-us/library/system.net.mail.mailmessage.aspx">MailMessage</a> and pass in our message to its constructor and attach any necessary files.&#160; Then we call the Send function on the SmtpClient we created, and the message goes on its merry way.</p>
<p>Users of PowerShell version 2 or greater can also make use of the <a title="Send-MailMessage" href="http://technet.microsoft.com/en-us/library/dd347693.aspx">Send-MailMessage</a> cmdlet, which wraps System.Net.Mail in an easy-to-use cmdlet.</p>
<h3>Implicit SSL with System.Web.Mail</h3>
<p>For servers that only support Implicit SSL, we’ll be using the <a title="System.Web.Mail Namespace" href="http://msdn.microsoft.com/en-us/library/system.web.mail.aspx">System.Web.Mail</a> namespace.&#160; This namespace has been made obsolete in favour of the newer System.Net.Mail namespace, but at the current time it’s still included in the .NET Framework and so we can take advantage of it here.&#160; </p>
<pre class="brush:plain">else
{
    # Load System.Web assembly
    [System.Reflection.Assembly]::LoadWithPartialName(&quot;System.Web&quot;) &gt; $null

    # Create a new mail with the appropriate server settigns
    $mail = New-Object System.Web.Mail.MailMessage
    $mail.Fields.Add(&quot;http://schemas.microsoft.com/cdo/configuration/smtpserver&quot;, $server)
    $mail.Fields.Add(&quot;http://schemas.microsoft.com/cdo/configuration/smtpserverport&quot;, $serverPort)
    $mail.Fields.Add(&quot;http://schemas.microsoft.com/cdo/configuration/smtpusessl&quot;, $true)
    $mail.Fields.Add(&quot;http://schemas.microsoft.com/cdo/configuration/sendusername&quot;, $credentials.UserName)
    $mail.Fields.Add(&quot;http://schemas.microsoft.com/cdo/configuration/sendpassword&quot;, $credentials.Password)
    $mail.Fields.Add(&quot;http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout&quot;, $timeout / 1000)
    # Use network SMTP server...
    $mail.Fields.Add(&quot;http://schemas.microsoft.com/cdo/configuration/sendusing&quot;, 2)
    # ... and basic authentication
    $mail.Fields.Add(&quot;http://schemas.microsoft.com/cdo/configuration/smtpauthenticate&quot;, 1)

    # Set up the mail message fields
    $mail.From = $from
    $mail.To = $to
    $mail.Subject = $subject
    $mail.Body = $body

    if ($hasAttachment)
    {
        # Convert to full path and attach file to message
        $attachmentPath = (get-item $attachmentPath).FullName
        $attachment = New-Object System.Web.Mail.MailAttachment $attachmentPath
        $mail.Attachments.Add($attachment) &gt; $null
    }

    # Send the message
    Write-Output &quot;Sending email to $to...&quot;
    try
    {
        [System.Web.Mail.SmtpMail]::Send($mail)
        Write-Output &quot;Message sent.&quot;
    }
    catch
    {
        Write-Error $_
        Write-Output &quot;Message send failed.&quot;
    }
}</pre>
<p>As we can see, using System.Web.Mail is quite a bit more convoluted.&#160; First up is loading the System.Web DLL, which is where this namespace resides.&#160; Then, we configure the mail client using <a title="Overview of CDO" href="http://msdn.microsoft.com/en-us/library/aa140862%28office.10%29.aspx">CDO</a> fields; most of them have pretty obvious settings, though <em>sendusing</em> and <em>smtpauthenticate</em> are a little obtuse (see the comments in the script for what each value means).&#160; Unlike System.Net.Mail, these server settings are made on the <a title="MailMessage Class (System.Web.Mail)" href="http://msdn.microsoft.com/en-us/library/system.web.mail.mailmessage.aspx">MailMessage</a> class itself, which is also where we set the message properties and add any necessary attachments.&#160; Finally, we send the mail using the <a title="SmtpMail.Send Method (System.Web.Mail)" href="http://msdn.microsoft.com/en-us/library/system.web.mail.smtpmail.send.aspx">Send</a> static function on <a title="SmtpMail Class (System.Web.Mail)" href="http://msdn.microsoft.com/en-us/library/system.web.mail.smtpmail.aspx">SmtpMail</a>, and the message goes on its merry way just as before </p>
<h3>A Final Note for Gmail Users</h3>
<p>Gmail’s authentication settings are a bit strange; in my testing, I’ve found that you need to enter <em>just</em> your username (<em>not</em> username@gmail.com) in order to authenticate with their SMTP servers.&#160; This causes a bit of a problem with Google Apps installations, which also use smtp.gmail.com as their SMTP gateway; username@domain does not work, and I’ve yet to find a workaround.</p>
<p>Also, while Gmail supports explicit and implicit SSL, it does so on different ports – 587 and 465, respectively.</p>
<h2>Sending Email with PowerShell – Piece of Cake!</h2>
<p>After a bit of hacking, I now understand just what those scripting folks feel when the advocate for scripting environments – it really is quite easy to accomplish what you need to accomplish without a whole lot of code.&#160; And even though I needed to drop into the .NET framework to get classes to deal with explicit and implicit SMTP servers, that was hardly a problem – those classes integrated with the rest of my PowerShell script seamlessly.&#160; PowerShell is certainly a very powerful environment, and I’m glad to add it to my technical bag of tricks.</p>
<p><a href="http://code.nicholasarmstrong.com/posts/blog/PowerShellEmail/PowerShellEmail.ps1">PowerShell Email Script</a> [ps1, 3.2K].</p>
]]></content:encoded>
			<wfw:commentRss>http://nicholasarmstrong.com/2009/12/sending-email-with-powershell-implicit-and-explicit-ssl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Technical Protectionism</title>
		<link>http://nicholasarmstrong.com/2009/10/technical-protectionism/</link>
		<comments>http://nicholasarmstrong.com/2009/10/technical-protectionism/#comments</comments>
		<pubDate>Sun, 18 Oct 2009 21:48:45 +0000</pubDate>
		<dc:creator>Nicholas Armstrong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://nicholasarmstrong.com/2009/10/technical-protectionism/</guid>
		<description><![CDATA[There’s a well known concept in economics known as comparative advantage.&#160; A formal definition has many nuances, but the basic principle can be summed up as each party undertaking the work that they are most productive at, such that the overall production of the system is higher than it would be if each party performed [...]]]></description>
			<content:encoded><![CDATA[<p>There’s a well known concept in economics known as <em>comparative advantage</em>.&#160; A formal definition has many nuances, but the basic principle can be summed up as each party undertaking the work that they are most productive at, such that the overall production of the system is higher than it would be if each party performed tasks they were less productive with.&#160; For example, if Farmer A’s farm could grow 100 bushels of apples or 200 bushels of carrots a year, and Farmer B’s farm could grow 75 bushels of apples or 50 bushels of carrots, then the highest production occurs when Farmer A grows carrots and Farmer B grows apples (75 + 200 = 275 bushels total).&#160; This is the case even though Farmer A can grow more apples than Farmer B; if there were demand for 100 bushels of apples, the best way of growing them is to have Farmer A grow 25 bushels and Farmer B grow 75 – total output is 100 bushels of apples and 150 bushels of carrots, which maximizes total output under the constraint that at least 100 bushels of apples must be grown.&#160; Since Farmer A is better at growing carrots, then it’s always economically beneficial for him/her to do so.</p>
<p>Though this example looks at farmers, it applies to countries as well.&#160; However, the use of regulations can complicate the analysis, as regulations can be applied (through tariffs, import controls, or other measures) to artificially tip the scales in favour of one party.&#160; If Farmer A were restricted to exporting 50 bushels of carrots, and not restricted on apples, then the market realities would result in Farmer A growing primarily apples even though he/she can grow carrots much more easily.&#160; And as a result, the total output of the economy is reduced to 200 bushels, down from 275.&#160; On the surface, applying regulations seems to be a pretty irrational thing to do – why would we work harder and produce less?</p>
<p>The answer to that question lies in the reasons behind applying those regulations, to which there are many.&#160; The one I want to focus on today is protectionism – policies designed to ‘protect’ workers and businesses in a country from outside competition.&#160; If India is able to produce technical workers more cheaply than North America can, then market pressures tend to result in those jobs being performed by Indian workers.&#160; But, you exclaim, they’re stealing our jobs!&#160; Outsourcing is bad!&#160; Of course we should have regulations in place to stop it!</p>
<p>Economists have many good reasons why this isn’t be the case – foremost amongst them the principle of comparative advantage – as even considering these job losses the economy is still better off as a whole.&#160; Though jobs are lost in the short term, in the longer term the local economy picks up the slack in areas the country is more suited to, resulting in a net gain.&#160; The rise of information technology is one example of this; when computers were made domestically in North America, they were relatively rare and obtaining one was expensive.&#160; By manufacturing them in countries with lower manufacturing costs, computers became mainstream and widespread – and we’ve subsequently built a massive business sector on top of them.&#160; For all practical purposes, the Internet as we know it today wouldn’t exist without low-cost computers, and had we regulated the economy to discourage the outsourcing of computer manufacturing, we’d be years behind where we are today.&#160; Granted, we missed out on the jobs that might have existed had we done that, but at the same time we’ve gained an entire sector of jobs in companies like Google, Microsoft, HP, Amazon, and the many, many tech startup companies.&#160; And then we’ve created a whole host of jobs to support those jobs – would Google’s chef’s have a job if Google weren’t around?&#160; Change is always hard, but by allowing it to happen we have indirectly benefitted ourselves – and the rest of the world!</p>
<p>The crux of this post is not comparative advantage and economic protectionism, but rather something I’m going to call <em>technical protectionism</em>.&#160; In the tech field, the players aren’t so much people or companies, but rather, technologies themselves.&#160; Few people would argue that Ruby is a better language to write web applications in than C, or that Photoshop is better than Paint, or that Mac is better than PC (just kidding!).&#160; Actually, it’s that last one that is entirely my point; the Mac versus PC debate will continue indefinitely, as many of those doing the debating are debating for solely protectionist reasons.&#160; There are completely valid technical (and non-technical) reasons why Mac is better than PC, and why PC is better than Mac, but more often than not the discussions seem to take place on a ‘it’s right for me, so it’s right for you’ level that lobs orthogonal arguments toward the opposing side in an attempt to win by attrition or disinterest.</p>
<p>The frustrating part in this whole issue is that, unlike with economic protectionism, technical protectionism is condoned by the tech community.&#160; When the US introduced ‘Buy American’ clauses into some of their economic stimulus packages, experts on both side of the border – and the media to some extent – erupted in condemnation.&#160; Now consider the last time you got into or observed a Mac versus PC, Windows versus Linux, Python versus Ruby style argument: those sorts of arguments are expected – and tolerated – by the technical community!</p>
<p>In my experience, these debates are intrinsically motivated by the participant’s own familiarity with a particular technology: I know how to build programs in technology X, therefore technology X is the right one to solve your problem with.&#160; You see this all over the place – just look at small consulting firms, which often specialize in a single technology stack (Microsoft, IBM, Oracle, LAMP, etc.).&#160; Having one of these firms pitch you a solution inevitably means them pitching a solution that runs on their stack without consideration of the others – if you want a vacation-planning application for 50 employees from an Oracle firm, then you’ll be paying for an enterprise grade Oracle database, regardless of whether a cheap LAMP application would have sufficed.&#160; Sure, it may be unfair for them to pitch the value of another company’s services, but at what point should they be saying ‘this is not something we do well’, and voluntarily withdrawing from consideration so not to waste everyone’s time?&#160; </p>
<p>Even taking a step back from companies, this behaviour is present even in the colleagues I interact with.&#160; Since I worked at Microsoft, in technical debates I am automatically assumed to be the enemy of everything open source and the chief defender of everything Windows.&#160; And while my experience gives me the ability to understand Windows’ capabilities and limitations, I’m not going to side with it automatically – it depends on the situation.&#160; If you need a cheap server with a small application, <em>Windows isn’t right</em>.&#160; If you need an expensive server with&#160; a massive application, <em>Windows isn’t right</em>.&#160; If you need a moderately expensive server with a medium sized application, <em>Windows isn’t right</em>.&#160; And you know what?&#160; You can replace ‘Windows’ in the previous three sentences with ‘Linux’, ‘Mac’, or any other technology – without looking at the precise details of the situation, it’s impossible to tell which combination of features and capabilities are appropriate for the problem at hand.</p>
<p>My fundamental point here is that it is impossible for one technology to solve <em>every</em> problem in the best way possible.&#160; Comparative advantage tells us that the best way of solving all of problems is to choose the right tool for the job, regardless of what that tool might be.&#160; Granted, choosing a tool is nowhere near as straightforward as counting bushels of produce, but the principle still applies: use the combined strength of all parties to the best of their individual abilities.&#160; Sure, we have to make allowances for expertise and to minimize tool diversity to keep overall costs down, but supporting the notion that one can advocate for a particular approach solely because it’s what they know or believe is unproductive.&#160; And yes, that means that you’re favourite solution won’t always win &#8211; and that’s OK.&#160; By choosing the best tool for the job, we’ll have a better outcome in the end.</p>
<p>That’s not to say that having opposing products and companies isn’t useful – it is.&#160; Sometimes you need to go against the grain and tackle the hard problems.&#160; But when you do, use the best tools for the job and not the ones you know just for the sake of doing so.&#160; Firefox is the browser it is because IE languished at the top of the market, and made no effort to improve.&#160; Competition from Firefox was good, as it made developers on both teams compete to have the better browser.&#160; At the same time, however, notice that the Firefox team didn’t start from scratch – they took the best technology that was available to them (Netscape) and made it better, rather than taking a protectionist approach and using what they knew.&#160; Innovation occurs when we create something new, not when we take the long way to get to where we’ve already been.</p>
<p>As a community, we need to dispel the notion that technical protectionism is an acceptable attitude to have.&#160; Objective criteria and constraints can be found for every problem we need to solve, and technologies can be evaluated against them impartially.&#160; The next time you encounter an argument from a protectionist position, make sure to call it out, and make it know that this sort of justification is unacceptable.&#160; Just as with outsourcing and the Internet, eliminating technical protectionism can have profound benefits we cannot even imagine, and until we start down that road, we’ll never know what we’re missing.</p>
]]></content:encoded>
			<wfw:commentRss>http://nicholasarmstrong.com/2009/10/technical-protectionism/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ECE 150 Programming Samples</title>
		<link>http://nicholasarmstrong.com/2009/09/ece-150-programming-samples/</link>
		<comments>http://nicholasarmstrong.com/2009/09/ece-150-programming-samples/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 02:28:05 +0000</pubDate>
		<dc:creator>Nicholas Armstrong</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[Waterloo]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[code sample]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://nicholasarmstrong.com/2009/09/ece-150-programming-samples/</guid>
		<description><![CDATA[This term, I’ve been given a position as a teaching assistant for ECE 150: Introduction to Programming at the University of Waterloo.  In the spirit of learning, I’ve decided to put together a handful of applications over the course of the term in order to demonstrate various features of the C# language for programming beginners.]]></description>
			<content:encoded><![CDATA[<p>This term, I’ve been given a position as a teaching assistant for ECE 150: Introduction to Programming at the University of Waterloo.&#160; Taught in C#, ECE 150 covers most of the basic features of programming languages and how programs are written, and assumes no basic programming knowledge on the part of the students taking it.&#160; Unfortunately for me, that means most of the cool parts of C# and the .NET framework – LINQ, WPF, WCF, ASP.NET MVC, and even language features like generics, anonymous functions, and lambda expressions – are off limits.&#160; However, it also means I need to know the basics <em>really well</em>; one of the other TAs and I were asked today the difference between <kbd>int.Parse()</kbd> [used in the lecture slides] and <kbd>Convert.ToInt32()</kbd> [used in the textbook]; the answer, as I found out, was <a title="Performance Profiling Parse vs. TryParse vs. ConvertTo" href="http://blogs.msdn.com/ianhu/archive/2005/12/19/505702.aspx">quite subtle</a> (<strong>NB:</strong> for students in the course, the difference isn’t relevant – use whichever you desire).</p>
<p>In that spirit, I’ve decided to put together a handful of applications over the course of the term in order to demonstrate various features of the C# language for programming beginners.&#160; All of the samples will be available via my <a title="ECE 150: Introduction to Programming | NicholasArmstrong.com" href="http://nicholasarmstrong.com/projects/teaching/ece150/">ECE 150 page</a>, and will be updated as the term progresses.&#160; How many I get done is entirely dependent on the amount of time and number of ideas I have; those that do get made will roughly correspond to each week’s content, and we’ll use them in the final review.&#160; <a href="http://code.nicholasarmstrong.com/teaching/ece150/">Full source code</a> for each application is also available for those who want a deeper look into some of the features of C# and the .NET platform.</p>
<p>Check them all out at <a title="ECE 150: Introduction to Programming | NicholasArmstrong.com" href="http://nicholasarmstrong.com/projects/teaching/ece150/">http://nicholasarmstrong.com/projects/teaching/ece150/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nicholasarmstrong.com/2009/09/ece-150-programming-samples/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Computer Engineering: A Graphical Overview</title>
		<link>http://nicholasarmstrong.com/2009/09/computer-engineering-a-graphical-overview/</link>
		<comments>http://nicholasarmstrong.com/2009/09/computer-engineering-a-graphical-overview/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 12:00:11 +0000</pubDate>
		<dc:creator>Nicholas Armstrong</dc:creator>
				<category><![CDATA[Waterloo]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[graphic]]></category>

		<guid isPermaLink="false">http://nicholasarmstrong.com/?p=211</guid>
		<description><![CDATA[During my 4A term at the University of Waterloo, a set of events that I don’t fully understand myself resulted in me becoming the yearbook editor for the Computer Engineering 2009 (8-stream) class.  When I was putting together our pages, I stumbled across Wordle – a web application for generating word clouds – and thought [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_212" class="wp-caption alignleft" style="width: 243px"><a href="http://nicholasarmstrong.com/wp-content/uploads/2009/09/ComputerEngineeringGraphicalOverview.pdf"><img class="size-full wp-image-212" title="CompEngGraphicalOverview_thumb" src="http://nicholasarmstrong.com/wp-content/uploads/2009/09/CompEngGraphicalOverview_thumb.png" alt="Computer Engineering: A Graphical Overview" width="233" height="180" /></a><p class="wp-caption-text">Computer Engineering: A Graphical Overview</p></div>
<p>During my 4A term at the University of Waterloo, a set of events that I don’t fully understand myself resulted in me becoming the yearbook editor for the Computer Engineering 2009 (8-stream) class.  When I was putting together our pages, I stumbled across <a title="Wordle - Beautiful Word Clouds" href="http://www.wordle.net/">Wordle</a> – a web application for generating word clouds – and thought that I could use it to sum up Computer Engineering at UW graphically.</p>
<p>For data, I used the <a title="Courses Electrical and Computer Engineering" href="http://www.ucalendar.uwaterloo.ca/0809/COURSE/course-ECE.html">ECE course descriptions</a> from the UW undergraduate calendar, filtered down to only include courses taken by computer engineering students, and with the addition of the course descriptions for core non-ECE courses (e.g. those offered through math or science).  The result was a word cloud consisting of the top 50 words used to describe computer engineering courses at the University of Waterloo, sized by the number of occurrences in course descriptions.</p>
<p>For those of you with the 2009 yearbook, I encourage you to check out the result on page 169; for everyone else, a PDF link is below.  Besides the words ‘computer’, ‘engineering’, and ‘ECE’, which were artistically weighted to dominate the cloud, it turns out that the terms ‘design’, ‘systems’, ‘analysis’, and ‘control’ all play a big part of a computer engineers’ academic life.  Who’d have guessed?</p>
<p><a href="http://nicholasarmstrong.com/wp-content/uploads/2009/09/ComputerEngineeringGraphicalOverview.pdf">Computer Engineering: A Graphical Overview</a> [pdf, 538K]</p>
]]></content:encoded>
			<wfw:commentRss>http://nicholasarmstrong.com/2009/09/computer-engineering-a-graphical-overview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HP Mini 110 with Windows 7</title>
		<link>http://nicholasarmstrong.com/2009/09/hp-mini-110-with-windows-7/</link>
		<comments>http://nicholasarmstrong.com/2009/09/hp-mini-110-with-windows-7/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 16:58:05 +0000</pubDate>
		<dc:creator>Nicholas Armstrong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[hpmini]]></category>
		<category><![CDATA[netbook]]></category>
		<category><![CDATA[win7]]></category>

		<guid isPermaLink="false">http://nicholasarmstrong.com/?p=202</guid>
		<description><![CDATA[After my previous laptop (an HP tablet) decided to pack it in for good after only 18 months of use, I decided to pick up a cheap netbook to tide me over until I’m finished my masters.  The netbook I got was an HP Mini 110-1030CA; this post details installing Windows 7 on it and my initial thoughts on using the netbook.]]></description>
			<content:encoded><![CDATA[<p><a href="http://nicholasarmstrong.com/wp-content/uploads/2009/09/hpmini.jpg"><img class="alignleft size-full wp-image-205" title="HP Mini 110-1030CA" src="http://nicholasarmstrong.com/wp-content/uploads/2009/09/hpmini_thumb.jpg" alt="HP Mini 110-1030CA" width="233" height="180" /></a>After my previous laptop (an HP tablet) decided to pack it in for good after only 18 months of use, I decided to pick up a cheap netbook to tide me over until I’m finished my masters (I’ve got a desktop PC that fills my day-to-day computing needs, but I can’t take it with me to class).  After a lot of research, my choice came down to an <a title="ASUSTek Computer Inc." href="http://ca.asus.com/products.aspx?l1=24&amp;l2=164&amp;l3=0&amp;l4=0&amp;model=3052&amp;modelmenu=2">Asus EEE PC 1005HA</a> or a <a title="Product Specifications HP Mini 110-1030CA PC - HP Customer Care" href="http://h10025.www1.hp.com/ewfrf/wc/document?docname=c01762199&amp;lc=en&amp;dlc=en&amp;cc=ca&amp;lang=en&amp;product=3979284">HP Mini 110-1030CA</a>.  Due to licensing restrictions on cheap versions of Windows XP, every (cheap) netbook you encounter has nearly identical specs – 1 GB RAM and an Atom N270/280 CPU – which means there isn’t much to differentiate between models.  Initially, I leaned toward the Asus – it’s 10 hour battery life (versus the Mini’s 3) and slightly taller (by 24 pixels) screen make it a better machine, but also result in a higher cost (not to mention that finding a retailer with it in Canada was nearly impossible).  Both computers had above-average keyboards for netbooks – the Mini’s is often recognized as the best available on a 10” netbook – my only real constraint.  After some well-timed sales and a bit of price matching, I was able to track down the HP for $90 cheaper than I could find the Asus for, making it a much better bargain.  I’m crossing my fingers that it will last longer than my previous HP laptop &#8211; which had 3 major failures requiring service over its short lifetime, the last of which fell outside its warranty – but at only $300, it’s worth the risk.</p>
<p>Having used Windows 7 off and on since last October – and using Vista for the year prior to that – going back to the version of Windows XP that came with the Mini just wasn’t an option for me.  Windows 7 has thoroughly impressed me so far on all the machines I’ve used it on, not only on a newer Intel quad-core but also on my 7-year-old Athlon XP desktop machine.  So I decided to grab the RTM version of Windows 7 off of MSDN and install it on the Mini; a quick guide to the install process and my initial thoughts on the Mini with Windows 7 follow.</p>
<h2>Installing Windows 7 on a HP Mini 110-1030CA</h2>
<h4>Step 1: Choosing an Install Method</h4>
<p>Like Vista before it, Windows 7 comes on a DVD – an awkward proposition for netbooks, which usually don’t come with an optical drive.  There are three general ways of getting Windows 7 on to these machines; via external DVD drive, via USB key, or via a DVD drive on a networked computer.  Since I don’t have an external DVD drive and my largest USB key is less than the required 4 GBs, I decided to take the third option – doing a network install via a DVD drive on another computer – and that’s the process I’m describing here.  A quick Google/Bing search for ‘windows 7 install netbook’ or similar should yield you a ton of results on how to do it with a USB key if you’re interested in that route, though it seems much more complicated than doing it over a network.</p>
<h4>Step 2: Share out your DVD Drive</h4>
<p>If you’ve shared a folder on your computer before, then sharing your DVD drive should be pretty easy.  Go to the computer you wish to share the drive from, and insert your Windows 7 disc.  If you’re on Windows 7, open ‘Computer’ by pressing Windows-E on the keyboard (or choose ‘Computer’ from the start menu) and locate the DVD drive in which you placed your Windows 7 install disc.  Right click on the drive and choose ‘Properties’ from the menu that appears; then, click the ‘Sharing’ tab.  Then, share the drive (‘Advanced Sharing’ –&gt; ‘Share this folder’).  Finally, check to make sure that your computer is set up to share files by opening the Network and Sharing Center (Start –&gt; ‘Control Panel’ –&gt; ‘Network and Sharing Center’ –&gt; ‘Advanced Sharing Settings’) and checking to make sure that ‘File and printer sharing’ is set to ‘Turn on file and printer sharing’.  You might also want to make sure ‘Password protected sharing’ is set as well.  Then, make a quick note of your computer’s name by hitting the Back button to go back to the Network and Sharing Center, and write down whatever the name of the computer is in the network map at the top of the screen (it will be labelled ‘this computer’).  If you are on Vista instead, the above instructions should work, though some of the items may have slightly different names.  And if you’re on Windows XP, then the steps are completely different – follow <a href="http://www.microsoft.com/windowsxp/using/networking/maintain/share.mspx">this support article</a> instead, except you’ll be sharing out a drive instead of a folder.</p>
<h4>Step 3: Configure your hard drive</h4>
<p>If you only want to have Windows 7 on your machine, this step isn’t necessary.  However, if you want to dual boot Windows XP and Windows 7, or want to keep your XP partition around for restore purposes (my HP Mini 110-1030CA didn’t come with restore discs or a restore partition), then you’ll want to partition the hard drive in order to create a separate partition for Windows XP.  I used the free version of <a href="http://download.cnet.com/Easeus-Partition-Master-Home-Edition/3000-2248_4-10863346.html">Easeus Partition Master</a> to do this, but there are other options (Partition Magic, GParted, etc.).  Using your partition tool, resize/shrink the Windows XP partition so that there is enough room leftover to install Windows 7 (<a href="http://windows.microsoft.com/systemrequirements">at least 16 GB</a>, though that won’t leave much room for applications – Win7 takes around 10 GB on its own).  Then, create a new partition in the empty space, formatted as NTFS.  Hit apply, wait for the changes to take place (a reboot is probably required), and once it finishes you’ll have two hard disk drives that show up, one (C:) your previous Windows XP drive, now smaller, and another one (D:, unless you’ve selected a different mount point) that’s completely empty and waiting for your Windows 7 install.</p>
<h4>Step 4: Start the install process</h4>
<p>Now it’s time to start the install.  Connect your Mini to the same network as the computer you are sharing the Windows 7 install disc from.  You may have to mark this network as a ‘Home’ or ‘Work’ network for the computer hosting the install disc, since by default Vista and Windows 7 don’t allow file sharing over public networks.  Then, on your Mini, open the ‘Run’ box by pressing Windows-R on the keyboard (or choose ‘Run’ from the start menu) and type two back-slashes followed by the name of the computer hosting the install disc (you wrote this down in step 2).  For instance, if your machine name was ‘dvd-pc’, you want to type ‘\\dvd-pc’ in the run box.  Then, press OK; after a few seconds, an explorer window should appear containing all of the shares on the host computer.  Double click on the share you created in step 2 corresponding to the computer’s DVD drive (by default, it’s a single letter matching the driver letter of the DVD device on the host computer).  The DVD should spin up on the host computer, and you should see a number of folders appear along with an executable named ‘setup.exe’.  Double click ‘setup.exe’, and wait as the Windows 7 autorun starts (it could take 30 seconds to a minute, depending on your network speed).  Once it starts, select the ‘Install Now’ option, and wait as the installer loads (another minute or two).  Follow the prompts that appear, selecting ‘Clean’ install and the drive you created in step 3 when asked, and then sit back and wait as the installer copies all of the necessary files off of the disc via the Mini’s network connection, reboots to perform the installation, and reboots once more to prepare everything for use.  Once it’s done, it’ll ask you to configure the time zone, license key, and password, then it’ll drop you into the Windows 7 desktop with everything installed.</p>
<h4>Step 5: Windows Update</h4>
<p>The first thing you should do after installing a new operating system is to update it to the newest version, in our case by running Windows Update.  Simply type ‘Windows Update’ in the start menu, open the program that appears, and press ‘Check for updates’.  Once it comes back with a list of things to be installed, ensure there is a checkbox beside all ‘Recommended’ items and any important ‘Optional’ items (there was a network driver waiting for me under ‘Optional’, but I didn’t need any additional languages), and then press update to download and apply the updates.</p>
<h4>Step 6: Install Missing Drivers</h4>
<p>Once Windows 7 has finished update, you’ll have to install any drivers it wasn’t able to install during the install or update process.  On my HP Mini 110-1030CA, Windows 7 was able to find <em>all</em> of the drivers it needed, but there is one driver it doesn’t get perfectly right: the touch pad.  Don’t worry – the touch pad still works, but the scrolling functionality doesn’t work.  To fix it, head on over to the touch pad manufacturer’s <a href="http://www.synaptics.com/support/drivers">driver site</a> and download the drivers for Windows Vista 32-bit Edition (or Windows 7 32 bit, if they are there – they weren’t when I tried it).  Once the drivers are finished downloading, double click to start the install, follow the prompts, and reboot.  If you’re not using the same Mini I am, head on over to the Device Manager (type ‘Device Manager’ in the start menu) and locate the drivers for any device with an exclamation point beside it.  Windows will expand any item that has devices with missing drivers, to if all of the top-level categories are collapsed, you’re good to go.</p>
<h4>Step 7: You’re Done!</h4>
<p>Yep, that’s it – you’ve managed to install Windows 7 on your HP Mini!  Before you finish up, consider un-sharing your DVD drive by reversing the things you did in step 1; however, if you have more CD/DVD based software to install, do that first.</p>
<h2>Windows 7 on a HP Mini 110-1030CA: The Results</h2>
<p>I’m pretty impressed with how well the machine runs. I’ve upped it to 2 GB of RAM over the stock 1 GB since I had a spare 2 GB stick – and 2G RAM sticks are cheap enough now to make it worthwhile in any case – which allows Windows 7 to use it to speed up program launches.  It’s not perfect, of course – the screen often feels small, and I have encountered the occasional slow down, but outside of that it’s surprisingly usable for just poking around the Internet.</p>
<h4>The Keyboard</h4>
<div id="attachment_207" class="wp-caption alignleft" style="width: 243px"><a href="http://nicholasarmstrong.com/wp-content/uploads/2009/09/hpmini_kbd.jpg"><img class="size-full wp-image-207" title="HP Mini 110-1030CA: Left Shift" src="http://nicholasarmstrong.com/wp-content/uploads/2009/09/hpmini_kbd_thumb.jpg" alt="I'd prefer a full-sized left shift, please and thanks" width="233" height="180" /></a><p class="wp-caption-text">I&#39;d prefer a full-sized left shift, please and thanks</p></div>
<p>The keyboard’s pretty good (most places regard the Mini as having the best keyboard on a netbook, and I tend to agree), though my model has an odd copy of the ‘|\’ key where the rest of the left shift key should be which I keep pressing by accident when I try to type a capital.  It might be because I have a Canadian model (the keyboard has the French-Canadian keyboard markings too), though it’s something I’m sure I will eventually get used to (or I’ll learn to use the right shift key, which is full size).  In the meantime, I’ve used <a title="SharpKeys - Home" href="http://www.codeplex.com/sharpkeys">SharpKeys</a> to remap the extra key to left shift so that it doesn’t interfere when hit by accident.  Incidentally, the other annoying key is the traditional ‘|\’ key; it is located on the middle row of the keyboard right before the two-row enter key, rather than above a single-row enter key.  Both my desktop keyboards have single-row enter keys, so this placement results in many accidental keypresses – and it’s not something SharpKeys can fix.  Outside of that, however, the keyboard has been great – a little smaller than I’m used to, but not enough to impact my typing.  The keys have a nice feel and travel, the arrow keys are arranged in an inverted T shape, both backspace and the spacebar are large, and the keys which have been removed from the keyboard to save space (home/page up/page down/end) have been function-mapped to easily memorable/accessible keys.  Surprisingly, HP didn’t function-map the number pad over the right half of the keyboard, but since I rarely use this feature I haven’t missed it.</p>
<h4>The Screen</h4>
<p>The screen is – as one would expect – quite small.  For web use, it hasn’t been a huge hassle; there’s just more scrolling than usual.  For regular application use, I’ve found it absolutely terrible at multiple windows.  At this point, I’ve basically given up using windows that aren’t maximized to the full screen size, and using more than one window at once is an exercise in alt-tabbing.  Even when using a single application, the small screen sometimes makes it difficult; there are a lot of applications that assume that vertical space is abundant, and fill it with 100+pixels of toolbars.  Careful selection and configuration can minimize this problem – I’ve found <a title="Google Chrome - Download a new browser" href="http://www.google.com/chrome">Google Chrome</a> to be the fastest and leanest browser; <a title="Thunderbird - Reclaim your inbox" href="http://www.mozillamessaging.com/thunderbird/">Thunderbird</a> (and <a title="Firefox web browser | Faster, more secure, &amp; customizable" href="http://www.mozilla.com/firefox/">Firefox</a>) work better when using small toolbar icons, no toolbar text, no status bar, and <a title="Compact Menu 2 :: Add-ons for Thunderbird" href="https://addons.mozilla.org/en-US/thunderbird/addon/4550">this extension</a> to get rid of the menu bar; <a title="Office Online Home Page - Microsoft Office Online" href="http://office.microsoft.com/">Office</a>’s ribbon can be minimized by double-clicking one of its tabs; and Windows 7 runs great with an auto-hide taskbar that’s mounted vertically along the side of the screen – but there are a few applications that perform poorly (I’m looking at you, <a title="Essentials - Windows Live" href="http://download.live.com/?sku=messenger">Windows Live Messenger</a>…).  Since more and more applications are on the web these days, the use of multiple windows is less and less of a concern.</p>
<h4>The Horsepower</h4>
<p>While I feared that the Mini would be underpowered, it has not turned out to be the case.  It’s not something I’d use for all my computing tasks, but for something small to tote around to check one’s email with and have something to do during otherwise wasted time, it can’t be beat.  The Mini has no trouble with regular-quality YouTube, even full-screen, though HD YouTube is too choppy to watch.  Microsoft Office runs great – heck, it’s even been handling Visual Studio admirably well.  With a Windows Experience Index of 2.0 (Processor: 2.2, Memory: 4.5, Graphics: 2.0, Gaming Graphics: 3.0, Hard Disk: 5.6), the HP Mini 110-1030CA is able to handle Windows Aero without trouble, too.  And it uses hyperthreading to present two ‘virtual’ processors to the operating system, which improves the interactivity of the system to the point where I haven’t noticed a foreground task being blocked by a heavy background one.  All in all, for the things I’m using the netbook for I can’t tell that this machine has significantly less power than the other machines I’ve used.</p>
<h4>The Operating System</h4>
<p>Windows 7 works great, no ifs, ands, or buts.  It’s modern, fast, and easy to use, and installing it (as the instructions above show) is a hassle-free experience.  And it’s certainly suited for netbooks – I’m running the Ultimate edition, and so far it has been consistently faster than the version of Windows XP that came with the Mini.  It responds instantaneously to keyboard and mouse input, and resuming from sleep or hibernate happens quickly.  With all of my commonly-used applications installed, it boots to the desktop in about 45 seconds, and it’s ready to go as soon as you see the desktop.  I haven’t experienced any stability problems, either with Windows itself or with the drivers it has loaded.  All in all, I’ve got no complaints whatsoever about Windows 7, and highly recommend that other netbook users out there install it as soon as they can get their hands on a copy.</p>
<h2>Final Thoughts</h2>
<p>Overall, I’m incredibly impressed with this little computer – and the emphasis there goes on both <em>little</em> <strong>and</strong> <em>computer</em>.  It’s sure easy to carry this thing around – it weighs just over a kilogram and measures 10.5” by 7.5”, making it smaller and lighter than most of my textbooks – and the battery life so far has been sufficient in every scenario I’ve used it.  And it’s an actual computer, not a glorified cell phone; I don’t feel myself avoiding typing on it or considering whether or not it supports something (Flash, Java, etc.), I just go ahead and do it.  The screen is large enough to read comfortably, and the speakers, while very definitely “laptop” sounding speakers, are clear and full.  Granted, there are some compromises one has to make – it’s certainly not a ‘desktop replacement’ laptop – but for me, those compromises are rare enough that I can work around them easily and still get a significant amount of utility from the Mini.  Final Vertdict: the HP Mini 110-1030CA is an excellent second (or third) computer for students and other people on the go, and works wonderfully with Windows 7.</p>
]]></content:encoded>
			<wfw:commentRss>http://nicholasarmstrong.com/2009/09/hp-mini-110-with-windows-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Ideal Work Term Progression for Computer Engineers, part VI</title>
		<link>http://nicholasarmstrong.com/2009/09/the-ideal-work-term-progression-for-computer-engineers-part-vi/</link>
		<comments>http://nicholasarmstrong.com/2009/09/the-ideal-work-term-progression-for-computer-engineers-part-vi/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 01:23:58 +0000</pubDate>
		<dc:creator>Nicholas Armstrong</dc:creator>
				<category><![CDATA[Waterloo]]></category>
		<category><![CDATA[computer engineering]]></category>
		<category><![CDATA[engineering]]></category>
		<category><![CDATA[work term]]></category>

		<guid isPermaLink="false">http://nicholasarmstrong.com/2009/09/the-ideal-work-term-progression-for-computer-engineers-part-vi/</guid>
		<description><![CDATA[The last part in a series of six on what you should be doing for each work term in order to get the best jobs with the best companies in your last few co-op terms when doing a co-op program at the University of Waterloo.]]></description>
			<content:encoded><![CDATA[<p>With their Computer Engineering degrees now complete, my classmates (and I, in a sense) are now working at – or searching for – their first permanent full-time jobs.&#160; Looking back on the journey that got us where we are, the one thing that stands out between my classmates is the experience they got while on their co-op terms, and the quality of their resulting full-time jobs.&#160; I thought I’d take this opportunity to share what I’ve learned about what co-op jobs you should be looking for at each stage in the Waterloo co-op progression.&#160; This article is the fifth in a series of 6 (parts <a title="The Ideal Work Term Progression for Computer Engineers, part I | Nicholas Armstrong" href="http://nicholasarmstrong.com/2009/08/the-ideal-work-term-progression-for-computer-engineers-part-i/">I</a>, <a title="The Ideal Work Term Progression for Computer Engineers, part II | Nicholas Armstrong" href="http://nicholasarmstrong.com/2009/08/the-ideal-work-term-progression-for-computer-engineers-part-ii/">II</a>, <a title="The Ideal Work Term Progression for Computer Engineers, part III | Nicholas Armstrong" href="http://nicholasarmstrong.com/2009/08/the-ideal-work-term-progression-for-computer-engineers-part-iii/">III</a>, <a title="The Ideal Work Term Progression for Computer Engineers, part IV | Nicholas Armstrong" href="http://nicholasarmstrong.com/2009/08/the-ideal-work-term-progression-for-computer-engineers-part-iv/">IV</a>, <a title="The Ideal Work Term Progression for Computer Engineers, part V | Nicholas Armstrong" href="http://nicholasarmstrong.com/2009/08/the-ideal-work-term-progression-for-computer-engineers-part-v/">V</a>, and VI) on what you should be doing for each co-op work term with the University of Waterloo in order to get jobs with the best companies in your last few co-op terms; this part covers your fifth work term.</p>
<p>This series is written for computer engineering students in the University of Waterloo’s cooperative education (co-op) program, which consists of a series of 6 work terms in a repeating 4 months school/4 months work pattern for four years of the student’s five year degree.&#160; Most of the information presented here is not unique to UW students, however; students in a more traditional university program can still apply these tips by ignoring the term specifications and applying them in order to their work opportunities instead.&#160; Longer (8-, 12-, or 16-month) work terms also fit into this model; aim to be done the same things as a 4-month UW co-op student would be at that level of work experience (for example, a 16-month intern should try to complete items up to the 4th work term level by the end of their internship).</p>
<h2>Your Sixth Work Term – Teeing Up the Rest of Your Life </h2>
<p><strong>Return to your previous employer, get a better job, or try something different &#8211; it&#8217;s up to you.</strong>&#160; If you were lucky enough to land a job with a company you could see working for full time – and don&#8217;t have any higher aspirations for a starting position – then certainly consider returning to this employer for your last work term.&#160; As was the case on your fourth work term, doing two consecutive work terms with the same employer allows you to leverage the company experience you obtained in your previous work term and gain more responsibility with less ramp up time.&#160; Unlike on the fourth work term, however, there isn&#8217;t any pressure from older students on the job supply, so if you&#8217;re not completely happy – or just want to try something different – then take the opportunity to go through the interview process one last time.&#160; Most employers hiring at the fifth and sixth work term levels evaluate their co-op students against the same standards they use for new graduates; this turns out to be a <em>huge</em> benefit for UW students.&#160; To start with, most co-op students have significantly more experience by their fifth work terms than students from other universities do by the time they graduate, making it very easy to surpass this standards.&#160; Secondly, most employers are very understanding of you taking your sixth work term to do something different and then returning to them full time, and will provide you with the contacts you need to land a job with the company in the future.&#160; When you combine these things, you end up with a situation that is incredibly advantageous for you, whatever you decide to do on this work term.&#160; And as long as you got a job on all of your previous work terms, you can even take this term off (though I’d suggest taking time off once you graduate instead; employers are well accustomed to it, and you’ll likely already have a full time job lined up and can afford to spend more).</p>
<p><strong>Get a job with a company you want return to.</strong>&#160; Getting a job with a company via co-op is usually significantly easier than the process new graduates follow, so using your sixth work term as an opportunity to get into a company is an excellent strategy.&#160; To give you an example, co-op students at Microsoft returning full-time to the same team usually have no other interviews than their initial 1 hour co-op interview, held on the UW campus.&#160; Switching teams requires more interviews, but its often more of a “can we work with this person” interview lasting an hour or so; your work for your former team vets your technical skills.&#160; New graduates who haven&#8217;t done an internship with Microsoft, on the other hand, face one or two 8 hour days of interviews &#8211; a very gruelling process – on the Microsoft campus, which requires flying all the way out there and back if the student is not from the area.&#160; Not only that, students from other schools start from scratch on their first day with the company, while you’ll already be an old hand by the time your first (full time) day rolls around.&#160; Using your sixth work term this way makes life a <em>lot</em> simpler, so consider it when applying for jobs.</p>
<p><strong>Negotiate upward.</strong>&#160; It’s hard to overstate the value of a co-op student returning to an employer; hiring good people is hard work, and your 4-month co-op term(s) with an employer serve as an extended audition.&#160; You can take advantage of this to negotiate a better position than is traditionally available to new grads – with a few caveats, of course.&#160; First, for bigger companies you’ll probably be entering on their standard “new grad” employment package, so negotiating salary/benefits/vacation time is not generally useful – college recruiters typically aren’t authorized to go outside the “standard” package.&#160; Some companies have a range of “standard” packages, but the choice of package is based on how valuable you are to the company; there’s not much you can do to change it (besides doing well on your co-op terms, of course).&#160; So what do you negotiate on?&#160; Your position!&#160; If there is a project area you want to lead, a committee you want to be on, a job description you want to have, whatever it is that relates to your job duties – just ask!&#160; Especially if you are returning to the same team under the same management, you’ll often get good results by discussing with your current manager what you are looking for in a full time position, and so long as it is reasonable, most managers are willing and able to hook you up.&#160; Even if it means working on a different team – talented people are good for a company, regardless of which department they work in – there is a good chance that your manager has been around long enough to develop relationships with the right people to get you a better job than you would normally get, and one that is precisely what you are interested in to boot.&#160; You’ll still end up starting as a new grad just like all of the other new grads, but while the other new grads are getting up to speed, you may be leading a feature area – which looks especially good come review time.</p>
<p><strong>Plan for the future.</strong>&#160; If you’ve found a company that you would consider returning to, plant seeds for the future.&#160; The people you meet may be your future colleagues, so make sure to network and do all of the things you need to do to start getting people on your side so that you have a pool of allies to help when you need stuff done.&#160; Indeed, as a co-op student you have the neat ability to use the naïveté defence of “I’m just a (dumb) co-op”, so you can even get away with asking senior people questions without repercussions – so forge relationships with some of these people by asking their advice.&#160; And since there are likely aspects of your job that will rely on the goodwill of others, make sure to start contributing when others need help.&#160; Always put your best effort into everything you do – you don’t want a colleague shooting down an idea of yours in a few years because their only experience of your track record was a couple of shoddy projects you did while you were a co-op.&#160; The boundary between co-op and fulltime employee becomes blurred on the last few co-op terms – especially if you return to the company full time – so make sure to take note and foster the image you want to have as a full time employee.</p>
<p><strong>That’s it &#8211; have fun!</strong>&#160; In the end, everybody’s co-op experience is different, and there is no right or wrong way of doing things.&#160; I hope this series has provided some guidance for the things you need to do and think about when you are working your way through co-op so that you can put yourself in a good position for a fulfilling (and lucrative) career in the computer industry.</p>
<p>Each work experience provides a different viewpoint on the set of skills necessary to make it to the top.&#160; If you’ve had experience in co-op and want to share your thoughts or (dis)agree with any of the points I’ve made, post a comment or send me a note (‘contact’ at this domain) and I’ll amend these posts with your feedback.&#160; </p>
]]></content:encoded>
			<wfw:commentRss>http://nicholasarmstrong.com/2009/09/the-ideal-work-term-progression-for-computer-engineers-part-vi/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Ideal Work Term Progression for Computer Engineers, part V</title>
		<link>http://nicholasarmstrong.com/2009/08/the-ideal-work-term-progression-for-computer-engineers-part-v/</link>
		<comments>http://nicholasarmstrong.com/2009/08/the-ideal-work-term-progression-for-computer-engineers-part-v/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 12:00:00 +0000</pubDate>
		<dc:creator>Nicholas Armstrong</dc:creator>
				<category><![CDATA[Waterloo]]></category>
		<category><![CDATA[computer engineering]]></category>
		<category><![CDATA[engineering]]></category>
		<category><![CDATA[work term]]></category>

		<guid isPermaLink="false">http://nicholasarmstrong.com/2009/08/the-ideal-work-term-progression-for-computer-engineers-part-v/</guid>
		<description><![CDATA[Part five in a series of six on what you should be doing for each work term in order to get the best jobs with the best companies in your last few co-op terms when doing a co-op program at the University of Waterloo.]]></description>
			<content:encoded><![CDATA[<p>With their Computer Engineering degrees now complete, my classmates (and I, in a sense) are now working at – or searching for – their first permanent full-time jobs.&#160; Looking back on the journey that got us where we are, the one thing that stands out between my classmates is the experience they got while on their co-op terms, and the quality of their resulting full-time jobs.&#160; I thought I’d take this opportunity to share what I’ve learned about what co-op jobs you should be looking for at each stage in the Waterloo co-op progression.&#160; This article is the fifth in a series of 6 (parts <a title="The Ideal Work Term Progression for Computer Engineers, part I | Nicholas Armstrong" href="http://nicholasarmstrong.com/2009/08/the-ideal-work-term-progression-for-computer-engineers-part-i/">I</a>, <a title="The Ideal Work Term Progression for Computer Engineers, part II | Nicholas Armstrong" href="http://nicholasarmstrong.com/2009/08/the-ideal-work-term-progression-for-computer-engineers-part-ii/">II</a>, <a title="The Ideal Work Term Progression for Computer Engineers, part III | Nicholas Armstrong" href="http://nicholasarmstrong.com/2009/08/the-ideal-work-term-progression-for-computer-engineers-part-iii/">III</a>, <a title="The Ideal Work Term Progression for Computer Engineers, part IV | Nicholas Armstrong" href="http://nicholasarmstrong.com/2009/08/the-ideal-work-term-progression-for-computer-engineers-part-iv/">IV</a>, V, and <a title="The Ideal Work Term Progression for Computer Engineers, part VI | Nicholas Armstrong" href="http://nicholasarmstrong.com/2009/09/the-ideal-work-term-progression-for-computer-engineers-part-vi/">VI</a>) on what you should be doing for each co-op work term with the University of Waterloo in order to get jobs with the best companies in your last few co-op terms; this part covers your fifth work term.</p>
<p>This series is written for computer engineering students in the University of Waterloo’s cooperative education (co-op) program, which consists of a series of 6 work terms in a repeating 4 months school/4 months work pattern for four years of the student’s five year degree.&#160; Most of the information presented here is not unique to UW students, however; students in a more traditional university program can still apply these tips by ignoring the term specifications and applying them in order to their work opportunities instead.&#160; Longer (8-, 12-, or 16-month) work terms also fit into this model; aim to be done the same things as a 4-month UW co-op student would be at that level of work experience (for example, a 16-month intern should try to complete items up to the 4th work term level by the end of their internship).</p>
<h2>Your Fifth Work Term – Making a Name for Yourself</h2>
<p><strong>Apply for your dream job.</strong>&#160; If you’ve been following the tips so far, you should be in striking range of your dream job – apply for it!&#160; If the job is offered through the university’s Jobmine system, it’s likely that your employer is familiar with the co-op process – so be sure to participate in all of their activities.&#160; Employer information sessions, group interviews, interview prep sessions, etc. – all are important to attend, even if they aren’t taking attendance (your competition is there, and employers often share tips about what it takes to impress them).&#160; For the same reasons, consider going to the employer information sessions for other employers of similar calibre; though each person has their own opinions on what makes a good resume and what to ask during an interview, most of the top-tier employers agree on a common subset of these items, and their tips can ensure you nail every one of them.&#160; Remember too that your goal is still to stand out, so be sure to introduce yourself to the recruiter, spend time on a good cover letter and tailored resume, and include a link to your portfolio – the top positions easily see more than 200 applicants a term, and while your experience to this point will get you on to a much shorter list of candidates they’d actually consider, you want to use every technique at your disposal to ensure you are in their interview set.&#160; If instead you’ve decided that your dream job is with a company that doesn’t do co-op hiring through Jobmine, you’ll face a lot less competition but a lot more work.&#160; First off, start early – landing an out-of-system job can take 3 months or more to set up, so make sure to start working at it midway through your previous work term.&#160; Second, make it easy on the company you’re looking to work for – make sure your cover letter clearly explains why you want to work for them, when you are available to work, and how the co-op process works (if you get a response from a company you contacted, CECS can help out with the specifics).&#160; Finally, be prepared to do everything yourself; you’ll need to arrange your visa if you are working out of country, you’ll have to find housing, and you’ll have to coordinate with CECS to ensure your work term gets counted for credit.&#160; If it’s truly a dream job, though, the rewards should be worth it – and at the very least, you’ll get experience that no other student on campus has!&#160; Regardless of where you’re looking for a dream job, the fifth term is the term to do it – in the best cases, you’ll have two terms to spend with the company (or one term with each of two companies); in the worst case, you’ll likely to still end up with interviews for a few of the top positions – which is great practice for your sixth work term interviews.</p>
<p><strong>Be passionate.</strong>&#160; The one thing that struck me about top-tier job interviews is how little they focused on the routine stuff (the “will this person play nicely with the other employees” type questions); in some fifth work term interviews, no questions of this type are asked.&#160; Rather, they tend to be focused on technical details, and specifically, determining whether a person is passionate about technical details.&#160; A lot of this is exposed through tricky technical questions – for those in the .NET world, it’s questions like those in <a title="Scott Hanselman&#39;s Computer Zen - What Great .NET Developers Ought To Know (More .NET Interview Questions)" href="http://www.hanselman.com/blog/WhatGreatNETDevelopersOughtToKnowMoreNETInterviewQuestions.aspx">this list by Scott Hanselman</a> – but some also focus on what I like to equate with passion.&#160; Looking back, I’d say that most of the questions I got while interviewing for my fifth work term were an attempt to figure out how passionate I was about technical things – though in most cases, I’d wager that the interviewer themselves didn’t realize that it was passion they were specifically looking for.&#160; I only picked up on it through an interview with a technical architect on the Microsoft Office team, who repeatedly drilled me for more and more detail on my previous work term, where I had done a lot of work in WPF.&#160; At the time, I couldn’t figure out why he was so interested – he admitted having no background in WPF – but he still rooted around in the details, had me justify why certain decisions were made, what was wrong with our project after we had finished, what we would do differently given different constraints (more people, more time, etc.), and generally poked around for technical details that had no apparent utility to him.&#160; It was only afterwards that I figured out what it was he was doing – he was finding out whether <em>I</em> was interested in the details, whether I was motivated enough to figure out why things the way they were before making a decision that depended on them, and whether I was cared enough to see the flaws in my project – or broadly, whether I was <em>passionate</em> about the software I was building.&#160; Whether or not I was passionate about the things he or his company did was secondary; his primary goal was to find out if I had the <em>capacity</em> to be just as passionate about his company’s products.&#160; To a competent engineer, the technical aspects will come naturally out of that passion; if you encounter a problem where you need to know some arcane algorithm, then your passion to do your job well will result in you learning what you need to know to make a great product.&#160; After recognizing this, I began seeing this search happening in other interviews, often not so explicitly but with the same (implicit) end goal in mind – if hired, will I care about what it is the employer does?&#160; So be passionate about the things that you do, and make sure it shows in the interview.&#160; Don’t just memorize the answers to common interview questions – know how they work and why your answer is correct.&#160; Be able to provide more detail on any question you answer, and admit that you don’t know when you don’t have sufficient knowledge to give a defensible answer.&#160; If passion isn’t one quality you possess about the work you are doing, then perhaps it’s time for a career change – the best employers will certainly be able to pick up on this, so don’t count on being able to land a great job without passion for what you do.</p>
<p><strong>Be an expert.</strong>&#160; By the time you’ve made it to your fifth work term, you will have accumulated more than a year’s worth of work experience – and three years of university – which is plenty of training to understand just about any practical technical topic out in industry.&#160; However, it’s highly likely that your technical knowledge is spread out over a number of different areas, and it’s certainly the case for your academic experience, which may include such varied topics as physics, calculus, software, hardware, communications, controls – and the list goes on.&#160; While a broad base of experience is always a good thing to have, detailed knowledge in a particular area (or areas) is more and more important as you progress through the co-op process.&#160; The simple fact is that businesses hire employees to solve their problems, whatever those problems happen to be (from improving efficiency of the company itself, to figuring out what their customers want, to building things that solve their customers problems).&#160; People who have detailed knowledge in solving a particular set of problems tend to come up with better solutions than those who don’t, and do so faster; both of these qualities are beneficial to a business.&#160; Becoming one of those people with detailed knowledge in an area can make you a very valuable asset to the companies you work for, so find an area you are interested in or working on, and go deep.&#160; Learn everything you can about it, by reading books and blogs, following industry developments in that area, and practicing your hand at it.&#160; Often, some of these areas will develop naturally for you as you are assigned work in them, but you still want to make and effort and take steps to improve your knowledge.&#160; Secondly, you want to volunteer your assistance in your expert areas to your co-workers; if your company can’t use your skill, then it effectively the same as you not having it.&#160; You want to be the go-to person for people looking for details on topic X; it doesn’t matter how specific or broad topic X is, just that you are the go-to person for it.&#160;&#160; Not only does it make you somewhat difficult to replace (for your current employer), but it’s one more defining characteristic that potential employers can use when hiring.&#160; And the skill of being an expert in an area is often the first skill you will have that your interviewer doesn’t – they’ll have more overall experience, sure, but might not know your area of expertise to the same level you do, making you an attractive hire.&#160; In my opinion, being an expert in an area is one of the most important characteristics of an employee; not only am I free from the responsibility of needing to know about everything and can instead rely on the experts nearby, but I am also secure in the knowledge that whatever it is that we’re building is the best that it can be, since each aspect was checked by an expert.&#160; </p>
<p><strong>Network.</strong>&#160; For me, networking is all about outsourcing, in the quite literal sense of the ability to outsource some of your tasks to a network of friends, family, colleagues, coworkers, etc. instead of completing them entirely on your own.&#160; Granted, in order to maintain your network, you are often required to contribute to the tasks of others, but the primary benefit your network has for you is its ability to outsource.&#160; My network is most efficient at two sorts of outsourced tasks: knowledge gathering or transfer and distributed job hunting.&#160; The network you build might have other capabilities, but those two are the ones I’ve found most useful.&#160; The first, knowledge gathering, is all about asking your network for help on a specific problem you are encountering that you cannot find the solution to.&#160; When your network is made up of experts (see above), this is an incredibly effective technique to use when you get stuck.&#160; For example, on my last work term my demo machine started freezing when WPF applications were launched.&#160; After a couple hours of fruitless investigation, I asked my network, and was quickly directed to one of the team testers, who found the problem in minutes.&#160; As it turned out, it involved an early version of Windows 7, an early version of the multi-touch API, and buggy touch panel drivers – a combination I never would have suspected, much less identified as fast as he did (nor would I have been able to come up with a fix).&#160; In a similar vein, those who had trouble finding jobs (or wanted a particular good job) often got great results by using their networks to get them into a good position to do so, either through references or through direct introductions by someone who already works at the company.&#160; Even now, when jobs are scarce, my network is still working to identify job opportunities for those still without; often, those opportunities haven’t made it to the open market.&#160; Building a network that is capable of taking some of your most difficult tasks and producing results is incredibly valuable – there is a lot of truth to the notion that “it’s not what you know, it’s who you know”.&#160; I’m not going to go into any strategies for actually going out and building a network – there are plenty of resources on the topic already – but it’s something you should be especially focused on during your last couple terms.&#160; Your network could very well mean the difference between an good job and a great one, so cultivate those relationships and use them in your times of need.</p>
]]></content:encoded>
			<wfw:commentRss>http://nicholasarmstrong.com/2009/08/the-ideal-work-term-progression-for-computer-engineers-part-v/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

