POGLAVLJE 2. IZVORNI TIPOVI PODATAKA

> ***“Wonder is the foundation of all philosophy,***
> inquiry its progress, ignorance its end.”
>
>

> -Michel de Montaigne
>
>

***'*2.1 Zaronimo**

Tipovi podataka. Ostavite sa strane svoj prvi Python program samo na minut i hajde da pričamo o tipovima podataka. U Python-u, svaka vrednost ima svoj tip podatka, ali Vi ne morate da deklarišete tip podataka varijabli. Kako to funkcioniše? Na osnovu svakog originalnog zadatka varijable, Python shvata koji je to tip i interno ga prati.

Python ima mnogo
izvornih tipova podataka. Evo onih bitnih:

1.     Booleans – ili su true (tačni) ili su false (netačni)

2.     Numbers – mogu biti celobrojna vrednost (1 i 2), zapis u pokretnom zarezu (1.1 i 1.2), razlomci (1/2 i 2/3) ili čak kompleksni brojevi.

3.     Strings – oni su sekvence Unicode karaktera, na primer HTML dokument.

4.     Bytes and
byte arrays – bitovi i nizovi bitova, na primer slika u JPEG formatu

5.     Lists – liste su uređene sekvence vrednosti

6.     Tuples – određene, nepromenljive sekvence vrednosti

7.     Sets – neuređeni skupovi vrednosti

8.     Dictionaries – neodređeni skupovi key-value parova

Naravno, postoji više tipova od ovoga. Sve je objekat u Python-u, znači imamo tipove kao što su moduli, funkcije, klase, metode, fajlovi pa čak i već sastavljeni kod. Već ste videli neke od ovih: moduli imaju imena, funkcije imaju docstrings, itd. Učićete o klasama u Classes & Iterators, i o fajlovima u Files.

Stringovi i bajtovi su sami po sebi dovoljno komplikovani zbog čega imaju zasebna poglavlja. Hajde da pogledamo prvo druge.

**2.2 Booleans**

Booleans sui ili True ili False. Python ima dve konstante, pametno nazvane True i False, koje mogu biti iskoriščene da Booleans-ima direktno dodele vredosti. Izrazi se takodje
mogu proceniti na Boolean vrednost. Ova “mesta” se zovu Boolean contexts.
Virtuelno, možete iskoristiti bilo koji izraz u Boolean context-u i Python će
da pokuša da odredi njegovu pravu vrednost. Različiti tipovi podataka imaju
različita pravila o tome koje vrednosti su true, a koje false u Boolean
context-u. (Ovo će imati više smisla jednom kada vidite čvrste primere kasnije
u ovom poglavlju.)

Na primer, uzmimo ovaj
               raise ValueError(‘number must be
non-negative’)

size je celobrojna vrednost, 0
je celobrojna vrednost i < je numerički operator.
Rezultat izraza size < 0 je uvek boolean. Možete
da proverite svoje znanje u Python interactive konzoli:

>>>
size = 1

>>> size
< 0

False

>>> size
= 0

>>> size
< 0

False

>>> size
= -1

>>> size
< 0

True

Zbog nekih zaostavljenih problema iz
Python-a 2, Booleans se mogu tretirati kao brojevi. 1 je True (tačno); 0 je
False (netačno).

>>> True
+ True

2

>>> True
– False

1

>>> True
\* False

0

>>> True
/ False

Traceback (most
recent call last):

File
"<stdin>", line 1, in <module>

ZeroDivisionError:
int division or modulo by zero

Ju, ju, ju! Ne radite to. Zaboravite da je
uopste pomenuto.

**2.3. Numbers**

Numbers (brojevi) su zakon. Ima ih toliko da
možete da birate. Python podržava i celobrojne brojeve i zapis u pokretnom
zarezu. Ne postoji tipska deklaracija po kojoj se razlikuju; Pzthon ih
razlikuje po prisutnosti ili odsutnosti decimalnog zareza.

>>>
type(1) ①

<class ‘int’>

>>>
isinstance(1, int) ②

True

>>> 1 + 1
③

2

>>> 1 +
1.0 ④

2.0

>>>
type(2.0)

<class
‘float’>

Možete koristiti type()
funkicju da proverite tip bilo koje vrednosti ili promenljive. Kao što možete
predpostaviti 1 je int.

Slično tome, možete korititi
instance() funkciju da proverite da li je vredost ili promenjiva odredjenog
tipa

Dodavanjem int-a int-u prisiljavamo
int.

Dodavanjem int-a float-u dobijamo
float. Python prisiljava int u float i vraca float kao rezultat.

**2.3.1. Prisiljavanje celobrojnih vrednosti u zapis u pokretnom zarezu I**
obrnuto

Kao žto ste mogli da vidite, neki operatori
(kao dodavanje) če “prisiliti” celobrojne vrednosti u zapis u pokretnom zarezu
ako je to potrebno. To možete i Vi sami da uradite.

>>> float(2) ①

2.0

>>>
int(2.0) ②

2

>>>
int(2.5) ③

2

>>>
int(-2.5) ④

-2

>>>
1.12345678901234567890 ⑤

1.1234567890123457

>>>
type(1000000000000000) ⑥

<class ‘int’>

Možete eksplicitno prisiliti
int u float pozivanjem float() funkcije.

Bez iznenađenja, takođe možete prisiliti float u int pozivanjem
int() funkcije.

Funkcija int() će se iseći, a ne zaokružiti.

Funkcija int() će iseći negativne brojeve prema 0. To je prava
funkcija skraćivanja, ne funkcija koja vraca manju ili jednaku celobrojnu
vrednost napomenute vrednosti ili izraza.

Zapis u pokretnom zarezu je tačan do 15 decimalnih mesta.

Celobrojne vrednosti mogu biti proizvoljno velike.

☞Python 2 je imao odvojene tipove za int i long.
Int tip podataka je bio ogranicen **sys.maxint**, što je variralo od platforme do
platforme, ali je inače bilo 223-1. Python 3 ima samo jedan tip celobrojnih
vrednosti, koje se ponasaju uglavnom kao stari long tip iz Python-a 2.
Pogledajte stranu 237 za više.

**2.3.2. Česte numeričke operacije**

Možete da radite razne
stvari kada su brojevi u pitanju.

               >>>
11 / 2 ①

5.5

>>> 11 //
2 ②

5

>>> −11
// 2 ③

−6

>>> 11.0
// 2 ④

5.0

>>> 11 \*\*
2 ⑤

121

>>> 11 %
2 ⑥

1

Operacija
/ vrši deljenje zapisa u pokretnom zarezu. Vraća float iako su oba broja int.

Operacija
// vrši čudno deljenje celobrojnih vrednosti. Kada je rezultat pozitivan,
možete ga smatrati kao skraćivanje (ne zaokruživanje) do 0 decimalnih mesta,
ali pazite se.

Kada deli
negativne celobrojne vrednosti, // operacja zaokružuje do najbliže celobrojne
vrednosti. Matematički gledano, to je zaokruživanje “nadole” jer je -6 manje od
-5, ali može Vas prevariti ako ste mislili da će ga iseći na -5.

Operacija
// neće uvek vratiti ceo broj. Ako sui brojilac ili imenilac float, i dalje će
ga zaokruživati do najbliže celobrojne vrednosti, ali će prava vraćena vrednost
biti float.

Operacija \*\*
znaci “podignuto na stepen”. 112 je 121.

Operacija %
daje ostatak pri deljenju celobrojnih vrednosti. 11 podeljeno sa 5 je 2 sa
ostatkom 1, znaci ovde je rezultat 1.

☞U Python-u 2, operacija / je obično označavala
deljenje celobrojnih vrednotsti, ali mogli ste da je naterate da se ponaša kao
deljenje zapisa u pokretnom zarezu tako što biste ukljucili specijalnnu
direktivu u svom kodu. U Python-u 3, operacija / uvel označava deljenje zapisa
u pokretnom zarezu. Pogledajte stranu 238 za više detalja.

**2.3.3.  Razlomci**

Python nije ograničen
na celobrojne vrednosti i zapise u pokretnom zarezu. On takođe može da radi svu
onu luksuznu matematiku koju ste naučili u srednjoj školi I naravno odmah
zaboravili.

               >>>
import fractions ①

>>> x =
fractions.Fraction(1, 3) ②

>>> x
Fraction(1, 3)

>>> x \* 2
③

Fraction(2, 3)

>>>
fractions.Fraction(6, 4) ④

Fraction(3, 2)

>>>
fractions.Fraction(0, 0) ⑤

Traceback (most
recent call last):

File "",
line 1, in <module>

File
"fractions.py", line 96, in \_\_new\_\_

raise
ZeroDivisionError('Fraction(%s, 0)' % numerator)

ZeroDivisionError:
Fraction(0, 0)

Za početak korišćenjem razlomaka ubacite fractions moduo.

Kako biste definisali razlomak, napravite fraction objekat i
dodajte brojilac i imenilac.

Možete vršiti standardne matematičke operacije sa razlomcima. Operacije
vraćaju novi fraction objekat, 2 \* (1/3) = (2/3)

Fraction objekat će automatski skratiti razlomke, (6/4) = (3/2)

Python ima dobar „osećaj“ da ne pravi razlomak kome je imenilac 0.

**2.3.4. Trigonometrija**

Takođe možete raditi i
osnovnu trigonometriju u Python-u.

               >>>
import math

>>>
math.pi ①

3.1415926535897931

>>>
math.sin(math.pi / 2) ②

1.0

>>>
math.tan(math.pi / 4) ③

0.99999999999999989

Math moduo
ima konstantu za π, odnos obima kruga i njegovog prečnika.

Math moduo
ima sve standardne trigonometrijske funkcije uključujući sin(), cos(), tan(), i
jos dosta različitih varijanti kao asin().

Međutim, imajte
na umu da Python nije beskonačno precizan. tan(π/4) treba da vrati 1.0, a ne  0.99999999999999989.

**2.3.5. Brojevi u Boolean context-u**

Možete da koristite
brojeve u Boolean context-u, kao što su **if** iskazi. Nulte vrednosti su false, a
ne-nulte vrednosti su true.

               >>>
def is\_it\_true(anything): ①

... if anything:

...            print("yes, it's true")

... else:

...            print("no, it's false")

...

>>>
is\_it\_true(1) ②

yes, it's true

>>>
is\_it\_true(-1)

yes, it's true

>>>
is\_it\_true(0)

no, it's false

>>>
is\_it\_true(0.1) ③

yes, it's true

>>>
is\_it\_true(0.0)

no, it's false

>>>
import fractions

>>>
is\_it\_true(fractions.Fraction(1, 2)) ④

yes, it's true

>>>
is\_it\_true(fractions.Fraction(0, 1))

no, it's false

Da li ste
znali da možete sami da definišete svoju sopstvene funkcije u Python-ovoj
interaktivnoj konzoli? Samo pritisnite ENTER na kraju svake linije i ENTER na
praznoj liniji da završite.

U Boolean context-u,
pozitivne ili negativne celobrojne vrednosti su true. 0 je false.

Pozitivni i
negativni zapisi u pokretnom zarezu su true; 0.0 je false. Budite oprezni sa ovim!
Ako postoji cak i minijaturna greška pri zaokruživanju (nije nemoguće, kao što
ste videli u prethodnom delu) onda će Python testirati 0.0000000000001
umesto 0 I vratiće true.

Razlomci se takođe mogu
koristiti u Boolean context-u. Fraction(0,n) je false za sve vrednosti n. Svi
ostali razlomci su true.

**2.4 Liste**

Liste
su Python-ovi najkorišćeniji tipovi podataka. Kada kažemo lista, možda mislite
na niz čiju veličinu treba deklarisati unapred, koja može sadržati predmete
istog tipa, &c. E pa ne mislite tako. Liste su mnog zabavnije od toga.

☞Lista u Python-u je kao niz u Perl 5. Perl 5, promenljive koje
cuvaju nizove uvek počinju karakterom @; u Python-u, promenljive mogu biti
nazvane bilo kako i Python prati tipove podataka interno.

☞Lsta u Python-u mnogo više od niza u Javi (iako se može tako
koristiti ako je to ono što stvarno želite u životu). Bolja analogija bi bila
ArrayList klasi koja može da drži proizvoljan objekat i da se dinamički širi kako
se novi predmeti u nju dodaju.

**2.4.1. Pravljenje liste**

Pravljenje liste je lako: koristite
kockaste zagrade da obmotate zarezom odvojene vrednosti.

>>>
a\_list = ['a', 'b', 'mpilgrim', 'z', 'example'] ①

>>>
a\_list

['a', 'b',
'mpilgrim', 'z', 'example']

>>>
a\_list[0] ②

'a'

>>>
a\_list[4] ③

'example'

>>>
a\_list[-1] ④

'example'

>>>
a\_list[-3] ⑤

'mpilgrim'

Prvo definišete listu od pet
elemenata. Imajte na umu da oni zadrzavaju svoj originalni red. To nije
slučajno. Lista je uređeni skup predmeta.

Lista takođe može biti
korišćena kao nulti zasnovan niz. Prvi predmet bilo koje ne-prazne liste je uvek
a\_list[0].

Negativan indeks pristupa predmetima sa kraja liste brojeći unazad.
Poslednji predmet iz ne-prazne liste je uvek a\_list[-1].

Ako Vas negativan indeks
zbunjuje, zamislite to na ovaj način: a\_list[-n] == a\_list[len(a\_list) - n].
dakle u ovoj listi a\_list[-3] == a\_list[5 - 3] == a\_list[2].