Разработка калькулятора на Python: от консоли до графического интерфейса

Раздел: Разработка на Python -> Создание приложений

Создание калькулятора на Python: основные подходы

Как сделать надежный консольный калькулятор с обработкой ошибок и бесконечным циклом?

Эффективное решение для терминала включает проверку ввода, обработку деления на ноль и цикл while True для повторных операций. Пример кода:


def calculator():
    print('Доступные операции: +, -, *, /, %')
    print('Для выхода введите exit')
    while True:
        op = input('Введите оператор (+, -, *, /, %) или exit: ')
        if op.lower() == 'exit':
            break
        if op not in ('+', '-', '*', '/', '%'):
            print('Неверный оператор')
            continue
        try:
            a = float(input('Первое число: '))
            b = float(input('Второе число: '))
        except ValueError:
            print('Ошибка: введите числовое значение')
            continue
        if op == '+':
            result = a + b
        elif op == '-':
            result = a - b
        elif op == '*':
            result = a * b
        elif op == '%':
            result = a % b
        else:
            if b == 0:
                print('Ошибка: деление на ноль')
                continue
            result = a / b
        print(f'Результат: {result}')

Python application py (создание приложения python)

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

  • Ошибка ValueError при вводе текста вместо числа – решается блоком try/except с повторным запросом.
  • Деление на ноль – проверка b == 0 перед операцией.
  • Неверный оператор – проверка на допустимые символы.

Как реализовать калькулятор с графическим интерфейсом на Tkinter?

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


import tkinter as tk

def click(btn):
    current = entry.get()
    if btn == '=':
        try:
            result = eval(current)
            entry.delete(0, tk.END)
            entry.insert(tk.END, str(result))
        except:
            entry.delete(0, tk.END)
            entry.insert(tk.END, 'Ошибка')
    elif btn == 'C':
        entry.delete(0, tk.END)
    else:
        entry.insert(tk.END, btn)

root = tk.Tk()
root.title('Калькулятор')
entry = tk.Entry(root, width=20, font=('Arial', 16))
entry.grid(row=0, column=0, columnspan=4)
buttons = [
    '7','8','9','/',
    '4','5','6','*',
    '1','2','3','-',
    '0','.','=','+',
    'C'
]
row_val = 1
col_val = 0
for btn in buttons:
    action = lambda x=btn: click(x)
    tk.Button(root, text=btn, command=action, width=5).grid(row=row_val, column=col_val)
    col_val += 1
    if col_val > 3:
        col_val = 0
        row_val += 1
root.mainloop()
  

создание игр на языке python (создание игр на python (pygame и др.))

Проблемы и решения:

  • Использование eval небезопасно – для учебного примера допустимо, но в реальном проекте стоит заменить на парсер (см. вариант с ast.literal_eval).
  • Неверное размещение кнопок – используйте grid() с правильными индексами.

Как сделать веб-калькулятор на Flask?

Веб-версия позволяет взаимодействовать через браузер. Пример приложения Flask с двумя маршрутами:


from flask import Flask, render_template_string, request

app = Flask(__name__)

html_template = '''
<form method="post">
  <input type="number" name="num1" step="any" placeholder="Число 1">
  <select name="op">
    <option value="+">+</option>
    <option value="-">-</option>
    <option value="*">*</option>
    <option value="/">/</option>
  </select>
  <input type="number" name="num2" step="any" placeholder="Число 2">
  <button type="submit">Вычислить</button>
</form>
{% if result is defined %}
  <p>Результат: {{ result }}</p>
{% endif %}
'''

@app.route('/', methods=['GET', 'POST'])
def index():
    result = None
    if request.method == 'POST':
        try:
            a = float(request.form['num1'])
            b = float(request.form['num2'])
            op = request.form['op']
            if op == '+':
                result = a + b
            elif op == '-':
                result = a - b
            elif op == '*':
                result = a * b
            elif op == '/':
                if b == 0:
                    result = 'Ошибка: деление на ноль'
                else:
                    result = a / b
        except ValueError:
            result = 'Некорректный ввод'
    return render_template_string(html_template, result=result)

if __name__ == '__main__':
    app.run(debug=True)
  

как сделать калькулятор в python (создание калькулятора на python)

Проблемы и решения:

  • Безопасность вычислений – избегайте eval; используйте явные операции.
  • Обработка дробных чисел – укажите step="any" для вещественных чисел.
Как использовать библиотеку sympy для символьных вычислений в калькуляторе?

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


from sympy import sympify, SympifyError

def calc_sym():
    expr = input('Введите выражение (например, x**2 + 1): ')
    try:
        parsed = sympify(expr)
        print('Результат:', parsed)
    except SympifyError as e:
        print('Ошибка в выражении:', e)

calc_sym()
  

Проблемы и решения:

  • Сложность синтаксиса sympy – пользователь должен знать особенности записи (например, степень через **).
  • Необходимость установки – pip install sympy.

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

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

Расширение консольного калькулятора, где каждая операция сохраняется в список и выводится по запросу:

Пример

class CalcHistory:
    def __init__(self):
        self.history = []

    def operate(self, a, b, op):
        if op == '+':
            res = a + b
        elif op == '-':
            res = a - b
        elif op == '*':
            res = a * b
        elif op == '/':
            if b == 0:
                return 'Ошибка'
            res = a / b
        else:
            return 'Неизвестная операция'
        self.history.append(f'{a} {op} {b} = {res}')
        return res

    def show_history(self):
        for item in self.history:
            print(item)

c = CalcHistory()
c.operate(10, 5, '+')
c.operate(8, 2, '*')
c.show_history()
10 + 5 = 15
8 * 2 = 16

Как создать калькулятор с поддержкой приоритетов операций и скобок без eval?

Используется алгоритм сортировочной станции (Shunting-yard) для преобразования в ОПЗ и последующего вычисления:

Пример

def infix_to_postfix(expression):
    precedence = {'+':1, '-':1, '*':2, '/':2, '^':3}
    output = []
    stack = []
    for token in expression.replace(' ', ''):
        if token.isdigit() or token == '.':
            output.append(token)
        elif token in precedence:
            while stack and stack[-1] != '(' and precedence.get(stack[-1],0) >= precedence[token]:
                output.append(stack.pop())
            stack.append(token)
        elif token == '(':
            stack.append(token)
        elif token == ')':
            while stack and stack[-1] != '(':
                output.append(stack.pop())
            stack.pop()
    while stack:
        output.append(stack.pop())
    return ' '.join(output)

def eval_postfix(expr):
    stack = []
    for token in expr.split():
        if token.replace('.','').isdigit():
            stack.append(float(token))
        else:
            b = stack.pop()
            a = stack.pop()
            if token == '+':
                stack.append(a+b)
            elif token == '-':
                stack.append(a-b)
            elif token == '*':
                stack.append(a*b)
            elif token == '/':
                stack.append(a/b)
            elif token == '^':
                stack.append(a**b)
    return stack[0]

print(eval_postfix(infix_to_postfix('(3+4)*5')))  # 35.0
35.0

Как реализовать безопасное вычисление введенного выражения через ast.literal_eval?

Для строк, содержащих числа и операторы, можно использовать модуль ast, но literal_eval не поддерживает операции. Вместо этого пишется собственный парсер или используется eval с ограничениями. Пример с ast – только для констант:

Пример

import ast
import operator

def safe_eval(expr):
    allowed_ops = {
        ast.Add: operator.add,
        ast.Sub: operator.sub,
        ast.Mult: operator.mul,
        ast.Div: operator.truediv,
        ast.Pow: operator.pow,
        ast.USub: operator.neg
    }
    def eval_node(node):
        if isinstance(node, ast.Num):
            return node.n
        elif isinstance(node, ast.BinOp):
            left = eval_node(node.left)
            right = eval_node(node.right)
            return allowed_ops[type(node.op)](left, right)
        elif isinstance(node, ast.UnaryOp):
            operand = eval_node(node.operand)
            return allowed_ops[type(node.op)](operand)
        else:
            raise ValueError('Unsupported node')
    tree = ast.parse(expr, mode='eval')
    return eval_node(tree.body)

print(safe_eval('3 + 4 * 2'))  # 11
11

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

Пример с использованием словаря для отображения выбора и lambda:

Пример

operations = {
    '1': ('Сложение', lambda a,b: a+b),
    '2': ('Вычитание', lambda a,b: a-b),
    '3': ('Умножение', lambda a,b: a*b),
    '4': ('Деление', lambda a,b: a/b if b!=0 else 'Ошибка')
}

while True:
    print('Меню калькулятора:')
    for key, (desc, _) in operations.items():
        print(f'{key}. {desc}')
    print('5. Выход')
    choice = input('Выберите пункт: ')
    if choice == '5':
        break
    if choice not in operations:
        print('Неверный выбор')
        continue
    try:
        a = float(input('Введите a: '))
        b = float(input('Введите b: '))
    except ValueError:
        print('Некорректные числа')
        continue
    func = operations[choice][1]
    result = func(a,b)
    print(f'Результат: {result}')

Создание калькулятора на Python - comments

En
как сделать калькулятор в python (python)