Start | ovningar3
 

Övningar



räkna fram tid

Du har ett klockslag givet som en tuple, (tim, min). Skriv en funktion som räknar fram klockslaget 10 minuter. Kom ihåg att en timme bara har 59 minuter och ett dygn bara 24 timmar.



förslag på lösning


#vi väljer krångligast möjliga tid tid = (23,55) def fram10Min(t): (h,m) = t m += 10 if(m>=60): m-=60 h+=1 if(h>=24): h-=24 return(h,m) print(fram10Min(tid))

word_freq

Skriv en funtion word_freq(text) som tar en text som argument och som returnerar en dictionary/lexikon/ordlista som består av ord och antal förekomster.



förslag på lösning


Så, vi behöver skapa en loop/snurra över alla ord i texten. För varje ord måste vi kolla om ordet finns i en dictionary. Om det inte finns, så lägger vi till det. Om det finns, så räknar vi upp antalet. Sen printar vi ut dictionaryn. Klart.

Det kluriga här är troligtvis att komma på att det egentligen är ganska enkelt. Hur ska dictionaryn se ut? Typ, såhär:

d = {"katt":1, "hund":1"}

Dvs, vi kan titta om ett ord finns med d.get("katt") som antingen ger antalet ifråga (ifall "katt" finns) eller None (om "katt" ej finns). Vi kan börja med situationen om ordet finns, isåfall vill vi räkna upp siffran. När vi gjort d.get(), därefter vet vi ju att ordet finns i dictionaryn, så då kan vi komma åt det som vanligt.

if(d.get(ord)!=None): antal = d[word] d[word] = antal + 1

Om ordet inte finns, då skapar vi ordet i dictionaryn med update.
text = """ Det var en gång en liten katt med svart päls och en vit svans. Katten hade en kompis som var en kanin med vit päls och svart svans. En vacker dag konstaterade kaninen. - Du, vi är ju som Yin och Yang, du och jag! - De e vi. De vet du, sa katten. Sen levde dom lyckliga i alla sina dagar. """ def word_freq(text): text_lst = text.split() dic = {} for word in text_lst: if(dic.get(word)!=None): antal = dic[word] dic[word] = antal + 1 else: dic.update({word:1}) return dic print(word_freq(text))

addera listor

Din uppgift är att skriva en funktion som tar en lista av listor med element (2d) och som returnerar en lista (1d) med alla element.



Förlag på lösning


En lista av lista innebär att du kan loopa över denna lista-av-listor. Inne i loopen loopar du över alla element i aktuell lista. Dessa element adderas till en ny lista som sedan returneras.
def addera_listor(lista_av_listor): ihopslagen_lista=[] for lista in lista_av_listor: for element in lista: ihopslagen_lista.append(element) return ihopslagen_lista print(addera_listor([[1,2,3,4],[5,6,7,8,9]]))

palindrom

Ett palindrom är ett ord som när man vänder på det fortfarande är samma ord. T.ex. är "abba" ett palindrom eller natur-programmet på SVT som hette "naturrutan". Din uppgift är att skriva en funktion som avgör om ett ord är ett palindrom.



Förlag på lösning


Funktionen tar en sträng som parameter, strängen som skall kontrolleras. Vi kan tänka oss en loop över strängen. Loopen behöver dock enbart gå halva vägen. Vi utnyttjar att man i python kan komma åt en sträng bakifrån med negativa index.

Vi utgår ifrån att texten är ett palindrom, dvs vi sätter pal = True, värdet som vi senare returnerar. Men hittar vi ett skäl sätta detta värde till False, så gör vi det.

Vi jämför nu bokstaven längst fram med den längst bak. Är dessa samma, så fortsätter vi bara kolla.

naturrutan
01234-5-4-3-2-1

Loopen går fram ett steg och vi jämför nästa tecken med varandra.

naturrutan
01234-5-4-3-2-1

Loopen går fram ytterligare ett steg och vi jämför på nytt dessa tecken med varandra. Skulle de vara olika så sätta pal = False och det blir False som returneras.

naturrutan
01234-5-4-3-2-1

Loopen går fram igen jämför på nytt dessa tecken med varandra. Skulle de vara olika så sätta pal = False och det blir False som returneras.

naturrutan
01234-5-4-3-2-1

När vi kommit fram till hälften så är loopen klar. Vi hittade inget som satte pal = False Så det kommer bli True som returneras.

naturrutan
01234-5-4-3-2-1

En klurig grej som inte får missas det är att första index från vänster är 0 (noll) medans första index från höger är -1. Eller hur? -0 finns inte.
def palindrom(str): pal = True halva = len(str)//2 for i in range(halva): if(str[i]!=str[-i-1]): pal = False return pal print(palindrom("naturrutan")) print(palindrom("abba")) print(palindrom("kalle"))
Okej, det finns en enklare lösning. Men jag är osäker på om er lärare kommer godkänna den. Så, det går helt enkelt ut på att jämföra framlänges ord med baklänges.
def palindrom(str): return(str == str[::-1]) print(palindrom("naturrutan")) print(palindrom("abba")) print(palindrom("kalle"))

split

Å nej, en bugg har stulit split från din python. Din uppgift är att skriva funktionen split. Den ska ta 2 argument, varav det 2:a är "optional". Det första argumentet är en text. Det andra är vilken separator som skall användas för att splitta texten.



Förlag på lösning


en ko kort
0123456789
start
stopp

I begynnelsen är start = stop = 0. Den inre while -loopen stegar fram stop till det första mellanrummet. Så start är fortfarande = 0 och stop = 2.

en ko kort
0123456789
start
stopp

Den inre loopen hoppar nu ut eftersom det är mellanslag. Dvs koden lista.append(str[start:stop]) körs, där start=0 och stop=2. Detta lägger till str[0:2] till den nya interna listan som senare kommer returneras. Vad är str[0:2] ? Detta slice:ar ur texten mellan 0 och 2. Dvs inklusive tecknet på 0 -positionen men inte inklusive tecknet på 2 -positionen, utan enbart tecknet före.

När detta är gjort stegar vi först fram stop 1 steg, för att "komma loss" från mellanrummet. Därefter sätter vi start=stop.

en ko kort
0123456789
start
stopp


Den inre loopen stegar fram stop till mellanrummet.

en ko kort
0123456789
start
stopp


Så nu är start=3 och stop = 5. Dvs koden lista.append(str[start:stop]) körs en gång till. Detta lägger även denna gång till str[start:stop] till den nya interna listan som senare kommer returneras. Vad var nu str[start:stop] igen? Detta slice:ar ur texten mellan start och stop inklusive tecknet på start -positionen men inte inklusive tecknet på stop -positionen, utan enbart fram till tecknet före.

Vi stegar fram stop ett steg för att komma loss. Därefter sätter vi start = stop.

en ko kort
0123456789
start
stopp


Den inre loopen stegar nu fram och denna gång kommer den inre loopen stanna pga att strängen tar slut. Dvs stopp=10, dvs stop < len(str) är inte längre sant, vilket är/var villkoret för den inre loopen. Därför terminerar den inre loopen.

en ko kort
0123456789
start


Så nu är start = 6 och stop = 10 (stop är ett steg utanför ovan matris). Dvs koden lista.append(str[start:stop]) körs en gång till. Detta lägger även denna gång till str[start:stop] till den nya interna listan som senare kommer returneras. Vad var nu str[start:stop] igen? Detta slice:ar ur texten mellan start och stop inklusive tecknet på start -positionen men inte inklusive tecknet på stop -positionen, utan enbart fram till tecknet före.

Båda loopar hoppar avslutar nu p.g.a. start och stop nått strängens längd.
def split(str, separator=" "): lista = [] start = 0 stop = 0 while(start < len(str)): while(stop < len(str) and str[stop] != separator): stop+=1 lista.append(str[start:stop]) stop += 1 start = stop return(lista) print(split("en ko kort")) print(split("kalle var en kul kille")) print(split("25;10;45.8;33;89", ';'))

klartext

Skriv ett program som tar en siffra 1-999 och ger ifrån sig samma siffra i text. Så t.ex. 834 ska bli åttahundratrettiofyra.


Förlag på lösning


#input: tal 1-999 #output: tal i text def dec2swe(tal): entaltxt = ["", "ett", "två", "tre", "fyra", "fem", "sex", "sju", "åtta", "nio", "tio", "elva", "tolv", "tretton", "fjorton", "femton", "sexton", "sjutton", "arton", "nitton"] tiotaltxt = ["tio", "tjugo", "trettio", "fyrtio", "femtio", "sextio", "sjutio", "åttio", "nittio"] hundrataltxt = ["hundra", "tvåhundra", "trehundra", "fyrahundra", "femhundra", "sexhundra", "sjuhundra", "åttahundra", "niohundra"] text = "" if tal < 20: text = entaltxt[tal] else: hundratal = int(tal/100) tal = tal - hundratal*100 tiotal = int(tal/10) if tiotal <= 1: tiotal = 0 tal = tal - tiotal*10 ental = int(tal) if hundratal >= 1: text = hundrataltxt[hundratal - 1] if tiotal >= 1: text += tiotaltxt[tiotal - 1] text += entaltxt[ental] return text for i in range(200): print(i, dec2swe(i))

matchpattern

Din uppgift är att skriva en funktion som tar 2 argument. Det första är en pattern (mönster) och det andra är ett ord. Funktionen ska ge ifrån sig True eller False beroende på om mönstret matchar ordet. Ett mönster kan se ut på formen "-a-" där strek kan vara vad som helst men bokstav ska stämma med ordet som matchar. Så t.ex. matchar "-a-" ordet "lax" men inte ordet "bok".


Förlag på lösning


#indata: b--x- ord = ["bok","tok","bord","mord","jord","hord", "sax","max","pax","lax","strax","brax"] def matchpattern(p, w): match = True if len(p) != len(w): return False for i in range(len(w)): if p[i] != "-": if p[i] != w[i]: match = False return match #print(matchpattern("p--x-", "blixt")) def matchword(p, o): for i in range(len(o)): if matchpattern(p, o[i])==True: print(o[i]) matchword("-a-", ord)

swenoun




def swenoun(word): a = ["a", "an", "or", "orna"] ion = ["ion", "ionen", "ioner", "ionerna"] are = ["are", "aren", "are", "arna"] e = ["e", "et", "en", "ena"] rest = ["", "en", "ar", "arna"] print(word[-1]) if word[-1] == "a": for andelse in a: print (word[0:-1]+andelse) if word[-1] == "e": for andelse in e: print (word[0:-1]+andelse) swenoun("äpple")

ta bort göteborskan

Din nya göteborgska vän är väldigt trevlig men det är väl mycket göteborska på henne. Din uppgift är att skriva en funktion som ersätter göteborskan med rikssvenska.



1) Du ska ta bort alla "ju" och "änna"
2) Du ska ersätta "goegubbe" med "person"

Programmet ska vara lätt att under hålla, dvs alla ord som ska tas bort ska finnas i en lista tabort och alla ord som ska ersättas ska finnas i en dictionary ersatt.

Förlag på lösning


tabort = ["ju","änna"] ersatt = { "goegubben":"personen" } def fixaspraket(txt, brt, erstt): ny_text = [] txt_lista = txt.split() for ord in txt_lista: if ord in tabort: continue if ersatt.get(ord)!=None: ny_text.append(ersatt[ord]) else: ny_text.append(ord) return(" ".join(ny_text)) t = "goegubben var ju änna lite trött" print(fixaspraket(t, tabort, ersatt))

ersätt ord i en text

För att inte barnen ska behöva stå ut med hemska ord, så censureras allt som de ouppfostrade vuxna säger i stundens hetta. Skriv en funktion som tar 2 argument, dels en text och dels en dictionary. Om ett ord finns i dictionaryn betyder det att ordet skall ersättas i texten.


Förlag på lösning


forbjudna_ord = { "fan":"fy tusan", "jävlarna":"illaluktande myrsnokarna", "stack":"avlägsnade sig" } def ersatt(text, ordlista): text_lista = text.split() censurerad_text = [] for ord in text_lista: if(forbjudna_ord.get(ord)==None): censurerad_text.append(ord) else: censurerad_text.append(forbjudna_ord[ord]) return(" ".join(censurerad_text)) t = "fan också de jävlarna stack" print(ersatt(t,forbjudna_ord))

räkna dubbletter

Skriv en funktion som tar en lista av tal eller strängar eller något annat. Funktionen ska ge ifrån sig en lista med alla värden som är dubbletter. Så om man anropar funktionen med listan [1,2,3,4,5,4,5,6,7] så skall listan [4,5] returneras.


Förlag på lösning


lista = [1,2,3,4,3,2,5,6,6,9] def dubbletter(xs): dubbletterna = [] for i in range(len(xs)): for j in range(len(xs)): if i!=j and xs[i]==xs[j]: if not xs[i] in dubbletterna: dubbletterna.append(xs[i]) return(dubbletterna) print(dubbletter(lista))
16.894817352295 ms