Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Monday, October 26, 2009

Watch your booleans!

Here's a simple reminder that, whether you're coding or doing a code review (and you ARE doing code reviews, right?), double check your booleans.
private void EnableDisableFancySchmancyControl(bool enable)
{
_fancySchmancyControl.ReadOnly = enable;
}

We have a piece of code like this in the software I work on daily. This tiny little piece of code, so minuscule, so obviously correct, caused an emergency promotion the day its bug was found because it didn't allow some users to do their work properly.

Why, you ask, do we have such a simple method? Wouldn't it do to just call
_fancySchmancyControl.ReadOnly = enable;
in the calling method? Yes, normally it would. The objective of this piece of code is to normalize the action with the question "Should I allow the user to edit the information in this control?", so that you don't end up with things like:
private void EnableEditing()
{
_control1.Enabled = true;
_control2.Readonly = false;
_control3.Enabled = true;
}

but instead have:
private void EnableEditing()
{
EnableDisableControl1(true);
EnableDisableControl2(true);
EnableDisableControl3(true);
}

Now, the error from our original snippet should be obvious when you're looking for it: the line should be
_fancySchmancyControl.ReadOnly = !enable;
That is, there should be a not (!) in front of enable; a control that is read-only is not editable by the user (which, remember, is our objective).

All of that to say: be extra careful with your booleans; even the simplest code can fall prey to this bug!

Monday, August 10, 2009

Partial Random Song about Data Conversions

(I'm gonna) Scrub that Data!

I'm gonna scrub that data 'til it's shiny and clean!
I'm gonna scrub that data 'til it says what it means!
It'll be so shiny when I give it to you;
But I know you'll mess it up in a day or two!

(That's how data is, baby. If it ain't messed up, it ain't bein' useful)

Saturday, January 10, 2009

Difference in POV between Centralized VCS and Distributed VCS

'However, the total cost of branching is paid by reduced code velocity to main, merge conflicts and additional testing can be expensive. Throughout this guidance we ask the user to confirm that a branch is really needed and always ask the question "how does this branch support my development project?"'
-- from the TFS branching guide.


I came across this interesting passage yesterday, and I was struck by the profound difference in point of view between centralized version control and distributed version control.

In distributed version control systems (dvcs), branching is fundamental (in most scenarios): every "checkout" is really a branch of the repository, with full history. Therefore the focus in developing dvcs has been on making branching and merging as simple, quick and painless as possible.

Now, arguably, branching is also fundamental to all version control; after all, when you check out a copy of the code and modify it, you make a kind of lightweight, local branch for your changes that is quickly merged back into the trunk. But, with centralized version control, the focus is on control of the codebase, which is concentrated in the trunk. So, not only is branching not optimized (because of the lack of focus), but it is indirectly made more costly by the controls put on the trunk. And, because local checkouts aren't recognized as 'branches', you lack most of the usual tools for managing them separately from the trunk/server, like full history and an easy way to exchange patches with another developer.

Now, this isn't to say that the above advice isn't germane (PSP: take a shot!). If you are using a centralized version control tool, then you should absolutely consider the costs associated with branching, because it is quite expensive. And, arguably, you could go crazy with dvcs as well, but it takes a lot more work, I think. But the elaborate systems that the aforementioned branching guide mentions for scenarios just seem baroque and unnecessary when considered from the context of a dvcs.

Tuesday, January 06, 2009

Better diff/merge

Wouldn't it be nice if your VCS/SCM understood the code that was checked in, so that it could show diffs that were correctly contained?

For example, I modify a method and delete the method right after it. It shouldn't show that as a single change, but as two (one change for the modify, one for the delete). Or if I move a method in the source file but leave it otherwise unchanged (or even change it!): it shows as a 'move' (and potentially, then, a change as well!).

Some of this could be done without understanding the code much, eg, looking for identical blocks of text between the new and old files, which constitute 'moves'.

And it wouldn't have to happen when sending changes to the server, just when comparing the two versions for human consumption.

Tuesday, December 30, 2008

Something to help make Windows suck less

Here's a program that helps Windows suck less: AutoHotKey, which is basically a scripting language/interpreter for intercepting keystrokes and acting on them.

It allowed me to write the following, which is the "Clipboard Swap" command I thought would be occasionally useful. (Clipboard Swap: It copies highlighted text to the clipboard while replacing it with the current clipboard contents. It's activated by Windows-v).

#v::
tempClip := clipboard
Send, ^c
ClipWait,0.5, 1
tempClip2 := clipboard
clipboard := tempClip
Send, ^v
clipboard := tempClip2
Return


Just copy the script, paste it into, eg, ClipboardSwap.ahk , and then run that file with AutoHotKey (you may want to include it in your Startup folder so it's loaded every time).

Inasmuch as the above code is copyrightable, I hereby relinquish it to the public domain.

Enjoy!

Sunday, December 28, 2008

Unintentionally Funny Code

So, a couple of weeks ago I was at work, digging through the codebase, trying to root out hard-coded client-specific logic.

Here's what I found (genericized to avoid non-disclosure problems):

public class Class1
{
public virtual bool IsClientOne()
{
return Class2.CanUseOptionA();
}
}


And then...

public class Class2
{
public virtual bool CanUseOptionA()
{
switch(Class3.Id)
{
case (int) Class3IdValue.ClientOne:
return true;
default:
return false;
}
}
}

Thursday, August 21, 2008

Inventory as Waste

My coworker Paul was telling me today about some of the presentations he attended at the Agile conference earlier this month, and one of the things he mentioned was the idea that inventory is a kind of waste.

It took me a little while to grasp this concept, but I think of it this way:

Imagine a mechanic's shop. There is a team of mechanics, and they all work together to fix cars (or whatever). They have an inventory of wrenches, and each wrench has a certain cost associated with it, based on the initial cost of the wrench, the cost of storing it, degradation of the wrench over time, etc. The wrench's purpose is to be used to fix cars. When used for its purpose, the wrench is not wasted; it is contributing to the goals of the team. Whenever the wrench is in storage instead of being used for its purpose, it is wasted; it costs the team to store it, track it, put it away, etc. So, ideally, every wrench should be used (appropriately; misuse of a tool is another topic!) as much as possible.

Now, of course, some waste might be necessary. Perhaps certain tasks require the use of multiple wrenches, or when the team is at capacity all the wrenches are in use (but this doesn't happen all the time, nice as that would be). So you have to find the appropriate balance of waste vs efficiency.

Sunday, June 15, 2008

Code Criticism

If you're a professional programmer, expect your code to be criticized.

Expect it on your worst code (because everyone writes crappy code sometimes).

Expect it on your best code (because there's almost always room for improvement).

Expect it to be helpful (because everyone brings a different perspective, talent and experience to the team).

Expect it to be worthless (because some people will want to bring you down or will just plain be wrong).

You should be worried if your code isn't criticized, because it means that either no one cares or no one is brave enough. Neither situation is good for the project.

Saturday, April 12, 2008

Demonstrating Monty Hall in Python

There was a recent article on the Monty Hall problem in the New York Times blog TiernyLab.

The problem is this: You're on a game show, and there are three doors you may choose from. One door contains a car (or something else that's desirable) and the other two doors contain goats (or something else that's undesirable). After you pick your first door (this is the important part), the host must open another door and show you a goat. You then may choose whether to stick with your original choice or switch doors.

Should you switch doors?

Most people's response is "it doesn't matter, because the car could be behind either door, so it's the same as if I'd just been given the choice of the two doors, so it's 50-50". But that's not true, and here's why:

Monty's Constraint, as I call it, changes the odds. When you first selected a door, you had a 1/3 chance of choosing the car, and you had a 2/3 chance of choosing a goat. If you were to switch at this point, before Monty (the host) opens another door, then your odds would still be the same.

But, because Monty has to choose a door with a goat behind it to show you, there are two possible scenarios. First, if you picked the car (a 1/3 probability), then Monty can show you either of the two remaining doors as he pleases. But, if you picked a goat (2/3 probability), then the door he doesn't pick must contain the car.

Therefore, your odds of winning if you switch are 2/3 (because those are the odds that you originally picked a goat) and your odds of winning if you stay are 1/3 (the original odds that you picked the car).

Don't believe me? Steve didn't, at first. So I wrote a little program to prove it. It's in Python, so you shouldn't have any trouble understanding it, even if you're not a programmer.

Link: Python interpretor.

The Code:

import random

switchWins = 0
stayWins = 0

CAR = 1
GOAT = 0

for i in range(0,10000):

# set up doors. the set of doors is an array of two 0s and one 1.
# The 1 represents the car.
# start off with an empty set
doors = [GOAT, GOAT, GOAT]

# choose a door to have a car
carDoor = random.randint(0,2)

doors[carDoor] = CAR


# choose door (player)
playerDoor = 1

# choose door (monty). We use this to ensure monty
# randomly chooses a goat door.
montyDoor = random.randint(0,2)

# if the door monty picks has a car, or if the door he picks is
# the player's door, we have to pick again.
while doors[montyDoor] == CAR or montyDoor == playerDoor:

montyDoor = random.randint(0,2)

# There are only two doors left. If the player's door doesn't have
# a car, then the player would win by switching, so count it

if doors[playerDoor] != CAR:
switchWins += 1

# Conversely, if the player's door does have a car, the player
# would win by staying, so count that
if doors[playerDoor] == CAR:
stayWins += 1

print switchWins, stayWins

Thursday, March 13, 2008

Saturday, March 08, 2008

Something to add to your bag of tricks

When dealing with import buffer tables that you're planning on normalizing,
create the import buffer tables with both sets of fields (incoming field and
normalized field) so that you can avoid using a ton of alter table
statements, which are quite expensive.

Tuesday, January 29, 2008

Leaving Haloscan? Use this handy scraper

I recently decided to use entirely to blogger comments for my blog, but I wanted to retain my old comments for posterity (and/or to occasionally enrage me). So, I went a-googling , and eventually came across a Haloscan comment scraper which performed the task very admirably. You just need to have python installed and be ready to enter your Haloscan username and password.

Note that it may not work forever, but it works as of today.

My next task is figuring out how to automatically put all the comments into blogger. Hoo boy.

Monday, November 19, 2007

First blog post for AppVenture

Some of you may know that I've been working for AppVenture, Inc. these past few months, and one of our projects is blogging about programming. So, I'm proud to announce my very first post at AppVenture, Synchronizing Contacts in Outlook 2003 using an Add-in. Enjoy!

Monday, April 16, 2007

Good Math, Bad Math and the Twilight Zone

Just a few more interesting articles. First, a funny article in "The American Conservative" (not my usual fare!) about the Bush administration and possible a explanation for their bizarre conceptions of reality, entitled "Twilight Zone". (Article link stolen directly from Human Iterations).

Next, if I haven't mentioned Good Math, Bad Math to you yet... it's amazing. Just about the geekiest blog on the planet, the focus is on math and computer science, with a light sprinkling of blasting IDiots for their failed use of math. The specific article I wanted to share with you was Strange Loops: Ken Thompson and the Self-referencing C Compiler, which discusses how Ken Thompson introduced a back door inserter directly into the C compiler itself, in such a way that the source for the compiler doesn't need to contain the back door after the first compilation of the compiler. Brilliant and terrifying at the same time; how much do you trust your compiler?

The City Born Great - How Long 'Til Black Future Month?

The second story in N. K. Jemisin's anthology How Long 'Til Black Future Month? , "The City Born Great," is an exciting ta...