Le plus grand nombre impair
Demandez à l'utilisateur de saisir 10 entiers, puis d'imprimer le plus grand nombre impair entré. Si aucun nombre impair n'a été entré, imprimez un message à cet effet.
J'ai essayé de résoudre ce problème avec python et je pense avoir trouvé un moyen qui couvre tous les cas possibles étant donné la définition mathématique d'un nombre impair. Pour être sûr, je voudrais vérifier si mon code est correct compte tenu de vos propres critères.
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))
Réponses
Pour votre programme actuel, nous pouvons améliorer plusieurs choses:
- Renommez
odd
enodds
(puisqu'il s'agit d'unlist
). - Utilisez à la
not odds
place delen(odds) == 0
(voir Comment vérifier si une liste est vide? Pour une raison pour laquelle cela est préféré). - Supprimer
counter
. Puisque nous n'utilisons quecounter
dans lawhile
condition, nous pouvons en fait remplacer le toutwhile
parfor _ in range(10)
. - Suivez PEP 8 . Par exemple, en utilisant 4 espaces pour chaque niveau d'indentation.
En tenant compte de tous ces changements, nous obtenons:
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))
Mais nous pouvons également améliorer l'efficacité de ce programme. À l'heure actuelle, nous gardons une trace de tous les nombres impairs, avant de choisir le maximum. Cela signifie que la complexité spatiale est O (N). Nous pouvons changer cela en O (1) en gardant une trace du plus grand nombre impair comme ceci:
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)
Notez que nous utilisons None
pour signifier qu'aucun nombre impair a été saisi jusqu'à présent, dans ce cas , sur un nombre impair étant entré nous avons mis max_odd
à x
directement. Sinon, nous nous sommes mis max_odd
à max(max_odd, x)
.
Pour ce type de programme, vous ne remarquerez pas l'augmentation de l'efficacité due à la réduction de la complexité de l'espace. Mais apprendre à reconnaître où ces réductions sont possibles vous permettra de voir les mêmes modèles dans les programmes où cela compte.
Il y a enfin une chose que vous pouvez faire. Si vous voulez permettre au programme de continuer à accumuler des nombres dans le cas où un str
est accidentellement tapé qui ne peut pas être analysé comme un nombre (tel que ""
), nous pouvons utiliser un try
/ except
enveloppé dans un while
comme ceci:
while True:
try:
x = int(input("Enter a number: "))
break
except ValueError:
continue
Cela remplacerait:
x = int(input("Enter a number: "))
dans le code d'origine. Cela continuerait à inviter l'utilisateur à taper un str
qui est analysable comme un int
jusqu'à ce qu'il le fasse. Étant donné que tout se passe dans la même itération du for
, le nombre de nombres qu'ils peuvent saisir (10 dans notre cas) ne serait pas réduit.
Ajout à l'avis précédent:
- Quand
x
est un entier,abs(x) % 2
équivaut àx % 2
en Python. La sortie de l'opérateur modulo%
a le même signe que le deuxième opérande. - Lorsque vous exécutez du code en dehors d'une méthode / classe, il est recommandé de placer le code dans un garde principal . Voir ici pour plus d'explications.
Dans Python 3.8, le code peut être raccourci en utilisant l'opérateur d'affectation :=
avec la max
fonction.
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}")
L'emballage int(input("Enter a number: "))
dans une fonction offre une meilleure lisibilité:
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}")
Une autre variante qui gère les entrées utilisateur non valides est la suivante:
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")
Puis-je vous demander quel langage de programmation avez-vous pratiqué avant python?
Je veux mentionner un one-liner pour cela:
max(l,key=lambda x:(x%2,x))
en supposant que vous avez déjà l
entré d'une manière ou d'une autre, comme
s='Enter a number: '
l=[int(input(s)) for i in range(10)]
Comment fonctionne le code? Il cherche au maximum key(x)
pour x
en l
et retourne tel x
. La clé ici est la fonction lambda qui renvoie tuple (1,x)
pour impair x
et (0,x)
pour pair x
. Les tuples sont comparés de gauche à droite, par exemple (1,x)>(0,y)
pour chaque x
et y
. Donc nous disons simplement "donnez-moi le maximum de l
, en supposant qu'un nombre impair est toujours plus grand qu'un nombre pair".
Donc tout le programme ressemblera à
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')
Court, sympa et facile, comme python.
Mais je suis d'accord qu'un bloc try-except autour de int(input())
la réponse acceptée est utile, sans pré-stockage de la liste entière des valeurs impaires.
Je voulais seulement démontrer le paradigme de la programmation fonctionnelle en python, lorsque vous dites simplement à python «Je veux que cela soit fait (par exemple, une valeur maximale)» et qu'il le fait pour vous, vous n'avez pas besoin d'expliquer comment il doit le faire.
Merci d'avoir lu.
Je vais essayer de m'appuyer sur la dernière suggestion de la réponse acceptée.
while True:
try:
x = int(input("Enter a number: "))
break
except ValueError:
continue
J'approuve définitivement cette suggestion, elle permet à votre programme de gérer les entrées invalides avec élégance au lieu de simplement planter.
Cependant, cela crée un problème d'utilisabilité. L'utilisateur qui vient de taper une lettre dans un nombre ne l'a probablement pas remarqué. Ils penseront qu'ils ont obtenu le numéro prévu, passeront au suivant, puis seront confus à la fin, lorsqu'ils penseront avoir tous les chiffres, mais l'ordinateur demande toujours le suivant.
Mieux vaut leur donner un feedback:
while True:
try:
x = int(input("Enter a number: "))
break
except ValueError:
print("Invalid number will be ignored.")
continue
... ou encore mieux, imprimez leur numéro tapé sur eux:
while True:
try:
inputString = input("Enter a number: ")
x = int(inputString)
break
except ValueError:
print("Invalid number will be ignored: {}".format(inputString))
continue
J'envisagerais également de conserver la liste complète des numéros valides saisis, pas seulement les numéros impairs, et de les imprimer tous à l'utilisateur avant le résultat, pour lui donner une dernière chance de repérer les fautes de frappe. Ils peuvent, après tout, avoir mal saisi un numéro valide mais involontaire. Notez que cela augmenterait l'utilisation de la mémoire et que certains considéreraient cela comme une sur-communication.
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))
Si vous faites cela, la prochaine étape serait de vous débarrasser de la variable "odds" et de déterminer la plus grande cote directement à partir de la liste complète.
Le point clé ici: chaque étape du processus ne fait qu'une chose simple. Vous construisez des programmes de cette façon - une étape incrémentielle et étroitement définie à la fois. Ne mélangez pas tout dans un fouillis - par exemple une boucle où nous interagissons avec un utilisateur tout en effectuant les conversions et les calculs nécessaires plus tard.
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))