Home > Back-end >  Python: Loop to check if an input is valid or not line by line
Python: Loop to check if an input is valid or not line by line

Time:10-24

Given the following inputs that simulates a grid with the respective dimensions:

totLines = int(input("Indicate the number os lines: "))
totColunms = int(input("Indicate the number of columns: "))

I want to check whether the input is valid or not (every digit must be between 0 and 20). The code should check each line of the grid and tell the user if the input is valid and if not ask for another input. The problem is that my code only checks the first digit of line1, the second digit of line2 and so own. For instance, in a 3x3 grid, if I input the following numbers for line1 (separated by spaces) - 21 10 10 - the code is gonna tell me that the input is not valid, but if I put the the incorrect digit in position 2 - 10 21 10 - the code is not gonna find any problem. I know the problem must be related with how I´m doing the loop but i can´t understand how to solve this. This is something easy to do but It´s my first time learning a programming language and I still have a lot to learn. Thanks!

for lin in range (1, totLines 1):
    print("Line", str(lin))
    while True:
        sMoves = input("Movement for this line: ")
        listMoves = sMoves.split()
        listMovesINT = list(map(int, listMoves))
        if listMovesINT[lin-1] > 0 and listMovesINT[lin-1] <= 20:
            break
        else:
            print ("Not a valid integer")
            continue

CodePudding user response:

I'd suggest putting the logic to get a valid list of moves in its own function, using all() to test all the values in the list (you don't need the current value of lin or anything else in the main loop to figure this out, and putting this task in its own function makes it easier to focus on it without accidentally mixing in other parts of your program):

def get_movement() -> list[int]:
    """Get a list of movement values between 1 and 20."""
    while True:
        try:
            moves = [int(n) for n in input("Movement for this line:").split()]
            if not all(1 <= n <= 20 for n in moves):
                raise ValueError("all values must be between 1 and 20")
            return moves
        except ValueError as e:
            print("Not a valid integer:", e)

and then in your main loop you can do:

for lin in range (1, totLines 1):
    print("Line", lin)
    moves = get_movement()
    # do whatever thing with moves

CodePudding user response:

As you noticed, you are "binding" the items in your input to your "board" (sort of the "board"... the totLines variable).

But you really just want to verify one input at a time, right? When the user writes the set of movements for any given line, it doesn't really matter whether it's for the first line of the "board" or for the last. Maybe you want the line index to display a nice prompt message, but that's about it. When it comes to ensuring that the input is valid, you really don't need the line for anything, isn't it?

So it all boils down to verifying that the inputs for any given line are valid, and keep pestering the user until they (all) are. Something like:

    valid_input = False
    while not valid_input:
        sMoves = input("Movement for this line: ")
        listMoves = sMoves.split()
        listMovesINT = list(map(int, listMoves))
        valid_input = all((0 < move <= 20) for move in listMovesINT)
        if not valid_input:
            print("One of the movements is not valid")

If you wanna use the number of total lines (totLines) to show a little bit more human-friendly prompt and then make the code a bit more like what you have it (with a for loop), you can just wrap the while not valid_input like this:

    totLines = int(input("Indicate the number os lines: "))
    for lineNum in range(1, totLines   1):
        valid_input = False
        while not valid_input:
            sMoves = input(f"Movement for line {lineNum}: ")
            listMoves = sMoves.split()
            listMovesINT = list(map(int, listMoves))
            valid_input = all((0 < move <= 20) for move in listMovesINT)
            if not valid_input:
                print("One of the movements is not valid")

CodePudding user response:

First, your code only check one integer per line.
You have an index but it is a line index (lin-1), not a number index.
Was the "while True" supposed to iterate over numbers. If yes, it should be after the "split()".

Here's a working example:

matrix = []
totlines=3
for i in range( totlines):
  line = input( "... ")
  numbers = [ int( text) for text in line.split()] # convert list of asciiNumbers to list of 3 integers
  for number in numbers:
    if (number <= 0) or (number>20):
      print( "Invalid number in line", i, ":", numbers)
  matrix.append( numbers)

print( matrix) 
  • Related