HTML

Programozó Páternoszter

Ez a Programozó Páternoszter (PP) blogja, a programozásról szól. Aktualitása, hogy a Debreceni Egyetem Informatikai Kara Magasszintű programozási nyelvek 1-2, C++ esattanulmányok, Java esettanulmányok című kurzusainak blogja is egyben.

A vadászat

A Debreceni Egyetem Programozói Évkönyve: az UDPROG projekt. A szakmai fórumunk a Facebook-en. Az új előadások a prezin.
A régi előadások:
Prog1:
1. C bevezetés
2. C tárgyalás
3. C befejezés
4. C a gyakorlatban
5. C++ bevezetés
6. C++ tárgyalás
7. C++ befejezés
8. C++ a gyakorlatban
9. Java platform bevezetés
10. Kvantuminformatikai alg. bev.
Prog2:
1. Java bevezetés
2. Java tárgyalás
3. Java befejezés
4. Java a gyakorlatban
5. Software Engineering bev.
6. Java EE bevezetés
7. AspectJ bevezetés
8. BPMN-BPEL SOA programozás
9. C++ haladó
10. Tensorflow

Kövess engem!

Friss topikok

Linkblog

Az ötödik labor

2011.03.06. 11:16 nb

Laborvezetőknek

A 3. előadás laborkártyáit kérdezzük végig a hallgatóktól (és persze a korábbiakból is osszunk ki, amelyeket fontosnak érezünk). Ha indokolt, akkor bevezethető a több sebességes labor, ahol az előre készülő hallgatók későbbi feladatokkal dolgoznak, vagy kapcsolódó mélyebb feladatot kapnak. A "tömeg", azaz a labor main stream-je pedig szorosabban együtt dolgozik a laborvezetővel.

Hallgatóknak

Sosem árt előre készülni a laborra, nálam szereztek így kisbajnokság trófeát. Ha többen is elkészítik, akkor holtversenyben mindannyian megkapják a "trófeákat".

Tematika

Az alábbi témák legtöbbjét próbáljuk lefedni a második gyakorlaton:

  • Beszéljük meg és teszteljük a g.c-t, itt azt kell kiemelni, hogy hármasával olvassuk a betűket a fájlból, de nagyon rossz gyakorlat, ha a ciklusban ciklusolgatni kezdünk... e helyett egyetlen ciklust használunk:
    // a betűket 3-asával "olvasom": nem kell cifrázni! egy ciklus
    // elvégzi, amiben megjegyzem, hogy melyik hányadik betű volt
    // aki ciklusban ciklusolgat, az már bénázik :)
    int
    main (void)
    {
      // hányadik betűn állok?
      int hanyadik_betu = -1;
      // azon a helyen mit olvastam?
      int elso = 0, masodik = 0, harmadik = 0, i = 0, jegy = 0;
    
      while ((i = getchar ()) != EOF)
        {
    
          switch (i)
    	{
    
    	case 'T':
    	  jegy = 0;
    	  break;
    	case 'C':
    	  jegy = 1;
    	  break;
    	case 'A':
    	  jegy = 2;
    	  break;
    	case 'G':
    	  jegy = 3;
    	  break;
    	}
    
          hanyadik_betu = (hanyadik_betu + 1) % 3;
    
          if (!hanyadik_betu)
    	elso = jegy;
          else if (!(hanyadik_betu - 1))
    	masodik = jegy;
          else
    	{
    	  harmadik = jegy;
    	  printf ("%s", genetikai_kod (elso * 16 + masodik * 4 + harmadik));
    	}
        }
    }
    
    vedd észre, hogy a kód pici továbbfejlesztése a progpater.blog.hu/2011/02/27/a_human_genom_projekt poszt bevezető progijának, csak ott kettesével olvasunk és két betűből készítettünk egy hexadecimális jegyet.
  • Feladat (kisebb sebességű): készíts "aminosav-hisztogramot", azaz a progi továbbfejlesztésével mond meg, melyik aminosav hányszor szerepel? (egy trófea, jöhet kommentben előre is)
  • Hogy változik ez a szám, ha az első kódoló betűt törlöd a bemenő fájlból (azaz a 2. betűtől méred fel a 3 betűket) (egy trófea, jöhet kommentben előre is)
  • Hogy változik ez a szám, ha az első két kódoló betűt törlöd a bemenő fájlból (azaz a 3. betűtől méred fel a 3 betűket) (egy trófea, jöhet kommentben előre is)
  • Feladat (nagyobb sebességű): módosítsd a z.c-t, hogy ne 0, 1 betűkre menjen, hanem a 4 T, C, A, G betűre és így építs fát (ez már nem bináris fa lesz persze), mennyi a 2. kromóra az LZW fa ághosszainak átlaga és sztenderd hibája? (ez 5 trófeát ér, jöhet kommentben is)
  • További két kisbajnokság, aki gyorsabbat ír:
    [norbi@sgu tcag]$ time ./g <hs_alt_Hs_Celera_chr2.fa >aminosavak

    real    0m17.428s
    user    0m16.593s
    sys     0m0.714s

     

BN laborján

 Tekerj tovább, itt jön a g.c teljes kódja is:

g.c

 

// g.c
//
// genetikai kód nyomtató
// Programozó Páternoszter
//
// Copyright (C) 2011, Bátfai Norbert, nbatfai@inf.unideb.hu, nbatfai@gmail.com
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// Ez a program szabad szoftver; terjeszthetõ illetve módosítható a
// Free Software Foundation által kiadott GNU General Public License
// dokumentumában leírtak; akár a licenc 3-as, akár (tetszõleges) késõbbi
// változata szerint.
//
// Ez a program abban a reményben kerül közreadásra, hogy hasznos lesz,
// de minden egyéb GARANCIA NÉLKÜL, az ELADHATÓSÁGRA vagy VALAMELY CÉLRA
// VALÓ ALKALMAZHATÓSÁGRA való származtatott garanciát is beleértve.
// További részleteket a GNU General Public License tartalmaz.
//
// A felhasználónak a programmal együtt meg kell kapnia a GNU General
// Public License egy példányát; ha mégsem kapta meg, akkor
// tekintse meg a <http://www.gnu.org/licenses/> oldalon.
//
// Version history: szösszenet
//
// A http://progpater.blog.hu/2011/02/27/a_human_genom_projekt poszt
// bevezető kódjának alapötletét használjuk fel, de nem kettesével,
// hanem most hármasával dolgozzuk fel az inputot
//
// Ennek a kódnak a részleteit az itteni kisbajnokikon is
// kamatoztathatod: http://progpater.blog.hu/2011/03/05/szonyegen_a_human_genom

#include <stdio.h>
#include <unistd.h>

// Egyszerűen felsorolom, pl. az alábbi alapján:
// http://en.wikipedia.org/wiki/DNA_codon_table
char *amino_sav[] = {
  "Stop",
  "Phe",
  "Leu",
  "Ile",
  "Met",
  "Val",
  "Ser",			// 6.
  "Pro",
  "Thr",
  "Ala",
  "Tyr",			// 10.
  "His",
  "Gln",
  "Asn",
  "Lys",
  "Asp",
  "Glu",
  "Cys",
  "Trp",			// 18.
  "Arg",			// 19.
  "Gly"				// 20.
};

// a 3 betű melyik aminosavat kódolja?
char *
genetikai_kod (int triplet)
{
  int index = 0;

  switch (triplet)
    {
    case 0:			// Phe
    case 1:
      index = 1;
      break;
    case 2:			// Leu
    case 3:
    case 16:			
    case 17:
    case 18:
    case 19:
      index = 2;
      break;
    case 32:			// Ile
    case 33:
    case 34:
      index = 3;
      break;
    case 35:			// Met
      index = 4;
      break;
// hogy jön ez? az 5 indexű a "Val"
// GTT-től GTG-ig van ez, jegyekben:
// 300-tól 303-ig 4-es számrendszerben
// ez van átváltva, pl.:
//      303(4) -> 3*16+0*4+3*1 = 51(10)      
    case 48:
    case 49:
    case 50:
    case 51:
      index = 5;
      break;
    case 4:
    case 5:
    case 6:
    case 7:
      index = 6;
      break;
    case 20:
    case 21:
    case 22:
    case 23:
      index = 7;
      break;
    case 36:
    case 37:
    case 38:
    case 39:
      index = 8;
      break;
    case 52:
    case 53:
    case 54:
    case 55:
      index = 9;
      break;
    case 8:
    case 9:
      index = 10;
      break;
    case 10:			// Stop
    case 11:
      index = 0;
      break;
    case 24:
    case 25:
      index = 11;
      break;
    case 26:
    case 27:
      index = 12;
      break;
    case 40:
    case 41:
      index = 13;
      break;
    case 42:
    case 43:
      index = 14;
      break;
    case 56:
    case 57:
      index = 15;
      break;
    case 58:
    case 59:
      index = 16;
      break;
    case 12:			// Cys
    case 13:
      index = 17;
      break;
    case 14:			// Stop
      index = 0;
      break;
    case 15:			// Trp
      index = 18;
      break;
    case 28:			// Arg
    case 29:
    case 30:
    case 31:
      index = 19;
      break;
    case 44:			// Ser
    case 45:
      index = 6;
      break;
    case 46:			// Arg
    case 47:
      index = 19;
      break;
    case 60:			// Gly
    case 61:
    case 62:
    case 63:
      index = 20;
      break;

    default:
      // csak tesztelesre a printf
      printf ("Zavar az eroben %d-nel", triplet);
      index = 0;
      break;
    }

  return amino_sav[index];
}

// a betűket 3-asával "olvasom": nem kell cifrázni! egy ciklus
// elvégzi, amiben megjegyzem, hogy melyik hányadik betű volt
// aki ciklusban ciklusolgat, az már bénázik :)
int
main (void)
{
  // hányadik betűn állok?
  int hanyadik_betu = -1;
  // azon a helyen mit olvastam?
  int elso = 0, masodik = 0, harmadik = 0, i = 0, jegy = 0;

  while ((i = getchar ()) != EOF)
    {

      switch (i)
	{

	case 'T':
	  jegy = 0;
	  break;
	case 'C':
	  jegy = 1;
	  break;
	case 'A':
	  jegy = 2;
	  break;
	case 'G':
	  jegy = 3;
	  break;
	}

      hanyadik_betu = (hanyadik_betu + 1) % 3;

      if (!hanyadik_betu)
	elso = jegy;
      else if (!(hanyadik_betu - 1))
	masodik = jegy;
      else
	{
	  harmadik = jegy;
	  printf ("%s", genetikai_kod (elso * 16 + masodik * 4 + harmadik));
	}
    }
}

 Mo.:

[norbi@sgu tcag]$ ./gh <hs_alt_Hs_Celera_chr2.fa
Stop 4226021
Phe 4938666
Leu 8650548
Ile 4703612
Met 1421143
Val 3903156
Ser 6864063
Pro 4211007
Thr 3892567
Ala 3197516
Tyr 2514516
His 2541712
Gln 3049116
Asn 3230810
Lys 4968633
Asp 1735431
Glu 2846839
Cys 2645039
Trp 1450350
Arg 3795349
[norbi@sgu tcag]$ ./gh1 <hs_alt_Hs_Celera_chr2.fa
Stop 4221767
Phe 4937003
Leu 8656133
Ile 4707263
Met 1422311
Val 3906383
Ser 6867537
Pro 4209152
Thr 3892895
Ala 3197221
Tyr 2513279
His 2541506
Gln 3044589
Asn 3230946
Lys 4973403
Asp 1733840
Glu 2844519
Cys 2643748
Trp 1450806
Arg 3793309
[norbi@sgu tcag]$ ./gh2 <hs_alt_Hs_Celera_chr2.fa
Stop 4229297
Phe 4936156
Leu 8652212
Ile 4707113
Met 1419910
Val 3904313
Ser 6867552
Pro 4209185
Thr 3892548
Ala 3196552
Tyr 2510652
His 2544819
Gln 3043507
Asn 3230271
Lys 4970475
Asp 1731580
Glu 2843714
Cys 2648913
Trp 1451891
Arg 3797276

26 komment

Címkék: pro met stop his tyr lys ser ala aminosav val phe lzw humán nenom leu ile thr gln asn

A bejegyzés trackback címe:

https://progpater.blog.hu/api/trackback/id/tr422714667

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

kecske20 2011.03.07. 13:25:34

Megoldás: komment,első betű nélkűl: 4221767 4937003 8656133 4707263 1422311 3906383 6867537 4209152 3892895 3197221 2513279 2541506 3044589 3230946 4973403 1733840 2844519 2643748 1450806 3793309

marwellazure 2011.03.07. 13:25:48

1-el eltolva:
Stop 4226013
Phe 4938670
Leu 8650544
Ile 4703612
Met 1421147
Val 3903151
Ser 6864066
Pro 4211003
Thr 3892562
Ala 3197520
Tyr 2514510
His 2541719
Gln 3049123
Asn 3230810
Lys 4968635
Asp 1735428
Glu 2846826
Cys 2645042
Trp 1450349
Arg 3795352
Gly 4195085

kecske20 2011.03.07. 13:28:35

Megoldás: komment, első 2 betű nélkül:
4229297 4936156 8652212 4707113 1419910 3904313 6867552 4209185 3892548 3196552 2510652 2544819 3043507 3230271 4970475 1731580 2843714 2648913 1451891 3797276

nb · http://fersml.blog.hu 2011.03.07. 16:08:24

@Rankerz: ez a helyes mo. (a korábbiban az első sorbeli "C" a kommentben elrontotta, l. szimih név alatt)

Jöhet a név privátban a könyveléshez

nb · http://fersml.blog.hu 2011.03.07. 16:10:10

@kecske20: Jó megoldás, jöhet a név privátban a könyveléshez

nb · http://fersml.blog.hu 2011.03.07. 16:11:09

@marwellazure: nem jó, eggyel előtted jött a jó.

basecamp 2011.03.08. 13:12:28

TACGTAGAGGCACAG

------T(1)
---------A(2)
------C(1)
---------A(2)
------------G(3)
---/(0)
------A(1)
------G(1)
---------A(2)
---------G(2)
melyseg=3

nb · http://fersml.blog.hu 2011.03.08. 18:37:28

@basecamp: átfutottam, jónak tűnik, annyi, hogy a fa építésénél több if helyett egy if elseif elseif else elegánsabb lenne.

Logos 2011.03.08. 19:19:28

Heló!

Valaki el tudná részletesen magyarázni, hogy a következő kódrészlet hogy működik?

hanyadik_betu = (hanyadik_betu + 1) % 3;

if (!hanyadik_betu)
elso = jegy;
else if (!(hanyadik_betu - 1))
masodik = jegy;
else
{
harmadik = jegy;
printf ("%s", genetikai_kod (elso * 16 + masodik * 4 + harmadik));
}

Logos 2011.03.08. 19:25:52

Mellesleg nem tudom letölteni ftp-ről a Humán Genóm fájlt (amiben TCAG... betűk vannak).
Honnan tudnám megszerezni? Így sajnos nem tudom kipróbálni a programomat...

nb · http://fersml.blog.hu 2011.03.08. 19:42:52

@Logos: ezt próbáltad: ftp://ftp.ncbi.nlm.nih.gov/genomes/H_sapiens/CHR_02/hs_alt_Hs_Celera_chr2.fa.gz

nb · http://fersml.blog.hu 2011.03.08. 19:47:13

@Logos: itt gondolom az egy operandusú negáló opira gondolsz. Ami ugye ezt az ekvivalenciát jelenti kb.:

if(!valt) <-> if(valt == 0)

de hogy magamat is ellenőrizzem és Téged is rávezesselek a személyes tapasztalat erejére, előbb próbáld ezt a rávezető módosítást ki:

[morpheus@zion morpheus]$ more minta.txt
123456789
[morpheus@zion morpheus]$ gcc k.c -o k
[morpheus@zion morpheus]$ ./k <minta.txt

a triplet elso betuje a 1 volt
a triplet masodik betuje a 2 volt
a triplet harmadik betuje a 3 volt

a triplet elso betuje a 4 volt
a triplet masodik betuje a 5 volt
a triplet harmadik betuje a 6 volt

a triplet elso betuje a 7 volt
a triplet masodik betuje a 8 volt
a triplet harmadik betuje a 9 volt

k.c:

#include <stdio.h>
#include <unistd.h>
int
main (void)
{
// hányadik betűn állok?
int hanyadik_betu = -1;
// azon a helyen mit olvastam?
int elso = 0, masodik = 0, harmadik = 0, i = 0, jegy = 0;

while ((i = getchar ()) != EOF)
{

switch (i)
{

case 'T':
jegy = 0;
break;
case 'C':
jegy = 1;
break;
case 'A':
jegy = 2;
break;
case 'G':
jegy = 3;
break;
}

hanyadik_betu = (hanyadik_betu + 1) % 3;

if (!hanyadik_betu)
{
elso = jegy;
printf ("\na triplet elso betuje a %c volt\n", i);
}
else if (!(hanyadik_betu - 1))
{
masodik = jegy;
printf ("a triplet masodik betuje a %c volt\n", i);
}
else
{
harmadik = jegy;
printf ("a triplet harmadik betuje a %c volt\n", i);
}
}
}

Logos 2011.03.10. 09:29:29

@nb: igen, arról próbáltam, de a böngészőben csak tölt-tölt...
Viszont elkértem egy csoporttársamtól, így ki tudtam próbálni de szerintem így is vannak gondok vele: elég sokszor írja hogy Zavar az erőben pl. 84-nél, 67-nél stb.
A megoldás pedig nem hasonlít egyikre sem a poszton leírtak közül:

Stop 4326271
Phe 4935384
Leu 8648358
Ile 4703731
Met 1421717
Val 3903637
Ser 6860253
Pro 4211171
Thr 3893279
Ala 3196901
Tyr 2513262
His 2541121
Gln 3048082
Asn 3230641
Lys 4965661
Asp 1735715
Glu 2847545
Cys 2643507
Trp 1449041
Arg 3795592

Logos 2011.03.10. 09:37:57

@nb: A k.c-t is kipróbáltam, már nagyjából értem, hogy mi a lényege: maradékos osztásnál ahánnyal osztom a 'hanyadik_betu'-t, anni féle számot generál: pl. % 3 = 0, 1, 2. Aztán ismét nullázódik és kezdődik elölről.
Az if-ek közül pedig először a főág, majd az else if, aztán az else hajtódik végre egymás után - persze külön ciklusban (bár fejből így sem tudnám leprogramozni).

nb · http://fersml.blog.hu 2011.03.10. 10:41:12

@Logos: nem is kell, soha nem fogsz sem fejben, sem papíron programozni, ezért ezt nem is gyakoroljuk :)

viszont arra emlékezni fogsz, hogy ha pár keveset kell ciklikusan (most sokból sokszor 3-at) olvasni, akkor így csináld és majd ezt a kódot építed be. S ha ezt már 6-7 esetben ismétled, akkor majd megy "fejből" is.

nb · http://fersml.blog.hu 2011.03.10. 10:42:20

@Logos: gyanús, az eddigi tesztek során senki nem számolt be zavarról az erőben. Bevágod ide a forrásod?

Logos 2011.03.10. 17:44:21

@nb: a bevezető szöveget kivágtam...

#include <stdio.h>
#include <unistd.h>

char *amino_sav[] = {
"Stop",
"Phe",
"Leu",
"Ile",
"Met",
"Val",
"Ser", // 6.
"Pro",
"Thr",
"Ala",
"Tyr", // 10.
"His",
"Gln",
"Asn",
"Lys",
"Asp",
"Glu",
"Cys",
"Trp", // 18.
"Arg", // 19.
"Gly" // 20.
};

int genetikai_kod (int triplet)
{
int index = 0;

switch (triplet)
{
case 0: // Phe
case 1:
index = 1;
break;
case 2: // Leu
case 3:
case 16:
case 17:
case 18:
case 19:
index = 2;
break;
case 32: // Ile
case 33:
case 34:
index = 3;
break;
case 35: // Met
index = 4;
break;
case 48:
case 49:
case 50:
case 51:
index = 5;
break;
case 4:
case 5:
case 6:
case 7:
index = 6;
break;
case 20:
case 21:
case 22:
case 23:
index = 7;
break;
case 36:
case 37:
case 38:
case 39:
index = 8;
break;
case 52:
case 53:
case 54:
case 55:
index = 9;
break;
case 8:
case 9:
index = 10;
break;
case 10: // Stop
case 11:
index = 0;
break;
case 24:
case 25:
index = 11;
break;
case 26:
case 27:
index = 12;
break;
case 40:
case 41:
index = 13;
break;
case 42:
case 43:
index = 14;
break;
case 56:
case 57:
index = 15;
break;
case 58:
case 59:
index = 16;
break;
case 12: // Cys
case 13:
index = 17;
break;
case 14: // Stop
index = 0;
break;
case 15: // Trp
index = 18;
break;
case 28: // Arg
case 29:
case 30:
case 31:
index = 19;
break;
case 44: // Ser
case 45:
index = 6;
break;
case 46: // Arg
case 47:
index = 19;
break;
case 60: // Gly
case 61:
case 62:
case 63:
index = 20;
break;

default:
// csak tesztelesre a printf
printf ("Zavar az eroben %d-nel\n", triplet);
index = 0;
break;
}

return index;
}

// a betűket 3-asával "olvasom": nem kell cifrázni! egy ciklus
// elvégzi, amiben megjegyzem, hogy melyik hányadik betű volt
// aki ciklusban ciklusolgat, az már bénázik :)
int
main (void)
{

int j, GY[20];

// GYűjtő tömb kinullázása
for (j = 0; j < 20; j++)
GY[j] = 0;

int hanyadik_betu = -1;

int elso = 0, masodik = 0, harmadik = 0, i = 0, jegy = 0;

while ((i = getchar ()) != EOF)
{

switch (i)
{

case 'T':
jegy = 0;
break;
case 'C':
jegy = 1;
break;
case 'A':
jegy = 2;
break;
case 'G':
jegy = 3;
break;
}

hanyadik_betu = (hanyadik_betu + 1) % 3;

if (!hanyadik_betu)
elso = jegy;
else if (!(hanyadik_betu - 1))
masodik = jegy;
else
{
harmadik = jegy;
++GY[genetikai_kod ( elso * 16 + masodik * 4 + harmadik )];
}
}

for (j = 0; j < 20; j++)
printf("%s\t%d\n", amino_sav[j], GY[j]);
}

nb · http://fersml.blog.hu 2011.03.10. 18:20:07

@Logos: a parancssort, amit futtatsz csak egérrel kivágva karakteresen be tudod ide tenni, mert ugye a 3*16+3*4+3*1=63 miatt a számok 0-63-ig lehetnének elvileg...

Logos 2011.03.10. 21:21:26

@nb: $ ./amino <hs_alt_Hs_Celera_chr2.fa
Aztán:
(ezekből nagyon sok van, nem is fér ki az egész a képernyőre:)

Zavar az eroben 84-nel
Zavar az eroben 84-nel
Zavar az eroben 84-nel
Zavar az eroben 84-nel
Zavar az eroben 64-nel
Zavar az eroben 76-nel
Zavar az eroben 69-nel
Zavar az eroben 67-nel
Zavar az eroben 66-nel
Zavar az eroben 67-nel
Zavar az eroben 78-nel

(itt pedig az aminosvak száma van...)

Logos 2011.03.10. 21:26:44

Én sem értem. A kimenetet átirányítottam egy fájlba, rengetegszer van "Zavar", legtöbbet a 84-et írja ki.

Logos 2011.03.10. 21:30:57

Mindenesetre majd próbálkozom még vele, de mivel otthon nincs net, így leghamarabb csak jövőhét szerdán tudok csak válaszolni. Azért köszönöm a segítséget.
süti beállítások módosítása