Preskoči na glavno vsebino
Učilnica FRI 24/25
  • Domov
  • Več
Zapri
Preklopi iskalni vnos
Slovenščina ‎(sl)‎
English ‎(en)‎ Slovenščina ‎(sl)‎ Македонски ‎(mk)‎ Русский ‎(ru)‎ 한국어 ‎(ko)‎
Trenutno uporabljate gostujoči dostop
Prijavite se
Učilnica FRI 24/25
Domov
Razširi vse Skrči vse
  1. pn
  2. Branje (in pisanje) datotek v formatih json, xml, pickle
  3. Albus Percival Wulfric Brian Dumbledore

Albus Percival Wulfric Brian Dumbledore

Zahteve zaključka
Rok za oddajo: sreda, 22. januar 2025, 20.00

Ocena 6

Za oceno 6 bo potrebno pokazati, da znamo brati datoteke csv ter delati z nizi in slovarji.


  • V datoteki osebe.csv se nahajajo polna imena vseh oseb iz Harryja Potterja (žal tudi iz kasnejših "dodatkov") in povezave na strani s podatki o njih na Wikidata. Preberite podatke iz datoteke in jih shranite v slovar z imenom osebe: ključi naj bodo polna imena oseb, pripadajoče vrednosti pa povezave. (Torej: drugi stolpec so ključi, prvi stolpec so vrednosti.)

    Program naj ne bo napisan za to specifično vsebino datoteke! Če spremenimo vsebino datoteke, tako da vsebuje osebe iz romana Vojna in mir, mora pač sestaviti slovar teh oseb. Računajte pa, da bo datoteki vedno ime osebe.csv.

    Pomembno: datoteka je v istem direktoriju kot programi in program naj datoteko odpre z open("osebe.csv"), brez imen direktorijev! Nobenih open("c:\Users\janez\programiranje\naloga11\oseba.csv")!

  • Napišite funkcijo brez_dodatkov(ime), ki prejme polno ime osebe in vrne ime te osebe brez "dodatkov". Klic brez_dodatkov("Mrs. Molly Weasley") vrne "Molly Weasley", klic brez_dodatkov("Cygnus Black III") vrne "Cygnus Blake" in klic brez_dodatkov("Madame Rolanda Hooch") vrne "Rolanda Hooch". Dodatki, ki jih morate odstraniti, so 'Mr. ', 'Mrs. ', ' III', ' II', ' I', 'the ', 'The ', ' Jr.', 'Sir ', 'Madam ', 'Madame '. (V seznamu sem prijazno dodal presledke pred ali za "dodatek"; to bi vam lahko pomagalo, če vam ne, pa jih pobrišite.)

    Pazi: "Sirius Black III" mora postati "Sirius Black", ne "ius Black"!

  • Napišite funkcijo po_priimkih(), ki vrne slovar, katerega ključi so priimki oseb, vrednosti pa množice (prvih) imen oseb s takšnim priimkom. Pri tem moraš iz imena pobrisati "dodatke" - kot je opisano zgoraj.

    • Če je za osebo znano le eno ime (Kreacher, Nagini), brez priimka, naj se ne pojavi v slovarju.
    • Če ima oseba več imen, je priimek zadnji, ime pa je prvo. V "Albus Percival Wulfric Brian Dumbledore" je priimek Dumbledore, ime pa Albus.

    V slovarju, ki ga vrne po_priimkih, je pri ključu "Dumbledore" vrednost {'Albus', 'Ariana', 'Percival', 'Kendra', 'Aberforth'}.

V datoteki potter6.txt je besedilo šestega dela knjige Harry Potter. (V izobraževalne namene in v ne preveč lepo berljivi obliki).

  • Napišite funkcijo je_stevilka_poglavja(vrstica), ki prejme vrstico iz datoteke in vrne True, če gre za vrstico s številko poglavja. Le-te so videti tako: — CHAPTER TWENTY-ONE —, le številka je vsakič druga.

    Pazi: — ni običajen minus. Skopiraj znak iz datoteke.

  • Vrstici s številko poglavja vedno sledi vrstica, ki vsebujejo ime poglavja. Napiši funkcijo imena_poglavij(ime_datoteke), ki prejme ime datoteke z besedilo (tako, da je reč uporabna tudi za druge knjige Harryja Potterja...) in vrne seznam imen poglavij. Seznam se začne z ['The Other Minister', 'Spinner’s End', 'Will and Won’t', 'Horace Slughorn',...

Ocena 7

Za oceno 7 se ne bo potrebno pretegniti: samo še malo bomo delali z nizi.


V besedilu se nahajajo

  • številke poglavij: zazna jih funkcija je_stevilka_poglavja, ki jo že imamo
  • naslovi poglavij: to so vrstice takoj za vrstico s številko poglavja
  • številke strani: te se začnejo ali končajo s številko, in vse besedilo je napisano s SAMIMI VELIKIMI ČRKAMI.

    Primera vrstice s številko strani sta " WILL AND WON'T 11 in "44 HARRY POTTER".

    Vrstici SCRIMGEOUR SUCCEEDS FUDGE in "5 miles’. The " nista vrstici s številko. Prva nima številke, druga ni zapisana s samimi veliki črkami.

Napiši funkcijo besedilo(ime_datoteke), ki prebere besedilo iz datoteke in ga vrne kot niz, ki vsebuje samo besedilo, brez številk in naslovov poglavij ter številk strani.

Za lažje testiranje bodo testi uporabljali izvleček besedila, potter6-zacetek.txt.

Ocena 8

Za oceno 8 bo potrebno brati json s spleta in ga razvozlati. Programiranja ne bo veliko, poudarek bo na tem, da znamo razumeti podatke, ki jih dobimo.


Podatke o osebah sem pridobil s fantastičnega vira, ki ima podatke o vsem na svetu - s Wikidata, ki je, v bistvu, Wikipedia v strojno berljivi obliki. Z njim je žal nekoliko nerodno delati. V domači nalogi boste okusili nekoliko tega. (Tema domače naloge so sicer osebe iz otroške literature; podobne reči bi lahko delali tudi z resnimi podatki!)

V brskalnik vnesite kakega izmed URL-jev v datoteki osebe.csv (lahko recimo, kliknete na tole: http://www.wikidata.org/entity/Q712548). Dobili boste stran iz podatkovne baze, ki vsebuje podatke o imenu te osebe v različnih jezikih, njegovih sorodnikih, spolu, datumu in kraju smrti... V nalogi za oceno 8 boste brali te podatke.

Opazite lahko, da vas je brskalnik preusmeril s strani, ki ste jo vpisali, npr. http://www.wikidata.org/entity/Q712548 na stran, ki pokaže podatke v človeku berljivi obliki https://www.wikidata.org/wiki/Q712548. Za začetek poberite vsebino strani http://www.wikidata.org/entity/Q712548 v Pythonu, tako kot smo se učili na predavanju. Ker gre za json, ga ustrezno dekodirajte, kot smo se tudi učili. (Pazi: program mora uporabiti URL, ki vsebuje entity in ne wiki.)

Videli boste, da ste dobili nek grozljiv slovar. Recimo, da ga shranite v spremenljivko z imenom podatki. Da ga lahko preberete, poskusite tole:

import pprint
pprint.pp(podatki)

Najprej nekaj o Wikidata. Vsaka stvar ("entiteta") ima "identifier". Q712548 je identifier Albusa Dumbledora, Q437 je mesto Ljubljana, Q34660 je J. K. Rowling, Q11518 je Pitagorov izrek. Kdo ali kaj je Q42, uganite.

Vsaka entiteta je opisana z lastnostmi (property). P1559 je full name -- pač za stvari, ki imajo full name; osebe ga imajo, Pitagorov izrek pač ne. P569 je dan rojstva, P21 je spol, P37 je uradni jezik, P625 so zemljepisne koordinate (Ljubljane, ne Pitagorovega izreka ali Albusa Dumbledora).

Pridobljeni slovar bo imel vedno en sem ključ entities; pripadajoča vrednost bo imela en sam ključ, namreč oznako entitete (na primer Q712548). Podatki so znotraj tega. Preglejte in se znajdite.

Najbolj zanimive stvari so znotraj claims. Ključi so lastnosti, vrednosti pa so ... te lastnosti zapisani v obliki, ki jo boste videli iz pprint-a.

  • Napiši funkcijo datum_rojstva_q(identifier), ki prejme oznako osebe in vrne terko z letom, mesecem in dnevom, na katerega je bila rojena ta oseba.

    Klic datum_rojstva_q("Q34660") vrne (1965, 7, 31), ker je bila J. K. Rowling rojena 31. julija 1965.

    Klic datum_rojstva_q("Q1031") vrne (1800, 12, 3), ko je bil rojen pesnik.

    Pomoč: poišči funkcijo strptime in poglej dokumentacijo. Datum na Wikidata je v obliki "+%Y-%m-%dT%H:%M:%SZ".

  • Napiši funkcijo datum_rojstva(ime), ki prejme ime osebe iz Harryja Potterja in vrne datum rojstva te fiktivne osebe.

    Klic datum_rojstva("Harry Potter") vrne (1980, 7, 31), ker je bil Harry Potter rojen 31. julija 1980.

  • Napiši funkcijo prevod_imena(ime), ki bo za podano ime povedal, kaj je iz tega imena naredil slovenski prevajalec. Klic prevod_imena("Severus Snape") vrne "Robaus Raws".

    (Rant: slovenskega prevoda nisem bral. Pogled na Wikipedijo pa pokaže, da se je izgleda samo slovenskemu in madžarskem prevajalcu zdelo potrebno zamenjati originalna imena z nekimi svojimi slaboumotvori.)

Da bo vaš program tekel hitreje, je testom priložena moja funkcija urlopen. Namesto da bi uvažali urlopen iz urllib.request, temveč kličite to, mojo funkcijo. Ta bo brala vnaprej pobrane podatke iz priložene datoteke osebe.json, pravo funkcijo urlopen pa poklicala le za podatke, ki jih ni v datoteki.

Ocena 9

Naloga za oceno 9 nas bo še malo vadila v igranju s slovarji, množicami in nizi. Predvsem bo treba razmisliti, kako se lotiti dela, da stvari ne bodo prepočasne.


Najprej bomo zamenjali imena in priimke vseh oseb z njihovimi imeni. V knjigi ima namreč veliko oseb lahko isti priimek, imena pa so (skoraj) unikatna. Napisati bo potrebno funkcijo, ki takole spreminja besedila.

  • po_imenih("Harry, Ron and Ginny Weasley, and also Dursley, Ollivander and Rosmerta walk'd down the corridor.") vrne "Harry Ron and Ginny and also Vernon Garrick and Rosmerta walk'd down the corridor" ,
  • po_imenih("Whether you call him Albus Dumbledore, or Albus Percival Wulfric Brian Dumbledore, or just Dumbledore, he was a great wizard.") vrne "Whether you call him Albus or Albus or just Albus he was a great wizard"

  • po_imenih("Dumbledore was a brother of Aberforth Dumbledore and Ariana.") vrne "Albus was a brother of Aberforth and Ariana"

  • po_imenih("The Potters and the Dursleys were neighbours.") vrne isto besedilo, le brez pike na koncu.

  • po_imenih("Justin Finch-Fletchley said: 'Don't talk to me like this - Potter!'") vrne "Justin said Don't talk to me like this Harry"

    Tudi rezultat klica z "Finch-Fletchley said: 'Don't talk to me like this - Potter!'" in "Finch-Fletchley said: 'Don't talk to me like this - Potter!'"

Funkcija mora izvesti naslednje operacije:

  • V besedilu mora ohraniti le besede. Besede so zaporedja, ki vsebujejo vsaj eno črko, poleg tega pa lahko vsebujejo znaka - in ', ki pa se morata pojaviti znotraj besede. S tem se ne zafrkavaj sam(a): testom je priložena funkcija samo_besede(s), ki prejme besedilo in vrne niz, ki vsebuje le besede. Samo pokliči jo.
  • V besedilu zamenja vse pojavitve imena in priimka z imenom. "Harry Potter" zamenja s "Harry", "Ginny Weasley" z "Ginny". Če ima oseba več imen, zamenja popolno različico in različico z enim samim imenom: "Albus Dumbledore" zamenja z "Albus", pa tudi "Albus Percival Wulfric Brian Dumbledore" zamenja z "Albus".
  • Nato (in šele nato!) zamenja vse priimke z imeni. "Potter" zamenja s "Harry", "Weasley" zamenja z "Ron", "Dumbledore" zamenja z "Albus". Kadar je priimek unikaten, je stvar jasna: "Granger" je lahko samo "Hermione". Kadar ima isti priimek več oseb, pa slovar primarna, ki je priložen testom, pove, katero ime je potrebno uporabiti: ključi slovarja so priimki, vrednosti pa "privzeto ime" za ta priimek. (Izbira je seveda moja, po občutku; Dursley je ponavadi Vernon in ne Dudley, recimo.)

Pomemben namig: Uporabljaj replace! Če boš delal zanko čez besede, bo funkcija veliko prepočasna, saj je besed 932130.

Malo zavozlan namig: tako besedilu kot temu, kar zamenjuješ kot temu, s čimer zamenjuješ, na začetek in konec prištej presledek. Tako se izogneš nevarnosti, da zamenjaš del besede.

  • Poleg tega napiši še funkcijo omembe(ime, besedilo) vrne indekse mest, na katerih se pojavi podano ime v besedilu, kakršnega vrne funkcija po_imenih.

    Vzemimo niz s = "Albus Dumbledore saw how Potter walked away with Ron Weasley, and Harry was saying something"). Funkcija po_imenih(s) bi zanj vrnila "Albus saw how Harry walked away with Ron and Harry was saying something". Zato klic omembe("Albus", s) vrne [0], klic omembe("Harry", s) vrne [6, 12], klic omembe("Ron", s) vrne [10].

    Očitno bo tvoja funkcija najprej poklicala funkcijo po_imenih...

Ocena 10

Za oceno 10 pa še malo numpyja.


  • Napiši funkcijo po_blokih(imena, besedilo, velikost_bloka), ki prejme seznam imen, besedilo knjige (npr. celotno vsebino datoteke potter6) in velikost bloka.

Besedilo obravnavamo v obliki, v kakršnega ga spremeni funkcija po_imenih (vsebuje samo osebe, vse osebe so predstavljene samo z imeni). Besedilo gledamo v blokih, ki vsebujejo toliko besed, kot določa velikost_bloka. Če je velikost_bloka enaka 10000, gledamo po 10000 besed skupaj. Če zadnji blok ni poln (in najbrž ni), ga ignoriramo.

Funkcija vrne numpy-jevo tabelo, ki ima toliko vrstic, kolikor je blokov in toliko stolpcev, kolikor je imen. Element na mestu [i, j] pove, kolikokrat se j-to ime pojavi v i-tem bloku.

V teste je dodana koda, ki bo, če imaš matplotlib in vse drugo, kar je treba, izrisala toplotni zemljevid pojavitev.

Bralci naj se spomnijo poteka zgodbe...

  • Za konec napiši še funkcijo sovpadanje(besedilo, ime1, ime2, sirina). Tudi ta prejme besedilo knjige in ga spusti čez funkcijo po_imenih. Nato izračuna "prekrivanje" med osebama po naslednjem postopku. Recimo, da pokličemo sovpadanje(besedilo, "Ginny", "Romilda", 20).

    • Recimo, da se "Ginny" pojavi na indeksih 100, 110, 180, in 250. Tedaj bomo rekli, da Ginny, "pokriva" mesta od 80 do 120 (vključno!), od 90 do 130, od 160 do 200 in od 230 do 270 -- torej besedo, na kateri se pojavi in še 20 besed levo in desno, ker smo 20 podali kot argument sirina. Ker istega mesta ne pokriva dvakrat, bi bilo prav reči, da pokriva 80 do 130, 160 do 200 in 230 do 270.
    • Recimo, da se "Romilda" pojave na indeksih 5, 70 in 255. Potem pokriva -15 do 25, 50 do 90 in 235 do 275.

    Prekrivanje med njima je potem od 80 do 90 in od 235 do 270. Velikost prekrivanje je 11 + 36 = 47. To je rezultat, ki ga mora vrniti funkcija.

    Za preprostejši primer vzemimo klic

    sovpadanje("Harry and Ron met Romilda and Romilda asked Harry about Ron", ime1, ime2, 2)
    

Spodnja slika kaže, katera mesta pokriva katera beseda (mesta so lahko tudi po koncu besedila ali pred začetkom!).


                   Harry and Ron met Romilda and Romilda asked Harry about Ron
Harry:    X    X     X    X   X                     X       X     X     X   X
Ron:                 X    X   X   X     X                         X     X   X     X     X
Romilda:                      X   X     X     X     X       X     X

Prekrivanje med Harry in Ron je 6 (kolikor je istoležnih indeksov v prvi in drugi vrstici), prekrivanje med Harry in Romilda (prva in zadnja vrstica) je 4, prekrivanje med Ron in Romilda pa prav tako 4.

Če zmanjšamo širino na 1,


               Harry and Ron met Romilda and Romilda asked Harry about Ron
Harry:     X     X    X                                 X     X     X   
Ron:                  X   X   X                                     X   X     X
Romilda:                      X     X     X     X       X    

je prekrivanje med Harry in Ron je 2, med ostalima paroma pa 1.

Testi

  • testi.zip testi.zip
    12. januar 2025, 17:50
Trenutno uporabljate gostujoči dostop (Prijavite se)
Pridobi mobilno aplikacijo
Stran poganja Moodle
Obvestilo o avtorskih pravicah