Pokaži črke

Napiši funkcijo pokazi_crke(beseda, crke), ki kot argument sprejme besedo in množico (set) črk. Funkcija mora vrniti besedo, v kateri so vse črke, ki ne nastopajo v množici crke, spremenjene v pike.


>>> pokazi_crke("PONUDNIK", set(["O", "N"]))
'.ON..N..'
>>> pokazi_crke("PONUDNIK", set(["O", "I", "K"]))
'.O....IK'
>>> pokazi_crke("PONUDNIK", set())
'........'
>>> pokazi_crke("PONUDNIK", set(["P", "O", "N", "I", "K", "U"]))
'PONU.NIK'

def pokazi_crke(beseda, crke):
    koncna = ""
    for crka in beseda:
        if crka in crke:
            koncna += crka
        else:
            koncna += "."
    return koncna

Uporabniške skupine

Unix zapisuje skupine uporabnikov v datoteko /etc/group. Vsaka vrstica opisuje eno skupino uporabnikov. V njej so štirje podatki, ločeni z dvopičji: ime skupine, geslo, številski id in seznam uporabnikov v skupini. Uporabniška imena so ločena z vejicami. Del datoteke je lahko, recimo, takšen(primer datoteke):


ana:x:500:ana
berta:x:501:berta
cilka:x:502:cilka
dani:x:503:dani
ordinary:x:504:ana,berta,cilka,dani
taccess:x:505:berta,cilka
wusers:x:506:ana,cilka

V njej vrstica taccess:x:505:berta,cilka pravi, da sta v skupini taccess uporabnici berta in cilka. Geslo in številka sta za to nalogo nepomembna.

Napiši funkcijo beri_skupine(ime_dat), ki kot argument prejme ime datoteke groups in kot rezultat vrne slovar, katerega ključi so uporabniki, vrednosti pa skupine, v katerih je ta uporabnik (torej obratno od tega, kar je v groups, kjer za skupino izvemo, katere uporabnike vsebuje).


>>> users = beri_skupine("groups")
>>> users["ana"]
['ana', 'ordinary', 'wusers']
>>> users["cilka"]
['cilka', 'ordinary', 'taccess', 'wusers']
>>> users["dani"]
['dani', 'ordinary']

Če imate težave pri reševanju, poskusite najprej s pomožnimi nalogami.

Pomožna naloga 1

Preberite datoteko groups in izpišite vse skupine uporabnikov.

Pomožna naloga 2

Poleg skupin izpišite tudi vse uporabnike v teh skupinah. Predlagam, da uporabnike shranite v seznam. Npr., tako:


skupina=ana, uporabniki so=[ana]
...
skupina=ordinary, uporabniki so=[ana,berta,cilka,dani]
...

Pomožna naloga 3

Zdaj pa napišimo program, ki prebere podatke in pripravi ustrezen slovar. Recimo, plan bi lahko bil takšen:

    1. Pripravimo si prazen slovar. Ker vemo, da bodo vrednosti seznami, lahko uporabimo razred defaultdict iz modula collections.
    2. Sprehodimo se čez zapise v datoteki groups (eno vrstico naenkrat).
      1. Shranimo skupino in uporabnike v ustrezni spremenljivki.
      2. Z zanko se sprehodimo čez uporabnike in vsakemu uporabniku dodajmo skupino (v slovar).

    S tem ste nalogo praktično že končali, napisati morate le še funkcijo. Za to nalogo ni testov, dovolj je, če deluje na priloženi datoteki.

    
    import collections
    def beri_skupine(ime_dat):
        users = collections.defaultdict(list)
        for line in open(ime_dat):
            group_name, password, group_id, group_list = line.strip().split(":")
            for user in group_list.split(","):
                users[user].append(group_name)
        return dict(users)
    
    

    Izvozniki

    Poberite si datoteko s podatki o izvozu iz posameznih držav in jo shranite v direktorij, v katerem boste pisali svoj program. Odprite jo v poljubnem urejevalniku besedil in si oglejte, kako je videti. (Pazite, da je pri tem ne bi ponesreči shranili, da ne bo kaj narobe.)

    Napišite funkciji kdo_izvaza(produkt) in kaj_izvaza(drzava). Primer:

    
    >>> kdo_izvaza("rum")
    {'Jamaica', 'Puerto Rico', 'Bahamas', 'British Virgin Islands', 'Guyana', 'Anguilla', 'Barbados'}
    >>> kdo_izvaza("aircraft")
    {'Canada', 'United States', 'European Union', 'Malta', 'France'}
    >>> kdo_izvaza("nickel")
    {'Botswana', 'Colombia', 'Cuba'}
    

    Najprej napišimo funkcijo, ki prebere podatke v dva globalna slovarja.

    
    def preberi_podatke():
        global drzave, produkti
        drzave = {}
        produkti = collections.defaultdict(set)
        for vrstica in open("izvoz.txt"):
            drzava, stvari = vrstica.strip().split("\t")
            stvari = stvari.strip().split(", ")
            drzave[drzava] = set(stvari)
            for stvar in stvari:
                produkti[stvar].add(drzava)
    

    Potem sta funkciji, ki jih potrebujemo, trivialni:

    def kdo_izvaza(produkt):
        return produkti[produkt]
    def kaj_izvaza(drzava):
        return drzave[drzava]
    

    Podobna beseda

    Sestavi funkcijo podobna(beseda, besede), ki kot argument sprejme besedo in seznam besed in kot rezultat vrne tisto besedo iz seznama, v kateri se pojavi čim več črk, ki se pojavijo tudi v dani besedi. Vsako ujemajočo se črko štejemo le enkrat, tudi če se v obeh besedah pojavi večkrat. Funkcija naj deluje tako, da ne razlikuje med malimi in velikimi črkami. Če obstaja več enako podobnih besed, vrnite prvo med njimi.

    
    >>> podobna("merjasec", ["ana", "berta", "cilka", "dani", "ema", "fanci", "greta", "hilda"])
    'berta'
    >>> podobna("zmaj", ["ana", "berta", "cilka", "dani", "ema", "fanci", "greta", "hilda"])
    'ema'
    >>> podobna("Krava", ["ana", "berta", "cilka", "dani", "ema", "fanci", "greta", "hilda"])
    'berta'
    

    Ana in krava ujemata v eni črki, namreč črki a in ne v dveh, pa čeprav imata po dva a-ja. (Opomba: vsaka podobnost med Berto in merjascem je zgolj naključna.)

    
    def podobna(beseda, besede):
        beseda = beseda.lower()
        bs = set(beseda)
        najCrk = 0
        for enaBeseda in besede:
            skupnih = len(bs & set(enaBeseda.lower()))
            if skupnih > najCrk:
                najCrk = skupnih
                najBeseda = enaBeseda
        return najBeseda
    

    Ali malo krajše, če znamo uporabljati funkcijo max in argument key:

    
    def podobna(beseda, besede):
        return max(besede, key=lambda x: set(beseda.lower()) & set(x.lower()))
    

    Raznolikost

    Napiši funkcijo najraznolika(bes), ki kot argument prejme seznam nizov in kot rezultat vrne niz, ki ima največ različnih znakov. Male in velike črke upoštevaj kot iste znake - beseda "MamA" ima samo dva različna znaka. Če obstaja več besed z enakim številom različnih znakov, naj vrne prvo med njimi.

    
    >>> besede = ["RABarbara", "izpit", "zmagA"]
    >>> najraznolika(besede)
    'izpit'
    
    
    def najraznolika(bes):
        najCrk = 0
        for b in bes:
            crk = len(set(b.lower()))
            if crk > najCrk:
                najCrk = crk
                najBeseda = b
        return najBeseda
    

    Podobno kot zgoraj, z funkcijo max in argumentom key:

    
    def najraznolika(bes):
        return max(besl, key=lambda x:len(set(x.lower())))
    

    Šifra

    Niz '\x19\x14\x1c]\x19\x0f\x14\t\x13\x18\t]\x12\x0e[\n\x1a\t\x18\x15\x12\x13\x1c' lahko odšifriramo z naslednjo funkcijo:

    def sifriraj(niz, kljuc):
        return ''.join(chr(ord(c) ^ (kljuc // 256**(i % 2) % 256)) for i, c in enumerate(niz))
    

    Problem je v tem, da ne poznamo ključa. Vemo le, da je nekje med 0 in 65536. Sumimo, da je originalno sporočilo v angleškem jeziku in da so vse besede slovnično pravilno zapisane. Napišite funkcijo sifra(niz), ki vrne odšifrirano sporočilo.

    >>> sifriraj('strawberry pudding', 1337)
    'JqKdNg\\wK|\x19uLa]lWb'
    >>> sifriraj('JqKdNg\\wK|\x19uLa]lWb', 1337)
    'strawberry pudding'
    >>> sifra('JqKdNg\\wK|\x19uLa]lWb')  # To funkcijo morate napisati vi
    'strawberry pudding'
    

    Namig:

    def sifra(niz):
        # Zgradimo množico vseh angleških besed. 
        words = set()
        f = open('Usr.Dict.Words'):
        for word in f:
            words.add(word.strip())
    
        # Sprehodimo se po vseh možnih ključih.
        for k in range(65536):
            plain = sifriraj(niz, k)
            for w in plain.split():
                if w not in words:
                    break
            else:
                return plain
    
    Zadnja sprememba: sreda, 4. marec 2026, 10.02