계산기를 구현하라 1
요구사항
1. 강사님께서 요구한 디자인의 형태(구체적이진 않았음.)
2. 복잡한 계산, 다항 계산이 아닌 345+23 정도의 간단한 계산식을 요구.
(23+23*43) 이러한 복잡 계산이 아니었다.
하지만
과제가 이렇다 한들 이렇게 끝내고 싶지 않은 게 사람의 욕심이었다.
추가
1. 소수점 자리 표현
2. 0일 때. 을 제외한 모든 기호의 기능 제한
3. 연속된 기호 입력 제한
4. 왼쪽항과 오른쪽 항의 조건을 충족하였을 때 기호 선택 시 계산 후 결괏값 출력.
5. = 버튼을 눌렀을 때에는 해당 기호에 대한 기능을 수행하고 출력한 뒤 저장 값 초기화.
JS 작성
1. input(화면에 보이는 내용)과 모든 버튼(숫자와 기호)들을 전역 변수로 설정
사실 모든 결과값을 누적하여 저장해야 하는 input 부분을 제외하면 굳이 전역 변수로 할 이유는 없었다.
특히 varZero등 다른 변수 역시 선언할 필요도 없었지만, 이번 수업 시간에 배운 것이 getElementById므로 해당 기능을 활용하기 위해 사용하였다.
해당 변수들을 제외하고 각 메서드에 문자열로 직접 숫자를 입력하면 똑같은 기능을 수행할 수 있게 된다.
<script type="text/javascript">
var input = '';
var btnZero = document.getElementById('btnZero');
var btnOne = document.getElementById('btnOne');
var btnTwo = document.getElementById('btnTwo');
var btnThree = document.getElementById('btnThree');
var btnFour = document.getElementById('btnFour');
var btnFive = document.getElementById('btnFive');
var btnSix = document.getElementById('btnSix');
var btnSeven = document.getElementById('btnSeven');
var btnEight = document.getElementById('btnEight');
var btnNine = document.getElementById('btnNine');
var btnDot = document.getElementById('btnDot');
var btnPlus = document.getElementById('btnPlus');
var btnMinus = document.getElementById('btnMinus');
var btnMulti = document.getElementById('btnMulti');
var btnDivide = document.getElementById('btnDivide');
var btnEqual = document.getElementById('btnEqual');
var btnCancel = document.getElementById('btnCancel');
var left;
var right;
</script>
2. A + B의 형태로 그 이상 항이 넘어가지 않게 계산이 진행되도록 하였다.
23+32+54+43와 같은 계산식으로 진행되지 않게끔 로직을 구성하였다.
항이 많아진다고 가정하였을때 고려해야 할 점들이 너무 많았다.
사칙 연산의 우선순위로 고려해야했으며, 숫자들을 담을 변수를 어떤 식으로 구현할 것인지 머리가 복잡해질 것만 같았다.
결국 그냥 A+B, A(==A+B) + C, A(==A+B+C) + D와 같은 형태로 계산이 진행될 수 있게 해야겠다 생각했다.
<script type="text/javascript">
btnPlus.onclick = function() {
var btnPlusN = btnPlus.value;
if (input == '0'|| input == '') {
} else if (input.includes('+') || input.includes('-')
|| input.includes('×') || input.includes('÷')) {
overlap()
if (input != '0') {
input = String(input) + '+';
}
} else {
input += btnPlusN;
}
inputDiv.innerHTML = input;
console.log(input);
}
...
function overlap() {
if (input.includes('+')) {
left = input.substring(0, input.indexOf('+'));
right = input.substring(input.indexOf('+') + 1);
input = String(Number(left) + Number(right));
} else if (input.includes('-')) {
left = input.substring(0, input.indexOf('-'));
right = input.substring(input.indexOf('-') + 1);
input = String(Number(left) - Number(right));
} else if (input.includes('×')) {
left = input.substring(0, input.indexOf('×'));
right = input.substring(input.indexOf('×') + 1);
input = String(Number(left) * Number(right));
} else if (input.includes('÷')) {
left = input.substring(0, input.indexOf('÷'));
right = input.substring(input.indexOf('÷') + 1);
input = String(Number(left) / Number(right));
}
}
</script>
사칙연산 메소드는 거의 동일한 틀을 가지고 있다.
1. HTML에서 있던 input값의 value를 새로운 변수에 대입.
실제로 구현할 때 없어도 된다.. 그냥 바로 기호("+")를 작성해도 무방하다.
그냥 수업시간때 배운 value를 가지고 오는 document.getElementId 명령어를 활용해보고 싶었을 뿐이다.
2. 현재의 input값이 0인지, 공백인지 확인
아무 숫자도 입력되어 있지 않은 상태 또는 계산이 끝마쳐 공백인 상태에서는 연산기호가 적용되지 않는다.라는 것을 첫 번째 전제 조건으로 진행하였다.
3-1. 현재의 input값에 사칙 연산 기호가 있는지 확인
내가 설계한 틀에서는 A + B + C의 계산이 불가하기 때문에 이미 기호가 있다면 새로운 기호를 추가하기 이전에 계산을 끝마쳐야 했다. 그렇기 때문에 이미 input에 기호가 있는지 확인했고, 해당 기호가 있다면 overlap() 함수를 실행시켰다.
그리고 그 결과값이 '0'이 아니라면 '+' 기호를 다시 추가해줬다.
3-2. overlap() 함수와 input != '0'의 사용 이유
overlap()는 equal 함수와 내용이 동일한데, 해당 식을 분석하고 계산을 진행하게 하는 함수이다. 현재 메서드인 "+"를 진행하기 이전에 input에 "+"가 있다면 덧셈을, "-"가 있다면 뺄셈을, "×"가 있다면 곱셈을, "÷"가 있다면 나눗셈을 진행하라는 메서드이다. 그리고 해당 overlap()이 진행되고 난 뒤의 숫자가 0이라면 연산을 진행할 수 없으므로 사칙연산 기호가 추가되지 않게 진행했었고, 0이 아니라면 기호가 붙어서 출력될 수 있도록 작성했다.
예를 들어 -23+23의 경우 0이므로 그 후에 + 기호가 붙을 수 없고, 23+23의 경우 46, 0이 아니므로 46+ 로 출력될 수 있도록 작성하였다.
3. 소수점 계산을 위한 함수
사실 소수점 계산을 위해 결국 배열을 써야 하는가?라는 생각을 했었고
배열을 사용하게 될 경우 지금까지 작성했던 코드를 모두 수정해야 하는 대 공사가 이뤄지기 때문에
그냥 강사님이 요구하지도 않은 기능인데 제외할까 라는 고민이 크게 이뤄졌었다.
고민 끝에 최대한 기존의 코드를 유지하면서 소수점을 사용하게끔 코드를 작성했고, 그로 인해 코드가 깔끔하다고 할 순 없게 되었다.
<script type="text/javascript">
btnDot.onclick = function() {
var btnDotN = btnDot.value;
if (input == '0') {
input += btnDotN;
} else if (input.includes('+') || input.includes('-') || input.includes('×') || input.includes('÷')) {
if (input.includes('+')) {
left = input.substring(0, input.indexOf('+'));
right = input.substring(input.indexOf('+') + 1);
if (right.includes('.') || right.empty) {
} else {
input += '.'
}
} else if (input.includes('-')) {
left = input.substring(0, input.indexOf('-'));
right = input.substring(input.indexOf('-') + 1);
if (right.includes('.') || right.empty) {
} else {
input += '.'
}
} else if (input.includes('×')) {
left = input.substring(0, input.indexOf('×'));
right = input.substring(input.indexOf('×') + 1);
if (right.includes('.') || right.empty) {
} else {
input += '.'
}
} else if (input.includes('÷')) {
left = input.substring(0, input.indexOf('÷'));
right = input.substring(input.indexOf('÷') + 1);
if (right.includes('.') || right.empty) {
} else {
input += '.'
}
}
} else if (input.includes('.')) {
} else {
input += btnDotN;
}
inputDiv.innerHTML = input;
console.log(input);
}
</script>
1. 0일 때도 사용 가능.
다른 기호와 달리 0일 때도 사용할 수 있도록 구현하였다.
2. input에 사칙 연산이 있는지 확인.
A+B의 형태로 진행되기 때문에 A에 소수점이 있는지, B에 소수점이 있는지 계속해서 확인해야 했다.
확인하지 않는다면 점의 중복이 이뤄지게 되고 저세상 계산이 될 수 있기 때문이다.
처음 있는 else if에서 사칙연산 기호가 이미 존재한다면 A와 B가 존재하고 있기 때문에 A와 B로 나눠준 후,
현재 소수점을 입력했다면 당연히 B항의 소수점이므로 B항에 '.' 점이 존재하는지 또는 B항이 비어있는지 확인 후 모든 조건을 만족하면 소수점을 추가하였다.
3. 그렇지 않다면 input이 '.'을 가지고 있는지 확인, 없으면 소수점 추가.
그렇지 않은 상황이란 사칙 연산이 없는 상황을 말한다.
사칙연산 기호가 없다면 A+B와 같은 형태가 아니므로 A가 소수점을 가지고 있는지만 확인하면 된다. 소수점을 가지고 있다면 아무런 기능을 진행하지 않고 다음 else문으로 진행되어 소수점이 추가되도록 한다.
완성된 코드
<script type="text/javascript">
window.onload = function() {
var input = '';
var btnZero = document.getElementById('btnZero');
var btnOne = document.getElementById('btnOne');
var btnTwo = document.getElementById('btnTwo');
var btnThree = document.getElementById('btnThree');
var btnFour = document.getElementById('btnFour');
var btnFive = document.getElementById('btnFive');
var btnSix = document.getElementById('btnSix');
var btnSeven = document.getElementById('btnSeven');
var btnEight = document.getElementById('btnEight');
var btnNine = document.getElementById('btnNine');
var btnDot = document.getElementById('btnDot');
var btnPlus = document.getElementById('btnPlus');
var btnMinus = document.getElementById('btnMinus');
var btnMulti = document.getElementById('btnMulti');
var btnDivide = document.getElementById('btnDivide');
var btnEqual = document.getElementById('btnEqual');
var btnCancel = document.getElementById('btnCancel');
var left;
var right;
btnCancel.onclick = function() {
input = "";
inputDiv.innerHTML = input;
}
btnZero.onclick = function() {
var btnZeroN = btnZero.value;
if (input == '0') {
input = btnZeroN;
} else {
input += btnZeroN;
}
inputDiv.innerHTML = input;
console.log(input);
}
btnOne.onclick = function() {
var btnOneN = btnOne.value;
if (input == '0') {
input = btnOneN;
} else {
input += btnOneN;
}
inputDiv.innerHTML = input;
console.log(input);
}
btnTwo.onclick = function() {
var btnTwoN = btnTwo.value;
if (input == '0') {
input = btnTwoN;
} else {
input += btnTwoN;
}
inputDiv.innerHTML = input;
console.log(input);
}
btnThree.onclick = function() {
var btnThreeN = btnThree.value;
if (input == '0') {
input = btnThreeN;
} else {
input += btnThreeN;
}
inputDiv.innerHTML = input;
console.log(input);
}
btnFour.onclick = function() {
var btnFourN = btnFour.value;
if (input == '0') {
input = btnFourN;
} else {
input += btnFourN;
}
inputDiv.innerHTML = input;
console.log(input);
}
btnFive.onclick = function() {
var btnFiveN = btnFive.value;
if (input == '0') {
input = btnFiveN;
} else {
input += btnFiveN;
}
inputDiv.innerHTML = input;
console.log(input);
}
btnSix.onclick = function() {
var btnSixN = btnSix.value;
if (input == '0') {
input = btnSixN;
} else {
input += btnSixN;
}
inputDiv.innerHTML = input;
console.log(input);
}
btnSeven.onclick = function() {
var btnSevenN = btnSeven.value;
if (input == '0') {
input = btnSevenN;
} else {
input += btnSevenN;
}
inputDiv.innerHTML = input;
console.log(input);
}
btnEight.onclick = function() {
var btnEightN = btnEight.value;
if (input == '0') {
input = btnEightN;
} else {
input += btnEightN;
}
inputDiv.innerHTML = input;
console.log(input);
}
btnNine.onclick = function() {
var btnNineN = btnNine.value;
if (input == '0') {
input = btnNineN;
} else {
input += btnNineN;
}
inputDiv.innerHTML = input;
console.log(input);
}
btnDot.onclick = function() {
var btnDotN = btnDot.value;
if (input == '0') {
input += btnDotN;
} else if (input.includes('+') || input.includes('-')
|| input.includes('×') || input.includes('÷')) {
if (input.includes('+')) {
left = input.substring(0, input.indexOf('+'));
right = input.substring(input.indexOf('+') + 1);
if (right.includes('.') || right.empty) {
} else {
input += '.'
}
} else if (input.includes('-')) {
left = input.substring(0, input.indexOf('-'));
right = input.substring(input.indexOf('-') + 1);
if (right.includes('.') || right.empty) {
} else {
input += '.'
}
} else if (input.includes('×')) {
left = input.substring(0, input.indexOf('×'));
right = input.substring(input.indexOf('×') + 1);
if (right.includes('.') || right.empty) {
} else {
input += '.'
}
} else if (input.includes('÷')) {
left = input.substring(0, input.indexOf('÷'));
right = input.substring(input.indexOf('÷') + 1);
if (right.includes('.') || right.empty) {
} else {
input += '.'
}
}
} else if (input.includes('.')) {
} else {
input += btnDotN;
}
inputDiv.innerHTML = input;
console.log(input);
}
btnPlus.onclick = function() {
var btnPlusN = btnPlus.value;
if (input == '0'|| input == '') {
} else if (input.includes('+') || input.includes('-')
|| input.includes('×') || input.includes('÷')) {
overlap()
if (input != '0') {
input = String(input) + '+';
}
} else {
input += btnPlusN;
}
inputDiv.innerHTML = input;
console.log(input);
}
btnMinus.onclick = function() {
var btnMinusN = btnMinus.value;
if (input == '0'|| input == '') {
} else if (input.includes('+') || input.includes('-')
|| input.includes('×') || input.includes('÷')) {
overlap()
if (input != '0') {
input = String(input) + '-';
}
} else {
input += btnMinusN;
}
inputDiv.innerHTML = input;
console.log(input);
}
btnMulti.onclick = function() {
var btnMultiN = btnMulti.value;
if (input == '0' || input == '') {
} else if (input.includes('+') || input.includes('-')
|| input.includes('×') || input.includes('÷')) {
overlap()
if (input != '0')
input = String(input) + '×';
} else {
input += btnMultiN;
}
inputDiv.innerHTML = input;
console.log(input);
}
btnDivide.onclick = function() {
var btnDivideN = btnDivide.value;
if (input == '0' || input == '') {
} else if (input.includes('+') || input.includes('-')
|| input.includes('×') || input.includes('÷')) {
overlap()
if (input != '0') {
input = String(input) + '÷';
}
} else {
input += btnDivideN;
}
inputDiv.innerHTML = input;
console.log(input);
}
btnEqual.onclick = function() {
if (input.includes('+')) {
left = input.substring(0, input.indexOf('+'));
right = input.substring(input.indexOf('+') + 1);
input = Number(left) + Number(right);
inputDiv.innerHTML = Number(left) + Number(right);
} else if (input.includes('-')) {
left = input.substring(0, input.indexOf('-'));
right = input.substring(input.indexOf('-') + 1);
input = Number(left) - Number(right);
inputDiv.innerHTML = Number(left) - Number(right);
console.log(left);
console.log(right);
} else if (input.includes('×')) {
left = input.substring(0, input.indexOf('×'));
right = input.substring(input.indexOf('×') + 1);
inputDiv.innerHTML = Number(left) * Number(right);
input = Number(left) * Number(right);
console.log(left);
console.log(right);
} else if (input.includes('÷')) {
left = input.substring(0, input.indexOf('÷'));
right = input.substring(input.indexOf('÷') + 1);
console.log(left);
console.log(right);
inputDiv.innerHTML = Number(left) / Number(right);
input = Number(left) / Number(right);
} else {
console.log('잘못된 접근입니다.');
}
console.log(input);
input = '';
}
function overlap() {
if (input.includes('+')) {
left = input.substring(0, input.indexOf('+'));
right = input.substring(input.indexOf('+') + 1);
input = String(Number(left) + Number(right));
} else if (input.includes('-')) {
left = input.substring(0, input.indexOf('-'));
right = input.substring(input.indexOf('-') + 1);
input = String(Number(left) - Number(right));
} else if (input.includes('×')) {
left = input.substring(0, input.indexOf('×'));
right = input.substring(input.indexOf('×') + 1);
input = String(Number(left) * Number(right));
} else if (input.includes('÷')) {
left = input.substring(0, input.indexOf('÷'));
right = input.substring(input.indexOf('÷') + 1);
input = String(Number(left) / Number(right));
}
}
}
</script>
작성하고 든 생각
1. 음수 표현이 가능하므로 "+", "-"도 0일 때 계산이 가능하도록 해야 하지 않을까
2. 소수점 표현을 진행할 때 '+', '-', '×', '÷'을 OR로 한 번에 묶고 if문으로 각 사칙연산일 때를 부여하여 subStrig을 한다면 코드를 줄일 수 있을 것 같다.
'회고록 > Archive' 카테고리의 다른 글
[미니 프로젝트] 블로그 만들기 0 (0) | 2022.07.06 |
---|---|
[계산기 구현] 계산기를 구현하라 2 (완성) (0) | 2022.06.27 |
[계산기 구현] 계산기를 구현하라 0 (HTML, CSS) (0) | 2022.06.27 |
[국비지원 교육] 02. IT 개발자 국비 지원 교육 준비, 국민 취업 지원 제도 (예체능 출신 비전공자 개발자 일기) (0) | 2022.06.11 |
[국비지원 교육] 01. 국비 지원 학원 면접 탈락, 국비 지원 학원 알아 보는 법 (예체능 출신 비전공자 개발자 일기) (0) | 2022.06.09 |