My good friend Carl Manaster sent me this a couple days ago, and I was really taken with just cool it was, and how much I wished other programmers were as diligent as he is (and I try to be).
This is his work, I have permission.
I noticed myself doing something last night that I have done hundreds
or thousands of times before, following a habit that I've
unconsciously adopted. It worked - again - and I decided to
formalize it, to make the practice easier to apply deliberately in
the future, to better be able to determine appropriate situations for
its application, and to share with others.
What I was doing was as follows. I had four little triangles to draw
around the outside of circles forming an irregular shape. I wrote a
routine to calculate the points of one of the triangles, with values
for all of the coordinates that would only work for the first case.
I then duplicated this routine, and reworked it for a second
triangle. I then generalized the code, writing a routine that could
handle any arbitrary triangle-outside-a-circle (within the context of
my application), replaced the original two routines with calls to
this one, and wrote the routines for the remaining triangles.
Here's the recipe:
- Write a specific case;
- Derive a second specific case from the first;
- Write a general solution;
- Apply the general solution to the first two cases;
- Use the general solution as needed.
and the rationale:
- Write a specific case;
This lets you solve the problem once without getting caught up in the
abstractions. It gives you something simple to test, and a good
motivation: you need this first case to work. You also need the
other cases to work, but the motivation for the general case is more
abstract - "softer", if you will. You can mess with values as much
as you need, and it won't be messing up any other cases.
- Derive a second specific case from the first;
This exposes your first implementation to some stress-testing. It
lets you see which parts are stable under different circumstances,
and which parts need to be flexible. It gives you a second, more
reflective look at the problem - because it is much easier than
solving the problem in the first case, you have more of a chance to
think about the problem without getting lost in the details.
- Write a general solution;
The bits you didn't need to change in (2) should form the basis for a
common solution, with the bits you did need to change representing
parameters to the routine.
- Apply the general solution to the first two cases;
If nothing else, this gets rid of embarrassing code bloat - but of
course there is much else: you get a chance to test against
already-working cases, and identify and resolve discrepancies.
- Use the general solution as needed.
Now that you've got it, put it to work. There may be a few remaining
things to fix in the general solutions - a sample size of two is,
after all, unlikely to be representative of most problem populations
- but these should be small, and the main work of the routine is
already behind you.
Note that at every step, except (4), you have something new to test.
That's good - you don't save up all the bugs for the final step. It
is also a fairly even distribution of thoughtload, so you're never
bored or overwhelmed.
--
Laziness, Impatience, Hubris, and Generosity.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.
|
|