간단한 계산기 만들기

jeongjwon·2023년 2월 23일
0

SEB FE

목록 보기
9/56

[과제1] 계산기 구현하기

Bare Minimum Requirements

  1. 버튼이 잘 눌렸는지 확인 -> 클릭시 console 창 확인
    버튼은 기본적으로 ( 숫자, 연산자 + - * /, 소수점. , 계산 Enter , 초기화 AC ) 으로 구성
    - 소숫점 버튼 클릭시 console 창에 '소숫점 버튼' 출력

    const buttons = calculator.querySelector('.calculator__buttons'); // calculator__buttons 엘리먼트와, 그 자식 엘리먼트의 정보 => 버튼들의 정보
    
    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')) {
       //클릭된 html 엘리먼트가 button과 일치할 경우
    		if (action === 'decimal') {
           //button의 class 명이 decimal 인 경우 
           //console 창에 '소수점 버튼' 출력
       		console.log('소수점 버튼');
     	}
     }
  2. 기본 계산 기능 구현하기 -> 두 숫자의 사칙연산
    textContent : 엘리먼트의 text 값

    1. 첫번째 칸에 숫자 나타내기 : 초기화 값인 0 인 경우에 클릭한 수를 입력시킴
    2. 두번째 칸에 숫자 나타내기 : 첫번째 칸에 숫자가 0이 아닌 경우(=이미 첫번째 칸에 숫자를 나타냄) 두번째 칸에 클릭한 수를 입력시킴
    const firstOperend = document.querySelector('.calculator__operend--left');//calculator__operend--left 엘리먼트와, 그 자식 엘리먼트의 정보 = 첫번째 칸
    const secondOperend = document.querySelector('.calculator__operend--right'); // calculator__operend--right 엘리먼트와, 그 자식 엘리먼트의 정보 = 두번째 칸
    
    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')) {
           //클릭된 html 엘리먼트가 button과 일치할 경우
          if (action === 'number') {
            //button의 class명이 number인 경우
            if(firstOperend.textContent === '0'){
              //현재 첫번째 칸의 '0'인 경우(기본값)에 클릭된 텍스트 정보인 buttonContent 값으로 변경
              firstOperend.textContent = buttonContent;
            }else{
              //현재 첫번째 칸의 '0'인 아닌 경우(이미 바꾸어진 값)에  
              secondOperend.textContent = buttonContent;
            }
          }
        }
    }
    1. 화면에 출력된 숫자와 연산자로 계산하기
      계산 Enter 버튼 클릭시 세번째 칸에 숫자 나타내기
    const operator = document.querySelector('.calculator__operator');//calculator__operator 엘리먼트와, 그 자식 엘리먼트의 정보 = 연산자 칸
    const calculatedResult = document.querySelector('.calculator__result'); // calculator__result 엘리먼트와, 그 자식 엘리먼트의 정보 = 세번째 칸 = 결과값
    
    function calculate(n1, operator, n2) {
      	//string 변수인 첫번째 칸 값, 연산자 값, 두번째 칸 값 을 매개변수로 가짐
      	let result = 0;
      	//연산자의 종류에 따라 문자열을 숫자형으로 바꿔준 후 계산한 값을 result로 받아 반환
      	if(operator === '+'){
          result = Number(n1) + Number(n2);
        }else if(operator === '-'){
          result = Number(n1) - Number(n2);
        }else if(operator === '*'){
          result = Number(n1) * Number(n2);
        }else if(operator === '/'){
          result = Number(n1) / Number(n2);
        }
      	return 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')) {
           //클릭된 html 엘리먼트가 button과 일치할 경우    
    		 if (action === 'calculate') {
               //button의 class 명이 calculate 인 경우
      			console.log('계산 버튼');
      			calculatedResult.textContent = calculate(firstOperend.textContent, operator.textContent, secondOperend.textContent);
               // calculate 함수로 결과값을 반환한 값으로 세번째 결과값에 변경
    		}
        }
    }
    1. 화면 상의 값을 초기화하기
      AC(All Cancel) 버튼으로 초기화 -> 첫번째칸과 두번째칸과 세번째칸의 수는 0으로 초기화, 연산자칸은 +로 초기화
	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')) {
           //클릭된 html 엘리먼트가 button과 일치할 경우
          if (action === 'clear') {
            //button의 class명이 number인 경우
            console.log("초기화 버튼");
            firstOperend.textContent = '0';
            secondOperend.textContent = '0';
            calculatedResult.textContent = '0';
            operator.textContent = '+';
          }
        }
    }




[과제2] User flow에 따라 기능 구현하기

Advanced Challenge test

display : 계산 혹은 숫자가 보이는 곳 // 설정하기 위해서는 'diplay.textContent = 값' 으로 설정
buttonContent : 현재 클릭한 값

//밑의 변수의 초기화는 undefined로 설정
firstNum : 첫번째 피연산자 값
operatorForAdvanced: 연산자 값 
previousNum : 두번째 피연산자 값
previousKey : 이전의 클릭한 action 종류 값//=> 이 변수를 이용하여 연속값인지 확인
  1. 숫자버튼 누르고 화면에 숫자를 입력하기

    • 숫자 버튼을 눌렀을 때, 계산기 화면 (display.textContent) 에 숫자가 보여야 함
    • 숫자버튼을 여러번 눌렀을 때, 이어붙어져야 함 (concat(buttonContent))
  2. Enter 버튼 눌러 계산하고 AC 버튼으로 초기화 시키기

    • 연산자 버튼을 눌렀을 때 계산기 화면에 보이는 숫자를 따로 저장 (firstNum에 저장) 하고 계산할 준비해야함
    • Enter 버튼을 눌렀을 떄, 계산기 화면에 보이는 숫자와 저장된 숫자를 함께 조합하여 계산한 결과 (display.textContent = calculate(firstNum, operatorForAdvanced, previousNum) 를 화면에 보여줘야함
    • AC 버튼을 눌렀을 때, 초기화 (firstNum , operatorForAdvanced, previousNum, previousKey => undefined / display.textContent = '0') **가 되어야 함
     if (action === 'number') {// 버튼의 종류가 number 인 경우
       if(firstNum === undefined){
         //첫번째 피연산자값이 설정되지 않은 경우
         firstNum = buttonContent;
         display.textContent = firstNum;
         //클릭한 그 숫자값이 곧 첫번째 피연산자값
       }else{
         if(operatorForAdvanced === undefined){
           //첫번째 피연산자 값이 설정되었지만, 연산자 값이 아직 설정되지 않았기 때문에 첫번째 피연산자 값에 이어붙어줘야 함
           firstNum = firstNum.concat(buttonContent); //혹은 firstNum += buttonContent;
           display.textContent = firstNum;
         }else{//첫번째 피연산자 값과 연산자 값도 모두 설정된 후 숫자를 클릭했을 경우
           if(previousNum === undefined){
             //두번째 피연산자를 처음으로 설정할 경우
             previousNum = buttonContent;
           }else{//앞서 설정된 두번째 피연선자 값에 추가로 덧붙여 줌
             previousNum = previousNum.concat(buttonContent);
           }
           display.textContent = previousNum;
         }
       }
       previousKey = 'number';
     }
     



Nightmare test

  1. calculate 함수 검사
    • 실수 연산 테스트
		function calculate(n1, operator, n2) {
  			let result = 0;
      		//1 . 실수인지 정수인지 판별 
       		if(!Number.isInteger(n1) || !Number.isInteger(n2)){
          	//실수인 경우 : n1 나 n2 하나라도 실수인 경우 => number 타입 실수로 변환
          		n1 = parseFloat(n1);
          		n2 = parseFloat(n2);
        	}else{
          	//정수인 경우: number 타입 정수로 변환
          		n1 = parseInt(n1);
          		n2 = parseInt(n2);
        	}
      
      		//2. 형변환으로 만든어진 수들로 연산자의 종류에 따라 계산
      		if(operator === '*'){
          		result = n1 + n2;
        	}else if(operator === '-'){
          		result = n1 - n2;
        	}else if(operator === '*'){
          		result = n1 * n2;
        	}else if(operator === '/'){
          		result = n1 / n2;
        	}
      	
      		return result;
    	}
  1. 계산기 특이 작동

    • 연산자 키 연속 클릭
      3 * * * * * 3 Enter => 3 (아무일 x)
    • Enter 키 연속 클릭
      3 * 3 Enter Enter Enter Enter => 243(3*3=9*3=27*3=243) => 즉, 결과값과 두번째 피연산자가 연산작용하여 결과값 도출
    • 연산자 - Enter 키 클릭
      3 * Enter => 9 (3*3=9) => 즉, 첫번째 피연산자가 두번째 피연산자로 대체되어 연산작용하여 결과값 도출
      if (action === 'calculate') {
      	if(previousKey === 'calculate'){
        	//연속 엔터인 경우
         	//첫번째 엔터의 결과값에 연산자와 두번째피연산자를 이용하여 다시 결과값 도출하여 화면에 출력
         		let res =  calculate(display.textContent, operatorForAdvanced, previous);
         		display.textContent = res;
       	}else{
             //연속 엔터 아닐 경우
             	if(previousKey === 'operator'){
              //이전의 키가 연산자일 경우 => 첫번째 피연산자와 연산자로만 계산
            		let res = calculate(firstNum, operatorForAdvanced, firstNum);
              	display.textContent = res;
           	}else{
            	//아닌 경우 => 평범한 상황이므로 첫번째 피연산자와 두번째 피연산자와 연산자로만 계싼 
            		let res = calculate(firstNum, operatorForAdvanced, previousNum);
            		display.textContent = res;
          	}
          }
         previousKey = 'calculate';
       }
    • 소수점 키 클릭, 소수점 키 연속 클릭
      100..1252 => 100.1252 => 덧붙이지 않고 그대로 유지 => 아무런 명령 x
      if (action === 'decimal') {
       if(previousKey !== 'decimal'){
        //연속 소수점키가 아닌 경우 => 소수점키를 처음 붙이는 경우
         if(firstNum === undefined){
         //첫번째 피연산자 값이 지정되지 않은 경우 => 0.으로 설정후 화면출력
           firstNum = '0.';
           display.textContent = firstNum;
         }else{//첫번째 피연산자 값이 지정된 경우
           if(operatorForAdvanced === undefined){
           //연산자가 설정되지 않은 경우 = 두번째 피연산자도 어차피 설정되지 않음 => 아직 첫번째 피연산자 값을 설정 중 => 첫번째 피연자 값에 .을 덧붙여줌
           //두번째 값이 지정되지 않은 경우 => 첫번째 피연산자 값에 .을 덧붙여줌	
             firstNum = firstNum.concat('.'); //혹은 firstNum += '.';
             display.textContent = firstNum;
           }else{//연산자가 설정된 경우 두번째 피연산자를 설정해줘야하는 차례
             if(previousNum === undefined){
             //두번째 피연산자가 설정되지 않은 경우 => 0.으로 설정 후 화면 출력
               previousNum = '0.';
             }else{
               //두번째 피연산자 값이 지정된 경우 => 두번째 피연산자 값에 .을 덧붙여 줌
               previousNum = previousNum.concat('.');// 혹은 previousNum += '.';
             }
             display.textContent = previousNum;
           }
         }
       }
       previousKey = 'decimal';
      }
      	
    • Enter 키 없이 연산키 클릭으로 계산 연장
      100 . . 1 2 5 2 + 1 2 + 1 5 - - 2 3 - 1 4 4 2 / 2 3 / / 1 2 * 2 3 Enter => 100.1252 + 12 + (112.1252 출력) + 15 -(127.1252 출력) - (연속 연산자는 아무일x) 23 - (104.1252 출력) 1442 / (-1337.8748출력) 23 / (-58.16846956521739출력) / 12 * (-4.847372463768116출력) 23 Enter (-111.48956666666668 최종출력
      if (action === 'operator'){
       //첫번째 피연산자와 두번째 피연산자, 연산자가 모두 설정이 된 후에 누른 버튼이 operator 인 경우 
       //=> 먼저 계산해준 후, 값을 화면에 출력하고 첫번째 피연산자는 결과값으로 갱신, 두번째 피연산자는 초기화, 연산자는 눌러진 연산자 버튼 값을 새로 갱신
       	if(previousNum !== undefined){
          //두번째 피연산자가 설정이 되어있는 경우 
          //= 즉, 첫번째 피연산자와 두번째 피연산자, 연산자가 모두 설정이 된 후 라는 말 
       		let res = calculate(firstNum, operatorForAdvanced, previousNum);
       		firstNum = res;
       		display.textContent = res;
       		previousNum = undefined;
         	}
       	operatorForAdvanced = buttonContent; //연산자 갱신은 모두 해당
       	previousKey = 'operator';
      }












       
       
       
   
   
   
    	

 
 

0개의 댓글