Online communities

I am part of some online “communities” but then again, I'm not—somehow. It's funny as I regularly contribute to some of them, namely Wikimedia Commons, Wikipedia, Rosetta Code and Stack Overflow (and its relatives). Now currently there are elections for new moderators on Stack Overflow and I (as most users) was asked to vote:

Stack Overflow moderator election information bar

But I honestly can't vote there.

The problem is that Stack Overflow is largely content-based. Whatever there may be in community is mostly driven by content and not by the users. Which means that I could judge the candidates by the content they contribute which is easy enough but doesn't tell me anything about their qualifications as a moderator. Equally unsuitable are the moderator nominations, mostly done by the candidates themselves and their user profiles; they simply aren't an accurate picture of how well they would do their job.

Stack Overflow goes great lengths in pushing the actual users into the background, emphasizing the questions and answers. There is a little incentive to continue contributing, namely reputation and badges; I'm playing that game too. But overall it doesn't really matter for Stack Overflow to keep specific persons there—as long as the contributions are still there and of high quality, no one can complain. But ultimately you don't really know about those people. You know about their technical knowledge and how they write or how willing they are to provide outstanding answers. But about how well they would perform as moderators? Nothing. While sometimes discussions arise in the comments on a question or answer they are mostly very short-lived, just as the questions/answers themselves (most questions, even those with stellar answers vanish after at most a few hours and no-one reads them anymore). What's more: comments are de-emphasized on purpose: smaller font size, gray text, hidden by default (except for the top-rated comments). As a discussion medium, where I could actually see how people approach problems, how they deal with it and ultimately solve it, this is a complete fail; again, on purpose.

Stack Overflow isn't alone in this regard; I just picked it out since it's the one example I'm most familiar with at the moment. The problem is similar for me at Wikipedia where the means of communication are comparably arcane and inefficient. Mostly you're communicating with a large blob of vaguely human form which could be anyone. And most of the time you don't talk to the same persons regularly. To me it is surprising that (at least for the German Wikipedia) many people participating in discussions, polls, &c. seem to know each other and are actually talking there. Maybe I'm the ugly kid who stands besides all this or maybe I just didn't see a suitable way of getting to know the people behind the content.

Ultimately, there are probably persons who could judge how well someone is suited as a moderator: Those that have access to logs that detail what moderator-like activities a person has done. For Stack Overflow this would include things like close-votes on questions, flagging questions and answers for moderator attention—that's the technical side. Then there's the human side which necessarily includes discussions (such as what makes a question programming-related). But discussions are, as noted, very much de-emphasized in contrast to questions and answers (which tell me only about technical problems someone faced and was able to solve).

For the normal user there is simply no easy way of looking at the things that would matter in this regard and help in a decision. As for the candidates: I've never had anything to do with the vast majority of them, except for two.

Well, back to my original point, I find it a little weird that such sites ask their members about positions that need certain qualifications, who—by definition and purpose of the site—don't know each other well enough to make an informed decision on that. I see it as a kind of pseudo-democracy where the site owners/administrators give the “community” something to decide. But in the end I doubt the final decision will be made with regard to the actual qualifications of the elected person. The votes itself are probably rather random for most people participating in the election or maybe guided by prior advertising on behalf of the candidates. I don't remember the original nominations of the candidates anymore but what I read of them didn't strike me as convincing. Heck, not knowing those people I couldn't even decide whether their application/nomination was meant seriously or is just full of senseless talk.

I think such sites should either make actual communication (read: social behavior of people) part of their purpose (not that I see this necessarily as a good thing—I'm part of no social network for a reason) or stop trying to pretend they have a community. In fact, they haven't, in my opinion; they have content, they have people that contribute it; but they have no community.

Random Word Tip: The Format Painter doesn't have to vanish after one use

I needed the format painter pretty often in the last few days. It's quite a handy tool sometimes, though with one caveat: The mode created by selecting the format painter ends after one use. So usually you can only paint the formatting onto a single destination before having to re-enable the tool. That's not very nice when having multiple places to apply the formatting.

However, you can simply double-click the button in the Ribbon which leaves the mode activated until Esc is pressed. Found this by accident but it is handy.

And, noticing now, it's even mentioned in the documentation. But who reads that? :-)

WPK PowerShell network checker

Currently at the 26C3 and the network is pretty flaky here. At least on the first day. Out of necessity a friend implemented a simple network connectivity checker as a Windows Sidebar gadget. I started playing around a bit with WPK and decided to do the same in PowerShell with a nice WPK interface.

After a long learning process and much trial and error the following came out:

Import-Module WPK

New-Window -AllowsTransparency -WindowStyle None -Background Transparent -SizeToContent WidthAndHeight -Topmost -BitmapEffect { New-DropShadowBitmapEffect -Opacity .5 } {
    New-StackPanel -Orientation Horizontal {
        New-Border -Width 40 -Margin ‘5,5,0,10’ -Child {
            New-StackPanel {
                New-TextBlock ‘4’ -FontSize 24 -Foreground White -HorizontalAlignment Center
                New-TextBlock -On_Loaded { Set-Variable tb4 $this } -Foreground ‘#80ffffff’ -HorizontalAlignment Center
            } -On_Loaded { Set-Variable c4 $this }
        } -CornerRadius ‘20,0,0,0’ -BorderThickness ‘2,2,0,2’ -BorderBrush Black -On_Loaded { Set-Variable -Name v4 -Value $this }
        New-Border -Width 40 -Margin ‘0,5,10,10’ -Child {
            New-StackPanel {
                New-TextBlock ‘6’ -FontSize 24 -Foreground White -HorizontalAlignment Center
                New-TextBlock -On_Loaded { Set-Variable tb6 $this } -Foreground ‘#80ffffff’ -HorizontalAlignment Center
            } -On_Loaded { Set-Variable c6 $this }
        } -CornerRadius ‘0,20,0,0’ -BorderThickness ‘0,2,2,2’ -BorderBrush Black -On_Loaded { Set-Variable -Name v6 -Value $this }
    }
} -On_Loaded {
    $block = {
        $net4 = 1
        try { $x = @(Test-Connection google.com -Count 1) } catch { $net4 = 0 }
        if ($x.Count -eq 0) { $net4 = 0 }
       
        $net6 = 1
        try { $x = @(Test-Connection ipv6.google.com -Count 1) } catch { $net6 = 0 }
        if ($x.Count -eq 0) { $net6 = 0 }
       
        switch ($net4) {
            1 {
                $v4.Background = ‘Green’
                $tb4.Text = $x[0].ResponseTime
                $tb4 | Move-Control -fadeIn -duration ([TimeSpan]::FromMilliSeconds(500))
            }
            0 { $v4.Background = ‘Red’
                $tb4 | Move-Control -fadeOut -duration ([TimeSpan]::FromMilliSeconds(500))
            }
            2 { $v4.Background = ‘Gold’ }
        }
        switch ($net6) {
            1 { $v6.Background = ‘Green’
                $tb6.Text = $x[0].ResponseTime
                $tb6 | Move-Control -fadeIn -duration ([TimeSpan]::FromMilliSeconds(500))
            }
            0 { $v6.Background = ‘Red’
                $tb6 | Move-Control -fadeOut -duration ([TimeSpan]::FromMilliSeconds(500))
            }
            2 { $v6.Background = ‘Gold’ }
        }
    }
    Register-PowerShellCommand -ScriptBlock $block -Run -In ‘0:0:1’
} -On_MouseRightButtonUp {
    $Window.Close()
} -On_MouseLeftButtonDown {
    $window.DragMove()
} -AsJob

To use it you have to install the PowerShellPack which includes WPK, the WPF PowerShell Toolkit.

The window looks as follows:

Network Checker

The two halves “4” and “6” correspond to IPv4 and IPv6 connectivity, respectively. The program tries pinging google.com and ipv6.google.com. If a half turns red this means that the ping failed. Below the IP version number is the last response time.

Programs, as seen by users

I recently came across the following image:

Programs, as seen by users

And I thought it greatly sums up the usual problem. Both users and developers think at vastly different levels of abstraction. To the developer the UI is “just another shell” around the core and most erratic behavior of the UI can easily be explained by the inner workings of another component in the program. To the user, however, the UI is the program. And she just doesn't bother with understanding anything else. For all intents and purposes it's really magic.

Now, above image is a bit small, unfortunately and I didn't find an original creator or a higher-resolution version, so I created a vector version of the image which is attached to this post. Actually, I made two vector versions, one white on black and one black on white, the latter of which should use up substantially less toner when printed:

Programs, as seen by users – white on black Programs, as seen by users – black on white

The font used on the high-res PDFs versions is the free (and pretty) Fontin font.

I attached the Expression Design files as well, if someone wants the “source” files. The Design and PDF files are released into the public domain by me.

What NetHack monster am I?

Cute:
.......
...h...
/......
If I were a NetHack monster, I would be a dwarf. I enjoy using expensive, high-quality equipment, and I'm not afraid to work hard to get it.
(If I weren't a dwarf, I'd be a tengu.)
But I think that doesn't quite fit.

Scripting Games

The 2009 Summer Scripting Games will open today. I am going to participate and try to golf the entries as well.

Announcements of the events are a bit hard to find, though. I only started today since I didn't know they were already at event 5. But officially they begin today.

My solutions to the individual events can be found in my SVN repository.

Update (2009–08–06): I won a signed copy of Windows Powershell: Step by Step.

On my way to a batch badge

Now that Stackoverflow got statistics on the tags I just had to look where I am with my favorite tag: Batch files.

And behold, I am first place for the last month and (more or less) close second behind Pax in the all-time stats.

Batch tag statistics on Stackoverflow

Pax, I get thee :P

Am I taking this a bit too serious? Maybe, maybe not. I have to agree, though, that he knows some evilness I didn't know so far so perhaps the current ranking is appropriate :-)

Also, a little competition isn't bad in itself :-)

Now I only need a few more upvotes to get a batch specialist badge.

Update (2009–08–06): By now I am first in the batch tag. Yay.

Powershell golf

NOTE: I do not encourage anyone to use these suggestions for real code that needs to be maintained. I won't take any responsibilities for exploded brains and the like. Although I have to admit, the amount of obfuscation you can do with Powershell with these tips is minimal and in most cases still understandable. Certainly not harder than trying to recognize design patterns in a gazillion lines of Java code.

I am currently playing some sort of code golf with a friend. We're both trying to solve the Project Euler problems (the easier ones, for now, as I am not yet that far) in as little code as possible. He's using Ruby, while I try my best in Windows Powershell.

So probably by not using (or even knowing) Perl or Ruby I am as far as I could get from the whole code golf thing but nevertheless, it's fun and for some solutions he beat me just by mere two or four bytes. But still, he consistently beats me. Now, if only Powershell could lose all those $ for variables or operators as unwieldy and lengthy as -eq or -lt … (although Ruby has similar problems with such horrendously long names like times or inject)

However, I've gained a few insights on how you can still squeeze some bytes out of Powershell scripts by knowing how the shell behaves in certain situations.

Whitespace

The first thing you should do when aiming for as little code as possible is remove all whitespace from the code. This can be done even around operators such as -lt, -eq, -contains, etc. A snippet like $_%7-eq0 is perfectly valid.

Aliases

Take advantage of predefined aliases, such as % for ForEach-Object and ? for Where-Object. Many commands also have very short aliases, should you need them; the command

alias | ?{ $_.Name.Length -lt 3 }

will list all aliases with a name shorter than three characters.

Booleans

Booleans are cumbersome. Period. Using $true and $false just gobbles up too many characters. You can take advantage of the following implicit conversions to boolean:

True False
$TRUE $FALSE
Any string of length > 0, except the word “false” Empty string or the string “false”
Any number ≠ 0 Any number = 0
Array of length > 1 Array of length 0
Array of length 1 whose element is true Array of length 1 whose element is false
A reference to any object Null

So using $b=1 instead of $b=$true is much shorter. In many cases, however, you won't need explicit boolean variables. I'll illustrate this with the following example. Suppose you just want to check whether an array contains a multiple of 7 and take that result to do something else. Then you need a boolean value, somehow. A naïve implementation known from Java or so might look like the following:

$b=0;$a|%{if($_%7-eq0){$b=1}};$b

This reflects how I have done things at first. I've already omitted all whitespace, but still, this is 32 characters long for returning a boolean. We can rewrite the check for the modulus as !($_%7) since everything zero gets casted to false. This saves one precious character:

$b=0;$a|%{if(!($_%7)){$b=1}};$b

Next we can get rid of the helper variable $b altogether, since we can just use the result of the pipeline as a boolean value:

$($a|%{if(!($_%7)){1}})
Now we're already down to 23 characters for this. A probably even easier way would be not to check within a ForEach-Object but rather use a Where-Object or ? and use the resulting output directly:
$($a|?{!($_%7)})

which reduces the length to 16 characters. Half of what we needed at the beginning.

Another thing that tends to come up sometimes is a logical operation of two values, like for example !($a)-or!($b). With De Morgan's laws you can easily rewrite that to !($a-and$b), saving two characters (or even four, if you had -and to begin with).

Powers of ten

Maybe you won't need them often, but sometimes they come in handy. Why write out a number like 10000 or even 10000000 when you can shorten it to 1e4 or 1e7, respectively?

Semicolons

Semicolons separate commands in one line. However, when you are just doing imperative programming crammed into one line it might look like this:

for($i=1;$i-lt5;$i++){$s+=$i};$s

The $s at the end simply drops the variable off the pipeline into the shell so it gets printed. However, you can omit the semicolon directly after a script block:

for($i=1;$i-lt5;$i++){$s+=$i}$s

is perfectly valid and a whole character shorter.

for loops

The for loop in Powershell looks very much like its cousin from C-like languages:

for($i=1;$i-lt5;$i++){$s+=$i}

Many times you're probably better of rewriting such a snippet (29 characters) to a pipeline (14 characters):

1..4|%{$s+=$_}

But sometimes you need a for loop since maybe the terminating condition isn't that simple. I'll take the above example nonetheless. What you can do first here is getting rid of the increment part and pack it into the terminating condition (27 characters):

for($i=1;++$i-lt5;){$s+=$i}

we need to use the prefix increment since we are comparing $i after the increment (which happens usually at the end of the loop). Unfortunately this messes up the loop since now the start of the loop isn't right. In fact, now we start at $i = 2 because of the additional increment at the start of the loop.

This can be easily fixed, however, by changing the initialization:

for($i=0;++$i-lt5;){$s+=$i}

What we notice now, however, is that we actually don't need to use the initialization anymore. Variables get initialized to   when they are first used (a fact that we already use with the summation variable $s). So the complete initalization can be removed (23 characters):

for(;++$i-lt5;){$s+=$i}

And then there is a last small thing with for loops and that is that any trailing semicolons in the loop header seem to be optional. So if we don't need the increment part of the header, we can throw away the semicolon as well:

for(;++$i-lt5){$s+=$i}

Down to 22 characters now. Using a pipeline is more code-size-efficient in many cases (see above), but still, the good old for loop can be optimized a bit as well.

Pipeline

Powershell has a very powerful pipeline, based on objects instead of strings which is a great help in many cases. We have already seen that the for loop can be shortened tremendously in some cases by simply using the range operator and piping that array.

Some things lend themselves quite well for pipeline processing. Basically every time you need to do something with the members of an array or a range. For example the following while loop terminates only if $n contains nothing but ones:

while($n|?{$_-ne1})

Accomplished by a rather small but nice pipeline in an otherwise imperative environment. Some things can be quite cumbersome and long when done imperatively and reduce to very small amount of code when done in a pipeline.

ETA: I have to admit, that by now I have discovered an even shorter way of checking this:

while(@($n|gu)[1])

Comparison operators

The built-in equality and comparison operators, such as
-eq[/eq], etc. all operate differently on collections. In that case they return all elements where the comparison evaluates to true:

[ps]
PS> 1..8 -le 4
1
2
3
 4

This is certainly shorter than

1..8|?{$_-le4}

and can be helpful in some circumstances. Careful though, in using the result in a boolean context, since the boolean conversion rules are a bit confusing at times.

Select-Object

Select-Object or its predefined alias select is a rather long way of getting the first or last element of a pipeline. Compare

|select -f 1

with

()[0]

for getting the first element of a pipeline. Similarly for getting the last element.

Typecasts

Sometimes they are necessary, for example if you want to treat a string or substring as a number or convert a number to a string. The straightforward approach would be

$s=[string]$i
$i=[int]$s
$d=[double]$s

Not very short. In fact, I try to avoid typecasts whenever possible, at least when trying to write concise code no-one else needs to read. You can, however, take advantage of the fact that Powershell converts operands. So you can just add the neutral element to something you want to convert:

$s=“$i”
$i=0+$s
$d=.0+$s

And we just got down the cost of a string typecast to two bytes, instead of eight, and for integers we're also at two bytes instead of five, while a double typecast can be shortened to three bytes instead of eight.

Conclusion

I have presented some techniques for getting Powershell scripts smaller by taking advantage of some mathematical properties, quirks in the Powershell syntax as well as different methods of accomplishing the same goal, sometimes with large differences in code size. Mostly accumulated over the past few days but I'm still learning.

If I find anything new then this list will get updated.

Yay, an HCI webcomic

I just stumbled over OK/Cancel, a webcomic devoted to HCI, Usability and the like.

Looks like an interesting read so far, especially since every comic seems to be accompanied by an explaining text. This should help people who otherwise don't see a need for usable user interfaces or research in that direction to see the problems UX people face.

Usability Nightmares: User cancelled

Message box of TortoiseSVN showing the text “User cancelled”

sigh A message box telling me what I already know since I initiated the action.

To reproduce:

  • Show log.
  • Click cancel or press Esc while the log is still loading.

Seems to work as well for other errors (or messages worth showing) in the “Show log” dialog. The “Update” dialog, however, shows errors directly in the window, without needing a message box (which I highly appreciate):

TortoiseSVN “Update” dialog showing an error message
Syndicate content