edubun 한국어

Project: tip calculator and FizzBuzz

A bill of 84 with a 20 percent tip split four ways comes to 25.20 each. This unit builds that calculator, then the classic FizzBuzz exercise, from the pieces in earlier units.

From a problem to a program

Writing a program starts before any code. First say in plain words what goes in, what comes out, and what happens in between. For a tip calculator, the inputs are the bill, the tip rate and the number of people. The outputs are the tip, the total and each person's share. In between there are three small calculations. Writing this down turns one vague task into several small ones, each of which you already know how to do.

Step 1: the calculation

const bill = 84;
const rate = 0.2;
const people = 4;

const tip = bill * rate;          // 16.8
const total = bill + tip;         // 100.8
const each = total / people;      // 25.2

Check the numbers by hand before trusting the code: 20 percent of 84 is 16.8, the total is 100.8, and 100.8 divided by 4 is 25.2. Testing with values whose answer you already know is how you catch mistakes such as a rate typed as 20 instead of 0.2, which would make the tip 1,680.

Step 2: showing money properly

Money is normally shown with two decimal places, and printing 25.2 looks unfinished. The number method toFixed(2) returns a string with exactly two decimals, so each.toFixed(2) gives "25.20". Remember from the numbers unit that decimals can carry tiny binary rounding errors; toFixed also hides those, which is another reason to use it for display. Keep the numbers as numbers while calculating and call toFixed only at the very end, when printing.

Step 3: wrap it in a function

A calculation you might run again with other numbers belongs in a function. The function below returns an object, so a single call can hand back all three results with clear names. Default parameters make the usual case short to write.

function splitBill(bill, rate = 0.15, people = 1) {
  const tip = bill * rate;
  const total = bill + tip;
  return { tip, total, each: total / people };
}

const r = splitBill(84, 0.2, 4);
console.log(`Tip: ${r.tip.toFixed(2)}`);       // Tip: 16.80
console.log(`Each: ${r.each.toFixed(2)}`);     // Each: 25.20

The line return { tip, total, each: total / people }; uses a shorthand: writing tip alone inside an object means tip: tip, a property whose key and variable share a name.

FizzBuzz

FizzBuzz is a counting game turned into a programming exercise. Count from 1 to 15. For multiples of 3 say Fizz, for multiples of 5 say Buzz, for multiples of both say FizzBuzz, and otherwise say the number. It uses a loop, the remainder operator and an if chain, and it has one trap. The number 15 is a multiple of 3, so if you test for 3 first, 15 prints Fizz and never reaches the FizzBuzz branch. The fix is the rule from the if unit: put the narrowest condition first.

for (let i = 1; i <= 15; i++) {
  if (i % 15 === 0) {
    console.log("FizzBuzz");
  } else if (i % 3 === 0) {
    console.log("Fizz");
  } else if (i % 5 === 0) {
    console.log("Buzz");
  } else {
    console.log(i);
  }
}

Testing i % 15 === 0 works because a number divisible by both 3 and 5 is divisible by 15. Writing i % 3 === 0 && i % 5 === 0 says the same thing more directly, and either is fine. When your version runs, compare its output line by line with the expected list: 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz.

What to build next

You now have the core of the language: values, variables, operators, decisions, loops, arrays, functions and objects. Almost every program is built from these pieces. Good next steps are to rewrite FizzBuzz as a function that takes the upper limit, to make the tip calculator round each share up to whole currency units with Math.ceil, or to keep a list of expenses in an array of objects and print a total by category. The MDN JavaScript Guide, which this course follows, continues with topics such as collections, classes and working with web pages.

inputWhat a program is given: bill, rate, people
outputWhat a program produces: tip, total, share
toFixed(2)A string with exactly two decimals: "25.20"
test caseAn input whose correct output you already know
FizzBuzzFizz for 3s, Buzz for 5s, FizzBuzz for both
shorthand property{ tip } means { tip: tip }
  1. What does this print?
    const bill = 50;
    const tip = bill * 0.1;
    console.log(bill + tip);
  2. What does this print?
    console.log((25.2).toFixed(2));
  3. What does this print?
    console.log(typeof (3).toFixed(2));
  4. In FizzBuzz, what is printed for 9?
    • Fizz
    • Buzz
    • FizzBuzz
    • 9
  5. In FizzBuzz, what is printed for 10?
    • Fizz
    • Buzz
    • FizzBuzz
    • 10
  6. In FizzBuzz, what is printed for 30?
    • Fizz
    • Buzz
    • FizzBuzz
    • 30
  7. What does this print?
    const i = 15;
    if (i % 3 === 0) {
      console.log("Fizz");
    } else if (i % 15 === 0) {
      console.log("FizzBuzz");
    }
  8. How many of the numbers 1 to 15 print as Fizz (not FizzBuzz)?
  9. What does this print?
    function split(total, people = 2) {
      return total / people;
    }
    console.log(split(30));
  10. What does this print?
    const tip = 4;
    const total = 24;
    const r = { tip, total };
    console.log(r.total - r.tip);
Key points
  • Name the inputs and outputs first, then the steps between them.
  • Check with values whose answers you know.
  • Calculate with numbers; use toFixed(2) only when printing.
  • Wrap reusable work in a function; return an object for several results.
  • FizzBuzz: test the narrowest case (multiples of 15) first.