улучшение моего простого калькулятора на Python

Sep 11 2020

Я новичок в python, и это мой самый первый проект, который я сделал сам. Мне интересно, могу ли я как-нибудь улучшить это или дать мне совет, как сделать это лучше. Спасибо

import sys
valid = ["+", "-", "*", "/"]
invalid = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
def start():
    while True:
        a = input("").lower()
        for banned in a:
            if banned in invalid:
                print("error")
            else:
                sum1 = int(a)
        cal = input("")
        b = input("").lower()
        for banned in b:
            if banned in invalid:
                print("Error")
                start()
            else:
                sum2 = int(b)
        break;
    for list in cal:
        if list in valid:
            if list == "+":
                total = sum1 + sum2
                print("=" + total)
            if list == "-":
                total = sum1 - sum2
                print(total)
                start()
            if list == "*":
                total = sum1 * sum2
                print(total)
                start()
            if list == "/":
                total = sum1 / sum2
                print(total)
                start()
        else:
            print("Wrong Format")
            start()
start()

Ответы

3 FMc Sep 11 2020 at 05:48

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

Как пользоваться этой программой ? Ваши input()звонки не говорят мне, что происходит. Помогите, пожалуйста.

Пользователи не любят утомительного взаимодействия с компьютером . Вы бы предпочли ввести число, нажать ввод, ввести оператор, нажать ввод, ввести число, нажать ввод ... ИЛИ просто ввести чертову формулу? Например:

reply = input('Enter equation: INT OP INT: ')

Пользователям действительно не нравится утомительное взаимодействие с компьютером . За редкими исключениями разумные программы командной строки вообще не используются input()- или, по крайней мере, не используются по умолчанию. Узнайте sys.argvи позвольте пользователям запускать ваш калькулятор напрямую, не заставляя их становиться лучшими друзьями со своим компьютером. Вот как может выглядеть использование командной строки:

$ python simple-calculator.py 32 + 10
42

Узнайте об обработке исключений . Вместо того, чтобы увязнуть в создании структуры данных, содержащей все возможные неправильные входные данные (что очень сложно, особенно если учесть все мыслимые входные данные UTF-8), просто попробуйте сделать то, что вы хотите сделать, - с защитной сеткой.

while True:
    try:
        # Each of these lines could fail. That's OK. Be optimistic!
        s1, op, s2 = reply.split()
        a = int(s1)
        b = int(s2)
        assert op in '+-*/'
        break                  # Success.
    except Exception as e:
        # The safety net.
        print('Invalid input')

Используйте структуры данных для упрощения логики . Разве не было бы круто избавиться от кучи if-elseчеков и вместо этого просто делать то, что вы хотите делать напрямую? В таких ситуациях часто может помочь структура данных. Нам нужен способ взять оператор, а затем использовать его для получения функции с двумя аргументами, которая будет выполнять необходимые математические вычисления. Другими словами, нам нужно отображение между операторами и соответствующими математическими функциями. Вот 3 способа добиться этого:

import operator

def add(a, b):
    return a + b

ops = {
    '+': add,                    # Define your own functions.
    '-': lambda a, b: a - b,     # Or lambdas.
    '*': operator.mul,           # Or get them from a library.
    '/': operator.truediv,
}

# With that data structure, our code would reduce to this.
answer = ops[op](a, b)     # Wrap in try-except to catch divide by 0.
print(answer)
1 user985366 Sep 11 2020 at 00:55

Предложение 1

Ваш список недопустимых символов и inпроверок будет работать так же хорошо, как и строка, но будет короче и удобнее для чтения.

invalid = 'abcdefghijklmnopqrstuvwxyz'

То же самое относится и к validмассиву символов.

Предложение 2

for banned in a:

banned- очень запутанное имя переменной для такого использования. Вы не узнаете, забанен ли он, пока не сравните его со invalidсписком персонажей. Вам лучше использовать characterили letterили более короткое базовое имя, например cили x.

Предложение 3

a = input("").lower()

aздесь тоже плохое имя, поскольку оно не говорит нам, что это такое. Скорее назовите это input1или что-то подобное, и, конечно, измените bна input2что-то другое, что является описательным.

Предложение 4

for list in cal:

listэто не просто плохо выбранное имя, которое вводит читателя в заблуждение, это также ключевое слово / функция в Python, и его не следует использовать в качестве имени переменной ни в какой ситуации. Я предлагаю operatorкак лучшее название, так как вы берете в расчет оператора.

Предложение 5

Вы звоните start()после каждой операции, кроме +. Это похоже на ошибку. Почему не за +?

Предложение 6

total = sum1 * sum2
print(total)

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

print(sum1 * sum2)