Vr3527
Vr3527

Reputation: 25

creating a loop that goes through a list of boolean values - Python

I have a function def next_generation(line, rule): where line is a list of booleans and rule is an integer

When you call it, it would look something like this:

>>> next_generation([True, True, True, False], 110)
[True, False, True, True]

The code takes the one before the first value (line[-1]), the first value (line[0], and the one after the first value (line[1]. Then does the same thing with the second value and so on. If that doesn't make sense here is a manual code of it that I wrote:

def next_generation(line, rule):
    
    new_gen = []

    first_cell = next_cell([line[-1], line[0], line[1]], rule)
    new_gen.append(first_cell)

    second_cell = next_cell([line[0], line[1], line[2]], rule)
    new_gen.append(second_cell)

    third_cell = next_cell([line[1], line[2], line[3]], rule)
    new_gen.append(third_cell)

    fourth_cell = next_cell([line[2], line[3], line[0]], rule)
    new_gen.append(fourth_cell)

    return new_gen

The code above works but only for a list of 4 boolean values. I want the code to do the same thing but loop through the list so it can do it for a list of any length.

Thanks in advance!

Edit:

I have now written:

def next_generation(line, rule):
    
    new_gen = []
    first_cell = next_cell([line[-1], line[0], line[1]], rule)
    new_gen.append(first_cell)
    for i in range(len(line)):
        new_gen.append(next_cell([line[i], line[i+1], line[i+2]], rule))

    last_cell = next_cell([line[-2], line[-1], line[0]], rule)
    new_gen.append(last_cell)

But it is giving me the error IndexError: list index out of range. I'm pretty sure this is happening when it says

new_gen.append(next_cell([line[i], line[i+1], line[i+2]], rule))

How should I prevent this?

Upvotes: 1

Views: 592

Answers (2)

smac89
smac89

Reputation: 43078

You can generate each cell using the loop:

First, let's just pretend we are still dealing with a list of 4 elements:

next_gen = []
for i in range(len(line)):
    next_gen.append(next_cell([line[i-1], line[i], line[i+1]], rule))

Now the above should produce the same output as your current program.

In order to have it work with arbitrary lines, you just need to fix the cell generation process. Again a simple loop should solve the problem:

cell_data = []
for c in range(i, len(line) + i):
    data_index = (c - 1) % len(line) if c > 0 else (c - 1)
    cell_data.append(line[data_index])

Putting it all together, we get:

next_gen = []
for i in range(len(line)):
    cell_data = []
    for c in range(i, len(line) + i):
        data_index = (c - 1) % len(line) if c > 0 else (c - 1)
        cell_data.append(line[data_index])
    next_gen.append(next_cell(cell_data, rule))

The trick with data_index is just to ensure that we only "wrap" when we are at an index greater than 0, otherwise using the modulus operator will not yield the correct results

Upvotes: 1

John
John

Reputation: 320

It looks like you're close. I believe using range(len(line) - 2), so you protect the bounds of i + 2, should resolve your IndexError.

So, then, you end up with something like the following:

def next_generation(line, rule):
    
    new_gen = []
    first_cell = next_cell([line[-1], line[0], line[1]], rule)
    new_gen.append(first_cell)

    for i in range(len(line) - 2):
        new_gen.append(next_cell([line[i], line[i + 1], line[i + 2]], rule))

    last_cell = next_cell([line[-2], line[-1], line[0]], rule)
    new_gen.append(last_cell)

Otherwise, you end up with the following execution for

next_generation([True, True, True, False], 110)
... first_cell = next_cell([line[-1], line[0], line[1]], rule)
... # Step 1 of your loop
... cell = next_cell([line[0], line[0 + 1], line[0 + 2]], rule)
... # Step 2 of your loop
... cell = next_cell([line[1], line[1 + 1], line[1 + 2]], rule)
... # Step 3 of your loop
... cell = next_cell([line[2], line[2 + 1], line[2 + 2]], rule)
...   raise IndexError(...)

Upvotes: 1

Related Questions