<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-5375156058364096448</atom:id><lastBuildDate>Mon, 28 Nov 2011 01:22:11 +0000</lastBuildDate><category>linux</category><category>Haskell</category><category>Python</category><category>design architecture</category><category>Vim</category><category>Resolver</category><category>lifehack</category><category>debugging</category><category>twitter</category><category>zshell</category><category>Conference</category><category>Nemerle</category><category>.net</category><category>mono</category><category>testing</category><category>IronPython</category><category>extremeprogramming</category><category>bash</category><category>review</category><category>xmonad</category><category>neat</category><title>Programmer's Weblog</title><description /><link>http://blog.kamil.dworakowski.name/</link><managingEditor>noreply@blogger.com (Kamil Dworakowski)</managingEditor><generator>Blogger</generator><openSearch:totalResults>52</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ProgrammersWeblog" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="programmersweblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-3866338411849439776</guid><pubDate>Thu, 13 Jan 2011 01:09:00 +0000</pubDate><atom:updated>2011-01-13T01:14:00.767Z</atom:updated><title>pinfruit - my mnemonic web app for memorizing numbers</title><description>&lt;p&gt;
I have created a web app to memorize numbers. It implements the &lt;a href="http://en.wikipedia.org/wiki/Mnemonic_major_system"&gt;mnemonic major system&lt;/a&gt;.
The system works on the principle that it is easier to remember words/sentences/stories than numbers. The web app facilitates
finding sequences of words that encode a number in the mentioned system. I called the app &lt;a href="http://pinfruit.com/"&gt;pinfruit&lt;/a&gt;.

&lt;/p&gt;&lt;p&gt; My first take on implementing the system was incorrect. I simply
associated digits to letters. According to wikipedia the mnemonic major
system assigns digits to sounds, rather then the letters of the alphabet.
And rightly so, I immediately noticed that it is easier to work with sound associations.

&lt;/p&gt;&lt;p&gt;
My mistake originated in that I
first learned the technique in Poland, and in Polish it does not
matter if you assign digits to letters or sounds because both correspond.
Unfortunately, in English this is not the case, the major difficulty in
learning the language.

&lt;/p&gt;&lt;p&gt;
I have used &lt;a href="http://pinfruit.com/"&gt;pinfruit&lt;/a&gt; to memorize mainly pins
and phone numbers, but also bank site's user identifiers, which often
come as numbers.

&lt;/p&gt;&lt;p&gt; The trick is to create a memorable (vivid or absurd) sentence/story for a number. My old
phone number: 07514590312, can be encoded with &lt;i&gt;husky leader leaps midway Hanoi&lt;/i&gt;,
&lt;i&gt;school weather helps Madonna&lt;/i&gt; or &lt;i&gt;sickly water leaps hometown&lt;/i&gt;.
I refer you to the &lt;a href="http://en.wikipedia.org/wiki/Mnemonic_major_system"&gt;wikipedia article&lt;/a&gt;
for the detailed description of the system.

&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-3866338411849439776?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/WSYDIJHwihU" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2011/01/pinfruit-my-mnemonic-web-app-for.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-4128785416047103635</guid><pubDate>Sun, 15 Aug 2010 20:41:00 +0000</pubDate><atom:updated>2010-08-15T22:05:11.576+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">design architecture</category><title>From layers to hexagonal architecture</title><description>&lt;p&gt;
The traditional layered architecture consists of data, domain and presentation
layers.
&lt;p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href=""http://2.bp.blogspot.com/_qxRRyN-iKdo/TGhRPwSozhI/AAAAAAAAABo/stp-NACaUZo/s1600/tiers.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 260px; height: 400px;" src="http://2.bp.blogspot.com/_qxRRyN-iKdo/TGhRPwSozhI/AAAAAAAAABo/stp-NACaUZo/s400/tiers.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5505739875563392530" /&gt; &lt;/a&gt;

&lt;p&gt;
 Separating the presentation layer from the domain layer is rather
easy. The presentation layer objects query the domain for data to display
on the screen. The persistence layer is another story. The fact that it
appears below the domain layer prohibits any of the classes in it knowing
about the domain entities.
&lt;p&gt;
But consider a Fetcher class for example, a class that has responsibility for querying
some domain object from the database. It has the domain type in the signature
and thus has to be defined in or above the domain layer. This is
leaking of the data access object out of the persistence layer.

&lt;p&gt;
This problem has been recognized and here we have an architecture which
works around it by separating out the domain objects package. But the result
is not as clear and compelling as the layered architecture.
&lt;p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_qxRRyN-iKdo/TGhRbJM2oYI/AAAAAAAAABw/in7Ym8I7kOs/s1600/LayeredArchitecture.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 252px;" src="http://1.bp.blogspot.com/_qxRRyN-iKdo/TGhRbJM2oYI/AAAAAAAAABw/in7Ym8I7kOs/s400/LayeredArchitecture.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5505740071228580226" /&gt;&lt;/a&gt;

&lt;p&gt;
The civilisation progressed and an architecture with nothing below the domain model
has been discovered. One can see this in the &lt;a href="http://dddsample.sourceforge.net/"&gt;ddd sample&lt;/a&gt;.
&lt;p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_qxRRyN-iKdo/TGhRh9tpFHI/AAAAAAAAAB4/KrStaTEB-lI/s1600/ddd.jpe"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://3.bp.blogspot.com/_qxRRyN-iKdo/TGhRh9tpFHI/AAAAAAAAAB4/KrStaTEB-lI/s400/ddd.jpe" border="0" alt=""id="BLOGGER_PHOTO_ID_5505740188403962994" /&gt;&lt;/a&gt;
&lt;p&gt;
The persistence concern is implemented as part of the infrastructure layer. Infrastructure
is that vertical layer that depends on the three other layers. Domain knows nothing about the
infrastructure.

&lt;p&gt;
Another example is the &lt;a href="http://alistair.cockburn.us/Hexagonal+architecture"&gt;Hexagonal Architecture&lt;/a&gt;.

&lt;p&gt;


&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_qxRRyN-iKdo/TGhRnEIaqxI/AAAAAAAAACA/4Le84Pj-8iw/s1600/hexagon.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 358px; height: 239px;" src="http://1.bp.blogspot.com/_qxRRyN-iKdo/TGhRnEIaqxI/AAAAAAAAACA/4Le84Pj-8iw/s400/hexagon.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5505740276026223378" /&gt;&lt;/a&gt;
&lt;p&gt;
The domain sits in the core of the application, with the persistence aspect implemented by an adapter.
The adapter layer corresponds to the infrastructure and the interfaces layer combined from the ddd sample architecture diagram.
The important part is that the domain does not depend on anything else.



&lt;p&gt;
Such layering is achieved by defining service interfaces in the domain layer for persistence purposes. These abstract
interfaces are implemented by the adapters in the outer layer of the application and injected into the
objects that need them.


&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_qxRRyN-iKdo/TGhRtKlrOOI/AAAAAAAAACI/QTOiMsXqSJc/s1600/enhances-diagram.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://2.bp.blogspot.com/_qxRRyN-iKdo/TGhRtKlrOOI/AAAAAAAAACI/QTOiMsXqSJc/s400/enhances-diagram.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5505740380838770914" /&gt;&lt;/a&gt;

&lt;p&gt;
As a result nothing in the domain layer needs to import anything from the hibernate package, or whatever
persistence technology is being used. The domain layer has a custom made, abstract interface to persistence
service, in its own terms. The domain code can be expressed without the details of the persistence technology being used.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-4128785416047103635?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/O1Kpuf-lVRg" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2010/08/from-layers-to-hexagon-architecture.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_qxRRyN-iKdo/TGhRPwSozhI/AAAAAAAAABo/stp-NACaUZo/s72-c/tiers.png" height="72" width="72" /><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-3145171950951608168</guid><pubDate>Sat, 27 Mar 2010 12:53:00 +0000</pubDate><atom:updated>2010-03-28T12:06:05.552+01:00</atom:updated><title>GOOS Book</title><description>&lt;p&gt;
&lt;a href="http://www.growing-object-oriented-software.com/"&gt;
&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 240px; height: 319px;" src="http://2.bp.blogspot.com/_qxRRyN-iKdo/S63_8yIjD7I/AAAAAAAAAA8/nUxiJ7F-h9M/s400/goos.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5453296143530397618" /&gt;&lt;/a&gt;

&lt;a href="http://www.growing-object-oriented-software.com/"&gt;
 Growing Object-Oriented Software, Guided by Tests&lt;/a&gt; by
Steve Freeman and Nat Pryce is a book I was long waiting for. GOOS demonstrates the techniques and highlights the
patterns as they show up in an application grown through the book. An albeit
small but a real world project is being developed from scratch in a way were
tests play as important a role as object-oriented design.

&lt;p&gt; It is an excellent opportunity to see how two skilled developers are
growing application. The authors work in TDD in a style characterised by
extensive mocking to avoid breaking encapsulation. In design they use fine
grain classes. All together the style demonstrated in the book is very
consistent.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-3145171950951608168?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/sLQSr0TLTbk" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2010/03/goos-book.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_qxRRyN-iKdo/S63_8yIjD7I/AAAAAAAAAA8/nUxiJ7F-h9M/s72-c/goos.jpg" height="72" width="72" /><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-8878604847749365133</guid><pubDate>Sun, 07 Feb 2010 18:03:00 +0000</pubDate><atom:updated>2010-02-07T18:07:03.664Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">IronPython</category><title>IronPython Dictionaries Memory Cost</title><description>&lt;p&gt; Maintaining a mapping as a dictionary can be quite expensive in terms of
memory, more than one would expect. A couple of days ago I have checked with
windbg how much a single entry in a dictionary mapping pairs to ints
costs. The code I measured is:

&lt;pre&gt;
d = {(1, 2): 3}
&lt;/pre&gt;

&lt;p&gt;
I have executed it in IronPython 2.6.

&lt;p&gt;
The graph below depicts what I saw on the heap. Each box
represents a single word in memory. In a 32 bit system,
a word is 4 bytes.

&lt;p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_qxRRyN-iKdo/S28BDre5yxI/AAAAAAAAAA0/1Phz5vat4WU/s1600-h/oo.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 258px;" src="http://1.bp.blogspot.com/_qxRRyN-iKdo/S28BDre5yxI/AAAAAAAAAA0/1Phz5vat4WU/s400/oo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5435564437983054610" /&gt;&lt;/a&gt;

&lt;p&gt;
Every object in .NET runtime has an overhead of two words. These are the pointer
to its class and some house-keeping data, which I don't know much
about. Allegedly some part of it is used for object locking.

&lt;p&gt; The graph shows objects below buckets array, these are the only that
count. A dictionary is a hashtable which is implemented with an array of
buckets. Each item in the dictionary is kept in a bucket. The size of
the Bucket object determines the size of an entry in the dictionary.

&lt;p&gt;
There are 23 boxes in the Bucket's subtree, which means its size is 23 * 4 = 92 bytes.
Quite a lot. A million numbers in that dictionary would take almost 100 megabytes!

&lt;p&gt; The main reason it comes out as that many is the generality of the
dictionary. The fact that it can store objects of arbitrary types means
that the numbers must be boxed. .NET generic collections, when specialized
for ints, would store numbers in place saving a lot of space.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-8878604847749365133?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/G5DkTFLOMQ4" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2010/02/ironpython-dictionaries-memory-cost.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_qxRRyN-iKdo/S28BDre5yxI/AAAAAAAAAA0/1Phz5vat4WU/s72-c/oo.png" height="72" width="72" /><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-2573114976060279467</guid><pubDate>Sun, 13 Sep 2009 12:27:00 +0000</pubDate><atom:updated>2009-09-13T13:31:08.689+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Vim</category><title>Unobtrusive highlighting of trailing whitespace in Vim</title><description>&lt;p&gt; Many programmers highlight trailing whitespace red to expose that unnecessary
gunk that is otherwise hard to spot. I did not much care about trailing whitespace, it
was never a problem for me, though now the distributed version control systems
tend to complain about this.

&lt;p&gt; Highlighting the trailing whitespace is effective but has this unwanted
side-effect of a red thing appearing under the cursor when typing space at the end
of line (most of the time I type space at the end of line it seems).

&lt;p&gt;This set of commands will only highlight the trailing whitespace on
opening the buffer and leaving the insert mode. Inspired by the
Vim tip wiki.

&lt;p&gt;
&lt;pre&gt;
highlight ExtraWhitespace ctermbg=red guibg=red
au ColorScheme * highlight ExtraWhitespace guibg=red
au BufEnter * match ExtraWhitespace /\s\+$/
au InsertEnter * match ExtraWhitespace /\s\+\%#\@&amp;lt;!$/
au InsertLeave * match ExtraWhiteSpace /\s\+$/
&lt;/pre&gt;

&lt;p&gt; Some notes: ctermbg=red is for vim, guibg is for gvim. The second line
is to prevent any color scheme to override the highlight settings.

&lt;p&gt;OK, that feels better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-2573114976060279467?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/8qHFHwFC1xY" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2009/09/unobtrusive-highlighting-of-trailing.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-3087147706731832945</guid><pubDate>Tue, 09 Jun 2009 13:21:00 +0000</pubDate><atom:updated>2009-06-09T14:23:55.583+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">extremeprogramming</category><title>Extreme programming too extreme?</title><description>&lt;p&gt; Is extreme programming as a methodology over? Has Kent Beck 
&lt;a href='http://www.threeriversinstitute.org/blog/?p=187' target='_blank'&gt;killed it himself&lt;/a&gt;? Until
now he insisted that you not write a single line of code without a failing
test. He was talking about his daughter who allegedly can not even imagine
writing code without tests first (in his book about test driven development)!

&lt;p&gt; Extreme programming is a set of good practices but the
problem is the emphasis on taking them to the extreme thus ignoring
the cost/benefit ratio. There is an obvious trade-off here.

&lt;p&gt; It would be optimal if people wrote just the right amount of tests,
not too little and not too much, to maximise the ROI. That of
course is very hard to judge, but for sure the answer is
not 100% coverage in all cases, as Kent kindly observes in his post.

&lt;p&gt;Extreme programming is flawed as a methodology, but I want
to argue that it is good for learning the craft.

&lt;p&gt; People have natural inclinations for not testing, not integrating
continuously but programming a feature for days not syncing with the main code
base, underestimating features and than putting in long hours, etc. Extreme
programming is like a correction program for these unwholesome inclinations. :)

&lt;p&gt; Aristotle noted in the Nicomachean Ethics that the best way to reach the
golden mean is to aim at the opposite extreme.

&lt;p&gt; In the dimension of testing, for example, people will naturally tend to
write too little tests, usually none. Practising extreme programming forces
us to go to other extreme: from none tests to 100% coverage no matter the
cost. This teaches that you can write tests you didn't previously
realized, but more importantly it changes the mindset of the programmer.  After
practising extreme programming you will find yourself uncomfortable without the safety net of 
tests, and while you will not necessarily want 100% coverage you will be in a much
better position to judge how much testing is really needed.

&lt;p&gt; I am glad that I was a part of an extreme programming team for
almost 2 years now. We might have been too extreme,
but too extreme in the good direction. 4:1 ratio of tests to code that
we have might be an overkill, but it is certainly better than no tests
at all. I feel similarly about other practices.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-3087147706731832945?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/hie8daKzCyo" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2009/06/extreme-programming-too-extreme.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-3582550727625251963</guid><pubDate>Fri, 22 May 2009 21:00:00 +0000</pubDate><atom:updated>2009-05-22T22:01:55.247+01:00</atom:updated><title>Applied computer science</title><description>&lt;p&gt; "Don't worry about people stealing an idea. If it's original, you will have
to ram it down their throats." It looks like one of those optimistic 
sentences that are supposed to lift spirits. And some people must believe
in it, I suppose, because otherwise it would not circulate.

&lt;p&gt; Each time I stumble upon it, it reminds me of NP problems. 

In general: finding a creative solution to a problem seems to me to
be a lot like finding a solution to an instance of a NP problem. 

&lt;P&gt;Just a
reminder, an NP problem is such for which there exists a nondeterministic Turing
machine solving it in polynomial time. Most people think that P!=NP, so
problems that are in NP and not in P require exponential time to solve, 
but just polynomial time to check if a solution is correct.

&lt;p&gt; So here, a whole class of problems, for all of which it is hard to find
a solution, but easy to see that a given solution is good. Boy was it worth
taking those computational complexity classes at the university ;).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-3582550727625251963?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/OAz8X1uj_XE" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2009/05/applied-computer-science.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-3882480286134185758</guid><pubDate>Sat, 16 May 2009 10:47:00 +0000</pubDate><atom:updated>2009-05-16T12:02:57.162+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">review</category><title>Sony PRS 505 ebook reader review</title><description>&lt;p&gt; I use Sony PRS 505 for more than a month now (see how it compares with
&lt;a href="http://wiki.mobileread.com/wiki/E-book_Reader_Matrix" target="_blank"&gt;other readers&lt;/a&gt;). It came with 100 classic
books, all of which look very tempting. I have already read
over 1000 pages of David Copperfield.

&lt;p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_qxRRyN-iKdo/Sg6auXkl91I/AAAAAAAAAAM/azf49dUxVqs/s1600-h/sony-reader.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 280px;" src="http://3.bp.blogspot.com/_qxRRyN-iKdo/Sg6auXkl91I/AAAAAAAAAAM/azf49dUxVqs/s400/sony-reader.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5336372729872774994" /&gt;&lt;/a&gt;
(BTW, the Reader shows the beginning of the first chapter of the new &lt;a href="http://www.manning.com/foord/" target="_blank"&gt;"IronPython in Action"&lt;/a&gt; book, by my colleagues &lt;a href="http://voidspace.org.uk" target="_blank"&gt;Michael Foord&lt;/a&gt; and Christian Muirhead.)

&lt;p&gt; They say that the battery life is 5000 page turns, but mine
died after about 1000 pages of mentioned David Copperfield. I have
been playing with it, and sometimes going back and forth, but for sure that
was not 4000 page turns worth of playing. Anyway, the battery life
is very good, but the 5000 page turns is misleading at best.

&lt;p&gt; The device comes with software for windows. It is not really
a problem for a Linux user, because you can mount the reader like
a usb stick, and copy the books directly - that is how I do it
at least. There is calibre project that is supposed to be heaps
better software for the reader than the official one, 
but it doesn't start on my system
and I don't see any reason to investigate -- I'm fine with cp.

&lt;p&gt; I have it for over a month and think it was worth every single
pound I payed for it. I write the review
now, because I have finally bought an ebook on-line and put it on
the reader. That feels right. Although, in the meantime I had
to buy one dead tree book simply because there was no ebook available.
Hopefully that will not happen often as amazon's Kindle gains
popularity.

&lt;p&gt; My biggest wish is that the screen was larger. Looks like the
upcoming &lt;a href="http://www.amazon.com/Kindle-DX-Amazons-Wireless-Generation/dp/B0015TCML0" target="_blank"&gt;Kindle DX&lt;/a&gt; is going to be the right size, though it is going to have a
lower resolution than the Sony Reader. I bet that other manufacturers are already
working on a larger version to compete with DX.

&lt;p&gt; The small size is not really right for books with code and
mathematical formulae (most cs papers and technical books). I found
that putting the reader into horizontal mode (buried down in the
settings) helps a lot with that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-3882480286134185758?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/bjEUAuBKZ9E" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2009/05/sony-prs-505-ebook-reader-reviewj.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_qxRRyN-iKdo/Sg6auXkl91I/AAAAAAAAAAM/azf49dUxVqs/s72-c/sony-reader.jpg" height="72" width="72" /><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-6475564767199811602</guid><pubDate>Sun, 10 May 2009 17:30:00 +0000</pubDate><atom:updated>2009-05-10T18:43:43.822+01:00</atom:updated><title>Unlock Huawei E220 - soap on a rope</title><description>&lt;p&gt; I have successfully unlocked myself a T-Mobile Huawei E220 modem. I 
followed the tutorial at &lt;a href='http://unlocke220.com/' target='_blank'&gt;unlockE220.com&lt;/a&gt;. However, at step 4 I could not find
the specified string. I suspect that might be due to firmware upgrade on the
device. Anyway, I have worked around it, so please follow the tutorial, and
if you get stuck at step 4, read what follows here.

&lt;p&gt; The unlock code is supposed to be string of 8 digits. First let's
find all the strings in the Flash.bin, created in one of the former steps; I used
the &lt;tt&gt;strings&lt;/tt&gt; command line program (in cygwin) to do it.

&lt;p&gt;
&lt;pre&gt;
strings Flash.bin &amp;gt; 'code-candidates.txt'
&lt;/pre&gt;

&lt;p&gt; Now, the &lt;tt&gt;code-candidates.txt&lt;/tt&gt; contains all the strings, one per line.
We are only interested in the ones composed from digits and at least 8 character long.
Here is a python code that reads the file and prints all possible codes.

&lt;pre&gt;
for l in open('code-candidates.txt').readlines():
    l = l.strip()
    if not all(map(lambda x: x &lt;= '9' and x &gt;= '0', list(l))):
        continue
    if 8 &lt;= len(l):
        print l
&lt;/pre&gt;


&lt;p&gt; Assuming you saved the above code fragment as &lt;tt&gt;find.py&lt;/tt&gt;, the command line to print the codes is:

&lt;pre&gt;
strings Flash.bin &amp;gt; 'code-candidates.txt'
python find.py
&lt;/pre&gt;

&lt;p&gt; In my case it printed 10 or so codes. Try them with the unlock program
provided at unlock220.com. Surprisingly, the unlock program reported
success for 3 of the codes, but only after I tried the last one had my sim card
got accepted.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-6475564767199811602?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/j3X2JrRjsqg" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2009/05/unlock-huawei-e220-soap-on-rope.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-4514106616945109493</guid><pubDate>Sun, 29 Mar 2009 11:12:00 +0000</pubDate><atom:updated>2009-03-29T13:17:45.964+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">twitter</category><title>Twitter outage</title><description>Twitter has been down for me for about a week or so. Every time I logged in it would say "something is terribly wrong". I tought it was down for everybody - you know twitter :) - until I read Menno's post where he reports about masive tweeting at PyCon. I have just reset my password and everything is right again. Odd.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-4514106616945109493?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/e5CxGLYkKek" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2009/03/twitter-outage.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-7509828675289645940</guid><pubDate>Sat, 14 Mar 2009 16:11:00 +0000</pubDate><atom:updated>2009-04-18T17:43:54.199+01:00</atom:updated><title>Quad Head</title><description>&lt;p&gt; In popular opinion programmer's job is just sitting in front of a
computer, each day. It is true it the same sense as life being just eating,
each day. But I am not trying to convince anyone here. I want to say that I
for one am not sitting in front of just any computer; I am sitting in front
of a deathstar control center&lt;a href="#deathstar"&gt;*&lt;/a&gt;! Pictures attached ;). 
&lt;p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ht3lkZS1sNs/SbvXqv1RZhI/AAAAAAAAAQk/gdOrwFQ-qDQ/s1600-h/p2020008.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_ht3lkZS1sNs/SbvXqv1RZhI/AAAAAAAAAQk/gdOrwFQ-qDQ/s400/p2020008.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5313077314808014354" /&gt;&lt;/a&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ht3lkZS1sNs/SbvX28Mo1-I/AAAAAAAAAQs/C9ljWSSc-HY/s1600-h/p2020013.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_ht3lkZS1sNs/SbvX28Mo1-I/AAAAAAAAAQs/C9ljWSSc-HY/s400/p2020013.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5313077524285675490" /&gt;&lt;/a&gt;


&lt;p&gt; OK, back from orbit. I have been using this setup at work for over a
month now and would like to share my observations. I expect many of you to
have reservations as to the added value of additional monitors. You probably
think that four monitors can't be bad but likely not much better than two.

&lt;p&gt; It depends on the type of activity. When browsing (reddit, blogs,
wikipedia), one monitor is usually enough. But when programming I
often wish I had more than four.
Traders have long known about the value of using &lt;a href="http://forexchronicles.files.wordpress.com/2008/03/trading-desk.jpg"&gt;multiple monitors&lt;/a&gt;.

&lt;p&gt; The reason it is so good for programming is that the activity requires
to keep millions of things in the head at once -- names of variables,
functions, classes, third party APIs. You can keep limited amount of
things in your head, depending on various factors affecting your
concentration like amount of sleep the previous night. You will have to &lt;i&gt;page
    fault&lt;/i&gt; to the rest. And when page faulting requires switching between windows
it adds friction. Energy that could have been used on solving problems is
wasted. 

&lt;p&gt; When pair programming the problem is even more itching. The pilot
(the person who has no control of the keyboard) has a high cost of page
fault  -- he needs to ask the driver to "show the page he needs". This
request will probably also disturb the concentration of the driver.

&lt;p&gt; Allocating windows across monitor is crucial. You want to have the
information you will need most often readily available. What you don't want
is to have two windows to which you need simultaneous access being on the
same monitor. 


&lt;p&gt;Even with four monitors, you will find that you have more than one window
on the same monitor. My average is about 2-3 windows per monitor and 2-3
virtual desktops (don't worry I don't use splits ;). For past month I had
one virtual desktop for lunch time, one for spiking an interactive console
for Resolver One, and one for main development.

&lt;p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ht3lkZS1sNs/SeoCV8DqgQI/AAAAAAAAAQ0/9StOgIVlOt8/s1600-h/multimon.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 80px;" src="http://2.bp.blogspot.com/_ht3lkZS1sNs/SeoCV8DqgQI/AAAAAAAAAQ0/9StOgIVlOt8/s400/multimon.png" border="0" alt="My screens during work" id="BLOGGER_PHOTO_ID_5326072085241037058" /&gt;&lt;/a&gt;

&lt;p&gt; Vista is not really well prepared for 4 monitors; windows appear on
different monitors at random. It is not unusual that an application on
monitor 4 will popup a dialog on monitor 1. Without some third party tools
it would be a chore to manage it all. I use winsplit for moving windows
around, &lt;a href="http://codeplex.com/vdm"&gt;vdm&lt;/a&gt; for virtual desktops and
ultramon for extending the taskbar.

&lt;p&gt;
For over a year now I am used to open two separate gvim instances, one
for the module under test and one for the unittests of that module. This
arrangement fits very well with test driven development, which involves
frequent going back and forth between tests and module under test.


&lt;p&gt;
&lt;a name="deathstar"&gt;*&lt;/a&gt; My desktop was named deathstar control center by &lt;a href="http://tartley.com"&gt;Jonathan&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-7509828675289645940?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/3ARra7dPQ7M" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2009/03/quad-head.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_ht3lkZS1sNs/SbvXqv1RZhI/AAAAAAAAAQk/gdOrwFQ-qDQ/s72-c/p2020008.jpg" height="72" width="72" /><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-2985625292479786928</guid><pubDate>Wed, 04 Feb 2009 12:22:00 +0000</pubDate><atom:updated>2009-02-04T12:29:29.866Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">Haskell</category><title>HLint</title><description>&lt;p&gt; I am used to pylint, which runs at the start of a build to ensure
code quality. If pylint complaints, the build is broken, so I run it prior to any
commit to avoid embarrassing BUILD FAILED emails sent to all developers by CI.

&lt;p&gt; No one has high expectations of such a tool, it just reports unused
variables and imports or redefined names. It also annoyingly complains
about defining names such as file, that shadow builtins. Well, I guess different
people are annoyed with different aspects of it. Anyway, my point here is that
this tool is simple.

&lt;p&gt; I was thrilled to see
&lt;a href='http://www-users.cs.york.ac.uk/~ndm/hlint/'&gt;HLint&lt;/a&gt; suggest
that instead of &lt;tt&gt;reverse . tail . reverse&lt;/tt&gt; I could just use &lt;tt&gt;init&lt;/tt&gt;.

&lt;p&gt;
&lt;pre&gt;
./Goals.hs:137:1: Error: Use init
Found:
  reverse . tail . reverse
Why not:
  init
&lt;/pre&gt;


&lt;p&gt; That is just whole new level. It also highlights redundant brackets:
&lt;pre&gt;
./Controller.hs:17:1: Warning: Redundant brackets
Found:
  (priority n1) `compare` (priority n2)
Why not:
  priority n1 `compare` priority n2
&lt;/pre&gt;

&lt;p&gt; And look at the next one,

&lt;pre&gt;
./Controller.hs:17:1: Warning: Use on
Found:
  byPriority n1 n2 = (priority n1) `compare` (priority n2)
Why not:
  byPriority = compare `on` priority
&lt;/pre&gt;

&lt;p&gt; I had no idea that `on` existed. How awesome
is that? As if by sufficiently advanced technology HLint knows better
how to code than I :).

&lt;p&gt; The tool was created by Neil Mitchell, who is also responsible for &lt;a href='http://haskell.org/hoogle/'&gt;Hoogle&lt;/a&gt; -- Haskell API search --
which I use daily.

&lt;p&gt; It is available thorough &lt;tt&gt;cabal install&lt;/tt&gt;, but &lt;tt&gt;cabal install hlint&lt;/tt&gt; didn't work for me until I cabal installed happy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-2985625292479786928?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/fzh1Ad8ISuY" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2009/02/hlint.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-1479208162550185845</guid><pubDate>Mon, 02 Feb 2009 21:00:00 +0000</pubDate><atom:updated>2009-02-02T22:18:00.237Z</atom:updated><title>Snowing in London</title><description>&lt;p&gt;It was snowing today in London, or as BBC holds it, there were severe
weather conditions. By Polish standards, it was nothing special, but London was
unprepared. I didn't realise how bad it was until I read an e-mail from
&lt;a href='http://orestis.gr'&gt;Orestis&lt;/a&gt;, that he doesn't want to risk coming to office. I had no idea
underground did not work, I live in a walking
distance from the office and today I was 10 minutes early.

&lt;p&gt;On my route to work I saw &lt;b&gt;palms&lt;/b&gt; under snow.
&lt;div style='text-align:center;margin:0px auto 10px;'&gt;&lt;a href='http://3.bp.blogspot.com/_ht3lkZS1sNs/SYde-8HyBTI/AAAAAAAAAP8/ChVcb_UB4Ts/s1600-h/P2020005.JPG'&gt;&lt;img src='http://3.bp.blogspot.com/_ht3lkZS1sNs/SYde-8HyBTI/AAAAAAAAAP8/ChVcb_UB4Ts/s400/P2020005.JPG' border='0' alt='' /&gt;&lt;/a&gt;&amp;nbsp;&lt;/div&gt;

&lt;p&gt;Anyway, that must have been great day for kids. If not for snow then at
least for closed schools. I took that photo in the evening. Yes, that snowman has
&lt;i&gt;style&lt;/i&gt; and surely many &lt;i&gt;bitches&lt;/i&gt;, and yes, he wears silver $ on his neck.


&lt;div style='text-align:center;margin:0px auto 10px;'&gt;&lt;a href='http://2.bp.blogspot.com/_ht3lkZS1sNs/SYde-7Kdb-I/AAAAAAAAAQE/-3Dwo7FokBc/s1600-h/IMG_0205.JPG'&gt;&lt;img src='http://2.bp.blogspot.com/_ht3lkZS1sNs/SYde-7Kdb-I/AAAAAAAAAQE/-3Dwo7FokBc/s400/IMG_0205.JPG' border='0' alt='' /&gt;&lt;/a&gt;&amp;nbsp;&lt;/div&gt;

&lt;p&gt;Not only schools were closed. I needed to go to Lloyds TSB, you know, &lt;i&gt;the bank
with the most branches&lt;/i&gt;. My branch greeted me with this:


&lt;div style='text-align:center;margin:0px auto 10px;'&gt;&lt;a href='http://2.bp.blogspot.com/_ht3lkZS1sNs/SYde-5Gx2dI/AAAAAAAAAQM/UTfZ2i0Bais/s1600-h/P2020018.JPG'&gt;&lt;img src='http://2.bp.blogspot.com/_ht3lkZS1sNs/SYde-5Gx2dI/AAAAAAAAAQM/UTfZ2i0Bais/s400/P2020018.JPG' border='0' alt='' /&gt;&lt;/a&gt;&lt;/div&gt;


&lt;p&gt; Weather conditions, yada yada, they are sorry, and point me to another
branch. Guess what, that second branch had a similar note pointing to third
branch. At this point I was sure that the third branch will close the cycle. I
was wrong, the third branch had a note saying that they are indeed open, but
only till 2pm; unlucky for me it was 2:15.

&lt;p&gt; I was pretty amazed when I first learned the notion of 
&lt;a href='http://en.wikipedia.org/wiki/Bank_holiday'&gt;Bank Holiday&lt;/a&gt;. Idea
that no other business can operate when banks are shut still seems dubious
to me. Far more convincing is that no other business can
operate without the tube.

&lt;p&gt; I am supposed to fly to Poland tomorrow, but all the today's flights were
cancelled. The weather is supposed to be the same tomorrow, my only hope is
that the UK will get better at coping with the snow.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-1479208162550185845?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/vsltnKi1mHc" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2009/02/snowing-in-london.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_ht3lkZS1sNs/SYde-8HyBTI/AAAAAAAAAP8/ChVcb_UB4Ts/s72-c/P2020005.JPG" height="72" width="72" /><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-7231099261664909788</guid><pubDate>Tue, 20 Jan 2009 08:56:00 +0000</pubDate><atom:updated>2009-01-21T23:25:06.798Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">Resolver</category><title>Beautiful Code: Resolver One</title><description>&lt;p&gt; &lt;a href='http://resolversystems.com/'&gt;Resolver One&lt;/a&gt;, aka the Python
Spreadsheet, has a beautiful design at its core, which I would like to
present to the programmer community. No knowledge of Python is necessary to
understand this article.

&lt;p&gt; The goal for the application is to provide seamless integration of 
spreadsheet (formulae in the cells) with sequential code. In MS Excel
the VBA integration is anything but seamless. In the rest of this post
I explain how Resolver One integrates Python with spreadsheet functionality.


&lt;p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ht3lkZS1sNs/SXWR9XgxgpI/AAAAAAAAAPk/KIQJb7AI2Z4/s1600-h/resolver.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 356px; height: 400px;" src="http://2.bp.blogspot.com/_ht3lkZS1sNs/SXWR9XgxgpI/AAAAAAAAAPk/KIQJb7AI2Z4/s400/resolver.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5293297420513411730" /&gt;&lt;/a&gt;
&lt;h3&gt; Spreadsheet&lt;/h3&gt;


&lt;p&gt; To ensure that we are on the same page, I'll pinpoint some facts about
spreadsheets.  In a traditional spreadsheet there are two types of content a
cell can hold:

&lt;ul&gt;
&lt;li&gt; constant: like number, date or text
&lt;li&gt; formula: an expression usually referencing other cells
&lt;/ul&gt;

&lt;p&gt; A user can enter this content by typing to a cell. Additionally, a user
can specify formatting for a cell by various GUI means; for example, make
the cell's font bold by clicking a toolbar button.

&lt;p&gt; How do you add sequential code to it? Resolver's solution is to turn the
spreadsheet into sequential program. User's custom code merges 
with the rest of the spreadsheet thus expressed.


&lt;H3&gt;Spreadsheet as a program&lt;/H3&gt;

&lt;p&gt; In Resolver One, what you see in the grid is the result of 
executing the code displayed in the coding pane.

&lt;p&gt; Following is the code that appears in a document created with File | New
command. I have pruned it by dropping comments and not required import
statements.

&lt;p&gt;
&lt;pre&gt;
from Library.Workbook import Workbook

workbook = Workbook()
workbook.AddWorksheet("Sheet1")
workbook.AddWorksheet("Sheet2")
workbook.AddWorksheet("Sheet3")

Constants = {}
Formatting = {}
workbook.Populate(Constants, Formatting)
&lt;/pre&gt;

&lt;p&gt; The above featured code creates a workbook with three empty worksheets.

&lt;p&gt; Where did the code come from? Resolver One generated it from
the model. By model I mean the data structure that remembers constants,
formatting and formulae input by the user through the GUI interface.


&lt;p&gt; The drill is: Resolver One generates code from the model, executes the program,
takes the resulting workbook object and displays it in the tabbed grid view.
This is called &lt;i&gt;recalculation&lt;/i&gt;.

&lt;p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ht3lkZS1sNs/SXWSNmiZhLI/AAAAAAAAAPs/KZPyyJmLRnY/s1600-h/recalc.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 337px;" src="http://3.bp.blogspot.com/_ht3lkZS1sNs/SXWSNmiZhLI/AAAAAAAAAPs/KZPyyJmLRnY/s400/recalc.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5293297699424666802" /&gt;&lt;/a&gt;

&lt;p&gt; Every time the user changes the model through the GUI commands, a new
recalculation is triggered. The next snippet presents code after me changing
the model by typing to some cells in the grid, I want to give you a feel of the generated
code. I put number &lt;tt&gt;1&lt;/tt&gt; into A1 and formula &lt;tt&gt;=A1*2&lt;/tt&gt; into B1.

&lt;pre&gt;
from Library.Workbook import Workbook

workbook = Workbook()
workbook.AddWorksheet("Sheet1")
workbook.AddWorksheet("Sheet2")
workbook.AddWorksheet("Sheet3")

Constants = {
    'Sheet1': {
        (1, 1): 1,
    },
}
Formatting = {}
workbook.Populate(Constants, Formatting)

workbook["Sheet1"].B1 = workbook["Sheet1"].A1*2
&lt;/pre&gt;

&lt;p&gt;
&lt;H3&gt; User Code &lt;/H3&gt; 

&lt;p&gt; All the code generated from the model is divided among three uneditable
sections in the coding pane:
&lt;ul&gt;
    &lt;li&gt; imports and worksheet creation
    &lt;li&gt; constants and formatting
    &lt;li&gt; formulae
&lt;/ul&gt;

&lt;p&gt; In addition, there are three editable sections for user code, one after
each of the generated ones. The user code is "on the same rights" with the
generated code which is creating the workbook to display; the merge is perfect :).


&lt;p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ht3lkZS1sNs/SXWSWwIYLrI/AAAAAAAAAP0/c4uwd2jxbCI/s1600-h/recalc2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 383px; height: 400px;" src="http://3.bp.blogspot.com/_ht3lkZS1sNs/SXWSWwIYLrI/AAAAAAAAAP0/c4uwd2jxbCI/s400/recalc2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5293297856618704562" /&gt;&lt;/a&gt;

&lt;h3&gt;Buttons&lt;/h3&gt;

&lt;p&gt; That would have been all and buttons aren't strictly necessary to
discuss here, but they fit quite well. A button can be created in the user
code and set as the value of a cell. Of course a button has a click handler
that a user would define as a function. This handler is not executed during
the recalculation of course. So when is it executed, and more importantly
what can it do?

&lt;p&gt; The first question is quite easy. The handler gets called when user
clicks the button. He can't click it until he can see it, which is after the
recalculation is finished the workbook is displayed on the grid.

&lt;p&gt; There is nothing magic in what a button can do. Python has lexical
scopes, so the handler has access to anything that was in scope where the
function was defined, in particular this means the workbook object. For
instance, handler could create two hundred new buttons and place them all
over the grid.

&lt;p&gt; When a user clicks a button the handler is called after which Resolver
One refreshes the grid to display any changes made to the displayed
workbook. There is no recalculation, because the &lt;b&gt;model didn't change&lt;/b&gt;.
This also means, that any changes made by the button handler will disappear
after the next recalculation is finished, because there will be simply
different workbook object being displayed.

&lt;p&gt; Note: Resolver One 1.4, next major release, will provide means for
changing the model from a button handler.

&lt;h3&gt;Wrapup&lt;/h3&gt; 

&lt;p&gt; So that is the architecture of Resolver One, brought to you by one of
the programmers on the team. Every other feature in the application revolves
around this foundation. Of course the model contains more stuff, for
which code needs to be generated; but it all ends up in one of the three
sections in coding pane. To fully grok different features in Resolver One, you need to understand recalculation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-7231099261664909788?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/Di0WK7KCyFc" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2009/01/beautiful-code-resolver-one-resolver.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_ht3lkZS1sNs/SXWR9XgxgpI/AAAAAAAAAPk/KIQJb7AI2Z4/s72-c/resolver.png" height="72" width="72" /><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-4682409634729834991</guid><pubDate>Wed, 07 Jan 2009 21:57:00 +0000</pubDate><atom:updated>2009-01-07T22:26:44.340Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">lifehack</category><title>Mailless mailing list</title><description>&lt;p&gt; I was being flooded with messages from various mailing lists . I wasn't
missing any personal mails, but I scanned through the inbox looking
for more important mails, and the ones from mailing lists were almost always less so.

&lt;p&gt; At one point I though that I could write an application to neatly track
the groups when I realized that such an app already exists, it is called &lt;a
    href="http://google.com/groups"&gt;Google Groups&lt;/a&gt;. Quite a discovery, I
know, thank you very much.

&lt;p&gt; Your google account is fine with the service of course. You can easily subscribe to
usenet groups, Google Groups native groups, or to proxies of Mailman managed groups
like &lt;a href="http://groups.google.com/group/ironpy"&gt;groups.google.com/group/ironpy&lt;/a&gt;, and
receive no mail whatsoever (if you indicate so in group settings).

&lt;p&gt; Ironpy was set up by Michael Foord. He set up the Google Group
for the existing mailing list: users @ lists.ironpython.com. If you just
subscribe to this google group, it serves as a sort of read-only view. You
can try to post but the mailman want let your e-mails through.  For this you
need to subscribe with the Mailman. I thought that here ended my mailless
mailing list project, but turns out that Mailman has a setting for not
sending the mail, vacation mode it is called. Hence, from now on
I'm on vacation ;). Brilliant!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-4682409634729834991?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/mfAAwkZT9ok" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2009/01/mailless-mailing-list.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-6379027449746479728</guid><pubDate>Mon, 29 Dec 2008 22:59:00 +0000</pubDate><atom:updated>2008-12-29T23:04:04.555Z</atom:updated><title>Key workaround</title><description>&lt;p&gt; When I was buying Lenovo ThinkPad T61, I was not aware of swapped Fn and
Ctrl keys on its keyboard nor how much pain that would cause me. They
placed Fn key were Ctrl should be. Needless to say that it caused numerous
errors, where instead of Ctrl I would hit the misplaced Fn key.

&lt;p&gt; I have found a satisfactory workaround that I want to share. I have
sticked a piece of scotch tape on top of the Ctrl key. It gives me sensory
feedback. It seems to have done the trick; I no longer inadvertently hit Fn
key.

&lt;p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ht3lkZS1sNs/SVlWao1xbCI/AAAAAAAAAPE/DxRQvvLfvks/s1600-h/PC290024.jpg"&gt;&lt;img style="float:center; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://3.bp.blogspot.com/_ht3lkZS1sNs/SVlWao1xbCI/AAAAAAAAAPE/DxRQvvLfvks/s400/PC290024.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5285350653335530530" /&gt;&lt;/a&gt;

&lt;p&gt; Note: originally I tried sticking it on top of Fn key, but for some reason it
didn't work for me.
&lt;p&gt; And one more thing, lenovo sux.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-6379027449746479728?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/9uwuBQVgDAI" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2008/12/key-workaround.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_ht3lkZS1sNs/SVlWao1xbCI/AAAAAAAAAPE/DxRQvvLfvks/s72-c/PC290024.jpg" height="72" width="72" /><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-8524387490845861096</guid><pubDate>Thu, 25 Sep 2008 13:26:00 +0000</pubDate><atom:updated>2008-09-25T22:45:31.206+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Haskell</category><title>Hackage packages</title><description>&lt;p&gt;
People behind Well-Typed have published this graph &lt;a href='http://blog.well-typed.com/2008/09/hackage-hacking-and-demo/'&gt;yesterday&lt;/a&gt;. It shows packages on hackage. I have added links from all the circles I could recognize to the corresponding packages on hackage.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ht3lkZS1sNs/SNuSuBh3UmI/AAAAAAAAAM0/dpRwuHxz5i4/s1600-h/hackage.png"&gt;&lt;/a&gt;

&lt;center&gt;&lt;img usemap='#hackage' src="http://img150.imageshack.us/img150/9361/hackagenz3.png" border="0" /&gt;&lt;/center&gt;



&lt;map name='hackage'&gt;
    &lt;area shape='circle' coords='98,364,50' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/mtl'/&gt;
    &lt;area shape='circle' coords='195,358,45' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/containers'/&gt;
    &lt;area shape='circle' coords='252,287,40' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/bytestring'/&gt;
    &lt;area shape='circle' coords='260,200,36' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/array'/&gt;
    &lt;area shape='circle' coords='318,252,28' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/parsec'/&gt;
    &lt;area shape='circle' coords='211,146,26' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/haskell98'/&gt;
    &lt;area shape='circle' coords='180,70,18' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/old-locale-1.0.0.0'/&gt;
    &lt;area shape='circle' coords='152,109,25' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/filepath'/&gt;
    &lt;area shape='circle' coords='104,129,18' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/binary'/&gt;
    &lt;area shape='circle' coords='195,358,45' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/filepath'/&gt;
    &lt;area shape='circle' coords='280,363,38' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/directory'/&gt;
    &lt;area shape='circle' coords='326,313,35' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/process'/&gt;
    &lt;area shape='circle' coords='370,271,32' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/old-time'/&gt;
    &lt;area shape='circle' coords='364,215,36' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/random'/&gt;
    &lt;area shape='circle' coords='323,174,35' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/network'/&gt;
    &lt;area shape='circle' coords='278,133,33' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/unix'/&gt;
    &lt;area shape='circle' coords='234,83,30' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/QuickCheck'/&gt;
    &lt;area shape='circle' coords='323,107,30' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/pretty'/&gt;
    &lt;area shape='circle' coords='326,313,35' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/process'/&gt;
    &lt;area shape='circle' coords='353,137,25' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/time'/&gt;
    &lt;area shape='circle' coords='371,274,28' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/old-time'/&gt;
    &lt;area shape='circle' coords='380,170,18' 
    href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/utf8-string'/&gt;
&lt;/map&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-8524387490845861096?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/kFPQDGojMxw" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2008/09/hackage-packages.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-5026663500827042421</guid><pubDate>Fri, 08 Aug 2008 07:42:00 +0000</pubDate><atom:updated>2008-08-08T08:43:44.206+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">testing</category><title>assert the machine did not explode</title><description>&lt;p&gt;
I see it often done by novices, heck, I used to do
that myself. When writing a unit test for a method cloning an
object, I would put an assertion to check that the original object is left
unchanged.

&lt;p&gt;
Well, that is wrong. This is checking against a possible bug in the
implementation, in which the original object gets modified. But this is just
one thing that could go wrong. There are infinitely many possible bugs like this,
maybe even one that causes your machine to explode. 
You can't
write assertions against all of them, so don't do it against any of them.

&lt;p&gt; It has two advantages. First is that you stop worrying you forget
assertions against some possible bug; that is, if you were worrying about
that in the first place. I am sure there are people out there who feel bad
about not testing against printing foul language. Second is that the tests
themselves become smaller, focused on the positive behavior, therefore easier
to read.

&lt;p&gt;
In the specific example of cloning: check that the cloned object is equal
to the original but they are not the same objects, and that is it. Nothing
else.

&lt;p&gt;
Unit tests are positive tests, they should only test what you want
the code to do, not what it shouldn't do. I am not sure about the case
when we fix a defect, but probably a functional test for the defect 
is enough.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-5026663500827042421?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/3YHBOBLGA7A" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2008/08/assert-machine-did-not-explode.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-6319031689637190956</guid><pubDate>Sun, 13 Apr 2008 17:30:00 +0000</pubDate><atom:updated>2008-04-13T18:33:30.855+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">testing</category><category domain="http://www.blogger.com/atom/ns#">Python</category><title>camelCaseSplit t  i   n    g</title><description>&lt;p&gt; Unit tests are whitebox tests. You want to have them cover all possible
paths through the code. If a method has an if statement, 
you need two tests to cover the two possible code paths. When you remove the
if statement, you can also remove one of the tests.

&lt;p&gt; Changing code often requires changing tests, and when you have 3 to 1
ratio of tests to code, you want the tests to be readable. 80 character
camelCase test names are not helping. You get used to reading camelCase but
you will never get as fast in it as reading spaced text.

&lt;p&gt; To write tests we use PyUnit framework, as it turned out the
&lt;tt&gt;unittest.TextTestRunner&lt;/tt&gt; would print the docstring for the method
implementing test, instead of the usual &lt;tt&gt;ClassName.testMethod&lt;/tt&gt;. The
only thing left was to write a
&lt;a href='http://code.google.com/p/pyunit-splitcamelcase'&gt;program&lt;/a&gt; that
would go through our 120 000 lines of test code and put the split name into docstrings.

&lt;p&gt; This is not ideal sulution, as it still requires unique method names.
 With 
&lt;a href='http://code.google.com/p/nzb-cli/source/browse/trunk/unittests.hs?r=23'&gt;HUnit&lt;/a&gt; and 
&lt;a href='http://nemerle.org/NemerleUnit'&gt;NemerleUnit&lt;/a&gt; you don't have this problem.

&lt;p&gt; When defining new tests we are going to put only additional information into the
docstring, trying not to exceed 4 components limit in the method name. Both class
and method names provide information, what the test is checking. The docstring
should be used as additional information.

&lt;p&gt; I had to slightly modify the TextRunner to get this behaviour, printing
the class and test name as well as the docstring, though. By default it
prints only docstring, if there is any.

&lt;p&gt; BTW, spaces were not introduced until 4th century AD. Plato
was writing without them, for example.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-6319031689637190956?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/Shaqq-Krcko" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2008/04/camelcasesplit-t-i-n-g.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-7138946970473079261</guid><pubDate>Sat, 05 Apr 2008 23:09:00 +0000</pubDate><atom:updated>2008-04-06T00:13:08.658+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Vim</category><title>GVim to convert code into html</title><description>&lt;p&gt; Few are aware of the fact that gvim can generate html for the code inside
the buffer. The command is :TOhtml; just type it in, and the html will promptly
appear in a split window. 

&lt;p&gt; In the browser, the generated html should look exactly as you
see it in gvim. By default it generates html that should work
in old browsers too, but can be &lt;i&gt;told&lt;/i&gt; to generate CSS stylesheets
or even xhtml. Type :help TOhtml for more details.

&lt;p&gt; It works only in gvim, though; not in vim. It is handy for posting snippets of code on the web.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-7138946970473079261?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/giiSUvPrRW8" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2008/04/gvim-to-convert-code-into-html.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-2599656558289804568</guid><pubDate>Thu, 03 Apr 2008 21:21:00 +0000</pubDate><atom:updated>2008-04-03T22:25:45.720+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Haskell</category><title>Starting a new blog</title><description>&lt;p&gt;
It will be a diary from developing an application in Haskell. I intend to
keep the posts clean and short. Initial post contains links to
two papers. To the first paper I have already linked to from this blog, it
compares Haskell with other languages. Second is a classic paper on
functional programming, &lt;i&gt;why functional programming matters&lt;/i&gt;, a highly
recommended read. Here is &lt;a href='http://dev-app-in-haskell.blogspot.com/'&gt;a link&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-2599656558289804568?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/La9Umr5y94g" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2008/04/starting-new-blog.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-8696229231829873901</guid><pubDate>Sun, 02 Mar 2008 14:05:00 +0000</pubDate><atom:updated>2008-03-02T14:29:10.528Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">.net</category><category domain="http://www.blogger.com/atom/ns#">mono</category><title>.NET BCL source code</title><description>&lt;p&gt; Source code for .NET Base Class Library has been made available for debugging sessions in
VS2008. It would download one file at a time as they are needed. 
Since then John Robbins and Karem Kusmezer have create a tool to download
all the source files without hassle, great work! The tool is 
&lt;a href='http://www.codeplex.com/NetMassDownloader'&gt;NetMassDownloader&lt;/a&gt;.

&lt;p&gt; Use it whilst it is still working :). Download, unpack, and run:
&lt;pre&gt;
NetMassDownloader.exe -output bcl
    -d C:\Windows\Microsoft.NET\Framework\v2.0.50727
&lt;/pre&gt;

&lt;p&gt; I executed in in Windows XP as a limited user and have seen numerous
failure messages printed out. Nevertheless, 120MB of data was downloaded and
I had all the files I wanted. The authors advise though to run it as a
privileged process (at least on Vista).

&lt;p&gt; The most interesting parts are 
&lt;tt&gt;bcl/redbits/ndp/clr/src/BCL/System&lt;/tt&gt; and
&lt;tt&gt;bcl/redbits/ndp/fx/src&lt;/tt&gt; where &lt;tt&gt;bcl&lt;/tt&gt; is the name of the
directory you provided after &lt;tt&gt;-output&lt;/tt&gt; switch. Together they are
about 75MB.

&lt;p&gt; It was pretty interesting to read the implementation of the classes I had
been using for so long: String, Hashtable, Arraylist. They are easy to
understand, with lots of comments, and of course in C#. 

&lt;p&gt; The classes I have read are all pretty basic and no wonder there are
lots of pointers and calls into unmanaged code, but it is still readable.

&lt;p&gt; One surprising thing, but obvious after knowing it, is that &lt;tt&gt;"  s  ".Trim()&lt;/tt&gt; will not
create a new string &lt;tt&gt;"s"&lt;/tt&gt;, but return a slice, an object that holds a reference to 
the original string
and knows where are the beginning and the end. This is possible thanks to the immutability
of strings. I bet the substring method is implemented like this too.

&lt;p&gt; There are also some monster methods to be seen. One example is internal
HttpListener.HandleAuthenticate spanning more than half a thousand lines.

&lt;p&gt; BTW source code for mono is available at &lt;a href='http://www.mono-project.com/AnonSVN'&gt;mono-project.com/AnonSVN&lt;/a&gt;.
Source for mono's BCL is under mcs/class/corlib. It might be interesting to compare the two.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-8696229231829873901?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/KbS6_J9w5c4" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2008/03/net-bcl-source-code.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-1734087859238964142</guid><pubDate>Sat, 01 Mar 2008 14:09:00 +0000</pubDate><atom:updated>2010-09-16T22:41:42.685+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Vim</category><title>Why Vim's modes frustrate newbies</title><description>&lt;p&gt;
Some people say they hate the Vim's modes.
Puzzling, because I consider the modes as the killer feature of Vim, something
that makes it superior to Emacs.


&lt;h3&gt;Why modes rock&lt;/h3&gt;

&lt;p&gt;
I spend most of the time in the normal mode. In this mode, undo is just
&lt;i&gt;u&lt;/i&gt;, delete line &lt;i&gt;dd&lt;/i&gt; and move one word forward &lt;i&gt;w&lt;/i&gt;. In Emacs
these commands would all include ctrl, shift, alt or whatever.  Inserting
text is not what I spend most of the time in an editor on. Most of the time I
need to quickly navigate around and make small modification to an already existing
text. It is false economy to have the keys on the keyboard be bound
to less often used functionality all the time.

&lt;p&gt;
When I reach the exact place where I need to enter some text, I
press &lt;i&gt;i&lt;/i&gt; to enter insert mode, type it, and immediately get back
to normal mode (I get to normal mode by pressing ctrl-[ rather than ESC).


&lt;h3&gt;Why modes frustrate newbies&lt;/h3&gt;

&lt;p&gt; While pairing with people new to Vim I noticed that they leave it
in whatever mode. So if they were inserting, they live it in
insert mode. When they come back to Vim window (after inspecting results of a test
run for example), they think they are typing normal-mode commands, but are
actually in the insert mode typing text. Or the opposite situation: start typing
and instead of inserting text they are rapidly killing one chunk of the file
after another.

&lt;p&gt; Experienced Vimers follow a convention. After doing something briefly in other
mode, immediately go back to the normal mode. I never live Vim in the insert
mode or any other mode than normal; when I get back to the Vim window I can always
assume Vim is in the normal mode.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-1734087859238964142?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/vMGWtLDH_nA" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2008/03/why-vims-modes-frustrate-newbies.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>6</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-7632396150420581291</guid><pubDate>Sun, 17 Feb 2008 15:40:00 +0000</pubDate><atom:updated>2008-12-09T13:23:52.199Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">linux</category><category domain="http://www.blogger.com/atom/ns#">xmonad</category><category domain="http://www.blogger.com/atom/ns#">Haskell</category><title>xmonad</title><description>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ht3lkZS1sNs/R7lMcPDA-BI/AAAAAAAAABw/zbA-qd7UG4w/s1600-h/Screenshot-1.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_ht3lkZS1sNs/R7lMcPDA-BI/AAAAAAAAABw/zbA-qd7UG4w/s320/Screenshot-1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5168246095343581202" /&gt;&lt;/a&gt;
&lt;p&gt;
I am running xmonad! I had some troubles configuring it though.

&lt;p&gt;
I am running Ubuntu Gutsy Gibbon and had to compile it from sources
which turned out to be easy, but then
the instructions to actually run it didn't work.
I have finally got it going by following instructions in 
&lt;a href='http://haskell.org/haskellwiki/Xmonad/Frequently_asked_questions#How_can_I_use_xmonad_with_a_display_manager.3F_.28xdm.2C_kdm.2C_gdm.29'&gt;FAQ&lt;/a&gt;
about using xmonad with a display manager.

&lt;p&gt; Before I got xmonad working I tried wmii, which was 
readily available in repositories. After installing it (&lt;tt&gt;sudo apt-get
install wmii&lt;/tt&gt;) you can log out, and in gdm (session manager) change
session to wmii to finally log in and enjoy wmii. wmii would be good
for me had I no dual head configuration. It was treating my two monitors
as one big virtual screen. This meant that a part of it was not visible to me as
my left monitor is shorter than the right. 

&lt;p&gt; xmonad has much fewer lines of code that wmii.
I have seen &lt;a href='http://www.google.co.uk/url?sa=t&amp;ct=res&amp;cd=1&amp;url=http%3A%2F%2Fweb.cecs.pdx.edu%2F~apt%2Fcs457_2005%2Fhudak-jones.pdf&amp;ei=TFC4R7nAD4nA0wTmkIjtDA&amp;usg=AFQjCNHF8zEHHymYozkfPEIFyMETzHbR6Q&amp;sig2=LOaWEup7LwVV9IYMeqG_7w'&gt;it&lt;/a&gt; a few times already, 
Haskell programs being
very small in comparison with alternatives in other languages.
wmii is proud to keep it small in under 10 000 lines of code, while
xmonad is written in less then &lt;i&gt;1300&lt;/i&gt; lines of Haskell. Additionally, there are 
583 lines in tests. Not bad considering that xmonad turned out to be better then wmii.

&lt;p&gt; I got these numbers by running the following command on ver 0.6 sources,
it ignores blank lines and comments.

&lt;pre&gt;
find . -name \*.hs -exec cat {} \; |\
    egrep -v "^ *$|^ *--" | wc
&lt;/pre&gt;

&lt;p&gt; BTW &lt;a href='http://xmonad.org/'&gt;xmonad&lt;/a&gt; is cool.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-7632396150420581291?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/1wevZL1Blc8" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2008/02/xmonad.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_ht3lkZS1sNs/R7lMcPDA-BI/AAAAAAAAABw/zbA-qd7UG4w/s72-c/Screenshot-1.png" height="72" width="72" /><thr:total>6</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-706163359435445252</guid><pubDate>Wed, 13 Feb 2008 21:10:00 +0000</pubDate><atom:updated>2008-02-13T21:34:32.284Z</atom:updated><category domain="http://www.blogger.com/atom/ns#">lifehack</category><title>Time tracking</title><description>&lt;p&gt; I get all those ideas and have no time to realize them. I just don't
know where all the time goes.

&lt;p&gt;
When I started studying my parents were sending me a fixed
amount of money for each month. But the money was running low so quickly that
in the last week of each month I needed to ask them for more. That was
slightly embarrassing, so I decided to keep track of my expenses to
justify it. After a few weeks I was able to find
a few "big wins", cutting down my expenses
without affecting quality of life. From then on 
I was staying within budget.

&lt;p&gt;
Since people say time is money, I would like to try this technique now
on time after it worked so good on money. I started noting
how time I spend on stuff with a pen 
and notebook, before
it occurred to me that there must be web 2.0 apps for this. There
seem to be plenty, I started using two of them simultaneously to
compare. The far better of the two turned out to be 
&lt;a href='http://slimtimer.com'&gt;slimtimer&lt;/a&gt;.

&lt;p&gt;
It is a brilliant app. If you ever need a time tracking app, check this
one first.

&lt;p&gt;
I am tracking my time for a week already, side effect is that I realized
my excuse for not switching to Linux is groundless. After analyzing my last
week's activities it is clear to me that I needed windows only for 2h total.It is my first blog entry published from Ubuntu Gutsy Gibbon and am looking
forward to trying out some 
&lt;a href='http://en.wikipedia.org/wiki/Tiling_window_manager'&gt;tiling window manager&lt;/a&gt;, I will
probably go for &lt;a href='http://xmonad.org/'&gt;xmonad&lt;/a&gt; just because it is written in Haskell :).

&lt;p&gt; Writing this entry took 19 minutes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5375156058364096448-706163359435445252?l=blog.kamil.dworakowski.name' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ProgrammersWeblog/~4/_uBOaBFosXI" height="1" width="1"/&gt;</description><link>http://blog.kamil.dworakowski.name/2008/02/time-tracking.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>2</thr:total></item></channel></rss>

