Calcolatrice Python di base
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
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()
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