'Modelling simple bacteria growth

so i'm trying to model a simple bacteria growth. The rules are as follow:

  1. Every one hour, the bacteria doubles
  2. Every 3 hours, the population of the bacteria drops 25%
def bakteri(init,hour):
  a = init*2
  b = a*2
  for t in range (1,hour):
    if t % 3 == 0:
      a = a - a*0.25
      yield a
      a, b = b, b*2
    else:
      a = a
      yield a
      a, b=b, b*2

a = [int(i) for i in bakteri(50,10)]
print(a)

I've tried to make it but the result shows [100, 200, 300, 800, 1600, 2400, 6400, 12800, 19200]

when it should be [100, 200, 300, 600, 1200, 1800, 3600, 7200, 10800, 21600]

Can anyone points out the mistake? Thank you so much



Solution 1:[1]

Your code is rather clunky. What do the a and b variables even do? Just use the init variable itself, like so:

def bakteri(init, hour):
    for i in range(1, hour + 1):
        init *= 2     # Same as init = init * 2
        if i % 3 == 0:
            init = 0.75 * init
        yield init

This is a very simple problem with a very simple solution. It looks as though you've been overcomplicating it a lot more that necessary. All you need to do is:

  1. Make the population double every iteration
  2. If the iteration number is divisible by 3, set it to 75% of itself

In that order.

Output

>>> print([int(i) for i in bakteri(50, 10)])
[100, 200, 300, 600, 1200, 1800, 3600, 7200, 10800]

Solution 2:[2]

The problem here is with:

a = a - a*0.25
yield a
a, b = b, b*2

Notice that here, even though a changed, disrupting the pattern, b has not been adjusted. b = a*2 was up before this change happened. So you didn't double the bacteria after a 0.25 decrease, you doubled the original before the decrease, and then carried on with it.

Preserving your original code structure, here's a revised one:

def bakteri(init,hour):
  a = init*2
  for t in range (1,hour+1):
    if t % 3 == 0:
      a = a - a*0.25
      b = a*2
      yield a
      a, b = b, b*2
      print(a, b)
    else:
      a = a
      b = a * 2
      yield a
      a, b = b, b*2
      print(a,b)

output = [int(i) for i in bakteri(50,10)]
print(output)

You need to have b = a*2 after you assign a value to a, for both the if and the else blocks.

Also note that range(a,b) stops at b-1. So when you did for t in range (1, hour) it only did 1 to 9 instead of 1 to 10.

(I also changed the "a" in the last two lines to "output", it's good to name variables differently to avoid confusion.

With that said, there is a more efficient way to program this. If you keep perfecting your code and learn, with time it'll come to you naturally.

The simpler code:

def bakteri(init, hour):
    for i in range(1, hour+1):
        init = init * 2
        if i % 3 == 0:
            init = init * 0.75 # Times 0.75 is the same as decrease by 0.25
        yield init


print([int(i) for i in bakteri(50, 10)])

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2