Now we'll talk about building and designing programs. This is a complicated topic that
we'll revisit many times. The general idea is that we need to find a way to strategically
develop programs. As an analogy, we don't write an English essay by sitting down and
just typing. Or at least, you shouldn't. You need to organize your thoughts first. Write
an outline, develop topic sentences in your main arguments, and then smooth it out. We
need to do something similar in programming. The strategy we're going to use is called
test-driven development. Before you write the program, what you do is decide exactly
what you want the program to do. You create specific test data that covers all the cases,
or at least as many as is practical. Spreadsheets can be great for this.
Let's take an example. We'll write a program that reads in the number of Facebook status
updates you make each day for seven days, and then projects how many you'd make in a
year. The first thing we do is develop the test data. So let's look for some easy cases
first. We call these boundary cases in programming. For example, if there are no status updates
made in seven days, you'd expect no status updates made in a year. That's an easy case.
It's also easy to look at what happens if you make one status update each day. Then
you'd expect 365 in a year. Let's look for some more interesting data though. Suppose
you made one the first day, two the second day, three the third day, and so on. The average
of those numbers is four, and so you'd make 4 times 365, or 1460 status updates in a year.
Let's think about some harder cases now. What if the average doesn't work out nicely to
an integer? You might make one status update the first three days and two the last four.
The average of those numbers is 1.57. So if we take 1.57 and multiply by 365, we'll get
573.5714. But should we show a decimal? It doesn't really make sense because you can't
post half a status update. Could we round? Well, we don't know how to do that yet, so
that's not a possibility. We do know how to truncate, so let's do that. We now have a
test table of data. You may be starting to see some of the advantages. For example, we've
thought about one of the problems we're going to run into when writing the code. That's
one of the points of test-driven development. We could add more test cases, and we really
should, but this is enough to get us started.
Now it's time to design our program. We usually design small programs by writing comments
that describe what the code will do. Here are some comments that I would think of. First
you would read in seven values from the user, keeping a running sum of the number of status
updates. Then calculate the average number of updates per day. Then calculate the number
of updates per year, and show the user the result.
Now let's finish the program. Now it's time to actually write the code. Do it slowly.
Check that it compiles and runs as often as possible, even if it doesn't do anything yet.
Usually, you're going to have some syntax errors. Then the code won't compile. You see
this in the clips by words that are underlined with little red squigglies. The first thing
to do is read your code carefully. Look for mistakes in spelling, punctuation, capitalization,
forgetting asterisks for multiplication, and substituting curly braces, parentheses, and
square brackets. You may need to compare to programs that do run to see the differences.
You may even have to get help from somebody else at first. But don't worry. Eventually
this gets easy.
Once your code compiles, you need to test it. You test it using the data that you've
already developed. When your test data doesn't match what your program puts out, it's time
to debug your program. The word "debugging" has an interesting story behind it. It was
coined by Admiral Grace Hopper when she found a moth that was stuck in the computer was
ruining her program, and we've called it debugging ever since. You can read more about this amazing
woman, and I encourage you to do so.
So let's talk about some debugging strategies. First, read your code carefully. Think about
the nuances of Java. Some common problems you want to consider are repeating loops one
too many time or one too few times. This has a special name too. That's called an off-by-one
bug. The likely mistake in this program would be having the while loop repeat six or eight
times instead of seven. It's also easy to make mistakes with integer and floating-point
operations. A likely mistake in this program would be forgetting that integer division
truncates the result. So, for example, suppose you have an int called totalUpdates and a
double called averageUpdatesPerDay. You could write averageUpdatesPerDay equals totalUpdates
divided by seven. This would be incorrect because totalUpdates is an integer and seven
is an integer. So the division is going to truncate. You do have to remember that the
test data can be wrong too. But the code is usually the problem, so consider that first.
Sometimes you're going to need help with debugging because it is complicated to learn how to
do. The most important strategy is to start early. Even great programmers sometimes need
help with tricky bugs. For example, I once spent six weeks looking for a bug in my program.
I had replaced an 'm' with an 'n'. It was a pretty painful six weeks. Create your test
data first. Design your program by writing comments to describe what the code should
do. Write the code a few lines at the time. Make sure it compiles as you go along. Run
your program as soon as possible and as often as possible, and check your test data carefully.
That should get you started on writing programs properly.