<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-5375156058364096448</atom:id><lastBuildDate>Sat, 14 Sep 2024 18:10:46 +0000</lastBuildDate><category>.net</category><category>IronPython</category><category>Resolver</category><category>Vim</category><category>giulietta</category><category>Haskell</category><category>debugging</category><category>design architecture</category><category>extremeprogramming</category><category>linux</category><category>mono</category><category>neat</category><category>review</category><category>testing</category><category>xmonad</category><title>Programmer&#39;s Weblog</title><description></description><link>http://blog.kamil.dworakowski.name/</link><managingEditor>noreply@blogger.com (Kamil Dworakowski)</managingEditor><generator>Blogger</generator><openSearch:totalResults>30</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-4524628427052400511</guid><pubDate>Wed, 05 Jan 2022 22:40:00 +0000</pubDate><atom:updated>2022-01-05T22:40:41.214+00:00</atom:updated><title>Home Assistant Renew DHCP Lease</title><description>This is a workaround for a problem with Home Assistant running in a Virtual Machine and not renewing a DHCP lease thus losing the connection to the local network after the lease runs out. You can define an automation that will periodically run a script that pokes the network interface forcing a lease renewal. I did it a while ago so I hope I remember all the elements required to make the workaround work.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The rest api that allows to poke the network interface of the home assistant os is not accessible from outside of the instance. You need to install the &quot;Terminal &amp;amp; SSH&quot; add-on to get access to the os running home assistant.&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Once you &quot;hack the system&quot; and get inside the home assistant via ssh, inside the config directory, define a script that pokes the card:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;curl -X POST \&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; -H &quot;Authorization: Bearer $SUPERVISOR_TOKEN&quot; \&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; -H &quot;Content-Type: application/json&quot; \&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; -d &#39;{&quot;enabled&quot;:&quot;True&quot;}&#39; \&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; http://supervisor/network/interface/enp0s3/update&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Where enp0s3 is the name of the network interface, it might well be different in you setup.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The script needs to be inside the config directory because config directory is special, contents are not deleted on restart for one.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Once you got access to the home assistant os, it is easy to see there seems to be cron available, but I tried in vain to use it. Not only is cron not running the crontab, but also any cron configs are wiped on restart.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Instead you can define a home assistant automation that will invoke the script.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Add to config/automations.yaml:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;- id: renew-dhcp-lease&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; alias: &quot;Renew DHCP lease&quot;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; trigger:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; - platform: time&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; at: &quot;21:35:00&quot;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; action:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; &amp;nbsp; - service: shell_command.cycle_network&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Add to config/configuration.yaml:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;shell_command:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp; cycle_network: bash cycle-network.sh&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This will trigger the action at 21:35 each day, which was good enough for me.&lt;/div&gt;</description><link>http://blog.kamil.dworakowski.name/2022/01/home-assistant-renew-dhcp-lease.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-5313948913036001591</guid><pubDate>Tue, 14 Dec 2021 22:44:00 +0000</pubDate><atom:updated>2021-12-14T22:44:00.047+00:00</atom:updated><title>Xiaomi Kingsmith Walking Pad A1 Pro WPA1F Review</title><description>I&#39;ve been using it since May this year, so for over half a year now. I&#39;m using it as part of a walking desk. It works well for me.

&lt;p&gt;

The belt size is more than enough -- I&#39;ve never tripped, never felt unsure footed. I&#39;d prefer it to be smaller actually, so it had a smaller footprint.

&lt;p&gt;
    
I used the smartphone app very rarely - set the default speed at 3 km/h. I exclusively use the manual mode -- this is the only one that makes sense for a walking desk. I usually walk at 3.5 or 4 km/h, sometimes faster if I want some exercise.
  
&lt;p&gt;
  
The biggest problem for me is the noise the fan makes. This is the fan that cools the engine. It only switches on a minute or two after you start walking and then stays on until the treadmill stops. At lower belt speeds, up to 4km/h, it is noisier than the belt and the engine themselves.
&lt;p&gt;
  
  
At 3.5 km/h the treadmill is 50-51 db before the fan switches on and 52-53 db with it. The fan noise is somehow more annoying too. It is tolerable for me, but it bothers my partner when I&#39;m using it.
It mostly limits the time I&#39;m walking to when she is away. I sometimes get away with using it when she has noise canceling headphones on.
&lt;p&gt;
  
If there was a walking pad running 3.5 km/h at 47 db I&#39;d replace this one in a heartbeat. I would also consider one that has at least a quieter fan.
  
&lt;p&gt;
  
A minor problem with the treadmill is static electricity it creas on the user. I&#39;m not sure what is causing it. I&#39;ve never experienced it from gym treadmills, and it was not happening at the beginning with this one either. Now I need to be grounded or else I experience uncomfortable static discharges when touching a laptop.
  
&lt;p&gt;
Overall the benefits are bigger than the drawbacks.
</description><link>http://blog.kamil.dworakowski.name/2021/12/xiaomi-kingsmith-walking-pad-a1-pro.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-2214800687127807356</guid><pubDate>Sun, 21 Oct 2018 12:00:00 +0000</pubDate><atom:updated>2018-10-21T13:05:15.334+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">giulietta</category><title>Random Seatbelt Alarm While Driving</title><description>&lt;p&gt; My car was intermittently not detecting that the seatbelt is fastened, randomly while driving. Possible solutions:

&lt;li&gt; cleaning the seatbelt tongue with isopropyl alcohol -- the quickest and I was surprised it actually worked, because the tongue did not look dirty
&lt;li&gt; getting a seatbelt extender
&lt;li&gt; replacing the seatbelt tongue -- seems like a lot of work
&lt;li&gt; disabling
the seatbelt check, on Alfa Romeo it can be done only through the OBD connector, but you need a special software
(alfaobd.com, 50EUR, windows, android -- I haven&#39;t tried it)

</description><link>http://blog.kamil.dworakowski.name/2018/10/random-seatbelt-alarm-due-to-dirty.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-2183205542462823040</guid><pubDate>Sun, 21 Oct 2018 11:42:00 +0000</pubDate><atom:updated>2018-10-21T13:13:28.081+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">giulietta</category><title>How To Replace the Accessory Drive Belt (Serpentine Belt) on Alfa Romeo Giulietta 1.4 MultiAir</title><description>
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqVLrhmyMoFIse7OSZmL9MuueA-ywPNmFMEpK1cOZpp30TW_cWy41hPgQ3B7d3nfnI6Iu7WUYbYEwPkLNbkLeoSCOGLvs_gfM1WVprEDMIAbzrElGVCndqU9bTiQ-eAmM1B_vwwgMW/s1600/fullsizeoutput_d16.jpeg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqVLrhmyMoFIse7OSZmL9MuueA-ywPNmFMEpK1cOZpp30TW_cWy41hPgQ3B7d3nfnI6Iu7WUYbYEwPkLNbkLeoSCOGLvs_gfM1WVprEDMIAbzrElGVCndqU9bTiQ-eAmM1B_vwwgMW/s400/fullsizeoutput_d16.jpeg&quot; width=&quot;400&quot; height=&quot;300&quot; data-original-width=&quot;1600&quot; data-original-height=&quot;1200&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

This could apply to other cars in Fiat Chrysler group. Find the
belt on the left of the engine. You can take a picture of the routing. Identify
the belt tensioner by pulling on the belt and seeing which pulley
yields. In my car it is the center pulley. It has a 13mm hex bolt on
it. Hold it while you pull on the belt to see which way it turns as it
yields. In my car it turns clockwise. I think there is a hole to lock
the loosened tensioner in place, but I did not even attempt it due to difficult
access. Use a ratchet and turn the tensioner with left hand and use the right hand to slide
the belt from/onto the bottom pulley. It will be easier to put on a
belt if it is longer rather than shorter. I got myself a rather short
replacement belt and it seemed I had to turn the tensioner to the
limit to put it on.

&lt;p&gt;

Tools used: a 1/2&quot; ratchet with 24cm arm, a 13mm hex socket, head lamp.
</description><link>http://blog.kamil.dworakowski.name/2018/10/how-to-replace-accessory-drive-belt.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqVLrhmyMoFIse7OSZmL9MuueA-ywPNmFMEpK1cOZpp30TW_cWy41hPgQ3B7d3nfnI6Iu7WUYbYEwPkLNbkLeoSCOGLvs_gfM1WVprEDMIAbzrElGVCndqU9bTiQ-eAmM1B_vwwgMW/s72-c/fullsizeoutput_d16.jpeg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-1987202121132416809</guid><pubDate>Thu, 04 Oct 2018 14:19:00 +0000</pubDate><atom:updated>2018-10-21T12:50:45.208+01:00</atom:updated><title>Front Suspension on E-Twow Electric Scooter</title><description>&lt;p&gt;

Etwow scooters are sold under other brands too, including Frugal, SXT and UrbanGlide. I am not actually sure ETWOW is the original manufacturer or just another brand and scooters are manufactured by a yet another company.


&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh24-wl3F9GoocJpedsq3sxK8kj20no3M2q_UkSqeM2tZ5xnGDUSWGAuaWcH5mS6cnBWRvoyTBZYUrihQDWYaa7NqXLE00Yu3ENA1y_zbWLCDRR21BMXwatd3Fa5y4Duw_0et0udd12/s1600/etwow.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh24-wl3F9GoocJpedsq3sxK8kj20no3M2q_UkSqeM2tZ5xnGDUSWGAuaWcH5mS6cnBWRvoyTBZYUrihQDWYaa7NqXLE00Yu3ENA1y_zbWLCDRR21BMXwatd3Fa5y4Duw_0et0udd12/s400/etwow.jpg&quot; width=&quot;400&quot; height=&quot;267&quot; data-original-width=&quot;1500&quot; data-original-height=&quot;1000&quot; /&gt;&lt;/a&gt;&lt;/div&gt;


&lt;p&gt;

I got myself a used one, and it came with several issues, one of which was a stuck front suspension. But first things first. This scooter has no air in tires, instead it relies on a spring front and rear suspension for comfort. In order to actually benefit from it you need to regulate it to your weight so that there is a sag when you mount it. The rear one is very easy, just loosen the screw tightening the spring. The front one has such a screw compressing the spring too, but the access is not easy. You need to detach the wheel and the steer pipe and then you need a special tool, a deep socket wrench size 10 if I remember correctly. Car mechanics usually have those if you can&#39;t find it in a store. See the photo below of how the scooter looks like being ready to loosen the tightening screw. Here is &lt;a href=&quot;https://electro.club/data/docs/e-twow-service-manual.pdf&quot;&gt;a link to the service manual for the scooter&lt;/a&gt;. You need to block the screw from the bottom with a 10 hex key, and turn from the top with the socket wrench. That socket wrench needs to be deep because there are four screw nuts on top of each other.

&lt;p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkmKtm8NvOkJYJp8RT3dOhE3QG0REhjMAAWL0HmG3PCH5ASB3xBFcBhXLpDBM4M4MZ2ZagpbEYC_BIwXH7Z_R25P41MU8ikmArF3IgceDwWxsiDrxOVNhMGMpP9mYTioINRmY1_WZs/s1600/IMG_2816.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkmKtm8NvOkJYJp8RT3dOhE3QG0REhjMAAWL0HmG3PCH5ASB3xBFcBhXLpDBM4M4MZ2ZagpbEYC_BIwXH7Z_R25P41MU8ikmArF3IgceDwWxsiDrxOVNhMGMpP9mYTioINRmY1_WZs/s400/IMG_2816.JPG&quot; width=&quot;300&quot; height=&quot;400&quot; data-original-width=&quot;1200&quot; data-original-height=&quot;1600&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;

For my electric scooter that adjusting was not enough though. The suspension was stuck because the plastic hexagonal bed was too tight for the metal rod that was moving in it. A friendly mechanic polished the metal rod by hand using some sort of metal grinding tool (no machines involved) just to make it a bit thinner so that it would move freely inside the plastic bed.

&lt;p&gt;
Even with the suspension working the ride is not as comfortable as on a full size bike with no suspension. I don&#39;t think it is the superiority of air tires over a spring suspension, but rather a function of wheel size.

&lt;p&gt; Disclaimer: Before all this work, I contacted etwow for some information on how to adjust the front suspension and the person I talked to said the front suspension is not adjustable and that the tightening screw is holding the spring in place and loosening is not advised. I chose to ignore him and adjusted it anyway. It works.

</description><link>http://blog.kamil.dworakowski.name/2018/10/front-suspension-on-e-twow-electric.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh24-wl3F9GoocJpedsq3sxK8kj20no3M2q_UkSqeM2tZ5xnGDUSWGAuaWcH5mS6cnBWRvoyTBZYUrihQDWYaa7NqXLE00Yu3ENA1y_zbWLCDRR21BMXwatd3Fa5y4Duw_0et0udd12/s72-c/etwow.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-9152548116912407700</guid><pubDate>Thu, 04 Oct 2018 11:17:00 +0000</pubDate><atom:updated>2018-10-04T12:17:15.267+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">giulietta</category><title>Alfa Romeo Giulietta Worn Hatch Button Badge</title><description>&lt;p&gt;

This post is about replacing a hatch button badge that looks worn,
but the button works fine. It seems to be a common issue for the model brought on by the way they are attached; I explain below.
You pry the aluminum logo off
the button with a knife - start with stabbing it near the edge toward
the center. The logo badge is attached to the
plastic button underneath with an adhesive. It is a 3 millimeter thick
layer of soft adhesive that is only present in the center of the
button. The adhesive not covering the whole button is most likely the
reason for the wear, as the damage happens near the edges where there
is no adhesive to support button pressing.

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDEsMU5ghCeCb_HAKxpZcBzHSv3IsV0wf_cJY3ucikrBg4M1wrAoQ5EZocC1Sa4aMFePshPH5wm6qi8mVFTVUusDXXOCeHOOdeEN_dJlFRczew4fHvXEXr_YAjfLuQ1uFeESD4_soa/s1600/IMG_2829.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDEsMU5ghCeCb_HAKxpZcBzHSv3IsV0wf_cJY3ucikrBg4M1wrAoQ5EZocC1Sa4aMFePshPH5wm6qi8mVFTVUusDXXOCeHOOdeEN_dJlFRczew4fHvXEXr_YAjfLuQ1uFeESD4_soa/s320/IMG_2829.JPG&quot; width=&quot;240&quot; height=&quot;320&quot; data-original-width=&quot;1200&quot; data-original-height=&quot;1600&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;
I attached a replacement badge using silicone just because I had some and it
seems to have a similar consistency to the original adhesive and would
be similarly easy to detach should I ever need to. I tried to distribute the silicone
on the whole button, not just the middle, to prevent deformation
on pressing. Silicone seems to hold it fine, haven&#39;t lost it yet.

&lt;p&gt;
As to the logo badge, you needed a 75mm wide one, the first one I bought, a 74mm one, did not fit. The badge is the same for the front and back.






</description><link>http://blog.kamil.dworakowski.name/2018/10/alfa-romeo-giulietta-worn-hatch-button.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDEsMU5ghCeCb_HAKxpZcBzHSv3IsV0wf_cJY3ucikrBg4M1wrAoQ5EZocC1Sa4aMFePshPH5wm6qi8mVFTVUusDXXOCeHOOdeEN_dJlFRczew4fHvXEXr_YAjfLuQ1uFeESD4_soa/s72-c/IMG_2829.JPG" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-3866338411849439776</guid><pubDate>Thu, 13 Jan 2011 01:09:00 +0000</pubDate><atom:updated>2018-10-31T10:08:22.624+00:00</atom:updated><title>pinfruit - my mnemonic web app for memorizing numbers</title><description>&lt;p&gt;
I have created a web app to memorize numbers. It implements the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mnemonic_major_system&quot;&gt;mnemonic major system&lt;/a&gt;.
The system works on the principle that it is easier to remember words/sentences/stories than numbers. The web app facilitates
finding sequences of words that encode a number in the mentioned system. I called the app &lt;a href=&quot;http://pinfruit.com/&quot;&gt;pinfruit&lt;/a&gt;.

&lt;/p&gt;&lt;p&gt; My first take on implementing the system was incorrect. I simply
associated digits to letters. According to wikipedia the mnemonic major
system assigns digits to sounds, rather than the letters of the alphabet.
And rightly so, I immediately noticed that it is easier to work with sound associations.

&lt;/p&gt;&lt;p&gt;
My mistake originated in that I
first learned the technique in Poland, and in Polish it does not
matter if you assign digits to letters or sounds because both correspond.
Unfortunately, in English this is not the case, the major difficulty in
learning the language.

&lt;/p&gt;&lt;p&gt;
I have used &lt;a href=&quot;http://pinfruit.com/&quot;&gt;pinfruit&lt;/a&gt; to memorize mainly pins
and phone numbers, but also bank site&#39;s user identifiers, which often
come as numbers.

&lt;/p&gt;&lt;p&gt; The trick is to create a memorable (vivid or absurd) sentence/story for a number. My old
phone number: 07514590312, can be encoded with &lt;i&gt;husky leader leaps midway Hanoi&lt;/i&gt;,
&lt;i&gt;school weather helps Madonna&lt;/i&gt; or &lt;i&gt;sickly water leaps hometown&lt;/i&gt;.
I refer you to the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mnemonic_major_system&quot;&gt;wikipedia article&lt;/a&gt;
for the detailed description of the system.
&lt;/p&gt;</description><link>http://blog.kamil.dworakowski.name/2011/01/pinfruit-my-mnemonic-web-app-for.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-4128785416047103635</guid><pubDate>Sun, 15 Aug 2010 20:41:00 +0000</pubDate><atom:updated>2010-08-15T22:05:11.576+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">design architecture</category><title>From layers to hexagonal architecture</title><description>&lt;p&gt;
The traditional layered architecture consists of data, domain and presentation
layers.
&lt;p&gt;

&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;&quot;http://2.bp.blogspot.com/_qxRRyN-iKdo/TGhRPwSozhI/AAAAAAAAABo/stp-NACaUZo/s1600/tiers.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 260px; height: 400px;&quot; src=&quot;http://2.bp.blogspot.com/_qxRRyN-iKdo/TGhRPwSozhI/AAAAAAAAABo/stp-NACaUZo/s400/tiers.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5505739875563392530&quot; /&gt; &lt;/a&gt;

&lt;p&gt;
 Separating the presentation layer from the domain layer is rather
easy. The presentation layer objects query the domain for data to display
on the screen. The persistence layer is another story. The fact that it
appears below the domain layer prohibits any of the classes in it knowing
about the domain entities.
&lt;p&gt;
But consider a Fetcher class for example, a class that has responsibility for querying
some domain object from the database. It has the domain type in the signature
and thus has to be defined in or above the domain layer. This is
leaking of the data access object out of the persistence layer.

&lt;p&gt;
This problem has been recognized and here we have an architecture which
works around it by separating out the domain objects package. But the result
is not as clear and compelling as the layered architecture.
&lt;p&gt;

&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://1.bp.blogspot.com/_qxRRyN-iKdo/TGhRbJM2oYI/AAAAAAAAABw/in7Ym8I7kOs/s1600/LayeredArchitecture.jpg&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 252px;&quot; src=&quot;http://1.bp.blogspot.com/_qxRRyN-iKdo/TGhRbJM2oYI/AAAAAAAAABw/in7Ym8I7kOs/s400/LayeredArchitecture.jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5505740071228580226&quot; /&gt;&lt;/a&gt;

&lt;p&gt;
The civilisation progressed and an architecture with nothing below the domain model
has been discovered. One can see this in the &lt;a href=&quot;http://dddsample.sourceforge.net/&quot;&gt;ddd sample&lt;/a&gt;.
&lt;p&gt;
&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://3.bp.blogspot.com/_qxRRyN-iKdo/TGhRh9tpFHI/AAAAAAAAAB4/KrStaTEB-lI/s1600/ddd.jpe&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;&quot; src=&quot;http://3.bp.blogspot.com/_qxRRyN-iKdo/TGhRh9tpFHI/AAAAAAAAAB4/KrStaTEB-lI/s400/ddd.jpe&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5505740188403962994&quot; /&gt;&lt;/a&gt;
&lt;p&gt;
The persistence concern is implemented as part of the infrastructure layer. Infrastructure
is that vertical layer that depends on the three other layers. Domain knows nothing about the
infrastructure.

&lt;p&gt;
Another example is the &lt;a href=&quot;http://alistair.cockburn.us/Hexagonal+architecture&quot;&gt;Hexagonal Architecture&lt;/a&gt;.

&lt;p&gt;


&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://1.bp.blogspot.com/_qxRRyN-iKdo/TGhRnEIaqxI/AAAAAAAAACA/4Le84Pj-8iw/s1600/hexagon.gif&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 358px; height: 239px;&quot; src=&quot;http://1.bp.blogspot.com/_qxRRyN-iKdo/TGhRnEIaqxI/AAAAAAAAACA/4Le84Pj-8iw/s400/hexagon.gif&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5505740276026223378&quot; /&gt;&lt;/a&gt;
&lt;p&gt;
The domain sits in the core of the application, with the persistence aspect implemented by an adapter.
The adapter layer corresponds to the infrastructure and the interfaces layer combined from the ddd sample architecture diagram.
The important part is that the domain does not depend on anything else.



&lt;p&gt;
Such layering is achieved by defining service interfaces in the domain layer for persistence purposes. These abstract
interfaces are implemented by the adapters in the outer layer of the application and injected into the
objects that need them.


&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://2.bp.blogspot.com/_qxRRyN-iKdo/TGhRtKlrOOI/AAAAAAAAACI/QTOiMsXqSJc/s1600/enhances-diagram.jpg&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;&quot; src=&quot;http://2.bp.blogspot.com/_qxRRyN-iKdo/TGhRtKlrOOI/AAAAAAAAACI/QTOiMsXqSJc/s400/enhances-diagram.jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5505740380838770914&quot; /&gt;&lt;/a&gt;

&lt;p&gt;
As a result nothing in the domain layer needs to import anything from the hibernate package, or whatever
persistence technology is being used. The domain layer has a custom made, abstract interface to persistence
service, in its own terms. The domain code can be expressed without the details of the persistence technology being used.</description><link>http://blog.kamil.dworakowski.name/2010/08/from-layers-to-hexagon-architecture.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_qxRRyN-iKdo/TGhRPwSozhI/AAAAAAAAABo/stp-NACaUZo/s72-c/tiers.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-3145171950951608168</guid><pubDate>Sat, 27 Mar 2010 12:53:00 +0000</pubDate><atom:updated>2010-03-28T12:06:05.552+01:00</atom:updated><title>GOOS Book</title><description>&lt;p&gt;
&lt;a href=&quot;http://www.growing-object-oriented-software.com/&quot;&gt;
&lt;img style=&quot;float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 240px; height: 319px;&quot; src=&quot;http://2.bp.blogspot.com/_qxRRyN-iKdo/S63_8yIjD7I/AAAAAAAAAA8/nUxiJ7F-h9M/s400/goos.jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5453296143530397618&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.growing-object-oriented-software.com/&quot;&gt;
 Growing Object-Oriented Software, Guided by Tests&lt;/a&gt; by
Steve Freeman and Nat Pryce is a book I was long waiting for. GOOS demonstrates the techniques and highlights the
patterns as they show up in an application grown through the book. An albeit
small but a real world project is being developed from scratch in a way were
tests play as important a role as object-oriented design.

&lt;p&gt; It is an excellent opportunity to see how two skilled developers are
growing application. The authors work in TDD in a style characterised by
extensive mocking to avoid breaking encapsulation. In design they use fine
grain classes. All together the style demonstrated in the book is very
consistent.</description><link>http://blog.kamil.dworakowski.name/2010/03/goos-book.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_qxRRyN-iKdo/S63_8yIjD7I/AAAAAAAAAA8/nUxiJ7F-h9M/s72-c/goos.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-8878604847749365133</guid><pubDate>Sun, 07 Feb 2010 18:03:00 +0000</pubDate><atom:updated>2010-02-07T18:07:03.664+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">IronPython</category><title>IronPython Dictionaries Memory Cost</title><description>&lt;p&gt; Maintaining a mapping as a dictionary can be quite expensive in terms of
memory, more than one would expect. A couple of days ago I have checked with
windbg how much a single entry in a dictionary mapping pairs to ints
costs. The code I measured is:

&lt;pre&gt;
d = {(1, 2): 3}
&lt;/pre&gt;

&lt;p&gt;
I have executed it in IronPython 2.6.

&lt;p&gt;
The graph below depicts what I saw on the heap. Each box
represents a single word in memory. In a 32 bit system,
a word is 4 bytes.

&lt;p&gt;
&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://1.bp.blogspot.com/_qxRRyN-iKdo/S28BDre5yxI/AAAAAAAAAA0/1Phz5vat4WU/s1600-h/oo.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 258px;&quot; src=&quot;http://1.bp.blogspot.com/_qxRRyN-iKdo/S28BDre5yxI/AAAAAAAAAA0/1Phz5vat4WU/s400/oo.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5435564437983054610&quot; /&gt;&lt;/a&gt;

&lt;p&gt;
Every object in .NET runtime has an overhead of two words. These are the pointer
to its class and some house-keeping data, which I don&#39;t know much
about. Allegedly some part of it is used for object locking.

&lt;p&gt; The graph shows objects below buckets array, these are the only that
count. A dictionary is a hashtable which is implemented with an array of
buckets. Each item in the dictionary is kept in a bucket. The size of
the Bucket object determines the size of an entry in the dictionary.

&lt;p&gt;
There are 23 boxes in the Bucket&#39;s subtree, which means its size is 23 * 4 = 92 bytes.
Quite a lot. A million numbers in that dictionary would take almost 100 megabytes!

&lt;p&gt; The main reason it comes out as that many is the generality of the
dictionary. The fact that it can store objects of arbitrary types means
that the numbers must be boxed. .NET generic collections, when specialized
for ints, would store numbers in place saving a lot of space.</description><link>http://blog.kamil.dworakowski.name/2010/02/ironpython-dictionaries-memory-cost.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_qxRRyN-iKdo/S28BDre5yxI/AAAAAAAAAA0/1Phz5vat4WU/s72-c/oo.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-3087147706731832945</guid><pubDate>Tue, 09 Jun 2009 13:21:00 +0000</pubDate><atom:updated>2009-06-09T14:23:55.583+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">extremeprogramming</category><title>Extreme programming too extreme?</title><description>&lt;p&gt; Is extreme programming as a methodology over? Has Kent Beck 
&lt;a href=&#39;http://www.threeriversinstitute.org/blog/?p=187&#39; target=&#39;_blank&#39;&gt;killed it himself&lt;/a&gt;? Until
now he insisted that you not write a single line of code without a failing
test. He was talking about his daughter who allegedly can not even imagine
writing code without tests first (in his book about test driven development)!

&lt;p&gt; Extreme programming is a set of good practices but the
problem is the emphasis on taking them to the extreme thus ignoring
the cost/benefit ratio. There is an obvious trade-off here.

&lt;p&gt; It would be optimal if people wrote just the right amount of tests,
not too little and not too much, to maximise the ROI. That of
course is very hard to judge, but for sure the answer is
not 100% coverage in all cases, as Kent kindly observes in his post.

&lt;p&gt;Extreme programming is flawed as a methodology, but I want
to argue that it is good for learning the craft.

&lt;p&gt; People have natural inclinations for not testing, not integrating
continuously but programming a feature for days not syncing with the main code
base, underestimating features and than putting in long hours, etc. Extreme
programming is like a correction program for these unwholesome inclinations. :)

&lt;p&gt; Aristotle noted in the Nicomachean Ethics that the best way to reach the
golden mean is to aim at the opposite extreme.

&lt;p&gt; In the dimension of testing, for example, people will naturally tend to
write too little tests, usually none. Practising extreme programming forces
us to go to other extreme: from none tests to 100% coverage no matter the
cost. This teaches that you can write tests you didn&#39;t previously
realized, but more importantly it changes the mindset of the programmer.  After
practising extreme programming you will find yourself uncomfortable without the safety net of 
tests, and while you will not necessarily want 100% coverage you will be in a much
better position to judge how much testing is really needed.

&lt;p&gt; I am glad that I was a part of an extreme programming team for
almost 2 years now. We might have been too extreme,
but too extreme in the good direction. 4:1 ratio of tests to code that
we have might be an overkill, but it is certainly better than no tests
at all. I feel similarly about other practices.</description><link>http://blog.kamil.dworakowski.name/2009/06/extreme-programming-too-extreme.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-3882480286134185758</guid><pubDate>Sat, 16 May 2009 10:47:00 +0000</pubDate><atom:updated>2009-05-16T12:02:57.162+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">review</category><title>Sony PRS 505 ebook reader review</title><description>&lt;p&gt; I use Sony PRS 505 for more than a month now (see how it compares with
&lt;a href=&quot;http://wiki.mobileread.com/wiki/E-book_Reader_Matrix&quot; target=&quot;_blank&quot;&gt;other readers&lt;/a&gt;). It came with 100 classic
books, all of which look very tempting. I have already read
over 1000 pages of David Copperfield.

&lt;p&gt;
&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://3.bp.blogspot.com/_qxRRyN-iKdo/Sg6auXkl91I/AAAAAAAAAAM/azf49dUxVqs/s1600-h/sony-reader.jpg&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 280px;&quot; src=&quot;http://3.bp.blogspot.com/_qxRRyN-iKdo/Sg6auXkl91I/AAAAAAAAAAM/azf49dUxVqs/s400/sony-reader.jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5336372729872774994&quot; /&gt;&lt;/a&gt;
(BTW, the Reader shows the beginning of the first chapter of the new &lt;a href=&quot;http://www.manning.com/foord/&quot; target=&quot;_blank&quot;&gt;&quot;IronPython in Action&quot;&lt;/a&gt; book, by my colleagues &lt;a href=&quot;http://voidspace.org.uk&quot; target=&quot;_blank&quot;&gt;Michael Foord&lt;/a&gt; and Christian Muirhead.)

&lt;p&gt; They say that the battery life is 5000 page turns, but mine
died after about 1000 pages of mentioned David Copperfield. I have
been playing with it, and sometimes going back and forth, but for sure that
was not 4000 page turns worth of playing. Anyway, the battery life
is very good, but the 5000 page turns is misleading at best.

&lt;p&gt; The device comes with software for windows. It is not really
a problem for a Linux user, because you can mount the reader like
a usb stick, and copy the books directly - that is how I do it
at least. There is calibre project that is supposed to be heaps
better software for the reader than the official one, 
but it doesn&#39;t start on my system
and I don&#39;t see any reason to investigate -- I&#39;m fine with cp.

&lt;p&gt; I have it for over a month and think it was worth every single
pound I payed for it. I write the review
now, because I have finally bought an ebook on-line and put it on
the reader. That feels right. Although, in the meantime I had
to buy one dead tree book simply because there was no ebook available.
Hopefully that will not happen often as amazon&#39;s Kindle gains
popularity.

&lt;p&gt; My biggest wish is that the screen was larger. Looks like the
upcoming &lt;a href=&quot;http://www.amazon.com/Kindle-DX-Amazons-Wireless-Generation/dp/B0015TCML0&quot; target=&quot;_blank&quot;&gt;Kindle DX&lt;/a&gt; is going to be the right size, though it is going to have a
lower resolution than the Sony Reader. I bet that other manufacturers are already
working on a larger version to compete with DX.

&lt;p&gt; The small size is not really right for books with code and
mathematical formulae (most cs papers and technical books). I found
that putting the reader into horizontal mode (buried down in the
settings) helps a lot with that.</description><link>http://blog.kamil.dworakowski.name/2009/05/sony-prs-505-ebook-reader-reviewj.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_qxRRyN-iKdo/Sg6auXkl91I/AAAAAAAAAAM/azf49dUxVqs/s72-c/sony-reader.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-7231099261664909788</guid><pubDate>Tue, 20 Jan 2009 08:56:00 +0000</pubDate><atom:updated>2009-01-21T23:25:06.798+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Resolver</category><title>Beautiful Code: Resolver One</title><description>&lt;p&gt; &lt;a href=&#39;http://resolversystems.com/&#39;&gt;Resolver One&lt;/a&gt;, aka the Python
Spreadsheet, has a beautiful design at its core, which I would like to
present to the programmer community. No knowledge of Python is necessary to
understand this article.

&lt;p&gt; The goal for the application is to provide seamless integration of 
spreadsheet (formulae in the cells) with sequential code. In MS Excel
the VBA integration is anything but seamless. In the rest of this post
I explain how Resolver One integrates Python with spreadsheet functionality.


&lt;p&gt;
&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiswjUxixVbpddBKQbTDDbLifiajQ7IIAtw1ZcS6fa0akw7f1p1ixZ5jkWMISL5NFM5mp9xz1nkp1omX6LIvmVKndJPQ6br2Zzsq4Y11BYRzCnh-a3ZrD6ikyWVmnGXr7btjKa4AoHR/s1600-h/resolver.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 356px; height: 400px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiswjUxixVbpddBKQbTDDbLifiajQ7IIAtw1ZcS6fa0akw7f1p1ixZ5jkWMISL5NFM5mp9xz1nkp1omX6LIvmVKndJPQ6br2Zzsq4Y11BYRzCnh-a3ZrD6ikyWVmnGXr7btjKa4AoHR/s400/resolver.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5293297420513411730&quot; /&gt;&lt;/a&gt;
&lt;h3&gt; Spreadsheet&lt;/h3&gt;


&lt;p&gt; To ensure that we are on the same page, I&#39;ll pinpoint some facts about
spreadsheets.  In a traditional spreadsheet there are two types of content a
cell can hold:

&lt;ul&gt;
&lt;li&gt; constant: like number, date or text
&lt;li&gt; formula: an expression usually referencing other cells
&lt;/ul&gt;

&lt;p&gt; A user can enter this content by typing to a cell. Additionally, a user
can specify formatting for a cell by various GUI means; for example, make
the cell&#39;s font bold by clicking a toolbar button.

&lt;p&gt; How do you add sequential code to it? Resolver&#39;s solution is to turn the
spreadsheet into sequential program. User&#39;s custom code merges 
with the rest of the spreadsheet thus expressed.


&lt;H3&gt;Spreadsheet as a program&lt;/H3&gt;

&lt;p&gt; In Resolver One, what you see in the grid is the result of 
executing the code displayed in the coding pane.

&lt;p&gt; Following is the code that appears in a document created with File | New
command. I have pruned it by dropping comments and not required import
statements.

&lt;p&gt;
&lt;pre&gt;
from Library.Workbook import Workbook

workbook = Workbook()
workbook.AddWorksheet(&quot;Sheet1&quot;)
workbook.AddWorksheet(&quot;Sheet2&quot;)
workbook.AddWorksheet(&quot;Sheet3&quot;)

Constants = {}
Formatting = {}
workbook.Populate(Constants, Formatting)
&lt;/pre&gt;

&lt;p&gt; The above featured code creates a workbook with three empty worksheets.

&lt;p&gt; Where did the code come from? Resolver One generated it from
the model. By model I mean the data structure that remembers constants,
formatting and formulae input by the user through the GUI interface.


&lt;p&gt; The drill is: Resolver One generates code from the model, executes the program,
takes the resulting workbook object and displays it in the tabbed grid view.
This is called &lt;i&gt;recalculation&lt;/i&gt;.

&lt;p&gt;

&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVg25Msn2Vlc4MfGz3DBuySiekRmmtNSXF1rhUZcU_MKzXkg2gvUj1sYX5XDbYjfECpfYeCRH_erDJ3ta5wOnV0mpNj1r_1pVVN5e4c3p0slY7qMlizi2SHsPNE5f_xkUjbUJldKr6/s1600-h/recalc.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 337px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVg25Msn2Vlc4MfGz3DBuySiekRmmtNSXF1rhUZcU_MKzXkg2gvUj1sYX5XDbYjfECpfYeCRH_erDJ3ta5wOnV0mpNj1r_1pVVN5e4c3p0slY7qMlizi2SHsPNE5f_xkUjbUJldKr6/s400/recalc.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5293297699424666802&quot; /&gt;&lt;/a&gt;

&lt;p&gt; Every time the user changes the model through the GUI commands, a new
recalculation is triggered. The next snippet presents code after me changing
the model by typing to some cells in the grid, I want to give you a feel of the generated
code. I put number &lt;tt&gt;1&lt;/tt&gt; into A1 and formula &lt;tt&gt;=A1*2&lt;/tt&gt; into B1.

&lt;pre&gt;
from Library.Workbook import Workbook

workbook = Workbook()
workbook.AddWorksheet(&quot;Sheet1&quot;)
workbook.AddWorksheet(&quot;Sheet2&quot;)
workbook.AddWorksheet(&quot;Sheet3&quot;)

Constants = {
    &#39;Sheet1&#39;: {
        (1, 1): 1,
    },
}
Formatting = {}
workbook.Populate(Constants, Formatting)

workbook[&quot;Sheet1&quot;].B1 = workbook[&quot;Sheet1&quot;].A1*2
&lt;/pre&gt;

&lt;p&gt;
&lt;H3&gt; User Code &lt;/H3&gt; 

&lt;p&gt; All the code generated from the model is divided among three uneditable
sections in the coding pane:
&lt;ul&gt;
    &lt;li&gt; imports and worksheet creation
    &lt;li&gt; constants and formatting
    &lt;li&gt; formulae
&lt;/ul&gt;

&lt;p&gt; In addition, there are three editable sections for user code, one after
each of the generated ones. The user code is &quot;on the same rights&quot; with the
generated code which is creating the workbook to display; the merge is perfect :).


&lt;p&gt;
&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv5R0YNkPW4hnArC00gI2Cs2RVf9CXB6wrfsvDz3fogIiFI52JHUluMwmte47Mq7uC1Wc9qmISm4Y-0jvggMk3l_FKDnU9TsKadD9uMBy-vbxe2pngpNgFfrfu9syHL4FWkpfW2_U9/s1600-h/recalc2.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 383px; height: 400px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv5R0YNkPW4hnArC00gI2Cs2RVf9CXB6wrfsvDz3fogIiFI52JHUluMwmte47Mq7uC1Wc9qmISm4Y-0jvggMk3l_FKDnU9TsKadD9uMBy-vbxe2pngpNgFfrfu9syHL4FWkpfW2_U9/s400/recalc2.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5293297856618704562&quot; /&gt;&lt;/a&gt;

&lt;h3&gt;Buttons&lt;/h3&gt;

&lt;p&gt; That would have been all and buttons aren&#39;t strictly necessary to
discuss here, but they fit quite well. A button can be created in the user
code and set as the value of a cell. Of course a button has a click handler
that a user would define as a function. This handler is not executed during
the recalculation of course. So when is it executed, and more importantly
what can it do?

&lt;p&gt; The first question is quite easy. The handler gets called when user
clicks the button. He can&#39;t click it until he can see it, which is after the
recalculation is finished the workbook is displayed on the grid.

&lt;p&gt; There is nothing magic in what a button can do. Python has lexical
scopes, so the handler has access to anything that was in scope where the
function was defined, in particular this means the workbook object. For
instance, handler could create two hundred new buttons and place them all
over the grid.

&lt;p&gt; When a user clicks a button the handler is called after which Resolver
One refreshes the grid to display any changes made to the displayed
workbook. There is no recalculation, because the &lt;b&gt;model didn&#39;t change&lt;/b&gt;.
This also means, that any changes made by the button handler will disappear
after the next recalculation is finished, because there will be simply
different workbook object being displayed.

&lt;p&gt; Note: Resolver One 1.4, next major release, will provide means for
changing the model from a button handler.

&lt;h3&gt;Wrapup&lt;/h3&gt; 

&lt;p&gt; So that is the architecture of Resolver One, brought to you by one of
the programmers on the team. Every other feature in the application revolves
around this foundation. Of course the model contains more stuff, for
which code needs to be generated; but it all ends up in one of the three
sections in coding pane. To fully grok different features in Resolver One, you need to understand recalculation.</description><link>http://blog.kamil.dworakowski.name/2009/01/beautiful-code-resolver-one-resolver.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiswjUxixVbpddBKQbTDDbLifiajQ7IIAtw1ZcS6fa0akw7f1p1ixZ5jkWMISL5NFM5mp9xz1nkp1omX6LIvmVKndJPQ6br2Zzsq4Y11BYRzCnh-a3ZrD6ikyWVmnGXr7btjKa4AoHR/s72-c/resolver.png" height="72" width="72"/><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-5026663500827042421</guid><pubDate>Fri, 08 Aug 2008 07:42:00 +0000</pubDate><atom:updated>2008-08-08T08:43:44.206+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">testing</category><title>assert the machine did not explode</title><description>&lt;p&gt;
I see it often done by novices, heck, I used to do
that myself. When writing a unit test for a method cloning an
object, I would put an assertion to check that the original object is left
unchanged.

&lt;p&gt;
Well, that is wrong. This is checking against a possible bug in the
implementation, in which the original object gets modified. But this is just
one thing that could go wrong. There are infinitely many possible bugs like this,
maybe even one that causes your machine to explode. 
You can&#39;t
write assertions against all of them, so don&#39;t do it against any of them.

&lt;p&gt; It has two advantages. First is that you stop worrying you forget
assertions against some possible bug; that is, if you were worrying about
that in the first place. I am sure there are people out there who feel bad
about not testing against printing foul language. Second is that the tests
themselves become smaller, focused on the positive behavior, therefore easier
to read.

&lt;p&gt;
In the specific example of cloning: check that the cloned object is equal
to the original but they are not the same objects, and that is it. Nothing
else.

&lt;p&gt;
Unit tests are positive tests, they should only test what you want
the code to do, not what it shouldn&#39;t do. I am not sure about the case
when we fix a defect, but probably a functional test for the defect 
is enough.</description><link>http://blog.kamil.dworakowski.name/2008/08/assert-machine-did-not-explode.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-7138946970473079261</guid><pubDate>Sat, 05 Apr 2008 23:09:00 +0000</pubDate><atom:updated>2008-04-06T00:13:08.658+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Vim</category><title>GVim to convert code into html</title><description>&lt;p&gt; Few are aware of the fact that gvim can generate html for the code inside
the buffer. The command is :TOhtml; just type it in, and the html will promptly
appear in a split window. 

&lt;p&gt; In the browser, the generated html should look exactly as you
see it in gvim. By default it generates html that should work
in old browsers too, but can be &lt;i&gt;told&lt;/i&gt; to generate CSS stylesheets
or even xhtml. Type :help TOhtml for more details.

&lt;p&gt; It works only in gvim, though; not in vim. It is handy for posting snippets of code on the web.</description><link>http://blog.kamil.dworakowski.name/2008/04/gvim-to-convert-code-into-html.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-8696229231829873901</guid><pubDate>Sun, 02 Mar 2008 14:05:00 +0000</pubDate><atom:updated>2008-03-02T14:29:10.528+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.net</category><category domain="http://www.blogger.com/atom/ns#">mono</category><title>.NET BCL source code</title><description>&lt;p&gt; Source code for .NET Base Class Library has been made available for debugging sessions in
VS2008. It would download one file at a time as they are needed. 
Since then John Robbins and Karem Kusmezer have create a tool to download
all the source files without hassle, great work! The tool is 
&lt;a href=&#39;http://www.codeplex.com/NetMassDownloader&#39;&gt;NetMassDownloader&lt;/a&gt;.

&lt;p&gt; Use it whilst it is still working :). Download, unpack, and run:
&lt;pre&gt;
NetMassDownloader.exe -output bcl
    -d C:\Windows\Microsoft.NET\Framework\v2.0.50727
&lt;/pre&gt;

&lt;p&gt; I executed in in Windows XP as a limited user and have seen numerous
failure messages printed out. Nevertheless, 120MB of data was downloaded and
I had all the files I wanted. The authors advise though to run it as a
privileged process (at least on Vista).

&lt;p&gt; The most interesting parts are 
&lt;tt&gt;bcl/redbits/ndp/clr/src/BCL/System&lt;/tt&gt; and
&lt;tt&gt;bcl/redbits/ndp/fx/src&lt;/tt&gt; where &lt;tt&gt;bcl&lt;/tt&gt; is the name of the
directory you provided after &lt;tt&gt;-output&lt;/tt&gt; switch. Together they are
about 75MB.

&lt;p&gt; It was pretty interesting to read the implementation of the classes I had
been using for so long: String, Hashtable, Arraylist. They are easy to
understand, with lots of comments, and of course in C#. 

&lt;p&gt; The classes I have read are all pretty basic and no wonder there are
lots of pointers and calls into unmanaged code, but it is still readable.

&lt;p&gt; One surprising thing, but obvious after knowing it, is that &lt;tt&gt;&quot;  s  &quot;.Trim()&lt;/tt&gt; will not
create a new string &lt;tt&gt;&quot;s&quot;&lt;/tt&gt;, but return a slice, an object that holds a reference to 
the original string
and knows where are the beginning and the end. This is possible thanks to the immutability
of strings. I bet the substring method is implemented like this too.

&lt;p&gt; There are also some monster methods to be seen. One example is internal
HttpListener.HandleAuthenticate spanning more than half a thousand lines.

&lt;p&gt; BTW source code for mono is available at &lt;a href=&#39;http://www.mono-project.com/AnonSVN&#39;&gt;mono-project.com/AnonSVN&lt;/a&gt;.
Source for mono&#39;s BCL is under mcs/class/corlib. It might be interesting to compare the two.</description><link>http://blog.kamil.dworakowski.name/2008/03/net-bcl-source-code.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-1734087859238964142</guid><pubDate>Sat, 01 Mar 2008 14:09:00 +0000</pubDate><atom:updated>2010-09-16T22:41:42.685+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Vim</category><title>Why Vim&#39;s modes frustrate newbies</title><description>&lt;p&gt;
Some people say they hate the Vim&#39;s modes.
Puzzling, because I consider the modes as the killer feature of Vim, something
that makes it superior to Emacs.


&lt;h3&gt;Why modes rock&lt;/h3&gt;

&lt;p&gt;
I spend most of the time in the normal mode. In this mode, undo is just
&lt;i&gt;u&lt;/i&gt;, delete line &lt;i&gt;dd&lt;/i&gt; and move one word forward &lt;i&gt;w&lt;/i&gt;. In Emacs
these commands would all include ctrl, shift, alt or whatever.  Inserting
text is not what I spend most of the time in an editor on. Most of the time I
need to quickly navigate around and make small modification to an already existing
text. It is false economy to have the keys on the keyboard be bound
to less often used functionality all the time.

&lt;p&gt;
When I reach the exact place where I need to enter some text, I
press &lt;i&gt;i&lt;/i&gt; to enter insert mode, type it, and immediately get back
to normal mode (I get to normal mode by pressing ctrl-[ rather than ESC).


&lt;h3&gt;Why modes frustrate newbies&lt;/h3&gt;

&lt;p&gt; While pairing with people new to Vim I noticed that they leave it
in whatever mode. So if they were inserting, they live it in
insert mode. When they come back to Vim window (after inspecting results of a test
run for example), they think they are typing normal-mode commands, but are
actually in the insert mode typing text. Or the opposite situation: start typing
and instead of inserting text they are rapidly killing one chunk of the file
after another.

&lt;p&gt; Experienced Vimers follow a convention. After doing something briefly in other
mode, immediately go back to the normal mode. I never live Vim in the insert
mode or any other mode than normal; when I get back to the Vim window I can always
assume Vim is in the normal mode.</description><link>http://blog.kamil.dworakowski.name/2008/03/why-vims-modes-frustrate-newbies.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>6</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-7632396150420581291</guid><pubDate>Sun, 17 Feb 2008 15:40:00 +0000</pubDate><atom:updated>2008-12-09T13:23:52.199+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Haskell</category><category domain="http://www.blogger.com/atom/ns#">linux</category><category domain="http://www.blogger.com/atom/ns#">xmonad</category><title>xmonad</title><description>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbGvAoQxipyKADpTPOYVoalot-HB1fbfa8hUlAPPHAob_6w8HypSJ35e5WxirkDa52hB8LdvobELYn-56TGHFR1tYGWjQ6HrWhdZVgssErg78RWigc5EMoeSJ3_n7CVPWIvuZ4Wgf6/s1600-h/Screenshot-1.png&quot;&gt;&lt;img style=&quot;float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbGvAoQxipyKADpTPOYVoalot-HB1fbfa8hUlAPPHAob_6w8HypSJ35e5WxirkDa52hB8LdvobELYn-56TGHFR1tYGWjQ6HrWhdZVgssErg78RWigc5EMoeSJ3_n7CVPWIvuZ4Wgf6/s320/Screenshot-1.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5168246095343581202&quot; /&gt;&lt;/a&gt;
&lt;p&gt;
I am running xmonad! I had some troubles configuring it though.

&lt;p&gt;
I am running Ubuntu Gutsy Gibbon and had to compile it from sources
which turned out to be easy, but then
the instructions to actually run it didn&#39;t work.
I have finally got it going by following instructions in 
&lt;a href=&#39;http://haskell.org/haskellwiki/Xmonad/Frequently_asked_questions#How_can_I_use_xmonad_with_a_display_manager.3F_.28xdm.2C_kdm.2C_gdm.29&#39;&gt;FAQ&lt;/a&gt;
about using xmonad with a display manager.

&lt;p&gt; Before I got xmonad working I tried wmii, which was 
readily available in repositories. After installing it (&lt;tt&gt;sudo apt-get
install wmii&lt;/tt&gt;) you can log out, and in gdm (session manager) change
session to wmii to finally log in and enjoy wmii. wmii would be good
for me had I no dual head configuration. It was treating my two monitors
as one big virtual screen. This meant that a part of it was not visible to me as
my left monitor is shorter than the right. 

&lt;p&gt; xmonad has much fewer lines of code that wmii.
I have seen &lt;a href=&#39;http://www.google.co.uk/url?sa=t&amp;ct=res&amp;cd=1&amp;url=http%3A%2F%2Fweb.cecs.pdx.edu%2F~apt%2Fcs457_2005%2Fhudak-jones.pdf&amp;ei=TFC4R7nAD4nA0wTmkIjtDA&amp;usg=AFQjCNHF8zEHHymYozkfPEIFyMETzHbR6Q&amp;sig2=LOaWEup7LwVV9IYMeqG_7w&#39;&gt;it&lt;/a&gt; a few times already, 
Haskell programs being
very small in comparison with alternatives in other languages.
wmii is proud to keep it small in under 10 000 lines of code, while
xmonad is written in less then &lt;i&gt;1300&lt;/i&gt; lines of Haskell. Additionally, there are 
583 lines in tests. Not bad considering that xmonad turned out to be better then wmii.

&lt;p&gt; I got these numbers by running the following command on ver 0.6 sources,
it ignores blank lines and comments.

&lt;pre&gt;
find . -name \*.hs -exec cat {} \; |\
    egrep -v &quot;^ *$|^ *--&quot; | wc
&lt;/pre&gt;

&lt;p&gt; BTW &lt;a href=&#39;http://xmonad.org/&#39;&gt;xmonad&lt;/a&gt; is cool.</description><link>http://blog.kamil.dworakowski.name/2008/02/xmonad.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbGvAoQxipyKADpTPOYVoalot-HB1fbfa8hUlAPPHAob_6w8HypSJ35e5WxirkDa52hB8LdvobELYn-56TGHFR1tYGWjQ6HrWhdZVgssErg78RWigc5EMoeSJ3_n7CVPWIvuZ4Wgf6/s72-c/Screenshot-1.png" height="72" width="72"/><thr:total>6</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-6098922081506288228</guid><pubDate>Mon, 04 Feb 2008 22:41:00 +0000</pubDate><atom:updated>2009-04-24T11:51:32.173+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">debugging</category><category domain="http://www.blogger.com/atom/ns#">IronPython</category><title>Debugging memory problems in an IronPython app</title><description>&lt;h3&gt;Introduction&lt;/h3&gt;
&lt;p&gt;
This blog entry contains notes on debugging memory problems in an IronPython
application on Windows. I also provide scripts that are helpful in the
process. I should also mention that it is specific to IronPython 1.*.

&lt;p&gt;
The Debugger I was using is &lt;a href=&#39;http://www.microsoft.com/whdc/devtools/debugging/default.mspx&#39;&gt;windbg.exe&lt;/a&gt;.
It is a GUI application, but feels more like a command line. It is certainly more
powerful than Visual Studio Debugger.

&lt;h3&gt;First steps&lt;/h3&gt; &lt;p&gt; First thing after starting windbg should be loading
SOS.dll, which is an extension to windbg providing commands specific to
debugging .NET apps (all starting with !). There is !help command that provides description for
these commands (invoke after loading sos). 
&lt;pre&gt; 
.load sos 
!help 
&lt;/pre&gt;

&lt;p&gt; If you have problems it might be because of the wrong &lt;tt&gt;sos.dll&lt;/tt&gt; version.
There is a different version for each .net runtime. Since IronPython runs in
.net 2.0 you need sos for that specific version. You can find it in the .net sdk
directory and specify the full path for the load command.

&lt;h3&gt;Say freeze ;)&lt;/h3&gt; &lt;p&gt; Windbg can attach to a process by id (F6
shortcut, but there is also a menu item for it).  From that moment on, the
debugee is freezed until you detach from it.

&lt;p&gt;
Before we actually do any debugging we need to have something to debug. Prepare
application so that after it does some considerable leaking, there is a moment in its execution
that you would attach windbg to it. This moment should be after doing thorough
garbage collection to ensure that during debugging we are dealing only with 
&lt;a href=&#39;http://blog.kamil.dworakowski.name/2008/01/anti-pattern-static-subject-to-observer.html&#39;&gt;alive&lt;/a&gt;
objects. You could have code like this:

&lt;pre&gt;
from System import GC
from System.Diagnostics import Process
from System.Threading import Thread
for _ in range(2):
    GC.Collect()
    GC.WaitForPendingFinalizers()
print &quot;attach now to process id %d&quot; %\
        Process.GetCurrentProcess().Id
Thread.Sleep(100000)
&lt;/pre&gt;

&lt;p&gt;
Next thing is to find objects that leak. In our case the biggest ones were Dictionaries
so it was enough to just list all dictionary objects. Sometimes it is unclear which
objects leak, this 
&lt;a href=&#39;http://dotnetdebug.net/2005/07/06/finding-memory-leaks-without-buying-a-memory-profiler/&#39;&gt;blogpost&lt;/a&gt;
suggest a strategy for finding out leaking objects. For this task you will find the
&lt;a href=&#39;http://code.google.com/p/ironpython-debugging-scripts/downloads/list&#39;&gt;dumpdiff.py&lt;/a&gt; helpful.

&lt;p&gt;
This following listing shows output of &lt;tt&gt;!dumpheap&lt;/tt&gt; command the heap with given 
substring in the type name. This is always the first command after attaching
to a process.

&lt;pre&gt;
!dumpheap -type System.Collections.Generic.Dictionary
...
1b489a58 000e2e00      124     
02713600 000e2e00   134720     
02b756b0 000e2e00  2503008     
24b496a0 000e2e00  2503008  
...
&lt;/pre&gt;

&lt;p&gt;
Now copy one of the addresses and issue gcroot command to find some of the
chains of references holding the object alive. I&#39;ll take the last address.
It is worth mentioning that 24b496a0 points to 
an array that holds the entries of the dictionary.

&lt;p&gt;
&lt;font class=&#39;code&#39;&gt;
!gcroot 24b496a0&lt;br/&gt;
...&lt;br/&gt;
13ab6360(&amp;lt;Unloaded Type&amp;gt;)-&amp;gt;&lt;br/&gt;
13ab63bc(IronPython.Runtime.FieldIdDict)-&amp;gt;&lt;br/&gt;
13ab63c8(System.Collections.Generic.Dictionary`2[[IronPython.Runtime.SymbolId, IronPython],[System.Object, mscorlib]])-&amp;gt;&lt;br/&gt;
13ab6424(System.Collections.Generic.Dictionary`2+Entry[[IronPython.Runtime.SymbolId, IronPython],[System.Object, mscorlib]][])-&amp;gt;&lt;br/&gt;
186787d4(&amp;lt;Unloaded Type&amp;gt;)-&amp;gt;&lt;br/&gt;
...
&lt;/font&gt;

&lt;p&gt;
The previous listing shows only a fragment of the output of the &lt;tt&gt;!gcroot&lt;/tt&gt; command.
Arrows indicate directions of references. In the output of &lt;tt&gt;!gcroot&lt;/tt&gt; command, the root
(a static object or value on some stack) will be at the top whereas the
object you invoked the &lt;tt&gt;!gcroot&lt;/tt&gt; with will be towards the bottom.

&lt;h3&gt;Difficulties in debugging an IronPython app&lt;/h3&gt; &lt;p&gt; Python is a dynamic
language and that makes it more difficult to debug IronPython than C# for
example (with windbg). There are two problems. Firstly, types defined in
IronPython appear under windbg as &lt;i&gt;Unloaded Type&lt;/i&gt;.  Even if the type
names would be shown (no clue why they are not), they would be C# types (or
should I say .NET native types) like &lt;tt&gt;OldType&lt;/tt&gt; and &lt;tt&gt;UserType&lt;/tt&gt;: the guts of the
IronPython implementation, not the classes defined in our IronPython code.

&lt;p&gt;
Secondly, the attributes
of an object are not fields. They are stored in a dictionary, and to make
things worse, that dictionary is not keyed by strings but by SymbolIDs.
Somewhere in memory lies a table containing strings to which SymbolIDs hold indexes.

&lt;p&gt; To find out the attribute name or the type name there are 
many commands needed. I have created
&lt;a href=&#39;http://code.google.com/p/ironpython-debugging-scripts/downloads/list&#39;&gt;two scripts&lt;/a&gt; to automate it. Explaining the windbg scripts is out of scope for this
entry, but I think I will post about it soon.

&lt;h3&gt;attr script&lt;/h3&gt;

&lt;p&gt; The first script, attr, takes two addresses as arguments, one to the
array holding the dictionary entries, second to the value of the
attribute, and prints the name of the attribute. Below I include the same
fragment of the gcroot output plus example use of the attr. It will display the name under
which 186787d4 is kept in the __dict__ of 13ab6360. Note that I pass to
attr the address of the array not 13ab6360.

&lt;p&gt;
&lt;font class=&#39;code&#39;&gt;
...
13ab6360(&amp;lt;Unloaded Type&amp;gt;)-&amp;gt;&lt;br/&gt;
13ab63bc(IronPython.Runtime.FieldIdDict)-&amp;gt;&lt;br/&gt;
13ab63c8(System.Collections.Generic.Dictionary`2[[IronPython.Runtime.SymbolId, IronPython],[System.Object, mscorlib]])-&amp;gt;&lt;br/&gt;
13ab6424(System.Collections.Generic.Dictionary`2+Entry[[IronPython.Runtime.SymbolId, IronPython],[System.Object, mscorlib]][])-&amp;gt;&lt;br/&gt;
186787d4(&amp;lt;Unloaded Type&amp;gt;)-&amp;gt;&lt;br/&gt;
...&lt;br/&gt;
$$&amp;gt;a&amp;lt;c:\path\attr 13ab6424 186787d4&lt;br/&gt;
Name: System.String&lt;br/&gt;
MethodTable: 790fc6cc&lt;br/&gt;
EEClass: 790fc62c&lt;br/&gt;
Size: 110(0x6e) bytes&lt;br/&gt;
 (C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)&lt;br/&gt;
String: _GUIThreadTestCase__guiControl&lt;br/&gt;
&lt;/font&gt;

&lt;p&gt;
The above listing assumes you save the &lt;tt&gt;attr&lt;/tt&gt; script in &lt;tt&gt;c:\path&lt;/tt&gt;, and the 
dollars are required, pounds will not do. 

&lt;p&gt;Make sure you invoke it giving an address of a dictionary entry
array keyed by &lt;tt&gt;SymbolId&lt;/tt&gt;s like in the above example.

&lt;p&gt;
So the above gives the name of one attribute. To get more attributes
you can invoke &lt;tt&gt;!dumparray&lt;/tt&gt; on the entry array, which will display
all the values there which you can then check individually with 
attr script (or write another script to automate it ^^).

&lt;pre&gt;
!dumparray -details &amp;lt;entryArrayAddress&amp;gt;
&lt;/pre&gt;

&lt;p&gt; The attr script may not work if the executable you are debugging is
running from a path that contains spaces. There is one constant in the
script that would have to be increased to make up for that additional space.

&lt;h3&gt;usrtype script&lt;/h3&gt;

&lt;p&gt; The next script is less reliable that the first one, it worked half 
the time I invoked it on a &lt;i&gt;Unloaded Type&lt;/i&gt; object. I think
it works for &lt;tt&gt;UserType&lt;/tt&gt;, so I named it &lt;tt&gt;usrtype&lt;/tt&gt;. It takes just one
argument which is the address of an object and returns the name of 
its Python type.

&lt;pre&gt;
$$&amp;gt;a&amp;lt;c:\path\usrtype &amp;lt;address&amp;gt;
&lt;/pre&gt;

&lt;p&gt;
I again assume you have it saved in c:\path.


&lt;h3&gt;!dumpobj&lt;/h3&gt;

&lt;p&gt; Now the most frequently used command, &lt;tt&gt;!dumpobj&lt;/tt&gt;.
It displays the values of the fields of an object. Of course
it displays only the fields defined in the .net class. It
knows what the object&#39;s type is, because each object on
the managed heap has the pointer to its type in its first
4 bytes (or 8 if it is 64 bit machine).

&lt;p&gt;Since all the leaking I was chasing ware caused by 
&lt;a href=&#39;http://blog.kamil.dworakowski.name/2008/01/anti-pattern-static-subject-to-observer.html&#39;&gt;design 
flaw in implementation of events in IronPython&lt;/a&gt;, I usually 
looked for object of type ReflectedEvent in the chain displayed
by the !gcroot. ReflectedEvent stores the name of the event. It
was usually also useful to inspect the IronPython.Runtime.Calls.Method
further down the chain,
from which you can get the name of the method handling the event
as well as the class this method is defined in.

&lt;h3&gt;Tips &amp; Tricks&lt;/h3&gt;
&lt;p&gt;
I hope you will find them useful.

&lt;h4&gt;Testing that the memory leak is gone&lt;/h4&gt;
&lt;p&gt;
So you got rid of the memory leak, but how do you test
that it is gone? I mean an automated unit test! 
&lt;p&gt;
&lt;font class=&quot;code&quot;&gt;
obj = objectThatMightLeak()&lt;br&gt;
weakRefToObj = WeakReference(obj)&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;del&lt;/b&gt;&lt;/font&gt;&amp;nbsp;obj&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;_ &lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;in&lt;/b&gt;&lt;/font&gt;&amp;nbsp;range(&lt;font color=&quot;#ff00ff&quot;&gt;2&lt;/font&gt;):&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GC.Collect()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GC.WaitForPendingFinalizers()&lt;br&gt;
assert !weakRefToObj.IsAlive&lt;br&gt;
&lt;/font&gt;

&lt;p&gt;
&lt;tt&gt;WeakReference&lt;/tt&gt; will allow GC to collect the object, and after
collection it will answer if the object was garbage collected. The &lt;tt&gt;del obj&lt;/tt&gt; line is very important,
ware it not there the test would have no chance of passing.

&lt;h4&gt;Marking objects&lt;/h4&gt;

&lt;p&gt; Let&#39;s say you suspect that some object is not being garbage collected, and its class
is defined in Python. 
Because of the dynamic nature of Python, its class is not represented as .NET type, hence you 
can&#39;t simply find it with &lt;tt&gt;!dumpheap -type &amp;lt;type_name&amp;gt;&lt;/tt&gt; command.
&lt;p&gt;
My mother works in laboratory, when she analyzes samples, she sometimes marks them with
special substance to make some elements stand out. You can mark Python objects in a similar way.

&lt;pre&gt;
from System import GopherStyleUriParser
pythonObject.tag = GopherStyleUriParser()
&lt;/pre&gt;

&lt;p&gt; GopherStyleUriParser is a good enough mark, there is low probability you
will have a second one on the heap, and because it is .NET type you can find it easily with
&lt;tt&gt;!dumpheap -type Gopher&lt;/tt&gt;. Then invoke &lt;tt&gt;!gcroot&lt;/tt&gt; on it
and you will find that the chain goes through your object.

&lt;p&gt; &lt;b&gt;Update:&lt;/b&gt; Previously I was recommending using ArithmeticException instead of GopherStyleUriParser for the tag; don&#39;t do this. As soon as you would get rid of the other leaks, the object would be kept alive by the instance of ArithmeticException, which captures the stack trace.

&lt;h4&gt;Nuking events&lt;/h4&gt;

&lt;p&gt; That one is a dirty hack. All the trouble I had with memory leaks were because of the 
events, how about nuking them? 

&lt;p&gt;The reason the IronPython team didn&#39;t just use the
.net implementation of events was that they wanted to allow removing handlers by object equality,
rather then by referential equality. 
By referential equality I mean comparing objects&#39; references
(&lt;tt&gt;is&lt;/tt&gt; operator in Python). 

&lt;p&gt; So how about defining an object that is equal to everything?

&lt;p&gt;
&lt;font class=&quot;code&quot;&gt;
&lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color=&quot;#008080&quot;&gt;EqualityForAll&lt;/font&gt;(object):&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;def&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color=&quot;#008080&quot;&gt;__eq__&lt;/font&gt;(_, __):&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;True&lt;br&gt;
&lt;/font&gt;

&lt;p&gt; That is a very fine fellow, which we can use to get all the handlers out of
an event.
&lt;p&gt;
&lt;font class=&quot;code&quot;&gt;
e = EqualityForAll()&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;_ &lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;in&lt;/b&gt;&lt;/font&gt;&amp;nbsp;irange(&lt;font color=&quot;#ff00ff&quot;&gt;100&lt;/font&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;control.OnClick -= e&lt;br&gt;
&lt;/font&gt;

&lt;p&gt; Ok, that will kill at most 100 handlers, but there is no way you can
find out how many there are. And not, it will not throw an exception if
there are no more handlers. If I remember correctly from looking at the
implementation code (open source is great), there are some exception being
thrown under the hood, but are swallowed higher up. This makes the operation
costly if there are no handlers, as the exception in .NET are much more
expensive than in CPython.


&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;
I thought that finding and stopping the leaks would be easy, but it took many days.
Perhaps fixing the IronPython implementation could have taken less time. Anyway,
if you think that the &lt;a href=&#39;http://blog.kamil.dworakowski.name/2008/01/anti-pattern-static-subject-to-observer.html&#39;&gt;bug&lt;/a&gt; should be fixed, please &lt;a href=&#39;http://www.codeplex.com/IronPython/WorkItem/View.aspx?WorkItemId=14454&#39;&gt;vote for it&lt;/a&gt;. It was given a low
priority and it is not easy to do, so without votes it might not make it to IronPython 2.0.</description><link>http://blog.kamil.dworakowski.name/2008/02/debugging-memory-problems-in-ironpython.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-4208805129209595920</guid><pubDate>Thu, 31 Jan 2008 01:35:00 +0000</pubDate><atom:updated>2012-10-12T03:29:11.419+01:00</atom:updated><title>Arc</title><description>&lt;p&gt;I have just read &lt;a href=&#39;http://ycombinator.com/arc/tut.txt&#39;&gt;the Arc tutorial&lt;/a&gt;. Here are some comments.  &lt;p&gt;&lt;i&gt;Since functions of one argument are so often used in Lisp programs, Arc has a special notation for them.  [... _ ...]  is an abbreviation for (fn (_) (... _ ...)).  So our first map example could have been written &lt;/i&gt; &lt;pre&gt;arc&amp;gt; (map [+ _ 10] &#39;(1 2 3))
(11 12 13 . nil)
&lt;/pre&gt;I know this feature from Nemerle, and miss it when programming in other languages.  &lt;p&gt;Another nice one seems to be ~ operator for negating a function, though would not be nearly as useful as the last one.  &lt;pre&gt;arc&amp;gt; (map ~odd &#39;(1 2 3 4 5)) 
(nil t nil t nil)
&lt;/pre&gt;&lt;p&gt;Code for adding an element to a hashtable does not look very natural:  &lt;pre&gt;arc&amp;gt; (= (airports &quot;Boston&quot;) &#39;bos)
bos
&lt;/pre&gt;In Python it would be: &lt;pre&gt;airports[&quot;Boston&quot;] = &#39;bos
&lt;/pre&gt;</description><link>http://blog.kamil.dworakowski.name/2008/01/arc.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-2389102216973256331</guid><pubDate>Wed, 30 Jan 2008 01:47:00 +0000</pubDate><atom:updated>2008-01-30T02:07:04.895+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Resolver</category><title>Resolver One for Open Source</title><description>&lt;p&gt; &lt;a href=&#39;http://www.resolversystems.com/screencasts/&#39;&gt;Resolver One&lt;/a&gt;, 
a new MS Excel&#39;s alternative, is currently available in
&lt;a href=&#39;http://www.resolversystems.com/get-it/&#39;&gt;two versions&lt;/a&gt;. 
First is a vanilla commercial one, whereas the second,
Resolver One - Non-Commercial, requires a bit of explanation.

&lt;p&gt; Resolver One - Non-Commercial is free (as in beer). Internally at
Resolver we used to call it Resolver One for Open Source. Not
because it comes with sources, because it doesn&#39;t, but because
it could only be used to produce open source. Since then we
have further relaxed the license to allow personal use.

&lt;p&gt; What a user gets after installing Resolver One Non-Commercial is 
feature-wise the same application as in the commercial one, but with 
a different license. The license requires the user to 
&lt;b&gt;make his spreadsheets open source&lt;/b&gt; or mark them as personal --
not for redistribution and profit.

&lt;p&gt; Technically, the Non-Commercial version will not save the spreadsheet
file until user decides on a license for his spreadsheet. When he tries to
save the file for the first time, he will be presented with seven well known
open source licenses to choose from (MIT, GPL, Creative Commons, ...), but
he can also mark it as personal. If he selects one of the open-source licenses, it is included on top of the code part of the
spreadsheet, making his spreadsheet free (as in speech).</description><link>http://blog.kamil.dworakowski.name/2008/01/resolver-one-for-open-source.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-2121982592248525823</guid><pubDate>Sun, 06 Jan 2008 16:39:00 +0000</pubDate><atom:updated>2008-12-09T13:23:53.683+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">IronPython</category><title>Anti-pattern: static subject to observer mapping</title><description>&lt;h4&gt;Short description&lt;/h4&gt;
&lt;p&gt;
When implementing observer pattern in a language with automatic garbage collection 
don&#39;t use static mapping from subject to observer. Doing this will
cause memory leaks.

&lt;p&gt;
Such an implementation involves having a hashtable which keys are subjects and values
are lists of observers. Then to notify about a change in a subject, get the list of its observers
from the mapping and notify them one by one.


&lt;h4&gt;Glossary&lt;/h4&gt;
&lt;p&gt;

&lt;b&gt;GC&lt;/b&gt; - &lt;a href=&#39;Garbage Collector&#39;&gt;Garbage Collector&lt;/a&gt;.
&lt;br&gt;
&lt;b&gt;Dead object&lt;/b&gt; - an object is dead when it is eligible for garbage collection 
(can&#39;t be reached by strong references from any root). By symmetry, an object can be called &lt;b&gt;alive&lt;/b&gt;.
&lt;br&gt;
&lt;b&gt;Strong reference&lt;/b&gt; - a reference that keeps an object alive (normal reference), as opposed to a weak reference.
&lt;br&gt;
&lt;b&gt;Weak reference&lt;/b&gt; - a reference that is not taken into account by GC. 
In .NET there is WeakReference class to define weak references. As far as I know this is the only way
to define a weak reference.

&lt;h4&gt;What is wrong with static subject to observer mapping&lt;/h4&gt;
&lt;p&gt;
&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLDKPRXWhZUCwhAZgRe1L22c_0IYzdE6GK7mD7w-0NOJU5gu6Ojn6n6KFzW-9R0LyqghqhcnuEFniyrQ_-Rny56leBRUNyKstaUqePDTJlVdza35qMdiesCoJcycix77MBu-God-KP/s1600-h/normal_obs.dot.png&quot;&gt;&lt;img style=&quot;float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLDKPRXWhZUCwhAZgRe1L22c_0IYzdE6GK7mD7w-0NOJU5gu6Ojn6n6KFzW-9R0LyqghqhcnuEFniyrQ_-Rny56leBRUNyKstaUqePDTJlVdza35qMdiesCoJcycix77MBu-God-KP/s320/normal_obs.dot.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5152405166255286418&quot; /&gt;&lt;/a&gt;

For a warm-up I will discuss the traditional implementation of observer pattern.
The nodes on the diagram represent objects. An arc from one object to 
another means that it is possible to get from one to the another following strong
references.

&lt;p&gt;
In the first diagram, observer can be reached from subject and vice versa.
The fact that observer can be reached from subject follows from subject keeping
a list of observers to notify. 

&lt;p&gt;
I would like to point out that the arrow from observer
to subject on this diagram indicates that there is, maybe indirect, way by strong
references from observer to subject, this does not follow from observer pattern.
However this being optional, in production code it is quite often that observers
keep references to the subjects.

&lt;p&gt;
What happens in this case when there are no more references to both subject and 
observer (apart from their own cycle of references)? They can&#39;t be reached from 
any root, so they are dead and the memory they occupy will be released during next 
garbage collection.

&lt;p&gt;
&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjLBaIj-7qXSgotV-uCKHuarmaawjsJqdVuXJYvwUKC1N_BWJBoNARUOSfiQLyiOfzoNeYej1OWcf8R1P6A-BfgdHU51BkFMY67tAZzzwzq8hZaqi-f8AZx0WEPAgxFpM130PDvykK/s1600-h/static.dot.png&quot;&gt;&lt;img style=&quot;float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjLBaIj-7qXSgotV-uCKHuarmaawjsJqdVuXJYvwUKC1N_BWJBoNARUOSfiQLyiOfzoNeYej1OWcf8R1P6A-BfgdHU51BkFMY67tAZzzwzq8hZaqi-f8AZx0WEPAgxFpM130PDvykK/s320/static.dot.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5152405655881558178&quot; /&gt;&lt;/a&gt;

The second diagram shows a situation where observers are kept in a weak hashtable.
The dashed arc from entry to subject indicates a weak reference.
This one is not that bad. If there are no references to subject and observers
apart from those on the diagram, the subject can be garbage collected, there being
only a weak reference to it. The observer will be kept alive by the strong reference
from weakhashmap, but WeakHashMaps are usually implemented so that on adding a new
entry they will remove entries which keys have been garbage collected. This prevents entries
with dead keys to pile up.

&lt;p&gt;
The third and last diagram depicts a case where there is a reference from observer
to subject. This is the situation which results in memory leaks. 
In this configuration the weakHashMap will keep both subject and observer
alive and every other object that can be reach from either of them.

&lt;p&gt;
&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_CJgs_3880hZ0K7APPXWQgs11X9eOTzswG9i8e7dHlbYSgXhf-IauagXAT0hF-sUQxn3zHhsoyJ7zVNYyuMib7LpQ7XndffxAg6ns_6bUNv2DWPJNxl8sawjunwcCCrUijyTPpbgO/s1600-h/static_cyclic.dot.png&quot;&gt;&lt;img style=&quot;float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_CJgs_3880hZ0K7APPXWQgs11X9eOTzswG9i8e7dHlbYSgXhf-IauagXAT0hF-sUQxn3zHhsoyJ7zVNYyuMib7LpQ7XndffxAg6ns_6bUNv2DWPJNxl8sawjunwcCCrUijyTPpbgO/s200/static_cyclic.dot.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5152405866334955698&quot; /&gt;&lt;/a&gt;
This happens because the reference from entry to the value must be strong, 
otherwise an observer might get garbage collected when its subject is still alive.

&lt;h4&gt;Known occurrences&lt;/h4&gt;
&lt;p&gt;
I have first come across this anti-pattern in the 
&lt;a href=&#39;http://hannemann.pbwiki.com/Design+Patterns&#39;&gt;paper&lt;/a&gt; about implementing GOF design 
patterns in AspectJ by Jan Hannemann and Gregor Kiczales. Gregor Kiczales is renowned for
leading the team in XEROX PARC that invented aspect-oriented programming.

&lt;p&gt;
In this paper they have a definition of an aspect, ObserverProtocol, that keeps a 
&lt;a href=&#39;http://java.sun.com/j2se/1.4.2/docs/api/java/util/WeakHashMap.html&#39;&gt;WeakHashMap&lt;/a&gt;
from subjects to list of observers. This mapping not being static per se, is kept alive 
throughout the lifespan of a program execution.

&lt;p&gt;
The second use I have seen was in 
&lt;a href=&#39;http://www.codeplex.com/IronPython/WorkItem/View.aspx?WorkItemId=14454&#39;&gt;IronPython&lt;/a&gt;&#39;s 
implementation of events. IronPython has it&#39;s own implementation of events because the one
in .NET runtime is not sufficient for IronPython&#39;s requirements.

&lt;p&gt;
For IronPython programmers it means that hooking to events will cause memory
leaks if source of the event can be reached from the handler (very common).

&lt;h4&gt;Summary&lt;/h4&gt;

&lt;p&gt; Both of these cases show how easy it is to make this mistake, therefore I have documented
it as an anti-pattern for the benefit of mankind ;).</description><link>http://blog.kamil.dworakowski.name/2008/01/anti-pattern-static-subject-to-observer.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLDKPRXWhZUCwhAZgRe1L22c_0IYzdE6GK7mD7w-0NOJU5gu6Ojn6n6KFzW-9R0LyqghqhcnuEFniyrQ_-Rny56leBRUNyKstaUqePDTJlVdza35qMdiesCoJcycix77MBu-God-KP/s72-c/normal_obs.dot.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-3567529796726999477</guid><pubDate>Thu, 03 Jan 2008 21:44:00 +0000</pubDate><atom:updated>2008-01-18T12:21:52.502+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.net</category><category domain="http://www.blogger.com/atom/ns#">neat</category><title>All possible FontStyles</title><description>&lt;p&gt;
That was funny. To instantiate Font in .NET 2.0 you call one of many 
Font&#39;s constructors. Basically you provide a font family (either an
object of the class FontFamily or a name of one as a string), size
and FontStyle. There is a constructor that doesn&#39;t take a FontStyle,
it assumes the FontStyle.Regular as default.

&lt;p&gt;
A FontFamily is a collection of fonts. Arial family will have Arial
Regular, Arial Bold, Arial Bold Italic...

&lt;p&gt;
Now, in theory there might be a family with only Bold Italic.
The requirement is in case there is no style
the user requested, give back a font from the family in any available style.

&lt;p&gt;
Unfortunatelly in FontFamily object there is no property returning available
members of the family, but there is a method for checking if given FontStyle is available.

&lt;p&gt;
FontStyle is an enumeration with the following members.
&lt;pre&gt;
FontStyle.Regular = 0
FontStyle.Bold = 1
FontStyle.Italic = 2
FontStyle.Underline = 4
FontStyle.Strikeout = 8
&lt;/pre&gt;

&lt;p&gt;
A font style can be created by bitwise or-ing the values. For example Bold Italic can
be defined by FontStyle.Bold | FontStyle.Italic wihich makes 3.

&lt;p&gt;
How to generate all possible combinations? 

&lt;p&gt;

&lt;font face=&quot;monospace&quot;&gt;
&lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;i &lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;in&lt;/b&gt;&lt;/font&gt;&amp;nbsp;xrange(&lt;font color=&quot;#ff00ff&quot;&gt;16&lt;/font&gt;):&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fontStyle = Enum.ToObject(FontStyle, i)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;fontFamily.IsStyleAvailable(fontStyle):&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Font(fontFamily, fontSize, fontStyle)&lt;br&gt;
&lt;/font&gt;

&lt;p&gt;
Integers from 0 to 15 form all valid combinations of the FontStyle. This sixteen numbers can
be represented with 4 bits, 15&#39;s binary representation having them all lit (8 + 4 + 2 + 1).</description><link>http://blog.kamil.dworakowski.name/2008/01/all-possible-fontstyles.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-2570546873799748489</guid><pubDate>Fri, 21 Dec 2007 21:16:00 +0000</pubDate><atom:updated>2007-12-21T21:21:11.891+00:00</atom:updated><title>BHO.CVX Trojan</title><description>&lt;p&gt;
My friend got this on his computer. The
most annoying thing for him was that his antivirus software would popup a warning
message about this Trojan every now and then.

&lt;p&gt;
The BHO probably stands for Browser Helper Object; I could find
it inside the Add-ons to IE, but deactivating it didn&#39;t help.
Thankfully the antivirus was yelling which file the Trojan is in, it
couldn&#39;t delete it because it was in use. Even in safe mode
the file was locked.

&lt;p&gt;
I was able to delete it from command line after booting up 
the computer using windows install CD and choosing Recovery mode 
(or sth like that, I have German Windows :) ).</description><link>http://blog.kamil.dworakowski.name/2007/12/bhocvx-trojan.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-5375156058364096448.post-893640700213131556</guid><pubDate>Sun, 16 Dec 2007 22:09:00 +0000</pubDate><atom:updated>2008-01-03T21:50:08.234+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.net</category><category domain="http://www.blogger.com/atom/ns#">IronPython</category><title>Evil locale</title><description>&lt;p&gt;
.NET is trying to protect developers from making simple mistakes 
while providing them with all sorts of non obvious problems completely 
for free.

&lt;p&gt;
The simple mistake is trying to mutate a &lt;b&gt;struct&lt;/b&gt; returned by a property.
Line 14 in the example code raises compile time error. This line is otherwise completely fine except that it doesn&#39;t make sense -- the Start property is returning a copy of the value type Point.

&lt;p&gt;
&lt;font face=&quot;monospace&quot;&gt;
&lt;font color=&quot;#804040&quot;&gt;&amp;nbsp;1 &lt;/font&gt;&lt;font color=&quot;#2e8b57&quot;&gt;&lt;b&gt;struct&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Point {&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;&amp;nbsp;2 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#2e8b57&quot;&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color=&quot;#2e8b57&quot;&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;x;&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;&amp;nbsp;3 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#2e8b57&quot;&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color=&quot;#2e8b57&quot;&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;y;&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;&amp;nbsp;4 &lt;/font&gt;}&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;&amp;nbsp;5 &lt;/font&gt;&lt;font color=&quot;#2e8b57&quot;&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Line {&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;&amp;nbsp;6 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Point start;&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;&amp;nbsp;7 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Point end;&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;&amp;nbsp;8 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#2e8b57&quot;&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Point Start {&lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;get&lt;/b&gt;&lt;/font&gt;&amp;nbsp;{&lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;start;}}&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;&amp;nbsp;9 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#2e8b57&quot;&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Point End {&lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;get&lt;/b&gt;&lt;/font&gt;&amp;nbsp;{&lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;end;}}&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;10 &lt;/font&gt;}&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;11 &lt;/font&gt;&lt;font color=&quot;#2e8b57&quot;&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color=&quot;#2e8b57&quot;&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Main {&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;12 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#2e8b57&quot;&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color=&quot;#2e8b57&quot;&gt;&lt;b&gt;static&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color=&quot;#2e8b57&quot;&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Main() {&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;13 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Line l = &lt;font color=&quot;#804040&quot;&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Line();&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;14 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;l.Start.x = &lt;font color=&quot;#ff00ff&quot;&gt;2&lt;/font&gt;&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;15 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;font color=&quot;#804040&quot;&gt;16 &lt;/font&gt;}&lt;br&gt;
&lt;/font&gt;
&lt;p&gt;

The example comes from &lt;a href=&#39;http://www.codeplex.com/IronPython/Wiki/View.aspx?title=Value%20Types&amp;referringTitle=More%20Information&#39;&gt;here&lt;/a&gt; 
The page explains that in such a case IronPython will also fail (by design) with an error.

&lt;p&gt;
Now about the free errors. They are all sponsored by the evil locale. Parsing in .NET takes
the operating system&#39;s locale into account. In Poland the floating point numbers are written
using coma instead of a dot. So 2.3 is written as 2,3. Trying to parse your settings
file containing floats on a computer with Polish locale will throw an exception if there
are any dots in them.

&lt;p&gt;
But it is not just parsing. If you invoke ToUpper on a string it also takes locale into account.
In Turkey they have dotted i and dotless ı. The letter i (the dotted one obviously) has upper case
equivalent which has a dot above it (expressible in unicode). If you have good fonts you should 
be able to see it right here: İ.

&lt;p&gt;
One more thing, when dealing with DateTime think about Buddhist Era in Sri Lanka :).</description><link>http://blog.kamil.dworakowski.name/2007/12/evil-locale.html</link><author>noreply@blogger.com (Kamil Dworakowski)</author><thr:total>1</thr:total></item></channel></rss>