Сделать калькулятор на Python

Вот текст задачи:

Реализуйте простой калькулятор, который позволяет выполнять операции сложения, вычитания, умножения и деления двух целых чисел.

Калькулятор должен:

Запрашивать у пользователя выбор операции: сложение (1), вычитание (2), умножение (3), или деление (4). Запрашивать два числа для выполнения выбранной операции, каждое в новой строке. Выполнять выбранную операцию над этими числами. Выводить результат операции. Как только пользователь при выборе операции вводит 0, калькулятор завершает работу с текстом "Программа завершена."

Более того, калькулятор обрабатывает ошибки:

При выборе деления, если второе число будет 0, он выдаст ошибку "Делить на ноль нельзя!" При вводе неверной команды выдаст ошибку "Неверная команда!" При этом, после вывода ошибок программа продолжает работу, пока не получит команду 0.

это мое решение:

operatorr = int(input())

while operatorr != 0:
    n1 = int(input())
    n2 = int(input())

    if operatorr == 0:
        break
    if operatorr == 1:
        print(n1 + n2)
    elif operatorr == 2:
        print(n1 - n2)
    elif operatorr == 3:
        print(n1 * n2)
    elif operatorr == 4:
        if n2 == 0:
            print('Делить на ноль нельзя!')
        else:
            print(n1 // n2)
    else:
        print('Неверная команда!')
    operatorr = int(input())

print('Программа завершена.')

как можно сократить код? Только не нужно через всякие функции и так далее, на уровне именно цикла While, как тут можно покороче сделать, и есть ли какие то ошибки?


Ответы (4 шт):

Автор решения: Danila Kartovitskii

Чтобы упростить код и избежать повторений, можно упростить проверку оператора в цикле while и избежать лишних условий внутри цикла. Также можно убрать лишние input() и использовать только один input() для оператора и чисел.

    while True:
    operatorr = int(input("Введите оператор (0 для выхода): "))

    if operatorr == 0:
        break

    n1 = int(input("Введите первое число: "))
    n2 = int(input("Введите второе число: "))

    if operatorr == 1:
        print(n1 + n2)
    elif operatorr == 2:
        print(n1 - n2)
    elif operatorr == 3:
        print(n1 * n2)
    elif operatorr == 4:
        if n2 == 0:
            print('Делить на ноль нельзя!')
        else:
            print(n1 // n2)
    else:
        print('Неверная команда!')

print('Программа завершена.')
→ Ссылка
Автор решения: Nikita Silaev

Так как уже имеется упрощённый вариант решения данной задачи в ответе выше, могу предложить просто короткую реализацию с использованием словаря, при которой не потребуется повторять строку кода с вычислением для каждого нового выражения:

operator = int(input('Выберите действие: '))
actions = {
    1: '+',
    2: '-',
    3: '*',
    4: '/',
}

while operator != 0:
    if operator in actions.keys():
        n1 = int(input('Первое число: ')); n2 = int(input('Второе число: '))
        
        try:
            print(eval(f'{n1}{actions[operator]}{n2}'))
        except ZeroDivisionError:
            print('Делить на 0 нельзя!')

    else:
        print('Неверная команда!')

    operator = int(input('Выберите действие: '))

print('Программа завершена.')
→ Ссылка
Автор решения: Alexey Trukhanov

Я бы начал с того, чтобы внес первый инпут внутрь условия цикла и убрал бы сравнение, так как сам результат присвоения и будет либо 0 (False) либо не ноль и тогда цикл отработает. Это избавит нас от двух лишних инпутов и от проверки завершения программы по вводу ноля. Заменил бы If/elif на match/case для красоты и заменил бы проверку деления на ноль на однострочник.

Итого:

while operatorr := int(input()):
    n1 = int(input())
    n2 = int(input())

    match operatorr:
        case 1:
            print(n1 + n2)
        case 2:
            print(n1 - n2)
        case 3:
            print(n1 * n2)
        case 4:
            print(n1 // n2) if n2 != 0 else print('Делить на ноль нельзя!') 
        case _:
            print('Неверная команда!')

print('Программа завершена.')

Оставил без изменения целочисленное деление, хотя в постановке задачи об этом не было сказано и я бы поставил простое деление.

→ Ссылка
Автор решения: eri

match это не switch - это сопоставление по образцу. Можно обрабатывать всю команду.

while operator:=int(input()):
    match [operator, int(input()), int(input())]:
        case 1, n1, n2:
            print(n1 + n2)
        case 2, n1, n2:
            print(n1 - n2)
        case 3, n1, n2:
            print(n1 * n2)
        case 4, n1, 0:
            print("Делить на ноль нельзя")
        case 4, n1, n2:
            print(n1 // n2)
        # case 0, n1, n2:
        #     break
        case _:
            print("Неверная команда")

print("Программа завешена")
→ Ссылка