-2
votes

Comment puis-je limiter une entrée à une plage de nombres?

Je veux limiter l'entrée à une plage de nombres (disons n). Si j'utilise while x not in range(n): x = input() , cela ne fonctionne pas. Donc, je mets while x not in range(n): x = int(input()) . Cela fonctionne bien sauf si je donne des lettres. Après quelques recherches, j'ai trouvé le code suivant:

x = None
while True:
try:
    while x not in range(n+1):
        x = int(input("X (1 to "+ str(n)+ ") :"))
        if x not in range(n+1):
            print("please enter a valid input")
    break
except:
    print("please enter a valid input")

Je veux savoir s'il existe un moyen de raccourcir le code comme la fusion des deux boucles while and ou or .


1 commentaires

7 Réponses :


0
votes

Vous pouvez peut-être faire quelque chose comme ceci:

fun = lambda y, x: print('ok') if len(y) > x else print('please input a valid number')
while True: fun(input(), 5)

Le len() retournera la longueur de la chaîne renvoyée par input() .

Vous pouvez également le simplifier et le rendre plus dynamique avec un lambda:

while True:
    if len(input()) > 20:
        print('please input valid input')


0 commentaires

1
votes

Je suppose que vous voulez un nombre de 0 à n puisque vous avez utilisé la range(n+1) qui va de 0 à n . Si vous voulez des nombres de 1 à n , utilisez range(1, n+1)

x = 0
while True:
    try:
        x = int(input("Enter a number"))
    except:
        print("Please enter a valid input")

    if x not in range(n+1):
        print("Please enter a valid input")
    else:
        break


0 commentaires

2
votes

Edit Oublié ValueError . Il est ValueError attraper explicitement ValueError plutôt que Exception car Exception peut également intercepter d'autres choses.

Vous pouvez tester le code rapidement avec les fonctions de comparaison intégrées.

En prime, j'ai utilisé des f-strings qui peuvent être plus faciles à lire.

n = 1000  # Example number
x = None
while True:
    try:
        x = int(input(f"X (1 to {n}) :"))
    except ValueError:
        print(f"{x} is not a number, please enter a number")
    else:
        if 1 <= x <= n:  # Inclusive of 1 and n, edit the comparisons if needed
            break
        else:
            print(f"{x} is not within range, please enter a valid number")


1 commentaires

Comment ce code «ne soulèvera pas d'exception»? L'utilisateur entre tout ce qui ne peut pas être converti en entier et Python lèvera ValueError.



0
votes
X (1 to 3) :3
X (1 to 3) :4
please enter a valid input
X (1 to 3) :3
X (1 to 3) :2
X (1 to 3) :1
X (1 to 3) :6
please enter a valid input
X (1 to 3) :

0 commentaires

0
votes

Le code suivant réduit le nombre de boucles for à 1 et intercepte toutes les entrées non valides.

Please enter a valid input in the range of (1, 10): 11.0
Please enter a valid input in the range of (1, 10): 0.0
Please enter a valid input in the range of (1, 10): 5.0
Number in range -> 5

Sortie avec entrée et nombres entiers invalides:

Please enter a valid input in the range of (1, 10):  一二三
Please enter a valid input in the range of (1, 10): 1²
Please enter a valid input in the range of (1, 10): asd
Please enter a valid input in the range of (1, 10): word
Please enter a valid input in the range of (1, 10): a
Please enter a valid input in the range of (1, 10): 9
Number in range -> 9

Sortie avec des nombres à virgule flottante:

n = 10
x = n + 1 

while x not in range(1, n + 1): # The loop keeps going until x is in range.
    x = input('Please enter a valid input in the range of (1, '+ str(n) +'): ')
    try:
        x = int(float(x)) # e.g 5.0 string literal gets converted to 5.
    except ValueError:
        x = n + 1 # Re-initialize x to keep iterating, until we get a valid input.
    if x in range(1, n + 1):
        print('Number in range ->', x)


1 commentaires

Demander des commentaires à l'utilisateur et espérer obtenir des réponses qui ne soulèvent jamais d'exception? «1²». isnumeric () vaut True mais sa conversion en int lèvera ValueError. Ainsi que toute lettre ou flottant saisi par l'utilisateur. Si l'on est si sûr de l'exactitude de l'entrée de l'utilisateur, aucune validation n'est nécessaire - si demandé, l'utilisateur fournit toujours un entier dans la plage correcte.



1
votes

Vous pouvez l'implémenter avec une approche plus générique:

def get_valid_input(input_message, validator_fn=None):
    while True:
        try:
            i = input(input_message)
            if validator_fn is None or validator_fn(i):
                return i
        except:
            print("please enter a valid input")


x = get_valid_input('X (1 to ' + str(n) + ') :',
                    lambda i: x in range(n + 1))

Le get_valid_input validera l'entrée avant de la renvoyer, de cette façon, vous pouvez également utiliser la même méthode pour d'autres entrées.


0 commentaires

0
votes

Si vous souhaitez raccourcir le code, voici un extrait de code qui peut vous aider:

n = 10
x = None

while True:
    try:
        x = int(input(f"X (1 to {n}): "))

        if x not in range(n + 1):
            raise Exception("ERROR: Not in range")

        break  # If no errors are thrown, break from the loop

    except:
        print('Please enter a valid number')

...

Pour le décomposer, l'instruction x.isdigit() s'assurera que x compose uniquement d'entiers (un . Dans la chaîne le rendra False cependant). Si ce cas réussit, il analysera la chaîne en un entier en toute sécurité, puis vérifiera si elle est dans la plage. Le not s'assurera que si ces cas échouent, la boucle doit continuer.

Ancienne réponse

Vous pouvez utiliser un try..except bloc à l' intérieur d' un while en boucle comme ci - dessous. Si la valeur n'est pas un entier, une erreur sera levée dès que python essaiera de l'analyser et si la valeur n'est pas dans la plage, une erreur sera lancée dans l'instruction if qui seront toutes deux gérées par le try..catch bloc de try..catch . Si aucune exception n'est levée, l'instruction break s'exécutera et sortira de la boucle ...

x = ''
n = 10

while not (x.isdigit() and int(x) in range(1, n + 1)):
    x = input(f'X (1 to {n}): ')


0 commentaires