Start | ovningar1
 

Övningar



Nedan är uppgifter från tentor i programmeringsteknik från universitet ute i landet.

Kommer det terminera?

Dvs, kommer följande program terminera eller snurra i en evighetsloop. Terminera betyder alltså avsluta. Tänk Terminator.

Klicka nu inte på programmet för att se facit. Tänk själv först! Resonera och förklara.
a = 1 while(2==1 or a>1 or (True and False)): a = a + 1 print("I´m stuck")

Vilken utskrift?

Vilken utskrift ger följande program? Du ska kunna förklara.
a = 4.3 b = False if(4 < a < 5): if(not b): print("Nästlad if-sats") else: print("falsk sådan") else: "Slut"

Vilken utskrift?

Förklara.
s = "123" while(len(s)>0): print(s) s = s[1:]

Vad händer här?

Vad händer när följande kod exekveras? Förklara koden. För att se svaret kan du lägga till print(x) i nedan kod.
x = str(int(4.3))+"mm"*2+" bred."

Fixa koden

(5p) Någon har skrivit en funktion xor(x,y) som är tänkt returnera True om x är True eller y är True men inte om båda är True. Programmeraren kom fram till följande:
def xor(x,y): if x: if y: return False return True return True
Ett fel har dock smugit sig in.

a) Vilket?
b) Skriv en rättad version. Du får inte använda and/or/not.


förslag på lösning


Börja med att göra en tabell, det underlättar rejält. Uppgiften beskriver sanningstabellen för xor, men du behöver föra ner det på papper i tabellform.

xyx xor y
FalseFalseFalse
FalseTrueTrue
TrueFalseTrue
TrueTrueFalse

Tänk såhär; det är 2 situationer som ska bli True. Låt if-satsen leda rätt. If x (dvs x är True), då är det else -sidan på y som ska gälla. Det ena True och andra False. Och vice versa. Studera förslaget en stund om det är klurigt. Försök sedan upprepa det.
def xor(x,y): if x: if y: return False else: return True else: if y: return True else: return False print(xor(False,False)) print(xor(False,True)) print(xor(True,False)) print(xor(True,True))

Vad blir utskriften?

(5p) Vad blir utskriften på följande program:
def sortTwoFirst(lst): if(lst[0] > lst[1]): lst[0], lst[1] = lst[1], lst[0] def tail(lst): return(lst[1:]) lista1 = [4,3,2,1] lista2 = lista1 sortTwoFirst(lista2) lista1 = tail(lista1) print(lista1)

lösning


1) lista1 = [4,3,2,1]
2) lista2 = lista1, detta betyder att lista2 och lista1 nu är synonymer för samma lista. Ungefär som Elisabeth kallas Lisa. Det är samma person.
3) eftersom element i [0] (dvs 4) är större än [1] (dvs 3) så byts plats på dessa element. lista 1 OCH lista 2 (det är ju numera samma lista) är alltså hädanefter [3,4,2,1]
4) lista1 = lista1[1:], dvs som vi lärde oss längre upp plockar vi bort första elementet. lista1 OCH lista2 (det är fortfarande samma lista) 'r nu [4,2,1]
5) Utskrift av [4,2,1]

Skriv funktion

(5p) Skriv en funktion findLast som tar en sträng str och ett tecken (sträng av längd 1). Funktionen ska returnera det största index i strängen str där tecknet c förekommer. Om tecknet c inte förekommer i strängen str skall ett undantag (exception) av typen ValueError kastat åtföljt av en beskrivande feltext.

exempel

findLast("Mississippi", "s")
6

findLast("Mississippi", "j")
ValueError: Couldnt find j in Mississippi

Inbyggda funktioner får inte användas. Du får använda len, for, while dock.

def findLast(s, t): pass print(findLast("Mississippi", "s")) print(findLast("Mississippi", "j"))

förslag på lösning


def findLast(s, t): pos = 0 matchpos = -1 while(pos < len(s)): if(s[pos]==t): matchpos = pos pos += 1 if(matchpos == -1): raise ValueError('Couldnt find '+t+' in '+s) return matchpos print(findLast("Mississippi", "s"))
De frågar efter det högsta värdet på positionen som matchar bokstaven. Det betyder att om vi letar efter positioner där det matchar och låter loopen fortsätta även efter att vi hittat någon matchning, så kommer matchpos motsvara den senaste (sista) matchningen i loopen, dvs den med högst värde (matchningen längst till höger). Om fler matchningar hittas så kommer ju tidigare värdet bara skrivas över och det värdet som blir kvar i slutändan motsvarar den senaste (sista) matchningen.

Om de istället frågat efter första matchningen då hade vi kunnat göra return direkt när denna matchningen inträffar och då behövs inte ens variabeln matchpos. Se nedan.
def findFirst(s, t): pos = 0 while(pos < len(s)): if(s[pos]==t): return pos pos += 1 raise ValueError('Couldnt find '+t+' in '+s) print(findFirst("Mississippi", "s"))

Skriv funktion

(5p) Studera följande kodsnutt
s = "abba" n = 0 while(len(s) > 0): if(n==len(s)): print("jämt antal tecken i strängen") n = n + 1 s = s[1:]
Identifiera lämpliga parametrar och kapsla in koden som en egen funktion. Modifiera koden så att funktionen returnerar true och strängen har jämnt antal tecken annars false (tips: utskriften i koden ljuger inte).
def jamt_antal_tecken(s): pass print(jamt_antal_tecken("Kalle")) print(jamt_antal_tecken("abba")) print(jamt_antal_tecken("apa"))

förslag på lösning


def jamt_antal_tecken(s): n = 0 while(len(s) > 0): if(n==len(s)): return True n = n + 1 s = s[1:] return False print(jamt_antal_tecken("Kalle")) print(jamt_antal_tecken("abba")) print(jamt_antal_tecken("apa"))

Skapa palindrom

Ett palindrom är ett ord som blir likadant även om man vänder på det. t.ex. "abba". Din uppgift är att skriva en funktion som skapar ett palindrom från ett ord. Du gör det genom att ta ordet och lägga till den bakvända varianten efter ordet. Om ordet är "dator" så skall du lägga till "ratad" efter och då får du "datorratad", som är ett palindrom.


förslag på lösning


Vi utnyttjar att vi kan komma åt bokstäverna med index bakifrån. Så vi räknar upp från 0 till strängens längd och bygger ihop baklänges-ordet genom att hämta bokstäverna bakifrån.
def palindrom(ord): baklanges = "" for i in range(len(ord)): baklanges+=ord[-1-i] return(ord+baklanges) print(palindrom("natur"))
En lösning till, som vänder på ordet med rekursion. Baklänges tar sista bokstaven i ordet och lägger till baklänges av resten.
def baklanges(ord): if ord: ord = ord[-1] + baklanges(ord[:-1]) return ord def palindrom(ord): return(ord+baklanges(ord)) print(palindrom("natur"))

molekylvikt

Antag vi har en textfil med atomer och deras massa, på varje rad en atom och massa åtskilld av mellanslag, exempel på fil: /ex/atom_massa.txt (öppnas i nytt fönster). Vi ska nu skriva en funktion som givet en molekyl t.ex. CH4, beräknar dess massa. Vi kan utnyttja att multiplikatorn alltid kommer efter atomen och vi kan anta att multiplikatorn bara är en (1st) siffra 2-9. OBS uppgiften förutsätter att även atomen enbart har en (1 st) bokstav (för en mer avancerad variant som kommer runt detta, se nästa uppgift).

förslag på lösning


Vi börjar med att läsa in filen och skapar en dictionary så att vi snabbt kan slå upp molekylvikten givet en atom.

För att beräkna en viss molekyls vikt loopar vi över strängen. Om tecknet är en bokstav, då är det en atom, dvs vi kollar upp vikten och lägger vikten i en lista. Om tecknet i strängen är en siffra, så multiplicerar vi senast ditlagda vikt i vår lista med denna multipel. Slutligen summerar vi alla vikter i vår lista och returnerar svaret.
vikt={} with open('/ex/atom_massa.txt') as fil: for rad in fil: atom,massa = rad.split() vikt[atom]=massa def mass(molekyl): molekylvikt=[] for m in molekyl: if(m.isnumeric()): molekylvikt[-1] = molekylvikt[-1] * float(m) else: molekylvikt.append(float(vikt[m])) return(sum(molekylvikt)) print("H2O",mass("H2O"),"g/mol") print("CH4",mass("CH4"),"g/mol") print("H2SO3",mass("H2SO3"),"g/mol")
En mer avancerad version av denna uppgift finns under filhantering.
16.427993774414 ms