Калькулятор (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 + сообщение);
  • синтаксические ошибки;
  • правоассоциативность степени;
  • команды выхода.
S
Description
Self-hosted project
Readme
121 KiB
0 Stars 1 Watchers 0 Forks