URLji

URL je sestavljen iz imena protokola, naslova strežnika in poti na strežniku. Ime protokola je beseda sestavljena iz črk in števk, ki ji sledi dvopičje (http:, https:, ftp: ali kaj podobnega). Imenu protokola sledita dve poševnici. V naslovu strežnika ni poševnic. Pot se, če ni prazna, začne s poševnico. Celoten URL je torej tak: protokol://strežnik/pot ali protokol://strežnik/ ali protokol://strežnik.

Napiši funkcijo razbijURL(u), ki prejme URL u in kot rezultat vrne ime protokola, naslov strežnika in pot.

print(razbijURL("https://ucilnica.fri.uni-lj.si/course/view.php?id=166"))
('https', 'ucilnica.fri.uni-lj.si', 'course/view.php?id=166')
Rešitev
def razbijURL(u):
    protokol, naslov = u.split("://")
    kosi = naslov.split("/")
    return protokol, kosi[0], "/".join(kosi[1:])

Zemljevid

Zemljevid je shranjen v datoteki v takšni obliki:

BF-FRI: trava, gravel, pesek
BF-FDV: pesek
BF-EF:
FRI-EF: trava

Napiši funkcijo preberi_zemljevid(ime_datoteke), ki prejme ime datoteke z zemljevidom in vrne slovar, katerega ključi so veščine, pripadajoče vrednosti pa množica povezav (povezava je podana s parom križišč), ki zahtevajo to veščino. Za primer na sliki mora vrniti {"trava": {("BF", "FRI"), ("FRI", "EF")}, "gravel": {("BF", "FRI")}, "pesek": {("BF", "FRI"), ("BF", "FDV")}.

Rešitev
def preberi_zemljevid(ime_datoteke):
    with open(ime_datoteke) as f:
        vecsine_poti = defaultdict(set)
        for line in f:
            ab, v = line.strip().split(":")
            a, b = ab.split("-")
            if v.strip():
                v = v.strip().split(", ")
                for vv in v:
                    vecsine_poti[vv].add((a, b))
    return vecsine_poti

Avtobusi

Napiši funkcijo naslednji_avtobus(prihodi), ki dobi seznam prihodov avtobusov (v številu minut od tega trenutka) in vrne "številko" (npr. "1" ali "6b") avtobusa, ki bo prišel prvi. Če je za več avtobusov napovedan isti čas do prihoda, naj vrne tistega z nižjo številko (a pazite: avtobus 2 ima nižjo številko od avtobusa 11, prav tako ima avtobus 6b nižjo številko od 11). Prihodi avtobusov so podani kot slovar, katerega ključi so "številke" avtobusov ("1", "6b"...), vrednosti pa seznami napovedanih časov do prihoda. Časi niso nujno urejeni po velikosti. Številke avtobusov so naravna števila, ki imajo lahko dodano še eno črko. Primerov, kjer vozi več avtobusov, ki se razlikujejo samo v črki, ne bo.

print(naslednji_avtobus({"1": [5, 7], "2": [11, 3, 18], "6b": [3, 7]}))
2
Rešitev
def naslednji_avtobus(prihodi):
    kdaj = 24*60
    for avtobus, minute in prihodi.items():
        stev = int(avtobus if avtobus[-1].isdigit() else avtobus[:-1])
        minute = min(minute)
        if minute < kdaj or (minute==kdaj and stev < najstev):
            kdaj, najstev, najavtobus = minute, stev, avtobus
    return najavtobus

Seštevke

S števili včasih delamo tole: seštejemo njihove števke, nato seštejemo števke vsote in tako naprej, dokler ne dobimo ene same števke. Vzemimo, recimo, 39. Seštejemo števke in dobimo 3+9=12. Tudi v dvanajst seštejemo vse (torej obe) števki in dobimo 1+2=3. Potem rečemo, da številu 39 pripada števka 3.

Napiši funkcijo sestevke(a, b), ki za vsa števila od a do vključno b izračuna pripadajoče števke ter rezultat vrne v obliki slovarja. Ključi slovarja naj bodo števke, vrednosti pa seznami števil, ki jim pripada ta števka.

print(sestevke(17, 27))
{8: [17, 26], 9: [18, 27], 1: [19], 2: [20], 3: [21], 4: [22], 5: [23], 6: [24], 7: [25]}
Rešitev
def sestevke(a, b):
    stevke = defaultdict(list)
    for i in range(a, b+1):
        v = i
        while v > 9:
            v = sum(int(c) for c in str(v))
        stevke[v].append(i)
    return stevke

Temperature

Napišite funkcijo enake_meritve(casi, temp1, temp2). Kot prvi argument casi sprejme navaden seznam časov meritev. Drugi in tretji argument pa sta numpy tabeli izmerjenih temperatur v dveh različnih krajih. Vsi argumenti so enake dolžine. Funkcija naj vrne numpy tabelo časov, ob katerih je bila izmerjena enaka temperatura v obeh krajih.

>>> casi = [9, 10, 12, 15, 16, 17, 18]
>>> kraj1 = np.array([20, 22, 23, 20, 19, 21, 25])
>>> kraj2 = np.array([20, 18, 23, 20, 22, 20, 25])
>>> enake_meritve(casi, kraj1, kraj2)
array([ 9, 12, 15, 18])
Rešitev
def enake_meritve(casi, temp1, temp2):
    return np.array(casi)[temp1 == temp2]

Brez negativnih

Napišite funkcijo brez_negativnih(a), ki sprejme 2D numpy tabelo a in vrne novo tabelo brez vrstic in stolpcev, ki vsebujejo kakšno negativno vrednost. V spodnjem primeru odstrani prvo in tretjo vrstico ter prvi, tretji in peti stolpec; ne ostane prav dosti.

>>> a = np.array([[1, 0, -3, 3, -4],
                  [1, 2, 5, 1, 8],
                  [-2, 3, 1, 4, 5],
                  [6, 2, 1, 7, 0]])
>>> brez_negativnih(a)
array([[2, 1],
       [2, 7]])
Rešitev
def brez_negativnih(a):
    return a[np.all(a >= 0, axis=1)][:, np.all(a >= 0, axis=0)]

Večkotnik

Napišite funkcijo veckotnik(a), ki izračuna in vrne obseg večkotnika. Sprejme 2D numpy tabelo a, ki podaja koordinate vozlišč večkotnika, kot si sledijo po vrsti (povezana sta tudi prvo in zadnje vozlišče).

>>> a = np.array([[-2,1], [0,-1], [1,0], [1,2], [-1,2]])
>>> veckotnik(a)
9.65685425
Rešitev
def veckotnik(a):
    return np.sum(np.sqrt(np.sum((a - np.roll(a,-1,axis=0))**2, axis=1)))

Človek ne jezi se

V poenostavljeni igri Človek ne jezi se ima vsak igralec eno figuro. Vsi začnejo na polju 0, igralna plošča pa je neskončno dolga. Igralci se krožno izmenjujejo na potezi. Ko je igralec na vrsti, vrže kocko in premakne figuro za toliko polj, kolikor pokaže kocka. Če pri tem pride na polje, na katerem že stoji kateri drugi igralec, gre tisti (drugi igralec) na polje 0.

Napiši funkcijo clovek_ne_jezi_se(igralcev, meti), ki kot argument dobi število igralcev in zaporedje metov, kot rezultat pa vrne številke polj, na katerih se po teh metih nahajajo igralci.

print(clovek_ne_jezi_se(5, [1, 2, 3, 4, 5, 4, 3, 2, 1, 1, 2, 3]))
[2, 3, 0, 5, 1]
Rešitev
def clovek_ne_jezi_se(igralcev, meti):
    pozicije = [0] * igralcev
    for poteza, met in enumerate(meti):
        igralec = poteza % igralcev
        nova = pozicije[igralec] + met
        pozicije = [0 if x == nova else x for x in pozicije]
        pozicije[igralec] = nova
    return pozicije

Datumi

V neki datoteki so datumi shranjeni v taki obliki:

01. 01. 2024
02. 01. 2024
03. 01. 2024
08. 01. 2024
10. 01. 2024

Napiši funkcijo preberi_datume(ime_datoteke), ki prejme ime datoteke z datumi in prešteje kolikokrat se vsak dan v tednu pojavi v tej datoteki. Za zgornji primer naj funkcija vrne slovar {"Monday": 2, "Tuesday": 1, "Wednesday":2}. Pomagaj si z metodo datum.strftime("%A"), kjer je datum tipa datetime.datetime.

Rešitev
def preberi_datume(ime_dat):
    stevec = defaultdict(int)
    with open(ime_dat) as f:
        for vrstica in f:
            dt = datetime.strptime(vrstica.strip(), "%d. %m. %Y")
            stevec[dt.strftime("%A")] += 1
    return stevec

Druzinsko drevo

Imamo družinsko drevo, ki izgleda nekako takole:

tree

in je zapisano s slovarjem, ki ga najdete v datoteki s testi. Prav tako je v datoteki s testi slovar v katerem so zapisane starosti vsakega od članov.

Napiši funkcijo najmlajsi_v_rodbini(ime), ki vrne starost in ime najmlajšega člana določene rodbine.

>>> najmlajsi_v_rodbini('Hans')
(64, 'Hans')
>>> najmlajsi_v_rodbini('Daniel')
(5, 'Alenka')
Rešitev
def najmlajsi_v_rodbini(ime):
    najmlajsi = (starost[ime], ime)
    for sin in otroci[ime]:
        najmlajsi = min(najmlajsi, najmlajsi_v_rodbini(sin))
    return najmlajsi

Čebele

V nalogi se bomo ukvarjali kar s čebelarjenjem. Napiši funkcijo po_vrstah(vrt), ki vrne seznam vsot količin nektarja po vseh vrstah. Torej, po_vrstah([[3, 5, 1], [1, 1, 1], [2, 0, 4]]) mora vrniti [9, 3, 6]. Nalogo reši z izpeljanimi seznami.

Rešitev
def po_vrstah(nektar):
    return [sum(vrsta) for vrsta in nektar]

Napiši funkcijo najboljsi(vrt), ki vrne seznam z maksimalnimi količin nektarja po vseh vrstah. Torej, najboljsi([[3, 5, 1], [1, 1, 1], [2, 0, 4]]) mora vrniti [5, 1, 4].

Rešitev
def najboljsi(nektar):
    return [max(vrsta) for vrsta in nektar]

Napiši funkcijo diagonala(vrt), ki pove, koliko naberejo čebele vrste Apis diagonalicus, ki gredo čez vrt vedno po diagonali, (0, 0), (1, 1), (2, 2), ...), dokler ne pridejo do roba (dokler ne zmanjka vrstic ali stolpcev). Klic po_diagonali([[3, 5, 1], [1, 1, 1], [2, 0, 4]]) mora vrniti 8 (to je, 3 + 1 + 4).

Rešitev
def diagonala(nektar):
    return sum(nektar[i][i] for i in range(min(len(nektar), len(nektar[0]))))
Last modified: Saturday, 20 January 2024, 8:58 PM