## Rabbit Population Simulation

To solve this problem, a class called PairOfRabbits has been created which will simulate an adult pair of rabbits. This class will have a field called lifetime which will contain the number of months of life that the pair of rabbits has.

In the main program, you define the number of available cages and the initial population. For this case, an initial population of 2 rabbits is defined, for which 499 cages are available at the time of starting the simulation.

Using a while loop, the simulation will run until the number of available cages drops to zero. When this happens, the total number of months it took for this event to occur will be printed, along with the total number of baby and adult rabbits.

The pairs of rabbits are stored in a list and using the len function the number of pairs (and occupied cages) is obtained for each instant of time.

```
import csv
# We will have an initial pair of rabbits
# Each pair of rabbits produces a new pair of new rabbits
# Each cage can hold one pair of rabbits
# We create a helper class
class PairOfRabbits():
def __init__(self, lifetime = 0):
self.lifetime = lifetime
def step(self):
self.lifetime += 1
# We will count the lifetime of the pair of rabbits in units of one, where one unit refers to one month
# So, based on their lifetime, the pair of rabbits are categorized as follow:
# 0: Baby
# 1: Adult Pair of Non-breeders
# 2: Adult Pair of Breeders
cages_ = 500 # total number of cages
# Create the initial pair of rabbits.
pairs = list()
pairs.append(PairOfRabbits(1))
# Initial number of available cages
availableCages = cages_ - len(pairs)
print("Month\tBreeders\tNon-breeders\tBabies\tSum")
# Open csv file and write header
f = open('rabbits.csv', 'w')
header = ['Month', 'Adult Pairs of Breeders', 'Adult Pairs of Non-breeders', 'Pairs of Baby Rabbits Born (same as the # of breeder pairs)', 'Sum of Breeders, Non-breeders, and Babies']
writer = csv.DictWriter(f, fieldnames = header)
writer.writeheader()
month = 1
run_simulation = True
while(run_simulation):
# Check number of rabbits that can breed
breeders = [p for p in pairs if p.lifetime > 1]
babies = [p for p in pairs if p.lifetime == 0]
nonbreeders = [p for p in pairs if p.lifetime == 1]
# Increment the lifetime of each pair of rabbits
for index, pair in enumerate(pairs):
p = pair
p.step()
pairs[index] = p
# Print results at beginning of current month
print("{}\t{}\t\t{}\t\t{}\t{}".format(month, len(breeders), len(nonbreeders), len(babies), len(breeders)+len(nonbreeders)+len(babies)))
row = {
'Month': month,
'Adult Pairs of Breeders': len(breeders),
'Adult Pairs of Non-breeders': len(nonbreeders),
'Pairs of Baby Rabbits Born (same as the # of breeder pairs)': len(babies),
'Sum of Breeders, Non-breeders, and Babies': len(breeders) + len(nonbreeders) + len(babies)}
writer.writerow(row)
# For each breeder, a new pair is generated
for i in range(len(breeders)+len(nonbreeders)):
pairs.append(PairOfRabbits(0))
availableCages -= 1
if(availableCages < 1):
print("At the end of month {} the number of pairs of rabbits reached {}".format(month, len(pairs)))
run_simulation = False
break
month += 1
f.close()
```