<?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-3169664517236002327</id><updated>2011-10-10T04:10:31.484-07:00</updated><category term='firefox'/><category term='greasemonkey'/><title type='text'>Sweet Syntactic Sugar</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>24</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-3166061839153642606</id><published>2011-06-25T04:20:00.001-07:00</published><updated>2011-06-25T04:20:04.398-07:00</updated><title type='text'>SPAM email – spreading classical literature?</title><content type='html'>&lt;p&gt;SPAM email has gotten quite smart in bypassing various spam filters, the funniest being the use of snippets from works of literature to pad the text, to make it look more “real”.&amp;#160; So it will start off by offering to increase the size of certain appendages, but then suddenly break into a snippet of Sherlock Holmes.&amp;#160; Sometimes these make you go “I wonder what book this comes from, I would love to read it!” – e.g. today’s SPAM from my inbox comes courtesy of two classics of literature:&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="2nxuy0ha" border="0" alt="2nxuy0ha" src="http://lh6.ggpht.com/-zkeEEfPFDSI/TgXEYmUmkzI/AAAAAAAAAco/7SeZQ5Mfj08/2nxuy0ha%25255B4%25255D.jpg?imgmax=800" width="525" height="104" /&gt;&lt;/p&gt;  &lt;p&gt;The first part apparently comes from “&lt;a href="http://www.pagebypagebooks.com/Bram_Stoker/Dracula/CHAPTER_17_p3.html"&gt;Dracula&lt;/a&gt;” (what CAN’T Google find?):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;&amp;quot;You are quite right. I did not trust you because I did not know you. But I know you now, and let me say that I should have known you long ago. I know that Lucy told you of me. She told me of you too. May I make the only atonement in my power?&lt;font style="background-color: #ffff00"&gt; Take the cylinders and hear them. The first half-dozen&lt;/font&gt; of them are personal to me, and they will not horrify you. Then you will know me better. Dinner will by then be ready. In the meantime I shall read over some of these documents, and shall be better able to understand certain things.&amp;quot;&lt;/em&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The other from “&lt;a href="http://www.gutenberg.org/files/17157/17157-h/17157-h.htm#TROD"&gt;Gulliver’s Travels&lt;/a&gt;”:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;“And, therefore, when he was again about to move, I screamed as loud as fear could make me. &lt;font style="background-color: #ffff00"&gt;Whereupon the huge creature trod short, and looking round about&lt;/font&gt; under him for some time, at last espied me as I lay on the ground. He considered awhile, with the caution of one who endeavors to lay hold on a small dangerous animal in such a manner that it shall not be able either to scratch or to bite him, as I myself have sometimes done with a weasel in England.”&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now I imagine they’ve had go from doing full paragraphs ripped out of Project Gutenberg either to chopped sentences either because filters in places like GMail are smart enough to look for longer Gutenberg matches, or to save space.&amp;#160; Or both.&amp;#160; Would love to find a site charting the evolution of countermeasures employed in SPAM to bypass various filters.&amp;#160; Maybe the final step in SPAM will be the evolution of AI to appear like a genuine unique email about a subject?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-3166061839153642606?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/3166061839153642606/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=3166061839153642606' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/3166061839153642606'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/3166061839153642606'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2011/06/spam-email-spreading-classical.html' title='SPAM email – spreading classical literature?'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/-zkeEEfPFDSI/TgXEYmUmkzI/AAAAAAAAAco/7SeZQ5Mfj08/s72-c/2nxuy0ha%25255B4%25255D.jpg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-3192709395357707185</id><published>2011-05-15T11:49:00.001-07:00</published><updated>2011-05-15T11:49:00.745-07:00</updated><title type='text'>.NET decompilers–or “Attack of the (currently inferior) Clones”</title><content type='html'>&lt;p&gt;RedGate’s &lt;a href="http://reflector.red-gate.com/download.aspx?TreatAsUpdate=1"&gt;Reflector&lt;/a&gt; tool has been ridiculously popular amongst .NET developers for a long time.&amp;#160; It has shed light on all kinds of dark .NET corners in both the shipped .NET assemblies and third party ones.&amp;#160; Heck, I’ve even used it to try to make sense of poorly obfuscated ones, with surprisingly positive results (&lt;a href="http://www.devart.com/dotconnect/oracle/"&gt;DevArt dotConnect&lt;/a&gt;, I’m looking at you!).&lt;/p&gt;  &lt;p&gt;But then we were all cast out of Eden.&amp;#160; &lt;a href="http://reflector.red-gate.com/download.aspx?TreatAsUpdate=1"&gt;Free Reflector no longer exists&lt;/a&gt;, and they want you to pony up $35 to get back in.&amp;#160; I tried to hold on to the old versions for as long as possible:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_h7bul_inQ00/TdAf7iqO4dI/AAAAAAAAAbc/YkApSJFl1QA/s1600-h/53df13017672394c64fd9ac9137001af%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="53df13017672394c64fd9ac9137001af" border="0" alt="53df13017672394c64fd9ac9137001af" src="http://lh3.ggpht.com/_h7bul_inQ00/TdAf8C66vyI/AAAAAAAAAbg/xlU9MteOotM/53df13017672394c64fd9ac9137001af_thumb%5B1%5D.png?imgmax=800" width="552" height="232" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;But eventually decided to have a look at Reflector 7, which I’ve now reached the end of the 14-day trial of:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_h7bul_inQ00/TdAf8qtG13I/AAAAAAAAAbk/v0iKGSBsw9A/s1600-h/22044c3cf7dc9872285180b33d162874%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="22044c3cf7dc9872285180b33d162874" border="0" alt="22044c3cf7dc9872285180b33d162874" src="http://lh6.ggpht.com/_h7bul_inQ00/TdAf88vmZcI/AAAAAAAAAbo/FwaHhkvID1s/22044c3cf7dc9872285180b33d162874_thumb%5B1%5D.png?imgmax=800" width="548" height="324" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So let’s have a look at the contenders for the “.NET Decompiler King” crown, that have surfaced from the nerd rage that bathed the web after the announcement of the demise of free Reflector.&lt;/p&gt;  &lt;p&gt;A good list of possibilities can be found in &lt;a href="http://stackoverflow.com/questions/2425973/open-source-alternatives-to-reflector"&gt;this&lt;/a&gt; StackOverflow discussion.&lt;/p&gt;  &lt;p&gt;I’ll look at the, what appear to me, top 3 offerings:&amp;#160; &lt;a href="http://wiki.sharpdevelop.net/ILSpy.ashx"&gt;ILSpy&lt;/a&gt;, which is open source,&amp;#160; &lt;a href="http://www.telerik.com/products/decompiling.aspx"&gt;JustDecompile&lt;/a&gt; from Telerik (free but closed), and &lt;a href="http://www.jetbrains.com/decompiler/"&gt;dotPeek&lt;/a&gt; from JetBrains (free but closed):&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;&lt;a href="http://wiki.sharpdevelop.net/ILSpy.ashx"&gt;ILSpy&lt;/a&gt;:&lt;/h4&gt;  &lt;p&gt;Interestingly, &lt;a href="http://wiki.sharpdevelop.net/ILSpy.ashx"&gt;ILSpy&lt;/a&gt; lists .NET4 as a prerequisite.&amp;#160; Meh.&amp;#160; Whatever, I’m hoping it’s an indicator of use of more “interesting” coding patterns.&lt;/p&gt;  &lt;p&gt;It’s a bit rough at the moment, but runs fast, and is pretty stable.&amp;#160; Navigation is not as fluid as in Reflector.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_h7bul_inQ00/TdAf-7rad1I/AAAAAAAAAbs/KGAtkAraZto/s1600-h/5534918e0a8a6c6915480c936739390b%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="5534918e0a8a6c6915480c936739390b" border="0" alt="5534918e0a8a6c6915480c936739390b" src="http://lh6.ggpht.com/_h7bul_inQ00/TdAf_2QehsI/AAAAAAAAAbw/dnlUPN8vpaw/5534918e0a8a6c6915480c936739390b_thumb%5B1%5D.png?imgmax=800" width="1104" height="709" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Lambda support is as bad as it was in Reflector 6, but is clearly on the roadmap on the ILSpy website.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_h7bul_inQ00/TdAgATreHUI/AAAAAAAAAb0/DWHlLVmZ_7s/s1600-h/9b8ba14fbfb13d67fcebe0d0ef4f7f86%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="9b8ba14fbfb13d67fcebe0d0ef4f7f86" border="0" alt="9b8ba14fbfb13d67fcebe0d0ef4f7f86" src="http://lh5.ggpht.com/_h7bul_inQ00/TdAgAv8OXaI/AAAAAAAAAb4/Hlf9ojrxNUA/9b8ba14fbfb13d67fcebe0d0ef4f7f86_thumb%5B1%5D.png?imgmax=800" width="899" height="203" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This has promise, but is lacking in the usability department.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;&lt;a href="http://www.telerik.com/products/decompiling.aspx"&gt;JustDecompile&lt;/a&gt;:&lt;/h4&gt;  &lt;p&gt;Overall, the look is very much like Reflector - types are hyperlinked, you can expand all members of a class etc.&amp;#160; Other assemblies are pulled in a needed if it can resolve them.&amp;#160; One annoying thing was that calls to &amp;quot;base&amp;quot; constructors weren't hyperlinked - something that's annoying if there are a lot of constuctor overloads.&lt;/p&gt;  &lt;p&gt;Overall impression is one of extreme slowness.&amp;#160; Assemblies take ages to load, everything is quite painfully slow.&amp;#160; But then again, it’s a young product.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_h7bul_inQ00/TdAgBsE2NjI/AAAAAAAAAb8/Vz54CW6EtQk/s1600-h/5173ac52f1ee58fc184076bdffad0ab4%5B9%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="5173ac52f1ee58fc184076bdffad0ab4" border="0" alt="5173ac52f1ee58fc184076bdffad0ab4" src="http://lh5.ggpht.com/_h7bul_inQ00/TdAgC08hbMI/AAAAAAAAAcE/0TW1HFno38M/5173ac52f1ee58fc184076bdffad0ab4_thumb%5B4%5D.png?imgmax=800" width="984" height="461" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Has nifty search, allowing to find usages.&amp;#160; A nice improvement that can already be seen is the ability to filter by only Read or Write usages.&amp;#160; Handy when you are trying to find possible culprits that are setting some member for example.&amp;#160; Although it didn't quite work as expected - as in, it didn't work for me.&lt;/p&gt;  &lt;p&gt;At the moment, the product seems a very sluggish, and a fair few crashes.&amp;#160; Also, from the various errors and the presence of the DLL in the directory, we can tell that Mono.Cecil is being used.&amp;#160; Refreshingly, at least for the moment, the application does not seem to be obfuscated, like Reflector was.&amp;#160; Anyhow, the product has a long way to go.&amp;#160; Until I see refinements like bookmarks, ability to create deeper navigation trees (in Reflector you could do deep investigations of using &amp;quot;used by/called by&amp;quot; to visualise a deep call tree you're interested in, expanding more and more nodes to reveal a long chain of callers to establish a relationship between two modules).&lt;/p&gt;  &lt;p&gt;Lambda handling is poor as well:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;IEnumerable&amp;lt;DOCUMENT&amp;gt; dOCUMENTs = ParameterExpression[] parameterExpressionArray3 = new ParameterExpression[1].Where(Expression.Lambda(parameterExpressionArray3[0] = parameterExpression, parameterExpressionArray3));&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;As for Add-Ins, which in my opinion endeared Reflector to the community, I posted &lt;a href="http://www.telerik.com/community/forums/justdecompile/general-discussions/will-there-eventually-be-an-ability-to-develop-plugins-addins.aspx"&gt;a question&lt;/a&gt; on the Telerik forums (which are already full of bug reports and feature requests, only a few days after release) and quickly got the response that &amp;quot;This is definitely an option that we'll target for the feature version of the product&amp;quot;.&amp;#160; So their heart seems to be in the right place.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;&lt;a href="http://www.jetbrains.com/decompiler/"&gt;dotPeek&lt;/a&gt;:&lt;/h4&gt;  &lt;p&gt;JetBrains has just released a very early version of their dotPeek software, and it's a little, well, undercooked. They must be coming from the &amp;quot;&lt;a href="http://en.wikipedia.org/wiki/Release_early,_release_often"&gt;release early, release often&lt;/a&gt;&amp;quot; school of development:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_h7bul_inQ00/TdAgEdgVWSI/AAAAAAAAAcI/Onch6DFowl0/s1600-h/image%5B9%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_h7bul_inQ00/TdAgGLTFZvI/AAAAAAAAAcM/6KP6LdEXkPU/image_thumb%5B4%5D.png?imgmax=800" width="1028" height="327" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;There appear to be various errors sprinkled through the code, and the treatment of lambdas is by far the least readable.&amp;#160; Navigation and search are very functional, as I expect they’re almost straight out of ReSharper.&lt;/p&gt;  &lt;h4&gt;Conclusion and musings:&lt;/h4&gt;  &lt;p&gt;Looking at these three, it seems to me that so far we're quite far off getting a decent replacement for Reflector.&amp;#160; Although the announcement of moving to a paid model has created this &lt;a href="http://en.wikipedia.org/wiki/Cambrian_explosion"&gt;Cambrian explosion&lt;/a&gt; of .NET decompilers, the current offerings seem to indicate that it's quite difficult to get the level of polish that Reflector had.&lt;/p&gt;  &lt;p&gt;An interesting differentiator in the near future for these products I think will be Lambda expressions - given how much more we're using Lambdas in day to day .NET development now, I'd say the final favourite decompiler will be the one that renders them properly, and so far it's a feature only available in Reflector 7 (even though it uses the &amp;quot;query&amp;quot; style syntax for rendering them): &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_h7bul_inQ00/TdAgGdupITI/AAAAAAAAAcQ/9KqXnqbRNhE/s1600-h/Image%281%29%5B10%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Image(1)" border="0" alt="Image(1)" src="http://lh6.ggpht.com/_h7bul_inQ00/TdAgG0dWcrI/AAAAAAAAAcU/hMEjdAw6fDU/Image%281%29_thumb%5B3%5D.png?imgmax=800" width="465" height="93" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We'll just have to wait and see what happens over the next few months.&amp;#160; All of the above tools are quite early on in their development, and I’m guessing they’re all shooting for mimicking Reflector’s abilities one to one, before adding their own flavour on top, but they’re not there yet.&lt;/p&gt;  &lt;p&gt;In the meantime, is $35 all that much to spend on a decent tool?&amp;#160; My feelings towards this were quite mixed initially, first I thought, well $35 is fine for a trusted tool, but then the feeling of betrayal sets in, especially because there isn’t even a free “lite” version.&amp;#160; On the other hand, I think a lot of people would have happily donated the $35, so this should be no different.&amp;#160; For example, if work didn’t pay for ReSharper, I’d most likely buy my own license, so what’s $35?&amp;#160; It’s all these mixed feelings from suddenly having to pay for something that you had for free.&amp;#160; Of course all sins would be forgiven if only RedGate offered a free “lite” version.&lt;/p&gt;  &lt;p&gt;It's illogical, Captain.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-3192709395357707185?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/3192709395357707185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=3192709395357707185' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/3192709395357707185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/3192709395357707185'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2011/05/net-decompilersor-attack-of-currently.html' title='.NET decompilers–or “Attack of the (currently inferior) Clones”'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_h7bul_inQ00/TdAf8C66vyI/AAAAAAAAAbg/xlU9MteOotM/s72-c/53df13017672394c64fd9ac9137001af_thumb%5B1%5D.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-3575796963874810304</id><published>2011-03-08T09:58:00.001-08:00</published><updated>2011-03-08T09:58:14.391-08:00</updated><title type='text'>Software Engineers writing fiction?</title><content type='html'>&lt;p&gt;I’ve just noticed that Mark Russinovich (of &lt;a href="http://technet.microsoft.com/en-gb/sysinternals"&gt;Sysinternals&lt;/a&gt; fame) is publishing a &lt;a href="http://www.amazon.com/Zero-Day-Novel-Mark-Russinovich/dp/031261246X"&gt;fiction book&lt;/a&gt;.&amp;#160; There was another CompSci author, Roger Pressman, who’s &lt;a href="http://www.amazon.com/Software-Engineering-Practitioners-Roger-Pressman/dp/0073375977/ref=sr_1_1?s=books&amp;amp;ie=UTF8&amp;amp;qid=1299605346&amp;amp;sr=1-1"&gt;non-fiction work&lt;/a&gt; was part of the reading during my university course, who had also written a fiction book, and despite only having one review on Amazon sounds like an exciting read.&amp;#160; Both are techno-thrillers.&amp;#160; I’d not expect a historical romance from a software developer!&amp;#160; &lt;/p&gt;  &lt;p&gt;I guess in both cases the authors have enough “street cred” to take a bit of time off to experiment with this idea of being a published author, and return back to their ordinary careers in case of failure – was this something they always wanted to do, but were too afraid to pursue full time?&amp;#160; &lt;/p&gt;  &lt;p&gt;One interesting side note about the “Aymara Bridge” is that (from another review I cannot find), it touches on trivalent logic – i.e. instead of True/False, it has an additional third state.&amp;#160; Apparently this logic type can be inferred from the language of the Aymara culture - &lt;a title="http://aymara.org/biblio/html/igr/igr3.html" href="http://aymara.org/biblio/html/igr/igr3.html"&gt;http://aymara.org/biblio/html/igr/igr3.html&lt;/a&gt;.&amp;#160; The third value indicates a kind of uncertainty that’s absent from “traditional” logic, but is linguistically somewhat natural.&amp;#160; Fascinating concept.&amp;#160; You can still construct some kind of logic system out of it, it’s just that it’s not terribly suited to computers. Pressman cites this idea as the &lt;a href="http://www.rspa.com/aymara/index.html"&gt;inspiration&lt;/a&gt; for his book.&lt;/p&gt;  &lt;p&gt;   &lt;table border="0" cellspacing="0" cellpadding="2" width="1221"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="200"&gt;&lt;a href="http://lh3.ggpht.com/_h7bul_inQ00/TXZuHGs8_yI/AAAAAAAAASA/wNAqJuS5ofg/s1600-h/image%5B2%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_h7bul_inQ00/TXZuJaLvVoI/AAAAAAAAASE/fhpkMLSiJ1Y/image_thumb.png?imgmax=800" width="244" height="244" /&gt;&lt;/a&gt;&lt;/td&gt;          &lt;td valign="top" width="1019"&gt;           &lt;p&gt;From the description at &lt;a href="http://www.amazon.com/Zero-Day-Novel-Mark-Russinovich/dp/031261246X"&gt;Amazon&lt;/a&gt;:&lt;/p&gt;            &lt;p&gt;&lt;em&gt;&lt;font size="1"&gt;The horror of cyberterrorism explodes on the page in Russinovich’s first novel. A plane over the Atlantic suddenly needs to reboot its computer to stay in the air, and the pilots barely avert disaster. A hospital network mixes up patient information, resulting in the death of several people. A law firm, which has lost all of its clients' data and can’&lt;/font&gt;&lt;/em&gt;&lt;em&gt;&lt;font size="1"&gt;t get its system running again, turns to Jeff Aiken, a former government analyst and computer expert. He discovers that all of the crashes are insidiously connected, and an even greater disaster is coming. Computer technospeak is handled with ease by Russinovich, who makes the jargon understandable for nongeeks but does so without losing authenticity. His background at Microsoft ensures that he knows what he’s writing about, but, equally important, he constructs a gripping narrative. A terrifying tale made all the more frightening by our concern that it could offers a glimpse into the future, Russinovich’s thriller just could become one of those books that prompts a real-world response, in this case a wake-up call for greater cybersecurity methods.&lt;/font&gt; &lt;/em&gt;&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="200"&gt;&amp;#160;&lt;/td&gt;          &lt;td valign="top" width="1019"&gt;&amp;#160;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="200"&gt;&lt;a href="http://lh5.ggpht.com/_h7bul_inQ00/TXZuLKiCK3I/AAAAAAAAASI/Uoji_muGrXY/s1600-h/image%5B5%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_h7bul_inQ00/TXZuM5bU3tI/AAAAAAAAASM/l2ctqtbTBX4/image_thumb%5B1%5D.png?imgmax=800" width="244" height="244" /&gt;&lt;/a&gt;&lt;/td&gt;          &lt;td valign="top" width="1019"&gt;           &lt;p&gt;From the description at &lt;a href="http://www.amazon.com/Aymara-Bridge-Roger-Pressman/dp/1401021077/ref=sr_1_7?s=books&amp;amp;ie=UTF8&amp;amp;qid=1299605527&amp;amp;sr=1-7"&gt;Amazon&lt;/a&gt;:&lt;/p&gt;            &lt;p&gt;&lt;em&gt;&lt;font size="1"&gt;Matt Sousa is young archaeologist with an unusual background. On a dig in the foothills of the Andes mountains, Matt uncovers a mysterious Inca object that appears to be almost 1,000 years old, but there's something odd about it, and it's unlike anything he's ever seen.                  &lt;br /&gt;RJ Fanler is the deposed founder of a major computer company who believes that its time for the personal computer to morph into something much more advanced. He believes that machine intelligence is the next great leap, but is struggling with how to achieve it.                   &lt;br /&gt;Marco Paena is a member of the Peruvian terrorist group, Shining Path. He wants to bring down the Peruvian government and needs money to finance a major terrorist strike.                   &lt;br /&gt;An ancient Inca language—Aymara—puts these men on a collision path.                   &lt;br /&gt;Set in Peru and the United States, The Aymara Bridge is a technological thriller that melds the mysteries of the Incas with one vision of a not too far distant future. &lt;/font&gt;&lt;/em&gt;&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-3575796963874810304?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/3575796963874810304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=3575796963874810304' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/3575796963874810304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/3575796963874810304'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2011/03/software-engineers-writing-fiction.html' title='Software Engineers writing fiction?'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_h7bul_inQ00/TXZuJaLvVoI/AAAAAAAAASE/fhpkMLSiJ1Y/s72-c/image_thumb.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-4799712677859210613</id><published>2011-01-31T05:45:00.001-08:00</published><updated>2011-01-31T05:45:11.176-08:00</updated><title type='text'>Humour link - What if Visual Studio had achievements?</title><content type='html'>&lt;p&gt;A proposal to have Steam/XBox style &lt;a href="http://blog.whiletrue.com/2011/01/what-if-visual-studio-had-achievements/"&gt;“achievements” in Visual Studio&lt;/a&gt; – and apparently it’s being made into an &lt;a href="http://channel9.msdn.com/Shows/This+Week+On+Channel+9/TWC9-Coding4Fun-DevLabs-projects-XAMLQuery-VS-Achievements"&gt;extension&lt;/a&gt;!&amp;#160; I’ve come dangerously close to getting some of these I think.&amp;#160;&amp;#160; Some examples from the site:&lt;/p&gt;  &lt;li&gt;&lt;b&gt;The Enterprise&lt;/b&gt; – Build Solution took more than 10 minutes &lt;/li&gt;  &lt;li&gt;&lt;b&gt;Highway to Hell&lt;/b&gt; – Successfully created a WCF service&lt;/li&gt;  &lt;li&gt;&lt;b&gt;Job Security&lt;/b&gt; – Written a LINQ query with over 30 lines of code&lt;/li&gt;  &lt;p&gt;I’d love one for architectural anti-patterns – a bunch of them were given unofficial names at work, but a bit too rude to put in print.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-4799712677859210613?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/4799712677859210613/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=4799712677859210613' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/4799712677859210613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/4799712677859210613'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2011/01/humour-link-what-if-visual-studio-had.html' title='Humour link - What if Visual Studio had achievements?'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-8911200504041703113</id><published>2011-01-11T10:55:00.001-08:00</published><updated>2011-01-11T10:55:27.492-08:00</updated><title type='text'>.NET Reflector 7 Beta is out!</title><content type='html'>&lt;p&gt;Haven’t actually played with it, but it has got to be good.&amp;#160; Apparently a popular community plugin is now built in.&lt;/p&gt;  &lt;p&gt;Get it &lt;a href="http://reflector.red-gate.com/Download.aspx#"&gt;here&lt;/a&gt;, use the link on the right side, the one that asks for you email is version 6.5.&lt;/p&gt;  &lt;p&gt;A list of new features available &lt;a href="http://coolthingoftheday.blogspot.com/2011/01/net-reflector-7-beta-released-with.html"&gt;here&lt;/a&gt; (which was where I heard the news).&amp;#160; There’s apparently a “&lt;a href="http://jasonhaley.com/blog/post/2009/10/14/PowerCommands-for-Reflector-13-and-Introducing-Query-Editor.aspx"&gt;Write LINQ against loaded assemblies&lt;/a&gt;” feature that sounds… intriguing.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-8911200504041703113?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/8911200504041703113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=8911200504041703113' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/8911200504041703113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/8911200504041703113'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2011/01/net-reflector-7-beta-is-out.html' title='.NET Reflector 7 Beta is out!'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-3470388871747569846</id><published>2011-01-09T09:20:00.001-08:00</published><updated>2011-01-09T09:20:54.486-08:00</updated><title type='text'>Launchy vs Windows 7 Start Menu Search</title><content type='html'>&lt;p&gt;For the last few years I’ve been using &lt;a href="http://www.launchy.net/index.php"&gt;Launchy&lt;/a&gt; for rapid keyboard based application launching.&amp;#160; It’s a distant, weaker cousin of QuickSilver on the Mac, with a tiny subset of its functionality, but still fantastic.&amp;#160; Some people, when seeing Launchy in action comment that in Windows 7 this functionality is built in via the Start menu search box.&lt;/p&gt;  &lt;p&gt;Not quite.&lt;/p&gt;  &lt;p&gt;For example typing “vis 10” in Launchy will match “Visual Studio 2010”, however in the Windows Start search thingie, it will not.&amp;#160; You would need “vis 2010”.&amp;#160; &lt;/p&gt;  &lt;p&gt;In the below screenshot, you can see that Launchy matched anything that has a “vis” followed by “08” anywhere in the application name.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_h7bul_inQ00/TSnucNJOVDI/AAAAAAAAAFc/QhqUqkMO6g0/s1600-h/image%5B3%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_h7bul_inQ00/TSnuc2QOmgI/AAAAAAAAAFg/Qkzui8_YigE/image_thumb%5B1%5D.png?imgmax=800" width="389" height="172" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In short, the Windows 7 search matches from the start of a word, whereas Launchy is happy for the match to be anywhere &lt;em&gt;within&lt;/em&gt; the word.&amp;#160; I think that’s a lot more useful, especially in situations where a program name is a concatenation of some words.&amp;#160; E.g. I might have a bunch of XML related applications, all with “XML” somewhere in the name… is it “&lt;strong&gt;XML&lt;/strong&gt;Spy” or “Spy&lt;strong&gt;XML&lt;/strong&gt;” ? The point is, I should be able to look for it by just typing “XML”.&lt;/p&gt;  &lt;p&gt;Anyhow, even if you’re on Windows 7, get &lt;a href="http://www.launchy.net/index.php"&gt;Launchy&lt;/a&gt;.&amp;#160; Or if you’ve been spoiled on a Mac, get QuickSilver.&amp;#160; You won’t regret it.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-3470388871747569846?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/3470388871747569846/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=3470388871747569846' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/3470388871747569846'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/3470388871747569846'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2011/01/launchy-vs-windows-7-start-menu-search.html' title='Launchy vs Windows 7 Start Menu Search'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_h7bul_inQ00/TSnuc2QOmgI/AAAAAAAAAFg/Qkzui8_YigE/s72-c/image_thumb%5B1%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-237210951131916164</id><published>2010-05-15T23:09:00.001-07:00</published><updated>2010-05-15T23:09:46.573-07:00</updated><title type='text'>Tron Legacy</title><content type='html'>&lt;p&gt;Tron is back! Forget Avatar, Iron Man, whatever. This looks awesome:&lt;/p&gt; &lt;object width="598" height="290"&gt;&lt;param name="movie" value="http://media2.firstshowing.net/firstshowing/flv-embed/flvplayer.swf"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;param name="allowfullscreen" value="true"&gt;&lt;/param&gt;&lt;param name="flashvars" value="width=598&amp;amp;height=290&amp;amp;file=http://wdmp.rd.llnwd.net/wdsmp/TRONLegacy/TR1/Grid_Trlr1_High.flv&amp;image;=http://media2.firstshowing.net/firstshowing/img/Grid_Trlr1_High-disneyCDN.jpg&amp;amp;logo=http://media2.firstshowing.net/firstshowing/img/FSnet-Video-Logo.png&amp;amp;link=http://www.firstshowing.net&amp;amp;stretching=exactfit&amp;amp;quality=false&amp;amp;bufferlength=6&amp;amp;volume=90"&gt;&lt;/param&gt; 	&lt;embed src="http://media2.firstshowing.net/firstshowing/flv-embed/flvplayer.swf" type="application/x-shockwave-flash" wmode="transparent" width="598" height="290" allowscriptaccess="always" allowfullscreen="true" flashvars="width=598&amp;height=290&amp;file=http://wdmp.rd.llnwd.net/wdsmp/TRONLegacy/TR1/Grid_Trlr1_High.flv&amp;image=http://media2.firstshowing.net/firstshowing/img/Grid_Trlr1_High-disneyCDN.jpg&amp;logo=http://media2.firstshowing.net/firstshowing/img/FSnet-Video-Logo.png&amp;link=http://www.firstshowing.net&amp;stretching=exactfit&amp;quality=false&amp;bufferlength=6&amp;volume=90" /&gt; &lt;/object&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-237210951131916164?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/237210951131916164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=237210951131916164' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/237210951131916164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/237210951131916164'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2010/05/tron-legacy.html' title='Tron Legacy'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-7267507396726091158</id><published>2010-05-02T05:19:00.001-07:00</published><updated>2010-05-02T05:19:12.830-07:00</updated><title type='text'>Visual Studio 2010 – Smartphone abandoned</title><content type='html'>&lt;p&gt;Started using the new and shiny VS’10 at work.&amp;#160; A glorious IDE.&amp;#160; However, Smart-device (PDAs and phones) development is &lt;a href="http://msdn.microsoft.com/en-us/library/sa69he4t.aspx" target="_blank"&gt;no longer supported&lt;/a&gt;, except for the upcoming Windows Mobile 7 – version 6.5 and prior are out.&amp;#160; Talk about drawing a line in the sand – presumably they think that in a year Windows Mobile 6.5 will be forgotten.&amp;#160; Presumably.&lt;/p&gt;  &lt;p&gt;And to think I thought I’d uninstall VS’08.&amp;#160; Silly me.&amp;#160; Have to keep it around for some time yet I think.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-7267507396726091158?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/7267507396726091158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=7267507396726091158' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/7267507396726091158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/7267507396726091158'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2010/05/visual-studio-2010-smartphone-abandoned.html' title='Visual Studio 2010 – Smartphone abandoned'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-1675569667241972479</id><published>2010-03-05T22:04:00.001-08:00</published><updated>2010-03-05T22:04:37.587-08:00</updated><title type='text'>Escalator of dooooom</title><content type='html'>&lt;p&gt;Saw this in Melbourne Central station.&amp;#160; An unfortunate positioning of visual elements, lends an escalator sign an entirely more sinister meaning (it’s even better with its caption):&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://lh6.ggpht.com/_h7bul_inQ00/S5HwZ9sB64I/AAAAAAAAAEo/R6at10_bJcA/s1600-h/IMAG02763.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="IMAG0276" border="0" alt="IMAG0276" src="http://lh6.ggpht.com/_h7bul_inQ00/S5HwcFNEARI/AAAAAAAAAEs/0W35HGafnJ0/IMAG0276_thumb1.jpg?imgmax=800" width="310" height="407" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Is it only me that sees this as an escalator with a drop into a chasm on the end?&amp;#160; Makes me think of “Lemmings”.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-1675569667241972479?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/1675569667241972479/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=1675569667241972479' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/1675569667241972479'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/1675569667241972479'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2010/03/escalator-of-dooooom.html' title='Escalator of dooooom'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_h7bul_inQ00/S5HwcFNEARI/AAAAAAAAAEs/0W35HGafnJ0/s72-c/IMAG0276_thumb1.jpg?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-4817340863344377234</id><published>2009-09-12T18:39:00.001-07:00</published><updated>2009-09-12T18:39:57.006-07:00</updated><title type='text'>Behold, the Meta-stamp</title><content type='html'>&lt;p&gt;Checking my paper mail, I noticed that Australia Post is peddling a new stamp.&amp;#160; Except it looked like two stamps.&amp;#160;&amp;#160; Now usually stamps are tiny postcard of cultural history – endangered species, famous people/places and the like, but one day you run out of ideas, and that’s how we get this– the Meta-stamp – a stamp depicting… errrm… &lt;a href="http://www.stamps.com.au/shop/stamps/australias-favourite-stamp/sku/16110671"&gt;a stamp&lt;/a&gt;!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_h7bul_inQ00/SqxNXMbNf_I/AAAAAAAAADk/aFB5PXP3Cxg/s1600-h/image2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_h7bul_inQ00/SqxNa7fMBcI/AAAAAAAAADo/qzc9BTW260g/image_thumb.png?imgmax=800" width="244" height="172" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I guess it’s kind of similar to when Hollywood remakes classic movies.&amp;#160; &lt;/p&gt;  &lt;p&gt;Can’t wait for the next one – the stamp of a stamp of a stamp. A bit like the &lt;a href="http://www.infinitecat.com/infinite/cat-html/1401-1500/1443.html"&gt;infinite cat project&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-4817340863344377234?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/4817340863344377234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=4817340863344377234' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/4817340863344377234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/4817340863344377234'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2009/09/behold-meta-stamp.html' title='Behold, the Meta-stamp'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_h7bul_inQ00/SqxNa7fMBcI/AAAAAAAAADo/qzc9BTW260g/s72-c/image_thumb.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-5147977338899380790</id><published>2009-05-25T23:45:00.001-07:00</published><updated>2009-05-25T23:45:59.993-07:00</updated><title type='text'>Robot arm ride</title><content type='html'>&lt;p&gt;This was forwarded to me a little while ago, by now making the rounds through the “tubes”.&amp;#160; Not sure if it’s a group of factory workers with too much time on their hands (a spectacular breach of Occupational Health &amp;amp; Safety, surely), or an equally unsafe attraction where you actually pay for the privilege of experiencing your face being millimetres away from being ground into the pavement by a giant robot arm.&amp;#160; Step right up.&lt;/p&gt; &lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/wOCmoYU6h1Q&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/wOCmoYU6h1Q&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-5147977338899380790?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/5147977338899380790/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=5147977338899380790' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/5147977338899380790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/5147977338899380790'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2009/05/robot-arm-ride.html' title='Robot arm ride'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-6838201635347135125</id><published>2009-05-14T20:51:00.001-07:00</published><updated>2009-05-14T20:51:52.377-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='greasemonkey'/><title type='text'>Printing MSDN Magazine articles from Firefox</title><content type='html'>&lt;p&gt;I like to read developer articles.&amp;#160; Some of the best dev articles (in my opinion) for the .NET space are published in the MSDN magazine, available online for free.&amp;#160; Sometimes it’s convenient to print them, to read on the train, or to make notes in the margins.&amp;#160; But Microsoft wants to make that difficult for you.&lt;/p&gt;  &lt;p&gt;They do this in two ways:&lt;/p&gt;  &lt;p&gt;&lt;font size="4"&gt;&lt;strong&gt;1.&lt;/strong&gt;&lt;/font&gt; &lt;em&gt;Refusal to remove a print redirection tag in the header of the articles&lt;/em&gt;.&amp;#160; The print redirection tag exists to suggest to browsers where they should go in order to get a more printer friendly version of the page. For example, say you look at &lt;a href="http://msdn.microsoft.com/en-us/magazine/dd569757.aspx"&gt;this&lt;/a&gt; article.&amp;#160; If you are in IE7 or IE8, when you go to File-&amp;gt;Print Preview, you’ll see a version of the page that’s entirely unlike what the original page looked like.&amp;#160; That was achieved via this directive in the header:&amp;#160; &lt;font color="#400080" face="Courier New"&gt;&amp;lt;link rel=&amp;quot;alternate&amp;quot; media=&amp;quot;print&amp;quot; href=&amp;quot;/en-us/magazine/dd569757(printer).aspx&amp;quot; /&amp;gt;&lt;/font&gt;.&amp;#160; The browser sees &lt;a href="http://www.w3.org/TR/REC-html40/types.html#type-media-descriptors"&gt;this&lt;/a&gt;, takes you to the “print version”, and prints it.&amp;#160; Note that Firefox seems to ignore this, and stubbornly refuses acknowledge that the creator of the page went to the effort of providing an optimised print page.&amp;#160; &lt;/p&gt;  &lt;p&gt;But ignoring that… so far so good – but then the web designers did something weird.&amp;#160; The print version of the page (to which you can get by clicking the “Print View” button on the page) has a printing header link… back to itself.&amp;#160; This has the effect of cancelling any changes you performed on the page, like expanding code regions etc – the page reloads just before printing.&amp;#160; &lt;/p&gt;  &lt;p&gt;Now recently, MS seems to have realized this, but their fix was nothing short of bizarre – add a script to automatically expand all the collapsed regions on load.&amp;#160; Why does the &lt;em&gt;print view&lt;/em&gt; redirect to the &lt;em&gt;print view at all&lt;/em&gt;??&amp;#160; Anyhow, the bizarre fix kind of works, in the past you couldn’t actually expand the collapsed regions, as they’d collapse as soon as you tried to print (because the page reloads).&amp;#160; Now they’re open by default.&amp;#160; But this doesn’t work for Firefox - when you print in Firefox, the regions are collapsed, the script for some reason doesn’t execute, and you’re off trying to expand all the regions by hand.&lt;/p&gt;  &lt;p&gt;&lt;font size="3"&gt;&lt;strong&gt;2.&lt;/strong&gt;&lt;/font&gt;&amp;#160; &lt;em&gt;Somebody forgot their stylesheets.&lt;/em&gt;&amp;#160; The generated page is full of class attributes, but the stylesheet definitions for a lot of them are missing:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_h7bul_inQ00/Sgzmv1CBH5I/AAAAAAAAACs/H6rCxjWcBrU/s1600-h/image22.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_h7bul_inQ00/SgzmwpuqPjI/AAAAAAAAACw/Pgt3Mwg4s14/image_thumb12.png?imgmax=800" width="306" height="194" /&gt;&lt;/a&gt; &lt;a href="http://lh4.ggpht.com/_h7bul_inQ00/SgzmxIjTKVI/AAAAAAAAAC0/lWvi2EaAEL4/s1600-h/image24.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_h7bul_inQ00/Sgzmx5hJxKI/AAAAAAAAAC4/Q0FnH7L9DCc/image_thumb14.png?imgmax=800" width="400" height="160" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;There is no differentiation between headings and text.&amp;#160; The class attributes are there.&lt;/p&gt;  &lt;p&gt;So what to do?&amp;#160; &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/748"&gt;Greasemonkey&lt;/a&gt;, that’s what.&amp;#160; Greasemonkey is an add-on for Firefox, that allows you to execute custom scripts after the page loads.&amp;#160; You can do funky things like tweaking the specific HTML elements, adjust styles etc.&amp;#160; There is a handy &lt;a href="http://diveintogreasemonkey.org/"&gt;online reference&lt;/a&gt;, that gets you started using it in no time.&amp;#160; So now every time I visit an MSDN print page, the styles are magically fixed.&lt;/p&gt;  &lt;p&gt;The resulting script I present here improves on the page in more ways than the above features – I’ve changed the code font to Courier, as that’s a far more common programmer font family, and removed items that “float”, upsetting printing, as well as removing the Copy Code link.&lt;/p&gt;  &lt;p&gt;Here is are some snapshots of the results, side by side (“before” on the left, “after” on the right):&lt;/p&gt;  &lt;p&gt;Header and “Sidebar” entries (I’ve moved the “Sidebar” element to appear inline, for better printing):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_h7bul_inQ00/SgzmyscFQpI/AAAAAAAAAC8/RC0mEuMiJVc/s1600-h/image16.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_h7bul_inQ00/Sgzmz1ZvgYI/AAAAAAAAADA/seFqwkDhfbY/image_thumb8.png?imgmax=800" width="797" height="304" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Section headings and code snippets (no need for the grey background in my opinion, or the “Copy Code “link):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_h7bul_inQ00/Sgzm0s7sYBI/AAAAAAAAADE/a9gTWkhqldA/s1600-h/image21.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_h7bul_inQ00/Sgzm1ld-ojI/AAAAAAAAADI/cUI3XeiuIAI/image_thumb11.png?imgmax=800" width="801" height="347" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;The entire script is below, enjoy (feel free to comment on any styles that I might have missed):&lt;/p&gt;  &lt;p&gt;The obvious barrier of entry is that you have to know how to actually add a script to Greasemonkey.&amp;#160; An exercise left to the reader.&lt;/p&gt; &lt;!-- Stylesheet link --&gt;&lt;link rel="stylesheet" type="text/css" href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" /&gt;&lt;!-- Code --&gt;  &lt;div style="width: 99%; height: 959px" id="hlDiv" class="dp-highlighter"&gt;   &lt;div class="bar"&gt;&lt;/div&gt;    &lt;ol class="dp-c"&gt;     &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;// ==UserScript==&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&lt;span class="comment"&gt;// @name&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; MSDN Magazine&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;// @namespace&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; a&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&lt;span class="comment"&gt;// @include&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; http://msdn.microsoft.com/en-*/*(printer).aspx&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;// ==/UserScript==&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;//this function is straight from the DiveIntoGreasemonkey tutorial&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&lt;span class="keyword"&gt;function&lt;/span&gt;&lt;span&gt; addGlobalStyle(css) {&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;var&lt;/span&gt;&lt;span&gt; head, style;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; head = document.getElementsByTagName(&lt;span class="string"&gt;'head'&lt;/span&gt;&lt;span&gt;)[0];&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (!head) { &lt;/span&gt;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;; }&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; style = document.createElement(&lt;span class="string"&gt;'style'&lt;/span&gt;&lt;span&gt;);&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; style.type = &lt;span class="string"&gt;'text/css'&lt;/span&gt;&lt;span&gt;;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; style.innerHTML = css;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; head.appendChild(style);&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;}&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&lt;span class="comment"&gt;//get rid of the copy code header&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;addGlobalStyle(&lt;span class="string"&gt;&amp;quot;.CodeSnippetTitleBar {display: none !important;}&amp;quot;&lt;/span&gt;&lt;span&gt;);&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;//code snippets&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;addGlobalStyle(&lt;span class="string"&gt;&amp;quot;pre.libCScode {background:#FFFFFF none repeat scroll 0 0 !important;border-top:1px solid #C8CDDE !important;border-bottom:1px solid #C8CDDE !important;border-left:1px solid #C8CDDE !important;border-right:1px solid #C8CDDE !important;display:block !important;font-family:courier,monospace !important;margin:0 0 10px !important;padding-left:5px !important;padding-right:5px !important;padding-top:5px !important;}&amp;quot;&lt;/span&gt;&lt;span&gt;);&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;addGlobalStyle(&lt;span class="string"&gt;&amp;quot;.ArticleTypeTitle {color:#008080 !important;font-family:'Segoe UI',Arial !important ;font-size:14px !important;font-style:normal !important ;font-variant:normal !important ;font-weight:bold !important;margin-top:3px !important;text-transform:none !important;}&amp;quot;&lt;/span&gt;&lt;span&gt;);&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&lt;span class="comment"&gt;//article section title&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;addGlobalStyle(&lt;span class="string"&gt;&amp;quot;.ColumnTypeTitle, .FeatureSmallHead {border-bottom:2px solid #008080 !important;color:#003399 !important;font-family:'Segoe UI',Arial !important;font-size:36px !important;font-style:normal !important;font-variant:normal !important;font-weight:normal !important;line-height:36px !important;margin-bottom:4px !important;padding-bottom:2px !important;text-decoration:none !important;text-transform:uppercase !important;}&amp;quot;&lt;/span&gt;&lt;span&gt;);&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;addGlobalStyle(&lt;span class="string"&gt;&amp;quot;.ColumnTypeSubTitle, .FeatureHeadline {color:#000000 !important;font-family:'Segoe UI',Arial !important;font-size:20px !important;font-style:normal !important;font-variant:normal !important;font-weight:normal !important;line-height:20px !important;margin-bottom:8px !important;text-decoration:none !important;}&amp;quot;&lt;/span&gt;&lt;span&gt;);&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;//author name in header&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;addGlobalStyle(&lt;span class="string"&gt;&amp;quot;.ColumnByLine, .FeatureByLine {color:#000000 !important;font-family:'Segoe UI',Arial;font-size:16px !important;font-style:normal;font-variant:normal;font-weight:normal !important;text-decoration:none !important;}&amp;quot;&lt;/span&gt;&lt;span&gt;);&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&lt;span class="comment"&gt;//sidebar header&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;addGlobalStyle(&lt;span class="string"&gt;&amp;quot;.SidebarHeadline {color:#008080;font-family:'Segoe UI',Arial;font-size:18px;font-weight:bold;line-height:20px;}&amp;quot;&lt;/span&gt;&lt;span&gt;);&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;//recently they've started using floating divs as well this gets rid of them&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;addGlobalStyle(&lt;span class="string"&gt;&amp;quot;div {float:none !important; height:auto !important; width:auto !important;}&amp;quot;&lt;/span&gt;&lt;span&gt;);&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&lt;span class="comment"&gt;//show all hidden panels&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;var&lt;/span&gt;&lt;span&gt; allLinks, thisLink;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;allLinks = document.evaluate(&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="string"&gt;&amp;quot;//div[@style]&amp;quot;&lt;/span&gt;&lt;span&gt;, //any style, as they start off invisible&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; document,&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;null&lt;/span&gt;&lt;span&gt;,&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;null&lt;/span&gt;&lt;span&gt;);&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&lt;span class="keyword"&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="keyword"&gt;var&lt;/span&gt;&lt;span&gt; i = 0; i &amp;lt; allLinks.snapshotLength; i++) {&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; thisLink = allLinks.snapshotItem(i);&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; thisLink.style.display='block';&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;}&amp;#160; &lt;/span&gt;&lt;/li&gt;   &lt;/ol&gt; &lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-6838201635347135125?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/6838201635347135125/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=6838201635347135125' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/6838201635347135125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/6838201635347135125'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2009/05/printing-msdn-magazine-articles-from.html' title='Printing MSDN Magazine articles from Firefox'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_h7bul_inQ00/SgzmwpuqPjI/AAAAAAAAACw/Pgt3Mwg4s14/s72-c/image_thumb12.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-8056709763248738169</id><published>2009-04-05T01:46:00.001-07:00</published><updated>2009-04-05T01:46:37.166-07:00</updated><title type='text'>MIX 09 Videos</title><content type='html'>&lt;p&gt;The MIX 09 conference is well over in the US, and all the content is now available online, all the presentations were recorded.&amp;#160; You can even get them all on the one page, instead of search the presentations for each day:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://videos.visitmix.com/MIX09/All" href="http://videos.visitmix.com/MIX09/All"&gt;http://videos.visitmix.com/MIX09/All&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-8056709763248738169?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/8056709763248738169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=8056709763248738169' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/8056709763248738169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/8056709763248738169'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2009/04/mix-09-videos.html' title='MIX 09 Videos'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-3259993915012759248</id><published>2009-03-23T06:16:00.001-07:00</published><updated>2009-03-23T06:16:00.704-07:00</updated><title type='text'>iPod lap timer parser</title><content type='html'>&lt;p&gt;The iPod Nano is a beautiful thing.&amp;#160; That is unless you want to do something custom.&amp;#160; So it is with the lap timer in it.&amp;#160; There is no obvious way of synchronising the timer logs with the computer.&amp;#160; Even if there is a way in ITunes (I’m pretty sure there isn’t), the point is moot, as I don’t use ITunes (instead I’m using the wonderful &lt;a href="http://mlipod.sourceforge.net/wiki/Main_Page"&gt;ml_ipod&lt;/a&gt; plugin for Winamp).&amp;#160; This is “suboptimal” if you want to, for example, use the lap timer to chart your jogging progress over the course of a year.&amp;#160; You want to crunch those stats in Excel or some such, you certainly aren’t going to copy them from the screen.&lt;/p&gt;  &lt;p&gt;The information on the web is a little sparse on this matter, but there are a number of applications that will let you do this.&amp;#160; The one that caught my eye was &lt;a title="http://wafflesoftware.net/ipodtimer/" href="http://wafflesoftware.net/ipodtimer/"&gt;http://wafflesoftware.net/ipodtimer/&lt;/a&gt; which luckily provided source code (Mac OS X only – aren’t we feeling exclusive).&amp;#160; A relatively trivial exercise in parsing.&amp;#160; The timer format was loosely described in the TimerFormat.txt in the zipped source.&amp;#160; At least detailed enough for me to whip up an implementation in C#.&amp;#160; Hence this post.&lt;/p&gt;  &lt;p&gt;The underlying format is a binary file.&amp;#160; Time to dust off .NET’s BinaryReader.&amp;#160; The below method ReadTimerEntries(string filepath) will read in an iPod timer file (on my Nano it’s &lt;em&gt;/IPod_Control/device/timer&lt;/em&gt;) and produce a list containing the date of the recording, and the associated laps.&amp;#160; From there you have all the info you need.&amp;#160; Anyway, it works for me, on an iPod Nano (3rd gen).&amp;#160; I don’t imagine that the file structure changes much though.&lt;/p&gt; &lt;!-- Stylesheet link --&gt;&lt;link rel="stylesheet" type="text/css" href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" /&gt;&lt;!-- Code --&gt;  &lt;div style="width: 99%; height: 1118px" id="hlDiv" class="dp-highlighter"&gt;   &lt;div class="bar"&gt;&lt;/div&gt;    &lt;ol class="dp-c"&gt;     &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt; partial &lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt; Form1 : Form&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;{&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt; Form1()&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; {&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; InitializeComponent();&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;#160;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt; button1_Click(&lt;/span&gt;&lt;span class="keyword"&gt;object&lt;/span&gt;&lt;span&gt; sender, EventArgs e)&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; {&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; OpenFileDialog ofd = &lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt; OpenFileDialog();&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ofd.FileName = Application.StartupPath;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DialogResult dr =ofd.ShowDialog();&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (dr == DialogResult.OK)&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; List&amp;lt;TimeEntry&amp;gt; entries = ReadTimerEntries(ofd.FileName);&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;foreach&lt;/span&gt;&lt;span&gt; (TimeEntry entry &lt;/span&gt;&lt;span class="keyword"&gt;in&lt;/span&gt;&lt;span&gt; entries)&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Diagnostics.Debug.WriteLine(entry.EntryDate.ToString());&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;foreach&lt;/span&gt;&lt;span&gt; (TimeSpan ts &lt;/span&gt;&lt;span class="keyword"&gt;in&lt;/span&gt;&lt;span&gt; entry.Laps)&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Diagnostics.Debug.WriteLine(ts.ToString());&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt; List&amp;lt;TimeEntry&amp;gt; ReadTimerEntries(&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt; filePath)&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; {&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; List&amp;lt;TimeEntry&amp;gt; results = &lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt; List&amp;lt;TimeEntry&amp;gt;();&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="comment"&gt;//open the file&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var stream = File.OpenRead(filePath);&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; BinaryReader br = &lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt; BinaryReader(stream);&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; br.ReadBytes(4); &lt;span class="comment"&gt;//start file&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;while&lt;/span&gt;&lt;span&gt; (!br.ReadBytes(4).SequenceEqual(&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;#160;&lt;/span&gt;&lt;span class="keyword"&gt;byte&lt;/span&gt;&lt;span&gt;[] { 0x13, 0, 0, 0xC0 }))&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="comment"&gt;//first 4 bytes are already consumed&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ReadRound(br, results);&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt; results;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;private&lt;/span&gt;&lt;span&gt;&amp;#160;&lt;/span&gt;&lt;span class="keyword"&gt;void&lt;/span&gt;&lt;span&gt; ReadRound(BinaryReader br, List&amp;lt;TimeEntry&amp;gt; itemList)&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; {&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; br.ReadBytes((16 * 5));&lt;span class="comment"&gt;// guff&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; br.ReadBytes(8);&lt;span class="comment"&gt;// start date&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;byte&lt;/span&gt;&lt;span&gt; seconds = br.ReadByte();&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;byte&lt;/span&gt;&lt;span&gt; minutes = br.ReadByte();&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;byte&lt;/span&gt;&lt;span&gt; hour = br.ReadByte();&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;byte&lt;/span&gt;&lt;span&gt; day = br.ReadByte();&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;byte&lt;/span&gt;&lt;span&gt; month = br.ReadByte();&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt; year = br.ReadInt16();&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; br.ReadByte(); &lt;span class="comment"&gt;//unknown use&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TimeEntry entry = &lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt; TimeEntry();&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; entry.EntryDate = &lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt; DateTime(year, month, day, hour, minutes, seconds);&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; itemList.Add(entry);&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; br.ReadBytes(4); &lt;span class="comment"&gt;//end date&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; br.ReadBytes(4); &lt;span class="comment"&gt;//start laps&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;while&lt;/span&gt;&lt;span&gt; (!br.ReadBytes(4).SequenceEqual(&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;#160;&lt;/span&gt;&lt;span class="keyword"&gt;byte&lt;/span&gt;&lt;span&gt;[] { 0x10, 0, 0, 0xC0&amp;#160; }))&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; br.ReadBytes(4); &lt;span class="comment"&gt;//start lap&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt; lapMilliseconds = br.ReadInt32(); &lt;/span&gt;&lt;span class="comment"&gt;//4 bytes&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TimeSpan lapTime = TimeSpan.FromMilliseconds(lapMilliseconds);&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; entry.Laps.Add(&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt; TimeSpan(0, 0, 0, 0, lapMilliseconds));&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; br.ReadBytes(4); &lt;span class="comment"&gt;//end lap&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; br.ReadBytes(4); &lt;span class="comment"&gt;//end round&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;}&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;#160;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt; TimeEntry&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;{&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt; DateTime EntryDate;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt; List&amp;lt;TimeSpan&amp;gt; Laps = &lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt; List&amp;lt;TimeSpan&amp;gt;();&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="class"&gt;&lt;span&gt;}&amp;#160; &lt;/span&gt;&lt;/li&gt;   &lt;/ol&gt; &lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-3259993915012759248?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/3259993915012759248/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=3259993915012759248' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/3259993915012759248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/3259993915012759248'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2009/03/ipod-lap-timer-parser.html' title='iPod lap timer parser'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-9193497910446679459</id><published>2009-03-22T00:40:00.001-07:00</published><updated>2009-03-22T00:40:16.503-07:00</updated><title type='text'>Terminator Salvation – coming to cinemas May 21</title><content type='html'>&lt;p&gt;Ahh, the Terminator movie that we’ve always wanted – entirely set in the future, focusing on the war between man and machine.&amp;#160; I’ve always wondered when they would show the future they hinted at, a void slightly filled by the Terminator &lt;a href="http://en.wikipedia.org/wiki/Terminator:_The_Sarah_Connor_Chronicles"&gt;TV series (Sarah Connor Chronicles)&lt;/a&gt;.&amp;#160; Another point of note is that this coming instalment is but the beginning of a Terminator revival – part of a &lt;a href="http://en.wikipedia.org/wiki/Terminator_(franchise)#Planned_sequels"&gt;new trilogy&lt;/a&gt; apparently.&amp;#160; And you can’t go wrong with Christian Bale as John Connor.&lt;/p&gt;  &lt;p&gt;&lt;object width="480" height="295"&gt;&lt;param name="movie" value="http://www.youtube.com/v/I_hIIDEQY3w&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/I_hIIDEQY3w&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-9193497910446679459?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/9193497910446679459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=9193497910446679459' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/9193497910446679459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/9193497910446679459'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2009/03/terminator-salvation-coming-to-cinemas.html' title='Terminator Salvation – coming to cinemas May 21'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-5157890380171851327</id><published>2009-03-05T03:42:00.001-08:00</published><updated>2009-03-05T03:42:49.429-08:00</updated><title type='text'>Reading database tables in Powershell</title><content type='html'>&lt;p&gt;Firstly, a correction.&amp;#160; Last time I &lt;a href="http://sweetsyntacticsugar.blogspot.com/2009/02/select-distinct-in-excel-and-powershell.html"&gt;posted about Powershell&lt;/a&gt;, I came up with something that did the job, but was, well, a tat long winded.&amp;#160; Kind of like building a skyscraper so that you can store garden tools in the basement.&amp;#160; Basically I didn’t realise that the Sort cmdlet already had a –Unique switch.&amp;#160; Thanks to Stephen Mills for pointing it out:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier"&gt;import-csv c:\mydata.csv | select Category, Subcategory | sort category, subcategory -Unique | Group-Object -Property category&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Now to the business at hand – reading database tables.&amp;#160; Consider a situation where you’re asked to read in the data in a database table into some readable form, for reference, printing or whatnot.&amp;#160; Rather than using SQL Management Studio to query the results, selecting the entire results grid, copying it, pasting into Excel (if available on the same machine), or into a text file, then getting it into Excel – you could just use Powershell to connect to the DB and dump out the results into a HTML table.&amp;#160; Behold:&lt;/p&gt; &lt;!-- Stylesheet link --&gt;&lt;link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" type="text/css" rel="stylesheet" /&gt;&lt;!-- Code --&gt;  &lt;div class="dp-highlighter" id="hlDiv"&gt;   &lt;div class="bar"&gt;&lt;/div&gt;    &lt;ol class="dp-rb"&gt;     &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;# Parse Database tables&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&lt;span class="comment"&gt;# This will connect to a database, do a &amp;quot;select *&amp;quot; on a table or view, and produce a html file with the data in a table.&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;# Note: don't forget to loosen up your execution policy &amp;quot;Set-ExecutionPolicy Unrestricted&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&lt;span class="comment"&gt;# and the connection string is ADO style : &amp;quot;Data Source=database;Initial Catalog=oesc_offerman;User Id =username;Password=password;Trusted_Connection=False;&amp;quot;&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;param&lt;/span&gt;&lt;span&gt; (&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="variable"&gt;$connectionString&lt;/span&gt;&lt;span&gt; = $(throw &lt;/span&gt;&lt;span class="string"&gt;&amp;quot;Specify connection string&amp;quot;&lt;/span&gt;&lt;span&gt; ),&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&lt;span class="variable"&gt;$tableName&lt;/span&gt;&lt;span&gt; = $(throw &lt;/span&gt;&lt;span class="string"&gt;&amp;quot;Specify a table or view name&amp;quot;&lt;/span&gt;&lt;span&gt;),&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="variable"&gt;$outputPath&lt;/span&gt;&lt;span&gt; =&amp;#160; $(throw &lt;/span&gt;&lt;span class="string"&gt;&amp;quot;Specify output path&amp;quot;&lt;/span&gt;&lt;span&gt;)&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;)&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;echo (&lt;span class="string"&gt;&amp;quot;Processing &amp;quot;&lt;/span&gt;&lt;span&gt; + &lt;/span&gt;&lt;span class="variable"&gt;$tableName&lt;/span&gt;&lt;span&gt;)&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="variable"&gt;$table&lt;/span&gt;&lt;span&gt; = new-object System.Data.DataTable;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&lt;span class="variable"&gt;$sqlConn&lt;/span&gt;&lt;span&gt; = new-object System.Data.SqlClient.SqlConnection(&lt;/span&gt;&lt;span class="variable"&gt;$connectionString&lt;/span&gt;&lt;span&gt;);&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="variable"&gt;$sqlConn&lt;/span&gt;&lt;span&gt;.Open();&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&lt;span class="variable"&gt;$adapter&lt;/span&gt;&lt;span&gt; = new-object System.Data.SqlClient.SqlDataAdapter((&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;select * from &amp;quot;&lt;/span&gt;&lt;span&gt; +&lt;/span&gt;&lt;span class="variable"&gt;$tableName&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span class="variable"&gt;$sqlConn&lt;/span&gt;&lt;span&gt;);&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="variable"&gt;$adapter&lt;/span&gt;&lt;span&gt;.Fill(&lt;/span&gt;&lt;span class="variable"&gt;$table&lt;/span&gt;&lt;span&gt;);&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&lt;span class="variable"&gt;$sqlConn&lt;/span&gt;&lt;span&gt;.Close();&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="variable"&gt;$table&lt;/span&gt;&lt;span&gt;.Rows | &lt;/span&gt;&lt;span class="builtin"&gt;ConvertTo-Html&lt;/span&gt;&lt;span&gt; | out-file &lt;/span&gt;&lt;span class="variable"&gt;$outputPath&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;   &lt;/ol&gt; &lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-5157890380171851327?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/5157890380171851327/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=5157890380171851327' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/5157890380171851327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/5157890380171851327'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2009/03/reading-database-tables-in-powershell.html' title='Reading database tables in Powershell'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-8274033647939361973</id><published>2009-03-04T03:11:00.001-08:00</published><updated>2009-03-04T03:11:42.404-08:00</updated><title type='text'>Fish blimp</title><content type='html'>&lt;p&gt;Had to share this one – from a homemade airship competition, footage of a small blip that uses a tail fin for propulsion – it looks very graceful, especially for a blimp – sure it’s not encumbered, with no wind, but it’s still mesmerising to watch:&lt;/p&gt; &lt;object width="500" height="325"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=1968128&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=1968128&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="225"&gt;&lt;/embed&gt;&lt;/object&gt;  &lt;br /&gt;&lt;a href="http://vimeo.com/1968128"&gt;Air Art&lt;/a&gt; from &lt;a href="http://vimeo.com/user568554"&gt;flip&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.     &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-8274033647939361973?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/8274033647939361973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=8274033647939361973' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/8274033647939361973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/8274033647939361973'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2009/03/fish-blimp.html' title='Fish blimp'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-5515538132416929383</id><published>2009-02-21T18:33:00.001-08:00</published><updated>2009-02-21T18:33:04.819-08:00</updated><title type='text'>“SELECT DISTINCT” in Excel and Powershell</title><content type='html'>&lt;p&gt;Just recently at work we had to import a large dataset into a database, but two of the columns were “category” and “subcategory”.&amp;#160; Naturally we wanted these in a separate table, so we needed a way of parsing through the existing data and get the unique categories, and the unique matching subcategories for each.&lt;/p&gt;  &lt;h4&gt;Excel:&lt;/h4&gt;  &lt;p&gt;Firstly, there’s the Excel ‘07 way (most likely also possible in other versions too):&lt;/p&gt;  &lt;p&gt;Select the two columns that hold your categories and subcategories. Go to the “Advanced” menu item in Filtering:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_h7bul_inQ00/SaC5MhhD6UI/AAAAAAAAACE/9u-GkLFM9s4/s1600-h/image2.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="92" alt="image" src="http://lh4.ggpht.com/_h7bul_inQ00/SaC5NuItWGI/AAAAAAAAACI/ByJ78VOak1c/image_thumb.png?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The presented dialog has the option of “Unique Records Only”&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_h7bul_inQ00/SaC5Ou8CLJI/AAAAAAAAACM/W5z3tv-o2_s/s1600-h/image5.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="image" src="http://lh4.ggpht.com/_h7bul_inQ00/SaC5Ptm5O0I/AAAAAAAAACQ/zWuUjrb6Chs/image_thumb1.png?imgmax=800" width="235" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Done, it’s the equivalent of doing a “distinct” in SQL.&amp;#160; Now sort the data, and you’re ready to go.&lt;/p&gt;  &lt;h4&gt;Powershell:&lt;/h4&gt;  &lt;p&gt;But no discussion of parsing/manipulating data is complete without mentioning Powershell – surely we can do this in PS.&amp;#160; Let’s assume that the data was saved in csv form (you could always save your Excel spreadsheet as .csv).&lt;/p&gt;  &lt;p&gt;Luckily, there’s already a command that is able to parse csv’s for us: “Import-Csv”.&amp;#160; This cmdlet will parse the csv and create objects that have properties named after the columns – in the below image you can see that the object has a “Category” and “SubCategory” property.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_h7bul_inQ00/SaC5QhLh7KI/AAAAAAAAACU/RFF82GxhiNE/s1600-h/image%5B4%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="image" src="http://lh5.ggpht.com/_h7bul_inQ00/SaC5S2X9cPI/AAAAAAAAACY/pK_-iwMpS68/image_thumb%5B2%5D.png?imgmax=800" width="459" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now that we have this collection of objects, use your favourite way of flushing out duplicates.&amp;#160; I’m keen on building up a new list, checking on each insert that the same entry doesn’t exist:&lt;/p&gt; &lt;!-- Stylesheet link --&gt;&lt;link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" type="text/css" rel="stylesheet" /&gt;&lt;!-- Code --&gt;  &lt;div class="dp-highlighter" id="hlDiv" style="width: 73.75%; height: 236px"&gt;   &lt;div class="bar"&gt;&lt;/div&gt;    &lt;ol class="dp-rb"&gt;     &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="variable"&gt;$temp&lt;/span&gt;&lt;span&gt; = @{}&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&lt;span class="variable"&gt;$data&lt;/span&gt;&lt;span&gt; | &lt;/span&gt;&lt;span class="keyword"&gt;foreach&lt;/span&gt;&lt;span&gt; {&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="variable"&gt;$temp&lt;/span&gt;&lt;span&gt;.ContainsKey(&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.Category))&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&amp;#160;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="comment"&gt;#check if subcategory exists, insert subcategory if doesnt &lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="variable"&gt;$temp&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.Category].ContainsValue(&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.Subcategory) -eq &lt;/span&gt;&lt;span class="variable"&gt;$false&lt;/span&gt;&lt;span&gt;)&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&amp;#160;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="variable"&gt;$temp&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.Category].Add(&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.Subcategory, &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.Subcategory);&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&amp;#160;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span&gt;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; {&amp;#160;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="comment"&gt;#put it in: &lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="variable"&gt;$temp&lt;/span&gt;&lt;span&gt;.Add(&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.Category, @{&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.Subcategory = &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.Subcategory});&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;}&amp;#160; &lt;/span&gt;&lt;/li&gt;   &lt;/ol&gt; &lt;/div&gt;  &lt;p&gt;This is all well and good, but there are issues.&amp;#160; The &amp;quot;Category” property names are hardcoded, and it depends on an existing $data variable.&amp;#160; Ideally we want a cmdlet that can support piping, and will let us specify the names of the columns.&lt;/p&gt;  &lt;p&gt;Luckily for us, Powershell is able support the following constructs:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_h7bul_inQ00/SaC5TQugOcI/AAAAAAAAACc/hhsQSEAo3S8/s1600-h/image%5B13%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="109" alt="image" src="http://lh3.ggpht.com/_h7bul_inQ00/SaC5VEgSfwI/AAAAAAAAACg/mdCaL2htq1c/image_thumb%5B7%5D.png?imgmax=800" width="368" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;What happened there is by putting the variable in brackets, PS will evaluate the variable and put it in the script.&amp;#160; I was able to create a variable &lt;em&gt;$somestring&lt;/em&gt;, which had a string value of “Subcategory”.&amp;#160; When I used it in brackets, it expanded out to “Subcategory” in the script, and functioned in the same way as $data[2].Subcategory.&amp;#160; Neat.&amp;#160; This is an invaluable feature in scripting.&lt;/p&gt;  &lt;p&gt;So we replacing all places where we previously had “Category” and “Subcategory” with expansions, and add them as required parameters. &lt;/p&gt;  &lt;p&gt;Last thing, we need to get rid of the assumption of pre-existing $data variable.&amp;#160; Ideally the input will be piped in.&amp;#160; No problem, the reserved &lt;em&gt;$input&lt;/em&gt; variable is the piped in parameters.&lt;/p&gt;  &lt;p&gt;So now we can call it like so:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier"&gt;import-csv c:\MyTest.csv | c:\categoryParser.ps1 &amp;quot;Category&amp;quot; &amp;quot;Subcategory&amp;quot;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The final script looks like this:&lt;/p&gt; &lt;!-- Stylesheet link --&gt;&lt;link href="http://www.thecomplex.plus.com/styles/SyntaxHighlighter.css" type="text/css" rel="stylesheet" /&gt;&lt;!-- Code --&gt;  &lt;div class="dp-highlighter" id="hlDiv" style="width: 88.26%; height: 371px"&gt;   &lt;div class="bar"&gt;&lt;/div&gt;    &lt;ol class="dp-rb"&gt;     &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;param&lt;/span&gt;&lt;span&gt; (&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&lt;span class="variable"&gt;$categoryName&lt;/span&gt;&lt;span&gt; = $(throw &lt;/span&gt;&lt;span class="string"&gt;&amp;quot;Specify category column name&amp;quot;&lt;/span&gt;&lt;span&gt; ),&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="variable"&gt;$subcategoryName&lt;/span&gt;&lt;span&gt; = $(throw &lt;/span&gt;&lt;span class="string"&gt;&amp;quot;specify subcategory name&amp;quot;&lt;/span&gt;&lt;span&gt;)&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;)&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&lt;span class="variable"&gt;$temp&lt;/span&gt;&lt;span&gt; = @{}&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="variable"&gt;$input&lt;/span&gt;&lt;span&gt; | &lt;/span&gt;&lt;span class="keyword"&gt;foreach&lt;/span&gt;&lt;span&gt; {&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="variable"&gt;$temp&lt;/span&gt;&lt;span&gt;.ContainsKey(&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.(&lt;/span&gt;&lt;span class="variable"&gt;$categoryName&lt;/span&gt;&lt;span&gt;)))&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; {&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="comment"&gt;#check if subcategory exists, insert subcategory if doesnt&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class="variable"&gt;$temp&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.(&lt;/span&gt;&lt;span class="variable"&gt;$categoryName&lt;/span&gt;&lt;span&gt;)].ContainsValue(&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.(&lt;/span&gt;&lt;span class="variable"&gt;$subcategoryName&lt;/span&gt;&lt;span&gt;)) -eq &lt;/span&gt;&lt;span class="variable"&gt;$false&lt;/span&gt;&lt;span&gt;)&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="variable"&gt;$temp&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.(&lt;/span&gt;&lt;span class="variable"&gt;$categoryName&lt;/span&gt;&lt;span&gt;)].Add(&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.(&lt;/span&gt;&lt;span class="variable"&gt;$subcategoryName&lt;/span&gt;&lt;span&gt;), &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.(&lt;/span&gt;&lt;span class="variable"&gt;$subcategoryName&lt;/span&gt;&lt;span&gt;));&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; {&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="comment"&gt;#put it in:&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="variable"&gt;$temp&lt;/span&gt;&lt;span&gt;.Add(&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.(&lt;/span&gt;&lt;span class="variable"&gt;$categoryName&lt;/span&gt;&lt;span&gt;), @{&lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.(&lt;/span&gt;&lt;span class="variable"&gt;$subcategoryName&lt;/span&gt;&lt;span&gt;) = &lt;/span&gt;&lt;span class="variable"&gt;$_&lt;/span&gt;&lt;span&gt;.(&lt;/span&gt;&lt;span class="variable"&gt;$subcategoryName&lt;/span&gt;&lt;span&gt;)});&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;}&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;      &lt;li class=""&gt;&lt;span&gt;&lt;span class="comment"&gt;#dump out the output&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="variable"&gt;$temp&lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;   &lt;/ol&gt; &lt;/div&gt;  &lt;p&gt;And produces something like this, a hashtable of objects each of which has the category name, and a hashtable of subcategories.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_h7bul_inQ00/SaC5V95G15I/AAAAAAAAACk/2vYjM6CrFO8/s1600-h/image%5B17%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="142" alt="image" src="http://lh4.ggpht.com/_h7bul_inQ00/SaC5XH8TiwI/AAAAAAAAACo/838pJjvfTOM/image_thumb%5B9%5D.png?imgmax=800" width="500" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;From here it would be easy to traverse them all with two nested foreach loops, and do whatever with them, like generating INSERT statements.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-5515538132416929383?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/5515538132416929383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=5515538132416929383' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/5515538132416929383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/5515538132416929383'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2009/02/select-distinct-in-excel-and-powershell.html' title='“SELECT DISTINCT” in Excel and Powershell'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_h7bul_inQ00/SaC5NuItWGI/AAAAAAAAACI/ByJ78VOak1c/s72-c/image_thumb.png?imgmax=800' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-7063627451708989330</id><published>2009-02-06T18:22:00.001-08:00</published><updated>2009-02-06T18:22:23.543-08:00</updated><title type='text'>Minotaur in a China Shop</title><content type='html'>&lt;p&gt;I have a soft spot for independent games – possibly the last bastion of innovation in computer gaming.&amp;#160; Came across a very amusing little independent game, about a Minotaur running a fine china shop.&amp;#160; The game is 3D, isometric perspective.&amp;#160; Runs in the browser.&amp;#160; The minotaur isn’t exactly light on his feet, and handles like fridge - thus there are two ways to win – trash your own shop to get an insurance payoff, or service customers.&amp;#160; Give it a go – most amusing.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blurst.com/minotaur-china-shop/play"&gt;http://blurst.com/minotaur-china-shop/play&lt;/a&gt;&lt;/p&gt; &lt;object width="400" height="225"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=2474951&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=2474951&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="225"&gt;&lt;/embed&gt;&lt;/object&gt;  &lt;br /&gt;&lt;a href="http://vimeo.com/2474951"&gt;Minotaur China Shop Trailer&lt;/a&gt; from &lt;a href="http://vimeo.com/blurst"&gt;Flashbang Studios&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.     &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-7063627451708989330?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/7063627451708989330/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=7063627451708989330' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/7063627451708989330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/7063627451708989330'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2009/02/minotaur-in-china-shop.html' title='Minotaur in a China Shop'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-1697930764851741864</id><published>2009-01-31T21:55:00.001-08:00</published><updated>2009-01-31T21:55:02.765-08:00</updated><title type='text'>On Precision</title><content type='html'>&lt;p&gt;Do YOU know your car’s height down to the millimetre?&amp;#160; You’d better…&lt;/p&gt;  &lt;p&gt;Saw this in Southbank:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_h7bul_inQ00/SYU5MC7YfZI/AAAAAAAAAB8/6JMyVh0uQu4/s1600-h/maxheight%5B4%5D.jpg"&gt;&lt;img title="maxheight" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="353" alt="maxheight" src="http://lh5.ggpht.com/_h7bul_inQ00/SYU5NUoSStI/AAAAAAAAACA/_P-iVl6O1Tc/maxheight_thumb%5B2%5D.jpg?imgmax=800" width="460" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-1697930764851741864?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/1697930764851741864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=1697930764851741864' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/1697930764851741864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/1697930764851741864'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2009/01/on-precision.html' title='On Precision'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_h7bul_inQ00/SYU5NUoSStI/AAAAAAAAACA/_P-iVl6O1Tc/s72-c/maxheight_thumb%5B2%5D.jpg?imgmax=800' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-592058867846904213</id><published>2009-01-29T01:21:00.001-08:00</published><updated>2009-01-29T01:21:44.218-08:00</updated><title type='text'>Blade Runner 2, Brave New World, Forever War – coming to a cinema near you… umm.. soon…</title><content type='html'>&lt;p&gt;In case you missed it, Slashdot had coverage of the fact that a &lt;em&gt;Blade Runner&lt;/em&gt; sequel may be in the works, as would a film based on &lt;a href="http://en.wikipedia.org/wiki/Brave_New_World"&gt;Brave New World&lt;/a&gt; (by Aldous Huxley), and &lt;a href="http://en.wikipedia.org/wiki/The_Forever_War"&gt;Forever War&lt;/a&gt; (by Joe Haldeman). &lt;/p&gt;  &lt;p&gt;&lt;em&gt;Brave New World&lt;/em&gt; didn’t really do much for me, but &lt;em&gt;Forever War&lt;/em&gt;, if properly done, could be the serious sci-fi movie people have been waiting for – they seem a bit thin on the ground these days.&amp;#160; More importantly, all this is supposedly to be directed by Ridley Scott (director of Blade Runner, Alien, Gladiator and Black Hawk Down among others).&amp;#160; Apparently he’s secured the rights to &lt;em&gt;Forever War&lt;/em&gt;, and is now looking for a script. &lt;/p&gt;  &lt;p&gt;Read all about it: &lt;a title="http://entertainment.slashdot.org/article.pl?sid=09%2F01%2F28%2F1355238&amp;amp;from=rss" href="http://entertainment.slashdot.org/article.pl?sid=09%2F01%2F28%2F1355238&amp;amp;from=rss"&gt;http://entertainment.slashdot.org/article.pl?sid=09%2F01%2F28%2F1355238&amp;amp;from=rss&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-592058867846904213?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/592058867846904213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=592058867846904213' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/592058867846904213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/592058867846904213'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2009/01/blade-runner-2-brave-new-world-forever.html' title='Blade Runner 2, Brave New World, Forever War – coming to a cinema near you… umm.. soon…'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-7280309152815075081</id><published>2009-01-27T04:47:00.001-08:00</published><updated>2009-01-27T04:47:28.332-08:00</updated><title type='text'>Chernoff Faces and Data Visualization</title><content type='html'>&lt;p&gt;While we might have a good feel for what makes a good UI, few of us give much thought to the niche are of data visualization.&amp;#160; Too often we’re content to present users with drab boring datagrids and lists.&amp;#160; While on one side there is the issue of familiarity (everyone has seen tables), the usability of grids for slicing and dicing data is limited at best.&amp;#160; Filtered columns, sorted columns can only get you so far, and certainly don’t provide you with a “feel” for the data.&lt;/p&gt;  &lt;p&gt;Having just finished reading &lt;a href="http://en.wikipedia.org/wiki/Blindsight_(science_fiction_novel)"&gt;Blindsight&lt;/a&gt; by Peter Watts (freely available &lt;a href="http://www.rifters.com/real/Blindsight.htm"&gt;online&lt;/a&gt; – not too bad, with an interesting central idea looking at the potential for self-awareness to be unnecessary for intelligence), one of the characters makes use of &lt;a href="http://en.wikipedia.org/wiki/Chernoff_face"&gt;Chernoff faces&lt;/a&gt; to visualise data.&lt;/p&gt;  &lt;p&gt;Chernoff faces are an attempt to make use of the special brain circuitry that we have for recognizing faces in the context of data visualization.&amp;#160; The idea is to present the user with a field of stylized faces, associate a specific data dimension to a facial feature, and let the brain do the rest.&amp;#160; The below example maps data onto a real geographical space, but that is not strictly speaking necessary, the map could have been a set of two dimensional data of more abstract nature.&amp;#160; Using the following key to map facial features:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_h7bul_inQ00/SX8B_dE_DFI/AAAAAAAAABk/A3aipzSzLlo/s1600-h/image8.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="293" alt="image" src="http://lh4.ggpht.com/_h7bul_inQ00/SX8CA_YJHXI/AAAAAAAAABo/Ja-izW5iSuI/image_thumb3.png?imgmax=800" width="392" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;You can for example sweep your eye across the map looking for all the “big eared” faces to give an idea of crime rate.&amp;#160; Or you could look for “frowning faces with big ears” (which would map to high unemployment and high crime rate).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_h7bul_inQ00/SX8CJhXh_0I/AAAAAAAAABs/S80wUY39pPY/s1600-h/image4.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="314" alt="image" src="http://lh3.ggpht.com/_h7bul_inQ00/SX8CRNSD93I/AAAAAAAAABw/TMu0_OxxcYE/image_thumb1.png?imgmax=800" width="438" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;(image from &lt;a title="http://gis.esri.com/library/userconf/educ04/papers/pap5000.pdf" href="http://gis.esri.com/library/userconf/educ04/papers/pap5000.pdf"&gt;http://gis.esri.com/library/userconf/educ04/papers/pap5000.pdf&lt;/a&gt;)&lt;/p&gt;  &lt;p&gt;(for another interesting example, go to &lt;a title="http://kspark.kaist.ac.kr/Human%20Engineering.files/Chernoff/Chernoff%20Faces.htm" href="http://kspark.kaist.ac.kr/Human%20Engineering.files/Chernoff/Chernoff%20Faces.htm"&gt;http://kspark.kaist.ac.kr/Human%20Engineering.files/Chernoff/Chernoff%20Faces.htm&lt;/a&gt;)&lt;/p&gt;  &lt;p&gt;While not bad on paper, it appears the applications are quite limited, and the data still doesn’t “jump out” at you, as well as the difficult issue of non-intuitiveness when dealing with abstract data sets (what facial feature should be “average sales”?).&amp;#160; Your mileage may vary – it still seems quite good at performing visual searches for specific patterns (for example consider the lot of faces with brown skin and short hair – higher percentage of collage graduates, but with lower incomes – what gives?) .&lt;/p&gt;  &lt;p&gt;Regardless, this is but one attempt at visualizing data in a non-tabular way.&amp;#160; There are other stabs at doing this, some which even add motion to the visualization to suggest another data dimension.&amp;#160; Consider “&lt;a href="http://carohorn.de/anymails"&gt;Anymails&lt;/a&gt;” where email is visualized as various critters moving around in the visual space – older email moves more slowly, and various characteristics of the email are encoded into the shape/color of the insects:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_h7bul_inQ00/SX8CV7ydFwI/AAAAAAAAAB0/imBPyqJ2ePM/s1600-h/image8%5B1%5D.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="338" alt="image" src="http://lh6.ggpht.com/_h7bul_inQ00/SX8CXSahPxI/AAAAAAAAAB4/0uW0clrvKPQ/image_thumb4.png?imgmax=800" width="442" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;(from &lt;a title="http://carohorn.de/anymails/" href="http://carohorn.de/anymails/"&gt;http://carohorn.de/anymails/&lt;/a&gt;, there’s also a video of the application in action there, I believe)&lt;/p&gt;  &lt;p&gt;Why am I bringing this up? Well it’s all to do with with the trend we’re seeing in UI technologies.&amp;#160; Silverlight and WPF are both platforms in which animation and custom drawing are readily available, giving the freedom to easily create “compelling” user interfaces that may give us the ability present data in a more intuitive way, as well as interaction options that would have been too “expensive” to create in the past.&amp;#160; This will require more focus on what the users are trying to achieve as opposed to regurgitating the same dropdowns and text-boxes.&amp;#160; It will take years for this trend to develop, as the area appears to be largely unexplored in mainstream software design, and would be classified as risky.&amp;#160; &lt;/p&gt;  &lt;p&gt;Regardless, creative thought in software engineering is back, and we should use the flexibility of SL and WPF to bring users the UIs that will give them truly better productivity, not just proxies of paper-based processes – Minority Report UI here we come!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-7280309152815075081?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/7280309152815075081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=7280309152815075081' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/7280309152815075081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/7280309152815075081'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2009/01/chernoff-faces-and-data-visualization.html' title='Chernoff Faces and Data Visualization'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_h7bul_inQ00/SX8CA_YJHXI/AAAAAAAAABo/Ja-izW5iSuI/s72-c/image_thumb3.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-5124411725738890559</id><published>2009-01-25T17:35:00.001-08:00</published><updated>2009-01-25T17:35:48.863-08:00</updated><title type='text'>Functionality vs Prettiness</title><content type='html'>&lt;p&gt;Although I’ve traditionally been a proponent of Windows Mobile as a platform for pocket devices, the arrival of the iPhone certainly shakes the foundations of that conviction.&amp;#160; Watching now the rapid spread of the iPhone I wonder at how something like that could become so popular.&amp;#160; After all, PDA devices that mixed the PDA functionality with a phone are nothing new.&amp;#160; Consider the O2 XDA range for example, which has been out for years.&amp;#160; Nor is the tilt sensor anything unique – Nokia N95 had done it earlier.&amp;#160; GPS – others had it.&amp;#160; We can argue that it was all these features finally have come together in one reasonable package, and we’d be right.&amp;#160; Mostly.&amp;#160; There is however another feature that I think cuts to the bottom of the iPhone sales mystery – the UI.&amp;#160; Apple recognises that great functionality only gets you so far – the average user is a sucker for a pretty UI.&amp;#160; The iPhone is simply a pleasure to look at and operate. Everything from the sliding menus to the gradient background screams “luxury”.&lt;/p&gt;  &lt;p&gt;For a lark, consider a unit/currency conversion application. Let’s ignore multi-touch, GPS and tilt sensors&amp;#160; Here’s a screenshot of an existing iPhone app that does this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_h7bul_inQ00/SX0TXZ04YZI/AAAAAAAAABU/Zh40JvvBYes/s1600-h/image4.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="362" alt="image" src="http://lh5.ggpht.com/_h7bul_inQ00/SX0TY_3MXGI/AAAAAAAAABY/-znMHHCIPp4/image_thumb2.png?imgmax=800" width="271" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And here’s the same functionality, mocked up in a Windows Mobile 5 emulator under Visual Studio 2008, using the Compact Framework:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_h7bul_inQ00/SX0TZoXC0iI/AAAAAAAAABc/B8BwqxSs2Y4/s1600-h/image%5B9%5D.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="361" alt="image" src="http://lh6.ggpht.com/_h7bul_inQ00/SX0TbSpjl_I/AAAAAAAAABg/KI4iuGP5vAo/image_thumb%5B6%5D.png?imgmax=800" width="274" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Sure, I could have made custom controls to beautify the thing, but the point is how far one could get with mostly out of the box tools, and there is no contest.&amp;#160; I’d buy the mobile that gives me the great looking UI, given the same functionality.&amp;#160; In fact I suspect a lot of people will take a hit on functionality for the sake of snazzy UI.&amp;#160; This is one of the reasons Silverlight on Windows Mobile is a big deal, and I look forward to it in “Q1 of 2009”.&amp;#160; No doubt MS will be playing catch-up to Apple for a few years.&lt;/p&gt;  &lt;p&gt;PS: I don’t actually own an iPhone, the above is strictly based on short impressions, however I’d argue that a lot of purchasing decisions are made that way, for the majority of the shopping populace.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-5124411725738890559?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/5124411725738890559/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=5124411725738890559' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/5124411725738890559'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/5124411725738890559'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2009/01/functionality-vs-prettiness.html' title='Functionality vs Prettiness'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_h7bul_inQ00/SX0TY_3MXGI/AAAAAAAAABY/-znMHHCIPp4/s72-c/image_thumb2.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3169664517236002327.post-5330358354390494738</id><published>2009-01-06T04:09:00.001-08:00</published><updated>2009-01-06T04:09:02.598-08:00</updated><title type='text'>Silverlight 2 for mobile devices</title><content type='html'>&lt;p&gt;Just finished watching a presentation from PDC2008, and apparently Silverlight 2 will be available as a tech preview on the mobile in the first quarter of 2009.&amp;#160; This is the first time I’ve heard of SL2 being released for mobile.&amp;#160; Previous announcements have centered around SL1, not version 2.&amp;#160; Version 2 was previously discussed as a distant Alpha, with no indication of timelines.&amp;#160; Silverlight 1 always seemed like a sad excuse for a framework, so I can’t say I was looking forward to a mobile release.&amp;#160; But the release of SL2 will finally give us the ability to design Iphone looking applications for the mobile. &lt;/p&gt;  &lt;p&gt;As expected, designing will be available from Blend as well as from Visual Studio.&amp;#160; According to the demo, the development experience will be very similar.&lt;/p&gt;  &lt;p&gt;See session PC10 for the announcement. (&lt;a title="http://channel9.msdn.com/pdc2008/PC10/" href="http://channel9.msdn.com/pdc2008/PC10/"&gt;http://channel9.msdn.com/pdc2008/PC10/&lt;/a&gt;)&lt;/p&gt;  &lt;p&gt;Performance will of course be an interesting issue, as will the experience on a non touch enabled phone, eg Smartphone.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3169664517236002327-5330358354390494738?l=sweetsyntacticsugar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sweetsyntacticsugar.blogspot.com/feeds/5330358354390494738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3169664517236002327&amp;postID=5330358354390494738' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/5330358354390494738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3169664517236002327/posts/default/5330358354390494738'/><link rel='alternate' type='text/html' href='http://sweetsyntacticsugar.blogspot.com/2009/01/silverlight-2-for-mobile-devices.html' title='Silverlight 2 for mobile devices'/><author><name>Ilya</name><uri>http://www.blogger.com/profile/08685551691203936819</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
