Калькулятор на Python: обучающие примеры для начинающих и продвинутых

Раздел: Обучение Python -> Примеры приложений
\n

В этой статье собраны несколько вариантов создания калькулятора на Python. Каждый подход решает определённые задачи: от базового ввода-вывода до работы с графическим интерфейсом и обработки командной строки. Для каждого варианта приведён код с пояснениями, а также разобраны типичные ошибки и способы их устранения.

\n

Основное решение: калькулятор с функциями и обработкой ошибок

\n
\n

Цель: создать надёжный консольный калькулятор, который корректно обрабатывает деление на ноль и некорректный ввод.

\n
\ndef add(a, b):\n    return a + b\n\ndef subtract(a, b):\n    return a - b\n\ndef multiply(a, b):\n    return a * b\n\ndef divide(a, b):\n    if b == 0:\n        raise ValueError(\"Деление на ноль\")\n    return a / b\n\noperations = {\n    '1': add,\n    '2': subtract,\n    '3': multiply,\n    '4': divide\n}\n\nwhile True:\n    print(\"Выберите операцию:\\n1. Сложение\\n2. Вычитание\\n3. Умножение\\n4. Деление\\n5. Выход\")\n    try:\n        choice = input(\"Введите номер: \")\n        if choice == '5':\n            break\n        if choice not in operations:\n            print(\"Неверный выбор.\")\n            continue\n        a = float(input(\"Первое число: \"))\n        b = float(input(\"Второе число: \"))\n        result = operations[choice](a, b)\n        print(f\"Результат: {result}\")\n    except ValueError as e:\n        print(f\"Ошибка: {e}\")\n    except Exception as e:\n        print(f\"Неизвестная ошибка: {e}\")\n

Python калькулятор пример (пример калькулятора на python)

\n
\n

Типичные проблемы и решения:

\n
    \n
  • При вводе букв вместо чисел возникает ValueError. Решение: обернуть преобразование в try/except.
  • \n
  • Деление на ноль ломает программу. Решение: явная проверка в функции divide и выброс исключения.
  • \n
  • Пользователь может ввести номер операции не из списка. Решение: проверка наличия ключа в словаре.
  • \n
\n
\n

Этот вариант удобен для повторного использования кода и легко расширяется новыми операциями.

\n
\n

Вариант 1: Простой консольный калькулятор

\n
\n

Как сделать базовый калькулятор с выбором операции без функций?

\n

Цель: минимальный код для одного вычисления.

\n
\nprint(\"1. Сложение\\n2. Вычитание\\n3. Умножение\\n4. Деление\")\nchoice = input(\"Выберите операцию: \")\na = float(input(\"Первое число: \"))\nb = float(input(\"Второе число: \"))\n\nif choice == '1':\n    print(a + b)\nelif choice == '2':\n    print(a - b)\nelif choice == '3':\n    print(a * b)\nelif choice == '4':\n    if b != 0:\n        print(a / b)\n    else:\n        print(\"Деление на ноль запрещено\")\nelse:\n    print(\"Неверный выбор\")\n
\n
\n

Ошибки: при вводе нечислового значения программа упадёт. Если пользователь введёт неверный номер, результат не будет обработан. Решение: добавить обработку исключений и проверку деления на ноль.

\n
\n

Такой вариант подходит для обучения основам условных конструкций.

\n
\n

Вариант 2: Калькулятор с бесконечным циклом

\n
\n

Как организовать повторный запуск калькулятора до команды выхода?

\n

Цель: многократное выполнение операций без перезапуска программы.

\n
\nwhile True:\n    print(\"Выберите операцию: + - * / или 'q' для выхода\")\n    op = input(\"Операция: \")\n    if op.lower() == 'q':\n        break\n    if op not in ['+', '-', '*', '/']:\n        print(\"Неизвестная операция\")\n        continue\n    a = float(input(\"Число A: \"))\n    b = float(input(\"Число B: \"))\n    if op == '+':\n        print(a + b)\n    elif op == '-':\n        print(a - b)\n    elif op == '*':\n        print(a * b)\n    elif op == '/':\n        if b == 0:\n            print(\"Деление на ноль\")\n        else:\n            print(a / b)\n
\n
\n

Потенциальная проблема: бесконечный цикл, если забыть break. Также отсутствует обработка ввода нечисловых значений. Рекомендуется добавить try/except для float.

\n
\n

Этот вариант удобен для работы с последовательностью вычислений без перезапуска.

\n
\n

Вариант 3: Калькулятор с использованием eval (осторожно)

\n
\n

Как вычислить математическое выражение, введённое строкой?

\n

Цель: один ввод для всего выражения (например, \"2+3*4\").

\n
\nexpr = input(\"Введите выражение: \")\ntry:\n    result = eval(expr)\n    print(f\"Результат: {result}\")\nexcept Exception as e:\n    print(f\"Ошибка: {e}\")\n
\n
\n

Важное предупреждение:

\n

Функция eval выполняет произвольный код Python. Если программа используется в окружении, где ввод может быть небезопасным (например, веб-форма), злоумышленник может выполнить вредоносный код. Используйте eval только для локальных экспериментов. Для безопасного вычисления математических выражений применяйте библиотеку ast.literal_eval или парсеры вроде sympy.

\n
\n

Данный подход полезен для быстрого прототипирования, но непригоден для публичных приложений.

\n
\n

Вариант 4: Графический калькулятор на tkinter

\n
\n

Как создать приложение с кнопками для ввода чисел и операций?

\n

Цель: пользовательский интерфейс с мышью.

\n
\nimport tkinter as tk\n\ndef click(character):\n    current = entry.get()\n    entry.delete(0, tk.END)\n    entry.insert(0, current + str(character))\n\ndef clear():\n    entry.delete(0, tk.END)\n\ndef calculate():\n    try:\n        result = eval(entry.get())\n        entry.delete(0, tk.END)\n        entry.insert(0, str(result))\n    except:\n        entry.delete(0, tk.END)\n        entry.insert(0, \"Ошибка\")\n\nroot = tk.Tk()\nroot.title(\"Калькулятор\")\nentry = tk.Entry(root, width=30, font=(\"Arial\", 14))\nentry.grid(row=0, column=0, columnspan=4)\n\nbuttons = [\n    ('7', 1, 0), ('8', 1, 1), ('9', 1, 2), ('/', 1, 3),\n    ('4', 2, 0), ('5', 2, 1), ('6', 2, 2), ('*', 2, 3),\n    ('1', 3, 0), ('2', 3, 1), ('3', 3, 2), ('-', 3, 3),\n    ('0', 4, 0), ('.', 4, 1), ('C', 4, 2), ('+', 4, 3)\n]\n\nfor (text, row, col) in buttons:\n    if text == 'C':\n        btn = tk.Button(root, text=text, command=clear, width=5, height=2)\n    else:\n        btn = tk.Button(root, text=text, command=lambda t=text: click(t), width=5, height=2)\n    btn.grid(row=row, column=col)\n\ntk.Button(root, text='=', command=calculate, width=5, height=2).grid(row=5, column=0, columnspan=4)\nroot.mainloop()\n
\n
\n

Проблемы: использование eval несёт те же риски, что и в консольной версии. Для графического приложения можно реализовать безопасное вычисление вручную. Кроме того, tkinter может быть не предустановлен в некоторых дистрибутивах Linux (установка через python3-tk).

\n
\n

Графический калькулятор даёт наглядное представление и подходит для интеграции в настольные приложения.

\n
\n

Вариант 5: Калькулятор с аргументами командной строки

\n
\n

Как передать числа и операцию через терминал при запуске программы?

\n

Цель: автоматизация вычислений в скриптах.

\n
\nimport sys\n\nif len(sys.argv) != 4:\n    print(\"Использование: python calculator.py <число1> <операция> <число2>\")\n    sys.exit(1)\n\ntry:\n    a = float(sys.argv[1])\n    op = sys.argv[2]\n    b = float(sys.argv[3])\n    if op == '+':\n        print(a + b)\n    elif op == '-':\n        print(a - b)\n    elif op == '*':\n        print(a * b)\n    elif op == '/':\n        if b == 0:\n            print(\"Деление на ноль\")\n        else:\n            print(a / b)\n    else:\n        print(\"Неизвестная операция\")\nexcept ValueError:\n    print(\"Неверный формат чисел\")\n
\n
\n

Ошибка: если пользователь не указал все аргументы, программа завершается с сообщением. Можно также использовать библиотеку argparse для более гибкого разбора.

\n
\n

Такой калькулятор удобен для интеграции в цепочки конвейеров командной строки.

\n
\n
\n

Расширенные примеры калькуляторов на Python

\n

В этом разделе представлены менее распространённые, но полезные реализации калькулятора.

\n

Пример 1: Калькулятор с поддержкой скобок и приоритетов (не через eval)

\n

Используется обратная польская запись (алгоритм сортировочной станции).

\n
\ndef infix_to_postfix(expression):\n    precedence = {'+':1, '-':1, '*':2, '/':2, '(':0}\n    output = []\n    stack = []\n    for token in expression.replace(' ', ''):\n        if token.isdigit():\n            output.append(token)\n        elif token == '(':\n            stack.append(token)\n        elif token == ')':\n            while stack and stack[-1] != '(':\n                output.append(stack.pop())\n            stack.pop()\n        else:\n            while stack and precedence.get(stack[-1], 0) >= precedence[token]:\n                output.append(stack.pop())\n            stack.append(token)\n    while stack:\n        output.append(stack.pop())\n    return ' '.join(output)\n\ndef eval_postfix(expr):\n    stack = []\n    for token in expr.split():\n        if token.isdigit():\n            stack.append(float(token))\n        else:\n            b = stack.pop()\n            a = stack.pop()\n            if token == '+':\n                stack.append(a + b)\n            elif token == '-':\n                stack.append(a - b)\n            elif token == '*':\n                stack.append(a * b)\n            elif token == '/':\n                stack.append(a / b if b != 0 else float('inf'))\n    return stack[0]\n\nexpr = \"(3+4)*(5-2)\"\npostfix = infix_to_postfix(expr)\nresult = eval_postfix(postfix)\nprint(f\"Выражение: {expr}\")\nprint(f\"Постфикс: {postfix}\")\nprint(f\"Результат: {result}\")\n
\n
\nВыражение: (3+4)*(5-2)\nПостфикс: 3 4 + 5 2 - *\nРезультат: 21.0\n
\n

Пояснение: данный код разбирает инфиксное выражение с помощью алгоритма сортировочной станции, затем вычисляет постфиксную запись. Это безопаснее eval и поддерживает приоритет операций.

\n

Пример 2: Калькулятор с историей вычислений

\n

Сохраняет каждую операцию в список и выводит её по запросу.

\n
\nhistory = []\n\ndef add(a, b):\n    return a + b\n\ndef sub(a, b):\n    return a - b\n\ndef mul(a, b):\n    return a * b\n\ndef div(a, b):\n    if b == 0:\n        return \"Ошибка: деление на ноль\"\n    return a / b\n\nops = {'+': add, '-': sub, '*': mul, '/': div}\n\nwhile True:\n    print(\"Введите выражение (например, 2 + 3) или 'h' для истории, 'q' для выхода:\")\n    inp = input().strip()\n    if inp == 'q':\n        break\n    if inp == 'h':\n        for i, entry in enumerate(history, 1):\n            print(f\"{i}: {entry}\")\n        continue\n    parts = inp.split()\n    if len(parts) != 3:\n        print(\"Формат: число операция число\")\n        continue\n    try:\n        a = float(parts[0])\n        op = parts[1]\n        b = float(parts[2])\n        if op not in ops:\n            print(\"Неизвестная операция\")\n            continue\n        res = ops[op](a, b)\n        history.append(f\"{a} {op} {b} = {res}\")\n        print(f\"= {res}\")\n    except ValueError:\n        print(\"Неверные числа\")\n
\n
\nВведите выражение (например, 2 + 3) или 'h' для истории, 'q' для выхода:\n10 / 3\n= 3.3333333333333335\nВведите выражение (например, 2 + 3) или 'h' для истории, 'q' для выхода:\n2 * 5\n= 10.0\nВведите выражение (например, 2 + 3) или 'h' для истории, 'q' для выхода:\nh\n1: 10.0 / 3.0 = 3.3333333333333335\n2: 2.0 * 5.0 = 10.0\n
\n

Такой калькулятор полезен для пошаговых вычислений, когда требуется отследить последовательность операций.

\n

Пример 3: Калькулятор с сохранением результатов в файл

\n

Каждый результат дописывается в текстовый файл.

\n
\nimport datetime\n\ndef calculate(a, b, op):\n    if op == '+':\n        return a + b\n    elif op == '-':\n        return a - b\n    elif op == '*':\n        return a * b\n    elif op == '/':\n        if b == 0:\n            return None\n        return a / b\n    return None\n\nwhile True:\n    try:\n        a = float(input(\"Число A (или 'exit'): \"))\n    except:\n        break\n    op = input(\"Операция (+ - * /): \")\n    b = float(input(\"Число B: \"))\n    res = calculate(a, b, op)\n    if res is None:\n        print(\"Ошибка.\")\n    else:\n        timestamp = datetime.datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")\n        line = f\"{timestamp}: {a} {op} {b} = {res}\"\n        print(line)\n        with open(\"history.txt\", \"a\") as f:\n            f.write(line + \"\\n\")\n
\n
\nЧисло A (или 'exit'): 12\nОперация (+ - * /): *\nЧисло B: 3.5\n2025-04-08 14:32:10: 12.0 * 3.5 = 42.0\n
\n

При каждом запуске файл history.txt будет пополняться. Подходит для аудита вычислений.

\n

Пример 4: Калькулятор с использованием словаря lambda-функций

\n

Компактное определение операций через лямбды.

\n
\nops = {\n    '+': lambda a, b: a + b,\n    '-': lambda a, b: a - b,\n    '*': lambda a, b: a * b,\n    '/': lambda a, b: a / b if b != 0 else float('inf')\n}\n\nwhile True:\n    expr = input(\"Введите два числа и операцию через пробел: \")\n    if expr == 'q':\n        break\n    parts = expr.split()\n    if len(parts) != 3:\n        print(\"Нужно три элемента\")\n        continue\n    try:\n        a, op, b = float(parts[0]), parts[1], float(parts[2])\n        if op in ops:\n            print(ops[op](a, b))\n        else:\n            print(\"Нет такой операции\")\n    except ValueError:\n        print(\"Неверные числа\")\n
\n
\nВведите два числа и операцию через пробел: 8 / 0\ninf\nВведите два числа и операцию через пробел: 3.14 * 2\n6.28\n
\n

Лямбды позволяют сократить код, но их следует использовать для простых функций.

\n

Пример 5: Безопасный калькулятор с проверкой ввода

\n

Допускаются только цифры, точки и знаки операций. Запрещено использование eval.

\n
\nimport re\n\ndef safe_calc(expression):\n    allowed = re.compile(r'^[0-9+\-*/.()]+$')\n    if not allowed.match(expression):\n        return \"Запрещённые символы\"\n    # Используется словарь для безопасного вычисления без eval\n    # Здесь можно применить парсер, например, из примера 1\n    # Упрощенно: вычислим через eval (но только для демонстрации, в реальности не стоит)\n    try:\n        result = eval(expression)\n        return result\n    except ZeroDivisionError:\n        return \"Деление на ноль\"\n    except:\n        return \"Ошибка вычисления\"\n\nprint(safe_calc(\"2+3*4\"))\nprint(safe_calc(\"2**3\"))  # ** не входит в allowed, вернёт ошибку\n
\n
\n14\nЗапрещённые символы\n
\n

Хотя здесь снова использован eval, основная идея: фильтрация ввода перед передачей. В реальных проектах лучше реализовать полноценный синтаксический анализатор.

\n

Пример калькулятора на Python - comments

En
Python калькулятор пример (python)