Tracks
/
Python
Python
/
Übungen
/
Notenvergabe
Notenvergabe

Notenvergabe

Lernübung

Einführung

Python hat zwei Schleifenkonstrukte. while-Schleifen für die unbestimmte (ungezählte) Iteration und for-Schleifen für die bestimmte (gezählte) Iteration. Die Schlüsselwörter break, continue und else helfen dabei, das Verhalten der Schleife anzupassen. range() und enumerate() helfen beim Zählen und Indizieren in Schleifen.

While

while-Schleifen werden so lange weiter ausgeführt, wie der loop expression oder „Test" im boolean context zu True ausgewertet wird. Sie enden, sobald er zu False ausgewertet wird:


# Lists are considered "truthy" in a boolean context if they
# contain one or more values, and "falsy" if they are empty.

>>> placeholders = ["spam", "ham", "eggs", "green_spam", "green_ham", "green_eggs"]

>>> while placeholders:
...     print(placeholders.pop(0))
...
'spam'
'ham'
'eggs'
'green_spam'
'green_ham'
'green_eggs'

For

Die grundlegende for-loop in Python lässt sich besser als for each beschreiben, die durch die Werte eines beliebigen iterierbaren Objekts läuft und endet, wenn der Aufruf von next() keine Werte mehr zurückgibt:


>>> word_list = ["bird", "chicken", "barrel", "bongo"]

>>> for word in word_list:
...    if word.startswith("b"):
...        print(f"{word.title()} starts with a B.")
...    else:
...        print(f"{word.title()} doesn't start with a B.")
...
'Bird starts with a B.'
'Chicken doesn\'t start with a B.'
'Barrel starts with a B.'
'Bongo starts with a B.'

Sequenzobjekt range()

Wenn kein bestimmtes iterable angegeben ist, wird die spezielle Sequenz range() als Schleifenzähler verwendet. range() benötigt eine int, vor der die Sequenz stop machen soll, und kann optional die Parameter start und step annehmen. Wenn keine start-Zahl angegeben wird, beginnt die Sequenz bei 0. range()-Objekte sind lazy (Werte werden auf Anfrage erzeugt), unterstützen alle allgemeinen Sequenzoperationen und belegen eine feste Menge an Speicher, egal wie lang die angegebene Sequenz ist.

# Here we use range to produce some numbers, rather than creating a list of them in memory.
# The values will start with 1 and stop *before* 7

>>> for number in range(1, 7):
...    if number % 2 == 0:
...       print(f"{number} is even.")
...    else:
...       print(f"{number} is odd.")
'1 is odd.'
'2 is even.'
'3 is odd.'
'4 is even.'
'5 is odd.'
'6 is even.'

# range() can also take a *step* parameter.
# Here we use range to produce only the "odd" numbers, starting with 3 and stopping *before* 15.

>>> for number in range(3, 15, 2):
...    if number % 2 == 0:
...       print(f"{number} is even.")
...    else:
...       print(f"{number} is odd.")
...
'3 is odd.'
'5 is odd.'
'7 is odd.'
'9 is odd.'
'11 is odd.'
'13 is odd.'

Werte und Indizes mit enumerate()

Wenn sowohl die Werte als auch ihre Indizes benötigt werden, gibt das eingebaute enumerate(<iterable>) (index, value)-Paare zurück:


>>> word_list = ["bird", "chicken", "barrel", "apple"]

# *index* and *word* are the loop variables.
# Loop variables can be any valid python name.

>>> for index, word in enumerate(word_list):
...    if word.startswith("b"):
...        print(f"{word.title()} (at index {index}) starts with a B.")
...    else:
...        print(f"{word.title()} (at index {index}) doesn't start with a B.")
...
'Bird (at index 0) starts with a B.'
'Chicken (at index 1) doesn\'t start with a B.'
'Barrel (at index 2) starts with a B.'
'Apple (at index 3) doesn\'t start with a B.'


# The same method can be used as a "lookup" for pairing items between two lists.
# Of course, if the lengths or indexes don't line up, this doesn't work.

>>> word_list = ["cat", "chicken", "barrel", "apple", "spinach"]
>>> category_list = ["mammal", "bird", "thing", "fruit", "vegetable"]

>>> for index, word in enumerate(word_list):
...    print(f"{word.title()} is in category: {category_list[index]}.")
...
'Cat is in category: mammal.'
'Chicken is in category: bird.'
'Barrel is in category: thing.'
'Apple is in category: fruit.'
'Spinach is in category: vegetable.'

Das Verhalten von Schleifen ändern

Mit dem Schlüsselwort continue kannst du zum nächsten Iterationsdurchlauf springen:

word_list = ["bird", "chicken", "barrel", "bongo", "sliver", "apple", "bear"]

# This will skip *bird*, at index 0
for index, word in enumerate(word_list):
    if index == 0:
        continue
    if word.startswith("b"):
        print(f"{word.title()} (at index {index}) starts with a b.")

'Barrel (at index 2) starts with a b.'
'Bongo (at index 3) starts with a b.'
'Bear (at index 6) starts with a b.'

Mit dem Schlüsselwort break (wie in vielen C-verwandten Sprachen) kannst du die Iteration stoppen und aus der innersten umgebenden loop „ausbrechen":

>>>  word_list = ["bird", "chicken", "barrel", "bongo", "sliver", "apple"]

>>> for index, word in enumerate(word_list):
...    if word.startswith("b"):
...        print(f"{word.title()} (at index {index}) starts with a B.")
...    elif word == "sliver":
...       break
...    else:
...       print(f"{word.title()} doesn't start with a B.")
... print("loop broken.")
...
'Bird (at index 0) starts with a B.'
'Chicken doesn\'t start with a B.'
'Barrel (at index 2) starts with a B.'
'Bongo (at index 3) starts with a B.'
'loop broken.'

Anleitung

Du bist Lehrassistent und korrigierst die Prüfungen der Schüler. Die Ergebnisse manuell zu verfolgen, wird mit der Zeit mühsam und fehleranfällig. Du beschließt, die Sache etwas interessanter zu machen, indem du ein paar Funktionen schreibst, die die Ergebnisse für die Klasse zählen und berechnen.

1. Punkte runden

Auch wenn du bei Prüfungsfragen „Teilpunkte“ vergeben kannst, müssen die Gesamtpunkte der Prüfung ints sein. Bevor du also irgendetwas anderes mit den Punkten der Klasse machen kannst, musst du die Noten durchgehen und alle float-Punkte in ints umwandeln. Zum Glück hat Python die eingebaute Funktion round(), die du verwenden kannst.

Erstelle die Funktion round_scores(student_scores), die eine list von student_scores entgegennimmt. Diese Funktion soll die Eingabe-list konsumieren und eine neue Liste returnen, die alle Punkte als ints enthält. Die Reihenfolge der Punkte in der resultierenden list ist nicht wichtig.

>>> student_scores = [90.33, 40.5, 55.44, 70.05, 30.55, 25.45, 80.45, 95.3, 38.7, 40.3]
>>> round_scores(student_scores)
...
[40, 39, 95, 80, 25, 31, 70, 55, 40, 90]

2. Nicht bestandene Schüler

Beim Korrigieren der Prüfung ist dir aufgefallen, dass einige Schüler nicht so gut abschnitten, wie du gehofft hattest. Aber du warst abgelenkt und hast vergessen, genau zu notieren, wie viele Schüler es waren.

Erstelle die Funktion count_failed_students(student_scores), die eine list von student_scores entgegennimmt. Diese Funktion soll die Anzahl der Schüler zählen, die keine bestandene Punktzahl haben, und diese Anzahl als Ganzzahl zurückgeben. Ein Schüler braucht eine Punktzahl größer als 40, um die Prüfung zu bestehen.

>>> count_failed_students(student_scores=[90,40,55,70,30,25,80,95,38,40])
5

3. Die „Besten“

Die Lehrkraft, der du assistierst, möchte die Gruppe von Schülern finden, die bei dieser Prüfung am besten abgeschnitten haben. Was als „am besten“ gilt, schwankt, also musst du die Punkte der Schüler finden, die größer oder gleich dem aktuellen Schwellenwert sind.

Erstelle die Funktion above_threshold(student_scores, threshold), die student_scores (eine list mit Noten) und threshold (den Schwellenwert für die „Höchstpunktzahl“) als Parameter entgegennimmt. Diese Funktion soll eine list mit allen Punkten zurückgeben, die >= dem Schwellenwert sind.

>>> above_threshold(student_scores=[90,40,55,70,30,68,70,75,83,96], threshold=75)
[90,75,83,96]

4. Buchstabennoten berechnen

Die Lehrkraft, der du assistierst, möchte neben numerischen Punkten auch Buchstabennoten vergeben. Da Schüler bei einer Prüfung selten 100 Punkte erreichen, werden die unteren Schwellenwerte für die Buchstabennoten auf Basis der höchsten erreichten Punktzahl berechnet. Sie steigen gleichmäßig zwischen der Höchstpunktzahl und der Schwelle zum Durchfallen von <= 40 an.

Erstelle die Funktion letter_grades(highest), die die „höchste“ Punktzahl der Prüfung als Argument entgegennimmt und eine list mit unteren Schwellenwerten für jedes „amerikanische“ Notenintervall zurückgibt: ["D", "C", "B", "A"].

"""Where the highest score is 100, and failing is <= 40.
       "F" <= 40
 41 <= "D" <= 55
 56 <= "C" <= 70
 71 <= "B" <= 85
 86 <= "A" <= 100
"""

>>> letter_grades(highest=100)
[41, 56, 71, 86]


"""Where the highest score is 88, and failing is <= 40.
       "F" <= 40
 41 <= "D" <= 52
 53 <= "C" <= 64
 65 <= "B" <= 76
 77 <= "A" <= 88
"""

>>> letter_grades(highest=88)
[41, 53, 65, 77]

5. Namen den Punkten zuordnen

Du hast eine Liste mit Prüfungspunkten in absteigender Reihenfolge und eine weitere Liste mit Schülernamen, die ebenfalls absteigend nach ihren Prüfungspunkten sortiert ist. Du möchtest jeden Schülernamen seinem Prüfungsergebnis zuordnen und eine Gesamtrangliste der Klasse ausgeben.

Erstelle die Funktion student_ranking(student_scores, student_names) mit den Parametern student_scores und student_names. Ordne jeden Schülernamen in der student_names-list seinem Punktwert aus der student_scores-list zu. Du kannst davon ausgehen, dass jede Argument-list vom höchsten zum niedrigsten Punktwert sortiert ist. Die Funktion soll eine list mit Strings im Format <rank>. <student name>: <student score> zurückgeben.

>>> student_scores = [100, 99, 90, 84, 66, 53, 47]
>>> student_names =  ['Joci', 'Sara','Kora','Jan','John','Bern', 'Fred']
>>> student_ranking(student_scores, student_names)
...
['1. Joci: 100', '2. Sara: 99', '3. Kora: 90', '4. Jan: 84', '5. John: 66', '6. Bern: 53', '7. Fred: 47']

6. Eine „perfekte“ Punktzahl

Auch wenn eine „perfekte“ Punktzahl von 100 bei einer Prüfung selten ist, ist es interessant zu wissen, ob mindestens ein Schüler sie erreicht hat.

Erstelle die Funktion perfect_score(student_info) mit dem Parameter student_info. student_info ist eine list von Listen, die den Namen und die Punktzahl jedes Schülers enthalten: [["Charles", 90], ["Tony", 80]]. Die Funktion soll das erste [<name>, <score>]-Paar des Schülers returnen, der 100 Punkte in der Prüfung erreicht hat.

Wenn in student_info keine 100 Punkte gefunden werden, soll eine leere Liste [] zurückgegeben werden.

>>> perfect_score(student_info=[["Charles", 90], ["Tony", 80], ["Alex", 100]])
["Alex", 100]

>>> perfect_score(student_info=[["Charles", 90], ["Tony", 80]])
[]
Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab
Python Exercism

Bereit, mit Notenvergabe zu starten?

Melde dich bei Exercism an, um Python mit 17 Konzepte146 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.