a bug in the range() function?

Asked

Viewed 94 times

0

I’ve been writing a function for a class that takes a dictionary and converts it into a string to represent a matrix.

def __str__(self):

    grid_str = ['' for _ in range(self.heigth)]

    for y in range(self.heigth):

        for x in range(self.heigth):

            grid_str[y] = grid_str[y] + self.st(self.grid[y, x])

    string = ""
    for line in grid_str:
        string = string + line + "\n"
    return string

But she makes the following mistake:

Traceback (most recent call last):
  File "C:/Users/Jean/Dropbox/game of life 2/core.py", line 51, in <module>
    print(g.__str__())
  File "C:/Users/Jean/Dropbox/game of life 2/core.py", line 41, in __str__
    grid_str[y] = grid_str[y] + self.st(self.grid[y, x])
KeyError: (10, 0)

So I decided to put a print call to debug.

def __str__(self):

    grid_str = ['' for _ in range(self.heigth)]

    for y in range(self.heigth):

        for x in range(self.heigth):

            print(x, ",", y)      #<<< chamada de print
            grid_str[y] = grid_str[y] + self.st(self.grid[y, x])

    string = ""
    for line in grid_str:
        string = string + line + "\n"
    return string

And the result was this:
0 , 0 1 , 0 2 , 0 3 , 0 4 , 0 5 , 0 6 , 0 7 , 0 ..., ... ..., ... 43 , 9 44 , 9 45 , 9 46 , 9 47 , 9 48 , 9 49 , 9 0 , 10 # <<< ??

Whereas it was a 10x50 matrix as well 0 , 10?
To my knowledge the range function starts counting from scratch and stops and does not return to zero, let alone complete with y = 10 in this case.
Well, if anyone knows what’s going on, I’d be grateful :) .

class grid:
    grid = {}
    width = 0
    heigth = 0

    def __init__(self, width, heigth):
        self.width = width
        self.heigth = heigth
        for x in range(width):
            for y in range(heigth):
                self.grid[x, y] = 0

    def set_region(self, replaceGrid, shift_X, shift_Y):
        for key, item in list(replaceGrid.items()):

            newkey = (key[0] + shift_X, key[1], shift_Y)
            self.grid[newkey] = item

    def rand_region(self, x1, y1, x2, y2, rate):
        from random import random
        for x in range(x1, x2):
            for y in range(y1, y2):
                if random() > rate:
                    v = 0
                else:
                    v = 1

                self.grid[x, y] = v

    st = str

    def __str__(self):

        grid_str = ['' for _ in range(self.heigth)]

        for y in range(self.heigth):

            for x in range(self.width):

                print(x, ",", y)
                grid_str[y] = grid_str[y] + self.st(self.grid[y, x])

        string = ""
        for line in grid_str:
            string = string + line + "\n"
        return string


if __name__ == "__main__":
    g = grid(10, 50)
    print(g.__str__())
  • 1

    in the internal cycle, for x in range(self.heigth): on this line will not be: for x in range(self.width):?

  • Yes, but the X and y axes are inverted when the print is called.

  • Wow, now I see, damn my dumb ass.

  • Actually, colleague @Miguel is right. Your code looks ok (tested on Ideone and I saw no problem beyond the fact that potentially your x loop is erroneously using height instead of width as the limit).

  • that strange, I changed the loop here and is still returning to zero.

  • Then prepare a [mcve] that reproduces the problem, so that we can test. As I said in my previous comment, I quickly tested your tie on Ideone and did not reproduce the problem you say occurs.

  • https://repl.it/FUKo/0, I did a small test and it did not return to 0. Can you post the code of the entire class and the call that is made? Or play there in the repl that is even easier to test.

  • of course, I thought the question would get too big, sorry I edited it with the full code.

  • @Luizvieira after all the mistake was not quite this, it was more a short-term memory lapse of colleague Jeacom :P , I answered below if you are curious

  • @Miguel Ok, now that AP edits the question including not only the relevant code but also the error message, it became clearer. I’ll withdraw my vote to close.

  • 1

    Tip: Python’s "range" function is No class and should be used every day by millions of developers. It’s a relatively simple function, which returns a not too complicated object - and people interested in understanding Python more deeply in general look at their source code. No, it doesn’t have a bug - if you think you have a bug in "range" or another very used function in Python, the error is in your code.

Show 6 more comments

1 answer

3


Now Jeacom, you had a subtle mistake, that’s how:

in this block where people self.grid in init:

for x in range(width):
    for y in range(heigth):
        self.grid[x, y] = 0

You’re so popular like this:

self.grid[x, y] = 0

in which the x is equivalent to a unit of width and y equivalent to a height unit, well, then when you’re trying to access the keys in this block you’re reversing, you’re trying to access the reverse order of the one you populated:

for y in range(self.heigth):
    for x in range(self.width):
        print(x, ",", y)
        grid_str[y] = grid_str[y] + self.st(self.grid[y, x])

Here x second element (which when we populated was the first) is a unit of width and the same goes for height:

That is, final correction:

...
for y in range(self.heigth):
    for x in range(self.width):
        print(x, ",", y)
        grid_str[y] = grid_str[y] + self.st(self.grid[x, y])
...

In the background it was only to reverse the order when you try to access the keys, it is:

self.grid[x, y]

Browser other questions tagged

You are not signed in. Login or sign up in order to post.