Take the 2-minute tour ×

I have to model bacterial growth as a function of optical density. The problem is simple: for every hour specified by the user, the OD in each cell in a table increases by 5%; when the cell reaches an OD of 1.0, the excess is distributed to cells N,E,S and W of the overflowing cell. If they are all at 1.0, no more growth takes place. The table of ODs is square and can be of any dimensions, it does not wrap around.

In the code below:

array3 is the initial table of ODs and length is the amount of rows and columns. I know that I am making a logical error in the nested while loop, because only the first row updates, and only once:

hours = input('how many hours do you want to run the experiment for?\n')
increase = 1.05

while elapsed <= hours:
    while i<length:
        while j<length:
            if array3[i, j]<1.0:
                array3[i, j]*=increase
            if array3[i, j]>=1.0:
                array3[i, j]=1.0
                excess=((array3[i, j]*increase)-1)/4
                array3[(i-1), j]+=excess
                array3[(i+1), j]+=excess
                array3[i, (j-1)]+=excess
                array3[i, (j+1)]+=excess
share|improve this question
You have to reset i and j after the loops. Or better use for loops. –  tobias_k Jun 27 '14 at 15:09
You're trying to write C code in Python. Write Python code instead; you'll be much happier. range() would be a good thing to use. –  Wooble Jun 27 '14 at 15:13
for the second row inner loop variable j still equal length because of this loop body will not run anymore. The same for second hour and forth. –  oleg Jun 27 '14 at 15:17

1 Answer 1

up vote 1 down vote accepted

As already pointed out in the comments, the problem is that you increase the counter variables in the loops, but you do not reset them to their original values before the next iteration. Adding i = 0 just before while i<length (and similar for j) would solve your problem, but I'd recommend to use for loops instead, looping over the range of values the variables should take.

for elapsed in range(hours):
    for i, j in itertools.product(range(length), repeat=2):
        if array3[i, j] < 1.0:
            array3[i, j] = min(1.0, array3[i, j] * increase)
            for di, dj in [(+1,0), (-1,0), (0,+1), (0,-1)]:
                if 0 <= i+di < length and 0 <= j+dj < length:
                    array3[i+di, j+dj] = min(1.0, array3[i+di, j+dj] + excess)

As you can see, I've made a few more alterations:

  • itertools is very useful, e.g. for iterating over the product of two variables, like i and j
  • you can use the min builtin function to cap the growth at 1.0
  • looping over all the 'deltas' for i and j instead of having the same code for all 4 neighbors
share|improve this answer

Your Answer


