Praca na modułach - pomoc

Praca na modułach - pomoc
U1
  • Rejestracja:ponad 6 lat
  • Ostatnio:ponad 6 lat
  • Postów:2
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:

Kopiuj
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
KO
fajny nick xD
AF
  • Rejestracja:prawie 7 lat
  • Ostatnio:około 21 godzin
  • Postów:172
0

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

Kopiuj
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):

Kopiuj
nuk = 'ACTG'
Kopiuj

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:

Kopiuj
y = random.randint(1, dlug//3) * 3
Kopiuj
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ć:

Kopiuj
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:

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

Zamień to na listę kodonow:

Kopiuj
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)
Kopiuj
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):

Kopiuj
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 :

Kopiuj
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
AF
  • Rejestracja:prawie 7 lat
  • Ostatnio:około 21 godzin
  • Postów:172
1

Ostatecznie:

Kopiuj
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
AF
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.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.