Files
sless/examples/POSTGRES/code/calc-python/handler.py
T

121 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Создано: 2026-04-10
# Простой калькулятор — возвращает HTML страницу с кнопками.
# Роутинг: GET → HTML страница; POST с {a, op, b} → вычисление и редирект с результатом.
# _method приходит от python3.11 рантайма в event.
_HTML = """<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Калькулятор (Python)</title>
<style>
body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; background: #1a1a2e; }
.calc { background: #16213e; border-radius: 16px; padding: 24px; box-shadow: 0 8px 32px rgba(0,0,0,0.5); width: 280px; }
h2 { color: #e2e8f0; text-align: center; margin: 0 0 16px; font-size: 18px; }
.badge { text-align: center; font-size: 11px; color: #64748b; margin-bottom: 16px; }
.display { background: #0f172a; color: #f1f5f9; font-size: 28px; text-align: right; padding: 12px 16px; border-radius: 8px; margin-bottom: 16px; min-height: 52px; word-break: break-all; }
.result { color: #22d3ee; font-size: 20px; text-align: right; padding: 4px 16px; margin-bottom: 8px; min-height: 28px; }
.btns { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
button { border: none; border-radius: 8px; padding: 16px 0; font-size: 18px; cursor: pointer; transition: filter 0.1s; }
button:active { filter: brightness(1.3); }
.btn-num { background: #334155; color: #f1f5f9; }
.btn-op { background: #0891b2; color: #fff; }
.btn-eq { background: #0d9488; color: #fff; grid-column: span 2; }
.btn-clr { background: #7f1d1d; color: #fca5a5; grid-column: span 2; }
.btn-zero { grid-column: span 2; }
</style>
</head>
<body>
<div class="calc">
<h2>Калькулятор</h2>
<div class="badge">Python 3.11</div>
<div id="display" class="display">0</div>
<div id="result" class="result">{result_line}</div>
<div class="btns">
<button class="btn-clr btn-zero" onclick="clr()">C</button>
<button class="btn-op" onclick="setOp('%2F')">÷</button>
<button class="btn-op" onclick="setOp('*')">×</button>
<button class="btn-num" onclick="inp('7')">7</button>
<button class="btn-num" onclick="inp('8')">8</button>
<button class="btn-num" onclick="inp('9')">9</button>
<button class="btn-op" onclick="setOp('-')"></button>
<button class="btn-num" onclick="inp('4')">4</button>
<button class="btn-num" onclick="inp('5')">5</button>
<button class="btn-num" onclick="inp('6')">6</button>
<button class="btn-op" onclick="setOp('+')">+</button>
<button class="btn-num" onclick="inp('1')">1</button>
<button class="btn-num" onclick="inp('2')">2</button>
<button class="btn-num" onclick="inp('3')">3</button>
<button class="btn-num btn-zero" onclick="inp('0')">0</button>
<button class="btn-num" onclick="inp('.')">.</button>
<button class="btn-eq" onclick="calc()">=</button>
</div>
</div>
<script>
let a = '', op = '', b = '', fresh = {fresh_js};
const disp = document.getElementById('display');
function inp(v) {{
if (op === '') {{ a += v; disp.textContent = a || '0'; }}
else {{ b += v; disp.textContent = b || '0'; }}
fresh = false;
}}
function setOp(o) {{
if (a === '') return;
if (b !== '') calc();
else {{ op = o; disp.textContent = a + ' ' + decodeURIComponent(o) + ' …'; }}
fresh = false;
}}
function clr() {{ a = ''; op = ''; b = ''; disp.textContent = '0'; }}
function calc() {{
if (a === '' || op === '' || b === '') return;
const form = document.createElement('form');
form.method = 'POST'; form.action = '';
const fields = {{a, op, b}};
for (const [k, v] of Object.entries(fields)) {{
const i = document.createElement('input');
i.type = 'hidden'; i.name = k; i.value = decodeURIComponent(v);
form.appendChild(i);
}}
document.body.appendChild(form);
form.submit();
}}
</script>
</body>
</html>"""
def handler(event):
# POST: тело приходит как JSON от рантайма
if event.get('_method') == 'POST':
return _compute(event)
# GET: показываем чистую страницу
return _html()
def _html(result_line='', fresh_js='true'):
return _HTML.replace('{result_line}', result_line).replace('{fresh_js}', fresh_js)
def _compute(event):
try:
a = float(event.get('a', 0))
b = float(event.get('b', 0))
op = event.get('op', '')
if op == '+':
res = a + b
elif op == '-':
res = a - b
elif op == '*':
res = a * b
elif op == '/':
if b == 0:
return _html('Деление на ноль', 'false')
res = a / b
else:
return _html('Неизвестный оператор', 'false')
# Убираем лишний .0 для целых результатов
res_str = str(int(res)) if res == int(res) else str(res)
return _html(f'{int(a) if a == int(a) else a} {op} {int(b) if b == int(b) else b} = {res_str}', 'false')
except (ValueError, TypeError) as exc:
return _html(f'Ошибка: {exc}', 'false')