white textured wall



person pouring purple liquid on clear glass container

Good Manager: Understands that developers are on the critical path: nothing "is" until someone writes some code.
Bad Manager: Thinks that developers are no different than business analysts, admins, or envelope stuffers, and treats them that way.

Good Manager:  Understands that formal process, while invaluable, is not infallible and must be augmented by the performance of excellent people.

Bad Manager: Forces creativity and determination to take a back seat to process.

Good Manager: Wants people to be "intrapreneurs", to feel as if they're running their own little "business within a business".
Bad Manager: Thinks that being "part of the team" is more important that getting work done, no matter what it takes.

Good Manager: Listens.
Bad Manager: Talks.

Good Manager: Strives to understand customer issues deeply as a basis for all technology decisions.
Bad Manager: Forces customers to fit into his vision of technology.

Good Manager: Prototypes and iterates in order to learn "what".
Bad Manager: The specs are the Bible, at least until Version 2.0.

Good Manager: Ready, Aim, Fire. Or when super speed is needed: Ready, Fire, Aim. 
Bad Manager: Fire. Fix. Fire. Fix. Fire. Fix.

Good Manager: Prioritizes "why"; facilitates "what"; accepts "how".
Bad Manager: Dictates "how". Blames when "what" doesn't match "why".

Good Manager: Daily interaction.
Bad Manager: He works here?

Good Manager: Leader.
Bad Manager: Politician.

Good Manager: Encourages customers to provide input and feedback.
Bad Manager: Depends upon training and documentation when customers don't "get it".

Good Manager: Encourages developers to identify their needs and is eager to satisfy them.
Bad Manager: Blames developers for missing deadlines when they lack the resources they need.

Good Manager: Offices or war rooms.
Bad Manager: Cubicles.

Good Manager: Intense interaction as needed.
Bad Manager: Meetings.

Good Manager: Has finger on the pulse of the organization.
Bad Manager: Needs town hall meetings and web conferences.

Good Manager: To foster moral, always strives to do the right thing.
Bad Manager: To foster moral, cheerleading and gimmicks.

Good Manager: Developers love coming to work.
Bad Manager: Developers love their work in spite of their company.

Good Manager: Googles you.
Bad Manager: Wants you go Google him.

Good Manager: Watches the project plans and schedules.
Bad Manager: Watches the clock.

Good Manager: Stays for years until our baby grows up.
Bad Manager: Moves on just before the smoke and mirrors clear up.

Good Manager: Worries about 2 things: Getting our work done and keeping our people.
Bad Manager: Worries about 2 things: How he looks and how he feels.


Bad, Better, Best in IT



Bad: Cubicle
Better: Office 
Best: Whatever works best for you.

Bad: Meetings without agendas. 
Better: Meetings with agendas. 
Best: Meetings whose need is so obvious to everyone that no agenda is needed.

Bad: Specs, waterfall, Systems Development Life Cycle. 
Better: Prototyping, agile, scrum. 
Best: Developers with enough domain knowledge to just build it.

Bad: No documentation. 
Better: Documentation. 
Best: No documentation needed.

Bad: No formal process. 
Better: Formal process. 
Best: People so much bigger than their jobs so that process is rarely relied upon.

Bad: Theory without experience 
Better: Experience without theory 
Best: Both

Bad: Help desk without programmers. 
Better: Programmers available to customers. 
Best: Code that just works.

Bad: Phone calls 
Better: Emails 
Best: Application software that encapsulates required communication

Bad: Code with early exits. 
Better: Code without early exits. 
Best: Code so simple because of the underlying data structure that the early exit debate is moot.

Bad: Bugs 
Better: Fixes 
Best: Enough 9's to never notice.

Bad: programmer error 
Better: user error 
Best: What's an error?

Bad: Missing deadlines 
Better: Hitting deadlines 
Best: A track record so good that deadlines are never given

Bad: Complex org chart 
Better: Simple org chart 
Best: Technology so sophisticated, less people are needed

Bad: Non-technical boss 
Better: Technical boss 
Best: No boss

Bad: Management 
Better: Leadership 
Best: Self-motivation

Bad: Best practices, with a Capital "B" (industry standards) 
Better: best practices, with a small "b" (what we figured out) 
Best: Just do your job.

not(AdviceForHackers)

I get a lot of emails these days from fellow hackers with [ distress | concern | depression ]. They're not looking for technical solutions or advice (which is good because I have neither), they're just not where they thought they'd be and are reaching out for *something*.

I try to make a point to answer all of them because, frankly, they're my most important emails. To me, the ones and zeroes inside my fellow humans heads are far more important than those on any computer.

If I built a Venn diagram of all of my responses, the intersection is significant. There are some things I end up telling almost everyone, regardless of their situation.

This is not(Advice). Just a bunch of observations from a fellow hacker who has also suffered and learned...

1. You don't have a time machine.

So many fellow hackers say, "If only I hadn't..." with "quit my job" being the top instance.

You can't "should have". You can only "do". You don't have to forget what happened in the past, but you don't have to overemphasize the importance of its input into your future.

My favorite example:

2 people are travelling from New York to San Francisco. One drives directly from New York to Chicago. The other drives to Florida, Texas, Tennesee, and then Chicago. They are now both in Chicago, well fed, rested, and ready to go. How should their plans differ? (Hint: Except for rare exceptions, they shouldn't.)

It doesn't matter how you got where you're at. It only matters where you're at, who you are, and what you've got.

2. You can't read others' minds.

I often hear things like, "If I only knew what she wanted, I would do it." You don't know. So ask. We humans are not connected via USB 3.0 (yet). Until then, we must talk to each other without fear. That usually improves our chances of success significantly.

3. There are no rewards or punishments, only consequences.

Life's not fair. With software, unknown input + known process = predictable result. In life, known input + unknown process = consequences. We spend a lifetime learning the processes, so we should get better predicting the consequences. When you were 16 are wrote that cool software that nobody wanted, you were disappointed. Now you should either adjust the input or stop being disappointed. You'll never be perfect, but with continuous learning, you should get pretty good knowing what will work and what won't.

It's not about luck. It's about adjusting the controls to maximize the possibility of desirable consequences. You didn't do that as well as you would have liked this last time. You'll do better next time.

4. Don't order a taco at a Chinese restaurant.

Many hackers are disappointed in the responses of others in their lives. "If only more people clicked that button." "If only my cofounder worked harder." "If only that angel got it."

Sometimes we expect things from others that they are incapable of giving. It's hard for we hackers to believe that it's so difficult (or impossible) for <Person A> to do <Task B> or understand <Concept C>. We might as well order a taco at a Chinese restaurant. (Hint: They don't have any.)

When others don't respond the way you expected, maybe it's because they couldn't or didn't know how. Don't blame them. Just order what they've got.

5. You are a Chinese restaurant that doesn't serve tacos.

Sometimes a friend or loved one says something like, "You had it all! You made more money than anyone I know and you threw it away for a silly dream. You could have had and done anything you wanted with a salary like that."

Whenever they do, they're ordering a taco from *your* Chinese restaurant. They think you're something you're not and they want something from you that you don't have to give them.

In general, most normals get a greater percentage of their satisfaction from mainstream thinking, good times, and "stuff". They don't understand the hacker mindset of getting satisfaction from building and achieving.

That's OK. Being different isn't the problem. Forgetting that we are is.

6. They love you. They want to help. They're always right. Pick two out of three. (Hint: It's the first two.)

I often hear things like, "My father criticizes me for <x> and I feel awful." You can only feel awful if you believe him. You only believe him if you think he's right. But as hard as it is to believe, sometimes he's actually wrong. This is probably one of those times. Get used to it.

7. It's all in your head.

It may sound like some enlightened Zen kind of thing, but it really is true. But knowing it and living it are two entirely different things.

It's easy to say things like, "I will manifest <y> in my life," especially for us hackers because we are used to making something seemingly out of nothing. But when we appear to not succeed at building something right out of our head, it's easy to dismiss our our responsibility and blame something external (time, money, support, luck, etc.)

It really is all in your head. You may not be ready right now, but eventually you will be. Then you'll try again.

8. I care. And I have a feeling I'm not the only one.

The single biggest response I ever get is something like, "Thank you. It's not what you said, but the fact that you responded that means so much to me."

Feel free to email me any time. Any feel free to engage others, too. But don't get concerned if they don't respond. Their Chinese restaurant doesn't serve tacos yet.

How my High School Job Prepared me for Building Software

I worked at McDonald's in high school. It was high volume, fast paced, hard work, low pay, and there were 10 other kids ready to take your job if you didn't like it.

I'm now a software developer. I've worked hard all my life, but I still think that McDonald's was the toughest and best job I've ever had. I learned lessons there that have helped me many times since.

Just a few of those lessons:

1. In order to do heavy volume, you have to be set up for heavy volume.

When we hung out with our friends who worked at Burger King or Wendy's, they'd tell us about their record hours and record days (in dollars). We were amazed.  What they called records, we did every day. Our records were 4 or 5 times as much. In restaurants that appeared the same.

The difference was always that McDonald's was set up for volume. We ran five lines where they ran one. We made 12 hamburgers at a time when them made one at a time. We had food cooking before people even ordered it.

If a bus pulled in, we fed everyone in 10 minutes. They took at hour. When 6 buses pulled in, we fed them all in an hour. 6 buses never pulled into Burger King or Wendy's.  They knew they wouldn't eat.

The same thing holds true for commercial software. Want to write lots of software?  You better have everything you need in place first. People. Hardware. Environments for development, testing, and production. Source control. Frameworks. Tools. And most importantly, a mindset and the experience to do a lot of work. Anything less and you'll end up with vaporburgers.


2. If you're not prepared to serve customers before they arrive, it's already too late.

If a customer arrived and ordered a sandwich that was not already cooked or a special order, no problem. We just made it. Just as long as the grill was hot, the freezer was full, the buns were laid out, and everything else was where it needed to be. If anything wasn't, we couldn't give good service to anyone.

There's a common misconception in software development that you don't really need much software before you meet your customer; they'll tell you what they need and you'll develop it. Wrong. You better have at least half of it already written, or you'll never deliver anything in a timely manner. You may not know their exact requirements, but a form is a form, a data base is a data base, a web page is a web page, and a process is a process.  You better have all your building blocks built before your customer arrives. No one wants to wait for your grill to warm up in order to make your sandwich and no one wants to wait for you to write your framework to make their app.


3. When you're operating on the razor's edge, every detail is critical.

Saturday night from 5 to 8 was always the busiest time of the week. So Saturday from 4 to 5 pm was the most important hour of the week. Everything had to be ready and everything had to be perfect. Four large stacks of buns were positioned perfectly along the wall.  The meat freezer had 300 pounds of beef patties with the boxes already dropped to break them apart. All condiments and paper goods were fully stocked; bags were even "fanned" to be easier to grab. There were no cabinet doors or drawers because there was simply no time to open and close them when you got busy. And the kitchen had to be spotless; there would be no time for sweeping, mopping, or cleaning when you'll be running 72 sandwiches at a time for 3 hours. We knew what was coming, so we got very good at eyeballing the kitchen at 4:45 to make sure everything was perfect.

The only difference in developing and deploying software is that your "crunch time" can come anytime, not just during rush hour. And you better be ready. You better know exactly where your code is and what it does. Your data better be in order. Hard copies of source code and specs have to be handy and ready to use. But most of all, the programmer has to be ready for the "burst". That means taking care of yourself and being prepared to work something through until it's right. So get enough sleep, exercise, and clear your mind.  And don't eat at McDonald's :-)


4. 1 + 1 = 3.  1 + 1 + 1 = 6

   In order to make 12 hamburgers, you'd have to:
    a. Put 12 bun crowns in the crown toaster.
    b. Put 12 meat patties on the grill.
    c. Sear the 12 meat patties.
    d. Season the 12 meat patties.
    e. Turn the 12 meat patties.
    f. Put 12 bun heals in the heal toaster.
    g. Remove the 12 bun crowns from the crown toaster and put them on the dressing table.
    h. Put ketchup on the 12 bun crowns.
    i. Put mustard on the 12 bun crowns.
    j. Put pickle slices on the 12 bun crowns.
    k. Move the dressed bun crowns next to the grill.
    l. Drain the 12 meat patties put them on the 12 bun crowns.
    m. Remove the 12 bun heels from the heel toaster and put them on the 12 meat patties.
    n. Wrap the 12 hamburgers.

One grill can hold 36 hamburgers. It takes 3 minutes to cook a hamburger patty. When I was stuck in the kitchen by myself late at night, I was able to make one set of 12 hamburgers in 5 minutes. Two of us could make 3 sets in 5 minutes by starting Set 1 at time 0, Set 2 in 1 minute and Set 3 in 2 minutes. Three of us could make 6 sets in 5 minutes by using 2 grills and helping each other with the dressing.

I have found that these multipliers work about the same for developing and deploying business software, with one, two, or three people working together as a team. Beyond that, the "kitchen" gets a little too crowded. 

5. Ideally, managers can do and doers can manage.

There were about 50 tasks that needed to be done all the time in these categories:
 - waiting on customers
 - cooking
 - cleaning
 - restocking

If you had 12 people, you specialized and divided up the work. If you had 6 people, everyone did multiple jobs at the same time. If you had two or three people, each had to be able to do anything, do it very well, and do it fast. If you had one person, they were called a manager and could run the restaurant alone if they had to. Imagine how much better the enterprise world would run if its managers were as versatile as McDonald's managers.

On the other hand, some doers were high school students preparing for college and had no plans to go into McDonald's management. But they were super-doers. They knew everything that had to be done and the best ways to get it done. They naturally gravitated to the top and started directing their peers. Eventually, McDonald's gave them the title of "swing manager" (someone who did everything a manager did but didn't get paid as much). It reached the point where swing managers were better than managers at day-to-day operations.  Funny, the best technicians anywhere are often the same ones who self-manage.


6. The difference between mediocre and good is small. The difference between good and great is large.

For us super-doers. Tuesday night was the most interesting time of the week. That's when the weekly schedule was made up. There were about 60 of us high schoolers on the payroll, and you better believe that it was critical who we were scheduled to work with. About 40 were mediocre, 15 were good, and 5 of us were great.

Monday night? Not busy, no big deal, put Martin on porter and Mike G. on the counter.  It won't make much difference. Friday night, we'll be pretty busy. If you don't have either Mark or Jay on grill, you'll never keep up. Saturday night, forget it, we'll get slammed.  It's me, Jay, and Wally in the kitchen. Have Mark on standby, but whatever you do, keep Jimmy and and Fred out of our kitchen! George and Patty better be on counter that night; we won't have any time for mistakes.

You kinda get the picture. Five Jimmys couldn't keep up with one Wally, and even if they did, you wouldn't want to eat their product.

I'd like to comment on how this applies to programming, but Joel Spolsky already has far better than I could in, "Hitting the High Notes":http://www.joelonsoftware.com/articles/HighNotes.html. My favorite line: "Five Antonio Salieris won't produce Mozart's Requiem. Ever. Not if they work for 100 years." What was true in music was true at McDonald's. And is still true in our software offices. Go figure.


7. Good work habits are like antibodies; once you get them, you have them for life.

There were 2 kinds of workers at McDonald's, those who got the work done properly and completely, no matter what, and everyone else. It only took about 5 minutes to tell who was who. And it never changed. Both groups were equally smart, equally capable, and equally personable. What was the critical difference? Work habits. Good workers refused to work in dirty work areas. They refused to release deficient product. They refused to put off what could be done later because they knew it would grow to twice as much work later and screw everything else up in the interim. And most of all, they hated working with those who didn't have the same good habits. Why should I get the product out hot, mop the floor, wipe the counters, stock the freezer, and prepare for closing while Jimmy has a smoke and hangs out in the back. Get him off my shift!

Years later, it's still the same. Got a critical project with a tough deadline?  Need to put out great product quickly and efficiently? Who you gonna call, the brilliant guy who sits and pontificates all night or the one who understands what it takes and won't quit until he's done. Work habits separate the good from the great and show you the way to success. Once you have that taste, it's awfully hard to become a slacker.

It Takes 6 Days to Change 1 Line of Code

(A true story.)

Philip (President): Our factory is underutilized by 10%. Either we start building more of our backlog or we lay people off. I'd rather keep everyone busy, build inventory, and get ahead of the curve before the busy season. How can we do that?

Lee (Operations Manager): Company policy restricts us from building more than 3 months of backlog. If you just change that to 4 months, we'll have plenty of work.

Philip: Done. Now how do we implement that?

Lee: I'm not really sure. I think we'd have to change a setting in the legacy software.

David (IT Director): No problem. It's probably one line of code in our core routine. Fill out a ticket and submit it to IT Services.

Judy (IT Admin): I'm assigning this request Ticket# 129281. But it still needs the section on Business Impact completed and Director approval.

David: It's for Philip. It we don't do this right away, we'll have to have a layoff.

Judy: OK, then I'll fill out that section myself and put this on the fast track.

2 days later.

David: What's the status of 129281?

Judy: It's the first Enhancement in the Developer Queue, after 14 Bug Reports.

David: Forget the queue. Mark it urgent and send it to Ed immediately.

1 hour later.

Ed (programmer): On line 1252 of Module ORP572, I changed the hard-coded variable MonthsOfBacklog from "3" to "4". I unit tested this successfully and ran 2 batch test runs. The Operations work queue increased 10% as expected. This is good to go. I just submitted it to Code Review and moved in to Homer for User Acceptance Testing.

Shirley (Code Review): It is now against company policy to have any hard-coded variables. You will have to make this a record in the Parameters file. Also, there are 2 old Debug commands, an unassigned variable warning message, and a hard-coded Employee ID that will all have to be fixed before this module can be moved to production.

Ed: Fuck that shit.

Shirley: That may very well be true. But since you were assigned ORP572, you are responsible for fixing preexisting errors that violate new company policy. I cannot promote this as it is.

2 hours later.

Ed: OK, done. I just resubmitted it to Code Review.

Julie (IT Testing): Homer is not available for User Acceptance Testing because Fred is running a controlled test for month-end accounting close. Use Marge instead.

Ed: I don't have access to Marge.

Julie: Then contact Joe in IT Security. He'll get you permissions.

2 hours later.

Joe (IT Security): I cannot grant you access to Marge without David's signature. He's out of town. Can this wait until Monday?

Ed: I don't think so. Philip wants this right away. Get him to grant access.

Shirley: Your new Parameters record "MonthsOfDemand" needs a better name. The offshore programmers won't understand what this means. Also, it should have an audit trail of changes.

Ed: What policy is that?

Shirley: It's not exactly written down anywhere. The offshore team is 3 months late updating the wiki, but I assure you, all new Parameter records must satisfy new naming requirements and keep audit trails.

1 day later:

Ed: I renamed the Parameters record "MonthsOfDemand" to "SelectedMonthsOfBacklogDemand" and added Module PAR634 to maintain that record and its audit trail. I have submitted it to Code Review.

Tony (IT Testing): I see 129281 on Marge, but I have no Test Plan.

Ed: Just run it the old way and the new way and note the increase in the total on the WorkOrdersHours report.

Tony: That's your test plan? No. This affects everything in the factory. I have to have user selected Test Cases, Expected Results, documented Test Runs, and user sign-off.

2 days later:

Philip: David, tell Tony to move Ed's program to production immediately.

David: Yes sir.

Total elapsed time: 6 days.
Lines of mission critical code changed: 1.
Bytes of mission critical code changed: 1.
Excedrin eaten: 24
Pissed off hours spent on Hacker News: 14.

Dear Boss: For a programmer, 10 minutes = 3 hours

10:48

Boss: Hey Ed, Sue in Detroit says that sometimes, the wrong Invoice Part Number is showing up on the Product History Screen. Can you help us figure this out.

Ed: I'm busy with something else at the moment. Put the ticket in my queue.

Boss: This will only take 10 minutes.

Ed: Are you sure about that?

Boss: Yes. I'll just set up a web conference. Sue can show you right away, then you can look into it when you have time.

Ed: OK.

Boss: Great. Check your Outlook for an invite.

11:05

Got an Outlook invite for a web conference at 11:30. Accepted.

11:25

Called the web conference 800 number from my IP phone. Busy. Tried again twice. Busy both times. Called my cell phone from my IP phone. Busy. OK, the IP phone system is screwed up again. Called the web conference phone from my cell phone. First one there. On hold. Clicked the link in my browser to the web conference. First one there.

(Ed starts reading Hacker News in another tab.)

11:38

Boss enters conference call: Where's Sue?

Ed: I don't know.

Boss: Can you see my screen?

Ed: No.

Boss: OK, hold on. Let me be the host. Can you see it now?

Ed: Yes, but I thought Sue was going to demonstrate the problem.

Boss: That's right. I'll just transfer host mode to her.

(Ed continues to read Hacker News in another tab.)

11:47

Sue enters conference call: OK, why are we here?

Boss: So that you can show Ed what's wrong with the Product History Display.

Sue: What's wrong with the Product History Display?

Boss: You know, sometimes the wrong Invoice Part Number displays.

Sue: You mean for mil-spec orders?

Boss: I really don't know. You sent the ticket.

Sue: What's the ticket number?

Boss: Hold on, let me check.

(Ed continues to read Hacker News in another tab.)

11:53

Boss: It's ticket number 13827. Remember now?

Sue: How do I see tickets on my PC?

Boss: Just click on the I.T. dashboard on the intranet.

Sue: I can't. The web conference software went full screen.

Boss: Then just hit Alt-F4. Then go to the intranet.

(Ed continues to read Hacker News in another tab.)

11:57

Sue: OK, what was that ticket number again?

Boss: I should have written it down. Let me look it up again...

Boss: 13827.

Sue: OK, I see. This only happens once in a while. No one knows why. It always breaks on Part Number R27-83.

Boss: OK, show Ed.

Sue: How to I get back to the web conference.

Boss: You have to start all over. Alt-F4 killed it.

(Ed continues to read Hacker News in another tab.)

12:04

Sue: OK, the web conference is up again. Can you see my screen?

Boss: No, you have to click "Host".

Sue: Where?

Boss: In the little box in the upper right hand corner.

Sue: The "History" box?

Boss: No, the "Attendees" box.

Sue: OK. Can you see my screen now?

Boss: No. Try again.

Sue: I did. It said that you have to give up host mode.

Boss: OK. I didn't know that.

(Ed continues to read Hacker News in another tab.)

12:14

Boss: I gave up host mode. Try again.

Sue: OK, can you see my screen?

Boss: Yes.

Ed: Yes.

Sue: OK, if I go into the main menu, click "Operations", then click "Sales", then click "History" it takes me to the Sales History Menu. See?

Boss: Yes.

Ed: Yes.

Sue: Then I click on Sales History Display by Part. I enter "R27-93" and the main screen pops up. Then I click on Invoices, I hit F5, then F3, then F7, and the Invoice Part Number changes to "GT548". This should never happen. What gives?

Ed: OK, let me check it out and get back to you.

Boss: OK, bye.

Sue: OK, bye.

Ed is now stuck in host mode because the other two logged off. He can't get out. Windows locks. He reboots.

12:38

Ed logs back in and goes to the dev system. He goes to the main screen, clicks "Operations", then clicks "Sales", then clicks "History" it takes him to the Sales History Menu. Then he clicks on Sales History Display by Part. He enters "R27-93" and the main screen pops up. Then he clicks on Invoices, hits F5, then F3, then F7, and the Invoice Part Number remains "R27-93", just as it should. It works in dev perfectly.

12:46

Ed logs into production through his secret back door. He goes to the main screen, clicks "Operations", then clicks "Sales", then clicks "History" it takes him to the Sales History Menu. Then he clicks on Sales History Display by Part. He enters "R27-93" and the main screen pops up. Then he clicks on Invoices, hits F5, then F3, then F7, and the Invoice Part Number changes to "GT548". Sue was right.

12:57

Ed checks the Version Control System. The program has been checked out by Fred since November 11. He runs a diff and sees that Fred has found and fixed the problem in the 425 lines of code he has changed.

1:03

Ed calls Fred to see what he's been up to. Voice mail.

1:07

Ed emails Fred, explaining the problem.

Ed returns to Hacker News.

1:17

Fred calls back. Ed tells him to read his email.

(Ed continues to read Hacker News in another tab.)

1:28

Fred calls back: OK, I remember that. The program was broken by one of the offshore programmers who was changing the header on every program in the Operations directory. He accidently removed a line of code before he recompiled. Somehow, it made it through QA, and now Sue has found the bug.

Ed: Well then, can you promote it now?

Fred: I don't think so. There are 12 other changes in this mod. Let me check and call you back.

(Ed continues to read Hacker News in another tab.)

1:36

Fred calls back: I can't promote any of these changes until the XL500 mods go through first. They're on hold until QA approves the spec. So we just have to wait.

Ed: OK, thanks Fred. I'll just email my boss and tell him.

Ed emails Boss with the explanation.

(Ed continues to read Hacker News in another tab.)

1:48

Boss: OK, this sounds like a problem. It looks like I'll have to escalate this to the Steering Committee. I'm glad you had 10 minutes to spare. Thanks.

(Ed continues to read Hacker News in another tab.)

Left-Handed Baseball Gloves

A local Sporting Goods retailer that had just acquired a Baseball competitor. Their ecommerce system had a clever database structure to make ordering easy from either the website or the call center. For any given Product, there could be hundreds of Stock Keeping Units (SKUs) based on Sport, Size, Color, Number, or other attribute. The database was easy to use but difficult to load.

Jim was brought in to build a one-time application that would build all the data base records needed from Excel spreadsheets from the old system. In addition, every SKU in the system had to be "smart"; that is, anyone can tell everything needed to know just from looking at the SKU. For example, a Wilson A2000 medium left handed female softball catcher's mitt might be: WIL-A2000-M-LFSC-01.

Jim wrote the application to build and load all the SKUs, Sales Orders, Work Orders, Inventory Locations, Boxes, Bins, history, and supporting indexes. He had 10 users log in to the new fulfillment system and update all the activity not on an Excel spreadsheet. This took 2 days.

Then a strange thing happened. The owner of the acquired company asked why they coded all of the left handed SKUs as right handed and vice versa.

Huh? Apparently the people from the acquiring company who encoded the Excel spreadsheets didn't realize that a left handed player wore their glove on their right hand! Every data base record was wrong.

The choices to fix this were:

1. Make L = Right and R = Left forever.

2. Jim could add one line of code to his load application to reverse the bad data on the Excel spreadsheets, rerun it, and then redo 2 days of data entry.

3. Jim could write a "quick and dirty" one-time program to fix 500,000 bad data base records. It would take a day or so to write, test, and run, but no one could do anything until he finished.

They chose Option 3, sent 5 people home, and had the other 5 do other work.

BIG QUESTION: Why didn't anyone in a Sporting Goods company know that a baseball player wears their glove on their non-throwing hand?

BIGGER QUESTION: Why didn't anyone from either company review any of the plans, specifications, or data BEFORE work began?

BIGGEST QUESTION: Why didn't a Sporting Goods company that had made 9 acquisitions in the past 3 years have any standard methodolgy to do acquisitions? Why did they even need Jim?


How to Participate in Hacker News

I recently received an inquiry from a Hacker News newcomer on how to best participate in the community. I was ready to reply, "Just follow the guidelines and be yourself." Then I realized that it was actually a very good question that deserved a much better answer.

So here is my more detailed answer, based upon many years of hard knocks.

First of all, follow the guidelines! This is a necessary, but not sufficient condition.

There are literally hundreds of discussions about Hacker News participation just a search away, with much to learn. Hopefully, I can add something new here:

1. Be yourself.

I know that sounds lame, but think about it for a moment. Who else are you going to be? I see no need for "personas". Just be yourself. Talk to others just as if you were in the room with them. Let others see you as your genuine self, full of strengths and areas primed for learning. We can all grow together. Many of us will meet our future in this community.

2. Participate!

I never understood why people lurked so long. No need to be shy here. If you have something to say, say it. If not, then just lurk and learn. But everybody has something of value to share. This is one of the best places to do it.

3. Be positive.

This can really be hard when smart people debate, but try it anyway. Notice the difference between:

  Person A: Water is dry.

  Person B: No it's not. You're full of shit.

and

  Person C: Water is dry.

  Person D: Not in my experience. What data have you encountered to cause you to arrive at that conclusion?

I realize that this is an extreme trivial example, but try to be more like Person D than Person B.

4. Make friends.

Harness the power of the internet! You are not restricted by geography, circumstances, or time period (to some degree). There are many incredible people here who you would likely never meet most other places. Take advantage to the opportunity to meet them, in Hacker News discussion threads, off-line via email, and even in person. Put your contact info in the "about" section of your profile (the "email" is private). Organize and participate in local Hacker News get-togethers. Who knows, your next co-founder, investor, or friend for life may be one or two clicks away.

5. Have something to add.

Again, this may sound obvious and lame, but think about it for a minute. Which comments do you like the most? The ones that add data (which very oftens translate into value). The key words are "add", "data", and "value". If you have something interesting to add, the please add it. It's not just your right, it's your responsibility! Everyone wins when you do this: the community gets richer, someone gets value, and you get a bit of a following as an expert in something.

6. Know when to talk and when to listen.

If you have experience doing something being discussed, then by all means, share it! If not then read, listen, and learn. If you have a theory about something but aren't too sure, fine. Just say so. Shocking, but just because you read something on the internets doesn't necessarily mean it's true. And most of all, please never start a sentence with, "It seems to me...". Many of us already get too much of that from our PHBs.

7. The articles may be valuable, but the real gold is in the comments.

If an interesting article posted on Hacker News fell in the forest and no one commented, did it make an impact? Sometimes I post something interesting just to see what you guys will say about it.

Remember:

  Good umpire: I call 'em as I see 'em.

  Better umpire: I call 'em as they are.

  Best umpire: They aren't anything until I call 'em.

Similarly:

  Good article: I write 'em as I see 'em.

  Better article: I write 'em as they are.

  Best article: I'm nothing until until the Hacker News community comments on me.

8. Try to focus on your work.

I know this is controversial, but our work is what makes this community what it is. There are debates about all kinds of things here and elsewhere, but remember, our work is our common thread. Frankly, I'm much more interested in what you built, what you encountered when you built it, and what you learned than your opinion about SOPA.

Another old story:

  Husband: I am the head of the household! I make all of our family's critical policy decisions on the world's major economic, political, and industrial issues!

  Wife: I decide the little things like where we'll live, what we'll eat, and where the kids go to school.

Similarly:

  Commenter 1: This major issue can have profound impact on our technological future.

  Commenter 2: I don't know much about that, but here's how it took me 9 tries to get my app just right for my audience.

Notice that everyone is right, but I still prefer reading the comments of the second person in each example.

9. Be nice.

Life's too short for anything less. There are many other places any of us could be, but we're here. When people aren't nice to me, I just close my browser and come back another day. I know that sounds silly, but it dealing with not nice people is just a big waste of time and everybody loses. Please don't be that person.

Patrick Swayze's character in "Roadhouse" says it much better than me:

10. No list is ever exhaustive, on Hacker News or anywhere else. Anyone have any other suggestions?

Famous Last Words by Bosses I've Had

Sorry to say, none of these were made up...

Me, 124 Monday lunches in a row: We need an adequate disaster recovery plan.
Boss: We do. We back up every day.
Me:   What happens when we try to restore one of those backups?
Boss: I don't know. Why?

Me:   Where's the test plan?
Boss: Jerry will make sure Fred's program works.

Me:   Where's the "Expected Results" section on the test plan?
Boss: What?

Me:   I don't have access to the production server.
Boss: I already emailed you your password.
Me:   I know, but I don't know my login.
Boss: What's a login?

Me:   That doesn't make any sense. Have the auditors approved it?
Boss: No, but we can't have everything.

Boss: I'm really upset that no one has updated me on Project 127.
Me:   I cc'd you on all 9 Project 127 emails I sent this week.
Boss: I haven't had time to get caught up on my email.

Me:   You've been invited to a meeting with 3 department heads to hash out their differences on Project 249.
Boss: I hate meetings.

Boss: Why haven't you started the Accounts Receivable project yet?
Me:   Because management has not yet decided whether customer credit limits should be per division or companywide.
Boss: What difference does that make?

Boss: We have hundreds of past due orders.
Me:   No, we have 22 past due orders.
Boss: I'm not going to argue with you.
Me:   Good, because you'd lose.

Me:   We're meeting with the customer at 8:00 a.m. tomorrow.
Boss: I hate mornings.

Me:   The server crashed. IT Services is working to bring it back up.
Boss: Don't confuse me with all these technical details.

Me:   The customer didn't receive that information because that product is not on our computer.
Boss: Give me a list of all products not on our computer.

Boss: Why haven't you started Project 193 yet?
Me:   Because the customer has not yet committed to the specs.
Boss: What difference does that make?

Me:   The program was written with 3 SQL selects inside a loop. It ran OK when we had 500 parts. Now that we have 10,000 parts, it runs real slow.
Boss: I don't understand.

Boss: What are you working on?
Me:   Project 432, which you said was my top priority. Remember?
Boss: No.

Boss: Why aren't you working on Project 387?
Me:   Because you said not to work on anything else until Project 432 was complete. Remember?
Boss: No.

Boss: I'm giving you only enhancements. I'm outsourcing all of the bug fixes.
Me:   But this is a bug fix. It says so right here on the ticket.
Boss: Oh, I didn't have time to read the ticket.

Boss: Amazon is threatening to shut us down because we ship too many orders late. How do we fix this?
Me:   Ship every order on time.
Boss: No, I meant, "How do we fix this with software?"

Boss, on December 31: Write a program to close every work order so we make our year end numbers.
Boss, on January 3:   Why is the database so screwed up?

Boss: You did great this year. I'm giving you a 2% increase.
Me:   I hate you. I quit.
Boss: Then I'll give you a 4% increase.
Me:   I still hate you. I still quit.

Insidious Bug or Comedy of Errors?

A client presented me with an obvious and significant problem that required immediate attention. I worked on the problem and helped them solve it. Along the way, I discovered a whole bunch of things that merit further examination by software developers.

The names and facts are changed and I will present the code as pseudo-code. I never compromise client confidences and the technology doesn’t matter: this could have happened anywhere.

This is pretty much bread-and-butter backroom application software for a large enterprise that processes lots of orders for lots of dollars...

I was presented of a pdf of a Purchase Order that had been emailed to a Vendor. The problem? No prices. Yikes. This could be a huge problem. The company emails thousands of Purchase Orders to Vendors every day, full of data supporting critical legal and mission critical transactions. The fundamental data elements are Part Number, Quantity, and Price. How could the price be missing? And how could it only be missing from one (or a few) out of thousands of Purchase Orders?

I started by doing what any digital sleuth would do: I tried to recreate the problem. Fortunately, this worked on the first try. I reprinted the Purchase Order and sure enough, no prices. I reprinted several others and there were prices.

The next step was to isolate the problem, debugging backwards. Output Record? Blank price. Variable feeding Output Record? Null value. Price on Purchase Order data base record. Fine. Hmmm. Next I examined the logic pulling the data from the data base and placing it in the output variable. It was looking for the Price in Column 22, the column for Foreign Currency Price. On an order to a California Vendor? OK, I was onto something.

I zeroed in on these two lines in the print program:

CurrencyCode = PORec[45]
if CurrencyCode = "USD" then PriceCol = 21 else PriceCol = 22

What was in Column 45 of this PO Record for this California Vendor? "USD" and a bunch of delimitters. Hmmm. That would cause PriceCol to be 22 when we obviously want it to be 21. The Price was in Column 21 but we are pulling a null out of Column 22. Bingo.

The customers are screaming. The business is suffering. Now what?

Stupid way out: Get the Currency Code from the Vendor record, not the PO Record
Lazy way out: Strip the delmitters from PORec[45].
Right way out: Find out what's putting delimitters into Column 45 of the PO Record.
Long term solution: See below.

The right way out can be very difficult with a large code base. First I isolated the 614 programs that had been promoted into production in the last 90 days. (I figured that the problem was new so the culprit program must be fresh.) I searched for the string "45". 42 hits. Nothing suspicious. Next I looked at data dictionaries and canned functions that provided potential synonyms for Column 45 of the PO Record. I found four possibilities. Then I searched the 614 programs for each of these. Nothing. Hmmm. Standards that no one follows. OK.

Then I simply scoured the list of 614 programs. One name caught my eye: "PoSplitter". Brand new. Written by a contractor who didn't know the whole application. Promoted 3 weeks ago. I read the whole program. No reference to "45", "Foreign Currency", or anything seemingly related. But one variable looked suspicious: DatasetCols. What was this? A list of columns in the PO Record that had matching multiple values, one for each Part on the PO. DatasetCols was a global variable passed down by a master routine. I read that routine and (bingo!) found 45 in the list of DatasetCols. I traced the mods back to 2005 when it was added to the list.

I double-checked the data dictionaries and the common functions. All said that Column 45 of the PO Record must be a single Foreign Currency Code defaulted from the Vendor Record and joined to a preset table. On the other hand, the master PO routine had it in a dataset list. A dataset list that had never been referenced by any other program until that contractor used it in PoSplitter. So, as soon as his program went into production, for every Purchase Order that was "split", Column 45 kept its original Foreign Currency Code along with a delimitter for each Part on the PO. Which in turn caused the PO Print program to fail to secure "USD" and automatically default to Foreign Currency (note that this bug would never affect foreign orders).

The immediate (right) solution:

1. Remove Column 45 from the variable "DatasetCols" in the master routine. Recompile all affected programs.
2. Clean up the data base.

The long term solution:

1. The data dictionary must be the Bible. Have no other code, variables, or function that can possibly say something else. Variables like "DatasetCols" must never be hardcoded, but must be populated from the data dictionary. All synonyms must also be defined in the data dictionary, not in many other routines.

2. Don't use datasets. Normalize your data. (Enough said).

3. Don't have hanging conditionals. Will If...then cover all possibilites? No? Then make a Case, catching any errors. ("USD***" is NOT a valid Foreign Currency Code!)

4. If something breaks, break it! The first time an error was encountered (see #3 above), the PO Print program should have stopped and demanded a help desk intervention. But since errors weren't being captured at the point of failure, 3500 Purchase Orders were printed without prices for three weeks before anybody who cared noticed.

5. Learn the app before you change it. I realize that this is easier said than done, but I'd like to think that the contractor should have understood what all the columns in the PO Record that he was changing. He simply trusted the variable "DatasetCols". Do you imagine that a senior developer would have caught that Column 45 was inconsistently documented in the existing code base? I don't know, but it's an interesting question.

6. Parallel test. The Split Line enhancement was big enough to run an automated parallel test. Column 45 of the POs from the test data base would not have matched those from the Control data base. This would have stuck out like a sore thumb if anyone had bothered to check.

7. Regression test. Just because the stuff that should have changed did change as expected, did everything that should not have changed stay the same? (I know, I know, how do we test for "everything else".) There's no easy answer for this, but doing nothing is the worst possible alternative.

What else would you add to my Long Term Solution list?