Skip to content

Instantly share code, notes, and snippets.

@isezen
Created November 4, 2017 07:45
Show Gist options
  • Save isezen/2061a1fbdc418d4b5dc3107d41941ce7 to your computer and use it in GitHub Desktop.
Save isezen/2061a1fbdc418d4b5dc3107d41941ce7 to your computer and use it in GitHub Desktop.
1-D Bacterium Example
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# pylint: disable=C0103, C0321, C0330
"""1-D Bacterium class example"""
from random import randint as rnd
import gc
import time
from matplotlib import pyplot as plt
from datetime import datetime as dt
class bact:
"""Bacterium Class"""
count = 0
life_time = 0.1
domain = list(range(1000))
elem = [None] * len(domain)
mitosis_prob = 50
mutation_prob = 25
def __init__(self, id=None, pos=None):
self.id = rnd(9000000, 9999999) if id is None else id
self.sid = bact.__sumofdig(self.id)
self.pos = rnd(min(bact.domain), max(bact.domain)) if pos is None else pos
self.birth_time = dt.now()
bact.count += 1
bact.elem[self.pos] = self
@classmethod
def __sumofdig(cls, x):
s = 0
while x > 0:
x, a = divmod(x, 10)
s += a
return(s)
def __mutate(self):
new_id = self.id
if rnd(0, 100) < bact.mutation_prob:
strid = str(self.id)
a = rnd(1, len(strid) - 1)
b = list(strid)
b[a] = str(rnd(0, 9))
new_id = int(''.join(b))
return(new_id)
def mitosis(self):
if rnd(0, 101) < bact.mitosis_prob:
for i in [-1, 1]: # left or right
pos = self.pos + i
if min(bact.domain) <= pos <= max(bact.domain):
b = bact.elem[pos]
if b is None:
bact(self.__mutate(), pos)
break
def die(self):
bact.count -= 1
bact.elem[self.pos] = None
def life_end(self):
td = dt.now() - self.birth_time
if td.total_seconds() > bact.life_time:
self.die()
def _conflict(self, b):
if b.sid != self.sid:
if self.sid > b.sid:
b.die()
else:
self.die()
def moveleft(self):
pos = self.pos - 1
if pos >= min(bact.domain):
b = bact.elem[pos]
if b is None:
bact.elem[pos] = self
bact.elem[pos + 1] = None
self.pos = pos
else:
self._conflict(b)
def moveright(self):
pos = self.pos + 1
if pos <= max(bact.domain):
b = bact.elem[pos]
if b is None:
bact.elem[pos] = self
bact.elem[pos - 1] = None
self.pos = pos
else:
self._conflict(b)
def move(self):
if [-1, 1][rnd(0, 1)] == -1:
self.moveleft()
else:
self.moveright()
@classmethod
def life_end_all(cls):
for b in cls.elem:
if b is not None:
b.life_end()
@classmethod
def mitosisall(cls):
for b in cls.elem:
if b is not None:
b.mitosis()
@classmethod
def moveall(cls):
for b in cls.elem:
if b is not None:
b.move()
@classmethod
def printpos(cls):
p = list(" " * len(cls.domain))
for b in cls.elem:
if b is not None:
p[b.pos] = "."
print("".join(p), end='')
print('\r', end='')
print((b'\x08').decode() * len(cls.domain), end='')
gc.collect()
for _ in range(3):
bact()
pop = []
species = []
for _ in range(10000):
pop.append(bact.count)
ids = [i.id for i in bact.elem if i is not None]
species.append(len(set(ids)))
bact.moveall()
bact.mitosisall()
bact.life_end_all()
bact.printpos()
# time.sleep(-time.time() % 0.1)
ids = [i.id for i in bact.elem if i is not None]
set(ids)
plt.plot(pop)
plt.plot(species)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment