Lily, Klaus, taxes, and bugs

America's golden age

In 2020, Cameron Esposito wins the US presidential election, sweeping to victory on a platform of side mullets and jean jackets. President Esposito and First Human Rhea Butcher raise the country to new standards of peace, dignity, and prosperity.

Among President Esposito's many achievements is a complete overhaul of the tax system. If you pretend to have extra income to impress people, that's taxable now. The economic boost you get from being attractive, that's taxable. Lying to your mother can earn you a tax penalty. Feeling guilty about something you didn't do is recognized as a legitimate life expense.

Confused tax prep company I&S Pyramid creates an Excel workbook to help people with form 1041.6.llama, the new individual income tax return. Unfortunately, grumpy I&S programmer Ronald Dump is so angered by America's new golden age that he does a lousy job.

Lily and Klaus agree to clean up Dump's mess. Let's watch them test and debug the program.

We need to start with the new tax code. This is the thing that Lily and Klaus are trying to match.

The rerevised tax code

The new system is different. Tax deductions have been replaced with tax credits, and… well, here's a picture of the worksheet, and the new rules.

The app

The Code, So Pay Attention

Wages: 80% of the first $50,000 is taxable, 100% of the rest is taxable.

Investment income: 100% is taxable.

Imaginary extra income (the difference between your real income and what you tell your cousins at the family reunion): 40% of the first $100,000 plus 70% of the rest is taxable.

Beauty benefit (the economic edge attractive people have): 150% is taxable, because the rest of us are jealous.

$1,000 tax credit for each human dependent, up to four. No credit for additional dependents.

$1,300 tax credit if you have one dog, $3,000 if you have two, with no credit for additional dogs.

$50 tax credit for the first cat, with no additional credit for more cats.

50% credit for educational expenses.

10% credit for jean jacket expenses.

40% credit for charitable donations. Unless you told your mother that you donated more than you did, in which case there is no credit.

Line 32 will indicate whether you owe us, or we owe you.

Taxable income is taxed according to the following table:

Taxable income Rate
Under 20,000 0%
20,000 to 50,000 18%
50,001 to 100,000 22%
Above 100,000 28%

Lily and Klaus

Lily and Klaus get Dump's workbook, and a copy of the tax code. The program is about 140 lines, several times longer than anything we've seen so far in this course. Their job is to test the workbook, and fix any bugs.

For now, we'll assume that users don't make mistakes when they type in data. This is unrealistic, of course. We'll add input validation later.

Let's watch Lily and Klaus at work. They're using fake accents today. I don't know why.

Klaus
Klaus
Lily, zere are so many inputs hier! Und so much code!

Ve can't test every combination of inputs. It vould take hours.

Klaus doesn't just start testing. He's thinking about it. How to do a thorough test in a reasonable time.

Lily
Lily
Aye. We canna test it like that, tryin' all input combinations. Our brains'll nay take the strain. We need a diffr'nt way.

Bu' what?

Hmm… let's loook at the firs' bi' o' code. Maybe get ideas, lad. The income stoof.

Income

  1. 'Compute taxable income
  2. 'Get input
  3. incomeWages = Cells(5, 2)
  4. incomeInvestments = Cells(6, 2)
  5. incomeImaginary = Cells(7, 2)
  6. incomeBeauty = Cells(7, 2)
  7. 'Wages
  8. If incomeWages <= 50000 Then
  9.     taxableWages = 40000 '50000 * 0.8
  10. Else
  11.     taxableWages = 40000 + (incomeWages - 50000)
  12. End If
  13. 'Imaginary
  14. If incomeImaginary <= 100000 Then
  15.     taxableImaginary = incomeImaginary * 0.4
  16. Else
  17.     taxableImaginary = 100000 * 0.4 _
  18.         + (incomeImaginary - 100000) * 0.7
  19. End If
  20. 'Beauty benefit
  21. taxableBeauty = incomeBeauty * 1.5
  22. 'Total taxable income
  23. totalTaxableIncome = Round(taxableWages + incomeInvestments _
  24.     + taxableImaginary + taxableBeauty)
  25. Cells(9, 2) = totalTaxableIncome
Klaus
Klaus
Ze first part gets inpoot from ze cells, into variables.
  1. 'Get input
  2. incomeWages = Cells(5, 2)
  3. incomeInvestments = Cells(6, 2)
  4. incomeImaginary = Cells(7, 2)
  5. incomeBeauty = Cells(7, 2)
Lily
Lily
Aye, 'tis so.

Och, lad, I have a notion. Check oot this code:

  1. 'Wages
  2. If incomeWages <= 50000 Then
  3.     taxableWages = 40000 '50000 * 0.8
  4. Else
  5.     taxableWages = 40000 + (incomeWages - 50000)
  6. End If
  7. ...
  8. 'Total taxable income
  9. totalTaxableIncome = Round(taxableWages + incomeInvestments _
  10.     + taxableImaginary + taxableBeauty)

Lily
Lily
There's a rool for wages, an' wages is added into a total.

Then…

  1. 'Imaginary
  2. If incomeImaginary <= 100000 Then
  3.     taxableImaginary = incomeImaginary * 0.4
  4. Else
  5.     taxableImaginary = 100000 * 0.4 _
  6.         + (incomeImaginary - 100000) * 0.7
  7. End If
  8. ...
  9. 'Total taxable income
  10. totalTaxableIncome = Round(taxableWages + incomeInvestments _
  11.     + taxableImaginary + taxableBeauty)

Lily
Lily
There's a rool for imaginary, and it gets added to a total.
Klaus
Klaus
Zat I see, Lily. How does zat help?

Lily
Lily
Dinna ya see, lad? We test each rool, one at a time. Put in inpoot jus' for that rule. See how tha' changes the total.

Let me show ya. Poot in wages, an' noothin' else, an' click Run.

Testing

Lily
Lily
An' we get:

Wages

Lily
Lily
We check tha' oot. Erase the data, an' test the next rool.

Investments

Klaus
Klaus
Ach du lieber! I zee! Ve look at vun rule at a time. Each vun is simple. Ve do not haf to look at all ze combinations.

Lily, du bist wunderbar!

Lily
Lily
Ooch, I bet ya say that to all the girls.
Klaus
Klaus
Ja, but viz you, I mean it.
Lily
Lily
So ya lie to the other girls?
Klaus
Klaus
Umm, er…

Ja, I suppose I do. I vill try to be better.

Zo, ve type in der nummers, und zee vat happens.

Aber, vhat nummers do ve type in?

Vait! I know! Ve look at ze rool in ze tax code. Type in ze numbers that test ze rule. Here is vun.

Wages: 80% of the first $50,000 is taxable, 100% of the rest is taxable.

Zo, ve type in nummer less than 50 000, und nummer more than 50 000. Check vith calculator.

Lily
Lily
Das ist gut! Ach, I mean, good lad!

But dinna forget the edge cases. Like 50,000.

Klaus
Klaus
Hmm, I zee vhat you mean. Ze rule ist:

Wages: 80% of the first $50,000 is taxable, 100% of the rest is taxable.

Vould be easy for programming mistake ven income is exactly 50 000.

They now have a testing strategy that makes sense for this program. There's a lot of data, but each piece of data is handled by a simple rule. (That's quite common in business programming.) They decide to test rule by rule. Including edge cases is a Good Thing. Klaus is right: it's easy to make programming mistakes when dealing with edge cases.

Lily
Lily
The firs' test:

Wages

Klaus
Klaus
A bug already! Himmel!

Hier ist der code.

  1. incomeWages = Cells(5, 2)
  2. ...
  3. If incomeWages <= 50000 Then
  4.     taxableWages = 40000 '50000 * 0.8
  5. Else
  6.     taxableWages = 40000 + (incomeWages - 50000)
  7. End If
Lily
Lily
Let's check that the inpoot is right, lad. A breakpoint like this…

Debugging

Klaus
Klaus
Ja, you typed 30 000, und ze variable, it is 30 000. Input is not ze bug.

Is taxable vages correct?

Lily presses F8 a few times, stepping through each line of code.

Debugging

The input (incomeWages) was right at the breakpoint, but taxableWages is wrong at the current line. So the bug is somewhere between them.

Lily
Lily
Och, I see the wee error. 'Tis in this line:

taxableWages = 40000 '50000 * 0.8

Klaus
Klaus
Vhere is der bug? 50 000 times 80% is 40 000. Zat is correct.
Lily
Lily
Aye, lad, but why use 50,000? The income is 30,000.
Klaus
Klaus
Mein Gott! Not 50 000 times 80%! Nein! 30 000 times 80%! Schülengrabterlichgruberfen!
Lily
Lily
If you say so, lad.

Let's change…

taxableWages = 40000 '50000 * 0.8

… to…

taxableWages = incomeWages * 0.8

Klaus
Klaus

Lily,
Lily,
Über alles…

Summary

Lily and Klaus looked at the code they were working with, and chose a testing and debugging strategy suited to that program. They tested one piece of data at a time. They compared the output that should have shown with what did show. When they found an error, they used breakpoints to track down the cause.