Calcolatrice Python di base

Oct 20 2020

Ho un mio giovane amico che sta iniziando a imparare Python a scuola e mi ha chiesto di dargli un piccolo incarico. Non sono in alcun modo un insegnante né un esperto di Python, ma ho accettato.

All'inizio ho pensato che sarebbe stato divertente iniziare con un po 'di analisi per l'input dell'operazione, come:

Enter your operation : 3+3

Ma sembrava un po 'opprimente per lui, quindi abbiamo deciso di separarlo in tre parti (primo numero, operando e secondo numero).

Ho fatto una piccola correzione ma lo trovo goffo e lo scopo dell'esercizio è mostrargli alcune buone pratiche.

Quindi ecco il mio codice:

calculate = True
while calculate:
    try:
        number1 = float(input("Enter the first number : "))
    except ValueError:
            print("Incorrect value")
            exit()
    symbol = input("Enter the operation symbol (+,-,/,*,%) : ")
    try:
        number2 = float(input("Enter the second number : "))
    except ValueError:
            print("Incorrect value")
            exit()
    operande = ["+", "-", "*", "/", "%"]
    resSentence = "Result of operation \"{} {} {}\" is :".format(number1, symbol, number2)
    if symbol not in operande:
        print("Incorrect symbol")
    elif symbol == "+":
        print(resSentence, number1 + number2)
    elif symbol == "-":
        print(resSentence, number1 - number2)
    elif symbol == "*":
        print(resSentence, number1 * number2)
    elif symbol == "/":
        print(resSentence, number1 / number2)
    elif symbol == "%":
        print(resSentence, number1 % number2)
    restart = input("Do you want to do another calcul (Y/n) ? ")
    while restart.lower() != "y" and restart.lower() != "n":
        print(restart.lower(), restart.lower(), restart.lower()=="n")
        restart = input("Please, enter \"y\" to continue or \"n\" to exit the program : ")
    if restart.lower() == "n":
        calculate = False

Avrei voluto fare un ciclo quando number1o number2non è valido floatfinché l'utente non immette un valore valido, ma non ho trovato un modo pulito per farlo. Accetterei volentieri consigli su questo (anche se so che questa non è una domanda per questo Stack Exchange, un buon modo Pythonic per farlo sarebbe fantastico :)).

Risposte

9 AryanParekh Oct 21 2020 at 04:59

Usa più funzioni

Hai una funzione calculate(), ma se vedi che fa molto di più che calcolare, questo fa sembrare il tuo codice irragionevolmente goffo. Ma c'è una soluzione molto semplice, usa più funzioni. E se il tuo ciclo principale potesse assomigliare

while True:
    number1,number2,operand = take_input()
    result = calculate(number1,number2,operand)
    print(f"Answer : {numebr1} {operand} {number2} = {result}")
    if input("Do you want to play again? (y/n): ").lower() == 'n':
        break 

Ciò semplifica la manutenzione del programma.

continue quando c'è un errore

try:
    number1 = float(input("Enter the first number : "))
except ValueError:
        print("Incorrect value")
        exit()

Chiediti, perché un programma dovrebbe terminare se l'utente immette un input non valido? Dagli un'altra possibilità xD

Mantieni un rientro coerente

try:
    number2 = float(input("Enter the second number : "))
except ValueError:
            print("Incorrect value")
            exit()

Cerca di mantenere un rientro coerente, dal momento che hai usato gli 4spazi in precedenza, non ci sono buoni motivi per usarli in 8seguito, potrebbe solo confondere le persone che leggono il codice in seguito.

Logica del codice 1

Consideriamo questo input di esempio

Enter the first number : 1
Enter the operation symbol (+,-,/,*,%) : I like python
Enter the second number : 2
Incorrect symbol

Chiaramente, symbolè sbagliato. Perché ho dovuto inserire il secondo numero, solo per scoprire di aver commesso un errore durante l'inserimento symbol? Avrebbe dovuto dirmi subito che il mio simbolo non era corretto, quindi avrei potuto correggerlo.

Basta spostare la if symbol not in operandsdichiarazione in modo che si trovi proprio accanto all'input.

eval

Eval in Python

Questo sarebbe il più grande miglioramento del tuo programma, poiché converte circa 10-15 righe di codice in una sola.

La eval()funzione valuta l'espressione specificata, se l'espressione è un'istruzione Python legale, verrà eseguita.

Sembra familiare, non stiamo sostanzialmente valutando espressioni semplici?

Usando eval, la tua parte di calcolo sarebbe simile

result = eval(f"{number1}{operand}{number2}")

Esempio, number1 = 5,number2 = 10, operand = '+'

Questo è ciò che sta sostanzialmente accadendo

result = eval("5+10")

Finale

Ecco il codice con i miglioramenti

def take_input():
    err_msg = "Invalid input"
    operands = ['+','-','*','/','%']
    try:
        num1 = float(input("Enter number 1: "))
    except Exception:
        print(err_msg)
        return take_input()
    try:
        num2 = float(input("Enter number 2: "))
    except Exception:
        print(err_msg)
        return take_input()

    print("Operands: " + ', '.join(x for x in operands))
    try:
        operand = input("Enter operand: ")
    except Exception:
        print(err_msg)
        return take_input()

    if operand not in operands:
        print(err_msg)
        return take_input()

    return num1,num2,operand

def calculate(num1,num2,operand):
    return eval(f"{num1}{operand}{num2}")


def mainloop():
    while True:
        num1,num2,operand = take_input()
        result = calculate(num1,num2,operand)
        print(f"Answer: {result}")
        if input("Do you want to play again? (y/n): ").lower() == 'n':
            break

mainloop()
5 Deep_Thoughts Oct 20 2020 at 21:54

Questa è un'alternativa al tuo codice, è un po 'più complesso ma è anche più leggibile. Sono riuscito a fare il loop ma è un po 'difficile da seguire. Scusate.

running = True
# Break Things up into functions each function does one single thing

def calculate(inputOne, operand, inputTwo):
    """
    Calculates inputOne operand and inputTwo
    """

    if operand == "+":
        return inputOne + inputTwo
    elif operand == "-":
        return inputOne - inputTwo
    elif operand == "*":
        return inputOne * inputTwo
    elif operand == "/":
        return inputOne / inputTwo
    elif operand == "%":
        return inputOne % inputTwo

def askInput():
    """
    Asks for a number until a number is given checks if each one is valid
    """

    isValid = [False, False, False] # none of the numbers are validated yet
    number1, symbol, number2 = ["", "", ""]
    
    # Here is a good implementation of the loop, it is kind of complex though
    while True:
        try:
            if not isValid[0]: # Asks for number1 if it is not valid
                number1 = int(input("Enter the first number : "))
                isValid[0] = True

            if not isValid[1]: # This is added functionality because there was a loophole in your program
                symbol = input("Enter the operation symbol (+,-,/,*,%) : ") # use tuples whenever possible
                supportedOperands = ("+", "-", "/", "*", "%")

                if symbol not in supportedOperands:
                    raise ValueError

                isValid[1] = True

            if not isValid[2]: # Asks for number2 if it is not valid
                number2 = int(input("Enter the second number : "))
                isValid[2] = True
            break
        
        except ValueError:
            continue # this just restarts the whole thing
    
    return number1, symbol, number2



def continueApp():
    """
    Checks if the input to restart is valid
    """
    restart = input("Do You want to do another calculation (Y/n) ? ").lower()

    while True:
        if restart == "y":
            return True
        elif restart == "n":
            return False
        else:
            restart = input("Please, enter \"y\" to continue or \"n\" to exit the program : ").lower()

while running:

    numberOne, operand, numberTwo = askInput()
    answer = calculate(numberOne, operand, numberTwo)
    resSentence = f"Result of operation {numberOne} {operand} {numberTwo} is : {answer}"
    print(resSentence)

    if continueApp():
        pass
    else:
        running = False
exit()


Suggerimenti:

  • Rompi le cose in funzioni:

Le funzioni sono solo contenitori di codice che può essere eseguito, le funzioni DEVONO fare UNA e solo UNA cosa in più sulle funzioni qui .

  • Prova a commentare il tuo codice, lo rende più facile da leggere e modificare.

Questa funzione

def calc():
    x = 1
    y = 12
    return (((x+y)/x)**y)+(3*x+4*y) # Please don't write like this in any case

sarebbe molto meglio con una spiegazione o cosa sta succedendo

def calc():
    """
    Accepts: Nothing
    Does: Adds X and Y, then divides it by X to the power of Y
          then it adds  it to X multiplied by three and 4 multiplied by Y
    Returns: integer (the result of Does) ^^^^^
    """
    x = 1
    y = 12
    return ((x+y)/x**y)+(3*x+4*y) # Again, please don't write code like this
  • Usa stringhe f (questo richiede python 3.6 e versioni successive)

le stringhe f vengono utilizzate in questo modo

value = "12"
print(f"Number {value} is an example of an f string") 

# Versus

print("Number {} is an example of an f string".format(value))
  • Prova a distanziare il codice

Credimi, questo rende il tuo codice più facile da leggere e capire.

def calc():
    """
    Accepts: Nothing
    Does: Adds X and Y, then divides it by X to the power of Y
          then it adds  it to X multiplied by three and 4 multiplied by Y
    Returns: integer (the result of Does) ^^^^^
    """
    x = 1
    y = 12
    ans = (x + y) / (x ** y)
    ans += (3 * x) + (4 * y) # just adds ans to the right side of the operator
    return ans