Skip to content

Commit 303baed

Browse files
Add files via upload
1 parent 3e95d6c commit 303baed

24 files changed

+1562
-0
lines changed

Task4/Task1/doodles.jpg

327 KB
Loading

Task4/Task1/index.html

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width,initial-scale=1" />
6+
<title>OIBSIP - calculator</title>
7+
<link rel="stylesheet" href="style.css">
8+
</head>
9+
<body>
10+
<main class="page">
11+
<div class="calc" role="application" aria-label="Calculator">
12+
<div class="display" aria-live="polite">
13+
<div id="expr" class="expression" aria-hidden="true">0</div>
14+
<div id="out" class="output" aria-live="polite">0</div>
15+
</div>
16+
17+
<div class="pad" id="pad" role="grid" aria-label="Calculator keys">
18+
<!-- Row 1 -->
19+
<button data-action="percent" aria-label="percent">%</button>
20+
<button data-action="paren" data-value="(" aria-label="open parenthesis">(</button>
21+
<button data-action="paren" data-value=")" aria-label="close parenthesis">)</button>
22+
<button data-action="clear" class="ce" aria-label="clear entry">CE</button>
23+
24+
<!-- Row 2 -->
25+
<button data-value="7">7</button>
26+
<button data-value="8">8</button>
27+
<button data-value="9">9</button>
28+
<button data-action="op" data-value="/" aria-label="divide">÷</button>
29+
30+
<!-- Row 3 -->
31+
<button data-value="4">4</button>
32+
<button data-value="5">5</button>
33+
<button data-value="6">6</button>
34+
<button data-action="op" data-value="*" aria-label="multiply">×</button>
35+
36+
<!-- Row 4 -->
37+
<button data-value="1">1</button>
38+
<button data-value="2">2</button>
39+
<button data-value="3">3</button>
40+
<button data-action="minus" aria-label="subtract">-</button>
41+
42+
<!-- Row 5 -->
43+
<button data-action="sqrt" aria-label="plus minus or square root">±√</button>
44+
<button data-value="0">0</button>
45+
<button data-value=".">.</button>
46+
<button data-action="plus" class="op" aria-label="add">+</button>
47+
</div>
48+
49+
<div class="bottom-row" role="toolbar" aria-label="additional controls">
50+
<button data-action="del" aria-label="backspace" class="backspace"></button>
51+
<button class="enter" data-action="enter" aria-label="enter">=</button>
52+
</div>
53+
</div>
54+
</main>
55+
56+
<script src="script.js" defer></script>
57+
</body>
58+
</html>

Task4/Task1/script.js

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
const exprEl = document.getElementById('expr');
2+
const outEl = document.getElementById('out');
3+
let expression = '';
4+
let lastAns = '0';
5+
6+
const isOperator = ch => ['+', '-', '*', '/'].includes(ch);
7+
const lastChar = () => expression.slice(-1);
8+
9+
function render() {
10+
exprEl.textContent = expression || '0';
11+
outEl.textContent = preview(expression) || '0';
12+
}
13+
14+
function safeEval(src) {
15+
if (!src) return '0';
16+
let s = src.replace(/×/g, '*').replace(/÷/g, '/').replace(/ans/g, String(lastAns));
17+
s = s.replace(/\s+/g, '');
18+
if (!/^[0-9+\-*/().%]+$/.test(s)) throw new Error('Invalid characters');
19+
if (/[\+\-\*\/\.%]$/.test(s)) throw new Error('Trailing operator');
20+
s = s.replace(/(\d+(?:\.\d+)?)%/g, '($1/100)');
21+
return String(Function(`return (${s})`)());
22+
}
23+
24+
function preview(src) {
25+
try { return safeEval(src); } catch { return ''; }
26+
}
27+
28+
function add(token) {
29+
if (['+', '*', '/'].includes(token) && expression === '') return;
30+
if (isOperator(token) && isOperator(lastChar())) {
31+
expression = expression.slice(0, -1) + token;
32+
render();
33+
return;
34+
}
35+
expression += token;
36+
render();
37+
}
38+
39+
function doAction(action, value) {
40+
switch (action) {
41+
case 'clear':
42+
expression = '';
43+
break;
44+
case 'del':
45+
expression = expression.slice(0, -1);
46+
break;
47+
case 'ans':
48+
expression += 'ans';
49+
break;
50+
case 'enter':
51+
try {
52+
const res = safeEval(expression);
53+
lastAns = res;
54+
expression = String(res);
55+
} catch (e) {
56+
expression = 'ERR';
57+
render();
58+
setTimeout(() => { expression = ''; render(); }, 800);
59+
return;
60+
}
61+
break;
62+
case 'percent':
63+
expression = expression.replace(/(\d+(?:\.\d+)?)$/, m => m + '%');
64+
break;
65+
case 'sqrt':
66+
try {
67+
const v = Number(safeEval(expression));
68+
if (Number.isNaN(v)) throw new Error('Bad value');
69+
expression = String(Math.sqrt(v));
70+
} catch {
71+
expression = 'ERR';
72+
render();
73+
setTimeout(() => { expression = ''; render(); }, 800);
74+
return;
75+
}
76+
break;
77+
case 'op':
78+
add(value);
79+
break;
80+
case 'paren':
81+
add(value);
82+
break;
83+
case 'plus':
84+
add('+');
85+
break;
86+
case 'minus':
87+
add('-');
88+
break;
89+
default:
90+
break;
91+
}
92+
render();
93+
}
94+
document.addEventListener('click', (e) => {
95+
const btn = e.target.closest('button');
96+
if (!btn) return;
97+
const action = btn.dataset.action;
98+
const value = btn.dataset.value;
99+
if (action) doAction(action, value);
100+
else if (typeof value !== 'undefined') add(value);
101+
});
102+
window.addEventListener('keydown', (e) => {
103+
if (e.key >= '0' && e.key <= '9') add(e.key);
104+
else if (e.key === '.') add('.');
105+
else if (e.key === 'Backspace') doAction('del');
106+
else if (e.key === 'Enter' || e.key === '=') doAction('enter');
107+
else if (['+','-','*','/','(',')'].includes(e.key)) add(e.key);
108+
else if (e.key === '%') doAction('percent');
109+
});
110+
render();

Task4/Task1/style.css

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
*{
2+
box-sizing:border-box;
3+
}
4+
5+
body{
6+
height: 100%;
7+
width: 100%;
8+
background-image: url(doodles.jpg);
9+
background-position: center;
10+
background-size: cover;
11+
}
12+
13+
body{
14+
margin:0;
15+
font-family:Inter, system-ui, -apple-system, 'Segoe UI', Roboto, Arial;
16+
display:flex;
17+
align-items:center;
18+
justify-content:center;
19+
min-height:100vh;
20+
}
21+
22+
.calc{
23+
width:360px;
24+
background:rgba(255, 255, 255, 0.8);
25+
backdrop-filter: blur(1px);
26+
border: 2px solid black;
27+
border-radius:16px;
28+
padding:16px;
29+
box-shadow:0 8px 24px rgba(0,0,0,0.12);
30+
}
31+
32+
.display{
33+
background:#afafaf;
34+
padding:12px 14px;
35+
border-radius:10px;
36+
border: 0.5px solid;
37+
margin-bottom:12px;
38+
width: 100%;
39+
overflow: hidden;
40+
}
41+
42+
.expression,
43+
.output {
44+
white-space: nowrap;
45+
overflow: hidden;
46+
text-overflow: ellipsis;
47+
}
48+
49+
.expression{
50+
color:beige;
51+
font-size:13px;
52+
font-weight: bolder;
53+
}
54+
55+
.output{
56+
font-size:34px;
57+
font-weight:700;
58+
color:#131313;
59+
text-align:right;
60+
}
61+
62+
.pad{
63+
display:grid;
64+
grid-template-columns:repeat(4,1fr);
65+
gap:10px;
66+
}
67+
68+
button{
69+
padding:14px;
70+
border-radius:8px;
71+
border:0.5px solid ;
72+
background:linear-gradient(180deg,#525456,#afafaf);
73+
font-size:16px;
74+
font-weight:600;
75+
cursor:pointer;
76+
transition: transform 120ms ease, box-shadow 120ms ease, opacity 120ms;
77+
min-height:48px;
78+
}
79+
80+
button:hover{
81+
transform:translateY(-3px);
82+
box-shadow:0 8px 18px rgba(0,0,0,0.25);
83+
color: beige;
84+
}
85+
86+
button:active{
87+
transform:translateY(0);
88+
box-shadow:inset 0 3px 6px rgba(0,0,0,0.4);
89+
}
90+
91+
button:focus{
92+
outline:3px solid rgba(255,255,255,0.4);
93+
outline-offset:2px;
94+
}
95+
96+
button.enter{
97+
grid-column:4/5;
98+
background:linear-gradient(180deg,#525456,#717374);
99+
color:#fff;
100+
}
101+
102+
.bottom-row{
103+
display:flex;
104+
gap:8px;
105+
margin-top:10px;
106+
}
107+
108+
.bottom-row button{
109+
flex:1;
110+
padding:12px;
111+
}
112+
113+
.bottom-row {
114+
display:flex;
115+
gap:10px;
116+
margin-top:12px;
117+
justify-content:center;
118+
}
119+
120+
.bottom-row .backspace {
121+
min-width: 92px;
122+
min-height: 44px;
123+
border-radius: 8px;
124+
background: linear-gradient(180deg, #4b4b4b, #353535);
125+
color: #fff;
126+
font-weight: 700;
127+
}
128+
129+
.bottom-row .enter {
130+
min-width: 120px;
131+
min-height: 44px;
132+
border-radius: 8px;
133+
background: linear-gradient(180deg, #dfe9ef, #c6d7e1);
134+
color: #111;
135+
font-weight: 800;
136+
}
137+
138+
@media (max-width:420px){
139+
.calc{
140+
width:320px
141+
}
142+
143+
button{
144+
min-height:56px;
145+
}
146+
}

Task4/Task2/damsel.jpg

158 KB
Loading

Task4/Task2/enola.jpg

14 KB
Loading

Task4/Task2/enola2.jpg

12.2 KB
Loading

Task4/Task2/img.webp

54 KB
Loading

Task4/Task2/img1.avif

90.6 KB
Binary file not shown.

Task4/Task2/img2.webp

95.2 KB
Loading

0 commit comments

Comments
 (0)