Pokaż wyniki 1 do 8 z 8

Temat: (Perl) prosty programik. co robie zle

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. Domyślnie programik

    Witam wszystkich. Mam na zaliczenie zrobic programik. No i zrobilem tylko nie wiem co zle zrobilem...

    Zadanie 7.
    Oblicz stopień identyczności dwóch sekwencji A i B (DNA,
    RNA lub białka) w odniesieniu:
    a. globalnym
    b. lokalnym.
    Dane wejściowe:
    dwie sekwencje DNA: A i B
    Wskazówki:
    ad a L = 2*(liczba zgodnych jednostek)/(liczba jednostek A + liczba jednostek B)
    ad. b L = (liczba zgodnych jednostek)/(liczba jednostek krótszej sekwencji)


    print "Program do obliczania stopnia identycznosci","\n";
    print "Wprowadz nazwe pliku z porownywana sekwencja nr1: ","\n";
    $plik1=<>;
    chomp $plik1;
    open (SEKW, "<$plik1");
    $s1='';
    while ($sek1=<SEKW>) {
    if ($sek1=~/^[ACTG]/i) {chomp $sek1; $s1=$s1.$sek1};
    }
    print "Wprowadz nazwe pliku z porownywana sekwencja nr2: ","\n";
    $plik2=<>;
    chomp $plik2;
    open(SEKW2, "< $plik2"),"\a";
    $s2='';
    while ($sek2=<SEKW2>) {
    if ($sek2=~/^[ACTG]/i) {chomp $sek2; $s2=$s2.$sek2};
    }
    #zamiana string ->array-----------------
    @ts1 = split('',$s1);
    $ts1=@ts1;
    @ts2 = split('',$s2);
    $ts2=@ts2;
    #------------------- MACIERZ------------
    $a{A}{A}=1;
    $a{A}{C}=0;
    $a{A}{T}=0;
    $a{A}{G}=0;
    #-------------
    $a{C}{A}=0;
    $a{C}{C}=1;
    $a{C}{T}=0;
    $a{C}{G}=0;
    #-------------
    $a{T}{A}=0;
    $a{T}{C}=0;
    $a{T}{T}=1;
    $a{T}{G}=0;
    #-------------
    $a{G}{A}=0;
    $a{G}{C}=0;
    $a{G}{T}=0;
    $a{G}{G}=1;
    #----------FUNKCJA OBLICZAJACA----------
    if ($ts1<ts2) {
    $koniec = $ts1;
    } else {
    $koniec = $ts2;
    }
    $suma=0;
    for($i = 0;$i <= $koniec;++$i){
    $ss1 = $ts1[$i];
    $ss2 = $ts2[$i];
    $suma = $suma+$a{$ss1}{$ss2};
    };
    print'SUMA:',"\t",$suma,"\n";
    $global=(2*$suma)/($ts1+$ts2);
    print'Stopien podobienstwa w odniesieniu globalnym wynosi: ',$global,"\n";
    $lokal=$suma/$koniec;
    print 'Stopien podobienstwa w odniesieniu lokalnym wynosi: ',$lokal,"\n";

    niestety program nie działa... Prosze o pomoc to bardzo wazne dla mnie
    Ostatnio edytowane przez pawelek4322 : 01-31-2012 - 16:40

  2. #2
    Zarejestrowany
    Jun 2006
    Skąd
    rand(.eu)
    Postów
    8,748

    Domyślnie

    Podaj jakies dane testowe i oczekiwany dla nich wynik to sie zobaczy... nie jest to trudne zadanie w sumie.

    Czy sprawdzales gotowe moduly do tego (Bio::Perl oraz google: bioperl)?

    EDIT:
    Na probe biore dane z GenBank Sample Record
    Porownam to co ponizej do nastepnej sekcji tak aby bylo tyle samo danych na probe... a na poczatek wezme pierwsze dwie linie z tego ponizej bo latwo recznie policzyc wynik (1+4+4+0+0+4=16).
    Kod:
    ORIGIN
            1 gatcctccat atacaacggt atctccacct caggtttaga tctcaacaac ggaaccattg
           61 ccgacatgag acagttaggt atcgtcgaga gttacaagct aaaacgagca gtagtcagct
          121 ctgcatctga agccgctgaa gttctactaa gggtggataa catcatccgt gcaagaccaa
          181 gaaccgccaa tagacaacat atgtaacata tttaggatat acctcgaaaa taataaaccg
          241 ccacactgtc attattataa ttagaaacag aacgcaaaaa ttatccacta tataattcaa
          301 agacgcgaaa aaaaaagaac aacgcgtcat agaacttttg gcaattcgcg tcacaaataa
          361 attttggcaa cttatgtttc ctcttcgagc agtactcgag ccctgtctca agaatgtaat
          421 aatacccatc gtaggtatgg ttaaagatag catctccaca acctcaaagc tccttgccga
          481 gagtcgccct cctttgtcga gtaattttca cttttcatat gagaacttat tttcttattc
          541 tttactctca catcctgtag tgattgacac tgcaacagcc accatcacta gaagaacaga
          601 acaattactt aatagaaaaa ttatatcttc ctcgaaacga tttcctgctt ccaacatcta
          661 cgtatatcaa gaagcattca cttaccatga cacagcttca gatttcatta ttgctgacag
          721 ctactatatc actactccat ctagtagtgg ccacgcccta tgaggcatat cctatcggaa
          781 aacaataccc cccagtggca agagtcaatg aatcgtttac atttcaaatt tccaatgata
          841 cctataaatc gtctgtagac aagacagctc aaataacata caattgcttc gacttaccga
          901 gctggctttc gtttgactct agttctagaa cgttctcagg tgaaccttct tctgacttac
          961 tatctgatgc gaacaccacg ttgtatttca atgtaatact cgagggtacg gactctgccg
    EDIT 2:
    Mam dzialajacy kod, wiec jesli chcesz to mozesz recznie wyliczyc dla sprawdzenia czy dziala ok.

    porownywalem linie 1 i 2, 2 i 3, 3 i 4 - sa akurat rownej dlugosci... Wyniki sa nastepujace:
    Kod:
    Podobne = 15, A = 0.25, B = 0.25
    Podobne = 12, A = 0.2, B = 0.2
    Podobne = 16, A = 0.266666666666667, B = 0.266666666666667
    Ostatnio edytowane przez TQM : 01-28-2012 - 22:19
    ctrl-alt-del.cc - soft reset site for IT admins and other staff :-)

  3. Domyślnie

    wiesz my tylko mieliśmy napisać program w notepad++ i odpalić go z wiersza poleceń... Plik zapisujemy w rozszerzeniu .pl czyli Perl. To czarna magia dla mnie napisać to to była sztuka... Nie wiem co mam zmienić w tym co zrobiłem żeby ten programik odpalił... Możesz jaśniej ja się na tym nie znam :/ czarna magia jak dla mnie to cale programowanie

    w sumie to nawet nie wiem czy to co zrobiłem do tej pory jest dobrze
    Ostatnio edytowane przez pawelek4322 : 01-28-2012 - 23:07

  4. #4
    Zarejestrowany
    Jun 2006
    Skąd
    rand(.eu)
    Postów
    8,748

    Domyślnie

    Kod napisales w sumie prawie poprawnie - to by dzialalo, gdyby dane wczytywane na prawde pasowalu do tego co sprawdzasz a widac ze to nie jest koniecznie poprawne zalozenie. Stosujesz hashes hashy i klucze masz jako duze litery - czy danych przypadkiem nie masz jako male litery?


    Moze conieco z mojego kodu...

    Dane wejsciowe wczytuje do tablicy @in wierszami z pliku wejsciowego podanego jako pierwszy argument wywolania skryptu:
    Kod:
     
    open (IN, $ARGV[0]) || die "Nie moge zaladowac pliku $ARGV[0]: $!\n";
    chomp(my @in = <IN>);
    close (IN);
    Nastepnie zanim zaczne obrabiac dane, wycinam z danych wejsciowych wszystkie znaki inne niz /[actg]/i niezaleznie od wielkosci liter
    Kod:
    map {
      s/[^agtc]//ig;
    } @in;
    ten kod dla kazdego elementu @in wykona podstawienie - zamieni kazda litere spoza grupy agtc na pusty znak (ignorujac wielkosc liter i robiac globalne podstawienia), co pozniej mozna pociac uzywajac split'a...
    Ten kod tez nie jest idealny bo zaklada, ze wszystkie sekwencje sa zapisane z uzyciem tej samej wielkosci liter, wiec jakbys mial jedna sekwencje pisana malymi a druga DUZYMI to moj dalszy kod tez nie zadziala... ale z doswiadczenia wiem ze dane nie sa recznie tworzone tylko pochodza z jakiegos powtarzalnego zrodla wiec zostawiam jak jest.

    Okreslenie podobienstwa robie poprzez porownanie genow na pozycji 1, 2, 3, 4... jesli na pozycji N w obu ciagach jest ten same gen to zwiekszam licznik o jeden.

    Kod:
    sub compare {
     my @a1 = split '', $_[0];
     my @a2 = split '', $_[1];
     # krotszy string decyduje o porownaniu
     my $koniec = $#a1 < $#a2 ? $#a1 : $#a2;
     my $wynik = 0;
     for (my $l=0; $l<=$koniec; $l++) {
      $wynik++ if $a1[$l] eq $a2[$l]; 
     }
     # wyliczamy globalne i loklane podobienstwo
     my $A = (2 * $wynik) / ($#a1 + $#a2 + 2);
     my $B = $wynik / ($koniec+1);
     print "Podobne = $wynik, A = $A, B = $B\n";
    }
    w przypadku A dodajemy 2 do wyniku, bo $#tablica to numer najwyzszego elementu liczac od zera a nie ilosc elementow, to samo dotyczy $koniec (tak samo wyliczane).

    Teraz odpalenie calosci aby porownac kolejne linie w tablicy @in:
    Kod:
    compare($in[0], $in[1]);
    compare($in[1], $in[2]);
    compare($in[2], $in[3]);
    Czy mam skomentowac ktorys kawalek kodu?

    Uwagi do Twojego kodu:
    Sekcja z hashem hashy nie ma wielkiego sensu - szybciej jest porownac wartosci elementow tablicy po indeksie zamiast przepisywac je bez konca do zmiennych itd, poza tym duzym problemem bedzie wielkosc liter - robiac to tak jak robisz musiz podac tez $a{C}{c}=1, $a{C}{g}=0 itd... Cala reszta kodu jest ok...

    Jesli poskladasz to co ja podalem i wrzucisz do compare() dwa stringi opisujace genom to dostaniesz porownanie tak jak chciales - jesli dobrze rozumiem cel zadania :-)
    ctrl-alt-del.cc - soft reset site for IT admins and other staff :-)

  5. Domyślnie

    Nie wiem kolego czy dobrze to poprawiłem ale jest jakiś postęp bo program prosi mnie o podanie sekwencji 1 i sekwencji 2 no ale na tym koniec... Napisałeś mi tam co mam wstawić ale nie wiem gdzie ta reszta ma być naprawdę to dla mnie czarna magia... nie mam pojęcia wysyłam Ci to co zmienielem do tej pory... Proszę o wyrozumiałość ja i programowanie to dwa różne światy niestety
    Kod:
    print "Program do obliczania stopnia identycznosci","\n";
    print "Wprowadz nazwe pliku z porownywana sekwencja nr1: ","\n";
    $plik1=<>;
    chomp $plik1;
    open (SEKW, "<$plik1");
    $s1='';
    while ($sek1=<SEKW>) {
    if ($sek1=~/[^ACTG]/i) {chomp $sek1; $s1=$s1.$sek1};
    }
    print "Wprowadz nazwe pliku z porownywana sekwencja nr2: ","\n";
    $plik2=<>;
    chomp $plik2;
    open(SEKW2, "< $plik2"),"\a";
    $s2='';
    while ($sek2=<SEKW2>) {
    if ($sek2=~/^[ACTG]/i) {chomp $sek2; $s2=$s2.$sek2};
    }
    #zamiana string ->array-----------------
    @ts1 = split('',$s1);
    $ts1=@ts1;
    @ts2 = split('',$s2);
    $ts2=@ts2;
    #------------------- MACIERZ------------
    $a{a}{a}=1;
    $a{a}{c}=0;
    $a{a}{t}=0;
    $a{a}{g}=0;
    #-------------
    $a{c}{a}=0;
    $a{c}{c}=1;
    $a{c}{t}=0;
    $a{c}{g}=0;
    #-------------
    $a{t}{a}=0;
    $a{t}{c}=0;
    $a{t}{t}=1;
    $a{t}{g}=0;
    #-------------
    $a{g}{a}=0;
    $a{g}{c}=0;
    $a{g}{t}=0;
    $a{g}{g}=1;
    #----------FUNKCJA OBLICZAJACA----------
    
    sub compare {
     my @a1 = split '', $_[0];
     my @a2 = split '', $_[1];
     # krotszy string decyduje o porownaniu
     my $koniec = $#a1 < $#a2 ? $#a1 : $#a2;
     my $wynik = 0;
     for (my $l=0; $l<=$koniec; $l++) {
      $wynik++ if $a1[$l] eq $a2[$l]; 
     }
     # wyliczamy globalne i loklane podobienstwo
     my $A = (2 * $wynik) / ($#a1 + $#a2 + 2);
     my $B = $wynik / ($koniec+1);
     print "Podobne = $wynik, A = $A, B = $B\n";
    }

  6. #6
    Zarejestrowany
    Jun 2006
    Skąd
    rand(.eu)
    Postów
    8,748

    Domyślnie

    Ok nie ma problemu.

    Zacznijmy od poczatku skryptu... prosisz usera o podanie nazw plikow - moim zdaniem (ale to tylko kwestia wyboru) aby user podal nazwy plikow w wierszu polecen:
    Kod:
    ./porownanie.pl plik1 plik2
    Wtedy dostep pliku robisz uzywajac zmiennych @ARGV (parametry wywolania programu jak podane w wierszu polecen)

    Kod:
    open (IN, $ARGV[0]) || die "Nie moge otworzyc pliky $ARGV[0] do odczytu: $!\n";
    # analogicznie $ARGV[1] to drugi parametr wywolania
    Procedura wczytania ktorej uzywasz jest bardzo powolna i do tego niedokladna, bo wczytujesz z pliku linie i szukasz znakow innych niz /[ACTG]/i i je przeskakujesz. Prosciej wczytac caly plik do tablicy, polaczyc wiersze tej tablicy w jedna linie i usuna w niej znaki ktore tam nie powinny wystepowac. Calosc mozna owinac w procedurke ktora wywolasz raz podajac jako parametr nazwe pliku

    Kod:
    sub wczytaj_plik {
      open (PLIK, $_[0]) || die "Nie moge zaladowac $_[0]: $!\n";
      chomp(my @temp = <PLIK>);
      close (PLIK);
      # laczymy wiersze z pliku w jedna dluga linie
      my $dna = join '', @temp;
      # wywalamy znaki ktore nie opisuja DNA
      $dna =~ s/[^actg]//gi;
      # mamy sekwencje DNA do zwrocenia
      return $dna;
    }
    Teraz calosc mozna ladnie uzyc w skrypcie:

    Kod:
    # wczytujemy sekwencje DNA z pliku
    my $dna1 = wczytaj_plik($ARGV[0]);
    my $dna2 = wczytaj_plik($ARGV[1]);
    to co dostajesz w $dna1 i $dna2 to kompletne ciagi juz odfiltrowane itd...

    Dalej sekcja przerabiania ze stringa na macierz - nie ma sensu, bo funkcja compare() robi to sama w sobie na samym poczatku. Tworzenie macierzy (w sumie to hash hashy a nie macierz) $a{t}{t}=... tez nie ma sensu bo funkcja compare() tego nie uzywa... sprawdza za to czy litery na N pozycji w obu ciagach DNA sa identyczne...

    Caly program mozna wiec zawrzec w takiej postaci:

    Kod:
    sub wczytaj_plik {
      open (PLIK, $_[0]) || die "Nie moge zaladowac $_[0]: $!\n";
      chomp(my @temp = <PLIK>);
      close (PLIK);
      # laczymy wiersze z pliku w jedna dluga linie
      my $dna = join '', @temp;
      # wywalamy znaki ktore nie opisuja DNA
      $dna =~ s/[^actg]//gi;
      # mamy sekwencje DNA do zwrocenia
      return $dna;
    }
    
    sub compare {
     my @a1 = split '', $_[0];
     my @a2 = split '', $_[1];
     # krotszy string decyduje o porownaniu
     my $koniec = $#a1 < $#a2 ? $#a1 : $#a2;
     my $wynik = 0;
     for (my $l=0; $l<=$koniec; $l++) {
      $wynik++ if $a1[$l] eq $a2[$l]; 
     }
     # wyliczamy globalne i loklane podobienstwo
     my $A = (2 * $wynik) / ($#a1 + $#a2 + 2);
     my $B = $wynik / ($koniec+1);
     print "Podobne = $wynik, A = $A, B = $B\n";
    }
    
    #
    # GLOWNA CZESC PROGRAMU
    # wywolanie: porownaj.pl plikdna1 plikdna2
    #
    
    # wersja czytelna
    my $dna1 = wczytaj_plik($ARGV[0]);
    my $dna2 = wczytaj_plik($ARGV[1]);
    compare ($dna1, $dna2);
    
    # wersja skrocona ktora robi dokladnie to samo... ale jest mniej czytelna
    #compare(wczytaj_plik($ARGV[0]), wczytaj_plik($ARGV[1]));
    ctrl-alt-del.cc - soft reset site for IT admins and other staff :-)

Zasady Postowania

  • Nie możesz zakładać nowych tematów
  • Nie możesz pisać wiadomości
  • Nie możesz dodawać załączników
  • Nie możesz edytować swoich postów
  •  
Subskrybuj