Naloge
Delali bomo s tviti. Ti so shranjeni v seznamih, ki izgledajo takole.
["sandra: Spet ta dež. #dougcajt",
"berta: @sandra Delaj domačo za #programiranje1",
"sandra: @berta Ne maram #programiranje1 #krneki",
"ana: kdo so te @berta, @cilka, @dani? #krneki",
"cilka: jst sm pa #luft",
"benjamin: pogrešam ano #zalosten",
"ema: @benjamin @ana #split? po dvopičju, za začetek?"]
Zapis tvita se začne z imenom avtorja (brez @), sledi dvopičje, nato pa besedilo tvita.
- Napišite funkcijo
unikati(s)
, ki prejme seznam nekih stvari in kot rezultat vrne nov seznam, v katerem se vsak element pojavi le enkrat. Vrstni red v rezultat naj bo enak vrstnemu redu prvih pojavitev v podanem seznamu. Klicunikati([1, 3, 2, 1, 1, 3, 2])
mora vrniti[1, 3, 2]
.
Rešitev
Najpreprosteje je sestaviti nov seznam in zlagati vanj. Preden dodamo posamezni element pa preverimo, ali je morda že v seznamu.def unikati(s):
t = []
for i in s:
if i not in t:
t.append(i)
return t
- Napišite funkcijo
avtor(tvit)
, ki vrne ime avtorja podanega tvita. Klicavtor("ana: kdo so te @berta, @cilka, @dani? #krneki")
vrne"ana"
.
Rešitev
Razbijemo glede na dvopičje in vrnemo prvi element.def avtor(tvit):
return tvit.split(":")[0]
- Napišite funkcijo
vsi_avtorji(tviti)
, ki prejme seznam tvitov in vrne seznam vseh njihovih avtorje. Vsak naj se v seznamu pojavi le enkrat; vrstni red naj bo enak vrstnemu redu prvih pojavitev. Če funkcijo pokličemo z gornjim seznamom tvitov, mora vrniti["sandra", "berta", "ana", "cilka", "benjamin", "ema"]
. Sandra se pojavi le enkrat, čeprav je napisala dva tvita.
Rešitev
Pomagajte si s funkcijami, ki ste jih že napisali.def vsi_avtorji(tviti):
imena = []
for tvit in tviti:
imena.append(avtor(tvit))
return unikati(imena)
Kmalu se bomo naučili, da gre tudi tako
def vsi_avtorji(tviti):
return unikati(map(avtor, tviti))
Napišite funkcijo
izloci_besedo(beseda)
, ki prejme neko besedo in vrne to besedo brez vseh ne-alfanumeričnih znakov (to je, znakov, ki niso črke ali števke) na začetku in koncu. Če pokličemoizloci_besedo("!%$ana---")
, mora vrniti"ana"
. Če pokličemoizloci_besedo("@janez-novak!!!")
, vrne"janez-novak"
(in ne"janeznovak"
!).Namig:
strip()
tule morda ne bo preveč uporaben. Pač pa v dokumentaciji Pythona preverite, kaj dela metodaisalnum
. Potem nalogo rešite tako, da odstranjujte prvi znak besede, dokler ta ni črka. In potem na enak način še zadnjega. Kako besedi odstranimo znak, pa boste - če se ne boste spomnili sami - izvedeli v zapiskih o indeksiranju.
Rešitev
Najpreprostejša rešitev je: odbijamo prvi znak, dokler nam ni všeč. In potem odbijamo zadnji znak, dokler nam ni všeč. Nato vrnemo rezultat.def izloci_besedo(beseda):
while beseda and not beseda[0].isalnum():
beseda = beseda[1:]
while beseda and not beseda[-1].isalnum():
beseda = beseda[:-1]
return beseda
Drug, za računalnik hitrejši, a za nas zamudnejši način je, da najdemo indeks prve in zadnje črke ter vrnemo, kar je vmes.
def izloci_besedo(beseda):
for prva in range(len(beseda)):
if beseda[prva].isalnum():
break
for zadnja in range(len(beseda), 0, -1):
if beseda[zadnja-1].isalnum():
break
return beseda[prva:zadnja]
Prvi del je lažji: zanko vrtimo, dokler ne pridemo do prve črke. Drugi je podoben, le indeksi so bolj zoprni: šli bomo od dolžine besede do 0 in preverjali en znak pred tem indeksom. Tako se splača zato, ker potem vrnemo vse znake do tega indeksa, se pravi vključno s tistim, ki smo ga preverjali.
- Napišite funkcijo
se_zacne_z(tvit, c)
, ki prejme nektvit
in nek znakc
. Vrniti mora vse tiste besede iz tvita, ki se začnejo s podanim znakomc
. Pri tem mora od besed odluščiti vse nealfanumerične znake na začetku in na koncu. Klicse_zacne_z("sandra: @berta Ne maram #programiranje1 #krneki", "#")
vrne["programiranje1", "krneki"]
.
Rešitev
Sestavimo prazen seznam, gremo čez besede v tvitu, in v seznam zložimo vse, ki se začnejo s podanim znakom. Mimogrede pa pokličemo še `izloci_besedo`.def se_zacne_z(tvit, c):
besede = []
for beseda in tvit.split():
if beseda[0] == c:
besede.append(izloci_besedo(beseda))
return besede
Naučili pa se bomo tudi krajše.
def se_zacne_z(tvit, c):
return [izloci_besedo(beseda) for beseda in tvit.split() if beseda[0] == c]
- Napišite funkcijo
zberi_se_zacne_z(tviti, c)
, ki je podobna prejšnji, vendar prejme seznam tvitov in vrne vse besede, ki se pojavijo v njih in se začnejo s podano črko. Poleg tega naj se vsaka beseda pojavi le enkrat. Če pokličemozberi_se_zacne_z(tviti, "@")
(kjer sotviti
gornji tviti), vrne['sandra', 'berta', 'cilka', 'dani', 'benjamin', 'ana']
. Vrstni red besed v seznamu je enak vrstnemu redu njihovih pojavitev v tvitih.
Rešitev
To je spet podobno: sestavimo seznam, gremo čez tvite in zlagamo vanj. Edina razlika je, da moramo tokrat uporabiti `+=` (ali `extend`) namesto `append`-a, saj lepimo skupaj sezname.def zberi_se_zacne_z(tviti, c):
afne = []
for tvit in tviti:
afne += se_zacne_z(tvit, c)
return unikati(afne)
- Napišite funkcijo
vse_afne(tviti)
, ki vrne vse besede v tvitih, ki se začnejo z @. Če ji podamo gornje tvite, mora vrniti['sandra', 'berta', 'cilka', 'dani', 'benjamin', 'ana']
.
Rešitev
def vse_afne(tviti):
return unikati(zberi_se_zacne_z(tviti, "@"))
- Napišite funkcijo
vsi_hashtagi(tviti)
. Za gornje tvite vrne['dougcajt', 'programiranje1', 'krneki', 'luft', 'zalosten', 'split']
.
Rešitev
def vsi_hashtagi(tviti):
return unikati(zberi_se_zacne_z(tviti, "#"))
- Napišite funkcijo
vse_osebe(tviti)
, ki vrne po abecedi urejen seznam vseh oseb, ki nastopajo v tvitih - bodisi kot avtorji, bodisi so omenjene v tvitih. Vsaka oseba naj se pojavi le enkrat. Za gornje tvite funkcija vrne['ana', 'benjamin', 'berta', 'cilka', 'dani', 'ema', 'sandra']
.
Rešitev
Funkcija mora vrniti tisto, kar vrneta funkciji `vsi_avtorji` in `vse_afne`, le unikate moramo pobrati in vse skupaj urediti.def vse_osebe(tviti):
osebe = unikati(vsi_avtorji(tviti) + vse_afne(tviti))
osebe.sort()
return osebe
Če vemo za funkcijo `sorted`, pa gre še hitreje.
def vse_osebe(tviti):
return sorted(unikati(vsi_avtorji(tviti) + vse_afne(tviti)))
- Napišite funkcijo
custva(tviti, hashtagi)
, ki prejme seznam tvitov in seznam hashtagov (brez začetnega #). Vrne naj vse avtorje, ki so uporabili vsaj enega od naštetih tagov. Avtorji naj bodo urejeni po abecedi in vsak naj se pojavi le enkrat. Kliccustva(tviti, ["dougcajt", "krneki"])
vrne["ana", "sandra"]
.
Rešitev
def custva(tviti, hashtagi):
avtorji = []
for tvit in tviti:
if neprazen_presek(se_zacne_z(tvit, "#"), hashtagi):
avtorji.append(avtor(tvit))
avtorji.sort()
return unikati(avtorji)
Za vsak tvit preverimo, ali je presek med besedami, ki se začnejo s `#` in podanimi `hashtagi` neprazen. Če je tako, dodamo avtorja tega tvita v seznam avtorjev, ki ga posortiramo in vrnemo.
Manjka nam še funkcija za neprazen presek?
def neprazen_presek(s, t):
for e in s:
if e in t:
return True
return False
Naučili pa se bomo tudi tako
def custva(tviti, hashtagi):
return unikati(sorted(avtor(tvit) for tvit in tviti if set(hashtagi) & set(se_zacne_z(tvit, "#"))))
- Napišite funkcijo
se_poznata(tviti, oseba1, oseba2)
, če jeoseba1
v katerem od svojih tvitov omenila osebooseba2
ali obratno.
Rešitev
Gremo prek vseh tvitov. Za vsakega odkrijemo avtorja in vse, ki so omenjeni. Če je prva oseba pisec, druga pa omenjena ali pa obratno, vrnemo `True`. Če se to ne zgodi v nobenem tvitu, vrnemo `False`.def se_poznata(tviti, oseba1, oseba2):
for tvit in tviti:
pisec = avtor(tvit)
omenjeni = se_zacne_z(tvit, "@")
if oseba1 == pisec and oseba2 in omenjeni or \
oseba2 == pisec and oseba1 in omenjeni:
return True
return False