Fundamentele programării (III) - Python

Cel de-al treilea episod al serialului dedicat fundamentelor programării va prezenta detalii legate de modul în care sunt executate diverse operații. De asemenea, vom vedea cum putrem adăuga informații suplimentare care nu afectează deloc modul în care sunt executate programele, dar ajută la înțelegerea acestora.

Altfel de atribuiri

În cadrul episodului anterior am văzut cum putem modifica valoarea unei variabile cu ajutorul instrucțiunii de atribuire. Dar, toate atribuirile pe care le-am prezentat nu făceau decât să dea unei variabile o simplă valoare.

Limbajele ne permit mult mai mult. De exemplu, am putea să atribuim unei variabile valoarea altei variabile. Să considerăm următoarea secvență:

În urma executării acestor instrucțiuni, atât variabila a, cât și variabila b, vor avea valoarea 3. Instrucțiunea din linia 2 indică faptul că variabilei b trebuie să i se atribuie valoarea variabilei a. Cele două variabile sunt în continuare independente. Dacă am continua programul cu a = 5 doar valoarea variabilei a se va modifica; valoarea variabilei b va rămâne 3.

Să facem acum un mic exercițiu. Să presupunem că avem două variabile a și b care conțin două valori diferite (pentru exemplul nostru vom considera că acestea sunt 2 și 4). Dorim să scriem un program care schimbă între ele cele două valori. Cele două variabile vor fi declarate și inițializate astfel:

Evident, pentru a rezolva problema, am putea scrie:

Dar, să ne închipuim că dorim ca programul să funcționeze corect indiferent care sunt valorile inițiale (de exemplu, am putea presupune că ele sunt introduse de utilizator și în momentul scrierii programului nu știm care vor fi.

Având în vedere că tocmai am prezentat cum unei variabile i se poate stribui valoarea altei variabile, ne-am putea gândi la o soluție de genul:

Dar, să vedem ceva ce se întâmplă; inițial a are valoare 2 și b are valoarea 4. Prin instrucțiunea a = b variabilei a i se atribuie valoarea curentă a variabilei b, adică 4. Așa cum am spus în cadrul episodului anterior, valoarea 2 se pierde. Cea de-a doua instrucțiune face ca variabilei b să i se atribuie valoarea variabilei a; dar această valoare este acum 4, deci în urma executării instrucțiunii, valoarea variabilei b va fi tot 4. Astfel, ajungem să avem aceeași valoare pentru ambele variabile și nu am schimbat valorile între ele.

Am spus că variabilele pot fi privite ca fiind niște recipiente. Să ne imaginem că cele două variabile ar fi două pahare pline cu lichide diferite și dorim să schimbăm lichidele între ele. Pentru a putea muta lichidul dintr-un pahar în altul, va trebui să vărsăm lichidul dintr-un pahar pentru a face loc. În principiu, lichidul se pierde în acest mod. Dar, l-am putea vărsa într-un al treilea pahar, nu?

Atunci, pentru a schimba lichidele între ele, vom lua un al treilea pahar, vom turna în el lichidul din primul pahar, apoi vom turna în primul pahar lichidul din al doilea și, la final, vom turna în al doilea pahar lichidul din cel de-al treilea. Astfel, în primul pahar vom avea lichidul care a fost inițial în al doilea, iar în al doilea pahar vom avea lichidul care a fost inițial în primul.

Ne dăm seama destul de ușor că pentru a schimba valorile a două variabile, avem nevoie de o a treia variabilă (ajutătoare). Secvența care schimbă valorile ar putea fi:

Am declarat variabila c și am și inițializat-o. După cum se vede și la inițializare e la fel ca la atribuire. Putem inițializa o variabilă cu valoarea altei variabile.

Prima operație

Totuși, până acum doar am declarat variabile, le-am dat valori și ne-am jucat puțin cu ele. Dar, lucrăm cu un calculator; la un moment dat ar trebui să facem și niște calcule, nu? Deși pare că e cam târziu fiindcă suntem deja la al treilea episod, vom realiza acum prima adunare. Presupunem că două variabile au anumite valori pe care dorim să le adunăm și să păstrăm rezultatul într-o a treia variabilă. Nu e nicio mare filosofie, codul arată cam cum v-ați aștepta;

Nu e nicio surpriză, valoarea variabilei c va fi 6. Dar, vedem că am atribuit variabilei c altceva, nu o simplă valoare și nici valoarea unei alte variabile. Am cerut efectuarea unui calcul, a unei operații; descrierea acestei operații poartă denumirea de expresie. De fapt, și anterior am folosit tot expresii, dar foarte simple. Valoarea simplă este și ea o expresie, la fel și valoarea unei variabile.

Expresii

Expresille pot fi foarte complexe. Ele pot conține valori simple, valori ale unor variabile, operatori și multe altele. De exemplu, putem aduna trei numere, dintre care doar două sunt păstrate în variabile, iar al treilea este o valoare simplă:

Așa cum vă așteptați, putem realiza și alte operații matematice. Pentru scăderi și înmulțiri nu avem nicio surpriza. La împărțire lucrurile sunt mai complicate și vom reveni.

Pentru înmulțire, operatorul folosit este *; putem efectua o înmulțire astfel:

Putem combina operațiile și regulile matematice se aplică:

Valoarea variabilei c va fi 11. Dacă dorim să modificăm ordinea firească a operațiilor, putem folosi paranteze:

În acest caz valoarea variabilei c va fi 20. Putem avea și paranteze în paranteze, dar nu chiar ca la matematică. Nu folosim paranteze drepte sau acolade. Toate parantezele sunt rotunde:

De data aceasta c va avea valoarea 12. Prima dată se calculează valoarea a - 2; rezultatul este 0. Urmează înmulțirea valorii variabilei a cu acest rezultat fiindcă înmulțirile se efectuează înaintea adunărilor dacă nu sunt paranteze; noul rezultat este tot 0. Urmează adunarea între 3 și acest rezultat (obținem 3), iar apoi înmulțirea cu b care duce la rezultatul final: 12.

Împărțirea

Dacă împărțim numărul 3 la 2 spunem fie că rezultatul este 1.5, fie că obținem câtul 1 și restul 1. În Python avem două comportamente puțin mai ciudate. Dacă ar fi să facem o simplă împarțire în Python 2.7 (cea mai populară versiune de Python) vom obține rezultate diferite față de Python 3 (cea mai nouă versiune de Python).

Dacă împărțim două numere întregi, în Python 2.7,  rezultatul operației este câtul, iar operatorul folosit este /. Dacă unul dintre numere este cu zecimale, atunci rezultatul este și el cu zecimale, nu doar câtul. Să vedem un exemplu:

Valoarea variabilei c va fi 1. Dar, dacă avem:

valoarea variabilei c va fi 1.5. Rezultatul va fi cu zecimale, dacă cel puțin unul dintre cele două numere este cu zecimale. De exemplu, și în următorul caz rezultatul este tot 1.5:

La fel stau lucrurile în situația următoare:

Însă, în Python 3, lucrurile stau un pic mai normal. Dacă dorim să împărțim 3 la 2, vom obține 1.5.

Valoarea variabilei c nu va fi 1, cum era în cazul anterior când foloseam Python 2.7, ci 1.5. După cum puteți observa, nu mai trebuie să scriem 2.0 pentru a obține rezultatul cu zecimale.

Putem face experimente mai interesante. Încercați să vă dați seama ce valori vor avea variabilele în Python 2.7 și Python 3:

În Python, dacă scriem 2, numărul este întreg, dar dacă scriem 2.0 el este considerat cu zecimale (partea fracționară fiind 0). Pe baza acestei informații ne dăm seama destul de ușor că valoarea variabilei a va fi 1, iar celelalte trei vor avea valoarea 1.5, în Python 2.7. În Python 3, toate variabilele vor avea valoare 1.5.

Ni se oferă și posibilitatea de a afla restul împărțirii. Pentru aceasta vom folosi un alt operator, anume %. În situația:

valoarea variabilei c va fi 2.

Deși e oarecum bizar, operatorul % poate fi folosit și pentru numere cu zecimale. Rezultatul este tot un fel de rest; se calculează partea întreagă a împărțirii și rezultatul este dat de "ce rămâne". Să vedem un exemplu:

Valoarea variabilei c va fi 1.5. Partea întreagă a împărțirii este 3; pentru acest rezultat se "consumă" 7.5 din 9 și "rămâne" 1.5.

Operații logice

Putem efectua operații și cu variabilele booleene. Chiar dacă au doar două valori posibile, există operații care pot fi efectuate. În primul rând avem negația; este o operație prin care adevărul devine fals și falsul devine adevăr. Operatorul este not; să îl folosim în cele două posibile situații:

Valoarea variabilei c va fi False, iar cea a variabilei d va fi True.

Dar, avem și operații puțin mai complicate.

De exemplu, putem efectua o operație care să ne spună dacă două valori booleene sunt ambele adevărate. Operația se numește ȘI; mai riguros, ea este numită conjuncție. Să vedem un exemplu:

Probabil v-ați dat seama, operatorul este and. Valoarea variabilei d va fi True, iar cea a variabilei e va fi False.

O altă operație pe care o avem la dispoziție ne spune dacă cel puțin una dintre două valori booleene este adevărată. Operația se numește SAU; mai riguros, ea este numită disjuncție. De data aceasta operatorul este or.  Să vedem acum câteva variante:

Doar g va avea valoarea False, fiindcă atât c, cât și d, au valoarea False. e și f vor avea valoarea True fiindcă cel puțin una dintre cele două variabile asupra căreia este efectuată operația are valoarea True (ambele pentru e, doar prima pentru f).

Acest SAU logic nu prea seamănă cu cel pe care îl folosim natural. De exemplu, dacă spunem că vrem o rochie roșie sau albastră, vrem să spunem că rochia poate fi fie roșie, fie albastră. Nu vrem să spunem că rochia poate fi și roșie și albastră; nu vrem nici să spunem că dorim două rochii, una roșie și una albastră (deși poate nu ar deranja pe nimeni). Un alt exemplu ar fi când spunem că dorim banane sau portocale; vrem una dintre cele două variante, nu amândouă.

Există o operație logică al cărei rezultat ne spune dacă exact una dintre cele două valori booleene este adevărată. Rezultatul este False dacă ambele valori sunt True sau dacă ambele valori sunt False. Acest sau natural este numit SAU EXCLUSIV sau disjuncție exclusivă. Operatorul este ^; să vedem exemplul:

Doar f va avea valoarea True, fiindcă a are valoarea True și c are valoarea Falsee și g vor avea valoarea False fiindcă ambele variabile asupra căreia este efectuată operația au aceeași valoare (True pentru e, False pentru g).

Operații cu string-uri

Operatorul + poate fi utilizat și pentru string-uri. Aplicat asupra a două varioabile de tip String, operatorul duce la unirea acestora. De exemplu, rezultatul operației "alpha" + "beta" este "alphabeta".  Operația poartă denumirea de concatenare. Ne putem reaminti de o instrucțiune din programul din primul episod:

Aici avem o concatenare de trei string-uri.

Rezultatul concatenării unor string-uri are tipul string. În Python nu putem aplica operatorul + în cazul în care una dintre cele două valori nu are tipul string. Iată câteva exemple:

În codul de mai sus, valoarea variabilei e va fi ceva2, dar când vom încerca să adunăm variabila a cu variabila c sau variabila d, vom primi o eroare.

Operația de adunare a două string-uri poartă numele de concatenare, dar vom vorbi despre ea și mai multe operații cu string-uri în alte articole.

Atribuiri mai interesante

Ce-ați zice dacă o variabilă ar apărea de ambele părți ale semnului = ale unei instrucțiuni de atribuire. Următoarea secvență este validă, dar nu prea interesantă fiindcă nu se întâmplă nimic special:

Totuși, am putea avea o expresie în dreapta. De exemplu:

Dacă a = a + 1 ar fi fost o ecuație, așa ceva nu ar avea sens. Dar, instrucțiunea de mai sus se traduce astfel: preia valoarea variabilei a, adună 1 și pune rezultatul în variabila a. Inițial a are valoarea 1, adunăm 1 și obținem 2 și a primește valoarea 2. Faptul că acest lucru este posibil este foarte util. Vă mai amintiți exemplul cu variabila goluri_gazde care conține numărul golurilor înscrise de echipa gazdă într-un meci de fotbal. În momentul în care echipa gazdă marchează un gol, valoarea acestei variabile trebuie să devină mai mare cu 1. Am putea scrie:

De fapt, astfel de instrucțiuni sunt atât de des folosite, încât ni se oferă posibilitatea să o scriem și prescurtat. Următoarea instrucțiune este echivalentă:

Operația prin care valoarea unei variabile crește cu 1 este numită incrementare, iar operațiunea prin care valoarea unei variabile scade cu 1 este numita decrementare.

Pentru majoritatea operatorilor avem variante prescurtate: există -=, *=, /=, %=  și multe altele.

Despre spații

În cadrul diverselor secvențe de cod prezentate până acum ați văzut că, în cadrul instrucțiunilor, diverse elemente sunt separate prin spații. Aceste spații pot lipsi de cele mai multe ori și, în marea majoritate a cazurilor, putem pune oricâte spații.

Spațiul este obligatoriul doar dacă absența sa ar crea confuzii. De exemplu, nu există o mare diferență între a = 2  și a=2 , ambele variante fiind corecte. Putem pune și mai multe spații dacă dorim:

Nu arată foarte bine, dar este corect. De fapt, de cele mai multe ori modul în care utilizăm spațiile are rol estetic; ne ajută să vedem mai ușor codul.

O parte foarte importantă în Python o reprezintă lizibilitatea codului (posibilitatea de a-l citi ușor). Nu putem scrie o instrucțiune pe mai multe linii. Însă, dacă chiar suntem nevoiți, putem face acest lucru folosind caracterul \. Un exemplu ar fi:

Din nou, parcă nu am vrea să arate așa codul nostru, dar este permis. După cum vedeți, am folosit și multe linii și multe spații.

Simbolurile care nu se văd și sunt folosite pentru a separa diverse elemente poartă denumirea de caractere albe. Deocamdată am văzut că astfel de caractere sunt spațiile, taburile și marcajele de sfârșit de linie.

Trebuie precizat faptul că în interiorul string-urilor caracterele albe își păstrează semnificația. De exemplu, string-urile "a   b" și "a b" sunt diferite.

Comentarii

Uneori scriem cod pe care dorim să nu îl mai folosim deocamdată, dar poate vom avea nevoie în viitor. Putem marca acest cod astfel încât el să nu se execute. Porțiunile marcate astfel poartă denumirea de comentarii.

În Python avem două tipuri de comentarii. Pe o linie, putem folosi caracterul # și tot ce urmează după el este comentariu.

Putem folosi și comentarii pe mai multe linii. Vom marca începutul comentariului prin ''' și sfârșitul său tot prin '''.

Dacă ''' sau # apar în interiorul unui string, atunci își pierd semnificația. De exemplu = "a#a"  este o instrucțiune care inițializează string-ul s cu valoarea a#a. La fel, nu avem un comentariu în instrucțiunea s = "a'''a".

Dar, putem folosi comentariile nu numai pentru a elimina temporar cod, ci și pentru a-l explica. Când altcineva citește codul nostru, îi va fi mult mai ușor să înțeleagă dacă acesta conține explicații. Acel "altcineva" poate fi chiar persoana care a scris codul, o lună mai târziu. În multe cazuri ne va fi foarte greu să ne dăm seama ce și cum am vrut să facem.

Trebuie să fim puțin atenți în câteva situații. Să presupunem că avem următorul cod:

Să presupunem că nu mai avem nevoie de variabilele c și d. Am putea comenta liniile corespunzătoare:

Va urma

În cadrul următorului episod vom vedea cum programele pot lua anumite decizii în funcție de împrejurări.

Te-ar putea interesa și: