PYTHON liburua/Sistemaren gaineko aukerak

Wikibookstik

9. Sistemaren gaineko aukerak[aldatu]

Lau azpiataletan banatuko ditugu Pythonetik balia daitezkeen aukerak: sistemaren komandoak, administrazioa, sistema-deiak eta multithreading bidezko konkurrentzia.

Lehen bi ataletako kontzeptuak lantzeko on-line dagoen liburu hau gomendatzen dugu: Linux: Sistemaren eta sarearen administrazioa (http://ueu.org/download/liburua/LINUXDebian.osoa.pdf). Sistema-deien inguruan dokumentu hau kontsulta daiteke: http://www.sc.ehu.es/acwlaalm/seo/teoria/2-gaia.pdf.

Zazpigarren kapituluan aipatu den os moduluak aukera handiak eskaintzen ditu sistema eragilearekiko interakziorako. Nagusiki bi dira SEak eskaintzen dituen eragiketak: komandoak eta sistema-deiak. Komandoak programa exekutagarriak izan ohi dira eta sistema-deien bidez programatu ohi dira. Sistema-deiak, berriz, SEaren oinarrizko funtzioak dira eta sistemen rogramazioaren oinarria. Informazio gehigarria URL honetan aurki daiteke: https://docs.python.org/3/library/os.html.

Kontuan hartu behar da Unix/Linux sistemetan bakarrik direla erabilgarriak ondoren azalduko ditugun metodoak.

Beste kapituluetan aukera eman dugu exekuzioak hodeian egiteko Colab bitartean edo norberaren konputagailuan. Kapitulu honetan ordea, norberarenean bakarrik egin ahal izango da, norberaren sstema eragilean.

9.1. SISTEMAREN KOMANDOAK[aldatu]

Komandoak exekutatzeko biderik erosoena os.system metodoa erabiltzea da. Parametro gisa komando-lerroa adierazten duen karaktere-katea izango da.

Adibidez 9.1. programan honako hau egiten da: proba1 fitxategia bertan sortu ('1' karakterea izango da haren edukia), berri izeneko katalogo berri bat sortu, bertara aurreko fitxategia kopiatu (laneko izenarekin) eta hasierako fitxategia (proba1) ezabatu.

9.1. programa. Komandoen erabilera Pythonetik:

import os
os.system("echo '1' >proba1")
os.system("mkdir berri")
os.system("cp proba1 berri/laneko")
os.system("rm proba1")

Modu orokor horrez gain, komando espezifikoak adierazteko metodoak ere eskaintzen ditu modulu honek. Arazotxo bat dute metodo hauek, haien izena batzuetan komando berarena da (chown, chroot, chmod, mkdir, mkfifo...), baina beste batzuetan beste luzeago bat (link eta ez ln, remove eta ez rm, rename eta ez mv...).

9.2. programa. Komandoei dagozkien metodo espezifikoak:

import os
os.system("echo '1' >proba1")
os.mkdir("berri")
os.system("cp proba1 berri/laneko")
os.remove("proba1")

9.2. programa aurrekoaren baliokidea da, baina kasu honetan mkdir eta remove metodo espezifikoak erabili dira system metodo orokorraren ordez.

9.3. programan, berriz, sistemaren kontrolerako komando batzuen erabilera ikus daiteke. top erabiltzen da prozesadorearen egoeraz jabetzeko, vmstat memoriarako, df disko-partizioetarako eta ifconfig sare-interfazeetarako.

import os
print("CPU:")
os.system("top -b -n 1 | head -2")
print("\nMemoria:")
os.system("vmstat")
print("\nPartizioak:")
os.system("df")
print("\nSare-interfazeak:") 
os.system("/sbin/ifconfig")

Komandoen exekuzioak itzultzen duena errore-kodea izan ohi da, baina eragina normalean irteera estandarrean islatzen da (edo, adibideetan egin den bezala, fitxategiren batean irteera estandarra birbideratuz). Irteera hori aldagairen batean eskuratzeko subprocess moduluaren check_output metodoa erabil daiteke. Adibidez:

emaitza = subprocess.check_output('df')

Bestalde, komandoen erabilera errazteko, eta batez ere sistemaren eraginkortasunaren kontrola errazteko, psutil modulua erabil daiteke (https://github.com/giampaolo/psutil). Bertako metodoen bidez sistemaren baliabideak (CPU, memoria, diskoa, sarea...) nola erabiltzen ari diren monitoriza daiteke. Aurretik instalatu behar da komando honen bidez:

sudo apt-get install python-psutil

9.4. adibidean erabileraren adibide bat agertzen da.

9.4. programa. Komandoei dagozkien metodo espezifikoak:

import psutil
print("CPU:\n", psutil.cpu_times())
print("\nMemoria:\n", psutil.virtual_memory())
print("\nPartizioak:\n", psutil.disk_partitions())
print("\nSare-interfazeak:\n", psutil.net_if_addrs())

9.2. ADMINISTRAZIOA[aldatu]

Administrazio-lanak burutzeko komandoak eta konfigurazioa-fitxategiak erabiltzen dira. Komando-fitxategiak osatu ohi dira lanak automatizatzeko scripting delakoaren bidez. Komando-fitxategi horietan komandoak eta script-lengoaiak konbinatu ohi dira eta Python, gero eta gehiago, erabiltzen da script-lengoaia gisa. Adibide batzuen bitartez landuko ditugu (URL honetan informazio gehiago horretaz: https://www.linuxjournal.com/content/python-scripts-replacement-bash-utility-scripts.

Hasteko adibide bat: testeatzeko script bat (wifi konexioarekin bakarrik proba daiteke). Linuxen 'sudo iw wlan0 scan' komandoaren bidez inguruan dauden sareen informazioa jaso daiteke (baimena behar da; hori dela-eta pasahitza eskatuko digu sistemak). Ariketa honetarako lerro desberdinetan dauden eremu hauek interesatzen zaizkigu: identifikazioa (SSID) eta seinalearen kalitatea (signal). 9.5. programan inguruko wifi konexioen datu horiek selekzionatzen ditugu.

9.5. programa. Inguruko wifien informazio laburtua:

import os
os.system("sudo iw wlan0 scan >tmp")

for lerro in open('tmp','r').readlines():	# lerroka
    if "signal" in lerro:
        ahal = lerro
    if "SSID" in lerro:
        print(lerro, ahal)

os.system("rm tmp")

Gauza konplexuagoak egin daitezke, adibidez konexioa aktibatzea. Ikus adib. <http://stackoverflow.com/questions/20470626/python-script-for-raspberrypi-to- connect-wifi-automatically>.

Bigarren adibidean sistemaren erabileraz arituko gara. 'ps -aux' komandoaren bidez lortzen den informazioa multzokatzen da erabiltzaileen arabera 9.6. adibidean, erabiltzaile bakoitzeko CPUren portzentaje metatuak lortuz.

Hona hemen komandoaren lehen lerroen adibide bat:

USER	 PID %CPU	%MEM VSZ	  RSS	  TTY	STAT	START	TIME	 COMMAND
root	 1	 0.0	0.0	 33736	3044	?	  Ss	 16:59	0:01	 /sbin/init
root	 2	 0.0	0.0	 0      0    ?    s	   16:59	0:00	 [kthreadd]
root	 3	 0.0	0.0	 0	    0	    ?	  S	   16:59	0:00	 [ksoftirqd/0]
root	 5	 0.0	0.0	 0	    0	    ?	  S<	 16:59	0:00	 [kworker/0:0H]
root	 7	 0.0	0.0	 0	    0	    ?	  S	   16:59	0:01	 [rcu_sched

Lehen eta hirugarren zutabeak dira interesatzen zaizkigunak. Lehena erabiltzailea denez, hiztegia indexatzeko erabil dezakegu. Hiztegi batean CPUren balioak metatuko ditugu (lagungarria izango da 6. kapituluan landutako hiztegiak).

9.6. programa. CPUren erabilera erabiltzaileen arabera:

import os

cpu = dict()

os.system("ps -aux >tmp")

for lerro in open('tmp','r').readlines():	# lerroka
    hitzak = lerro.split() 
    if hitzak[0]!='USER':			# lehen lerroa ez
        if hitzak[0] in cpu:			# hiztegian?
            cpu[hitzak[0]] += float(hitzak[2])	
        else:
            cpu[hitzak[0]] = float(hitzak[2])

for erab in cpu:				# erabiltzaileka
	print(erab,cpu[erab])

Beste aukera bat dago, Python programatik komandoen erreferentzia kendu eta komando-lerro hau idatzi:

ps -aux | python3 p9-6_script2b.py

Gainera, programaren sarrerak ez du tmp izan behar, sarrera estandarra baizik. Hori dela-eta, irakurketa errazten da, honela geratuz:

for lerro in sys.stdin:

Konplexutasuna igoz, 9.7. adibidean, azkenik, http://askubuntu.com/questions/547437/find-delete-duplicated-files-on-multiple-harddisks-at-once web orrian aurkitutako scriptaren moldaketa agertzen da. Bertan, parametro gisa jasotzen diren katalogoetan bilatzen dira izen bereko fitxategiak, eta izen errepikatuak pantailaratzen dira.

Horretarako erabilgarri gertatzen da os.walk metodoa, zeinaren bidez katalogo baten azpian dauden azpikatalogo bakoitzeko (bera barne) azpikatalogo eta fitxategi guztiak itzultzen dituen. Horrela hirukoteen zerrenda bat itzultzen du, hirukote bat azpikatalogo bakoitzeko, hirukotearen elementuak hauek izanik: (azpi)katalogoaren bidea, azpian dituen azpikatalogoak (zerrenda) eta azpian dituen fitxategiak (zerrenda).

9.7. programa. Fitxategi bikoiztuak bilatzeko scripta:

#http://askubuntu.com/questions/547437/find-delete-duplicated-files-on-multiple-harddisks-at-once

import os
import sys

izenak = []		# izen sinpleak biltzeko
fitxategiak = []	# izen osoak biltzeko

def bilatu_fitx(dir):	# katalogoaren fitx-ak os.walk bidez
    l = []; l2 = []
    for erro, dir_ak, fitx_ak in os.walk(dir):
        for fitx in fitx_ak:
            l.append(fitx)		# izen sinpleak	
            l2.append(erro+"/"+fitx)	# izen osoak
    return (l, l2)		# itzuli izen sinpleak eta osoak

for dir_i in sys.argv:		# argumentuak
    print("Fitxategien zerrenda sortzen...", dir_i)
    izenak = izenak+bilatu_fitx(dir_i)[0]		# 0-sinpleak
    fitxategiak = fitxategiak+bilatu_fitx(dir_i)[1]	# 1-osoak

print("Bikoiztuak detektatzen ("+str(len(izenak)),"fitx)...")
for izen in izenak:
    n = izenak.count(izen)
    if n > 1:
        print("-"*60,"\n>  bikoiztuta:", izen, n, "\n")
        for item in fitxategiak:
            if item.endswith("/"+izen):	#endswith metodoa bukaerarako
                print(item)


Programa probatzeko onena da bi azpikatalogo sortzea (dir1 eta dir2) eta bakoitzean hainbat fitxategi kopiatzea. Deitzean bi katalogoen izenak parametro gisa pasako dira, eta fitxategiren bat bi katalogoetan baldin badago, detektatuko da.

9.3. SISTEMA-DEIAK[aldatu]

Esan bezala sistema-deiak SEaren oinarrizko funtzioak dira. Python sistemen programazioari eta administrazioari begira lengoaia egokia da, beste gauzen artean, sistema-deiak zuzenean erabiltzea bideratzen duelako.

Sistema-deien bidez sistemaren baliabideak zuzenean erabil daitezke. Adibidez:

  • prozesuen informazioa eskuratzea eta aldatzea: getpid, getuid, seteuid...
  • prozesuak sortzea, exekutatzea, itxoitea eta hiltzea: fork, exec-en aldaerak (execl, execvp...), wait, kill
  • komunikazioak: pipe, mkfifo...
  • fitxategiak (zuzenean kanal-zenbakiaren bidez): open, read, write, lseek, dup...

Hemen ez dugu tokirik sistema-deien inguruko kontzeptuetan sakontzeko, baina aipatutako gunean horren inguruko informazio ugari aurki daiteke. Oro har, sistema-dei bakoitzari metodo bat dagokio.

9.8. adibidean sistemen programazioan ohikoak diren bi eragiketa (metodoak Pythonez) erabiltzen dira: prozesu umea sortzea (fork) eta komunikazio-kanala sortzea (pipe). Adibidean sortzen den kanalaren bidez umeak idazten duena gurasoak irakurtzen du eta pantailaratzen du.

# FIFO batez komunikatzea

import os, sys, time

# izen gabe FIFOa (pipe) sortzea
ir,id=os.pipe()	# bi zenbaki itzultzen du bat irakurtzeko eta bestea idazteko

# 2 fitxategi 
blokel=1024
r=os.fdopen(ir,'r',blokel)	# irakurketarako ireki
w=os.fdopen(id,'w',blokel)	# idazketarako ireki

pid = os.fork()
if pid:          # gurasoa (irakurlea)
    w.close()
    while 1:
        data=r.readline()	# FIFOtik irakurri
        if not data: break
        print("gurasoa read: ", data.strip())  # inprimatu pantailan

else:             # umea (idazlea)
    r.close()
    for i in range(10):
        w.write("lerroa: " + str(i) + "\n")  # FIFOn idatzi
        w.flush()		# memoriatik S/Ira
        time.sleep(1)		# segundo bat itxoin

9.4. MULTITHREADING[aldatu]

Multiprozesadoreen aukeraz baliatzeko eta aplikazioak azkartzeko hari anitzeko edo multithreading izeneko mekanismoa erabiltzen da. Hariak (thread) exekuzio-fluxuak dira, prozesuaren memoria eta fitxategiak partekatzen dituztenak, baina prozesadoreari (edo prozesadoreei) begira lehiakideak direnak. Gaur egungo programazio konkurrente eta paraleloaren funtsa dira, eta programazio-lengoaien esku dago haiei etekina ateratzea (beti azpiko sistema eragileak uzten duenean).

Pythonen kasuan alde handi samarra dago ezaugarri honi begira Python2.4 bertsiotik aurrera. Lehenago thread moduluari dagozkion metodoak erabiltzen ziren helburu horrekin. Ahalmen mugatua du modulu honek, adibidez prozesu umeen zain geratzeko. Python2.4 bertsiotik aurrera muga horiek gainditu dira threading moduluaren bidez, eta, gainera, objektuei orientatutako programazioari eman zaio lehentasuna. Hala ere, aurreko moduluaren metodoak ere erabil daitezke, baina Python3 erabiltzen bada, aldaketatxo bat gertatu da: _thread izena zehaztu behar da modulu hori erabiltzeko. Laburbilduz, Python3-n bi modulu erabili ahal izango dira, _thread izenekoa, sinplea baina mugatua; eta threading izenekoa, osatuagoa eta objektuei orientatua.

Programazioari dagokionez, hari bakoitzari funtzio bat edo metodo bat dagokio. Programaren arabera hariek funtzio/metodo bera erabiliko dute (nagusi-morroi eredua deitu ohi denean morroiekin egiten den bezala) edo hari bakoitzak metodo/funtzio berezi bat edukiko du (pipe eredua da horren adibidea). Bi kasuetan funtzioak/metodoak definitu eta gero, programa nagusia harien sorreraz arduratuko da.

Adibide sinple batekin hasiko gara. Bi hari sortuko ditugu eta bakoitzak ordua inprimatuko du hiru aldiz denbora-tarte bat itxaron eta gero. Hori programatzeko bi aukera ditugu: bertsio zaharretan erabiltzen zen thread klaseko start_new_thread metodoa (p-thread-1.py); eta threading klaseko Thread metodoa p-thread-1b.py). Lehen kasuan, programa nagusia zain geratzen da etengabe, bestela bukatuko litzateke hariak amaiaraziz. Beraz, probatzean CTRL-C bidez amaiarazi beharko duzu.

9.9a. programa. Bi hari, bakoitzak bere ordua idazten:

mport _thread as thread 
import time

# hariari dagokion funtzioa
def inpri_denbora(haria, atzerapena):
   kontag = 0
   while kontag < 3:		# 3 aldiz
      time.sleep(atzerapena)	# itxoitea (segundotan)
      kontag = kontag + 1
      print(haria, "- ordua:", time.ctime(time.time()))

# programa nagusia: bi hari sortuko duena
try:
   thread.start_new_thread(inpri_denbora,("1. haria",2,))
   thread.start_new_thread(inpri_denbora,("2. haria",4,))
except:
   print("Errorea: ezin haria sortu")

# itxoitea harien bukaerararte
while 1:
   pass

Bigarren kasuan, gomendagarriena, programa nagusian ez da itxaron behar; baina hari bakoitzeko bi urrats egiten dira: hariaren definizioa Thread metodoaren bidez batetik, eta haria martxan jartzea start metodoaz.

9.9b. programa. Bi hari, bakoitzak bere ordua idazten:

from threading import Thread
import time

# hariari dagokion funtzioa
def inpri_denbora(haria, atzerapena):
   kontag = 0
   while kontag < 3:		# 3 aldiz
      time.sleep(atzerapena)	# itxoitea (segundotan)
      kontag = kontag + 1
      print(haria, "- ordua:", time.ctime(time.time()))

# programa nagusia: bi hari sortuko duena
try:
   t1=Thread(target=inpri_denbora, args=("1. haria",2,))
   t1.start()
   t2=Thread(target=inpri_denbora, args=("2. haria",4,))
   t2.start()
except:
   print("Errorea: ezin haria sortu")


threading modulua oso ahaltsua da, baina konplexua ere. Oinarrizko metodoak hauek dira (Thread klasean, baina threading klasetik eskuragarri):

  • run(): Hariaren sarrera-puntua definitzeko objektuetan.
  • start(): Haria abiaraztea run metodoa erabiliz (objektuetan) edo funtzio batez.
  • join([time]): Harien zain geratzea.
  • isAlive(): Haria indarrean dagoen ala ez galdetzea.
  • getName(): Hariaren izena lortzea.
  • setName(): Hariaren izena ezartzea.

Aurreko moduluaren metodoez gain, beste batzuk ditugu eskuragarri threading moduluan:

  • threading.activeCount() : Sortutako hari aktiboen kopurua itzultzen du.
  • threading.currentThread() : Hari deitzaileari dagozkion harien kopurua itzultzen du.
  • threading.enumerate() : Indarrean dauden harien izenak itzultzen ditu, zerrenda batean.

Gainera, klase-herentzia bidez klase berriak defini daitezke, objektuei orientatutako metodologiari jarraituz. Horrela 9.9b. adibidea eratorritako klase batez ebazten da 9.9c. programan. Bertan, DenbHaria klasea definitzen da, threading. Thread klasetik eratorrita, beraz, haren objektuei klasearen metodo guztiak aplika dakizkieke. Gure kasuan run metodoa birdefinitu da eta start metodoa aplikatzen da hura aktibatzeko.

9.9c. programa. Hariak klase eratorri gisa:

import threading
import time

class DenbHaria (threading.Thread):
    def __init__(self, threadID, izen, kont):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.izen = izen
        self.kont = kont
    def run(self):
        inpri_denbora(self.izen, self.kont)

def inpri_denbora(haria, atzerapena): 
   kontag = 0 
   while kontag < 3:		# 3 aldiz 
      time.sleep(atzerapena)	# itxoitea (segundotan) 
      kontag = kontag + 1 
      print(haria, "- ordua:", time.ctime(time.time())) 

try:
# Hariak sortzea
   t1 = DenbHaria(1, "Thread-1", 2)
   t2 = DenbHaria(2, "Thread-2", 4)
# Hariak abiatzea
   t1.start()
   t2.start()
except: 
   print("Errorea: ezin haria sortu")
aaaaa


Aurreko programa nahiko sinplea da, baina ez da oso praktikoa. Praktikotasunaren bila, p-koman-2.py adibideko programa harien bidez programatuko dugu (threading modulua erabiliz). Zazpigarren kapituluan egindako baten egokitzapena da. Bertan hainbat URLtatik irakurtzen da, eta horretarako hari bat sortzen da hari bakoitzeko. Irakurritakoa inprimatzen da HTML etiketak kenduta, eta horretarako erabiltzen da instalatu dugun html2text modulua.

9.10. programa. Webguneak irakurtzen hari desberdinetatik:

import sys
import threading
from urllib.request import urlopen
from html2text import html2text

# 7.9 programaren egokitzapena

# hariari dagokion funtzioa
def eskuratu_url(url):
    print(url)
    orri=urlopen(url)
    for lerro in orri: 
        lerro = lerro.decode('utf-8')
        txt = html2text(lerro)		# html etiketak kentzeko
        if len(txt)>20:		# 20 karakatere baino gehiago
            print(txt)

urlak = ["http://sustatu.eus", "http://ueu.eus"]

for u in urlak:
    t = threading.Thread(target=eskuratu_url, args = (u,))
    t.start()


Liburu honetan ez dugu asko sakonduko gai honetan. Adibidez ez gara sartuko sinkronizazio eta komunikaziorako dauden klase eta metodoetan. Edozein kasutan http://www.tutorialspointkk.com/python/python_multithreading.htm helbidean informazioa osa daiteke (https://docs.python.org/3/library/threading.html

Python3-ko zehaztasunetarako). Adibide konplexuago bat helbide honetan kontsulta daiteke: http://www.toptal.com/python/beginners-guide-to-concurrency-and-parallelism-in-python.

9.5. ADIBIDEAK[aldatu]

9.5.1. 1. enuntziatua:[aldatu]

Katalogo baten fitxategi guztietan testu baten agerpena bilatzen duen programa egin behar da, baina fitxategi bakoitzean bilaketa hari batez egingo da. Hari bakoitzaren kodea sinplea izango da, grep komandoa erabiltzea baino ez. Komando horrek 0 itzuliko du, karaktere-katea aurkitu badu. Komandoaren irteera pantailatik ager ez dadin, /dev/null dispositibo nulura birbideratuko da. Objektuen orientazioarekin egingo dugu, eta horretarako 9.9c. programan oinarrituko gara.

9.11. programa. grep bidezko bilaketa konkurrentea:

import threading
import os
import sys

class BilaFitxHaria (threading.Thread):
    def __init__(self, fitx, st):
        threading.Thread.__init__(self)
        self.fitx = fitx
        self.st = st
    def run(self):
        bila_fitx(self.fitx, self.st)

def bila_fitx(f, kate): 
   em = os.system("grep " + kate + " " + f + " >/dev/null") 
   if not em:		
      print(f) 

try:
   for f in os.listdir(sys.argv[1]):	# katalogoko fitxategi bakoitzeko 
      if(os.path.isfile(f)):		# fitxategiekin bakarrik
         t = BilaFitxHaria(f,sys.argv[2])
         t.start()
except: 
   print("Errorea: ezin haria sortu")

Erabiltzeko bi parametro pasa behar dira: katalogoa eta bilatu nahi den karaktere-katea. Bilaketa katalogoko fitxategietan egiten da azpikatalogoetan sartu gabe. Azpikatalogoetan sakontzeko os.walk metodoa erabil daiteke.

9.5.2. 2. enuntziatua:[aldatu]

9.8. programan azaldutako FIFOaren adibidea harien bidez ebatzi behar da, prozesuen bidez erabili beharrean. Horretarako, bi funtzio definituko dira: irakurlea bata, idazlea bestea. Thread metodoaren bidez abiatuko dira. Sistema-dei gehienak (prozesuak sortzearenak kenduta) berdin geratzen dira.

9.12a. programa. FIFO batez komunikatzea hariak erabiliz:

# FIFO batez komunikatzea hariak erabiliz

import os, sys, time
import threading

def irakurle(irf):
    print("...irakurtzen")
    while 1:
        data=irf.readline()	# FIFOtik irakurri
        print("irakurle read: ", data.strip())  # inprimatu pantailan
    return

def idazle(idf):
    global harikop
    print("...idazten")
    for i in range(10):
        idf.write("lerroa: " + str(i) + "\n")  # FIFOn idatzi
        idf.flush()		# memoriatik S/Ira
        time.sleep(1)		# segundo bat itxoin
    return

# izen gabe FIFOa (pipe) sortzea
ir,id=os.pipe()	# bi kanal, bat irakurtzeko eta bestea idazteko

# 2 fitxategi 
blokel=1024
ird=os.fdopen(ir,'r',blokel)	# irakurketarako ireki
idd=os.fdopen(id,'w',blokel)	# idazketarako ireki

print("Hasiera")
t1=threading.Thread(target=irakurle,args=(ird,))
t1.start()
print("irakurlea martxan")
t2=threading.Thread(target=idazle,args=(idd,))
t2.start()
print("idazlea martxan")

9.6. PROPOSATUTAKO ARIKETAK[aldatu]

1) Aldatu 9.6. programa CPUren portzentajeak metatzeaz gain, memoriakoak ere metatzeko. Gainera, emaitzek erabileraren arabera sailkatuta agertu behar dute (sort komandoa erabil daiteke horretarako, baina Pythonen klaseak ere). 2)Aldatu 9.10. programa, honako helburuak lortzeko:

    • Irakurri behar diren web orrien helbideak fitxategi batean egotea.
    • Hariak klase eratorri gisa definitzea.
    • Irakurtzen diren orrietatik testua lortu ondoren, inprimatu beharrean hiztegia osatu eta maiztasunak kalkulatzea. Horretarako hari guztien informazioa jaso beharko da.

3) Egin Python programa bat bi matrizeren arteko biderketa egiteko harien bitartez. Hari bakoitzaren funtzioa izango da errenkada eta zutabe bat biderkatzea eta emaitzaren elementu bat lortzea. Bukaeran emaitza inprimatuko da. Oinarri gisa 6.4. programa har daiteke.