Zum Inhalt springen

Wintersemester 2024/25

Wintersemester 2024/25. 9 ECTS: alle Aufgaben, 180 Minuten, 120 Punkte. 6 ECTS: nur A1 bis A6, 120 Minuten, 80 Punkte.

A1: Grundlagen (17 Punkte)

A1a (4 Punkte)

Geben Sie bei den folgenden Beispielen an, ob es sich eher um eine Textdatei oder eine Binärdatei handelt.

Ein kompiliertes C-Programm.
Der Quellcode eines C-Programms.
Eine Textdatei, die eine Hexadezimalzahl als String enthält: “0xff1193”
Ein JPEG-Bild.

A1b (6 Punkte)

Identifizieren Sie in folgendem Programmcode ein konkretes Beispiel für jeden der aufgelisteten Begriffe. Geben Sie das exakte Zeichen oder die Zeichenfolge aus dem Code an (nicht die Zeilennummer). Falls für einen Begriff kein Beispiel im Programm vorhanden ist, tragen Sie “fehlt” ein.

#include <cs50.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    string names[] = {"Barky", "Meowy"};
    string name = get_string("Name: ");
    for (int i = 0; i < 3; i++)
    {
        if (strcmp(names[i], name) == 0)
        {
            printf("Found %s\n", name);
            return 0;
        }
    }
    return 1;
}
Literal:
Variable:
Rückgabewert:
Escapesequenz:
Formatcode:
Einen Programmierfehler:

A1c (3 Punkte)

Welche Farben stellen die folgenden hexadezimalen RGB-Farbcodes dar? Ordnen Sie die Farbe zu, die am ehesten zutrifft.

Es stehen zur Auswahl:

  • eine rötliche Farbe
  • ein kräftiges Blau
  • schwarz
  • grau
#808080
#000000
#cc0000

A1d (4 Punkte)

Welches oder welche der in der Vorlesung behandelten grundlegenden informatischen Prinzipien lassen sich in folgendem Programm (Pseudocode) erkennen? Nennen Sie den oder die Fachbegriffe durch Leerzeichen getrennt.

FUNKTION länge(text):
    WENN text = "" DANN
        RÜCKGABE 0
    SONST
        RÜCKGABE 1 + länge(text ohne erstes Zeichen)

Hauptprogramm:
    AUSGABE "Bitte geben Sie einen Text ein: "
    text = EINGABE

    AUSGABE "Länge des Textes:"
    AUSGABE länge(text)
Erkennbare Prinzipien:
Durch Leerzeichen getrennte Fachbegriffe

Zu welchem Problem könnte es zur Laufzeit kommen, wenn der Pseudocode in C implementiert und ausgeführt wird? Bitte nennen Sie den Fachbegriff und die Bedingung unter der es zum Problem kommt.

Fachbegriff und Bedingung
[Fachbegriff] wenn [Bedingung]

A2: Grundlagen der C-Programmierung (14 Punkte)

A2a (3 Punkte)

Welche Werte erhalten die Variablen s und t, wenn der folgende Code-Abschnitt ausgeführt worden ist?

Falls Sie sich nicht mehr daran erinnern, wie der verwendete Operator funktioniert, können Sie den Code kompilieren und ausführen. Falls Sie VS Code verwenden möchten, lesen Sie bitte zuerst die Hinweise, die zu Beginn dieser Aufgabe verlinkt sind.

string str = "Test";
int s = 0;
int t = 0;
s = ((t = strlen(str)) > 10) ? 1 : 0;
Wert von s:
Wert von t:
Die Konstruktion mit "?" und ":" ist der sogenannte … Operator. Welcher Fachausdruck gehört in die Lücke?

A2b (7 Punkte)

Implementieren Sie ein Programm deduplicate.c, das Duplikate aus einem bereits sortierten Array von ganzen Zahlen entfernt. Duplikate sind Werte, die im Array mehrfach vorkommen.

Implementieren Sie die folgende Funktionalität direkt in main():

  • Deklarieren Sie ein Array mit den Namen numbers, das mindestens sieben sortierte fest kodierte Werte enthält. Zwei Werte sollen einfach vorkommen, ein Wert soll zweifach vorkommen und ein Wert soll dreifach vorkommen (z.B. 1, 2, 2, 3, 8, 8, 8).
  • Schreiben Sie direkt in die main()-Funktion Ihren Deduplicate-Algorithmus. Dieser Algorithmus muss das Array numbers verarbeiten und das Ergebnis auf der Konsole ausgeben, wobei aufeinanderfolgende Zahlen durch Leerzeichen voneinander getrennt sein sollen. Es ist nicht erforderlich, das deduplizierte Array abzuspeichern.
  • Es sollen keine Duplikate ausgegeben werden.
  • Die ausgegebenen Zahlen sollen weiterhin sortiert sein.
  • Nach der letzten Zahl soll ein Zeilenumbruch ausgegeben werden.
  • Überflüssige Leerzeichen am Zeilenende spielen in dieser Teilaufgabe keine Rolle.

Beispiele:

Wenn numbers anfangs die Werte 1, 2, 2, 3, 4, 4, 4, 5 enthält, wird die Zeichenfolge 1 2 3 4 5 ausgegeben. Wenn numbers hingegen die Werte 3, 3, 3, 3, 3 enthält, wird die Zeichenfolge 3 ausgegeben.

Überlegen Sie sich einen möglichst einfachen Weg, der ausnutzt, dass das Array bereits sortiert ist.

Kopieren Sie den gesamten Code Ihres Programms in dieses Feld:

Erstellen Sie eine Kopie Ihres Programms und nennen Sie diese zum Beispiel comma.c. Wandeln Sie Ihren Code so ab, dass er bei der Ausgabe die Zahlen mit einem Komma und einem Leerzeichen voneinander trennt. In den oben genannten zwei Beispielen soll also 1, 2, 3, 4, 5 bzw. weiterhin 3 ausgegeben werden.

Achten Sie – anders als in der vorigen Teilaufgabe – darauf, dass nach der letzten Zahl kein Komma und kein überflüssiges Leerzeichen ausgegeben wird, sondern nur ein Zeilenumbruch.

Sollte Ihr Programm deduplicate.c nicht lauffähig sein oder nicht korrekt funktionieren, können Sie hilfsweise in diesem Feld ein Programm abgeben, das die Werte eines Integer-Arrays mit beliebigen Werten so formatiert ausgibt, wie in der Aufgabenstellung gefordert.

Kopieren Sie den gesamten Code Ihres Programms in dieses Feld:

A2c (4 Punkte)

Das folgende Programm rechnet falsch, aber nur manchmal.

#include <cs50.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    int scores[3];
    scores[0] = get_int("Wert 1: ");
    scores[1] = get_int("Wert 2: ");
    scores[2] = get_int("Wert 3: ");

    float result = (scores[0] + scores[1] + scores[2]) / 3;
    int okay = 1;
    for(int i = 0; i < 3; i++)
    {
        if(scores[i] < 1)
        {
            okay = 0;
        }
    }
    if(okay)
    {
        printf("Durchschnittswert: %f\n", result);
    }
    else
    {
        printf("Werte kleiner 1 sind nicht erlaubt.\n");
    }
}

Bei den folgenden Fragen geben Sie die Werte bitte mit Leerzeichen getrennt an.

Geben Sie ein Beispiel für drei Eingabewerte an, bei denen das Programm korrekt rechnet.
mit Leerzeichen getrennte Werte
Geben Sie ein Beispiel für drei Eingabewerte an, bei denen das Programm fehlerhaft rechnet.
mit Leerzeichen getrennte Werte

A3: Palindrom-Checker (12 Punkte)

In dieser Aufgabe erstellen Sie schrittweise ein C-Programm palindrome.c, das prüft, ob ein als erstes Kommandozeilenargument übergebener String ein Palindrom ist. Zur Erinnerung: Ein Palindrom ist eine Zeichenfolge, die vorwärts und rückwärts gelesen identisch ist. Beispiele hierfür sind z.B. “anna”, “radar” und “lagerregal”.

Für diese Aufgabe stellen wir Ihnen Quellcode zur Verfügung, den Sie vervollständigen müssen. Wechseln Sie dazu im Terminal in das Verzeichnis exam-files/palindrome, das sich in Ihrem Homeverzeichnis /home/student befindet, und führen Sie dort aus:

code palindrome.c

Wenn Sie diese Schritt befolgt haben, steht Ihnen check50 zur Verfügung. Um check50 zu verwenden, führen Sie im Verzeichnis, in dem palindrome.c liegt, folgenden Befehl aus:

check50 checks/palindrome

Zuvor sollten Sie Ihr Programm kompilieren.

A3a (5 Punkte)

In dieser Teilaufgabe sollen Sie erst einmal nur die Eingaben des Benutzers überprüfen.

Wenn der Benutzer beim Aufruf des Programms keine Kommandozeilenargumente oder mehr als ein Argument übergibt, soll das Programm mit dem Rückgaberwert 1 beendet werden und folgende Meldung auf die Konsole (Standardausgabe) schreiben:

Usage: ./palindrome <word>

Wenn das übergebene Argument kein String ist, der ausschließlich aus Kleinbuchstaben besteht, soll das Programm ebenfalls mit dem Rückgabewert 1 beendet werden, in diesem Fall mit folgender Ausgabe:

The argument must be a lowercase string!

Vervollständigen Sie dazu die vorgegebene Funktion is_lowercase und rufen Sie diese in main() auf.

Kopieren Sie den gesamten Quellcode der Datei palindrome.c in dieses Feld.

A3b (7 Punkte)

Vervollständigen Sie nun die Funktion is_palindrome, die überprüft, ob es sich bei der übergebenen Zeichenkette um ein Palindrom handelt. Wenn die Zeichenkette ein Palindrom ist, soll das Programm folgendes ausgeben:

The string is a palindrome

Andernfalls soll es ausgeben:

The string is not a palindrome

Kopieren Sie den gesamten Quellcode der Datei palindrome.c in dieses Feld.

A4: Operation Pixel Whispers (12 Punkte)

Während sich die Kryptographie mit der Geheimhaltung von Informationen beschäftigt, hat die Steganographie ein anderes Ziel: Hier geht es darum, eine Nachricht in einem Medium (z.B. einem Bild) so zu verstecken, dass Außenstehende nicht bemerken, dass diese existiert. Bei Bildern werden dazu die Farbwerte verändert.

Sie sind eine Agentin oder ein Agent des Bureau of Steganographic Operations & Decryption, spezialisiert auf die Wiederherstellung von steganographischen Nachrichten, die in Windows-Bitmap-Dateien (BMP-Dateien) versteckt sind. Sie haben ein verdächtiges Bild abgefangen, von dem Sie glauben, dass es eine geheime Nachricht enthält.

Für diese Aufgabe stellen wir Ihnen Bilder und Quellcode zur Verfügung, den Sie vervollständigen müssen. Wechseln Sie dazu im Terminal in das Verzeichnis exam-files/pixels, das sich in Ihrem Homeverzeichnis /home/student befindet.

A4a (2 Punkte)

Ein befreundeter Nachrichtendienst hat Ihnen mitgeteilt, dass ein äußerst primitives Steganographie-Verfahren verwendet wird, bei dem kurze Nachrichten recht offensichtlich in einem der drei Farbkanäle transportiert werden. Hat man das Originalbild und das steganographisch veränderte Bild, kann man die geheime Botschaft leicht dekodieren.

Sehen Sie sich das Originalbild (cat.bmp) und das geänderte Bild (crypt.bmp) an, etwa in VS Code mit code cat.bmp und code crypt.bmp vergleichen Sie Vergrößerungen beider Bilder visuell.

Falls es Ihnen schwer fällt, einen Unterschied zu erkennen, können sie mit dem bereits kompilierten Kommandozeilenprogramm grayscale arbeiten, das im gleichen Verzeichnis liegt wie die Bilder. Dieses Program liest ein Bild ein und gibt es als Graustufenbild (grayscale.bmp) im aktuellen Verzeichnis aus. Da ein Graustufenbild nur noch Helligkeitswerte keine Farbinformationen mehr enthält, sollte es Ihnen leichter fallen zu ermitteln, wo sich die Nachricht befindet.

In welchem Farbkanal ist die geheime Botschaft versteckt?

A4b (4 Punkte)

Sie vermuten, dass die XOR-Operation verwendet wurde, um die Nachricht zu verstecken. Vervollständigen Sie das Programm poc.c, um einen Proof of Concept (PoC) zu entwickeln. Mit dem PoC wollen Sie zeigen, dass Sie das erste ASCII-Zeichen der steganographisch verschleierten Nachricht wiederherstellen können.

Durch manuelle Analyse der zwei Bilder haben Sie folgende Informationen ermittelt: das erste Byte, das im modifzierten Bild anders ist als im Original, hat im modifizierten Bild den Wert 210. In der Originaldatei steht an dieser Position der Wert 255. Passen Sie poc.c so an, dass zu sehen ist, wie man in C aus diesen Informationen das erste ASCII-Zeichen der Nachricht berechnen kann. Geben Sie das ASCII-Zeichen aus. In dieser Teilaufgabe ist es also nicht erforderlich, die Bilder einzulesen.

Hinweise zur Bearbeitung. Bei XOR handelt sich um einen logischen Operator, der auf einzelne Bits oder Bitfolgen (in C z.B. auf int oder char) angewendet werden kann. Das Ergebnis der XOR-Operation ist “wahr” (bzw. 1), wenn genau eines der beiden Eingabebits wahr (bzw. 1) ist, sonst ist das Ergebnis 0. Für zwei Eingabebits ergibt sich also:

aba XOR b
000
011
101
110

Wird XOR auf Werte angewendet, die aus mehreren Bits bestehen, werden die Bits paarweise verarbeitet. Verknüpft man beispielsweise die Zeichen ‘A’ und ‘a’ mit XOR, so erhält man ein Leerzeichen:

Binary      Hex     ASCII
0100 0001   0x41    A
0110 0001   0x61    a
---------------------------
0010 0000   0x20    <space>

Die XOR-Operation wird in C mit ^ kodiert. Dieses Zeichen liegt auf einer deutschen Tastatur über der Tab-Taste, also neben der Ziffer 1. Abschließend noch zwei Hinweise, die Ihnen helfen können, zu verstehen, wie eine Nachricht in ein Bild eingebettet wird und wie sie wieder extrahiert werden kann, wenn zusätzlich das Originalbild vorliegt:

a ^ a = 0
a ^ a ^ b = b
Kopieren Sie den gesamten Quellcode der Datei poc.c in dieses Feld.

A4c (6 Punkte)

Nachdem Sie sich mit dem Proof of Concept davon überzeugt haben, dass Ihr Ansatz funktioniert, vervollständigen sie als nächstes recover.c. Dieses Programm soll die ganze verschleierte Nachricht aus den beiden vorliegenden Bild-Dateien wiederherstellen. Geben Sie die Nachricht als ASCII-Text aus. Stellen Sie bei der Umsetzung sicher, dass ihr Programm keine Speicherlecks aufweist.

Hinweis: Es ist keine effiziente Implementation erforderlich. Wenn man mit printf einen char-Wert ausgeben lässt, der den Wert 0x00 hat, wird nichts ausgegeben und das Programm läuft weiter.

Kopieren Sie den gesamten Quellcode der Datei recover.c in dieses Feld.

A5: Sortieren und Tries (10 Punkte)

Die folgende Abbildung zeigt die aus der Vorlesung bekannte Visualisierung von Sortieralgorithmen. Sortiert wird jeweils ein Array mit zufällig angeordneten Zahlen. Die Visualisierung zeigt den aktuellen Zustand des Algorithmus und der Arrays zu einem bestimmten Zeitpunkt während des Sortiervorgangs. Beide Algorithmen haben zu Beginn das gleiche Array erhalten und wurden nach der gleichen Laufzeit angehalten.

Zwei Momentaufnahmen von Balkendiagrammen beim Sortieren. Links: nur ganz links ein paar kurze Balken sortiert und farbig markiert, der Rest ungeordnet. Rechts: mehrere bereits aufsteigend sortierte Teilfolgen nebeneinander, die größte links

A5a (6 Punkte)

Welche der drei in der Vorlesung behandelten Sortierverfahren kommen hier zum Einsatz?

Nennen Sie den in der Abbildung links verwendeten Algorithmus in der ersten Zeile. Begründen Sie ab der zweiten Zeile, warum es sich gerade um diesen handeln muss.
Name des Algorithmus Begründung
Nennen Sie den in der Abbildung rechts verwendeten Algorithmus in der ersten Zeile. Begründen Sie ab der zweiten Zeile, warum es sich gerade um diesen handeln muss.
Name des Algorithmus Begründung

A5b (4 Punkte)

Zur Erinnerung: Eine Speicherplatz-effiziente Umsetzung eines Tries ist mit folgender Datenstruktur möglich:

struct trie_node {
  char letter;
  char* str; // Stringpointer (falls Eintrag existiert; sonst NULL)
  struct trie_node* nachbar;
  struct trie_node* kind;
};

Mit dieser Datenstruktur wurde ein Trie für ein Abkürzungsverzeichnis erzeugt, der bereits zwei Elemente enthält:

  • CSS: Cascading Style Sheets
  • CPU: Central Processing Unit"

Im Speicher wird dies wie folgt abgebildet (Speicheradressen sind vierstellig):

// Root-Knoten (zeigt auf den ersten Buchstaben)
struct trie_node* root = 0x1000;

0x1000: ['C', NULL, NULL, 0x2000]
0x2000: ['P', NULL, 0x3000, 0x2100]
0x2100: ['U', Pointer auf "Central Processing Unit", NULL, NULL]
0x3000: ['S', NULL, NULL, 0x3100]
0x3100: ['S', Pointer auf "Cascading Style Sheets", NULL, NULL]
Fügen Sie den neuen Eintrag “CSV: Comma Separated Values” in die Trie-Struktur ein. Legen Sie dazu einen oder mehrere neue Knoten mit von Ihnen gewählten, beliebigen vierstelligen Speicheradressen an. In Ihrer Antwort geben Sie den oder die neuen Knoten in der gleichen Schreibweise an wie in der Aufgabenstellung, also Speicheradresse gefolgt vom Inhalt des Knotens. Sofern erforderlich, muss Ihre Antwort auch Änderungen an bestehenden Knoten dokumentieren (auch hier Angabe der Speicheradresse und des veränderten Inhalts).

A6: Structs und Pointer (15 Punkte)

A6a (6 Punkte)

Füllen Sie die mit “…” gekennzeichneten Lücken in folgendem C-Programm so, dass die Strukturen für Person 1 und Person 2 korrekt allokiert, befüllt und ausgegeben werden, ohne Zeilen des bereits vorhandenen Codes zu ändern oder zu löschen. Falls die gekennzeichneten Lücken zur Beantwortung nicht ausreichen, können Sie dem Code weitere Zeilen hinzufügen. Vermeiden Sie unnötige Speicheranforderungen.

#include <stdio.h>
#include <string.h>

struct person1
{
    unsigned int *age;
    char *name;
};

struct person2
{
    unsigned int age;
    char name[100];
};

int main(void)
{
    unsigned int age1 = 23;
    unsigned int age2 = 42;
    char* name1 = "Cathy";
    char* name2 = "Clark";

    // Person 1 (Cathy, 23) anlegen

    ... p1 = ...

    // Person 1 ausgeben:
    printf("1st: %d %s\n", ..., ...);

    // Person 2 (Clark, 42) anlegen:

    ... p2 = ...

    // Person 2 ausgeben:
    printf("2nd: %d %s\n", ..., ...);
}
Geben Sie hier den Inhalt der main-Funktion ein.
int main(void) { ...

A6b (4 Punkte)

Als Alias einer Variable bezeichnet man in C einen Ausdruck, der auf dasselbe Element im Speicher zugreift wie diese Variable, aber syntaktisch anders aussieht.

Gegeben sei eine Variable i und ein Pointer p, der auf i zeigt. Einige der folgenden Konstruktionen sind Aliase, einige sind keine Aliase, einige sind syntaktisch ungültig:

(a) *p      (c) *&p       (e) *i      (g) *&i
(b) &p      (d) &*p       (f) &i      (h) &*i

Beantworten Sie die folgenden Fragen, indem Sie eine durch Kommas getrennte Liste von Buchstaben der Ausdrücke angeben; beispielsweise a, c, e, wenn sie der Meinung sind, dass *p, *&p und *i Aliase sind, also auf das gleiche Objekt verweisen.

Welche Ausdrücke sind Aliase von i?
Welche Ausdrücke sind Aliase von p?

A6c (5 Punkte)

Implementieren Sie eine Funktion int count(sllnode* head, int value), die zählt, wie oft ein bestimmter Wert in einer Liste vorkommt. Eine leere Liste ist daran erkennbar, dass head NULL ist. Diesen Fall muss Ihre Funktion korrekt behandeln. Verwenden Sie dabei folgende Datenstruktur:

typedef struct sllnode {
    int value;
    sllnode *next;
} sllnode;

int count(sllnode *head, int value) {
    int counter = 0;
    // ...
    return counter;
}

Es ist nicht erforderlich, diese Aufgabe in VS Code zu lösen. Zum Testen Ihres Codes kann es jedoch hilfreich sein.

Kopieren Sie die Implementierung Ihrer Funktion count in dieses Feld:
int count(sllnode* head, int value) { ...

B1: Python und OOP (19 Punkte)

Sie müssen diese Aufgaben nur lösen, wenn Sie die 9-ECTS-Prüfung schreiben. Für die Lösung ist Python zu verwenden.

B1a (6 Punkte)

Schreiben Sie ein Python-Programm celsius.py, das einen Temperaturwert F in der Einheit Grad Fahrenheit einliest, diesen in die Einheit Grad Celsius (C) umrechnet und ausgibt. Die Formel für die Konvertierung ist

C = (F - 32) * 5/9

Benutzen Sie input() um die Temperatur einzulesen. Der Benutzer soll mit folgender Ausgabe zur Eingabe aufgefordert werde: “Wert: “. Falls Sie die Eingabeaufforderung mit der Funktion print() ausgeben, müssen Sie einen geeigneten benannten Parameter verwenden, damit die einzugebende Zahl direkt hinter der Eingabeaufforderung eingegeben werden kann, also in der gleichen Zeile. Andere Ansätze, um das gewünschte Verhalten zu erreichen, sind auch in Ordnung. Die Nutzung der cs50-Bibliothek ist bei dieser Teilaufgabe allerdings nicht zulässig. Geben Sie das Ergebnis auf eine Dezimalstelle gerundet aus. Beispiel:

Wert: 68
Ausgabe: 20.0
Kopieren Sie Ihren gesamten Quellcode in dieses Feld.

B1b (6 Punkte)

Schreiben Sie ein Programm fizzbuzz.py, das folgende Anforderungen erfüllt:

  • Eine Zahl n vom Benutzer einliest. Anders als bei der vorigen Aufgabe sollen Sie dafür nun get_int aus der cs50-Bibliothek verwenden.

  • Die Zahlen von 1 bis einschließlich n ausgibt, eine pro Zeile. Dabei sind folgende Sonderfälle zu beachten:

    • Wenn die Zahl durch 3 teilbar ist, gib die Zahl aus, gefolgt von einem Leerzeichen und dem String “Fizz”.
    • Wenn die Zahl durch 5 teilbar ist, gib die Zahl aus, gefolgt von einem Leerzeichen und dem String “Buzz”.
    • Wenn die Zahl sowohl durch 3 als auch durch 5 teilbar ist, gib die Zahl aus, gefolgt von einem Leerzeichen und dem String “FizzBuzz”.

Beispiel:

Eingabe: 7

Ausgabe:
1
2
3 Fizz
4
5 Buzz
6 Fizz
7
Kopieren Sie ihren gesamten Quellcode in dieses Feld.

B1c (3 Punkte)

Schreiben Sie ein Programm student.py eine Klasse Student, die bei der Initialisierung zwei Parameter entgegennimmt: Matrikelnummer (mat_num) und Name (name) entgegennimmt. Die übergebenen Werte sollen als Attribute gespeichert werden. Es ist nicht erforderlich, Properties zu verwenden.

Fügen Sie am Ende der Datei Code hinzu, der ein Student-Objekt mit dem Namen Max Mustermann und der Matrikelnummer 123456 erstellt und die Matrikelnummer dieses Objekts auf der Standardausgabe ausgibt.

Kopieren Sie den gesamten Quellcode von student.py in dieses Feld.

B1d (4 Punkte)

Erweitern Sie student.py wie folgt.

Fügen Sie der Klasse Student eine Methode add_grade(course, grade) hinzu. add_grade nimmt einen Kursnamen (String) und eine Note (Float) als Parameter entgegen. add_grade speichert die Note in einem Dictionary-Attribut grades, wobei der Kursname als Schlüssel verwendet wird und die Note als Wert.

grades soll beim Initialisieren von Objekten als leeres Dictionary angelegt werden.

Fügen Sie eine weitere Methode best() hinzu, die die beste (also betragsmäßig kleinste) Note berechnet und zurückgibt. Falls noch keine Noten eingetragen worden sind, soll die Methode den Wert 0 zurückgeben.

Nach der bestehenden Klassen-Definition und dem bereits vorhandenen Code, der die Matrikelnummer von Max Mustermann ausgibt, fügen Sie dem bereits erstellten Student-Objekt drei Noten hinzu:

  • “DM” mit Note 1.7
  • “EDS” mit Note 1.3
  • “Inf-Einf-B” mit Note 2.0

Rufen Sie die Methode best() auf, um die beste Note (nicht den Kursnamen) auf der Standardausgabe auszugeben.

Bei Problemen mit der Implementierung der Student-Klasse in der vorigen Aufgabe können Sie in dieser Aufgabe Teilpunkte erhalten, indem Sie ein Dictionary als globale Variable grades anlegen und add_grade(dict, course, grade) und best(dict) als eigenständige Funktionen außerhalb einer Klasse implementieren. add_grade soll die eingetragenen Noten in grades speichern; best soll sie daraus auslesen.

Kopieren Sie den gesamten Quellcode von student.py in dieses Feld.

B2: Wetterdaten (21 Punkte)

Sie müssen diese Aufgaben nur lösen, wenn Sie die 9-ECTS-Prüfung schreiben.

In dieser Aufgabe bearbeiten Sie eine Flask-Anwendung, die die aktuelle Temperatur in verschiedenen Städten anzeigt. Für diese Aufgabe stellen wir Ihnen Quellcode zur Verfügung, den Sie vervollständigen müssen. Wechseln Sie dazu im Terminal in das Verzeichnis exam-files/temperature, das sich in Ihrem Homeverzeichnis /home/student befindet.

Damit Code-Änderungen vom Flask-Server automatisch berücksichtigt werden, müssen Sie den Server wie folgt starten:

flask --debug run

Um die Anwendung im Browser zu öffnen, klicken Sie bei gedrückter Strg-Taste auf die URL (Running on …), die Flask nach dem Start anzeigt. Um Flask zu beenden, verwenden Sie die Tastenkombination Strg-C.

Die Anwendung enthält zwei Routen:

  • Die Route index, die nur GET-Requests annimmt, alle gespeicherten Städte einliest, und diese mit Hilfe eines Jinja2-Templates in einer Tabelle ausgibt.
  • Die Route add_city akzeptiert sowohl GET- als auch POST-Requests. Bei einem GET-Request wird ein HTML-Formular generiert, das einen Namen und eine Temperatur entgegennimmt. Bei POST-Requests werden diese Daten aus dem Formular gelesen und an eine Datei angehängt.

Zur Datenspeicherung soll eine JSON-Datei verwendet werden, die folgenden Aufbau hat:

[{"name": "Berlin", "temperature": 8}, {"name": "Hamburg", "temperature": 8}, ...]

B2a (6 Punkte)

Machen Sie sich mit dem vorhandenen Code vertraut. Vervollständigen Sie dann zunächst die index-Route. Rufen Sie dazu zunächst die Funktion read_cities auf, um die Daten einzulesen. Anschließend müssen Sie das Template index.html so anpassen, dass die gelesenen Daten beim Aufruf der index-Route im Browser in der Tabelle ausgegeben werden.

Fügen Sie hier nur den Code der Funktion index ein.
def index(): ...
Fügen Sie hier den gesamten Inhalt Ihres Templates index.html ein.

B2b (5 Punkte)

Erstellen Sie im Template add_city.html nun ein HTML-Formular, das beim Absenden einen POST-Request erzeugt (das Rendern dieses Templates und die Behandlung des POST-Requests erfolgen erst in Teilaufgabe B2c). Das Formular soll zwei input-Felder mit den name-Attributen name und temperature sowie einen Button zum Absenden des Forms enthalten. Eine clientseitige Validierung der Eingaben ist nicht erforderlich.

Fügen Sie hier den gesamten Inhalt Ihres Templates add_city.html ein.

B2c (6 Punkte)

Passen Sie die Funktion add_city nun so an, dass diese nur GET- und POST-Requests akzeptiert.

Wenn die Funktion per GET aufgerufen wird, soll das Template add_city.html gerendert werden (das Template soll in dieser Aufgabe nicht mehr angepasst werden).

Beim Aufruf per POST sollen name und temperature aus dem HTTP-Request extrahiert und der Datei cities.json hinzugefügt werden. Vervollständigen Sie dazu die bereits vorhandene Funktion write_cities und rufen sie sie auf. Nach der Aktualisierung der Datei soll die Liste der Städte (index-Route) angezeigt werden. Eine serverseitige Validierung der Eingaben ist nicht erforderlich.

Fügen Sie hier den gesamten Inhalt der Datei app.py ein.

B2d (4 Punkte)

Zum Abschluss folgen Fragen zu HTTP und CSS.

Welchen HTTP-Status-Code liefert ein Webserver zurück, wenn eine angeforderte Seite nicht gefunden wird?

Geben Sie die Nummer des Status-Codes ein.
z.B. 100

Welchen HTTP-Status-Code liefert ein Webserver zurück, wenn eine Anfrage erfolgreich war?

Geben Sie die Nummer des Status-Codes ein.
z.B. 100

Nehmen Sie an, für ein p-Tag (Klasse: “absatz”, ID: “#absatz1”) werden in einer Webseite an unterschiedlichen Stellen sich widersprechende CSS-Eigenschaften festgelegt, etwa verschiedene Schriftfarben (color). Welche Schriftfarbe wird gemäß der CSS-Spezifizitätsregelung vom Browser angezeigt?

  • A. Die im Tag-Selektor definierte: p { ... }
  • B. Die im Klassen-Selektor definierte: .absatz { ... }
  • C. Die im ID-Selektor definierte: #absatz1 { ... }
  • D. Die im style-Attribut des Absatzes definierte <p style="...">
Antworten Sie mit einem der Buchstaben A, B, C oder D.
Buchstabe

Diese Seite als Markdown: ansehen herunterladen