Basis: lambda

Deze pagina bevat uitvoerbare code.

De uitslag van de schoolrun

Op de sportdag lopen de leerlingen een rondje van drie kilometer. Na afloop moet er een uitslag komen: wie was het snelst, wat is de ranglijst, en wie wint in de jeugdklasse? In deze opgave schrijf je die functies. Bij elke functie geef je een andere functie mee: aan max, min of sorted, of aan een functie die je zelf schrijft.

De uitslag

De uitslag is een lijst van lijsten. Elke deelnemer is een lijst met drie elementen:

Index

Betekenis

Voorbeeld

0

naam

"Noor"

1

leeftijd in jaren

17

2

tijd in seconden

754

Noor liep het rondje dus in 754 seconden: 12 minuten en 34 seconden. Wie de kleinste tijd heeft, was het snelst. De cel hieronder zet de uitslag klaar in RESULTS. Voer hem eerst uit.

RESULTS = [
    ["Noor", 17, 754],
    ["Sem", 19, 698],
    ["Lotte", 18, 698],
    ["Yara", 16, 812],
    ["Finn", 21, 745],
]

Wat je gaat maken

Stap

Functie

Doet

Wat je meegeeft

1

fastest

de naam van de snelste

een lambda-functie aan min

2

ranking

de namen van snel naar langzaam

een lambda-functie met een sleutel van twee delen aan sorted

3

select

de deelnemers die aan een voorwaarde voldoen

een functie als parameter van je eigen functie

4

winner

de naam van de snelste die aan een voorwaarde voldoet

een functie die je doorgeeft

Stap 1: fastest(results)

Geeft de naam van de deelnemer met de kleinste tijd. results is niet leeg. Hebben twee deelnemers dezelfde tijd, dan wint wie het eerst in de lijst staat.

Aanroep

Resultaat

fastest(RESULTS)

"Sem"

fastest([["Ali", 20, 600]])

"Ali"

Hint

min met een lambda-functie achter key= geeft de hele deelnemer met de kleinste tijd, zoals max(players, key=lambda p: p[1]) in het tweede college. Van die deelnemer geef je alleen de naam terug. Bij gelijke tijden geeft min vanzelf de eerste.

# jouw oplossing
assert fastest(RESULTS) == "Sem"
assert fastest([["Ali", 20, 600]]) == "Ali"

Stap 2: ranking(results)

Geeft een lijst met de namen van alle deelnemers, van de snelste naar de langzaamste. Hebben twee deelnemers dezelfde tijd, dan komt de naam die in het alfabet eerst komt vooraan.

Aanroep

Resultaat

ranking(RESULTS)

["Lotte", "Sem", "Finn", "Noor", "Yara"]

ranking([])

[]

Sem en Lotte hebben allebei 698 seconden. Lotte staat vooraan, want de L komt vóór de S.

Hint

Een sleutel mag ook een lijst zijn. Python vergelijkt twee lijsten zoals twee woorden: eerst het eerste element, en pas als dat gelijk is het tweede. [698, "Lotte"] komt dus vóór [698, "Sem"]. Laat de lambda-functie de lijst [tijd, naam] teruggeven. Zet daarna met een list comprehension alleen de namen in een lijst.

# jouw oplossing
assert ranking(RESULTS) == ["Lotte", "Sem", "Finn", "Noor", "Yara"]
assert ranking([["Bo", 30, 700], ["Ad", 25, 700]]) == ["Ad", "Bo"]
assert ranking([]) == []

Stap 3: select(results, test)

test is een functie die bij een deelnemer True of False teruggeeft. Geeft een lijst met de deelnemers uit results waarvoor test True teruggeeft, in dezelfde volgorde.

Aanroep

Resultaat

select(RESULTS, lambda r: r[1] < 18)

[["Noor", 17, 754], ["Yara", 16, 812]]

select(RESULTS, lambda r: r[1] > 30)

[]

De lambda-functie in het eerste voorbeeld geeft True voor wie jonger is dan 18: de jeugdklasse.

Hint

Een list comprehension met een if, zoals in week 2. Roep in de if de functie test aan op elke deelnemer.

# jouw oplossing
assert select(RESULTS, lambda r: r[1] < 18) == [["Noor", 17, 754], ["Yara", 16, 812]]
assert select(RESULTS, lambda r: r[2] < 700) == [["Sem", 19, 698], ["Lotte", 18, 698]]
assert select(RESULTS, lambda r: r[1] > 30) == []

Stap 4: winner(results, test)

Geeft de naam van de snelste deelnemer waarvoor test True teruggeeft. Er is altijd minstens één zo’n deelnemer.

Aanroep

Resultaat

winner(RESULTS, lambda r: r[1] < 18)

"Noor"

winner(RESULTS, lambda r: r[1] >= 18)

"Sem"

Hint

Je hebt alles al. winner geeft test door aan select, en zoekt in wat daar uitkomt de snelste met fastest. Dat past op één regel.

# jouw oplossing
assert winner(RESULTS, lambda r: r[1] < 18) == "Noor"
assert winner(RESULTS, lambda r: r[1] >= 18) == "Sem"
assert winner(RESULTS, lambda r: r[0][0] == "Y") == "Yara"

Tot slot

Sem en Lotte liepen even snel: allebei 698 seconden. fastest geeft Sem, omdat hij eerder in de lijst staat en min bij een gelijke tijd de eerste kiest. De ranglijst zet Lotte vooraan, omdat daar bij een gelijke tijd het alfabet beslist. Twee functies, twee regels voor een gelijke stand. In de jeugdklasse wint Noor.

In elke stap gaf je een functie mee. In stap 1 en 2 gaf je een lambda-functie aan min en sorted, die hem bij elke deelnemer aanriepen. In stap 3 schreef je zelf een functie met een functieparameter, en in stap 4 gaf je die functie weer door. Zo maakt één winner de winnaar van elke klasse: alleen de lambda-functie die je meegeeft, verschilt.