-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
99 lines (85 loc) · 2.93 KB
/
Copy pathscript.js
File metadata and controls
99 lines (85 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
const expressionDisplay = document.querySelector('#expression');
const resultDisplay = document.querySelector('#result');
const keys = document.querySelectorAll('.key');
let expression = '';
let justCalculated = false;
function formatResult(value) {
if (!Number.isFinite(value)) return 'Error';
return Number.isInteger(value) ? String(value) : String(Number(value.toFixed(10)));
}
function evaluate(currentExpression) {
const normalized = currentExpression.replace(/%/g, '/100').replace(/\^/g, '**');
if (!normalized || !/^[0-9+\-*/%.()\s]+$/.test(normalized.replace(/\*\*/g, ''))) return null;
try {
const value = Function(`"use strict"; return (${normalized})`)();
return typeof value === 'number' && Number.isFinite(value) ? value : null;
} catch {
return null;
}
}
function updateDisplay() {
expressionDisplay.textContent = expression || '0';
const preview = evaluate(expression);
const looksComplete = /[0-9)%]$/.test(expression);
resultDisplay.textContent = preview === null ? (expression ? (looksComplete ? 'Error' : '...') : '0') : formatResult(preview);
}
function appendValue(value) {
if (justCalculated && /[0-9.]/.test(value)) expression = '';
justCalculated = false;
const lastCharacter = expression.at(-1);
if (/[+\-*/^]/.test(value) && /[+\-*/^]/.test(lastCharacter)) {
expression = expression.slice(0, -1);
}
if (value === '.' && (lastCharacter === '.' || /\.[0-9]*$/.test(expression.split(/[+\-*/^]/).at(-1)))) return;
expression += value;
updateDisplay();
}
function clearCalculator() {
expression = '';
justCalculated = false;
updateDisplay();
}
function deleteLast() {
expression = expression.slice(0, -1);
justCalculated = false;
updateDisplay();
}
function squareRoot() {
const value = evaluate(expression);
if (value === null || value < 0) {
resultDisplay.textContent = 'Error';
return;
}
expression = formatResult(Math.sqrt(value));
justCalculated = true;
updateDisplay();
}
function calculate() {
const value = evaluate(expression);
if (value === null) {
resultDisplay.textContent = expression ? 'Error' : '0';
return;
}
expression = formatResult(value);
justCalculated = true;
updateDisplay();
}
function handleInput(value, action) {
if (action === 'clear') clearCalculator();
else if (action === 'delete') deleteLast();
else if (action === 'equals') calculate();
else if (action === 'sqrt') squareRoot();
else appendValue(value);
}
keys.forEach((key) => {
key.addEventListener('click', () => handleInput(key.dataset.value, key.dataset.action));
});
document.addEventListener('keydown', (event) => {
const keyMap = { Enter: 'equals', '=': 'equals', Escape: 'clear', Backspace: 'delete', Delete: 'clear' };
const action = keyMap[event.key];
const value = /[0-9+\-*/%^().]/.test(event.key) ? event.key : undefined;
if (!action && value === undefined) return;
event.preventDefault();
handleInput(value, action);
});
updateDisplay();