Numero dispari più grande
Chiedere all'utente di inserire 10 numeri interi e quindi stampare il numero dispari più grande immesso. Se non è stato inserito alcun numero dispari, stampare un messaggio in tal senso.
Ho cercato di risolvere questo problema con Python e penso di aver trovato un modo che copre tutti i casi possibili data la definizione matematica di un numero dispari. Per essere sicuro, vorrei controllare se il mio codice è corretto in base ai tuoi criteri.
counter = 0
odd = []
while counter < 10:
x = int(input("Enter a number: "))
if abs(x)%2 != 0:
odd.append(x)
counter += 1
if len(odd) == 0:
print("No odd number was entered")
else:
print("The largest odd number is:", max(odd))
Risposte
Per il tuo programma attuale possiamo migliorare un paio di cose:
- Rinomina
odd
inodds
(poiché è alist
). - Utilizzare
not odds
invece dilen(odds) == 0
(vedere Come posso verificare se un elenco è vuoto? Per un motivo sul motivo per cui è preferibile). - Elimina
counter
. Dato che usiamo solocounter
nellawhile
condizione, possiamo effettivamente sostituire il tuttowhile
confor _ in range(10)
. - Segui PEP 8 . Ad esempio, utilizzando 4 spazi per ogni livello di rientro.
Tenendo conto di tutti questi cambiamenti, otteniamo:
odds = []
for _ in range(10):
x = int(input("Enter a number: "))
if abs(x) % 2 != 0:
odds.append(x)
if not odds:
print("No odd number was entered")
else:
print("The largest odd number is:", max(odds))
Ma possiamo anche migliorare l'efficienza di questo programma. In questo momento teniamo traccia di tutti i numeri dispari, prima di scegliere il massimo. Ciò significa che la complessità dello spazio è O (N). Possiamo cambiarlo in O (1) tenendo traccia del numero dispari più grande in questo modo:
max_odd = None
for _ in range(10):
x = int(input("Enter a number: "))
if abs(x) % 2 != 0:
max_odd = x if max_odd is None else max(max_odd, x)
if max_odd is None:
print("No odd number was entered")
else:
print("The largest odd number is: ", max_odd)
Si noti che usiamo None
per indicare che nessun numero dispari è stato inserito fino ad ora, in questo caso su un numero dispari di essere entrati abbiamo impostato max_odd
a x
direttamente. Altrimenti, ci mettiamo max_odd
a max(max_odd, x)
.
Per questo tipo di programma non si noterà l'aumento di efficienza dovuto alla riduzione della complessità dello spazio. Ma imparare a riconoscere dove sono possibili queste riduzioni ti permetterà di vedere gli stessi schemi nei programmi in cui è importante.
C'è finalmente un'altra cosa che puoi fare. Se vuoi consentire al programma di continuare ad accumulare numeri nel caso in cui str
venga accidentalmente digitato un che non può essere analizzato come un numero (come ""
), possiamo usare un try
/ except
avvolto in un while
modo simile:
while True:
try:
x = int(input("Enter a number: "))
break
except ValueError:
continue
Questo sostituirebbe:
x = int(input("Enter a number: "))
nel codice originale. Ciò continuerebbe a chiedere all'utente di digitare un str
che è analizzabile int
fino a quando non lo fa. Poiché tutto questo accade nella stessa iterazione di for
, il conteggio dei numeri che arrivano a digitare (10 nel nostro caso) non verrebbe ridotto.
Aggiunta alla recensione precedente:
- Quando
x
è un numero intero,abs(x) % 2
è equivalente ax % 2
in Python. L'output dell'operatore modulo%
ha lo stesso segno del secondo operando. - Quando si esegue codice al di fuori di un metodo / classe, è buona norma inserire il codice all'interno di una guardia principale . Vedi qui per ulteriori spiegazioni.
In Python 3.8, il codice può essere abbreviato utilizzando l'operatore di assegnazione :=
insieme alla max
funzione.
if __name__ == "__main__":
# Number generator
num_gen = (o for _ in range(10) if (o := int(input("Enter a number: "))) % 2 != 0)
max_odd = max(num_gen, default=None)
if max_odd is None:
print("No odd number was entered")
else:
print(f"The largest odd number is: {max_odd}")
Il wrapping int(input("Enter a number: "))
in una funzione fornisce una migliore leggibilità:
def read_input() -> int:
return int(input("Enter a number: "))
if __name__ == "__main__":
num_gen = (o for _ in range(10) if (o := read_input()) % 2 != 0)
max_odd = max(num_gen, default=None)
if max_odd is None:
print("No odd number was entered")
else:
print(f"The largest odd number is: {max_odd}")
Un'altra variante che gestisce gli input degli utenti non validi è la seguente:
def read_input() -> int:
while True:
try:
return int(input("Enter a number: "))
except ValueError:
continue
if __name__ == "__main__":
try:
max_odd = max(o for _ in range(10) if (o := read_input()) % 2 != 0)
print(f"The largest odd number is: {max_odd}")
except ValueError:
# Since read_input() no longer raises ValueError, the except
# statement here only handles the cases where max() gets no inputs
print("No odd number was entered")
Posso chiederti quale linguaggio di programmazione praticavi prima di Python?
Voglio menzionare una battuta per questo:
max(l,key=lambda x:(x%2,x))
supponendo che tu abbia già in l
qualche modo inserito, come
s='Enter a number: '
l=[int(input(s)) for i in range(10)]
Come funziona il codice? Sembra per un massimo di key(x)
per x
in l
e restituisce tale x
. La chiave qui è la funzione lambda che restituisce tupla (1,x)
per dispari x
e (0,x)
pari x
. Le tuple vengono confrontate da sinistra a destra, ad esempio (1,x)>(0,y)
per ogni x
e y
. Quindi stiamo solo dicendo "dammi il massimo di l
, assumendo che un numero dispari sia sempre maggiore di un numero pari".
Quindi tutto il programma sarà simile
s='Enter a number: '
l=[int(input(s)) for i in range(10)]
m=max(l,key=lambda x:(x%2,x))
if m%2:
print('The largest odd number is: %d'%m)
else: #the greatest is even, therefore no odd numbers
print('No odd number was entered')
Breve, simpatico e facile, come il pitone.
Ma sono d'accordo sul fatto che un blocco di prova tranne che intorno int(input())
alla risposta accettata sia utile, insieme a non pre-memorizzare l'intero elenco di valori dispari.
Volevo solo dimostrare il paradigma della programmazione funzionale in python, quando dici a python "Voglio che sia fatto (ad esempio un valore massimo)" e lo fa per te, non hai bisogno di spiegare come dovrebbe farlo.
Grazie per aver letto.
Cercherò di basarmi sull'ultimo suggerimento della risposta accettata.
while True:
try:
x = int(input("Enter a number: "))
break
except ValueError:
continue
Approvo decisamente questo suggerimento, consente al tuo programma di gestire l'input non valido con grazia invece di bloccarsi.
Tuttavia, crea un problema di usabilità. L'utente che ha appena digitato una lettera in un numero probabilmente non l'ha notato. Penseranno di aver inserito il numero desiderato, procederanno con il successivo e poi si confonderanno alla fine, quando penseranno di aver inserito tutti i numeri, ma il computer sta ancora chiedendo il prossimo.
Meglio dare loro un feedback:
while True:
try:
x = int(input("Enter a number: "))
break
except ValueError:
print("Invalid number will be ignored.")
continue
... o ancora meglio, stampa loro il numero digitato:
while True:
try:
inputString = input("Enter a number: ")
x = int(inputString)
break
except ValueError:
print("Invalid number will be ignored: {}".format(inputString))
continue
Vorrei anche considerare di mantenere l'elenco completo dei numeri validi inseriti, non solo quelli dispari, e di stamparli tutti di nuovo all'utente prima del risultato, per dare loro un'ultima possibilità di individuare errori di battitura. Dopotutto, possono aver digitato male un numero valido ma non intenzionale. Si noti che ciò aumenterebbe l'utilizzo della memoria e alcuni lo considererebbero una comunicazione eccessiva.
print("Numbers provided are: {}".format(all_valid_numbers_inputted))
if not odds:
print("No odd number was entered")
else:
print("The largest odd number is:", max(odds))
Se lo fai, il passo successivo sarebbe quello di sbarazzarti della variabile "odds" e capire la quota più grande direttamente dall'elenco completo.
Il punto chiave qui: ogni fase del processo fa solo una semplice cosa. Crei i programmi in questo modo: un passaggio incrementale, strettamente definito alla volta. Non mescolare tutto in un guazzabuglio, ad esempio un ciclo in cui interagiamo con un utente mentre effettuiamo anche conversioni e calcoli necessari in seguito.
def as_int(s):
try:
return int(s)
except Exception:
return 0
N = 3
MSG = 'Enter number: '
replies = [input(MSG) for _ in range(N)] # Interact.
nums = [as_int(r) for r in replies] # Convert.
odds = [n for n in nums if n % 2] # Compute.
if odds: # Report.
print(max(odds))