TIL 7일차

안광의·2021년 6월 22일
0

Today I Learned

목록 보기
7/64
post-thumbnail

시작하며

오늘은 어제하던 계산기 과제를 Nightmare 단계까지 구현이 가능하도록 수정하였다. Pair와 막히는 부분에 대해서 생각해보기로 하고 과제를 마쳤는데, 혼자 1시간 정도 코드를 수정하다보니 Nightmare 단계까지 완료가 되어서 오늘은 알고리즘에 대해서 Pair에게 설명하고 개선할 부분을 찾는 방향으로 진행하였다.

완성된 코드

const calculator = document.querySelector('.calculator'); // calculator 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.
const buttons = calculator.querySelector('.calculator__buttons'); // calculator__keys 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.

const display = document.querySelector('.calculator__display--for-advanced'); // calculator__display 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.
let first, second, last, operatorForAdvanced

function calculate(n1, operator, n2) {
  let result = 0;
  let num1 = Number(n1);
  let num2 = Number(n2)
  if(operator === '+') result = num1 + num2;
  if(operator === '-') result = num1 - num2;
  if(operator === '*') result = num1 * num2;
  if(operator === '/') result = num1 / num2;
  // TODO : n1과 n2를 operator에 따라 계산하(n1)는 함수를 만드세요.
  // ex) 입력값이 n1 : '1', operator : '+', n2 : '2' 인 경우, 3이 리턴됩니다.
  return String(result);

buttons.addEventListener('click', function (event) {
  // 버튼을 눌렀을 때 작동하는 함수입니다.

  const target = event.target; // 클릭된 HTML 엘리먼트의 정보가 저장되어 있습니다.
  const action = target.classList[0]; // 클릭된 HTML 엘리먼트에 클레스 정보를 가져옵니다.
  const buttonContent = target.textContent; // 클릭된 HTML 엘리먼트의 텍스트 정보를 가져옵니다.

  if (target.matches('button')) {
    if (action === 'number') {
      if (display.textContent === '0') {
        display.textContent = buttonContent
      }
      else if (first !== '' && second === '') {
        display.textContent = buttonContent;
        second = buttonContent;
      }
      else if (second !== '') {
      display.textContent = display.textContent + buttonContent;
      second = display.textContent;
      }
      else display.textContent = display.textContent + buttonContent
    }
    if (action === 'operator') {
      if (last === '+' || last === '-' || last === '*' || last === '/') {
        operatorForAdvanced = buttonContent
      }
      else if (second === '') {
      first = display.textContent;
      operatorForAdvanced = buttonContent;
      }
      else if (second !== '' ) {
      first = calculate(first, operatorForAdvanced, second);
      second = '';
      operatorForAdvanced = buttonContent;
      }
    }
    if (action === 'decimal') {
      if (last === '.') {}
      else if (first === '' && second === '') {
        display.textContent = display.textContent + '.'
      }
      else if (second === '') {
        display.textContent = '0.'
        second = display.textContent
      }
      else if (second !== '') {
        display.textContent = display.textContent + '.'
        second = display.textContent
      }
    }
    if (action === 'clear') {
     display.textContent = '0'
     first = ''
     second = ''
     operatorForAdvanced = ''
    }
    if (action === 'calculate') {
      if (first === '' && second === '') {}
      else if (second === '') {
        display.textContent = calculate(first, operatorForAdvanced, first);
      }
      else {
        display.textContent = calculate(first, operatorForAdvanced, second);
        first = calculate(first, operatorForAdvanced, second);
      }
    }
    last = buttonContent
  }

});

해결과정

가장 처음에 막혔던 부분은 '.'을 입력할때 첫번째 항과 두번째 항을 구분해 주는 것이었다. 초기에 알고리즘을 설계할 때 처음 숫자를 입력하고 연산자(+,-,*,/)를 클릭하면 디스플레이에 입력되었던 숫자를 first 변수에 입력하고 그이후 숫자는 누를때마다 second 변수에 할당하도록 설계하였다. 그래서 if로 첫번째 항을 입력하고 있는지 두번째 항을 입력하고 있는지를 구분해서 '.'버튼이 변수들에 할당되도록 코드를 수정했다.

그 이후에 Nightmare 단계의 테스트 코드 중 통과하지 못한 부분은 '.'을 연속으로 눌렀을 때 오류가 나는 것이었다. 처음에는 charAt method를 디스플레이의 마지막 글자가 '.'인 경우 무시하도록 코드를 작성하였으나 연산자를 연속으로 눌렀을때에도 다른 값이 출력되는 오류가 발생해서 두 오류를 묶어서 같은 방식으로 처리하기로 했다. 마지막에 buttonContent를 last란 변수에 할당하여 버튼을 클릭하였을때 이전에 클릭한 버튼이 무엇인지를 last 변수를 통해 확인할 수 있도록 하는 것이다. last에 '.'이 할당되어 있는데 '.'을 다시 클릭하거나 연산자가 할당되어 있는데 연산자를 다시 클릭한 경우에는 무시되도록 코드를 수정하였다. 단, 연산자가 연속으로 입력되었을 때에는 buttonContent를 operatorForAdvanced에 할당하여 마지막에 누른 연산자로 계산될 수 있도록 하였다.

그리고 마지막 테스트 코드는 '1+5-2+7/8 ='과 같이 계속해서 계산을 하는 경우였는데, second 변수에 값이 할당되어 있을때 연산자를 클릭한 경우 현재 first와 second 변수에 있는 값을 계산해서 fisrt 변수에 재할당하고 second에 할당된 값을 지우는 것으로 Nightmare 단계를 마쳤다.

마치며

문제가 긴 코딩테스트 하는 것 같은 느낌이었는데, 내가 만든 웹페이지가 작동되는지를 직관적으로 확인할 수 있어 성취감이 있었다. 과제를 진행하면서 더 간결한 코드가 있지 않을까, 알고리즘을 초기에 잘못 설계한 것이 아닌가에 대해서 끊임없이 고민했다. 앞으로는 Nightmare 단계까지의 테스트코드를 확인한 후 알고리즘을 설계해야겠다고 생각했다.

profile
개발자로 성장하기

0개의 댓글