PYTHON liburua/Klase berriak eta ohikoenak
8. Klase berriak eta ohikoenak
[aldatu]Kapitulu honetan aurreko kapituluetan landu ezin izan diren hainbat kontzeptu eta aukera jartzen dira praktikan, azalpen laburrekin lagunduta. Bi multzotan banatu dira landuko diren gaiak: klaseetan sakontzea eta eskuragarri dauden modulu interesgarrienak (matematikoak, grafikoak, CSV, XML eta JSON formatuei dagozkienak, datu-baseetakoak...) azaltzea. Gaiak oso zabalak dira eta hemen sarrera bat baino ez dugu egingo, beti bezala adibideekin lagunduta. Hurrengo kapituluetan gai horietako batzuetan sakontzen da, baina kapitulu bakoitzari dagokion gaiaren barruan.
8.1. KLASEETAN SAKONTZEN
[aldatu]Hasieran esan den bezala, liburu hau ez dago zuzenduta algoritmika ikastera edota objektuei orientatutako programazio eta metodologiak ikastera. Neurri batean edo bestean algoritmika jakinda, objektuei orientatutakoa barne, hori aplikatzea Python lengoaian da liburu honen helburua. Atal honi dagokionez, objektuei orientatutako metodologian ohikoak diren kontzeptuak eta praktikak azaletik aztertuko dira erabilera bultzatuz.
Lehenago 5. kapituluan objektuei orientatutako programazioaren (OOP) inguruko ezaugarri nagusiak eta oinarrizko adibideak azaldu dira. Kapitulu honetan objektuen erabilera aurreratuari ekingo diogu, herentzia eta poliformismoa esaterako. Gai honetan gehiago sakontzeko webgune hau da gomendagarriena: https://docs.python.org/3/tutorial/classes.html.
8.1.1. Aldagaien eta funtzioen esparrua
[aldatu]Aldagaien eta funtzioen izenek Pythonen izen-sistema osatzen dute eta izen horien esparrua askotarikoa izan daiteke:
- Lokala, funtzioarena edo metodoarena, bertan definitzen bada.
- Klaseko globala, klasearen metodoetatik kanpo definitzen denean. Klaseetako metodoak ere esparru honetakoak dira.
- Globala, programa osoarena, klaseetatik eta funtzioetatik kanpo definitzen bada.
- Erabatekoa, built-in funtzioen kasua (builtins izeneko moduluan daude horiek).
Interpretatzaileak aipatutako ordenan bilatzen ditu izen bat ebatzi behar duenean, lokaletik globalera alegia, eta beraz anbiguotasuna dagoenean lokalean hautatuko da.
Dena den, kontuan hartu behar da funtzioak defini daitezkeela beste funtzioen esparruan, beraz, halakoetan, lokal-global kontzeptua lausoa da, inkremental bihurtuz; eta esparru estuagoa/zabalagoa esatea da egokiena.
Horrez gain, aipatutako esparruak alda daitezke bi gako erabilita: global eta nonlocal. Lehenarekin, hainbat lengoaiatan bezala, esparru lokaletik globalera zabaltzen da esparrua, bertako aldagaiaren izena modulu osora zabalduz. Bestalde, aldagai globalak edo esparru zabalagokoak beste esparru batean erabiltzen direnean ezin dira aldatu, irakurtzeko bakarrik erabil daitezke; aldatu ahal izateko nonlocal gisa zehaztu beharko dira (bestela lokal bat sortuko da balio berria barneratzeko).
8.1. programa. Izenen esparrua:
# moldatuta
# https://docs.python.org/3/tutorial/classes.html
def esparru_test():
def f_lokal():
mezu = "mezu lokala"
def f_ezlokal():
nonlocal mezu
mezu = "mezu ezlokala"
def f_global():
global mezu
mezu = "mezu globala"
mezu = "mezu hasiera"
f_lokal()
print("Esleipen lokalaren ondoren:", mezu)
f_ezlokal()
print("Esleipen ez-lokalaren ondoren:", mezu)
f_global()
print("Esleipen globalaren ondoren:", mezu)
esparru_test()
print("Esparru globalean:", mezu)
8.1. programan esparruen inguruko adibide bat azter daiteke. Exekuzioaren irteera hauxe da:
Esleipen lokalaren ondoren: mezu hasiera
Esleipen ez-lokalaren ondoren: mezu ezlokala
Esleipen globalaren ondoren: mezu ezlokala
Esparru globalean: mezu globala
Hasiera batean portaera harrigarria egiten bada ere, urratsez urrats uler daiteke, beti kontuan hartuta mezu aldagai bat baino gehiago dagoela: bat lokala f_lokal funtzioaren barruan; beste bat f_global funtzioaren barruan definituta, baina globala dena; eta hirugarrena esparru_test funtzio osorako, hasierako balioa hartzen duena. Hori kontuan hartuta
- f_lokal exekutatzean bertako aldagai lokalari aldatzen zaio balioa, baina inprimatzean programa esparru horretatik kanpo dago, beraz, funtzio osoko esparrua duen aldagaia inprimatzen da.
- Bigarren eta hirugarren inprimaketetan aldagai bera inprimatzen da, baina nonlocal deklarazioa dela-eta f_ezlokal funtzioan aldatu zaio balioa.
- f_global funtzioan bertako aldagaia aldatzen da, baina globala denez, azken inprimaketan, esparru_test funtziotik kanpo, haren balioa inprimatzen da.
8.1.2. Herentzia eta polimorfismoa
[aldatu]OOPn erabat normala da dauden objektuetatik abiatuz beste objektu berri bat definitzea. Herentzia hitza erabiltzen da hori adierazteko, klase batek bere ezaugarriak beste klase batetik heredatzen dituela pentsa dezakegulako. Bide horretatik klaseen hierarkia bat finkatzen da, klase umea klase gurasoengandik heredatzen dela.
Polimorfismoa forma bat baino gehiago izateko tasuna da eta Pythonek ere integratzen du. Eragile berak objektu desberdinekin modu desberdinetan eragiteko ahalmena izendatzen du polimorfismoak OOPn, hau da, objektu desberdinek modu diferentean erantzuten diotela metodo berberari.
Ezaugarri horiek lantzeko ohiko adibidea dugu: poligonoak eta dagozkien azalerak kalkulatzeko moduak. 8.2. programan ikus daitekeenez, Poligonoa klasea definitzen da hasieran, hiru metodo dituela: eraikitzailea (init), datuak sartzekoa (SartuAldeak) eta aldeak inprimatzekoa (InpriAldeak). Gero Triangelua eta Laukizuzena klase eratorriak (herentzia bidez) definitzen dira, class espezifikazioan Poligonoa klasea zehaztuz eta metodo eraikitzailean ere aipatuz. Azalera metodoa bakoitzean definitzen da modu desberdinean eratorritako klase bakoitzerako, eta gainera SartuAldeak metodoa birdefinitzen da Laukizuzena klasean (bi alde emanda nahikoa da-eta). Poliformismoaren adibideak dira azken bi metodoak, baina bigarrenean heredatutako metodoa aldatu egin da.
8.2. programa. Objektuen arteko herentziaren adibidea:
class Poligonoa:
def __init__(self, alde_kop):
self.n = alde_kop
self.aldeak = [0 for i in range(alde_kop)]
def SartuAldeak(self):
for i in range(self.n):
self.aldeak[i] = float(input("Sartu aldea("+str(i+1)+") : "))
def InpriAldeak(self):
for i in range(self.n):
print(i+1, "aldea", self.aldeak[i])
class Triangelua(Poligonoa):
def __init__(self):
Poligonoa.__init__(self,3)
def Azalera(self):
a, b, c = self.aldeak
s = (a + b + c) / 2
azal = (s*(s-a)*(s-b)*(s-c)) ** 0.5
print('Triangeluaren azalera %0.2f' %azal)
class Laukizuzena(Poligonoa):
def __init__(self):
Poligonoa.__init__(self,4)
def SartuAldeak(self):
for i in range(2):
self.aldeak[i] = float(input("Sartu aldea("+str(i+1)+") : "))
self.aldeak[2] = self.aldeak[0]
self.aldeak[3] = self.aldeak[1]
def Azalera(self):
a, b, c, d = self.aldeak
azal = a*b
print('Errektanguluaren azalera %0.2f' %azal)
t = Triangelua()
t.SartuAldeak()
t.InpriAldeak()
t.Azalera()
l = Laukizuzena()
l.SartuAldeak()
l.InpriAldeak()
l.Azalera()
Objektuek klase desberdinetatik heredatutako ezaugarriak eduki ditzakete. Horri askotariko herentzia esaten zaio, eta Pythonen erabil daiteke. Horretarako class espezifikazioan eta metodo eraikitzailean klase gurasoak zehaztu beharko dira.
8.2. MODULUAK INSTALATZEN
[aldatu]Sarean modulu asko eta asko daude eta, funtsezkoenak kenduta, gerta daiteke erabili nahi dugun modulua ez egotea instalatuta gure konputagailuan. import agindua ondo ibil dadin, dagokion moduluak instalatuta eta indexatuta egon behar du (Paketeak edukitzen dituzten katalogoetan init.py izeneko fitxategi batek egon behar du, bestela ez da bertan bilatuko. Aipatutako fitxategi hutsa izan daiteke, baina batzuetan erabiltzen da hainbat aldagai hasieratzeko. https://docs.python.org/3/tutorial/modules.html#packages).
Moduluak kudeatzeko hainbat programa dago eta pip da horien artean ezagunena. pip erabiltzeko aurretik instalatu behar da. Linuxen, eta Python3.4-tik aurrera, honako hau egin behar da instalatzeko:
sudo apt-get install python3-pip
Beste bertsioetarako, mesedez kontsultatu URL hau: https://pip.pypa.io/en/stable/installing/.
Behin pip kudeatzailea edukita, paketeak instalatzea erraza da. Adib. html2text modulua instalatzeko ondoko komandoetako bat nahikoa da (kapitulu honetan modulu hori erabiliko dugu, beraz, instalatzea gomendatzen da):
sudo python3 -m pip install html2text
sudo pip3 install html2text
Liburuaren sarreran esan den bezala, gaur egungo programazioan funtsezkoa da kodea berrerabiltzea. Horretarako, aurretik aipatutako moduluak inportatuko dira. Ondoren, eta hurrengo ataletan, eta kapituluetan, ohiko programetarako erabiltzen diren moduluak aipatu eta landuko dira.
Azalduko ez diren baina liburutegi estandarrean dauden metodoak eta klaseak hemen kontsulta daitezke: https://docs.python.org/3/library/.
8.3. KALKULURAKO MODULUAK
[aldatu]math modulua asko erabiltzen da, baina horrekin batera beste hauek ere: random zorizko zenbakietarako eta statistics estatistika-arlorako (https://docs.python.org/3/library/numeric.html). Oinarrizko eragiketetatik at, kalkuluak egin behar direnean modulu hauetako metodoak erabiltzea da ohikoena.
8.3.1. Funtzio matematikoak
[aldatu]Has gaitezen math moduluaren metodo ohikoenekin (asko daude):
math.fabs(t)
t zenbakiaren osoko balio absolutua itzuliko du.
math.pow(o, b)
o ber b balioa itzuliko du.
math.sqrt(t)
t zenbakiaren erro karratu positiboa itzuliko du. t negatiboa bada, errorea gertatuko da.
math.exp(t)
t-ren esponentziala itzuliko du.
math.log(t)
t-ren logaritmo nepertarra itzuliko du. Bigarren parametro gisa oinarria zehatz daiteke
math.log10(t)
t-ren logaritmo hamartarra itzuliko du. Trigonometria ere math moduluaren ardurapean dago:
math.sin(t)
t-ren sinua itzuliko du.
math.cos(t)
t-ren kosinua itzuliko du.
math.tan(t)
t-ren tangentea itzuliko du.
Hiru metodo trigonometriko horiez gain beste asko daude: asin (arku sinua), acos (arku kosinua), atan (arku tangentea), sinh (sinu hiperbolikoa), cosh (kosinu hiperbolikoa), tanh (tangente hiperbolikoa)...
Neurri gehienak radianetan ematen dira, baina radian/gradu bihurketetarako radians eta degrees metodoak erabil daitezke.
Balio singularrak ere lor daitezke modulu hau erabiliz:
math.pi
π balioa (3.141592...)
math.e
e balioa (2.718281...)
8.3.2. Zorizko zenbakiak eta estatistikak
[aldatu]Zorizko zenbakietarako, berriz, random modulua erabili behar da. Aukera handia dago, baina hauek dira erabilienak:
random.random()
Zoriz sortutako zenbaki erreal bat (0 eta 1 artean) itzuliko du.
random.seed(h)
Zorizko zenbakien sorrera hasieratzeko hazi (h) batekin.
random.randrange(n)
0 eta n-1 arteko zenbaki osokoak sortzeko. Adibidez 0 eta 9 arteko bat lortzeko 10 zehaztuko da.
random.sample(zerr,n)
Zerrendako elementuen artean n aukeratzeko zoriz. Zerrenda bat itzuliko du.
random.choice(s)
Sekuentzia baten barruko elementu bat aukeratzeko zoriz. Karaktere-kateak ere zehatz daitezke.
Adibide sinple batzuk (idle bitartez):
>> import random
>>> random.random()
0.17970987693706186
>>> random.randrange(6)
# balio bat 0 eta 5 artean
4
>>> random.choice([‘gora’, ‘behera’, ‘berdin’])
‘gora’
>>> random.sample(range(100), 5)
# 5 balio 0 eta 99 artean
[30, 83, 16, 4, 8]
Zorizko zenbakiak asko erabiltzen dira. Adibidez katalogo bateko mp3 motako fitxategien artean bat aukeratzeko 8.3. programa erabil daiteke.
8.3. programa. Abesti bat aukeratzea zoriz:
import sys
import random
list = []
n = 0
for f in os.listdir(sys.argv[1]): # katalogoko fitxategi bakoitzeko
if(f.endswith('.mp3')): # bukaera egiaztatzeko
n += 1
list.append(f)
i=random.randrange(n) # zorizko bat 0 eta n-1 artea
print(list[i])
Estatistikan ohikoak diren neurriak ere erabil daitezke statistics moduluaz:
statistics.mean(zerr
Zerrendako elementuen arteko batezbestekoa itzuliko du.
statistics.median(zerr)
Zerrendako elementuen arteko mediana itzuliko du.
statistics.mode(zerr)
Zerrendako elementuen arteko moda itzuliko du.
statistics.variance(zerr)
Zerrendako elementuen arteko bariantza itzuliko du.
statistics.stdev(zerr)
Zerrendako elementuen arteko desbiderapen tipikoa itzuliko du.
Kalkulu matematiko konplexuetarako eta estatistika sofistikatuak egiteko modulu interesgarriak daude, NumPy (www.numpy.org) edo StatsModels (statsmodels. sourceforge.net) esaterako, baina hori liburu honen esparrutik kanpo geratzen da.
8.4. DATUEN FORMATUAK
[aldatu]7. kapituluan landutako ohiko testu-fitxategiaz gain gero eta gehiago erabiltzen dira trukerako formatuetan oinarritutako fitxategiak. XML da markaketa-lengoaia orokorrena (hedagarria den neurria), baina CSV eta JSON lengoaien erabilera ere oso hedatuta dago. HTML ere formatu interesgarria da.
Serializatzeko edo markatzeko formatuekin hasi baino lehen datuen formatuekin lotutako hainbat modulu azpimarragarri aipatu behar dira:
- Unicode kodeketarekin lotutako modulua: unicodedata (https://docs.python.org/3/library/unicodedata.html).
- Datu-trinkoketarekin lotutako moduluak: glib, gzip, bz2, zipfile, tarfile (https://docs.python.org/3/library/archiving.html).
- Zifraketarekin lotutako modulak: crypt, hashlib, hmac (https://docs.python.org/3/library/crypto.html).
8.4.1. CSV formatua
[aldatu]Estatistikako lanak batzuetan kalkulu-orrietatik edo datu-baseetatik ekarritako fitxategien gainean egiten dira. CSV (Comma Separated Values, komaz banatutako balioak) da esportazioetarako formatu erabilienetako bat. Formatu horren gainean lan egiteko csv eta Pandas moduluak erabil daitezke.
8.4.1.1 csv modulua
[aldatu]Barneratzen dituen metodoen artean honako hauek dira erabilienak:
csv.reader(f)
CSV fitxategia interpretatzeko metodoa. Parametro gisa irekitako fitxategia (f) behar du eta eremu-banatzailea koma ez bada delimiter gakoa eta bere balioa (adibidez delimiter=';'). CSV motako objektu bat itzultzen du, iteragarria dena, fitxategien modura erabil daitekeena. Horrela lortutako objektuaren gainean errenkadak lor daitezke in eragilearen bidez, eta zutabeak indizearen bidez (0tik hasita).
csv.writer(f)
CSV formatura bihurtzeko metodoa. Parametro gisa idazteko irekitako fitxategia behar du. CSV motako objektu bat itzultzen du.
csv.writerow(z)
CSV motako objektu baten gainean errenkada bat idazteko balio du. Parametro gisa zutabe guztiak dituen zerrenda bat eman ohi zaio.
8.4a programan erabileraren adibide bat dugu, 1936ko otsailean Bizkaian izan ziren )hauteskunde-emaitzak dituen CSV fitxategi batetik abiatuta hautagai batek herrietan jaso zituen boto-kopuruak inprimatzen ditu. Bi parametro pasa behar zaizkio programari: fitxategia eta hautagaiari dagokion zutabea. Erabiliko dugun csv fitxategia mun_bizkaia_capital_1936_feb_e.csv da ; helbide honetatik jaso dugu: http://www.euskadi.eus/web01-a2haukon/eu/contenidos/informacion/w_em_contexto_historico_1936/eu_def/result_1936/csv/mun_bizkaia_capital_1936_feb_e.csv ; eta hau da barruan duen csv fitxategiaren edukia:
# | HERRIAK | Boto-emaileen kopurua | Joaquin Adón mon. Ind(1) | José M. Areilza Ren. Esp(2) | José M. Juaristi Ctrad(3) | Miguel Goldaracena CEDA(4) | José Horn PNV(5) | Manuel Robles PNV(5) | Francisco Arregui PNV(5) | José M. Izaurieta PNV(5) | Indalecio Prieto PSOE(6) | Mariano Ruiz Funes IR(7) | Julián Zugazagoitia PSOE(6) | Leandro Carro PCE(8) | Bestelakoak | Zuriak |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | ABANTO Y CIERVANA | 3953 | 250 | 251 | 249 | 252 | 477 | 476 | 472 | 474 | 3217 | 3218 | 3218 | 3213 | NaN | 7.0 |
1 | ARRIGORRIAGA | 1903 | 206 | 201 | 202 | 203 | 684 | 685 | 685 | 683 | 997 | 999 | 1001 | 998 | NaN | - |
2 | BARACALDO | 15663 | 2374 | 2362 | 2372 | 2366 | 4079 | 4077 | 4085 | 4070 | 9143 | 9120 | 9215 | 9208 | 3.0 | 19.0 |
3 | BARRICA | 325 | 50 | 50 | 50 | 50 | 230 | 230 | 230 | 230 | 45 | 45 | 45 | 45 | NaN | NaN |
4 | BASAURI | 4167 | 1453 | 1451 | 1447 | 1446 | 836 | 834 | 827 | 831 | 1862 | 1869 | 1874 | 1872 | 4.0 | NaN |
5 | BERANGO | 533 | 177 | 177 | 177 | 177 | 210 | 210 | 210 | 210 | 147 | 146 | 147 | 147 | NaN | NaN |
6 | BILBAO | 72252 | 17026 | 16768 | 16829 | 16890 | 22441 | 22335 | 22178 | 22311 | 32511 | 32673 | 32506 | 32355 | 22.0 | 97.0 |
7 | ECHEVARRI | 566 | 143 | 141 | 143 | 143 | 219 | 216 | 218 | 217 | 203 | 201 | 204 | 204 | NaN | 1.0 |
8 | ERANDIO | 4914 | 586 | 583 | 584 | 590 | 2250 | 2251 | 2242 | 2244 | 2062 | 2068 | 2067 | 2065 | 2.0 | 1.0 |
9 | GORLIZ | 542 | 113 | 110 | 109 | 113 | 335 | 336 | 334 | 334 | 112 | 112 | 110 | 106 | NaN | 4.0 |
10 | GUECHO | 7284 | 2099 | 2091 | 2089 | 2098 | 3316 | 3313 | 3118 | 3180 | 1906 | 1906 | 1910 | 1880 | 3.0 | 6.0 |
11 | LAUQUINIZ | 288 | 78 | 78 | 78 | 78 | 157 | 157 | 157 | 157 | 3 | 3 | 3 | 3 | NaN | NaN |
12 | LEJONA | 2088 | 282 | 282 | 282 | 282 | 969 | 968 | 970 | 969 | 824 | 828 | 827 | 827 | NaN | 2.0 |
13 | LUJUA | 612 | 197 | 198 | 198 | 198 | 406 | 406 | 406 | 406 | 36 | 36 | 36 | 36 | 4.0 | NaN |
14 | MUSQUES | 1683 | 196 | 196 | 194 | 194 | 320 | 329 | 326 | 326 | 1157 | 1159 | 1158 | 1161 | NaN | NaN |
15 | ORDUÑA | 1488 | 772 | 770 | 770 | 770 | 478 | 479 | 479 | 479 | 239 | 239 | 237 | 236 | NaN | NaN |
16 | PLENCIA | 1055 | 341 | 341 | 340 | 341 | 598 | 598 | 594 | 596 | 115 | 113 | 114 | 111 | NaN | NaN |
17 | PORTUGALETE | 4695 | 1095 | 1097 | 1088 | 1095 | 956 | 946 | 948 | 943 | 2631 | 2640 | 2643 | 2632 | 7.0 | 5.0 |
18 | S. SALVADOR DEL VALLE | 3351 | 270 | 269 | 269 | 269 | 733 | 733 | 732 | 732 | 2341 | 2346 | 2347 | 2346 | NaN | 2.0 |
19 | SANTURCE (A) | 2853 | 575 | 572 | 571 | 572 | 729 | 727 | 722 | 725 | 1530 | 1536 | 1537 | 1535 | NaN | 1.0 |
20 | SANTURCE (O) | 2722 | 126 | 125 | 125 | 126 | 362 | 359 | 361 | 360 | 2231 | 2235 | 2233 | 2234 | 1.0 | NaN |
21 | SESTAO | 8242 | 1437 | 1429 | 1435 | 1432 | 1436 | 1429 | 1420 | 1426 | 5310 | 5348 | 5335 | 5329 | 2.0 | 10.0 |
22 | SOPELANA | 544 | 76 | 77 | 77 | 76 | 270 | 270 | 269 | 269 | 196 | 196 | 196 | 196 | NaN | 2.0 |
23 | URDULIZ | 425 | 67 | 67 | 67 | 67 | 309 | 309 | 308 | 309 | 47 | 49 | 49 | 48 | NaN | NaN |
24 | ZAMUDIO | 690 | 221 | 221 | 221 | 221 | 416 | 416 | 416 | 416 | 50 | 50 | 50 | 50 | NaN | 3.0 |
25 | BOTOAK GUZTIRA | 142887 | 30209 | 29909 | 29960 | 30049 | 43223 | 43099 | 42707 | 42897 | 68913 | 69240 | 69062 | 68837 | 49.0 | 164.0 |
8.4a programa. Hauteskundeen fitxategitik hautagai baten emaitzak erakustea (Indalecio Prietorenak):
import csv
import sys
csvfitx = csv.reader(open('mun_bizkaia_capital_1936_feb_e.csv'))
##
zut=10 ## Indalecio Prieto (PSOE)
for errenk in csvfitx:
print(errenk[0], ' '*(20-len(errenk[0])), errenk[1],' '*(35-len(errenk[1])), errenk[zut])
Emaitza:
HERRIAK Boto-emaileen kopurua Indalecio Prieto PSOE(6)
ABANTO Y CIERVANA 3953 3217
ARRIGORRIAGA 1903 997
BARACALDO 15663 9143
BARRICA 325 45
BASAURI 4167 1862
BERANGO 533 147
BILBAO 72252 32511
ECHEVARRI 566 203
ERANDIO 4914 2062
GORLIZ 542 112
GUECHO 7284 1906
LAUQUINIZ 288 3
LEJONA 2088 824
LUJUA 612 36
MUSQUES 1683 1157
ORDUÑA 1488 239
PLENCIA 1055 115
PORTUGALETE 4695 2631
S. SALVADOR DEL VALLE 3351 2341
SANTURCE (A) 2853 1530
SANTURCE (O) 2722 2231
SESTAO 8242 5310
SOPELANA 544 196
URDULIZ 425 47
ZAMUDIO 690 50
BOTOAK GUZTIRA 142887 68913
8.4.1.2 Pandas modulua
[aldatu]Antzera baina Pandas paketea erabilita. CSV orriaren lerroak eta zutabeak iragazteko erraztasun handia eskaintzen du "Pandas" moduluak. Ondoko programaren bukaeran erakusten da datuak iragazteko erraztasun hori. Zein herritan irabazi dio 1. hautagaiak (Areilza) 8.ari (Prieto, sozialista) eta zenbat puntu atera dizkio boto-ehunekoetan? Agindu sinple honek csv fitxategiko errenkada guztiak prozesatzen ditu eta bakarrik uzten ditu baldintza betetzen dituzten errenkadak:
herri_sozialistak = csvfitx[(csvfitx[hautagaiak[haut1]] > csvfitx[hautagaiak[haut2]])]
8.4a2. programa. CSV formatua, Pandas paketearekin:
import pandas as pd
import sys
csvfitx = pd.read_csv('mun_bizkaia_capital_1936_feb_e.csv')
hautagaiak = list(csvfitx.keys())[2:]
print('Hautagaiak: ', hautagaiak)
print ('\n')
haut1 = 1
haut2 = 8
print(haut1, '. hautagaia: ', hautagaiak[haut1])
print(haut2, '. hautagaia: ', hautagaiak[haut2])
print('\n')
print('HERRIAK ', ' 1.aren botoak', '2.aren botoak')
for index, lerroa in csvfitx.iterrows():
print(lerroa['HERRIAK '], ' '*(22-len(lerroa['HERRIAK '])), lerroa[hautagaiak[haut1]],'\t' , lerroa[hautagaiak[haut2]])
print('\n')
print('1. hautagaiak 2.ari irabazi dio herri hauetan:')
#herri_sozialistak = csvfitx['HERRIAK '][(csvfitx[hautagaiak[1]] < csvfitx[hautagaiak[8]])].values
herri_sozialistak = csvfitx[(csvfitx[hautagaiak[haut1]] > csvfitx[hautagaiak[haut2]])]
#print(herri_sozialistak)
#for herria in herri_sozialistak:
for index, lerroa in herri_sozialistak.iterrows():
dif = 100 * (lerroa[hautagaiak[haut1]] - lerroa[hautagaiak[haut2]]) / lerroa[1]
print(lerroa['HERRIAK '], ' '*(22-len(lerroa['HERRIAK '])), lerroa[hautagaiak[haut1]],'\t' , lerroa[hautagaiak[haut2]], 'dif_ehunekotan:', dif)
Emaitza:
Hautagaiak: ['Joaquin Adón mon. Ind(1)', 'José M. Areilza Ren. Esp(2)', 'José M. Juaristi Ctrad(3) ', 'Miguel Goldaracena CEDA(4)', 'José Horn PNV(5)', 'Manuel Robles PNV(5)', 'Francisco Arregui PNV(5)', 'José M. Izaurieta PNV(5)', 'Indalecio Prieto PSOE(6)', 'Mariano Ruiz Funes IR(7)', 'Julián Zugazagoitia PSOE(6)', 'Leandro Carro PCE(8)', 'Bestelakoak', 'Zuriak']
1 . hautagaia: José M. Areilza Ren. Esp(2)
5 . hautagaia: Manuel Robles PNV(5)
HERRIAK 1.aren botoak 2.aren botoak
ABANTO Y CIERVANA 251 476
ARRIGORRIAGA 201 685
BARACALDO 2362 4077
BARRICA 50 230
BASAURI 1451 834
BERANGO 177 210
BILBAO 16768 22335
ECHEVARRI 141 216
ERANDIO 583 2251
GORLIZ 110 336
GUECHO 2091 3313
LAUQUINIZ 78 157
LEJONA 282 968
LUJUA 198 406
MUSQUES 196 329
ORDUÑA 770 479
PLENCIA 341 598
PORTUGALETE 1097 946
S. SALVADOR DEL VALLE 269 733
SANTURCE (A) 572 727
SANTURCE (O) 125 359
SESTAO 1429 1429
SOPELANA 77 270
URDULIZ 67 309
ZAMUDIO 221 416
BOTOAK GUZTIRA 29909 43099
1. hautagaiak 2.ari irabazi dio herri hauetan:
BASAURI 1451 834 dif_ehunekotan: 14.806815454763619
ORDUÑA 770 479 dif_ehunekotan: 19.556451612903224
PORTUGALETE 1097 946 dif_ehunekotan: 3.2161874334398295
CSV paketeaz gehiago sakontzeko gune hau gomendatzen da: https://docs.python.org/3/library/csv.html
8.4.1.3 CSV fitxategia hiztegi moduan tratatua
[aldatu]Aurreko metodoez gain CSV fitxategiak hiztegi moduan tratatzeko bi klase daude: csv.DictReader eta csv.DictWriter. Ondoko adibidean ikusi ahal izango denez, izenburu gisa dauden etiketak erabil daitezke hiztegiaren gako gisa programa egitean.
8.4b. programan sarrera CSV formatuan dagoen fitxategi bat da, non hainbat operaren datuak dauden: urtea, izena, egilea eta hizkuntza. Lehen lerroan izenburuak agertzen dira. Programaren helburua Trivial moduko joko baterako galderak automatikoki sortzea da. Sortutako galderak, erantzun zuzenarekin eta bi erantzun okerrekin idatziko dira CSV fitxategi batean.
8.4b. programa. CSV formatua, hiztegi moduan:
#!/usr/bin/python3
# -*- kodeketa: utf-8 -*-
# CSVak kudeatzeko:
import csv
# urteak zoriz sortzeko
import random
sar_fitx = "operak-sar.csv"
irt_fitx = "operak-irt.csv"
# sarrera fitxategia ireki
with open(sar_fitx, newline='') as csv_sarrera:
# sarrera fitxategia hiztegi batean kargatu
firak = csv.DictReader(csv_sarrera)
# irteera fitxategia ireki
with open(irt_fitx,'w') as csv_irteera:
# irteera fitxategian idazteko aldagaia prestatu (hiztegia)
# (CSV formatua izanik, dena kudeatzeko objektua sortu dugu)
eremuak = ["Galdera","Zuzena","Oker1","Oker2"]
fidaz = csv.DictWriter(csv_irteera,fieldnames=eremuak)
fidaz.writeheader()
# aurrena fitxategiko idazle guztiak jasoko ditugu
# gero distraigarriak sortu ahal izateko
jatorrizko_fitxategia = list(firak)
idazleguztiak = set()
for elementu in jatorrizko_fitxategia.copy():
idazleguztiak.add(elementu["egilea"].strip())
# galderak sortuko ditugu eta fitxategian idatzi
for errenkada in jatorrizko_fitxategia:
galdera = "Nork idatzia da "+errenkada["izena"].strip()+" opera?"
zuzena = errenkada["egilea"].strip()
# okerrak sortu (3, badaezpada bat zuzena den)
okerrak = random.sample(idazleguztiak,3)
# okerren artean zuzena badago, kendu
if zuzena in okerrak:
okerrak.remove(zuzena)
# lehenengo bi elementuak jaso okerren zerrendatik
oker1,oker2 = okerrak[0:2]
fidaz.writerow({"Galdera":galdera,"Zuzena":zuzena,
"Oker1":oker1,"Oker2":oker2})
Probatu ezazu programa. Ez du parametrorik behar.
Honetaz gehiago sakontzeko gune hau gomendatzen da: https://docs.python.org/3/library/csv.html.
Adibidez, "operak-sar.csv" fitxategiaren edukia kalkulu-orri hau baldin bada:
Urtea | Izena | Egilea | Hizkuntza |
---|---|---|---|
1876 | Siegfried | Richard Wagner | DE |
1876 | Götterdämmerung | Richard Wagner | DE |
1877 | L'étoile | Emmanuel Chabrier | FR |
1879 | Eugene Onegin | Tchaikovsky | RU |
1843 | Don Pasquale | Donizetti | IT |
1842 | Nabucco | Verdi | IT |
1842 | Rienzi | Richard Wagner | DE |
1846 | La damnation de Faust | Berlioz | FR |
1859 | Un ballo in maschera | Verdi | IT |
1867 | Don Carlos | Verdi | DE |
1869 | Das Rheingold | Richard Wagner | DE |
1886 | Khonvanschina | Mussorgsky | RU |
1887 | Otello | Verdi | IT |
1892 | Iolanta | Tchaikovsky | RU |
1893 | Manon Lescaut | Puccini | IT |
1898 | Sadko | Rimsky-Korsakov | RU |
1899 | Cendrillon | Massenet | FR |
1893 | Hansel und Gretel | Humperdinck | DE |
1890 | Cavalleria Rusticana | Pietro Mascgani | IT |
1897 | Konigskinder | Humperdinck | DE |
1890 | Knyaz' Igor | Borodin | RU |
1892 | Werther | Massenet | FR |
1881 | Les contes d'Hoffmann | Offenbach | FR |
1900 | Tosca | Puccini | IT |
1903 | Elektra | Richard Strauss | DE |
Hau da lortu daitezkeen Trivial galdera batzuk ("operak-irt.csv"):
Galdera | Zuzena | Oker1 | Oker2 |
---|---|---|---|
Nork idatzia da Siegfried opera? | Richard Wagner | Berlioz | Emmanuel Chabrier |
Nork idatzia da Götterdämmerung opera? | Richard Wagner | Berlioz | Verdi |
Nork idatzia da L'étoile opera? | Emmanuel Chabrier | Richard Strauss | Verdi |
Nork idatzia da Eugene Onegin opera? | Tchaikovsky | Richard Strauss | Pietro Mascgani |
Nork idatzia da Don Pasquale opera? | Donizetti | Rimsky-Korsakov | Pietro Mascgani |
Nork idatzia da Nabucco opera? | Verdi | Humperdinck | Donizetti |
Nork idatzia da Rienzi opera? | Richard Wagner | Verdi | Berlioz |
Nork idatzia da La damnation de Faust opera? | Berlioz | Borodin | Emmanuel Chabrier |
Nork idatzia da Un ballo in maschera opera? | Verdi | Emmanuel Chabrier | Puccini |
Nork idatzia da Don Carlos opera? | Verdi | Richard Wagner | Puccini |
Nork idatzia da Das Rheingold opera? | Richard Wagner | Tchaikovsky | Pietro Mascgani |
Nork idatzia da Khonvanschina opera? | Mussorgsky | Verdi | Richard Strauss |
Nork idatzia da Otello opera? | Verdi | Donizetti | Puccini |
Nork idatzia da Iolanta opera? | Tchaikovsky | Humperdinck | Richard Strauss |
Nork idatzia da Manon Lescaut opera? | Puccini | Humperdinck | Rimsky-Korsakov |
Nork idatzia da Sadko opera? | Rimsky-Korsakov | Borodin | Massenet |
Nork idatzia da Cendrillon opera? | Massenet | Offenbach | Rimsky-Korsakov |
Nork idatzia da Hansel und Gretel opera? | Humperdinck | Borodin | Tchaikovsky |
Nork idatzia da Cavalleria Rusticana opera? | Pietro Mascgani | Offenbach | Rimsky-Korsakov |
Nork idatzia da Konigskinder opera? | Humperdinck | Richard Strauss | Tchaikovsky |
Nork idatzia da Knyaz' Igor opera? | Borodin | Donizetti | Rimsky-Korsakov |
Nork idatzia da Werther opera? | Massenet | Pietro Mascgani | Richard Strauss |
Nork idatzia da Les contes d'Hoffmann opera? | Offenbach | Berlioz | Mussorgsky |
Nork idatzia da Tosca opera? | Puccini | Massenet | Mussorgsky |
Nork idatzia da Elektra opera? | Richard Strauss | Pietro Mascgani | Richard Wagner |
8.4.2. JSON
[aldatu]JSON gero eta gehiago erabiltzen den formatua dugu. Interneteko hainbat APIk JSON (JavaScript Object Notation, JavaScript objektuen idazkera) formatuan itzultzen dituzte emaitzak. Zerbitzu eraginkorrak eskaintzeari zuzenduta dago. Programetan erabilitako datuak serializatzea ere du helburu, beraz, programen arteko komunikazio eraginkorrerako da egokia.
Formatu horren gainean lan egiteko json modulua dago. Barneratzen dituen metodoen artean, honako hauek dira erabilienak:
json.dumps
- JSON formatura bihurtzeko metodoa. separators izeneko parametroaren bidez defini daitezke banatzaileak.
json.loads
- JSON formatuko segidak interpretatzeko metodoa. Fitxategi batean badago, fitxategia ireki (open) eta lerro bakoitzari aplikatu egiten zaio. json.load metodoa erabil daiteke fitxategi osoa bihurtzeko, baina ez da ohikoa.
JSON formatuan informazioa bikoteetan (gakoa/balioa) egon ohi da eta aurreko metodoaren bidez Python hiztegi bihurtzen dira. Ohikoa da balioa hiztegia ere izatea, kasu horretan hiztegia indexatzeko bi indize (edo gehiago) erabiliko dira.
8.5. programan erabileraren adibide bat dugu, non Twitter API bidez jasotako JSON formatuko txioak eskuratu eta inprimatzen diren (identifikadorea, hizkuntza eta mezua). Erabiltzeko parametro bat pasa behar zaio: JSON formatuko fitxategia (Probak egiteko https://list.github.com/hrp/900964 fitxategia hartu dugu eta twitter.json fitxategian gorde. Probatzeko adib. python3 p8-5_json.py datu_twitter.json).
8.5. programa. JSON formatuko txioen tratamendua:
import sys
import json
f = open(sys.argv[1],'r')
# json erregistro bakoitza lerro batean
for lerro in f:
txio = json.loads(lerro)
try:
testu = txio['text']
id = txio['id_str']
hizk = txio['user']['lang'] # hiztegia hiztegiaren barruan
print(id, hizk, testu)
except:
continue # ezer ez egitea
Honetaz gehiago sakontzeko gune hau gomendatzen da: <https://docs.python.org/3/library/json.html>.
8.4.3. XML gaineko metodoak
[aldatu]XML, eXtensible Markup Language, dokumentuak markatzeko edo etiketatzeko estandarra da. Markatze-etiketak eta edukia bera testua dira, eta hortaz testu-fitxategiak dira, non etiketak eta datuak txertatzen diren. Metalengoaia da XML, eta bertatik eratorriko lengoaia asko dago (Hona hemen zerrenda luze bat: <https://en.wikipedia.org/wiki/List_of_XML_markup_languages>). Horrela, HTML bera XMLtik eratorritako lengoaia gisa ikus daiteke eta ondo eratutako HTML dokumentuak (XHTML) XML dokumentuak dira. (Hemen ez gara gaiaz luzatuko, baina honetaz sakondu nahi duenak dokumentu hau irakurtzea gomendagarria da: http://www.unibertsitatea.net/otarrea/ingeniaritza-eta-teknologia-1/informatika/xml-oinarriak)
Edozein kasutan, programazio-lengoaia gehienetan liburutegi ugari daude XML egiturak sortzeko, irakurtzeko edota aldatzeko. Eta Python ez da salbuespena.
Pythonek hainbat built-in modulu eskaintzen ditu XML fitxategiak prozesatzeko, ElementTree-k, DOM, edota SAX adibidez. SAX gauza sinpleak egiteko pentsatuta dago eta DOMek azkartasunari begiratzen dio, XML fitxategi osoa memorian kargatuz. ElementTree, berriz, XML zuhaitz gisa errepresentatzen du XML fitxategia, eta modu erraz eta eraginkorrean XML zuhaitzen gainean eragiketak egiteko baliagarria da. Azke au izango da adibideetan erabiliko duguna.
Badaude ahaltsuagoak diren liburutegiak ere, lxml adibidez, baina funtzio eta atributu ugari partekatzen dituzte ElementTree moduluarekin, hortaz atal honetan Pythonen berezko moduluarekin lan egingo dugu.
Honako XML dokumentua erabiliko dugu hurrengo programetan (herrialdeak.xml):
<?xml version=”1.0”?>
<datuak>
<herrialdea izena=”Portugal”>
<posizioa>111</posizioa>
<hizkuntza>portugesa</hizkuntza>
<azalera>92212</azalera>
</herrialdea>
<herrialdea izena=”Argentina”>
<posizioa>8</posizioa>
<hizkuntza>espainola</hizkuntza>
<azalera>2780400</azalera>
</herrialdea>
<herrialdea izena=”Mongolia”>
<posizioa>19</posizioa>
<hizkuntza>mongoliera</hizkuntza>
<azalera>1564115</azalera>
</herrialdea>
</datuak>
ElementTree moduluak XML dokumentua zuhaitz moduan errepresentatzeko aukera ematen du. XML dokumentuaren erroa Element motako objektu batean kokatuta, zuhaitzean zehar mugitzeko eta bilaketak egiteko aukera ematen du modu errazean (ElementTree moduluari buruz gehiago ikasteko Pythonen dokumentazioa ikus daiteke https://docs.python.org/3/library/xml.etree.elementtree.html.
Adibidez, aurreko irudiko XML egituran, herrialdea da objektuaren adabegi edo nodo nagusia, gero, maila berean, posizioa, hizkuntza eta azalera.
Informazioa aurkitzeko metodo oso sinple zein ahaltsuak eskaintzen ditu: findall, find eta findtext. Metodo horiek parametro gisa pasatako elementua edota elementuaren testua aurkitzeko erabiltzen dira. findall metodoak parametroaren adierazpena betetzen duten ume guztiak itzultzen ditu zerrenda batean, find metodoak adierazpena betetzen duen lehenengo elementua, eta findtext metodoak elementuaren testua (datua). Testua eskuratzeko attrib metodoa ere erabil daiteke elementuaren gainean. Parametro gisa Xpath espresioak ere erabil daitezke.
8.6. programan, halako aipatutako XML dokumentua irakurri, eta hiztegi bat sortuko dugu herrialdeen izenekin eta dagozkien hizkuntzekin.
8.6. programa. XML fitxategien erabilera:
import xml.etree.ElementTree as ET
#XML dokumentua irakurri eta zuhaitz gisa jaso Element objektu batean
tree = ET.parse('herrialdeak.xml') #fitxategitik XML jaso zuhaitz moduan
root = tree.getroot() #Erro elementua jaso Element motako objektuan
hiztegia = dict()
#erro elementuaren umeak diren 'herrialdea' elementuak
for herrialde in root.findall('herrialdea'):
# herrialdearen "izena" atributuko balioa jaso
izena = herrialde.attrib('izena')
# hizkuntza umearen testu balioa jaso
hizkuntza = herrialde.findtext('hizkuntza')
hiztegia[izena] = hizkuntza
print(hiztegia)
HTML fitxategiekin lan egiteko ere berdin-berdin balio du modulu honek, betiere ondo eratuta baldin badaude, hau da, XHTML fitxategia bada. Web orriekin lan egiteko adibide gehiago azalduko dira 10. kapituluan.
8.5. KONEXIOA DATU-BASEEKIN
[aldatu]Datu-base mota ugari daude gaur egunean erabilgarri, Oracle, MySql, Postgres, SqlServer, SQLite (guztiak SQL datu-baseak dira. Gaur egun NoSQL datu-baseak ere erabiltzen dira (MongoDB esaterako), baina liburu honen esparrutik kanpo geratzen dira) ... Erabileraren arabera datu-base mota bat erabiliko du garatzaileak, weberako MySql, enpresa munduko gauzetarako Oracle edo Postgres... Pythonek horiek guztiak kudeatzeko moduluak eskaintzen ditu: MySQLdb, cx_Oracle...
Liburu honetan baina, SQLite datu-baseak erabiltzen ikasiko dugu. Lite hitzak txikia, ez oso pisutsua esan nahi du ingelesez, eta horregatik SQLite-ri datu-base txertatua ere esaten zaio. MySQL edo Oracle aparteko softwareak dira, eta horrela kanpotik konektatu beharra dago beraiekin lan egiteko. SQLite aldiz ez, garatzen ari garen aplikazioaren barruan gordetzen da. Gaur egunean oso erabiliak dira musika- jotzaileetan, mugikor adimendunetan, autoetan...
Pythonek built-in modulu bat dauka SQLite motako datu-baseekin lan egiteko: sqlite3. Hortaz, aparteko ezer instalatu gabe erabil ditzakegu modulu horren metodoak gure programetan.
Atal honetan datu-base batera konektatzen ikasiko dugu, baita taula berri bat sortzen eta tauletan eragiketak egiten ere. Azkenik, datuak modu eraginkorrean nola jaso ditzakegun ikusiko dugu.
8.7. programan datu-base batekin konexioa ezarri eta taula berri bat sortzen da. Ostean, sortutako taula berrian datuak sartuko dira eta, bukatzeko, taulatik datuak jaso eta pantailaratuko dira. Emandako urratsak honakoak dira:
- Datu-basera konexioa oso modu errazean burutzen da connect metodoaren bitartez. Datu-basea ez bada aurretik sortu, momentu horretan sortuko da uneko direktorioa.
- Hainbat SQL espresio egikarituko dira datu-basearen gainean execute metodoa erabiliz: taula berria sortu ("CREATE TABLE"), errenkadak gehitu ("INSERT"), eta datuak jaso ("SELECT"). Edozein SQL espresio egikaritu daiteke metodo honi esker.
- Egindako aldaketak datu-basean gorde daitezen commit metodoa erabiltzen da.
- Datu-basearekin konexioa ixten da close metodoaz.
8.7. programa. SQL datu-basearen gaineko eragiketak:
import sqlite3
conn = sqlite3.connect('proba.db') #Datu basearekin konexioa ireki
#Datu-baseari taula bat gehitu:
conn.execute('''CREATE TABLE Herrialdea #Taularen izena
(ID INT PRIMARY KEY NOT NULL, #Taularen gakoa
Izena TEXT NOT NULL, #Testu motako atributua
Azalera INT NOT NULL);''')#Zenbaki oso motako atributua
#Herrialdea taulari errenkadak txertatu:
conn.execute(“INSERT INTO Herrialdea (ID,Izena,Azalera) \
VALUES (1,'Argentina',2780400)”)
conn.execute(“INSERT INTO Herrialdea (ID,Izena,Azalera) \
VALUES (2,'Portugal',92212)”)
conn.execute(“INSERT INTO Herrialdea (ID,Izena,Azalera) \
VALUES (3,'Mongolia',1564115)”)
conn.commit() # Aldaketak gordetzeko
#Herrialdea taulako errenkadak pantailaratu:
kurtsore = conn.execute("SELECT ID, Izena, Azalera from Herrialdea")
for errenkada in kurtsore:
print("ID =", errenkada[0])
print("Izena =", errenkada[1])
print("Azalera =", errenkada[2])
conn.close() #Datu basearekin konexioa itxi
8.6. GRAFIKOAK ETA IRUDIAK
[aldatu]Grafikoak eta irudiak ez ohi dira sortu programazio-lengoaia orokorren bitartez. Dena den, programa batzuetan emaitzak modu grafikoan ematea oso ezaugarri garrantzitsua izan daiteke. Modulu asko daude lan horretan laguntzeko, horietako gutxi batzuk baino ez ditugu landuko.
8.6.1. Irudiak
[aldatu]Pythonen, beste programazio-lengoaietan bezala, oinarrizko tresnak erabiliz oso nekeza da irudiak sortzea, baina publikoak diren modulu eta klaseei esker lan hori asko sinplifika daiteke eta oso emaitza ikusgarriak lortu lan askorik egin gabe.
Irudietarako ezagunen diren Python moduluak hauek dira: graphics.py eta pycairo. Guk pycairo probatu dugu, oso ahaltsua delako eta beste lengoaietan ere (C++, Perl, PHP...) erabiltzen delako.
Ondoko adibidean pycairo moduluaren erabilera landuko dugu, ahalmenaren eta oinarrizko ezaugarrien adibide gisa. 8.1. irudian agertzen den irudia 8.8. programak sortu du.
8.1. irudia. pycairo bitartez lortutako grafiko baten adibidea:
??8.1 irudia
Programa (helbide honetan http://cairographics.org/pycairo/tutorial/ aurkitutako adibide batetik eratorria da) hainbat bloketan dago banatuta:
- Moduluen (math eta cairo) kargatzea.
- Hondoaren definizioa: cairo objektuaren bidez lantzen da hasieran (ImageSurface eta Context metodoak erabiliz). Azken metodoak beste objektu bat eskaintzen digu (testuingurua: testuing); eta horren gainean hainbat metodo aplikatuz (rectangle eta fill) eta objektu laguntzaile baten laguntzaz (bide) hondoa ezarrita geratzen da.
- Marrazkia bera metodo geometrikoen bidez: testuing objektuaren gainean marrazteko tipikoak diren metodoak erabiltzen dira: arc (arku zirkularretarako), line_to (lerroetarako), curve_to (kurbetarako)...
- Marrazkiaren zehaztasunak eta idazketa. Lerroen kolorea eta zabalera definitu ondoren, marrazkia finkatzen da eta png formatura bihurtzen da.
8.8. programa. Marrazketaren adibidea cairo modulua erabiliz:
# iturburua: http://cairographics.org/pycairo/tutorial/
import math
import cairo
#neurriak 256 puntuko karratua
ZABAL, LUZ = 256, 256
# hondoa definitu
azalera = cairo.ImageSurface (cairo.FORMAT_ARGB32, ZABAL, LUZ)
testuing = cairo.Context (azalera)
testuing.scale (ZABAL, LUZ) # eskala-normalizazioa
# hondoko kolorea
# prestakuntza -> bide
bide = cairo.LinearGradient (0.0, 0.0, 0.0, 1.0)
# kolore degradatua bi zatitan
bide.add_color_stop_rgba (1, 0.7, 0, 0, 0.5)
bide.add_color_stop_rgba (0, 0.9, 0.7, 0.2, 1)
# hondoa marraztu eta koloreztatu
testuing.rectangle (0, 0, 1, 1) # errektangulua (x0, y0, x1, y1)
testuing.set_source (bide)
testuing.fill ()
testuing.translate (0.1, 0.1) # Abiapuntu-aldaketa
# marrazten hasi
testuing.move_to (0, 0)
# arku zirkular bat (cx, cy, erradioa, hasiera_angulua, bukaera_angulua)
testuing.arc (0.2, 0.1, 0.1, -math.pi/2, 0)
# lerro zuzen bat (x,y)-raino
testuing.line_to (0.8, 0.2)
# kurba bat 3 puntuz (x1, y1, x2, y2, x3, y3)
testuing.curve_to (0.4, 0.2, 0.5, 0.4, 0.2, 0.8)
# hasierara itzuli
testuing.close_path ()
# arkatzaren kolorea eta lodiera
testuing.set_source_rgb (0.3, 0.2, 0.5)
testuing.set_line_width (0.01)
# finkapena
testuing.stroke ()
# fitxategira
azalera.write_to_png ("adib-marrazki.png") # irteera png formatoan
Kontuan hartu behar da metodoak objektu desberdinen gainean aplikatzen direla: cairo gainean hasieran (cairo.ImageSurface eta cairo.Context esaterako), baina baita metodo horiek itzulitako objektuen gainean ere (testuing.arc, t¡testuing.line edo azalera.write_to_png esaterako).
8.6.2. Grafikoak
[aldatu]Bisualizazio-tresnak gero eta garrantzia handiagoa hartzen ari dira informazioa azaleratzeko orduan. Datu numerikoak aurkezteko tresnak gero eta zabalduago daude, eta atal honetan Pythoneko aukera interesgarrienak aipatu eta adibide bat landuko dugu.
Matplotlib da modulu zahar eta ezagun bat, baina oso oinarrizkoa da. Liburutegi horretan oinarrituta beste batzuk sortu dira lana errazteko moduan: Pandas, Seaborn, eta ggplot. Plotly ere aipa daiteke, hodeiko zerbitzu bat delako, baina Pythonetik atzitzeko API bat daukana. Informazio gehiago kontsulta daiteke web orri honetan: http://pbpython.com/visualization-tools-1.html. Bertatik ere hartu ditugu adibidearen ideia nagusiak.
Pandas izango da adibidean erabiliko duguna. Pandas (https://pypi.python.org/pypi/pandas) ahaltsua eta malgua da, NumPy moduluan oinarritzen da kalkulu numerikorako, eta R lengoaiarekin lan egiten dutenentzat gertuko ezaugarriak ditu.
Erabili baino lehen, matplotlib, numpy eta pandas moduluak instalatu behar dira (denbora luze samar hartzen du):
apt-get install libfreetype6-dev
# gerta daiteke ez izatea
sudo python3 -m pip install numpy
sudo python3 -m pip install matplotlib
sudo python3 -m pip install pandas
Bisualizatzeko datu-fitxategia, berriz, CSV ataleko adibidean erabiliko dugu gure adibidean, CSV izan ohi baita ohiko formatu bat datu-analisietako atazetan.
8.9. programan dugu pandas erabiltzeko erraztasuna adierazten duen adibide bat. Bertan barren bidezko grafiko bat idazten da (png fitxategi batera) 6 urratsetan:
- moduluen karga import bitartez
- csv fitxategia irakurtzea read_csv metodoaz
- boto-emaileen araberako sailkapena eta erregistroen selekzioa (4 handienak) sort_values metodoaren bitartez
- grafikoa sortzea plot metodoaz
- irudi bihurtzea, get_figure metodoaz
- png formatuan gordetzea savefig metodoaz
8.9. programa. Datuak modu grafikoan pandas moduluaren bitartez.
import pandas
bozk = pandas.read_csv("adibidea.csv")
# boto-emaleez sailkatu eta handiena (totalak) kendu eta lehen 4ak hartu
bozk = bozk.sort_values('Boto-emaleak',ascending=False)[2:6]
# graf mota (bar), x ardatzean Herria
bozk_plot = bozk.plot(kind="bar",x=bozk["Herria"],
title="Parte hartzea (lehen 4ak)",
legend=False)
fig = bozk_plot.get_figure()
fig.savefig("adibidea-plot.png")
Aurreko adibidean bezala, metodoak objektu desberdinen gainean aplikatzen dira: pandas gainean hasieran, honek itzulitako bozk gainean gero, eta prozesuan sortutako bozk_plot eta fig objektuen gainean bukaeran.
Lortutako irudia 8.2. irudian ikus daiteke.
8.2. irudia. Datuetatik lortutako grafikoa:
??? 8.2 irudia
8.7. BESTELAKOAK
[aldatu]Luze joko luke Pythoneko liburutegi osoa, bere modulu guztiekin, azaltzeak. Kapitulua bukatu baino lehen bi multzo bakarrik: internazionalizazioari dagozkionak eta datu-egituren ingurukoak.
8.7.1. Internazionalizazioa (i18n)
[aldatu]Hainbat hizkuntzatara egokitutako programak egiteko internalizazio deritzon prozesua funtsezkoa da. Mezuak, zenbakien zein daten idazkera eta abar egokitu behar dira hizkuntzen arabera. Hizkuntza bakoitzaren egokitzapen horri locale izena ematen zaio eta prozesuari lokalizazioa. Internalizazio/lokalizazio prozesu horietarako Pythonen ezinbestekoa da gettext eta locale moduluak, beste lengoaia askotan ere erabiltzen direnak, ulertzea eta erabiltzea.
Testuen itzulpenari dagokionez, gettext modulua .po eta .mo motako fitxategietan oinarritzen da. Bost urratsetan oinarritzen da internazionalizatzeko egokitutako programa:
- Inprimatzeko mezuak hizkuntza lehenetsian idazten dira (ingelesez gure adibidean) programan, baina print(mezu_aldag) edo print("mezu") zehaztu beharrean print(_(mezu_aldag)) edo print(_(u"mezu")) zehaztuz. u hori garrantzitsua da Unicode aplika dadin.
- Mezuak lortu jatorrizko programatik pygettext programaren bidez, eta .pot luzapena duen fitxategi batean gorde (messages.pot fitxategian geratzen dira besterik esaten ez bada).
- Prestatu mezuak hainbat hizkuntzatarako eta gorde .po eta .mo formatuan (bana hizkuntza bakoitzeko). Horretarako editore berezi bat erabil daiteke, adibidez poedit (Instalatzeko: sudo apt-get install poedit). .mo eta .po fitxategiak aplikazioari dagokion katalogoaren azpian: gure kasuan locale/eu/LC_MESSAGES/proba-i18n.mo
- Berriro programan, hasieran, gettext modulua barneratu import bitartez, eta gettext.translation metodoaz mezuak itzultzeko lotura egin (proiektuaren izena eta katalogoa zehaztuz). Lotura egin eta gero install metodoa ere zehaztuko da.
8.10. programan ikus daiteke adibide bat, aipatutako 1. eta 4. urratsak barneratzen dituena.
8.10. programa. Internazionalizaziorako proba:
import gettext
lokal = gettext.translation('proba-i18n', localedir='locale', languages=['eu'])
#lokal = gettext.translation('proba-i18n', localedir='locale')
lokal.install()
try:
print(_(u"Hello world"))
print(_(u"i18n for internazionalization"))
print(_(u"l10n for localization"))
print(_(u"Bye"))
except:
print(_(u"Error in program"))
Aipatutako 2. eta 3. urratsak egiten badituzu eta p-i18n.py programa probatzen baduzu, honako emaitza aterako da exekutatzean:
Kaixo mundua
i18n intenazionalizaziorako
l10n lokalizaziorako
Agur
Nahiz eta programaren mezuak ingelesez egon. Gauza bera gertatuko da gettext.translation metodoa zehazten ez baduzu eta sistema euskaraz baduzu (euskaraz duzula egiaztatzeko komando hau erabil dezakezu: echo $LANG) . Kasu horretan sistemak ezarrita duen hizkuntzan ariko da.
Oinarrizko informazioa hemen kontsulta daiteke: https://docs.python.org/3/library/i18n.html. Adibide osagarri bat hemen aurki daiteke: http://inventwithpython.com/blog/2014/12/20/translate-your-python-3-program-with-the-gettext-module/.
Bukatzeko, locale moduluaren bidez Python kodean lokalizazioari dagozkion aldagaiak ezar daitezke, LC_ALL batez ere. getlocale eta setlocale metodoak dira erabilienak. Adibidez aurreko programan ondoko bi lerroak gehitzen baditugu hasieran: (Instalatuta dituzun locale-ak ezagutzeko komando bat dago: locale)
import locale
locale.setlocale(locale.LC_ALL, 'eu_ES.utf8'*)
8.8. PROPOSATUTAKO ARIKETAK
[aldatu]- Sortu modulu bat liburutegi sinple baterako. Oinarrizko objektua dokumentua izango da, eta bertatik eratorriko dira liburuak eta aldizkarietako artikuluak. Dena paperean. Oinarrizko metodoak hauek izango dira biltegiratzea, inprimatzea, maileguan uztea eta mailegutik itzultzea.
- Moldatu 8.3. programa zure argazkien artean zoriz 5 hautatzeko.
- Esportatu zure kalkulu-orri bat eta 8.4. programan oinarrituta inprimatu hainbat eremu. Kalkulatu zutabe edo errenkada baten batezbestekoa eta desbiderapen tipikoa. Sortu grafiko bat Pandas bitartez.
- Datu-baseen gaineko metodoak erabiliz, 8.7. programaren kodea zabaldu datu-baseko datuak editatzeko. Probatzeko zuzendu Argentinaren azalera.
- Datu-base berri bat sortu behar duzu csv fitxategi batetik. Horretarako WorldData info gunetan dagoen fitxategia erabiliko da (https://www.worlddata.info/downloads/countries.csv) eta bertan dauden informazioak barneratuko dira datu-basean. Bigarren urrats moduan herrialdeen hizkuntza nagusiak (gehienez 3) gehitzeko aukera programatu behar duzu.