Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
ss16:physiksimulation_doc_python [2016/08/13 16:49] markumnus Visualizer hinzugefügt |
ss16:physiksimulation_doc_python [2016/08/14 22:37] (aktuell) markumnus |
||
---|---|---|---|
Zeile 3: | Zeile 3: | ||
</a></center></html> | </a></center></html> | ||
- | <- [[ss16:Physiksimulation_doc_components|zurück zur Liste der Komponenten]] | + | **[[ss16:Physiksimulation|Physiksimulation]]/[[ss16:Physiksimulation_Doc_Main|Dokumentation]]/[[ss16:Physiksimulation_doc_components|Komponenten]]/** |
- | + | =====Python-Teil===== | |
- | =====Physiksimulation | Python-Teil===== | + | |
====Programmstruktur==== | ====Programmstruktur==== | ||
{{ :ss16:physiksimulation_struktur2107.png?nolink |}} | {{ :ss16:physiksimulation_struktur2107.png?nolink |}} | ||
+ | |||
+ | |||
+ | ====Parser.py==== | ||
+ | In der Ergebnis-Textdatei sind einzelne Zeitschritte mit **//|//** getrennt, Objekte mit **//;//** und die Koordinaten der Objekte mit **//,//**. Die //parse()//-Funktion macht aus einem String nach diesem Muster eine Liste aus Tupeln mit den Positionsdaten. | ||
+ | <code Python> | ||
+ | def parse (string): | ||
+ | """ | ||
+ | Nimmt einen String mit Object-Positionsdaten entgegen und | ||
+ | gibt eine Liste aus Tupeln mit Positionsdaten zurueck. | ||
+ | Beispiel: | ||
+ | "0.0037, 0.0024, -0.0001;-0.315, -0.9603, -0.0001;-0.3129, -0.9592, -0.0002;|" -> [(0.0037, 0.0024, -0.0001), (-0.315, -0.9603, -0.0001), (-0.3129, -0.9592, -0.0002)] | ||
+ | """ | ||
+ | result = [] | ||
+ | |||
+ | # aufteilen | ||
+ | objects = string.split(";") | ||
+ | |||
+ | # bereinigen | ||
+ | for o in objects: | ||
+ | if o == "": | ||
+ | objects.remove(o) | ||
+ | |||
+ | # Koordinaten extrahieren | ||
+ | for o in objects: | ||
+ | coords = o.split(",") | ||
+ | |||
+ | # Whitespace entfernen | ||
+ | for i, c in enumerate (coords): | ||
+ | coords[i] = c.strip() | ||
+ | |||
+ | # in Floats umwandeln | ||
+ | try: | ||
+ | coords = map (float, coords) | ||
+ | except ValueError: | ||
+ | print "Konnte", coords, "nicht umwandeln." | ||
+ | |||
+ | result.append (tuple(coords)) | ||
+ | |||
+ | return result | ||
+ | </code> | ||
+ | |||
+ | |||
+ | ====Reader.py==== | ||
+ | In der Datei Reader.py wird die Klasse Reader definiert. Wir haben uns hier für eine Klasse entschieden (anstatt nur einer Funktion wie beim Parser), da wir die //%%__getitem__()%%//-Funktion nutzen wollten, um die Ergebnis-Datei wie eine Liste indizierbar zu machen. Mit reader[time_step] kann man bequem auf die Positionsdaten des jeweiligen Zeitschritts zugreifen. | ||
+ | <code Python> | ||
+ | ####################################### | ||
+ | # IMPORTE | ||
+ | ####################################### | ||
+ | import Parser | ||
+ | |||
+ | class Reader: | ||
+ | |||
+ | time_steps = [] | ||
+ | |||
+ | def __init__ (self, filename): | ||
+ | # Deklarationen | ||
+ | self.FILENAME = filename | ||
+ | |||
+ | # File lesen | ||
+ | with open (self.FILENAME) as f: | ||
+ | file_cont = f.read() | ||
+ | |||
+ | # Zeitschritte voneinander trennen | | ||
+ | self.time_steps = file_cont.split('|') | ||
+ | | ||
+ | # letztes, leeres Element entfernen | ||
+ | self.time_steps.pop() | ||
+ | |||
+ | |||
+ | def __getitem__ (self, key): | ||
+ | """ | ||
+ | Indiziert einen Zeitschritt und gibt die Koordinaten der Objects zu diesem Zeitschritt zurueck. | ||
+ | """ | ||
+ | return Parser.parse(self.time_steps[key]) | ||
+ | | ||
+ | | ||
+ | def __len__ (self): | ||
+ | """ | ||
+ | Gibt Anzahl der verfuegbaren Zeitschritte zurueck. | ||
+ | """ | ||
+ | return len (self.time_steps) | ||
+ | | ||
+ | def __str__ (self): | ||
+ | s = "Reader auf \"" + self.FILENAME + "\" mit " + str(len(self)) + " Zeitschritten." | ||
+ | return s | ||
+ | |||
+ | def __repr__(self): | ||
+ | return self.__str__() | ||
+ | |||
+ | </code> | ||
====Visualizer.py==== | ====Visualizer.py==== | ||
Diese Datei deklariert die Klasse //Visualizer//. Im Konstruktor nimmt sie eine Liste mit Objekten entgegen, die visualisiert werden sollen. Außerdem wird die //scene// für Visual initialisiert.\\ | Diese Datei deklariert die Klasse //Visualizer//. Im Konstruktor nimmt sie eine Liste mit Objekten entgegen, die visualisiert werden sollen. Außerdem wird die //scene// für Visual initialisiert.\\ | ||
- | Mit der Methode //run()// wird die Animation gestartet. Die benötigten Positionsdaten werden mithilfe eines [[abc|Readers]] ausgelesen. | + | Mit der Methode //run()// wird die Animation gestartet. Die benötigten Positionsdaten werden mithilfe des Readers ausgelesen. |
<code Python> | <code Python> | ||
from visual import * | from visual import * | ||
Zeile 86: | Zeile 175: | ||
self.w.show() | self.w.show() | ||
</code> | </code> | ||
- | ... welches wiederum Buttons hat, die z.B. beim Klicken auf "OK" ein Objekt erstellen und es zunächst per [[abc|Interface]] im [[abc|Universe]] speichern: | + | ... welches wiederum Buttons hat, die z.B. beim Klicken auf "OK" ein Objekt erstellen und es zunächst per [[ss16:Physiksimulation_Doc_cpp#Interface.cpp|Interface]] im [[ss16:Physiksimulation_Doc_cpp#Universe.cpp|Universe]] speichern: |
<code Python> | <code Python> | ||
def output0(self): | def output0(self): |