Process to pass from problem to code. How did you learn?

Solution 1:

I go via the test-driven approach.

1. I write down (on paper or plain text editor) a list of tests or specification that would satisfy the needs of the problem.

- simple calculations (no discounts and concessions) with:
    - single item
    - two items
    - maximum number of items that doesn't have a discount
- calculate for discounts based on number of items
    - buying 10 items gives you a 5% discount
    - buying 15 items gives you a 7% discount
    - etc.
- calculate based on hourly rates
    - calculate morning rates
    - calculate afternoon rates
    - calculate evening rates
    - calculate midnight rates
- calculate based on buyer's age
    - children
    - adults
    - seniors
- calculate based on combinations
    - buying 10 items in the afternoon

2. Look for the items that I think would be the easiest to implement and write a test for it. E.g single items looks easy

The sample using Nunit and C#.

[Test] public void SingleItems()
{
    Assert.AreEqual(5, GetPrice(5, 1));
}

Implement that using:

public decimal GetPrice(decimal amount, int quantity)
{
    return amount * quantity; // easy!
}

Then move on to the two items.

[Test]
public void TwoItemsItems()
{
    Assert.AreEqual(10, GetPrice(5, 2));
}

The implementation still passes the test so move on to the next test.

3. Be always on the lookout for duplication and remove it. You are done when all the tests pass and you can no longer think of any test.

This doesn't guarantee that you will create the most efficient algorithm, but as long as you know what to test for and it all passes, it will guarantee that you are getting the right answers.

Solution 2:

the old-school OO way:

  • write down a description of the problem and its solution
  • circle the nouns, these are candidate objects
  • draw boxes around the verbs, these are candidate messages
  • group the verbs with the nouns that would 'do' the action; list any other nouns that would be required to help
  • see if you can restate the solution using the form noun.verb(other nouns)
  • code it

[this method preceeds CRC cards, but its been so long (over 20 years) that I don't remember where i learned it]

Solution 3:

when learning programming I don't think TDD is helpful. TDD is good later on when you have some concept of what programming is about, but for starters, having an environment where you write code and see the results in the quickest possible turn around time is the most important thing.

I'd go from problem statement to code instantly. Hack it around. Help the student see different ways of composing software / structuring algorithms. Teach the student to change their minds and rework the code. Try and teach a little bit about code aesthetics.

Once they can hack around code.... then introduce the idea of formal restructuring in terms of refactoring. Then introduce the idea of TDD as a way to make the process a bit more robust. But only once they are feeling comfortable in manipulating code to do what they want. Being able to specify tests is then somewhat easier at that stage. The reason is that TDD is about Design. When learning you don't really care so much about design but about what you can do, what toys do you have to play with, how do they work, how do you combine them together. Once you have a sense of that, then you want to think about design and thats when TDD really kicks in.

From there I'd start introducing micro patterns leading into design patterns

Solution 4:

I did something similar.

  • Figure out the rules/logic.
  • Figure out the math.
  • Then try and code it.

After doing that for a couple of months it just gets internalized. You don't realize your doing it until you come up against a complex problem that requires you to break it down.