Procesarea limbajului natural

Nu esti logat.

Laboratorul 1

(Deadline: 18.11.2018 23:59:59)

Daca nu sunteti logati exercitiile nu se mai afiseaza.

Instalare Python

In cadrul laboratorului vom lucra cu Python 3. In principiu puteti folosi orice versiune de Python 3 dar nu si de Python 2 (2.7.*) deoarece riscati sa nu puteti rula exemplele de laborator. Puteti downloada Python de pe site-ul oficial.

In cazul in care nu aveti acces la Python pe calculator sau laptop puteti folosi consola online pentru Python. Scrieti codul in panoul din stanga, apasati pe butonul Execute si vedeti rezultatul in dreapta.

Diferente intre Python 2 si Python 3

Mai jos aveti un tabel cu cateva diferente intre cele doua versiuni:

Puteti citi mai mult in acest articol despre diferentele dintre Python 2 si 3.

Python 2Python 3
Pentru afisare, print poate fi folosita ca instructiune fara paranteze: print "ceva" Se putea apela si cu paranteze dar nu era vazuta ca functie. Interpretorul considera ca instructiunea print e apelata cu un tuplu. print("ceva", "altceva") In exemplu paranteza ("ceva", "altceva") este vazuta ca un tuplu. >>> print("ceva","altceva")
('ceva', 'altceva')
In Python 3, print este apelata ca functie. Deci va fi urmata mereu de o paranteza cu argumente: print("ceva", "altceva") In exemplu paranteza ("ceva", "altceva") este paranteza cu argumentele functiei. >>> print("ceva","altceva")
ceva altceva
Daca doream sa transmitem tuplul ("ceva", "altceva") ca argument: >>> print(("ceva","altceva"))
('ceva', 'altceva')
Operatorul / face impartire pe numere intregi (div) daca operanzii sunt numere intregi: >>> 5/2
2
Putem obtine rezultatul impartirii pentru numere rationale daca scriem si operanzii ca numere de tip float: >>> 5.0/2.0
2.5
Operatorul / face impartire pe numere float chiar daca scriem operanzii ca numere intregi: >>> 5/2
2.5
Pentru a realiza operatia div avem operatorul // >>> 5//2
2
nu exista clasa byte avem clasele byte si bytearray
raw_input() input()
In Python 2 range() returna o lista: >>> print(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> l=range(10)
>>> type(l)
<type 'list'>
In Python 3 range() este mai degraba asemanatoare cu functia xrange() >>> print(range(10))
range(0, 10)
>>> type(l)
<class 'range'>
etc.

Comentarii

Comentariile sunt de doua feluri:

Tipuri de date

Desi nu definim tipu de date pentru variabile, totusi exista tipuri de date care vin cu anumite proprietati si operatori.

Tipul int

Tipul int reprezinta numerele intregi. Teoretic, spre deosebire de alte limbaje, in Python nu avem limita superioara si inferioara pentru int, limitarea fiind data de memoria calculatorului. a=10**1000
print(a)
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Putem scrie intregii si in alta baza decat baza 10 (cea default), astfel:

  • baza 2 (binar): folosind prefixul 0b. De exemplu 0b10 (=2 in baza 10)
  • baza 8 (octal): folosind prefixul 0o. De exemplu 0o11 (=9 in baza 10)
  • baza 16 (hexazecimal): folosind prefixul 0x. De exemplu 0x1a (=26 in baza 10)

Daca alocam o valoare in alta baza unei variabile, nu inseamna si ca va fi afisata in acel stil: a=0o11
print(a)
va afisa tot 9.

Tipul float

Tipul float e folosit pentru reprezentarea numerelor rationale.

In momentul in care folosim punctul zecimal pentru a reprezenta un numar, ea este automat considerata float chiar daca valoarea sa reprezinta si un numar intreg in acelasi timp ( de exemplu 1 e vazut ca int, dar 1.0 e vazut ca float).

In cazul in care avem 0 de-o parte sau de cealalta a punctului zecimal, nu mai nevoie sa scriem si cifra zero. Astfel, .1 este de fapt 0.1, iar 1. este 1.0 .

Pentru numerele float putem folosi si scrierea stiintifica. De exemplu in scrierea 1.5e3, 1.5 se inmulteste cu 103, obtinand numarul float 1500.0 .

Spre deosebire de int, numerele float au totusi o limita: >>> import sys
>>> sys.float_info.max
1.7976931348623157e+308
>>> sys.float_info.min
2.2250738585072014e-308
>>> sys.float_info
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)

Tipul complex

Numerele complexe se scriu sub forma n1+n2j unde n1 si n2 sunt numere reale. >>> x=5+2j
>>> y=2+8j
>>> x+y
(7+10j)

Tipul boolean

Contine valorile True si False

Functia type()

Functia type() este folosita pentru a indica tipul de date al parametrului primit.

De exemplu:

print("tipul de date al valorii 5 este", type(5))
a=3
print("tipul de date al variabilei a este", type(a))
print("tipul de date al valorii 5.0 este",type(5.0))
print("tipul de date al valorii \"ceva\" este",type("ceva"))
print("tipul de date al valorii True este",type(True))

Va afisa:

tipul de date al valorii 5 este <class 'int'>
tipul de date al variabilei a este <class 'int'>
tipul de date al valorii 5.0 este <class 'float'>
tipul de date al valorii "ceva" este <class 'str'>
tipul de date al valorii True este <class 'bool'>
Cum verificam cu ajutorul functiei type() daca o anumita valoare e de un anumit tip dat? >>> type(3) is int
True
>>> type("sir") is str
True
>>> type("sir") is float
False

Variabile si constante

In Python variabilele nu se declara separat (cum se intampla in alte programe unde inainte de a folosi o variabila trebuia sa o definim impreuna cu tipul ei). O variabila isi incepe existenta in momentul in care o initializam. a=5
b=7
c=5+7
print(c)
va afisa 12.

Asignare multipla

Sunt doua tipuri de asignare multipla

  • Asignam aceeasi valoare mai multor variabile: a=b=c=d=1
  • Asignam valori diferite mai multor variabile:

    a,b,c=1,2,3

    In acest caz, a va avea valoarea 1, b valoarea 2 si c valoarea 3.

    Atentie, mai intai se face evaluarea expresiei din dreapta si apoi asignarea: a,b,c=1,2,3
    print(a,b,c)
    a,b=2*b,2*b
    print(a,b)
    Va afisa: 1 2 3
    4 4

    Intai se evalueaza 2*b cu valoarea curenta a lui b (2), obtinand rezultatul 4, si abia apoi se aloca valorile calculate lui a si b.

    Astfel, puteti interschimba usor variabile in python, prin: a,b=b,a

Constante?

In Python nu putem declara efectiv constante. Pur si simplu declaram variabile pe care apoi tinem minte sa nu le modificam. Ca sa ne dam seama usor cine ar trebui sa fie constanta si cine nu, vom folosi drept conventie denumirea constantelor in totalitate cu litere mari (de exemplu nu vom denumi o constanta abc sau Abc, ci ABC). ABC=3 Evident putem sa-i asignam mai tarziu o alta valoare; tine de programator sa aiba grija sa nu isi strice "constantele".

Totusi mai incolo, cand aprofundati Python, puteti folosi un hack pentru definirea constantelor (autor: Alex Martelli)

Operatori

Puteti intra pe urmatorul link pentru o lista a operatorilor.

Amintim doar cateva diferente fata de alte limbaje de programare:

Conversii

Avem conversii implicite: >>> 3==3.0
True
>>> 3==True
False
>>> 1==True
True
>>> 0==False
True
>>> True+3
4
>>> "a"+3
Traceback (most recent call last):
  File "<pyshell#57>", line 1, in <module>
    "a"+3
TypeError: Can't convert 'int' object to str implicitly
si conversii explicite: >>> type(2+3)
<class 'int'>
>>> float(2+3)
5.0
>>> int(2.5)
2
>>> "a"+str(3)
'a3'
>>> int("3")+2
5
>>>

Structuri de control:if...elif...else, while, for

a="ceva"
if (a == "ceva"):
    print("este")
else:
    print("nu este")
    
a=3
if (a > 10):
    print("a > 10")
elif (a <= 10):
    print("a <= 10")
elif type(a) is int:
    print("a intreg")
else:
    print("niciun caz validat")
    
a="abracadabra"
i=0;
nr=len(a)
while (i<nr-1 and a[i]<a[i+1]):
    print(a[i], end='')
    i=i+1
print()

for chr in a:
    print(chr, end=' ')

print("---")
for i in range(5,11): #numerele de la 5 la 10
    print (i)

print("---")
for i in range(11,5,-1): #ce va afisa? si de ce?
    print (i)
este
a <= 10
ab
a b r a c a d a b r a
---
5
6
7
8
9
10
---
11
10
9
8
7
6

Instructiunea break iese din bucla. Instructiunea continue sare peste restul instructiunilor din bucla si trece direct la noua iteratie.

Expresii conditionale

Sunt de forma val_true if conditie else val_false. >>> x= "pozitiv" if 10>0 else "negativ"
>>> x
'pozitiv'

I/O de la tastatura

>>> a=input("a? ")
a? 5
>>> print(a)
5

Definirea functiilor

def sum_int(a,b):
        if(type(a)==int and type(b)==int):
                return a+b
        else:
                return "eroare" #de ce nu e o practica buna? cum putem rezolva?
print(sum_int("ceva", 10))
print(sum_int(5, 10))

Siruri

Sirurile se pot scrie atat intre apostrofuri cat si intre ghilimele (nu exista nicio diferenta intre cele doua moduri de scriere). Astfel, atat "ceva" cat si "ceva" sunt siruri valide.

Putem scrie un sir pe mai multe randuri: sir="""ceata
lui
pitigoi
cu
linii
noi"""
print(sir)
si va afisa: ceata
lui
pitigoi
cu
linii
noi

In schimb sir = ("ceata"
"lui"
"pitigoi"
"fara"
"linii"
"noi")
print(sir)
va afisa: ceataluipitigoifaraliniinoi

Accesarea elementelor sirului: >>> sir="abcdef"
>>> sir[0]
'a'
>>> sir[1]
'b'
>>> sir[-1]
'f'
>>> sir[2:4]
'cd'
>>> sir[:4]
'abcd'
>>> sir[2:]
'cdef'
>>> sir[:]
'abcdef'
>>> sir[-2:]
'ef'
>>> sir[:-2]
'abcd'
>>> sir[-4:-2]
'cd'
>>> sir[3:-2]
'd'
>>> a=2
>>> sir[a:5]
'cde'
>>> sir[0:100]
'abcdef'
>>>"ab" in "xaby"
True
>>> sir="abcde"
>>> sir[::-1]
'edcba'

Cateva functii si metode utile specifice sirurilor:

Functia len()
>>> len("abc")
3
Metodele upper(), lower() si title()
>>> "AbcDe".lower()
'abcde'
>>> "AbcDe".upper()
'ABCDE'
>>> "AbcDe".title()
'Abcde'
Metodele lstrip(), rstrip() si strip()
>>> "   a".lstrip()
'a'
>>> "a   ".rstrip()
'a'
>>> "   a   ".strip()
'a'
>>> "+++a".lstrip("+")
'a'
>>> "+++---+-a".lstrip("+-")
'a'
Metodele startswith(), endswith() si find()
>>> "hapciu".startswith("ha")
True
>>> "hapciu".startswith("ham")
False
>>> "hapciu".endswith("ciu")
True
>>> "hapciu".endswith("piu")
False
>>> "hapciu".find("pc")
2
>>> "car cu fan".find("ac")
-1
Metodele isalpha(), isdigit() si isalnum()
>>> "hapciu".isdigit()
False
>>> "hapciu".isalpha()
True
>>> "hapciu".isalnum()
True
>>> "hap123".isalnum()
True
>>> "123".isdigit()
True
>>> "hap123".isdigit()
False

Puteti gasi mai multe metode in acest tutorial despre tipul string din python

Liste

In Python, pentru colectiile de elemente vom folosi liste. Acestea pastreaza proprietatile vectorilor (arrays) din alte limbaje. Intr-o lista putem avea elemente de tipuri diferite.

Crearea unei liste:

Accesarea elementelor unei liste se face ca si la siruri

Operatii rapide cu liste

>>> l1=[2,3,4]
>>> l2=[5,6]
>>> l3=l1+l2
>>> l3
[2, 3, 4, 5, 6]
>>> l4=2*l1
>>> l4
[2, 3, 4, 2, 3, 4]

Functii si metode utile pentru liste

>>> l=["a", "b","c","d"]
>>> del l[1]
>>> l
['a', 'c', 'd']
>>> l.append("e")
>>> l
['a', 'c', 'd', 'e']
>>> l.remove("c")
>>> l
['a', 'd', 'e']
>>> l[1:2]=["x","y","z"]
>>> l
['a', 'x', 'y', 'z', 'e']
>>> len(l)
5

Parcurgerea unei liste

Tupluri

Sunt ca si listele, dar immutable (nu le putem schimba continutul). Sescriu intre paranteze rotunde t=(1,2,3).

Dictionare

Sunt formate din perechi de forma cheie:valoare.

Definirea unui dictionar: >>> d={"a":10, "b":20, "c":30, "d":40}
>>> d
{'c': 30, 'd': 40, 'a': 10, 'b': 20}
>>> dictVid={}
>>> dictVid
{}

Metode utile >>> d
{'c': 30, 'd': 40, 'a': 10, 'b': 20}
>>> d.keys()
dict_keys(['c', 'd', 'a', 'b'])
>>> d["a"]
10
>>> d.values()
dict_values([30, 40, 10, 20])
>>> d["a"]=123
>>> d
{'c': 30, 'd': 40, 'a': 123, 'b': 20}
>>> len(d)
4
>>> d.items()
dict_items([('c', 30), ('d', 40), ('a', 123), ('b', 20)])
>>> d["z"]=17
>>> d
{'c': 30, 'd': 40, 'a': 123, 'z': 17, 'b': 20}
>>> del d["z"]
>>> d
{'c': 30, 'd': 40, 'a': 123, 'b': 20}
>>> d.clear()
>>> d
{}

Parcurgerea unui dictionar: d={"a":10, "b":20, "c":30, "d":40}
for k in d.keys():
    print ("d[{}] = {}".format(k,d[k]))
    
for (k, v) in d.items():
    print ("d[{}] = {}".format(k,v))

Pentru ambele foruri se va afisa: d[a] = 10
d[b] = 20
d[c] = 30
d[d] = 40

Matrici

Nu avem un tip caracteristic. Folosim liste de liste.

>>> m=[[3,0,1],[2,2,1]]
>>> m[1][1]
2
>>> m[1]
[2, 2, 1]

Cerintele PEP 8 (cod bine structurat si stilizat)

PEP este abrevierea pentru Python Enhancement Proposals. Exista destul de multe PEPs pe care le puteti vizualiza pe site-ul oficial Python

Va recomand sa urmati in exercitii, teme si viitoare proiecte cerintele PEP8. Cu toate ca programul vostru va rula in continuare fara aceste cerinte, nu va fi la fel de usor de urmarit si inteles. Se va da un bonus la final de semestru pentru cei care au urmarit cerintele PEP 8.

Puteti sa va verificati codul online pentru greseli de stil folosind pep8 online checker

Tema