# 3. O introducere informală în Python

În exemplele următoare, intrările și ieșirile se deosebesc prin prezența, respectiv prin absența prompturilor (>>> și …): ca să probați un exemplu, va trebui să tastați tot ce urmează după promptul lui, atunci când vă apare promptul; liniile care nu încep cu un prompt fac parte din ieșirea interpretorului. Țineți seama de faptul că prezența promptului secundar de unul singur pe o linie dintr-un exemplu înseamnă că trebuie să introduceți o linie goală; prin aceasta se încheie o comandă de mai multe linii.

Folosiți butonul „Copy” (acesta apare în colțul din dreapta-sus atunci când deplasați cursorul ori dați clic oriunde pe suprafața casetei exemplului), care șterge prompturile și elimină afișările de rezultate, pentru a copia și a insera liniile de cod ale exemplelor în interpretorul dumneavoastră.

Multe din exemplele acestui manual, inclusiv cele introduse la promptul interactiv, includ comentarii. Comentariile încep în Python cu caracterul haștag, `#`, și țin până la finalul liniei fizice. Un comentariu poate apărea la început de linie, în continuarea unui spațiu gol sau a codului, dar nu în interiorul unui șir de caractere. Un caracter haștag aflat în interiorul unui șir de caractere este un simplu caracter haștag. Deoarece comentariile sunt destinate clarificării codului și nu sunt interpretate de Python, le puteți omite atunci când veți tasta exemplele.

Câteva exemple

    # acesta este primul comentariu
    sâc = 1   # iar acesta este cel de-al doilea comentariu
              # ... și acum un al treilea!
    text = "# Acesta nu e un comentariu pentru că este pus între ghilimele."

## 3.1. Folosind Python-ul pe post de calculator

Haideți să încercăm niște comenzi simple în Python. Porniți interpretorul și așteptați să apară promptul principal, `>>>`. (N-ar trebui să dureze mult.)

### 3.1.1. Numere

The interpreter acts as a simple calculator: you can type an expression into it and it will write the value. Expression syntax is straightforward: the operators `+`, `-`, `*` and `/` can be used to perform arithmetic; parentheses (`()`) can be used for grouping. For example:

    >>> 2 + 2
    4
    >>> 50 - 5*6
    20
    >>> (50 - 5*6) / 4
    5.0
    >>> 8 / 5  # împărțirea întoarce întotdeauna numere în virgulă mobilă
    1.6

Numerele întregi (precum `2`, `4`, `20`) sunt de tipul `int`, cele cu parte fracționară (cum ar fi `5.0`, `1.6`) de tipul `float`. Vom reveni ulterior la tipurile numerice în tutorial.

Împărțirea (`/`) întoarce întotdeauna un număr în virgulă mobilă. Pentru a găsi partea întreagă la împărțirea cu rest, cu alte cuvinte, pentru a obține un rezultat întreg al împărțirii va trebui să folosiți operatorul `//`; pentru calculul restului, utilizați-l pe `%`:

    >>> 17 / 3  # împărțirea obișnuită întoarce un număr în virgulă mobilă
    5.666666666666667
    >>>
    >>> 17 // 3  # împărțirea cu rest elimină partea fracționară
    5
    >>> 17 % 3  # operatorul % întoarce restul împărțirii
    2
    >>> 5 * 3 + 2  # câtul * împărțitorul + restul
    17

În Python, puteți folosi operatorul `**` pentru a calcula puteri [1]:

    >>> 5 ** 2  # 5 la pătrat
    25
    >>> 2 ** 7  # 2 la puterea a 7-a
    128

Semnul egal (`=`) se folosește pentru a atribui o valoare unei variabile. După aceasta, nu se se va afișa nimic până la apariția următorului prompt interactiv:

    >>> lățime = 20
    >>> lungime = 5 * 9
    >>> lățime * lungime
    900

Dacă o variabilă nu este „definită” (nu i s-a atribuit o valoare), atunci când veți încerca să o folosiți vi se va semnala o eroare:

    >>> popescu  # încercați să accesați o variabilă nedefinită
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'popescu' is not defined

Folosirea numerelor în virgulă mobilă are suport complet; operatorii cu operanzi de tipuri diferite vor converti operandul întreg la un operand în virgulă mobilă corespunzător:

    >>> 4 * 3.75 - 1
    14.0

În modul interactiv, ultima expresie afișată va fi atribuită variabilei `_`. Ceea ce înseamnă că, atunci când folosiți Python-ul drept calculator de birou, este cumva mai ușor să continuați calculele lungi, ca de exemplu:

    >>> taxele = 12.5 / 100
    >>> prețul = 100.50
    >>> prețul * taxele
    12.5625
    >>> prețul + _
    113.0625
    >>> round(_, 2)
    113.06

Această variabilă trebuie considerată ca fiind doar-de-citit de către utilizator. Nu-i atribuiți în mod explicit nicio valoare — dacă o veți face, atunci veți fi definit o variabilă locală, independentă, cu același nume, care va masca variabila predefinită în limbaj cu tot cu purtarea ei magică.

În afară de `int` și de `float`, Python-ul suportă și alte tipuri de numere, precum `Decimal` și `Fraction`. De asemeni, Python-ul are suport predefinit pentru numerele complexe și folosește sufixul `j` sau `J` pentru a desemna partea imaginară (ca în `3+5j`).

### 3.1.2. Text

Python-ul poate manipula textul (reprezentat de tipul `str`, așa-numitele „șiruri de caractere”; de la englezescul string, la singular) la fel de bine ca numerele. Acesta include caractere precum „`!`”, cuvinte cum ar fi „`iepure`”, nume ca „`Paris`”, propoziții de felul lui „`Te ajut eu.`”, șamd. „`Uraa! :)`”. Toate acestea pot fi încadrate fie de ghilimele simple (`'...'`) fie de ghilimele duble (`"..."`), cu același rezultat [2]. Exemplul care urmează folosește referințe intraductibile la scheciurile Monty Python. Astfel, apar expresiile spam eggs și Paris rabbit got your back.

    >>> 'cărniță oușoare'  # ghilimele simple
    'cărniță oușoare'
    >>> "Paris iepurașul ți-apără sălașul :)! Uraa!"  # ghilimele duble
    'Paris iepurașul ți-apără sălașul :)! Uraa!'
    >>> '1975'  # cifrele și numerele dintre ghilimele simple sunt șiruri de caractere
    '1975'

Ca să citați ghilimelele (simple sau duble), trebuie să le „salvați” (de la englezescul escape; vom utiliza constructele: caracter escape, secvență escape, a escapa și derivate ale lor, întâlnite în literatura de specialitate) prefixându-le cu `\`. Altfel, puteți încadra textul respectiv cu celălalt tip de semne de punctuație pentru citare:

    >>> 'McDonald\'s'  # folosim \' ca sa inserăm ghilimele simple...
    "McDonald's"
    >>> "McDonald's"  # ...sau folosim ghilimelele duble
    "McDonald's"
    >>> '"Da," ziseră ei.'
    '"Da," ziseră ei.'
    >>> "\"Da,\" ziseră ei."
    '"Da," ziseră ei.'
    >>> '"Omu\' nostru," spuseră ei.'
    '"Omu\' nostru," spuseră ei.'

În interpretorul de comenzi Python, rezultatul afișării unui șir de caractere poate să difere mult de definiția șirului de caractere. Funcția `print()` produce o afișare lizibilă a acestuia, omițând ghilimele care îl încadrează și tipărind caracterele escape, respectiv caracterele speciale:

    >>> s = 'Prima linie.\nA doua linie.'  # \n înseamnă linie nouă
    >>> s  # fără print() caracterele speciale vor fi inserate în șir
    'Prima linie.\nA doua linie.'
    >>> print(s)  # cu print() caracterele speciale vor fi interpretate, deci \n va produce o linie nouă
    Prima linie.
    A doua linie.

Dacă nu doriți să fie interpretate drept caractere speciale caracterele prefațate cu `\`, atunci puteți utiliza șirurile brute (de la englezescul raw) de caractere adăugând un `r` înaintea ghilimelelor simple de început:

    >>> print('C:\prenume\nume')  # aici \n înseamnă linie nouă!
    C:\prenume
    ume
    >>> print(r'C:\prenume\nume')  # remarcați r-ul dinaintea ghilimelelor
    C:\prenume\nume

Există o subtilitate vizavi de șirurile brute de caractere: un șir brut de caractere nu se poate termina cu un număr impar de caractere `\`; vedeți rubrica FAQ/IFF (întrebări formulate frecvent) pentru mai multe informații și tehnici de evitare a dificultăților.

Valorile literale (de la englezescul literals; vom folosi și constructele: literal, literale, întâlnite în literatura de specialitate) șir-de-caractere se pot întinde pe mai multe linii. Pentru aceasta puteți utiliza semne de citare triple: `"""..."""` sau `'''...'''`. Caracterele sfârșit-de-linie sunt incluse automat în șirul de caractere, ceea ce poate fi evitat prin adăugarea unui `\` la final de linie. În exemplul următor, caracterul linie-nouă inițial nu va fi inserat:

    >>> print("""\
    ... Mod de folosință: comanda [OPȚIUNI]
    ...      -h                   Afișati acest mesaj de utilizare
    ...      -H numele_gazdei     Numele gazdei la care vreți să vă conectați
    ... """)
    Mod de folosință: comanda [OPȚIUNI]
         -h                   Afișati acest mesaj de utilizare
         -H numele_gazdei     Numele gazdei la care vreți să vă conectați

    >>>

Șirurile de caractere pot fi concatenate (lipite unul de celălalt) cu operatorul `+`, respectiv repetate cu operatorul `*`:

    >>> # 'un' de 3 ori, urmat de 'ium'
    >>> 3 * 'un' + 'ium'
    'unununium'

Două sau mai multe literale șir-de-caractere (adică șiruri de caractere încadrate de semne de citare), odată ce sunt plasate unul lângă celălalt, vor fi concatenate automat:

    >>> 'Py' 'thon'
    'Python'

Această caracteristică este utilă mai ales atunci când intenționați să porționați șirurile lungi de caractere:

    >>> textul = ('Puneți mai multe șiruri de caractere între paranteze '
    ...           'pentru ca ele să fie îmbinate.')
    >>> textul
    'Puneți mai multe șiruri de caractere între paranteze pentru ca ele să
    fie îmbinate.'

Această tehnică funcționează numai cu valori literale, deci nu cu variabile și nici cu expresii:

    >>> prefixul = 'Py'
    >>> prefixul 'thon'  # nu concatenăm o variabilă cu o valoare literală
      File "<stdin>", line 1
        prefix 'thon'
               ^^^^^^
    SyntaxError: invalid syntax
    >>> ('un' * 3) 'ium'
      File "<stdin>", line 1
        ('un' * 3) 'ium'
                   ^^^^^
    SyntaxError: invalid syntax

Dacă doriți să concatenați variabile ori o variabilă cu o valoare literală, atunci folosiți `+`-ul:

    >>> prefixul + 'thon'
    'Python'

Șirurile de caractere pot fi indexate (numerotate), primul caracter din șir având indicele 0. Nu există tipul caracter de sine stătător; un caracter este doar un șir de caractere cu lungimea 1:

    >>> cuvântul = 'Python'
    >>> cuvântul[0]  # caracterul de pe poziția 0
    'P'
    >>> cuvântul[5]  # caracterul de pe poziția 5
    'n'

Indici pot fi și numerele negative, dacă dorim să începem numărătoarea de la dreapta:

    >>> cuvântul[-1]  # ultimul caracter
    'n'
    >>> cuvântul[-2]  # penultimul caracter
    'o'
    >>> cuvântul[-6]
    'P'

Remarcați că, deoarece -0 este totuna cu 0, indicii negativi încep de la -1.

În afară de indexare, este suportată și tranșarea (felierea, de la englezescul slicing). În timp ce indexarea se folosește la obținerea de caractere individuale, tranșarea vă permite să extrageți un subșir de caractere:

    >>> cuvântul[0:2]  # caractere de la poziția 0 (cu) până la 2 (fără)
    'Py'
    >>> cuvântul[2:5]  # caractere de la poziția 2 (cu) până la 5 (fără)
    'tho'

Indicii unei tranșe au valori implicite utile; un indice de început, odată ce este omis, va fi implicit zero pe când un indice de final, omis, va lua în mod implicit ca valoare lungimea șirului de caractere în curs de tranșare.

    >>> cuvântul[:2]   # caractere de la început până la poziția 2 (fără)
    'Py'
    >>> cuvântul[4:]   # caractere de la poziția 4 (cu) până la sfârșit
    'on'
    >>> cuvântul[-2:]  # caractere de la penultimul (cu) până la final
    'on'

Remarcați că începutul este întotdeauna inclus, pe când finalul este întotdeauna lipsă. Această proprietate face ca `s[:i] + s[i:]` să fie egal întotdeauna cu `s`:

    >>> cuvântul[:2] + cuvântul[2:]
    'Python'
    >>> cuvântul[:4] + cuvântul[4:]
    'Python'

O metodă de a ține minte cum funcționează tranșatul este să vă imaginați indicii ca țintind între caractere, iar muchia stângă a primului caracter ca fiind numerotată cu 0. Atunci, muchia dreaptă a ultimului caracter al unui șir de caractere de n caractere va avea indexul n, ca de exemplu:

     +---+---+---+---+---+---+
     | P | y | t | h | o | n |
     +---+---+---+---+---+---+
     0   1   2   3   4   5   6
    -6  -5  -4  -3  -2  -1

Primul rând de numere dă poziția fiecăruia dintre indicii 0…6 ai șirului de caractere; cel de-al doilea rând pe cea a indicilor negativi corespunzători. Tranșa de la i la j constă din toate caracterele situate între muchiile notate cu i și respectiv cu j.

Pentru indicii nenegativi, lungimea unei tranșe este diferența indicilor, aceasta dacă amândoi sunt în limita valorilor permise. De exemplu, lungimea lui `cuvântul[1:3]` este 2.

Încercarea de a folosi un indice prea mare va conduce la o eroare:

    >>> cuvântul[42]  # cuvântul are numai 6 caractere
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    IndexError: string index out of range

Cu toate acestea, indicii care depășesc plaja valorilor permise vor fi rezolvați cu eleganță atunci când îi folosim la tranșare:

    >>> cuvântul[4:42]
    'on'
    >>> cuvântul[42:]
    ''

Șirurile de caractere Python nu pot fi modificate — ele sunt imutabile. De aceea, atribuirea de valori unei poziții indexate dintr-un șir de caractere va produce o eroare:

    >>> cuvântul[0] = 'J'
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'str' object does not support item assignment
    >>> cuvântul[2:] = 'py'
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'str' object does not support item assignment

Dacă este nevoie să modificați un șir de caractere, atunci va trebui să creați un șir de caractere nou:

    >>> 'J' + cuvântul[1:]
    'Jython'
    >>> cuvântul[:2] + 'py'
    'Pypy'

Funcția predefinită `len()` returnează lungimea unui șir de caractere. Șirul de caractere supercalifragilistic… este intraductibil:

    >>> s = 'supercalifragilisticexpialidocious'
    >>> len(s)
    34

Vezi și

Tipul secvență de text – str

  Șirurile de caractere sunt exemple ale tipurilor secvență de date și permit operațiile suportate în mod obișnuit de asemenea tipuri.

Metodele șirurilor de caractere

  Șirurile de caractere suportă un număr mare de metode privind transformările uzuale și căutarea.

f-șiruri

  Valori literale șir-de-caractere care includ expresii.

Sintaxa șirurilor de format

  Informații despre formatarea șirurilor de caractere cu `str.format()`.

Formatarea șirurilor de caractere în vechiul stil printf

  Vechile operații de formatare invocate atunci când șiruri de caractere îi sunt operand stâng operatorului `%` sunt descrise în detaliu aici.

### 3.1.3. Liste

Python-ul înțelege mai multe tipuri de date compozite, folosite la punerea laolaltă de valori diverse. Cel mai versatil dintre tipuri este lista, pe care o putem scrie în formă de șir încadrat de paranteze drepte și format din valori (itemi) separate între ele prin virgule. Listele pot conține itemi de tipuri diferite, însă cel mai adesea toți itemii sunt de același tip.

    >>> pătrate_perfecte = [1, 4, 9, 16, 25]
    >>> pătrate_perfecte
    [1, 4, 9, 16, 25]

Aidoma șirurilor de caractere (și a tuturor tipurilor secvență predefinite), listele pot fi atât indexate cât și tranșate:

    >>> pătrate_perfecte[0]  # indexarea returnează itemul corespunzător
    1
    >>> pătrate_perfecte[-1]
    25
    >>> pătrate_perfecte[-3:]  # felierea returnează o listă nouă
    [9, 16, 25]

De asemenea, listele suportă operații precum concatenarea:

    >>> pătrate_perfecte + [36, 49, 64, 81, 100]
    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Spre deosebire de șirurile de caractere, care sunt imutabile, listele sunt un tip mutabil, adică este posibil să le modificăm conținutul:

    >>> cuburi_perfecte = [1, 8, 27, 65, 125]  # ceva nu-i în regulă aici
    >>> 4 ** 3  # 4 la cub face 64, nu 65!
    64
    >>> cuburi_perfecte[3] = 64  # înlocuim valoarea greșită
    >>> cuburi_perfecte
    [1, 8, 27, 64, 125]

De asemenea, puteți adăuga itemi noi la sfârșitul listei, folosind metoda `list.append()` (vom discuta mai multe despre metode ulterior):

    >>> cuburi_perfecte.append(216)  # adăugăm cubul lui 6
    >>> cuburi_perfecte.append(7 ** 3)  # și cubul lui 7
    >>> cuburi_perfecte
    [1, 8, 27, 64, 125, 216, 343]

În Python, simpla atribuire nu copiază niciodată datele. Atunci când asignați o listă unei variabile, variabila se va referi la lista de față. Indiferent ce schimbare faceți în listă prin intermediul unei variabile, schimbarea va fi vizibilă prin intermediul tuturor celorlalte variabile care se referă la prima variabilă.:

    >>> rgb = ["Roșu", "Verde", "Albastru"]
    >>> rgba = rgb
    >>> id(rgb) == id(rgba)  # se referă la același obiect
    True
    >>> rgba.append("Alf")
    >>> rgb
    ["Roșu", "Verde", "Albastru", "Alf"]

Toate operațiile de feliere vor returna o listă nouă conținând elementele cerute. Ceea ce înseamnă că următoarea tranșare va returna o copie superficială (de la englezescul shallow copy) a listei:

    >>> rgba_corect = rgba[:]
    >>> rgba_corect[-1] = "Alfa"
    >>> rgba_corect
    ["Roșu", "Verde", "Albastru", "Alfa"]
    >>> rgba
    ["Roșu", "Verde", "Albastru", "Alf"]

Asignarea la tranșe este, de asemenea, posibilă iar aceasta poate schimba până și mărimea listei ori șterge toate elementele ei:

    >>> litere = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
    >>> litere
    ['a', 'b', 'c', 'd', 'e', 'f', 'g']
    >>> # înlocuim anumite valori
    >>> litere[2:5] = ['C', 'D', 'E']
    >>> litere
    ['a', 'b', 'C', 'D', 'E', 'f', 'g']
    >>> # acum să le ștergem
    >>> litere[2:5] = []
    >>> litere
    ['a', 'b', 'f', 'g']
    >>> # ștergem lista înlocuindu-i șirul de elemente cu o listă goală
    >>> litere[:] = []
    >>> litere
    []

Funcția predefinită `len()` se aplică și la liste:

    >>> litere = ['a', 'b', 'c', 'd']
    >>> len(litere)
    4

Este posibil să imbricăm liste (de la englezescul to nest; adică să creăm liste care conțin alte liste), ca de exemplu:

    >>> a = ['a', 'b', 'c']
    >>> n = [1, 2, 3]
    >>> x = [a, n]
    >>> x
    [['a', 'b', 'c'], [1, 2, 3]]
    >>> x[0]
    ['a', 'b', 'c']
    >>> x[0][1]
    'b'

## 3.2. Primii pași în programare

Evident, putem folosi Python-ul la sarcini mult mai complicate decât la a-l aduna pe 2 cu 2. De exemplu, putem construi primii termeni ai șirului lui Fibonacci după cum urmează:

    >>> # șirul lui Fibonacci:
    >>> # suma a doi termeni îl definește pe următorul
    >>> a, b = 0, 1
    >>> while a < 10:
    ...     print(a)
    ...     a, b = b, a+b
    ...
    0
    1
    1
    2
    3
    5
    8

Acest exemplu introduce mai multe caracteristici noi.

- Prima linie conține o atribuire multiplă: variabilele `a` și `b` primesc simultan noile valori 0 și 1. Atribuirea va fi folosită din nou pe ultima linie, ceea ce ne va arăta că toate expresiile din partea dreaptă a semnului atribuirii sunt evaluate înainte să se facă orice atribuire. Aceste expresii din partea dreaptă a atribuirii se evaluează de la stânga la dreapta.

- Execuția ciclului (de la englezescul loop; vom folosi și constructele: buclă, instrucțiune iterativă, instrucțiune de ciclare, întâlnite în literatura de specialitate) `while` se repetă atâta vreme cât condiția lui (în cazul nostru: `a < 10`) rămâne adevărată. În Python, la fel ca în C, orice număr întreg nenul are valoarea logică adevărat; zero, în schimb, are valoarea logică fals. Condiția buclei poate lua chiar și valoarea unei liste ori a unui șir de caractere, în fapt, pe cea a oricărei date de tip secvență; orice obiect de lungime nenulă are valoarea logică adevărat, pe când secvențele nule au valoarea logică fals. Testul folosit în exemplu este o simplă comparație. Operatorii tipici de comparație se notează la fel ca în C: `<` (mai mic decât), `>` (mai mare ca), `==` (egal cu), `<=` (mai mic sau egal cu), `>=` (mai mare sau egal cu) și `!=` (neegal cu).

- Corpul instrucțiunii iterative are indentare: indentarea este modul în care Python-ul grupează instrucțiuni (de la englezescul statements). La promptul interactiv, trebuie să tastați fie un Tab fie un spațiu gol pentru fiecare linie cu indentare. În practică, veți prepara inputurile mai complicate destinate Python-ului cu ajutorul unui editor de text; toate editoarele de text decente posedă sisteme de indentare automată. Atunci când o instrucțiune compozită este introdusă în mod interactiv, ea trebuie urmată de o linie goală pentru a indica faptul că s-a încheiat (dat fiind că parserul nu poate ghici când intenționați să tastați utima linie de cod). Remarcați că fiecare din liniile unui asemenea bloc de cod trebuie să aibă o indentare de aceeași lungime.

- Funcția `print()` înscrie valoarea argumentului(elor) primit(e). Această înscriere diferă de simpla inserare a expresiei pe care doriți să o scrieți (așa cum am procedat anterior la exemplele privind calculatorul de birou) prin modul în care prezintă argumentele multiple, cantitățile în virgulă mobilă, precum și șirurile de caractere. Șirurile de caractere sunt tipărite fără semne de citare, cu un spațiu inserat între itemi, astfel încât să puteți formata detaliile într-un mod plăcut, cum ar fi:

      >>> i = 256*256
      >>> print('Valoarea lui i este', i)
      Valoarea lui i este 65536

  Argumentul cuvânt-cheie end poate fi utilizat pentru a evita trecerea la o linie nouă după afișare, precum și atunci când dorim ca afișarea să se încheie cu un șir de caractere diferit de caracterul linie-nouă:

      >>> a, b = 0, 1
      >>> while a < 1000:
      ...     print(a, end=',')
      ...     a, b = b, a+b
      ...
      0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,

Note de subsol

[1]

Deoarece `**` este prioritar (de la englezescul higher precedence) față de `-`, `-3**2` va fi interpretată drept `-(3**2)` și astfel rezultatul va fi `-9`. Pentru a nu se întâmpla așa ceva și a obține `9`, puteți scrie `(-3)**2`.

[2]

Spre deosebire de alte limbaje, caracterele speciale precum `\n` au aceeași semnificație indiferent dacă sunt scrise cu ghilimele simple (`'...'`) ori cu ghilimele duble (`"..."`). Singura deosebire între cele două modalități este că atunci când întrebuințăm ghilimele simple nu este nevoie să escapăm ghilimelele `"` (cu toate că trebuie escapate ghilimelele simple `\'`) și viceversa.