Preskoči na glavno vsebino
Učilnica FRI 23/24
  • Domov
  • Več
Zapri
Preklopi iskalni vnos
Slovenščina ‎(sl)‎
English ‎(en)‎ Slovenščina ‎(sl)‎ Македонски ‎(mk)‎ Русский ‎(ru)‎ 한국어 ‎(ko)‎
Trenutno uporabljate gostujoči dostop
Prijavite se
Domov
Course Activities
Forumi Naloge Viri
Nedavno dostopani predmeti
You are not enrolled in any courses
  1. pn
  2. Gutenberg

Gutenberg

Zahteve zaključka
Rok za oddajo: petek, 19. januar 2024, 23.59

V domači nalogi delamo z enakimi podatki kot na predavanju in vajah, vendar je projekt Guttenberg na dan ali dva po predavanjih spremenil obliko svojih strani. To je odlično, saj boste morali svoje znanje pokazati na podobni, vendar malenkost drugačni nalogi.

Podatki projekta Gutenberg so dostopni tudi v lažje berljivi obliki. Tole delamo za vajo.

Ocena 6

Za oceno 6 bo potrebno napisati le dve funkciji, ki ne bi smeli imeti več kot 10 vrstic.

  • Funkcija prenesi_podatke() naj stori naslednje.

    • Če v trenutnem direktoriju (v katerem teče program) ni poddirektorija authors, ga naredi (glej koristne funkcije, spodaj).
    • Vanj direktorij authors shrani datoteke s strani https://ucilnica.fri.uni-lj.si/mod/folder/view.php?id=54634. Rezultat prenašanja morajo torej biti datoteke authors/a.html, authors/b.html, authors/c.html ... Datotek, ki že obstajajo, ne prenašaj ponovno.

    Predpostaviti smeš, da se datoteke nahajajo na naslovih https://ucilnica.fri.uni-lj.si/pluginfile.php/217381/mod_folder/content/0/{crka}.html, pri čemer so crka male črke angleške abecede.

    Koristne funkcije:

    • os.path.exists
    • os.mkdir ali os.mkdirs
    • `string.ascii_lowercase``
    • urllib.request.urlopen, ki, pazi, ne vrne niza temveč bajte. Kdor je pozabil, kako to spremeniti v niz, naj bere zapiske, saj smo morali to narediti tudi na predavanju.

    V vsem ostanku naloge uporabljaj te datoteke, da ne nadleguješ Učilnice brez potrebe.

  • Funkcija avtorji(priimek) vrne seznam vseh avtorjev s podanim priimkom.

    • Kaj so "avtorji", je očitno s spletne strani: poglej strukturo strani, da uvidiš, za kateri element gre.
    • Priimek je vse, kar se nahaja pred prvo vejico v vrstici z imenom avtorja.
    • V seznamu naj bodo celotne vrstice.

    Klic avtorji("Fairfax") vrne seznam ['Fairfax, Cecil', 'Fairfax, Edward, -1635']. Seznam ne vsebuje "Fairfax Muckley, A. (Angelo)", saj je priimek tega avtorja Fairfax Muckley in ne samo Fairfax.

    Koristne funkcije:

    • Elementi, ki jih vrača BeautifulSoup imajo atribut strings z vsemi nizi znotraj elementa. Če imamo element el, ki vsebuje
    <div><a href="peter.html">Peter</<a> je pojedel veliko <img src="melona.png"> in šel v <img src="melona.png">.</div>
    

    bo el.strings vseboval "Peter", " je pojedel veliko ", " in šel v ", in ".". strings ni seznam, temveč generator. Če želimo seznam, pokličemo list(el.strings), lahko pa ga podamo tudi kaki drugi funkciji ali metodi, na primer (namig!) metodi join, ki jo imajo nizi. (Nasvet: ko združuješ, ne vrivaj presledkov, razen v nalogi za oceno 10.)

Ocena 7

  • Funkcija razberi_avtorja(s), prejme vrstico z imenom avtorja ter letnicami rojstva in smrti.

    Če vrstica ne vsebuje ne letnice rojstva ne letnice smrti, funkcija vrne None.

    Sicer pa vrne četverko z naslednjimi elementi:

    • niz s priimkom avtorja (vse, kar je pred prvo vejico)
    • seznam z ostalimi elementi imena; dobimo ga tako, da vse, kar ni priimek ali letnice, razdelimo po vejicah
    • številka z letnico rojstva, če je podana; če ni naj bo ta element enak None.
    • številka z letnico smrti, če je podana; če ni naj bo ta element enak None.

    Letnici rojstva in smrti sta tisto, kar sledi zadnji vejici, pod pogojem, da imata primerno obliko in sta ločeni z - (brez presledkov).

    Letnica ima primerno obliko, če je

    • sestavljena iz števk,
    • ki jim morda sledi vprašaj (ki ga ignoriraj) ter,
    • morda, presledek, ki mu sledi BC.

    Dodatnih presledkov ali drugih znakov ni. Če se v datotekah pojavi kaj, kar je podobno letnici, vendar ne ustreza temu opisu, potem predpostavimo, da to ni letnica in jo ignoriramo. (Pazi: zadnji vejici mora slediti presledek in tako nato letnici. Če je vmes še kaj, na primer "active", potem tega avtorja ignoriraj.)

    Letnico pretvori v številko; če ji sledi BC, mora biti negativna.

    Če vrstica vsebuje ime brez vejic in nato letnico (na primer Guérin de Bouscal, 1613?-1657), se vedemo, kot da je celotno ime avtorja priimek, imena pa nima.

    • Klic razberi_avtorja('Macaulay, James, Peter, Joe-Ann, 1817?-1902') vrne ("Macaulay", ["James", "Peter", "Joe-Ann"], 1817, 1902).
    • Klic razberi_avtorja("Cicero, Marcus Tullius, 106 BC-43 BC") vrne ("Cicero", ["Marcus Tullius"], -106, -43)
    • Klic razberi_avtorja("Bach, P. D. Q., 33-12? BC") vrne ("Bach", ["P. D. Q."], 33, -12). 33 nima BC, torej je pozitivna, 12 pa, torej je negativna. Ker P. D. Q. Bach.
    • Klic razberi_avtorja("Štefan, Jožef") vrne None, ker manjkata letnici.
    • Klic razberi_avtorja("Kralj, Ludvik, 1914") vrne None, ker manjkata letnici (1914 je videti kot leto, vendar ni znaka -)
    • Klic razberi_avtorja("Kralj, Ludvik, 1914-ič") vrne None, ker manjkata letnici (ič niso števke)

    Koristne funkcije:

    • re.match; glej zapiske predavanja o regularnih izrazih. Tam je skoraj vse, kar potrebujemo, le za BC bo potrebno poskrbeti. Brez tega bo najbrž malo naporneje. Učenje regularnih izrazov je koristna naložba.
  • Funkcija zberi_podatke(crke) prejme niz črk in vrne slovar, katerega ključi so priimki avtorjev, pripadajoče vrednosti pa seznam podatkov za vse avtorje s tem priimkom, pri čemer so "podatki" natančno četverke, ki jih vrača gornja funkcija. Avtorji so urejeni po vrstnem redu njihovega pojavljanja na strani.

    Funkcija uvrsti v slovar le tiste avtorje, katerih priimek se začne z eno od črk v podanem nizu crke. Če je ta niz prazen, pa prebere vse avtorje. Tako zberi_podatke("mte") sestavi slovar le za avtorje, katerih priimki se začnejo z m, t, ali e; klic zberi_podatke("m") zbere le podatke z avtorji s priimki na črko m; klic zberi_podatke("") zbere podatke za vse avtorje.

    Slovar, ki ga vrne zberi_podatke("g") se začne tako:

    {'Gaal': [('Gaal', ['György'], 1783, 1855),
              ('Gaal', ['József'], 1811, 1866),
              ('Gaal', ['Mózes'], 1863, 1936)],
     'Gabel': [('Gabel', ['Norman E.'], 1906, 1961)],
     'Gaboriau': [('Gaboriau', ['Emile'], 1832, 1873)],
     'Gabrielean': [('Gabrielean', ['M. Smbat'], 1856, 1919)],
     'Gabriel': [('Gabriel', ['Gilbert W. (Gilbert Wolf)'], 1890, 1952)],
     'Gabrielian': [('Gabrielian', ['Mugurdich Chojhauji'], 1857, None)],
     'Gade': [('Gade', ['John A. (John Allyne)'], 1875, 1955)],
     'Gadow': [('Gadow', ['Hans'], 1855, 1928)],
     'Gaebelein': [('Gaebelein', ['Arno Clemens'], 1861, 1945)],
     'Gaffarel': [('Gaffarel', ['Paul'], 1843, 1920)],
     'Gage': [('Gage', ['George W.'], 1887, 1957),
              ('Gage', ['Harry Lawrence'], 1887, 1982),
              ('Gage', ['Matilda Joslyn'], 1826, 1898),
              ('Gage', ['Thomas'], 1603, 1656),
              ('Gage', ['Thomas'], 1721, 1787)],
     'Gagneur': [('Gagneur', ['M.-L. (Marie-Louise)'], 1832, 1902)],
    
     ...
    

    Če so poleg "g" še druge črke, vsebuje še priimke, ki se začnejo s temi črkami; če ga pokličemo s praznim nizem, pa vsebuje vse avtorje.

  • V program dodaj (izven funkcije!) par vrstic, ki naredijo tole: če trenutni direktorij ne vsebuje datoteke "authors.json", pokliče funkcijo zberi_podatke("") in slovar, ki ga funkcija vrne kot rezultat, shrani v datoteko authors.json. Kot je očitno iz končnice, mora biti datoteka zapisana v obliki json.

    Testi ne bodo preverjali, da ne pišeš datoteke, če že obstaja. Tvoj problem, če bo program brez potrebe počasen.

    Vse naslednje funkcije. ki potrebujejo podatke o avtorjih, naj nalagajo to datoteko, namesto da brskajo po HTML-jih. Na ta način se bodo izvajale precej hitreje.

    Koristne funkcije:

    • modul json; glej zapiske.

Ocena 8

Pazi: Ta in nadaljnje funkcije predpostavljajo, da bereš podatke iz jsona. Pri tem se terke spremenijo v sezname, zato bodo testi pričakovali, četverko s podatki o avtorjih kot sezname in ne terke. Pretvarjanje bi bilo možno, vendar nima smisla, da si zapletamo življenje.

  • Funkcija v_obdobju(rojen, umrl, zacetek, konec) vrne True, če je oseba, ki je živela med leti rojen in umrl, vsaj del življenja živela znotraj obdobja med zacetek in konec.

    Pesnik, rojen v 1800 in umrl v 1848, je živel, na primer v obdobjih 1800-1900, 1750-1810, 1848-1552, ne pa v obdobju 1850-1900 ali 1750-1799.

    Ena izmed letnic, rojen ali umrl, je lahko tudi None. V tem primeru preveri le, ali se letnica, ki je znana, nahaja znotraj odbobja. (Tudi za osebo, ki je umrla 1551, ne bomo trdili, da je živela v 1500-1550, čeprav najbrž je, sicer je ne bi bilo na seznamu.)

    Predpostaviti smeš, da ne gre za P. D. Q. Bacha in je letnica rojstva manjša ali enaka letnici smrti. Letnica začetka obdobja je manjša ali enaka letnici konca.

    Da te odvrnemo od zank in drugih nepotrebnih komplikacij, na primer range, pa so letnice lahko tudi izjemno velike, na primer 10^22 in niso nujno cela števila.

    Koristne funkcije

    • Operator <= (pa še kakšen is, not, and in or) bo pametnemu povsem zadoščal. :)
  • Funkcija avtorji_v_obdobju(zacetek, konec) vrne seznam vseh avtorjev, ki so živeli v podanem obdobju. Vsak avtor je opisan s četverko, kot so shranjene v authors.json. Za avtorja se šteje, da je živel v podanem obdobju, če tako pravi prejšnja funkcija.

    Seznam naj bo urejen po priimkih, med tistimi z enakim priimkom pa po ostalih elementih imena.

    Klic avtorji_v_obdobju(1310, 1311) vrne

    [['Amir Khusraw Dihlavi', [], 1253, 1325],
     ['Bury', ['Richard de'], 1287, 1345],
     ['Dante Alighieri', [], 1265, 1321],
     ['Gao', ['Ming'], 1306, 1359],
     ['Joinville', ['Jean', 'sire de'], 1224, 1317],
     ['Juan Manuel', ['Infante of Castile'], 1282, 1347],
     ['Liu', ['Ji'], 1311, 1375],
     ['Llull', ['Ramon'], 1232, 1316],
     ['Ma', ['Zhiyuan'], 1250, 1324],
     ['Petrarca', ['Francesco'], 1304, 1374],
     ['Polo', ['Marco'], 1254, 1324],
     ['Rolle', ['Richard', 'of Hampole'], 1290, 1349],
     ['Ruiz', ['Juan'], 1283, 1350],
     ['Ruusbroec', ['Jan van'], 1293, 1381],
     ['Shi', ["Nai'an"], 1290, 1365],
     ['Wang', ['Mian'], 1287, 1359],
     ['Wang', ['Shifu'], 1260, 1316],
     ['Zhu', ['Mingshi'], 1260, 1340]]
    

    Koristne funkcije:

    • Za urejenja bo dovolj poklicati sorted na končnem seznamu, brez posebnih ceremonij. Ta bo urejal po prvem elementu in potem po ostalih.
  • Funkcija razpon() vrne par števil z najzgodnejšo letnico rojstva in najkasnejšo letnico smrti v podatkih.

    Funkcija mora vrniti (-1810, 2023). Vendar ne goljufaj in to dejansko izračunaj.

    (Kateri pisatelj je bil rojen leta -1810? Le poteši si radovednost. Ni napaka. Je zanimivo.)

  • Funkcija pokritost(zacetek, konec) vrne seznam, ki vsebuje toliko števil, kolikor je let med zacetek in (vključno) konec. Element z indeksom i pove, koliko avtorjev v bazi je bilo živih v letu zacetek + i. Upoštevaj le pisatelje z znanima letnicama rojstva in smrti.

Ocena 9

V tej nalogi se bomo ukvarjali z deli avtorjev. Upoštevajte le pisne knjige, ne avdio zapisov - v spodnjem primeru torej le prvo delo, ne drugega.

<li class="pgdbetext"><a href="/ebooks/16527">1001 задача для умственного счета</a> (Russian) (as Author)</li>
<li class="pgdbaudio"><a href="/ebooks/19681">Детство</a> (Russian) (as Author)</li>
  • Funkcija razberi_delo(s) dobi niz, ki morda vsebuje opis dela. Če gre za opis dela, vrne njegov naslov in jezik; sicer vrne None.

    Opis dela je oblikovan tako, da

    • naslovu dela
    • sledi presledek,
    • nato je v oklepajih naveden jezik; lahko vsebuje več besed ("Old English") ali vezaje ("Napoletano-Calabrese"), (opomba: ignorirajte jezike, kateri opis vsebuje kak drug znak kot črke, presledke in vezaje; opravičujem se v času sestavljanja naloge spregledanim govorcem jezika "Gaellic, Scottish" - ta jezik ignorirajte, ker njegov opis vsebuje vejico)
    • sledi presledek,
    • nato pa v oklepajih niz as Author.

    Če ni oklepajev z jezikom in oklepajev z as Author, ne gre za opis dela.

    • razberi_delo("Lightships and Lighthouses (English) (as Author)") vrne ("Lightships and Lighthouses", "English").
    • razberi_delo("Histoire de la Litterature Anglaise (Volume 1 de 5) (French) (as Author)") vrne 'Histoire de la Litterature Anglaise (Volume 1 de 5)', 'French').
    • razberi_delo("My Reminiscences (English) (as Translator)") vrne None.

      Opisi nekaterih del obsegajo več kot eno vrstico (torej: vsebujejo znake \n ali \r). Ta dela ignoriraj. (Lepše bi bilo, če jih ne bi. Vendar bi vam bilo upoštevanje teh tako ali tako del najbrž samo otežilo nalogo, predvsem pa smo to posebnost spregledali v času pisanja testov, zato jih tudi testi ignorirajo.)

    Uporabne funkcije

    • re.match. Da bo preprosteje, izdam del izraza, ki bo ulovil jezik: \(([\w\- ]+)\):

      • \w pomeni poljubno črko ali števko.
      • [\w\- ] pomeni poljubno črko ali števko ali - ali presledek. Vzvratna poševnica pred - je potrebna, ker ima - znotraj [] sicer poseben pomen; a-f bi pomenil vse znake med a in f.
      • [\w\- ]+ pomeni zaporedje z vsaj enim takšnim znakom.
      • ([\w\- ]+): z oklepaji označimo ta del vzorca kot skupino, tako da jo bomo lahko potem izločili z groups.
      • \(([\w\- ]+)\): \( in \) pomenita oklepaj in zaklepaj; vzvratna poševnica je potrebna, ker imata ( in ) v regularnih sicer poseben pomen (glej gornjo vrstico).

    V podanem dokumentu bi lahko delo in jezik sicer dobili tudi na drugačen, nekoliko preprostejši način. Vendar povadimo regularne izraze. Kdor ima težave, naj prebere zapiske. Če ne bo dovolj, pa pošlje mail.

  • Funkcija dela() vrne seznam z vsemi deli vseh avtorjev v vseh HTML-jih, ki ste jih pripravili v nalogi za oceno 6. Delo se šteje kot delo, če ga gornja funkcija prepozna kot delo.

    Elementi seznama naj bodo šesterke z naslednjimi elementi

    • ime dela,
    • jezik,
    • priimek avtorja,
    • ostali deli imena avtorja,
    • leto rojstva,
    • leto smrti.

    Prva dva elementa sta torej takšna, kot ju vrne gornja funkcija, ostali štirje so takšni, s kakršnimi smo avtorje opisovali v prejšnjih.

    Vrstni red elementov v seznamu je poljuben.

    Ker se bo ta funkcija najbrž izvajala več kot 10 sekund, bodo testi prihranili tvoj čas tako, jo bodo nehali testirati, ko se v direktoriju pojavi datoteka works.json.

    Koristne funkcije:

    • Elementi, ki jih vrača BeautifulSoup imajo atribut parent, ki vrne očeta vozlišča.
    • Elementi imajo tudi metodo find_previous_sibling(name), ki pregleduje prejšnje brate vozlišča in vrne prvega s podanim imenom. Če je el nek element, bo el.find_previous_sibling("img") med brati elementa el našel najbližji prejšnji element img.
  • Podobno kot smo shranili avtorje, shranimo tudi dela. V program dodaj (izven funkcije!) dve, tri vrstice, ki naredijo tole: če trenutni direktorij ne vsebuje datoteke "works.json", pokliče funkcijo dela() ter seznam, ki ga funkcija vrne kot rezultat, shrani v datoteko works.json - datoteka mora biti očitno v obliki json.

  • Funkcija dela_po_jezikih() vrne slovar, katerega ključi so vsi jeziki, v katerih so napisana dela avtorjev, pripadajoče vrednosti pa število del v tem jeziku.

Ocena 10

Čestitam, prišli ste do nalog z oceno 10. Za vzpodbudo jih ni veliko in niso težke. Z malo spretnosti bo vsaka vsebovala le eno vrstico in potem (mogoče malo daljši, a ne zapleten) return.

  • Funkcijo preveri_delo definiraj s takimi argumenti: preveri_delo(delo, avtor=None, naslov=None, jezik=None, leto=None). Poklicati jo bo možno z, recimo preveri_delo(delo, jezik="English", leto=1950).

    Funkcija prejme opis posameznega dela v obliki šesterke, kakršne smo sestavljali v funkciji dela() ter ime (ali del imena) avtorja, ime (ali del imena) dela, jezik dela ali leto. Katerikoli argument (razen prvega) je lahko tudi None; če je tako, ga ne upoštevamo. Funkcija vrne True, če velja vse naslednje.

    • Ime avtorja vsebuje podani niz avtor. Ime avtorja predtem obdelamo tako, da postavimo imena na začetek in jih združimo s presledki, priimek pa damo na konec. Tako iz "Dostojevski", ["Fjodor", "Mihajlovič"] nastane "Fjodor Mihajlovič Dostojevski"; funkcija vrne True, če je avtor, na primer "Dostojevski", "Mihaj" ali tudi "ovič Dos".

    • Ime dela vsebuje podani podniz naslov. naslov "čin in kaz", se ujema z "Zločin in kazen".

    • Delo je napisano v zahtevanem jeziku.

    • Avtor je bil živ v podanem letu leto.

    Tiste dele poizvedbe, ki so None, ignoriramo. Če je, recimo, podan le avtor in jezik, funkcija preveri le, ali gre za delo podanega avtorja v podanem jeziku, naslov dela in leto pa ignorira.

    Kadar je podan argument leto, vendar za avtorja ni znano leto rojstva ali smrti, funkcija vrne False. (Da si ne zapletamo življenja, vrnemo False tudi, če je, recimo, leto rojstva neznano, leto smrti pa sicer morda ravno enako iskanemu letu.)

  • Napiši funkcijo poisci(avtor=None, naslov=None, jezik=None, leto=None), ki vrne seznam vseh del, ki ustrezajo podanim kriterijem.

    Koristne funkcije:

    • preveri_delo :)

Testi

  • testi.py testi.py
    8. januar 2024, 18:23
◄ Guttenberg: Avtorji, katerih priimki se začnejo s črko B
Strani z avtorji del, objavljenih na projektu Gutenberg ►
Trenutno uporabljate gostujoči dostop (Prijavite se)
Pridobi mobilno aplikacijo Obvestilo o avtorskih pravicah
Stran poganja Moodle