OK, dziś będzie o seksie ;-) ale w ujęciu informatycznym....
Dojdziemy do podstaw ;-)
Bo jakby na to nie patrzeć, w seksie, czy nam się to podoba czy nie, głównie chodzi o robienie dzieci.
Nawet może bardziej podstawowo, nie o robienie dzieci, a o kopiowanie genów.
To jest opowieść o tym jak to wygląda od strony kodu ;-)
Najpierw potrzebujemy gamet.
Gameta to taka dziwna komórka, która w odróżnieniu do zwyczajnych komórek w ciałach zwierząt czy roślin* ma w sobie tylko 1 kopię chromosomów.
Robienie gamety wygląda mniej więcej tak jak w programie poniżej ;-)
import random
"Probability of mutation is very low... it is not a constant, it depends from many factors, but for our purposes it will be consant ;-)"
PROBABILITY_OF_MUTATION=1E-9
class Chromosome:
"Here we keep our genes ;-)"
def __init__(self, id, aminoacids):
self.id = id
self.aminoacids = aminoacids
class Pair:
"In normal diploidal cell we need 2 copies of each chromosome"
def __init__(self, copy1, copy2):
self.copy1 = copy1
self.copy2 = copy2
class Genome:
"In our case Genome is set of pairs of chromosomes"
def __init__(self, pairs):
self.pairs = pairs
class Gamet:
"Gamed is 1n cell which have only one copy for each chromosome... in most cases, in rare cases it may have more and it may make for humans/animals big problems, for plants it is usually completly OK"
def __init__(self, chromosomes):
self.chromosomes = chromosomes
class Cell:
"Diploidal cell contains pairs of chromosomes in genome"
def __init__(self, genome):
self.genome = genome
def buildGamet(self):
"Building a gamet is quiet easy when coded ;-), we simply need to iterate over all pairs, and build new chromosome from those which cell got from parents (not parent cell, but parents for whole organism)"
chromosomes = []
for i in range(len(genome.pairs)):
pair = genome.pairs[i]
"And here is interesting part"
chromosome = self.crossingOver(pair.copy1, pair.copy2)
chromosomes.append(chromosome)
return Gamet(chromosomes)
def crossingOver(self, copy1, copy2):
"Builds new chromosome from 2 parent chromosomes by cutting both in the same place and exchanging"
# if Y we do not cross over, but only choose which one to return (works only for some mammals)
if copy1.id=="Y" or copy2.id=="Y":
if random.random()>0.5:
return Chromsome(copy1.id, self.deleteMethylation(copy1.aminoacids))
else:
return Chromsome(copy2.id, self.deleteMethylation(copy2.aminoacids))
aminoacids1 = copy1.aminoacids
aminoacids2 = copy2.aminoacids
cutPoint = int(random.random()*len(aminoacids1))
newStrand = self.mutate(aminoacids1[:cutPoint])+self.mutate(aminoacids2[cutPoint:])
return Chromosome(copy1.id, self.deleteMethylation(newStrand))
def mutate(self, aminoacids):
"Copying of genes is not perfect, sometimes something goes wrong and copying makes mistakes"
copy = ""
for i in range(len(aminoacids)):
"To make things easier we are doing only on one type of mutation, changing letter, we omit skipping, repeating and other types"
if random.random()<PROBABILITY_OF_MUTATION:
letters = "ACGT"
copy=copy+letters[int(random.random()*len(letters))]
else:
copy=copy+aminoacids[i]
return copy
def deleteMethylation(self, aminoacids):
"OK, we need to cheat, lets pretend that metylation in our case means that in our aminoacids letters we have * after each letter which is 'blocked' by methylation"
demethyled = ""
for i in range(len(aminoacids)):
if aminoacids[i]!='*':
demethyled=demethyled+aminoacids[i]
return demethyled
Główna magia dzieje się w metodzie buildGamet() klasy Cell.
Mając komórkę (Cell), możemy zawołać na niej metodę buildGamet() i dostaniemy gametę :-)
Jak mamy gamety to tu jest ten cały skomplikowany proces jak sprawić by 2 gamety się spotkały... to jest to co zwykle nazywamy seksem, a jeszcze wcześniej zalotami, albo po prostu magią życia... na to programy są ciut bardziej skomplikowane ;-)
Może innym razem ;-)
Idźmy jednak dalej, mamy 2 gamety... co dalej?
Okazuje się, że nasz kod dla gamety nie jest dokładny... brakuje kodu, który obsługuje zapłodnienie (oraz tego, który odpowiada np. za różne zachowanie gamet męskich i żeńskich...).
Bardziej poprawny kod powinien wyglądać dla Gamet mniej więcej tak:
class Gamet:
"Gamed is 1n cell which have only one copy for each chromosome... in most cases, in rare cases it may have more and it may make for humans/animals big problems, for plants it is usually completly OK"
def __init__(self, chromosomes):
self.chromosomes = chromosomes
def fertilization(self, otherGamet):
otherChromosomes = otherGamet.chromosomes
pairs = []
for i in range(len(chromosomes)):
"OK, again we are cheating to make things easier.... first we assume that we have exactly the same number of chromosomes... it should be true, but in case we don't have we will throw some scary exception"
"additionally we assume that our chromosomes are in exact same order, so we don't pair chromosomes by id's assuming that those are already in proper order"
pairs.append(Pair(chromosomes[i], otherChromosomes[i]))
return Cell(Genome(pairs))
Ta klasa ma teraz nową metodę fertilization, która dostaje jako parametr nic innego jak inną gametę :-)
Gdy wywoła się na gamecie metodę fertilization z inną gametą to dochodzi do stworzenia nowej komórki ;-) która może być później wykorzystana (a bardziej któryś z jej potomków) do zawołania buildGamet() ;-)
I to wszystko się toczy jakoś wg tego programu:
population = STARTING_POPULATION
while True:
"Here happens magic of life, children become adults, adults pair with other adults, adults get older, adults die"
partner1, partner2 = magicOfLife(population)
gamet1 = partner1.buildGamet()
gamet2 = partner2.buildGamet()
baby = gamet1.fertilization(gamet2)
population.append(baby)
I tak to w uproszczeniu wygląda ;-)
Uproszczeń w tym programie jest WIELE.
Spójrzmy na klasę Genome, zakłada ona, że genom składa się z par chromosomów.
Tak prosto nie jest, czasem może być tych chromosomów więcej... czasem który chromosom może pęknąć, albo jakieś 2 się połączą.
Jeśli gdzieś są 3 kopie chromosomu, albo i więcej to zwykle u zwierząt znaczy to problemy.
Żeby nie było te problemy nie oznaczają, że taki genom jest gorszy, nie, jest inny niż zwykle, a to znaczy, że mogą się dziać różne nieprzewidziane rzeczy, np. może się produkować więcej jakiegoś białka, a to może powodować, że tego białka będzie zbyt dużo w danych warunkach, albo znów może reagować inaczej na sygnały chemiczne. Taki genom działa prawidłowo, nie łamie żadnych zasad, po prostu inne kawałki genomu mogą oczekiwać czegoś innego.
Zwykle to prowadzi do problemów, czasem nie.
W końcu nasi najbliżsi żyjący kuzyni, czyli szympansy mają inną liczbę chromosomów niż my, bo gdzieś kiedyś (między 0.75 mln lat a 4.5 mln lat temu ;-)) gdzieś była najpewniej jakaś blisko spokrewniona grupa, w której występowała "wada genetyczna" polegająca na tym, że 2 chromosomy zaczęły się łączyć albo już nawet połączyły.
My jesteśmy ich potomkami ;-)
Więc czasem (a bardziej z czasem) te problemy w kopiowaniu prowadzą do specjacji i powstawania nowych gatunków.
Ale tak z grubsza to mniej więcej tak wygląda ;-)
* - rośliny są dziwne....
Podobne postybetaGenerał Jaruzelski wg. KuklińskiegoZrównoleglamy ;-)SleepAdvisor - komórka pomaga w wyspaniu się ;-)Cytat ;-)Tworzenie poprawnych nazw plików :-)