Thursday, February 28, 2008

Workday scheduling method 0

In the past, I've tried to schedule my work days in advance based on project commitments (contracts), and when the customers wanted things completed. I could leave time for unscheduled events. I could leave flexibility for meetings, and for projects than ran too long.

But I can't find a way to account for cases where the customer first says he's ready, then it turns out he's actually not. The work I've carefully planned for suddenly becomes impossible. This is probably a result of scheduling work instead of scheduling on-site time in which work is to be done. When you're on site with a customer, it doesn't matter whether they're ready for you or not. You're just there. But being there when the customer isn't ready is a waste of everyone's time, and the customer's money.

Customers want me to reserve time for them, and make promises. E.g., promise that you can finish this 10 hours of work by the end of the week. But when I do so, and I organize my other work around it, and I reserve time to complete this 10 hours of work, then the customer still might renege on his willingness for me to start the work this week. I.e., I'm unable to  

But I have to find some way to inject sanity into my workday. I've got to find a method that works.

Workday Scheduling Method 0.

1. Read email. (1a) If responding can be delayed, then leave the email open in a window, and minimize the window. (1b) If I can readily respond and delaying a response would limit someone's ability to do their own work, then respond immediately, and close the email.

2. Review project list. (2a-runnable) Create a to-do item for each workable task stating exactly what can be accomplished in the day.  (2b-iowait) Create a to-do item for each non-runnable task where I'm waiting on input, or information, or approval from someone else; this to-do item says to contact the people on whom I'm waiting.

3. Do each to-do item, then review each email. (3a) Start with the longest task of the day with a deadline; give this task four hours. (3b) Do remaining tasks should be done earliest-deadline-first.

Condition A. At the end of the day, leave to-do items for the next day.

Condition B. If a task is an emergency, then do it before other remaining tasks. An "emergency" is a task that if ignored or delayed, could cause death or imprisonment.

Condition C. Don't check email or login to IM until the first work-task of the day is completed.

The problem is that everything is an emergency

I'd like to say that I'll schedule my day and work diligently, and I'm
willing to drop anything for an emergency.

But what's an emergency?

If it's something that "requires immediate attention", then who gets
to decide what is "required"? For some customers, everything they want
is an emergency. In fact, some seem to intentionally implement things
without planning; that way when it doesn't work, they can call it an
emergency.

If it's something that can cause "real irrevocable harm" if ignored or
delayed, then practically anything in business could satisfy this.
Delaying almost anything could cost somebody some money. Spending more
money than you have (or not making as much as you need) can cause real
harm; people lose their goodwill, their jobs, go bankrupt, lose their
property, etc.

(My context is the telephone companies for whom I do technical work --
i.e., troubleshooting, configuration, and programming)

Tuesday, February 26, 2008

On Questions and Questionnaires

I normally send questions to your customers in a plain-text ASCII
email, and they normally respond in kind. Things are fine. It's just
email, and it works OK.

But then I decided to send the same questions as an attachment. After
all, an attachment makes it appear that the questions are pre-planned
and generic. It gives the sense that we have experience doing the
project. By sending the questions as a "questionnaire", we're hoping
the recipient will think, "He didn't just think of those questions off
the top of his head! Those questions are the result of some work."

The attachment is a plain-text ASCII .txt file. When customers click
on the attachment, it brings up a random text editor on the
recipient's system. It's not displayed inline with the email in the
font they're accustomed to viewing. In fact, it looks downright goofy.

Suddenly, the same questions, in the same data format, look worse! The
entire effort to appear more professional has failed.

Thursday, February 14, 2008

Object Oriented Design Note: Constructors and Exceptions

Background. I've done a fair bit of Object Oriented programming professionally -- around three years. I've read about OO languages, and I've studied Design Patterns, and I've studied The Pragmatic Programmer and other books. But I still have a lot of questions about OO design. I know how to build classes, interfaces, methods, exceptions, etc. I'm just not sure I know when and how to use them all. Should the method be in this class, or in that class? Should this method just "throws" the exception it gets internally, or it should it re-throw it as a new type of exception? I only find hints here and there at the answers.

This note is about my hope to find those answers. Here's one topic that my good friend Chris Vaughan and I discussed today.

Should a method throw an Exception? 

Proposal: Only a class constructor, or static methods, should throw exceptions.

Exceptions are a nice idea, because they force you to handle error conditions. With exceptions, it's hard to just call a method and ignore errors that occur. With traditional C-style programming, you could call a function like socket() and just ignore the return response if there's an error.

But once you've successfully instantiated an object, should its methods be able to return errors? For example, let's say you have a Report class, and it has method toHtml() that provides an HTML-formatted version of the report. Should toHtml() be able to throw exceptions?  This proposal says that no, it shouldn't. If there would be such exceptions, the constructor itself should fail.

This is analogous to a rule of database design: every row should be meaningful. The implication is that we refuse to allow a row to exist that isn't meaningful. We do this with constraints; for example, if it makes no sense for a row in the "students" table to lack a "student ID", then we make the "student ID" field mandatory.

If we say that every method should be callable without the risk of exceptions, then we're saying that our constructor guarantees us that we have a meaningful -- and functional -- object. As Chris said, this forces some structure on us. In our example, this rule would require that we guarantee in the constructor that toHtml() will work when we call it because we're not allowed to let it throw an Exception.

A weakness here is that this may require the constructor to basically pre-calculate the html rendering -- or else otherwise guarantee it'll work. If the underlying report is encoded as XML somewhere, then this might mean parsing that XML to confirm it's valid before returning the object. This removes some of our options for lazy execution; we might have preferred to wait on that XML parsing until it's actually needed.

A serious weakness is this rule's ability to deal with nondeterminism. For example, let's say we have a Connection object that represents some network connection and functions as a two-way communication channel, and we have a read() method that reads in data received from that channel. What if the channel fails? Perhaps the network has stopped working. Or perhaps the other side of the connection decides to forcefully terminate the connection. In this case, we might like the read() method to throw an exception.

But should the read() method throw an exception? Perhaps no;  maybe read() should simply return null -- i.e., nothing was read. In that case, if you want to know about the status of the Connection object, you'll have to ask somebody else. Or perhaps the Connection class isn't a good abstraction anyway; perhaps it's just an accident of history and the way we all think of the BSD Sockets implementation. Perhaps each time we want to read something, we're really instantiating a new object -- i.e., whatever was read in. Perhaps that constructor should fail if nothing can be read in.

Thanks to Chris Vaughan for this idea.

Sunday, February 10, 2008

Comments on "Time Management for Architects and Designers: Challenges and Remedies", by Thorbjoern Mann (part 1)


In late 2007 I got frustrated, again. I was getting some work done, but it seemed like I ought to be getting more done. It ought not be so stressful. I shouldn't have this nagging feeling that I'm not working on the most important, or urgent task at the time. In the past, I've described a sort of work-management-maturity model. Down that the bottom of the scale, I've got work to do, but I'm not getting it done. I felt like I was spending too much time there.

I found this book, "Time Management for Architects and Designers: Challenges and Remedies", by Thorbjoern Mann, on Amazon. I always aspire to be compared with architects, industrial designers, and hard-science engineers [1]. But does this book really apply to me? Mann mentions this on p.10:  "Design" is understood here to apply to many fields besides architecture; it is "an activity aiming at the production of a plan whose implementation is expected to produce a situation with certain desirable properties and without undesirable side- and aftereffects" [2]. I do this when I'm writing software, and when I'm planning computer (and telephony) networks.

By the way, Software Design has borrowed a major concept from Architecture before: Design Patterns.[3]

Mann uses lots of examples from architecture, but many of his points on time management apply to Software Design and Network Design. There are fundamental factors in "design" that make "time management" tricky, he argues. 

A designer must focus on his work. Distractions are evil [4]. Mann mentions that even a two-second interruption can take a full minute, maybe more, to recover the level of focus to return to work.

Getting Prepared

From p.29, Many people don't allow themselves to see the discrepancies between their work requirements and their preparations until too late. This results in delays, frustration, and mistakes. Make a regular habit of brushing up on the skills and knowledge needed for your work. For example, if you've never parsed XML, and you know you've got a project coming up that requires writing an XML parser, then you may be in trouble if you discover this in the last hour before the project is due. Or, if you know you're likely to need to plan a network with two links to the Internet, be sure you take the time to figure out how this is done before you get into a time crunch.

Bad Attitudes




A designer's attitude can create problems too. From p.32, Many architects see projects as falling into one of two groups: "great architecture" . . . and lowly "bread-and-butter projects". . . . The difference is your attitude. You can look at each project as an opportunity to be creative, solve problems, please the client, manage the project skillfully, and make great architecture, or you can view it as another dull bread-and-butter project full of drudgery and embarrassing compromises. Mann makes an excellent point here. For example, in network design, it's easy to think, "Oh, this is just another customer premise network" or "yet another walled-garden VoIP-core network". But every project has an opportunity to fail; therefore there's an opportunity to succeed. Every project is an opportunity to explore a new technique [4] [5].

Mann suggests a neat idea to help with the attitude problem. Write a statement about the project you are working on, reflecting a positive attitude: "This project is a great opportunity to . . . ". Hang the statement on the wall . . . then act "as if" it is true. For example, "The voiptelco.com network design is a great opportunity to provide sub-second fault recovery".

Fear of Getting Started

Fear of embarrassment or of failure can impede design progress. In software, fear of building the wrong thing -- the thing that won't accomplish what's needed, or will leave out some key capability, or that will be difficult to maintain -- can keep you from starting. My good friend and respected colleague Chris Vaughan [6] and I have worked together on some software projects where the list of requirements just kept growing, and all the constraints on the software design were just massive. Software can be nasty like this.

Don't wait for the great idea or the complete, deep understanding of the problem. That will come along the way; just get going. One "baby step" is all it takes. (p. 33) This is excellent advice. I'm learning that excellent designs don't spring fully formed from great minds; even Leonardo da Vinci practiced his drawings; Unix has evolved heavily since its inception; the original IP networks would collapse when used heavily and had to be modified to keep them running [7].

Mann also suggests an idea that seems interesting, but I don't understand it fully yet. Another way to overcome fear of making a fool out of yourself is to deliberately set out to explore all the biggest blunders one might commit for the project.  . . . It contributes to your understanding of the problem, it helps you to think "outside the box" while clarifying just where the boundaries of the box are . . .
(p. 33)  This seems like you're designing the "complement" of the problem, or sort-of deconstructing the possible working designs. I'll have to think about this more, or try it.

Overconfidence

In CS 140, my second software development class in college [8], Dr. Boyd  assigned us a really fun game project. I could definitely implement what was needed to the project, but I wanted to do something fun. We had a couple of weeks to do it. I wanted my program to support a mouse, and I wanted to represent the game board using a bitmap instead of the ordinary two-dimensional array of booleans. I thought about it for a while, and finally got started in earnest a couple of days before it was due. Then I realized how much there was to do, and I realized that the basic problem (the one I thought was so simple) actually had some complexity. It was harder to read from the mouse than I thought. While I normally finished my projects the evening before they were due, this one was far from complete by 10pm the night before. I was over-confident.  From P.34: Overconfidence can lead to procrastination: "There's no big hurry; things are under control." Then as deadlines approach, you retreat into a kind of arrogant defensiveness. . . . Another result of overconfidence is misguided self-reliance: the sense that the problem can be resolved without other people's input. 

I tend to bump into this problem; over-confidence expresses itself as scheduling work at the last possible minute. This is easy to do, and even encouraged, because other tasks are available to work now. Then I end up doing the work, and realizing that I really did need input from other people.

Pet Ideas

Mann introduces the idea of a "preconceived idea" or "pet idea". Designers quickly develop an initial, intuitive vision of hat the solution will be: a preconceived idea. This is natural and okay -- you wouldn't be a designer if that didn't happen. But progress can get derailed if you uncritically barge ahead with such a pet idea or delay addressing it properly. Some designers use their first preconceived idea exclusively as the basis for all subsequent work. (p. 36). I know I've been guilty of this in the past, especially if this project looks a lot like the last project. I tend not to re-think through how I came to the last project's conclusions -- I only focus on what's common between the two, then try to fit the last design into this new project. I see this tendency in other designers when every project becomes an opportunity to use Buzzword-compliant-new-technology-X.[9] 

Mann suggests bringing the preconceived idea out into the open as soon as possible. Just go ahead and talk about what you're thinking. If there's a mismatch between the preconceived idea and the design requirements, then be honest enough to deal with it. When you try to force a match between the need and your idea, then you're not designing any more -- you're selling.

He also suggests trying to generate more than one idea initially, as soon as possible. This helps in the brainstorming, and helps to compare merits between the ideas.

Fads

Professions fall victims to trends and fads. (p.37) This is clear to anyone who's seen 1960-genre public buildings, or the hideous Bauhaus-esque square buildings with flat roofs and square windows. Software design gets into this, as well. Is there any new data format that's not XML lately? Does MPLS have to be used in every new network? Does every web site need a "social networking" component? Is a "MOS" score really the only way to evaluate network quality for VoIP? Mann recommends that you be especially aware of these fads, with the hope you won't be unduly influenced.

Creativity Imperative

He also mentions the "creativity imperative", which mandates that designers should produce innovative, unprecedented, "creative" solutions for every problem or project they face (p.38). This is a pressure I put on myself, and I expect a lot of other designers do it. I always want my new design to excel above my old designs in some way. I want my new software to be the picture of perfect modularity. I want my new network to be elegant and symmetrical, or its documentation to be the finest documentation ever made for a network. But I have to be careful not to burn up a project's time on this goal. It's not always best to mimic an old design ("rely on precedent"), and it's not always best to create something new and different. 


I hope to discuss some of the other interesting topics in a later post.




[1] My job title is "Systems Engineer". But this is an immature field and the standards for being called a "system engineer" are low. When I say "hard-science engineer", I mean things like electrical engineering, mechanical engineering, or chemical engineering.

[2] I'm quoting Mann. Mann is quoting H. Rittel, Design Methods Lectures, UC Berkeley.  I'm not sure who Rittel is quoting.

[3] I can't remember who wrote the book, "Notes on the Synthesis of Design". But that was the origin of "Design Patterns" popularized in software by the book "Object Oriented Design Patterns".

[4] DeMarco and Lister in "Peopleware" talk at length about how distractions are, and how they cause us to miss key insights and overall do worse work. They also discuss the idea of making projects seem fresh by trying out something new each time. I'm very attracted to this practice.

[5] What's great about consulting work is that projects are pretty well packaged. Usually, they're defined by a Statement of Work agreement. What's bad about work as an employee within a company is that projects are often not well defined. It's just a long list of unimportant tasks. I think interdepartmental billing is very important. People need to pay something to get your services; they'll thus appreciate your services more, and take your product more seriously.


[7] Apparently Van Jacobson designed the congestion-control system into TCP sometime in the mid-1980's. Before that, the largest IP network, the ARPANET, would basically screech to a halt every afternoon.


[9] Are you as tired as I am of hearing how MPLS is the answer to every woe? Oh, and by the way, it's almost always the hardware vendor. Oh, and by the way, you'll need new hardware to get the full MPLS feature set.

Wednesday, February 06, 2008

The biggest laugh from business plans: monthly growth percentage

Working around small businesses for a few years, I've had the chance
to see some business plans. There's always one hilarious component:
the baseless guesses about their sales growth.

For example, one I've seen recently predicts 30% quarterly growth in
customers. Now that kind of math might make sense for a compound
savings account, but why on earth do people assume compound growth for
customer count? Perhaps they're betting on some word-of-mouth effect.

It seems much more reasonable to make a ballpark of the count of new
customers that will sign up every month. For example, we expect to
hear from 1500 new customers every month, and we expect that 500 will
leave us, so we net 1000 new customers every month. Then you could
have a conversation about whether those constant values make sense.

But this compound growth of customers just doesn't strike me as
meaningful. (And, in fact, I've never actually seen it realized.)