4.8 KiB
4.8 KiB
Калькулятор (Python CLI)
Лёгкий интерактивный калькулятор на чистом Python — без внешних зависимостей.
Возможности
- Операции:
+ - * / //(целочисленное), скобки() - Приоритет операций (скобки меняют порядок)
- Унарный минус/плюс:
-5,+3 - Проценты:
50 %→0.5;7 % 3→1(бинарный остаток;%без правого операнда = процент) - Возведение в степень:
2 ** 10(правостороннее) - Экспоненциальная запись:
1e3,2.5E-4; разделители разрядов:1_000_000 - Константы:
pi,e,tau,inf(регистр не важен) - Функции:
sqrt,abs,exp,ln,log,log2,log10,round,floor,ceil,sin,cos,tan,asin,acos,atan(тригонометрия — в радианах) - Деление на ноль обрабатывается красиво (без падения с exception)
- Переменная
ans— последнее вычисление (можно подставить:ans + 4) - История вычислений и команды сессии (
help,vars,hist,reset) в интерактивном режиме - Форматирование результата: без артефактов float (
0.1 + 0.2→0.3) - Сообщения об ошибках с указанием позиции неверного символа
Структура
| Файл | Назначение |
|---|---|
calculator.py |
Публичный API (parse_and_eval / try_evaluate) |
parser.py |
Токенизатор и синтаксический анализатор -> AST |
nodes.py |
Узлы AST + рекурсивный оценщик |
cli.py |
Интерактивная точка входа (REPL/пакетный режим) |
test_calculator.py |
Unit-тесты (pytest / unittest) |
pyproject.toml |
Пакет, entry point calc, конфиги ruff/mypy/coverage |
README.md |
Это |
Архитектура
Конвейер из трёх стадий: токенизация -> AST -> eval. Парсер строит
dерево узлов (NumNode, BinaryNode, PowNode, CallNode, IdNode, …),
оценщик Evaluator вычисляет его в словаре переменных env (в CLI там живёт
ans). Ошибки — одна иерархия ASTError (SyntaxError_,
DivisionByZeroError) из nodes.py, re-экспортируется через calculator.py.
Установка и запуск
pip install -e . # даёт команду calc
calc # REPL
calc "2 + 3" # пакетный режим
Или без установки: python cli.py.
Разработка
ruff check . # линтер (конфиг в pyproject.toml)
mypy calculator.py parser.py nodes.py cli.py
pytest --cov test_calculator.py
CI (Gitea Actions, .github/workflows/ci.yml): lint -> type-check -> test+coverage
на каждый push/PR в master.
Запуск
Калькулятор работает на Python 3.10+ (без установки пакетов).
Интерактивный режим
python cli.py
После запуска вводите выражение, построчно:
$ python cli.py
Калькулятор. Введите выражение, 'выход'/'exit' — для завершения.
2 + 3 * (4 - 1) % 100
6
выход
Пока!
Пакетный режим (аргументы строки выражений)
python cli.py "2 + 2" "(2 + 3) * 4" "1 / 0" "2 ** 10"
4
20
Ошибка: Деление на ноль
1024
Выход из цикла
выход или exit (регистронезависимо, допускаются пробелы вокруг).
Тесты
# через pytest (рекомендуется)
python -m pytest test_calculator.py -v
# через stdlib unittest
python -m unittest test_calculator -v
Тесты покрывают:
- базовые операции и отрицательные числа;
- приоритет операций и скобки (в т.ч. вложенные);
- проценты;
- деление на ноль (raise + сообщение);
- синтаксические ошибки;
- правоассоциативность степени;
- команды выхода.