<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-10202973</id><updated>2011-12-01T04:01:00.155+11:00</updated><category term='applications'/><category term='project'/><category term='jobs'/><category term='remember'/><category term='subjects'/><category term='concurrency'/><category term='scripts'/><category term='teaching'/><category term='programming'/><category term='mac'/><category term='swingame'/><title type='text'>Thinking at the Edge</title><subtitle type='html'>Thoughts from the edge of teaching, software development and .NET.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>92</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-10202973.post-7659500113293585214</id><published>2009-12-02T12:05:00.006+11:00</published><updated>2009-12-02T12:33:10.353+11:00</updated><title type='text'>Locking a Mac</title><content type='html'>Leaving your mac sitting logged in on your desk is not very secure... is there an easy way to lock access to your machine when you step away? Unfortunately there is no ctrl-L style key combination built in, but you can get the same effect using the Screen Saver and hot corners.&lt;div&gt;&lt;ol&gt;&lt;li&gt;Open &lt;b&gt;System Preferences&lt;/b&gt;, and move into the &lt;b&gt;Desktop &amp;amp; Screen Saver&lt;/b&gt; preference pane.&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 160px;" src="http://2.bp.blogspot.com/_olmWkE7TQpE/SxW-uAeChmI/AAAAAAAAABo/gMwwQZVSrqs/s200/Screen+shot+2009-12-02+at+12.10.42+PM.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5410440224964773474" /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li style="clear:both"&gt;Click the &lt;b&gt;Hot Corners&lt;/b&gt; button and have the screen saver start when you move the mouse to one of the four corners of your screen. I use the top left corner. Then click &lt;b&gt;OK&lt;/b&gt;, and &lt;b&gt;Show All&lt;/b&gt; to return back to the System Preferences window.&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 160px;" src="http://4.bp.blogspot.com/_olmWkE7TQpE/SxXBnyyVxnI/AAAAAAAAACA/HSqEg99AVd0/s200/Screen+shot+2009-12-02+at+12.08.59+PM.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5410443416747492978" /&gt;&lt;/li&gt;&lt;li style="clear:both"&gt;Now open the &lt;b&gt;Security&lt;/b&gt; preference pane.&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 160px;" src="http://4.bp.blogspot.com/_olmWkE7TQpE/SxXBFAw40_I/AAAAAAAAAB4/fACn0DEUHgE/s200/Screen+shot+2009-12-02+at+12.20.59+PM.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5410442819204076530" /&gt;&lt;/li&gt;&lt;li style="clear:both"&gt; Finally set the &lt;b&gt;Require password &lt;i&gt;n seconds&lt;/i&gt; after sleep or screen saver&lt;/b&gt;. I use the &lt;b&gt;5 seconds&lt;/b&gt; setting as this gives you a few of seconds to move the mouse when the screen saver kicks in when you are reading a document or similar.&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 160px;" src="http://2.bp.blogspot.com/_olmWkE7TQpE/SxXCkXWNe2I/AAAAAAAAACI/IYCU4SVCwig/s200/Screen+shot+2009-12-02+at+12.26.28+PM.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5410444457353771874" /&gt;&lt;/li&gt;&lt;li style="clear:both"&gt;Now when its coffee time just move your mouse to the appropriate &lt;i&gt;hot corner&lt;/i&gt; and your screen saver will lock your computer.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-7659500113293585214?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/7659500113293585214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=7659500113293585214' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/7659500113293585214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/7659500113293585214'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2009/12/locking-mac.html' title='Locking a Mac'/><author><name>Andrew</name><uri>http://www.blogger.com/profile/09614394427342357758</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_olmWkE7TQpE/SOFz3g05WXI/AAAAAAAAAAM/JpkST5_jGTw/S220/face.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_olmWkE7TQpE/SxW-uAeChmI/AAAAAAAAABo/gMwwQZVSrqs/s72-c/Screen+shot+2009-12-02+at+12.10.42+PM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-6358354329394268646</id><published>2009-11-09T16:23:00.003+11:00</published><updated>2009-11-09T17:05:49.126+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='swingame'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Regex for Tracing</title><content type='html'>I've been working on SwinGame, and one of the tasks has been to add tracing code to the core to make it easier to debug problems. This involves adding TraceEnter and Trace exit calls to each procedure in the code.&lt;br /&gt;&lt;br /&gt;To avoid having to do this by hand I am using a Regular Expression in TextMate to find procedures in the code, and replace them with a version that includes the injected trace enter and exit code. The regex I am using is shown below. It will work with a maximum depth of four begin/end groups... so its not completely automatic, but is a good start.&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;(function |procedure )(.*?)(;(\n|.)*?begin)((\n|(begin(\n|(begin(\n|(begin(\n|(begin(\n|.)*?end)|.)*?end)|.)*?end)|.)*?end)|.)*?)(\n  end;)&lt;/span&gt;&lt;/blockquote&gt;This is then replaced using the following replace text. The $1 values are the groups that are matched in the regular expression. This enables me to place the procedure name, parameters and return type in the traced output ($2). It also ensures that all of the code from the program is output in the right spot.&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; $1$2$3&lt;br /&gt;   {$IFDEF TRACE}&lt;br /&gt;     TraceEnter('sgCamera', '$2', '');&lt;br /&gt;   {$ENDIF}&lt;br /&gt;   $5 &lt;br /&gt;   {$IFDEF TRACE}&lt;br /&gt;     TraceExit('sgCamera', '$2', '');&lt;br /&gt;   {$ENDIF}&lt;br /&gt; $15&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;This regular expression converts the following code...&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;function VectorFrom(x, y: Single): Vector; overload;&lt;br /&gt; begin&lt;br /&gt;   result := VectorFrom(x, y, false);&lt;br /&gt; end;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;into this code which now has the tracing details added.&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;function VectorFrom(x, y: Single): Vector; overload;&lt;br /&gt; begin&lt;br /&gt;   {$IFDEF TRACE}&lt;br /&gt;     TraceEnter('sgCamera', 'VectorFrom(x, y: Single): Vector', '');&lt;br /&gt;   {$ENDIF}&lt;br /&gt;  &lt;br /&gt;   result := VectorFrom(x, y, false);&lt;br /&gt;  &lt;br /&gt;   {$IFDEF TRACE}&lt;br /&gt;     TraceExit('sgCamera', 'VectorFrom(x, y: Single): Vector', '');&lt;br /&gt;   {$ENDIF}&lt;br /&gt; end;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;This should save me some time... though a real parser trace injector would be great!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-6358354329394268646?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/6358354329394268646/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=6358354329394268646' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/6358354329394268646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/6358354329394268646'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2009/11/regex-for-tracing.html' title='Regex for Tracing'/><author><name>Andrew</name><uri>http://www.blogger.com/profile/09614394427342357758</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_olmWkE7TQpE/SOFz3g05WXI/AAAAAAAAAAM/JpkST5_jGTw/S220/face.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-3400037514193223590</id><published>2009-10-09T09:17:00.003+11:00</published><updated>2009-10-09T09:27:45.754+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><title type='text'>Finding Menu Options</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_olmWkE7TQpE/Ss5l0BFcvWI/AAAAAAAAABg/CkoYqAjJehw/s1600-h/Screen+shot+2009-10-09+at+9.20.14+AM.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px; height: 139px;" src="http://1.bp.blogspot.com/_olmWkE7TQpE/Ss5l0BFcvWI/AAAAAAAAABg/CkoYqAjJehw/s200/Screen+shot+2009-10-09+at+9.20.14+AM.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5390357748327955810" /&gt;&lt;/a&gt;Another small feature of MacOS that I use often is the help search feature. This searches for the text you type in the program's menu options. The image here shows searching for "Picture" in Word. Selecting one of the found options opens the menu and a pointer indicates where the option is. You can then either click the menu or just execute it directly from the help itself.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This has actually changed the way I use the menu itself. I no longer try to remember where a menu option is. Instead I use the help to search and execute the option.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-3400037514193223590?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/3400037514193223590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=3400037514193223590' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/3400037514193223590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/3400037514193223590'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2009/10/finding-menu-options.html' title='Finding Menu Options'/><author><name>Andrew</name><uri>http://www.blogger.com/profile/09614394427342357758</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_olmWkE7TQpE/SOFz3g05WXI/AAAAAAAAAAM/JpkST5_jGTw/S220/face.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_olmWkE7TQpE/Ss5l0BFcvWI/AAAAAAAAABg/CkoYqAjJehw/s72-c/Screen+shot+2009-10-09+at+9.20.14+AM.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-6982580784988990547</id><published>2009-09-25T19:41:00.002+10:00</published><updated>2009-09-25T19:50:47.200+10:00</updated><title type='text'>Dictionary Mac Tip</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_olmWkE7TQpE/SryQl0NapmI/AAAAAAAAABY/mOGMWBXmyAk/s1600-h/Screen+shot+2009-09-25+at+7.42.00+PM.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px; height: 138px;" src="http://4.bp.blogspot.com/_olmWkE7TQpE/SryQl0NapmI/AAAAAAAAABY/mOGMWBXmyAk/s200/Screen+shot+2009-09-25+at+7.42.00+PM.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5385338233772746338" /&gt;&lt;/a&gt;A few people I know have recently switched to using Macs, so I thought I would try to put up Mac related tips for them here on my blog. I'll try to do one each week, but... we'll see :).&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One cool feature of Mac OS is the ability to use the dictionary to lookup words in many applications (any that use the basic mac text rendering - so not office for example).  I find this useful when reading web sites and when writing documents. Try hovering the mouse over any word and pressing &lt;b&gt;Command + Control + D&lt;/b&gt;. You should get a drop down that shows you the words details from the dictionary. The drop down also lets you look the word up in the thesaurus.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-6982580784988990547?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/6982580784988990547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=6982580784988990547' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/6982580784988990547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/6982580784988990547'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2009/09/dictionary-mac-tip.html' title='Dictionary Mac Tip'/><author><name>Andrew</name><uri>http://www.blogger.com/profile/09614394427342357758</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_olmWkE7TQpE/SOFz3g05WXI/AAAAAAAAAAM/JpkST5_jGTw/S220/face.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_olmWkE7TQpE/SryQl0NapmI/AAAAAAAAABY/mOGMWBXmyAk/s72-c/Screen+shot+2009-09-25+at+7.42.00+PM.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-1873721647717286779</id><published>2009-09-11T18:47:00.002+10:00</published><updated>2009-09-11T19:12:11.411+10:00</updated><title type='text'>SDL + Objective-C Garbage Collection</title><content type='html'>&lt;div&gt;Today I had another try at getting a version of SDL 1.2 with support for garbage collection. I got a bit further this time... I managed to get SDL to compile for 10.5 (and 10.6 Snow Leopard) with gc support turned on. My games run with the new framework as long as -fobj-gc isn't supported or required by the application... The games start with garbage collection, but don't it seems that there is an issue loading LiveType. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'll have to look into it again later... but if you have any ideas let me know! (happy to provide compiled SDL framework for anyone interested in helping)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-1873721647717286779?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/1873721647717286779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=1873721647717286779' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/1873721647717286779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/1873721647717286779'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2009/09/sdl-objective-c-garbage-collection.html' title='SDL + Objective-C Garbage Collection'/><author><name>Andrew</name><uri>http://www.blogger.com/profile/09614394427342357758</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_olmWkE7TQpE/SOFz3g05WXI/AAAAAAAAAAM/JpkST5_jGTw/S220/face.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-1551809482210498602</id><published>2009-09-09T14:54:00.002+10:00</published><updated>2009-09-09T15:04:04.503+10:00</updated><title type='text'>Setting the title of a slide...</title><content type='html'>I've been playing around with two different presentation tools and found the different approaches to scripting to be quite interesting. The two scripts are shown below.&lt;div&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 39.2px; text-indent: -39.3px; font: 12.0px Verdana; min-height: 15.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 39.2px; text-indent: -39.3px; font: 12.0px Verdana"&gt;&lt;b&gt;tell&lt;/b&gt; &lt;span style="color:#3600fc;"&gt;&lt;i&gt;application&lt;/i&gt;&lt;/span&gt; "A"&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 78.5px; text-indent: -78.6px; font: 12.0px Verdana"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;b&gt;set&lt;/b&gt; &lt;span style="color:#8300d9;"&gt;title&lt;/span&gt; &lt;b&gt;of&lt;/b&gt; (&lt;span style="color:#8300d9;"&gt;current slide&lt;/span&gt; &lt;b&gt;of&lt;/b&gt; &lt;b&gt;first&lt;/b&gt; &lt;span style="color:#3600fc;"&gt;&lt;i&gt;slideshow&lt;/i&gt;&lt;/span&gt;) &lt;b&gt;to&lt;/b&gt; "Hello World"&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 39.2px; text-indent: -39.3px; font: 12.0px Verdana"&gt;&lt;b&gt;end&lt;/b&gt; &lt;b&gt;tell&lt;/b&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 39.2px; text-indent: -39.3px; font: 12.0px Verdana; min-height: 15.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 39.2px; text-indent: -39.3px; font: 12.0px Verdana; min-height: 15.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 39.2px; text-indent: -39.3px; font: 12.0px Verdana"&gt;&lt;b&gt;tell&lt;/b&gt; &lt;span style="color:#3600fc;"&gt;&lt;i&gt;application&lt;/i&gt;&lt;/span&gt; "B"&lt;/p&gt; &lt;p  style="margin: 0.0px 0.0px 0.0px 78.5px; text-indent: -78.6px; font: 12.0px Verdana; color:#3600fc;"&gt;&lt;span style="color:#000000;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;activate&lt;/b&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 78.5px; text-indent: -78.6px; font: 12.0px Verdana; min-height: 15.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p  style="margin: 0.0px 0.0px 0.0px 78.5px; text-indent: -78.6px; font: 12.0px Verdana; color:#8300d9;"&gt;&lt;span style="color:#000000;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;b&gt;set&lt;/b&gt; &lt;/span&gt;&lt;span style="color:#53930f;"&gt;theIndex&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;b&gt;to&lt;/b&gt; &lt;/span&gt;slide index&lt;span style="color:#000000;"&gt; &lt;b&gt;of&lt;/b&gt; &lt;/span&gt;&lt;span style="color:#3600fc;"&gt;&lt;i&gt;slide&lt;/i&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;b&gt;of&lt;/b&gt; &lt;/span&gt;&lt;span style="color:#3600fc;"&gt;&lt;i&gt;view&lt;/i&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;b&gt;of&lt;/b&gt; &lt;/span&gt;active window&lt;/p&gt; &lt;p  style="margin: 0.0px 0.0px 0.0px 78.5px; text-indent: -78.6px; font: 12.0px Verdana; color:#53930f;"&gt;&lt;span style="color:#000000;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;b&gt;set&lt;/b&gt; &lt;/span&gt;selectedSlide&lt;span style="color:#000000;"&gt; &lt;b&gt;to&lt;/b&gt; &lt;/span&gt;&lt;span style="color:#3600fc;"&gt;&lt;i&gt;slide&lt;/i&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;theIndex&lt;span style="color:#000000;"&gt; &lt;b&gt;of&lt;/b&gt; &lt;/span&gt;&lt;span style="color:#8300d9;"&gt;active presentation&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 78.5px; text-indent: -78.6px; font: 12.0px Verdana"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;b&gt;set&lt;/b&gt; &lt;span style="color:#8300d9;"&gt;content&lt;/span&gt; &lt;b&gt;of&lt;/b&gt; &lt;span style="color:#3600fc;"&gt;&lt;i&gt;text range&lt;/i&gt;&lt;/span&gt; &lt;b&gt;of&lt;/b&gt; &lt;span style="color:#3600fc;"&gt;&lt;i&gt;text frame&lt;/i&gt;&lt;/span&gt; &lt;b&gt;of&lt;/b&gt; &lt;span style="color:#3600fc;"&gt;&lt;i&gt;shape&lt;/i&gt;&lt;/span&gt; 1 &lt;b&gt;of&lt;/b&gt; &lt;span style="color:#53930f;"&gt;selectedSlide&lt;/span&gt; &lt;b&gt;to&lt;/b&gt; "Hello World"&lt;span class="Apple-style-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 39.2px; text-indent: -39.3px; font: 12.0px Verdana"&gt;&lt;b&gt;end&lt;/b&gt; &lt;b&gt;tell&lt;/b&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;The two scripts both set the title of the current slide to "Hello World". Its interesting to note that while "B" has more features the script is quite brittle, things like selecting the slide in the outline cause it to fail to select the current slide.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and the moral of the story is... "don't over engineer your code... keeping things simple with clean abstractions is always better"&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-1551809482210498602?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/1551809482210498602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=1551809482210498602' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/1551809482210498602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/1551809482210498602'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2009/09/setting-title-of-slide.html' title='Setting the title of a slide...'/><author><name>Andrew</name><uri>http://www.blogger.com/profile/09614394427342357758</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_olmWkE7TQpE/SOFz3g05WXI/AAAAAAAAAAM/JpkST5_jGTw/S220/face.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-4038679555069495489</id><published>2009-05-12T22:03:00.002+10:00</published><updated>2009-05-12T22:07:21.697+10:00</updated><title type='text'>Explore Regex</title><content type='html'>I've been playing around with the Google Web Toolkit, and it looks very interesting. As a small project I created a Regular Expression testing web site (see &lt;a href="http://exploreregex.appspot.com/"&gt;http://exploreregex.appspot.com/&lt;/a&gt;). This uses a simple regular expression highlighting service that you post sample data and a regex, and it returns HTML formatted data indicating the matched expressions. This all works asynchronously, which the GWT makes easy...&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next will be to add in some of the AppEngine features...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-4038679555069495489?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://exploreregex.appspot.com/' title='Explore Regex'/><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/4038679555069495489/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=4038679555069495489' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/4038679555069495489'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/4038679555069495489'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2009/05/explore-regex.html' title='Explore Regex'/><author><name>Andrew</name><uri>http://www.blogger.com/profile/09614394427342357758</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_olmWkE7TQpE/SOFz3g05WXI/AAAAAAAAAAM/JpkST5_jGTw/S220/face.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-4056198246076052772</id><published>2008-12-27T18:39:00.002+11:00</published><updated>2008-12-27T20:02:08.738+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><title type='text'>Got a new mac... what now?</title><content type='html'>A few of my friends have recently got their first mac... so what things would I recommend for anyone switching from PC to Mac?&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Realise that it will take some time to get started with a new platform... and switching to mac is the same. You will need to spend some time really getting used to using the Mac, but the effort will be worth it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1: What can I do with my PC data and apps I need to use?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I think the key to switching is to immerse yourself in the new platform and avoid using the old one for a few weeks... otherwise the temptation will always be to revert back to using Windows and you will never really get the benefits a Mac has to offer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://i3.parallels.com/r/upload/pdbox.gif"&gt;&lt;img style="float:left; margin:0 10px 10px 10px;cursor:pointer; cursor:hand;width: 73px; height: 107px;" src="http://i3.parallels.com/r/upload/pdbox.gif" border="0" alt="" /&gt;&lt;/a&gt;However, for somethings you do need Windows... Visual Studio for example. I use &lt;a href="http://www.parallels.com/"&gt;Parallels&lt;/a&gt; Desktop for Mac. Its a &lt;a href="http://en.wikipedia.org/wiki/Virtual_machine"&gt;virtual machine&lt;/a&gt;, and allows you to run Windows, or other operating systems, under Mac OS. I have found this has worked really well for me. If you are moving from an existing PC, you can also make use of Parallels Transporter. It can be used to create a Virtual Machine image of your existing PC. You can then use this as a full backup, ensuring you don't lose any of those important settings or data from your PC.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.virtualbox.org/graphics/vbox_logo2_gradient.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 140px; height: 180px;" src="http://www.virtualbox.org/graphics/vbox_logo2_gradient.png" border="0" alt="" /&gt;&lt;/a&gt;An alternative to Parallels is &lt;a href="http://www.virtualbox.org/"&gt;Virtual Box&lt;/a&gt;. I know a few people who have used this, but I haven't tried it myself. The benefit of this is that it is free...&lt;/div&gt;&lt;div&gt;I don't think it has an equivalent to Parallels Transporter, but you cant argue with the price.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;2: What general things should I know about?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well there are many but here are a few important points:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Clicking the Red x on the top left corner only closes the window, in many cases the program is still running. You need to use the Quit link from the program's menu.&lt;/li&gt;&lt;li&gt;Running programs appear in the Dock with a small light blue ball under it.&lt;/li&gt;&lt;li&gt;You can quit a program by right clicking on the program in the Dock.&lt;/li&gt;&lt;li&gt;System Preferences is the equivalent to Control Panel.&lt;/li&gt;&lt;li&gt;Learn to use Expose.&lt;/li&gt;&lt;li&gt;Command replaces control for many shortcuts - Command Q quits for example.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Things you need to configure:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Make sure you turn on two finger scrolling, and secondary clicks with two fingers in Trackpad settings in System Preferences.&lt;/li&gt;&lt;li&gt;Set the right button on the mouse to secondary click.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;3: What Mac programs should I look at using?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.adiumx.com/images/logo.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 128px; height: 128px;" src="http://www.adiumx.com/images/logo.png" border="0" alt="" /&gt;&lt;/a&gt;If you use any form of chat, you'll want to get &lt;a href="http://www.adiumx.com/"&gt;Adium&lt;/a&gt;, a free chat client that can be used to chat with MSN, Yahoo, Google, Facebook, and others... There are heaps of extras that really make it an impressive application. The duck image is really cute, and the many replacement dock images are worth looking at.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://manual.macromates.com/images/project_window_with_tabs.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 330px; height: 226px;" src="http://manual.macromates.com/images/project_window_with_tabs.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://macromates.com/"&gt;Textmate&lt;/a&gt; is a fantastic text editor for developers. Its not free, but it is well worth the price. It comes with many extensions, such as &lt;a href="http://ciaranwal.sh/2008/08/29/projectplus-update-2"&gt;Project Plus&lt;/a&gt; that integrates SVN flags into the project draw. The extensions for different code formats are also worth looking at.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.educational-software.com/images/products/microsoft-office-2008-for-macintosh-full.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 150px; height: 150px;" src="http://www.educational-software.com/images/products/microsoft-office-2008-for-macintosh-full.jpg" border="0" alt="" /&gt;&lt;/a&gt;Office for Mac is likely to be another program that you need. It is mostly compatible with the Windows version, though the 2008 edition is missing VBA support. I have both the 2008 and the 2004 version installed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are some alternatives to Office such as &lt;a href="http://www.neooffice.org/neojava/en/index.php"&gt;NeoOffice&lt;/a&gt;, and Apple's &lt;a href="http://www.apple.com/iwork/"&gt;iWork&lt;/a&gt;. I have been using iWork for a number of tasks, and it is great at creating presentations (in Keynote) and documents (in Pages). It is not as full featured as Office, but I have found it easier to get the layout I want in many cases.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.neooffice.org/neojava/images/ship2.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 128px; height: 128px;" src="http://www.neooffice.org/neojava/images/ship2.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://yourtech.typepad.com/main/WindowsLiveWriter/iwork.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 150px; height: 150px;" src="http://yourtech.typepad.com/main/WindowsLiveWriter/iwork.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well that should be enough to get started with... &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-4056198246076052772?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/4056198246076052772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=4056198246076052772' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/4056198246076052772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/4056198246076052772'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2008/12/got-new-mac-what-now.html' title='Got a new mac... what now?'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-7067165678162951592</id><published>2008-12-01T14:30:00.002+11:00</published><updated>2008-12-01T15:19:04.279+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Plans for APS</title><content type='html'>&lt;div&gt;Next year I will be teaching Algorithmic Problem Solving (APS) in first semester, a subject that I have developed and worked on over a few years. At the start of this year I trialled portfolio assessment with some success in this subject, though I improved on this in semester 2 with Object Oriented Programming. So what am I going to do differently next year?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Greater focus on the portfolio assessment: &lt;/span&gt;The portfolio assessment was good in this subject last year, but the focus can be even better. I found that this helped the students focus on what was important in OOP, the intended learning outcomes. My plan is to provide assessed learning activities during the semester, the resulting work will then be included in the students' portfolios. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Simpler book: &lt;/span&gt;The first few times I ran this subject we used the language manual that comes with the language we are using. Its very dry, and not presented in an order that is useful for learning. This year I tried providing my own details, but didn't really get that right. So next year I will be providing a new book.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The book is what I am focusing on now. This will use a syntax based approach to learning the language, along with clear descriptions and illustrations to help students understand the programming abstractions. At this stage I have the following sections for the book:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Programs - introduces the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Program&lt;/span&gt; abstraction and a large number of new "programming language" terms such as identifier, keyword, procedure, procedure call, expression, literal, etc.&lt;/li&gt;&lt;li&gt;Creating Procedures - focuses on creating your own procedures. &lt;/li&gt;&lt;li&gt;Storing and Using data - variables, and the assignment statement.&lt;/li&gt;&lt;li&gt;Passing Data Around - introduces parameters (both in, out, and in/out).&lt;/li&gt;&lt;li&gt;Calculating Values - covers functions and function calls.&lt;/li&gt;&lt;li&gt;External Libraries - introduces units, shows how to use external units, and provides an example function from the SysUtils unit.&lt;/li&gt;&lt;li&gt;User Input - Up to this stage we will have been using literal values, but now all of the framework is in place to understand user input. This includes ReadLn, as well as reading command line arguments.&lt;/li&gt;&lt;li&gt;Branching - Indicates the change from programming "infrastructure" to control flow, and algorithm design.&lt;/li&gt;&lt;li&gt;Looping - For, while, repeat, etc...&lt;/li&gt;&lt;li&gt;Data abstractions - now the focus changes to the programming abstractions for data. This will include arrays, records and pointers.&lt;/li&gt;&lt;li&gt;Creating Libraries - Lastly onto creating your own programming libraries&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;My idea for this is to have each section as self contained as possible. Knowledge will be built up without the need for any "magic". This is the reason for delaying user input... this requires functions and out parameters, with library use being necessary if you want to convert values from strings to integers for example.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;These 11 chapters will be covered in the first five weeks of the semester. Week one will cover 1 &amp;amp; 2, week two will be 3 &amp;amp; 4, week three on 5, 6 &amp;amp; 7, week four on 8 &amp;amp; 9, and week five on 10 &amp;amp; 11. This leaves seven weeks of the semester to learn about how these abstractions are used to create programs. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Along with this I am aiming to keep the explanation of each concept or part of the syntax down to a single page, where possible. This is enough room to convey the important aspects, but not too much that the end result is overwhelming. It should also help to create a useful reference, where each idea has its own page. So far I am up to chapter 5 which start at page 39, so there isn't too may pages per chapter.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let me know what you think. I'll post up some chapters later...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-7067165678162951592?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/7067165678162951592/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=7067165678162951592' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/7067165678162951592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/7067165678162951592'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2008/12/plans-for-aps.html' title='Plans for APS'/><author><name>Andrew</name><uri>http://www.blogger.com/profile/09614394427342357758</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_olmWkE7TQpE/SOFz3g05WXI/AAAAAAAAAAM/JpkST5_jGTw/S220/face.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-2936981380753293644</id><published>2008-11-26T10:08:00.004+11:00</published><updated>2008-11-26T11:34:00.914+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><title type='text'>2008 Retrospective</title><content type='html'>Well the semester is over, and I'm starting to reflect upon a year with many experiments. The big things for me this year has been trying to put into practice many of the things that I have been reading about in the education area. The main focus has been on helping students to develop a greater understanding of software development and programming in general.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Background &amp;amp; the idea:&lt;/span&gt;&lt;br /&gt;Software development is challenging, something that is easy to forget (once you get it). We have taught this through extended practice, in many cases without addressing  or even discussing the associated principles. One of my frustrations with this has been the way many people subsequently approach their programming, usually with little thought or understanding. The classic symptom here is observed when the student makes random changes in the hope of fixing a bug, rather than thinking through their program and reasoning about its structure and implementation.&lt;br /&gt;&lt;br /&gt;Is this a symptom of a lack of experience, or a greater problem related to the students understanding of the abstractions they are working with.&lt;br /&gt;&lt;br /&gt;I am of the opinion that it is largely the latter, and that by refocusing on principles and core concepts we can teach people to better understand what they are doing when they create their own programs.&lt;br /&gt;&lt;br /&gt;The idea, for this year, has been to refocus my teaching around the core principles. Teaching the principles of structured programming in first semester, and object oriented principles in second semester.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;The method:&lt;/span&gt;&lt;br /&gt;My teaching method aimed to get students engaged with the material, it is what the student does that counts...&lt;br /&gt;&lt;br /&gt;Along with this I wanted students to be able to be adventurous, without risking losing marks. It was more important to have good quality, that a fixed time line. I moved to an extreme "Theory Y" position, with the perceived benefits of greater flexibility for the students along with greater responsibility.&lt;br /&gt;&lt;br /&gt;I also wanted to make better use of the lectures, by distributing weekly reading and creating podcasts and using the lectures to discuss issues students were having with the concepts.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;The results:&lt;/span&gt;&lt;br /&gt;Now that semester 2 is over I am reflecting on the results of this approach. For me it has been a real roller coaster of highs and lows. Some aspects have worked well, others need improvement.&lt;br /&gt;&lt;br /&gt;There was a marked difference between the introductory and advanced programming subjects. In general this approach has worked well with the more advanced students (Enterprise .NET), but how about the introductory subjects?&lt;br /&gt;&lt;br /&gt;Releasing control of the system was definitely a different experience, though not an overly positive one in the introductory subjects. During the semester it was obvious that many of these students had failed to take responsibility for their learning. This was seen through missed deadlines, lack of attendance, and few questions on challenging areas. Flexible due dates meant leaving work until the last minute, rather than a chance to do quality work. The marking then reflected this situation, with many of those who "relaxed" failing to submit anything as the workload exceeded their time remaining.&lt;br /&gt;&lt;br /&gt;On the positive side, there were some truly brilliant portfolios submitted. Those students who did take responsibility for their learning were able to demonstrate far more than I could have wished for. I hope that these students appreciated the flexibility, and the chance to explore areas they were interested in. But how can I adjust the process to better suite the larger majority of students.&lt;br /&gt;&lt;br /&gt;Another positive was the portfolio assessment. This was time consuming and while course grained it has given very "accurate" grades, with no students being awarded a grade higher than they deserved due to a poor testing or marking scheme. On the other hand there were some students who's result I believe could have been better if they applied themselves more to the task, and demonstrating their learning.&lt;br /&gt;&lt;br /&gt;The lecture method worked Ok with the advanced students, but need some tweaking. With the introductory subjects it really failed, which was disappointing. I think the problems were many... The text books were really 500% of what was "really" needed. As a result many students didn't do the required reading and subsequently blundered along trying to learn details from "lectures" without any real depth to their understanding. The method was significantly different and I failed to engage them in the process. Not providing my own large design early was not a great idea. Some of the lab exercises were incorrectly focused. Some of the portfolio pieces I suggested were overly large and time consuming, without the intended benefits.&lt;br /&gt;&lt;br /&gt;Some bad points:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Not enough focus on programming (overcompensation)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Only few truly engaged with the method&lt;br /&gt;&lt;/li&gt;&lt;li&gt;In general students did a poor job of managing their learning&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Some students didn't end up understanding the portfolio idea&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Some good points:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Large responsibility on students to manage their own learning.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Mature students are better equipped for this method&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Portfolios were able to capture student learning&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Assessment was "fair"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;No penalties for those who learn during the semester, and can communicate their learning by the end.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;English communication skills can be enhanced, and communication issues are less severe then with exams (which require time compressed communication)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Reflections &amp;amp; Plans:&lt;/span&gt;&lt;br /&gt;In summary this year has been a huge disappointment, and I'll need to try and reinvigorate myself before next year. I think the approach can work, and if I can get it right there should be some great benefits for the students. Reading back over this has, however, provided me with some hope.&lt;br /&gt;&lt;br /&gt;"Once more unto the breach, dear friends, once more;"&lt;br /&gt;&lt;br /&gt;My plans are to focus on teaching the learning process... as well as teaching about programming :). The method is different and I dont think I spent enough time on what was expected, and how to take advantage of the environment. I also have some more practical ideas related to using more "traditional" practices alongside this to help ease students into the experience. I am also more experienced now on what I need them to focus on in this approach. It has been a long time since I really engaged with these principles, and I'll be better equipped next year.&lt;br /&gt;&lt;br /&gt;So to my introductory programming students from this year... sorry...&lt;br /&gt;&lt;br /&gt;I would love to know what you thought of this experience and any suggestions you have... what do you think could be done to better next time.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;I also promise to blog more... if you are interested in my plans and progress stay in touch! I need all the help I can get :)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-2936981380753293644?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/2936981380753293644/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=2936981380753293644' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/2936981380753293644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/2936981380753293644'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2008/11/2008-retrospective.html' title='2008 Retrospective'/><author><name>Andrew</name><uri>http://www.blogger.com/profile/09614394427342357758</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_olmWkE7TQpE/SOFz3g05WXI/AAAAAAAAAAM/JpkST5_jGTw/S220/face.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-3500315465558868151</id><published>2008-09-30T10:34:00.005+10:00</published><updated>2008-09-30T10:51:48.684+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><title type='text'>Automator Postscript Actions &amp; Leopard</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_sV9xRhltz80/RcrsQxz1EhI/AAAAAAAAABg/LVWAzcFsJWo/s200/Picture+5.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 100px;" src="http://bp0.blogger.com/_sV9xRhltz80/RcrsQxz1EhI/AAAAAAAAABg/LVWAzcFsJWo/s200/Picture+5.png" border="0" alt="" /&gt;&lt;/a&gt;Back in &lt;a href="http://andrewcain.blogspot.com/2007/02/postscript-automator-actions.html"&gt;February 2007&lt;/a&gt; I developed some Automator actions to manipulate Postscript files. I used these actions in the past to convert my presentation slides into multi-page PDFs. By creating these as scripts it became easy to quickly convert a large number of presentations into "lecture notes" that I could upload for the students.&lt;br /&gt;&lt;br /&gt;Today I went back to test is they worked... and they didn't! The problem was that Leopard is now unix2003 compatible, and my script wasn't. The issue was my use of the &lt;em&gt;file -i {}&lt;/em&gt; command which worked in the legacy mode, but fails when using the updated version. The fix was simple, when I found it, use &lt;em&gt;file --mime {}&lt;/em&gt;...&lt;br /&gt;&lt;br /&gt;For those who are interested... &lt;a href="http://mercury.it.swin.edu.au/swinbrain/images/a/a7/Automator_Actions.zip"&gt;download the automator actions...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-3500315465558868151?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/3500315465558868151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=3500315465558868151' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/3500315465558868151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/3500315465558868151'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2008/09/automator-postscript-actions-leopard.html' title='Automator Postscript Actions &amp; Leopard'/><author><name>Andrew</name><uri>http://www.blogger.com/profile/09614394427342357758</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_olmWkE7TQpE/SOFz3g05WXI/AAAAAAAAAAM/JpkST5_jGTw/S220/face.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_sV9xRhltz80/RcrsQxz1EhI/AAAAAAAAABg/LVWAzcFsJWo/s72-c/Picture+5.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-8999353088931252754</id><published>2008-03-05T20:17:00.005+11:00</published><updated>2008-03-06T07:33:30.866+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='swingame'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Python is intriguing...</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.python.org/images/python-logo.gif"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px;" src="http://www.python.org/images/python-logo.gif" border="0" alt="" /&gt;&lt;/a&gt;I share an office with Clinton who has lately become somewhat of a &lt;span style="font-style:italic;"&gt;Python&lt;/span&gt; convert. Today I started to play with Python for the first time. Unlike "normal" people I didn't start with Python in Python... I started by embedding it within a Pascal program. Embedding Python within Pascal was really simple - I am totally amazed! With less than 20 lines of Pascal code you can embed a Python interpreter and have it load and run python modules.&lt;br /&gt;&lt;br /&gt;The code for this will be placed on Google Code once I have it a little farther along.&lt;br /&gt;&lt;br /&gt;Why am I doing this? We are looking at providing the ability to run Scripts within &lt;a href="http://www.swingame.com"&gt;SwinGame&lt;/a&gt;, its looking like we should have something interesting soon!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-8999353088931252754?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/8999353088931252754/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=8999353088931252754' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/8999353088931252754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/8999353088931252754'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2008/03/python-is-intriguing.html' title='Python is intriguing...'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-1573127000328715988</id><published>2008-02-27T08:58:00.000+11:00</published><updated>2008-02-27T09:09:41.436+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='swingame'/><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><title type='text'>Portfolio Assessment</title><content type='html'>Well semester 1 has started... I can where did all that time go? This semester I am teaching HIT1301 Algorithmic Problem Solving again, and as always there are improvements to be made. This semester most of the changes revolve around the assessment, with some minor changes to the lectures and resources available. &lt;br /&gt;&lt;br /&gt;On the assessment side of things the assessment will be much more flexible than in the past. Basically for APS there will be some core assignments and tests, each quite short but covering all the basics. Passing these means you pass the subject, in most cases you need to get them working to pass so dont think 50% = pass for these! To get anything greater than this students will need to submit a portfolio that shows their capabilities and depth of understanding of software development. This means students can choose what they want to focus on, while still ensuring they cover all bases. The focus of this assessment is on depth of understanding and quality of work, rather than quantity.&lt;br /&gt;&lt;br /&gt;I'll keep you informed of how this goes... Let me know what you think of the idea.&lt;br /&gt;&lt;br /&gt;In other news we are  (well Clinton really) making progress with the new python port of &lt;a href="http://www.swingame.com"&gt;SwinGame&lt;/a&gt;. This will mean that you will be able to call the SwinGame API from Python... the next step is to embed Python within SwinGame :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-1573127000328715988?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/1573127000328715988/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=1573127000328715988' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/1573127000328715988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/1573127000328715988'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2008/02/portfolio-assessment.html' title='Portfolio Assessment'/><author><name>Andrew</name><uri>http://www.blogger.com/profile/09614394427342357758</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_olmWkE7TQpE/SOFz3g05WXI/AAAAAAAAAAM/JpkST5_jGTw/S220/face.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-3918193522461728216</id><published>2008-02-04T20:40:00.000+11:00</published><updated>2008-02-04T20:44:34.062+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='swingame'/><title type='text'>SwinGame Excitement</title><content type='html'>The &lt;a href="http://www.swingame.com"&gt;swingame&lt;/a&gt; project has gone through some very exciting developments. Over the last few weeks we have managed to develop a new edition of SwinGame (version 1.1) and is now available for download. Have a look at the game promo videos that we have created for this of &lt;a href="http://www.youtube.com/swingame"&gt;YouTube&lt;/a&gt; they have been great fun to create.&lt;br /&gt;&lt;br /&gt;Let us know what you think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-3918193522461728216?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/3918193522461728216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=3918193522461728216' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/3918193522461728216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/3918193522461728216'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2008/02/swingame-excitement.html' title='SwinGame Excitement'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-87361561621503357</id><published>2007-12-14T08:04:00.001+11:00</published><updated>2007-12-14T11:07:41.513+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='swingame'/><title type='text'>Exciting things are afoot</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_sV9xRhltz80/R2HIeNNsMbI/AAAAAAAAACI/66waieOjfHY/s1600-h/Picture+2.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://bp3.blogger.com/_sV9xRhltz80/R2HIeNNsMbI/AAAAAAAAACI/66waieOjfHY/s200/Picture+2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5143612670702530994" /&gt;&lt;/a&gt; The Summer Semester Project this year is working on extending the SwinGame API that was started last year. This is a really exciting project with some great outcomes already, and we're less than half way through...&lt;br /&gt;&lt;br /&gt;So what have the students achieved? The most visible part is the &lt;a href="http://www.swingame.com"&gt;SwinGame&lt;/a&gt; web site. This site will be used to promote and distribute the SDKs when they are finished. The site uses a combination of MediaWiki and phpBB, combined together with a common theme. The wiki will be used to document the API while the forum will offer a place to discuss the games, and any issues with the API. You can read their comments on the &lt;a href="http://swingame.blogspot.com/"&gt;SwinGameSDK Development&lt;/a&gt; blog.&lt;br /&gt;&lt;br /&gt;I've used the SDK to create a small game, "Alien Flight". Its been great fun to have a chance to play around with this, though I guess I'll need to get back to work soon :(. I'll be putting the game up on the site some time soon.&lt;br /&gt;&lt;br /&gt;Anyway check out the site and let me know what you think. Its a little empty at the moment, but we're working on getting content in soon.&lt;br /&gt;&lt;br /&gt;Have a great christmas, and new year!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-87361561621503357?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/87361561621503357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=87361561621503357' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/87361561621503357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/87361561621503357'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2007/12/exciting-things-are-afoot.html' title='Exciting things are afoot'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_sV9xRhltz80/R2HIeNNsMbI/AAAAAAAAACI/66waieOjfHY/s72-c/Picture+2.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-5870142249741983330</id><published>2007-10-29T21:47:00.000+11:00</published><updated>2007-10-29T22:32:45.139+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><title type='text'>PS Printing in Leopard</title><content type='html'>Back in February I created some Automator scripts to automate the process of printing and publishing my lecture notes. These scripts hinged on the ability to use a small printer script that send the printer output to file, simple ps script. Upgrading to Leopard has caused me some issues in this regard.&lt;br /&gt;&lt;br /&gt;The first issue is the fact that the &lt;span style="font-style: italic;"&gt;Print Center&lt;/span&gt; has been removed. In the past you could Option click the &lt;span style="font-style: italic;"&gt;Add Printer&lt;/span&gt; button to enable the &lt;span style="font-style: italic;"&gt;Advanced&lt;/span&gt; options. With the new Printer Preferences Pane  this option has been removed.  So my first issue was adding the printer back at all. After some searching I found that the cups process can be administered remotely using &lt;a href="http://localhost:631"&gt;http://localhost:631&lt;/a&gt;. To create the new printer you can do the following:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Add a generic printer using Printer Preferences Pane&lt;/li&gt;&lt;li&gt;Open a web browser and navigate to &lt;a href="http://localhost:631"&gt;http://localhost:631&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Navigate to the printers tab&lt;/li&gt;&lt;li&gt;Choose &lt;span style="font-style: italic;"&gt;Modify Printer&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Step through the process configuring the printer as you would have in the Print Center Advanced options.&lt;/li&gt;&lt;/ol&gt;Following this process I was able to add back the printer, which unfortunately was not able to print :(.&lt;br /&gt;&lt;br /&gt;On Tiger the cups process is run by the root user, however on Leopard the security has been tightened and now the printer is run using a low privilege account, _lp. My old postscript saving scripts would output the file to any folder you chose, and then alter the ownership to the calling user. The new script can no longer do this. I've listed the new script below for anyone interested the corrected script. Please note that you will need to setup the printer with reference to a location that can be written to by this user, I have used /tmp.&lt;br /&gt;&lt;br /&gt;I'll look into this again later, but for the moment this meets my needs. Other suggestions are welcome.&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;#!/bin/sh&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;#&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;# Michael Goffioul&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;# Updated by P T Withington for Mac OS X&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;# Updated by Richard Bronosky&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;# Updated by Steve Palm (N9YTY) - case insensitive URI, unique output files&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;# Recreated as PS copy by Andrew Cain&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;LOGFILE=&lt;/span&gt;/tmp/psprinter.log&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;FILENAME=&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;CPBIN=&lt;/span&gt;/bin/cp&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;ECHOBIN=&lt;/span&gt;/bin/cat&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;RUNAS=&lt;/span&gt;`/usr/bin/whoami`&lt;br /&gt; &lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"Script:           $0"&lt;/span&gt; &amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$LOGFILE&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"Run as:           $RUNAS"&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$LOGFILE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"job:              $1"&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$LOGFILE&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"user:             $2"&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$LOGFILE&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"title:            $3"&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$LOGFILE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"num-copies:       $4"&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$LOGFILE&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"options:          $5"&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$LOGFILE&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"filename:         $6"&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$LOGFILE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;# case of no argument, prints available URIs&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt; $&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;# -eq 0 ]; then&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"direct PS &lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\"&lt;/span&gt;Unknown&lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\"&lt;/span&gt;PS Writing&lt;span style="color: rgb(0, 0, 153); font-weight: bold;"&gt;\"&lt;/span&gt;"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 102);"&gt;exit&lt;/span&gt; &lt;span style="color: rgb(204, 102, 204);"&gt;0&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;fi&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;# case of wrong number of arguments&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt; $&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;# -ne 5 -a $# -ne 6 ]; then&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"Usage: ps job-id user title copies options [file]"&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 102);"&gt;exit&lt;/span&gt; &lt;span style="color: rgb(204, 102, 204);"&gt;1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;fi&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;# get ps directory from device URI, and check write status&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;URI_PRE=&lt;/span&gt;`&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$DEVICE_URI&lt;/span&gt; | cut -c &lt;span style="color: rgb(204, 102, 204);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(204, 102, 204);"&gt;-2&lt;/span&gt; | tr &lt;span style="color: rgb(255, 0, 0);"&gt;"[a-z]"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"[A-Z]"&lt;/span&gt;`&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;URI_BODY=&lt;/span&gt;`&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$DEVICE_URI&lt;/span&gt; | cut -c &lt;span style="color: rgb(204, 102, 204);"&gt;3&lt;/span&gt;-`&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;DEVICE_URI=&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"${URI_PRE}${URI_BODY}"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"Device URI: $DEVICE_URI"&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$LOGFILE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;PSDIR=&lt;/span&gt;$&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;DEVICE_URI&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;#PS:}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt; `&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$PSDIR&lt;/span&gt;|cut -c1&lt;span style="color: rgb(204, 102, 204);"&gt;-3&lt;/span&gt;` = //~ &lt;span style="color: rgb(102, 204, 102);"&gt;]&lt;/span&gt;; &lt;span style="color: rgb(177, 177, 0);"&gt;then&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 255);"&gt;PSDIR=&lt;/span&gt;/Users/$&lt;span style="color: rgb(204, 102, 204);"&gt;2&lt;/span&gt;`&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$PSDIR&lt;/span&gt;|cut -c4-`&lt;br /&gt;  &lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;# This step added by Richard Bronosky to allow referencing the users home directory&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;fi&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"PS DIR: $PSDIR"&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$LOGFILE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt;&amp;nbsp;! -d &lt;span style="color: rgb(255, 0, 0);"&gt;"$PSDIR"&lt;/span&gt; -o&amp;nbsp;! -w &lt;span style="color: rgb(255, 0, 0);"&gt;"$PSDIR"&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;]&lt;/span&gt;; &lt;span style="color: rgb(177, 177, 0);"&gt;then&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"ERROR: $PSDIR not writable"&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$LOGFILE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"ERROR: directory $PSDIR not writable"&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 102);"&gt;exit&lt;/span&gt; &lt;span style="color: rgb(204, 102, 204);"&gt;1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;fi&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"ps directory:    $PSDIR"&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$LOGFILE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;# generate output filename&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;OUTPUTFILENAME=&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"$3"&lt;/span&gt; = &lt;span style="color: rgb(255, 0, 0);"&gt;""&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;]&lt;/span&gt;; &lt;span style="color: rgb(177, 177, 0);"&gt;then&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 255);"&gt;OUTPUTFILENAME=&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"$PSDIR/unknown.ps"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;else&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 255);"&gt;OUTPUTFILENAME=&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"$PSDIR/${3//[^[:alnum:]]/_}.ps"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;fi&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;FBASE=&lt;/span&gt;`basename &lt;span style="color: rgb(0, 0, 255);"&gt;$&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;OUTPUTFILENAME&lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;/span&gt; .ps`&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;typeset&lt;/span&gt; -i &lt;span style="color: rgb(0, 0, 255);"&gt;I=&lt;/span&gt;&lt;span style="color: rgb(204, 102, 204);"&gt;1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;while&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt; -e &lt;span style="color: rgb(0, 0, 255);"&gt;$OUTPUTFILENAME&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;do&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;OUTPUTFILENAME=&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"${PSDIR}/${FBASE}_$I.ps"&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;I=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;$I&lt;/span&gt;&lt;span style="color: rgb(204, 102, 204);"&gt;+1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;done&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"Output file name: $OUTPUTFILENAME"&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$LOGFILE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;# move ps to destination&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt; $&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;# -eq 6 ]; then&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"copy $6 $OUTPUTFILENAME"&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 255);"&gt;$CPBIN&lt;/span&gt; $&lt;span style="color: rgb(204, 102, 204);"&gt;6&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$OUTPUTFILENAME&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$LOGFILE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;#  $GSBIN $6 -o $OUTPUTFILENAME &amp;gt;&amp;gt; $LOGFILE&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;else&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;#cp /dev/stdin $OUTPUTFILENAME&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"$ECHOBIN - &amp;gt;&amp;gt; $OUTPUTFILENAME"&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 255);"&gt;$ECHOBIN&lt;/span&gt; - &amp;gt;&amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$OUTPUTFILENAME&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;#  $GSBIN -i -o $OUTPUTFILENAME &amp;gt;&amp;gt; $LOGFILE&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;fi&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;# modify ownership and permissions on the file&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;#  - world readable&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;#  - owns to user specified in argument&lt;/span&gt;&lt;br /&gt;chmod a+r &lt;span style="color: rgb(0, 0, 255);"&gt;$OUTPUTFILENAME&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"$2"&lt;/span&gt;&amp;nbsp;!= &lt;span style="color: rgb(255, 0, 0);"&gt;""&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;]&lt;/span&gt;; &lt;span style="color: rgb(177, 177, 0);"&gt;then&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"Change ownership with: chown $2 $OUTPUTFILENAME"&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$LOGFILE&lt;/span&gt;&lt;br /&gt;  chown $&lt;span style="color: rgb(204, 102, 204);"&gt;2&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$OUTPUTFILENAME&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;fi&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;exit&lt;/span&gt; &lt;span style="color: rgb(204, 102, 204);"&gt;0&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-5870142249741983330?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://andrewcain.blogspot.com/2007/02/presentation-to-pdf.html' title='PS Printing in Leopard'/><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/5870142249741983330/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=5870142249741983330' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/5870142249741983330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/5870142249741983330'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2007/10/ps-printing-in-leopard.html' title='PS Printing in Leopard'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-6694360439837669898</id><published>2007-10-26T22:18:00.001+10:00</published><updated>2007-10-26T22:25:50.906+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><title type='text'>Meow...</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://images.apple.com/home/2007/images/leopardavailable_20071026.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px;" src="http://images.apple.com/home/2007/images/leopardavailable_20071026.jpg" border="0" alt="" /&gt;&lt;/a&gt;Ok installing Leopard was a little more complicated that I thought! &lt;br /&gt;&lt;br /&gt;The main problem related to a lack of resources...&lt;br /&gt;&lt;br /&gt;Yes, thats right, we were nearly out of diesel and with the current diesel shortage finding some so we could get home was an issue :)&lt;br /&gt;&lt;br /&gt;Ok, now seriously. Install = insert DVD, double click (install icon), enter username/password, click, click, click, wait, wait, click, done. It ... well ... just worked.&lt;br /&gt;&lt;br /&gt;Total time almost 2hrs. Validating the DVD took 1hr, install took 1hr.&lt;br /&gt;&lt;br /&gt;I did need to login with my admin account to finish the registration. Most apps are working, though I found that Menu Shades doesn't... &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-6694360439837669898?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/6694360439837669898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=6694360439837669898' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/6694360439837669898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/6694360439837669898'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2007/10/meow.html' title='Meow...'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-3591665522375386404</id><published>2007-10-26T17:48:00.001+10:00</published><updated>2007-10-26T17:48:41.753+10:00</updated><title type='text'>Alpha Geek</title><content type='html'>Last launch party I went to was for Windows 98... which was a bit disappointing, and as Raj reminds me took me until 4 in the morning to install. If I remember correctly... the issue was drivers for my SCSI HDD.&lt;br /&gt;&lt;br /&gt;So does it make me a Geek to say that even though I should be home in bed (... I'm not well), tonight I'll be there at the Leopard "Launch Party" down at the nearest store?&lt;br /&gt;&lt;br /&gt;I hope so :)&lt;br /&gt;&lt;br /&gt;More details once this Tiger has gone, and a Leopard takes its place. That is assuming the update goes to plan... I'm dreaming right... this never really works... Well I'll let you all know soon enough.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-3591665522375386404?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/3591665522375386404/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=3591665522375386404' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/3591665522375386404'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/3591665522375386404'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2007/10/alpha-geek.html' title='Alpha Geek'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-9071583038959456807</id><published>2007-10-25T11:24:00.001+10:00</published><updated>2007-10-25T11:24:09.811+10:00</updated><title type='text'>Whats up?</title><content type='html'>Well I haven't blogged for a while... and I just found a nice little Blogger Widget that allows me to post from Dashboard.&lt;br /&gt;&lt;br /&gt;So what exciting has happened lately? Well not much, actually. The semester went slowly at the start but the last few weeks have really shot by.&lt;br /&gt;&lt;br /&gt;In OOP the SwinTrek assignment appears to have causes some students issues, but those who really put in the effort are now showing the benefits. I definately think the assignment has proven itself in terms of learning outcomes.&lt;br /&gt;&lt;br /&gt;Advanced .NET is crusing along. The students are now starting to push themselves. Maybe I need to make the assignments due a bi earlier.&lt;br /&gt;&lt;br /&gt;Well thats enough for now. If your studying one of my subjects please let me know what you think...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-9071583038959456807?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/9071583038959456807/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=9071583038959456807' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/9071583038959456807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/9071583038959456807'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2007/10/whats-up.html' title='Whats up?'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-3803910419297422567</id><published>2007-09-11T21:00:00.000+10:00</published><updated>2007-09-11T21:07:38.957+10:00</updated><title type='text'>What should we aim for?</title><content type='html'>There has been renewed discussion of &lt;span style="font-weight:bold;"&gt;another&lt;/span&gt; round of curriculum review. If we are to review the PSD degree what should we change? What should the aims of the degree be?&lt;br /&gt;&lt;br /&gt;I think we need to build good basic software development skills, but focus more on generic skills like the ability to learn independently, investigate/research topics etc.&lt;br /&gt;&lt;br /&gt;Any ideas?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-3803910419297422567?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/3803910419297422567/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=3803910419297422567' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/3803910419297422567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/3803910419297422567'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2007/09/what-should-we-aim-for.html' title='What should we aim for?'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-5722846739267468813</id><published>2007-09-10T16:44:00.000+10:00</published><updated>2007-09-10T17:37:15.617+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><title type='text'>How important is being open?</title><content type='html'>I've been so busy since I got back from leave that I haven't had ten minutes to put any of my thoughts down in writing. Today I've finally got some time to spare so I thought I would write a quick blog entry.&lt;br /&gt;&lt;br /&gt;Over the last two years we have been planning, developing, and delivering the new Bachelor of Science (Professional Software Development) or PSD for short. This is a new degree program aimed at teaching students about modern software development, agile processes, etc. This semester I have been teaching the new Database Programming subject, the last of their programming subjects, and so I've been looking back to see how the program has turned out.&lt;br /&gt;&lt;br /&gt;I think in general that the new degree has been quite a bit of an improvement over previous degrees, in that very few of the students "hate" programming. However I think we can improve further in some areas. The one the has surprised me the most is how fixed in their ways some of the students are. Anything that offers a slight challenge is a major obstacle, and the tool is always seems to be to blame. Its not that they are not capable of using the tools, its their attitude that I am finding intriguing. The old saying "A poor worker blames his tools" keeps popping into my mind... Having said all of this, there are also students who are doing well, and are handling the challenges in an admirable fashion. I just want to improve the odds...&lt;br /&gt;&lt;br /&gt;I think its really important to be open to new ideas, and to be prepared to spend time to understand how a tool works. As software developers these students are going to be constantly faced with configuration/installation/integration types of problems. They will need to be able to work out how other software works in order to be able to work effectively with it. &lt;br /&gt;&lt;br /&gt;Anyone have any ideas for how we can encourage these students to be more open in their thinking?&lt;br /&gt;&lt;br /&gt;I want them to be inquisitive about technology, prepared to explore the potential of various solutions.&lt;br /&gt;&lt;br /&gt;I think what shocked me most (and got me wanting to write this) was one conversation I overheard... it went something like this:&lt;br /&gt;&lt;br /&gt;"My notebook is running too slow. I think I will install Linux and Beryl like X did."&lt;br /&gt;"Really! You dont want to do that. He will have spent ages tweaking it... do you really want to do that... etc. etc."&lt;br /&gt;"Yeah your right, installing Linux is too difficult... etc. etc."&lt;br /&gt;&lt;br /&gt;This really isn't what you want to hear. Playing around with another OS is a really good learning experience, and a good working knowledge of Linux is a real advantage. Not installing it because you may have to learn how to configure it is a really lame excuse. My suggestion, install Linux. Play with Beryl. What have you lost if you end up going back to Windows? Setup a dual boot, then you can play with Windows and Linux. Learning should be fun.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-5722846739267468813?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/5722846739267468813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=5722846739267468813' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/5722846739267468813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/5722846739267468813'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2007/09/how-important-is-being-open.html' title='How important is being open?'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-8026645847587568026</id><published>2007-07-25T17:52:00.000+10:00</published><updated>2007-07-25T17:57:39.553+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='subjects'/><title type='text'>Back to work</title><content type='html'>The &lt;a href="http://alipatch.blogspot.com"&gt;holiday&lt;/a&gt; had to end at some stage... I'm back at work now, and not much has changed. Currently getting ready for the semester which starts in a few weeks.&lt;br /&gt;&lt;br /&gt;My main problem at the moment is finding tutors for a new subject on Database Programming. If you know anyone good who is interested in teaching, and knows Java + C# (or one and happy to learn the other) please let me know. We currently have 6 hours of laboratories that need a tutor. Any ideas?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-8026645847587568026?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/8026645847587568026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=8026645847587568026' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/8026645847587568026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/8026645847587568026'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2007/07/back-to-work.html' title='Back to work'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-2607451597227171758</id><published>2007-05-10T17:31:00.000+10:00</published><updated>2007-05-10T18:09:00.759+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='subjects'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>To Thread or Not To Thread</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.bbc.co.uk/drama/shakespeare/60secondshakespeare/images/times/hamlet_yorick.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px;" src="http://www.bbc.co.uk/drama/shakespeare/60secondshakespeare/images/times/hamlet_yorick.jpg" border="0" alt="" /&gt;&lt;/a&gt;Today I have been asked a few threading questions from students studying at Swinburne. Usually these were about the "How to" do something with threads, when I think the real question was should threads be used at all?&lt;br /&gt;&lt;br /&gt;From what I know these students are developing a torrent like application and network protocol. The issue is that they need to accept data from a number of peers at the same time. Initially this appears to suggest the need for threads... but are they really needed?&lt;br /&gt;&lt;br /&gt;In this case I think not. The project indicate potentially thousands of peers... a threaded client with one thread per client will kill the machine with context switches before any real work can be done. So what is the answer? &lt;strong&gt;Non-Blocking IO&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;With Non-Blocking IO you dont need to block, waiting for data to arrive from a peer. Rather you keep a list of connected peers and then loop through those that have data currently available. This can all be performed on a single thread, giving good performance and throughput. &lt;br /&gt;&lt;br /&gt;Java offers a number a library of non-blocking IO utilities. Have a look at the &lt;a href="http://java.sun.com/j2se/1.4.2/docs/guide/nio/example/NBTimeServer.java"&gt;NBTimeServer.java&lt;/a&gt; example. This shows a time server that accepts connections using non-blocking IO. A quick look through the Java API and you will find the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/nio/channels/SelectableChannel.html#register(java.nio.channels.Selector,%20int)"&gt;SelectableChannel&lt;/a&gt; and the &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SelectionKey.html"&gt;SelectionKey&lt;/a&gt; class. Using the register methods, and the various SelectionKey options you can loop through only those connections that actually have data waiting to be processed.&lt;br /&gt;&lt;br /&gt;There is a good article, with a good source code example at &lt;a href="http://tim.owlmountain.com/tutorials/NonBlockingIo.htm"&gt;http://tim.owlmountain.com/tutorials/NonBlockingIo.htm&lt;/a&gt; though there is an interesting note at the start.&lt;br /&gt;As suggested in the article, you could also look at &lt;a href="http://mina.apache.org/"&gt;MINA&lt;/a&gt; the &lt;strong&gt;Multipurpose Infrastructure for Network Applications&lt;/strong&gt;. If you use MINA just stick with the basic "getting started" code and build on top of that. There is no real need to worry about fiddling with the thread model. But... check with the subject convener first...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-2607451597227171758?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/2607451597227171758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=2607451597227171758' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/2607451597227171758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/2607451597227171758'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2007/05/to-thread-or-not-to-thread.html' title='To Thread or Not To Thread'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-1423705108561593844</id><published>2007-05-08T14:46:00.000+10:00</published><updated>2007-05-08T15:01:35.087+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='subjects'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Programming 2D Games</title><content type='html'>Are you interested in programming 2d games? Got a PC, Mac, or linux box? That all you need with the new &lt;a href="http://mercury.it.swin.edu.au/swinbrain/index.php/SwinGame_V2_Pascal_API"&gt;SwinGame API&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The SwinGame API was developed initially by &lt;a href="http://mercury.it.swin.edu.au/swinbrain/index.php/User:Dchambers"&gt;Daniel Chambers&lt;/a&gt; as a Windows API for developing small games. Over the last few weeks I have been modifying the code to extend its features, and to make it cross platform. The latest version is still in testing, but is worth looking at if you are interested in creating a 2D game.&lt;br /&gt;&lt;br /&gt;SwinGame features:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Window drawing is double buffered&lt;/li&gt;&lt;li&gt;Create a Window of any size&lt;/li&gt;&lt;li&gt;Load and display images of various formats including bmp, png, and jpg&lt;/li&gt;&lt;li&gt;Works with 32 bit images, including alpha blending&lt;/li&gt;&lt;li&gt;Load true type fonts&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Read and write text&lt;/li&gt;&lt;li&gt;Draw lines, and shapes&lt;/li&gt;&lt;li&gt;Sprite management routines&lt;/li&gt;&lt;li&gt;Load and play sounds in various formats including wav, ogg, and mp3&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Detect collisions between sprites, bitmaps, and areas of the screen&lt;/li&gt;&lt;li&gt;Perform pixel level collision detection&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Vector manipulation routines&lt;/li&gt;&lt;li&gt;Use matrices to manipulate game vectors &lt;/li&gt;&lt;/ul&gt;There are a couple of games in the process of being built by the 1st year PSD students at the moment, and I will make these available for download from &lt;a href="http://mercury.it.swin.edu.au/swinbrain"&gt;SwinBrain&lt;/a&gt; as soon as they are complete.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-1423705108561593844?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/1423705108561593844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=1423705108561593844' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/1423705108561593844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/1423705108561593844'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2007/05/programming-2d-games.html' title='Programming 2D Games'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-9146644343823278685</id><published>2007-03-27T16:34:00.000+10:00</published><updated>2007-03-27T16:48:49.579+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Empty your Mind</title><content type='html'>Today one of the PSD students showed me what he had started for the game he was developing for Algorithmic Problem Solving. He had started on the game yesterday, and it already looks quite impressive. Basically this is going to be a scrolling space arcade game. So far he has the weapon firing in a number of shot combinations. The screenshot below shows the largest fire pattern.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_sV9xRhltz80/Rgi7eltwGXI/AAAAAAAAAB4/RooddeHnQQM/s1600-h/Picture+1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_sV9xRhltz80/Rgi7eltwGXI/AAAAAAAAAB4/RooddeHnQQM/s200/Picture+1.png" alt="" id="BLOGGER_PHOTO_ID_5046489516663118194" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Looks like some of the students are having fun with this assignment. The SwinGameAPI is a real hit, making this possible without having to worry about many complexities. &lt;br /&gt;&lt;br /&gt;Keep the games coming...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-9146644343823278685?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/9146644343823278685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=9146644343823278685' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/9146644343823278685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/9146644343823278685'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2007/03/empty-your-mind.html' title='Empty your Mind'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_sV9xRhltz80/Rgi7eltwGXI/AAAAAAAAAB4/RooddeHnQQM/s72-c/Picture+1.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-4335305745621360320</id><published>2007-02-14T16:50:00.000+11:00</published><updated>2007-02-14T16:53:54.240+11:00</updated><title type='text'>Another Web Development Position</title><content type='html'>I have another request for anyone interested in some web development work. Please get in touch with me if you are interested. Details follow...&lt;br /&gt;&lt;br /&gt;I'm currently looking for a student (2nd year or higher) to take on some web&lt;br /&gt;development work for us here in Corporate Marketing - 1 to 2 days a week&lt;br /&gt;fitting in with their study schedule.&lt;br /&gt;&lt;br /&gt;Here's a brief outline:&lt;br /&gt;&lt;br /&gt;Essential skills &lt;br /&gt;- HTML, CSS, graphics and JavaScript&lt;br /&gt;&lt;br /&gt;Other desirable skills&lt;br /&gt;- PHP, SQL/Databasing, Flash, design, audio and video&lt;br /&gt;&lt;br /&gt;Software&lt;br /&gt;- Dreamweaver, Fireworks, Flash&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-4335305745621360320?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/4335305745621360320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=4335305745621360320' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/4335305745621360320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/4335305745621360320'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2007/02/another-web-development-position.html' title='Another Web Development Position'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-4218015140529203811</id><published>2007-02-08T20:22:00.000+11:00</published><updated>2007-02-08T17:15:53.602+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Postscript Automator Actions</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_sV9xRhltz80/RcrsQxz1EhI/AAAAAAAAABg/LVWAzcFsJWo/s1600-h/Picture+5.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 100px;" src="http://bp0.blogger.com/_sV9xRhltz80/RcrsQxz1EhI/AAAAAAAAABg/LVWAzcFsJWo/s200/Picture+5.png" alt="" id="BLOGGER_PHOTO_ID_5029091706905367058" border="0" /&gt;&lt;/a&gt;Having played with Automator some yesterday I thought it would be interesting to create an Automator action to perform the Postscript manipulation. This would mean that I could package the scripts together in a workflow to make producing the PDFs for my subjects even easier...&lt;br /&gt;&lt;br /&gt;Creating an Automator action is actually quite easy. It basically uses an architecture inspired by Unix pipes. You can pass output from one action to the input of the next. I decided to create script actions as I already had the bash script all worked out. With this script the input is passed via the standard input. Automator also allows you to provide arguments via a simple user interface. These arguments are then passed in as environment variables. The following script illustrates the Postscript to PDF Automator action...&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_sV9xRhltz80/Rcr1TRz1EiI/AAAAAAAAABo/8Nv_oeyyRA4/s1600-h/Picture+8.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_sV9xRhltz80/Rcr1TRz1EiI/AAAAAAAAABo/8Nv_oeyyRA4/s200/Picture+8.png" alt="" id="BLOGGER_PHOTO_ID_5029101645459690018" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;pre class="bash"&gt;&lt;span style="color: rgb(128, 128, 128); font-style: italic;"&gt;#!/usr/bin/env sh&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt; -e &lt;span style="color: rgb(255, 0, 0);"&gt;"$PS2PDFBIN"&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;]&lt;/span&gt;; &lt;span style="color: rgb(177, 177, 0);"&gt;then&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;while&lt;/span&gt; &lt;span style="color: rgb(0, 0, 102);"&gt;read&lt;/span&gt; line; &lt;span style="color: rgb(177, 177, 0);"&gt;do&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt; -e &lt;span style="color: rgb(255, 0, 0);"&gt;"$line"&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;]&lt;/span&gt;; &lt;span style="color: rgb(177, 177, 0);"&gt;then&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;FILETYPE=&lt;/span&gt;`/usr/bin/file -b -i &lt;span style="color: rgb(255, 0, 0);"&gt;"$line"&lt;/span&gt;`&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"$FILETYPE"&lt;/span&gt; = &lt;span style="color: rgb(255, 0, 0);"&gt;"application/postscript"&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;]&lt;/span&gt;; &lt;span style="color: rgb(177, 177, 0);"&gt;then&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;OUTDIR=&lt;/span&gt;`/usr/bin/dirname &lt;span style="color: rgb(255, 0, 0);"&gt;"$line"&lt;/span&gt;`&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;FBASE=&lt;/span&gt;`/usr/bin/basename &lt;span style="color: rgb(255, 0, 0);"&gt;"$line"&lt;/span&gt; .ps`&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;OUTNAME=&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"${OUTDIR}/${FBASE}.pdf"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;typeset&lt;/span&gt; -i &lt;span style="color: rgb(0, 0, 255);"&gt;I=&lt;/span&gt;&lt;span style="color: rgb(204, 102, 204);"&gt;1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;while&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt; -e &lt;span style="color: rgb(0, 0, 255);"&gt;$OUTNAME&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;do&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 255);"&gt;OUTNAME=&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"${OUTDIR}/${FBASE}.$I.pdf"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 255);"&gt;I=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;$I&lt;/span&gt;&lt;span style="color: rgb(204, 102, 204);"&gt;+1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;done&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;PATH=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;$PATH&lt;/span&gt;:`/usr/bin/dirname &lt;span style="color: rgb(255, 0, 0);"&gt;"$PS2PDFBIN"&lt;/span&gt;`&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;$PS2PDFBIN&lt;/span&gt; -q -&lt;span style="color: rgb(0, 0, 255);"&gt;sPAPERSIZE=&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"$PAPER"&lt;/span&gt; -dNOPAUSE -dBATCH -&lt;span style="color: rgb(0, 0, 255);"&gt;sDEVICE=&lt;/span&gt;pdfwrite &lt;span style="color: rgb(255, 0, 0);"&gt;"$line"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"$OUTNAME"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;/bin/&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"$OUTNAME"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;else&lt;/span&gt;&lt;br /&gt;/bin/&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$line&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;fi&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;else&lt;/span&gt;&lt;br /&gt;/bin/&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$line&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;fi&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;done&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;else&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"Cannot locate executable: '$PS2PDFBIN'"&lt;/span&gt; &lt;span style="color: rgb(204, 102, 204);"&gt;1&lt;/span&gt;&amp;gt;&amp;&lt;span style="color: rgb(204, 102, 204);"&gt;2&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;exit&lt;/span&gt; &lt;span style="color: rgb(204, 102, 204);"&gt;1&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;fi&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;I will upload the action bundles soon if anyone is interested...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-4218015140529203811?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/4218015140529203811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=4218015140529203811' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/4218015140529203811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/4218015140529203811'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2007/02/postscript-automator-actions.html' title='Postscript Automator Actions'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_sV9xRhltz80/RcrsQxz1EhI/AAAAAAAAABg/LVWAzcFsJWo/s72-c/Picture+5.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-1588565023522895150</id><published>2007-02-07T19:51:00.000+11:00</published><updated>2007-02-08T09:18:16.493+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='remember'/><title type='text'>Presentation to PDF</title><content type='html'>Today I have spent a significant time preparing my lecture notes for my subjects. The subject that I am preparing has a large number of PowerPoint files that need to be printed as PDF. I wanted to print all of the PowerPoint files to double sided PDFs. Rather than doing this manually I wanted to create a script to automate the process.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_sV9xRhltz80/Rcmbslu6I9I/AAAAAAAAAA4/9bp_c1qKUJA/s1600-h/Picture+5.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; width: 100px; cursor: pointer;" src="http://bp3.blogger.com/_sV9xRhltz80/Rcmbslu6I9I/AAAAAAAAAA4/9bp_c1qKUJA/s200/Picture+5.png" alt="" id="BLOGGER_PHOTO_ID_5028721649281278930" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;Opening the Files: &lt;/span&gt;the first part of my process involved creating a script to automate the process of opening the PDF files. I organise my documents in folders, so all of the documents that I wanted to print are located in a tree under a single directory.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_sV9xRhltz80/RcmZDVu6I8I/AAAAAAAAAAw/1yWWcgMXtKA/s1600-h/Picture+4.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp2.blogger.com/_sV9xRhltz80/RcmZDVu6I8I/AAAAAAAAAAw/1yWWcgMXtKA/s200/Picture+4.png" alt="" id="BLOGGER_PHOTO_ID_5028718741588419522" border="0" /&gt;&lt;/a&gt; The Automator workflow to open the PowerPoint files is actually very simple (shown here). I attached three finder actions. The first is the &lt;span style="font-style: italic;"&gt;Get Folder Contents&lt;/span&gt; action. This action is used to process all of the items within the selected folder. Select the &lt;span style="font-style: italic;"&gt;Repeat for each subfolder found&lt;/span&gt;, so that all of the subfolders are processed.&lt;br /&gt;&lt;br /&gt;Following this action is the &lt;span style="font-style: italic;"&gt;Filter Finder Items&lt;/span&gt; action. I use this action to filter the items to those that end with "Handout.ppt" as this is the ending to all of the presentations that I want to open. The last action in the workflow is the &lt;span style="font-style: italic;"&gt;Open Finder items&lt;/span&gt; action. This action will open all of the items that are passed to it from the previous actions.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Printing the Presentations&lt;/span&gt;: The next step should have been simple... but it isn't. I started approaching this by creating a Applescript that printed via PDF. Getting the Print dialog to appear was simple, and examples all over the web illustrate how to click that PDF button, but none of them worked for me. I ended up using the UI element explorer and finding that the path to this menu is not easily achieved. In fact the explorer had issues highlighting it... If anyone knows how to get this working please let me know.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_sV9xRhltz80/RcmtD1u6I-I/AAAAAAAAABI/a0GxDZQF4Fk/s1600-h/Picture+6.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp0.blogger.com/_sV9xRhltz80/RcmtD1u6I-I/AAAAAAAAABI/a0GxDZQF4Fk/s200/Picture+6.png" alt="" id="BLOGGER_PHOTO_ID_5028740740410909666" border="0" /&gt;&lt;/a&gt; My next approach was to find a PDF printer... yes I know you can save as a PDF, but not with a script as far as I can tell. This was actually much easier than I first thought. Following the discussion on &lt;a href="http://www.macosxhints.com/article.php?story=20031116190809396"&gt;this forum&lt;/a&gt;.  The best description is on the &lt;a href="http://www.macosxhints.com/comment.php?mode=display&amp;format=threaded&amp;amp;order=ASC&amp;pid=59118"&gt;second page&lt;/a&gt;. Using this and some simple VBA script (basically for each presentation, print out the presentation) I can now print all of the open presnetations using the selected printer. Using the new PDF printer allows me to print these to PDF.&lt;br /&gt;&lt;br /&gt;Next I wanted to have the PDFs printed two per page. Adjusting the print settings and printing via the script did not work. I started looking around and found some useful postscript editing utilities... So I had gone to all that effort to get the PDF printer and what I really wanted was a postscript printer. I created a modified version of the PDF script that copied the passed in postscript to a file, allowing me to use the existing scripts. Using this I was able to create postscript files of the notes for all of the presentation.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://fink.sourceforge.net/img/mlogo.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: right; cursor: pointer; width: 100px;" src="http://fink.sourceforge.net/img/mlogo.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;Scripting PS manipulation&lt;/span&gt;: To get the postscript modifying programs download &lt;a href="http://www2.blogger.com/post-create.g?blogID=10202973"&gt;Fink&lt;/a&gt;. This installer allows you to download common Unix utilities compiled to run on Mac OS X. Install the &lt;span style="font-style: italic;"&gt;ghostscript&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;gv&lt;/span&gt;, and &lt;span style="font-style: italic;"&gt;psutils-a4&lt;/span&gt; package (for the A4 version). From the command line run the following instructions...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;find . -type f -path "*.ps" -exec psnup -b0 -m0 -l -pa4 -2 {} "{}.ps"&lt;br /&gt;find . -type f -path "*.ps.ps" -exec ps2pdfwr -sPAPERSIZE=a4 {}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_sV9xRhltz80/RcmutVu6I_I/AAAAAAAAABQ/Q9SZGAthY9Y/s1600-h/Picture+7.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp2.blogger.com/_sV9xRhltz80/RcmutVu6I_I/AAAAAAAAABQ/Q9SZGAthY9Y/s200/Picture+7.png" alt="" id="BLOGGER_PHOTO_ID_5028742552887108594" border="0" /&gt;&lt;/a&gt; This will create some strangely named file (a.ps becomes a.ps.ps and then a.ps.pdf), however the script will create the files as two per page PDF. The script also allows you to quickly process large numbers of presentations at once. With a little more work I am sure that I can create a better script, but this one has worked fine for the moment.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-1588565023522895150?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/1588565023522895150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=1588565023522895150' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/1588565023522895150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/1588565023522895150'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2007/02/presentation-to-pdf.html' title='Presentation to PDF'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_sV9xRhltz80/Rcmbslu6I9I/AAAAAAAAAA4/9bp_c1qKUJA/s72-c/Picture+5.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-733019021245594010</id><published>2007-02-05T16:57:00.000+11:00</published><updated>2007-02-05T17:04:09.449+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jobs'/><title type='text'>Interested in some part time PHP</title><content type='html'>With Uni about to go back, I have been asked if I know anyone who would be interested in a part time Job at Swinburne working on their web content using PHP... Are you interested?&lt;br /&gt;&lt;br /&gt;Who are they looking for? A Swinburne student who is interested in programming, and in learning PHP and working with MySQL.&lt;br /&gt;Do you need to already know PHP? No... as long as you are a capable programmer that should be fine.&lt;br /&gt;How about MySQL? You need to know SQL...&lt;br /&gt;How much time/money? One or two days a week in 2007 at $21 an hour&lt;br /&gt;Who do I contact? Please contact me initially. I can then put you in touch with the person in question. You will need to have an interview...&lt;br /&gt;When? You need to get in contact with me ASAP... before the start of semester 1.&lt;br /&gt;&lt;br /&gt;Let me know if you are interested.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-733019021245594010?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/733019021245594010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=733019021245594010' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/733019021245594010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/733019021245594010'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2007/02/interested-in-some-part-time-php.html' title='Interested in some part time PHP'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-117030375995061732</id><published>2007-02-01T15:22:00.000+11:00</published><updated>2007-02-01T22:39:33.657+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><category scheme='http://www.blogger.com/atom/ns#' term='applications'/><title type='text'>More Mac Tools</title><content type='html'>After having watched a vast number of &lt;a href="http://www.twit.tv/MB"&gt;MacBreak&lt;/a&gt; issues over the last week I have started to play around with a number of new applications. I thought that I would share these with you...&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.growl.info/"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 100px;" src="http://www.growl.info/img/growlicon.png" alt="" border="0" /&gt;&lt;/a&gt;The first piece of software that I have played with is &lt;a href="http://www.growl.info/"&gt;Growl&lt;/a&gt;, a notification tool for the Mac. This allows me to display notification of various events, such as network address changes, track changes in iTunes, email, Adium etc. Growl also provides a nice network feature that allows me to get notifications from my notebook on my desktop. This allows me to work without having to look at the notebook screen for "interesting" events.&lt;br /&gt;&lt;br /&gt;I have really enjoyed the &lt;a href="http://www.twit.tv/mb33"&gt;Distracted Mac&lt;/a&gt; and related episodes with &lt;a href="http://www.43folders.com/"&gt;Merlin Mann&lt;/a&gt; and as a result have started playing around with the tools that he mentions in the episode. The first &lt;span style="font-style: italic;"&gt;productivity enhancing&lt;/span&gt; change I have made is to clean up my desktop...&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_sV9xRhltz80/RcHEZFu6I5I/AAAAAAAAAAM/HgTtOXQrXJI/s1600-h/Picture+1.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp1.blogger.com/_sV9xRhltz80/RcHEZFu6I5I/AAAAAAAAAAM/HgTtOXQrXJI/s200/Picture+1.png" alt="" id="BLOGGER_PHOTO_ID_5026514594436883346" border="0" width="100" /&gt;&lt;/a&gt; To really clean this I have been playing with &lt;a href="http://www.cocoatech.com/pf4/"&gt;Path Finder&lt;/a&gt; and its ability to hide the desktop icons. In addition to hiding the desktop icons this program provides a replacement for Finder. I am still using the trial and I am not sure that its worth the $, so I have been looking for alternatives. Path Finder is quite nice, but the interface is a little too busy.  I'm not sure but I will think about it when my trial hsa run out.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://media.flip.macrobyte.net/images/ape-icon.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 100px;" src="http://media.flip.macrobyte.net/images/ape-icon.jpg" alt="" border="0" /&gt;&lt;/a&gt; Rather than switch to Path Finder on both my Macbook and my desktop I decided to look for another alternative. What I found was &lt;a href="http://flip.macrobyte.net/software/desktopsweeper"&gt;Desktop Sweeper&lt;/a&gt;, which is a &lt;a href="http://unsanity.com/haxies/ape/"&gt;Application Enhancer&lt;/a&gt; plug-in that hides desktop icons. This has worked really well, and I absolutely love the icon :)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_sV9xRhltz80/RcHJw1u6I6I/AAAAAAAAAAU/Z63Ok5kE9GI/s1600-h/Picture+2.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp0.blogger.com/_sV9xRhltz80/RcHJw1u6I6I/AAAAAAAAAAU/Z63Ok5kE9GI/s200/Picture+2.png" alt="" id="BLOGGER_PHOTO_ID_5026520500016915362" border="0" width="100" /&gt;&lt;/a&gt; The next tool is &lt;a href="http://www.versiontracker.com/dyn/moreinfo/macosx/25271"&gt;Menu Shades&lt;/a&gt;. This program provides the ability to hide the menu bar, removing another source of distraction. It is quite a nice program, but the problem is that it takes up space in the Dock. It would be much better is this had a menu bar icon... So I started looking for a way to remove the icon from the dock...&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_sV9xRhltz80/RcHMf1u6I7I/AAAAAAAAAAc/wU0EMV7iHD4/s1600-h/Picture+3.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp0.blogger.com/_sV9xRhltz80/RcHMf1u6I7I/AAAAAAAAAAc/wU0EMV7iHD4/s200/Picture+3.png" alt="" id="BLOGGER_PHOTO_ID_5026523506494022578" border="0" width="100" /&gt;&lt;/a&gt;Having a look around I found the &lt;a href="http://www.versiontracker.com/dyn/moreinfo/macosx/18195"&gt;Dockless&lt;/a&gt; program. This provides an easy way to indicate to programs that you don't want  them to load in the Dock. The program is a little "interesting" but it does work. The quit and relaunch buttons are used to quit or relaunch the selected applications... Anyway it all worked fine once I understood how it worked. Don't relaunch the Menu Shades program from this as it then fails to load it preferences. I got Dockless to remove it from the Dock and then manually restarted and it worked fine. Menu is shaded, and it is not in the Dock.&lt;br /&gt;&lt;br /&gt;I have been playing around with some other applications, but more on those at another time. If you have some other interesting Mac applications let me know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-117030375995061732?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/117030375995061732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=117030375995061732' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/117030375995061732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/117030375995061732'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2007/02/more-mac-tools.html' title='More Mac Tools'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_sV9xRhltz80/RcHEZFu6I5I/AAAAAAAAAAM/HgTtOXQrXJI/s72-c/Picture+1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-116475949467305814</id><published>2006-11-29T10:57:00.000+11:00</published><updated>2006-11-29T11:18:15.280+11:00</updated><title type='text'>PSD Summer Scholarship 2006 Pict Blog</title><content type='html'>Over the last few years we (Swinburne, and more specifically the &lt;span style="font-style:italic;"&gt;Gang of Geeks&lt;/span&gt;) have been working on developing a new software development focused degree, the Bachelor of Science(Professional Software Development) or PSD for short. The first group of PSD students have now completed their first year of the degree. There have been some issues but the course has been moving along well and the students have been great.&lt;br /&gt;&lt;br /&gt;To encourage these students to extend themselves we created the first &lt;a href="http://www.swinburne.edu.au/ict/psd/summerscholarship2006.htm"&gt;PSD Summer Scholarship&lt;/a&gt;. This program has now started and the students are making progress on several game related projects. They will be maintaining a &lt;a href="http://psdss06.blogspot.com/"&gt;Pict Blog&lt;/a&gt; (picture blog) to document their progress. Feel free to check out their work and leave some comments...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-116475949467305814?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://psdss06.blogspot.com/' title='PSD Summer Scholarship 2006 Pict Blog'/><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/116475949467305814/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=116475949467305814' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/116475949467305814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/116475949467305814'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/11/psd-summer-scholarship-2006-pict-blog.html' title='PSD Summer Scholarship 2006 Pict Blog'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-116400040041325646</id><published>2006-11-20T16:26:00.000+11:00</published><updated>2006-11-20T16:26:40.670+11:00</updated><title type='text'>I am still alive</title><content type='html'>Well it has been a while since my last post...&lt;br /&gt;&lt;br /&gt;Exams have finished and the semester is now over, so what did I learn this year? Well basically things went to plan and I have been happy with the results this semester, where as semester 1 was a bit of a mixed bag. Semester 1 I was teaching the new Algorithmic Problem Solving and the old Enterprise .NET, while I took the new Object Oriented Programming and the old Advanced .NET in semester 2. &lt;br /&gt;&lt;br /&gt;Algorithmic Problem Solving was really great, I used approaches from the Beyond Bullet Points to plan the subject and to develop the lectures. I feel that this helped manage the amount of material covered in each presentation. The results for APS were really good, not just from a numeric point of view but also from the learning outcomes. Enterprise .NET on the other hand was a bit of a mess, and as a result will not run next year as I develop new material for it.&lt;br /&gt;&lt;br /&gt;Object Oriented programming took off where APS finished. This was also a great success, but probably not as much as APS. With some more planning and re-work the results should be better still next year. Advanced .NET was really great to deliver, but still needs some rework for next year. The focus on concurrency is really now starting to concentrate on the unique issues in .NET, which is much better now.&lt;br /&gt;&lt;br /&gt;The new approaches to assessment also went well though I think I may have over done it a little. I like the idea of pass, distinction, and high distinction assessment items, though I would like to know what the students thought of it...&lt;br /&gt;&lt;br /&gt;Since the end of exams I have been creating the new Database Programming material. So far the development is going slowly, but I have been distracted by so many things. I hope to really get into it soon.&lt;br /&gt;&lt;br /&gt;Coming up for me is the PSD Summer Scholarship, I will be supervising six students who will work on developing some software and tutorial like material or four weeks. The guys start next week so I better get something organised for them :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-116400040041325646?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/116400040041325646/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=116400040041325646' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/116400040041325646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/116400040041325646'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/11/i-am-still-alive.html' title='I am still alive'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-116011820189920276</id><published>2006-10-06T14:43:00.000+10:00</published><updated>2006-10-11T10:27:27.036+10:00</updated><title type='text'>What do we learn from</title><content type='html'>I was having an interesting discussion with a colleague about our role as educators, and what was expected of that role. Basically the discussion focused on the importance of material. Is it that material that makes a good subject, or the way it is presented? This lead to two versions of an educators' role.&lt;br /&gt;&lt;br /&gt;1: &lt;i&gt;The text selector&lt;/i&gt;: The educators' role is to choose an appropriate textbook. To determine what will be covered from the text, and outline this to the students.&lt;br /&gt;2: &lt;i&gt;Guide or mentor&lt;/i&gt;: The educators' role is to provide a learning environment in which the students are able to learn the required material.&lt;br /&gt;&lt;br /&gt;From a university perspective they would prefer that teaching staff fit in category 1. A text selector is easy to replace, and move. A great educator would then be able to quickly and easily select texts, moving them from subject to subject would result very quickly an improvement across the board.&lt;br /&gt;&lt;br /&gt;I prefer to think of my role as more than just selecting a text, or even developing material. I hope that I bring more than some slides and books to the subjects that I deliver. I see my role as the development of a environment in which capable and willing students can learn. I aim to inspire students to learn, and then to be there to support their efforts. Lecture provide a means to inspire and inform (support). Laboratories give you the ability to directly assist them practice the material.&lt;br /&gt;&lt;br /&gt;Raj has a great quote for this from his agile material:&lt;br /&gt;&lt;br /&gt;"Software is built by people (not processes)&lt;br /&gt;Good people are needed to build good software&lt;br /&gt;Poor quality resources WILL build poor quality software&lt;br /&gt;A process does not build software&lt;br /&gt;A good process will aim to reduce variability (in other words will increase consistency)&lt;br /&gt;Simply put: “A bad team with a great process will &lt;span style="font-style:italic;"&gt;consistently&lt;/span&gt;&lt;br /&gt;generate garbage”&lt;br /&gt;If you are in the software game, focus on people"&lt;br /&gt;&lt;br /&gt;I think this also applies to education.&lt;br /&gt;&lt;br /&gt;So what is the role of the material that we develop? Contact time for a subject is very small, not enough to actually learn much at all. I see the material (otherwise know as &lt;span style="font-style:italic;"&gt;content&lt;/span&gt;) as playing a supporting role. With the lectures providing a few key "take home points", additional material is needed to provide the missing details. Without the material students will be on their own... Providing them with access to good material is still important, and can come from links to sites, textbooks, or custom material.&lt;br /&gt;&lt;br /&gt;So basically both are important, but I feel that presence and delivery are more important. Good delivery of the material will help students with the central points of the material, and give them the enthusiasm to put in the extra work that is needed to succeed.&lt;br /&gt;&lt;br /&gt;My 2c. Comments welcome. Have you done a subject were you feel you learnt more than others? What do you feel contributed to this?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-116011820189920276?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/116011820189920276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=116011820189920276' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/116011820189920276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/116011820189920276'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/10/what-do-we-learn-from.html' title='What do we learn from'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-115951298704461515</id><published>2006-09-29T16:56:00.000+10:00</published><updated>2006-09-29T16:56:27.516+10:00</updated><title type='text'>Beware the concurrency monster</title><content type='html'>Just when you think you know it, you relax a little and the concurrency monster is back with a vengeance! This is a true story...&lt;br /&gt;&lt;br /&gt;Once upon a time there lived a lecturer who taught concurrent programming. After years of training and practice he wandered the concurrent landscape with pride and confidence. His offerings to the programming gods had granted him safe travel, and he ventured forth with his new batch of students aiming to get further into the landscape than ever before.&lt;br /&gt;&lt;br /&gt;The adventure was going well and one night the lecturer started examining the progress of his young apprentices. While many were doing well they needed a small challenge, something to test the tools they had created. Their latches, semaphores, barriers and exchangers all looked promising, but had remained untested. &lt;br /&gt;&lt;br /&gt;"The end of the trek is near, so the challenge must be quickly created." the lecturer thought to himself as he studied their tools. Consulting the dark concurrency forces, he searched for a suitable challenge. Using a cauldron of dread he combined Wing of Interrupt, with Heart of Thread, and a touch of Join dust. In his rush he failed to see the beast that was being created... All day and all night the potion brewed, and on the following day he offered it to his students.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.deardeath.com/pictures/death_hound.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px;" src="http://www.deardeath.com/pictures/death_hound.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;Each student took the potion without question, after all he was the lecturer. The potion was slow, allowing the lecturer to depart before it stirred. Initially the tools held the beast at bay, the Latch stood strong, the Semaphore withheld... then the Barrier was broken, the Exchanger collapsed, and the tools began to fall one after the other. Valiantly the students poured over their code, inspecting it line by line, trying to find the cause of this beast. Their efforts were misguided, none could withstand the beast for it came from the potion, not their code. The concurrency monster leapt from the lecturer's code and roared into existence.&lt;br /&gt;&lt;br /&gt;The howling of the beast woke the lecturer with a jolt. Rushing to his students side the lecturer began looking for the cause of this mighty beast. Confident in his code he re-examined the students' code, but one after the other the code was safe. It handled the interrupts, and the many threads, but failed to meet at the join. There could only be one source for this beast... HIS code!&lt;br /&gt;&lt;br /&gt;Stepping up to the code, the lecturer went one on one with the beast he had created. The beast was strong, and would not go down without a fight. Code was flying here and there as the beast and lecturer did battle. Minutes later the lecturer rose, covered in code, but triumphant. Returning the tamed test to the students, he stayed around to see if the beast woke again.&lt;br /&gt;&lt;br /&gt;His caution was warranted as the second round of tests woke the very same beast. His battle had been in vain. Mustering the last of his strength the lecturer began to mind meld with the beast. Inspecting its structure and form. Searching for its weakness. Then it sprang to him. The timed methods, that can bring these tools back to life. With this new knowledge he reentered the fray and after a few hours had the beast cornered. A quick TryAcquire followed by TryExchange, and the beast went down begging for mercy. Then the final death blow, TryArrive.&lt;br /&gt;&lt;br /&gt;With the beast gone (for now) the students returned to testing their utilities. The latches held, the semaphores counted, the barriers stayed strong, and the exchangers once again began to exchange. A cautious peace returned to the world of concurrency. The lecturer once again went back to roaming the concurrency landscape. But the scars from the battle causing him to limp slightly...&lt;br /&gt;&lt;br /&gt;So when you next venture into the world of concurrency and pray to the Programming Gods, remember to make an offering to the concurrency monster... just in case.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-115951298704461515?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/115951298704461515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=115951298704461515' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115951298704461515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115951298704461515'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/09/beware-concurrency-monster.html' title='Beware the concurrency monster'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-115872136259341223</id><published>2006-09-20T12:21:00.000+10:00</published><updated>2006-09-20T13:06:12.090+10:00</updated><title type='text'>Pollution Death</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.climatechange.sa.gov.au/images/carbon_level.gif"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 200px;" src="http://www.climatechange.sa.gov.au/images/carbon_level.gif" alt="" border="0" /&gt;&lt;/a&gt; I have now read the &lt;a href="http://www.amazon.com/Inconvenient-Truth-Al-Gore/dp/0747589062/sr=8-4/qid=1158719199/ref=pd_bbs_4/002-2910676-8418404?ie=UTF8&amp;amp;s=books"&gt;Inconvenient Truth&lt;/a&gt; and seen the Movie. I have also read a number of other books on this issue, and feel a little informed. If you want to hear about what &lt;a href="http://www.ecolo.org/lovelock/"&gt;James Locklock&lt;/a&gt; thinks about this you really need to hear &lt;a href="http://www.abc.net.au/rn/scienceshow/stories/2006/1726869.htm"&gt;this program&lt;/a&gt; from &lt;a href="http://www.abc.net.au/rn/scienceshow/default.htm"&gt;Radio National Science Show&lt;/a&gt;. This is a good program, in a really bad way.&lt;br /&gt;&lt;br /&gt;Why pollution Death? Read &lt;a href="http://sethgodin.typepad.com/seths_blog/2006/03/the_problem_wit.html"&gt;Seth's blog&lt;/a&gt;, basically "Global Warming" is too fuzzy and friendly...&lt;br /&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;I am not quite at &lt;a href="http://en.wikipedia.org/wiki/K%C3%BCbler-Ross_model"&gt;despair&lt;/a&gt; yet... I believe in putting my money where my mouth is, my actions so far include:&lt;br /&gt;1: Green energy&lt;br /&gt;2: Carbon credits to offset gas usage&lt;br /&gt;3: Energy efficient appliances and light bulbs&lt;br /&gt;4: Fuel efficient car&lt;br /&gt;5: I walk to the train to go to work, unless I really need to drive (currently 1 day a week when I have late classes)&lt;br /&gt;6: I vote and there is nothing more important than this issue&lt;br /&gt;7: Letting others know (22 of us went to the Inconvenient Truth)&lt;br /&gt;8: Turn off appliances I am not using (at the wall, no standby)&lt;br /&gt;&lt;br /&gt;Future plans:&lt;br /&gt;1: Buy carbon credits for car and motorbike&lt;br /&gt;2: Buy carbon credits for purchases&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-115872136259341223?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/115872136259341223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=115872136259341223' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115872136259341223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115872136259341223'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/09/pollution-death.html' title='Pollution Death'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-115767604259143776</id><published>2006-09-08T10:40:00.000+10:00</published><updated>2006-09-08T12:37:20.566+10:00</updated><title type='text'>Migrating to Mac: Part 5: Mac Apps</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5773/3154/400/iMac.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 160px;" src="http://photos1.blogger.com/blogger/5773/3154/400/iMac.png" alt="" border="0" /&gt;&lt;/a&gt; Well I have now been using the Mac for a while, and the great thing is that I keep learning new things and finding new and interesting apps. Today I was looking at how to stop Expose trapping the F8 - F12 keys in Parallels, and I came across this &lt;a href="http://flernk.blogspot.com/2006/07/guide-to-os-x-software-for-switchers.html"&gt;blog&lt;/a&gt; on Mac apps for people switching from Windows. Its a really good read and I have installed many of the apps that are mentioned. I have also found the following apps quite useful when switching to the Mac.&lt;br /&gt;&lt;br /&gt;(Clinton provided the answer for solving my Expose problem... hold down the Apple key when pressing the F key.)&lt;br /&gt;&lt;br /&gt;&lt;h3 style="margin:0pt 0pt"&gt;Firefox&lt;/h3&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mozilla.com/firefox/"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 80px;" src="http://www.mozilla.com/images/firefox-logo-64x64.png" border="0" alt="" /&gt;&lt;/a&gt;While Safari is nice, I just cant get by without my Firefox plugins. Firefox runs well unders MacOS... so there are no problems here.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3 style="margin:0pt 0pt"&gt;Muvo Helper&lt;/h3&gt;&lt;a href="http://www.cg-tg.com/tutorials/mac/muvohlp/install/index.html" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.cg-tg.com/tutorials/mac/muvohlp/install/files/page41_5.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 160px;" src="http://www.cg-tg.com/tutorials/mac/muvohlp/install/files/page41_5.png" alt="" border="0" /&gt;&lt;/a&gt; The MuVo Helper is a small utility that performs background tasks for Creative MP3 Players like my Zen Neeon. While not essential, it is a nice addon. Basically it sits in the background removing the extra files that MacOs copies onto the device as you add music to it.&lt;br /&gt;&lt;br /&gt;&lt;h3 style="margin:0pt 0pt"&gt;Menu Meters&lt;/h3&gt;&lt;a href="http://www.ragingmenace.com/software/menumeters/" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.ragingmenace.com/software/menumeters/MenuMetersIcon.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 80px;" src="http://www.ragingmenace.com/software/menumeters/MenuMetersIcon.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;a href="http://www.byteclub.net/blog/cwoodward/"&gt;Clinton&lt;/a&gt; brought this one to my attention. This little app installs menu bar icons to show computer activity such as disk, cpu, memory, and network usage. A real must have for anyone wanting to know what is currently happening in their Mac.&lt;br /&gt;&lt;br /&gt;&lt;h3 style="margin:0pt 0pt"&gt;xCHM&lt;/h3&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://xchm.sourceforge.net/"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 80px;" src="http://xchm.sourceforge.net/pics/logo.jpg" border="0" alt="" /&gt;&lt;/a&gt;Another gem from &lt;a href="http://www.byteclub.net/blog/cwoodward/2006/08/30/view-chm-in-os-x/"&gt;Clinton's blog&lt;/a&gt;. This utility allows you to read the Microsoft help files on the Mac. Great for when you are writing code in Parallels. The code is shown on one screen in Parallels, and the documentation can be open on the Mac on another screen.&lt;br /&gt;&lt;br /&gt;&lt;h3 style="margin:0pt 0pt"&gt;Aquamacs&lt;/h3&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://aquamacs.org/"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 80px;" src="http://aquamacs.org/aquamacs.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;a href="http://www.apple.com/downloads/macosx/productivity_tools/aquamacsemacs.html"&gt;Aquamacs&lt;/a&gt; is emacs for the Mac. It includes both emacs shortcuts as well as standard MacOs shortcuts. This works well for me...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3 style="margin:0pt 0pt"&gt;Booxter&lt;/h3&gt;&lt;a href="http://www.deepprose.com/" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand; width: 80px;" src="http://www.deepprose.com/images/booxter/BooxterIconSmall.png" border="0" alt="" /&gt;&lt;/a&gt;This is a funky little library application, allowing you to keep track of your personal library. It has features to track who has borrowed your books, and can import details from various web sites such as Amazon. The ability to scan books using the Mac's built in camera is also neat... though I have found it doesn't pick up the details that easily.&lt;br /&gt;&lt;br /&gt;&lt;h3 style="margin:0pt 0pt"&gt;Poseidon for UML&lt;/h3&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.gentleware.com"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/1294/778/200/Picture%201.png" border="0" alt="" /&gt;&lt;/a&gt;I needed a tool for drawing UML diagrams, and this did the trick. It is a little clunky to use, though I haven't spent much time with it at the moment. This is a full UML tools keeping track of the model, so with some reverse engineering support it should be good. There is a free community edition.&lt;br /&gt;&lt;br /&gt;&lt;h3 style="margin:0pt 0pt"&gt;iTerm&lt;/h3&gt;&lt;a href="http://www.macupdate.com/info.php/id/10301" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 80px;" src="http://www.macupdate.com/images/icons/10301.png" border="0" alt="" /&gt;&lt;/a&gt;An alternative terminal program that allows terminals in tabs... Quite a nice alternative to the standard terminal.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-115767604259143776?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/115767604259143776/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=115767604259143776' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115767604259143776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115767604259143776'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/09/migrating-to-mac-part-5-mac-apps.html' title='Migrating to Mac: Part 5: Mac Apps'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-115735352686087007</id><published>2006-09-04T16:45:00.000+10:00</published><updated>2006-09-15T10:25:32.876+10:00</updated><title type='text'>Documenting C# Projects</title><content type='html'>Playing around with .NET 2.0 and Visual Studio .NET 2005 has left me asking what do I need to communicate with my designs. The class diagrams in Visual Studio are very elegant, and remove my desire for creating UML class diagrams once I start playing around with a solution. UML class diagrams are great for modelling problem space, and thinking pre-solution, but one I start thinking solution I am now heading to VS for my diagrams.&lt;br /&gt;&lt;br /&gt;There are a few things missing from the VS diagram that do cause me some headaches.&lt;br /&gt;1: Dependency. It would be great to be able to show dependency type relations in the diagram.&lt;br /&gt;2: Lack of diagrams to represent object dynamics.&lt;br /&gt;&lt;br /&gt;I have voted on the first item on the MS &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=115080"&gt;feedback &lt;/a&gt;regarding VS.&lt;br /&gt;&lt;br /&gt;On the second point I am still using UML diagrams to describe these. Visio has been my UML tool in the past, though it is challenging to use. Today I started playing around with &lt;a href="http://www.gentleware.com/"&gt;Poseidon for UML&lt;/a&gt;.  Looks like it has potential, but it does not support reading in class details from C# code... Examining the list of features it does support shows XMI, so I started looking for a tool to convert my C# code into XMI, and I found the following freeware. The &lt;a href="http://www.download.com/DotNet2UML/3000-10252-10341372.html"&gt;DotNet Assembly to XMI Creator 2.1&lt;/a&gt; tool is able to convert .NET assemblies into XMI according to its documentation. Unfortunatly the product does not support .NET 2 assemblies... nice try :(&lt;br /&gt;&lt;br /&gt;An open solution to this would be nice... I have created a quick open source library to do this called &lt;a href="http://code.google.com/p/xmi4dotnet/"&gt;xmi4dotnet&lt;/a&gt;. I have hosted it on google to allow access to the source. I will also setup a game for it at sometime on SwinBrain. This tool allows you to export xmi code from .NET assemblies. It uses the Reflector tool to examine the model and loads into this tool as an addin. It exports all the different .NET types as well as fields, properties, etc. I have tested the export and the xmi can be loaded into Poseidon. Try it out and let me know any changes you want made (use the bug tracker on the google code hosting page).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-115735352686087007?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/115735352686087007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=115735352686087007' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115735352686087007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115735352686087007'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/09/documenting-c-projects.html' title='Documenting C# Projects'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-115732623378217584</id><published>2006-09-04T09:30:00.000+10:00</published><updated>2006-09-04T09:30:33.983+10:00</updated><title type='text'>Microsoft Recruiting in AU</title><content type='html'>Microsoft is recruiting developers in Australia again. If you are finishing your degree this year, or have already finished, you may want to apply...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-115732623378217584?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://mercury.it.swin.edu.au/acain/media/MSIntRecruit06.pdf' title='Microsoft Recruiting in AU'/><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/115732623378217584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=115732623378217584' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115732623378217584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115732623378217584'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/09/microsoft-recruiting-in-au.html' title='Microsoft Recruiting in AU'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-115671956369779495</id><published>2006-08-28T08:33:00.000+10:00</published><updated>2006-08-28T08:59:24.230+10:00</updated><title type='text'>Open Day Fun</title><content type='html'>Yesterday was &lt;a href="www.swinburne.edu.au"&gt;Swinburne's&lt;/a&gt; open day, and once again this ment a day of answering questions about our new &lt;a href="http://www.swin.edu.au/ict/courses/undergrad/PSD.htm"&gt;B.Sc. (Professional Software Development)&lt;/a&gt; degree. I dont know how many people I talked to, but I didn't stop all day. The two presentations I gave were great fun, and I hope people were informed as well as inspired by them. We had several give aways, including &lt;a href="http://www.atomicmpc.com.au/"&gt;atomic magazine&lt;/a&gt;, and fun stuff like pens and flashing badges. For me open day was a great success. Lets hope the prospective students did as well... I look forward to seeing you guys next year if you did :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-115671956369779495?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/115671956369779495/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=115671956369779495' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115671956369779495'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115671956369779495'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/08/open-day-fun.html' title='Open Day Fun'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-115328148531973642</id><published>2006-07-19T13:34:00.000+10:00</published><updated>2006-07-20T12:47:33.500+10:00</updated><title type='text'>Migrating to Mac: Part 4: Parallels</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.parallels.com/files/upload/desktop_for-mac_box3.gif"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 200px;" src="http://www.parallels.com/files/upload/desktop_for-mac_box3.gif" alt="" border="0" /&gt;&lt;/a&gt;I have now been using the Mac for a number of weeks, and have been enjoying the experience. So far I haven't had any real issues that I haven't been able to get around. Setting up the printer was the hardest task...&lt;br /&gt;&lt;br /&gt;I am using &lt;a href="www.parallels.com"&gt;parallels&lt;/a&gt; desktop for Mac to allow me to run Windows while working on the Mac. Initially I also installed Boot Camp but I found that I just didn't use it... So after a few week I reclaimed the space from Boot Camp and now run purely with parallels.&lt;br /&gt;&lt;br /&gt;There are a few things that really help make the Parallels experience even better. These are the things that I have done so far, and I am open to new suggestions.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://unsanity.com/images/icons/big/ape.gif"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 200px;" src="http://unsanity.com/images/icons/big/ape.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;1: Install unsanity's &lt;a href="http://www.unsanity.com/haxies/ape"&gt;Application Enhancer&lt;/a&gt; and then get the &lt;a href="http://www.multisolar.com/software/PDTweaker/"&gt;PD Tweaker&lt;/a&gt;. This "tweaks" Paralells Desktop and I have found helps smooth the experience of using it and other applications at the same time. If you are interested you can read about this at &lt;a href="http://www.macosxhints.com/article.php?story=20060622090404212"&gt;MacOS X Hints&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2: Initially I was using the bridged network adapter that comes with Paralells. This has the unfortunate (and fully intentional) problem that it exposes the virtual machine to the network. This causes me some problems as the network admins here tend to block access to "strange" machines that appear on the network. Also, I wanted to be able to access the host machine from the Windows machines. As I move between networks the real IP address of my machine changes, as will the bridged interface. To avoid this I switched to host only access, and then routed connections using the Mac's internet sharing.&lt;br /&gt;&lt;br /&gt;Getting internet sharing working takes a little work if you also want to firewall your machine. If you follow the Mac's advice it will have you installing the Personal Web Service, and openning ports to the world... You can get around this by configuring the firewall yourself. A script on &lt;a href="http://www.macworld.com/forums/ubbthreads/showflat.php?Cat=&amp;Board=newsthread&amp;amp;amp;amp;amp;Number=404105&amp;page=0&amp;amp;view=collapsed"&gt;MacWorld&lt;/a&gt; shows how to configure the firewall using ipfw. With some modification you should be able to change this script to provide Parallels access to the network.&lt;br /&gt;&lt;br /&gt;4: Setting up a source repository was next on the list. With the host now being accessible at 192.168.2.1 I have a fixed point to access... Step 1 is to get the sshd running to allow remote login to my Mac. This turns out to be as simple as clicking a button. In System Preferences goto the Sharing section and in Services turn on Remote Login... and your done.&lt;br /&gt;&lt;br /&gt;Now you will be able to access your machine both from inside Parallels, but also from the outside world. To turn this off edit your Firewall script and alter the rule that allows any access to destination ports ssh, http, and https. Change the any to $inrange1 and your done. Re-run the Firewall script and check access from Parallels and from an external machine. With ssh access the next step is to setup cvs.&lt;br /&gt;&lt;br /&gt;Setup the cvs repository on the Mac and imported a test module. Now to access it from the PC. WinCVS was already installed as was Putty and PLink, so I created a new key file and set it up to allow login using Pageant. Connecting to cvs on the mac was then as easy as entering the new cvs root and checking out the test module. I also have Tortoise installed, but cant get it to connect using the ext protocol anymore...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-115328148531973642?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/115328148531973642/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=115328148531973642' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115328148531973642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115328148531973642'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/07/migrating-to-mac-part-4-parallels.html' title='Migrating to Mac: Part 4: Parallels'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-115041586461909445</id><published>2006-06-16T08:56:00.000+10:00</published><updated>2006-06-16T09:57:44.833+10:00</updated><title type='text'>Migrating to Mac: Part 3: Tale of the two Syncs...</title><content type='html'>One of the things that I knew would be an issue with my new Mac was syncing me PDA. I have an old O2 XDA II Pocket PC (Phone Edition). Anyone who has used a PocketPC Phone knows that the only way to use it is with a PC. Keeping your contacts and appointments synchronised across the devices is important. Getting something to sync the Mac with the PDA was critical.&lt;br /&gt;&lt;br /&gt;I decided to setup a sync program as one of my first tasks. So after installing Office 2004 and copying my e-mail across I started searching for a solution. I found that there are two main solutions &lt;a href="http://www.pocketmac.com"&gt;PocketMac&lt;/a&gt; and &lt;a href="http://www.markspace.com/"&gt;The Missing Sync&lt;/a&gt;. From my initial reading PocketMac appeared to have been around longer and had a few extra features. So I paid, downloaded and installed PocketMac.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.pocketmac.com/images/pro_box_small.jpg"&gt;&lt;img style="float:left; margin:0 10px 0px 10px;cursor:pointer; cursor:hand;width: 100px;" src="http://www.pocketmac.com/images/pro_box_small.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;PocketMac was a little tricky to get working correctly and does not work with USB on the new Intel Macs. Their web site indicates that it is a Mac problem that they have to work around, I should have realised something was wrong when I read this... Anyway, I eventually got it working with Bluetooth. It worked ok for one day, and then... it stopped working. I'm not exactly sure what went wrong. I was in the process of installing a variety of other programs so what was conflicting with what was not something that I could work out. I followed PocketMac's troubleshooting advice and eventually, after about 5 hours of reading logs and experimenting, I eventually gave up and posted a support request. I posted their trace report, and made sure that I outlined most of what I had tried. After a day I got back a post of their "Dont use USB, use Bluetooth". So they didn't even read any of my help request. I replied, and after another day they esclated it to their next support level. I waited, and waited, and well nothing. After a week and a half I gave up on them and asked for a refund. Looking back, their product was not really well polished, and their web site is not very professional.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.markspace.com/images/icon_wm_sync.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 160px;" src="http://www.markspace.com/images/icon_wm_sync.jpg" alt="" border="0" /&gt;&lt;/a&gt; So yesterday I purchased The Missing Sync for Windows Mobile. After such a bad experience with PocketMac I prepared for the worst. Their web site has a section on &lt;a hred="http://www.markspace.com/support/index.php?x=&amp;mod_id=2&amp;amp;id=1"&gt;migrating from PocketMac&lt;/a&gt;, which I thought was interesting. I followed their instructions and rid my Mac and PocketPC of their software. With this done I set about installing The Missing Sync. The install went smoothly. I plugged in my PocketPC and started the Sync. A connecting overlay appeared on screen and the PocketPC tried to connect to the Mac. This was a nice addition, the status shows which state the connection is in something that wasn't provided by PocketMac. Anyway the bad news at this point was that it failed to connect... I was not overly concerned as in the attempt to connect with PocketMac I had played with many settings on the PocketPC. I renamed the PocketPC for sync purposes then tried connecting again. This time everything worked. I setup the partnership which overrode the PocketMac partnership on the device. The sync was a little slower than with PocketMac. However, it works and provides feedback on where it is up to which is always good to see. The Missing Sync program is far more polished, as is their web site. I cannot comment on their support as I haven't needed it. The Missing Sync also connects via USB and Bluetooth, both of which are working fine for me.&lt;br /&gt;&lt;br /&gt;Both PocketMac and Missing Sync are able to sync contacts with Entourage, or the Mac Address Book, and appointments with Entourage or iCal. So you dont need Entourage to make use of these.&lt;br /&gt;&lt;br /&gt;Note: I didn't try renaming my PocketPC with PocketMac. This may have corrected the issue I was having. However, I dont know and I'm not going to reinstall it to try.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-115041586461909445?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/115041586461909445/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=115041586461909445' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115041586461909445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115041586461909445'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/06/migrating-to-mac-part-3-tale-of-two.html' title='Migrating to Mac: Part 3: Tale of the two Syncs...'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-115024521958467607</id><published>2006-06-14T09:06:00.000+10:00</published><updated>2006-06-14T10:40:18.146+10:00</updated><title type='text'>Migrating to Mac: Part 2</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/1294/778/1600/OfficeEntourage.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://photos1.blogger.com/blogger/1294/778/200/OfficeEntourage.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Having received my Mac the first task I had was to migrate my e-mail, contacts, and appointments. On my notebook I have been using Outlook 2003, so the plan was to switch to Microsoft's equivalent program on the Mac. The first issue was finding what that product was called. I had incorrectly thought that it would still be called Outlook... With some googling I became familiar with the Entourage product, the mail/contacts/appointments program in &lt;a href="http://www.microsoft.com/mac/products/office2004/office2004.aspx?pid=office2004"&gt;Office 2004 for Mac&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;As we have licenses for Office for Mac I installed the suite which was a very pleasant process compared to the same process on a PC. Insert the CD start the installer and the hard work is all done. Before I could get up the installer was finished. Having used a PC for so long I am used to the hours of waiting while office installs and registers everything...&lt;br /&gt;&lt;br /&gt;With Entourage installed the next step was to migrate my data from Outlook 2003. Cant be that difficult I thought to myself, after all it is Microsoft -&gt; Microsoft. Open Entourage, which looks great its not just a simple port of Outlook, and then start looking for import. Entourage can import mail from csv files, mbox, earlier versions of office for Mac, but not any of the Outlook for Windows products. Ok... Goggle time.&lt;br /&gt;&lt;br /&gt;There are several ways of performing this migration.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.macuser.co.uk/macuser/news/70286/microsoft-pipes-outlook-to-entourage.html"&gt;MacUser&lt;/a&gt; has a very convincing article noting that Microsoft has released a converter. When you get to the Microsoft site you find that it can only import from previous Mac versions.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.entourage.mvps.org/cross_platform/win_mac.html"&gt;mvp.org&lt;/a&gt; has a page that lists a few options including using an IMAP or Exchange server neither of which I had access to. They also offer links to some scripts to do this. These seem overly complex for the task in my opinion.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;There is a product called &lt;a href="http://www.littlemachines.com/index.html"&gt;O2M&lt;/a&gt;. For $10 this is a good option. It can transport mail, contacts, appointments, etc. from Outlook to mbox, iCal, etc formats that you can then import on the Mac. I used the trial version but was too cheap to purchase it for the one off transfer of data.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;The approach that I used is explained by &lt;a href="http://www.riches.com.au/articles/export-outlook-entourage.htm"&gt;Dave Riches&lt;/a&gt; and also on the &lt;a href="http://www.oreillynet.com/cs/user/view/cs_msg/9928"&gt;O'Reilly Network&lt;/a&gt;. This process involves converting the e-mail in your Outlook PST file into individual mbox files that can then be imported into Entourage.&lt;br /&gt;&lt;br /&gt;The process that I followed best matches Dave's process.&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Install &lt;a href="http://www.mozilla.com/thunderbird/"&gt;Thunderbird&lt;/a&gt;, which has the ability to import PST files and internally it stores its mail as mbox files.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Copy files to Mac&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Drag mbox files into Entourage&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;The process is simple enough except that I arrange my mail into a hierarchy of folders. When you import your mail into Thunderbird it will create a folder for each mail folder in Outlook. Each of these folders then contains its subfolders and a mbox file with the mail from that folder. There was no way that I was going to drag all of these individual files into Entourage. However, the files are now just simple text files and can therefore be altered via the command line.&lt;br /&gt;&lt;br /&gt;The first thing that I decided to do was to compact some of my folder hierarchies. I did this at a Command Prompt on my Windows machine. The command to do this is:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(for /F "delims=" %i IN ('dir /s /b *.') DO @type "%i") &gt; NewMailFile.mbox&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Execute this command in the folder that you want to compress the mbox files into. In my case I kept a folder with all of my internet site subscription e-mails (like blogger, feedburner, bloglines, etc). I have subscribed to many sites! I executed this command in the folder containing my "Internet Sites" mailbox, compressing these into a single mbox file.&lt;br /&gt;&lt;br /&gt;At this point I copied all of the mbox files to my Mac. Thunderbird does not add an mbox extension to its files and unfortunately Entourage will only import them if they have the mbox extension. The following command run at the Mac Terminal, in the directory where you copied your mail files and folders.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;find . -type f -print -exec mv "{}" "{}.mbox" \;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With this done you can now drag each of the mbox files into Entourage. The import is complete.&lt;br /&gt;&lt;br /&gt;With my mail in Entourage I then proceeded to transfer my contacts and appointments. As I use a PDA I did this by syncing Outlook with my PDA and then syncing the PDA with Entourage. In order to do this I purchases &lt;a href="http://www.pocketmac.com/"&gt;PocketMac Pro&lt;/a&gt;. Once I got it installed and followed the instructions it synced all of my contacts and appointments. PocketMac itself worked for a couple of days but lately it has stopped working. I'm not sure what else I have installed that could cause this problem and the PocketMac support is very slow. If this is not resolved soon I am going to try &lt;a href="http://www.markspace.com/missingsync_windowsmobile.php"&gt;The Missing Sync for Windows Mobile, v2.0&lt;/a&gt;, unfortunately they don't have a trial version otherwise I would have switched sooner. (If anyone has any advice on this let me know...)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-115024521958467607?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/115024521958467607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=115024521958467607' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115024521958467607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/115024521958467607'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/06/migrating-to-mac-part-2.html' title='Migrating to Mac: Part 2'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114958601568060324</id><published>2006-06-06T19:26:00.000+10:00</published><updated>2006-06-07T10:51:35.566+10:00</updated><title type='text'>Migrating to Mac: Part 1</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://images.apple.com/au/macbookpro/images/index1520060424.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px;" src="http://images.apple.com/au/macbookpro/images/index1520060424.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;Recently I decided to get a new notebook. My current notebook is a Toshiba S1 with 1GB RAM and a ATI Mobile 9000 card. I needed to upgrade for several reasons. Firstly I need more RAM. I do distributed .NET development and presentations on the notebook and I want to run multiple Virtual PCs at once. One running a web server, another for the app server and one for the database server. With 1GB of RAM I can run one virtual machine but the others are really pushing it. Secondly I want to play around with Vista, I need a DirectX 9.0 graphics card. With this in mind I started looking for a notebook to meet my needs.&lt;br /&gt;&lt;br /&gt;Needs:&lt;br /&gt; - Presentations and office document creation (PowerPoint, Word, Excel)&lt;br /&gt; - .NET development (3-Tier demonstrations... with 3 tiers)&lt;br /&gt; - DirectX 9 capable (for Vista)&lt;br /&gt;&lt;br /&gt;I have been reading about Apple's &lt;a href="http://www.apple.com/au/macbookpro/"&gt;MacBook Pro&lt;/a&gt; and this started to look like a viable alternative. Apple offers a nice package, well thought out design, good hardware spec, with the capability of running both MacOS and Windows. Other notebooks offer similar features, but not the entire package.&lt;br /&gt;&lt;br /&gt;I spent some time finding out the capabilities of the MacBook in relation to my requirements. A quick watch of the &lt;a href="http://www.youtube.com/watch?v=Dbt9upE6hpM"&gt;Fast OS Switching&lt;/a&gt; and related videos appear to demonstrate the ability for the MacBook to meet my most important requirement, multiple virtual machines. The main issue with these videos is that they are usually running only a web browser in each virtual machine. I need to do more. Based on the machine spec I believe that it will be capable of meeting my requirements.&lt;br /&gt;&lt;br /&gt;So the Plan became:&lt;br /&gt;* Get a MacBook Pro 2.16GHz with 2GB RAM (and faster disk).&lt;br /&gt;* Get Office 2004&lt;br /&gt;* Migrate Outlook to Entourage (Office 2004's equivalent to outlook)&lt;br /&gt;* Install &lt;a href="www.parallels.com"&gt;Parallels&lt;/a&gt;&lt;br /&gt;* - Setup multiple virtual machines to enable distributed .NET development&lt;br /&gt;* Install Boot Camp&lt;br /&gt;* Install Vista in VM Ware within XP&lt;br /&gt;&lt;br /&gt;This plan has recently been put into action. I have now received my MacBook Pro and have started the migration process. A few issues have arisen since I received the notebook. I need the following:&lt;br /&gt;&lt;br /&gt;1: a keyboard that supports both Mac and Windows.&lt;br /&gt;2: to be able to sync my PocketPC with Entourage&lt;br /&gt;3: to be able to sync music with my Zen Neeon&lt;br /&gt;&lt;br /&gt;The keyboard issue was one that I had not thought of before. At home I used a &lt;a href="http://www.logitech.com/index.cfm/downloads/software/AU/EN,CRID=1796,contentid=6997"&gt;Logitech Cordless MX Duo&lt;/a&gt; that has drivers for both Mac and Windows, so problem solved. I will cover the other details as I go.   &lt;br /&gt;&lt;br /&gt;In the next part I will look at migrating my contacts and mail from Outlook to Entourage.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114958601568060324?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114958601568060324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114958601568060324' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114958601568060324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114958601568060324'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/06/migrating-to-mac-part-1.html' title='Migrating to Mac: Part 1'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114897458838693275</id><published>2006-05-30T17:35:00.000+10:00</published><updated>2006-05-30T17:36:28.520+10:00</updated><title type='text'>Thinking in Objects</title><content type='html'>Finally got around to starting the new Object Oriented Programming subject today. I have now selected a text that I hope will work out well. The Object Oriented Programming subject is going to use C# as the implementation language, though it will focus on Object Oriented Programming and design rather than on the language and related libraries... &lt;br /&gt;&lt;br /&gt;The book I am going with (and yes it is too late to change now) is "Object Design: Roles, Responsibilities, and Collaborations". I have skimmed over most of it and now read chapter one in detail. It looks really good. The initial focus is on understanding design concepts. I think this is a good start. For the first lecture I have created a "Everything C#" followed by "Building programs with objects" presentations. The first is a bit shock and awe, covering most of the C# syntax, but that needs to be done somewhere and I want to get it out of the way so we can start on the real material. The second presentation looks at what objects are and how we build programs using them. I am happy with how it has turned out so far. Another Beyond Bullet Points success, I hope.&lt;br /&gt;&lt;br /&gt;Week one is mostly out of the way. I have found an online tutorial for learning C# so that will be the lab work. The structure for the presentations is out of the way, and I have the text to fill in the design gaps that I am leaving. Its great being able to focus purely on objects knowing that these guys will have some idea about what programs are and their internal workings.&lt;br /&gt;&lt;br /&gt;More to come as this unrolls...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114897458838693275?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114897458838693275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114897458838693275' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114897458838693275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114897458838693275'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/05/thinking-in-objects.html' title='Thinking in Objects'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114834024187490731</id><published>2006-05-23T09:23:00.000+10:00</published><updated>2006-05-23T09:24:02.173+10:00</updated><title type='text'>MacSaber</title><content type='html'>The real reason for me getting a MacBook is &lt;a href="http://isnoop.net/blog/2006/05/20/macsaber-turn-your-mac-into-a-jedi-weapon?www.reghardware.co.uk"&gt;now out&lt;/a&gt;!.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114834024187490731?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://isnoop.net/blog/2006/05/20/macsaber-turn-your-mac-into-a-jedi-weapon?www.reghardware.co.uk' title='MacSaber'/><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114834024187490731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114834024187490731' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114834024187490731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114834024187490731'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/05/macsaber.html' title='MacSaber'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114833600617623067</id><published>2006-05-23T08:07:00.000+10:00</published><updated>2006-05-23T08:13:26.470+10:00</updated><title type='text'>Blogging as a PSD</title><content type='html'>So you are a uni student now. Why should you blog? Blogging is a great way of letting others know about the cool and interesting stuff that you are doing. Found a cool web site, got some new hardware, done a great assignment, played with some new tech, want to comment on your lectures... All of these are great blog topics.&lt;br /&gt;&lt;br /&gt;Keep your blog reasonably professional and it can become part of your online profile that you can use in your resume. Shows employers that you are interested in IT. When you review something new upload a review to your blog and it will also show that you are capable. &lt;br /&gt;&lt;br /&gt;Get a blog now, and let others (me included) know about it. I'm ready to subscribe...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114833600617623067?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114833600617623067/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114833600617623067' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114833600617623067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114833600617623067'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/05/blogging-as-psd.html' title='Blogging as a PSD'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114792038417338728</id><published>2006-05-18T12:17:00.000+10:00</published><updated>2006-05-18T12:46:24.416+10:00</updated><title type='text'>The Security Guy</title><content type='html'>I have attended a number of presentations over the last week, and one has really stuck with me... Unfortunately not because of how good it was. The presentation was about the current state of internet security. The person was really passionate about identity theft, but was way over the top with his message. The result was that anything of value was lost...&lt;br /&gt;&lt;br /&gt;My recall of the presentation goes as follows:&lt;br /&gt;&lt;br /&gt;You use fly buys - wow... Don't use fly buys&lt;br /&gt;You use internet banking - wow... Don't use internet banking&lt;br /&gt;You don't encrypt your hard drive - wow...&lt;br /&gt;don't leave your computer on...&lt;br /&gt;don't access the internet&lt;br /&gt;You use internet explorer - wow... Don't use IE&lt;br /&gt;You use office - wow don't use office&lt;br /&gt;(now let me go a little further...)&lt;br /&gt;don't use a computer&lt;br /&gt;don't cross the road&lt;br /&gt;don't drive a car&lt;br /&gt;don't carry cash&lt;br /&gt;don't deal with banks&lt;br /&gt;don't deal with people&lt;br /&gt;Become a hermit and remove yourself from society&lt;br /&gt;&lt;br /&gt;That is the logical extension of the presentation...&lt;br /&gt;&lt;br /&gt;Now unfortunately there was no real advice. There was nothing of value that you could take away from the presentation. In a work environment many people use Office, they are going to need to. Saying don't use office is not going to help. Saying, office has a large number of issues, these are the main ones, this is what you can do to avoid many issues, these are the risks that you cant avoid, etc. That would be useful, you can take something away from the presentation. Just saying 'don't use it' is really a waste of time. I use it every day and I'm still here...&lt;br /&gt;&lt;br /&gt;If you give a presentation think about what your audience is taking away. If there is nothing for them they will not be satisfied.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114792038417338728?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114792038417338728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114792038417338728' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114792038417338728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114792038417338728'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/05/security-guy.html' title='The Security Guy'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114776430736875527</id><published>2006-05-16T17:21:00.000+10:00</published><updated>2006-05-16T17:25:07.936+10:00</updated><title type='text'>Media Center</title><content type='html'>I can now say that Media Center has been a real success. Last week Alison said that we should get "something" so that we could connect the TV in the bedroom to the Media Center. Life with standard TV is no longer acceptable. The next part of the conversation went "We should get another 360 for the bedroom", "Yes ... something like that". This comment has been strongly denied :)&lt;br /&gt;&lt;br /&gt;I will look into the cost of getting another Media Center extender, but if the cost of getting a 360 drops then that will be the desired device.&lt;br /&gt;&lt;br /&gt;Big ticks for media center.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114776430736875527?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114776430736875527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114776430736875527' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114776430736875527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114776430736875527'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/05/media-center.html' title='Media Center'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114739120784160725</id><published>2006-05-12T08:27:00.000+10:00</published><updated>2006-05-12T09:46:48.190+10:00</updated><title type='text'>XBox = Sport</title><content type='html'>&lt;a href="http://www.theregister.co.uk/2006/05/11/ms_newscorp_gaming_collaboration/"&gt;Microsoft and NewsCorp&lt;/a&gt; are banding together to create a professional gaming league... &lt;br /&gt;&lt;br /&gt;"News Corp will aim the big guns of DirecTV, IGN Entertainment and Fox Interactive Media at the project, which is likely to glorify Microsoft Xbox games"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114739120784160725?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114739120784160725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114739120784160725' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114739120784160725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114739120784160725'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/05/xbox-sport.html' title='XBox = Sport'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114715804592586739</id><published>2006-05-09T16:54:00.000+10:00</published><updated>2006-05-09T17:00:56.796+10:00</updated><title type='text'>My first step toward becoming a pod person</title><content type='html'>Well I have asked for a MacBook Pro and even before I get it I'm thinking how I can use Mas OS X rather than windows for a number of things... Get Office for Mac, Free Pascal works, get the mono c# compiler. hmmm so what will I use windows for?&lt;br /&gt;&lt;br /&gt;Well I still love Visual Studio. So Parallels can host a virtual PC for me with Windows and I'll run Visual Studio in that as I need to. Thats what I do at the moment on my PC anyway (except with Virtual PC rather than parrellels).&lt;br /&gt;&lt;br /&gt;With some luck I'll get approval and start looking at dual booting with Vista soon!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114715804592586739?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://apple.slashdot.org/apple/06/05/04/1944243.shtml' title='My first step toward becoming a pod person'/><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114715804592586739/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114715804592586739' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114715804592586739'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114715804592586739'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/05/my-first-step-toward-becoming-pod.html' title='My first step toward becoming a pod person'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114713998811428273</id><published>2006-05-09T11:59:00.000+10:00</published><updated>2006-05-09T11:59:48.510+10:00</updated><title type='text'>Talents</title><content type='html'>I have been thinking about people's talents and their study choices.&lt;br /&gt;&lt;br /&gt;If you are talented in some area, and you enjoy it, should you seek to advance this or study other areas which are more "in favor" with industry at the time? &lt;br /&gt;&lt;br /&gt;As a faculty of ICT we have been blessed with many students lately. Most of these had little talent or interest in ICT. (I'm sure that they all have talents, just not in ICT) These students obviously thought that it was better to study something that is in favor than to study what they are good at and interest in...&lt;br /&gt;&lt;br /&gt;In my opinion I would always choose to build upon my talents than to go with current trends. &lt;br /&gt;&lt;br /&gt;Having said this, I haven't always done this. I studied a Business/IT degree even though my real talents and interest lay in software development. At the time I didn't realise what I was doing. The degree that I studied came with a scholarship and the money helped make a real difference. I also didn't realise what I was missing. No one ever bothered to say "Hey your good at this. Did you know that there is all this other stuff that you may also be interested in..." I ended up doing well in my degree and getting a job that I hated. Being a proactive person within 6 (painful) months I got myself another scholarship and went back to uni to learn as much of "the other stuff" as I could. The only problem was that I was now doing it on my own. If I had my time again I would choose to do a technical IT degree, and do IBL to get some extra $.&lt;br /&gt;&lt;br /&gt;Anyway the question remains, should you follow your interests (and talents), or study areas which have job shortages and hope to build interest and talent? What are your thoughts on this?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114713998811428273?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114713998811428273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114713998811428273' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114713998811428273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114713998811428273'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/05/talents.html' title='Talents'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114645520614542098</id><published>2006-05-01T12:56:00.000+10:00</published><updated>2006-05-01T14:44:12.846+10:00</updated><title type='text'>Late Weekend</title><content type='html'>Wow, am I tired. This weekend was a struggle. Its good to be back at work.&lt;br /&gt;&lt;br /&gt;Friday night I decided to extend the WinGraph Pascal unit to include the ability to load and draw images on the screen. Finding the code to load bitmaps in the Win32 API is much more difficult than from the .NET RTL. Once I found the code getting it to work didn't take long, though I did make a few really simple mistakes (like passing b then a to a procedure rather than a then b) that took a while to find. Once I got the code basically working I modified the MazeGame and made a little graphical version. Sleep - 1&lt;br /&gt;&lt;br /&gt;On Saturday we decided to buy a new TV Tuner and HDD from the Media Center PC. I remember reading somewhere that Media Center can support upto 3 TV tuners, so we planned to get the Fusion Dual tuner and a 300GB HDD. The purchase went ok, and we spent the next part of the day shopping for my brothers birthday present. Got home around 4ish and thought that I would install the HDD and TV Tuner quickly... Big mistake. Basically installed the TV Tuner, and HDD (at the some time) and booting windows failed. My first thoughts were, "damn TV tuner card". Removed the card and tried again. Same problems, wouldn't even post this time. Something did not like the new HDD. Removed the other tuner card, and the wireless network card. Basically the same problem. Got a little further then the machine froze. Change cables, change SATA ports, repeat, repeat, repeat... Anyway, at 6 we went to my brothers party which was great fun. Didn't even think about the PC for a few hours. Got home about midnight and started it again. Thought I had it working, formatted disk (almost 1hr). Then post failed again... Crap. Finally gave up on HDD.&lt;br /&gt;&lt;br /&gt;Next trick was to install the tuner. Which turned out to be easy. Plug in, follow instructions. All working in about 1/2 an hour. Go into Media Center, turn them on and get the error "Select one or two tuners only". ARGH... Upto 3 turns out to mean "2" outside US, or "3" (1 digital, 2 analog) in US. Bummer. I could have saved some $$$ and just got another the same as the one I had. So at 3:30 I head off to bed.&lt;br /&gt;&lt;br /&gt;Sunday I went to take back the HDD. The guys I got it from check it and it worked ok in their machine. Not much good to me, but they suggested a bios update. So back home update bios. Same problem. Install original drivers, same problem. Install latest drivers, same problem. Back to shop with PC. The technician had told me "Bring it in and I'll have a quick look at it.". When I took it back he wanted $35 to have a quick look at it... Stuff that. There is nothing left for him to change. The customer service rep and technician were quite rude, and unhelpful. I now know why you should use MSY, everyone I know who has had a problem with their equipment has been well treated. Anyway after a little arguing I got them to exchange it for another brand of disk. "There is a 10% repacking fee", fantastic, the customer service here just gets better and better. So I ended up with a 250Gb HDD and a little change + some happy memories. I had always wondered why the shop had so many "Email complaints to ..." signs around the store. Now I know.&lt;br /&gt;&lt;br /&gt;Spend the remainder of the day driving around shopping for other things. Finally got home about 6:30pm and installed HDD. Amazing (sarcastic), it worked. First time, no problem. I had some drivers issues with the Tuner card, which I reinstalled. So everything is working well now. &lt;br /&gt;&lt;br /&gt;Last thoughts, don't shop anywhere that has a prominent "complaints" signs. You may have to queue for a while, but MSY is worth the wait.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114645520614542098?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114645520614542098/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114645520614542098' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114645520614542098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114645520614542098'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/05/late-weekend.html' title='Late Weekend'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114596446338771860</id><published>2006-04-25T21:07:00.000+10:00</published><updated>2006-04-25T21:30:04.213+10:00</updated><title type='text'>XBox 360 + Media Center</title><content type='html'>Wow am I loving my 360 and Media Center PC. This year for my 30th birthday I got an XBox 360, my birthday is in February and this meant a long wait for the actual machine. During this wait I did some research on what you can do with the 360 and I discovered Media Center. Basically this setup allows me to store my media on the PC and stream it to the 360 for output. &lt;br /&gt;&lt;br /&gt;So how has it been? Well having had the 360 for a month now I can safely say its been as good as I had hoped. Most of my music is now recorded in MP3s on the PC, allowing it to be shared between Media Center, Media Player and iTunes. The music plays perfectly on the PC and 360, as well as on my Zen and Alison's iPod. TV watching has also changed. I now try and pre-record everything that I want to watch. The TV guide (once setup) allows Media Center to automatically record all of the shows that I watch. I also have the digital photos on the Media Center PC, and am currently playing with setting up albums, and seeing if I can add audio (you can play these together manually, I want to see if there is an option for creating and saving this)&lt;br /&gt;&lt;br /&gt;Games for the 360 have also been great. I got the VIP pack with Perfect Dark Zero, but I haven't played it much, the other games I got are far too addictive. Oblivion is my number one game at the moment, and I have clocked over 30hours game play already (on one set of batteries for the controller as well, you can buy a lot of batteries for the price of the recharger kit...). I still feel that I am only just getting started with this game. Every time I play it feels like such a huge world, great game. &lt;br /&gt;&lt;br /&gt;The other game I'm playing is Need for Speed Most Wanted. After hitting 30hours on Oblivion I thought that I should play this a little, and have been hooked on it since. Love the graphics and game action. Basically it was a toss up between NFS and PGR, and I chose NFS mainly due to price. It was more expensive and there was an "all games $75" sale, so I saved more by getting it. Why not both? I'm an academic, so $ are not in great supply :(. Main problem with my choice is that all the others I know get PGR and not NFS... No big deal, I am loving the game. Just hit #9 on the BlackList and the races are starting to get really challenging. Should be good.&lt;br /&gt;&lt;br /&gt;Problems? Well I have had some. The 360 has crashed on me a couple of times in Oblivion with disk read errors, and also in NFS. This hasn't happened so often that I feel the need to take it back, but if it happens more I will be. Other than that everything has been great.&lt;br /&gt;&lt;br /&gt;So what's next? Well I need more disk space on the PC for all the media I have. I also want to get some extra tuner cards so that I can record and watch more than one channel at once. Then there is a steering wheel for the 360, and more racing/adventure games. For the moment I need to save some $... but that's nothing new :)&lt;br /&gt;&lt;br /&gt;For anyone on XBox Live my gamertag is "The MS Guy"... See you online.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114596446338771860?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114596446338771860/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114596446338771860' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114596446338771860'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114596446338771860'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/04/xbox-360-media-center.html' title='XBox 360 + Media Center'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114586080386216677</id><published>2006-04-24T16:37:00.000+10:00</published><updated>2006-04-24T16:40:04.886+10:00</updated><title type='text'>LA Times runs a feature Beyond Bullets</title><content type='html'>This LA Times article examines the Beyond Bullet Point approach. Front page of the business section. Very impressive.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114586080386216677?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.beyondbullets.com/2006/04/la_times_runs_a.html' title='LA Times runs a feature Beyond Bullets'/><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114586080386216677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114586080386216677' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114586080386216677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114586080386216677'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/04/la-times-runs-feature-beyond-bullets.html' title='LA Times runs a feature Beyond Bullets'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114429389550693933</id><published>2006-04-06T13:15:00.000+10:00</published><updated>2006-04-07T08:33:21.020+10:00</updated><title type='text'>Making progress</title><content type='html'>A small group of students stayed back with me after the lab last night. It was really great fun! We extended the &lt;a href="http://mercury.it.swin.edu.au/swinbrain/index.php/Pascal_Worked_Example:_Maze_Game"&gt;maze game&lt;/a&gt; to include the &lt;a href="http://mercury.it.swin.edu.au/swinbrain/index.php/Pascal_Worked_Example:_Maze_Game:_Monster_Idea"&gt;monsters&lt;/a&gt; and then went further to improve the monsters movement, and this morning one student talked to me about adding multiple monsters. This is a very funky little program now. I have added a screen shot below. Basically the player can move the "person" around in the maze while the monsters will move themselves. The code for this is available from the above links, there is a maze txt file at the end of the first iteration. The &lt;a href="http://www.freepascal.org"&gt;Pascal compiler&lt;/a&gt; is free and open source.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/1294/778/1600/MazeGame.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/1294/778/320/MazeGame.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114429389550693933?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114429389550693933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114429389550693933' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114429389550693933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114429389550693933'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/04/making-progress.html' title='Making progress'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114412903793275371</id><published>2006-04-04T15:20:00.000+10:00</published><updated>2006-04-04T15:37:18.166+10:00</updated><title type='text'>Students and Learning</title><content type='html'>One of my favorite (modified) sayings is:&lt;br /&gt;&lt;br /&gt;"You can lead a student to material but you cant make them study"&lt;br /&gt;&lt;br /&gt;This is the joy that I am having at the moment. Motivating first years to actually study is a lot harder than I thought. Today I looked at how many people are actually looking at the Discussion Board. This is used for all important messages to students (such as when assignments are released, general feedback, guidance, suggestions, etc). Most of these messages are not communicated in any other way.&lt;br /&gt;&lt;br /&gt;The following image shows the number of accesses to the Discussion Board by student. There are about 80 students of which 45 have never accessed a single discussion board posting.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/1294/778/1600/UsingDiscussionBoard.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/1294/778/320/UsingDiscussionBoard.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Evil plan 1&lt;/b&gt;: Make sure that I release much more help via the discussion board... :)&lt;br /&gt;&lt;br /&gt;Evil plan 1 is going into action today when I am releasing the assignment... I told them it would be available this week and that I would announce it on the discussion board. Lets see how many actually paid attention in class... My bet is about 35 :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114412903793275371?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114412903793275371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114412903793275371' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114412903793275371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114412903793275371'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/04/students-and-learning.html' title='Students and Learning'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114368192959850420</id><published>2006-03-30T12:22:00.000+11:00</published><updated>2006-03-30T12:25:29.703+11:00</updated><title type='text'>Blog Moved</title><content type='html'>Today I got thinking about where to host my blog again. This time I decided to actually do something about it. I am going with blogspot. Fortunately I used a feedburner feed which I have now redirected. Anyway its good to finally have a place where this can live without worrying about if it is going to be around next week...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114368192959850420?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114368192959850420/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114368192959850420' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114368192959850420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114368192959850420'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/03/blog-moved.html' title='Blog Moved'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114368162401307652</id><published>2006-03-30T12:19:00.000+11:00</published><updated>2006-03-30T12:20:24.103+11:00</updated><title type='text'>Using Full Text Searching with SQL Server</title><content type='html'>The MurrayBookshop allows users to search for books using SQL Servers Full Text Searching. This works resonably well but could be better.&lt;br /&gt;&lt;br /&gt;Currently we use a constructed SQL string that is run via sp_executesql. This is required as we perform paging using SELECT TOP x, where x is a variable based upon the page selected, and the number of records per page. With SQL Server 2005 the SELECT TOP command now allows a variable number of records to be selected so this can then be re-designed to be much simpler.&lt;br /&gt;&lt;br /&gt;The other problem is that uses may type anything into the search box. Unfortunatly the full text search does not allow any text to be used to perform the select. To overcome this you need to watch for two errors when using Fill from a SqlAdapter. (base.FillDataSet uses a SqlDataAdapter with the passed in command).&lt;br /&gt;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;base.FillDataSet(newData, _BrowseCommand);&lt;br /&gt;&lt;br /&gt;return new ProductBrowseResponse(request, newData, (int)_BrowseCommand.Parameters["@TotalPages"].Value, (int)_BrowseCommand.Parameters["@TotalProducts"].Value, ok);&lt;br /&gt;}&lt;br /&gt;catch(SqlException e)&lt;br /&gt;{&lt;br /&gt;if(e.Number == 7619 || e.Number == 7603)&lt;br /&gt;{&lt;br /&gt;return BrowseProductsWithoutSearch(request);&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;throw new DatabaseTechnicalException("Error browsing for products", Connection.ConnectionString, e);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;A cutdown version of the select command is shown below. This selects the second page of 10 records that match the text in @SearchStringSQL.&lt;br /&gt;&lt;br /&gt;SELECT Product.[ProductCode], Product.[ProductTitle], [Rank]&lt;br /&gt;FROM [Product]&lt;br /&gt;INNER JOIN&lt;br /&gt;( SELECT ProductCode, ProductTitle, Rank&lt;br /&gt;  FROM&lt;br /&gt;  ( SELECT TOP 10 ProductCode, ProductTitle, Rank&lt;br /&gt;    FROM&lt;br /&gt;    ( SELECT TOP 20 [Key] As ProductCode, ProductTitle, Rank&lt;br /&gt;      FROM FREETEXTTABLE(Product, ProductTitle, @SearchStringSQL) AS KEY_TBL&lt;br /&gt;      INNER JOIN Product ON KEY_TBL.[Key] = Product.ProductCode&lt;br /&gt;      ORDER BY Rank DESC, ProductTitle ASC&lt;br /&gt;    ) AS Table1&lt;br /&gt;    ORDER BY Rank ASC, ProductTitle DESC&lt;br /&gt;  ) AS Table2&lt;br /&gt;) AS TABLE3 ON Table3.ProductCode = Product.ProductCode&lt;br /&gt;ORDER BY Rank DESC, Product.ProductTitle ASC;&lt;br /&gt;&lt;br /&gt;The BrowseProductsWithoutSearch performs the same query without the full text search.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114368162401307652?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114368162401307652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114368162401307652' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114368162401307652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114368162401307652'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/03/using-full-text-searching-with-sql.html' title='Using Full Text Searching with SQL Server'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114368159179649709</id><published>2006-03-30T12:18:00.000+11:00</published><updated>2006-03-30T12:19:51.910+11:00</updated><title type='text'>Password Strength Indicator</title><content type='html'>(Apologies for the format of this post)&lt;br&gt;(Feel free to use this, but if you do please let me know)&lt;br&gt;&lt;br&gt;The other day I registered a friend with MSN Messenger and was impressed by their password strength indicator. Today I decided to implement my own. The results are below.&lt;br&gt;&lt;br&gt;Basically I use a regular expression to evaluate the strength of the password. Weak = 6 characters at least, Medium = a combination of characters, and numbers, Strong = combination of characters, numbers, and special characters.&lt;br&gt;&lt;br&gt;&lt;hr&gt;&lt;br&gt;&lt;br&gt;The JavaScript is:&lt;br&gt;&lt;br&gt;&amp;lt;script language="javascript"&amp;gt;&lt;br&gt;var ieDOM = false, nsDOM = false;&lt;br&gt;var stdDOM = document.getElementById; function initMethod()&lt;br&gt;{&lt;br&gt;//Determine the browser support for the DOM&lt;br&gt;if( !stdDOM )&lt;br&gt;&lt;p&gt;{&lt;br&gt;ieDOM = document.all;&lt;/p&gt; if( !ieDOM )&lt;br&gt;&lt;p&gt;{&lt;br&gt;nsDOM = ((navigator.appName.indexOf('Netscape') != -1) &amp;amp;&amp;amp; (parseInt(navigator.appVersion) ==4));&lt;br&gt;}&lt;br&gt;}&lt;br&gt;&lt;br&gt;passwordChanged();&lt;br&gt;}&lt;/p&gt; function getObject(objectId)&lt;br&gt;&lt;p&gt;{&lt;br&gt;if (stdDOM) return document.getElementById(objectId);&lt;br&gt;if (ieDOM) return document.all[objectId];&lt;br&gt;if (nsDOM) return document.layers[objectId];&lt;br&gt;}&lt;/p&gt; function getObjectStyle(objectId)&lt;br&gt;&lt;p&gt;{&lt;br&gt;if (nsDOM) return getObject(objectId);&lt;/p&gt; var obj = getObject(objectId);&lt;br&gt;&lt;p&gt;return obj.style;&lt;br&gt;}&lt;/p&gt; function showDefault(objectId)&lt;br&gt;&lt;p&gt;{&lt;br&gt;showCell(objectId, "#E2E2E2", "#E2E2E2");&lt;br&gt;}&lt;/p&gt; function showCell(objectId, foreColor, backColor)&lt;br&gt;{&lt;br&gt;getObjectStyle(objectId).color = foreColor;&lt;br&gt;&lt;p&gt;getObjectStyle(objectId).backgroundColor = backColor;&lt;br&gt;}&lt;/p&gt; function showWeak()&lt;br&gt;&lt;p&gt;{&lt;br&gt;showCell("pwWeak", "Black", "#FF6666");&lt;/p&gt; showDefault("pwMedium");&lt;br&gt;&lt;p&gt;showDefault("pwStrong");&lt;br&gt;}&lt;/p&gt; function showMedium()&lt;br&gt;&lt;p&gt;{&lt;br&gt;showCell("pwWeak", "#FFCC66", "#FFCC66");&lt;br&gt;showCell("pwMedium", "Black", "#FFCC66");&lt;br&gt;&lt;br&gt;showDefault("pwStrong");&lt;br&gt;}&lt;/p&gt; function showStrong()&lt;br&gt;&lt;p&gt;{&lt;br&gt;showCell("pwWeak", "#80FF80", "#80FF80");&lt;br&gt;showCell("pwMedium", "#80FF80", "#80FF80");&lt;br&gt;showCell("pwStrong", "Black", "#80FF80");&lt;br&gt;}&lt;/p&gt; function showUndetermined()&lt;br&gt;&lt;p&gt;{&lt;br&gt;showDefault("pwWeak");&lt;br&gt;showDefault("pwMedium");&lt;br&gt;showDefault("pwStrong");&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;br&gt;function passwordChanged()&lt;br&gt;{&lt;br&gt;var strongRegex = new RegExp("^(?=.{8,})(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*\\W).*$", "g");&lt;br&gt;var mediumRegex = new RegExp("^(?=.{7,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))).*$", "g");&lt;br&gt;var enoughRegex = new RegExp("(?=.{6,}).*", "g");&lt;br&gt;&lt;br&gt;&lt;br&gt;var pwd = getObject("txtPassword").value;&lt;br&gt;if( false == enoughRegex.test(pwd) )&lt;br&gt;{&lt;br&gt;showUndetermined();&lt;br&gt;}&lt;br&gt;else if( strongRegex.test(pwd) )&lt;br&gt;{&lt;br&gt;showStrong();&lt;br&gt;}&lt;br&gt;else if( mediumRegex.test( pwd ) )&lt;br&gt;{&lt;br&gt;showMedium();&lt;br&gt;}&lt;br&gt;else&lt;br&gt;{&lt;br&gt;showWeak();&lt;br&gt;}&lt;br&gt;}&lt;br&gt;&amp;lt;/script&amp;gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; &lt;hr&gt;&lt;br&gt;The password strength indicator table is:&lt;br&gt;  &lt;p&gt;&amp;lt;TABLE style="BORDER-RIGHT: black thin solid; BORDER-TOP: black thin solid; FONT-SIZE: 75%; BORDER-LEFT: black thin solid; BORDER-BOTTOM: black thin solid"&lt;br&gt;&lt;br&gt;cellSpacing="0" cellPadding="0" width="100%"&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;TR&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;TD id="pwWeak" style="BORDER-RIGHT: black thin solid" align="center" width="34%" title="Has at least six characters"&amp;gt;Weak&amp;lt;/TD&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;TD id="pwMedium" style="BORDER-RIGHT: black thin solid" align="center" width="33%" title="Has a mix of numbers, lower &amp;amp; upper case characters."&amp;gt;Medium&amp;lt;/TD&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;TD id="pwStrong" align="center" width="33%" title="Has numbers, special characters, lower &amp;amp; upper case characters."&amp;gt;Strong&amp;lt;/TD&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;/TR&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;/TABLE&amp;gt;&lt;br&gt;&lt;/p&gt;   &lt;p&gt;&lt;ht&gt;&lt;/ht&gt;&lt;/p&gt; &lt;hr&gt;&lt;br&gt;  &lt;p&gt;And this required an action to be added to the txtPassword. As this is ASP.NET we use the following in the page load event for the class:&lt;br&gt;&lt;/p&gt;   &lt;p&gt;txtPassword.Attributes.Add("onKeyUp", "passwordChanged()");&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114368159179649709?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114368159179649709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114368159179649709' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114368159179649709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114368159179649709'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/03/password-strength-indicator.html' title='Password Strength Indicator'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114368124001099772</id><published>2006-03-30T12:12:00.000+11:00</published><updated>2006-03-30T12:17:56.623+11:00</updated><title type='text'>Hiding controls in ASP.NET</title><content type='html'>If you use control.visible = false for controls in your web application these will not be rendered to the resulting HTML. If you want to interact with the control via Javascript there are going to be problems...&lt;br /&gt;&lt;br /&gt;Fortunatly one of my Enterprise .NET students found a potential solution. Try the following in your web applications:&lt;br /&gt;&lt;br /&gt;control.Style.Add("display","block"); // makes visible&lt;br /&gt;control.Style.Add("display","none"); // makes invisible&lt;br /&gt;&lt;br /&gt;Thanks for finding this solution.&lt;br /&gt;&lt;br /&gt;The following script can be used to show and hide controls based on the state of a checkbox.&lt;br&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;        &amp;lt;script language="javascript"&amp;gt;    &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  var ieDOM = false, nsDOM = false;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  var stdDOM = document.getElementById;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;                        &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  function initMethod()&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  {&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    //Determine the browser support for the DOM&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    if( !stdDOM )&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    {&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;      ieDOM = document.all; &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;                &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;      if( !ieDOM )&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;      {&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;        nsDOM = ((navigator.appName.indexOf('Netscape') != -1) &amp;amp;&amp;amp; (parseInt(navigator.appVersion) ==4)); &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;      }&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    }&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;                &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    checkedChanged();&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  }&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;            &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  function getObject(objectId) &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  {&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    if (stdDOM) return document.getElementById(objectId);&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    if (ieDOM) return document.all[objectId];&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    if (nsDOM) return document.layers[objectId];&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  }&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;            &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  function getObjectStyle(objectId) &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  {&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    if (nsDOM) return getObject(objectId);&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;                &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    var obj = getObject(objectId);&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    return obj.style;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  }&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;            &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  function show(objectId) &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  {&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    var objs = getObjectStyle(objectId);&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    objs.visibility = 'visible';&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  }&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;            &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  function hide(objectId) &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  {&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    var objs = getObjectStyle(objectId); &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    objs.visibility = 'hidden';&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  }&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;            &lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  function checkedChanged()&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  {&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    var chkBox = getObject('chkBox');&lt;/span&gt;&lt;br&gt; &lt;span style="font-family: courier new;"&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;    chkBox.checked ? show('txtCreditLimit') : hide('txtCreditLimit');&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;  }&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: courier new;"&gt;        &amp;lt;/script&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;initMethod() must be called when the page loads: &lt;span style="font-family: courier new;"&gt;&amp;lt;body onload="initMethod();"&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;You also need to add some code to the page load to register the checkChanged with the click event on the checkbox. &lt;span style="font-family: courier new;"&gt;chkBox.Attributes.Add("onclick", "checkedChanged();");&lt;/span&gt;&lt;br&gt;&lt;br&gt;This then allows the control to be shown and hidden using client side Java script.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114368124001099772?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114368124001099772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114368124001099772' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114368124001099772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114368124001099772'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/03/hiding-controls-in-aspnet.html' title='Hiding controls in ASP.NET'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114283222539879334</id><published>2006-03-20T16:22:00.000+11:00</published><updated>2006-03-20T16:23:45.416+11:00</updated><title type='text'>.NET Job</title><content type='html'>Another past student contacted me looking for a .NET developer. Here is what they asked me to post:&lt;br /&gt;&lt;br /&gt;Full time positions are available at InsuranceLine for a .NET developer with the following requirements.&lt;br /&gt;&lt;br /&gt;The ideal candidate would have experience working on a distributed application in .NET, with the following skills summarized below.&lt;br /&gt;1. Excellent command over the VB.net language.&lt;br /&gt;2. Implementation knowledge and exposure to Microsoft multi-layer/tier application architecture model for distributed .net Apps.&lt;br /&gt;3. Experience and excellent command over SqlServer 2000 client tools and TSQL.&lt;br /&gt;4. Expereince with writing unit tests in nUnit.&lt;br /&gt;5. Experience of debugging, testing and writing serviced components in COM+.&lt;br /&gt;&lt;br /&gt;Also desirable skills include&lt;br /&gt;1. Exposure to VS 2005.&lt;br /&gt;2. Microsoft Application blocks for .NET (UIPAB in particular)&lt;br /&gt;3. Experience in various common patterns of Enterprise Architecture.&lt;br /&gt;4. Managing Security, roles, and permissions in a distributed application in COM+.&lt;br /&gt;&lt;br /&gt;Resumes + Cover letters can be forwarded at afif.mohammed@mel.insuranceline.com.au&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114283222539879334?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114283222539879334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114283222539879334' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114283222539879334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114283222539879334'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/03/net-job.html' title='.NET Job'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114224150829489638</id><published>2006-03-13T20:13:00.000+11:00</published><updated>2006-03-13T20:18:39.870+11:00</updated><title type='text'>XBox 360</title><content type='html'>Am I hanging out for this or what... I have the premier pack and this weekend I cracked. I opened all of the packaging and drooled over the bits. The controller is much lighter than I thought it would be, but unfortunately pointing it at my tv and pushing the buttons did nothing :). Anyway only a few days to go now... Much keep repeating that to get myself...&lt;br /&gt;&lt;br /&gt;The game looks good and the manual is interesting... well thats all I can do with it at the moment. &lt;br /&gt;&lt;br /&gt;Cant wait!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114224150829489638?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114224150829489638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114224150829489638' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114224150829489638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114224150829489638'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/03/xbox-360.html' title='XBox 360'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114188268972905528</id><published>2006-03-09T16:29:00.000+11:00</published><updated>2006-03-09T16:38:09.740+11:00</updated><title type='text'>Week 2 well under way</title><content type='html'>I am almost ready for HIT1301 now :) and its only half way through week 2. I have finally finished the labs, and got the basic outline for the material on SwinBrain. Now its time to see how this is going to go...&lt;br /&gt;&lt;br /&gt;I have finished all of my HIT1301 (Algorithmic Problem Solving) tutorials for this week and for the most part they were quite good. This week we looked at reading and understand source code (with a little bit of coding for fun). Most of the students are prepared to give it a go, and I hope they had some fun with the exercises. My favorite exercise from this week was the program to make the screen flash red, green, then blue. It only takes a few lines of code, but this is much more interesting than just printing text to the screen. I must say that everything is much easier and more interesting when you dont have to deal with objects and the like.&lt;br /&gt;&lt;br /&gt;Next week there is a quiz, so I'll have a bit better idea how people are going after that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114188268972905528?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114188268972905528/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114188268972905528' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114188268972905528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114188268972905528'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/03/week-2-well-under-way.html' title='Week 2 well under way'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114161746848512868</id><published>2006-03-06T14:48:00.000+11:00</published><updated>2006-03-06T14:57:48.496+11:00</updated><title type='text'>Teaching again</title><content type='html'>The "teaching period" (aka semester) started last week and labs have started this week. Both of my subjects have started well. I am teaching Algorithmic Problem Solving and Enterprise .NET. The two ends of the programming spectrum at Swinburne. Algorithmic Problem Solving (APS) is an introductory subject where students are learning to read and understand code at the moment, and will soon move to writing code and solving problems. Enterprise .NET is Enterprise .NET :) we will start looking at developing multi-layered software, and database programs this week.&lt;br /&gt;&lt;br /&gt;APS is a totally new subject, and it is always interesting to see how the new material works out. It appears to be going well so far, though I'm sure its either to fast or to slow. Student who have programmed before will find the start a little slow, while for the new programmers we are covering a lot of new material in a short time.&lt;br /&gt;&lt;br /&gt;Today I had my first APS labs. The lectures are always hard to judge, but the labs really give you a feel for how everyone is progressing. So far most students are going well. I have had a few new programmers "get it" for a number of new concepts.&lt;br /&gt;&lt;br /&gt;As far as challenge goes, we are already looking at procedures and functions in code, as well as working with the different control flow statements. These concepts are core and once covered we can start writing more interesting code. Having said that most other introductory programming subjects would not have covered so much by week 2... Lets hope it all goes well... If you are doing this subject and feel "up to date" you are doing really well. If not keep reading and ask questions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114161746848512868?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114161746848512868/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114161746848512868' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114161746848512868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114161746848512868'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/03/teaching-again.html' title='Teaching again'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114060576963841018</id><published>2006-02-22T21:52:00.000+11:00</published><updated>2006-02-22T21:56:09.650+11:00</updated><title type='text'>Hoards of Darkness</title><content type='html'>Microsoft is doing their second round of interviews in AU at the moment. Recently I have been contacted by two of my HIT8099/HIT8197 students from last semester and they both have 2nd round interviews in Sydney next week! Fantastic news. I hope they you guys go well.&lt;br /&gt;&lt;br /&gt;Anyone else picked up an interesting .NET job after doing HIT8099 or HIT8197? Let me know what you are up to.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114060576963841018?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114060576963841018/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114060576963841018' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114060576963841018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114060576963841018'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/02/hoards-of-darkness.html' title='Hoards of Darkness'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-114014431997324268</id><published>2006-02-17T13:42:00.000+11:00</published><updated>2006-02-17T13:45:19.983+11:00</updated><title type='text'>Another Job</title><content type='html'>One of my past student recently contacted me looking for some .NET graduates. His company is expanding, and looking to take on some more .NET people. Unfortunately this isn't the best time for me as semester is about to start, but if your are looking for a job with .NET have a look at http://www.roadhouse.com.au/Content.aspx?topicID=235. I know for a fact that some very talented people work there...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-114014431997324268?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/114014431997324268/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=114014431997324268' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114014431997324268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/114014431997324268'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/02/another-job_17.html' title='Another Job'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-113945229458372920</id><published>2006-02-09T13:25:00.000+11:00</published><updated>2006-02-09T13:31:34.593+11:00</updated><title type='text'>Definition of the week</title><content type='html'>Yesterday I read a very interesting statement:&lt;br /&gt;&lt;br /&gt;"A class is a pointer to an object"&lt;br /&gt;&lt;br /&gt;I think this definition really describes the relationship between classes and objects quite well for some languages. The language in question was Delphi. In Delphi, just like Java, C# and Visual Basic .NET, a class type would be referred to as a reference type. What does this mean? A variable of this type is a reference to an object, not the object itself. Or in other words, a class is a pointer to an object. If we could define an object, a class would just be a pointer to that type i.e.&lt;br /&gt;&lt;br /&gt;PersonObj = object &lt;br /&gt; ...&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;Person = ^object;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-113945229458372920?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/113945229458372920/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=113945229458372920' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113945229458372920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113945229458372920'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/02/definition-of-week.html' title='Definition of the week'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-113937122419028721</id><published>2006-02-08T14:59:00.000+11:00</published><updated>2006-02-08T15:00:24.203+11:00</updated><title type='text'>Another Job</title><content type='html'>BOSS Software International is advertising two new junior developer positions. You can get the details from the link above.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-113937122419028721?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://mercury.it.swin.edu.au/acain/BOSS_Job_2006_02_24.htm' title='Another Job'/><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/113937122419028721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=113937122419028721' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113937122419028721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113937122419028721'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/02/another-job.html' title='Another Job'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-113892894652422879</id><published>2006-02-03T12:06:00.000+11:00</published><updated>2006-02-03T12:09:06.526+11:00</updated><title type='text'>The problem with ...</title><content type='html'>The problem with languages like Java and C# is that you need to understand many things in order to create any kind of solution. Using these languages implies an object oriented solution, which in turn implies an understanding of objects. Objects are created by combining data and functionality, so objects implies an understanding of these concepts. Dont get me wrong I use these languages, and I am quite capable of creating elegant oo solutions. I just think that before you start using objects it would be good to have a strong understanding of data and functionality (i.e. sequence, selection, repetition, and functions and procedures). This is way Algorithmic Problem Solving, a new subject I am working on, will be focusing on these concepts and not introducing objects until near the very end.&lt;br /&gt;&lt;br /&gt;Objects are important. Objects are good. But there is no need for objects first.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-113892894652422879?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/113892894652422879/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=113892894652422879' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113892894652422879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113892894652422879'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/02/problem-with.html' title='The problem with ...'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-113738038437595138</id><published>2006-01-16T13:44:00.000+11:00</published><updated>2006-01-16T13:59:44.386+11:00</updated><title type='text'>A question of Language</title><content type='html'>Last year a group of us at Swinburne proposed a new IT degree aimed at producing software developers. At the heart of this degree was a new programming stream aimed at teaching students the fundamentals of programming starting with procedural programming then moving to object oriented programming, but also including introductions to functional and stack based programming. We are now in the process of developing these subjects and are pondering (again) the choice of language and approach.&lt;br /&gt;&lt;br /&gt;What are the choices? Well at the moment the real choices are between C and Delphi. We have decided to avoid Java, C#, or Visual Basic .NET as these languages provide a higher level of abstraction that will be better understood after having learnt procedural programming.&lt;br /&gt;&lt;br /&gt;At the moment my preference is to go with Delphi. The language is far more readable than C, providing an environment that is a little further removed from low level concepts. If we go with Delphi the approach we will take is to introduce program comprehension first then move to basic development, data structures and memory management, and finally recursion and backtracking. Using Delphi we can still use call by reference (pass by reference) and call by value (pass by value), we have pointers, function pointers, and easy to use strings.&lt;br /&gt;&lt;br /&gt;On the other hand C is the cheaper option. By using C we can eliminate one subject as this will be taught to the engineers as well. I believe that the approach to programming with C would need to be different to the above approach. The language is not as readable, and requires a better understanding of hardware and memory. Having said this the subject would be mostly taught to engineers who should be interested in  this lower level of abstraction. I think therefore that the C approach could take a far more low level approach. You would probably start with a little hardware introduction followed by basic instructions and then move onto memory management. You could then go on to look at controlling hardware devices in C, possibly also looking at assembler. Basically keep the subject more on a hardware control level where C will work well.&lt;br /&gt;&lt;br /&gt;I haven't had long to think on the C approach, so I'm not really sure about it still... Any comments will be appreciated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-113738038437595138?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/113738038437595138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=113738038437595138' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113738038437595138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113738038437595138'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/01/question-of-language.html' title='A question of Language'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-113713763094813114</id><published>2006-01-13T18:30:00.000+11:00</published><updated>2006-01-25T22:32:40.566+11:00</updated><title type='text'>Where to blog?</title><content type='html'>With the tragic loss of my last blog, and a number of friends moving to new blog sites, I am starting to think about where I should blog...&lt;br /&gt;&lt;br /&gt;What do I want?&lt;br /&gt;1: Backups... I dont want to lose it all again!&lt;br /&gt;2: Time... It would be good to know that I dont have to move again.&lt;br /&gt;3: Price... I'm cheap :)&lt;br /&gt;&lt;br /&gt;Are there any problems with this location? Well not really except for points 2 and 3. This site is run by Raj who is paying to have this hosted. Will it stay around? It will as long as we keep paying. So with this in mind I am asking you where do you blog? What is it like? Most importantly where should I blog?&lt;br /&gt;&lt;br /&gt;Anyone?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-113713763094813114?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/113713763094813114/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=113713763094813114' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113713763094813114'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113713763094813114'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/01/where-to-blog.html' title='Where to blog?'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-113633087749787453</id><published>2006-01-04T10:21:00.000+11:00</published><updated>2006-01-09T11:30:12.383+11:00</updated><title type='text'>Java Schools</title><content type='html'>An interesting read on Joel's view of Java based schools.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-113633087749787453?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html' title='Java Schools'/><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/113633087749787453/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=113633087749787453' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113633087749787453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113633087749787453'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/01/java-schools.html' title='Java Schools'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-113632790445064924</id><published>2006-01-04T09:21:00.000+11:00</published><updated>2006-01-04T09:39:05.960+11:00</updated><title type='text'>Brains</title><content type='html'>I read an interesting article on Conference Presentations and our Brains... There was some interesting points that seem to fit well with the overall approach that I have been working with lately. The article was titled "Conference Presentation Mind Control" by Paul Fenwick and was presented at the OSDC in December (Melbourne).&lt;br /&gt;&lt;br /&gt;One of the most interesting quotes from the presentation relates to people having trouble paying attention in technically interesting presentations - "Half our brain is bored, and suppressing it is hard work. Similar reasoning can be used to explain why many technical professionals are more effective if they listen to music while they work". Something that I immediately relate to.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-113632790445064924?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://osdc2005.cgpublisher.com/proposals/53/index_html' title='Brains'/><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/113632790445064924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=113632790445064924' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113632790445064924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113632790445064924'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/01/brains.html' title='Brains'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-113626539426327156</id><published>2006-01-03T16:11:00.000+11:00</published><updated>2006-01-03T16:16:34.263+11:00</updated><title type='text'>SwinBrain</title><content type='html'>I have been working for a while on a new project called "SwinBrain". This is a wiki designed to provide subject content material for Swinburne student (well some of them anyway). The idea of the wiki is to allow Swinburne subjects to share knowledge, something that I have found frustrating in the past. In this way when you need to provide background material for students who may not have done something (like Database for example), you can reference to the appropriate section on the wiki. I hope that this will enhance the consistence of the message that we deliver.&lt;br /&gt;&lt;br /&gt;The site is very much limited at the moment as there are only a few of us working on this. If you have any suggestions for material, or any comments on the idea let me know...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-113626539426327156?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://mercury.it.swin.edu.au/swinbrain' title='SwinBrain'/><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/113626539426327156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=113626539426327156' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113626539426327156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113626539426327156'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/01/swinbrain.html' title='SwinBrain'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-113624187003865995</id><published>2006-01-03T09:36:00.000+11:00</published><updated>2006-01-03T09:44:30.040+11:00</updated><title type='text'>New Year</title><content type='html'>Well the new year is upon us, and I am now back at work! This new year should see several new challenges as we start to introduce the new PSD degree at Swinburne.&lt;br /&gt;&lt;br /&gt;The most tragic thing to happen to me last year was the loss of the blogs from Tyler, the byteclub server. My byteclub blog was my main blog for a long time and to lose this content really hurts! What also hurts is the loss of the other byte club blog that I have been actively reading. I will have to see what can be done to get something back up and running for the ByteClub, but I think I will keep this blog as my main blog for the moment anyway.&lt;br /&gt;&lt;br /&gt;To anyone from ByteClub who lost their blog please post a comment and let me know where your new blog is if you have created one.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-113624187003865995?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/113624187003865995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=113624187003865995' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113624187003865995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/113624187003865995'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2006/01/new-year.html' title='New Year'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-112677370011737265</id><published>2005-09-15T15:28:00.000+10:00</published><updated>2005-09-15T18:41:40.426+10:00</updated><title type='text'>Concurrency Utilities in .NET</title><content type='html'>Today I have great fun in my HIT8197 Advanced .NET lab. We decided to do some group programming in order to create "the" bounded channel for .NET. For those of you who are not familiar with this concept you can read about it on &lt;a href="http://mercury.it.swin.edu.au/acain/mediawiki/index.php/Concurrent_Programming_-_Channel."&gt;SwinBrain&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;The one thing that is often overlooked in .NET concurrent programming is the Interrupt exception on the enterring a lock.&lt;br /&gt;&lt;br /&gt;I will write more on this tomorrow...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-112677370011737265?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/112677370011737265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=112677370011737265' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/112677370011737265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/112677370011737265'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/09/concurrency-utilities-in-net.html' title='Concurrency Utilities in .NET'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-111527844161933582</id><published>2005-05-05T17:30:00.000+10:00</published><updated>2005-05-05T17:34:01.653+10:00</updated><title type='text'>Message Based Architecture of the Murray Bookshop</title><content type='html'>Below I have attached the outline of the architecture for the Murray Bookshop applications that the students of HIT8099 have been working with. Any comments are very welcome...&lt;br /&gt;&lt;h1&gt;Message Based Architecture of the Murray Bookshop &lt;/h1&gt;The Murray Bookshop is a “virtual company” that forms the basis of the Enterprise .NET subject at Swinburne University of Technology. Students of HIT8099 extend the application, with each semester building on the previous semester. The bookshop has been running for one year and currently includes a web site that allows customers to browse the products on offer, and place and track orders. A Windows application is used by warehouse staff to fill orders, order shipping, and mark orders as collected. As this is a virtual company, a Windows service is provided to simulate employees and customers. This service places orders and performs warehouse operations at timed intervals.&lt;br /&gt;&lt;p&gt;This document outlines the core architecture used in this project. This architecture is designed with several key areas namely: layered architecture, stateless business components, message based communication, and loosely coupled components. &lt;/p&gt;&lt;h2&gt;Layered Architecture &lt;/h2&gt;Applications built for the Murray Bookshop use a layered architecture consisting of a presentation layer, business layer, and data access layer. The architecture used is based upon the recommendations in Microsoft's Patterns and Practices book titled &lt;em&gt;Application Architecture for .NET: Designing Applications and Services &lt;/em&gt; available at &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/distapp.asp"&gt;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/distapp.asp &lt;/a&gt;.&lt;br /&gt;&lt;p&gt;&lt;em&gt;Implementation Notes:&lt;br /&gt;&lt;/em&gt;Database access is not available to the presentation layer components. &lt;/p&gt;&lt;h2&gt;Stateless Business Components &lt;/h2&gt;&lt;p&gt;The Murray Bookshop uses stateless business components to help avoid concurrency issues at the business layer. This also helps reduce issues related to access via the web, as these components are typically accessed via a web application, or web service. &lt;/p&gt;&lt;p&gt;&lt;em&gt;Implementation Notes:&lt;br /&gt;&lt;/em&gt;Avoid instance variables within business components.&lt;br /&gt;Use local variables for interacting with database components (as these contain state information).&lt;br /&gt;Do not use Business Entities. &lt;/p&gt;&lt;h2&gt;Message Based Communication &lt;/h2&gt;&lt;p&gt;Messages are used for communication between components across layers. To facilitate this, a set of classes has been included in the core assemblies. These classes contain the details sent to the service to make a request, and returned from the service in response to this request. This simplified the process of changing the communication channel used as these classes are Serializable and encapsulate all information to be exchanged between parties &lt;/p&gt;&lt;p&gt;  &lt;/p&gt;&lt;p&gt;&lt;em&gt;Implementation Notes:&lt;br /&gt;&lt;/em&gt;The &lt;em&gt;Murray.Core.Common.Messages &lt;/em&gt; namespace contains the message classes.&lt;br /&gt;Each service offered by the bookshop has a &lt;em&gt;Request &lt;/em&gt; (Message) and a &lt;em&gt;Response &lt;/em&gt;.&lt;/p&gt;&lt;p&gt;The &lt;em&gt;FetchCustomerOrderMessage &lt;/em&gt; is used to request customer orders to view on the accounts page of the web site. This request is sent from the web application to the &lt;em&gt;IManageOrders &lt;/em&gt; component when then generates a &lt;em&gt;FetchCustomerOrderResponse &lt;/em&gt;, which is then returned to the caller. The &lt;em&gt;FetchCustomerOrderMessage &lt;/em&gt; contains the details required to make this request including the customer's code, the order status filter (indicates all orders, outstanding orders, or previous orders), as well as the page requested, and the records per page. The &lt;em&gt;FetchCustomerOrderResponse &lt;/em&gt;contains the response from this request. The response contains the requests details, the total number of pages, and a dataset with the results.&lt;/p&gt;&lt;p&gt;Several parts of all requests will be consistent across all requests and responses. For a request message this includes the page requested, the records per page, and also a search filter (not used in this example). For the response this includes the requests details, and the total number of records. This functionality is encoded in the &lt;em&gt;BaseSelectRequest &lt;/em&gt; and &lt;em&gt;BaseSelectResponse &lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Future Considerations/Changes: &lt;/em&gt;&lt;/p&gt;&lt;p&gt;Currently the individual message classes are contained within the core assembly. This reduces the ability to work on the individual projects in isolation. This location is currently used as these classes are needed in the database, business, and presentation layers. If this was reduced to the presentation and business layer the classes could be located in application assemblies rather than the core assemblies.&lt;/p&gt;&lt;p&gt;With .NET 2.0 generics will allow more functionality to be moved into the base class messages. This may allow all message to use just these base classes, though requests will then require a &lt;em&gt;Parameters &lt;/em&gt; class (example). &lt;/p&gt;&lt;h2&gt;Loosely Coupled Components &lt;/h2&gt;&lt;p&gt;The business components are only accessible via interfaces. The user of these classes loads the component via the &lt;em&gt;ComponentLoader &lt;/em&gt; and &lt;em&gt;GenericFactory &lt;/em&gt; classes. For example the &lt;em&gt;OrderManagementService &lt;/em&gt; implements the &lt;em&gt;IManageOrders &lt;/em&gt; interface. This class can be loaded via the &lt;em&gt;OrderManagerLoader &lt;/em&gt;'s &lt;em&gt;Load &lt;/em&gt; method. This method reads the assembly and class details from the associated app.config file, loads this assembly and then constructs an object of the configured class. &lt;/p&gt;&lt;p&gt;This structure allows for communication between the presentation and business layer to be changed. During testing locally installed business components can be directly used, while in production a proxy can be installed locally that communicates with the application server. Additionally this allows for changes to be made to business components without requiring modifications to the user interfaces. This will allow easier deployment of bug fixes and minor business changes. &lt;/p&gt;&lt;p&gt;&lt;em&gt;Implementation Notes:&lt;br /&gt;&lt;/em&gt;The current applications include an adapter that used COM+/Enterprise Services to allow communication between the presentation layer on the web server and business layer on the application server. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-111527844161933582?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/111527844161933582/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=111527844161933582' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/111527844161933582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/111527844161933582'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/05/message-based-architecture-of-murray.html' title='Message Based Architecture of the Murray Bookshop'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-110862194319540437</id><published>2005-02-17T17:30:00.000+11:00</published><updated>2005-02-17T17:32:23.196+11:00</updated><title type='text'>Windows ME -&gt; Longhorn?</title><content type='html'>A friend of mine raised the question "will Longhorn be the &lt;a href="http://www.byteclub.net/blog/egrant/index.php?entry=entry050217-161342"&gt;Windows ME of the XP Era&lt;/a&gt;?". This is an interesting perspective.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-110862194319540437?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.byteclub.net/blog/egrant/index.php?entry=entry050217-161342' title='Windows ME -&gt; Longhorn?'/><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/110862194319540437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=110862194319540437' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110862194319540437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110862194319540437'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/02/windows-me-longhorn.html' title='Windows ME -&gt; Longhorn?'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-110859889691553911</id><published>2005-02-17T11:02:00.000+11:00</published><updated>2005-02-17T11:08:56.563+11:00</updated><title type='text'>Tips and Tricks</title><content type='html'>Over the last week I have been reading a number of articles on .NET development, and was thinking on what I should do with the information I had read. What I wanted was to keep track of what I had learnt. My ideas were: 1: Write a Review of each article, 2: Add an entry to my blog.&lt;br /&gt;&lt;br /&gt;I decided not to do 1 as I didn't want to do a full review of each article, I just wanted some notes to help me remember it and a link to refer back to it. I decided against 2 as well, as I don't really want to sort through both my blog entries  to find information on that one article you want.&lt;br /&gt;&lt;br /&gt;In the end I decided to create a new blog just for these tips and tricks. My plan is to  use this as a repository for links to articles that I find useful, and a record of what was useful from the article.&lt;br /&gt;&lt;br /&gt;If you are intereted the link is &lt;a href="http://www.thoughtlabs.net/andrew/tipsandtricks/index.html"&gt;http://www.thoughtlabs.net/andrew/tipsandtricks&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-110859889691553911?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.thoughtlabs.net/andrew/tipsandtricks/index.html' title='Tips and Tricks'/><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/110859889691553911/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=110859889691553911' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110859889691553911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110859889691553911'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/02/tips-and-tricks.html' title='Tips and Tricks'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-110845078912612613</id><published>2005-02-15T16:00:00.000+11:00</published><updated>2005-02-15T17:59:49.133+11:00</updated><title type='text'>Examining the UPC Framework</title><content type='html'>&lt;p&gt;Today I started looking into making changes to Microsoft's User Process Component Application Block. I am writing this blog entry so that I can remember what I have learnt...&lt;img src="http://thoughtlabs.net/andrew/files/blogimages/upc/overview.jpg" align="right" border="0" /&gt;&lt;/p&gt; The framework is as appears in the image here (from the UPC Application Block help).&lt;p&gt;As you can see, the UPC block centers around the idea of screen navigation. The coordinating class (in terms of the block) here is the Navigator. Developers provide the functionality for the Application (&lt;span style="font-style: italic;"&gt;Your Application&lt;/span&gt;) the Controller (&lt;span style="font-style: italic;"&gt;Your Controller&lt;/span&gt;)  and the views (&lt;span style="font-style: italic;"&gt;Your Views&lt;/span&gt;). The Navigator coordinates the transition between views.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;One error on this diagram is the link between the Controller Base and the State. This is actually contained within the Navigator (i.e. the ControllerBase asks the Navigator for the State information). So the Navigator contains the state.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;The navigator is loaded based on the information in the navigationGraph node in the Config file, or from the use of Open Tasks.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;Goal: Remove the link from &lt;span style="font-style: italic;"&gt;Your View&lt;span style="font-style: italic;"&gt;s &lt;/span&gt;&lt;/span&gt;to &lt;span style="font-style: italic;"&gt;Your Controllers&lt;/span&gt;.&lt;br /&gt;Reason: Increase the reusability of &lt;span style="font-style: italic;"&gt;Your Views&lt;/span&gt;, and the flexibility of &lt;span style="font-style: italic;"&gt;Your Controllers&lt;/span&gt;.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;Ideas:&lt;br /&gt;Views have a specific purpose. Views can use and store information in State objects. A View which is accepting information from the user should store the supplied information in the State before propogating action requests.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;Views can initiate actions (i.e. button clicks). Actions are received by a framework component and routed to the Controller, thereby avoiding the direct connection. The view has access to the Navigator (also not in the diagram), and so this can act as the &lt;span style="font-style: italic;"&gt;Coordinator&lt;/span&gt;.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;Concentrating on the Navigation Graph style for the moment:&lt;br /&gt;Currently the graph has Nodes that have navigateTo links. These specify the destination view for a given action. For example:&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&amp;lt;navigationgraph&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;node view='Form1'&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;navigateto navigatevalue='next' view='Form2'/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/node&amp;gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;node view='Form2'&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;navigateto navigatevalue='previous' view='Form1'&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;navigateto navigatevalue='finish' view='Form3'/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/node&amp;gt;&lt;br&gt; &amp;lt;/navigationgraph&amp;gt;&lt;/p&gt; &lt;p&gt;My thoughts so far suggest to replace navigateTo with a trigger node that contains one or more actions:&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&amp;lt;navigationgraph&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;node view='Form1'&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;trigger value='next'&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;navigateTo view='Form2' /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/trigger&amp;gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/node&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;node view='Form2'&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;trigger value='previous'&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;navigateTo view='Form1'/&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/trigger&amp;gt;&lt;br&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;trigger value='finish'&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;controllerAction name='updateDatabase' / &amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;navigateTo view='Form3' /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/trigger&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/node&amp;gt;&lt;br&gt;&lt;br /&gt;&amp;lt;/navigationgraph&amp;gt;&lt;/p&gt; &lt;p&gt;The data for the 'updateDatabase' action would be taken from the tasks associated state information.&lt;/p&gt;&lt;p&gt;This allows the actions on the controller to be configured rather than hard coded.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-110845078912612613?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/110845078912612613/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=110845078912612613' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110845078912612613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110845078912612613'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/02/examining-upc-framework.html' title='Examining the UPC Framework'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-110807302503791304</id><published>2005-02-11T08:32:00.000+11:00</published><updated>2005-02-11T09:03:45.036+11:00</updated><title type='text'>User Process Components and State</title><content type='html'>I have had some more thoughts on user process components and thought I should try to put it into writing...&lt;br /&gt;&lt;br /&gt;If we are to separate more completely the user interface from the processing, there still needs to be some way to share information between the user interface and the process, and visa versa. My current thoughts on this are leading me towards a more specific shared state. Let me explain.&lt;br /&gt;&lt;br /&gt;In the current UPC (version 2), the state shared between the controller and the user interface uses a general key-value pair scheme. Both the user interface and the controller must &lt;span style="font-weight: bold;"&gt;know&lt;/span&gt; which keys contain which values, and which keys are manipulated by which user interface screen. This logic is not obvious from the types involved in the transaction, and so must be maintained in project documentation.&lt;br /&gt;&lt;br /&gt;In order to further decouple the user interface from the processing, this state contract can be strengthened. Rather than using simple key value pairs, I believe that it will be better to introduce interfaces on the state information. Each of the user interface components (UIC) can then interact with one of these interfaces. The state passed into the UIC would conform to this interface, and the actions of the UIC would then guarantee that certain actions are performed upon the state passed in (view, add, update, etc.).&lt;br /&gt;&lt;br /&gt;The User Process Component (UPC) framework would provide a base interface from which the other state interfaces would inherit. This interface would provide access to the key-value pair exposed by the state base class. More detailed interfaces would expose a more fine grain access, allowing access to specific data (possibly read only). Each interface would be designed to represent a single aspect of the state. In this way, multiple interfaces would be used on a single state item. For example you can have a IAddressInformation interface. This would be used to represent data that contains an address, such as a Customer, Order, etc. An Address form can then be created in the UICs, and can be used to manipulate address information for multiple UPC (for example Create Order, ChangeAddress, Register Customer, etc.) . As the actual processing is not within the UIC this will be very flexible.&lt;br /&gt;&lt;br /&gt;This should be able to be implemented in the UPC version 2 framework.  Something that I will have to look into soon.&lt;br /&gt;&lt;br /&gt;Always remember to look on the bright side of life...&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-110807302503791304?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/110807302503791304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=110807302503791304' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110807302503791304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110807302503791304'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/02/user-process-components-and-state.html' title='User Process Components and State'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-110784431694694448</id><published>2005-02-08T17:29:00.000+11:00</published><updated>2005-02-08T17:36:53.373+11:00</updated><title type='text'>Blog Location</title><content type='html'>&lt;div&gt;                &lt;!-- &lt;img src="http://www.csthota.com/blogmap/blogapi.ashx?method=blogmap&amp;feed=http://www.byteclub.net/blog/acain/rss.php&amp;height=250&amp;width=150&amp;label=Andrew Cain - aka Saruman" alt="'my" style="'border-color:Black;border-width:1px;border-style:Dashed;'/" /&gt; --&gt;Have a look at this greate concept... Blog Locations.&lt;br /&gt;My blog location is:&lt;br /&gt;&lt;br /&gt;             &lt;img src="http://www.csthota.com/blogmap/blogapi.ashx?method=blogmap&amp;feed=http://feeds.feedburner.com/AndrewCain&amp;amp;amp;amp;height=250&amp;width=150&amp;amp;label=Andrew%20Cains%20Blog" alt="my blogmap" style="border: 1px dashed Black;" /&gt;&lt;br /&gt;&lt;br /&gt;Have a look at &lt;a href="http://www.csthota.com/blogmap/"&gt;http://www.csthota.com/blogmap/&lt;/a&gt;&lt;br /&gt;     &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-110784431694694448?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/110784431694694448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=110784431694694448' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110784431694694448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110784431694694448'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/02/blog-location.html' title='Blog Location'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-110747557464796064</id><published>2005-02-04T11:00:00.000+11:00</published><updated>2005-02-04T11:06:14.646+11:00</updated><title type='text'>XC#</title><content type='html'>Well I have tried to get XC# to work with Whidbey with no luck.&lt;br /&gt;&lt;br /&gt;Installed ok, but when VS2005 was loaded it was unable to locate office.dll. The office.dll is used by the AddIn to interact with the command bars of Visual Studio. To fix this I modified the code so that it used the Whidbey style AddIn code to interact with the command bars, this does not require office.dll and so the AddIn now loads.&lt;br /&gt;&lt;br /&gt;Now there is a problem with the XC# compiler. During compilation the compiler throws an exception as it is unable to load the System.Collections.Generic.Dictionary class. As I dont have the source code to this there is very little I can do...&lt;br /&gt;&lt;br /&gt;At the moment I want to play around with Whidbey a little more, so I will delay a look at this until after I have finished playing with this.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-110747557464796064?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/110747557464796064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=110747557464796064' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110747557464796064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110747557464796064'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/02/xc.html' title='XC#'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-110730313474079963</id><published>2005-02-02T10:55:00.000+11:00</published><updated>2005-02-02T11:12:14.740+11:00</updated><title type='text'>Aspect Oriented .NET</title><content type='html'>On another of my projects I am looking at ways to help automate commonly repeated tasks. For example. In this project, all exceptions within the service layer are managed and wrapped in a custom exception. The Exception Management application block is used to publish the exceptions details. Each of the exceptions has an associated Publishable Exception, which contains the exception to be thrown beyond the service layer. This ensures that only appropriate exceptions are made public.&lt;br /&gt;&lt;br /&gt;In order to implement this all public methods in the service layer must catch all unhandled exceptions and then throw the associated Publishable Exception. For example the code is something like this:&lt;br /&gt;&lt;br /&gt;public void ServiceLayerMethod(Parameters p)&lt;br /&gt;{&lt;br /&gt;   try&lt;br /&gt;   {&lt;br /&gt;           ...&lt;br /&gt;   }&lt;br /&gt;   catch(Exception exc)&lt;br /&gt;   {&lt;br /&gt;       Manager.RaiseFilteredException(exc);&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;While this is not much code it is annoying to type, and a bigger problem if missed.&lt;br /&gt;&lt;br /&gt;Getting this out of the code and into some form of aspect, or even attribute, has been a goal of mine for a while. This can be achieved by using ContextBound objects, but this forces the developer to inherit from this class and is not as flexible as I would like. Today I have spend some time looking into some of the other Aspect Oriented extensions for .NET. This has lead me to XC# from &lt;a href="http://www.resolvecorp.com/"&gt;ResolveCorp&lt;/a&gt;. I have only just download the VS2005 version and will investigate it over the next few days.&lt;br /&gt;&lt;br /&gt;Has anyone tried using this? The documentation on the site is very thin... but it does appear that I should be able to implement this as an aspect. If this is the case the plan is to create a ExceptionManaged attribute that can be applied at a class or method level. At a class level, all non-private methods will be wrapped with the exception management code.&lt;br /&gt;&lt;br /&gt;If you have had any experience with XC# that you think will help please let me know... if not I will post up my progress as I go.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-110730313474079963?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/110730313474079963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=110730313474079963' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110730313474079963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110730313474079963'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/02/aspect-oriented-net.html' title='Aspect Oriented .NET'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-110721567437479585</id><published>2005-02-01T09:04:00.000+11:00</published><updated>2005-02-01T10:54:34.376+11:00</updated><title type='text'>UIP Application Block</title><content type='html'>I have started reading the details about the application block (&lt;a href="http://msdn.microsoft.com/library/en-us/dnpag/html/uipab.asp"&gt;User Interface Process Application Block - Version 2&lt;/a&gt;). The block aims to allow you to more easily implement MVC applications where the transitions between views is flexible. The block states that it wants to make it easier to "Add new pages", etc.&lt;br /&gt;&lt;br /&gt;The block implements much of this very well. The views are, however, coupled to the controller. On page 60 of the PDF that comes with the block it indicates "to add navigations to your view call the methods defined within your controller." This has several negative side effects.&lt;br /&gt;&lt;br /&gt;Firstly, it is now difficult to add new views into the application. If additional steps are added to a user interface process, this requires changes to the existing views, and controller, and the addition of the new view.&lt;br /&gt;&lt;br /&gt;Secondly, you cannot use a single view for multiple tasks. In some cases it may be possible for a single view to participate in multiple tasks. If the controller is directly called from the view this is not easy to implement.&lt;br /&gt;&lt;br /&gt;Ideally we should be able to decouple the view from the controller. This in itself will be a complex addition as there is some coupling required between these entities. The controller is currently decoupled from the view. However, operations of the controller will require information from the view.&lt;br /&gt;&lt;br /&gt;How this can be decoupled must be considered carefully.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-110721567437479585?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/110721567437479585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=110721567437479585' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110721567437479585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110721567437479585'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/02/uip-application-block.html' title='UIP Application Block'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-110680316537869871</id><published>2005-01-27T15:11:00.000+11:00</published><updated>2005-01-27T16:19:25.376+11:00</updated><title type='text'>Asynchronous User Interfaces</title><content type='html'>I have been thinking about this topic over the last few days. How should you build concurrency into user interface processes. In this context concurrency is used entirely to ensure responsiveness, not due to any form of concurrent nature of the application. In other words how can we gain the required responsiveness without introducing the issues related to concurrency.&lt;br /&gt;&lt;br /&gt;As some of the previous blogs entries on this have discussed, concurrency is difficulty, with shared data being the cause of the issues. Within the user interface only limited sharing of data between threads is only required. We need to communication progress, and completion (with success or failure etc).&lt;br /&gt;&lt;br /&gt;While I have been thinking about this in the back of my mind, I have also been reviewing some of the material I use to teach enterprise development with .NET. In particular, User Interface Process Components, see http://msdn.microsoft.com/library/en-us/dnbda/html/AppArchCh2.asp?frame=true. I think the concept of User Interface Process Components is great. The application block, http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/uipab.asp, is ok but IMO lacks some basic functionality. Mainly I would liked to have see the ability to link actions to user interface events, rather than just transitions. Transitions can then become actions, multiple actions can be performed by composition. Having this reduces the functionality of the user interface components to notifying the user interface process of certain events + managing the view. The "What happens" part of the application is controlled by the user interface process.&lt;br /&gt;&lt;br /&gt;Given this, it would be nice to have asynchronous support built into this. Given tasks (or parts of tasks) could then be marked as asynchronous. Running these tasks is then coordinated by the UIP framework. Asynchronous tasks could be given the ability to indicate progress. The coordination of data required to do this would also be managed by the framework. Basically, by using this developers will be able to gain responsiveness, without (as many) concerns for concurrency.&lt;br /&gt;&lt;br /&gt;I haven't spent anywhere need long enough thinking about this but I am interested in any comments you have.&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;Issues I can think of off the top of my head:&lt;br /&gt;&lt;br /&gt;1: Interaction with the UI. If a task is asynchronous the developer must not interact with GUI elements. Doing so is asking for disaster...&lt;br /&gt;2: Web application. I think this will be ok but there are some tricks that need to be done to get this to work ok.&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;Just some random thoughts on this (so I don't forget):&lt;br /&gt;&lt;br /&gt;UIC --&gt; UIP (User interface components are dependent on User Interface Processes)&lt;br /&gt;&lt;br /&gt;Each UIC would have a specific functionality, for example collecting data from the user and storing it in the UIP. Therefore UIP is not dependent on UIC.&lt;br /&gt;&lt;br /&gt;UIP needs to move to new views. UIP --&gt; UIC... UIP &lt;--&gt; UIC. However page transitions are already implemented in the application block. This interdependence is already present within the block.&lt;br /&gt;&lt;br /&gt;Moving actions into UIP ensures that it is encoded here and not in the UIC.&lt;br /&gt;&lt;br /&gt;Do you really want one UIP for web and windows? Does the extra complexity outweigh the benefits?&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;Any thoughts on this are very welcome.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-110680316537869871?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/110680316537869871/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=110680316537869871' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110680316537869871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110680316537869871'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/01/asynchronous-user-interfaces.html' title='Asynchronous User Interfaces'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-110645541448505420</id><published>2005-01-23T15:40:00.000+11:00</published><updated>2005-01-23T15:43:34.486+11:00</updated><title type='text'>Concurrency Articles</title><content type='html'>I have uploaded a couple of articles on concurrency.  These are very introductory and cover race conditions, and locks.&lt;br /&gt;&lt;br /&gt;Having written these I think I need a thread basics to introduce threading itself as a concept. The next article will cover liveness and deadlocks. I plan then to introduce other thread exclusion mechanisms, and then move onto coordinating multiple thread.&lt;br /&gt;&lt;br /&gt;Any comments will be greatly appreciated.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-110645541448505420?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/110645541448505420/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=110645541448505420' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110645541448505420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110645541448505420'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/01/concurrency-articles.html' title='Concurrency Articles'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-110625834612353487</id><published>2005-01-21T08:11:00.000+11:00</published><updated>2005-01-21T09:06:24.960+11:00</updated><title type='text'>Concurrent Programming</title><content type='html'>As Matthew points out on his &lt;a href="http://spaces.msn.com/members/mwadams/Blog/cns%211pAMOzaH98ZfHK1uhQS5Bd5g%21128.entry"&gt;blog, &lt;/a&gt; another potential solution to the concurrency issue is to stop further requests by disabling the button...&lt;br /&gt;&lt;br /&gt;I have updated by &lt;a href="http://www.thoughtlabs.net/andrew/downloads/Deadlock2.zip"&gt;DeadLock2.zip&lt;/a&gt; file to include a new fourth solution.&lt;br /&gt;&lt;br /&gt;In this solution I have separated out the logic of the library functionality. I think I understand the intended model a little better now, and as I see it, it is responsible for echoing a stored message + some additional string. I have coded this into an "Echoer" class that internally stores the message.&lt;br /&gt;&lt;br /&gt;Using this library, the UI requests an echo from the Echoer with the additional string "1 ". The result that is echoed is then used to update the Echoer's message property.&lt;br /&gt;&lt;br /&gt;If you examine the solution I have uploaded, you will notice that there are no locks used. This implementation is thread safe due to the structuring of the program. Updates to the Echoer's Message property occur on the GUI thread. The worker thread is responsible for processing the echo and returning the new string. The thread safety is ensured by stopping the GUI thread from interacting with this variable until after the transaction is completed.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;So why the differing views?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There are two perspectives on this issue. When I read the code originally I was viewing it from a concurrency mindset. Therefore you look for potential cases of concurrency and try to determine all of the potential race conditions. The fix to this issue is then to modify the library to include thread safety mechanisms. Thereby ensuring that the library will be usable in a concurrent environment.&lt;br /&gt;&lt;br /&gt;We can also consider this from the perspective of an application developer using a non-thread safe library object. In this case the responsibility of ensuring thread safety lies in the UI, as the library cannot be changed.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;And the motto of the story is?&lt;/span&gt;&lt;br /&gt;Writing good concurrent programs is not hard... it is very hard. A slight oversight and you will have introduced unexpected bugs. These bugs are not the friendly kind that will appear in testing, these are the nasty kind that only show up on rare occasions (in my experience this is usually when it is critical that the don't show up).&lt;br /&gt;&lt;br /&gt;One of the most important things to consider with any of these solutions is communication. How do you communicate that the line "button1.Enabled = false;" is absolutely critical to the safety of the application? If this line is removed, the safety of the application is compromised. In a team development environment you need to ensure that there is a good understanding of the strategies used to ensure that the application remains safe and live.&lt;br /&gt;&lt;br /&gt;Patterns can help greatly with communication. I am really looking forward to seeing Matthew's future entries on this topic...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;On Invoke and BeginInvoke&lt;/span&gt;&lt;br /&gt;Basically I agree with Matthew, BeginInvoke is usually the better option. However, I would not go as far as saying that Invoke should never be used. Rather, it is my opinion that you should understand what you are trying to do and choose the one that is most appropriate. This in most cases will be BeginInvoke.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-110625834612353487?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://spaces.msn.com/members/mwadams/Blog/cns!1pAMOzaH98ZfHK1uhQS5Bd5g!128.entry' title='Concurrent Programming'/><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/110625834612353487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=110625834612353487' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110625834612353487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110625834612353487'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/01/concurrent-programming.html' title='Concurrent Programming'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-110619764635591990</id><published>2005-01-20T14:21:00.000+11:00</published><updated>2005-01-21T09:08:22.556+11:00</updated><title type='text'>Beware BeginInvoke</title><content type='html'>&lt;span style="font-style: italic;"&gt;Updated 21/01: Included additional solution in download. See this &lt;a href="http://thoughtlabs.net/andrew/blog/2005/01/concurrent-programming.html"&gt;entry&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;After reading &lt;a href="http://spaces.msn.com/members/mwadams/Blog/cns%211pAMOzaH98ZfHK1uhQS5Bd5g%21124.entry"&gt;Matthew's blog&lt;/a&gt; entry in detail I have a few comments...&lt;br /&gt;&lt;br /&gt;The code for this is available for &lt;a href="http://www.thoughtlabs.net/andrew/downloads/Deadlock2.zip"&gt;download&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Is this really thread safe?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To answer this we must ask, what is the intended semantics? While there is little to go on, I have assumed that each click of the button should add the text, "plus a bit" to the end of the label. So clicking this button multiple times should result in that number of "plus a bit"s being added to the label.&lt;br /&gt;&lt;br /&gt;Does this occur? What does the 'evil little daemon' have to say about this?&lt;br /&gt;&lt;br /&gt;Download the code and give it a try... Click the button quickly 10 times, and watch the result.&lt;br /&gt;&lt;br /&gt;It works... But is it safe?&lt;br /&gt;&lt;br /&gt;The problem is that the &lt;span style="font-style: italic;"&gt;evil little daemon&lt;/span&gt; is a slacker! He (or she) does not want to work all the time. So lets give him a hand.&lt;br /&gt;&lt;br /&gt;Try inserting the line "System.Threading.Thread.Sleep(1000);" after the lock.&lt;br /&gt;&lt;br /&gt;This puts the current thread (i.e. the worker) to sleep for 1000 milliseconds, giving the evil little daemon a chance to work his magic.&lt;br /&gt;&lt;br /&gt;Run it again and see the results, clicking the button 10 times. In my case three "plus a bit"s were added to the label, with a little delay due to the sleep. Why? Race conditions, as I &lt;a href="http://thoughtlabs.net/andrew/blog/2005/01/interacting-with-gui.html"&gt;discussed &lt;/a&gt;&lt;a href="http://thoughtlabs.net/andrew/blog/2005/01/interacting-with-gui.html"&gt;earlier&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To view the problem for yourself, download the new version of the code and run it in the debugger. You can then view the changes that occur on the instance variable in the output window. You should notice that the value gets updated the correct number of times, but that the values are wrong (much like the account problem I &lt;a href="http://thoughtlabs.net/andrew/blog/2005/01/interacting-with-gui.html"&gt;discussed &lt;/a&gt;&lt;a href="http://thoughtlabs.net/andrew/blog/2005/01/interacting-with-gui.html"&gt;earlier&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Where is the problem? The problem exists because of the locking strategy. In this case the lock is acquired to read the value, but is then released allowing other threads to read and write to this value. This thread plans on reading the value, changing the value, and writing the value back (via the GUI thread). Because the lock is released after reading, it is possible that it has changed before the write occurs. As the semantics of our program require that none of these values get lost, this is not safe. So what can be done?&lt;br /&gt;&lt;br /&gt;There are several potential approaches, so lets discuss them.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Solution 1&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;If the update can be performed on the worker thread then the update is simple. Move the updating of the value into the lock with the read. Now that is code is updating the instance variable we do not need to tell the GUI of the value of the string, the GUI can re-query for it. As a result we can use a standard method invoker and get the form to update itself.&lt;br /&gt;&lt;br /&gt;The new code looks like this (I have changed "plus a bit" to " 1" as it is easier to count the correct number in the output)&lt;br /&gt;&lt;br /&gt;         lock( littleLockObject )&lt;br /&gt;         {&lt;br /&gt;             //read and update the string...&lt;br /&gt;             myUsefulString += " 1";&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;To make the test fairer this can be changed to:&lt;br /&gt;&lt;br /&gt;         lock( littleLockObject )&lt;br /&gt;         {&lt;br /&gt;             string copy;&lt;br /&gt;             copy = myUsefulString;&lt;br /&gt;             System.Threading.Thread.Sleep(1000);&lt;br /&gt;             myUsefulString = copy + " 1";&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;This way the sleep is between the read and the write, as it was before.&lt;br /&gt;&lt;br /&gt;With this we can now consider the String to be our model and GUI our view. The GUI code only views the value, it doesn't update it. Ideally we could move this into another class, and then raise an even upon change etc...&lt;br /&gt;&lt;br /&gt;When you run this you will see that all of the clicks get through to the label.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Solution 2&lt;/span&gt;&lt;br /&gt;A much more complex solution is to remain with the updating of the instance variable from the GUI thread. In order to ensure that this works safely we must ensure that only one thread can be performing this operation at a time. We can do this by introducing a boolean variable that controls access to this functionality. The body of the method can then be guarded via a condition on this variable, see the code below:&lt;br /&gt;&lt;br /&gt;  public class Form1 : System.Windows.Forms.Form&lt;br /&gt;  {&lt;br /&gt;      private bool _MutexAvailable = true;&lt;br /&gt;&lt;br /&gt;      private void DoSomeWork()&lt;br /&gt;      {&lt;br /&gt;          string copy;&lt;br /&gt;          lock( littleLockObject )&lt;br /&gt;          {&lt;br /&gt;              while(false == _MutexAvailable)&lt;br /&gt;                  Monitor.Wait( littleLockObject );&lt;br /&gt;&lt;br /&gt;              _MutexAvailable = false;&lt;br /&gt;             copy = myUsefulString;             &lt;br /&gt;          }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So how does this work? The thread waits until _MutexAvailable is true, it then sets _MutexAvailable to be false and then processes the body of the method. No others can continue as they are blocked by the guard, i.e. they are waiting for _MutexAvailable to become true.&lt;br /&gt;&lt;br /&gt;At the end of the method we now need to reset _MutexAvailable and wake any waiting threads. This must be done in a critical section to ensure safety. So the following code is added to the end of the method:&lt;br /&gt;&lt;br /&gt;          lock( littleLockObject )&lt;br /&gt;          {&lt;br /&gt;              _MutexAvailable = true; &lt;br /&gt;              Monitor.PulseAll( littleLockObject );&lt;br /&gt;          }&lt;br /&gt;&lt;br /&gt;The PulseAll wakes the threads from the Wait at the top of the method.&lt;br /&gt;&lt;br /&gt;Run the program again. Leave in the Sleep so that we are testing the same thing. Now all of the clicks result in an update of the label.&lt;br /&gt;&lt;br /&gt;Is this safe? I am afraid that it is not...&lt;br /&gt;&lt;br /&gt;Why?&lt;br /&gt;Try adding a sleep to the UpdateTheUI method.&lt;br /&gt;&lt;br /&gt;Running the program now causes incorrect updating again. The problem is now the use of BeginInvoke. With BeginInvoke a new thread is being used to update the value. This allows the worker to pulse another thread and have it read a stale value from the instance variable. The solution is to replace BeginInvoke with Invoke. It is critical that we wait at this point until after the instance variable is updated.&lt;br /&gt;&lt;br /&gt;Running this again, with the two sleeps, and now it works correctly.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Solution 3&lt;/span&gt;&lt;br /&gt;The problem with solution 2 is that it is full of thread management code that is not fun to play with (for most people). This can be extracted out into a utility class and can then be reused again and again. In this case the utility is called a Mutex. However, this is not the Mutex that comes with .NET, rather it is a lightweight Mutex.&lt;br /&gt;&lt;br /&gt;The code now looks like this:&lt;br /&gt;&lt;br /&gt;     private void DoSomeWork()&lt;br /&gt;     {&lt;br /&gt;         string copy;&lt;br /&gt;&lt;br /&gt;         _MyMutex.Acquire();&lt;br /&gt;&lt;br /&gt;         try&lt;br /&gt;         {&lt;br /&gt;             //no need for lock, this is a reference to a immutable object&lt;br /&gt;             copy = myUsefulString;&lt;br /&gt;&lt;br /&gt;             System.Threading.Thread.Sleep(1000);&lt;br /&gt;&lt;br /&gt;             if( this.InvokeRequired )&lt;br /&gt;             {&lt;br /&gt;                 Invoke( new StringMethodInvoker( UpdateTheUI ), new object[] { copy + " 1" } );&lt;br /&gt;             }&lt;br /&gt;             else&lt;br /&gt;             {&lt;br /&gt;                 UpdateTheUI( copy + " plus a bit" );&lt;br /&gt;             }&lt;br /&gt;         }&lt;br /&gt;         finally&lt;br /&gt;         {&lt;br /&gt;             _MyMutex.Release();&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;The lock is no longer used as the Mutex provides us with the concurrency control.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Concurrency is difficult. There are no magic solution. BeginInvoke is a great tool, but you must take care if you want to ensure total safety.&lt;br /&gt;&lt;br /&gt;Having said this, I cannot imagine the circumstances that would be required for this safety issue to raise itself without the inserted Sleep statements. Personally, however, I think you are best to try to make your application as safe as possible (i.e. live + safe).&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-110619764635591990?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://spaces.msn.com/members/mwadams/Blog/cns%211pAMOzaH98ZfHK1uhQS5Bd5g%21124.entry' title='Beware BeginInvoke'/><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/110619764635591990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=110619764635591990' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110619764635591990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110619764635591990'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/01/beware-begininvoke.html' title='Beware BeginInvoke'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-110618955661118569</id><published>2005-01-20T13:33:00.000+11:00</published><updated>2005-01-20T13:54:35.096+11:00</updated><title type='text'>Interacting with a GUI</title><content type='html'>If you look at GUI libraries in the .NET and Java platforms, you will find that these both require that interactions with the GUI are performed upon a single thread. This has become a hot topic lately, see &lt;a href="http://spaces.msn.com/members/mwadams/Blog/cns%211pAMOzaH98ZfHK1uhQS5Bd5g%21124.entry"&gt;Matthew Adams blog&lt;/a&gt;, and the related links.&lt;br /&gt;&lt;br /&gt;So why is this implemented in this way?&lt;br /&gt;&lt;br /&gt;This is a form of exclusion, enforced only by documentation (and the fact that you risk deadlocks if you ignore this).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Exclusion?&lt;/span&gt;&lt;br /&gt;In a concurrent program multiple threads may attempt to access data elements at the same time. This can lead to a number of issues, referred to as race conditions. For example.&lt;br /&gt;&lt;br /&gt;Consider the following pseudocode:&lt;br /&gt;&lt;br /&gt;Thread 1:&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;Read account value&lt;/li&gt;   &lt;li&gt;Increase value by $100&lt;/li&gt;   &lt;li&gt;Write back new account value&lt;/li&gt; &lt;/ol&gt; Thread 2:&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;Read account value&lt;/li&gt;   &lt;li&gt;Increase value by $50&lt;/li&gt;   &lt;li&gt;Write back new account value&lt;/li&gt; &lt;/ol&gt; In a sequential (single threaded) programs there would be no issues with this type of code... However, if these two threads run concurrently then we have an issue.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Why?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The execution may occur in such as way that the result, after completion, does not result in the balance of the account increasing by $150. Imagine the following execution:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;Thread 1: Reads the account value as $1000 (the starting balance)&lt;/li&gt;   &lt;li&gt;Thread 1: Adds $100 to this, the result being $1100 is currently stored in a temporary variable.&lt;/li&gt;   &lt;li&gt;Thread 2: Reads the account value as $1000 ($1100 has not been stored yet!)&lt;/li&gt;   &lt;li&gt;Thread 2: Adds $50 to this, the result being stored in a temporary variable.&lt;/li&gt;   &lt;li&gt;Thread 2: Writes the value back into the account, the accounts balance is now $1050&lt;/li&gt;   &lt;li&gt;Thread 1: Writes the value stored in its temporary variable back into the account. The accounts balance is now $1100!&lt;/li&gt; &lt;/ol&gt; There are several ways to get around this issue, one such approach is called &lt;span style="font-style: italic;"&gt;exclusion&lt;/span&gt;. Using this approach, you ensure that only one thread at a time can manipulate the shared data. Exclusion can be implemented via critical section, locks that allow only a single thread to enter the critical section of code. With the GUIs, the exclusion is by protocol. In essence, the documentation indicates that, while they don't stop it, you are not allowed to access these items from other threads.&lt;br /&gt;&lt;br /&gt;The issue then is, so how do you interact with the GUI? The answer is, with care and invoke. I will leave the details for you to read in the linked articles above.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-110618955661118569?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/110618955661118569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=110618955661118569' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110618955661118569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110618955661118569'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/01/interacting-with-gui.html' title='Interacting with a GUI'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-110607955606581886</id><published>2005-01-19T07:19:00.000+11:00</published><updated>2005-01-19T07:43:36.280+11:00</updated><title type='text'>Concurrency</title><content type='html'>  &lt;p class="MsoNormal"&gt;Yesterday I was sent an &lt;a href="http://www.gotw.ca/publications/concurrency-ddj.htm"&gt;interesting article on concurrency&lt;/a&gt;. I have had a quick skim read of it and it is basically echoing what I have been saying over the last few months... Concurrency is the next big step in computing. Why? Multi-core CPUs.&lt;br /&gt;&lt;br /&gt;In order to take advantage of multi-core CPUs, applications will need to be developed that use multiple threads. Multiple threads = concurrency. Concurrency = "You need to know what you are doing!" (have a read of some of the links from my site to concurrency issues such as Double Check Locking).&lt;br /&gt;&lt;br /&gt;Having read this, it leads me to thinking, can you introduce concurrency into applications? I would agree to some degree that you can... You can offload things like loading images, saving and loading files, and background tasks., but generally the core functionality is usually single threaded. Will the offloading of "background" tasks give sufficient performance advantages, given the addition of concurrency control mechanisms? This is something that I need to do some more thinking on and will post my thoughts...&lt;br /&gt;&lt;br /&gt;Let us consider an application example: PowerPoint: what threads could exist in this application?&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;   &lt;ol start="1" type="1"&gt; &lt;li class="MsoNormal" style=""&gt;Load and render slides      (potentially many threads, using structural exclusion to load different      slides)&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;User interface management      (the GUI thread, interacted with from the threads above)&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;Save thread (save files...      requires lock on model...)&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;Spelling and Gramma thread      (interacts with changing model, and UI)&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt; &lt;/ol&gt;   &lt;p class="MsoNormal"&gt;So multiple threads is possible, but this has greatly increased the complexity of the application. The model now requires appropriate critical sections, and/or locking strategies. How would this work in a team environment? Communication is the key. More developers need to know and understand concurrency, and strategies to overcome concurrency issues.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;Beware Shameless Plug Below&lt;/span&gt;&lt;br /&gt;So this bring me to the question:&lt;br /&gt;Why do Advanced .NET at Swinburne?&lt;br /&gt;&lt;br /&gt;Until recently Advanced .NET has been a subject that covered topics that most people would never work on again in their lives. This subject is hard. Most people work really really hard, and still only get a passing mark... What is the deal?&lt;br /&gt;&lt;br /&gt;Advanced.NET deals with concurrency. This subject will help you learn about developing safe and effective concurrent applications.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-110607955606581886?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/110607955606581886/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=110607955606581886' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110607955606581886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110607955606581886'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/01/concurrency.html' title='Concurrency'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10202973.post-110602276186119785</id><published>2005-01-18T15:27:00.000+11:00</published><updated>2005-01-18T15:38:50.790+11:00</updated><title type='text'>Welcome Message</title><content type='html'>Welcome to my new BLOG.&lt;br /&gt;&lt;br /&gt;My previous blog on the byte club server will no longer be active...  Please ensure that you use my new &lt;a href="http://feeds.feedburner.com/AndrewCain"&gt;feed&lt;/a&gt; to keep up to date.&lt;br /&gt;&lt;br /&gt;If you are interested in finding older entries please refer to &lt;a href="http://www.byteclub.net/blog/acain/index.php"&gt;my old blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This blog will discuss my thoughts on software development, teaching, and other (sometimes related) work.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10202973-110602276186119785?l=andrewcain.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrewcain.blogspot.com/feeds/110602276186119785/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10202973&amp;postID=110602276186119785' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110602276186119785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10202973/posts/default/110602276186119785'/><link rel='alternate' type='text/html' href='http://andrewcain.blogspot.com/2005/01/welcome-message_18.html' title='Welcome Message'/><author><name>Andrew Cain</name><uri>http://www.blogger.com/profile/05258615955880287223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://lh6.google.com/image/alipatchdrewcain/RlFvcdwrJHI/AAAAAAAAABw/3NvTYvi0PlY/s144/Photo%207.jpg'/></author><thr:total>3</thr:total></entry></feed>
