Introducere în Pseudocod

Lecții de algoritmică, tips & tricks

Introducere în Pseudocod

Postby eni4ever » 15 Jul 2011, 20:12

Introducere în Pseudocod [adevăratul Pseudocod]

Acest topic tematic abordează întrebări precum :
  1. Ce este acest pseudocod ?
  2. Care sunt aromele de pseudocod și cum le recunoaștem?
  3. Putem să abordăm pseudocod-ul corect în comunitate ?
  4. Când și cum îl folosim în producție ?
  5. Referințe (?)

1. Ce este acest pseudocod ?

Vom răspunde la această întrebare cu o definiție mai neaoșă [2] :
dexonline wrote:s. n. (inform.) limbaj în proiectarea și documentarea programelor, prin grefarea unor reguli sintactice pe limbaj natural. (< engl. pseudocode)

Vom demonstra, pe baza unor observații de bun simț, de ce această definiție este, în cel mai bun caz, incompletă dacă nu eronată :
  1. "pseudocod - un limbaj". Etimologic, pseudocod = pseudo(grecesc pentru fals) + cod(latină(codex) pentru o notare cu elemente grafice). O limbă/limbaj natural(ă) presupune elemente de fonetică ceea ce, evident, pseudocod-ul nu are cum să le aibă fiind doar un "cod fals" cu elemente improprii.
  2. "[modalitate] grefarea unor reguli sintactice pe limbaj natural". Greșit, iar motivul va apărea evident imediat.
O definiție mai pertinentă este dată de wiktionary [3] :
wiktionary tradus în Română wrote:Pseudocodul reprezintă o descriere a unui algoritm destinat aplicațiilor PC ce folosește convențiile structurale ale limbajelor de programare, dar omite expunerea în detaliu a subrutinelor sau a sintaxei dependente de limbaj.

Pe baza acestei definiții, se poate înțelege că [1]:
  1. Pseudocodul reprezintă o exprimare în limbaj natural a unui algoritm de rezolvare a unei probleme
  2. Ca și componență, pseudocodul încearcă să elimine pe cât posibil detaliile neesențiale care pot conduce la îngreunarea înțelegerii problemei. Printre aceste detalii se pot aminti : tipuri de variabile, cod dependent de sistem, subrutine, etc.

De amintit este faptul că, datorită naturii sale de reprezentare ca exprimare în limbaj natural, cuvântul cheie "exprimare" implică opinii divergente ce țin de experiența fiecărui utilizator în parte. În acest sens, pseudocod-ul nu are standard de notare (aparține întregii gândiri programatorești și nici-unuia). El este prezent ca și instrument în manuale și lucrări științifice pentru a facilita principiul înțelegerii soluției/algoritmului înainte de a recurge la o implementare proprietară într-un limbaj de programare specific.

Pseudocodul rerezintă un echilibru între limbajul uzual, care impune un nivel ridicat de detalii ce-l face uneori greu de implementat, și cod sursă, care ridică inerenta problemă: în ce limbaj ? : C/C++, Delphi, ș.a.m.d. Prin urmare, găsirea acestui echilibru între ușurința la citire/asimilare și precizia informațiilor relativ la domeniul problemei este, de cele mai multe ori o sarcină netrivială. Ca și consecință a acestui aspect, pseudocod-ul adevărat se citește ușor, dar se scrie greu. [4]

Prin acest ultim paragraf se poate înțelege de ce grefarea nu este tocmai cuvântul potrivit pentru procedeu. Nu este suficientă o exprimare cursivă, etapizată a pașilor necesari soluționării sarcinii ci trebuie ca acești pași să aparțină unui registru special și anume cel al problemei și nu cel al implementării. [6]

2. Care sunt aromele de pseudocod și cum le recunoaștem?

În viziunea taoiștilor de Yin și Yang asupra realității, pseudocod-ul poate fi observat, în natură, în 2 arome existente :
  1. Pseudocod bun [4] :
    • Ignoră detaliile nenecesare (nu intră în detalii obsesive cu aspectul de sintaxă)
    • Nu evidențiază evidentul (ex. tipul variabilelor se poate citi din context, deci nu este necesar să fie precizat)
    • Consideră contextul adresat (un algoritm menit să explice bubblesort, de pildă, nu poate conține indicații precum "apel la bubblesort cu v")
    • Nu pierde din vedere modelul vizat (lucru ce ar îngreuna înțelegerea algoritmului)
    • Permite implementarea imediată în cod a pașilor descriși în secvențe [5]
    • Vizează echilibrul (citire <-> specificitate)
  2. Pseudocod rău [5] :
    • Include detalii specifice unui limbaj de programare anume (cum sunt problemele de la partea I de informatică de la bacalaureat)
    • Mută atenția pe modul în care codul final va fi scris și nu îl lasă pe scopul algoritmului în proiectarea soluției
    • Se pierde în detalii de codare (ex. explică ce returnează un apel la o funcție)
    • Nu poate fi transformat în comentarii schelet de nivel ridicat ce poate fi introdus într-o implementare concretă
Acum că am văzut ce este bun și ce nu este bun la o scriere în pseudocod, să observăm câteva exemple [6]:
(bun) Extrage urmatorul cuvant din linie
(slab) Seteaza cuvant pentru a obtine urmatoarea valoare

(bun) Adauga extensia fisierului la nume
(slab) nume = nume + extensie

Exemplu practic, extras din [5]:
Pseudocod rău :
  1. Incrementează numărul resursă cu 1
  2. Alocă o structură dlg cu malloc
  3. Daca malloc() a returnat NULL atunci returnează 1
  4. Apeleaza OSrsrc_init pentru a initializa o resursa a sistemului de operare
  5. *hRsrcPtr = numărul resursă
  6. Returnează 0

Ce o fi vrând să spună aici ? Acest exemplu încalcă toate motivele unui pseudocod bun și le evidențiază pe acelea pe care ne-am aștepta să le gasim la un pseudocod rău.

Pseudocod bun :
  1. Ține evidența resurselor utilizate
  2. Dacă o altă resursă este disponibilă
  3.    Alocă o structură de tip dialog
  4.    Dacă structura a putut fi alocată
  5.       Evidențiază faptul că încă o resursă este utilizată
  6.       Inițializează resursa
  7.       Stochează numărul resurse la locația arătată de apelant
  8.    Sfârșit Dacă
  9. Sfârșit Dacă
  10.  
  11. Returnează adevărat dacă o resursă nouă a fost creată, iar în caz contrar returnează fals

Acum apele sunt mai limpezi, corect prieteni? Așa și trebuie să rămână!

3. Putem să abordăm pseudocod-ul corect în comunitate ?

Aceasta este o întrebare din aceea monosilabică la care răspunsul ar fi mai potrivit dacă ar fi unul de tip explicativ. Răspuns direct : eu cred că da, iar în acest sens, propun următoarea notație de pseudocod în comunitate (eu voi încerca să țin cont de ea pentru uniformitate, dar este la liber arbitru dacă doriți și voi să-l urmați). Desigur, modificări argumentate sunt binevenite și încurajate.

S-a demonstrat că pentru înțelegerea unui algoritm sunt necesare doar 3 structuri [6]:
  1. Secvența - o suită de instrucțiuni, fiecare pe câte un rând individual cu indentare uniformă pe nivel (2 spații/nivel) care se execută în manieră incrementală, de sus în jos, în ordinea în care au fost scrise.
    Exemplu:
    1. Bate la ușă
    2. Deschide ușa
    3. Șterge pe picioare
    4. Intră la musafiri
  2. CâtTimp - ciclu cu test inițial
    Sintaxă :
    1. CâtTimp <condiție>
    2.   <secvență>
    3. Sfârșit CâtTimp

    Exemplu :
    1. CâtTimp butonul este apăsat
    2.   Crește temperatura cu 1 grad/secundă
    3. Sfârșit CâtTimp
  3. Dacă - Atunci - Altfel - o structură decizională
    Sintaxă:
    1. Dacă <condiție> atunci
    2.   <secvență1>
    3. altfel
    4.   <secvență2>
    5. Sfârșit Dacă

    Observație : ramura de altfel poate lipsi!
    Exemplu :
    1. Dacă se aud zgomote ciudate
    2.   scoate revolverul de sub pernă
    3. altfel
    4.   dormi în continuare
    5. Sfârșit Dacă

Pe lângă aceste 3 structuri de bază, mai se pot utiliza, după preferințe, următoarele 3:
  1. Repetă - Până când - structură repetitivă cu test final
    Sintaxă:
    1. Repetă
    2.   <secvență>
    3. Până când <condiție>

    Exemplu :
    1. Repetă
    2.   Alege orezul
    3. Până când bolul este gol
  2. Verifică - structură decizională de mai multe nivele
    Sintaxă:
    1. Verifică <expresie> pentru
    2.   <val1> :
    3.     <secvență1>
    4.   ...
    5.   <valn> :
    6.     <secvențăn>
    7.   ÎnCazContrar :
    8.     <secvență implicită>
    9. Sfârșit Verifică

    Exemplu:
    1. Verifică titlul invitatului pentru
    2.   domn :
    3.     servește-l cu o bere
    4.   domnișoară frumoasă :
    5.     arată-i dormitorul personal
    6.   domnișoară urâtă :
    7.     salută respectos
    8.   ÎnCazContrar :
    9.     ignoră invitat
    10. Sfârșit Verifică
  3. Pentru - un ciclu cu număr de iterații cunoscut
    Sintaxă :
    1. Pentru <granițele domeniului de acțiune>
    2.   <secvență>
    3. Sfârșit Pentru

    Exemplu :
    1. Pentru fiecare lună din an
    2.   Vizitează amantă
    3. Sfârșit Pentru

4. Când și cum îl folosim în producție ?

Prin producție mă refer la scriere efectivă de cod : există o modalitate prin care pseudocodul se poate integra într-o fază de dezvoltare ? Ei bine, Steve McConnell[5] propune una care mi se pare cel puțin interesantă.
El sugerează ca pseudocodul bun să fie integrat în cod sub formă de comentarii de nivel înalt, iar mai apoi, pe principiul iterațiilor, să se rafineze etapele îmbrăcând logica incremental cu implementare efectivă.
Pe baza acestei propuneri, el mai sugerează și o abordare etapizată în producție :
  1. Proiectează rutina în pseudocod
  2. Codează rutina peste pseudocod
  3. Verifică codul
  4. Realizează o curățare de termeni neadaptați
  5. Repetă dacă este cazul
Pe acest principiu se bazează într-o oarecare măsură și sistemul de extragere de documentație Doxygen.
Rămâne la latitudinea cititorului să implementeze, dacă consideră de cuviință, aceste indicații.

5. Referințe
[1] http://en.wikipedia.org/wiki/Pseudocode
[2] http://dexonline.ro/definitie/pseudocod
[3]http://en.wiktionary.org/wiki/pseudocode
[4]Naomi Nishimura, http://www.cs.cornell.edu/Courses/cs482/2003su/handouts/pseudocode.pdf
[5]Steve McConnell, Code Complete 2: A Practical Handbook of Software Construction
[6]http://users.csc.calpoly.edu/~jdalbey/SWE/pdl_std.html

Spor
6.33p / 3 votes
Image

"Rațiunea vine în umbre scurte numite suferințe." Victor Adăscăliței
"Bender: Anything less than immortality is a complete waste of time.
Zoidberg: Then suicide it is! Step into my office ..." Futurama S06E06
User avatar
eni4ever
DWord
 
Joined: 03 Jan 2010
Location: Timișoara
Status: 57.83

Return to Tutoriale

Who is online

Users browsing this forum: No registered users and 0 guests

cron