-
7일차인 오늘은 어제 6일차에 이어서 계산기에 대한 코드를 완성하는 sprint가 진행되었다. 계산기 과제는 bare-minimum, advanced, nightmare 단계로 오른쪽으로 갈수록 그 난이도가 올라간다. 그리고 여기서 제시되는 과제는 bare-minimum 까지만 코드를 완성하고 제출해도 다음 단계로 넘어가는 최소 기준이 완료된다. 나는 어제 bare-minimum을 완료해서 오늘은 nightmare 단계까지 시도하여 결국 nightmare를 완료하고 제출까지 마쳤다. 오늘은 계산기 code작성 외에 추가적으로 학습이 이루어진 것이 없기에 오늘 코드 작성을 하면서 마주친 문제점들과 문제 해결 방식에 대해서 아래 적었다.
JavaScript 계산기 기능 구현
계산기의 형태 변경
처음 bare-minimum 과제에서는 위와 같은 계산기에서 1자리 수의 숫자를 활용해 연산의 결과 값을 뽑아내는 작업을 했다.
그리고 advanced와 nightmare에 들어서면서 위 이미지와 같은 우리가 아는 일반적인 계산기 형태에서 이미지를 구현하는 작업을 했다.
계산기에서 첫번째와 다르게 변경되면서 우선 입력하는 값을 변수에 지정하는 작업이 필요했다.
이전이라면 계산기 상에서 이미 그에 해당되는 값이 표기되는 동시에 값을 보존하는 역할을 하였으므로 굳이 변수를 따로 잡을 필요성이 없었다.변수 설정
과제는 github에 올라와 있는 코드를 다운받아서 지정된 코드 입력란에 코드를 넣는 형태로 진행된다.
그래서 파일을 다운받으면 일부 사전에 힌트처럼 묘하게 이게 왜 여기 있는거지? 하는 것들이 일부 코드안에 있었다.
nightmare단계의 과제를 풀이하는데에 있어서 필요한 변수들도 마찬가지로 사전에 코드안에 담겨 있었다.let firstNum, operatorForAdvanced, previousKey, previousNum;
위 변수들에 대해서 firstNum은 처음 입력한 숫자를 저장하고, operatorForAdvanced는 계산기의 연산자(+, - 등)를 넣으면 되는 변수로 보았다.
그리고 previousNum에는 이전에 입력을 완료한 숫자인 듯하였고 각 변수를 활용해 연산을 진행하면 될 것으로 보였다(?)
여기서 previousKey같은 경우는 어디에 쓰는 변수인지 감이 오지 않아서 문제를 풀 때는 안 쓰고 풀었다.
이렇게 문제를 풀고 나중에 문제 풀기전에 보는 글들을 다시 봤는데 previousKey가 이전 입력한 키 값을 저장하는 변수란다...
(나중에 쓰긴 했는데 원래 의도된 기능으로 쓰지 않고 잠깐 일부 값을 임시 저장하는 용도로 썻다...)
문제를 풀기전에 그 글에 왠지 힌트가 좀 쎄게 있을 것 같아서 안 봤는데 다 풀고 난 다음에 후회했다.
previousKey변수의 용도를 알고 난 다음에 저걸 썻으면 2시간 일찍 풀었겠지...이전 키 값을 저장하는 변수가 있는 것과 없는 것의 차이는 대략 다음과 같은 문제에 마주칠 때 활용가능할 것으로 보인다.
(보인다라고 한건 난 그런 용도로 저 변수를 쓰지 않았기 떄문이다)'3', '*', '계산'이 입력되는 경우
일반적인 계산기라면 저 과정에서 3 * 3 = 9가 결과 값으로 나온다. 그리고 다시 '계산'버튼을 누르면 9에 3을 다시 곱한다.
'3', '*', '3', '+', '3'이 입력되는 경우
여기서 유의해야할 부분은 연산자 하나가 사용되고 '계산'이 입력되어 연산이 진행되는 것이 아닌 다시 또 하나의 연산자가 들어와서 그 연산자 입력에 따라 다시 계산 기능이 이루어진다는 것이다.
위 2가지 경우 외에도 코드를 작성하고 테스트 코드로 검사받는 과정에서 previousKey에 이전 입력했던 키 값을 저장했다면 좋았을 경우가 많아 보였다.
아래는 코드 전문을 그냥 가져와서 붙여봤다.
굳이 모든 코드를 여기 올리는 이유는 우선 이렇게 한번에 100줄 넘는 코드를 스스로 작성해본 적이 없고,
스스로 만족감을 느끼게되어서 앞으로도 힘들떄면 이 코드를 보려고 한다.const calculator = document.querySelector(".calculator"); // calculator 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다. const buttons = calculator.querySelector(".calculator__buttons"); // calculator__keys 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다. const firstOperend = document.querySelector(".calculator__operend--left"); // calculator__operend--left 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다. const operator = document.querySelector(".calculator__operator"); // calculator__operator 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다. const secondOperend = document.querySelector(".calculator__operend--right"); // calculator__operend--right 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다. const calculatedResult = document.querySelector(".calculator__result"); // calculator__result 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다. function calculate(n1, operator, n2) { //계산 함수 let result = 0; n1 = Number(n1); n2 = Number(n2); if (operator === "+") { result = n1 + n2; } else if (operator === "-") { result = n1 - n2; } else if (operator === "*") { result = n1 * n2; } else if (operator === "/") { result = n1 / n2; } return String(result); } let operatorCount = 0; // ! 아래부터는 bare-minimum 과제 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")) { // TODO : 계산기가 작동할 수 있도록 아래 코드를 수정하세요. 작성되어 있는 조건문과 console.log를 활용하시면 쉽게 문제를 풀 수 있습니다. // 클릭된 HTML 엘리먼트가 button이면 if (action === "number") { if (operatorCount < 1) { if (firstOperend.textContent === "0") { firstOperend.textContent = ""; } firstOperend.textContent = firstOperend.textContent + buttonContent; // = > += } else { if (secondOperend.textContent === "0") { secondOperend.textContent = ""; } secondOperend.textContent = secondOperend.textContent + buttonContent; } console.log("숫자 " + buttonContent + " 버튼"); } if (action === "operator") { operator.textContent = buttonContent; operatorCount = 1; console.log("연산자 " + buttonContent + " 버튼"); } if (action === "decimal") { console.log("소수점 버튼"); } if (action === "clear") { firstOperend.textContent = "0"; secondOperend.textContent = "0"; operator.textContent = "+"; calculatedResult.textContent = "0"; operatorCount = 0; console.log("초기화 버튼"); } if (action === "calculate") { calculatedResult.textContent = calculate( firstOperend.textContent, operator.textContent, secondOperend.textContent ); console.log("계산 버튼"); } } }); // ! 아래부터는 Advanced Challenge test와 Nightmare test const display = document.querySelector(".calculator__display--for-advanced"); // calculator__display 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다. let firstNum, operatorForAdvanced, previousKey, previousNum; buttons.addEventListener("click", function (event) { const target = event.target; // 클릭된 HTML 엘리먼트의 정보가 저장어 있습니다. const action = target.classList[0]; // 클릭된 HTML 엘리먼트에 클레스 정보를 가져옵니다. const buttonContent = target.textContent; // 클릭된 HTML 엘리먼트의 텍스트 정보를 가져옵니다. // ! 위 코드는 수정하지 마세요. // ! 여기서부터 Advanced Challenge & Nightmare 과제룰 풀어주세요. if (target.matches("button")) { if (action === "number") { if (operatorForAdvanced === undefined) { if (display.textContent === "0") { display.textContent = ""; } display.textContent += buttonContent; firstNum = display.textContent; } else { if (previousNum === undefined) { display.textContent = ""; } display.textContent += buttonContent; previousNum = display.textContent; } } if (action === "operator") { if (firstNum !== undefined && previousNum !== undefined) { display.textContent = calculate( firstNum, operatorForAdvanced, previousNum ); firstNum = display.textContent; previousNum = undefined; } operatorForAdvanced = buttonContent; } if (action === "decimal") { if (display.textContent.includes(".") !== true) { if (operatorForAdvanced !== undefined && previousNum === undefined) { display.textContent = "0"; } display.textContent += buttonContent; if (operatorForAdvanced !== undefined && previousNum === undefined) { previousNum = display.textContent; } } } if (action === "clear") { display.textContent = "0"; firstNum = undefined; previousNum = undefined; operatorForAdvanced = undefined; previousKey = undefined; } if (action === "calculate") { if (operatorForAdvanced === undefined) { display.textContent = firstNum; } else { if (previousNum === undefined) { if (previousKey === undefined) { previousKey = firstNum; } display.textContent = calculate( firstNum, operatorForAdvanced, previousKey ); } else { display.textContent = calculate( firstNum, operatorForAdvanced, previousNum ); previousKey = previousNum; previousNum = undefined; } firstNum = display.textContent; } } } });
'개발학습 > 코드스테이츠 SE Bootcamp' 카테고리의 다른 글
코드스테이츠 SEB 9일차 TIL - Git 기초 (0) 2021.07.29 코드스테이츠 SEB 8일차 TIL - CLI 기본명령어, Node.js (0) 2021.07.28 코드스테이츠 SEB 6일차 TIL - CSS 기초, 계산기 웹 애플리케이션 (0) 2021.07.26 코드스테이츠 SEB 5일차 TIL - HTML 기초 (0) 2021.07.23 코드스테이츠 SEB 4일차 TIL - JS 반복문 (0) 2021.07.23 댓글