Essay 30 “Hard to Code” Might Mean “Hard to Use”

TurboTax takes something nearly impossible to comprehend and makes it approachable to the masses. Complexity is shifted from the user to the code.

However, not always is this shift a zero-sum game. Sometimes overly complex logic is just a sign that the function of the application is confusing. Complex code supporting a complex interface? How about we don’t?

Confusion in the Elevator

Imagine we’re part of a team of engineers attempting to build better software to control an elevator for a 50-story high-rise. The elevator can monitor which floor people enter and which floor button they press. Our manager walks in with one simple commandment: people are complaining about waiting inside the elevator, so let’s build the elevator so that people collectively spend the least amount of time in it.

images/andertoons_5521.jpg

We start brainstorming through the scenarios. Suppose John steps in from the ground floor and pushes the button to go to his penthouse on floor 50. On its way up, the elevator stops at floor 8. In comes Steve, the UPS delivery guy, with a large brown box. He has to deliver the package to someone on floor 5, so he quickly presses 5.

What should the elevator do? Should the elevator stop at floor 5 first because it’s closer or stop at floor 5 second because it’s already heading up?

If the elevator heads back down to floor 5, John and Steve will pass a total of 59 floors. John will have gone up eight floors, back down three, and then back up the remaining forty-five floors to his penthouse. Steve will have gone down only three floors.

  • John: 8 up + 3 down + 45 up = 56 floors passed.

  • Steve: 3 down = 3 floors passed.

  • Total floors spent by John and Steve: 59.

Compare this to the alternative. If the elevator, instead, keeps going up, before coming back down to floor 5, they’d collectively pass more than twice that many:

  • John: 50 up = 50 floors passed.

  • Steve: 42 up + 45 down = 87 floors passed.

  • Total floors spent by John and Steve: 137.

The answer is clear. The elevator should go down to drop Steve and his brown box off first before going all the way to Steve’s penthouse. We all agree the new elevator is going to be all the rage!

Let’s continue our brainstorm. Suppose Steve, the UPS delivery guy, had entered the elevator at floor 30, instead of floor 8. Here’s what happens if the elevator comes back down first:

  • John: 30 up + 25 down + 45 up = 100 floors passed.

  • Steve: 25 down = 25 floors passed.

  • Total floors spent by John and Steve: 125.

Now, what if, instead, the elevator kept going up to John’s penthouse before coming back down?

  • John: 50 up = 50 floors passed.

  • Steve: 20 up + 45 down = 65 floors passed.

  • Total floors spent by John and Steve: 115.

In this scenario, we save 10 “man” floors if the elevator goes up! So, depending on when Steve gets on, the elevator may decide to continue its ascent or descend first before re-ascending. With two people, programming for the optimal elevator ride for two people is a fairly benign task.

Now suppose a third person, Samantha, enters the elevator. Now, there are six potential ways we could let each person off the elevator. Our program would have to calculate the total number of floors passed for each scenario before deciding on the best route.

  • Case 1: John, Steve, Samantha

  • Case 2: John, Samantha, Steve

  • Case 3: Steve, John, Samantha

  • Case 4: Steve, Samantha, John

  • Case 5: Samantha, Steve, John

  • Case 6: Samantha, John, Steve

In fact, the number of scenarios that need to be tested is just the factorial of the number of people on the elevator at a given time:

  • 2 people = 2! = 2 comparisons

  • 3 people = 3! = 6 comparisons

  • 4 people = 4! = 24 comparisons

  • 8 people = 8! = 40,320 comparisons

Once we get past just a few people, the number of cases to test becomes impractical. But that’s only one aspect of the complexity problem.

People are getting on and off the elevator at different times. Each time a new person enters the elevator, we would need to track how many floors the existing passengers have already passed before making a new set of calculations.

In other words, we couldn’t sufficiently deduce the path the elevator has already taken just by looking at who’s currently on it. If Mike enters on floor 25 and then Sanjay enters at floor 35, did the elevator travel ten floors between Mike’s entrance and Sanjay’s, or did it go back to floor 21 first to drop off Samantha?

At more than two elevator riders, we’d also need to track when people leave the elevator so we can omit them from future calculations.

In addition, what happens when someone forgets to hit their floor number or hits the wrong floor number and then presses a button during mid-ascent? Does our software recalculate and potentially shift gears in mid-flight?

If you’re new to programming, this is, sadly, not an exaggeration of how complex a seemingly simple goal—such as getting people off an elevator as quickly as possible—can be.

Complexity with Little Payoff

After all those extra obstacles, suppose, somehow, that we’ve built the perfect system. We’ve managed to write code in such a way that everyone collectively leaves the elevator in the shortest amount of time—calculating thousands of scenarios in a split second, taking into account everyone’s already taken path. It’s a true feat of technology! But how are John, Steve, and the rest of the gang faring? Probably not so well.

Code is great at processing the tediously automatable, and this is certainly a case of the extraordinarily tedious. But humans aren’t good at it. Nobody inside the elevator can possibly run through all the scenarios in their heads that quickly. The people waiting to get off are at the complete mercy of the elevator, not knowing which general direction they’ll be going when the next person gets on, nor why.

Here we have a case where hard to code means hard to use. Complexity, in this case, hurts both ways. By the time even a fourth person gets on the elevator, there are just too many scenarios for a human to know what route the elevator wants to take. Even when the elevator is accomplishing the goal of getting everyone off in the fewest amount of collectively traveled floors, the people inside are left wondering when it’ll be their turn.

They might well prefer the simple, traditional algorithm an elevator abides by.

Sure, they probably wouldn’t reach the optimal path, but by favoring a simpler solution, the people in the elevator have better knowledge of what’s going on. That level of predictability trumps the more complex solution even if it’s theoretically more efficient.

When details become egregiously hard to code, it may be a smell that the actual function of the system is difficult to understand. And while you may pat yourself on the back for successfully programming something really complex, others are punching you in the back after they use it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.190.144