User Tools

Site Tools


aplicatii-practice

Aplicații practice

Până acum am învățat elementele de bază ale limbajului Python. Ca să facem aplicații utile, nu are rost să implementăm de la zero toată funcționalitatea, este mai comod să folosim biblioteci existente. Unele vin la pachet cu Python, altele se instalează separat. În acest capitol vom explora câteva biblioteci și vom face exerciții cu ele.

Pentru a instala biblioteci suplimentare pe Windows vom folosi pachetele de aici.

funcția open

Funcția open este “builtin”, adică poate fi folosită oriunde fără un import prealabil. Primește ca argument numele unui fișier, și, opțional, al doilea argument este modul în care să deschidă fișierul (rb și rt pentru citire binar/text, wb și wt pentru scriere binar/text). Vom folosi versiunile binare pentru că funcționează consecvent pe toate platformele. open returnează un obiect de tip fișier cu următoarele metode:

  • read([size]) citește din fișier, primește ca argument opțional un număr maxim de bytes de citit, iar fără argument citește până la sfârșit.
  • write(str) scrie în fișier, primește ca argument un șir de caractere.
  • close() închide fișierul, și este preferabil să o apelăm explicit, chiar dacă fișierul se va închide când se termină programul.
>>> f = open('file.txt', 'wb')
>>> f.write('foo')
>>> f.write('bar')
>>> f.close()
>>> g = open('file.txt', 'rb')
>>> g.read(2)
'fo'
>>> g.read()
'obar'
>>> g.close()

re (expresii regulate)

Expresiile regulate (modulul re ) sunt folosite pentru a căuta eficient șiruri de caractere într-un text. Avem la dispoziție un limbaj pentru a descrie șirul de caractere căutat. De exemplu, secvența \d înseamnă cifră, \s înseamnă spațiu, + înseamnă că elementul anterior trebuie să apară cel puțin o dată. Sunt mai multe secvențe disponibile și combinațiile sunt nelimitate. Urmează un exemplu care extrage toate numerele (secvențele de una sau mai multe cifre alăturate) dintr-un text.

>>> import re
>>> text = "ana are 2 mere, primește 5, cumpără 10 și în final are 17."
>>> re.findall(r"\d+", text)
['2', '5', '10', '17']

Am folosit notația r”” pentru expresia regulată. Este o constantă de tip string obișnuită, doar caracterele \ (backslash) nu sunt scoase din string.

random

Modulul random folosește un generator de numere pseudoaleatoare și ne oferă câteva metode comode pentru diverse operațiuni comune:

  • random() returnează un număr float din intervalul [0, 1).
  • randint(a, b) returnează un număr din intervalul închis [a, b].
  • choice(seq) returnează un element aleator din secvența seq.
  • sample(population, k) returnează k elemente unice din population.
  • uniform, triangular, expovariate, gammavariate, gauss, etc returnează numere random cu diverse proprietăți de distribuție.
>>> import random
>>> random.choice(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
'b'
>>> random.sample(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], 3)
['e', 'c', 'f']

csv

Formatul Comma-separated values este folosit pentru a reprezenta informații tabelare. Poate fi citit și scris de programe spreadsheet (Excel, Libre Office Spreadsheet, Google Docs spreadsheet, etc), și este popular, fiind ușor de citit și generat programatic. Din păcate nu există un standard formal, se folosesc mai multe variante pentru separatori, quoting și encoding de text. În Python vom folosi biblioteca csv pentru a citi și scrie documente CSV, și poate fi configurată să folosească diverse variante de format.

În exemplul următor, deschidem un fișier pentru citire, unul pentru scriere, și copiem liniile din primul fișier în al doilea, adăugând la început o coloală cu numărul curent.

>>> import csv
>>> f1 = open('data1.csv', 'rb')
>>> f2 = open('data2.csv', 'wb')
>>> reader = csv.reader(f1)
>>> writer = csv.writer(f2)
>>> n = 0
>>> for row in reader:
>>>     n += 1
>>>     writer.writerow([n] + row)
>>> f1.close()
>>> f2.close()

zipfile

Putem citi și scrie arhive în format Zip folosind biblioteca zipfile . Deschidem arhiva creând un obiect de tip ZipFile, primul argument este numele fișierului, iar al doilea, opțional, modul de acces, r pentru citire și w pentru scriere. Obiectul ZipFile are următoarele metode:

  • namelist() returnează o listă cu numele fișierelor din arhivă.
  • writestr(name, data) adaugă un fișier în arhivă. data este un string ce reprezintă conținutul fișierului.
  • read(name) citește și returnează conținutul unui fișier din arhivă sub formă de string.
>>> import zipfile
>>> zf = zipfile.ZipFile('foo.zip', 'w')
>>> bar = zf.writestr('bar.txt', 'hello world!')
>>> zf.close()
>>> zf = zipfile.ZipFile('foo.zip')
>>> for name in zf.namelist():
...     data = zf.read(name)
...     print [name, data]
...
['bar.txt', 'hello world!']
>>> zf.close()

json

Formatul JSON poate reprezenta orice combinație de numere, șiruri de caractere, liste, dicționare, și valoarea nulă. Deoarece este foarte simplu, poate fi ușor inspectat vizual, și există implementări pentru mai toate limbajele de programare.

{
    "titlu": "Acesta este un document JSON",
    "numar": 13,
    "lista": ["foo", "bar", 22],
    "dictionar": {
        "ultimate answer": 42,
        "alta lista": [
            "unu",
            "doi",
            {"contine": "un dictionar"}
        ]
    },
    "valoarea nula": null
}

În Python putem folosi biblioteca json pentru a citi și scrie documente JSON:

>>> import json
>>> data = {'foo': ['bar', 13, None], 'baz': 42}
>>> data_json = json.dumps(data)
>>> data_json
'{"foo": ["bar", 13, null], "baz": 42}'
>>> json.loads(data_json) == data
True

requests

Dacă vrem să folosim un serviciu online, este foarte posibil ca API-ul acelui serviciu să fie implementat prin HTTP , și atunci vom folosi o bibliotecă client. Există multe astfel de biblioteci în Python, noi vom folosi requests .

Download pentru Windows.

>>> import requests
>>> response = requests.get('http://httpbin.org/headers')
>>> response
<Response [200]>
>>> response.headers['Content-Type']
'application/json'
>>> response.content
'{\n  "origin": "109.99.235.83"\n}'
>>> response.json()
{u'origin': u'141.85.227.117'}

matplotlib

Vom folosi biblioteca matplotlib să desenăm grafice. La modul cel mai simplu, putem reprezenta o linie, cu liste de coordonate pentru axele X și Y. Biblioteca are o mulțime de posibilități de reprezentare pentru diferite tipuri de date.

Pentru a putea folosi matplotlib pe Windows, cel mai simplu este să instalăm Canopy, un set de programe ce conține Python și alte biblioteci utile. Instalarea se efectuează obișnuit (next, next) iar apoi suntem întâmpinați de un nou mediu de lucru. Putem folosi interpretorul din partea de jos a ecranului, sau putem scrie într-un fișier separat, în partea de sus. Programul din fișier se poate rula cu butonul verde, de tip play, din meniu.

>>> from matplotlib import pyplot
>>> data_x = [0, 1, 2, 3, 4]
>>> data_y = [2, 1, 2, 1, 2]
>>> pyplot.plot(data_x, data_y)
>>> pyplot.show()

Exerciții

  • Creați o arhivă zip. Folosiți Python pentru a verifica ce fișiere conține.

Soluție:

import zipfile
z = zipfile.ZipFile('.........', 'r')
print z.namelist()
  • Descărcați această pagină html. Folosind Python, afișați adresele către care trimite pagina. Considerați că orice șir de forma ”http://litere_sau_cifre_sau/” este o adresă.

Soluție:

import re
 
with open('site.html') as f:
    data = f.read()
 
print re.findall(r'http://[\w\.]+', data)
  • Calculați numărul aparițiilor cuvintelor (transformate în litere mici) dintr-un text citit din fișier. Afișați cele mai populare zece cuvinte. Exportați rezultatele într-un fișier în format JSON. [Optional] Afisati un grafic cu cele mai populare cuvinte si numarul aparitiilor.

Soluție:

import json
import re
 
import matplotlib.pyplot as plt
 
with open('sherlock.txt') as f:
    data = f.read()
 
cuvinte = re.split(r'[\s,\.]+', data)
aparitii = {}
 
for cuvant in cuvinte:
    if len(cuvant) < 3:
        continue
    cuvant = cuvant.lower()
    if cuvant in aparitii:
        aparitii[cuvant] += 1
    else:
        aparitii[cuvant] = 1
 
ordonate = sorted(aparitii.items(), key=lambda x: x[1], reverse=True)
for pereche in ordonate[:10]:
    print pereche[0]
 
with open('rezultate.json', 'w') as rez:
    json.dump(ordonate, rez)
 
cuv = [c[0] for c in ordonate[:10]]
apar = [c[1] for c in ordonate[:10]]
ypos = range(10)
 
plt.barh(ypos, apar, align='center')
plt.yticks(ypos, cuv)
plt.xlabel("Aparitii")
plt.title("Cele mai frecvente cuvinte")
 
plt.show()
  • Vom folosi un algoritm probabilistic pentru a calcula valoarea lui Pi. Pentru aceasta, vom genera puncte în mod aleator în interiorul unui pătrat de latură 1. Apoi vom număra punctele care se află în interiorul cercului de rază 1 ce poate fi înscris în pătrat. Raportul dintre numărul acestor puncte și numărul total de puncte reprezintă (aproximativ) raportul dintre aria cercului și a pătratului. De aici, obținem valoarea lui Pi.

Soluție:

import random
import math
 
PUNCTE = 1000000
 
interior = 0
i = 0
while i < PUNCTE:
    x = random.uniform(-1, 1)
    y = random.uniform(-1, 1)
 
    dist = math.sqrt(x*x + y*y)
    if dist <= 1:
        interior +=1
 
    i += 1
 
print "PI = %.2f" % (4 * float(interior) / PUNCTE)
  • Afișați graficul funcției descrisă de fișierul data.txt. Fiecare linie este o pereche de două numere zecimale, separate prin spațiu: valorile x și y.

Soluție:

import matplotlib.pyplot as plt
 
with open('data.txt') as f:
    data = f.read()
 
xs = []
ys = []
for line in data.splitlines():
    nums = line.split()
    x = float(nums[0])
    y = float(nums[1])
    xs.append(x)
    ys.append(y)
 
plt.plot(xs, ys)
plt.show()
  • Afișați un grafic care să arate cum ați generat punctele pentru a calcula valoarea lui Pi.

Soluție:

import matplotlib.pyplot as plt
import random
import math
 
PUNCTE = 100000
 
interior = 0
xs_in = []
ys_in = []
xs_out = []
ys_out = []
i = 0
while i < PUNCTE:
    x = random.uniform(-1, 1)
    y = random.uniform(-1, 1)
 
    dist = math.sqrt(x*x + y*y)
    if dist <= 1:
        interior +=1
        xs_in.append(x)
        ys_in.append(y)
    else:
        xs_out.append(x)
        ys_out.append(y)
 
    i += 1
 
print "PI = %.2f" % (4 * float(interior) / PUNCTE)
 
plt.scatter(xs_in, ys_in, alpha=0.5, c='green')
plt.scatter(xs_out, ys_out, alpha=0.5, c='blue')
plt.show()
aplicatii-practice.txt · Last modified: 2013/12/27 11:51 by mihneadb