Coding for KidsCoding for Kids
Kreative LevelHerausforderungenLehrerhandbuch
Für Funktionen abstimmen
Fortgeschrittener Python-Entwicklungskurs
Kapitel
>
Stufe

Serialisierungsmodule
Strukturmodul

Zielsetzung

Richte die endgültige Datenaufteilung für das neue landwirtschaftliche Gelände mithilfe des struct-Moduls ein.

Am Ende der Straße befindet sich eine Tankstelle, die das neue landwirtschaftliche Gelände verwaltet, das bereits gebaut und bepflanzt ist. Hier werden wir die Daten der bereits gepflanzten Feldfrüchte sowie den prognostizierten Ertrag des Geländes inspizieren und verarbeiten. Wie in den anderen Abschnitten dieses Kapitels arbeiten wir mit der Serialisierung und Deserialisierung von Daten und führen ein letztes Modul ein, das struct-Modul.

Das struct-Modul bietet eine Reihe von Serialisierungsfunktionen, die Daten im Binärformat packen. Im Gegensatz zu den anderen verwendeten Modulen hast du jedoch eine größere Kontrolle darüber, wie die Daten strukturiert werden, sowohl während der Serialisierung als auch bei der späteren Deserialisierung, was es vielseitiger macht als andere Module. Verwende import struct, um auf die folgenden Funktionen zuzugreifen, die wir zur Verarbeitung der Daten verwenden:

  • struct.calcsize(): Bestimmt, wie viele Bytes ein gegebener Format-String belegt. Es nimmt ein (1) Argument, nämlich das Format, dessen Byte-Größe du überprüfen möchtest. Die Formate, die wir verwenden werden, sind:
    • integer: dargestellt als 'i' ist das Format für Daten, die als ganze Zahlen repräsentiert werden
    • float: dargestellt als 'f' ist das Format für Daten, die als Dezimalzahlen repräsentiert werden
    • double: dargestellt als 'd' ist das Format für Daten, die als komplexere Dezimalzahlen repräsentiert werden, wenn das float-Format nicht ausreicht.
  • struct.pack(): Serialisiert Daten in Binärform, gepackt in ein Format deiner Wahl. Du kannst zwei (2) oder mehr Argumente übergeben, nämlich das Format, das du verwenden möchtest, und die Werte, die du serialisieren möchtest. Die Formate sind die zuvor genannten, und du musst sie entsprechend der Anzahl der hinzugefügten Argumente angeben.
  • struct.unpack(): Deserialisiert gepackte Binärdaten, nimmt zwei (2) Argumente: das Format, in dem es verglichen werden muss mit dem Format, in dem die Daten serialisiert wurden, und als zweites die Daten, die serialisiert wurden.
  • struct.iter_unpack(): Deserialisiert gepackte Binärdaten, funktioniert genauso wie struct.unpack(), iteriert jedoch durch jeden Datenblock einzeln mithilfe einer Schleife.
  • struct.pack_into(): Eine erweiterte Version von struct.pack(), nimmt vier (4) Argumente entgegen, nämlich das Format, das du verwenden möchtest, den Datenpuffer, in den du die Daten einfügen möchtest, die Position im Puffer, an der die Daten platziert werden sollen, und schließlich die zu packenden Daten.
  • struct.unpack_from(): Eine erweiterte Version von struct.unpack(), nimmt drei (3) Argumente entgegen: das Format, das du verwenden möchtest, den Datenpuffer, den du entpacken möchtest, und zuletzt die Position im Puffer, von der du entpacken möchtest. Dies ermöglicht es dir, spezifische Teile der Daten zu entpacken.

Gehe zum Licht X Markierung an der Tankstelle und richte dich zum Schreibtisch, erstelle drei (3) Variablen mit den Namen: integer , float und double. Wir verwenden diese, um die Größe in Bytes jedes Formats mithilfe der Funktion struct.calcsize() zu überprüfen. Für die Variable integer verwendest du die Funktion mit 'i' als Argument, für die Variable float verwendest du die Funktion mit 'f' als Argument und schließlich für die Variable double die Funktion mit 'd' als Argument. Beispiel: integer = struct.calcsize('i') . Füge die drei (3) Variablen der vorgegebenen write() Funktion hinzu.

Gehe zur goldenen X Markierung und verwende die Funktion read(), um Daten über das neue landwirtschaftliche Gelände zu sammeln, notiere dir die Datenpunkte und das Format für die zukünftige Verwendung, nämlich: Ressourcen , Größe und Schätzung. Sobald du die Daten notiert hast, gehe zum Licht X Markierung über den blauen Teppich und erstelle eine Variable namens blue_data .

Speichere in der Variable blue_data den Wert der Funktion struct.pack(), wobei als Argumente das Format und die Werte verwendet werden, die du zuvor notiert hast. Beim Schreiben des Formats musst du die Format-Typen zu einer einzigen Einheit "packen". Beispiel: Das Integer-Format wird, wie oben beschrieben, durch 'i' dargestellt; wenn du drei Integer-Datentypen hinzufügst, schreibst du sie als 'iii' . Ebenso, wenn du einen Integer, einen Float und einen Double hinzufügst, wäre das Format 'ifd' . Die Daten werden als einzelne Argumente hinzugefügt. Hier ein Gesamtbeispiel:

data_1 = 8 # ist ein Integer data_2 = 2.25 # ist ein Float data_3 = 900.702938103 # ist ein Double blue_data = struct.pack('ifd', data_1, data_2, data_3)

Die Funktion struct.pack() bietet viel Flexibilität, da du festlegen kannst, wie du die Daten formatieren möchtest, und mehrere Datenpunkte gleichzeitig serialisieren kannst, ganz nach deinem Ermessen. Füge die zuvor erfassten Daten anhand des obigen Beispiels als Grundlage hinzu. Verwende die Funktion display() mit blue_data als Argument, um die gepackten Daten anzuzeigen.

Gehe zur dunklen X Markierung über den blauen Teppich und richte dich zum Terminal, erstelle eine Variable namens blue_unpack und speichere den Wert der Funktion struct.unpack(), indem du das gleiche Format, das zum Packen der Daten verwendet wurde, und die Variable blue_data als Argumente übergibst. Das Format wird in derselben Weise geschrieben wie bei der Funktion struct.pack(), sodass du die Daten in derselben Weise deserialisieren kannst, wie du sie ursprünglich serialisiert hast. Verwende die Funktion write() mit blue_unpack als Argument, um die zuvor gepackten Daten zu überprüfen.

Am selben Ort verwenden wir auch die Funktion struct.iter_unpack(). Diese nimmt genau die gleichen Argumente wie struct.unpack(), ist jedoch in Form einer for-Schleife gestaltet. Dadurch können wir über die Daten iterieren, anstatt sie einfach alle auszugeben. Die Funktion wird wie folgt kodiert:

for values in struct.iter_unpack(-insert value-, -insert value-): player.speak(values)

Wir werden die Funktion speak() verwenden, um die Werte anzuzeigen. Für die fehlenden Argumente in der Funktion struct.iter_unpack() gibst du dieselben wie zuvor bei struct.unpack() an, da es sich um Variationen der gleichen Funktion handelt.

Gehe zur goldenen X Markierung über den roten Teppich und richte dich zum Schreibtisch. Verwende die Funktion read(), um die Mengen der Feldfrüchte zu überprüfen. Notiere dir alle Mengen und das jeweilige Format für jede Feldfrucht. Gehe zum Licht X Markierung über den roten Teppich und erstelle ein Objekt namens buffer und füge den Wert bytearray(16) hinzu. Dies ist eine Sammlung von Bytes, die wir ansprechen können, bevor wir sie befüllen. Für unsere Zwecke wirkt es wie ein Datenspeicher, in dem du die Daten manuell ablegen kannst. Die Zahl 16 als Argument gibt an, wie viele Bytes im buffer-Objekt gespeichert werden können.

Verwende die Funktion struct.pack_into(), um das von dir erstellte buffer-Objekt zu befüllen. Es ist nicht notwendig, eine Variable zu erstellen, um den Funktionswert zu speichern, da die Funktion die Werte direkt in das buffer-Objekt einfügt. Wir werden die Funktion für jeden der zuvor notierten Werte verwenden und die entsprechenden Argumente übergeben.

Beispielsweise, für den ersten angegebenen Erntewert bekommst du das Format, die Byte-Position und die Menge. Füge als ersten Parameter das Format hinzu, als zweiten Parameter den Ort, an dem die Bytes serialisiert werden sollen, in diesem Fall buffer. Setze als dritten Parameter die Position, an der der Wert im buffer hinzugefügt werden soll; das Format bestimmt die beanspruchten Bytes, sodass du auf Daten packen musst, die zuvor nicht belegt waren. Füge zuletzt den Wert hinzu, den du serialisieren und in das buffer-Objekt packen möchtest.

struct.pack_into('i', buffer, 0, 82)

Das buffer-Objekt verfügt, wie bereits erwähnt, über 16 Bytes. Im obigen Codebeispiel hat das Integer-Format 4 Bytes und wird an Position 0 eingefügt. Das bedeutet, dass nach dem Einfügen der Daten im buffer noch nur 12 Bytes übrig sind, wobei die Positionen 0-3 von dem eingefügten Wert, in diesem Fall 82, belegt sind. Wiederhole dies für alle zuvor notierten Ernte-Datenpunkte; insgesamt gibt es drei (3). Verwende die Funktion display() und füge buffer hinzu, um die serialisierten Daten anzuzeigen.

Gehe zur dunklen X Markierung über den roten Teppich und richte dich zum Terminal. Hier werden wir die Daten deserialisieren, um den Inhalt zu überprüfen und eine korrekte Speicherung sicherzustellen. Erstelle drei Variablen mit den Namen: lettuce , carrots und melons. Wir werden die Datenpunkte einzeln entpacken. Für jede Variable speicherst du den Wert von struct.unpack_from() und übergibst als Argumente dieselben Daten, die du zum Packen der Daten notiert hast. Setze als ersten Parameter das Format, als zweiten den buffer, also den Ort, von dem entpackt werden soll, und zuletzt die Position im buffer, von der entpackt werden soll. Beispiel:

lettuce = struct.unpack_from('i', buffer, 0)

Diese Daten entsprechen dem zuvor gepackten Beispiel, das entpackt wird. Mache dasselbe für die beiden anderen Variablen und füge lettuce , carrots und melons der vorgegebenen write()-Funktion hinzu, um das Level abzuschließen.

Codebuch