Jump to content
def on_grid(grid, r, c):    """     Given a grid and a coordinate, this function determines whether or not     the coordinate exists withing the grid    """        range_rows = 0    range_columns = 0        range_rows = range(len(grid))    range_columns = range(len(grid[0]))        if r in range_rows and c in range_columns:        return True    else:        return False        def count_neighbors(grid, r, c):    """     Given a Grid and two integers indicating a cell coordinate,     this function returns how many living neighbors there are.     """    live_count = 0        # This loop checks for living cells around cell in question.    for x in range(r - 1, r + 2):           for y in range(c - 1, c + 2):               if x == r and y == c:   # Skips cell in question                continue            if on_grid(grid, x, y) and grid[x][y] == True:                live_count += 1        return live_count    def next_gen(grid):    """     Give a Grid, this function creates a new Grid that     represents the next generations.    """    next_generation = grid        for x in range(len(grid)):        for y in range(len(grid[x])):            if count_neighbors(grid, x, y) == 2 or count_neighbors(grid, x, y) == 3:                next_generation[x][y] == grid[x][y]            elif grid[x][y] == True and (count_neighbors(grid, x, y) >= 4 or count_neighbors(grid, x, y) <= 1):                next_generation[x][y] == False            elif grid[x][y] == False and count_neighbors(grid, x, y) == 3:                next_generation[x][y] == True                return next_generation    next_gen([[False, True, False], [False, True, False], [False, True, False]])

This is a portion of conway's game of life. I cannot for the life of me figure out why this code doesn't work. The next_gen function returns the next generation of the grid. And I have no way of debugging this so I can't figure out what is wrong myself...Any help would be appreciated. Thank you!

Link to comment
https://linustechtips.com/topic/476035-python-please-help/
Share on other sites

Link to post
Share on other sites

Why don't you have a debugger? 

 

The problem (at least one of them) is that you're using == when you should be using =.

Wow....why didn't I see that....And my professor wants us writing in Notepad++ and I don't believe that it has one. The only alternative is the python visualizer, but it cuts out at 300 steps because it thinks it's an infinite loop.

Link to comment
https://linustechtips.com/topic/476035-python-please-help/#findComment-6379563
Share on other sites

Link to post
Share on other sites

Why don't you have a debugger? 

 

The problem (at least one of them) is that you're using == when you should be using =.

Do you happen to know what else is wrong?

def on_grid(grid, r, c):    """     Given a grid and a coordinate, this function determines whether or not     the coordinate exists withing the grid    """        range_rows = 0    range_columns = 0        range_rows = range(len(grid))    range_columns = range(len(grid[0]))        if r in range_rows and c in range_columns:        return True    else:        return False        def count_neighbors(grid, r, c):    """     Given a Grid and two integers indicating a cell coordinate,     this function returns how many living neighbors there are.     """    live_count = 0        # This loop checks for living cells around cell in question.    for x in range(r - 1, r + 2):           for y in range(c - 1, c + 2):               if x == r and y == c:   # Skips cell in question                continue            if on_grid(grid, x, y) and grid[x][y] == True:                live_count += 1        return live_count    def next_gen(grid):    """     Give a Grid, this function creates a new Grid that     represents the next generations.    """    next_generation = grid        for x in range(len(grid)):        for y in range(len(grid[x])):            if count_neighbors(grid, x, y) == 2 or count_neighbors(grid, x, y) == 3:                next_generation[x][y] = grid[x][y]            elif grid[x][y] == True and (count_neighbors(grid, x, y) >= 4 or count_neighbors(grid, x, y) <= 1):                next_generation[x][y] = False            elif grid[x][y] == False and count_neighbors(grid, x, y) == 3:                next_generation[x][y] = True                return next_generation
Link to comment
https://linustechtips.com/topic/476035-python-please-help/#findComment-6379668
Share on other sites

Link to post
Share on other sites

First of all, the way I debug is by printing out variables to a console. Second of all, what is the data stored in the grid? If it is booleans, then that's not the problem, but try printing out it's type to check.

˙ǝɯᴉʇ ɹnoʎ ƃuᴉʇsɐʍ ǝɹɐ noʎ 'sᴉɥʇ pɐǝɹ oʇ ƃuᴉʎɹʇ ǝɹɐ noʎ ɟI

Link to comment
https://linustechtips.com/topic/476035-python-please-help/#findComment-6379863
Share on other sites

Link to post
Share on other sites

Lists are reference types, so assigning one to a variable doesn't create a copy of the list. Because of that you end up using data from the new generation instead of the old one.

Ok yeah I see that now. How can I fix that? Because what I want to do is create a list based off of that one (same size and everything).

Link to comment
https://linustechtips.com/topic/476035-python-please-help/#findComment-6379930
Share on other sites

Link to post
Share on other sites

I'm not allowed to import modules...I don't understand why the other things aren't working.

 

You need to understand the difference between a shallow copy and a deep copy. Here is some info about that. The other options are doing a shallow copy, which doesn't give you true copies of the internal lists. The deepcopy method does, but since you're not allowed to use it, then you have to manually implement it for your case.

 

So assuming the inner lists can't also contain lists, loop through the list (grid), doing a shallow copy on each element adding it to a new list (next_generation) yourself. Basically, manually build the new list from the data in the old list.

Link to comment
https://linustechtips.com/topic/476035-python-please-help/#findComment-6380434
Share on other sites

Link to post
Share on other sites

You need to understand the difference between a shallow copy and a deep copy. Here is some info about that. The other options are doing a shallow copy, which doesn't give you true copies of the internal lists. The deepcopy method does, but since you're not allowed to use it, then you have to manually implement it for your case.

 

So assuming the inner lists can't also contain lists, loop through the list (grid), doing a shallow copy on each element adding it to a new list (next_generation) yourself. Basically, manually build the new list from the data in the old list.

Interesting. Thanks for that! Now one last question. How do I create a copy using for loops? I'm having trouble because it's a list of lists. By the way, I'm not as dumb as I seem...haha I'm coming from Java and Python has been a little tricky for me so far, especially the for loops.

for x in range(len(grid)):        for y in range(len(grid[x])):            next_generation.append[grid[x][y]]
Link to comment
https://linustechtips.com/topic/476035-python-please-help/#findComment-6380468
Share on other sites

Link to post
Share on other sites

 

Interesting. Thanks for that! Now one last question. How do I create a copy using for loops? I'm having trouble because it's a list of lists. By the way, I'm not as dumb as I seem...haha I'm coming from Java and Python has been a little tricky for me so far, especially the for loops.

for x in range(len(grid)):        for y in range(len(grid[x])):            next_generation.append[grid[x][y]]

 

It's ok, the syntax is a bit different. It's quite nice when you get the hang of it though.

 

That code is copying every element to the new list, but it's getting rid of the inner lists.

# With your code, this[[True, False], [False, True]]# Will become this[True, False, False, True]

This isn't quite what you're after. You need to preserve the original structure as well (ie: a list of lists). In this case you'd want to append the elements to a new list, and then append that new list to next_generation.

for x in range(len(grid)):    innerList = []    for y in range(len(grid[x])):        innerList.append(grid[x][y])    next_generation.append(innerList)

You don't actually need to access the elements in the inner loops at all though. You can append the lists at grid[x] to next_generation. That would look like this.

for x in range(len(grid)):    next_generation.append(grid[x])

This simplifies the code a fair bit. However, this isn't quite right because you're still sharing the references between the inner lists which was your original problem. You need to also use one of the shallow copy options on grid[x].

for x in range(len(grid)):    next_generation.append(list(grid[x]))

One thing that can help simplify this a bit more is that Python can iterate over the list directly.

for item in grid:  # item is just a variable and can be named whatever you want    next_generation.append(list(item))

This would be similar to Java's for each loop

# Pythonfor variable in someList:    # do something with variable// Javafor (Type variable : someList){    // do somethign with variable}
Link to comment
https://linustechtips.com/topic/476035-python-please-help/#findComment-6380624
Share on other sites

Link to post
Share on other sites

 

It's ok, the syntax is a bit different. It's quite nice when you get the hang of it though.

 

That code is copying every element to the new list, but it's getting rid of the inner lists.

# With your code, this[[True, False], [False, True]]# Will become this[True, False, False, True]

This isn't quite what you're after. You need to preserve the original structure as well (ie: a list of lists). In this case you'd want to append the elements to a new list, and then append that new list to next_generation.

for x in range(len(grid)):    innerList = []    for y in range(len(grid[x])):        innerList.append(grid[x][y])    next_generation.append(innerList)

You don't actually need to access the elements in the inner loops at all though. You can append the lists at grid[x] to next_generation. That would look like this.

for x in range(len(grid)):    next_generation.append(grid[x])

This simplifies the code a fair bit. However, this isn't quite right because you're still sharing the references between the inner lists which was your original problem. You need to also use one of the shallow copy options on grid[x].

for x in range(len(grid)):    next_generation.append(list(grid[x]))

One thing that can help simplify this a bit more is that Python can iterate over the list directly.

for item in grid:  # item is just a variable and can be named whatever you want    next_generation.append(list(item))

This would be similar to Java's for each loop

# Pythonfor variable in someList:    # do something with variable// Javafor (Type variable : someList){    // do somethign with variable}

Awesome, it works! Thanks so much for your help, I really appreciate it. I will definitely study that whole shadow copy thing a little more later on. I had learned about that, but I had never actually worked with it until now. Thanks again!

Link to comment
https://linustechtips.com/topic/476035-python-please-help/#findComment-6380640
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×