Created
November 4, 2017 07:45
-
-
Save isezen/2061a1fbdc418d4b5dc3107d41941ce7 to your computer and use it in GitHub Desktop.
1-D Bacterium Example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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