Praca na modułach - pomoc

Odpowiedz Nowy wątek
2019-01-15 21:02
0

Witam, mam problem z napisaniem programu dla tego zadania:
"Napisz program, który pobiera od użytkownika maksymalna długość DNA, lecz nie mniejszą niż 9, program pyta do skutku aż poda min.9. Następnie generuje losową sekwencje DNA o losowej długości, niezerowej i nieprzekraczającej maksymalnej liczy oraz podzielnej przez 3. Dodaje kodon start( ATG). Następnie dzieli sekwencje na kodony i wprowadza losowe pojedyncze mutacje w 3 innych, losowych kodonach. Jeśli ocalał kodon start wyświetla końcową sekwencje. Jeśli mutacje naruszyły kodon start, należy napisać, że nie udało się stworzyć genu. Mutacje można wprowadzić małymi literami."

Starałam się sama napisać, aczkolwiek na tym poziomie kończą się moje umiejętności z pisania programu:

from random import choice
from random import randint
import random

dlug=int(raw_input("Podaj maksymalna dlugosc sekwencji, minimum 9: "))
while dlug < 9:
    dlug=int(raw_input("Podaj dlugosc sekwencji MINIMUM 9: "))

losseq_mut=""

nuk = ["A","C","T","G"]
mutacja = ["a","c","t","g"]
losseq_mut=""
y=1
while y%3!=0:
    y=random.randint(1,dlug)
losseq=""
for k in range(y):
    losseq+=choice(nuk)
dna="ATG"+losseq
for j in range(0,len(dna),3):
    print dna[j:j+3]

u=int(y)+3
print "Dlugosc wylosowanej sekwencji z kodonem start wynosi %i" %(u)

t=random.randint(0,u)        
r=random.randint(0,u)
e=random.randint(0,u)
while r==t:
    r=random.randint(0,u)

while e==t or e==r:
    e=random.randint(0,u)

for s in range(len(dna)):

    if s == t or s == e or s == r:
        losseq_mut+=choice(mutacja)
    else:
        losseq_mut+=dna[s]

if losseq_mut.startswith("ATG"):
    print losseq_mut
else:
    print "nie udalo sie"

Jedynie czego nie wiem jak zrobić to to, aby nie było więcej niż 1 mutacja w kodonie. Będę wdzięczna za pomoc!!`

edytowany 2x, ostatnio: ułom123, 2019-01-15 22:57
fajny nick xD - komuher 2019-01-15 21:11

Pozostało 580 znaków

2019-01-16 12:44
0

To co zrobiłaś do tej pory ma sens ale zaproponuję parę poprawek.

losseq_mut=""

nuk = ["A","C","T","G"]
mutacja = ["a","c","t","g"]
losseq_mut=""

Wielokrotnie definiujesz losseq_mut. nuk można przechowac jako string (string w Pythonie możemy iterować jak listę). mutacja to po prostu nuk.lower() - na razie to ominę (później wskażę dlaczego):

nuk = 'ACTG'

y=1
while y%3!=0:
    y=random.randint(1,dlug)

Działa ale da się sprytniej. Jeżeli chcemy tylko losowe podzielne przez 3 liczby mniejsze od dlug - to zgodnie z matematyką będą to tylko wielokrotności 3 mieszczące się w dlug. Wystarczy więc podzielić dlug i zaokrąglić w dół aby uzyskać liczbę 3. Wylosować liczbę od 1 do tej liczby i pomnożyć przez 3. Przykład:

y = random.randint(1, dlug//3) * 3
losseq=""
for k in range(y):
    losseq+=choice(nuk)

Stringi w Pythonie sa immutable - oznacza to, że nie możemy ich zmieniać. Zapis += nie dodaje do istniejącego stringa a po prostu tworzy nowy string ze starego i nowego. Dlatego wydajniej jest napisać:

losseq = ''.join(choice(nuk) for k in range(y))

Co do samego problemu "Jedynie czego nie wiem jak zrobić to to, aby nie było więcej niż 1 mutacja w kodonie" - wystarczy traktować sekwencję jako listę kodonów i wybrać losowo 3 kodony i dokonać jednej zmiany. Podział w zasadzie już masz:

dna="ATG"+losseq
for j in range(0,len(dna),3):
    print dna[j:j+3]

Zamień to na listę kodonow:

dna = ['ATG']
for j in range(0,len(losseq),3):
   dna.append(losseq[j:j+3])
print(dna)
print "Dlugosc wylosowanej sekwencji z kodonem start wynosi %i" %(len(dna)*3)
t=random.randint(0,u)        
r=random.randint(0,u)
e=random.randint(0,u)
while r==t:
    r=random.randint(0,u)

while e==t or e==r:
    e=random.randint(0,u)

Żeby wybrać 3 losowe liczby, które są od siebie różne można zastosować poniższy sposób. Wybiera 3 próbki z podanej listy/generatora - tutaj range z len(dna):

t,r,e = random.sample(range(len(dna)), 3)

Teraz możemy po prostu odnieść się do 3 wybranych indeksów. Uzyłem zapisu z kodon[:i] + ran.. ponieważ jak wspomniałem nie możemy modyfikowac stringow a jedynie tworzyc nowe na podstawie obecnych :

def mutate(kodon, mutations):
   i = random.randint(0, 3)
   return kodon[:i] + random.choice(mutations) + kodon[i+1:]

dna[t] = mutate(dna[t], nuk.lower())
dna[r] = mutate(dna[r], nuk.lower())
dna[e] = mutate(dna[e], nuk.lower())

I potem wystarczy sprawdzic czy dna[0]=='ATG'.

edytowany 1x, ostatnio: AsterFV, 2019-01-16 12:56

Pozostało 580 znaków

2019-01-16 12:48

Ostatecznie:

import random

def mutate(kodon, mutations):
   i = random.randint(0, 3)
   return kodon[:i] + random.choice(mutations) + kodon[i+1:]

dlug=int(raw_input("Podaj maksymalna dlugosc sekwencji, minimum 9: "))
while dlug < 9:
    dlug=int(raw_input("Podaj dlugosc sekwencji MINIMUM 9: "))

nuk = 'ACTG'
y = random.randint(1, dlug//3) * 3

losseq = ''.join(random.choice(nuk) for k in range(y))

dna = ['ATG']
for j in range(0,len(losseq),3):
   dna.append(losseq[j:j+3])
print(dna)
print "Dlugosc wylosowanej sekwencji z kodonem start wynosi %i" %(len(dna)*3)

random_indexes = random.sample(range(len(dna)), 3)
for index in random_indexes:
  dna[index] = mutate(dna[index], nuk.lower())

if dna[0]=="ATG":
    print (dna)
else:
    print ("nie udalo sie")

Literówki i drobne błędy jak najbardziej możliwe - sprawdź.

edytowany 3x, ostatnio: AsterFV, 2019-01-16 13:14
Oczywiście można tez po prostu sprawdzić czy w random_indexes nie mamy 0 - bo jak mamy to oznacza, że mutujemy kodon start i wtedy nic się nie uda ;) Bez znaczenia dla 3 mutacji ale przy setkach+ lepiej sprawdzić tego typu warunki przed przeprowadzeniem mutacji. - AsterFV 2019-01-16 12:51

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0