python

Relacionet: Fjalorët

Krijimi i fjalorëve

Deri tani kemi parë disa lloje të dhënash: të dhënat që janë të llojit numër (numrat e plotë, dhjetorë etj.), të dhënat që janë të llojit sekuencë (vargje, lista, n-she etj.). Tani do të shohim të dhënat e llojit relacion: fjalorët.

Relacionet janë koleksione të ndryshueshme që grupojnë struktura të dhënash të llojeve të ndryshme. Fjalorët janë i vetmi lloj që na ofron pythoni në kategorinë relacione. Për fjalorët mund të themi se janë:

Fjalorët mund t'i krahasojmë me fjalorët gjuhësorë. Kur duam të dimë shpjegimin e një fjale të caktuar në fjalor, ne i referohemi fjalës, për të gjetur përmbajtjen e saj. Në analogji me fjalorët gjuhësorë edhe me fjalorët në python veprohet në të njëjtën mënyrë. Fjalorët kanë çelësa (si fjalët që duam të kërkojmë në fjalor) dhe vlera ( si shpjegimi i këtyre fjalëve). Njësoj si në fjalorët gjuhësorë, ku fjalët janë unike ndërsa shpjegimet edhe mund të përsëriten, edhe tek fjalorët e pythonit, çelesat janë unike ndërsa vlerat jo detyrimisht. Shembuj mund të sjellim psh. me fjalët udhë-rrugë.

Rrugë:
  1. 1. Brez ose rrip toke i rrahur a i shtruar për të kaluar njerëzit, kafshët dhe mjetet; vija në ajër ose në det, nëpër të cilën kalojnë mjetet e fluturimit a të lundrimit; udhë.
  2. 5. Largesa që duhet të përshkojmë për të shkuar nga një vend në një tjetër; koha që duhet për të shkuar në një vend tjetër.
Udhë
  1. 1. Brez ose rrip toke i rrahur a i shtruar për të kaluar njerëzit dhe mjetet; vija në ajër ose në det, nëpër të cilën kalojnë mjetet e fluturimit a të lundrimit; rrugë.
  2. 3. Largësia për të shkuar nga një vend në një tjetër; koha që duhet për të shkuar në një vend tjetër.

Në fjalor disa nga shpjegimet e këtyre dy fjalëve janë pothuajse të njejta, por dy herë fjalën udhë apo rrugë nuk e gjejmë të renditur në fjalor. Nëse në fjalorët e pythonit do të tentonim të kishim dy çelësa me të njëjtin emër dhe vlera të ndryshme, do të pranohej vetëm vlera e fundit që do t'i jepnim. Thënë ndryshe vlera që do t'i jepnim herën e dytë, nuk krijon një çelës të ri por ndryshon vlerën e çelësit që krijuam.

Sintaksa për krijimin e një fjalori është kjo:

emri_fjalorit = {'celes': 'vlere', 'celesi tjeter': 'vlera tjeter'}

Shembull:

>>> fjalor = {'gjuha': 'perl', 'gjuha': 'python'}
>>> fjalor
{'gjuha': 'python'}

Siç e shohim kemi dy çelësa me të njëjtin emër dhe kanë dy vlera të ndryshme, në këtë rast mbahet vetëm vlera e fundit.

Çelësat e fjalorëve janë të pandryshueshëm. Kjo do të thotë se mund të jenë të llojit: numra, vargje dhe n-she që përmbajnë numra, stringje ose vetë n-she por jo lista, pasi këto të fundit siç i kemi parë janë struktura të ndryshueshme. Pythoni jep gabim sintakse nëse tentohet një listë për çelës. Nëse çelesat do të ishin struktura të ndryshueshme ne momente të caktuara mund të ndryshonin dhe të referonin diku tjetër nga vlera që ne i kemi dhënë.

Fjalorët janë grupime të ndryshueshme, të parenditura, të llojeve të ndryshme të të dhënave.

Shtimi i elementeve dhe heqja e tyre

Sintaksa për të shtuar elementet e një fjalori është:

emri_fjalorit['celesi'] = 'vlera'

Shembull:

>>> f = {'libra': 'programim', 5: 'pese'}
>>> f['printer'] = 'hp'
>>> f
{'libra': 'programim', 5: 'pese', 'printer': 'hp'}

Thamë se fjalorët janë të ndryshueshëm. Për të modifikuar vlerat e elementeve të një fjalori përdoret e njëjta sintaksë si për të shtuar elemente të rinj.

>>> f['libra'] = 'python'
>>> f
{'libra': 'python', 5: 'pese', 'printer': 'hp'}

Në këtë shembull kemi ndryshuar vlerën e çelësit libra nga programim në python. Për të hequr elementet në një fjalor përdoret komanda del dhe metoda clear. Me anë të komandës del mund të heqim një element të fjalorit ose mund ta fshijmë komplet atë.

>>> del f[5]
>>> f
{'libra': 'pyton', 'printer': 'hp'}
>>> del f  # fshin te gjithe fjalorin

Metoda clear() fshin të gjithë elementet e një fjalori por jo vetë fjalorin, pra mbetet një fjalor bosh. Fjalorët bosh nuk kanë elemente ata paraqiten me dy kllapa {}.

>>> f = {'numer': 5, 'muaj': 'shtator'}
>>> f.clear()
>>> f
{}

Shembull: Regjistrimi i popullsisë

Ne mënyrë që të shpjegojmë më qartë fjalorët do të japim një shembull i cili përmbledh edhe disa nga njohuritë e deritanishme. Programi është për regjistrimin e popullsisë dhe sipas kërkesave tona na jep të dhënat e një ose më shumë individi. Le ta shohim hap pas hapi. Hapni një dritare të re dhe le të shkruajmë kodin.

Fillimisht duhet të kemi të qartë se çdo individ duhet të ketë: emrin, mbiemrin, atësinë, ditëlindjen, kodin zip, kombësinë dhe shtetësinë. Këto të dhëna do të ruhen në një n-she me fjalorë. N-shet janë të pandryshueshme dhe shumë praktike për tu përdorur në këtë rast.

Pra n-shja me emrin njerëzit do të këtë katër elemente të llojit fjalor:

njerezit = (
    {
        'emri': 'altin',
        'mbiemri': 'prifti',
        'atesia': 'genti',
        'ditelindja': '29 05 1993',
        'kodizip': '3003',
        'shtetesia': 'shqiperi',
        'kombesia': 'shqiperi'
    },
    {
        'emri': 'altin',
        'mbiemri': 'hoxha',
        'atesia': 'astrit',
        'ditelindja': '08 03 1990',
        'kodizip': '1000',
        'shtetesia': 'austri',
        'kombesia': 'shqiperi'
    },
    {
        'emri': 'klodi',
        'mbiemri': 'hoxha',
        'atesia': 'ismail',
        'ditelindja': '17 11 1978',
        'kodizip': '9400',
        'shtetesia': 'itali',
        'kombesia': 'shqiperi'
    },
    {
        'emri': 'robert',
        'mbiemri': 'krasniqi',
        'atesia': 'bujar',
        'ditelindja': '02 12 1981',
        'kodizip': '2000',
        'shtetesia': 'shqiperi',
        'kombesia': 'shqiperi'
    },
)

Ne duam që ky program të japë të gjitha rezultatet e një fjalori sipas fushës së kërkimit që zgjedh përdoruesi. P.sh përdoruesi mund të dojë t'i shfaqen në ekran të gjithë ata njerëz me të gjitha të dhënat perkatëse të tyre, sipas mbiemrit. Nëse do të donim të na shfaqeshin të gjithë individët me emër altin, do të merrnim këtë pergjigje nga programi:

{'emri': 'altin', 'mbiemri': 'prifti', 'atesia': 'genti', 'ditelindja': '29 05 1993', 'kodizip': '3003', 'shtetesia': 'shqiperi', 'kombesia': 'shqiperi'}
{'emri': 'altin', 'mbiemri': 'hoxha', 'atesia': 'astrit', 'ditelindja': '08 03 1990', 'kodizip': '1000', 'shtetesia': 'austri', 'kombesia': 'shqiperi'}

Tani na duhet të krijojmë një funksion që ruan të dhënat nga kërkesat që jep përdoruesi, kërkon për ekzistencën e këtyre kërkesave tek n-shja njerëzit dhe fund shton dhe ruan në një listë rezultatin.

def kerko_sipas(kriteri, kerkimi, db):
    rezultatet = []
    for rekord in db:
        if rekord[kriteri] == kerkimi:
            rezultatet.append(rekord)
    return rezultatet

Funksioni kerko_sipas ka tre parametra: kriteri, kerkimi dhe db. Parametri kriteri do të përdoret për të përcaktuar fushën e kërkimit të cilat janë: emer, mbiemer, atesia, ditelindja, zipkodi, shtetesia dhe kombesia. Në këtë moment na duhet të krijojmë një listë kriteret e cila duhet të përmbajë këto elemente.

kriteret = ('emri', 'mbiemri', 'atesia', 'ditelindja', 'kodizip', 'shtetesia', 'kombesia')

Parametri i dytë i funksionit kerko_sipas është kerkimi. Ky parametër është inputi i përdoruesit, i cili merret pasi përdoruesi ka përcaktuar kriterin sipas të cilit do të shfaqen rezultatet. Psh. nëse ka zgjedhur t'i shfaqen rezultatet sipas kombësisë, i kërkohet nga programi të shkruajë një komb. Parametri i tretë që ndodhet të funksioni kerko_sipas është db. Sipas parimit të përgjithësimit të kodit të shpjeguar te kapitulli i funksioneve, funksionin kerko_sipas e krijojmë në mënyrë të tillë që të jetë sa më i përgjithshëm. Në programin tonë parametrit db do t'i kalojmë si vlerë n-shen njerezit tek e cila do të bëhen këto kërkime.

Funksioni kërkon tek elementet e n-shes, nëse një nga fushat gjendet atëherë e shton atë në listë përmes metodës append() dhe e ruan tek lista që fillimisht është përcaktuar të jetë bosh.

Tani na duhet të marrim të dhënat nga përdoruesi dhe të thërrasim funksionin që krijuam.

kerkimi = ''
while kerkimi == '':
    try:
        kerkimi = int(raw_input('Do te kerkoni sipas emrit(0), mbiemrit(1), atesise(2), ditelindjes(3), kodit zip(4), shtetit(5) apo kombit(6)? '))
    except ValueError:
        print "Zgjidh nje numer"
kriteri = kriteret[kerkimi]
termi = raw_input('Shkruaj ' + kriteri + ': ')
rekordet = kerko_sipas(kriteri, termi, njerezit)
if rekordet:
    for rekordi in rekordet:
        print rekordi, "\n"
else:
    print kriteri, 'nuk u gjet'

Kjo pjesë e kodit ka filluar me deklarimin e një ndryshoreje, kerkimi, që ka vlerën ''. Për sa kohë kerkimi është bosh '' zbato komandat e mëposhtme. Kur hedhim një vlerë tek kjo ndryshore cikli ndalon.

Inputi që marrim nga përdoruesi ruhet në ndryshoren kerkimi. Nëse inputi nuk është numër, shfaqet një mesazh që i shpjegon perdoruesit që mund të vendosë vetëm numra. Kjo arrihet tek rreshtat e kodit:

except ValueError:
    print "zgjidh nje numer"

Inputi që merret nga përdoruesi i ruajtur tek ndryshorja kerkimi i hidhet si vlerë ndryshores kriteri.

kriteri = kriteret[kerkimi]

Tani që përdoruesi është pyetur se sipas cilës kategori do të kërkojë na duhet të pyesim serish për permbajtjen që do kërkojë.

termi = raw_input('Shkruaj ' + kriteri + ': ')

Pasi përdoruesi ka zgjedhur kategorinë psh. 1 për mbiemrin atëherë i del një pyetje e dytë ku i thotë në këtë rast: "Shkruaj mbiemri:". Mbiemri që përdoruesi shkruan ruhet tek ndryshorja termi.

Në këtë fazë thirret funksioni kerko_sipas dhe vlera që ai kthen i jepet ndryshores rekordet. Funksionit kerko_sipas i kalohen tri argumenta: kriteri, termi dhe njerezit. Këto tre argumenta janë inputi që morëm në fillim për kategorinë, termi që shkruajti përdoruesi në bazë të kategorisë dhe n-shja njerezit. Pra ne i themi funksionit merr kategorinë, përmbajten e kësaj kategorie dhe n-shen. Pythoni e ndrepret leximin e rreshtit të mëposhtëm të kodit tonë dhe shkon të zbatojë komandat që përmban funksioni kerko_sipas.

Nëse funksioni ktheu rekorde (në një bazë të dhënash, rekord quhet një rresht me vlerat e secilës fushë) atëherë i shfaqim në ekran një nga një, përndryshe themi se ky kriter me këtë vlerë nuk gjendet.

if rekordet:
    for rekordi in rekordet:
        print rekordi, "\n"
    else:
        print kriteri, 'nuk u gjet'

Psh. nëse përdoruesi zgjedh fushën 0 pra emrin dhe shkruan një emër që nuk ndodhet tek njerezit, atëherë i thuhet se ky emër që përdoruesi ka shkruar nuk u gjet.

Programit tonë mund t'i bëjmë shtesa ( përmirësime) të ndryshme. Një gjë që mund të ndodhë shpesh është që perdoruesi të shkruajë një numër më të madh sesa 6. Këtë mund ta mënjanojmë nëse vendosim një kufi të zgjedhjeve, gjithashtu të lajmërojmë përdoruesin për përzgjedhjen e numrave.

kerkimi = ''
while kerkimi == '':
    try:
        kerkimi = int(raw_input('Do te kerkoni sipas emrit(0), mbiemrit(1), atesise(2), ditelindjes(3), kodit zip(4), shtetit(5) apo kombit(6)? '))
    except ValueError:
        print "Zgjidh nje numer"
    if kerkimi != '' and ( kerkimi < 0 or kerkimi > 6 ):
        kerkimi = ''
        print "zgjidh nje numer midis 0 dhe 6"
kriteri = kriteret[kerkimi]
termi = raw_input('Shkruaj ' + kriteri + ': ')
rekordet = kerko_sipas(kriteri, termi, njerezit)
if rekordet:
    for rekordi in rekordet:
        print rekordi, "\n"
else:
    print kriteri, 'nuk u gjet'

Rreshtat që janë shtuar janë theksuar dukshëm. Nëse përdoruesi zgjedh një numër më të madh se 6, ai njoftohet për zgjedhjen që duhet të bëjë dhe pyetet sërish nga programi.

Një tjetër ndryshim është që përdoruesit mos t'i mbyllet programi pasi merr një pergjigje nga programi por të ketë mundësi të vazhdojë kërkimet. Na duhet të pyesim përdoruesin nëse do të vazhdojë apo të mbyllë programin. Për sa kohë që përdoruesi na jep si input fjalën po, pra deshiron të vazhdojë ne e kthejmë rrjedhën e programit në fillim.

vazhdo = 'po'
while vazhdo == 'po':
    kerkimi = ''
    while kerkimi == '':
        try:
            kerkimi = int(raw_input('Do te kerkoni sipas emrit(0), mbiemrit(1), atesise(2), ditelindjes(3), kodit zip(4), shtetit(5) apo kombit(6)? '))
        except ValueError:
            print "Zgjidh nje numer"
        if kerkimi != '' and ( kerkimi < 0 or kerkimi > 6 ):
            kerkimi = ''
            print "zgjidh nje numer midis 0 dhe 6"
    kriteri = kriteret[kerkimi]
    termi = raw_input('Shkruaj ' + kriteri + ': ')
    rekordet = kerko_sipas(kriteri, termi, njerezit)
    if rekordet:
        for rekordi in rekordet:
            print rekordi, "\n"
    else:
        print kriteri, 'nuk u gjet'
    vazhdo = raw_input('Deshiron te kerkosh serish? (po vazhdon / cdo buton tjeter per te ndaluar) :')

Programi i plotë me të gjitha ndryshimet është ky:

# nje n-she me fjalore eshte struktura me praktike per te ruajtur te dhenat
njerezit = (
{'emri': 'altin', 'mbiemri': 'prifti', 'atesia': 'genti', 'ditelindja': '29 05 1993', 'kodizip': '3003', 'shtetesia': 'shqiperi', 'kombesia': 'shqiperi'},
{'emri': 'altin', 'mbiemri': 'hoxha', 'atesia': 'astrit', 'ditelindja': '08 03 1990', 'kodizip': '1000', 'shtetesia': 'austri', 'kombesia': 'shqiperi'},
{'emri': 'klodi', 'mbiemri': 'hoxha', 'atesia': 'ismail', 'ditelindja': '17 11 1978', 'kodizip': '9400', 'shtetesia': 'itali', 'kombesia': 'shqiperi'},
{'emri': 'robert', 'mbiemri': 'krasniqi', 'atesia': 'bujar', 'ditelindja': '02 12 1981', 'kodizip': '2000', 'shtetesia': 'shqiperi', 'kombesia': 'shqiperi'},
)

# kjo ndryshore na lehteson perzgjedhjen e kategorise permes nje numri
kriteret = ('emri', 'mbiemri', 'atesia', 'ditelindja', 'kodizip', 'shtetesia', 'kombesia')

# funksioni qe ben krahasimin e vleres se kerkuar tek struktura jone
def kerko_sipas(kriteri, kerkimi, db):
    rezultatet = []
    for rekord in db:
        if rekord[kriteri] == kerkimi:
            rezultatet.append(rekord)
    return rezultatet

# ketu fillon ekzekutimi i programit
vazhdo = 'po'
while vazhdo == 'po':
    kerkimi = ''
    while kerkimi == '':
        try:
            kerkimi = int(raw_input('Do te kerkoni sipas emrit(0), mbiemrit(1), atesise(2), ditelindjes(3), kodit zip(4), shtetit(5) apo kombit(6)? '))
        except ValueError:
            print "Zgjidh nje numer"
        if kerkimi != '' and ( kerkimi < 0 or kerkimi > 6 ):
            kerkimi = ''
            print "zgjidh nje numer midis 0 dhe 6"
    kriteri = kriteret[kerkimi]
    termi = raw_input('Shkruaj ' + kriteri + ': ')
    rekordet = kerko_sipas(kriteri, termi, njerezit)
    if rekordet:
        for rekordi in rekordet:
            print rekordi, "\n"
    else:
        print kriteri, 'nuk u gjet'
    vazhdo = raw_input('Deshiron te kerkosh serish? (po vazhdon / cdo buton tjeter per te ndaluar) :')

Metodat e gatshme të pythonit për fjalorët

Metoda Shpjegimi
clear() Fshin elementet e një fjalori
copy() Jep një fjalor të ri me të njëjtat çifte çelësa-vlera, si tek fjalori origjinal
has_key(celes) Kërkon për ekzistencen e një çelësi
get(celes) Kthen vlerën e çelësit nëse ekziston
keys() Shfaq një listë me çelësat e fjalorit
values() Shfaq një listë me vlerat e fjalorit
items() Shfaq një listë me tufa të fjalorit duke paraqitur elementet në formën: çelës-vlerë.
update(fjalor tjeter) Shton elementet e një fjalori nga një fjalor tjetër.

Shembuj ilustrues për metodat e fjalorëve:

Metoda clear është ilustruar më sipër kur kemi shpjeguar mënyrat për fshirjen e elementeve të fjalorit.

Metoda copy ashtu siç është shpjeguar tek tabela bën një kopje të fjalorit origjinal me të gjithë çiftet çelës-vlerë.

>>> f1 = {'stine': 'dimer', 'muaji': 'shkurt'}
>>> f2 = f1.copy()
>>> f2
{'muaji': 'shkurt', 'stine': 'dimer'}

Metoda has_key kërkon për një çelës në fjalor. Përgjigja që ne marrim është e vërtetë nëse çelësi ekziston dhe e gabuar në të kundërt.

>>> f = {'muzike': 'pop'}
>>> f.has_key('html')
False
>>> f.has_key('muzike')
True

Metoda get kthen vlerën sipas çelësit që ne i japim. Nëse ai nuk ekziston kthehet None ( angl. asnjë).

>>> f = {'muzike': 'pop', 'libra': 'publicistike'}
>>> f.get('muzike')
'pop'
>>> f.get('pop')
>>> print f.get('pop')
None

Metoda keys jep një listë me çelësat e fjalorit.

>>> f = {'stine': 'vjeshte', 'muaj': 'nentor', 'viti': '2011'}
>>> f.keys()
['viti', 'muaj', 'stine']

Metoda values jep një listë me vlerat e fjalorit.

>>> f = {'stine': 'vjeshte', 'muaj': 'nentor', 'viti': '2011'}
>>> f.values()
['2011', 'nentor', 'vjeshte']

Metoda items() jep një listë me n-she të çifteve çelës-vlerë të fjalorit.

>>> f1 = {'viti': '2011', 'stine': 'dimer', 'muaj': 'nentor', 'data': '24'}
>>> f1.items()
[('viti', '2011'), ('stine', 'dimer'), ('muaj', 'nentor'), ('data', '24')]

Metoda update shton elementet e një fjalori tjetër tek një fjalor ekzistues. Nëse nuk ekzistojnë ato shtohen, ekzistojnë ndryshohen vlerat.

>>> f1 = {'stine': 'vjeshte', 'muaj': 'nentor', 'viti': '2011'}
>>> f2 = {'stine': 'dimer', 'data':'24'}
>>> f1.update(f2)
>>> f1
{'data': '24', 'viti': '2011', 'muaj': 'nentor', 'stine': 'dimer'}