Recent blog updates

Shown here are only posts related to fun. You can view all posts here.

Zeno's Flat Screen TV Paradox

If I was to explain Zeno's paradoxes to an American, I'd start with their variation I'd call the Zeno's Flat Screen TV Paradox. The reason why I'd choose it would be its practicality: we have firsthand experience in real-life application of this deeply philosophical problem each time we shop for something.

Too much choice, even in Africa. Thankfully, ancient Greek philosophers are to the rescue.

Imagine you come to a store, and see two TVs: a cheaper 30 inch one for $500, and a more expensive 50 inch one for $1000; otherwise the TVs are identical. Which one would you buy?

Zeno's Flat Screen TV paradox states that the only rational choice would be to buy a 50'' TV. Here's the proof.

Imagine you buy a 30'' TV instead. You bring it home, unpack it, start watching your favorite show, and a salesman knocks on your door. "Hey, I see your TV is only 30'' long," he says. "Would you like to upgrade to a 31'' TV for just 25 bucks?"

Well, 25 bucks isn't that much. It's like a half tank of gas, two cinema tickets, or a cab ride across the city. For that price, you permanently get one inch of screen diagonal! Only a fool wouldn't agree. You seal the deal, the salesman takes your old TV, and installs a new one, and you enjoy your 31 inch LED flat screen.

A moment later, a salesman knocks onto your door and asks if you'd like to increase a diagonal of your TV for 1 inch at only a $25 price. This is as good of a deal as the previous one, Even better: as the diagonal length increases, you get more screen space per inch for the same price! You seal the deal, and get a 32 inch TV. But before you even install it, a salesman knocks onto your door with a great offer...

This repeats until you end up paying $500 + 20*$25 = $1000 for a 50'' inch TV set--just as you could have done at the store in the first place. Since you got it as a series of increasingly lucrative deals, there is no sense to buy a 30'' one, and you should definitely go for a thousand dollar 50''. Which means that, a choice of a 30'' TV is never optimal.

Quot Erat Demonstrandum.

Note that it's sensible to manufacture smaller TVs in smaller quantities, because the comparison with a smaller screen is the gist of the paradox. Meanwhile, people have been buying 30'' televisions over and over, while this is completely irrational! And that's the Zeno's Flatscreen TV Paradox.

Read on | Comments (0) | Make a comment >>

A Tie for a Python Programmer

A couple of weeks ago I started a new project in ROSA. The project is a dynamic system that tracks health of our Linux distribution repository in real-time by watching the builds and repository status, and running external analyzers. This is a relatively small system that should end up with less than 50k LoC, so I could choose any language I wanted. I would choose Ruby, of course, but this time I had to raise the significance of social issues, and chose Python. I never wrote a single Python program before, but all my peers didn't want to learn Ruby, so I took this chance to learn a new language.

Python logo

This is the logo of Python the programming language. Definitely, these aren't snakes, sure.

Python is named after Monty Python's flying Circus, as per wikipedia entry rather than after a non-venomous snake family. Snakes, however, are featured at the Python's logo, and Monty Pythons are not well known in Russia, so it's easier to associate snakes with Python language when it comes to computing.

To aid me in learning a new language, and to make it more fun, I needed an artifact that helps me. Due to my unhealthy devotion to shirts/ties, I thought of buying a tie with snakes painted on them. I didn't find one although I searched all shops in my district, including those that sell clothes for kids. I couldn't even find a tie made out of snake skin; while they're referenced in literature, they're either mythological or require the social connections I don't have to obtain one.

It wasn't until my colleague linked me this website when I found the way to make a snake out of my tire. Indeed, if I can't buy one, why can't I make one?


I started with a black tie I no longer liked. Time to revive it by turning it into a programmer-friendly snake! Here's a step-by-step guide, inspired by the one linked above. You'll need

  • 50 grams of cotton wool;
  • a piece of red cloth (polyethylene should go as well)
  • a sheet of A4 paper to experiment with the eyes, a pen to paint the pupils; and
  • something to attach the two latter things to tie (glue, pins, and/or sticky tape, see below).

Making the Snake Tie

Start with tying your favorite knot, and marking the place where it ends. Starting from that place and below, the two-dimensional tie will turn into a three-dimensional snake. Open the tie up making sure it won't fall apart (I had to re-knot the threads that were running through the yet-to-become Python manually—I didn't have any GIL to assist me!) I had to also open the bottom end of the tie, because it was detached from the upper part:

Start filling the tie with the cotton wool. To make the wool through the tie, you might need something long and stiff, I used a toothbrush.

As you fill the tie, it may no longer keep the original shape. I used a pin to strengthen the lower end. To make the pin completely hidden, stick it into the inner half outwards, and pin the outer one onto it, hiding the pin itself in the fold.

Do not fill it all the way to the knot point! Tie the knot first. Here's the Windsor knot I tied; look how you still have the access to the hole you made at the very beginning. Stuff the tie with more cotton wool.

Now you can attach a tongue. A nice red split tongue is what makes your former tie a mighty snake rather than a boring worm. Cut it from the red cloth you prepared. I had to cut it several times before I managed to make a tongue good enough. Attach it with a small pin, sticking it as close as possible to the tip of the tie. The pin will be concealed when you look from the front side.

Now make eyes for your snake. I just painted with a pen on small pieces of paper. This is an easy part; you may experiment as much as you like; I found that the snake looks most crazy if the eyes are placed close to each other. I also felt that the color of the pupils should fit the color of the tie itself, so I used black.

After you found the proper shape and place for the eyes, you should attach them. Sticking a nail into your future friend's eye is disgusting (and the result wouldn't look real enough), so you'd rather use glue. I didn't have any glue, so I used one-sided sticky tape a body patch was made of, and rolled it up to make it "two-sided".

Your new friend is ready. Make sure it stays away from mice!

If you're brave enough, you may even go to work wearing it.

I hope I won't get fired because of that. This would be programming language discrimination anyway!


So that's how you—or, more likely, your kid—can assemble a Python tie from the old useless things you find at home. I hope that programming Python itself will be different than putting the same old stuff together—and more fun.

Read on | Comments (0) | Make a comment >>

The Most Stupid Mistake You Can Make with Ruby

Programming languages have strict and mostly very compressed syntax. The origins of that are twofold.

First, actively used programming languages have a considerable history, and were started decades ago. Back then, screen space was limited, and, before that, there was little storage available for source code. Second, programmers have technically-oriented minds and like to endow abstract symbols with complex abstractions instead of using words to describe them. That's why, I guess, many programming languages heavily depend on correct usage of individual characters. Even as few characters as one may make a difference in program behavior as well as in whether program compiles.

Such caveats in different languages include:

  1. C++ templates. You can't write map<int,vector<int>> when you define a mapping from integers to arrays of integers, because C++ parsers thinks that >> as a bit-shift operator in an improper place. A correct program differs by a single space between the < signs.
  2. Makefile tabs. A rule body in the Unix Makefiles should be indented with a Tab. Spaces do not work. Being a software with more than 30 years of history, make had it fixed only a year ago.
  3. CSS delimiters. When you define a cascading style sheet, amd want to define the same block of style attributes for a certain class inside a certain tag, you write the selector as tag .class. It's just a space away from tag.class that defines the styles only for tag elements of class class.
  4. C-style equality in conditional statements. If you're a seasoned professional, you should have already forgotten about this. In many languages, including C, Ruby, Python, Javascript, C# and others, if (a = 1) is always true, since it's an assignment of 1 to a, followed by checking the a's value for truthfulness. The correct version of that has one extra equality sign: if (a == 1). More confusion is created by languages, where the first version is the legitimate way to compare values, such as Pascal.

Imagine how surprised I was when I realized that I made a variation of mistake #4 in my Ruby code today! Here's what it was about.

Ruby hash niceness

Named parameter is a way to specify function arguments at call by name (rather than by order, as in the standard function call notation).

Here you may find how the Named Parameter is implemented in various programming languages.

To emulate a Named Parameter Idiom, Ruby uses hashes and some syntax sugar. The last parameter of a function may be a hash, which maps from parameter names to values. Syntax sugar allows a programmer to write

This sugar is not unique to Ruby; Perl also supports it.

instead of

The :name notation specifies a symbolic constant, which effectively is an immutable string that is defined by only one ancillary character.

Such hashes and symbols seem as a very useful feature. It allows you to emulate DSL-s; here's an example of Ruby on Rails web framework routing configuration:

Until one day, after an hour of debugging you find yourself having written something like this:

See what's wrong here? Indeed, here's how the code of the function called might look like:

So, options[:attribute_check] should evaluate to false boolean value, but... :false is a totally different thing; it's an immutable string of five characters that evaluates to true instead! Just one colon that lurked into the code, and it made it behaving very wrong way.

Just like in a C-style typo, some expressions that are evaluated as true in boolean context look like those that are evaluated as false, and you should be careful with the borderline.

New named attribute definition style in Ruby

New named attribute passing style was not designed to address this problem. However, the abundance of colons in such a code makes it look worrying in case there is a mistake like the above:

You see that the mistake is easy to spot, because the conjunction between the name and the parameter value is so ugly, that it immediately draws attention. However, if you actually need to specify symbol as a value, then you'll have to look ugly with this style.

Moreover, you can't erase the space between the parameter name and value, because for this code:

Ruby parser will think that it's false method in an attribute_check object, as :: is a scope resolution operator, just like in C++. Space matters again, as in typo #1 desccribed above.

People say that this style resembles that of C# or JSON. So, maybe, it is a good idea to migrate to it. Only two things prevent me from doing this so far: it's not portable to previous version of Ruby, 1.8 (though it slowly becomes obsolete), and I find the old style look much more cute :-)


This was yet another typo that makes our programs behave differently than we expect them to. And again, it was just one character that breaks the expected behavior of if statements that implicitly convert the condition to boolean type. Unfortunately, while the new Ruby named parameter syntactic sugar could help, it sometimes looks even worse to me.

I hope this post will help you avoid the similar mistake if you code in Ruby.

I would like to end with a joke about a mythical C++ programmer leaving hist last commit after having been fired:

Happy debugging to you, indeed!

Read on | Comments (0) | Make a comment >>

Typical Janitor's Failures

How easy is it, to write a program that removes a file or a folder? Okay, assume you have all the power a modern operating system provides you, including rm shell convenience command, and unlink system call. Do you really think the answer is still "very"?.. Then take a look at these examples.

Permission trap

Today one of my peers, Denis, was writing a program that somehow analyzed packages in Mandriva Linux distribution. Since trying to analyze the contents of a package without unpacking it looks more like gynecologist's work than that of a programmer, the software Denis wrote unpacked it first. Then it analyzed the package, and erased it with rm -rf in order to avoid disk pollution.

But sometimes it failed to erase it, which led to strange failures of the whole program.

The reason was the permission trap. Common sense tells us that if you can create a file, then you can remove it. This is wrong when it comes to uncommon permissions. Certain software that is very secure sets up specific attributes for certain files. In particular, it revoked writing permissions from certain catalogs, which prevented recursive removal of the unpacked files. You may try it yourself:

$ mkdir -p /tmp/try/this; chmod a-w /tmp/try; rm -rf /tmp/try
rm: cannot remove `/tmp/try/this': Permission denied

Oops. Even if you're the owner of the file, you won't remove it. Even --force doesn't help. To avoid this, I guess, you should chmod files recursively before removing them.

Why does Chromium remove its files twice?

By the way, I encountered a couple of engineers from PVS Studio when they visited Institute for System Programming, in which I worked; they were looking for a mentor for a Ph.D. thesis one of them was going to defend. Small world!

One more totally not interesting thing is that they are not going to support Linux because there is no enough users of their software on that platform. This is both funny and sad: on the one hand, Linux should have much more support, but on the other hand, if your static analysis tool is not decoupled enough to be somewhat platform-independent, then you do not deserve a Ph.D.

I read about this interesting issue here. Most likely, it won't hit you in the nearest years if you're using Linux, but for Windows users it might be interesting and maybe useful. Let me quote the piece of code they referenced

Why in the world would anyone try to remove a file twice determinedly? What was the programmer trying to achieve? Let's quote that article again:

A file can be definitely removed or cannot be removed at all only in textbooks and in some abstract world. In the real system it often happens that a file cannot be removed right now and can be removed an instance later. There may be many reasons for that: antivirus software, viruses, version control systems and whatever. Programmers often do not think of such cases. They believe that when you cannot remove a file you cannot remove it at all. But if you want to make everything well and avoid littering in directories, you should take these extraneous factors into account.

"Remove" vs. "unlink"

Okay, so you've managed to remove a file. The question is, have you freed some space on your disk? The answer is maybe.

Removing is called unlinking on purpose. What you do by "unlinking" is removing a reference from a directory index to a certain chunk on your hard disk. The chunk, nevertheless, may persist, especially if there are more references to it. One of the possibilities is hard links, but you explicitly created them. Another could be a badly working file system, but that was your choice.

However, there is a very harsh way to experience the difference between removing and unlinking. Assume you have a long-running program that writes something to its log file. The information it writes is not very useful, and you might want to discard it. As the program spends hours of working, the log file grows larger and larger, and you realize that you really should erase the log to prevent your disk from filling up. You rm -rf log_file, and... nothing happens. The log is still being written somewhere, and there is as little space as there was.

The thing is that you unlinked the file, but the file system's directory index wasn't the last place it was referenced from. Another place is the file handler of the program running, and it will be referenced until the file is closed. Otherwise, as far as I know, the only way to fix it is to shut the program down. So, do not turn on too much logging by default.

Uncannily removing sensitive files

Of course, you know this. It's like knowing that you should move carefully in a room full of rakes and nevertheless getting hit by one because it's just so obvious...

These are classical rm -rf $FOO/* when $FOO happens to be unset... These are when you type rm -rf /etc, and thus crush your system, instead of rm -rf etc to remove a backup copy of /etc you were so prudent to create. These are the famous bumblebee bugfix—or was it mere viral marketing?


Usually, you think that creating is easy, and destroying is simple. In many cases, however, it's not true. In Russia, for instance, it's much easier to open a business than to shut it. And when it gets to removing files, it's also sometimes true. So, if your program really depends on successful file removing, it should be more careful with such a seemingly simple operation.

Read on | Comments (2) | Make a comment >>

Looking for a Match, a Geekier Way

As unlikely as it seems, the "match" the heading refers to is not a regular expression match. Being in a longstanding relationship with computers, I also pay a certain bit of attention to opposite sex subjects of my species. This involves two immediate conclusions:

  • I have a shortage of such subjects available for dating in my nearest social circle;
  • The more information technology-abundant the process of mating is the more I'm likely to succeed.

Which, in turn, makes it obvious that I like to visit dating sites. If your first guess was that I use a geek-oriented fully-automatic neural-bayessian-expert-system-network-powered social site, you would be wrong. Automated matching engines appeared a bad solution: the criteria they use are too generic for a person with perfectionism syndrome, common for programmers though; besides they're not as popular as those that target generic audience. Therefore, the only option I have is to look for the one at generic-purpose dating sites.

The problem with generic-purpose dating sites

These sites (I tried several) share a common issue: they are annoyingly inefficient.

What's the source of the inefficiency there? It's the way search results are presented and managed. Or, to be more specific, how they're unmanageable by design. When you try to look for a woman to date, you're presented with a search result page, which is sorted by a complex weighted formula. A large weight is assigned to the last visit date, however, an even larger weight is of a paid (or, sometimes, free) service to move yourself up in search results page.

No wonder that a lot of women you have already considered as a potential mate and have rejected keep showing up in search result, distracting your attention from those potentially dateable. This decreases the efficiency dramatically.

I already tried to apply a "geek-like" approach to another "real-life" problem I head, an overweight. The solution I found appeared to be quite efficient: the graph of my weight is still the biggest motivator for making myself less fat.

A solution

A solution to this would be to filter search results on server side, discarding girls a user has already seen. However, aside from the apparent marketing-related problems—how would you sell good places in search results if they're so easy to hide permanently?—user-specific search yield should suffer from performance impediments, especially on popular sites.

Therefore, a filter on the user side could solve the problem. And the web browsers (at lease, some of them), do already have such mechanism. User scripts.

I used Firefox and GreaseMonkey to make a simple script to improve the girl finding experience. Here it is:

This script sets up an event listener to the ENTER key. When you press it, it locates the parts of the web page that look like girl userinfo or like search results. If it finds the search result that has already been seen, it shades it, making the other girls more visible. If the script finds that I'm currently at the girl-specific user info page with a lot of details, it will strike out the user next time, because a girl I closely looked and rejected should be even less visible.

The script uses GM_setValue and GM_getValue special functions. Greasemonkey Firefox addon specifically provides them to access a permanent storage that persists across browser invocations.

Here goes the rant

The script, however, looks a bit more monstrous than it should, and there is indeed a number of issues for this. I found a nice JavaScript reference; it was not as unhelpful as many other ones, but some issues left unresolved anyway. Let's enumerate them.

Ajax loading

The simplest architecture for the script, of course, would be just to fix up a page after it's loaded. Why do we need a lot of creepy event listeners?

The key here is after it's loaded. We can't tell when the page, or a piece of its content is loaded when running a userscript. The dating site I targeted was a complex piece of software with a lot of frames, with ajax-powered search result loading, etc. It heavily suffered from the issue described in this StackOverflow question, and the solution presented there with onhashchange event didn't help.

Therefore, I had to retreat to the User Brain Slowness. A user should hit ENTER after the page is loaded, making the script parse everything correctly. However, this worked badly too, hence all these event handlers that seem excessive at first sight.

XML traversal

Okay, so assume we have successfully loaded the document HTML tree. How can I now traverse it, spending as few keystrokes as possible?

As far as I know, there's no way to do this. All ways are browser-specific, and do not look even closely as a foreach loop. You may see these ugly constructs back from 90s near the FIRST_ORDERED_NODE_TYPE constants in the code above.


Having tried this, I really do not understand why JavaScript-based interfaces are becoming industry standard. Perhaps, I know JavaScript too badly to see its full power (this is my first JS program). Or, perhaps, programmers that prefer and are capable to make convenient languages merely steered clear from web-programming, and preferred to lock themselves up in ivory towers...

The only conclusion I'm sure about is that, the night I wrote the script, programming successfully distracted me from women for several hours again. What a jealous activity it is!

Read on | Comments (0) | Make a comment >>

Penn&Paper's Solutions™: Table Scroll Sanitizer

A couple of days ago, doing a routine tasks of analyzing how well our tools were finding Linux kernel bugs, I was to check a large table.

I was to check if there are correlations in values each row between columns A, B, and C that weren't adjacent. The hypothesis was, like "if there is a 1 in B, there should be 1 in either A, or C". However, the table had a lot of rows and columns; so many, that it didn't fit into the screen neither vertically, nor horizontally, so I was quickly getting lost in determining which column is what.

The obvious idea would be to automate this task. However, the data representation wasn't nice enough for automated analysis. First, the table was a page in a browser. Second, there were certain tricky javascripts involved, which prevented me from copying it and pasting to a spreadsheet program or to a plain CSV text file. Also, the table wasn't large enough to implement a script to do the checking, so I started to doing the check manually.

So I called my old friend, Mrs. Violet Page from Penn&Paper's Solutions™. Violet already introduced one of the products to the readers. I asked her if her company has something to offer to me to simplify this daunting task of browsing a big table—and they really had something to offer me!

Table Scroll Sanitizer

The tool they offered was the Table Scroll Sanitizer. The instructions are simple: just touch the relevant columns with the pen tool, and apply the resultant sheet to the browser window:

This way, the sheet you've created won't move when you scroll, and thus you'll always see the columns you're interested in marked. This made the tedious analysis assignment much less tiresome, and my performance had an upheaval.

Free implementation

However, our company wasn't satisfied with the price of this wonderfull Penn&Paper's product. Its price was totally inacceptable: it was just too small for our accountants to bother with arranging the purchase! That's why I decided to make a free implementation, which is both easy to use and free. Here's a screenshot:

Just open a text editor, arrange the marks like you would do with the Table Scroll Sanitizer, and place it right below (or on top of) the broswer, and it also won't move when you scroll either!

So, if you find yourself in a middle of a large table, and you are lost, you now know what to do. Good luck!

Read on | Comments (0) | Make a comment >>

A poor man's benchmark and stopwatch

Recently I wanted to measure how long it would take my program to execute a certain action. I didn't want to search for time-related functions in that language, so I had just been going to just use my Casio watch. However, I suddenly realized that I forgot them at home...

"Wait a minute", I thought, "I have a PC with a modern operating system, openSuSE Linux! How come it doesn't have a stopwatch program?" I scratched my head, but couldn't remember anything like that in standard Linux utils.

I asked my peers about such a program, and Konstantin Vlasov proposed a solution: use... dd!

What is dd?

If you still don't get it, I'll remind you. dd is a standard Unix (Hence Linux) tool... to perform low-level data stream copying. Its most popular use is to clone raw partitions (as array of bytes, not as sets of files):

dd if=/dev/sdb5 of=/dev/sdc1
dd if=/dev/cdrom of=image.iso

But we'll get to its conventional use later, and now...

dd as stopwatch

The funny thing about dd is that in the default mode it prints the time it's been running. Indeed, dd is a data copying program, so it's natural to print, at the end, how much data it has copied, and how fast.

So it prints total size of the data copied, the time it took it to do this, and the resultant speed... Wait a minute... the time! That's it!

To use dd as stopwatch, you don't need to copy actual data. Just run it without arguments and hit Ctrl+C when you need to stop the countdown. Here's how the output will look like:

pavel@lonely ~ $ dd
^C0+0 records in
0+0 records out
0 bytes (0 B) copied, 5.97049 s, 0.0 kB/s

There it is, the stopwatch triggered by just Enter and Ctrl+C keys.

Note that instead of triggering the stop manually with Ctrl+C, you may just send a signal to dd, and have the same effect. We'll utilize this in the further section.

dd as a benchmark

So, we've just learned that dd can print speed of the data copy operation it performed. And Linux has nice pseudo-files that just generate streams of data... why don't we try to use this files to measure how fast can a computer copy nothing to nowhere?

Let's check how much data your machine will copy in ten seconds! Here's a sample listing:

pavel@lonely ~ $ dd if=/dev/zero of=/dev/null bs=64k & sleep 10 ; kill -INT %1 ; wait %1
[1] 885
1434838+1 records in
1434838+0 records out
94033543168 bytes (94 GB) copied, 10.0106 s, 9.4 GB/s
[1]+  Interrupt               dd if=/dev/zero of=/dev/null bs=64k

Standard Linux shell, Bash, has quite simple features to control it child processes. For example, the code at the left features "job specifications" ("jobspecs"). When a program is run in the background (with use of & at the end of a statement, instead of the usual ;), it gets a job number, and its pid can be gotten by writing %n, where n is that number.

In our code we feature sending a a signal to a certain jobspec, and waiting for it (if it weren't for wait, the shell prompt could mingle with the output of the dd's signal handler). And if we only have one job running in current shell, its jobspec will always be %1.

This command will launch dd process that copies a stream of zero bytes maintained by kernel (/dev/zero) to stream that chews everything it gets without any effect (/dev/null). You may try to test how this simple copying works and learn how fast is your... well, it's hard to tell, what exactly, but you can compare computers with your friends and beat them in this competition! We've held dd benchmarking comparison at the message board of our university, and the top result was 70.6 GB/s, which is like ten times faster than on my machine!

By the very same means you may analyze performance of your disk, by putting a file as the of= argument. But that's a poor man's solution anyway, as there are better benchmarks both for disks and for memory.

Other (not interesting) uses of dd

Aside from copying raw partitions (it's especially useful if you're trying to recover your disk, and accessing it as a file system requires a lot of unnecessary reads, which may be harmful), dd may also be used to create big files of specific size. Why would one want it?... Right, to create swap files. Here's a sample listing to create a 1 Gb swap file

I learned this in a hard time at work, where an important launch of our experiments had the controlling program leaked 4 Gb of memory...

Here's a (really good) Wikipedia article about various uses of dd that presents even more examples of the neat tricks you can employ dd for.


Although I'm an experienced Linux user, it doesn't stop to surprise me. The dd program is not the only tool that, due to its simplicity, serves different purposes. That simplicity of basic tools, which leads to their powerful combinations, is one of the things in Linux I appreciate most.

And sometimes it can be even amusing.

Read on | Comments (2) | Make a comment >>

Penn&Paper's Solutions™: Progress Tracker

A couple of weeks ago I began to develop a new component of the system we ship. In order to not get lost in where I currently am, I decided to employ a tool to visualize structure of the component, and to track progress of its development.

However, I was too busy to write a program on my own. Therefore, I decided to purchase an enterprise solution. I analyzed the market, and asked a couple of questions. And I found a product. The product. "Penn&Paper™'s Progress Tracker 8.3 Personal Edition by Penn&Paper™'s Solutions. The one that suited me, fulfilled all my requirements, and was very easy to use.

I was so satisfied with this product, that I even decided to publish an interview with one of "Penn&Paper™'s" sales managers in my extremely popular blog. To make it more interesting, I accompanied it with pictures about my experience with usage of their product.

Interview with a Penn&Paper's Solutions™ representative

So, here it is. Violet Page, a sales manager from "Penn&Paper™'s Solutions" presents their "Progress Tracker 8.3 Personal"!

Pavel Shved: Violet, first, I must confess that I'm a fan of your company nowadays. You seem to create very "natural" products for human beings to operate. So, I guess, that a description of how easy it is to work with would be a good thing to start.

Violet Page: Yeah, "Penn&Paper™'s Progress Tracker 8.3 Personal" is very easy to work with indeed! You start the application, and it automatically opens a sheet. Then you may just select a Pen tool

and draw a couple of lines. You can draw straight and freehand lines—whatever you wish, there's no limitations! This is all what it takes to draw a scheme of component distribution of your application.

P.S. Allright, we'd get a diagram of a component's architecture. But what about progress?

V.P. Oh, that's also easy. Just select a Marker tool,

and apply it to the parts of the system you've implemented

You can apply it to the interfaces and implementations, depending of what you've drawn with a pen tool in the first place. You're free to shade your items partially, and to use different colors.

This way you'll clearly see that the parts you've already implemented are shaded, and those you still haven't—are not.

As you gradually progress in developing the system, you'll shade more and more parts.

And more parts

Until, finally, you implement everything you've planned for the release.

P.S. You said I can draw freehand lines, but what if I just want to type some text?

V.P. That's easy to accomplish through the very same "Pen tool". Just user the context menu and select "type text" item. The text tool supports UTF-8, so you don't have to struggle to type symbols in your native language

P.S. What about teamwork? You know, you usually track progress not just to please yourself. Rather, one of your primary objectives is to provide a shiny picture for your managers and peers. How could I share results of my work with the other developers?

V.P. You have two options here. First, you can take a screenshot, and publish it the way you prefer.

You can post it to your corporate wiki, or mail to the parties interested. Or just make an animated GIF out of it:

P.S. What's the other option?

V.P. Our "Progress Tracker" integrates smoothly with the other "Penn&Paper's Solutions™" products. For example, you may seamlessly re-play your progress when you're having a corporate video conference call with "Penn&Paper's Conference Table™", so that your peers could envision the roadmap of the discussion:

Check out how the developer covers more of the diagram with his Marker tool as he explains the architecture of his software:

The other useful way of integration for collaboration is posting your work onto a "Penn&Paper's Blackboard™" knowledge sharing tool:

P.S. Hey, wait a minute. Collaboration over the same sheet usually causes merge conflicts. What can you do about them? The format you employ is obviously binary, and automatic merges are impossible... aren't they?

V.P. Yes, it's impossible. We adopted a technique familiar to many developers. Your colleagues may just "check out" your sheet (like in older revision-control systems), discuss it, make amendments, and then put it back to your workplace. We think that it's the most natural workflow.

P.S. What about protection? Are my sheets foolproof?

V.P. Well, for any protection there's a person stupid enough to bypass it. However, we provide some protection functionality. The first is the notorious "Trash can", into which your sheets are placed if accidentally deleted.

You can recover them easily from the "Trash can" unless it's really stuffed, and your sheets are disengaged.

However, the Personal Edition doesn't support Undo functionality. For this feature to work, you have to purchase one of our corporate products, such as the aforementioned "Blackboard":

P.S. Alright, so we've observed all the major features. But what's the price?

V.P. We've adopted a pay-as-you-go licensing model, popular in business applications. For example, for 4.95 you may paint 15 miles of lines without restrictions to the number of components you draw, or any time limitations! Our competitors require much greater funding.

P.S. Indeed, I drew this whole system, and the 5$ license isn't even half-used. Mrs. Page, thank you for the interview, and good luck in your future affairs!


So, unless you're dumb, you have already understood that it all is entirely fictional. You know, a whole generation emerged, of people who only saw floppy disks on "save buttons". And here comes a generation that discovers the stuff that surrounds them in their offices by studying allegations in software products, with which they (we) are much more familiar.

Of course, I'll continue to use "Penn&Paper's™" products. In fact, we're currently using one of them, the "Penn&Paner's™ Blackboard" referenced above, which is extremely useful in our Scrum daily meetings. I also have made a quick overview of "Penn&Paner's™ Table Scroll Sanitizer®", an open-source alternative of which I developed. I'm looking forward to more interviews with Violet Page, and, actually, to a small discount on their products >__<.

Read on | Comments (3) | Make a comment >>

An example of indentation

Some languages are whitespace-sensitive, some are not, but in all of them we indent our code.

Why do we do this? To make our programs look readable. To structure them. To separate logical blocks, and collocate items that belong together.

But recently I encountered an interesting indentation pattern. It was in the C sources of an implementation of the OCaml language virtual machine.

(I'll just add a couple of paragraphs, so that "Recent updates" div doesn't make the indentation really ugly.)

(Yes, you should also have a screen wide enough. If you see a messy crap down there, just maximize your browser window, and stretch it beyond the screen border if even that doesn't help.)

Here's an excerpt:

Wonderful, isn't it? This source file has more of that:

I find the alignment of these Asserts and "Case N" comments very beautiful and "mathematical". It provides even more separation of different parts of the code. But not only it's useful, it also makes me want to print the code, set it into a frame and stare at it, smiling.

Read on | Comments (0) | Make a comment >>

Software engineering as Kama Sutra

At the meeting today we thought that the idea of our bored manager (you've seen it in Dilbert) to adapt Scrum is not so bad. It seems we're experiencing sudden attempt to use yet another cool software engineering framework; that is all developers usually don't like. Having been unusually and weirdly excited about such a commonly undesirable change, I tried to figure out why's that...

And I think I got it. Tomorrow we're trying to try a new sex position with my beloved wife. Yes, I lately realized that I'm totally married to my job (which I unconsciously referred to in a recent blog post). And the excitement is that we're finally going to switch that missionary position to something new and with more... movement, I guess.

But then I suddenly realized. The whole software engineering thing is just a large group sex Kama Sutra.

Just look at it.

"Agile methodologies" will totally require you being in a good physical shape to satisfy the project and do a lot of different things for that.

We actually started doing scrum at work a couple of months after this post was published. Here's a post with my impressions on what Scrum is like.

Scrum, with all its "chicken" and "pigs" being a reference to "men" and "women", requires rhythmic moving. However, I think, constantly questioning the partner whether things go well doesn't work well in the bed. Hell, "think"; I know; you too do.

Some techniques are even worse, however. "Extreme programming", that values fast delivery, isn't that women usually want. And this DSDM technique... I don't think it needs further explanations.

Of course, while in nearly every domain of human activity you can find sexual reference, it was funny to look it up in software engineering. However, it appears to be not that funny as I expected. So, basically, tomorrow I'm having a new sex. Isn't it what 80% of blogs are about?

Read on | Comments (1) | Make a comment >>

More posts about fun >>