JOB REFERRALS
    ON THIS PAGE
    ARCHIVES
    CATEGORIES
    BLOGROLL
    LINKS
    SEARCH
    MY BOOKS
    DISCLAIMER
 
 Friday, May 14, 2010
Emotional commitment colors everything

As a part of my program to learn how to use the Mac OS more effectively (mostly to counteract my lack of Mac-command-line kung fu, but partly to get Neal Ford off my back ;-) ), I set the home page in Firefox to point to the OSX Daily website. This morning, this particular page popped up as the "tip of the day", and a particular thing about it struck my fancy. Go ahead and glance at it before you continue on.

On its own merits, there's nothing particularly interesting about it—it's a tip about how to do a screen-capture in OS X, which is hardly a breakthrough feature. But something about the tenor struck me: "You’ve probably noticed there is no ‘Print Screen’ button on a Mac keyboard, this is to both simplify the keyboard and also because it’s unnecessary. Instead of hitting a “Print Screen” button, you’ll hit one of several keyboard combination shortcuts, depending on the exact screen capture action you want taken. ... Command+Shift+3 takes a screenshot of the full screen ... Command+Shift+4 brings up a selection box .... Command+Shift+4, then spacebar, then click a window takes a screenshot of the window...."

Wait a second. This is simpler?

If "you're a PC", you're probably rolling on the floor with laughter at this moment, determined to go find a Mac fanboi and Lord it over him that it requires the use of no less than three keystrokes to take a friggin' screenshot.

If, on the other hand, you love the Mac, you're probably chuckling at the idiocy of PC manufacturers who continue to keep a key on the keyboard dating back from the terminal days (right next to "Scroll Lock") that rarely, if ever, gets used.

Who's right? Who's the idiot?

You both are.

See, the fact is, your perceptions of a particular element of the different platforms (the menubar at the top of the screen vs. in the main window of the app, the one-button vs. two-button mouse, and so on) colors your response. If you have emotionally committed to the Mac, then anything it does is naturally right and obvious; if you've emotionally committed to Windows, then ditto. This is a natural psychological response—it happens to everybody, to some degree or another. We need, at a subconscious level, to know that our decisions were the right ones to have made, so we look for those facts which confirm the decision, and avoid the facts that question it. (It's this same psychological drive that causes battered wives to defend their battering husbands to the police and intervening friends/family, and for people who've already committed to one political party or the other to see huge gaping holes in logic in the opponents' debate responses, but to gloss over their own candidates'.)

Why bring it up? Because this also is what drives developers to justify the decisions they've made in developing software—when a user or another developer questions a particular decision, the temptation is to defend it to the dying breath, because it was a decision we made. We start looking for justifications to back it, we start aggressively questioning the challenger's competency or right to question the decision, you name it. It's a hard thing, to admit we might have been wrong, and even harder to admit that even though we might have been right, we were for the wrong reasons, or the decision still was the wrong one, or—perhaps hardest of all—the users simply like it the other way, even though this way is vastly more efficient and sane.

Have you admitted you were wrong lately?

(Check out Predictably Irrational, How We Decide, and Why We Make Mistakes for more details on the psychology of decision-making.)


Conferences | Development Processes | Industry | Mac OS | Reading | Solaris | Windows

Friday, May 14, 2010 2:40:33 AM (Pacific Standard Time, UTC-08:00)
Comments [2]  | 
 Monday, May 10, 2010
Code Kata: RoboStack

Code Katas are small, relatively simple exercises designed to give you a problem to try and solve. I like to use them as a way to get my feet wet and help write something more interesting than "Hello World" but less complicated than "The Internet's Next Killer App".

 

This one is from the UVa online programming contest judge system, which I discovered after picking up the book Programming Challenges, which is highly recommended as a source of code katas, by the way. Much of the advice parts of the book can be skimmed or ignored by the long-time professional developer, but it's still worth a read, since it can be an interesting source of ideas and approaches when solving real-world scenarios.

 

Problem: You work for a manufacturing company, and they have just received their newest piece of super-modern hardware, a highly efficient assembly-line mechanized pneumatic item manipulator, also known in some circles as a "robotic arm". It is driven by a series of commands, and your job is to write the software to drive the arm. The initial test will be to have the arm move a series of blocks around.

 

Context: The test begins with n number of blocks, laid out sequentially next to each other, each block with a number on it. (You may safely assume that n never exceeds 25.) So, if n is 4, then the blocks are laid out (starting from 0) as:

0: 0

1: 1

2: 2

3: 3

The display output here is the block-numbered "slot", then a colon, then the block(s) that are stacked in that slot, lowest to highest in left to right order. Thus, in the following display:

0:

1:

2: 0 1 2 3

3:

The 3 block is stacked on top of the 2 block is stacked on top of the 1 block is stacked on top of the 0 block, all in slot 2. This can be shortened to the representation [0:, 1:, 2: 0 1 2 3, 3:] for conciseness.

 

The arm understands a number of different commands, as well as an optic sensor. (Yeah, the guys who created the arm were good enough to write code that knows how to read the number off a block, but not to actually drive the arm. Go figure.) The commands are as follows, where a and b are valid block numbers (meaning they are between 0 and n-1):

  • "move a onto b" This command orders the arm to find block a, and return any blocks stacked on top of it to their original position. Do the same for block b, then stack block a on top of b.
  • "move a over b" This command orders the arm to find block a, and return any blocks stacked on top of it to their original position. Then stack block a on top of the stack of blocks containing b.
  • "pile a onto b" This command orders the arm to find the stack of blocks containing block b, and return any blocks stacked on top of it to their original position. Then the arm must find the stack of blocks containing block a, and take the stack of blocks starting from a on upwards (in other words, don't do anything with any blocks on top of a) and put that stack on top of block b.
  • "pile a over b" This command orders the arm to find the stack of blocks containing block a and take the stack of blocks starting from a on upwards (in other words, don't do anything with any blocks on top of a) and put that stack on top of the stack of blocks containing block b (in other words, don't do anything with the stack of blocks containing b, either).
  • "quit" This command tells the arm to shut down (and thus terminates the simulation).

Note that if the input command sequence accidentally offers a command where a and b are the same value, that command is illegal and should be ignored.

 

As an example, then, if we have 4 blocks in the state [0: 0, 1: 1, 2: 2, 3: 3], and run a "move 2 onto 3", we get [0: 0, 1: 1, 2:, 3: 3 2]. If we then run a "pile 3 over 1", we should end up with [0: 0, 1: 1 3 2, 2:, 3:]. And so on.

 

Input: n = 10. Run these commands:

  1. move 9 onto 1
  2. move 8 over 1
  3. move 7 over 1
  4. move 6 over 1
  5. pile 8 over 6
  6. pile 8 over 5
  7. move 2 over 1
  8. move 4 over 9
  9. quit

The result should be [0: 0, 1: 1 9 2 4, 2:, 3: 3, 4:, 5: 5 8 7 6, 6:, 7:, 8:, 9:]

 

Challenges:

  • Implement the Towers of Hanoi (or as close to it as you can get) using this system.
  • Add an optimizer to the arm, in essence reading in the entire program (up to "quit"), finding shorter paths and/or different commands to achieve the same result.
  • Add a visual component to the simulation, displaying the arm as it moves over each block and moves blocks around.
  • Add another robotic arm, and allow commands to be given simultaneously. This will require some thought—does each arm execute a complete command before allowing the other arm to execute (which reduces the performance having two arms might offer), or can each arm act entirely independently? The two (or more) arms will probably need separate command streams, but you might try running them with one command stream just for grins. Note that deciding how to synchronized the arms so they don't conflict with one another will probably require adding some kind of synchronization instructions into the stream as well.

.NET | C# | C++ | F# | Industry | Java/J2EE | Languages | Mac OS | Objective-C | Parrot | Python | Ruby | Security | Visual Basic

Sunday, May 9, 2010 11:01:36 PM (Pacific Standard Time, UTC-08:00)
Comments [0]  | 
 Thursday, May 6, 2010
Code Kata: Compressing Lists

Code Katas are small, relatively simple exercises designed to give you a problem to try and solve. I like to use them as a way to get my feet wet and help write something more interesting than "Hello World" but less complicated than "The Internet's Next Killer App".

 

Rick Minerich mentioned this one on his blog already, but here is the original "problem"/challenge as it was presented to me and which I in turn shot to him over a Twitter DM:

 

I have a list, say something like [4, 4, 4, 4, 2, 2, 2, 3, 3, 2, 2, 2, 2, 1, 1, 1, 5, 5], which consists of varying repetitions of integers. (We can assume that it's always numbers, and the use of the term "list" here is generic—it could be a list, array, or some other collection class, your choice.) The goal is to take this list of numbers, and "compress" it down into a (theoretically smaller) list of numbers in pairs, where the first of the pair is the occurrence number of the value, which is the second number. So, since the list above has four 4's, followed by three 2's, two 3's, four 2's, three 1's and two 5's, it should compress into [4, 4, 3, 2, 2, 3, 3, 1, 2, 5].

Update: Typo! It should compress into [4, 4, 3, 2, 2, 3, 4, 2, 3, 1, 2, 5], not [4, 4, 3, 2, 2, 3, 3, 1, 2, 5]. Sorry!

Using your functional language of choice, implement a solution. (No looking at Rick's solution first, by the way—that's cheating!) Feel free to post proposed solutions here as comments, by the way.

 

This is a pretty easy challenge, but I wanted to try and solve it in a functional mindset, which the challenger had never seen before. I also thought it made for an interesting challenge for people who've never programming in functional languages before, because it requires a very different approach than the imperative solution.

 

Extensions to the kata (a.k.a. "extra credit"):

  • How does the implementation change (if any) to generalize it to a list of any particular type? (Assume the list is of homogenous type—always strings, always ints, always whatever.)
  • How does the implementation change (if any) to generalize it to a list of any type? (In other words, a list of strings, ints, Dates, whatever, mixed together within the list: [1, 1, "one", "one", "one", ...] .)
  • How does the implementation change (if any) to generate a list of two-item tuples (the first being the occurence, the second being the value) as the result instead? Are there significant advantages to this?
  • How does the implementation change (if any) to parallelize/multi-thread it? For your particular language how many elements have to be in the list before doing so yields a significant payoff?

By the way, some of the extension questions make the Kata somewhat interesting even for the imperative/O-O developer; have at, and let me know what you think.


.NET | Android | C# | C++ | Development Processes | F# | Flash | Industry | iPhone | Java/J2EE | Languages | LLVM | Mac OS | Parrot | Python | Ruby | Scala | Visual Basic

Thursday, May 6, 2010 1:42:09 PM (Pacific Standard Time, UTC-08:00)
Comments [13]  |