Skip to content

Commit 82d2cc3

Browse files
committed
Fix calculator decimal and infinity logic
1 parent 76ad5a0 commit 82d2cc3

1 file changed

Lines changed: 86 additions & 65 deletions

File tree

web-app/js/projects/calculator.js

Lines changed: 86 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ function getCalculatorHTML() {
124124
function initCalculator() {
125125
const display = document.getElementById("calcDisplay");
126126
if (!display) return;
127-
128127
let expression = "";
129128

130129
function update() {
@@ -140,7 +139,11 @@ function initCalculator() {
140139

141140
function safeEval(expr) {
142141
try {
143-
return String(eval(format(expr)));
142+
if (!expr) return "";
143+
let result = eval(format(expr));
144+
if (result === undefined) return "";
145+
if (isNaN(result)) return "Error";
146+
return String(result);
144147
} catch {
145148
return "Error";
146149
}
@@ -149,48 +152,64 @@ function initCalculator() {
149152
function applyFunction(type) {
150153
try {
151154
let value = eval(format(expression || "0"));
152-
155+
let result;
153156
switch (type) {
154-
case "sin": return String(Math.sin(value));
155-
case "cos": return String(Math.cos(value));
156-
case "tan": return String(Math.tan(value));
157-
case "sqrt": return String(Math.sqrt(value));
158-
case "square": return String(value * value);
159-
case "inv": return value === 0 ? "Error" : String(1 / value);
157+
case "sin": result = Math.sin(value); break;
158+
case "cos": result = Math.cos(value); break;
159+
case "tan": result = Math.tan(value); break;
160+
case "sqrt": result = Math.sqrt(value); break;
161+
case "square": result = value * value; break;
162+
case "inv": result = 1 / value; break;
160163
}
164+
if (isNaN(result)) return "Error";
165+
return String(result);
161166
} catch {
162167
return "Error";
163168
}
164169
}
165170

166-
document.querySelectorAll(".calc-btn").forEach(btn => {
167-
btn.addEventListener("click", () => {
171+
172+
function clearIfFinished() {
173+
if (expression === "Error" || expression === "NaN") {
174+
expression = "";
175+
}
176+
}
168177

178+
document.querySelectorAll(".calc-btn").forEach((btn) => {
179+
btn.addEventListener("click", () => {
180+
clearIfFinished();
181+
169182
const value = btn.dataset.value;
170183
const action = btn.dataset.action;
171184

172185
if (value !== undefined) {
186+
if (value === ".") {
187+
188+
const lastOperand = expression.split(/[\+\-\*\/\^\(\)]/).pop();
189+
if (lastOperand.includes(".")) return;
190+
}
173191
expression += value;
174192
update();
175193
return;
176194
}
177195

178196
if (!action) return;
179197

198+
180199
switch (action) {
181-
182200
case "clear":
183201
expression = "";
184202
break;
185-
186203
case "delete":
187-
expression = expression.slice(0, -1);
204+
if (expression === "Infinity" || expression === "-Infinity") {
205+
expression = "";
206+
} else {
207+
expression = expression.slice(0, -1);
208+
}
188209
break;
189-
190210
case "=":
191211
expression = safeEval(expression);
192212
break;
193-
194213
case "sin":
195214
case "cos":
196215
case "tan":
@@ -199,11 +218,19 @@ function initCalculator() {
199218
case "inv":
200219
expression = applyFunction(action);
201220
break;
202-
203221
case "^":
204-
expression += "^";
222+
case "+":
223+
case "-":
224+
case "*":
225+
case "/":
226+
227+
const lastChar = expression.slice(-1);
228+
if (["+", "-", "*", "/", "^"].includes(lastChar)) {
229+
expression = expression.slice(0, -1) + action;
230+
} else {
231+
expression += action;
232+
}
205233
break;
206-
207234
default:
208235
expression += action;
209236
}
@@ -212,54 +239,48 @@ function initCalculator() {
212239
});
213240

214241
document.addEventListener("keydown", (e) => {
215-
216-
const key=e.key;
217-
if(!document.getElementById("calcDisplay")) return;
218-
if(key==="Enter" ||
219-
key==="Backspace" ||
220-
key==="Escape" ||
221-
key==="=" ||
222-
["+","-","*","/","^",".","(",")"].includes(key) ||
223-
/^[0-9]$/.test(key)
224-
) {
225-
e.preventDefault()
226-
}
227-
if(/^[0-9]$/.test(key)){
228-
expression+=key;
229-
}
230-
else if(key==="."){
231-
expression+=".";
232-
}
233-
else if(["+","-","*","/"].includes(key)){
234-
expression+=key;
242+
const key = e.key;
243+
if (!document.getElementById("calcDisplay")) return;
244+
245+
// Whitelist allowed keys to prevent typing letters
246+
const allowedKeys = ["Enter", "Backspace", "Escape", "=", "+", "-", "*", "/", "^", ".", "(", ")"];
247+
if (allowedKeys.includes(key) || /^[0-9]$/.test(key)) {
248+
e.preventDefault();
249+
} else {
250+
return;
235251
}
236-
else if(key===")" || key==="("){
237-
expression+=key;
238-
}
239-
else if(key==="^"){
240-
expression+="^";
241-
}
242-
else if(key==="Enter" || key==="="){
243-
expression=safeEval(expression);
244-
}
245-
else if(key==="Backspace"){
246-
expression=expression.slice(0,-1);
247-
}
248-
else if(key==="Escape" || key.toLowerCase()==="c"){
249-
expression="";
250-
}
251-
update();
252-
// if (!isNaN(e.key) || e.key === ".") expression += e.key;
253-
254-
// if (["+", "-", "*", "/"].includes(e.key)) expression += e.key;
255-
256-
// if (e.key === "^") expression += "^";
257-
258-
// if (e.key === "Enter") expression = safeEval(expression);
259252

260-
// if (e.key === "Backspace") expression = expression.slice(0, -1);
253+
clearIfFinished();
261254

255+
if (/^[0-9]$/.test(key)) {
256+
expression += key;
257+
} else if (key === ".") {
258+
const lastOperand = expression.split(/[\+\-\*\/\^\(\)]/).pop();
259+
if (!lastOperand.includes(".")) {
260+
expression += ".";
261+
}
262+
} else if (["+", "-", "*", "/", "^"].includes(key)) {
263+
const lastChar = expression.slice(-1);
264+
if (["+", "-", "*", "/", "^"].includes(lastChar)) {
265+
expression = expression.slice(0, -1) + key;
266+
} else {
267+
expression += key;
268+
}
269+
} else if (key === ")" || key === "(") {
270+
expression += key;
271+
} else if (key === "Enter" || key === "=") {
272+
expression = safeEval(expression);
273+
} else if (key === "Backspace") {
274+
if (expression === "Infinity" || expression === "-Infinity") {
275+
expression = "";
276+
} else {
277+
expression = expression.slice(0, -1);
278+
}
279+
} else if (key === "Escape" || key.toLowerCase() === "c") {
280+
expression = "";
281+
}
282+
update();
262283
});
263-
284+
264285
update();
265-
}
286+
}

0 commit comments

Comments
 (0)