12. Ingenieurwissenschaftliches Arbeiten¶
In den Ingenieurswissenschaften kommt dem Scientific Computing (d.h. der Numerik) ein immer größerer Stellenwert zu (siehe Abbildung Scientific Computing in Python).
Python und IPython haben wir bereits kennen gelernt. In diesem Kapitel werden wir die Bibliotheken:
- NumPy
- Scipy
- Matplotlib
- Jupyter
genauer kennen lernen.
Einige kennen wahrscheinlich Matlab. Python in Kombination mit NumPy, SciPy, Matplotlib und Pandas kann als vollwertiger Ersatz für MATLAB genutzt werden.
12.1. NumPy¶
NumPy ist ein Akronym für „Numerisches Python“.
Das Modul wird importiert mittels :
import numpy
Wesentlich häufiger findet man jedoch die Abkürzung:
import numpy as np
12.1.1. Erzeugung von Arrays¶
NumPy Arrays können einfach aus Python Listen erzeugt werden:
In [1]: import numpy as np # Import des Moduls
In [2]: a = np.array([2, 4, 5, 9]) # Erzeuge NumPy Array aus Liste
In [3]: a
Out[3]: array([2, 4, 5, 9]) # 'array' zeigt den Objecttyp an
In [4]: type(a) # Objecttyp Abfrage
Out[4]: numpy.ndarray
In [5]: a.dtype # Datentyp Abfrage
Out[5]: dtype('int32')
Alternativ kann man NumPy Funktionen zur Erzeugung verwenden:
In [1]: b = np.zeros((2, 3)) # Erzeuge 2D Array mit "0"
In [2]: b
Out[2]:
array([[0., 0., 0.],
[0., 0., 0.]])
In [3]: c = np.ones((2,3,4), np.int) # 3D Array mit "1", Datentyp Integer
In [4]: c
Out[4]:
array([[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]],
[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]]])
NumPy bietet Funktionen, um Arrays aus Intervallen zu erzeugen:
In [1]: import numpy as np
In [2]: a = np.arange(1,7) # Array mittels Intervall: start, stop
In [3]: a # Objecttyp: numpy.ndarray
Out[3]: array([1, 2, 3, 4, 5, 6])
In [4]: c = np.arange(4, dtype=np.float) # 1D array mit Datentyp Angabe
In [5]: c
Out[5]: array([0., 1., 2., 3.])
Die arange
Funktion sollte nicht mit der Standard Python range
Funktion verwechselt werden:
In [1]: x = range(1,7) # Standard Python range Funktion
In [2]: x
Out[2]: range(1, 7) # .. ist ein Iterator
In [3]: list(x) # Umwandlung in Liste
Out[3]: [1, 2, 3, 4, 5, 6]
12.1.2. Grundlegende Rechenoperationen¶
Einige Grundlegen Rechenoperationen mit NumPy-Arrays lauten:
In [1]: import numpy as np
In [2]: a = np.array( [20,30,40,50] )
In [3]: b = np.arange( 4 )
In [4]: b
Out[4]: array([0, 1, 2, 3])
In [5]: c = a-b
In [6]: c
Out[6]: array([20, 29, 38, 47])
In [7]: b**2
Out[7]: array([0, 1, 4, 9], dtype=int32)
In [8]: 10*np.sin(a)
Out[8]: array([ 9.12945251, -9.88031624, 7.4511316 , -2.62374854])
In [9]: a<35
Out[9]: array([ True, True, False, False])
Anders als in vielen Matrixsprachen arbeitet der Produktoperator *
in NumPy-Arrays Elementweise. Das Matrixprodukt kann mit dem Operator @
(in Python> = 3.5) oder der Funktion dot
ausgeführt werden:
In [10]: A = np.array( [[1,1],
...: [0,1]] )
In [11]: B = np.array( [[2,0],
...: [3,4]] )
In [12]: A * B # Elementweises Produkt
Out[12]:
array([[2, 0],
[0, 4]])
In [13]: A @ B # Matrix Produkt seit Python 3.5
Out[13]:
array([[5, 4],
[3, 4]])
In [14]: A.dot(B) # Altes Matrix "dot" Produkt
Out[14]:
array([[5, 4],
[3, 4]])
12.1.3. Einfache NumPy-Array Funktionen¶
Einfache NumPy-Array Funktion sind:
In [15]: rg = np.random.default_rng() # erzeuge einen Zufallszahlen Generator
In [16]: a = rg.random((2,3))
In [17]: a
Out[17]:
array([[0.1798896 , 0.11681055, 0.93822687],
[0.2420247 , 0.53870043, 0.34058512]])
In [18]: a.sum() # Summe aller Array Elemente
Out[18]: 2.356237274510712
In [19]: a.min() # Minimum
Out[19]: 0.11681055455275102
In [20]: a.max() # Maximum
Out[20]: 0.9382268744684458
In [21]: np.max(a) # Alternative Schreibweise
Out[21]: 0.9382268744684458
In [22]: np.sqrt(a)
Out[22]:
array([[0.42413394, 0.34177559, 0.96862112],
[0.49196005, 0.73396214, 0.58359671]])
In [23]: np.exp(a)
Out[23]:
array([[1.1970852 , 1.12390649, 2.55544627],
[1.27382565, 1.71377823, 1.4057699 ]])
12.1.4. Array Manipulation¶
Typische NumPy-Array Manipulationen sind:
In [1]: import numpy as np
In [2]: a = np.array( [[1.1 , 1.9, 2.5], # beliebiger Array
...: [3.2, 6.7, 1.4 ]])
In [3]: a.shape # 2D Array: 2 Zeilen, 3 Spalten
Out[3]: (2, 3)
In [4]: b = np.floor(a) # (ab)runden
In [5]: b
Out[5]:
array([[1., 1., 2.],
[3., 6., 1.]])
In [6]: b.ravel() # 1D Array "flatten"
Out[6]: array([1., 1., 2., 3., 6., 1.])
In [7]: b.reshape(3,2) # Neue "Shape": 3 Zeilen, 2 Spalten
Out[7]:
array([[1., 1.],
[2., 3.],
[6., 1.]])
In [8]: b.T # Transponierte von b
Out[8]:
array([[1., 3.],
[1., 6.],
[2., 1.]])
12.1.5. Zeiger und Kopien¶
NumPy-Arrays verhalten sich gleich wie veränderbare Datentypen z.B. Listen:
In [1]: import numpy as np
In [2]: a = np.array( [2, 4, 7] ) # beliebiger Array
In [3]: b = a # kein neues Objekt erzeugt
In [4]: b is a # gleiches Objekt = Zeiger
Out[4]: True
In [5]: b[0] = 5 # Modifikation von b ...
In [6]: a # ... aendert auch a!
Out[6]: array([5, 4, 7])
In [7]: c = a.copy() # "Deep Copy"
In [8]: c is a # unterschiedliche Objekte
Out[8]: False
In [9]: c[0] = 9
In [10]: a # Modifikation von a ...
Out[10]: array([5, 4, 7])
In [11]: c # ... aendert c nicht!
Out[11]: array([9, 4, 7])
12.1.6. Lineare Algebra¶
NumPy enthält eine Vielzahl von Funktionen für die Lineare Algebra:
In [1]: import numpy as np
In [2]: A = np.array([[1.0, 2.0], [3.0, 4.0]]) # 2x2 Matrix
In [3]: print(A)
[[1. 2.]
[3. 4.]]
In [4]: A.T # Transponierte
Out[4]:
array([[1., 3.],
[2., 4.]])
In [5]: np.linalg.inv(A) # Inverse
Out[5]:
array([[-2. , 1. ],
[ 1.5, -0.5]])
In [6]: I = np.eye(2) # 2x2 Einheitsmatrix; "eye" fuer "I"
In [7]: I
Out[7]:
array([[1., 0.],
[0., 1.]])
In [8]: R = np.array([[0.0, -1.0], [1.0, 0.0]]) # 2x2 Matrix
In [9]: R @ R # Matrix Produkt
Out[9]:
array([[-1., 0.],
[ 0., -1.]])
In [10]: np.trace(I) # Spur der Matrix
Out[10]: 2.0
In [11]: y = np.array([[5.], [7.]]) # 2x1 Vektor
In [12]: y
Out[12]:
array([[5.],
[7.]])
In [13]: x = np.linalg.solve(A, y) # x = A.y (lin. Gleichungssyst.)
In [14]: x # Loesungsvektor 2x1
Out[14]:
array([[-3.],
[ 4.]])
In [15]: np.linalg.eig(A) # Eigenwertanalyse
Out[15]:
(array([-0.37228132, 5.37228132]),
array([[-0.82456484, -0.41597356],
[ 0.56576746, -0.90937671]]))
12.1.7. Beispiel¶
Gegeben ist folgendes Beispiel aus der Mechanik zum Thema Kräftegleichgewicht.
Gesucht ist die Größe der Kraft im Seil und der Winkel .
Von der Mechanik wissen wir dass die Summe der Kraft null ergeben muss. Der Python
Code zur Lösung des Beispiels mit NumPy lautet (siehe Beispiel beispiel_numpy.py
):
"""
-----------------------------
Beispiel Kraeftegleichgewicht
-----------------------------
Author : D.H.Pahr
Datum : 12.08.2020
-----------------------------
"""
import numpy as np
print(__doc__)
# gegeben: Kraftvektoren
W = np.array( [0.,-80.] )
T = np.array( [40.,0.] )
print("Ergebnis")
print("~~~~~~~~")
# gesucht: F aus Gleichgewicht F+W+T=0
F = -W - T
print(f"F1 = {F[0]} N")
print(f"F2 = {F[1]} N")
# Winkel aus Skalarprodukt: W.(-F) = |W| |-F| cos(alpha)
Wn = np.linalg.norm(W)
Fn = np.linalg.norm(-F)
dotWF = np.dot(W,-F)
alpha = np.arccos( dotWF/Wn/Fn ) * 180./np.pi # rad --> deg!
print(f"alpha = {alpha:.2f} °")
mit der Ausgabe:
-----------------------------
Beispiel Kraeftegleichgewicht
-----------------------------
Author : D.H.Pahr
Datum : 12.08.2020
-----------------------------
Ergebnis
~~~~~~~~
F1 = -40.0 N
F2 = 80.0 N
alpha = 26.57 °
12.2. Matplotlib¶
Das Modul Matplotlib bietet vielseitige Plot-Funktionalitäten. Beispielsweise wurden die Plots in Abbildung Matplotlib Beispiele damit erstellt.
Für die Erstellung eines Plots verwenden wir das Untermodul pyplot
welches Matlab ähnlich aufgebaut ist mittels des Imports:
import matplotlib.pyplot as plt
Einen einfachen Linienplot kann man erzeugen mit:
In [2]: plt.plot([-1, -4.5, 16, 23, 15, 59])
Out[2]: [<matplotlib.lines.Line2D at 0x2c076b5f848>]
und der Plot wir in Spyder rechts oben dargestellt.
Es gibt eine Vielzahl von Möglichkeiten Plots zu erzeugen. Die wichtigsten sind im folgenden Beispiel zusammengestellt (siehe Beispiek matplotlib_plot2.py
).
import matplotlib.pyplot as plt
# Erzeugung von Daten
tage = list(range(1,9))
celsius_min = [19.6, 24.1, 26.7, 28.3, 27.5, 30.5, 32.8, 33.1]
celsius_max = [24.8, 28.9, 31.3, 33.0, 34.9, 35.6, 38.4, 39.2]
# Achsenbeschriftung
plt.xlabel('Tag')
plt.ylabel('Grad Celsius')
# Plots erstellen
plt.plot(tage, celsius_min, "og", label="Min") # Daten, 'o'..Kreis, 'g'..gruen
plt.plot(tage, celsius_min, "g--") # Linie, '--'..strichliert
plt.plot(tage, celsius_max, "b")
plt.plot(tage, celsius_max, "^b", label="Max")
# Optional: Min/Max Werte der Achsen veraendern
xmin, xmax = 0, 10
ymin, ymax = 0, 42
plt.axis([xmin, xmax, ymin, ymax])
# Optional: Legende einfuegen, label in plt.plot Funktion
plt.legend(loc='lower right') # Position der Legende
# Zeige Plot (nicht notwendig in Sypder)
plt.show()
Eine umfangreichere Beschreibung der Funktionalität von Matplotlib findet sich unter: https://www.python-kurs.eu/matplotlib.php
12.3. Scipy¶
SciPy „Scientific Python“ wird oft im gleichen Atemzug wie NumPy genannt. SciPy erweitert die Leistungsfähigkeit von NumPy.
Ein Beispiel ist die Interpolation von Datenpunkten (siehe Beispiel scipy_interpolate.py
):
"""
SciPy Beispiel 1D Interpolation
"""
import numpy as np
from scipy.interpolate import interp1d
# xy Punktwerte z.B Messwerte
x = np.linspace(0, 10, num=11, endpoint=True)
y = np.array( [ 1.,0.99,0.90,0.54,-0.21,-0.93,-0.65,0.67,0.68,-0.91,0.12] )
print(y)
# Interpolation
f = interp1d(x, y)
f2 = interp1d(x, y, kind='cubic')
# Ausgabe
xnew = np.linspace(0, 10, num=41, endpoint=True)
import matplotlib.pyplot as plt
plt.plot(x, y, 'o', xnew, f(xnew), '-', xnew, f2(xnew), '--')
plt.legend(['Messdaten', 'Linear', 'Kubisch'], loc='best')
plt.show()
Im folgenden Bild sieht man die Datenwerte, sowie eine linear und kubische Interpolation.
Ein weiteres Beispiel ist die numerische Integration. Das folgende Integral
kann numerisch gelöst werden mittels (siehe Beispiel scipy_integrate.py
):
"""
SciPy Beispiel Numerische Integration
"""
from scipy.integrate import quad
# zu integrierende Funktion
def integrand(x, a, b):
return a*x**2 + b
# Berechnung des Integrals
a = 2
b = 1
Integral, Fehler = quad(integrand, 0, 1, args=(a,b)) # Fortran QUADPACK
print("Ergebnis =", Integral)
Die Ausgabe des Python Skriptes lautet
Ergebnis = 1.6666666666666667
12.4. Jupyter¶
Jupyter, genauer gesagt Jupyter Notebooks,
- sind Webdokumente für die interaktive Entwicklung und Präsentation von wissenschaftlichen Projekten welche
- Code und Ausgabe in ein Dokument integrieren und
- Visualisierungen, narrativen Text, mathematische Gleichungen und andere Inhalte kombinieren.
12.4.1. Start von Jupyter¶
Anaconda fügt unter Windows dem Startmenü Jupyter hinzu. Das Starten dieser App öffnet eine neue Registerkarte im Standard-Webbrowser.
localhost
deutet darauf dass es sich um eine lokale Seite und keine Webseite handelt.
Mittels Klick auf New
und Python 3
erzeugt man ein neues Notebook.
Es wird automatisch ein File Untitled.ipynb
im Arbeitsverzeichnis (Verzeichnis welches die Registerkarte im Standard-Webbrowser anzeigt) gespeichert. Mit Save as ..
kann man dieses File umbenennen.
12.4.2. Notebook Interface¶
Das Notebook Interface ist ein erweiterter Texteditor welcher neben formatierten Text auch ausführbaren Code enthalten kann.
Diese einzelnen Text- oder Code Blöcke („In [..]“) werden als Cells bezeichnet. Die „Computational Engine“ (hier der Python Interpreter) welche Code verarbeitet wird als Kernel bezeichnet.
Gibt man in die erste Code Cell folgendes ein:
print("Hello Jupyter")
ein und führt diese mit dem Run
Knopf oder Ctrl + Enter
Shortcut aus, erhält man wie in der Abbildung gezeigt eine Ausgabe.
Wichtige Befehle bzw. Shortcuts eines Notebooks sind:
- Eine neue Zelle erzeugt man mit dem Knopf
+
oderA
- Alle Tastatur Shortcuts erhält man durch klicken auf den Tastatur Knopf (rechts oben).
- Zwischen Edit und Command Mode wechselt man mit
Esc
(blauer Zellrahmen links) undEnter
(grüner Zellrahmen).
Im Command Mode (blauer Zellrahmen links) kann man:
- mit
Rauf
undRunter
Tasten zwischen Zellen wechseln- mit
A
oderB
darunter oder darüber Zellen erzeugenM
wechselt zu einer Markdown (Text) Zelle.Y
wechselt zu einer Code Zelle.- zweimal
D
löscht die aktive Zelle.Z
macht das Löschen rückgängig- mit
Shift
+ halten undRauf
/Runter
Tasten kann man mehrere Zellen markieren,Shift
+M
fügt markierte Zellen zusammen
12.4.3. Markdown¶
Im Edit Mode lässt sich einfach ein formatierter Text erzeugen. Gibt man in eine Markdown Zelle folgenden Text ein:
# Überschrift 1
## Überschrift 2
Normaler Text mit **fett** und *italic* Text.
Ein neuer Paragraph wird durch eine leere Zeile erzeugt.
* Manchmal braucht man Aufzählungen
* Mit mehreren Punkten.
oder
1. nummerierte Listen
2. wie hier dargestellt.
[Es ist möglich Hyperlinks einzufügen](https://www.example.com)
Inline code wird mittels einfacher Hochkomma erzeugt z.B. `foo()`, und Code Blöcke mit dreifachen Hochkomma:
```
bar()
```
Auch Bilder sind einfach einzufügen:
![Titel](code.png)
Formel kann man mittels $\LaTeX$ Syntax einfügen:
$$e^{i\pi} + 1 = 0$$
Tabellen einfach so:
| Das | ist |
|------|---------|
| eine | Tabelle |
erhält man nach ausführen der Zelle mit Ctrl + Enter
folgendes Ergebnis:
und kann damit schön formatierte technische Berichte erzeugen.
12.4.4. Kernel¶
Hinter jedem Notebook läuft ein Kernel, bei uns Python 3. Beispielsweise kann man in einer Zelle folgendes definieren:
import numpy as np
def wurzel(x):
return x ** 0.5
und danach diese Funktion verwenden d.h.:
Dabei gibt es folgendes zu beachten:
- Ändert man Werte in einer Zelle, muss man diese mit
Ctrl + Enter
neu berechnen. - Möchte man alle Zellen neu berechnen, muss man
Restart & Run All
ausführen!
12.5. Jupyter Beispiel¶
Das Beispiel findet sich unter Jupyter_Beispiel.ipynb
und demonstriert eine ingenieurwissenschaftliche Anwendung aus dem Bereich der Physik.
Es wird dabei die Flugbahn eines Projektils untersucht und gleichzeitig ein Berechnungsbericht erstellt. Das folgende Bild zeigt ein Ergebnis dieser Untersuchungen.
12.6. Übungsbeispiele¶
Aufgabe 12.1
In dieser Aufgabe soll die Kraft-Verschiebungs-Kurve einer Probe aus dem Bereich des Biomedical-Engineerings mit Hilfe von Python ausgewertet werden. Im anschließenden Bild sehen Sie die getestete Probe, sowie die zugehörige Kraft-Verschiebungs-Kurve, die mit einer Materialprüfmaschine gemessen wurde.
Die Daten für die Verschiebung in mm und Kraft in Newton sind als Listen gegeben:
# Verschiebung in mm
verschiebung = [ 0. , 0.09810706, 0.19972906, 0.30051106, 0.40117306,
0.50129506, 0.60165706, 0.70189806, 0.80202006, 0.90190206,
1.00214806, 1.10196806, 1.20214806, 1.30184806, 1.40196806,
1.50238806, 1.60227806]
# Kraft in Newton
kraft = [ 10. , 84.3959, 167.649 , 238.241 , 297.654 , 350.267 ,
397.334 , 440.565 , 479.436 , 511.907 , 543.733 , 574.285 ,
601.333 , 618.475 , 585.185 , 510.965 , 498.479 ]
Ziel ist es, die Belastung in kg über die Verschiebung grafisch darzustellen, sowie die maximale Belastung und die Belastung der Probe bei einer Verschiebung von 0.35 mm zu ermitteln.
Gehen Sie dafür wie folgt vor:
Wandeln Sie die Listen
verschiebung
undkraft
in NumPy-Arrays um.Ziehen Sie die Vorlast von 10 Newton von allen Einträgen des
kraft
arrays ab. Rechnen Sie anschließend die Belastung von Newton in kg um, indem Sie alle Einträge mit 9.81 (m/s^2) dividieren. Daskraft
array sollte dann wie folgt aussehen:In [1]: print(kraft_array_kg) [ 0. 7.58367992 16.07023445 23.26615698 29.32252803 34.68572885 39.48358818 43.89041794 47.85280326 51.16279307 54.40703364 57.52140673 60.27859327 62.02599388 58.63251784 51.0667686 49.79398573]
Stellen Sie den Verlauf der Belastung in kg über die Verschiebung in mm dar. Verwenden Sie dafür die
plot
Funktion der Bibliothek matplotlib (siehe Kapitel 12.2. im Skriptum). Ihr Ergebnis sollte dann wie folgt aussehen:
Berechnen Sie abschließend die maximale Belastung der Probe in kg sowie die Belastung bei einer Verschiebung von 0.35 mm. Um die Kraft bei einer bestimmten Verschiebung zu berechnen, verwenden Sie
interp1d
von Scipy (siehe Kapitel 12.3. Skriptum). Geben Sie dann das Ergebnis perprint
Befehl aus. Die Ausgabe sollte dann in etwa wie folgt aussehen:Maximale Belastung: 62.03 kg Belastung bei 0.35mm: 26.24 kg
12.7. Übungsbeispiel für Kolloquium¶
Das folgende Beispiel ist aufbauend und kapitelübergreifend. Es soll Ihnen beim Üben bzw. bei der Vorbereitung für das Kolloquium helfen. Es ist allerdings nicht repräsentativ für Art, Umfang oder Schwierigkeitsgrad der Beispiele des Kolloquiums!
Aufgabe K.1
- Schreiben Sie eine Klasse
Haus
. Der Konstruktor bekommt die ArgumenteAdresse
(string),Hoehe
(float-Zahl) undEtagenanzahl
(integer-Zahl) übergeben und soll sie als Klassenattribute initialiseren. Die Adresse soll als privates Attribut gespeichert werden. - Schreiben Sie eine get-Methode, mit der die Adresse abgefragt werden kann.
- Die Klasse soll eine überladene print-Funktion enthalten, sodass mittels print die Adresse, die Höhe und die Etagenanzahl ausgegeben werden.
- Ergänzen Sie Ihre Klasse
Haus
durch ein statisches AttributAnzahl_Haus
.Anzahl_Haus
soll immer die Anzahl, der jeweils bisher im gesamten Skript erzeugten Instanzen der Klasse zählen. - Überladen Sie zusätzlich den
kleiner
-Vergleichsoperator (__lt__
). Ein Haus soll als kleiner als ein zweites Haus angesehen werden, wenn es niedriger (Höhe geringer) ist.
Überprüfen Sie Ihre Implementierung mit geeignetem Input im Abschnitt ‚main‘. z.B.:
In [1]: Haus1 = Haus("Kirchengasse 3",16.27,5)
In [2]: print(Haus1)
Adresse: Kirchengasse 3, Hoehe: 16.27, Etagenanzahl: 5
In [3]: print(Haus1.Get_Adresse())
Kirchengasse 3
In [4]: print(Haus1.Anzahl_Haus)
1
In [5]: Haus2 = Haus("Kellergasse 1",18.3,6)
In [6]: print(Haus1 < Haus2)
True
In [7]: print(Haus1.Anzahl_Haus)
2
Aufgabe K.2
- Schreiben Sie eine Klasse
Wolkenkratzer
, die von der KlasseHaus
abgeleitet wird. Sie soll zusätzlich zu den Attributen vonHaus
noch das AttributName
(string) haben. Wolkenkratzer sind meistens über ihren Namen und nicht über ihre Adresse bekannt (z.B. DC-Tower, Donauturm, Empire-state-building,…). - Überladen Sie für die Klasse
Wolkenkratzer
die print-Funktion, sodass ein String, der alle Attribute vonWolkenkratzer
enthält, mit print ausgegeben werden kann. - Ergänzen Sie Ihre Klasse
Wolkenkratzer
durch ein statisches AttributAnzahl_Wolkenkratzer
.Anzahl_Wolkenkratzer
soll immer die Anzahl, der jeweils bisher im gesamten Skript erzeugten Instanzen der Klasse zählen.
z.B.:
In [1]: Wolkenkratzer1 = Wolkenkratzer("Donau-City-Strasse 7",220.3,60,"DC-Tower")
In [2]: print(Wolkenkratzer1)
Adresse: Donau-City-Strasse 7, Hoehe: 220.3, Etagenanzahl: 60, Name: DC-Tower
Aufgabe K.3
Schreiben Sie in einem neuen python-File eine Funktion Read_Haeuser
(soll keine Klassen-Methode sein!). Dieser Funktion wird der Name einer Textdatei übergeben, die zeilenweise mehrere Häuser enthält. Eine Beispieldatei „Input_Haeuser.txt“ ist in TUWEL verfügbar:
Parkring 18, 18.2, 5
Donau-City-Strasse 7, 220.3, 60, DC-Tower
Handelskai 94-96, 171.5, 50, Millenium-Tower
Kirchengasse 3, 16.27, 5
- Importieren Sie Ihre Klassen
Haus
undWolkenkratzer
. - Die Funktion soll zunächst mit Hilfe einer Ausnahmebehandlung überprüfen, ob das File geöffnet werden kann:
- Falls nein, soll die Funktion die Art des Fehlers als string zurück geben.
- Falls ja, soll die Textdatei eingelesen werden.
- Die Textdatei enthält mehrere Zeilen, wobei jede Zeile ein Haus bzw. einen Wolkenkratzer definiert:
- Ein Haus wird in der Textdatei wie folgt definiert: Adresse, Höhe, Etagenanzahl
- Ein Wolkenkratzer wird in der Textdatei wie folgt definiert: Adresse, Höhe, Etagenanzahl, Name
Lesen Sie das File ein und erstellen Sie eine Liste aus Haus- und Wolkenkratzer-Objekten, wobei jede Zeile des Files zur Initialisierung eines Haus- oder eines Wolkenkratzer-Objektes verwendet werden soll.
- Danach soll diese Hausliste mit Hilfe des überladenen
kleiner
-Operators aufsteigend sortiert werden, d.h. nach der Höhe sortiert werden. Die sortierte Liste der Häuser soll zurück gegeben werden.
Hinweis
- Die Python-Funktionen
sort
undsorted
verwenden den kleiner-Operator zum Sortieren. - Damit der überladene print-Operator zum Ausgeben der Liste von Häusern und Wolkenkratzern verwendet wird, muss eine Schleife über die Liste verwendet werden.
- Sie können auch testen, ob Ihr Skript noch funktioniert wenn Sie versuchen eine nicht existierende Datei oder die Datei „Input_Haueser2.txt“ aus TUWEL einzulesen.
Beispiel für Nutzung der Funktion und Ausgabe:
In [1]: Gebaeude_Liste = Read_Haeuser("Input_Haeuser.txt")
In [2]: for i in Gebaeude_Liste:
...: print(i)
Adresse: Kirchengasse 3, Hoehe: 16.27, Etagenanzahl: 5
Adresse: Parkring 18, Hoehe: 18.2, Etagenanzahl: 5
Adresse: Handelskai 94-96, Hoehe: 171.5, Etagenanzahl: 50, Name: Millenium-Tower
Adresse: Donau-City-Strasse 7, Hoehe: 220.3, Etagenanzahl: 60, Name: DC-Tower