<?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-9890172</id><updated>2012-01-26T11:20:32.266+02:00</updated><category term='kindle'/><category term='education'/><category term='android'/><category term='running'/><category term='ebooks'/><category term='python'/><category term='windows'/><category term='music'/><category term='vim'/><category term='bay area'/><category term='crackbook'/><category term='piano'/><category term='hardware'/><category term='google'/><title type='text'>Prose practice</title><subtitle type='html'>Life stuff and computer stuff.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>83</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9890172.post-5275117127671273593</id><published>2011-08-31T00:21:00.004+03:00</published><updated>2011-08-31T00:27:14.988+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='crackbook'/><title type='text'>Crackbook</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-drJ3dB4v4Xc/Tl1UvdKsYEI/AAAAAAAAATE/tD08be-ewW8/s1600/Screen%2Bshot%2B2011-08-30%2Bat%2B23.03.05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://1.bp.blogspot.com/-drJ3dB4v4Xc/Tl1UvdKsYEI/AAAAAAAAATE/tD08be-ewW8/s400/Screen%2Bshot%2B2011-08-30%2Bat%2B23.03.05.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;
Shortly before starting my job at Google, I had invested a little time into writing a Chrome extension called &lt;a href="https://chrome.google.com/webstore/detail/nbgjmohekjolcgemlolblankocjlgalf"&gt;Crackbook&lt;/a&gt;. It helps against wasting time on the web by delaying access to selected sites (see this &lt;a href="http://xkcd.com/862/"&gt;XKCD cartoon&lt;/a&gt; for an illustration, and check out the hint too). Because access is just delayed rather than blocked, you are less likely to just disable the tool after a while, which is exactly what happened to the other tools I tried to use.&lt;/p&gt;

&lt;p&gt;
Having found a little free time in the evenings, I have just updated the extension. If you use Chrome, please &lt;a href="https://chrome.google.com/webstore/detail/nbgjmohekjolcgemlolblankocjlgalf"&gt;try it&lt;/a&gt; and give feedback!&lt;/p&gt;

&lt;p&gt;
The extension also collects anonymous statistics on what domains people tend to mark as junk and how often the domains are hit. Some very basic results are available at &lt;a href="http://crackbook.info/"&gt;crackbook.info&lt;/a&gt;. Now that a fair amount of data has been collected, a deeper statistical inspection is in the plans. Stay tuned.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-5275117127671273593?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/5275117127671273593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=5275117127671273593' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/5275117127671273593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/5275117127671273593'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2011/08/crackbook.html' title='Crackbook'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-drJ3dB4v4Xc/Tl1UvdKsYEI/AAAAAAAAATE/tD08be-ewW8/s72-c/Screen%2Bshot%2B2011-08-30%2Bat%2B23.03.05.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-6883321890316002583</id><published>2011-04-02T20:11:00.001+03:00</published><updated>2011-04-02T20:13:02.726+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='kindle'/><category scheme='http://www.blogger.com/atom/ns#' term='ebooks'/><title type='text'>Amazon Kindle 3</title><content type='html'>For the past couple years I had been reading very little, two or three books a year.&lt;br /&gt;
&lt;br /&gt;
For the past month my average has been two books per &lt;i&gt;week&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
The culprit is the &lt;a href="http://amazon.com/Kindle"&gt;Amazon Kindle&lt;/a&gt;&amp;nbsp;3 I bought during my stay in the US. I just can not recommend it enough. For starters, it is quite affordable at $139. The image quality is wonderful, and reading in daylight or even in direct sunlight is pleasant. This is a welcome change from a backlit screen as the eyes get noticeably less strained. The format of the device is even more convenient than of a real book (the size is perfect for plain text, start thinking about the Kindle DX if and only if you intend to read PDFs). The Kindle is quite thin and convenient to hold (and you do not need to keep it from closing as with paperback bindings). Battery life is on the order of weeks. Extra functionality (e.g., web browsing) is available, but not convenient, but that is almost an advantage as distractions are kept at bay.&amp;nbsp;The Amazon store is great, I have already shelled out over $50 with little remorse (my time is much more expensive than the measly $9.99 a typical book costs). There are quite a few free books around too. And to top it off, the "screensaver" with pictures of writers is a very nice touch.&lt;br /&gt;
&lt;br /&gt;
The Kindle is also useful for going through longer articles you would normally be reading on your laptop. The Chrome extension&amp;nbsp;&lt;a href="https://chrome.google.com/webstore/detail/ipkfnchcgalnafehpglfbommidgmalan"&gt;Send to Kindle&lt;/a&gt;&amp;nbsp;has worked well for me, do check it out.&lt;br /&gt;
&lt;br /&gt;
The most important drawback of the Kindle is that it is slow to turn pages, so it is not easy to browse a book. Turning a page takes a second or so. This is extremely annoying when reading in non-linearly, e.g. taking in study material, when you constantly need to go back to check up details of previous material. A PDF interpreter is available, but the screen is too small to show a full PDF page (a Kindle DX or an iPad would probably be better) and scrolling is painful because of the delays. Wireless seems to drain the battery noticeably, there have been a few cases where I forgot to turn it off and found a dead Kindle a few days later. I wish the WiFi connection would manage itself intelligently somehow.&lt;br /&gt;
&lt;br /&gt;
The Kindle drove the point home for me that &lt;b&gt;dead-tree books will be going the way of vinyl soon&lt;/b&gt;, much sooner than I had expected. And for good reasons. Go order now if you do not have an e-book reader yet (and do not forget to order a sleeve too, given the time you will be spending carrying the device it will come in very handy).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-6883321890316002583?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/6883321890316002583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=6883321890316002583' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/6883321890316002583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/6883321890316002583'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2011/04/amazon-kindle-3.html' title='Amazon Kindle 3'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-5121693152361589566</id><published>2011-03-16T13:57:00.001+02:00</published><updated>2011-03-16T13:57:51.921+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Google Munich</title><content type='html'>It looks like I have made it through most of the hurdles of the Google hiring process, and I should be starting my new job at Google's Munich office soon. Now I just need to haul my stuff to Munich and get the paperwork done. It sure looks like this is going to be a very interesting year.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-5121693152361589566?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/5121693152361589566/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=5121693152361589566' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/5121693152361589566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/5121693152361589566'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2011/03/google-munich.html' title='Google Munich'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-2763746172232389398</id><published>2011-03-06T04:37:00.002+02:00</published><updated>2011-03-06T04:37:46.833+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bay area'/><title type='text'>Trip to Bay Area coming to an end</title><content type='html'>My trip to the Bay Area is coming to the end. It has been surprisingly productive. Here's some things I have done in the nearly two weeks I have been here:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;got acquainted with San Francisco&lt;/li&gt;
&lt;li&gt;interviewed for a job at a startup&lt;/li&gt;
&lt;li&gt;visited Stanford University &amp;amp; Berkeley University campuses&lt;/li&gt;
&lt;li&gt;visited Google Mountain View and San Francisco offices&lt;/li&gt;
&lt;li&gt;hanged out with folks from Google, from Twitter and from some very promising startups, also a Stanford professor, a researcher from Berkeley and a Berkeley undergrad student, among others&lt;/li&gt;
&lt;li&gt;hanged out with people from &lt;a href="http://singinst.org/"&gt;The Singularity Institute for Artificial Intelligence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;spent a day biking in the Golden Gate National Recreation Area&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
While I am getting a little travel-weary, I know I will be sad leaving this place.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://lh5.googleusercontent.com/-Al85QxVXogg/TXLxuMdCmOI/AAAAAAAAAQI/7_jFdtcrVl0/s1600/IMG_0027.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="https://lh5.googleusercontent.com/-Al85QxVXogg/TXLxuMdCmOI/AAAAAAAAAQI/7_jFdtcrVl0/s320/IMG_0027.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;ul&gt;&lt;/ul&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-2763746172232389398?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/2763746172232389398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=2763746172232389398' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/2763746172232389398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/2763746172232389398'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2011/03/trip-to-san-francisco-coming-to-end.html' title='Trip to Bay Area coming to an end'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/-Al85QxVXogg/TXLxuMdCmOI/AAAAAAAAAQI/7_jFdtcrVl0/s72-c/IMG_0027.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-1361774250494296303</id><published>2011-02-23T04:01:00.000+02:00</published><updated>2011-02-23T04:01:05.070+02:00</updated><title type='text'>Off to San Francisco!</title><content type='html'>The interview at Munich seemed to go well. Well, at least, I had fun. We'll see how that turns out.&lt;br /&gt;
&lt;br /&gt;
For now, I'm off again for another job interview, this time to Palo Alto. This will be my first time to the West Coast, so I have postponed the return flight for two weeks to familiarize myself with the proverbial area. If anyone's from around the San Francisco Bay Area, I would be very happy to meet over lunch/dinner/beer!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-1361774250494296303?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/1361774250494296303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=1361774250494296303' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/1361774250494296303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/1361774250494296303'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2011/02/off-to-san-francisco.html' title='Off to San Francisco!'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-2207269488605548042</id><published>2011-02-16T08:21:00.001+02:00</published><updated>2011-02-16T08:24:09.952+02:00</updated><title type='text'>Interviewing with Google</title><content type='html'>I somehow made it through Google's phone interviews in one piece, and&amp;nbsp;now they are flying me in for an on-site interview in Munich (Germany), which will take place tomorrow. Keep your fingers crossed for me!&lt;br /&gt;
&lt;br /&gt;
I will be landing in Munich in a few hours, and today I am free to look around the city. Anyone from here up for lunch or a beer?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-2207269488605548042?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/2207269488605548042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=2207269488605548042' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/2207269488605548042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/2207269488605548042'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2011/02/interviewing-with-google.html' title='Interviewing with Google'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-8892080239571135564</id><published>2010-12-19T22:59:00.000+02:00</published><updated>2010-12-19T22:59:43.722+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><title type='text'>Lithuanian (AltGr) keyboard for Windows</title><content type='html'>In GNU/Linux I usually use an AltGr-based keyboard layout for entering Lithuanian characters. That is, you can enter Lithuanian diacritics by holding down AltGr (right Alt)). I had lived with separate modes for entering English and Lithuanian until I found out that having a single layout was a &lt;b&gt;huge &lt;/b&gt;relief.&lt;br /&gt;
&lt;br /&gt;
Windows does ship with a Lithuanian layout where AltGr switches to English characters, but I use the English layout much more, so I need it the other way around. So, I grabbed Microsoft's Keyboard Layout Creator and made the layout I needed. The result is available on a GitHub&amp;nbsp;&lt;a href="http://github.com/gintas/LitAltGr"&gt;repository&lt;/a&gt;. You may also &lt;a href="https://github.com/gintas/LitAltGr/raw/master/LitAltGr.zip"&gt;download the installer directly&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
In Linux, keymaps, being plain text files, are more transparent, but to be fair, in this case the Windows way wins. Not only do you get a GUI tool to create the layout, but also an installer can be generated automatically for deployment of the layout.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-8892080239571135564?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/8892080239571135564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=8892080239571135564' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/8892080239571135564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/8892080239571135564'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2010/11/lithuanian-altgr-keyboard-for-windows.html' title='Lithuanian (AltGr) keyboard for Windows'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-8579862428660225936</id><published>2010-12-19T19:13:00.001+02:00</published><updated>2010-12-19T19:13:00.092+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Mobile App Camp</title><content type='html'>On the last weekend my team and I participated in the Mobile App Camp (&lt;a href="http://www.omnitel.lt/dirbtuves"&gt;link in Lithuanian&lt;/a&gt;) organized by &lt;a href="http://www.omnitel.lt/"&gt;Omnitel&lt;/a&gt;,&amp;nbsp;which is one of the dominant mobile operators in Lithuania.&amp;nbsp;The event seems to be part of Omnitel's push for increasing the share of smartphones in the Lithuanian market, which has been lagging behind the European trends.&lt;br /&gt;
&lt;br /&gt;
Our team consisted of Povilas Kytra, who is behind the &lt;a href="http://www.tv.lt/"&gt;TV.LT&lt;/a&gt; project, Mantas Kanaporis from &lt;a href="http://www.again.lt/en"&gt;A-Gain&lt;/a&gt;&amp;nbsp;and me. In the weekend we built an &lt;a href="http://m.tv.lt/"&gt;app&lt;/a&gt; that shows the TV programme for the coming day for all the Lithuanian TV channels. (The app is not yet available on the Android Market, but we are working on it.)&lt;br /&gt;
&lt;br /&gt;
Here's a screenshot of the main screen of the application:&lt;br /&gt;
&lt;div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/_zn_T2bmMZn0/TQ1JdYXcxMI/AAAAAAAAAOs/tkVoO3nEIRE/s1600/tvltapp.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/_zn_T2bmMZn0/TQ1JdYXcxMI/AAAAAAAAAOs/tkVoO3nEIRE/s320/tvltapp.png" width="212" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
The app was built using the standard Android Development Toolkit on Eclipse. The app gets the content from a &lt;a href="http://rubyonrails.org/"&gt;Rails&lt;/a&gt;-based server containing a simple database and couple JSON views.&lt;br /&gt;
&lt;br /&gt;
I had some experience of developing for Android before, but it was mostly about working with graphics on canvas, while in this app we used some standard GUI controls (with some nifty styling).&lt;br /&gt;
&lt;br /&gt;
For the source control, we used a private repository on &lt;a href="http://bitbucket.org/"&gt;bitbucket.org&lt;/a&gt;. That one was a huge letdown: a 'hg push' or 'hg pull' would take ages (or at least that's how it seemed to me in comparison to &lt;a href="http://www.github.com/"&gt;GitHub&lt;/a&gt;), and we had no end of trouble with merging, partly due to the number of commands needed to get the repositories in sync (hg pull; hg update; hg merge; hg commit; hg push). Even &lt;a href="http://subversion.tigris.org/"&gt;Subversion &lt;/a&gt;would probably have worked better.&lt;br /&gt;
&lt;br /&gt;
The event itself was great fun. It had been a while since I had last coded intensively for the entire weekend. There were quite a few decent ideas presented by the participants, and some of them were successfully implemented.&lt;br /&gt;
&lt;br /&gt;
The rating system was somewhat disappointing though. The event was supposed to be a contest, with four predefined criteria for winning apps (still available on the website): uniqueness in the Lithuanian market, magnitude of the target group, value provided to the user and creativity. In the end, however, the jury nominated apps for three different awards (best app built on an existing database, best app built anew, and the "hope" nomination) with one app awarded from each category. Our app scored second in the first nomination, so we did not get an award, even though we would probably have been in the global top three, were the original criteria upheld.&lt;br /&gt;
&lt;br /&gt;
To be fair, we did not stand much chance against the winner in our category, an app based on &lt;a href="http://vaistai.lt/"&gt;vaistai.lt&lt;/a&gt;, which sported a database of pharmaceuticals with detailed usage instructions, information about drug stores in Lithuania with maps and inventory status, and even a barcode scanner. Hats off to them. Another winner was &lt;a href="http://www.appbrain.com/app/alaus-radaras/alaus.radaras"&gt;"Alaus radaras"&lt;/a&gt; ("Beer radar") with locations of local beer bars and inventory info. The third one was "3 milijonai teisėjų" (Three million judges"), which, as far as I understood, was a conception for a basketball-throwing game (basketball is very big in Lithuania, it is a second national religion).&lt;br /&gt;
&lt;br /&gt;
To conclude, it was a fun event and I wish we will be having more of those in Vilnius, even though the Monday after the long weekend was &lt;i&gt;very &lt;/i&gt;unproductive.&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-8579862428660225936?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/8579862428660225936/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=8579862428660225936' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/8579862428660225936'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/8579862428660225936'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2010/12/mobile-app-camp.html' title='Mobile App Camp'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_zn_T2bmMZn0/TQ1JdYXcxMI/AAAAAAAAAOs/tkVoO3nEIRE/s72-c/tvltapp.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-5783503686715561321</id><published>2010-12-07T10:00:00.001+02:00</published><updated>2010-12-07T10:00:01.730+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><title type='text'>Windows (III): Packaging &amp; nitpicks</title><content type='html'>(This is a part of a series of posts on my recent experience with Windows; see&amp;nbsp;&lt;a href="http://blog.miliauskas.lt/2010/11/windows-i.html"&gt;Windows (I)&lt;/a&gt;&amp;nbsp;&amp;nbsp;and &lt;a href="http://blog.miliauskas.lt/2010/12/windows-ii-user-interface.html"&gt;Windows (II): User Interface&lt;/a&gt;.)&lt;br /&gt;
&lt;br /&gt;
Every GNU/Linux desktop distribution hangs on a package management system as a foundation, and as a result the packaging systems are quite advanced, while Windows is stuck with those pesky installation wizards. There have been several stabs to implement a package system for Windows (see &lt;a href="http://www.logilab.org/blogentry/9861"&gt;here&lt;/a&gt;), but none seem to have caught on.&lt;br /&gt;
&lt;br /&gt;
There are three main disadvantages on not having good package management: tedium of manual installation, no dependency resolution and no system-wide automatic updates. In practice they are less important than it might seem. Installation wizards are indeed tedious, but in terms of time I found them to be quick enough to get through. Moreover,&amp;nbsp;apps tend to be less specialized and more encompassing than Linux utilities, and as a result you do not need to install as many things as in Linux. For the same reason dependency resolution is not as important: there are few dependencies in general. As for automatic updates, most high-profile apps have integrated mechanisms to deal with that, however, I found that those mechanisms tended to result in nagging the user with messages. After a while I started ignoring the update notifications. I suspect that happens to many users.&lt;br /&gt;
&lt;br /&gt;
The one thing that Windows has going for it is simplicity. You download installation binaries and you run them, and that's it. Linux package systems tend to be very complicated, and if (when) they break, you will need serious sysadmin chops to deal with the problem. Also installing specific versions (either older ones, or newer ones not yet available in the distro) of specific apps/libraries can be unnecessarily complicated, and the dependency graph limits your actions. In my experience, Windows does well enough without all this complexity as long as you don't reinstall your system too often.&lt;br /&gt;
&lt;br /&gt;
As for the other complaints, I frequently run into the restriction of moving/editing files opened by another application. Coming from Linux, that one is stupidly annoying. Furthermore, it is frustrating not to be able to move inactive (or stuck) background windows. I really miss my unified filesystem namespace. Also there's quite a bit of nagging in general on Windows which I would rather do without. In the end, these are not dealbreakers though.&lt;br /&gt;
&lt;br /&gt;
In my next (and probably final) post I will discuss software development on Windows.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-5783503686715561321?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/5783503686715561321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=5783503686715561321' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/5783503686715561321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/5783503686715561321'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2010/12/windows-iii-packaging-nitpicks.html' title='Windows (III): Packaging &amp; nitpicks'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-5364377296666324083</id><published>2010-12-01T17:13:00.002+02:00</published><updated>2010-12-01T21:55:30.090+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><title type='text'>Windows (II): User Interface</title><content type='html'>(This is a part of a series of posts on my recent experience with Windows. See &lt;a href="http://blog.miliauskas.lt/2010/11/windows-i.html"&gt;Windows (I)&lt;/a&gt; for the first post.)&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
The Windows user interface is definitely acceptable. The charge that it is too colorful or toy-like is completely unfounded. Rather, perhaps geeks should spend less time looking at their gray Motif boxy controls. In terms of speed, the UI is generally more responsive than on Linux, though maybe less so than previous versions of Windows (that could be because my Intel video IGP is a slouch).&lt;br /&gt;
&lt;br /&gt;
An interesting observation is that apps are almost as heterogeneous in terms of interface as in GNU/Linux, even though the standard controls are ubiquitous. Even apps by Microsoft can be separated into different "generations" of UI (e.g., folder windows, Control Panel,&amp;nbsp;Microsoft Office). &amp;nbsp;Also it is clear that generally more attention is paid to UI and usability by app developers, although perhaps not as much as in Apple products.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
The greatest asset and the worst offender at the same time, by far, is the overall GUI orientation of the system. Needless to say, it aids discoverability, but reduces scripting capabilities. Problem is, even if you do not need to write scripts per se, command-line actions are useful because they can be repeated and chained very easily, using shell history. In Windows, I occasionally find myself doing much repetitive clicking that would likely be an "Alt-Tab Up Enter" (or sometimes just one key) sequence in Linux. Moreover,&amp;nbsp;the lack of good standartized scripting is a huge pain during app deployments which tend be repetetive. I did not like Windows on servers before, and I do not like it now.&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
To be fair, my complaints about scripting capabilities may be partly moot because I have only used vanilla Windows batch files, and have not looked at all into&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Windows_PowerShell"&gt;Windows PowerShell&lt;/a&gt;, which is a new-generation scripting tool. The&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Windows_PowerShell#Examples"&gt;examples&amp;nbsp;&lt;/a&gt;are fairly impressive. The language has a nice look and is clearly powerful, but also looks somewhat complicated which keeps me away until I find a good reason to learn it.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
Initially I missed workspaces. The one app I found that was supposed to emulate workspaces would take several seconds to switch the workspace, so it was completely unusable. I learned to do without them rather quickly though. Actually I'm starting to think that using many workspaces is a sign that you are doing too many things at once and also they are an invitation to distraction (how many of you have a "blog reader" workspace right aside your "work" workspace, ready at your fingertips at a moment's notice?). Workspaces do have one killer feature: you can jump directly to a given workspace instead of cycling through windows. This is very useful when working with more than two apps, in which case without workspaces you are forced to think about the morphing Alt-Tab queue when switching windows.&lt;br /&gt;
&lt;br /&gt;
Speaking about UI generations, I much prefer the ribbon toolbars of the new Office. The still-prevalent toolbars with zillions of old-style 32x32 (or 16x16) toolbar icons are really ugly. Typically only a few of the toolbar buttons are actually useful, and they make the user interface unnecessarily cramped and busy. The move to fewer and larger toolbar buttons is definitely on the right track.&lt;br /&gt;
&lt;br /&gt;
The explorer context menus also tend to grow crazy long. Every app wants to get in there, and in the end you have a context menu that takes up half a screen vertically. Needless to say, most of those items are not used much. Sure, you can opt out during app installation, but at that time it is difficult to say how useful the context menu item will be, and there's no easy way&amp;nbsp;(i.e. easier than just ignoring the cruft)&amp;nbsp;to remove the entries afterwards.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
In my coming posts I will cover package management and application development on Windows.&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-5364377296666324083?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/5364377296666324083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=5364377296666324083' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/5364377296666324083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/5364377296666324083'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2010/12/windows-ii-user-interface.html' title='Windows (II): User Interface'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-4959454925153026474</id><published>2010-11-25T06:15:00.003+02:00</published><updated>2010-12-01T17:17:12.019+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><title type='text'>Windows (I)</title><content type='html'>I have been helping with an overdue web app project lately, and the project uses ASP.NET MVC, so I have had to use Windows for most of my day. Since I had been using GNU/Linux almost exclusively since 2003, this is quite an adventure (imagine trying out GNU/Linux after a seven year break). It is not nearly as bad as I thought it would be, even though I am using the not-so-well-liked Windows Vista which came pre-installed with my computer.&lt;br /&gt;
&lt;br /&gt;
The first thing that struck me is how much less important the OS is when compared to the situation a few years ago: a lot of the applications I depend on are web-based (GMail, Google Calendar, Google Docs, &lt;a href="http://springpadit.com/"&gt;Springpad&lt;/a&gt;), and the ones that are not web-based are multiplatform and installable with a few clicks (&lt;a href="http://www.vim.org/"&gt;GVim&lt;/a&gt; comes to mind). In fact, I do not think there is a single piece of software that I &lt;i&gt;really&amp;nbsp;&lt;/i&gt;missed in Windows. (An interesting corollary of this observation is that it should be equally easy to migrate to GNU/Linux nowadays.)&lt;br /&gt;
&lt;br /&gt;
The one thing where the operating system matters is hardware support, and I do not think I have to say much here. After years of whack-a-mole GNU/Linux upgrades which would fix support for one component but break another (for things as essential as video and sound), it was absolutely&amp;nbsp;&lt;i&gt;weird&lt;/i&gt;&amp;nbsp;having all hardware work properly at the same time (sound after suspend! no video glitches! high quality webcam picture!). There is no point recounting the reasons why hardware support in Linux is as it is, but now I am starting to think that Linux users do tend to suffer from a sort of Stockholm syndrome regarding hardware support; I know I did.&lt;br /&gt;
&lt;br /&gt;
The other important thing that operating systems do is resource management, and I did not have problems here either. In fact, I liked the virtual memory behaviour much better: when Windows ran out of memory (I had filled up the smallish Windows partition and there was no space left for the swap file to grow), it started rejecting malloc calls from applications, but the system was kept alive and responsive, and I could close apps and clean up the mess without much trouble. In Ubuntu, with the default settings, whenever a runaway process ate too much RAM, the system would start thrashing so hard that it would be very difficult to fix. My standard procedure (switch to text console, log in, find and kill app using command line tools) would take &lt;i&gt;minutes&lt;/i&gt; and was so annoying that I would sometimes just reset the computer instead. And in the end, even if I did not reset, an important app would possibly be killed anyway. I know there are kernel parameters for tweaking this behaviour (swappiness?), but I never got around to figuring them out as this situation does not arise that frequently, and testing is painful.&lt;br /&gt;
&lt;br /&gt;
I did not like the Windows FS security model. ACLs are much more complicated and thus less transparent that the Unix approach, even though they are more powerful. My main gripe with them is that I do not know a good way to display them easily (as with &lt;i&gt;ls -l&lt;/i&gt; in Unix). I have not had to deal with them much though.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
I have had no stability issues. It seems that this argument should be put to rest.&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
Long blog posts are annoying, so I will leave the user interface, the developer experience and my complaints with the system for separate posts (edit: you can now read my &lt;a href="http://blog.miliauskas.lt/2010/12/windows-ii-user-interface.html"&gt;next post&lt;/a&gt;&amp;nbsp;about the&amp;nbsp;UI).&lt;/div&gt;
&lt;ul&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-4959454925153026474?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/4959454925153026474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=4959454925153026474' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/4959454925153026474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/4959454925153026474'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2010/11/windows-i.html' title='Windows (I)'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-3110332634697172948</id><published>2010-11-21T01:18:00.001+02:00</published><updated>2010-11-21T16:48:30.677+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>Laptop trouble</title><content type='html'>My trusty somewhat-old laptop has been under the weather lately. It will not boot when it's cold, and it's fairly picky. ~20 °C seems too cold already; so I have to heat it up at little.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/_zn_T2bmMZn0/TOhUgdA-M5I/AAAAAAAAAOk/ddwB28XhNIw/s1600/IMG_0031.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/_zn_T2bmMZn0/TOhUgdA-M5I/AAAAAAAAAOk/ddwB28XhNIw/s320/IMG_0031.JPG" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;
Now that winter is coming, this needs to be done almost every morning, and that is extremely annoying. Does anybody have an idea of what could be wrong? It seems that the problem is not just a loose connection, as the laptop goes up in stages:&lt;br /&gt;
&lt;br /&gt;
1) when the power button is pressed the power LED will blink for a split-second and nothing will happen,&lt;br /&gt;
2) the LED will light up for slightly longer, but the laptop still will not boot,&lt;br /&gt;
3) the laptop starts booting but shuts off spontaneously after while on the BIOS screen,&lt;br /&gt;
4) the laptop goes through the BIOS screen, but shuts down before showing the boot menu.&lt;br /&gt;
Past that, apparently the CPU generates enough heat for stable operation.&lt;br /&gt;
This is fairly complicated behaviour for a hardware problem. I wonder, maybe the power supply is at fault? Any ideas, anyone? This is a good excuse to buy a new laptop, but I would rather not splurge right before Christmas season.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-3110332634697172948?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/3110332634697172948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=3110332634697172948' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/3110332634697172948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/3110332634697172948'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2010/11/laptop-trouble.html' title='Laptop trouble'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_zn_T2bmMZn0/TOhUgdA-M5I/AAAAAAAAAOk/ddwB28XhNIw/s72-c/IMG_0031.JPG' height='72' width='72'/><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-8887693426622716260</id><published>2010-11-15T01:22:00.001+02:00</published><updated>2010-11-22T12:06:03.284+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='music'/><title type='text'>Verdi's Requiem</title><content type='html'>The choir I sing in (&lt;a href="http://www.promusica.lt/"&gt;Pro Musica&lt;/a&gt;) will be performing on January 22nd in Bremen, Germany. Together with two local choirs we will perform Verdi's &lt;i&gt;Requiem&lt;/i&gt;, which is absolutely fabulous. See for yourself:
&lt;br /&gt;
&lt;object height="385" width="480"&gt;&lt;param name="movie" value="http://www.youtube.com/v/TVjDP0vlem4?fs=1&amp;amp;hl=lt_LT&amp;amp;color1=0x3a3a3a&amp;amp;color2=0x999999"&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/TVjDP0vlem4?fs=1&amp;amp;hl=lt_LT&amp;amp;color1=0x3a3a3a&amp;amp;color2=0x999999" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;

&lt;br /&gt;
(Also try &lt;a href="http://www.youtube.com/watch?v=pW1Uc-grcMs"&gt;Solti's version&lt;/a&gt; for better sound quality, but no video.)&lt;br /&gt;
It's going to be a busy month preparing for the concert. Verdi's melodies are not complicated, but he's crazy with dynamics: I think it's the first time I've seen a quintuple pianissimo (&lt;i&gt;ppppp&lt;/i&gt;) or a quadruple fortissimo (&lt;i&gt;ffff&lt;/i&gt;) in sheet music.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-8887693426622716260?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/8887693426622716260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=8887693426622716260' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/8887693426622716260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/8887693426622716260'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2010/11/verdis-requiem.html' title='Verdi&apos;s Requiem'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-6328269201313463577</id><published>2010-11-03T22:55:00.000+02:00</published><updated>2010-11-04T02:33:38.934+02:00</updated><title type='text'>Living a monastic life for 10 days</title><content type='html'>&lt;p&gt;About a month ago, at the end of August, I finished a 10-day Vipassana meditation course. This was probably one of the more extreme activities I have ever participated in, and it's well worth a blog post.&lt;/p&gt;

&lt;p&gt;I found out about the course in a ridiculously trivial way, by following a link in a Reddit comment (I wonder if I could track down that comment...).  The &lt;a href="http://www.dhamma.org/"&gt;website&lt;/a&gt; referenced by the comment contained (almost) no new-agey mumbo-jumbo and looked legit in general. I also appreciated the fact that this was a relatively serious and intensive course, which should be enough to form a reasonably founded opinion on meditation in general. When learning sporadically, in small bits, it is hard to say whether the material itself is no good, or you just do not understand it yet and need to study more; I was quite skeptical towards the practice, but wanted to give it fair trial. I was quite impressed that there was a course available in Lithuania, a few hours by train from where I live. Finally, the course was free (by tradition Vipassana is taught without monetary compensation). I went ahead and signed up for a standard introductory 10-day course.&lt;/p&gt;

&lt;p&gt;Vipassana (also called insight meditation) is a meditation technique allegedly coming back from Gautama Buddha himself (well, all the traditions like to claim that origin...). It has been experiencing a renaissance, partly due to an &lt;a href=""&gt;organization&lt;/a&gt; set up by a meditation teacher S. N. Goenka which has founded meditation centers all over the world. &lt;/p&gt;

&lt;p&gt;The essence of Vipassana is a method of teaching your mind to &lt;em&gt;act&lt;/em&gt; instead of merely &lt;em&gt;reacting&lt;/em&gt; to outside stimuli such as pain, anger of other people or hardships. The technique provided is to monitor your sensations, watch them with &lt;a href="http://en.wikipedia.org/wiki/Equanimity"&gt;equanimity&lt;/a&gt; and suspend any reaction, and slowly it sinks in that all things are temporary and you can choose what to react to and how. That's the basic idea; I don't want to go deep into exposition of Vipassana as there is plenty of information about that (also at the same time the information is almost useless because you have to experience it to really understand it). Instead, I will sure some of the more personal remarks and experiences.&lt;/p&gt;

&lt;p&gt;The course took place in an cottage near Kretinga, housing around 50 people. The living conditions were absolutely great, and this would have been a true holiday if not for the regime and the rules. The day would start very early, at 4 AM (ending at around 9:30 PM), and we'd do about 12 hours of meditation in total inbetween, with occasional breaks, but the most gruesome part is that no communication at all was allowed with anyone except the manager of the camp (and the teacher during a specified time). That gets to you after a few days, but still, there are people around you, so it's bearable; on the other side, the senses (touch, smell) become very acute. The food was taken care of by volunteers (students who have finished the course), and I could say it was quite good actually. The goal, of course, was to keep the environment from interfering with meditation, and I think it was done very well.&lt;/p&gt;

&lt;p&gt;The presentation of the actual technique also did not disappoint.  Each day a new step would be introduced, with the whole day to practice before moving on. Looking back, the pacing worked well. Every day in the evening there were lectures on theory. They were somewhat informative, but also sometimes annoyingly primitive and verbose. The little mistakes, holes in logic and slight doses of mumbo-jumbo almost drove me nuts by the middle of the course, until I learned not to react to them. Despite the shortcomings of presentation, the simplicity and lucidity of the practice and lightness of theoretical baggage really appealed to me. The whole organisation in general gave the impression of complete transparency, with no strings attached, no financial interests in play and no agitation for further involvement.&lt;/p&gt;

&lt;p&gt;While there are many meditation techniques, I am happy that I've gone with Vipassana in particular for one reason: Vipassana meditation uses no artificial tools to help you concentrate, such as mantras, visualisations, counting, etc. Such methods make concentration &lt;em&gt;much&lt;/em&gt; easier, but they also create a dependence on the methods themselves. I appreciate the purity of Vipassana in this regard.&lt;/p&gt;

&lt;p&gt;Not everything in the practice is roses though. First, a particular worldview supported by Vipassana is presented as "scientific" and supposedly "the right way to live", and if even if you don't agree, "the truth" of Vipassana will become obvious to you with time. This is a distinctive mark of ideologies. The thing that makes everything break is the reincarnation, which is generally assumed as true, even if it's not shoved down the student's throat. Every rationalization of a world view has a "white lie" (usually related to the concept of eternity somehow) at the core, and in this context reincarnation is it. Given what we know now about the relationship between the mind and the body, reincarnation is absolutely ridiculous and completely untenable, and that breaks all "moral" reasoning for practicing meditation as opposed to doing something else. I'm not the first to bring up this problem, there's plenty of material about it online.&lt;/p&gt;

&lt;p&gt;The second slippery idea is that the concept of "negative happiness" is central in Vipassana, that is: happiness is defined as lack of suffering. This point is not that unreasonable actually, from personal experience I could indeed call the state of non-suffering happiness, but there is definitely something missing when compared to the state of mind when I'm truly, positively happy. Whether you consider that something important or not, it's definitely there.&lt;/p&gt;

&lt;p&gt;Third, Vipassana suggests that it is only you who is at fault when your inner state is disturbed; the world affects you as much as you let it, and in order to find happiness you should learn to control the "interface" rather than the outside world, which will usually not behave as you want.  This may be correct, but sometimes it could just be easier to fix the world rather than change yourself, and I have the suspicion that it this is much more frequently the case in the modern world compared to the pre-modern environment. (This is one of the points which break when reincarnation is rejected, as with reincarnation you have the whole eternity to fix yourself.)&lt;/p&gt;

&lt;p&gt;While the complaints are serious, they do not mean complete rejection of Vipassana but rather integration among the various other techniques available. The actual meditation technique is still great for gaining and maintaining mental composure, reducing anxiety and improving well-being. Now, if I could only get used to meditating regularly...&lt;/p&gt;

&lt;p&gt;If you have the chance, I highly recommend you try out an introductory 10-day course. There is little to lose and a lot to gain. And if you do go ahead, I have two hints. First, do not even think about leaving the course before it's over. Any hardships are temporary and will be overcome quickly. Second, use the time with the teacher, those interactions were very helpful to me. Also, given the "noble silence", talking to someone once in a while will not hurt.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-6328269201313463577?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/6328269201313463577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=6328269201313463577' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/6328269201313463577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/6328269201313463577'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2010/09/living-monastic-life-for-10-days.html' title='Living a monastic life for 10 days'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-2967594896151762477</id><published>2010-07-29T02:33:00.009+03:00</published><updated>2010-07-29T10:43:43.912+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Python course projects</title><content type='html'>&lt;p&gt;
This spring I read a course on &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt; in &lt;a href="http://www.vu.lt/"&gt;Vilnius University&lt;/a&gt;, Department of Mathematics and informatics. The course was not mandatory, which I suspect is one of the reasons why my students were quite a bright and motivated bunch. I began the course with a brief introduction to the Python language and the standard library, then dedicated a few lectures to &lt;a href="http://www.djangoproject.com/"&gt;Django&lt;/a&gt; and in the remainder I covered various libraries (GUI toolkits, Pygame) and techniques (testing, debugging, optimization).
&lt;/p&gt;

&lt;p&gt;One of the major tasks of the course (and the deciding factor in the final valuation) was to develop a project using Python. The students were given complete freedom over the topic of the project and the tools used, as long as Python was involved. The quality of the result varied, of course; had I given concrete tasks, the low bar would definitely have been higher. However, I am happy with how things turned out.
&lt;/p&gt;

&lt;p&gt;Probably the best-executed project was &lt;a href="http://www.1000-online.com/"&gt;1000 Online&lt;/a&gt;, an online multiplayer card game (see &lt;a href="http://www.1000-online.com/rules"&gt;rules&lt;/a&gt;). It was developed by Vytautas Karpavičius. Vytautas apparently had prior experience with Python and Django, nevertheless, the quality of the app (and the code behind it) is impressive. Among the other projects, &lt;a href="http://gegute.lt/"&gt;Gegute.lt&lt;/a&gt;, a Lithuanian clone of &lt;a href="http://www.reddit.com/"&gt;Reddit&lt;/a&gt; is still up and running. It's nothing too fancy, but looks quite clean for a university project. Other projects perhaps were not perfectly executed, but were very interesting conceptually. Jonas Keturka developed a bot (&lt;a href="http://bitbucket.org/kukmedis/pyproj"&gt;BitBucket&lt;/a&gt;) for the online strategy game &lt;a href="http://travian.com/"&gt;Travian&lt;/a&gt;. Marius Damarackas developed a web-based guess-the-song game. He used YouTube for the song material and Last.fm (IIRC) to make you guess among similar songs, so that it would not be too easy. Andrius Chamentauskas developed a Puyo Pop clone (&lt;a href="http://github.com/sinsiliux/Puyo"&gt;GitHub&lt;/a&gt;) with PyGame, complete with multiplayer and an AI. Paulius Budzinskas worked towards his course paper by developing a bacteria movement modelling and visualisation app (&lt;a href="http://github.com/ePaulius/Bakt_modeliavimas"&gt;GitHub&lt;/a&gt;; Lithuanian only). David Abdurachmanov developed a spell-checker bot for WikiAnswers.com, with a really baroque and sophisticated architecture. I believe he has applied to Google Summer of Code with that project; I wonder how that is working out.&lt;/p&gt;

&lt;p&gt;For reference, you can find links to all student repositories on GitHub/BitBucket in &lt;a href="http://python.gintas.net/wiki/StudentuSarasas"&gt;this list&lt;/a&gt;. Beware: some of them may be documented/commented in Lithuanian.
&lt;/p&gt;

&lt;p&gt;Another interesting effect of the course was that people started using Python in other related courses, for example in Mathematical Modelling and Numeric Methods. I even heard that the lecturer was impressed and expressed interest in learning Python. Another lecturer, this time a statistician, was interested in teaching and using &lt;a href="http://www.sagemath.org/"&gt;SAGE&lt;/a&gt; at lab practice. Feeling such 'ripples' going through the department sure felt nice.
&lt;/p&gt;

&lt;p&gt;By the way, the university also offers lectures on Ruby, read by Saulius Grigaitis. I took some inspiration from him for the course form and content.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-2967594896151762477?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/2967594896151762477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=2967594896151762477' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/2967594896151762477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/2967594896151762477'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2010/07/python-course-projects.html' title='Python course projects'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-1684209953518440826</id><published>2010-05-24T19:30:00.001+03:00</published><updated>2010-09-16T22:03:56.824+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='running'/><title type='text'>Riga marathon</title><content type='html'>&lt;p&gt;I participated in the &lt;a href="http://www.nordearigasmaratons.lv/"&gt;Riga marathon&lt;/a&gt; and ran the full 42km! The time (4:39) isn't great at all, but I'm happy to have finished at all!&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zn_T2bmMZn0/TJJpACVNN1I/AAAAAAAAAOM/lsrcT_8dVhU/s1600/b1274818344.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 267px;" src="http://2.bp.blogspot.com/_zn_T2bmMZn0/TJJpACVNN1I/AAAAAAAAAOM/lsrcT_8dVhU/s400/b1274818344.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5517587942829012818" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-1684209953518440826?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/1684209953518440826/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=1684209953518440826' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/1684209953518440826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/1684209953518440826'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2010/05/riga-marathon.html' title='Riga marathon'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_zn_T2bmMZn0/TJJpACVNN1I/AAAAAAAAAOM/lsrcT_8dVhU/s72-c/b1274818344.jpg' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-5484551814550469122</id><published>2009-12-16T21:52:00.003+02:00</published><updated>2009-12-16T22:56:17.014+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Android apps</title><content type='html'>&lt;p&gt;I've recently gotten myself an &lt;a href="http://www.android.com"&gt;Android&lt;/a&gt; phone. The Android app market is not as mature as iPhone's App Store, but there is a lot of applications, and plenty of chaff to separate the wheat from. I found most of the apps I use by browsing "top Android apps" lists on the web, so I am putting up a similar list here in case someone finds it useful.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Everyday apps&lt;/strong&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;Astrid Task/Todo List&lt;/em&gt; - a great To-Do list app that integrates with &lt;a href="http://www.rememberthemilk.com"&gt;Remember The Milk&lt;/a&gt; &lt;/li&gt;
  &lt;li&gt;Quick Calendar - an "upcoming events" widget&lt;/li&gt;
  &lt;li&gt;CardioTrainer - nice jogging app, records routes using GPS, integrates with music player&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Language tools&lt;/strong&gt;
&lt;ul&gt;
  &lt;li&gt;Thesaurus Free - a thesaurus&lt;/li&gt;
  &lt;li&gt;Free Dictionary Org - reference dictionary&lt;/li&gt;
  &lt;li&gt;QuickDic German Dictionary - an English-German-English dictionary&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Media content&lt;/strong&gt;
&lt;ul&gt;
  &lt;li&gt;Listen - an app to find audio content online&lt;/li&gt;
  &lt;li&gt;Mother TED - search and view TED talks&lt;/li&gt;
  &lt;li&gt;TuneWiki - music, song lyrics&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Games&lt;/strong&gt;
&lt;ul&gt;
  &lt;li&gt;Lumbricidae - guide a worm using your accelerometer&lt;/li&gt;
  &lt;li&gt;Flying High - plane flying (also accelerometer-based)&lt;/li&gt;
  &lt;li&gt;miniMatcher - memory game&lt;/li&gt;
  &lt;li&gt;Iconic Memory - another memory game&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;


&lt;li&gt;&lt;strong&gt;Cool apps&lt;/strong&gt;
&lt;ul&gt;
  &lt;li&gt;Phonalyzr - pretty phone call (and SMS) stats&lt;/li&gt;
  &lt;li&gt;Shazam - identify a song by recording a short snippet; possibly one of the coolest apps available&lt;/li&gt;
  &lt;li&gt;SnapTell - look up product information by scanning a barcode (or even by snapping a photo!)&lt;/li&gt;
  &lt;li&gt;Backgrounds - background images&lt;/li&gt;
  &lt;li&gt;Google Sky Map - shows constellations&lt;/li&gt;
  &lt;li&gt;Layar Reality Browser 3.0 - a fancy-looking Augmented Reality app&lt;/li&gt;
&lt;/ul&gt;


&lt;li&gt;&lt;strong&gt;Music&lt;/strong&gt;
&lt;ul&gt;
  &lt;li&gt;Sonorox - tune composition for everyone (the pentatonic scale is great, isn't it?)&lt;/li&gt;
  &lt;li&gt;Loops! Lite - another music composition app&lt;/li&gt;
  &lt;li&gt;Tuner - gStrings - a guitar tuner&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;


&lt;li&gt;&lt;strong&gt;Miscellaneous&lt;/strong&gt;
&lt;ul&gt;
  &lt;li&gt;Task Manager - a process monitor utility, useful for checking up on app resource usage&lt;/li&gt;
  &lt;li&gt;Currency - a currency converter&lt;/li&gt;
  &lt;li&gt;Sleep Logger - a very simple, but useful app for tracking your sleep habits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-5484551814550469122?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/5484551814550469122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=5484551814550469122' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/5484551814550469122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/5484551814550469122'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2009/12/android-apps.html' title='Android apps'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-7741142431868328975</id><published>2009-09-28T01:44:00.003+03:00</published><updated>2009-09-28T01:47:10.736+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='piano'/><title type='text'>Piano improv #2</title><content type='html'>Here's a recording of a recent improvisation.  It's very simple, but I'm quite happy with it.

&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube-nocookie.com/v/wQeNXwps9ow&amp;hl=en&amp;fs=1&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-nocookie.com/v/wQeNXwps9ow&amp;hl=en&amp;fs=1&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/9890172-7741142431868328975?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/7741142431868328975/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=7741142431868328975' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/7741142431868328975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/7741142431868328975'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2009/09/piano-improv-2.html' title='Piano improv #2'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-5209446679094653452</id><published>2009-05-14T01:15:00.003+03:00</published><updated>2009-05-14T01:21:05.861+03:00</updated><title type='text'>Lęšis.lt</title><content type='html'>&lt;p&gt;A friend of mine has recently launched a contact lens e-shop, &lt;a href="http://www.lesis.lt"&gt;lesis.lt&lt;/a&gt;.  It only ships in Lithuania at the moment, but if you're based here, have a look, you might find it useful.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-5209446679094653452?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/5209446679094653452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=5209446679094653452' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/5209446679094653452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/5209446679094653452'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2009/05/lesislt.html' title='Lęšis.lt'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-1820680421562431513</id><published>2009-04-15T15:35:00.002+03:00</published><updated>2009-04-15T15:40:39.599+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='piano'/><title type='text'>Piano improv</title><content type='html'>My today's experiments on piano:

&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube-nocookie.com/v/rOMMrTmCA6s&amp;hl=en&amp;fs=1&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-nocookie.com/v/rOMMrTmCA6s&amp;hl=en&amp;fs=1&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/9890172-1820680421562431513?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/1820680421562431513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=1820680421562431513' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/1820680421562431513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/1820680421562431513'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2009/04/piano-improv.html' title='Piano improv'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-9045067239490905851</id><published>2009-03-04T17:20:00.002+02:00</published><updated>2009-03-04T17:39:41.234+02:00</updated><title type='text'>Peer reviewed blogging</title><content type='html'>&lt;p&gt;Here's an idea: what if there was a website where you could upload a topical blog post, which would then be reviewed and edited by experts in the area and then posted on that website? Such a process would ensure that articles are at least well-named, appropriately tagged, well-structured and not methodologically deficient, and could result in a database of articles of decent quality. Would you upload your blog posts that are juicier in terms of content to such a site? Would you volunteer to do reviews and editing?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-9045067239490905851?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/9045067239490905851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=9045067239490905851' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/9045067239490905851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/9045067239490905851'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2009/03/peer-reviewed-blogging.html' title='Peer reviewed blogging'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-4083326266918150069</id><published>2008-12-26T22:14:00.003+02:00</published><updated>2008-12-26T22:34:36.411+02:00</updated><title type='text'>Hacker spaces</title><content type='html'>&lt;p&gt;I just found out about &lt;a href="http://hackerspaces.org/wiki/Hacker_Spaces"&gt;hacker spaces&lt;/a&gt;.  For a nice example of a hack space, see &lt;a href="http://metalab.at/wiki/English"&gt;The Metalab&lt;/a&gt;.  Such places seem quite suitable for work on individual public projects and for growing teams by sorting out the wheat from the chaff.&lt;/p&gt;

&lt;p&gt;
It's a pity there are no hacker spaces &lt;a href="http://hackerspaces.org/wiki/List_of_Hacker_Spaces"&gt;east of Vienna&lt;/a&gt;.  I wonder if one could be set up in Vilnius.  There probably are enough people around. but quite a bit of organising work (see &lt;a href="http://hackerspaces.org/w/images/8/8e/Hacker-Space-Design-Patterns.pdf"&gt;Hackerspace Design Patterns [PDF]&lt;/a&gt;) needs to be done to establish a hacker space.  I would do it, but I am overbooked as it is.  Any takers?
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-4083326266918150069?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/4083326266918150069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=4083326266918150069' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/4083326266918150069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/4083326266918150069'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/12/hacker-spaces.html' title='Hacker spaces'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-375537370717132396</id><published>2008-12-04T15:22:00.003+02:00</published><updated>2008-12-04T15:36:21.294+02:00</updated><title type='text'>Python 3.0</title><content type='html'>&lt;p&gt;Python 3.0 (also known as Python 3000) has been released yesterday, so I thought I'd give it a try.  It turns out that a recent release candidate is in official Ubuntu 8.10 (intrepid) repositories, so I did not even need to compile anything: &lt;code&gt;apt-get install python3.0&lt;/code&gt; and we're done.  You may want to read the &lt;a href="http://docs.python.org/dev/3.0/whatsnew/3.0.html"&gt;summary of changes&lt;/a&gt; from Python 2 beforehand.&lt;/p&gt;

&lt;p&gt;Here's a quick demo of unicode identifiers:&lt;/p&gt;

&lt;pre&gt;
&gt;&gt;&gt; 二 = 2
&gt;&gt;&gt; 四 = 二 + 二
&gt;&gt;&gt; 四
4
&gt;&gt;&gt; import math
&gt;&gt;&gt; π = math.pi
&gt;&gt;&gt; α = π/3
&gt;&gt;&gt; math.sin(α)
0.8660254037844386
&lt;/pre&gt;

&lt;p&gt;This isn't quite &lt;a href="http://en.wikipedia.org/wiki/APL_(programming_language)"&gt;APL&lt;/a&gt; yet, but we are getting closer!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-375537370717132396?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/375537370717132396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=375537370717132396' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/375537370717132396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/375537370717132396'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/12/python-30.html' title='Python 3.0'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-4844667379662444539</id><published>2008-11-28T23:01:00.003+02:00</published><updated>2008-11-28T23:13:28.921+02:00</updated><title type='text'>Silly translations</title><content type='html'>&lt;p&gt;Since I do some work on software translation, I have seen my fair share of silly translations (in my case from English to Lithuanian).  Here's my latest find: in Gmail there is a choice of chat list for every person in the address book, and there are four options: &lt;em&gt;Auto&lt;/em&gt;, &lt;em&gt;Always&lt;/em&gt;, &lt;em&gt;Never&lt;/em&gt;, and &lt;em&gt;Block&lt;/em&gt;. The Lithuanian translation of the option "Auto" is ... "Automobiliai" which means "Cars".  Took me a while to figure out what happened the first time I saw it.  This ranks right next to the already classic wizzard button translation "Kitas", "Kitas", "Suomių" for "Next", "Next", "Finish" (translated back to English that would be "Next", "Next", "Finnish" – as the language of Finns) and my personal favourite: Finnish translated as "Finikiečių" (Phoenician).&lt;/p&gt;

&lt;p&gt;FWIW I tried to apply for access to Gmail translations (there are many more inconsistencies, mistakes and screwups in there), but it seems that Google is not interested.  I wonder if they have any translation quality control at all.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-4844667379662444539?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/4844667379662444539/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=4844667379662444539' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/4844667379662444539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/4844667379662444539'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/11/silly-translations.html' title='Silly translations'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-4639673917446776109</id><published>2008-11-21T23:55:00.002+02:00</published><updated>2008-11-22T00:18:40.137+02:00</updated><title type='text'>Computer-generated music</title><content type='html'>&lt;p&gt;&lt;a href="http://arts.ucsc.edu/faculty/cope/experiments.htm"&gt;EMI&lt;/a&gt; (Experiments in Musical Intelligence) by David Cope changed my mind on the state of computer music generation software.  I had come across numerous "music generation" programs, but it would have been a long stretch to call their results "music".  They would produce, at best, strange patterns of beeps.  I had heard of a live "jazz improvisation gig partner" machine (probably &lt;a href="http://www.sigchi.org/chi97/proceedings/paper/wfw.htm"&gt;this one&lt;/a&gt;), but EMI is on a completely different level – just listen to &lt;a href="http://arts.ucsc.edu/faculty/cope/mp3page.htm"&gt;the MP3 samples&lt;/a&gt;.  Sure, in the end it is mostly splicing and rehashing of existing pieces, but Cope claims that in blind tests even experienced listeners would sometimes confuse an original piece by a composer and a composition by EMI.  In other words, EMI passed the equivalent of a Turing test for music generation software.  If that is not impressive, I do not know what is.&lt;/p&gt;

&lt;p&gt;Unfortunately David Cope's site is skimpy on the details of how EMI works, even though there is an extensive &lt;a href="http://arts.ucsc.edu/faculty/cope/bibliography.htm"&gt;bibliography&lt;/a&gt;  (note the time span: 20 years!).  At least some information can be gathered from the webpages of his numerous books.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-4639673917446776109?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/4639673917446776109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=4639673917446776109' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/4639673917446776109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/4639673917446776109'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/11/computer-generated-music.html' title='Computer-generated music'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-3030470125947047268</id><published>2008-11-20T22:33:00.002+02:00</published><updated>2008-11-20T22:41:15.044+02:00</updated><title type='text'>Book meme</title><content type='html'>&lt;p&gt;I am a bit of a bookworm, so I could not resist &lt;a href="http://leonardof.org/2008/11/14/book-meme/en/"&gt;this meme&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grab the nearest book.&lt;/li&gt;
&lt;li&gt;Open it to page 56.&lt;/li&gt;
&lt;li&gt;Find the fifth sentence.&lt;/li&gt;
&lt;li&gt;Post the text of the sentence in your journal along with these instructions.&lt;/li&gt;
&lt;li&gt;Don't dig for your favorite book, the cool book, or the intellectual one: pick the CLOSEST.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The book is actually a Lithuanian translation, but I'll translate the sentence into English for you:&lt;/p&gt;

&lt;cite&gt;After entering the palace, he seduced the king's wife, killed the king with her help and seized his throne.&lt;/cite&gt;

&lt;p&gt;Can you guess which book the sentence is from?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-3030470125947047268?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/3030470125947047268/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=3030470125947047268' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/3030470125947047268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/3030470125947047268'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/11/book-meme.html' title='Book meme'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-7782153458070145443</id><published>2008-11-14T14:55:00.003+02:00</published><updated>2008-11-14T15:04:32.989+02:00</updated><title type='text'>Non-native LCD resolutions</title><content type='html'>&lt;p&gt;Now that LCD monitors have spread, I keep noticing one thing: lots of public places with computers have the resolution set to some non-native value.  Blur in cafes, libraries, everywhere!  It seems that people just do not notice the blurriness, and I do not really blame them – how could they know that there's a better resolution?  This makes me think that it would be a good idea to &lt;strong&gt;warn&lt;/strong&gt; the user on the desktop environment configuration level about reduced quality whenever the screen is an LCD and they are trying to switch to a non-native resolution.  A non-intrusive, but informative message could do the trick, I think.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-7782153458070145443?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/7782153458070145443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=7782153458070145443' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/7782153458070145443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/7782153458070145443'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/11/non-native-lcd-resolutions.html' title='Non-native LCD resolutions'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-1500589727555363107</id><published>2008-09-13T15:49:00.004+03:00</published><updated>2008-09-13T16:12:06.515+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Python syntax highlighting in LaTeX</title><content type='html'>&lt;p&gt;LaTeX provides a &lt;code&gt;listings&lt;/code&gt; package to typeset code.  The standard output is great for black-and-white printouts, but not for &lt;a href="http://latex-beamer.sourceforge.net/"&gt;beamer&lt;/a&gt; presentations, where a more dynamic color scheme would be suitable.  Having recently worked on slides with Python code, I have prepared a &lt;a href="http://licejus.lt/~gintas/files/pythonlisting.tex"&gt;file&lt;/a&gt; that you can include to get nice colourful code that looks good on a presentation:&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_zn_T2bmMZn0/SMu57ijEELI/AAAAAAAAAEQ/NUWu9gToz7U/s1600-h/latex-python.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_zn_T2bmMZn0/SMu57ijEELI/AAAAAAAAAEQ/NUWu9gToz7U/s400/latex-python.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5245490623540367538" /&gt;&lt;/a&gt;

&lt;p&gt;My code is based on a snippet found on &lt;a href="http://ubuntuforums.org/archive/index.php/t-331602.html"&gt;Ubuntu forums&lt;/a&gt;.  I added some more keywords and tweaked the color scheme to correspond to the one that IDLE uses (that color scheme is not ideal, but my audience uses IDLE for coding and I wanted some consistency).&lt;/p&gt;

&lt;p&gt;To use the package, copy the file to the same folder as your document and include it in the header:&lt;/p&gt;
&lt;pre&gt;
\include{pythonlisting}
&lt;/pre&gt;

&lt;p&gt;Then, to render code, use &lt;code&gt;python&lt;/code&gt; sections:&lt;/p&gt;

&lt;pre&gt;
\begin{python}
def foo():
    print "bar"
\end{python}
&lt;/pre&gt;

&lt;p&gt;Note that if you want to use this in a &lt;code&gt;beamer&lt;/code&gt; frame, you will have to mark the frame that contains Python code as &lt;code&gt;fragile&lt;/code&gt;, like this:&lt;/p&gt;

&lt;pre&gt;
\begin{frame}[fragile]{Some Python code}

\begin{python}
def foo():
    print "bar"
\end{python}

\end{frame}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-1500589727555363107?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/1500589727555363107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=1500589727555363107' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/1500589727555363107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/1500589727555363107'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/09/python-syntax-highlighting-in-latex.html' title='Python syntax highlighting in LaTeX'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_zn_T2bmMZn0/SMu57ijEELI/AAAAAAAAAEQ/NUWu9gToz7U/s72-c/latex-python.png' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-8126835753321715704</id><published>2008-09-13T15:22:00.003+03:00</published><updated>2008-09-13T15:38:26.333+03:00</updated><title type='text'>Better Russian-English dictionaries</title><content type='html'>&lt;p&gt;A reader called Kuno notes that there are now some good Russian-English dict-format dictionaries available online.  They are very likely better than the ones I extracted &lt;a href="http://gintasm.blogspot.com/2006/05/russian-to-english-dictionaries-on.html"&gt;a couple years ago&lt;/a&gt;.  The dictionary files suggested by Kuno can be &lt;a href="http://dictd.xdsl.by/dicts/"&gt;downloaded directly&lt;/a&gt;, fetched with rsync (&lt;code&gt;rsync rsync://dictd.xdsl.by/dicts/&lt;/code&gt;) or the server can be queried with a dict client (try "&lt;code&gt;dict -h dictd.xdsl.by -D&lt;/code&gt;" for a list of available dictionaries).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-8126835753321715704?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/8126835753321715704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=8126835753321715704' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/8126835753321715704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/8126835753321715704'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/09/russian-english-dictionaries-proper.html' title='Better Russian-English dictionaries'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-115305660076284449</id><published>2008-08-18T20:03:00.002+03:00</published><updated>2008-08-18T20:09:27.721+03:00</updated><title type='text'>Buffalo buffalo</title><content type='html'>"Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo" is a gramatically correct sentence!  See Wikipedia for an &lt;a href="http://en.wikipedia.org/wiki/Buffalo_buffalo_Buffalo_buffalo_buffalo_buffalo_Buffalo_buffalo"&gt;explanation&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-115305660076284449?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/115305660076284449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=115305660076284449' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115305660076284449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115305660076284449'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/08/buffalo-buffalo.html' title='Buffalo buffalo'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-4918566003811904645</id><published>2008-05-30T01:56:00.010+03:00</published><updated>2008-09-13T15:48:52.902+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>IronPython on Ubuntu</title><content type='html'>&lt;p&gt;After reading on &lt;a href="http://blog.jimmy.schementi.com/2008/05/sudo-apt-get-install-ironpython-thats.html"&gt;Jimmy Schementi's weblog&lt;/a&gt; that IronPython, the .NET implementation of Python, is just an &lt;code&gt;apt-get install ironpython&lt;/code&gt; away, I thought I'd give it a whirl.  Here's what I got.&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_zn_T2bmMZn0/SD8574w-2EI/AAAAAAAAADA/LGWk5VVk6OQ/s1600-h/ironpython-white.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_zn_T2bmMZn0/SD8574w-2EI/AAAAAAAAADA/LGWk5VVk6OQ/s400/ironpython-white.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5205943395276478530" /&gt;&lt;/a&gt;

&lt;p&gt;Huh? Maybe Microsoft took that "significant whitespace" thing a little too literally...&lt;/p&gt;
&lt;p&gt;It turns out that IronPython &lt;em&gt;really wants&lt;/em&gt; you to use a dark background (&lt;a href="https://bugs.launchpad.net/ubuntu/+source/ironpython/+bug/235898"&gt;bug report&lt;/a&gt;).&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_zn_T2bmMZn0/SD85m4w-2DI/AAAAAAAAAC4/N73lrUT2B5Q/s1600-h/ironpython-black.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_zn_T2bmMZn0/SD85m4w-2DI/AAAAAAAAAC4/N73lrUT2B5Q/s400/ironpython-black.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5205943034499225650" /&gt;&lt;/a&gt;

&lt;p&gt;Ah, so that's why the background of Jimmy's blog is black!&lt;/p&gt;

&lt;p&gt;As you can see from the screenshot, it's also a bit difficult to quit from the Ubuntu version of IronPython.  That weird symbol is a result of pressing &lt;code&gt;Ctrl+D&lt;/code&gt;.  Even &lt;code&gt;Ctrl+\&lt;/code&gt;, which usually helps in such cases, only produces a nasty .NET CLR traceback with no ill effects to the interpreter.&lt;/p&gt;

&lt;p&gt;On the bright side, this is a good start. IronPython seems to be more or less functional, with speed comparable to CPython, even though the example code included in Debian looks a little "heavy" (see &lt;code&gt;/usr/share/doc/ironpython/Tutorial&lt;/code&gt;).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-4918566003811904645?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/4918566003811904645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=4918566003811904645' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/4918566003811904645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/4918566003811904645'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/05/ironpython-on-ubuntu.html' title='IronPython on Ubuntu'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_zn_T2bmMZn0/SD8574w-2EI/AAAAAAAAADA/LGWk5VVk6OQ/s72-c/ironpython-white.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-4290782456650492424</id><published>2008-05-07T23:41:00.003+03:00</published><updated>2008-05-08T02:08:47.198+03:00</updated><title type='text'>Europanto</title><content type='html'>&lt;p&gt;&lt;a href="http://www.europanto.be/euro6.html#190"&gt;This&lt;/a&gt; made my day!  Here's an excerpt if you're too lazy to click on the link:&lt;/p&gt;

&lt;cite&gt;
"Als humanos, tambien nations, after seine geborn, become bambinos und grow adult. Aber als humanos, sommige nations never become adult und necessite psychiatrico help", dixit once Sigmund Freud aan Herr Kanzelier Otto Von Bismarck attemptante de le convince que Germania eine tumultuosa puberty was traversante.&lt;br/&gt;
Otto Von Bismarck ignored die wise parolas des fader des psychanalyse und wat happened aan Germania next, wir know mucho well.&lt;br/&gt;
Die freudiana diagnose noch todag applicable und validissima est, by exemplo, por wat Grosse Britannia betreft. Eine nation die encore play mit kleine soldatos und make carnaval parades out des season, mature est suremente nicht.&lt;br/&gt;
Wat pushe flegmaticos aged britannicos de dresse in hooliganicos costumes und parade mit tambouros und trompettes in der nordirlandico landscape? Sicheremente eine mucho neglected mentale desease.&lt;br/&gt;
Eine people waar hombres can wel dress in skirts, waar animals habe more rights dann mensen, waar man drive op de wronge side des strada, must echtemente seriose problemas van personnality habe.
Eine people die nicht only play cricket und darts, aber les regarde tambien op TV, bastante insane must definitamente esse.&lt;br/&gt;
(...)
&lt;/cite&gt;

&lt;p&gt;There are more texts in this, er, language, on the &lt;a href="http://www.europanto.be/"&gt;Europanto main site&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edit: fixed link&lt;/em&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-4290782456650492424?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/4290782456650492424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=4290782456650492424' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/4290782456650492424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/4290782456650492424'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/05/europanto.html' title='Europanto'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-1716524089342593653</id><published>2008-04-19T00:55:00.002+03:00</published><updated>2008-04-19T01:31:21.039+03:00</updated><title type='text'>Calibrating the keyboard autorepeat setting</title><content type='html'>&lt;p&gt;The default keyboard autorepeat setting on most systems is boringly slow.  Even worse, the delay before autorepeat kicks in is so long.  This is great for novice users, but we programmers deserve better.  Here's a calibration procedure that I use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The autorepeat delay should be as short as possible, but a concentrated, damp but short keypress should not cause multiple keypress events.&lt;/li&gt;
&lt;li&gt;To determine the most suitable autorepeat rate, test your accuracy.  Open an editor and try to enter multiple lines of about 50 characters using the autorepeat feature.  Pick the highest setting with which you can consistently get the line length within 2-3 characters of the target. (The 2-3 character margin comes from the practice of releasing the autorepeated key a little early and entering the remaining 1-3 characters, if any, with separate keystrokes.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For me an autorepeat delay of ~250ms and 80 char/s rate works well.  To get your numbers, you can use the command &lt;code&gt;xset q | grep 'repeat rate'&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;This tweak make the standard direction keys (and particularly the &lt;code&gt;backspace&lt;/code&gt; &amp;amp; &lt;code&gt;delete&lt;/code&gt; keys) much more useful: you can frequently get away without using special editor commands or, say, having to select things to delete them and thus resetting the X buffer.  It makes things a little faster and more responsive.  Try reverting to the standard setting after a few weeks of fast repeat to feel the difference.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-1716524089342593653?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/1716524089342593653/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=1716524089342593653' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/1716524089342593653'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/1716524089342593653'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/04/calibrating-keyboard-autorepeat-setting.html' title='Calibrating the keyboard autorepeat setting'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-6791855802657170596</id><published>2008-04-13T13:59:00.005+03:00</published><updated>2008-04-13T14:42:48.046+03:00</updated><title type='text'>Perl program 'design'</title><content type='html'>&lt;p&gt;&lt;a href="http://search.cpan.org/dist/Acme-EyeDrops/lib/Acme/EyeDrops.pm"&gt;Acme::Eyedrops&lt;/a&gt; allows you to 'design' your Perl programs (if you have any; you'd better not).  Basically, given a Perl program and a "shape" file, it produces a perl program that visually resembles the given shape &lt;em&gt;and&lt;/em&gt; behaves like the former program. Here's my favorite example:&lt;/p&gt;

&lt;pre&gt;
    ''=~(        '(?{'        .('`'        |'%')        .('['        ^'-')
    .('`'        |'!')        .('`'        |',')        .'"'.        '\\$'
    .'=='        .('['        ^'+')        .('`'        |'/')        .('['
    ^'+')        .'||'        .(';'        &amp;'=')        .(';'        &amp;'=')
    .';-'        .'-'.        '\\$'        .'=;'        .('['        ^'(')
    .('['        ^'.')        .('`'        |'"')        .('!'        ^'+')
   .'_\\{'      .'(\\$'      .';=('.      '\\$=|'      ."\|".(      '`'^'.'
  ).(('`')|    '/').').'    .'\\"'.+(    '{'^'[').    ('`'|'"')    .('`'|'/'
 ).('['^'/')  .('['^'/').  ('`'|',').(  '`'|('%')).  '\\".\\"'.(  '['^('(')).
 '\\"'.('['^  '#').'!!--'  .'\\$=.\\"'  .('{'^'[').  ('`'|'/').(  '`'|"\&amp;").(
 '{'^"\[").(  '`'|"\"").(  '`'|"\%").(  '`'|"\%").(  '['^(')')).  '\\").\\"'.
 ('{'^'[').(  '`'|"\/").(  '`'|"\.").(  '{'^"\[").(  '['^"\/").(  '`'|"\(").(
 '`'|"\%").(  '{'^"\[").(  '['^"\,").(  '`'|"\!").(  '`'|"\,").(  '`'|(',')).
 '\\"\\}'.+(  '['^"\+").(  '['^"\)").(  '`'|"\)").(  '`'|"\.").(  '['^('/')).
 '+_,\\",'.(  '{'^('[')).  ('\\$;!').(  '!'^"\+").(  '{'^"\/").(  '`'|"\!").(
 '`'|"\+").(  '`'|"\%").(  '{'^"\[").(  '`'|"\/").(  '`'|"\.").(  '`'|"\%").(
 '{'^"\[").(  '`'|"\$").(  '`'|"\/").(  '['^"\,").(  '`'|('.')).  ','.(('{')^
 '[').("\["^  '+').("\`"|  '!').("\["^  '(').("\["^  '(').("\{"^  '[').("\`"|
 ')').("\["^  '/').("\{"^  '[').("\`"|  '!').("\["^  ')').("\`"|  '/').("\["^
 '.').("\`"|  '.').("\`"|  '$')."\,".(  '!'^('+')).  '\\",_,\\"'  .'!'.("\!"^
 '+').("\!"^  '+').'\\"'.  ('['^',').(  '`'|"\(").(  '`'|"\)").(  '`'|"\,").(
 '`'|('%')).  '++\\$="})'  );$:=('.')^  '~';$~='@'|  '(';$^=')'^  '[';$/='`';
&lt;/pre&gt;

&lt;p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-6791855802657170596?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/6791855802657170596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=6791855802657170596' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/6791855802657170596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/6791855802657170596'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/04/perl-program-design.html' title='Perl program &apos;design&apos;'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-3245212644942553644</id><published>2008-04-05T01:17:00.004+03:00</published><updated>2008-04-05T01:40:11.083+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>The meaning of code</title><content type='html'>&lt;p&gt;I had an "Aha!" moment today when I came to a Wittgensteinian realization that while the &lt;em&gt;sense&lt;/em&gt; of a piece of code corresponds to the formal behaviour of that code, the &lt;em&gt;meaning&lt;/em&gt; of the snippet is the set of possible contexts where this code could be used.  This idea has changed my view of teaching programming (I have been teaching Python in a &lt;a href="http://licejus.lt/"&gt;local school&lt;/a&gt; for a couple months now).&lt;/p&gt;

&lt;p&gt;This attitude is nothing new, but for some reason I have not come across it, or rather, I have never seen it applied.  (The fashionable problem-based learning thing has some similarities, but isn't quite it.)  Having an idea to start from, it was not hard to find good articles expanding the idea.  I especially liked Robert Strandh's short writeup on &lt;a href="http://dept-info.labri.fr/~strandh/Teaching/MTP/Common/Strandh-Tutorial/idioms.html"&gt;idioms&lt;/a&gt; and Elliot Soloway's &lt;a href="http://citeseer.ist.psu.edu/soloway86learning.html"&gt;Learning To Program = Learning To Construct Mechanisms And Explanations (1986)&lt;/a&gt;. Experienced programmers will not learn much, but anyone dealing with CS education, teachers and students alike, ought to have a look.&lt;/p&gt;

&lt;p&gt;The moral is that emphasis should be placed on reading exemplary code ("experienced programmers do X this way") rather than definitions ("function Y does Z").  Programming seems to be closer to language use than to mathematics, and teaching methods should reflect that.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-3245212644942553644?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/3245212644942553644/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=3245212644942553644' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/3245212644942553644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/3245212644942553644'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/04/meaning-of-code.html' title='The meaning of code'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-1062834279324049406</id><published>2008-03-29T15:22:00.003+02:00</published><updated>2008-03-29T15:28:21.804+02:00</updated><title type='text'>"Home" toolbar button on Firefox 3</title><content type='html'>&lt;p&gt;The "Home" toolbar button seems to have been removed from the default configuration of Firefox 3.  Moreover, it not trivial to get it back as it is not available in the "Customize toolbar" list of optional buttons either.  It turns out that to add it you have to &lt;a href="http://www.tech-recipes.com/rx/2822/firefox_3_restore_home_button_back_navigation_toolbar"&gt;drag it from the bookmarks&lt;/a&gt; instead.&lt;p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-1062834279324049406?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/1062834279324049406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=1062834279324049406' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/1062834279324049406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/1062834279324049406'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/03/home-toolbar-button-on-firefox-3.html' title='&quot;Home&quot; toolbar button on Firefox 3'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-2278971659082686438</id><published>2008-03-25T21:43:00.002+02:00</published><updated>2008-03-25T22:30:54.068+02:00</updated><title type='text'>Reverting to packaged translations on Launchpad</title><content type='html'>&lt;p&gt;It turns out that I did a poor job of looking for information on how to revert to packaged translations on Launchpad Translations.  There is a &lt;a href="https://bugs.launchpad.net/rosetta/+bug/107737"&gt;bug report (#107737)&lt;/a&gt; on the very same issue with some useful information. Interestingly, the German team which reported the problem was even &lt;a href="https://bugs.launchpad.net/rosetta/+bug/107737/comments/7"&gt;contemplating&lt;/a&gt; reverting &lt;em&gt;all&lt;/em&gt; local Launchpad translations.&lt;/p&gt;

&lt;p&gt;Furthermore, there is already a high-priority &lt;a href="https://blueprints.launchpad.net/rosetta/+spec/revert-translation-to-packaged"&gt;Launchpad blueprint for reverting translations of whole packages&lt;/a&gt;.  There is no news on its implementation, but at least the idea is there.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-2278971659082686438?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/2278971659082686438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=2278971659082686438' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/2278971659082686438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/2278971659082686438'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/03/reverting-to-packaged-translations-on.html' title='Reverting to packaged translations on Launchpad'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-3506543941449050658</id><published>2008-03-22T02:16:00.003+02:00</published><updated>2008-03-22T03:19:26.952+02:00</updated><title type='text'>Pianofiles</title><content type='html'>&lt;p&gt;&lt;a href="http://pianofiles.com"&gt;pianofiles.com&lt;/a&gt;, a sheet music exchange site which I &lt;a href="http://gintasm.blogspot.com/2005/02/piano-resources_13.html"&gt;had mentioned two years ago&lt;/a&gt;, has gotten a nice facelift. It used to be very slow and neither very pretty nor convenient.  Most of these shortcomings have now been corrected. It's a great place to look particularly for modern tunes which, unlike classical works (which are usually public domain anyway), do not have a canonical version, but heaps of arrangements and transcriptions of live performances.  Quality of course varies, but point is that you can get your hands on many versions and compare them.  Typical latency of requests is about a day. For example, just yesterday I fired off a few emails, and today I have got three versions of &lt;a href="http://youtube.com/watch?v=IA7d6P7yXSo"&gt;"Nardis" by Bill Evans&lt;/a&gt;.  Feel free to ask for &lt;a href="http://pianofiles.com/user/173953/sheets"&gt;any sheets I've got&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/9890172-3506543941449050658?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/3506543941449050658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=3506543941449050658' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/3506543941449050658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/3506543941449050658'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/03/pianofiles.html' title='Pianofiles'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-8691502901680145459</id><published>2008-03-21T01:39:00.004+02:00</published><updated>2008-03-22T03:18:30.146+02:00</updated><title type='text'>Launchpad translations revisited</title><content type='html'>&lt;p&gt;I am trying to add some order to the mess that is the Launchpad translation repository.  Problem is, strings translated just once through Launchpad stick around forever, even if you change them in upstream later.  In effect, a lot of translation bugfixes were not reaching Ubuntu users.  I &lt;a href="http://gintasm.blogspot.com/2008/03/launchpad-translation-synchronization.html"&gt;thought&lt;/a&gt; I had that covered.  Unfortunately it's not the case.&lt;/p&gt;

&lt;p&gt;I just noticed that in the Launchpad &lt;a href="https://translations.launchpad.net/ubuntu/hardy/+lang/lt/"&gt;package list&lt;/a&gt; sorting by changed strings only sorts the first page!  Initially I had noticed random package names and mistakenly thought that the whole package list was sorted.  The whole list (~1500 packages, shown in 75 package chunks) is sorted by "importance", so it's basically random.  Good luck finding modified packages in that haystack.&lt;/p&gt;

&lt;p style="border: 1px solid black; width: 20em"&gt;Seeking computer-literate monkeys.&lt;br/&gt;Earn up to five bananas per hour!&lt;br/&gt;Must be able to use mouse.&lt;/p&gt;

&lt;p&gt;Unless... how about increasing the batch size?  Turns out that in Launchpad the batch size is not capped, so by changing a URL parameter you can just set it to a high number, wait a few short moments, and get the complete list of packages.  Sort that by changed strings and we're done, right?&lt;/p&gt;

&lt;p&gt;We're done finding the local translations, but not fixing (reverting) them. The new, larger list reveals that there are more than a few of those with &lt;em&gt;quite&lt;/em&gt; more than a few strings that should in 99% of the cases be reverted to packaged versions.  Here's how that works:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monkey operator instruction manual&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Click on 'Packaged' radio button for all 10 entries on page (no batch size modifications allowed here...)&lt;/li&gt;
&lt;li&gt;Click 'save'&lt;/li&gt;
&lt;li&gt;Repeat until the page says 'No more translations'&lt;/li&gt;
&lt;li&gt;Done. &lt;strong&gt;Not!&lt;/strong&gt;  When you click the 'Save button', the starting offset is changed for the next page.  However, the translations you just marked are removed from the list at the same time.  So, if you were looking at translations 1-10, after pressing 'Save &amp; Continue' you will actually be looking at translations 21-30, not 11-20!  To get to the 'lost' translations, you have to retrieve the list from the start again.  So, load the initial page and go to step #1 to fix the remaining half of translations.  Next time you reach this step, half of those will be left.  Next time, half of half of those.  Isn't that fun!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Where's that monkey ad again?&lt;/p&gt;

&lt;p&gt;A brute force solution could be to write a script.  That could save some bananas. Not that we could run out of them as this whole thing is pretty much bananas.  That does not look like a clean solution though.  Does anyone know if there there is a better way?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-8691502901680145459?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/8691502901680145459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=8691502901680145459' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/8691502901680145459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/8691502901680145459'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/03/launchpad-translations-revisited.html' title='Launchpad translations revisited'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-3824557951471844375</id><published>2008-03-20T01:38:00.003+02:00</published><updated>2008-03-20T01:54:50.238+02:00</updated><title type='text'>Trickle the userspace traffic limiter</title><content type='html'>&lt;p&gt; &lt;a href="http://monkey.org/~marius/pages/?page=trickle"&gt;trickle&lt;/a&gt; (available in a package repository near you) is a neat little tool to limit network bandwidth of a particular app.  It's very useful for those situations where you don't want your connection gobbled up, but the application in question does not implement traffic limiting.  For example, to run a dist-upgrade capped at 30 KB/s, run this:
&lt;p&gt;&lt;code&gt;trickle -s -d 30 apt-get dist-upgrade&lt;/code&gt;&lt;/p&gt;
&lt;p style="font-size: smaller"&gt;(Care to guess what I'm doing now?)&lt;/p&gt;
&lt;p&gt;Note that &lt;code&gt;trickle&lt;/code&gt; does not seem to work across the &lt;code&gt;sudo&lt;/code&gt; boundary:  don't do &lt;code&gt;trickle -s -d 30 sudo foo&lt;/code&gt;, do &lt;code&gt;sudo trickle -s -d 30 foo&lt;/code&gt; .&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-3824557951471844375?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/3824557951471844375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=3824557951471844375' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/3824557951471844375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/3824557951471844375'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/03/trickle-userspace-traffic-limiter.html' title='Trickle the userspace traffic limiter'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-4827794304529784265</id><published>2008-03-12T23:46:00.003+02:00</published><updated>2008-03-13T00:06:37.739+02:00</updated><title type='text'>Launchpad translation synchronization</title><content type='html'>&lt;p&gt;Ubuntu package translation storage in Launchpad used to annoy me, primarily because the synchronization workflow between Launchpad and upstream was unclear.  My questions have been &lt;a href="https://answers.launchpad.net/rosetta/+question/26663"&gt;partly answered&lt;/a&gt; on Launchpad Answers. Others working with translations in Launchpad might be interested in this information.&lt;/p&gt;

&lt;p&gt;Here's another tip for translation coordinators.  I used to worry about translation pollution in Launchpad, until I found that you can clean up efficiently by sorting packages by the number of translations changed locally in Launchpad (to try it out, you can go &lt;a href="https://translations.launchpad.net/ubuntu/hardy/+lang/lt"&gt;here&lt;/a&gt; and click twice on the "Changed" column).  Click on the number of changed translations in a given package and you will be presented with a list of the changed translations, which you can reset to upstream versions one by one by choosing "packaged" versions. It seems to be a good idea to perform such a cleanup once in a while, to keep the amount of cruft to a minimum.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-4827794304529784265?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/4827794304529784265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=4827794304529784265' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/4827794304529784265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/4827794304529784265'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2008/03/launchpad-translation-synchronization.html' title='Launchpad translation synchronization'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-4597407342968912586</id><published>2007-09-15T23:37:00.000+03:00</published><updated>2007-09-16T01:15:14.041+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Opening files quickly in Vim</title><content type='html'>&lt;p&gt;
My Python development environment consists of a GVim window for editing code and a gnome-terminal for running the unit tests.  This works out well, but leaves some integration to be desired.  In particular, jumping to a test failure point is a little cumbersome.  I used to do it this way: copy the filename from the traceback, switch to vim, then type :e, paste the filename with middle-click (now I know I can use &lt;C-r&gt;* instead) and press Enter, then enter the line number and press G.  That is barely acceptable; this particular wart has even contributed to pushing a ex-co-worker towards Emacs (the horror!).
&lt;/p&gt;

&lt;p&gt;
I have written a small vimscript function to make the aforementioned use case slightly easier.  Now to jump to a failure point, just triple-click the corresponding line in the traceback (that selects the whole line), switch to Vim and invoke the function, which scrapes the clipboard for a filename and line number and opens it in the active buffer.
&lt;/p&gt;

&lt;p&gt;
Installation: paste the &lt;a href="http://gintas.pov.lt/files/openfile.vim"&gt;OpenFileFromClipboard function&lt;/a&gt; in your &lt;code&gt;~/.vimrc&lt;/code&gt; and bind it to a key by adding the following lines to your .vimrc:
&lt;/p&gt;

&lt;pre&gt;nmap &lt;F4&gt; :call OpenFileFromClipboard()&lt;CR&gt;
imap &lt;F4&gt; &lt;C-o&gt;:call OpenFileFromClipboard()&lt;CR&gt;
&lt;/pre&gt;

&lt;p&gt;
These commands bind the key F4 to our function.  The first command handles normal mode, and the second handles insert mode (hence the &lt;C-o&gt; to momentarily escape the insert mode).  You can of course change the shortcut to whatever you like.
&lt;/p&gt;

&lt;p&gt;
The function should handle following types of references from the clipboard:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc/passwd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;John saved his work to ~john/doc.txt and left.&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;File "/home/gintas/devel/project/tests.py", line 123, in tests.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/usr/include/stdio.h:333:extern int sprintf (char *__restrict __s,
&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;
I hope someone finds this useful.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-4597407342968912586?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/4597407342968912586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=4597407342968912586' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/4597407342968912586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/4597407342968912586'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2007/09/opening-files-quickly-in-vim.html' title='Opening files quickly in Vim'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-115551413149100244</id><published>2006-08-14T02:47:00.000+03:00</published><updated>2006-08-14T03:08:51.530+03:00</updated><title type='text'>Localization coordination for Debian #6</title><content type='html'>&lt;p&gt;With the deadline approaching, it appears that my productivity is rising. Seems like the typical &lt;em&gt;efficiency=1/days_left&lt;/em&gt; (and at T=0 my brain explodes).&lt;/p&gt;

&lt;p&gt;Basically I'm happy with what I have for DDTP.  It will need some testing to replace the current system.  One thing that I would like to have is package priorities: this has some support in the old system.  I am not sure how to approach this yet, but I'm sure I'll think of something.  Anyway, this is not a priority and will probably be settled after the deadline.&lt;p&gt;

&lt;p&gt;Priorities for next (and last) week are to get the relational backend running and to write a guide to the API.  I have already started work on the RDB backend.  I am using &lt;a href="http://www.sqlalchemy.org"&gt;SQLAlchemy&lt;/a&gt; as the wrapper.  A nice side-effect is that SQLAlchemy supports &lt;a href="http://www.sqlite.org/"&gt;SQLite&lt;/a&gt;, which means that getting the thing to run would be a snap, without requiring fancy configuration of MySQL or PostgreSQL.  On the other hand, having these options allows better scalability as the database and the web server(s) can be separated.  As for the guide, I am aiming for a style similar to &lt;a href="http://docs.python.org/lib/"&gt;library documentation&lt;/a&gt; on python.org.  I expect no trouble here because I already have some experience with L&lt;sup&gt;A&lt;/sup&gt;T&lt;sub&gt;E&lt;/sub&gt;X.&lt;/p&gt;

&lt;/p&gt;Last but not least, I have to remember to clean up quite a few leftover TODO and XXX markers in the things that I have.  Most of them are benign, however.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-115551413149100244?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/115551413149100244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=115551413149100244' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115551413149100244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115551413149100244'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2006/08/localization-coordination-for-debian-6.html' title='Localization coordination for Debian #6'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-115517107233485484</id><published>2006-08-10T03:22:00.000+03:00</published><updated>2006-08-10T03:51:12.396+03:00</updated><title type='text'>Localization coordination for Debian #5.5</title><content type='html'>&lt;p&gt;I have been working on getting the DDTP to work with Pootle.  Import from DDTP translation files works fine now (although it takes a while) as well as export to Translation-?? file format.  I have also created a layer to split the translations up in groups by name, to avoid humongous multi-megabyte .po files.&lt;/p&gt;

&lt;p&gt;More information and plans for next week coming up tomorrow.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-115517107233485484?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/115517107233485484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=115517107233485484' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115517107233485484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115517107233485484'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2006/08/localization-coordination-for-debian.html' title='Localization coordination for Debian #5.5'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-115446994679489529</id><published>2006-08-01T22:37:00.000+03:00</published><updated>2006-08-02T01:23:43.430+03:00</updated><title type='text'>Firefox tip-of-the-day</title><content type='html'>&lt;p&gt;A small tip for Firefox: use mouse gestures for basic operations.  They are provided by the &lt;a href="http://optimoz.mozdev.org/gestures/"&gt;mouse gestures&lt;/a&gt; extension.  I am no big expert here, as I only use three gestures: &lt;code&gt;go back&lt;/code&gt; (left), &lt;code&gt;go forward&lt;/code&gt; (right) and &lt;code&gt;close tab&lt;/code&gt; (down,right).  Nevertheless, having these around is already very convenient, because they are so simple and so frequently needed.  I usually do browsing with (surprise) my mouse and these gestures streamline the process because now I don't have to care about the toolbar (and the &lt;code&gt;close tab&lt;/code&gt; buttton in particular) any more.&lt;/p&gt;

&lt;p&gt;If you are only interested in the simple gestures, I found that it helps to disable diagonal gestures: in the extension's properties, Additional Settings tab, set diagonal tolerance to 0 percent.  This will disable some advanced gestures but I never wanted those anyway, so it reduces the chance of my gesture being incorrectly recognized.  I also disable the &lt;code&gt;New window&lt;/code&gt; (down) gesture ("General" tab, "Edit gestures" button) because it would sometimes be activated instead of &lt;code&gt;close tab&lt;/code&gt; when the "right" in my "down, right" motion were too small.&lt;/p&gt;

&lt;p&gt;Mouse gestures, like anything, need some time to get used to, but after a while they require much less effort than seeking out a button.  In a few days you will learn that very little motion is required for the gesture to be recognized.  For other applications usually the keyboard is actively used, so keystroke shortcuts would be faster, but for web browsing in particular, mouse gestures fit the bill very well in my opinion.&lt;/p&gt;

&lt;p&gt;By the way, &lt;a href="http://www.opera.com/"&gt;Opera&lt;/a&gt; supports mouse gestures natively.&lt;/p&gt;

&lt;p&gt;In other news, my work on Debian l10n project was mentioned on &lt;a href="http://www.debian.org/News/weekly/2006/31/"&gt;Debian Weekly News&lt;/a&gt;.  I found it very funny that they linked to &lt;a href="http://www.worldforge.org/"&gt;Worldforge&lt;/a&gt;, which is an open sorce MMORPG, instead of &lt;a href="http://www.wordforge.org/drupal/en/projects/wordforge"&gt;WordForge&lt;/a&gt;, the localisation project.  Admittedly I had made this mistake myself previously, and unfortunately WordForge has a much lower profile than WorldForge.  Oh well, real news publishers do this kind of stuff all the time :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-115446994679489529?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/115446994679489529/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=115446994679489529' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115446994679489529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115446994679489529'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2006/08/firefox-tip-of-day.html' title='Firefox tip-of-the-day'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-115439276769085987</id><published>2006-08-01T03:22:00.000+03:00</published><updated>2006-08-01T03:39:27.756+03:00</updated><title type='text'>Localization coordination for Debian #5</title><content type='html'>&lt;p&gt;There have not been updates for an extended period of time as I have taken a completely unplanned and unexpected holiday.  Now I'm back on track.&lt;/p&gt;

&lt;p&gt;Work I have accomplished since the last update:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;updated TranslationUnit and the .po parser.  In the end I decided that it's not worth making it too different from Pootle's pofile.  Comments are now dealt with and the header is treated specially.&lt;/li&gt;
&lt;li&gt;merging templates.  I defined an interface for objects able to merge translation stores and provided a simple implementation.  Pootle already has an implementation of this too, I'll try to encapsulate that as well.&lt;/li&gt;
&lt;li&gt;help with move to Subversion for the Wordforge project.  The Subversion repository is already operational at https://svn.sourceforge.net/svnroot/translate/trunk, although it's read-only at this moment.&lt;/li&gt;
&lt;li&gt;some small shufflings in the API.  Generally the defined interface are holding out fairly well new code, so only small modifications are needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's what I want to do next week:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wire this thing up to DDTP.  Should be easy, I just need to ask about a good way to fetch DDTP translations.  Probably this will be a download-only demo in the beginning.&lt;/li&gt;
&lt;li&gt;Same for debconf l10n templates.&lt;/li&gt;
&lt;li&gt;Come up with a translation review and approval model.  This is one of the cornerstones of the API and may be tricky to get right.  I think that it is essential to have a sort of a 'diff' tool working at translation unit level (much like ordinary 'diff' works on text).  To get usable diffs several copies of the template (upstream &amp; local) should be stored.  With this in place it shouldn't be hard to implement pushing of new DDTP / debconf translations upstream.&lt;/li&gt;
&lt;li&gt;further updates to the API as flaws and missing features pop up.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-115439276769085987?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/115439276769085987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=115439276769085987' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115439276769085987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115439276769085987'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2006/08/localization-coordination-for-debian-5.html' title='Localization coordination for Debian #5'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-115236965202524697</id><published>2006-07-08T17:05:00.000+03:00</published><updated>2006-07-08T17:46:45.936+03:00</updated><title type='text'>Localization coordination for Debian #4</title><content type='html'>&lt;p&gt;This was a week of prototyping.&lt;/p&gt;

&lt;p&gt;I performed some more basic changes to the API. I introduced folders so that arbitrary tree-like grouping structures would be possible. I also moved the language layer below the module layer (previously it was above, like in pootle), because it eliminates parallel hierarchies in the whole structure.  It also just appears more logical to me.  While the bottom-most TranslationUnit class needs more work until it's complete, I hope that the container interfaces will not need to be changed much more, as there would be more and more work to update the corresponding implementations.&lt;/p&gt;

&lt;p&gt;I have written a prototype .po parser that uses Wordforge's tools to parse a .po file and converts the result into structures defined by the new API.  Admittedly it's at a very early stage.  There is also a preliminary implementation that can read Pootle's backend storage directory structure.  It is read-only at the moment, and does not read Pootle's metadata files yet, but it is usable.  There's also an XML-RPC server that demonstrates this backend: you can send XML-RPC requests to translate words in specified Pootle projects.&lt;/p&gt;

&lt;p&gt;After having dealt with containers this week, next week I will probably concentrate on the actual translation objects and look deeper into structure of XLIFF to ensure decent compatibility.  I would like to accommodate most of what Wordforge currently supports in this regard.  I will also probably start thinking about the security subsystem (I have a feeling that this will spur a few discussions on the mailing list).&lt;/p&gt;

&lt;p&gt;I have also tried to gently push Wordforge to migrate to Subversion.  Sourceforge has its own migration facilities, so hopefully the transition will be easy and painless.  CVS has been a little of a pain, and now I noticed that it's actually threatening me!&lt;/p&gt;

&lt;pre&gt;
...
revision 1.1
date: 2006/07/08 12:06:43;  author: gintautasm;  state: dead;
branches:  1.1.2;
...
&lt;/pre&gt;

&lt;p&gt;There was some interest on the Wordforge mailing list about using the XML-RPC interface to co-operate with thick clients (KBabel, etc.).  For the moment I have enough work on Pootle itself and XML-RPC is not a priority, but if anyone would be interested in implementing the client side for some translation application, I would be very happy to cooperate and coordinate the server's XML-RPC interface.&lt;/p&gt;

&lt;p&gt;Hopefully next week the weather will be a bit cooler too: it's so hot that it is difficult to fall asleep because of the heat.  The heat definitely does not help to get actual work done.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-115236965202524697?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/115236965202524697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=115236965202524697' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115236965202524697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115236965202524697'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2006/07/localization-coordination-for-debian-4.html' title='Localization coordination for Debian #4'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-115168030232670896</id><published>2006-06-30T17:57:00.000+03:00</published><updated>2006-06-30T18:14:08.346+03:00</updated><title type='text'>Localization coordination for Debian #3</title><content type='html'>&lt;p&gt;This time the weekly report is late, sorry about that.  I spent the better part of the week without access to the internet.&lt;/p&gt;

&lt;p&gt;I did have my computer with me, and I have worked a bit on the Pootle backend API, which was received without major complaints on the Pootle mailing list.  There were some very slight changes to the interfaces.  Most importantly I whipped up a simple proof-of-concept implementation of the interfaces.  That revealed a few more small problems, but now I am confident that the interfaces are consistent and can actually be implemented.  This demo implementation is not persistent, but it might be useful as a base for other implementations and in tests, or it could be trivially made persistent with use of pickle.&lt;/p&gt;

&lt;p&gt;The current API and the implementation are in the Pootle CVS repository (see &lt;a href="http://translate.cvs.sourceforge.net/translate/src/Pootle/storage/"&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Next, I will attempt to wrap .po file classes that Pootle currently has.  Implementing basic functionality should not be very difficult there, especially with recent changes by David Fraser.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-115168030232670896?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/115168030232670896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=115168030232670896' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115168030232670896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115168030232670896'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2006/06/localization-coordination-for-debian-3.html' title='Localization coordination for Debian #3'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-115076147427568550</id><published>2006-06-20T02:48:00.000+03:00</published><updated>2006-06-30T18:12:56.523+03:00</updated><title type='text'>Localization coordination for Debian #2</title><content type='html'>&lt;p&gt;I sent a new revision of the suggested translation storage API to the mailing list, addressing all the shortcomings that have been pointed out.  Hopefully it will not change much any more and I can start working on an implementation this week.&lt;/p&gt;

&lt;p&gt;My plan is to first produce a very simple pickle-based implementation of the API.  This should be relatively quick to build and would highlight the weak points of the API.  I think that this can be finished this week.  After that (and possibly revisions to the API) comes the important part: writing a nice wrapper for the existing pofile class.  This should not take too long either, another week at most (especially since my exams would already be over).&lt;/p&gt;

&lt;p&gt;When a .po-based implementation is in place, the fun starts.  I'd then like to try to have another application that concurrently uses Pootle's backend storage (currently po-based).  Another week of work.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-115076147427568550?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/115076147427568550/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=115076147427568550' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115076147427568550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115076147427568550'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2006/06/localization-coordination-for-debian-2.html' title='Localization coordination for Debian #2'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-115023454494487941</id><published>2006-06-13T18:18:00.000+03:00</published><updated>2006-06-14T00:35:45.003+03:00</updated><title type='text'>Localization coordination for Debian #1</title><content type='html'>&lt;p&gt;I have been working on an integrated l10n infrastructure for Debian.  Instead of starting from scratch, the &lt;a href="www.wordforge.org"&gt;Wordforge&lt;/a&gt; project was chosen to be used as the base.  Currently Wordforge has a &lt;a href="http://translate.sourceforge.net/"&gt;toolkit&lt;/a&gt; for various l10n operations as well as a web frontend &lt;a href="http://pootle.wordforge.org/"&gt;Pootle&lt;/a&gt; that uses this toolkit.  My job is to adapt these tools to Debian needs.&lt;/p&gt;

&lt;p&gt;I see three major areas of my future work in Wordforge:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scalability: importing all translations of all packages in Debian into Wordforge as it is would require a very powerful computer.  I believe that a planned transition to a relational database as the backend of Wordforge (instead of plain old files) will help immensely here.
&lt;/li&gt;
&lt;li&gt;frontends: there is only one frontend to the system, Pootle.  Debian will need an e-mail interface, an XML-RPC interface, a Subversion interface and possibly others in addition to the web interface.  This is more difficult than it sounds because Pootle is intertwined with the backend.  Work is underway to define a clear API for the backend that could be used by various clients.&lt;/li&gt;
&lt;li&gt;process: Debian translators have strict translation review and ownership processes.  These would have to be incorporated into Pootle.&lt;/li&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A (to me almost distressingly) large amount of discussions took place on the debian-i18n and Wordforge mailing lists on these topics and more as I dug into Wordforge to better understand the current situtation and plans of other developers.  After the initial communication peak, now things are really starting to roll. Here's what we have now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A general concensus for a move in Wordforge towards a relational database.  This took quite a bit of convincing ;)&lt;/li&gt;
&lt;li&gt;Agreement on the ideas of a new backend API&lt;/li&gt;
&lt;li&gt;A sketch (in code) of the new API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I posted the sketch of the API to the Pootle mailing list.  There was little opposition and mostly constructive remarks.  Unless a disagreement pops up, I would expect the API design to be finished by next week.&lt;/p&gt;

&lt;p&gt;My longer term plans:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;write an implementation for the new API (a week)&lt;/li&gt;
&lt;li&gt;cover the current file-based backend under the API (difficult to estimate)&lt;/li&gt;
&lt;li&gt;migrate Pootle to use the new backend (difficult to estimate)&lt;/li&gt;
&lt;li&gt;write a new frontend or two: e-mail, XML-RPC (a week)&lt;/li&gt;
&lt;li&gt;write a backend based on a relational database (a week)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One thing that is still keeping me down a is a couple of exams due in a week.  After that I should have much more time to work on this project.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-115023454494487941?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/115023454494487941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=115023454494487941' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115023454494487941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/115023454494487941'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2006/06/localization-coordination-for-debian-1.html' title='Localization coordination for Debian #1'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-114772851621617641</id><published>2006-05-16T00:12:00.000+03:00</published><updated>2006-05-16T00:28:36.230+03:00</updated><title type='text'>z3reload moved to the Zope 3 base</title><content type='html'>&lt;p&gt;A small project of mine, &lt;a href="http://gintas.pov.lt/z3reload"&gt;z3reload&lt;/a&gt;, which implements very basic view code reloading, has moved to the &lt;a href="http://codespeak.net/z3"&gt;Zope 3 Base&lt;/a&gt;.  Hopefully that will make it a bit more visible.  Zope 3 is already fragmented as is, some consolidation can't hurt.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-114772851621617641?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/114772851621617641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=114772851621617641' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/114772851621617641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/114772851621617641'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2006/05/z3reload-moved-to-zope-3-base.html' title='z3reload moved to the Zope 3 base'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-114643747036595297</id><published>2006-05-01T00:49:00.001+03:00</published><updated>2008-09-13T15:43:53.205+03:00</updated><title type='text'>Russian to English dictionaries on Linux</title><content type='html'>&lt;p&gt;&lt;strong&gt;Update (2008-09-13): the dictionaries in &lt;a href="http://dictd.xdsl.by/dicts"&gt;http://dictd.xdsl.by/dicts&lt;/a&gt; are probably more complete than the ones provided here, see &lt;a href="http://gintasm.blogspot.com/2008/09/russian-english-dictionaries-proper.html"&gt;this post&lt;/a&gt; for more information.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is very convenient for me to have a local dictd server set up, not only to look up obscure English words and jargon, but also for translation from foreign languages.  Dictd is quite fast and powerful, with a multitude of dict clients to choose from.  There are some pretty good free dictionaries too. For German, the dictionary in the Debian (Ubuntu) package &lt;code&gt;dict-de-en&lt;/code&gt; (German-English + English-German) is fairly good.  For Russian, the Mueller English-Russian dictionary (&lt;code&gt;mueller7accent-dict&lt;/code&gt;) is great.&lt;/p&gt;

&lt;p&gt;Unfortunately, the Mueller dictionary does not contain translations from Russian to English.  I have been using &lt;code&gt;ksocrat&lt;/code&gt; for that purpose, but KSocrat is a little buggy and its usability does not shine.  I looked around on the web for a downloadable Russian-English dictionary in dict format, but surprisingly could not find anything useful.  There are quite a few online translation sites, heaps of small DOS-era utilities and some home-made Windows stuff, but nothing that would be easy to feed to dictd.  What I did find was Sdictionary.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sdict.com"&gt;Sdictionary&lt;/a&gt; is a dictionary application that has a fairly large community.   Its Russian-English dictionary with 300 000 words was more than adequate for my purposes, but the database format was incompatible with dictd, and I couldn't find a converter on the web, so I wrote one.&lt;/p&gt;

&lt;p&gt;The converter from Sdictionary to Dictd formats is a &lt;a href="http://gintas.pov.lt/files/sdict2dictd.sh"&gt;bash script&lt;/a&gt; that dumps an Sdictionary file to a plain text file and massages it a bit so that it can be fed to dictfmt.  To use the script you will need to install PTkSdict from &lt;a href="http://swaj.net/sdict/index.html"&gt;swaj.net&lt;/a&gt; (&lt;a href="http://swaj.net/sdict/ptksdict_1.1.6_all.deb"&gt;Debian package&lt;/a&gt;) and the Ubuntu packages &lt;code&gt;dictfmt&lt;/code&gt; and &lt;code&gt;dictzip&lt;/code&gt;.  Then just drop the script in the same directory as some dictionary &lt;code&gt;foo.dct&lt;/code&gt; and run &lt;code&gt;./sdict2dictd.sh foo&lt;/code&gt; (where &lt;code&gt;foo&lt;/code&gt; is the name of the dct file).  The script should produce &lt;code&gt;foo.dict.gz&lt;/code&gt; and &lt;code&gt;foo.index&lt;/code&gt; which you can install into &lt;code&gt;/usr/share/dictd&lt;/code&gt;.  The script is far from perfect and discards some formatting but it's better than nothing.  The best solution would probably be to extend &lt;code&gt;dictfmt&lt;/code&gt; so that it could read the Sdict dump files directly.&lt;/p&gt;

&lt;p&gt;If you just want a dictd Russian-English dictionary, I have uploaded the files converted from Sdict here: &lt;a href="http://gintas.pov.lt/files/rus_eng_full.dict.dz"&gt;rus_eng_full.dict.dz&lt;/a&gt; (8MB), &lt;a href="http://gintas.pov.lt/files/rus_eng_full.index"&gt;rus_eng_full.index&lt;/a&gt; (15MB).&lt;/p&gt;

&lt;p&gt;By the way, when running in daemon mode, &lt;code&gt;dictd&lt;/code&gt; eats an unreasonable amount of RAM (it's taking 40MB resident memory on my machine).  If the dict server is only for personal use, it makes sense to run it through &lt;code&gt;inetd&lt;/code&gt; as described in &lt;code&gt;/usr/share/doc/dictd/README.inetd.gz&lt;/code&gt;.  It appears that the speed difference is not noticeable on modern computers.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-114643747036595297?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/114643747036595297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=114643747036595297' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/114643747036595297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/114643747036595297'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2006/05/russian-to-english-dictionaries-on.html' title='Russian to English dictionaries on Linux'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-113526497717788756</id><published>2005-12-22T15:35:00.000+02:00</published><updated>2005-12-22T17:33:20.353+02:00</updated><title type='text'>Kalba ir kalbininkai</title><content type='html'>&lt;p&gt;
Sorry, English speakers, this post is in Lithuanian; writing it in English would be an oxymoron.
&lt;/p&gt;

&lt;p&gt;
Neseniai užtikau internete tipišką žmogaus, nusistačiusio prieš informatikos terminijos lietuvinimą, &lt;a href="http://bro1.centras.info/book_kalba_lietuviu.html"&gt;puslapį&lt;/a&gt;.  Tokią nuomonę turi nemažai žmonių, ir kai kurie mėgsta apie tai garsiai pašnekėti internete ar forumuose, tuo tarpu iš kitos barikadų pusės tokių aktyvistų gerokai mažiau.  Pabandysiu apginti (nebūčiau Gintautas!) kalbininkų darbą.
&lt;/p&gt;

&lt;p&gt;Pirmiausia pulsiu lengviausiai paneigiamą teiginį &amp;mdash; kad kalba nesvarbi tautiniam identitetui ir kad ji savaime nėra vertybė.  Manau, kad vienas iš dalykų, apibrėžiančių tautą, yra jos žmonių mąstysena, o kalba yra tos mąstysenos atspindys. Esmė ta, kad ryšys abipusis &amp;mdash; kalba savo ruožtu veikia mąstymą.  Nors mintys ir nėra rišlūs sakiniai, vis vien remiamės kalba.  Ši idėja tiksliau išreikšta &lt;a href="http://venus.va.com.au/suggestion/sapir.html"&gt;Sapiro-Vorfo hipotezėje&lt;/a&gt;.  Paprasčiau kalbant, pabandykite įsivaizduoti vokietį, nekalbantį vokiškai.  Arba prancūzą, nekalbantį prancūziškai.  Japoną, nekalbantį japoniškai.  Kiną?  Suomį?  Indą?  Italą? Pagaliau anglą?  Manau, kad tai pakankamai stiprus argumentas, kad kalba yra vienas iš pagrindinių, jei ne pats pagrindinis tautiškumo pagrindas ir labai svarbi kultūros dalis (tai, beje, argumentas, kodėl kalbos paskirtis nėra vien informacijos perdavimas).  Savimonė taip pat svarbu, be savimonės tauta negali egzistuoti, tačiau savęs supratimas nebūtinai susijęs su tautiškumu.  Žmonės kartais save apgaudinėja &amp;mdash; jiems atrodo, kad jie skiriasi nuo kitų, nors iš tiesų tų skirtumų labai nedaug.&lt;/p&gt;

&lt;p&gt;Manęs visai nežavi idėjos, kad visas pasaulis kalbėtų viena kalba; gerai, kad tai nelabai įmanoma.  Būdas su žmonėmis susikalbėti jau egzistuoja senų seniausiai: tiesiog reikia mokytis užsienio kalbų.  Aišku, tai nėra paprasta, tačiau ne tik suteikia galimybę bendrauti, tačiau ir apskritai praplečia akiratį.&lt;/p&gt;

&lt;p&gt;Dar įmesiu akmenį į airių daržą.  Gal anglų kalba jiems ir atnešė ekonominį klestėjimą investicijomis iš užsienio, tačiau kartu atkeliavo ir nelabai gerų dalykų.  Jei neklystu, Airija buvo viena iš didžiausių programinės įrangos patentų propaguotojų.  Viena iš priežasčių &amp;mdash; Airijoje plačiai įsikūręs Microsoft galėjo tampyti politikų virveles ekonominiais argumentais.  Taigi airiai praranda ne tik kalbą, bet ir galią savo pačių valstybėje.&lt;/p&gt;

&lt;p&gt;Dabar galime pereiti prie, atrodytų, universaliai nekenčiamų kalbininkų.  Tie dykaduoniai tik nieko nesuprasdami išradinėja naujus žodžius ir kiša nosį ne į savo reikalus, ar ne?  Ne.  Mano supratimu, kalbininkų tikslas &amp;mdash; išsaugoti lietuvių kalbos grynumą.  Manau, kad tai nėra kvailas tikslas, nes lietuvių tauta nėra didelė, ir todėl kitos kalbos (anglų ir rusų) nesunkiai daro įtaką.  Aš didžiuojuosi savo kalba, ir nenorėčiau po 50 metų turėti lietrusių ar anglietuvių kalbos.  Kalbininkai stengiasi neįsileisti visiškai netinkamų skolinių todėl, kad jei įleidžiame keletą, tada visi pamato, kad taip galima, ir nebelieka priežasties neįleisti ir daugiau.  Taip kalba gali pasikeisti smarkiai per trumpą laiką.  Gal tai atrodo kaip ėjimas prieš žmones, bet mano galva, žmonės tiesiog linkę rinktis paprastesnį sprendimą nemąstydami apie ilgalaikes pasekmes, kurias svarstyti ir yra kalbininkų (ir apskritai valstybės) pareiga, panašiai kaip rūpinimasis aplinkos tarša.&lt;/p&gt;

&lt;p&gt;Nesutinku su populiaria nuomone, kad kalbininkai nesugeba atlikti savo darbo.  Pirmiausia, jie yra savo darbo specialistai, ir aš mieliau palikčiau vertimą jiems, negu kokiems nors inžinieriams.  Imant pavyzdį iš programų kūrimo konteksto, jei reikia parašyti verslo programą, juk darbą atlieka programuotojas, o ne verslininkas.  Programuotojo pareiga yra išnagrinėti dalykinę sritį ir tada dirbti savo darbą.  Verslininkas gali galvoti, kad jis daug geriau parašytų programą, nors tai dažniausiai netiesa.  Apskritai, dažnai verslininkas net nežino, kokios programos iš tiesų nori.  Lygiai taip pat, kalbininko pareiga yra išnagrinėti dalykinę sritį ir tada dirbti savo darbą.  Programuotojas gali galvoti, kad jis daug geriau susitvarkytų su terminais, nors tai dažniausiai netiesa.  Apskritai, dažnai programuotojas net nežino, kokių terminų iš tiesų nori.&lt;/p&gt;

&lt;p&gt;Teisybė, kartais kalbininkai sugalvoja keistų, gal net juokingų žodžių.  Kartais jie iš tiesų nepataiko, bet man atrodo, kad dauguma sugalvotų terminų pakankamai geri kasdieniam naudojimui.  O žodžių juokingumas yra labai miglota savoka.  Pabandykite lėtai, nesigilindami į prasmę, ištęsdami, pasimaivydami ištarti bet kokį paprastą žodį, pavyzdžiui, „piešti“ arba „šluota“.  Man po tokios procedūros vos ne bet koks žodis atrodo juokingas, ir ne dėl to, kad juokingai ištariamas -- tas keistas tarimas reikalingas tam, kad būtų galima atskirti žodį nuo jo tiesioginės prasmės ir suvokti tik garsą ir ryšius su kitais žodžiais.  Daug naujų žodžių gali atrodyti juokingi dėl deminutyvų („skreitinukas“) arba moteriškos giminės („derintuvė“).  Jie atrodo juokingi todėl, kad neįprasti.  Čia bėda ta, kad anglų kalba daiktams nepriskiria giminės ir neturi deminutyvinių formų, todėl tokie vertimai į lietuvių kalbą (mes įpratę prie svetimžodžio klijuoti vyriškos giminės galūnę be jokių priesagų) atrodo keisti.  Tuo tarpu kasdieniuose žodžiuose tokios formos gana dažnos („mikrobangų krosnelė“, „degtukas“, „mentelė“). Štai ir pavyzdys, kaip skoliniai skurdina kalbą.&lt;/p&gt;

&lt;p&gt;Neprotinga šnekėti, kad kalbininkai nori pakeisti profesinį žargoną.  Tarpusavyje bendraujantys profesionalai greičiausiai kaip ir šnekėjo, taip ir šnekės pusiau angliškai, pusiau lietuviškai  (deja, ir man tenka taip daryti; mielai pabandyčiau naudoti lietuviškus terminus, jei neprieštarautų bendradarbiai).  Iš tiesų sprendžiamas svarbus klausimas: ką daryti, kai reikia parašyti apie dalyką knygą, arba išdėstyti medžiagą universitete?  Aš manau, kad mano lietuvių kalbos jausmas neblogas, ir man labai nemalonu rasti sudarkytų skolinių profesionaliame tekste.  Manau, kad daug lietuvių jaustųsi panašiai.&lt;/p&gt;

&lt;p&gt;Galiausiai norėčiau pastebėti įdomią vidinę prieštarą.  Dažnai žmonės, besipriešinantys šiems naujiems terminams, šiaip yra progresyvūs, domisi naujomis technologijomis, gyvena modernų gyvenimą ir laiko save atvirais kitų nuomonei.  Tuo tarpu priešinimasis šiems terminams, mano supratimu, yra labai konservatyvus veiksmas: „Aš jau naudoju šį terminą tris mėnesius, todėl prašom jo nekeisti, ir apskritai, jūsų alternatyvos man atrodo juokingos.“  Alternatyvos juokingos vien dėl to, kad tai ne tas pats skolinys (kuris, beje, „aiškus“ turbūt todėl, kad akivaizdus ryšys su anglišku atitikmeniu).  Pamažu tie žodžiai įeis į bendrąją kalbą ir bus visiškai natūralūs.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-113526497717788756?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/113526497717788756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=113526497717788756' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/113526497717788756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/113526497717788756'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/12/kalba-ir-kalbininkai.html' title='Kalba ir kalbininkai'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-113097103894029411</id><published>2005-11-02T23:37:00.000+02:00</published><updated>2005-11-03T11:12:11.346+02:00</updated><title type='text'>Hassle-free IPv6 connectivity</title><content type='html'>&lt;p&gt;I have recently discovered that nowadays it's very easy to get &lt;a href="http://www.ipv6.org/"&gt;IPv6&lt;/a&gt; access if you're using Debian (or Ubuntu):&lt;/p&gt;

&lt;pre&gt;apt-get install tspc&lt;/pre&gt;

&lt;p&gt;Try &lt;code&gt;ping6 www.kame.net&lt;/code&gt;, it should work out of the box.  A 6to4 tunnel should have been automatically established to &lt;a href="http://www.hexago.com"&gt;Hexago&lt;/a&gt;, which hosts &lt;a href="http://www.freenet6.net"&gt;www.freenet6.net&lt;/a&gt;.  You don't even have to register for an account, although it might be a good idea to get one if you are really planning to use IPv6, as the anonymous tunnel broker is rather slow (I had ping times on the order of 300-500ms), and you will probably want a statically allocated address space.  Moreover, a tunneling protocol based on UDP which supports NAT punching is now available, so you do not need a public IP address to connect.  This situation is orders of magnitude better than the one when I tried to set up IPv6 on my router at home a couple years ago.&lt;/p&gt;

&lt;p&gt;At the moment there is not much you can do with your new shiny IPv6 connection  IPv6 is still  "basking" in obscurity, there's not much to see on the IPv6 web yet: &lt;a href="http://www.kame.net"&gt;dancing kame&lt;/a&gt;, &lt;a href="http://www.ipv6.bieringer.de/"&gt;some stats&lt;/a&gt; about fellow IPv6 users... Nothing really practical.  However, given the trivial setup procedure, I'm sure some uses could be found. One that comes to mind immediately is SSH access.  Since the tunnel can punch NAT's, even machines behind routers can be reached without any trouble.  While 300ms lag is not pleasant, there is also some security through obscurity to be gained - who would bother scanning 128bit IP addresses?  Of course, if you completely disable SSH on IPv4, a tunnel failure could be very unpleasant.  There is still some sense having both running. For example, you can restrict SSH access to several static IPv4 addresses that you usually use; you can connect from external sites using IPv6.  Besides, it's quite nice to have the ability to fix those nasty firewall setup slips when you lock yourself out by accident (that has happened to me several times).&lt;/p&gt;

&lt;p&gt;While IPv4 is not giving way to IPv6 yet, a fair amount of software and hardware already supports the new standard.  A concise overview of the advantages can be found at &lt;a href="http://www.netbsd.org/Documentation/network/ipv6/#diff_ipv4"&gt;NetBSD IPv6 FAQ&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/9890172-113097103894029411?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/113097103894029411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=113097103894029411' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/113097103894029411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/113097103894029411'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/11/hassle-free-ipv6-connectivity.html' title='Hassle-free IPv6 connectivity'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-112946610355150066</id><published>2005-10-16T13:53:00.000+03:00</published><updated>2005-10-16T15:45:26.290+03:00</updated><title type='text'>Design by Contract in Python</title><content type='html'>&lt;p&gt;
In the light of recent lectures on Design by Contract in the university I decided see if there are any nice Python implementations.
&lt;/p&gt;

&lt;p&gt;
To begin with, Design by Contract is a technique to increase reliability of programs, and in particular for reusable components.  Invented by &lt;a href="http://archive.eiffel.com/general/people/meyer/"&gt;Bertrand Meyer&lt;/a&gt; more than ten years ago, it is a central notion in the programming language &lt;a href="http://www.eiffel.com/"&gt;Eiffel&lt;/a&gt; that he created.  There is a nice &lt;a href="http://archive.eiffel.com/doc/manuals/technology/contract/"&gt;introduction to Design by Contract&lt;/a&gt; available.  I'll try to summarize it very quickly.
&lt;/p&gt;

&lt;p&gt;
Basically, in the context of software engineering a contract is a collection of obligations for a component.  These obligations are divided into three major categories:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Class invariants&lt;/em&gt; are supposed to be (almost) always valid.  For example, the attribute ISBN of a class Book should always be valid according to the ISBN checksum algorithm.  A possible invariant for a class Window would be "not (window.maximized and window.minimized".&lt;/li&gt;

&lt;li&gt;&lt;em&gt;Preconditions&lt;/em&gt; are input conditions, they validate the arguments of a method or function call.  For example, a precondition for the function sqrt(x) could be that its argument must be non-negative (assuming that it cannot deal with complex numbers).  The caller of the function is responsible for supplying arguments that don't violate preconditions.&lt;/li&gt;

&lt;li&gt;&lt;em&gt;Postconditions&lt;/em&gt; are result obligations.  They validate the result of a function/method and state changes of an object.  An example of a postcondition for sqrt(): "abs(result * result - x) &lt; 0.001".  Postconditions can also access attributes and ensure that they have (or have not) been changed appropriately.&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;DBC might not look very pleasant for pythoneers at first glance, because it makes programs more rigid.  Besides, unit and integration tests should catch all the problems, right?  Well, not quite.  I have experienced numerous bugs caused by violations of informally (if at all) described invariants. The problem with unit tests is that when you find a bug where one component (the "client") uses another component (the "server") incorrectly, you can fix the client and test for regressions in that client, but you cannot ensure that other clients have the same problem.  Well, you can add assertion statements on the server, but I'm not particulary fond of assert statements as they clutter up the code and they are not suitable for checking a set of invariants in multiple locations.  A nice thing about DBC is that, unlike static typing, which is an all-or-nothing affair, you can go only as far as you wish.&lt;/p&gt;

&lt;p&gt;Preconditions in particular can be very beneficial to beginners.  I have heard at least several people complain about dynamic typing in Python because they were frustrated by mysterious errors coming from the depths of a large framework which turned out to be a result of incorrect API usage.  Comprehensive preconditions can eliminate such problems much better than any static typing system.&lt;/p&gt;

&lt;p&gt;In Zope 3 applications that I worked with, a fair number of assumptions was supposed to hold at all times, they were mostly mentioned in interface docstrings, but only occasionally checked in actual code, and certainly not systematically.  We've had a fair share of problems with objects referencing other objects that should have been deleted ("hanging in the air") and with processing inconsistent data structures.  In relational databases, such requirements could be checked using constraints and triggers, but I am not aware of similar mechanisms for ZODB. In the end we bolted on a component that would swoop through all the objects in our application and check various things, but this component had to be invoked externally, using a cron job or manually pointing the browser at a particular URL.  However, this was still far from perfect, because the component was separate, so requirements for components were not localized adjacent to the corresponding code.  Using the Zope 3 component architecture would help with that, but it would increase the overhead for adding checks.&lt;/p&gt;

&lt;p&gt;A possible complication with DBC in Python is the performance hit taken by all the extra checks.  For compiled languages it's not nearly as bad as in Python where running unit-tests already takes minutes for larger applications.  However, Python has always favoured convenience and doing the right thing over performance, so, given the benefits, this is not against the ideology at all.  I do not like the current situation in zope.interface where if you want something checked against the interface, you have to run the check manually.&lt;/p&gt;

&lt;p&gt;Of the Python implementations of DBC, I liked &lt;a href="http://www.wayforward.net/pycontract/"&gt;Contracts for Python&lt;/a&gt; most.  In fact, its author Terence Way even proposed to include DBC in Python (see &lt;a href="http://www.python.org/peps/pep-0316.html"&gt;PEP-316&lt;/a&gt;), but the PEP was deferred.  The general idea of the implementation is to declare the contract in docstrings, similar to doctest.  This is much more lightweight and convenient than the other approaches which require to inherit from special classes (or set metaclasses) and/or define new special methods.  Here is an example of a contract from the implementation's homepage:

&lt;pre&gt;
def sort(a):
    """Sort a list *IN PLACE*.

    pre:
        # must be a list
        isinstance(a, list)

        # all elements must be comparable with all other items
        forall(range(len(a)),
               lambda i: forall(range(len(a)),
                                lambda j: (a[i] &lt; a[j]) ^ (a[i] &gt;= a[j])))

    post[a]:
        # length of array is unchanged
        len(a) == len(__old__.a)

        # all elements given are still in the array
        forall(__old__.a, lambda e: __old__.a.count(e) == a.count(e))

        # the array is sorted
        forall([a[i] &gt;= a[i-1] for i in range(1, len(a))])
    """
&lt;/pre&gt;

&lt;p&gt;
There is not much point in reiterating the concise documentation found in the package.  You can find more examples on the &lt;a href="http://www.wayforward.net/pycontract/"&gt;"Contracts for Python" homepage&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;It is unfortunate that the implementation is a bit stale, last touched more than two years ago as of today.  I managed to find a trivial bug (&lt;a href="http://gintas.pov.lt/files/pycontract-import.patch"&gt;patch&lt;/a&gt;) related to importing packages to be processed, but otherwise it seems to be still working fine.  I also tried to make it work properly with Zope interfaces, so that implemented interfaces are treated as superclasses.   Problem is, interfaces are not quite ordinary classes, so there were some complications.  I might look further into it if anyone is interested.  By the way, speaking about Zope interfaces, they already include support for invariants (see zope.interface.invariant), although I prefer the "Contracts for Python" way.  Furthermore, preconditions and postconditions are not supported.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-112946610355150066?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/112946610355150066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=112946610355150066' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/112946610355150066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/112946610355150066'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/10/design-by-contract-in-python.html' title='Design by Contract in Python'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-112456416430017986</id><published>2005-08-20T21:21:00.000+03:00</published><updated>2005-08-21T00:23:45.033+03:00</updated><title type='text'>Zope 3 views reloaded</title><content type='html'>&lt;p&gt;One of the few things I dislike most about &lt;a href="http://dev.zope.org/Zope3/"&gt;Zope 3&lt;/a&gt; is the time it takes to start the server, which becomes an annoyance when running functional tests or when tinkering with view code and checking the results in the browser.  It's so refreshing sometimes to work with page templates where the a browser reload is enough.  I would frequently think how useful it would be if at least the views behaved the same too.&lt;/p&gt;

&lt;p&gt;A little bit of peeking in Zope 3 code and a little bit of coding, and we've got a package called &lt;a href="http://gintas.pov.lt/z3reload"&gt;z3reload&lt;/a&gt; (&lt;a href="http://gintas.pov.lt/z3reload/z3reload-0.1.tar.gz"&gt;tarball&lt;/a&gt;) that does exactly that, reloads the view code before each render. This only really works for views, but in my experience views tend to be the largest and most complex part of the code, so writing them consumes the bulk of the time programming, and they need manual testing most (unit tests are usually enough for the model classes).&lt;/p&gt;

&lt;p&gt;Installation of z3reload is relatively simple: just drop some files in Zope3 package-includes, and specify which views to patch in z3reload-configure.zcml.  Be sure to look through the &lt;a href="http://gintas.pov.lt/darcs/z3reload/README.txt"&gt;README&lt;/a&gt; file.&lt;/p&gt;

&lt;p&gt;z3reload might come in handy to speed up functional testing iterations as well, if you use the script &lt;a href="http://gintas.pov.lt/files/runfdoctests.py"&gt;runfdoctests.py&lt;/a&gt; by my co-worker &lt;a href="http://mg.pov.lt"&gt;Marius Gedminas&lt;/a&gt; (I hope he doesn't mind me publishing this script).  Drop it into your Zope 3 directory and run it.  This script runs the Zope 3 initialization routines just once, and then you can edit functional doctests and immediately run them without the overhead of reinitializing everything.  The script is already a great timesaver.  Thing is, now with z3reload you not only get to modify the functional test source without having to reinitialize Zope, but you can edit the view code as well.&lt;/p&gt;

&lt;p&gt;It is a bit puzzling to me why such a thing has not been done before (well, at least I was not able to find it).  I have heard there was something similar in Zope 2, and now Zope 3 people seem to have the notion that code reloading is not worth it, it's too complex and bug-prone to implement.  Sure, my version is very limited, but I think it has significant productivity advantages.&lt;/p&gt;

&lt;p&gt;Beware, I have not used or tested z3reload much.  It's quite possible that it breaks horribly in some typical circumstances. Needless to say, don't use it on production servers or precious databases.&lt;/p&gt;

&lt;p&gt;For my co-workers stuck with an old revision of Zope 3, from the times Zope 3 had services, I have put up a &lt;a href="http://gintas.pov.lt/z3reload/z3reload-services.tar.gz"&gt;backported version of z3reload&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/9890172-112456416430017986?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/112456416430017986/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=112456416430017986' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/112456416430017986'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/112456416430017986'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/08/zope-3-views-reloaded.html' title='Zope 3 views reloaded'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-112111904477047143</id><published>2005-07-11T23:08:00.000+03:00</published><updated>2005-07-12T00:58:52.216+03:00</updated><title type='text'>EuroPython 2005, continued</title><content type='html'>&lt;p&gt;I promised to review some of the talks that I attended.  I will cover those which were most memorable or useful.&lt;/p&gt;

&lt;p&gt;Kit Blake presented the &lt;a href="http://www.python-in-business.org/ep2005/talk.chtml?talk=2905&amp;track=694"&gt;Document Library&lt;/a&gt;, which is basically a document archival application.  What's interesting is that it's built using Zope 3 technologies.  I think that this need for this type of applications is going to grow and it's nice to have a free implementation.  Besides, since it's in Zope 3, it should be easy to integrate into other projects.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.gocept.com/gocept/activities/innovation/alphaflow"&gt;AlphaFlow&lt;/a&gt;, presented by &lt;a href="http://www.gocept.com/Members/ctheune"&gt;Christian Theune&lt;/a&gt;, revealed to me how libraries can help manage workflow.  Besides, I followed a link from AlphaFlow's webpage and found &lt;a href="http://is.tm.tue.nl/research/patterns/"&gt;Workflow Patterns&lt;/a&gt;, which has some nice research on workflow.
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://webpages.charter.net/edreamleo/"&gt;Edward K. Ream&lt;/a&gt;, an impressive person by himself, introduced &lt;a href="http://webpages.charter.net/edreamleo/front.html"&gt;Leo&lt;/a&gt;, which is similar to an outliner, but much more powerful.  It is not very easy to precisely define Leo because it is a generic tool to manage information.  A nice introduction is on the &lt;a href="http://webpages.charter.net/edreamleo/WhatIsLeo.html"&gt;What Is Leo&lt;/a&gt; page.  I was quite fascinated with Leo, but found it to be imperfect in some regards.  Maybe it's just me, but the Tkinter GUI looks outdated and the whole application does not look very polished.  Leo is also very ambitious and provides its own editor, which I don't think I'd like to switch to, especially since I'm a &lt;a href="http://www.vim.org"&gt;vim&lt;/a&gt; user.  It does provide some Emacs-like shortcuts.  It has some novel ideas, but I ran out of patience trying to find an efficient way to work with it.  I also did not want to lose many very useful tools that work on the standard filesystem and integrate with vim/Emacs.  It also seems to me that versioning should be in the big picture too.  It's obviously a hard problem though.
&lt;/p&gt;

&lt;p&gt;Two talks by Theo de Ridder were energizing and even frenetic.  It's obvious that he is an extremely smart person, but most people from the audience lost the thread about halfway through his talks, myself included.  The fact that I think it's my fault shows that the presentations were excellent in other regards.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://kamaelia.sourceforge.net/Home"&gt;Kamaelia&lt;/a&gt;, presented by Michael Sparks, is a framework for asynchronous applications constructed from components linked via communication channels.  The nice thing is that Python generators are used to achieve multitasking, which makes components much easier to write.  It was interesting to hear that the best way they found to design parallel systems was to first write a simple modularized version and parallelise afterwards.  I liked the basic idea of small components talking together to do complex tasks.  It's like a simple and elegant application of parallelization to component-based architectures, which are more frequently built as libraries or have much more complex synchronization mechanisms.  I was a bit disappointed by the state of the project (they don't even have Kamaelia packaged for easy download...).&lt;/p&gt;

&lt;p&gt;Both Steve Alexander's talks that I attended were brilliant as usual.  In particular the &lt;a href="http://www.python-in-business.org/ep2005/talk.chtml?talk=1610&amp;track=692"&gt;talk about Zope 3 security&lt;/a&gt; was interesting to me.  The slides elucidated the Zope 3 security mechanisms and offered a nice use case in Launchpad.  Even though the presentation took 60 minutes, it didn't seem long at all (unlike the other one, about Leo, which could easily have been compressed).&lt;/p&gt;

&lt;p&gt;Tommi Virtanen talked about &lt;a href="http://www.python-in-business.org/ep2005/talk.chtml?talk=1036&amp;track=692"&gt;Twisted news&lt;/a&gt;.  We had used &lt;a href="http://twistedmatrix.com/products/twisted"&gt;Twisted&lt;/a&gt; in &lt;a href="http://www.schooltool.org"&gt;SchoolTool&lt;/a&gt; previously and it's possible that we will be using it in the future (there is, or at least was, talk of Zope 3 integration with Twisted).  It was nice to hear about all the new things being worked on.&lt;/p&gt;

&lt;p&gt;The talk on &lt;a href="http://codespeak.net/pypy/"&gt;PyPy&lt;/a&gt; by its main contributors Armin Rigo,  Holger Krekel, Christian Tismer and Carl Friedrich Holz was lucid and helped understand the structure and goals of PyPy.  I was impressed by their early demonstrations of simple Python code compilation to C, giving a tenfold speed increase.  They have gone a fair way since the last Europython, where I attended their presentation on PyPy too.  In fact, I participated in the PyPy sprint after the conference, I helped a bit with the standard library update.  PyPy uses the CPython standard library, but there were a few issues to be resolved to update the library to that in Python 2.4. &lt;/p&gt;

&lt;p&gt;Michael Hudson talked about Recoverable Exceptions.  He was being a bit too apologetic, but the talk came out OK, at least it was interesting for me.  He talked about smart handling of exceptions, that is, other behaviours than just aborting to the nearest except block without a way back when an exception is raised.  While I'm currently quite satisfied with the standard exceptions that Python has, it's some food for thought.&lt;/p&gt;

&lt;p&gt;Armin Rigo talked about greenlets, coroutines in Python.  They are based on Python generators and use some C-level magic stack manipulation.  The presentation helped me finally understand what &lt;a href="http://www.python.org/peps/pep-0342.html"&gt;PEP 342&lt;/a&gt; is all about.  Now that Guido van Rossum has accepted PEP 342 and I believe the implementation has been checked in, most of what greenlets offer will be in the Python core eventually.&lt;/p&gt;

&lt;p&gt;Web Application testing using Selenium was not particularly impressive, perhaps because I knew most of the things being presented.  The idea and technology behind &lt;a href="http://selenium.thoughtworks.com/index.html"&gt;Selenium&lt;/a&gt; itself is sound and very practical though.  If you are doing web application development, be sure to have a close look.&lt;/p&gt;

&lt;p&gt;Michael Salib is another one of those energetic speakers that deliver memorable talks.  In this Europython he talked about &lt;a href="http://www.divmod.org/projects/xapwrap"&gt;Xapwrap&lt;/a&gt;, a wrapper for the &lt;a href="http://www.xapian.org"&gt;Xapian&lt;/a&gt; text indexing library, and &lt;a href="http://www.divmod.org/projects/q2q"&gt;q2q&lt;/a&gt;, a peer-to-peer connection management protocol. The former might come out a viable alternative for Lucene in some cases.  q2q is rather immature at the moment but it seems to be solving the right problems the right way.  It's a pity that slides for the q2q presentation don't seem to be available, they were hilarious.
&lt;/p&gt;

&lt;p&gt;I spent most of my time on the Python lightning talks track rather than the Zope lightning talks.  Python talks were so much more fun.  I forgot most of the content, but I had a great time.  I actually did a lightning talk about &lt;a href="http://abridgegame.org/darcs/"&gt;darcs&lt;/a&gt;, David Roundy's Revision Control System, which I found very useful.  Michael Sparks, who spoke about Kamaelia, has a very nice &lt;a href="http://cerenity.org/Europython/2005.html"&gt;summary&lt;/a&gt; of Python lightning talks.  By the way, to answer his doubts about my talk: yes, darcs is not written in Python, but it's great for managing Python code as any other, a very useful tool for any developer.  Steve Alexander did a talk on &lt;a href="http://bazaar-ng.org/"&gt;bazaar-NG&lt;/a&gt;, which also looks very promising, but at the moment in my opinion darcs is much more mature and usable.&lt;/p&gt;

&lt;p&gt;Most of the descriptions were rather terse, you will have to excuse me for that.  There is just too much to cover.  Reinout van Rees  has a more thorough &lt;a href="http://vanrees.org/weblog/1119870845"&gt;overview&lt;/a&gt; of Europython 2005 talks that he attended (there is not much overlap with my list), you should have a look there too.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-112111904477047143?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/112111904477047143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=112111904477047143' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/112111904477047143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/112111904477047143'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/07/europython-2005-continued.html' title='EuroPython 2005, continued'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-112013628548993383</id><published>2005-06-30T15:09:00.000+03:00</published><updated>2005-06-30T15:58:05.496+03:00</updated><title type='text'>Europython 2005 report</title><content type='html'>&lt;p&gt;&lt;a href="http://europython.org"&gt;Europython 2005&lt;/a&gt; is now officially over.&lt;/p&gt;

&lt;p&gt;I did a &lt;a href="http://www.python-in-business.org/ep2005/talk.chtml?talk=1724&amp;track=692"&gt;talk&lt;/a&gt; on Monday that covered &lt;a href="http://gintas.pov.lt/gtktest/"&gt;gtktest&lt;/a&gt;, a small collection of helpers to make unit-testing pyGTK applications easy.  Check out the &lt;a href="http://gintas.pov.lt/ep2005/ep2005-gtktest.pdf"&gt;slides (PDF)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I also delivered a lightning talk on &lt;a href="http://abridgegame.org/darcs/"&gt;darcs&lt;/a&gt;, which is a very well-designed revision control system.  &lt;a href="http://gintas.pov.lt/ep2005/ep2005-darcs.pdf"&gt;Slides (PDF)&lt;/a&gt; are available.  I use darcs for managing gtktest code, and it has been great so far, much more pleasant to use that &lt;a href="http://www.gnuarch.org/"&gt;Arch&lt;/a&gt; and much more powerful than &lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt; which I use at &lt;a href="http://pov.lt"&gt;work&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I have compiled a list of talks that I attended.  You can find a description of each talk on the Europython website, but I was too lazy to add direct hyperlinks on each and every talk.  I did include links to day timetables, where you can find complete lists of talks (with hyperlinks to descriptions and slides).&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;Monday (&lt;a href="http://www.europython.org/sections/tracks_and_talks/schedule_day_1"&gt;schedule&lt;/a&gt;)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;The art of giving a talk (Hellwig)&lt;/li&gt;
&lt;li&gt;Architecture of a large Zope 3 system (Alexander)&lt;/li&gt;
&lt;li&gt;A Python Framework for Rapid Application Development (Goodwin, Wrigley)&lt;/li&gt;
&lt;li&gt;Document Library (Blake)&lt;/li&gt;
&lt;li&gt;AlphaFlow (Theune)&lt;/li&gt;
&lt;li&gt;MayaVi2 (Ramachandran)&lt;/li&gt;
&lt;li&gt;The world according to Leo (Ream)&lt;/li&gt;
&lt;li&gt;Teaching computational engineering (Fangohr)&lt;/li&gt;
&lt;li&gt;Enabling bare Python as universal connector for ad-hoc networks (de Ridder)&lt;/li&gt;
&lt;li&gt;Pulling Java Lucene into Python: PyLucene (Vajda)&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;Tuesday (&lt;a href="http://www.europython.org/sections/tracks_and_talks/schedule_day_2"&gt;schedule&lt;/a&gt;)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Kamaelia (Sparks, Lord)&lt;/li&gt;
&lt;li&gt;Complex security with Zope 3 and an RDB (Alexander)&lt;/li&gt;
&lt;li&gt;Twisted news (Virtanen)&lt;/li&gt;
&lt;li&gt;PyPy as a compiler (Bolz, Krekel, Tismer, Rigo)&lt;/li&gt;
&lt;li&gt;Recoverable Exceptions In Python (Hudson)&lt;/li&gt;
&lt;li&gt;Greenlets: coroutines aren't stranger than generators (Rigo)&lt;/li&gt;
&lt;li&gt;Where metaclasses surpass decorators (de Ridder)&lt;/li&gt;
&lt;li&gt;Solving puzzles with Python (Niemeyer)&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;Wednesday (&lt;a href="http://www.europython.org/sections/tracks_and_talks/schedule_day_3"&gt;schedule&lt;/a&gt;)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Stupidity and laser cat toys: Indexing the US Patent Database with Xapian and Twisted (Salib)&lt;/li&gt;
&lt;li&gt;The Python revolution in the publishing industry (Masini)&lt;/li&gt;
&lt;li&gt;ItsATree - creating a multimedia editor (Gietz)&lt;/li&gt;
&lt;li&gt;Web Application Testing with Selenium (Roeder, Roeder)&lt;/li&gt;
&lt;li&gt;WYSIWYG interface design with CPSSkins and CPSPortlets (Orliaguet, Anguenot)&lt;/li&gt;
&lt;li&gt;The Personal Internet Endpoint: Using Python and Twisted to write Reliable Peer-To-Peer Programs (Salib)&lt;/li&gt;
&lt;li&gt;Lots of Python lightning talks (I did one too)&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;I will cover the talks that I liked best later.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-112013628548993383?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/112013628548993383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=112013628548993383' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/112013628548993383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/112013628548993383'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/06/europython-2005-report.html' title='Europython 2005 report'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-111938872067211512</id><published>2005-06-21T23:57:00.000+03:00</published><updated>2005-06-22T00:18:40.676+03:00</updated><title type='text'>Back again</title><content type='html'>&lt;p&gt;It's been quite a while since my last post.  Now, having finished my exam session, I hope to resume regular posting.&lt;/p&gt;

&lt;p&gt;So, what's been up lately?  Well, just a few days ago version 1.1.1 of the calendaring server &lt;a href="http://www.schooltool.org/schoolbell"&gt;SchoolBell&lt;/a&gt;, free software that I'm working on, has been released.  I am fairly satisfied with the reliability of this version as it fixes most problems that surfaced in SchoolBell 1.1, which was tested by quite a few people.  SchoolBell will not be developed further on its own in the near future, instead &lt;a href="http://www.pov.lt"&gt;we&lt;/a&gt; will be working on &lt;a href="http://www.schooltool.org/schoolbell"&gt;SchoolTool Calendar&lt;/a&gt; (version 0.10 released recently), which is an extension for SchoolBell that accommodates some education-related use cases.  You can find some nice screenshots on the webpage and in the "screencasts" for &lt;a href="http://www.schooltool.org/releases/schooltool0.10/st-setup.pdf/file_view"&gt;SchoolTool&lt;/a&gt; and &lt;a href="http://www.schooltool.org/schoolbell/sb-using.pdf/file_view"&gt;SchoolBell&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;In other news: I'm leaving for &lt;a href="http://europython.org/"&gt;EuroPython&lt;/a&gt; in Sweden on Saturday with my colleagues.  I will be doing a presentation there on unit-testing PyGTK applications, which is not quite my area of expertise, but, well, they accepted the talk, so they can't complain.  The code behind the idea still needs a lot work but I intend to clean it up a little bit and make it public before I leave.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-111938872067211512?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/111938872067211512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=111938872067211512' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/111938872067211512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/111938872067211512'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/06/back-again.html' title='Back again'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-111273932505469680</id><published>2005-04-06T00:08:00.000+03:00</published><updated>2005-04-06T01:22:11.620+03:00</updated><title type='text'>SpamBayes</title><content type='html'>&lt;p&gt;I was fed up with the low, but increasingly annoying flow of spam into my mailboxes, so I have finally decided to set up a spam filter.  I chose &lt;a href="http://spambayes.sourceforge.net/"&gt;SpamBayes&lt;/a&gt;, as I had heard some good things about it (besides, it's written in Python).&lt;/p&gt;

&lt;p&gt;As I use Debian (unstable), installation was just an &lt;code&gt;apt-get install spambayes&lt;/code&gt; away.   Setup and integration with &lt;a href="http://www.gnome.org/projects/evolution/"&gt;Evolution&lt;/a&gt;, my mail client, was a bit more tedious.  (By the way, &lt;a href="http://spamassassin.apache.org/"&gt;SpamAssassin&lt;/a&gt; might have been a sensible choice, as it integrates well with Evolution.)  First, I investigated the approach of using SpamBayes by piping messages to one of the SpamBayes scripts, then I even found a script (&lt;code&gt;sb_evoscore.py&lt;/code&gt;) that is for use with Evolution specifically, but these solutions had a few drawbacks, so in the end I settled with the standard proxy server approach.&lt;/p&gt;

&lt;p&gt;The user interface of the SpamBayes server impressed me.  The server sports a simple web server which you can use to configure SpamBayes, review messages, train the filter or view statistics.  Configuration of the server was straightforward.&lt;/p&gt;

&lt;p&gt;The server is started by running the script sb_server.py, residing in /usr/bin, so it should be in your path. I was slightly annoyed by the fact that the script would immediately litter the working directory with files, and that it had no way of daemonizing, i.e., detaching from the terminal.  I created the directory &lt;code&gt;.spambayes&lt;/code&gt; in my home directory for storing the SpamBayes database. To run the server automatically, I whipped up a &lt;a href="http://gintas.pov.lt/files/spambayes"&gt;simple init script&lt;/a&gt;.  It runs &lt;code&gt;sb_server.py&lt;/code&gt; in the background as the specified user (just one user though - this will not work for a multiuser system with several people running the SpamBayes server).  You will need to create &lt;code&gt;/etc/default/spambayes&lt;/code&gt; where the variables DBDIR (the directory for the databases) and RUNAS (the name of the user) would be specified, e.g.:&lt;/p&gt;

&lt;pre&gt;
DBDIR=/home/gintas/.spambayes
RUNAS=gintas
&lt;/pre&gt;

&lt;p&gt;I have not yet figured out why, but after changing the network the SpamBayes server would sometimes wedge up and refuse to connect to a POP3 server because it could not resolve the domain name.  For now, I added &lt;code&gt;/etc/init.d/spambayes restart&lt;/code&gt; to my suspend script as a workaround.&lt;/p&gt;

&lt;p&gt;As I had anticipated setting up a Bayesian spam filter, I have been marking my mail as spam in Evolution rather than simply deleting it for a while.  However, when I wanted to train the filter, I could not find the spam folder on my filesystem (Evolution stores mail in the mbox format, in ~/.evolution/mail/local).  My first try at training the filter was to simply copy the contents of the Spam folder to a temporary mail folder, which would show up as a file, and feed that as "spam" to SpamBayes, and the other mailboxes as "ham".  However, I noticed that the filter didn't work well.  Then I found out why the Spam mail folder was not showing up as a file - Spam is actually a virtual folder, and when a message is marked as spam, it is simply hidden from the view rather than moved to a different mailbox.  It makes some sense - in case you change your mind about the message, you don't have to know where it came from, it will appear where it was.  Therefore the spam training went fine, but supplying the "good" mailboxes was a mistake, because they included the spam too.  In the end I had to create another temporary mail folder and copy some good messages to it, and use that one to train the filter.&lt;/p&gt;

&lt;p&gt;Wiring up Evolution to use the proxy was easy.  I had to change the POP3 server settings in my Evolution accounts to point to localhost:proxied_port as the server, so that Evolution would get messages with the spam indication headers.  To use the filtering, I added two rules, one for messages tagged as spam by SpamBayes, and another one for "unsure"  (the tag can be found in the header "X-SpamBayes-Classification"). I set the former one to give the message Spam status and mark it read, so I wouldn't even notice it, and the latter to mark the message as Spam but leave it unread, so that I would have a look at it before discarding it.  These rules suit me well, as I have never had a false positive, and most of the "unsure" messages (21 out of 24) are spam.&lt;/p&gt;

&lt;p&gt;After you train SpamBayes, remember to run a sanity check by querying some common "ham" / "spam" words - that's how I discovered my blunder.  Such words as "money", "rich" should show up as spam content.  As for ham content, you know best what words are most frequent in your emails (in my case "python" was a clear shot at 87 ham messages vs. 0 spam messages).&lt;/p&gt;

&lt;p&gt;Further training of SpamBayes is performed either by reviewing the messages through the web, or running a proxy for the outgoing mail server so that you can send emails to fictitious addresses used for notifying SpamBayes about mistakes.  I went for the former.  Now once in a while I visit the message review page to classify the unsure messages, though even that is probably unnecessary, as SpamBayes should be chugging along well enough with the existing database.&lt;/p&gt;

&lt;p&gt;In conclusion, with zero positives, zero negatives and just a handful of unsure messages to date, I'm quite satisfied with SpamBayes. I had tried to look around on the web for information on using Evolution with SpamBayes and found very little, so I hope that this article will turn out to be useful to someone.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-111273932505469680?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/111273932505469680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=111273932505469680' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/111273932505469680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/111273932505469680'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/04/spambayes.html' title='SpamBayes'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-111136006981955407</id><published>2005-03-21T00:52:00.000+02:00</published><updated>2005-03-21T01:07:49.823+02:00</updated><title type='text'>Poetry in Translation</title><content type='html'>&lt;p&gt;I have recently discovered a very funny page which abuses Google translation services to get really funny results.  Ever found oddly simple insights in automatic translation?  Well, there's a fair dose of them in &lt;a href="http://douweosinga.com/projects/poetryintranslation"&gt;Poetry in Translation&lt;/a&gt;, which translates English to German to French to German to English.  The comments section is a bit indecent, but there are some outright hilarious results:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;"I have a broken heart" -&gt; "I have a defective heart"&lt;/li&gt;
&lt;li&gt;"Get busy living, get busy dying" -&gt; "If you receive a life employed, you receive death employed"&lt;/li&gt;
&lt;li&gt;"The quick brown fox jumped over the lazy dog." -&gt; "the fast brown fox jumped on the putrefied dog."&lt;/li&gt;
&lt;li&gt;"Just die, why don't you?" -&gt; "Cubic straight lines, why not him?"&lt;/li&gt;
&lt;li&gt;"you won't fool the children of the revolution" -&gt; "children of rotation tromp you"&lt;/li&gt;
&lt;li&gt;"the pen is mightier" -&gt; "the feather is more powerful"&lt;/li&gt;
&lt;li&gt;"Oh how i love my girl" -&gt; "How how my girl is expensive!"&lt;/li&gt;
&lt;li&gt;"One for all, all for one" -&gt; "For all, all"&lt;/li&gt;
&lt;li&gt;"Be Afraid, Very Afraid" -&gt; "Have fear very timidly,"&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-111136006981955407?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/111136006981955407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=111136006981955407' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/111136006981955407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/111136006981955407'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/03/poetry-in-translation.html' title='Poetry in Translation'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-111135887650747107</id><published>2005-03-21T00:35:00.000+02:00</published><updated>2005-03-21T00:47:56.523+02:00</updated><title type='text'>Hard drive benchmarking</title><content type='html'>&lt;p&gt;Marius Gedminas &lt;a href="http://mg.pov.lt/blog/measuring-disk-speed.html"&gt;experimented&lt;/a&gt; a bit with &lt;code&gt;hdparm&lt;/code&gt; and his results showed no difference in linear disk read rate at the beginning of the disk as compared to at the end.  That made me curious.  I whipped up a very simple Python script to time some plain reads from the disk and the results are consistent with ones from &lt;code&gt;dd&lt;/code&gt;, and with &lt;a href="http://www.xbitlabs.com/images/storage/hitachi-25-7200/gr1.gif"&gt;another benchmark&lt;/a&gt; of my new drive.  Yes, using Python for benchmarking is a stupid idea, and the results are not stable, but I do consistently get almost 40MB/s at the start and no more than 28MB/s at the end of the disk.  You can try the script for yourself:&lt;/p&gt;

&lt;pre&gt;&lt;font face="Lucida,Courier New"&gt;&lt;font color="#008000"&gt;#!/usr/bin/env python
&lt;/font&gt;
&lt;font color="#C00000"&gt;import&lt;/font&gt; &lt;font color="#000000"&gt;sys&lt;/font&gt;
&lt;font color="#C00000"&gt;import&lt;/font&gt; &lt;font color="#000000"&gt;time&lt;/font&gt;

&lt;font color="#000000"&gt;MiB&lt;/font&gt; &lt;font color="#0000C0"&gt;=&lt;/font&gt; &lt;font color="#0080C0"&gt;2&lt;/font&gt;&lt;font color="#0000C0"&gt;**&lt;/font&gt;&lt;font color="#0080C0"&gt;20&lt;/font&gt;

&lt;font color="#000000"&gt;BLOCKS&lt;/font&gt; &lt;font color="#0000C0"&gt;=&lt;/font&gt; &lt;font color="#0080C0"&gt;128&lt;/font&gt; &lt;font color="#008000"&gt;# number of megabytes to read at a time&lt;/font&gt;
&lt;font color="#000000"&gt;SPACING&lt;/font&gt; &lt;font color="#0000C0"&gt;=&lt;/font&gt; &lt;font color="#0080C0"&gt;4&lt;/font&gt; &lt;font color="#0000C0"&gt;*&lt;/font&gt; &lt;font color="#0080C0"&gt;1024&lt;/font&gt; &lt;font color="#008000"&gt;# number of megabytes to seek forward&lt;/font&gt;


&lt;font color="#C00000"&gt;if&lt;/font&gt; &lt;font color="#000000"&gt;len&lt;/font&gt;&lt;font color="#0000C0"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;sys&lt;/font&gt;&lt;font color="#0000C0"&gt;.&lt;/font&gt;&lt;font color="#000000"&gt;argv&lt;/font&gt;&lt;font color="#0000C0"&gt;)&lt;/font&gt; &lt;font color="#0000C0"&gt;&amp;lt;&lt;/font&gt; &lt;font color="#0080C0"&gt;2&lt;/font&gt;&lt;font color="#0000C0"&gt;:&lt;/font&gt;
    &lt;font color="#C00000"&gt;print&lt;/font&gt; &lt;font color="#004080"&gt;"You must supply a device (e.g., '/dev/hda') as an argument"&lt;/font&gt;
    &lt;font color="#000000"&gt;sys&lt;/font&gt;&lt;font color="#0000C0"&gt;.&lt;/font&gt;&lt;font color="#000000"&gt;exit&lt;/font&gt;&lt;font color="#0000C0"&gt;(&lt;/font&gt;&lt;font color="#0080C0"&gt;1&lt;/font&gt;&lt;font color="#0000C0"&gt;)&lt;/font&gt;
&lt;font color="#C00000"&gt;try&lt;/font&gt;&lt;font color="#0000C0"&gt;:&lt;/font&gt;
    &lt;font color="#000000"&gt;f&lt;/font&gt; &lt;font color="#0000C0"&gt;=&lt;/font&gt; &lt;font color="#000000"&gt;open&lt;/font&gt;&lt;font color="#0000C0"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;sys&lt;/font&gt;&lt;font color="#0000C0"&gt;.&lt;/font&gt;&lt;font color="#000000"&gt;argv&lt;/font&gt;&lt;font color="#0000C0"&gt;[&lt;/font&gt;&lt;font color="#0080C0"&gt;1&lt;/font&gt;&lt;font color="#0000C0"&gt;]&lt;/font&gt;&lt;font color="#0000C0"&gt;,&lt;/font&gt; &lt;font color="#004080"&gt;'r'&lt;/font&gt;&lt;font color="#0000C0"&gt;)&lt;/font&gt;
&lt;font color="#C00000"&gt;except&lt;/font&gt; &lt;font color="#000000"&gt;IOError&lt;/font&gt;&lt;font color="#0000C0"&gt;,&lt;/font&gt; &lt;font color="#000000"&gt;e&lt;/font&gt;&lt;font color="#0000C0"&gt;:&lt;/font&gt;
    &lt;font color="#C00000"&gt;if&lt;/font&gt; &lt;font color="#000000"&gt;e&lt;/font&gt;&lt;font color="#0000C0"&gt;.&lt;/font&gt;&lt;font color="#000000"&gt;errno&lt;/font&gt; &lt;font color="#0000C0"&gt;==&lt;/font&gt; &lt;font color="#0080C0"&gt;13&lt;/font&gt;&lt;font color="#0000C0"&gt;:&lt;/font&gt;
        &lt;font color="#C00000"&gt;print&lt;/font&gt; &lt;font color="#0000C0"&gt;(&lt;/font&gt;&lt;font color="#004080"&gt;"Permission denied to read the device, you"&lt;/font&gt;
               &lt;font color="#004080"&gt;" may need root privileges"&lt;/font&gt;&lt;font color="#0000C0"&gt;)&lt;/font&gt;
        &lt;font color="#000000"&gt;sys&lt;/font&gt;&lt;font color="#0000C0"&gt;.&lt;/font&gt;&lt;font color="#000000"&gt;exit&lt;/font&gt;&lt;font color="#0000C0"&gt;(&lt;/font&gt;&lt;font color="#0080C0"&gt;1&lt;/font&gt;&lt;font color="#0000C0"&gt;)&lt;/font&gt;

&lt;font color="#000000"&gt;offset&lt;/font&gt; &lt;font color="#0000C0"&gt;=&lt;/font&gt; &lt;font color="#0080C0"&gt;0&lt;/font&gt;
&lt;font color="#C00000"&gt;while&lt;/font&gt; &lt;font color="#000000"&gt;True&lt;/font&gt;&lt;font color="#0000C0"&gt;:&lt;/font&gt;
    &lt;font color="#000000"&gt;start&lt;/font&gt; &lt;font color="#0000C0"&gt;=&lt;/font&gt; &lt;font color="#000000"&gt;time&lt;/font&gt;&lt;font color="#0000C0"&gt;.&lt;/font&gt;&lt;font color="#000000"&gt;time&lt;/font&gt;&lt;font color="#0000C0"&gt;(&lt;/font&gt;&lt;font color="#0000C0"&gt;)&lt;/font&gt;
    &lt;font color="#C00000"&gt;try&lt;/font&gt;&lt;font color="#0000C0"&gt;:&lt;/font&gt;
        &lt;font color="#000000"&gt;f&lt;/font&gt;&lt;font color="#0000C0"&gt;.&lt;/font&gt;&lt;font color="#000000"&gt;seek&lt;/font&gt;&lt;font color="#0000C0"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;offset&lt;/font&gt; &lt;font color="#0000C0"&gt;*&lt;/font&gt; &lt;font color="#000000"&gt;MiB&lt;/font&gt;&lt;font color="#0000C0"&gt;)&lt;/font&gt;
    &lt;font color="#C00000"&gt;except&lt;/font&gt; &lt;font color="#000000"&gt;IOError&lt;/font&gt;&lt;font color="#0000C0"&gt;:&lt;/font&gt;
        &lt;font color="#C00000"&gt;break&lt;/font&gt; &lt;font color="#008000"&gt;# We probably hit the end of the disk&lt;/font&gt;
    &lt;font color="#C00000"&gt;for&lt;/font&gt; &lt;font color="#000000"&gt;i&lt;/font&gt; &lt;font color="#C00000"&gt;in&lt;/font&gt; &lt;font color="#000000"&gt;range&lt;/font&gt;&lt;font color="#0000C0"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;BLOCKS&lt;/font&gt;&lt;font color="#0000C0"&gt;)&lt;/font&gt;&lt;font color="#0000C0"&gt;:&lt;/font&gt;
        &lt;font color="#000000"&gt;f&lt;/font&gt;&lt;font color="#0000C0"&gt;.&lt;/font&gt;&lt;font color="#000000"&gt;read&lt;/font&gt;&lt;font color="#0000C0"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;MiB&lt;/font&gt;&lt;font color="#0000C0"&gt;)&lt;/font&gt;
    &lt;font color="#000000"&gt;delta&lt;/font&gt; &lt;font color="#0000C0"&gt;=&lt;/font&gt; &lt;font color="#000000"&gt;time&lt;/font&gt;&lt;font color="#0000C0"&gt;.&lt;/font&gt;&lt;font color="#000000"&gt;time&lt;/font&gt;&lt;font color="#0000C0"&gt;(&lt;/font&gt;&lt;font color="#0000C0"&gt;)&lt;/font&gt; &lt;font color="#0000C0"&gt;-&lt;/font&gt; &lt;font color="#000000"&gt;start&lt;/font&gt;
    &lt;font color="#000000"&gt;rate&lt;/font&gt; &lt;font color="#0000C0"&gt;=&lt;/font&gt; &lt;font color="#000000"&gt;BLOCKS&lt;/font&gt; &lt;font color="#0000C0"&gt;/&lt;/font&gt; &lt;font color="#000000"&gt;delta&lt;/font&gt;
    &lt;font color="#C00000"&gt;print&lt;/font&gt; &lt;font color="#004080"&gt;'Offset: %d GB, read rate: %3.2f MB/s'&lt;/font&gt; &lt;font color="#0000C0"&gt;%&lt;/font&gt; &lt;font color="#0000C0"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;offset&lt;/font&gt; &lt;font color="#0000C0"&gt;/&lt;/font&gt; &lt;font color="#0080C0"&gt;1024&lt;/font&gt;&lt;font color="#0000C0"&gt;,&lt;/font&gt; &lt;font color="#000000"&gt;rate&lt;/font&gt;&lt;font color="#0000C0"&gt;)&lt;/font&gt;
    &lt;font color="#000000"&gt;offset&lt;/font&gt; &lt;font color="#0000C0"&gt;+=&lt;/font&gt; &lt;font color="#000000"&gt;SPACING&lt;/font&gt;

&lt;font color="#C00000"&gt;print&lt;/font&gt; &lt;font color="#004080"&gt;'Finished.'&lt;/font&gt;&lt;font color="#000000"&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-111135887650747107?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/111135887650747107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=111135887650747107' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/111135887650747107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/111135887650747107'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/03/hard-drive-benchmarking.html' title='Hard drive benchmarking'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-111083537311310909</id><published>2005-03-14T23:21:00.000+02:00</published><updated>2005-03-14T23:22:53.123+02:00</updated><title type='text'>The Commonly Confused Words Test</title><content type='html'>&lt;table align="center" cellpadding="20"&gt; &lt;tbody&gt;&lt;tr&gt; &lt;td align="center"&gt; &lt;font color="black" size="5"&gt;&lt;b&gt;English Genius&lt;/b&gt;&lt;/font&gt;&lt;br&gt; You scored 100% Beginner, 93% Intermediate, 93% Advanced,  and 88% Expert! &lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt; You did so extremely well, even &lt;i&gt;I&lt;/i&gt;
can't find a word to describe your excellence! You have the uncommon
intelligence necessary to understand things that most people don't. You
have an extensive vocabulary, and you're not afraid to use it properly!
Way to go!
&lt;p&gt;
Thank you so much for taking my test. I hope you enjoyed it!
&lt;/p&gt;
&lt;p&gt;
For the complete Answer Key, visit my blog: http://shortredhead78.blogspot.com/. &lt;/p&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td align="center"&gt;  &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;br&gt;&lt;br&gt;&lt;br&gt; &lt;table cellpadding="20"&gt; &lt;tbody&gt;&lt;tr&gt; &lt;td&gt; &lt;span id="comparisonarea"&gt;My test tracked 4 variables How you compared to other people &lt;i&gt;your age and gender&lt;/i&gt;:&lt;blockquote&gt;&lt;table border="0" cellpadding="0" cellspacing="4"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="middle"&gt;&lt;table bgcolor="black" border="0" cellpadding="0" cellspacing="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#b2cfff" height="20" width="116"&gt;&lt;img src="http://is1.okcupid.com/graphics/0.gif"&gt;&lt;/td&gt;&lt;td bgcolor="white" width="34"&gt;&lt;img src="http://is1.okcupid.com/graphics/0.gif"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;td valign="middle"&gt;You scored higher than &lt;b&gt;77%&lt;/b&gt; on &lt;b&gt;Beginner&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="middle"&gt;&lt;table bgcolor="black" border="0" cellpadding="0" cellspacing="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#b2cfff" height="20" width="59"&gt;&lt;img src="http://is1.okcupid.com/graphics/0.gif"&gt;&lt;/td&gt;&lt;td bgcolor="white" width="91"&gt;&lt;img src="http://is1.okcupid.com/graphics/0.gif"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;td valign="middle"&gt;You scored higher than &lt;b&gt;39%&lt;/b&gt; on &lt;b&gt;Intermediate&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="middle"&gt;&lt;table bgcolor="black" border="0" cellpadding="0" cellspacing="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#b2cfff" height="20" width="92"&gt;&lt;img src="http://is1.okcupid.com/graphics/0.gif"&gt;&lt;/td&gt;&lt;td bgcolor="white" width="58"&gt;&lt;img src="http://is1.okcupid.com/graphics/0.gif"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;td valign="middle"&gt;You scored higher than &lt;b&gt;61%&lt;/b&gt; on &lt;b&gt;Advanced&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="middle"&gt;&lt;table bgcolor="black" border="0" cellpadding="0" cellspacing="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#b2cfff" height="20" width="146"&gt;&lt;img src="http://is1.okcupid.com/graphics/0.gif"&gt;&lt;/td&gt;&lt;td bgcolor="white" width="4"&gt;&lt;img src="http://is1.okcupid.com/graphics/0.gif"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;td valign="middle"&gt;You scored higher than &lt;b&gt;97%&lt;/b&gt; on &lt;b&gt;Expert&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;/span&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;table cellpadding=20&gt;&lt;tr&gt;&lt;td&gt;Link: &lt;a href='http://www.okcupid.com/tests/take?testid=14457200288064322170'&gt;The Commonly Confused Words Test&lt;/a&gt; written by &lt;a href='http://www.okcupid.com/profile?tuid=577245280159428717'&gt;shortredhead78&lt;/a&gt; on &lt;a  href='http://www.okcupid.com'&gt;Ok Cupid&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-111083537311310909?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/111083537311310909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=111083537311310909' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/111083537311310909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/111083537311310909'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/03/commonly-confused-words-test.html' title='The Commonly Confused Words Test'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-111075601482099591</id><published>2005-03-14T01:16:00.000+02:00</published><updated>2005-03-14T01:20:14.823+02:00</updated><title type='text'>New hard disk for my laptop</title><content type='html'>&lt;p&gt;Just a few days ago I bought a new 7200rpm Hitachi hard disk (&lt;a href='http://www.hitachigst.com/portal/site/hgst/?epi_menuItemID=72dec1c7bd2c113aa5a8f2b6aac4f0a0&amp;epi_menuID=0f34be57a7adb6fd25ad4e8060e4f0a0&amp;epi_baseMenuID=22f0deefa8f3967dafa0466460e4f0a0'&gt;Travelstar E7K60&lt;/a&gt;) to replace my old 4200rpm one by Toshiba that came together with the laptop. Now I really regret that I did not do this earlier. This is easily the best investment in a laptop's performance, unless you have a really old CPU or less than 256MB RAM.&lt;/p&gt;

&lt;p&gt;The speed increase is very noticeable. Bootup now takes only half the time it used to, and applications start significantly faster. Seeks are more silent in the new drive, and I have not noticed any background noise because of the increased rotational speed. Battery usage has not changed at all. In general, I noticed only improvements and no regressions after upgrading.&lt;/p&gt;

&lt;p&gt;While partitioning the new disk, I noticed that in my old Toshiba drive the root (/) partition was located at the very end of the disk, because of hysterical raisins. I did not have a separate partition for /usr, so its contents were there too. Make sure not to make my mistake of putting frequently accessed data at the end: hard disks are usually faster at the start. This is because the rotational speed of the disk is constant, but the circumference of outer tracks is larger, therefore, if the data density is uniform over the disk, the transfer rate is greater.&lt;/p&gt;

&lt;p&gt;Speed of some drives may be more sensitive to track diameter than others. If you are curious, you can do a quick benchmark. My new one shows about 38MB/s linear read speed on the outer tracks (start of disk) and about 27MB/s on the inner ones (end of disk), a quite significant difference. To get these numbers, I used this command on Linux: &lt;code&gt;sudo dd if=/dev/hda of=/dev/null bs=1M count=1024 skip=0&lt;/code&gt;. It reads a gigabyte of data from a given offset in the disk, the operation should take about half a minute. &lt;code&gt;dd&lt;/code&gt; even counts the transfer rate for you. To measure performance on the inner tracks, adjust the &lt;em&gt;skip&lt;/em&gt; parameter (e.g., about 37000 for a 40GB drive). You might want to repeat the command a few times and average the results. Do not pick an amount of data (the &lt;em&gt;count&lt;/em&gt; parameter) less than twice your RAM, because the results may be skewed because of caching.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-111075601482099591?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/111075601482099591/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=111075601482099591' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/111075601482099591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/111075601482099591'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/03/new-hard-disk-for-my-laptop.html' title='New hard disk for my laptop'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-111006662793612538</id><published>2005-03-06T01:56:00.000+02:00</published><updated>2005-03-06T01:56:38.226+02:00</updated><title type='text'>One-button testing</title><content type='html'>&lt;p&gt;I &lt;a href='http://gintasm.blogspot.com/2005/01/python-unit-test-runners.html'&gt;wrote&lt;/a&gt; about some inefficiencies in my procedure of running tests a while ago. I really dislike the repetitiveness of commands to switch context, as I use the vim editor for editing code and a terminal for running the tests. Had it been code, I would have refactored it long ago. Now I decided that it's time to optimize this part a little bit.&lt;/p&gt;

&lt;p&gt;My very first idea which I had come up with long ago was to write a small script called &lt;code&gt;loop&lt;/code&gt;, which would loop a command given as an argument infinitely, waiting for a keypress between runs. The script was an extremely simple one-liner:
&lt;pre&gt;while true; do $@ ; read; done&lt;/pre&gt;
However, it only helped me with losing the &lt;kbd&gt;Up,Enter&lt;/kbd&gt; habit a little bit, as &lt;kbd&gt;Enter&lt;/kbd&gt; would be sufficient.&lt;/p&gt;

&lt;p&gt;The second go at the problem was on the right track. I decided to write a small Python script to behave much like the &lt;code&gt;loop&lt;/code&gt; script, but it would register a global shortcut handler so that I could do an iteration without having to switch to the terminal.&lt;/p&gt;

&lt;p&gt;The idea of handling global shortcuts was OK, but the implementation gave me some pains. I tried to look around for some examples of registering global shortcuts with GNOME, but found nothing really useful. I then remembered that a multitude of KDE apps register global shortcuts, and decided to try the KDE Python bindings. In the end I wasted several hours scouring the web for information and watching my app segfault because of odd reasons. It took me a long while to get the details mostly right, and because of reentrancy problems I managed to wedge my keyboard completely so that I had to login remotely and kill the Python process to get control back. I did not quite like having to load KDE libraries either, which took a whole second to import on script startup. In the end I dumped &lt;a href='http://gintas.pov.lt/files/sleeper.py'&gt;this solution&lt;/a&gt; for a more simplistic approach.&lt;/p&gt;

&lt;p&gt;After playing with the KDE shortcuts for a while, I finally understood that I don't really need a &lt;em&gt;global&lt;/em&gt; shortcut, as 99% of the time I need to run the tests while I am working in Vim. This allowed for a much simpler system. The &lt;code&gt;loop&lt;/code&gt; script has remained, but has evolved significantly from the one-liner. Notably, it now checks the return status of the executed command and prints a red or a green horizontal bar with a timestamp. It is very nice to have coloured feedback on whether the tests have passed. There is also an option to run an alternate hardcoded command.&lt;/p&gt;

&lt;p&gt;I implemented interprocess communication in a slightly hacky way, by having the &lt;code&gt;loop&lt;/code&gt; script invoke another shell script for user input (this way I sidestepped smart signal handling in a shell script). The client, in our case vim, can then send a signal to the primitive sub-script with a simple &lt;code&gt;killall&lt;/code&gt; command. Using the process name as a unique identifier is not very clean, but good enough for me.&lt;/p&gt;

&lt;p&gt;So, there are three scripts in total:
&lt;ul&gt;
&lt;li&gt;&lt;a href='http://gintas.pov.lt/files/loop'&gt;loop&lt;/a&gt; (to be used from the command line)&lt;/li&gt;
&lt;li&gt;&lt;a href='http://gintas.pov.lt/files/dumbass.sh'&gt;dumbass.sh&lt;/a&gt; (the stupid sub-process, only used internally)&lt;/li&gt;
&lt;li&gt;&lt;a href='http://gintas.pov.lt/files/dumbass-kick.sh'&gt;dumbass-kick.sh&lt;/a&gt;, which abstracts the &lt;code&gt;killall&lt;/code&gt; command in case I want to implement it in a cleaner way. It accepts '1' or '2' as an argument. If you pass '2', &lt;code&gt;loop&lt;/code&gt; runs the alternate command.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;
To be able to run the tests from vim by a single keypress, I added these lines to my .vimrc to bind the given command to &lt;kbd&gt;F12&lt;/kbd&gt;, and the hardcoded alternate command to &lt;kbd&gt;Shift+F12&lt;/kbd&gt;:
&lt;pre&gt;
nmap &amp;lt;silent&amp;gt; &amp;lt;F12&amp;gt; :wall&amp;lt;CR&amp;gt;:silent !dumbass-kick.sh 1&amp;lt;CR&amp;gt;
imap &amp;lt;silent&amp;gt; &amp;lt;F12&amp;gt; &amp;lt;C-o&amp;gt;:wall&amp;lt;CR&amp;gt;&amp;lt;C-o&amp;gt;:silent !dumbass-kick.sh 1&amp;lt;CR&amp;gt;
nmap &amp;lt;silent&amp;gt; &amp;lt;S-F12&amp;gt; :wall&amp;lt;CR&amp;gt;:silent !dumbass-kick.sh 2&amp;lt;CR&amp;gt;
imap &amp;lt;silent&amp;gt; &amp;lt;S-F12&amp;gt; &amp;lt;C-o&amp;gt;:wall&amp;lt;CR&amp;gt;&amp;lt;C-o&amp;gt;:silent !
&lt;/pre&gt;
These commands also save all active files before running the tests. I added that because occasionally I forget or mistype the write command in vim and then waste some time trying to understand why the tests are misbehaving. All in all, this provides true one-button testing, you don't even have to exit from insert mode.
&lt;/p&gt;

&lt;p&gt;If you really want a global mapping, you can map a key to invoke &lt;code&gt;dumbass-kick.sh&lt;/code&gt; in your window manager. That's a more lightweight solution than importing KDE libraries just to use their shortcut mechanism.&lt;/p&gt;

&lt;p&gt;Even though I mostly use these scripts for running unit tests, they could be useful whenever you need to repeat the same command lots of times. For example, I have been toying around with &lt;a href='http://lilypond.org'&gt;Lilypond&lt;/a&gt; (music typesetting software) a bit, and I used &lt;code&gt;loop&lt;/code&gt; on lilypond to generate DVI output on a keypress so that I could see my changes immediately without stopping to type and switching windows. The script could be useful with &lt;code&gt;make&lt;/code&gt; when working with compiled languages.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-111006662793612538?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/111006662793612538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=111006662793612538' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/111006662793612538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/111006662793612538'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/03/one-button-testing.html' title='One-button testing'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110963392646220278</id><published>2005-03-01T01:38:00.000+02:00</published><updated>2005-03-01T01:38:46.476+02:00</updated><title type='text'>Dictionaries</title><content type='html'>&lt;p&gt;Having a computer look up words for you in a dictionary can be a great timesaver sometimes, especially if you need to check many words.  There are several choices of a computerised dictionary.&lt;/p&gt;

&lt;p&gt;A simple and straightforward choice is to use a web-based dictionary. You can usually find some quite complete and verbose ones with many examples. Some sites even provide other linguistic data (&lt;a href='http://www.canoo.net/services/Controller?service=wordformation&amp;input=informieren&amp;features=%28Cat+V%29%28Aux+haben%29'&gt;this database&lt;/a&gt; really impressed me). Besides, Google is always handy to search for extra information. &lt;/p&gt;

&lt;p&gt;If you have a text that has many unknown words, it might be faster to run it through a general-purpose translator, such as &lt;a href='http://translate.google.com'&gt;translate.google.com&lt;/a&gt;.  You will lose precision, but at least you might get a good laugh from the results.
&lt;/p&gt;

&lt;p&gt;Having the dictionary installed locally is more convenient (you do not need an internet connection) and faster (almost zero latency). For some languages specialised dictionary software is available, but there is also the &lt;abbr&gt;dict&lt;/abbr&gt; network protocol which defines a standard way for a generic dictionary client and a dictionary server to communicate.  This model is quite powerful.&lt;/p&gt;

&lt;p&gt;Setting up a dict server on Linux is not hard, in Debian it's just an &lt;code&gt;apt-get install dictd&lt;/code&gt; away. Note that you will need to install the dictionaries yourself. Debian provides some dictionaries, e.g., &lt;code&gt;dict-de-en&lt;/code&gt;. There is also a number of dict-freedict-* packages, but I have the impression that they are not very complete.&lt;/p&gt;

&lt;p&gt;Now that you have a server running, you need a client to use it. There are quite a few clients available, I will mention several:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;dict&lt;/strong&gt; - the command-line client. Just type &lt;code&gt;dict foo&lt;/code&gt; in a terminal and you'll get the query results immediately. Very handy but not convienient for looking up many words&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;gnome-dictionary&lt;/strong&gt; - the GNOME dictionary client (&lt;a href='http://www.lynucs.org/index.php?screen_type=1&amp;screen_id=147513448541c0696a814e8&amp;m=screen'&gt;screenshot&lt;/a&gt;, look on the right - not to the point, but will do). Looks nice at first but in my opinion it is not very usable, I hate the popup window when no matches are found for a query. And it pushes GNOME's "live preferences" to the uncomfortable limit - when you enter a new server, the same preferences dialog box is immediately reconfigured to that server, which looks very awkward.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;kdict&lt;/strong&gt; - the KDE dictionary client (&lt;a href='http://www.lernnetz-sh.de/kmlinux/doc/kmLinux/software/screenshots/kdict.png'&gt;screenshot&lt;/a&gt;). I slightly disliked it because the input box would lose focus after executing a query, so I would have to use the mouse to enter another word. Jeez, even the web-based dictionaries get this right with some JavaScript. The problem can be worked around with by mapping &lt;kbd&gt;Ctrl+L&lt;/kbd&gt; to the "Clear Input Field" action. I would rather it selected the word instead of deleting it, but this solution is satisfactory. In addition, kdict offers database sets, which turns out to be very helpful. In most dict clients you can only query either a single dictionary or all dictionaries available. Database sets are like virtual dictionaries. An example of a use case is when you want to translate from English to another language and you have several dictionaries for this purpose, but you don't want the general-purpose ones to get in the way.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;After finding out about the &lt;kbd&gt;Ctrl+L&lt;/kbd&gt; tweak I liked KDict best. I would prefer it to be a GTK+ application rather than Qt, but it is practical, which matters most to me.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110963392646220278?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110963392646220278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110963392646220278' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110963392646220278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110963392646220278'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/03/dictionaries_110963392646220278.html' title='Dictionaries'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110824905861743120</id><published>2005-02-13T00:57:00.000+02:00</published><updated>2005-02-19T17:13:54.520+02:00</updated><title type='text'>Piano resources</title><content type='html'>&lt;p&gt;I get most of my piano sheet music from the internet, for free. The guitar players are probably in a even better position, with tablature for most pop songs, (and classical pieces too, I suppose) freely available. However, there is a fair share of free sheet music for the piano as well.&lt;/p&gt;

&lt;p&gt;Because of the copyright laws, most sites do not contain material created later than the early 20th century. Finding modern pieces is a problem. However, there are plenty of public-domain classical (in the broad sense) pieces available. When searching for a piece you will probably want to visit several sheet music repositories before you turn to Google, which will give you heaps of trash to wade through.&lt;/p&gt;

&lt;p&gt;If you are looking for a piece by a very famous composer, chances are that there is a dedicated site where you can download sheet music /  recordings (e.g., &lt;a href='http://www.chopinmusic.net/library.php'&gt;www.chopinmusic.net&lt;/a&gt;, &lt;a href='http://www.jsbach.org/'&gt;www.jsbach.org&lt;/a&gt;). You may want to look at such sites first, they are usually quite complete and the quality is good.&lt;/p&gt;

&lt;p&gt;When I am looking for classical music, my first stop is usually the &lt;a href='http://sheetmusicarchive.net/'&gt;The Sheet Music Archive&lt;/a&gt;. The info page says that the site contains over 4000 pages of sheet music. It is a pity that it only allows two downloads per day (unless you are smart and guess the filename of the piece), but that is usually enough.&lt;/p&gt;

&lt;p&gt;If you can read Russian, you might find Boris Tarakanov's Sheet Music Archive at &lt;a href='http://notes.tarakanov.net'&gt;notes.tarakanov.net&lt;/a&gt; very handy. I have only discovered it recently, but already found a few pieces which I had been looking for. You do not need to actually understand Russian to browse the site &amp;mdash; an online translation service might work if you can't read text in Cyrillic.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://mfiles.co.uk/'&gt;mfiles.co.uk&lt;/a&gt; seems to have a little bit of everything. You can find various well-known pieces and some comments on them here. This site is nice to browse when you want are looking for new material.&lt;/p&gt;

&lt;p&gt;It is sometimes helpful to hear a piece to decide if you like it before looking for the score. In other cases, you only know the composer and the melody, but not the name / number of the piece. &lt;a href='http://www.kunstderfuge.com'&gt;kunstderfuge.com&lt;/a&gt; has an extensive collection of classical MIDI files. Of course, MP3s are more pleasant to the ear, but they are also harder to obtain and take much longer to download. MIDIs can usually give you the basic idea. Googling for MIDI files is easier than searching for free sheet music, but still a pain, so look here before you wander off.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://sibelius.com/'&gt;Sibelius&lt;/a&gt;, the most popular notation software package, has a large repository of Sibelius scores on &lt;a href='http://sibeliusmusic.com'&gt;sibeliusmusic.com&lt;/a&gt;. You do not need to have Sibelius, but you will have to install Scorch (Windows and Mac only), a free browser plugin to view sheet music and play the pieces. Although all pieces on the site can be played and viewed for free, most (but not all) will cost a few dollars if you want to print them out. As this is a community site, there is also a lot of music here that is not worth your time, but there are quite a few &lt;a href='http://sibeliusmusic.com/cgi-bin/show_score.pl?scoreid=18137'&gt;gems&lt;/a&gt; to be discovered too.&lt;/p&gt;

&lt;p&gt;If you are willing to pay money for the sheet music, the best sites are probably &lt;a href='http://sheetmusicplus.com/'&gt;sheetmusicplus.com&lt;/a&gt; and &lt;a href='http://virtualsheetmusic.com/'&gt;virtualsheetmusic.com&lt;/a&gt;. This is just my impression however, as I have not used either of these services.&lt;/p&gt;

&lt;p&gt;Finally, if you are after a relatively modern or rare piece, you might want to check out &lt;a href='http://pianofiles.com'&gt;pianofiles.com&lt;/a&gt;. You will not find sheet music on the site itself, but it can provide you with e-mail addresses of people who have the piece you are after. You may then contact them by e-mail and ask politely to send the score to you. You might be asked for something in return. You can search the database anonymously, but the system will not show any e-mail addresses until you register. You can find a list of sheet music that I have on my &lt;a href='http://www.pianofiles.com?173953'&gt;member page&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/9890172-110824905861743120?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110824905861743120/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110824905861743120' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110824905861743120'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110824905861743120'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/02/piano-resources_13.html' title='Piano resources'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110771869839385525</id><published>2005-02-06T21:38:00.000+02:00</published><updated>2005-02-06T21:38:20.480+02:00</updated><title type='text'>Cryptonomicon</title><content type='html'>&lt;p&gt;I have recently finished reading &lt;a href='http://www.cryptonomicon.com/'&gt;"Cryptonomicon"&lt;/a&gt; by Neal Stephenson, kindly lended to me by &lt;a href='http://mg.pov.lt'&gt;Marius&lt;/a&gt;. To begin with, it was quite a bit thicker than I'd like (almost a thousand pages), but in the end this book was worth the time.&lt;/p&gt;

&lt;p&gt;I think there is no point in retelling the plot, as you can find that in lots of places. In fact, I think that it was not quite top-notch. Most of the book feels a little sluggish and I could not see where things were going. Only the last hundred pages were really interesting plot-wise for me. I might have been happier, had the remaining part been shorter.&lt;/p&gt;

 &lt;p&gt;This book seems to excel at style, however. Stephenson is not afraid to spend lots of time describing elaborately crafted environments and delving into details. There is a fair bit of intelligent humour and sarcasm thrown in.&lt;/p&gt;

&lt;p&gt;There are some geeky parts, about computers and cryptography, that made me slightly uneasy. Some I might consider insulting my intelligence, like the large sections about modular arithmetic or simple text transformations. The scenes concerning computers seemed out of place somewhat (why would I care if Randy was writing a bash or a Perl script, or what UNIX commands he was typing?). Maybe it's just me because I have a technical background, perhaps Stephenson just paid these details as much attention as he did to the non-technical ones.&lt;/p&gt;

&lt;p&gt;Frankly, I do not have much to compare the book to, so take my comments with a grain of salt. Personally, I found the book quite enjoyable.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110771869839385525?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110771869839385525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110771869839385525' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110771869839385525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110771869839385525'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/02/cryptonomicon.html' title='Cryptonomicon'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110461519638678652</id><published>2005-02-03T23:08:00.000+02:00</published><updated>2005-02-03T23:08:38.863+02:00</updated><title type='text'>PyQLogger reloaded</title><content type='html'>&lt;p&gt;The author of &lt;a href='http://pyqlogger.berlios.de/wiki/index.php/Main_Page'&gt;PyQLogger&lt;/a&gt; (a nice and functional PyQt-based blogging client) has been very helpful and has promptly fixed most of the problems I &lt;a href='http://gintasm.blogspot.com/2005/01/pyqlogger.html'&gt;had mentioned&lt;/a&gt;. Even an improved spellchecking interface is in the works. A version with the fixes included has not been released yet, but you can check it out from the project's Subversion &lt;a href='http://svn.berlios.de/viewcvs/pyqlogger'&gt;repository&lt;/a&gt;:
&lt;pre&gt;svn checkout svn://svn.berlios.de/pyqlogger/stable-1.x pyqlogger&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;In addition, a Debian &lt;a href='http://download.berlios.de/pyqlogger/pyqlogger_1.3.3.0-1_all.deb'&gt;package&lt;/a&gt; is now available. Unlike the &lt;a href='http://download.berlios.de/pyqlogger/PyQLogger-1.3.3.0.tar.gz'&gt;source tarball&lt;/a&gt;, the APT package does include most of the recent updates and fixes.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110461519638678652?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110461519638678652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110461519638678652' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110461519638678652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110461519638678652'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/02/pyqlogger-reloaded.html' title='PyQLogger reloaded'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110677685770898379</id><published>2005-01-30T15:11:00.000+02:00</published><updated>2005-01-30T15:11:37.336+02:00</updated><title type='text'>Tidbits for developers who use the Vim editor</title><content type='html'>&lt;p&gt;&lt;a href='http://www.vim.org'&gt;Vim&lt;/a&gt; is an excellent general-purpose text editor, but it is relatively stupid by itself in some situations. Thankfully, it can be &lt;a href='http://vimdoc.sourceforge.net/htmldoc/usr_41.html'&gt;scripted&lt;/a&gt;. You can find many scripts on &lt;a href='http://www.vim.org/scripts/index.php'&gt;www.vim.org/scripts&lt;/a&gt;, I will mention a few useful ones here.&lt;/p&gt;

&lt;p&gt;Every decent code editor has a shortcut to quickly comment / uncomment a block of code. A similar effect can be achieved on Vim by installing &lt;a href='http://www.vim.org/scripts/script.php?script_id=665'&gt;FeralToggleCommentify&lt;/a&gt;. This plugin works with a great number of different filetypes. I especially like to use it to comment out HTML/XML markup because XML comment tags are tedious to type (the script comments each line of the selection separately though). The binding C-c, although on a nasty key, is quite useful as well - it makes a copy of the current line and comments it out.&lt;/p&gt;

&lt;p&gt;If you work with Subversion and write commit messages with Vim, you might find &lt;a href='http://www.vim.org/scripts/script.php?script_id=978'&gt;svn-diff&lt;/a&gt; handy (you will need Python scripting support in vim). It shows the diff of your commit in a pane below the commit message. Besides, Vim does syntax highlighting, so the patch is easier to read than on the console. Remember that if you see something wrong in the diff, you can always abort the commit by not saving the commit message file or, if you have already saved it, deleting the file (&lt;code&gt;:!rm %&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Python coders will appreciate the smart handling of indentation by the alternative &lt;a href='http://www.vim.org/scripts/script.php?script_id=974'&gt;python indent&lt;/a&gt; script. It is sometimes too smart and therefore annoying, but works well in most cases.&lt;/p&gt;

&lt;p&gt;The &lt;a href='http://www.vim.org/scripts/script.php?script_id=301'&gt;XML editing plugin&lt;/a&gt; is also nice to have if you deal a lot with HTML / XML. Its functions appear to be quite useful (I keep forgetting the bindings): jumping between opening and closing tags, enclosing content in tags and deleting enclosing tags, etc.&lt;/p&gt;

&lt;p&gt;If you work in Vim a lot, I highly recommend to remap &lt;kbd&gt;Escape&lt;/kbd&gt;. The standard position makes you move your hand away from the home row. I have remapped &lt;kbd&gt;Escape&lt;/kbd&gt; to &lt;kbd&gt;Caps Lock&lt;/kbd&gt; which I never use. It takes a few minutes to readjust to the standard &lt;kbd&gt;Escape&lt;/kbd&gt; position when working in Vim on other computers, but that is a small price to pay for the increased productivity. You can remap the key on X by using &lt;code&gt;xmodmap&lt;/code&gt;. Run &lt;code&gt;xmodmap ~/.xmodmaprc&lt;/code&gt; after creating the &lt;code&gt;.xmodmaprc&lt;/code&gt; file in your home directory that contains these two lines:
&lt;pre&gt;
clear lock
keycode 66 = Escape
&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;Make sure to have a look at &lt;a href='http://mg.pov.lt/blog/hacking-tools.html'&gt;a post&lt;/a&gt; by Marius Gedminas about CTags and id-utils if you are not familiar with these two timesavers.&lt;/p&gt;

&lt;p&gt;I have uploaded my &lt;a href='http://gintas.pov.lt/files/vimrc'&gt;vimrc&lt;/a&gt;, maybe you will find something useful in there. I highly encourage to go through the Vim internal features that are turned on in the script, you will probably want to use most of them. Do not expect the script to work out of the box, you will have to remove the sections that depend on other scripts and plugins.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110677685770898379?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110677685770898379/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110677685770898379' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110677685770898379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110677685770898379'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/01/tidbits-for-developers-who-use-vim.html' title='Tidbits for developers who use the Vim editor'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110708633802971172</id><published>2005-01-30T14:56:00.000+02:00</published><updated>2005-01-30T14:56:07.443+02:00</updated><title type='text'>Time bug in kernel 2.6.10</title><content type='html'>&lt;p&gt;The kernel 2.6.10 has an uncanny ability to lose track of time when it is sleeping. Whenever I would suspend my computer and then wake it up, I would find the clock hours or even days ahead from reality.&lt;p&gt;

&lt;p&gt;I tried to circumvent the problem with &lt;code&gt;hwclock&lt;/code&gt;, but that made things even worse. &lt;a href="http://www.gnome.org/projects/evolution/"&gt;Evolution&lt;/a&gt; would get extremely confused the moment I resumed my laptop and it would suck up all CPU and then some. In the end I would have to switch to a text console, login (wait 20 seconds for the prompt to come up), &lt;code&gt;killall evolution evolution-alarm-notify evolution-data-server-1.0&lt;/code&gt;, wait another 5 seconds for the processes to actually get killed and then see the flurry of messages from modules being loaded by my resume script.&lt;/p&gt;

&lt;p&gt;To fix the timeshifting problem I had to modify the code as described in &lt;a href="http://lkml.org/lkml/2004/11/22/31"&gt;this LKML post&lt;/a&gt;. The fix is in 2.6.11pre. If you decide to try out 2.6.10, and you use suspend, make sure to apply the patch.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110708633802971172?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110708633802971172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110708633802971172' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110708633802971172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110708633802971172'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/01/time-bug-in-kernel-2610.html' title='Time bug in kernel 2.6.10'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110708945756420905</id><published>2005-01-30T14:55:00.000+02:00</published><updated>2005-01-30T14:55:09.380+02:00</updated><title type='text'>A new Scheme standard in the works</title><content type='html'>&lt;p&gt;I was surprised to find out that &lt;acronym title="Revised^7 Report of the algorithmic language Scheme"&gt;R&lt;sup&gt;7&lt;/sup&gt;RS&lt;/acronym&gt;, a new revision of the &lt;a href='http://www.schemers.org'&gt;Scheme&lt;/a&gt; standard, is being prepared. There is a &lt;a href='http://www.schemers.org/Documents/Standards/Charter/2004-10-13.pdf'&gt;report (PDF)&lt;/a&gt; on the progress of the standard.&lt;/p&gt;

&lt;p&gt;The most important thing in the new standard is that a module system will be defined. Some interesting things have been considered, such as language case-sensitivity (no decision), non-hygienic macros (no decision), square brackets equivalent to parentheses (passed). Lots of practical suggestions (Unicode support, regular expressions, I/O, hash tables, object-oriented programming, network programming, serialisation, etc.) are also being reviewed.&lt;/p&gt;

&lt;p&gt;I was a bit disappointed that a lot of ideas are either still not decided upon or have been postponed for R&lt;sup&gt;7&lt;/sup&gt;RS. It is still nice to know that the language is still evolving and improving&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110708945756420905?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110708945756420905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110708945756420905' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110708945756420905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110708945756420905'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/01/new-scheme-standard-in-works.html' title='A new Scheme standard in the works'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110677789618078841</id><published>2005-01-27T00:18:00.000+02:00</published><updated>2005-01-27T00:18:16.210+02:00</updated><title type='text'>Nasty memory leak in X</title><content type='html'>&lt;p&gt;Quite recently a friend of mine has found the cause of a leak in X that has been plaguing me for ages. The problem is that the X cursor library does not free animated cursors properly. As a result, my X server would hoard hundreds of megabytes of RAM after a few days of use.&lt;/p&gt;

&lt;p&gt;If you are using an animated mouse cursor theme, you might want to check if you are affected (most machines seem not to be for reasons that I have not yet found out). Run &lt;code&gt;top&lt;/code&gt; and find the XFree86 process (you might want to sort by memory usage by pressing &lt;code&gt;M&lt;/code&gt;). Then have a look at the value in the 'RES' column (it is typical for X to hoard lots of virtual memory, so you should not pay attention to the other values). If it is significantly more than about 40m, chances are that you are experiencing the aforementioned leak. I would suggest working around the issue for now by switching to standard non-animated X cursors.&lt;/p&gt;

&lt;p&gt;More information about the bug and a sample application to reproduce the problem is &lt;a href='http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=281050'&gt;available&lt;/a&gt; in the Debian bug tracking system. As far as I can see, the problem has not yet been fixed. By the way, my tests indicate that the problem is pertinent to X.Org too.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110677789618078841?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110677789618078841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110677789618078841' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110677789618078841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110677789618078841'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/01/nasty-memory-leak-in-x.html' title='Nasty memory leak in X'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110720091274641481</id><published>2005-01-26T23:59:00.000+02:00</published><updated>2005-01-31T21:55:18.126+02:00</updated><title type='text'>PyQLogger</title><content type='html'>&lt;p&gt;Since I found out about &lt;a href="http://www.gnome.org/~seth/gnome-blog/"&gt;Gnome Blog&lt;/a&gt;, had a look, liked what I saw, and then discovered the fact that it could not set post titles on blogger.com, I have been looking around for other blog applications that can cooperate with blogger.com. I have found several, and finally settled with &lt;a href="http://pyqlogger.berlios.de/wiki/index.php/Main_Page"&gt;PyQLogger&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While PyQLogger does not &lt;a href="http://pyqlogger.berlios.de/wiki/index.php/Screenshots"&gt;look&lt;/a&gt; as neat as Gnome Blog, it is quite functional. It uses a smart interface to blogger.com - posts can also be retrieved from blogger.com, edited and republished without touching the web browser. I really liked the idea of saving unfinished drafts. HTML highlighting and easily accessible post preview are quite nice to have. Spellchecking is also supported, although it is not very convenient.&lt;/p&gt;

&lt;p&gt;Since PyQLogger is based on PyQt, it does not blend in with my Gnome desktop, but I do not really mind. There are many worse things. The interface is a bit overcrowded. There are some very annoying bugs. The hyperlink dialog is buggy (the "Cancel" button works as "OK", and the "OK" button does not work at all). And it is annoying that Home/End keys jump to the start / end of the paragraph rather than the active line. The OSD library seems to be used out of plain vanity in situations where a statusbar message would do.&lt;/p&gt;

&lt;p&gt;Still, PyQLogger does its job. If someone weeded the bugs out and cleaned up the interface, it would be excellent. For now, it is acceptable, but still better than most of the other clients I have tried.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110720091274641481?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110720091274641481/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110720091274641481' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110720091274641481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110720091274641481'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/01/pyqlogger.html' title='PyQLogger'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110660281033234305</id><published>2005-01-24T23:50:00.000+02:00</published><updated>2005-01-24T23:50:44.606+02:00</updated><title type='text'>Kernel 2.6.10 on a Toshiba laptop</title><content type='html'>&lt;div&gt;
&lt;p&gt;I upgraded the Linux &lt;a href="http://www.kernel.org"&gt;kernel&lt;/a&gt; to 2.6.10 about a week ago. I had been using 2.6.8. Here are some impressions.&lt;/p&gt;

&lt;p&gt;There were a few pleasant changes. I have already  &lt;a href="http://gintasm.blogspot.com/2005/01/cd-packet-writing-on-linux.html"&gt;covered&lt;/a&gt; CD packet writing earlier. ACPI support has also improved a bit. A minor but very pleasant detail is that my laptop automatically resumes now when I open the lid.&lt;/p&gt;

&lt;p&gt;I was surprised to find out that suspend-to-disk kind-of-works now. It used to hang during resume, now it resumes successfully, but maims USB. After resuming the kernel starts spewing messages such as these:
&lt;pre&gt;
Jan 16 17:26:42 localhost kernel: usb 1-2: khubd timed out on ep0out
Jan 16 17:26:49 localhost kernel: usb 1-2: khubd timed out on ep0in
&lt;/pre&gt;
As my USB mouse stops working after this, suspend-to-disk is still not viable for everyday use to me, but at least it seems to be getting there.
&lt;/p&gt;

&lt;p&gt;I have also noticed that the clock would at least a few hours off after each resume. I have worked around by saving the system time to the hardware clock right before suspending, and then restoring the time just after resuming. Nonetheless I keep finding premature Evolution alerts after resuming. Really annoying, I hope this will be fixed.&lt;/p&gt;

&lt;p&gt;3D support in X still breaks after suspend. It's not really important though, I can restart the X server when I really need 3D working. Besides, it is quite slow anyway.&lt;/p&gt;

&lt;p&gt;People who own a Toshiba A15-S157 laptop might find my &lt;a href="http://gintas.pov.lt/files/toshiba-config-2.6.10"&gt;kernel configuration&lt;/a&gt; and &lt;a href="http://gintas.pov.lt/files/memsusp"&gt;suspend script&lt;/a&gt; useful.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110660281033234305?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110660281033234305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110660281033234305' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110660281033234305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110660281033234305'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/01/kernel-2610-on-toshiba-laptop.html' title='Kernel 2.6.10 on a Toshiba laptop'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110652449999819172</id><published>2005-01-24T01:54:00.000+02:00</published><updated>2005-01-24T01:56:11.370+02:00</updated><title type='text'>JScheme</title><content type='html'>&lt;p&gt;I have recently come across an interesting project called &lt;a href='http://jscheme.sourceforge.net/jscheme/main.html'&gt;JScheme&lt;/a&gt;, which, as far as I understand, is something similar to &lt;a href='http://www.jython.org/'&gt;Jython&lt;/a&gt;, but for the &lt;a href='http://www.schemers.org/'&gt;Scheme&lt;/a&gt; language. As Scheme syntax differs a lot from Java (Python syntax is very similar in comparison), JScheme adopted special syntax called &lt;a href='http://jscheme.sourceforge.net/jscheme/doc/javadot.html'&gt;the Java dot notation&lt;/a&gt; to manipulate Java objects, which is quite simple but adequate.&lt;/p&gt;

&lt;p&gt;Since JScheme is implemented in Java, you can run it as an applet too. An
&lt;a href='http://jscheme.sourceforge.net/jscheme/contrib/jswebapp/jscheme/demo/JSchemeEvaluator.html'&gt;online demo&lt;/a&gt; is available. The interface is cumbersome and ugly, but enough to demonstrate the concept.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110652449999819172?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110652449999819172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110652449999819172' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110652449999819172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110652449999819172'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/01/jscheme.html' title='JScheme'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110643006105079170</id><published>2005-01-22T23:40:00.000+02:00</published><updated>2005-01-22T23:41:01.306+02:00</updated><title type='text'>Packrats</title><content type='html'>&lt;p&gt;It is interesting that people have absolutely no problem filling up latest storage devices despite the rapid advances of data storage technology.  This topic has seen some &lt;a href='http://slashdot.org/article.pl?sid=04/12/10/148203'&gt;attention&lt;/a&gt; from the Slashdot crowd. I do not think that the amount of useful data on a typical computer changes at the same astounding rate. So, where does the space go?&lt;/p&gt;

&lt;p&gt;Probably most of the data is multimedia - movies and songs. I wonder how much of those are just played once or twice and then left alone for the rest of time, or until the hard drive dies, whichever comes first. It is none of my business what people do with their multimedia, but I think that it is foolish to hoard things that you will never use.&lt;/p&gt;

&lt;p&gt;Movies, in my experience, are a one-off thing. Some do deserve several viewings, but then you do not wait a year before watching them again. I can not think of a good reason not to delete the movie, unless it is one of the few very specials that you actually would want to see after a long period of time passes. Could it be because it "took me a week to download, so it's precious!" Perhaps a friend might want it some time in the future (I can hear the MPAA growling, but I'm not in the USA so I do not care), but then save him/her a few hours and lend a good book instead.&lt;/p&gt;

&lt;p&gt;Songs are a slightly different matter. In particular because I have a larger store of them than I would want to (80MB of MIDI from the old times, 5GB of MP3s just locally on my laptop and 350MB of sheet music). I could argue that I do listen to various pieces occasionally. I understand why people are reluctant to delete music. However, I still maintain that collecting for the sake of collection is not a bright thing to do.&lt;/p&gt;

&lt;p&gt;Collecting trash is not smart either. Some store all bits of information that they have come in contact with. I say, who cares about the SMS messages, archives of mailing lists, notes, articles that you found "interesting" at the time, artifacts of experiments and primitive one-off scripts. In theory, they could come in useful one day, but in practice they do not by overwhelming proportions.&lt;/p&gt;

&lt;p&gt;I suspect that some people put up with the trash just because they are lazy to clean it up. Unorganised files pile up and then in a few years they have trouble finding anything. Well, I think that just like in real life it pays to have a tidy work environment.&lt;/p&gt;

&lt;p&gt;The big question is, why am I discussing this? I think that usability and efficiency problems arise out of the sheer amounts of cruft accumulated, and we do not notice. Technical ones too, but that is not important. Database-like file systems are promising, but maybe we could go along with what we have now if we revised our habits a bit. I am not comfortable with the fact that the amount of useless information is increasing so rapidly, and we are battling it by improving searching technology. It would be much better if the signal-to-noise ratio could be improved.&lt;/p&gt;

&lt;p&gt;That is a sensible message for developers too: users should be encouraged to throw away what they do not need.&lt;/p&gt;

&lt;p&gt;Such an approach of tidying things up does not work on distributed systems, for obvious reasons. That is why we do need good search capabilities and the semantic web. However, in most cases, you are the  boss of your computer, so locally you can organize things however you want.&lt;/p&gt;

&lt;p&gt;There are practical reasons to keep only useful data around other than searching. Backups are smaller and therefore easier to do, therefore you do them more frequently, therefore your data is safer, QED. Furthermore, there is less risk to accidentally throw away something important while cleaning up junk when you need some extra space.  And for me it's a nice feeling that my computer is not a huge pile of virtual trash with the important things buried somewhere inside.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110643006105079170?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110643006105079170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110643006105079170' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110643006105079170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110643006105079170'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/01/packrats.html' title='Packrats'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110587559428300137</id><published>2005-01-16T14:24:00.000+02:00</published><updated>2005-01-31T21:53:52.683+02:00</updated><title type='text'>CD packet writing on Linux</title><content type='html'>&lt;p&gt;The CD packet writing mode on Linux allows you to mount rewritable compact discs as ordinary read/write media. It brought my attention when I was upgrading my &lt;a href="http://www.kernel.org"&gt;Linux&lt;/a&gt; kernel to 2.6.10. Apparently, patches to implement packet writing were floating around previously for some time, but now it has made it into the mainline kernel (darn, can't wait until &lt;a href="http://www.namesys.com"&gt;reiser4&lt;/a&gt; is merged).&lt;/p&gt;

&lt;p&gt;It is fairly obvious that packet writing support makes using rewritable discs much easier. I have abhorred floppy discs since I got a CD writer. Floppies are so unreliable and their capacity is appalling by modern standards. However, burning CDs involved much overhead - I had to start a burning application, find an unused CD, erase it, create a new compilation, and then finally burn it. That made CDs inconvenient for storing and exchanging small documents of several megabytes.&lt;/p&gt;

&lt;p&gt;Probably the biggest disadvantage of packet writing is that you lose about a sixth of the disc capacity - GNOME shows 550MiB free on a fresh 700MB disc. That means that you will have to burn movies the old-fashioned way, otherwise they will not fit.&lt;/p&gt;

&lt;p&gt;Packet writing is slower than burning normal images, which is not surprising.  I did a small benchmark. Copying a directory of 11 files, about 10 megabytes each, 90MB in total, took about two minutes of real time. My CD burner supports 10x (1500KB/s). I included spin-up time and unmount time. Linux seems to cache writes, so work with the disc is snappy (well, until you fill the buffer), but unmounting takes some time. In theory, the minimum amount of time required would be one minute plus spin-up time. The result is not so bad. If I was burning the data as an image, I would have had to first erase the disc and then wait while lead-in and lead-out were written out in addition to the data itself.&lt;/p&gt;

&lt;p&gt;Compatibility with Windows is extremely important. Modern versions support UDF without problems. I just tried to read the CD on Windows XP. It had the title of "LinuxUDF", included the folder "lost+found", and a empty file "Unallocated space", but other files were read properly. Oh, and that darn GNOME created a directory called .Trash-gintas which I had not noticed. Out of curiosity I tried to write to the CD on Windows by drag and drop, and it did not work, therefore Linux CD-RW support is superior.&lt;/p&gt;

&lt;p&gt;Here is a guide to get CD packet writing working on Debian GNU/Linux (with udev):
&lt;ol&gt;
&lt;li&gt;Upgrade the &lt;a href="http://www.kernel.org"&gt;kernel&lt;/a&gt; to 2.6.10. If you are compiling it yourself, you will need UDF read/write support and packet writing support (CDROM_PKTCDVD).&lt;/li&gt;
&lt;li&gt; &lt;code&gt;modprobe pktcdvd&lt;/code&gt; (add &lt;code&gt;pktcdvd&lt;/code&gt; to /etc/modules if you want). You obviously do not need it if packet writing support is statically compiled into the kernel.&lt;/li&gt;
&lt;li&gt; &lt;code&gt;apt-get install udftools&lt;/code&gt; You need not create the device nodes when asked to, they are for the older packet writing interface.&lt;/li&gt;
&lt;li&gt;Edit the file /etc/default/udftools. Uncomment the DEVICES declaration, set the value to your CD device, "/dev/cdrom" should work in most cases. You will need to run&lt;code&gt;/etc/init.d/udftools start&lt;/code&gt; afterward.&lt;/li&gt;
&lt;li&gt;Find an unused rewritable disc, preferably one that supports fast speeds, and insert it.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;cdrwtool -d /dev/cdrom -q&lt;/code&gt;. The CD will be erased and formatted, an UDF file system will be created on the disc.&lt;/li&gt;
&lt;li&gt;While the CD is being prepared, which will take a while, mounting can be set up. Create the directory /mnt/cdrw, then edit /etc/fstab, add this line:
&lt;pre&gt;/dev/pktcdvd/0 /mnt/cdrw      udf       rw,user,noauto,noatime 0 0&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;After the CD has been prepared, &lt;code&gt;mount /mnt/cdrw&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;I had some permission problems - /mnt/cdrw was owned by root with no word-write permissions. If you make changes to its permissions, they appear to be saved into the CD. I used &lt;code&gt;chmod 1777 /mnt/cdrw&lt;/code&gt;. Maybe there is a better way.&lt;/li&gt;
&lt;li&gt;Try copying files to the mounted disc. I especially like the fact that deleting files is trivial. Run &lt;code&gt;umount /mnt/cdrw&lt;/code&gt; when you're done playing.  If you use GNOME, you should also be able to mount and eject UDF discs by a single click, just like standard CDs. Use the CD-RW icon instead of CD-ROM in the Computer window.&lt;/li&gt;
&lt;/ol&gt;
&lt;/p&gt;

&lt;p&gt;By the way, you can use any file system, not just UDF, but remember to use the &lt;code&gt;noatime&lt;/code&gt; option so that the disc is not written to on every read. You do not want to put too much wear on the disc, as they can endure about a thousand rewrites.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110587559428300137?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110587559428300137/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110587559428300137' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110587559428300137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110587559428300137'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/01/cd-packet-writing-on-linux.html' title='CD packet writing on Linux'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110574450630731824</id><published>2005-01-15T01:15:00.000+02:00</published><updated>2005-01-15T01:20:10.020+02:00</updated><title type='text'>On blogger.com</title><content type='html'>&lt;p&gt;Here's an easy one for the Friday night.&lt;/p&gt;&lt;p&gt;
A few people have been asking about &lt;a href="http://www.blogger.com"&gt;blogger.com&lt;/a&gt;, I thought that I could briefly cover my experiences here.&lt;/p&gt;&lt;p&gt;
Things I like most are the fact that there is no hassle with setting up software on a local server, and that design is a matter of choosing a template. The former has a few drawbacks - I can not have trackbacks as they are not yet supported by blogger.com, and backups are not trivial. I do not care much about either of these. As for design, I can make things look neat, but not attractive and beautiful. Preset templates saved a whole lot of time, although I did spend almost an hour picking one as they are all quite nice.&lt;/p&gt;&lt;p&gt;
My absolute worst complaint about blogger.com is that it treats paragraphs in a completely braindead way. There are two modes: either no paragraph breaks are inserted (you have to write &amp;lt;p&amp;gt; and &amp;lt;br&amp;gt; tags yourself), or each line break is replaced with an &amp;lt;br&amp;gt; tag. That means that you can not have normal paragraphs in &amp;lt;p&amp;gt; tags. Even if you leave an empty line, two breaks are inserted and that's it. I decided to stick with the manual markup option. The developers of blogger.com really ought to address this problem, it does not look hard to fix.&lt;/p&gt;&lt;p&gt;
I was a bit appalled by customisation of links to other blogs. Let me tell how templates work: you choose one from a list (previews are available) and then you can further fine-tune the HTML source. Well, you have to edit the source to add links, which means that if you decide to change the template, they will be lost. I had hoped for a more generic method - links are just a collection of titles and hyperlinks, how hard can it be to implement a page to deal with them?&lt;/p&gt;&lt;p&gt;
Today &lt;a href="http://mg.pov.lt"&gt;Marius Gedminas&lt;/a&gt; brought my attention to gnome-blog, a small GTK app for posting to blogs, written in Python. It looks a bit unpolished, but seems to be quite functional. And judging from the code it should insert those dreaded &amp;lt;p&amp;gt; tags to form paragraphs. This is my first post through this nice program, I will soon find out if publishing works correctly.&lt;/p&gt;&lt;p&gt;
In conclusion, I could recommend blogger.com as a way to publish blogs without hassle. It may not have the latest features, but there should be more than enough for most people.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;b&gt;gnome-blog report&lt;/b&gt;: it did handle the paragraph tags correctly (yay!), but the title I entered was put as the first line of the post, and the real title of the post was left empty.  Well, since it's Python, such a minor problem should be easy to fix.
&lt;/i&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110574450630731824?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110574450630731824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110574450630731824' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110574450630731824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110574450630731824'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/01/on-bloggercom.html' title='On blogger.com'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110566238839582629</id><published>2005-01-14T01:32:00.000+02:00</published><updated>2005-01-14T02:27:16.430+02:00</updated><title type='text'>Me, I, umm, myself...</title><content type='html'>&lt;p&gt;While writing English texts, especially this blog, I frequently shuffle with discomfort as
can not find a way around using the words "I" and "me" several times in almost each sentence of every paragraph.  I guess that using these words a lot is natural, as I am writing a lot about myself, yet it takes some getting used to for me.  Using passive voice is an alternative, but it causes more stylistic problems than it solves.  I think that some prolific writers structure their sentences to dodge the problem somehow, but I just can not grasp, much less adopt it.
&lt;/p&gt;

&lt;p&gt;The awkwardness probably comes from my native language. In Lithuanian there is no need to repeat the "I"'s because all verbs have a first-person form, if my phrasing is correct.  I can only think of the word "am" in English, as in "I am here", as an analogy,  other verbs do not have the difference ("I live" vs. "you live" vs. "they live").  Actually I frequently spot naïve translations from English which indicate the agents explicitly when it is not needed, and this makes the sentences more blunt and unfriendly.  I seem to remember a text which discussed fundamental differences between languages where the agent is implied and ones where it is not, so I might have covered just the tip of the iceberg (note to self: cut down on clichés).
&lt;/p&gt;

&lt;p&gt;One could speculate if using "I" and "me" frequently has a subconscious effect on the writer (or the reader).  However, as I am not a psychologist, I will refrain from discussion.&lt;/p&gt;

&lt;p&gt;I will again slightly change topic here and use the chance to mention E-Prime.  In short, E-Prime is a subset of English which does not include forms of the verb "to be".  There are already enough resources to explain it on the web (such as &lt;a href="http://www.nobeliefs.com/eprime.htm"&gt;this one&lt;/a&gt;), so I need not do that here.  I just thought I would mention it as it tries to deal with other aspects of bluntness of the English language.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110566238839582629?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110566238839582629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110566238839582629' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110566238839582629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110566238839582629'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/01/me-i-umm-myself.html' title='Me, I, umm, myself...'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110557029914846320</id><published>2005-01-13T01:50:00.000+02:00</published><updated>2005-01-13T00:51:39.146+02:00</updated><title type='text'>¿Punctuation?</title><content type='html'>&lt;p&gt;Most of my friends know my uncanny ability to notice typos
everywhere.  I am not sure why that is so, as I do not read all that
much (that I do intend to change).  There is a bit of irony that I am
working on &lt;a href="http://www.schooltool.org"&gt;SchoolTool&lt;/a&gt; (school
administration software) at the moment.  Darn, I wish I was good at
punctuation instead of spelling, which is becoming less useful as
automatic spellcheckers get better.  Which brings me to the point.
&lt;/p&gt;

&lt;p&gt;Recently I have come across an interesting essay called &lt;a
href="http://www.press.uchicago.edu/Misc/Chicago/721833.html"&gt;"The
Philosophy of Punctuation"&lt;/a&gt; by Paul Robinson.  It is rather wordy,
but well worth reading.  I have picked a few things that I could apply
to my own writings.
&lt;/p&gt;

&lt;p&gt;Most importantly the essay brought my attention to the fact that I am
overusing punctuation.  I used to like long, intricate sentences with
dashes, parentheses and semicolons.  Connecting ideas in various ways
seemed interesting and original.  However, Robinson claims that
overusing punctuation indicates a lack of writing ability. "Expository
prose is linear," and therefore ideas should be presented sequentially.
Dashes and semicolons "betoken stylistic laziness," they are a sign of
weakly connected ideas.
&lt;/p&gt;

&lt;p&gt;With regard to long sentences, I read somewhere on the web that
varying sentence length helps keep the reader interested.  I still
rarely use short sentences, but I'm getting better.  At least my recent
writings are stylistically lighter and more lucid than ones I wrote a
few years ago.  I am still dissatisfied with structure of my writings,
that will probably take time to improve.
&lt;/p&gt;

&lt;p&gt;I found the personified descriptions of the punctuation marks highly
entertaining and persuasive.  The style also helps the message that it
is not a good idea to try to outwit yourself.  It is not clever to
obfuscate content, and trying to be modern is a bad excuse.  Making the
text overly complex means that you distance yourself from the reader,
which hinders not only readability of the text, but emotional response
as well.
&lt;/p&gt;

&lt;p&gt;Robinson also expressed the old idea that "Good writing is as much a
matter of subtraction as creation."  This is good to be reminded of, and
so obvious that I need not add anything.
&lt;/p&gt;

&lt;p&gt;For technical people who care about their writing I could suggest to
have a look at Lyn Dupre's "BUGS in Writing: A Guide to Debugging Your
Prose" (&lt;a
href="http://www.amazon.com/exec/obidos/tg/detail/-/020137921X/103-2724917-0023840?v=glance"&gt;amazon.com&lt;/a&gt;).
Although in my opinion sometimes Dupre overshoots while trying to attain
lucidity, that may not be necessarily a bad thing as the goal is to help
people who are already used to a formal, rigid writing style.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110557029914846320?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110557029914846320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110557029914846320' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110557029914846320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110557029914846320'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/01/punctuation.html' title='¿Punctuation?'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110512554090541443</id><published>2005-01-07T21:19:00.000+02:00</published><updated>2005-01-09T00:57:43.926+02:00</updated><title type='text'>Python unit test runners</title><content type='html'>&lt;p&gt;
As I do test-driven &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt;
development almost every day, I care a lot about testing infrastructure.
&lt;/p&gt;

&lt;p&gt;
Currently my development environment of choice is &lt;a href="http://www.vim.org/"&gt;Vim&lt;/a&gt; + a terminal (for running PyUnit
tests).  It's rather low-tech, but it works reasonably well. I usually
do not use Vim's &lt;a href="http://vimdoc.sourceforge.net/htmldoc/quickfix.html"&gt;QuickFix&lt;/a&gt;
because it's a bit cumbersome to use (I do use quickfix in combination
with &lt;a href="http://www.gnu.org/software/idutils/idutils.html"&gt;idutils&lt;/a&gt;).  I
could outline two main inefficiencies of my current approach.
&lt;/p&gt;

&lt;p&gt;First, to run the tests I have to save the changed files (which I
occasionally forget to do), then M-tab to the terminal window and use
&lt;kbd&gt;Up,Enter&lt;/kbd&gt; to run the previous command, which was most likely
to run the tests.  The latter step, which is now pretty much a reflex as
I do it hundreds of times a day, does unexpected things when I forget
that the previous command was something different.  I have tried to
improve upon things by using a shell snippet &lt;code&gt;while true; do ./test
-pv foo bar ; read; done&lt;/code&gt;, which requires only &lt;kbd&gt;Enter&lt;/kbd&gt; to
be pressed.  I find it hard to drop the habit and still press
&lt;kbd&gt;Up,Enter&lt;/kbd&gt; most of the time. Well, at least unexpected things
do not happen.  Yet this is clearly a poor man's approach.  It also
makes changing the arguments to the test runner slightly harder.
&lt;/p&gt;

&lt;p&gt;Second, I am currently doing the jumping to errors manually. QuickFix
could do it automatically, but it sometimes does not work as I would
like it to, because sometimes I want to jump to a function higher up in
the stack rather the one that raised the exception.  Typing the line
numbers in by hand is not that much trouble, but tedious.
&lt;/p&gt;

&lt;p&gt;
The page that turned my attention into my testing routine inefficiencies
is &lt;a href="http://www.c2.com/cgi/wiki?OneButtonTesting"&gt;One Button
Testing&lt;/a&gt;.  It contains some interesting ideas.  I especially liked
the suggestion to use a smart test runner that automatically runs the
tests when you save the code.  Now I am thinking that, for starters, it
might be quite easy to write a small script that would monitor a
directory (either by polling or by utilising dnotify/inotify) and would
invoke an ordinary text-mode test runner when a file changed.
&lt;/p&gt;

&lt;p&gt;
I have thought up some features (in addition to the usual ones) that my
imagined test runner should have:&lt;/p&gt;&lt;p&gt;

&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GUI.&lt;/strong&gt; Command-line interfaces are really powerful and
great for scripting, but they require typing, which is exactly what we
want to avoid. (I would not mind if the backend was a text-based test
runner.)
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Global keyboard shortcuts.&lt;/strong&gt; Some examples:
&lt;kbd&gt;C-M-a&lt;/kbd&gt; to run all tests, &lt;kbd&gt;C-M-l&lt;/kbd&gt; to only run tests
that failed the last time, &lt;kbd&gt;C-M-s&lt;/kbd&gt; to show and hide the test
result window. All without having to switch away from the code editor.
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Notification area support.&lt;/strong&gt; It would be great to see
without switching windows if a test run is in progress, whether the last
run had failures or not, and other things.
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;File monitoring.&lt;/strong&gt; This is the idea from
OneButtonTesting.  The critical thing here is to run the tests only for
the module that has been updated.  Otherwise we either have to run all
the tests of a project (slow) or type in a specific subsystem to test
(error prone and requires typing).
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integration with Vim and &lt;a href="http://www.gnu.org/software/emacs/emacs.html"&gt;Emacs&lt;/a&gt;.&lt;/strong&gt;
As discussed, clicking on a traceback to jump to corresponding code in
the editor would save some keystrokes.  It would be great if it also did
not require using the mouse (e.g., use &lt;kbd&gt;Left/Right&lt;/kbd&gt; to switch
between failed tests, &lt;kbd&gt;Up/Down&lt;/kbd&gt; to walk between stack frames in
a traceback, &lt;kbd&gt;Enter&lt;/kbd&gt; to go to the highlighted code)
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are already quite a few test runners out there, and some of
them already implement a few of the items in the above list. First, the
text-only ones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;a href="http://dev.zope.org/Zope3"&gt;Zope 3&lt;/a&gt; test runner is a
quite usable, and has some nifty features.
&lt;/li&gt;
&lt;li&gt;The &lt;a href="http://www.schooltool.org/"&gt;SchoolTool&lt;/a&gt; test runner (&lt;a href="http://source.schooltool.org/svn/trunk/schooltool/test.py"&gt;download&lt;/a&gt;)
has been written by &lt;a href="http://mg.b4net.lt/"&gt;Marius Gedminas&lt;/a&gt;, my
colleague and a very bright Python hacker (if you are a Python
programmer, make sure to have a look at his &lt;a href="http://mg.pov.lt/blog"&gt;blog&lt;/a&gt;).  I prefer this test runner over
the Zope 3 one, because it is faster (&lt;a href="http://mg.pov.lt/blog/using-schooltool-test-runner.html"&gt;demonstration&lt;/a&gt;) and neater.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are also some GUI test runners out there already.  In my
opinion they are inferior to the text runners available, at least the
ones I have tried.  Here is a list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href="http://www.c2.com/cgi/wiki?PyUnitTestBrowser"&gt;PyUnit
test browser&lt;/a&gt; has integration with vim, idle and kate, but that's
about it.  It is hard to figure out, requires a few dependencies and in
general looks unmaintained.  Besides, it uses Tkinter, therefore it
looks ugly.
&lt;/li&gt;
&lt;li&gt;The &lt;a href="http://pyunit.sourceforge.net/"&gt;PyUnit&lt;/a&gt; GUI test
runner (&lt;a href="http://pyunit.sourceforge.net/screenshot.gif"&gt;screenshot&lt;/a&gt;) is
rather simple and not very useful.  It uses Tkinter too.
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://python.net/%7Egherman/Pycotine.html"&gt;Pycotine&lt;/a&gt; is
for Macs, I have not tried it.
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.wordtech-software.com/pyunit.html"&gt;PyUnitOSX&lt;/a&gt;
seems to be a port of the PyUnit GUI test runner to the Mac.  I have not
tried it either.  Well, at least it looks nicer than the original.
&lt;/li&gt;
&lt;li&gt;The &lt;a href="http://www.nunit.org/index.html"&gt;NUnit&lt;/a&gt; GUI test
runner (&lt;a href="http://www.nunit.org/img/gui-verify.gif"&gt;screenshot&lt;/a&gt;) is not a
Python test runner, but I wanted to mention it because it gets some
things right.  Notably, it sports file monitoring -- whenever you
rebuild your project, the runner notices and resets status of all tests.
Besides, it is not ugly.  However, other things in my wishlist are
missing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
As a sidenote, I would like to mention the std library by Armin Rigo and
Holger Krekel, two top-notch Python hackers.  However, it's buried in
obscurity, I do not think it even has a web page.  You can check it out
from the &lt;a href="http://codespeak.net/"&gt;CodeSpeak&lt;/a&gt; Subversion
repository
(&lt;a href="http://codespeak.net/svn/std/trunk/src/std/"&gt;here&lt;/a&gt;).  The
library makes unit tests more Pythonic by doing dissection of
expressions (it provides values of context variables with the
traceback). It also encourages use of the plain &lt;code&gt;assert&lt;/code&gt;
statement, which is so much cleaner than the Java-esque
&lt;code&gt;self.assertEquals&lt;/code&gt; and others.  As assertEquals was
primarily used so that the value of variables would be shown on failure,
there is no need to use it if you use the std library. There are more
cool ideas, go see for yourself.
&lt;/p&gt;

&lt;p&gt;I would implement the stuff I described myself, but I have quite a
few unfinished matters already (I will cover them in other posts) and my
conscience would not let me drop them and start a yet another project.
Therefore, I am hoping that someone with too much free time and good
Python skills will have a look at my wishlist, say "These are neat
ideas!" and go on and implement them in a couple evenings.  Make sure to
let me know if you do. By the way, I have seen a &lt;a href="http://www.pygtk.org/"&gt;pygtk&lt;/a&gt;-based GUI test runner by &lt;a href="http://mg.pov.lt/"&gt;Marius Gedminas&lt;/a&gt; .  I suspect that it is
rather incomplete, but I would not be surprised if Marius, being so
ingenious, came up with something really useful, as he has with the
SchoolTool test runner.
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Darn, another essay-post.  Indeed, my original intent was to
provide content, but this is too time-consuming to keep up.  I will have
to try to be more concise.&lt;/em&gt;&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110512554090541443?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110512554090541443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110512554090541443' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110512554090541443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110512554090541443'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/01/python-unit-test-runners.html' title='Python unit test runners'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9890172.post-110496780679637582</id><published>2005-01-06T01:30:00.000+02:00</published><updated>2005-01-09T01:09:42.366+02:00</updated><title type='text'>Why blog?</title><content type='html'>&lt;p&gt;Today I would like to discuss the reasons why I thought that blogging
would be a good thing to pick up for me. While there are already
numerous essays covering the psychology of the blogger (such as &lt;a
href="http://grohol.com/blogs/"&gt;this one&lt;/a&gt;), I thought that I could
present a few of my personal thoughts.&lt;/p&gt;

&lt;p&gt;The most straightforward reason why I started this blog is that my
attempts of creating a homepage were rather unsuccessful. I would only
occasionally find time to reserve for building the page, and when I did,
it was not apparent what to do next, what information to put up and how
to organise it, not to mention my poor design skills getting in the way.
Because the process was so slow, it was not fun and a negative feedback
loop ensued. As a result, I have not touched the web page for half a
year. Conversely, it is really easy to post to a blog, so I hope that
blogging will be fun and will not die off.&lt;/p&gt;

&lt;p&gt;A case for blogging is that nowadays there is little point in
carefully organising information that you put up on the web. Chances are
that the people who need the information will come through a web search
engine, therefore, they won't see or care about the structure. Of
course, it is a completely different story for large sites which harbour
lots of information on a specific field, but I am talking about typical
homepages that include information fragmented by nature, for example,
"How to set up Linux on a Toshiba laptop", "Some useful &lt;a
href="http://www.python.org/"&gt;Python&lt;/a&gt; tricks", "My favourite links",
and "Public-domain sheet music of pieces that I like to play". Just post
when you feel like it and the info will be scanned by Google in at most
a week.&lt;/p&gt;

&lt;p&gt;
Technical reasons and fun factor aside, there are more serious reasons
why I picked up blogging. Browsing the web started to seem too passive
for me. I despise television because it makes people passive receivers
of whatever is fed to them. The web is better in this regard, because
you can (and have to) choose what to read. It is much more interactive.
However, I think that to take in the information you need to put it into
your own words, or, even better, to explain it to someone. Posting on a
blog is communication (even though it is indirect), and you can also get
comments, so I expect blogging to be intellectually stimulating.
&lt;/p&gt;

&lt;p&gt;
By the way, &lt;a href="http://www.paulgraham.com"&gt;Paul Graham&lt;/a&gt; has
written an interesting text called &lt;a
href="http://www.paulgraham.com/essay.html"&gt;The Age of the Essay&lt;/a&gt;,
which discusses the idea of the essay and how it improves mind flow.  I
think that some ideas from the text may apply to blogging as well.
&lt;/p&gt;

&lt;p&gt;
My memory is not something I am completely satisfied with. That might be
the reason why when reading a book or a lengthy text I sometimes feel
that reading is pointless. The words just seem to zoom by without a
leaving a lasting trace. I sometimes recognise quotes from books (to my
surprise). However, I find that I can not consciously recall most of the
essence of a book not long after I have finished it.  I have discovered
that whereas rephrasing helps comprehension, writing down the rephrased
thoughts helps memory.  It would be reasonable to hope that jolting down
my thoughts will help me remember things.
&lt;/p&gt;

&lt;p&gt;
Most of the above does not explain why I would want to make my thoughts
available to the public.  (I find it funny that apparently only now have
I realised why people would write diaries.)  Fact is, I am now trying to
be more open and transparent to other people.  I used to be a rather
reserved person, but I have found that it is not the best way.  Besides,
I do not think that I have much to hide - for example, this essay is
completely open and honest, yet I do not think there is anything in here
that I would want to keep secret.
&lt;/p&gt;

&lt;p&gt;
I also find the idea of blogging appealing to reveal my personality to
people who cannot meet me in person.  Just as everyone, I communicate by
e-mail with lots of people whom I have never met.  The Internet is
already an alienating medium in many ways, so it can not be a bad idea
to make communication warmer and more personal.  I, for one, would
really appreciate the chance to find essays similar to this one by
people I have to deal with but can't meet.
&lt;/p&gt;

&lt;p&gt;
The last, trivial and a really simple reason to have a blog is to
improve English skills.  I am not quite satisfied with my English
writing abilities.  In particular, I would like to improve not just the
quality of my writing (which is reasonable, but it still could be much
better), but efficiency as well.  If I develop a habit of posting

regularly, surely there will have to be a noticeable improvement.
&lt;/p&gt;

&lt;p&gt;
I hope you have learnt something about me from this essay.  Even better
if you found out something about yourself - in my opinion, that is the
most important goal of most non-technical writings.  Now go write
something about yourself if you have not yet done that, there is nothing
to lose, only to gain -- to personalise your online identity, and to
find out things you might not have noticed.
&lt;/p&gt;

&lt;br /&gt;

&lt;p&gt;
&lt;em&gt;
Whew, now that was a whole essay rather than a post.  Well, I had lots
of things to say and this particular text would look weird posted a
paragraph a day.  I guess I made up for the lag - darn, five whole days
since the first post, I will have to try and improve...
&lt;/em&gt;
&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9890172-110496780679637582?l=blog.miliauskas.lt' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.miliauskas.lt/feeds/110496780679637582/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9890172&amp;postID=110496780679637582' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110496780679637582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9890172/posts/default/110496780679637582'/><link rel='alternate' type='text/html' href='http://blog.miliauskas.lt/2005/01/why-blog.html' title='Why blog?'/><author><name>Gintautas Miliauskas</name><uri>http://www.blogger.com/profile/02484887646163794311</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://gintas.pov.lt/files/gintas.jpg'/></author><thr:total>2</thr:total></entry></feed>
