mrman3
mrman3

Reputation: 23

for loop not functioning correctly?

I've gotten into python very recently and I've been experiencing this strange bug on a program I've been writing in my own time.

the program makes a grid of letters in accordance to a list called all_object_info, where it stores more lists telling a function named make_line() what to do. these sublists contain 3 entries: the first index is for the x value, the second for the y, and the third for what letter is to be put by make_line()

the "make_line()" function takes an argument for what y value it is for, then it cycles through the amount of x values as defined by num_of_xrows adding an empty (also defined by variable) letter to a line variable if there are no objects with the same x and y values that it is currently on, and adding the third index of the object if the values do match up.

the issue I've ran into is that the for in the function for what ever reason skips over and ends up placing an empty where there is meant to be a object, this only seems to happen when two objects are side-by-side of one another where the one to the right is not "rendered".

thus:

empty = "░"
num_of_yrows = 10
num_of_xrows = 10

all_object_info = [[2,2,"B"],[1,2,"B"]]


def make_line(row):
    x=0
    y=row
    line=""

    while x <= num_of_xrows:
        for obj in all_object_info:
            if x == obj[0] and row == obj[1]:
                line += obj[2]
                x += 1
        if x <= num_of_xrows:
            line += empty
            x += 1
    return line


def make_grid():
    grid = ""
    num = 0
    while  num <= num_of_yrows:
        grid += make_line(num)+"\n"
        num += 1
    print(grid)

make_grid()

would produce:

░░░░░░░░░░░
░░░░░░░░░░░
░B░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░

when it is meant to produce:

░░░░░░░░░░░
░░░░░░░░░░░
░BB░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░

strangely, switching the values in all_object_info to: [[1,2,"B"],[2,2,"B"]] from [[2,2,"B"],[1,2,"B"]] makes it produce the desired outcome:

░░░░░░░░░░░
░░░░░░░░░░░
░BB░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░
░░░░░░░░░░░

I'm pretty certain that the only thing wrong with the program is with the make_line() function, as I've gone over it countless times with a python visualizer to see that the for loop was skipping over when it was not meant to

Upvotes: 2

Views: 89

Answers (2)

Zhubei Federer
Zhubei Federer

Reputation: 1268

You will skip x when you do x += 1 twice in a for-loop. Maybe you can try this:

def make_line(row):
    x=0
    line=""
    while x <= num_of_xrows:
        is_found =False
        for obj in all_object_info:
            if x == obj[0] and row == obj[1]:
                line += obj[2]
                is_found = True
        if not is_found:
            line += empty
        x += 1
    return line

Upvotes: 3

Daniel Walker
Daniel Walker

Reputation: 6772

In make_line, you could potentially increase x by 2 in a single iteration of the while loop.

That is, look at what happens when x is 1. You'll add a 'B' to line and then increase x to 2. Since the elements of all_object_info are out of order, you won't check against the other object again this iteration.

After that, you compare x to num_of_xrows which is 10. Since x is 2, the if block is executed, an empty is added to line, and x is increased to 3.

You therefore skip over the 'B' which is supposed to be added when x is 2.

Instead, try this:

def make_line(row):
    x=0
    y=row
    line=""

    while x <= num_of_xrows:
        for obj in all_object_info:
            if x == obj[0] and row == obj[1]:
                line += obj[2]
                break
        else: # That is, if we didn't hit a break.
            if x <= num_of_xrows:
                line += empty
        x += 1
    return line

Upvotes: 3

Related Questions