edubun English

프로젝트: 팁 계산기와 피즈버즈

84짜리 계산서에 팁 20퍼센트를 얹어 넷이 나누면 한 사람에 25.20입니다. 이 단원에서는 앞 단원의 조각들로 이 계산기를 만들고, 이어서 유명한 연습 문제 피즈버즈를 풉니다.

문제에서 프로그램으로

프로그램은 코드보다 먼저 시작합니다. 무엇이 들어가고, 무엇이 나오고, 그 사이에 무슨 일이 일어나는지 평범한 말로 먼저 정리합니다. 팁 계산기라면 입력은 계산서 금액, 팁 비율, 사람 수입니다. 출력은 팁, 총액, 한 사람 몫입니다. 그 사이에 작은 계산이 세 개 있습니다. 이렇게 적어 두면 막연한 일 하나가 작은 일 여러 개로 나뉘고, 그 하나하나는 이미 할 줄 아는 것입니다.

1단계: 계산

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

코드를 믿기 전에 손으로 확인합니다. 84의 20퍼센트는 16.8, 총액은 100.8, 100.8을 4로 나누면 25.2입니다. 답을 이미 아는 값으로 시험해 봐야 비율을 0.2 대신 20으로 넣어 팁이 1,680이 되는 것 같은 실수를 잡을 수 있습니다.

2단계: 돈을 제대로 보여 주기

돈은 보통 소수 둘째 자리까지 보여 주는데, 25.2라고 출력하면 덜 끝난 것처럼 보입니다. 숫자 메서드 toFixed(2)는 소수점 아래 정확히 두 자리인 문자열을 돌려주므로 each.toFixed(2)는 "25.20"입니다. 숫자 단원에서 본 것처럼 소수에는 아주 작은 이진 반올림 오차가 있을 수 있는데, toFixed는 그것도 감춰 줍니다. 계산하는 동안에는 숫자로 두고, 출력하는 맨 마지막에만 toFixed를 부르세요.

3단계: 함수로 감싸기

다른 숫자로 또 돌릴 계산은 함수에 넣습니다. 아래 함수는 객체를 돌려주므로, 한 번 불러서 세 결과를 분명한 이름과 함께 받을 수 있습니다. 기본 매개변수 덕분에 흔한 경우는 짧게 쓸 수 있습니다.

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

return { tip, total, each: total / people };에는 줄임 표기가 있습니다. 객체 안에 tip만 쓰면 tip: tip이라는 뜻입니다. 키와 변수 이름이 같은 속성입니다.

피즈버즈

피즈버즈는 숫자 세기 놀이를 프로그래밍 연습으로 바꾼 것입니다. 1부터 15까지 셉니다. 3의 배수면 Fizz, 5의 배수면 Buzz, 둘 다의 배수면 FizzBuzz라고 하고, 나머지는 숫자를 그대로 말합니다. 반복문, 나머지 연산자, if 사슬을 쓰고, 함정이 하나 있습니다. 15는 3의 배수이므로 3부터 검사하면 15에서 Fizz가 나오고 FizzBuzz 갈래에는 닿지 못합니다. 해결법은 if 단원에서 본 규칙입니다. 가장 좁은 조건을 맨 앞에 둡니다.

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);
  }
}

i % 15 === 0으로 검사해도 되는 것은 3과 5로 모두 나누어떨어지는 수는 15로도 나누어떨어지기 때문입니다. i % 3 === 0 && i % 5 === 0이라고 쓰면 같은 뜻을 더 바로 드러내며, 어느 쪽이든 괜찮습니다. 직접 쓴 코드를 실행하면 출력을 기대하는 목록과 한 줄씩 비교해 보세요. 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz입니다.

다음에 만들어 볼 것

이제 언어의 뼈대를 모두 갖췄습니다. 값, 변수, 연산자, 판단, 반복, 배열, 함수, 객체입니다. 거의 모든 프로그램이 이 조각들로 만들어집니다. 다음으로는 피즈버즈를 끝 수를 받는 함수로 다시 써 보거나, 팁 계산기가 Math.ceil로 한 사람 몫을 원 단위로 올리게 하거나, 지출 목록을 객체의 배열에 담아 종류별 합계를 출력해 보면 좋습니다. 이 과정이 따라온 MDN 자바스크립트 안내서는 컬렉션, 클래스, 웹 페이지 다루기 같은 주제로 이어집니다.

입력프로그램이 받는 것. 금액, 비율, 사람 수
출력프로그램이 내놓는 것. 팁, 총액, 몫
toFixed(2)소수 정확히 두 자리 문자열. "25.20"
시험 사례올바른 출력을 이미 아는 입력
피즈버즈3의 배수 Fizz, 5의 배수 Buzz, 둘 다 FizzBuzz
속성 줄임 표기{ tip }은 { tip: tip }
  1. 무엇이 출력될까요?
    const bill = 50;
    const tip = bill * 0.1;
    console.log(bill + tip);
  2. 무엇이 출력될까요?
    console.log((25.2).toFixed(2));
  3. 무엇이 출력될까요?
    console.log(typeof (3).toFixed(2));
  4. 피즈버즈에서 9일 때 출력은?
    • Fizz
    • Buzz
    • FizzBuzz
    • 9
  5. 피즈버즈에서 10일 때 출력은?
    • Fizz
    • Buzz
    • FizzBuzz
    • 10
  6. 피즈버즈에서 30일 때 출력은?
    • Fizz
    • Buzz
    • FizzBuzz
    • 30
  7. 무엇이 출력될까요?
    const i = 15;
    if (i % 3 === 0) {
      console.log("Fizz");
    } else if (i % 15 === 0) {
      console.log("FizzBuzz");
    }
  8. 1부터 15까지 중 Fizz(FizzBuzz 제외)로 출력되는 수는 몇 개일까요?
  9. 무엇이 출력될까요?
    function split(total, people = 2) {
      return total / people;
    }
    console.log(split(30));
  10. 무엇이 출력될까요?
    const tip = 4;
    const total = 24;
    const r = { tip, total };
    console.log(r.total - r.tip);
핵심 정리
  • 입력과 출력부터 정하고, 그 사이 단계를 적습니다.
  • 답을 아는 값으로 확인합니다.
  • 계산은 숫자로 하고, toFixed(2)는 출력할 때만 씁니다.
  • 다시 쓸 일은 함수로 감싸고, 결과가 여럿이면 객체로 돌려줍니다.
  • 피즈버즈: 가장 좁은 경우(15의 배수)를 먼저 검사합니다.