Basis#

Bij deze opdrachten vragen we je drie programma’s die lussen gebruiken te lezen en te wijzigen. Lussen zijn een krachtige controlestructuur voor iteratie, het herhaaldelijke uitvoeren van dezelfde handeling.

Looping for a while…#

Iets heel vaak herhalen is waar computers op hun best zijn en mensen in het algemeen duidelijk niet van gediend zijn!

Opdracht 1#

a. Lees, om een beeld te krijgen van het gebruik van lussen de onderstaande functie met commentaar. Dit is een functie die de faculteit berekent door middel van een for-lus.

def fac(n):
    """Loop-based factorial function

    Argument: a nonnegative integer, n
    Return value: the factorial of n
    """
    result = 1                 # beginwaarde; lijkt op een basisgeval
    for x in range(1, n + 1):  # herhaal van 1 tot en met n
        result = result * x    # pas het resultaat aan door keer x te doen
    return result              # merk op dat dit NA de lus is!

#
# Tests voor de lus-versie van de faculteit
#
assert fac(0) == 1
assert fac(5) == 120
# probeer dit voorbeeld

b. Maak nu een nieuwe functie power(b, p) door de bovenstaande functie te kopiëren en aan te passen, of door de functie zelf te schrijven op dezelfde manier. Deze functie moet aan de volgende eisen voldoen:

  • Accepteert een numerieke waarde b (base, grondtal)

  • Accepteert een niet-negatieve integer p (power, macht) (p kan 0 zijn)

  • Geeft de waarde van b ** p terug

  • De functie moet een for-lus gebruiken! Je mag niet gewoon b ** p gebruiken…

  • In dit geval doen we alsof power(0, 0) gelijk is aan 1.0, ook als dat wiskundig niet helemaal juist is.

Hier zijn een paar tests die je kan omzetten naar asserts:

#
# Tests voor de lus-versie van machtsverheffen
#
print("power(2, 5): is 32 ==", power(2, 5))
print("power(5, 2): is 25 ==", power(5, 2))
print("power(42, 0): is 1 ==", power(42, 0))
print("power(0, 42): is 0 ==", power(0, 42))
print("power(0, 0): is 1 ==", power(0, 0))

Overeenkomst met de faculteitsfunctie

De parameter n uit de faculteitsversie heeft dezelfde functie als de parameter p in deze functie. Het grondtal b wordt alleen gebruikt om mee te vermenigvuldigen.

# jouw oplossing

Opdracht 2#

a. De volgende functie summed telt alle elementen van een lijst bij elkaar op. Lees de functie eerst goed door.

def summed(L):
    """Loop-based function to return a numeric list.
       ("sum" is built-in, so we're using a different name.)

    Argument: L, a list of integers.
    Result: the sum of the list L.
    """
    result = 0
    for e in L:
        result = result + e    # of result += e
    return result

# tests!
assert summed([4, 5, 6]) == 15
assert summed(range(3, 10)) == 42
# probeer dit voorbeeld

b. Maak nu zelf een functie summed_odds(L) door deze functie als voorbeeld te gebruiken, die

  • Een lijst integers L accepteert.

  • Je mag ervan uitgaan dat de lijst alleen integers bevat.

  • De functie moet de som teruggeven van alle oneven getallen in L.

  • Als er geen oneven getallen in de lijst zijn, moet de functie 0 teruggeven.

  • Maak gebruik van een lus!

Vergeet niet de functie voldoende te testen!

# tests!
assert summed_odds([4, 5, 6]) == 5
assert summed_odds(range(3, 10)) == 24

Tip

Maak binnen de lus gebruik van een if-statement, zodat je de waarde alleen aan het resultaat toevoegt onder de juiste omstandigheden.

# jouw oplossing

Opracht 3#

Bij deze opdracht kijken we naar wat ook wel de verjaardagenparadox wordt genoemd.

  • Zelfs in een vrij kleine groep mensen (al vanaf 23!) is de kans dat twee van die mensen dezelfde verjaardag hebben groter dan 50%.

  • Wikipedia heeft hier ook een pagina over met wat meer details.

a. Lees eerst deze functie om getallen te raden met een while-lus goed door.

import random

def count_guesses(hidden):
    """Uses a while loop to guess "hidden", from 0 to 99.

    Argument: hidden, a "hidden" integer from 0 to 99.
    Result: the number of guesses needed to guess hidden.
    """
    guess = random.choice(range(0, 100))     # 0 tot en met 99
    num_guesses = 1                          # we hebben nu 1 keer geraden
    while guess != hidden:
        guess = random.choice(range(0, 100)) # opnieuw raden!
        num_guesses += 1                     # 1 toevoegen aan het aantal pogingen
    return num_guesses
# probeer dit voorbeeld

b. Gebruik count_guesses als voorbeeld om een variant te schrijven die we until_a_repeat(high) gaan noemen.

  • Deze functie houdt een lijst L bij van alle getallen die geraden zijn. Begin met L = []!

  • We blijven getallen raden zolang alle elementen van L uniek zijn (dus zolang er geen herhalingen zijn).

    • Gebruik een while-lus!

    • Gebruik de functie unique(L) hieronder die een boolean teruggeeft.

  • Binnen de while-lus doet de funtie het volgende:

    • Gok een getal van 0 tot high met behulp van range(0, high)

    • Houd het aantal geraden getallen bij (bijvoorbeeld met een telvariabele)

    • Voeg het getal toe aan de lijst L

  • Als de while-lus klaar is moet de functie het aantal geraden getallen teruggeven dat nodig was om een dubbel getal te krijgen.

Tip

  • Onthoud dat je 1 aan een variabele kan toevoegen met count += 1

  • Op dezelfde manier kan je een element, bijvoorbeeld 42 aan het einde van een lijst toevoegen met L = L + [42].

    Het element moet wel tussen blokhaken staan, omdat alleen lijsten mogen worden opgeteld bij een lijst.

Hier is de hulpfunctie unique die je al eerder hebt gezien.

def unique(L):
    """Returns whether all elements in L are unique.

    Argument: L, a list of any elements.
    Return value: True, if all elements in L are unique,
            or False, if there is any repeated element
    """
    if len(L) == 0:
        return True
    elif L[0] in L[1:]:
        return False
    else:
        return unique(L[1:])  # in deze functie mag je WEL recursie gebruiken!

Nadat je until_a_repeat hebt geschreven, kan je controleren dat until_a_repeat(365) inderdaad verrassend kleine getallen oplevert! Bijvoorbeeld,

In [1]: until_a_repeat(365)
Out[1]: 25

In [2]: until_a_repeat(365)
Out[2]: 8

In [3]: until_a_repeat(365)
Out[3]: 23

In [4]: until_a_repeat(365)
Out[4]: 33
# jouw oplossing