Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Showing
with 26577 additions and 1916 deletions
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
%% Cell type:markdown id: tags:
# Seminar Problemorientierte Programmierung
## 3 Extra: Reguläre Ausdrücke
Dieses Kapitel taucht nicht im englischen Python-Kurs auf und wird separat gepflegt.
In der Praxis können wir reguläre Ausdrücke nutzen, um in Texten zu suchen und Muster zu entdecken. Python bietet uns im `re`-Modul (re = Regular Expression = Regulärer Ausdruck) viele Funktionen an, um mit regulären Ausdrücken zu arbeiten.
Es gibt dabei zwei "Dimensionen" an denen wir uns "entlanghangeln" müssen: die Funktionen, die vom `re`-Modul bereitgestellt werden und die regulären Ausdrücke selber, die komplex werden können. Wir beginnen zunächst mit nur einer Funktion und werden Stück für Stück komplexere Ausdrücke kennenlernen. Danach schauen wir uns weitere Funktionen an.
### Ihre Lernziele
Beschreiben Sie in 2-3 Stichpunkten kurz was Sie im Seminar heute lernen wollen. Klicken Sie dazu doppelt auf diesen Text und bearbeiten Sie dann den Text:
-
-
-
### Exkurs: Was mir an Python gefällt
In einer Datei alle E-Mail-Adressen extrahieren geht recht einfach:
In ihrem Verzeichnis sollte eine Datei `test.txt` liegen. Öffnen Sie diese in einem Texteditor Ihrer Wahl. Schauen Sie jetzt, wie leicht man mit dem Modul `re` in Python E-Mail-Adressen extrahieren kann:
%% Cell type:code id: tags:
```
import re
def find_in_file(pattern, file):
reg_pattern = re.compile(pattern)
for line in file:
for found in reg_pattern.findall(line):
print(found[0])
find_in_file(r"([a-zA-Z0-9-!#$%&'*+-/=?^_`{|}~]+@([A-Za-z0-9-]+\.)+[a-zA-Z]{2,})", open("test.txt", "rt"))
```
%% Cell type:markdown id: tags:
### 3.1 Einfache Suche
Wir können mit der Funktion `findall` alle Teilzeichenketten in einer Zeichenkette finden, die auf ein gegebenes Muster (in Form eines regulären Ausdrucks) passen. Die Funktion erwartet zwei Argumente: einen regulären Ausdruck und die Zeichenkette, die durchsucht werden soll:
%% Cell type:code id: tags:
```
import re
re.findall(r'f[a-z]*', 'which foot or hand fell fastest')
```
%% Cell type:markdown id: tags:
1. In der ersten Zeile wird das `re`-Modul importiert. Das muss einmal am Anfang unseres Programms passieren. Hier im Jupyter-Notebook reicht es, wenn das Modul in einem Block importiert wird - sobald der Block ausgeführt wurde, kann es in allen folgenden Blöcken verwendet werden.
2. In der nächsten Zeile wird - mittels der Punkt-Notation - die `findall`-Funktion im `re`-Modul aufgerufen.
3. Der Funktion werden zwei Argumente übergeben: `r'f[a-z]*'` und `'which foot or hand fell fastest'`.
4. Das erste Argument ist ein regulärer Ausdruck. Reguläre Ausdrücke werden in Hochkommata `''` eingeschlossen und beginnen mit einem `r`.
5. Das heißt, der eigentliche reguläre Ausdruck lautet `f[a-z]*`. Dieser Ausdruck beschreibt Zeichenketten, die mit einem `f` beginnen und von beliebig vielen - auch 0! - (`*`) Kleinbuchstaben (`[a-z]`) gefolgt werden. Dabei beschreibt der Ausdruck `[a-z]` in eckigen Klammern ein Zeichen, welches die Werte `a` bis `z` haben darf, das `*` dahinter besagt, dass dieses Zeichen beliebig oft wiederholt werden darf.
6. Das zweite Argument (`'which foot or hand fell fastest'`) ist die Zeichenkette, in der wir nach Teilzeichenketten suchen, die auf den übergebenen regulären Ausdruck passen.
Das Ergebnis des Aufrufs von `findall` ist eine Liste der Teilzeichenketten, die auf das Muster passen - in unserem Beispiel sind das die Zeichenketten `foot`, `fell` und `fastest`.
Probieren Sie es hier selber aus:
%% Cell type:code id: tags:
```
regaus = r'f[a-z]*'
text = input("Geben Sie eine Zeichenkette zum Testen ein:")
ergebnis = re.findall(regaus, text)
if ergebnis:
print("Es wurden folgende Teilzeichenketten erkannt:", ergebnis)
else:
print("Leider wurde nichts erkannt, probieren Sie es noch einmal.")
```
%% Cell type:markdown id: tags:
Ändern Sie den regulären Ausdruck im folgenden Beispiel, so dass alle Wörter, die mit einem `b` beginnen ausgegeben werden:
%% Cell type:code id: tags:
```
re.findall(r'b', 'Wir bauten und bohrten bis das Haus fertig war.')
```
%% Cell type:markdown id: tags:
Die Ausgabe sollte so aussehen:
```
['bauten', 'bohrten', 'bis']
```
Ändern Sie den regulären Ausdruck, so dass jetzt nur Wörter ausgegeben werden, die mit einem `b` beginnen und mit einem `n` enden. Die Ausgabe sollte dann so aussehen:
```
['bauten', 'bohrten']
```
Welche Probleme sind bei Ihren Versuchen aufgetreten?
-
-
%% Cell type:markdown id: tags:
### 3.2 Schritt für Schritt: ein beliebiges Zeichen
Der Punkt `.` steht für ein beliebiges Zeichen:
%% Cell type:code id: tags:
```
re.findall(r'a.', "Am Anfang aßen wir alle Manna und Kartoffeln")
```
%% Cell type:markdown id: tags:
Im Satz `Am Anfang aßen wir alle Kartoffeln.` gibt es genau sechs Vorkommen von einem kleinen `a` mit einem Zeichen dahinter. Wie wir sehen, wird auch das `a` am Ende von `Manna`, welches von einem Leerzeichen gefolgt ist, erkannt. Das liegt daran, dass der Punkt für wirklich jedes Zeichen (auch das Leerzeichen) steht. Die zwei Zeichenketten `Am` und `An` werden nicht erkannt, da sie ein großes `A` enthalten, wir aber nach einem kleinen gesucht haben.
%% Cell type:markdown id: tags:
### 3.3 Und weiter
Sie kennen jetzt eine Funktion, um reguläre Ausdrücke in Python anzuwenden und damit Texte zu durchsuchen. Weitere Funktionen ermöglichen die Extraktion und das Ersetzen von Teilzeichenketten in Texten. Bevor wir diese Funktionen kennenlernen, ist es praktisch, mit regulären Ausdrücken vertraut zu werden. Eine sehr gute interaktive Übungsseite dazu finden Sie [hier](https://regexone.com/lesson/introduction_abcs). Arbeiten Sie diese Seite gemeinsam Schritt für Schritt durch. Schrecken Sie nicht vor dem englischen Text zurück - ich helfe Ihnen bei Fragen gerne weiter.
Es gibt noch viele andere gute Tutorials zu regulären Ausdrücken, z.B. [hier](https://ryanstutorials.net/regular-expressions-tutorial/) oder [hier](https://www.python-kurs.eu/re.php). Sie können auch eine dieser Anleitungen durcharbeiten, wenn Sie damit besser zurechtkommen.
%% Cell type:markdown id: tags:
### 3.4 weitere nützliche Funktionen des `re`-Moduls
Sie haben in den Tutorials einige regulären Ausdrücke kennengelernt. Nun können wir weitere Funktionen des `re`-Moduls benutzen. Im Folgenden werden mehrere Funktionen vorgestellt. Anschließend können Sie diese in Übungen testen.
%% Cell type:markdown id: tags:
#### 3.4.1 Suchen und Matchen
Die Funktion `findall(regex,string)` haben sie schon kennengelernt:
%% Cell type:code id: tags:
```
import re
re.findall(r'f[a-z]*', 'which foot or hand fell fastest')
```
%% Cell type:markdown id: tags:
Zudem gibt es eine Funktion `search(regex,string)`. Die Argumente sind diesselben wie bei `findall`.
Diese Funktion durchsucht eine Zeichenkette *string* nach dem Vorkommen eines Teilstrings, der auf den regulären Ausdruck *regex* passt. Der erste gefundene Teilstring wird zurückgeliefert. Die Rückgabe ist ein sogennantes *match-Objekt*.
%% Cell type:code id: tags:
```
import re
object1 = re.search(r'f[a-z]*', 'which foot or hand fell fastest')
object2 = re.search(r'f[a-z]*', 'The regex did not match anything.')
print(object1,"\n",object2)
```
%% Cell type:markdown id: tags:
Ein *match-Objekt* enthält die Methoden `group()`, `span()`, `start()` und `end()`, die man im folgenden Beispiel im selbsterklärenden Einsatz sieht:
%% Cell type:code id: tags:
```
object1 = re.search(r'f[a-z]*', 'which foot or hand fell fastest')
print(object1.group())
print(object1.span())
print(object1.start())
print(object1.end())
```
%% Cell type:markdown id: tags:
Es gibt zuletzt noch eine dritte Funktion `match(regex,string)`. Diese Funktion checkt, ob ein Teilstring, der auf den regulären Ausdruck *regex* passt, am Anfang der Zeichenkette *string* vorkommt, Die Rückgabe ist wieder ein *match-Objekt*.
%% Cell type:code id: tags:
```
object1 = re.match(r'f[a-z]*', 'foot or hand fell fastest')
object2 = re.match(r'f[a-z]*', 'which foot or hand fell fastest')
print(object2)
print(object1)
print(object1.group())
print(object1.span())
print(object1.start())
print(object1.end())
```
%% Cell type:markdown id: tags:
#### 3.4.1 Übung:
Denken Sie sich eine Zeichenkette und einen regulären Ausdruck aus, die die Unterschiede der drei kennengelernten Funktionen wiedergibt.
%% Cell type:code id: tags:
```
```
%% Cell type:markdown id: tags:
#### 3.4.2 Ersetzen
%% Cell type:markdown id: tags:
Das `re`-Modul stellt nicht nur Funktionen zum Durchsuchen von Zeichenketten zur Verfügung. Mit der Funktion `re.sub(regex, replacement, string)` kann man Teilstrings ersetzen. Jede Übereinstimmung des regulären Ausdrucks *regex* in der Zeichenkette *string* wird durch die Zeichenkette *replacement* ersetzt.
%% Cell type:code id: tags:
```
re.sub(r'f[a-z]*', 'beer', 'which foot or hand fell fastest')
```
%% Cell type:markdown id: tags:
#### 3.4.3 Kompilieren
Wenn man bestimmte reguläre Ausdrücke mehrmals benutzen möchte, kann man die Funktion `compile(regex)` benutzen. Diese Funktion kompiliert einen regulären Ausdruck *regex* in eine regex-Objekt. Dieses kann man dann für weitere Funktionen nutzen.
%% Cell type:code id: tags:
```
regex_1 = re.compile(r'f[a-z]*')
print(regex_1.findall('which foot or hand fell fastest'))
print(regex_1.search('which foot or hand fell fastest'))
print(regex_1.match('which foot or hand fell fastest'))
print(regex_1.sub('beer','which foot or hand fell fastest'))
```
%% Cell type:markdown id: tags:
### Aufgaben
#### Aufgabe 1
Schreiben Sie eine Funktion, die eine Zeichenkette als Parameter entgegennimmt und überprüft, ob die Zeichenkette nur Kleinbuchstaben und Zahlen enthält.
Benutzen Sie reguläre Ausdrücke und die obigen Funktionen.
%% Cell type:code id: tags:
```
```
%% Cell type:markdown id: tags:
#### Aufgabe 2
Schreiben Sie eine Funktion, die eine Zeichenkette als Parameter entgegennimmt und überprüft, ob die Zeichenkette einen Teilstring enthält, der aus einem "a" und nachfolgend aus mindestens einem "b" besteht. (z.B. "abb", "abbbbb", "abbbbbbbbbbbbbbbb").
Benutzen Sie reguläre Ausdrücke und die obigen Funktionen.
%% Cell type:code id: tags:
```
```
%% Cell type:markdown id: tags:
#### Aufgabe 3
Schreiben Sie eine Funktion, die eine Zeichenkette als Parameter entgegennimmt und alle darin enthaltenen Leerzeichen durch ein Minus ersetzt.
Benutzen Sie reguläre Ausdrücke und die obigen Funktionen.
%% Cell type:code id: tags:
```
```
%% Cell type:markdown id: tags:
#### Aufgabe 4
Schreiben Sie eine Funktion, die eine Zeichenkette *s* und eine natürliche Zahl *n* als Parameter entgegennimmt und alle Wörter der Länge n aus der Zeichenkette *s* entfernt.
Benutzen Sie reguläre Ausdrücke und die obigen Funktionen.
%% Cell type:code id: tags:
```
```
%% Cell type:markdown id: tags:
![Speichern](https://amor.cms.hu-berlin.de/~jaeschkr/teaching/spp/floppy.png) Speichern Sie dieses Notebook so, dass Ihre Änderungen nicht verlorengehen (nicht auf einem Pool-Rechner). Klicken Sie dazu oben links auf das Disketten-Icon und nutzen Sie beispielsweise einen USB-Stick, E-Mail, Google Drive, Dropbox oder Ihre [HU-Box](https://box.hu-berlin.de/).
%% Cell type:markdown id: tags:
![Smiley](https://upload.wikimedia.org/wikipedia/commons/a/a7/Emblem-fun.svg)
Herzlichen Glückwunsch! Sie haben das 3. Kapitel geschafft. Weiter geht es in [4: Fallstudie: Schnittstellenentwurf](seminar04.ipynb).
%% Cell type:markdown id: tags:
![CC-BY-NC](https://scm.cms.hu-berlin.de/ibi/python/-/raw/master/img/cc-by-nc.png)
Dieses Notebook ist als freies Werk unter der Lizenz [Creative Commons Attribution-NonCommercial 3.0 Unported](http://creativecommons.org/licenses/by-nc/3.0/) verfügbar. Sie dürfen die Inhalte kopieren, verteilen und verändern, solange Sie die Urheber nennen und sie nicht für kommerzielle Zwecke nutzen.
......
%% Cell type:markdown id: tags:
# Jupyter Notebook Grundlagen
<h1>Table of Contents<span class="tocSkip"></span></h1>
<div class="toc"><ul class="toc-item"><li><span><a href="#Jupyter-Notebook-Grundlagen" data-toc-modified-id="Jupyter-Notebook-Grundlagen-1"><span class="toc-item-num">1&nbsp;&nbsp;</span>Jupyter Notebook Grundlagen</a></span><ul class="toc-item"><li><span><a href="#Standardbrowser" data-toc-modified-id="Standardbrowser-1.1"><span class="toc-item-num">1.1&nbsp;&nbsp;</span>Standardbrowser</a></span><ul class="toc-item"><li><span><a href="#Anleitungen" data-toc-modified-id="Anleitungen-1.1.1"><span class="toc-item-num">1.1.1&nbsp;&nbsp;</span>Anleitungen</a></span></li></ul></li><li><span><a href="#Shortcuts" data-toc-modified-id="Shortcuts-1.2"><span class="toc-item-num">1.2&nbsp;&nbsp;</span>Shortcuts</a></span><ul class="toc-item"><li><span><a href="#Beispiel:-Markdown-Zelle-vs.-Code-Zelle" data-toc-modified-id="Beispiel:-Markdown-Zelle-vs.-Code-Zelle-1.2.1"><span class="toc-item-num">1.2.1&nbsp;&nbsp;</span>Beispiel: Markdown Zelle vs. Code Zelle</a></span></li></ul></li></ul></li><li><span><a href="#Python-Grundlagen" data-toc-modified-id="Python-Grundlagen-2"><span class="toc-item-num">2&nbsp;&nbsp;</span>Python Grundlagen</a></span><ul class="toc-item"><li><span><a href="#Grundlegende-Datentypen" data-toc-modified-id="Grundlegende-Datentypen-2.1"><span class="toc-item-num">2.1&nbsp;&nbsp;</span>Grundlegende Datentypen</a></span></li><li><span><a href="#Listen" data-toc-modified-id="Listen-2.2"><span class="toc-item-num">2.2&nbsp;&nbsp;</span>Listen</a></span></li><li><span><a href="#Mengen" data-toc-modified-id="Mengen-2.3"><span class="toc-item-num">2.3&nbsp;&nbsp;</span>Mengen</a></span></li><li><span><a href="#Ranges" data-toc-modified-id="Ranges-2.4"><span class="toc-item-num">2.4&nbsp;&nbsp;</span>Ranges</a></span></li><li><span><a href="#Tupel" data-toc-modified-id="Tupel-2.5"><span class="toc-item-num">2.5&nbsp;&nbsp;</span>Tupel</a></span></li><li><span><a href="#Dictionaries" data-toc-modified-id="Dictionaries-2.6"><span class="toc-item-num">2.6&nbsp;&nbsp;</span>Dictionaries</a></span></li><li><span><a href="#If-Anweisungen" data-toc-modified-id="If-Anweisungen-2.7"><span class="toc-item-num">2.7&nbsp;&nbsp;</span>If-Anweisungen</a></span></li><li><span><a href="#Schleifen" data-toc-modified-id="Schleifen-2.8"><span class="toc-item-num">2.8&nbsp;&nbsp;</span>Schleifen</a></span></li><li><span><a href="#Funktionen" data-toc-modified-id="Funktionen-2.9"><span class="toc-item-num">2.9&nbsp;&nbsp;</span>Funktionen</a></span></li></ul></li><li><span><a href="#----------------Praktisch-für-Python,-aber-nicht-für-unseren-Kurs------------------" data-toc-modified-id="----------------Praktisch-für-Python,-aber-nicht-für-unseren-Kurs-------------------3"><span class="toc-item-num">3&nbsp;&nbsp;</span><font color="red">--------------- Praktisch für Python, aber nicht für unseren Kurs -----------------</font></a></span><ul class="toc-item"><li><span><a href="#Lambda-Funktionen" data-toc-modified-id="Lambda-Funktionen-3.1"><span class="toc-item-num">3.1&nbsp;&nbsp;</span>Lambda-Funktionen</a></span></li><li><span><a href="#List-Comprehensions" data-toc-modified-id="List-Comprehensions-3.2"><span class="toc-item-num">3.2&nbsp;&nbsp;</span>List Comprehensions</a></span></li><li><span><a href="#Klassen" data-toc-modified-id="Klassen-3.3"><span class="toc-item-num">3.3&nbsp;&nbsp;</span>Klassen</a></span></li></ul></li></ul></div>
- open-source, browserbasiertes Tool für verschiedene Programmiersprachen (wir benutzen Python)
- Code, Visualisierungen und Text
- Notebook besteht aus Blöcken / Zellen
- Unter der Zelle wird der Rückgabewert des letzten Statements ausgegeben
- Quellcode kann auf mehrere Blöcke aufgeteilt werden (Variablen behalten ihre Gültigkeit/Sichtbarkeit)
%% Cell type:markdown id: tags:
# Grundlagen Jupyter Notebooks
Falls Sie im Python-Programmierkurs sind und dies ihr erstes geöffnetes Jupyter Notebook ist: Herzlichen Glückwunsch! :)
Falls Sie im Python-Programmierkurs sind und dies ihr erstes geöffnetes Jupyter Notebook ist, lesen Sie nur bis bis zum Kapitel "Python.Grundlagen". Danach wechseln Sie zum Notebook [seminar00.ipynb](seminar00.ipynb).
- Jupyter ist freie Software – ein browserbasiertes Tool für verschiedene Programmiersprachen (wir benutzen Python).
- Es stellt Quellcode, Visualisierungen, Text und Erklärungen in einem (Web-)Dokument – dem Jupyter Notebook – dar.
- Notebooks bestehen aus Blöcken bzw. "Zellen".
- Es gibt zwei Arten von Blöcken: "Code" ist für Python-Code, "Markdown" ist für Texte, die Sie mit Hilfe der [Markdown-Syntax](https://de.wikipedia.org/wiki/Markdown#Auszeichnungsbeispiele) formatieren können.
- Blöcke können "ausgeführt" werden, dabei wird der Python-Code ausgeführt und Markdown in HTML umgewandelt und angezeigt.
- Unterhalb eines Blocks mit Quellcode wird der Rückgabewert der letzten Anweisung ausgegeben.
- Quellcode kann auf mehrere Blöcke aufgeteilt werden (Variablen behalten ihre Gültigkeit/Sichtbarkeit).
- Sie können auf Text doppelt klicken, um sich den Markdown-Quellcode anzuzeigen. Probieren Sie es mit diesem Text aus.
- Durch die Tastenkombination "Strg" und "Enter" oder durch Drücken des "Run"-Buttons oben im Menü kommen Sie wieder in den Lesemodus
- Wenn Sie mal etwas "kaputtgespielt" haben, hilft es evtl., im "Kernel"-Menü den "Restart"-Eintrag auszuwählen.
- Mit der Funktion help können Sie in Python zu vielen Funktionen Hilfe erhalten. Die offizielle Python-Dokumentation finden Sie hier: https://docs.python.org/3/.
## Standardbrowser
Bitte verwenden Sie **nicht** Safari oder Internet Explorer. Auch mit Windows Edge gab es in der Vergangenheit Probleme. Wir empfehlen die Verwendung von Firefox, aber auch Google Chrome lief in der Vergangenheit problemlos. Wenn Sie unsicher sind, was ihr aktueller Standardbrowser ist, folgen Sie einfach der folgenden Anleitung zum Ändern des Standardbrowsers und gehen Sie sicher, dass der richtige Standardbrowser ausgewählt ist.
### Anleitungen
**Änderung des Standardbrowsers in...**
*macOS:*
1. Öffnen sie die Systemeinstellungen.
2. Klicken Sie auf „Allgemein“.
3. Wählen Sie unter „Standard-Webbrowser“ den gewünschten Browser aus.
*Ubuntu Linux:*
1. Öffnen Sie die System Settings.
2. Klicken Sie auf „Applications“.
3. Wählen Sie in der linken Spalte „Default Applications“ aus.
4. Klicken Sie in der Spalte rechts davon auf „Web Browser“.
5. Wählen Sie „in the following browser:“ aus.
6. Wählen Sie den gewünschten Browser aus.
*Windows:*
1. Öffnen Sie die Systemsteuerung.
2. Klicken Sie auf „Standardprogramme“.
3. Klicken Sie auf „Standardprogramme festlegen“.
4. Klicken Sie in der Liste auf den gewünschten Browser.
5. Klicken Sie dann auf „Dieses Programm als Standard festlegen“.
%% Cell type:markdown id: tags:
# Shortcuts
Übersicht: *Help -> Keyboard Shortcuts*
- *Enter*: Editiermodus für selektierte Zelle (grün)
- *Esc*: Editiermodus verlassen/Kommandomodus (blau)
- *Shift+Strg*: Selektierte Zelle ausführen
- *Shift+Enter*: Selektierte Zelle ausführen und in nächste Zelle springen
## Shortcuts
**Bitte probieren Sie alle unten stehenden Befehle und verstehen Sie, was gemacht wird. Das ist die Basis, die Sie für das Arbeiten mit Jupyter Notebooks brauchen.**
Übersicht: *Menü Help -> Keyboard Shortcuts*
Wichtigste Shortcuts:
- *Enter*: Editiermodus für selektierte Zelle (grün umrandet)
- *Esc*: Editiermodus verlassen/Kommandomodus (blau umrandet)
- *Strg + Enter*: Selektierte Zelle ausführen
- *Shift + Enter*: Selektierte Zelle ausführen und in nächste Zelle springen
Im Editiermodus:
- Tab: Autocomplete oder Einrücken
- *Tab*: Autocomplete oder Einrücken
- *Shift + Tab*: Einrücken rückwärts
Im Kommandomodus:
Im Kommando-/Lesemodus:
- *B*: Zelle darunter einfügen
- *A*: Zelle darüber einfügen
- *DD*: Zelle löschen
- *M*: Zelltyp Markdown (für formatierte beschreibende Texte)
- *M*: Zelltyp Markdown (für formatierte beschreibende Texte, zB diese Zelle)
- *Y*: Zelltyp Code (Default)
%% Cell type:code id: tags:
```
```
%% Cell type:markdown id: tags:
%% Cell type:markdown id: tags:
### Beispiel: Markdown Zelle vs. Code Zelle
%% Cell type:markdown id: tags:
Dies ist eine **Markdown Zelle**. Hier kann jeglicher Text geschrieben werden. Durch Strg+Enter wird er in den Lesemodus gebracht, durch ein einfach Enter (oder Doppelklick) in den Editiermodus.
Hier werden keine Rechnungen ausgeführt, siehe:
5+3
In diesen Feldern werden Erklärungen, Aufgabenstellungen und schriftliche Antworten von euch stehen.
%% Cell type:code id: tags:
```
# Das ist eine **Code Zelle**, bei Strg+Enter wird die folgende Rechnung ausgeführt und darunter angezeigt
# Mit Enter kommt man in den Editiermodus, mit Strg+Enter wird der Code ausgeführt.
# Der Text kann hier nur stehen, da eine Raute am Anfang der Zeile steht.
# Dadurch werden diese Zeilen nicht ausgeführt.
5+3
# In diesen Zellen wird der Python Code geschrieben, manchmal müssen Sie ihn schreiben,
# manchmal steht der Code schon dort und muss von Ihnen nur ausgeführt werden.
```
%% Cell type:markdown id: tags:
# Python Grundlagen
# Python-Grundlagen
- Dynamisch typisierte Sprache
- Statt geschweifter Klammern für Codeblöcke (Funktionen, Schleifen) wird Code mit vier Leerzeichen (pro Hierarchieebene) eingerückt
- Die meisten Editoren ersetzen Tab automatisch durch vier Leerzeichen
- Kommentare beginnen mit Raute #
%% Cell type:markdown id: tags:
## Grundlegende Datentypen
Zahlentypen (int/float) sind größtenteils äquivalent zu Java. Strings können mit doppelten oder einfachen Anführungszeichen deklariert werden.
%% Cell type:code id: tags:
```
# Variablen definieren
a = 2*2.0
b = 5
# Ausgabe
print(a + b)
# Diese Zelle auswählen und mit `<SHIFT> + <ENTER>` ausführen.
# Der letzte Rückgabewert der Zelle wird dann unten ausgegeben,
# hier also der Wert von `a+b`:b
```
%% Cell type:markdown id: tags:
Die grundlegenden Rechenoperationen __`+`, `-`, `*`, `/`__ und __`**`__ sind ebenfalls in Python verfügbar und verhalten sich, wie man es erwartet:
%% Cell type:code id: tags:
```
# äquivalent zu a = a + 1
a += 1
print(a)
```
%% Cell type:code id: tags:
```
# Potenzieren
2**4
```
%% Cell type:code id: tags:
```
# Division
2/4
```
%% Cell type:markdown id: tags:
Es gibt verschiedene Variablentypen:
- int (Ganzzahl, z.B. 1, 20, 52432432)
- float (Gleitkommazahl, z.B. 1.423, 1/3, 0.23487235723)
- str (Zeichenkette, z.B. "Hello World", 'this is a string')
- bool (Wahrheitswerte, z.B. True, False)
%% Cell type:code id: tags:
```
# Zeichenketten bzw. strings
text1 = 'Hallo '
text2 = "Welt"
print (text1 + text2)
# Andere Datentypen müssen explizit in Strings konvertiert werden,
# wenn sie an einen String angehängt werden sollen.
print(text1 + str(1))
# oder man muss sie durch Kommata trennen:
print(text1,1)
```
%% Cell type:code id: tags:
```
# Zeichenkette zu float
float('1')
```
%% Cell type:code id: tags:
```
# integer zu float
float(1)
```
%% Cell type:markdown id: tags:
*None* entspricht *null* in Java.
%% Cell type:code id: tags:
```
myvar = None
```
%% Cell type:code id: tags:
```
print(myvar)
```
%% Cell type:code id: tags:
```
if myvar is None:
print('x ist nicht definiert')
```
%% Cell type:markdown id: tags:
## Listen
Listen werden mit eckigen Klammern oder list() initialisiert.
%% Cell type:code id: tags:
```
l = [1,2,3,3]
l.append(4)
print(l)
```
%% Cell type:markdown id: tags:
Vorsicht bei der Kombination von Listen. append hängt die übergebene Variable als einzelnen Listeneintrag an die Liste an.
%% Cell type:code id: tags:
```
l.append([5, 6])
print(l)
```
%% Cell type:markdown id: tags:
Zur Kombination von zwei Listen wird der +-Operator verwendet.
%% Cell type:code id: tags:
```
l2 = l + [5,6]
print(l2)
```
%% Cell type:markdown id: tags:
## Mengen
Mengen können mit geschweiften Klammern oder set() initialisiert werden.
%% Cell type:code id: tags:
```
s = {1,2,3,3}
s2 = set([2,3,4,5])
print(s)
print(s.intersection(s2))
```
%% Cell type:code id: tags:
```
s.add(9)
s.remove(2)
s
```
%% Cell type:markdown id: tags:
Mit list() und set() können die Typen auch ineinander konvertiert werden.
%% Cell type:code id: tags:
```
list(s)
```
%% Cell type:code id: tags:
```
set([1,2,3])
```
%% Cell type:markdown id: tags:
## Ranges
Auflistung von Zahlen, werden z.Bsp. für for-Schleifen mit Index verwendet.
%% Cell type:code id: tags:
```
for i in range(5):
print(i)
```
%% Cell type:markdown id: tags:
## Tupel
Für sortierete Werte mit fester Komponentenanzahl und fester Bedeutung für jeden Eintrag.
%% Cell type:code id: tags:
```
essen = 'Chili'
preis = 2.51
boneintrag = (essen, preis)
print(boneintrag)
print(boneintrag[0])
print(boneintrag[1])
```
%% Cell type:code id: tags:
```
(essen2, preis2) = boneintrag
print(essen2)
print(preis2)
```
%% Cell type:markdown id: tags:
Klammern können oft weggelassen werden
%% Cell type:code id: tags:
```
boneintrag = essen, preis
essen2, preis2 = boneintrag
print(boneintrag)
print(essen2)
print(preis2)
```
%% Cell type:markdown id: tags:
## Dictionaries
Äquivalent zu Maps.
%% Cell type:code id: tags:
```
d = {'Chili': 1.90, 'Penne': 2.50}
```
%% Cell type:code id: tags:
```
d.keys()
```
%% Cell type:code id: tags:
```
d.values()
```
%% Cell type:code id: tags:
```
for key, val in d.items():
print('{}: {}'.format(key, val))
```
%% Cell type:code id: tags:
```
d['Chili']
```
%% Cell type:code id: tags:
```
d['Burger'] = 4.90
d
```
%% Cell type:code id: tags:
```
del d['Burger']
d
```
%% Cell type:markdown id: tags:
## If-Anweisungen
%% Cell type:code id: tags:
```
if 2>1 or 1>2:
print ('Bedingung erfüllt.')
```
%% Cell type:code id: tags:
```
y = 10
x = 5 if y > 10 else 4
print(x)
```
%% Cell type:markdown id: tags:
## Schleifen
%% Cell type:code id: tags:
```
x = 5
while x > 0:
x -= 1
x
```
%% Cell type:code id: tags:
```
for x in ['a', 'b', 'c']:
print(x)
```
%% Cell type:markdown id: tags:
## Funktionen
%% Cell type:code id: tags:
```
def sum_upto(n):
return n*(n+1)/2
sum_upto(4)
```
%% Cell type:markdown id: tags:
Zur besseren Übersicht (insbesondere bei vielen Parametern) können diese auch namentlich zugewiesen werden.
%% Cell type:code id: tags:
```
sum_upto(n=4)
```
%% Cell type:markdown id: tags:
Funktionen können *Default-Parameter* haben, d.h. Werte, die von der Funktion als Standardwert verwendet werden (wenn kein anderer Wert übergeben wird). Default-Parameter müssen am Ende der Funktion stehen und übergeben werden.
%% Cell type:code id: tags:
```
def fun_with_default(x=3):
print('Parameter is {}'.format(x))
```
%% Cell type:code id: tags:
```
fun_with_default()
```
%% Cell type:code id: tags:
```
fun_with_default(x=4)
```
%% Cell type:markdown id: tags:
Funktionen können wie Variablen referenziert werden (Pointer auf die Funktion) und zum Beispiel als Parameter übergeben werden.
%% Cell type:code id: tags:
```
def calc_and_print(calc_function, n):
calc_result = calc_function(n)
print(calc_result)
```
%% Cell type:code id: tags:
```
calc_and_print(sum_upto, 4)
```
%% Cell type:markdown id: tags:
# <font color='red'>--------------- Praktisch für Python, aber nicht für unseren Kurs -----------------</font>
%% Cell type:markdown id: tags:
## Lambda-Funktionen
I.d.R. für Inline-Funktionen. Können zum Beispiel an Funktionen als Parameter übergeben oder als Variable deklariert werden. Lambdas enthalten ein einzelnes Statement, dessen Wert automatisch der Rückgabewert ist.
%% Cell type:code id: tags:
```
calc_square = lambda x: x**2
calc_square(3)
```
%% Cell type:code id: tags:
```
calc_and_print(calc_square, 4)
```
%% Cell type:code id: tags:
```
calc_and_print(lambda x: x**3, 4)
```
%% Cell type:markdown id: tags:
## List Comprehensions
%% Cell type:code id: tags:
```
y = [x**2 for x in range(10)]
y
```
%% Cell type:code id: tags:
```
xy = [(x, x**2) for x in range(10) if x%2 == 0]
xy
```
%% Cell type:markdown id: tags:
## Klassen
Objekte einer Klasse bekommen bei Methodenaufrufen als ersten Parameter automatisch das *"self"*-Objekt übergeben (vgl. *this* in Java). Dieser Parameter muss also immer auch als erster Parameter einer Klassenmethode übergeben werden.
%% Cell type:code id: tags:
```
class Vehicle():
# Constructor
def __init__(self, n_wheels=4, noise='beep'):
self.n_wheels = n_wheels
self.noise = noise
def make_noise(self):
print(self.noise)
```
%% Cell type:code id: tags:
```
basicVehicle = Vehicle()
basicVehicle.make_noise()
```
%% Cell type:markdown id: tags:
Properties sind immer von außen sichtbar und lassen sich verändern. Properties, die nicht zur Veränderung gedacht sind, werden nach Konvention durch zwei Unterstriche im Namen gekennzeichnet.
%% Cell type:code id: tags:
```
basicVehicle.n_wheels
```
%% Cell type:markdown id: tags:
Vererbung ist in Python möglich. In der Regel wird aber Duck-Typing verwendet.
“When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.”
%% Cell type:code id: tags:
```
bike = Vehicle(n_wheels=2, noise='ring')
bike.make_noise()
```
%% Cell type:code id: tags:
```
class Bike(Vehicle):
def __init__(self):
self.n_wheels = 2
self.noise = 'ring'
```
%% Cell type:code id: tags:
```
Bike().make_noise()
```
%% Cell type:markdown id: tags:
![CC-BY-NC](https://scm.cms.hu-berlin.de/ibi/python/-/raw/master/img/cc-by-nc.png)
Dieses Notebook ist als freies Werk unter der Lizenz [Creative Commons Attribution-NonCommercial 3.0 Unported](http://creativecommons.org/licenses/by-nc/3.0/) verfügbar. Sie dürfen die Inhalte kopieren, verteilen und verändern, solange Sie die Urheber nennen und sie nicht für kommerzielle Zwecke nutzen.
......
This diff is collapsed.
%% Cell type:markdown id: tags:
# 12. Übungsblatt
Mit diesem Python-Code können Sie Ihren regulären Ausdruck testen:
%% Cell type:code id: tags:
```
import re
"""
Ändern Sie den folgenden regulären Ausdruck, so dass alle
positiven Muster erkannt werden, aber kein negatives Muster.
"""
muster = re.compile("Z")
positive = [
"rap them",
"tapeth",
"apth",
"wrap/try",
"sap tray",
"87ap9th",
"apothecary"
]
negative = [
"aleht",
"happy them",
"tarpth",
"Apt",
"peth",
"tarreth",
"ddapdg",
"apples",
"shape the"
]
# testen, ob alle positiven Muster richtig erkannt werden
positive_not_matched = [s for s in positive if not muster.findall(s)]
if positive_not_matched:
print("Folgende positiven Muster wurden nicht erkannt:", ", ".join(positive_not_matched))
# testen, ob keine negativen Muster erkannt werden
negative_matched = [s for s in negative if muster.findall(s)]
if negative_matched:
print("Folgende negativen Muster wurden erkannt:", ", ".join(negative_matched))
if not positive_not_matched and not negative_matched:
print("Herzlichen Glückwunsch, Sie haben das richtige Muster gefunden!")
```
%% Cell type:markdown id: tags:
Nachfolgend noch einige Beispiele zur Verwendung von regulären Ausdrücke mit Python:
%% Cell type:code id: tags:
```
# Funktionen für reguläre Ausdrücke werden im Modul "re" bereitgestellt
import re
# die Methode "findall" findet alle Teilzeichenketten in einer Zeichenkette,
# die auf das angegebene Muster passen
re.findall("cat|dog", "This sentence contains a dog.")
```
%% Cell type:code id: tags:
```
# die Methode "match" testet, ob die gesamte Zeichenkette auf das angegebene Muster passt
re.match(".*dog\\.", "This sentence contains a dog.")
```
%% Cell type:code id: tags:
```
re.match(".*(cat|dog)", "This sentence contains a cat.")
```
%% Cell type:markdown id: tags:
Mit "match" können wir beispielsweise unsere Ergebnisse für Aufgabe 1 prüfen:
%% Cell type:code id: tags:
```
if re.match("[hc]?at", "cat"):
print("Wort wurde erkannt")
else:
print("Wort wurde nicht erkannt")
```
%% Cell type:markdown id: tags:
%% Cell type:code id: tags:
```
# Es gibt eine umfangreiche eingebaute Hilfe:
help(re)
```
%% Cell type:code id: tags:
```
```
%% Cell type:markdown id: tags:
![CC-BY-NC](https://scm.cms.hu-berlin.de/ibi/python/-/raw/master/img/cc-by-nc.png)
Dieses Notebook ist als freies Werk unter der Lizenz [Creative Commons Attribution-NonCommercial 3.0 Unported](http://creativecommons.org/licenses/by-nc/3.0/) verfügbar. Sie dürfen die Inhalte kopieren, verteilen und verändern, solange Sie die Urheber nennen und sie nicht für kommerzielle Zwecke nutzen.
......
This diff is collapsed.
This diff is collapsed.
%% Cell type:markdown id:1fe95632 tags:
# Ein Python-Modul entwicklen und veröffentlichen
<br/>
<br/>
Dieses Notebook finden Sie hier: https://scm.cms.hu-berlin.de/ibi/python/-/blob/master/programmierspass/Develop_and_publish_modul.ipynb
<br/>
![CC-BY-NC](https://scm.cms.hu-berlin.de/ibi/python/-/raw/master/img/cc-by-nc.png)
Dieses Notebook ist als freies Werk unter der Lizenz [Creative Commons Attribution-NonCommercial 3.0 Unported](http://creativecommons.org/licenses/by-nc/3.0/) verfügbar. Sie dürfen die Inhalte kopieren, verteilen und verändern, solange Sie die Urheber nennen und sie nicht für kommerzielle Zwecke nutzen.
%% Cell type:markdown id:c7dc7204 tags:
## Was ist ein Modul?
- Ein Modul ist eine Datei, die Python-Definitionen und -Anweisungen beinhaltet. Oder anders gesagt: Jede Python-Datei ist ein Modul und der Name des Moduls ist der Dateiname ohne die Endung `.py`
- Ein Package ist eine Sammlung von Modulen. Hierfür liegen mehrere Module in einem Ordner, welcher auch eine Datei `__init__.py` enthalten muss. Dies unterscheidet ein Package von einem Ordner, der zufällig mehrere Module enthält.
%% Cell type:markdown id:21e7cd83 tags:
## Module verwenden
- Python wird mit einer Bibliothek von Standardmodulen ausgeliefert. Ein solches Modul kann mit dem Befehl `import` importiert und anschließend verwendet weden.
%% Cell type:code id:94cad5e7 tags:
```
import json
```
%% Cell type:markdown id:1129c831 tags:
- Wenn wir nun versuchen ein Modul zu installieren, welches nicht in den Standardmodulen enthalten ist, dann kommt es zu einer Fehlermeldung.
%% Cell type:code id:3aa3db5d tags:
```
import pandas
```
%% Cell type:markdown id:bdc84dcf tags:
## Module installieren
- Module, die nicht in der Bibliothek von Standardmodulen enthalten sind, müssen vor dem Import installiert werden. Hierfür wird ein Paketverwaltungsprogramm verwendet. Dies ist im Normfall `pip`. Mit dem Befehl `pip install` können Pakete installiert werden.
%% Cell type:code id:2148e19b tags:
```
!pip install pandas
```
%% Cell type:markdown id:2dce18c9 tags:
## Doch was passiert hier eigentlich?
%% Cell type:markdown id:f07907eb tags:
### Python Package Index (PyPI)
- `pip`lädt Pakete aus dem Python Package Index (PyPI).
- PyPI ist ein Sofware-Vezeichnis der Programmiersprache Python.
- PyPI umfasst knapp 420.00 Projekte (Stand: Dezember 2022)
- Jede:r kann sich auf PyPI (https://pypi.org) registrieren und ein Projekt erstellen.
<div class="alert alert-info">
<b>Hinweis</b> Der Begriff "Package" kann etwas verwirrend sein. PyPI spricht auch von Packages. Ein PyPI-Package kann ein einzelnes Python-Modul sein oder aber auch mehrere Python-Packages umfassen.
</div>
%% Cell type:markdown id:d45b9900 tags:
### PyPI Testumgebung
- Für Testzwecke gibt es die PyPI Testumgebgung (https://test.pypi.org)
- Diese funktioniert genau wie die reale Version und sollte verwendet werden um die eigene Konfiguration zu testen.
%% Cell type:markdown id:cbf98fba tags:
## Mein erstes PyPI (Test)-Package
%% Cell type:markdown id:0cbf8602 tags:
### Beispiel für ein minimales Projekt
```
pypi-example/
├── LICENSE
├── pyproject.toml
├── README.md
└── pypiex/
├── __init__.py
└── example.py
```
%% Cell type:markdown id:8b3f6ddf tags:
### pyproject.toml - Konfiguration von Metadaten
```toml
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[project]
name = "Pypiex"
version = "0.0.1"
authors = [
{ name = "Frederik Arnold", email = "frederik.arnold@hu-berlin.de" }
]
description = "Eine kurze Beschreibung für PyPiex"
readme = "README.md"
requires-python = ">=3.7"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: Apache Software License",
"Operating System :: OS Independent",
]
[project.urls]
"Homepage" = "https://..."
"Bug Tracker" = "https://..."
```
- Weitere Informationen zu den einzelnen Angaben: https://packaging.python.org/en/latest/specifications/declaring-project-metadata/#declaring-project-metadata
%% Cell type:markdown id:927e9459 tags:
### README.md
```
# Mein Projekt
Dies ist ein Beispielprojekt.
```
%% Cell type:markdown id:4c8acd0d tags:
### LICENSE
```
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
[...]
```
%% Cell type:markdown id:d4b197a7 tags:
### Package für den Upload erzeugen
- Für die Erzeugung der zum Upload benötigten Dateien, muss zuerst in den Projektordner navigiert werden, und dort die folgende Befehle ausgeführt werden.
%% Cell type:markdown id:68e05d16 tags:
- Zuerst müssen für den Build benötigten Pakete installiert werden.
```
pip install --upgrade build
```
%% Cell type:markdown id:3cf7b4cd tags:
- Dann kann anhand der `pyproject.toml` das Package erstellt werden. Dieses wird in den Ordner `dist` im Projektordner gespeichert.
```
python -m build
```
%% Cell type:markdown id:afd1c91e tags:
- Wenn die Befehle korrekt ausgeführt werden konnten, dann sollte die letzte Zeile so lauten:
```
Successfully built xyz-version.tar.gz and xyz-version-py3-none-any.whl
```
- Außerdem sollten zwei Dateien im Ordner `dist` erzeugt worden sein. Es gibt verschiedene Arten von Packages.
- Die Datei mit der Endung `.tar.gz` ist eine Source Distribution.
- Die Datei mit der Endung `.whl` (Wheel-Datei) ist eine Built Distribution. Dieses Format ist neuer und hat verschiedene Vorteile. Die Details sind an dieser Stelle nicht relevant.
%% Cell type:markdown id:a87cd03e tags:
### Package auf den Testserver hochladen
- Um Pakete hochladen zu können muss zuerst ein Account erstellt werden.
<div class="alert alert-info">
<b>Hinweis</b> Der PyPI Testserver ist unabhängig von der Produktionsumgebung und es werden jeweils eigene Accounts benötigt.
</div>
%% Cell type:markdown id:1444d33a tags:
- Jetzt muss ein `API token` generiert werden. Dies geschieht in den Kontoeinstellungen im Bereich `API-Token`. Folgender Link führt automatisch dort hin: https://test.pypi.org/manage/account/#api-tokens. Auf `API-Token hinzufügen` klicken. Dort einen sinnvollen Namen vergeben und den Geltungsbereich auf `Gesamtes Konto` stellen.
<div class="alert alert-info">
<b>Hinweis</b> Ein erstelltes Token muss direkt gesichert werden, da es danach nicht mehr einsehbar ist.
</div>
%% Cell type:markdown id:abf06326 tags:
- Jetzt die für den Upload benötigten Packages laden und installieren:
```
pip install --upgrade twine
```
%% Cell type:markdown id:325e2694 tags:
- Und dann den Upload ausführen. Hierbei wird nach dem Username und Passwort gefragt. Für den Username muss `__token__` verwendet werden und für Passwort das gerade erstelle Token inklusive des `pypi` Prefix.
```
python -m twine upload --repository testpypi dist/*
```
<div class="alert alert-info">
<b>Hinweis</b> Soll eine neue Version für ein Paket hochgeladen werden, dann muss vor der Erzeugung des Pakets immer zuerst die Versionsnummer in der `pyproject.toml` angepasst werden. Eine Version kann immer nur ein Mal hochgeladen werden.
</div>
%% Cell type:markdown id:a55a2eb7 tags:
## Package installieren und verwenden
- Das Paket kann jetzt mit `pip` installiert werden. Hierzu muss der Testserver angegeben werden.
%% Cell type:code id:eab699f8 tags:
```
!pip install --index-url https://test.pypi.org/simple/ --no-deps Pypiex
```
%% Cell type:code id:2f369bf9 tags:
```
from pypiex import example
example.say_hello("Frederik")
```
%% Cell type:markdown id:2a17f85c tags:
## Literatur
- https://packaging.python.org/en/latest/tutorials/packaging-projects/
- https://setuptools.pypa.io/en/latest/userguide/index.html
%% Cell type:code id:ee4663eb tags:
```
```
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="100mm"
height="75.000336mm"
viewBox="0 0 100 75.000336"
version="1.1"
id="svg5"
inkscape:version="1.2 (dc2aedaf03, 2022-05-15)"
sodipodi:docname="Spielfeld.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2"
inkscape:cx="221"
inkscape:cy="149.5"
inkscape:window-width="1600"
inkscape:window-height="837"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-49.726025,-39.780482)">
<rect
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.379429;stroke-linecap:square"
id="rect184"
width="100"
height="75"
x="49.726025"
y="39.780819"
ry="0.038814995" />
<path
style="fill:none;fill-opacity:1;stroke:#c8c8c8;stroke-width:0.508291;stroke-linecap:square;stroke-opacity:1"
d="M 99.726025,40.034628 V 114.52625"
id="path899" />
<circle
style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:0.247871;stroke-linecap:square;stroke-opacity:1"
id="path1216"
cx="99.726021"
cy="77.280823"
r="2" />
<rect
style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:0.290918;stroke-linecap:square;stroke-opacity:1"
id="rect2360"
width="1"
height="14"
x="148.2"
y="70.280823"
ry="0.033486359" />
<rect
style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:0.290918;stroke-linecap:square;stroke-opacity:1"
id="rect2360-1"
width="1"
height="14"
x="50.237"
y="70.280823"
ry="0.033486359" />
</g>
</svg>
This diff is collapsed.
allData = {}
\ No newline at end of file