Edukira joan

PYTHON liburua/Klase berriak eta ohikoenak

Wikibookstik

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:

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:

Caption text
# 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]
  1. 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.
  2. Moldatu 8.3. programa zure argazkien artean zoriz 5 hautatzeko.
  3. 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.
  4. Datu-baseen gaineko metodoak erabiliz, 8.7. programaren kodea zabaldu datu-baseko datuak editatzeko. Probatzeko zuzendu Argentinaren azalera.
  5. 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.