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
%% Cell type:markdown id:5705b2a6 tags:
# Kapitel 11: Tupel
[Chapter 11: Tuples](https://colab.research.google.com/github/AllenDowney/ThinkPython/blob/v3/chapters/chap11.ipynb)
In diesem Kapitel wird ein weiterer eingebauter Datentyp, das Tupel, vorgestellt und gezeigt, wie Listen, assoziative Datenfelder und Tupel zusammenarbeiten.
Außerdem beinhaltet das Kapitel Informationen zu Tupel-Zuweisungen und einer nützlichen Eigenschaft für Funktionen mit Argumentlisten variabler Länge: die Verpack- und Entpack-Operatoren.
In den Übungen werden wir Tupel zusammen mit Listen und assoziativen Datenfeldern verwenden, um mehr Worträtsel zu lösen und effiziente Algorithmen zu implementieren.
### 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:
-
-
-
%% Cell type:markdown id:9a0b03e4-0e53-40b4-8850-5fa03078f99a tags:
## Herunterladen des unterstützenden Codes
Die folgende Zelle lädt eine Datei herunter und führt einen Code aus, der speziell für dieses Notebook verwendet wird. Sie müssen diesen Code nicht verstehen, aber Sie sollten die Zelle vor allen weiteren Zellen in diesem Notebook ausführen:
%% Cell type:code id:295ac6d7 tags:
``` python
from os.path import basename, exists
def download(url):
filename = basename(url)
if not exists(filename):
from urllib.request import urlretrieve
local, _ = urlretrieve(url, filename)
print("Downloaded " + str(local))
return filename
download('https://github.com/AllenDowney/ThinkPython/raw/v3/thinkpython.py');
download('https://github.com/AllenDowney/ThinkPython/raw/v3/diagram.py');
import thinkpython
```
%% Cell type:markdown id:19474596 tags:
## Tupel sind wie Listen
Ein **Tupel** (Englisch: *tuple*) ist eine Abfolge von Werten. Diese Werte können jeden Datentypen haben und sind mit ganzen Zahlen indexiert, in dieser Hinsicht sind Tupel Listen also sehr ähnlich.
Der wichtigste Unterschied zwischen den beiden ist aber, dass Tupel unveränderbar sind.
Um ein Tupel zu erstellen können wir eine Liste mit Werten schreiben, die durch Kommata getrennt werden:
%% Cell type:code id:fb0bdca2 tags:
``` python
t = 'l', 'u', 'p', 'i', 'n'
type(t)
```
%% Cell type:markdown id:a2ec15d8 tags:
Auch wenn es nicht unbedingt notwendig ist, werden Tupel häufig in runden Klammern geschrieben:
%% Cell type:code id:5a6da881 tags:
``` python
t = ('l', 'u', 'p', 'i', 'n')
type(t)
```
%% Cell type:markdown id:9194a159 tags:
Um ein Tupel mit einem einzigen Element zu erstellen, müssen wir es mit einem Komma am Ende schreiben:
%% Cell type:code id:e2596ca7 tags:
``` python
t1 = 'p',
type(t1)
```
%% Cell type:markdown id:e39b95a5 tags:
Ein einzelner Wert in Klammern ist kein Tupel:
%% Cell type:code id:a0d350a6 tags:
``` python
t2 = ('p')
type(t2)
```
%% Cell type:markdown id:a64bfb64 tags:
Ein anderer Weg, ein Tupel zu erstellen, ist die eingebaute Funktion `tuple`. Ohne Argument erstellt diese ein leeres Tupel:
%% Cell type:code id:c9100ee4 tags:
``` python
t = tuple()
t
```
%% Cell type:markdown id:f3447831 tags:
Wenn das Argument eine Folge ist (eine *Zeichenkette*, eine *Liste* oder ein *Tupel*), ist das Ergebnis ein Tupel mit den Elementen der Folge:
%% Cell type:code id:44bd3d83 tags:
``` python
t = tuple('lupin')
t
```
%% Cell type:markdown id:2e48b980 tags:
Da `tuple` der Name einer eingebauten Funktion ist, sollten wir vermeiden, es als Variablennamen zu verwenden.
Die meisten Operatoren für Listen funktionieren auch mit Tupeln.
Der Klammer-Operator zum Beispiel indexiert ein Element:
%% Cell type:code id:92e55b2c tags:
``` python
t[0]
```
%% Cell type:markdown id:2f702785 tags:
Und der Slice-Operator wählt Elemente aus einem angegebenen Bereich aus:
%% Cell type:code id:38ee5c2a tags:
``` python
t[1:3]
```
%% Cell type:markdown id:c9ed9af2 tags:
Der `+`-Operator konkateniert Tupel:
%% Cell type:code id:2e0e311a tags:
``` python
tuple('lup') + ('i', 'n')
```
%% Cell type:markdown id:1d7dcd6d tags:
Und der `*`-Operator dupliziert ein Tupel eine angegebene Anzahl von Malen:
%% Cell type:code id:8bb7d715 tags:
``` python
tuple('spam') * 2
```
%% Cell type:markdown id:a53ce8bd tags:
Die `sorted`-Function funktioniert auch mit Tupeln -- aber das Ergebnis ist eine Liste, kein Tupel:
%% Cell type:code id:e653e00f tags:
``` python
sorted(t)
```
%% Cell type:markdown id:50e5cadc tags:
Die `reversed`-Function funktioniert ebenfalls mit Tupeln:
%% Cell type:code id:8969188d tags:
``` python
reversed(t)
```
%% Cell type:markdown id:f6d973c5 tags:
Das Ergebnis ist ein `reversed`-Object, das wir in eine Liste oder ein Tupel konvertieren können:
%% Cell type:code id:65d7ebaa tags:
``` python
tuple(reversed(t))
```
%% Cell type:markdown id:a7cb9ee6 tags:
Ausgehend von den bisher gezeigten Beispielen könnte man annehmen, dass Tupel das Gleiche sind wie Listen.
%% Cell type:markdown id:8c3f381e tags:
## Aber Tupel sind unveränderlich
Wenn wir versuchen, ein Tupel mit dem Klammer-Operator zu modifizieren, erhalten wir einen `TypeError`:
%% Cell type:code id:b4970fe0 tags:
``` python
%%expect TypeError
t[0] = 'L'
```
%% Cell type:markdown id:592ce99c tags:
Und Tupel haben keine der Methoden, die verwendet werden um Listen zu verändern, wie etwa `append` und `remove`:
%% Cell type:code id:772738cc tags:
``` python
%%expect AttributeError
t.remove('l')
```
%% Cell type:markdown id:70772ba2 tags:
Erinnern Sie sich daran, dass ein "Attribut" eine Variable oder eine Methode ist, die in Zusammenhang mit einem Objekt steht -- diese Fehlermeldung bedeutet, dass Tupel keine Methode namens `remove` haben.
Weil Tupel unveränderlich sind, sind sie hashbar, was bedeutet, dass sie als Schlüssel in einem assoziativen Datenfeld verwendet werden können.
Das folgende assoziative Datenfeld enthält zum Beispiel zwei Tupel, die als Schlüssel auf ganze Zahlen verweisen.
%% Cell type:code id:37e67042 tags:
``` python
d = {}
d[1, 2] = 3
d[3, 4] = 7
```
%% Cell type:markdown id:47ba17ab tags:
So können wir Tupel in einem assoziativen Datenfeld suchen:
%% Cell type:code id:d809a490 tags:
``` python
d[1, 2]
```
%% Cell type:markdown id:f2c0a354 tags:
Oder wir können, wenn es eine Variable gibt, die sich auf das Tupel bezieht, diese als Schlüssel verwenden:
%% Cell type:code id:dfc42a8b tags:
``` python
t = (3, 4)
d[t]
```
%% Cell type:markdown id:2ea8fc3c tags:
Tupel können auch als Werte in einem assoziativen Datenfeld vorkommen:
%% Cell type:code id:2debf30c tags:
``` python
t = tuple('abc')
d = {'schluessel': t}
d
```
%% Cell type:markdown id:25655ab3 tags:
## Tupel-Zuweisung
Wir können ein Tupel mit Variablen auf die linke und ein Tupel mit Werten auf die rechte Seite einer Zuweisung schreiben:
%% Cell type:code id:1e94ea37 tags:
``` python
a, b = 1, 2
```
%% Cell type:markdown id:92c00ceb tags:
Die Werte werden den Variablen von links nach rechts zugewiesen -- in diesem Beispiel erhält `a` den Wert `1` und `b` den Wert `2`.
Wir können so die Ergebnisse anzeigen:
%% Cell type:code id:99c96c7f tags:
``` python
a, b
```
%% Cell type:markdown id:6362b36e tags:
Etwas allgemeiner gesprochen: wenn die linke Seite einer Zuweisung ein Tupel ist, dann kann die rechte Seite jede Art von Folge sein -- *Zeichenkette*, *Liste* oder *Tupel*.
Um eine email-Adresse in Username und Domain aufzuteilen können wir zum Beispiel schreiben:
%% Cell type:code id:b67881ed tags:
``` python
email = 'monty@python.org'
username, domain = email.split('@')
```
%% Cell type:markdown id:d134a94c tags:
Der Rückgabewert von `split` ist eine Liste mit zwei Elementen -- das erste Element wird ` username` zugewiesen, das zweite `domain`:
%% Cell type:code id:b4515e2b tags:
``` python
username, domain
```
%% Cell type:markdown id:5a7e3c62 tags:
Die Anzahl der Variablen auf der linken und die Anzahl der Werte auf der rechten Seite müssen gleich sein -- andernfalls erhalten wir einen `ValueError`:
%% Cell type:code id:8e5b4a14 tags:
``` python
%%expect ValueError
a, b = 1, 2, 3
```
%% Cell type:markdown id:808c2928 tags:
Tupel-Zuweisung ist praktisch für die Fälle in denen wir die Werte zweier Variablen tauschen möchten.
Bei einer konventionellen Zuweisung müssten wir hierfür eine temporäre Variable verwenden, wie im folgenden Beispiel:
%% Cell type:code id:2389d6de tags:
``` python
temp = a
a = b
b = temp
```
%% Cell type:markdown id:98496d02 tags:
Das funktioniert zwar, aber mit einer Tupel-Zuweisung können wir das Gleiche ohne die temporäre Variable tun:
%% Cell type:code id:5512edec tags:
``` python
a, b = b, a
```
%% Cell type:markdown id:a66a87bc tags:
Das funktioniert, da alle Ausdrücke auf der rechten Seite vor jeglichen Zuweisungen ausgewertet werden.
Wir können Tupel-Zuweisungen auch in `for`-Ausdrücken verwenden.
Zum Beispiel können wir, um in einer Schleife durch die Elemente eines assoziativen Datenfeldes zu gehen, die `items`-Methode benutzen:
%% Cell type:code id:651ab417 tags:
``` python
d = {'eins': 1, 'zwei': 2}
for item in d.items():
schluessel, wert = item
print(schluessel, '->', wert)
```
%% Cell type:markdown id:dd0d4feb tags:
Bei jedem Durchgang der Schleife wird `item` ein Tupel zugewiesen, das einen *Schlüssel* und den korrespondierenden *Wert* enthält.
Wir können diese Schleife auch etwas prägnanter schreiben:
%% Cell type:code id:2c0b7d47 tags:
``` python
for schluessel, wert in d.items():
print(schluessel, '->', wert)
```
%% Cell type:markdown id:f0513578 tags:
Bei jedem Durchgang der Schleife werden ein Schlüssel und der korrespondierende Wert direkt `schluessel` und `wert` zugewiesen.
%% Cell type:markdown id:efedeb37 tags:
## Tupel als Rückgabewerte
Streng genommen kann eine Funktion nur einen Wert zurückgeben, wenn dieser Wert aber ein Tupel ist, hat dies den gleichen Effekt als würde man mehrere Werte zurückgeben.
Wenn wir zum Beispiel zwei ganze Zahlen dividieren und den Quotienten sowie den Rest berechnen möchten, ist es ineffizient zuerst `x//y` und dann `x%y` zu berechnen. Es ist besser, beide gleichzeitig zu berechnen.
Die eingebaute Funktion `divmod` nimmt zwei Argumente auf und gibt ein Tupel mit zwei Werten, dem *Quotienten* und dem *Rest* zurück:
%% Cell type:code id:fff80eaa tags:
``` python
divmod(7, 3)
```
%% Cell type:markdown id:33f3c57d tags:
Wir können Tupel-Zuweisung nutzen, um die Elemente des Tupels in zwei Variablen zu speichern:
%% Cell type:code id:4a0eb2a9 tags:
``` python
quotient, rest = divmod(7, 3)
quotient
```
%% Cell type:code id:d74ba1b6 tags:
``` python
rest
```
%% Cell type:markdown id:15079805 tags:
Hier ist ein Beispiel für eine Funktion, die ein Tupel zurückgibt:
%% Cell type:code id:dad3b3bb tags:
``` python
def min_max(t):
return min(t), max(t)
```
%% Cell type:markdown id:43c4e1e0 tags:
`max` und `min` sind eingebaute Funktionen, die das größte und das kleinste Element einer Folge finden.
`min_max` berechnet beide und gibt ein Tupel mit zwei Werten zurück:
%% Cell type:code id:fbd90b0e tags:
``` python
min_max([2, 4, 1, 3])
```
%% Cell type:markdown id:86b60e71 tags:
So können wir die Ergebnisse Variablen zuweisen:
%% Cell type:code id:5a101efb tags:
``` python
niedrig, hoch = min_max([2, 4, 1, 3])
niedrig, hoch
```
%% Cell type:markdown id:112b5aa2 tags:
## Argumente verpacken
Funktionen können eine variable Anzahl von Argumenten aufnehmen.
Ein Parametername, der mit dem `*`-Operator beginnt, **verpackt** (Englisch: *packs*) die Argumente in ein Tupel.
Die folgende Funktion nimmt zum Beispiel eine beliebige Zahl an Argumenten auf und berechnet deren arithmetisches Mittel -- also deren Summe, geteilt durch die Anzahl der Argumente:
%% Cell type:code id:0a33e2d0 tags:
``` python
def mittel(*args):
return sum(args) / len(args)
```
%% Cell type:markdown id:6044fc1b tags:
Der Parameter kann jeden beliebigen Namen haben, die übliche Benennung ist aber `args`.
Wir können die Funktion so aufrufen:
%% Cell type:code id:336a08ca tags:
``` python
mittel(1, 2, 3)
```
%% Cell type:markdown id:a5e8b158 tags:
Wenn wir eine Folge von Werten haben und diese als mehrere Argumente an eine Funktion übergeben wollen, können wir den `*`-Operator verwenden, um das Tupel zu **entpacken** (Englisch: *unpack*).
`divmod` nimmt zum Beispiel exakt zwei Argumente auf -- wenn wir ein Tupel als Parameter übergeben erhalten wir eine Fehlermeldung:
%% Cell type:code id:991810bc tags:
``` python
%%expect TypeError
t = (7, 3)
divmod(t)
```
%% Cell type:markdown id:5a9110db tags:
Obwohl das Tupel zwei Elemente enthält, zählt es als ein einzelnes Argument.
Aber wenn wir das Tupel entpacken, wird es behandelt als wären es zwei Argumente:
%% Cell type:code id:f25ebee1 tags:
``` python
divmod(*t)
```
%% Cell type:markdown id:da554863 tags:
Verpacken und entpacken können nützlich sein, wenn wir das Verhalten einer schon existierenden Funktion anpassen wollen.
Diese Funktion nimmt zum Beispiel eine beliebige Anzahl von Argumenten auf, entfernt das niedrigste und das höchste und berechnet den Mittelwert vom Rest:
%% Cell type:code id:7ad64412 tags:
``` python
def getrimmt_mittel(*args):
niedrig, hoch = min_max(args)
getrimmt = list(args)
getrimmt.remove(niedrig)
getrimmt.remove(hoch)
return mittel(*getrimmt)
```
%% Cell type:markdown id:d1e05e49 tags:
Zuerst verwendet sie `min_max`, um das niedrigste und das höchste Element zu finden.
Danach konvertiert sie `args` zu einer Liste, damit die `remove`-Methode verwendet werden kann.
Zuletzt entpackt sie die Liste, sodass die Elemente als separate Argumente und nicht als eine Liste an `mitte` weitergegeben werden.
Hier ist ein Beispiel, das die Auswirkungen davon zeigt:
%% Cell type:code id:b2863701 tags:
``` python
mittel(1, 2, 3, 10)
```
%% Cell type:code id:cc1afa29 tags:
``` python
getrimmt_mittel(1, 2, 3, 10)
```
%% Cell type:markdown id:35e04996 tags:
Diese Art von "getrimmtem" Mittelwert wird in manchen Sportarten mit subjektiver Bewertung -- zum Beispiel Tauchen oder Gymnastik -- verwendet, um die Auswirkungen eines einzelnen Wertungsrichters, dessen Bewertung sich sehr von denen der anderen unterscheidet zu reduzieren.
%% Cell type:markdown id:c4572cd2 tags:
## Zip
Tupel sind praktisch, um in einer Schleife durch die Elemente zweier Folgen zu gehen und Operationen an den korrespondierenden Elementen durchzuführen.
Nehmen wir zum Beispiel an, zwei Mannschaften spielen eine Serie von sieben Spielen und wir tragen die Ergebnisse in zwei Listen ein, eine pro Team:
%% Cell type:code id:ad3e6f81 tags:
``` python
ergebnisse1 = [1, 2, 4, 5, 1, 5, 2]
ergebnisse2 = [5, 5, 2, 2, 5, 2, 3]
```
%% Cell type:markdown id:b44f228b tags:
Lasst uns nun überprüfen, wie viele Spiele jede Mannschaft gewonnen hat.
Dafür werden wir `zip` verwenden, eine eingebaute Funktion, die zwei oder mehr Folgen aufnimmt und ein **Zip-Objekt** zurückgibt, das so genannt wird, weil es die Elemente der Folgen wie die Zähnchen eines Reißverschlusses (Englisch: *zipper*) verpaart:
%% Cell type:code id:9ce313ce tags:
``` python
zip(ergebnisse1, ergebnisse2)
```
%% Cell type:markdown id:9adcf8f9 tags:
Wir können das Zip-Objekt verwenden, um in einer Schleife paarweise durch die Werte der Folgen zu gehen:
%% Cell type:code id:321d9c30 tags:
``` python
for paar in zip(ergebnisse1, ergebnisse2):
print(paar)
```
%% Cell type:markdown id:51d1dabb tags:
Bei jedem Schleifendurchlauf wird `pair` ein Tupel mit Ergebnissen zugewiesen.
Jetzt können wir die Ergebnisse Variablen zuweisen und dann folgendermaßen die Siege des ersten Teams zählen:
%% Cell type:code id:7eb73d5d tags:
``` python
siege = 0
for team1, team2 in zip(ergebnisse1, ergebnisse2):
if team1 > team2:
siege += 1
siege
```
%% Cell type:markdown id:ad740fcd tags:
Leider hat die erste Mannschaft nur drei Spiele gewonnen und damit diese Serie verloren.
Wenn wir zwei Listen haben und eine Liste mit Paaren haben wollen, können wir `zip` und `list` verwenden:
%% Cell type:code id:9529baa8 tags:
``` python
t = list(zip(ergebnisse1, ergebnisse2))
t
```
%% Cell type:markdown id:ec4249fa tags:
Das Ergebnis ist eine Liste mit Tupeln, also können wir so das Ergebnis des letzten Spiels bekommen:
%% Cell type:code id:dbde77b8 tags:
``` python
t[-1]
```
%% Cell type:markdown id:436486b9 tags:
Wenn wir eine Liste mit Schlüsseln und eine Liste mit Werten haben, können wir `zip` und `dict` verwenden, um ein assoziatives Datenfeld zu erstellen.
So können wir zum Beispiel ein assoziatives Datenfeld erstellen, das von jedem Buchstaben auf seine Position im Alphabet verweist:
%% Cell type:code id:dbb7d0b3 tags:
``` python
buchstaben = 'abcdefghijklmnopqrstuvwxyz'
zahlen = range(len(buchstaben))
buchstaben_verweis = dict(zip(buchstaben, zahlen))
```
%% Cell type:markdown id:b4de6974 tags:
Jetzt können wir nach einem Buchstaben suchen und erhalten den Index von dessen Position im Alphabet:
%% Cell type:code id:49e3fd8e tags:
``` python
buchstaben_verweis['a'], buchstaben_verweis['z']
```
%% Cell type:markdown id:cc632542 tags:
In diesem Mapping ist der Index von `'a'` `0` und der Index von `'z'` `25`.
Wenn wir in einer Schleife durch die Elemente einer Folge und deren Indizes gehen müssen, können wir die eingebaute Funktion `enumerate` verwenden:
%% Cell type:code id:9e4f3e51 tags:
``` python
enumerate('abc')
```
%% Cell type:markdown id:92ad45bb tags:
Das Ergebnis ist ein **Enumerate-Objekt** (Deutsch etwa: *Aufzählungs-Objekt*), das eine Folge von Paaren in einer Schleife durchläuft, wobei jedes Paar einen Index (beginnend bei `0`) und ein Element aus der angegebenen Folge enthält:
%% Cell type:code id:c1dcb46d tags:
``` python
for index, element in enumerate('abc'):
print(index, element)
```
%% Cell type:markdown id:cf0b55d7 tags:
## Vergleichen und Sortieren
Die relationalen Operatoren funktionieren auch mit Tupeln und anderen Folgen.
Wenn wir zum Beispiel den `<`-Operator mit Tupeln verwenden, beginnt er damit, das erste Element jeder Folge zu vergleichen.
Wenn diese gleich sind, geht er zum nächsten Elemente-Paar weiter, und so weiter und so fort, bis er ein Paar findet, das sich unterscheidet:
%% Cell type:code id:aed20c28 tags:
``` python
(0, 1, 2) < (0, 3, 4)
```
%% Cell type:markdown id:65ceea86 tags:
Nachfolgende Elemente werden nicht mehr betrachtet -- selbst wenn sie sehr groß sind:
%% Cell type:code id:4d9e73b3 tags:
``` python
(0, 1, 2000000) < (0, 3, 4)
```
%% Cell type:markdown id:55e4a35e tags:
Diese Art Tupel zu vergleichen ist praktisch, um eine Liste von Tupeln zu sortieren, oder um ein Minimum oder Maximum zu finden.
Lasst uns als ein Beispiel den häufigsten Buchstaben in einem Wort finden.
Im vorherigen Kapitel haben wir `wert_zaehlen` geschrieben, was eine Zeichenkette aufnimmt und ein assoziatives Datenfeld zurückgibt, in dem jeder Buchstabe auf die Anzahl der Male, die er vorkommt verweist:
%% Cell type:code id:2077dfa9 tags:
``` python
def wert_zaehlen(string):
zaehler = {}
for buchstabe in string:
if buchstabe not in zaehler:
zaehler[buchstabe] = 1
else:
zaehler[buchstabe] += 1
return zaehler
```
%% Cell type:markdown id:a80012c1 tags:
Hier ist das Ergebnis für die Zeichenkette `'banana'`:
%% Cell type:code id:b3d40516 tags:
``` python
zaehler = wert_zaehlen('banana')
zaehler
```
%% Cell type:markdown id:cc1ea4a7 tags:
Mit nur drei Elementen können wir leicht sehen, dass der häufigste Buchstabe das `'a'` ist, das dreimal vorkommt.
Aber gäbe es mehr Elemente, dann wäre es praktisch, diese automatisch sortieren zu können.
Wir können so die Elemente von `zaehler` erhalten:
%% Cell type:code id:8288c28f tags:
``` python
elemente = zaehler.items()
elemente
```
%% Cell type:markdown id:ac8dea7a tags:
Das Ergebnis ist ein `dict_items`-Objekt, das sich wie eine Liste von Tupeln verhält, wir können es also folgendermaßen sortieren:
%% Cell type:code id:bbbade35 tags:
``` python
sorted(elemente)
```
%% Cell type:markdown id:b690d17a tags:
Standardmäßig wird das erste Element aus jedem Tupel zum Sortieren der Liste verwendet und im Fall eines Gleichstands auf das zweite Element zurückgegriffen.
Um aber das Element mit dem höchsten Zähler zu finden, wollen wir das zweite Element zum Sortieren der Liste verwenden.
Wir können das tun, indem wir eine Funktion schreiben, die ein Tupel nimmt und dessen zweites Element zurückgibt:
%% Cell type:code id:a4c31795 tags:
``` python
def zweites_element(t):
return t[1]
```
%% Cell type:markdown id:b964aa14 tags:
Dann können wir diese Funktion an `sorted` als optionales Element namens `key` weitergeben, was anzeigt, dass diese Funktion verwendet werden soll, um den **Sortier-Schlüssel** (Englisch: *sort key*) für jedes Element zu berechnen:
%% Cell type:code id:f3d3619a tags:
``` python
elemente_sortiert = sorted(elemente, key=zweites_element)
elemente_sortiert
```
%% Cell type:markdown id:4dc96848 tags:
Der Sortier-Schlüssel bestimmt die Reihenfolge der Elemente in der Liste.
Der Buchstabe mit der niedrigsten Zahl erscheint zuerst, der Buchstabe mit der höchsten Zahl zuletzt.
So können wir wie folgt den häufigsten Buchstaben finden:
%% Cell type:code id:f078c8a6 tags:
``` python
elemente_sortiert[-1]
```
%% Cell type:markdown id:d0d8b999 tags:
Wenn wir nur das Maximum wollen, müssen wir die Liste nicht sortieren.
Wir können `max` verwenden, was ebenfalls `key` als optionales Argument aufnimmt:
%% Cell type:code id:54030d8f tags:
``` python
max(elemente, key=zweites_element)
```
%% Cell type:markdown id:8a8327df tags:
Um den Buchstaben mit der niedrigsten Zahl zu finden, könnten wir `min` auf die gleiche Weise nutzen.
%% Cell type:markdown id:a62394a5 tags:
## Assoziatives Datenfeld umkehren
Nehmen wir an, wir wollen ein assoziatives Datenfeld invertieren, sodass wir nach einem Wert suchen können und dessen korrespondierenden Schlüssel erhalten.
Wenn wir zum Beispiel einen Wortzähler haben, der von jedem Wort auf die Anzahl von dessen Vorkommen verweist, können wir ein assoziatives Datenfeld erstellen, das von ganzen Zahlen auf die Wörter verweist, die entsprechend oft vorkommen.
Aber es gibt ein Problem -- die Schlüssel in einem assoziativen Datenfeld müssen im Gegensatz zu den Werten einmalig sein. In einem Wortzähler könnte es zum Beispiel viele Wörter geben, die gleich oft vorkommen.
Ein Weg, das assoziative Datenfeld umzukehren ist also, ein neues assoziatives Datenfeld zu erstellen, in dem die Werte Listen mit Schlüsseln aus dem ursprünglichen Datenfeld sind.
Lasst uns zum Beispiel die Buchstaben in `papagei` zählen.
%% Cell type:code id:ef158f81 tags:
``` python
d = wert_zaehlen('papagei')
d
```
%% Cell type:markdown id:f4570eae tags:
Wenn wir dieses assoziative Datenfeld umkehren, sollte das Ergebnis `{2: ['p', 'a'], 1: ['g', 'e', 'i']}` sein, was darauf hinweist, dass die Buchstaben, die einmal vorkommen `'g'`, `'e'` und `'i'`, und die Buchstaben, die zweimal vorkommen `'p'` und `'a'` sind.
Die folgende Funktion nimmt ein assoziatives Datenfeld und gibt dieses umgekehrt als neues assoziatives Datenfeld zurück:
%% Cell type:code id:d3607b8d tags:
``` python
def invertiert_dict(d):
neu = {}
for schluessel, wert in d.items():
if wert not in neu:
neu[wert] = [schluessel]
else:
neu[wert].append(schluessel)
return neu
```
%% Cell type:markdown id:ca5fa025 tags:
Die `for`-Anweisung geht in einer Schleife durch die Schlüssel und Werte in `d`.
Wenn sich ein Wert noch nicht in dem neuen assoziativen Datenfeld befindet, wird er hinzugefügt und mit einer Liste verknüpft, die ein einzelnes Element enthält.
Andernfalls wird er an die bestehende Liste angehängt.
Wir können das so testen:
%% Cell type:code id:692d9cf8 tags:
``` python
invertiert_dict(d)
```
%% Cell type:markdown id:4cfb1693 tags:
Und wir erhalten das erwartete Ergebnis,
Das ist das erste Beispiel, das wir gesehen haben, in dem die Werte eines assoziativen Datenfelds Listen sind.
Weitere werden folgen!
%% Cell type:markdown id:6d138cd7 tags:
## Debuggen
Listen, assoziative Datenfelder und Tupel sind **Datenstrukturen** (Englisch: *data structures*).
In diesem Kapitel beginnen wir, zusammengesetzte Datenstrukturen zu sehen, wie Listen von Tupeln oder assoziative Datenfelder, die Tupel als Schlüssel und Listen als Werte enthalten.
Zusammengesetzte Datenstrukturen sind praktisch, aber auch anfällig für Fehler, die zum Beispiel vorkommen wenn eine Datenstruktur den falschen Datentyp, die falsche Größe oder Struktur hat.
Wenn eine Funktion zum Beispiel eine Liste aus ganzen Zahlen erwartet und Sie ihr nur eine einfache ganze Zahl geben (nicht in einer Liste), wird sie wahrscheinlich nicht funktionieren.
Um beim Debuggen dieser Art von Fehler zu helfen, habe ich ein Modul namens `structshape` geschrieben, das eine Funktion, die ebenfalls `structshape` heißt, zur Verfügung stellt. Diese nimmt jegliche Art von Datenstruktur als Argument auf und gibt eine Zeichenkette zurück, die deren Struktur beschreibt.
Sie können es hier herunterladen:
<https://raw.githubusercontent.com/AllenDowney/ThinkPython/v3/structshape.py>.
%% Cell type:code id:e9f03e91 tags:
``` python
download('https://raw.githubusercontent.com/AllenDowney/ThinkPython/v3/structshape.py');
```
%% Cell type:markdown id:646f4d55 tags:
Wir können es so importieren:
%% Cell type:code id:90ab624a tags:
``` python
from structshape import structshape
```
%% Cell type:markdown id:86cc6ccc tags:
Hier ist ein Beispiel mit einer einfachen Liste:
%% Cell type:code id:6794330f tags:
``` python
t = [1, 2, 3]
structshape(t)
```
%% Cell type:markdown id:9de4f6ec tags:
Hier ist eine Liste mit Listen:
%% Cell type:code id:54cd185b tags:
``` python
t2 = [[1,2], [3,4], [5,6]]
structshape(t2)
```
%% Cell type:markdown id:aced9984 tags:
Wenn die Elemente einer Liste nicht dem gleichen Datentypen entsprechen, gruppiert sie `structshape` nach Typ:
%% Cell type:code id:04028afd tags:
``` python
t3 = [1, 2, 3, 4.0, '5', '6', [7], [8], 9]
structshape(t3)
```
%% Cell type:markdown id:f63ff690 tags:
Hier ist eine Liste aus Tupeln:
%% Cell type:code id:b5d45c88 tags:
``` python
s = 'abc'
lt = list(zip(t, s))
structshape(lt)
```
%% Cell type:markdown id:c9ec67eb tags:
Und hier ist ein assoziatives Datenfeld mit drei Elementen, das von ganzen Zahlen zu Zeichenketten verweist:
%% Cell type:code id:15131907 tags:
``` python
d = dict(lt)
structshape(d)
```
%% Cell type:markdown id:f29bb82b tags:
Wenn es Ihnen Schwierigkeiten bereitet, einen Überblick über Ihre Datenstrukturen zu behalten, kann `structshape` helfen.
%% Cell type:markdown id:7a113d88-a078-4b89-b887-ccaed7981eef tags:
## Glossar
Legen wir uns eine Liste mit den wichtigsten Begriffen an, die wir im Kapitel 11 gelernt haben:
- verpacken:
- entpacken:
- Zip-Objekt:
- Enumerate-Objekt:
- Sortier-Schlüssel:
- Datenstruktur:
Ergänzen Sie die Liste in eigenen Worten. Das ist eine gute Erinnerungs- und Übungsmöglichkeit.
%% Cell type:markdown id:1471b3c0 tags:
## Übung
%% Cell type:code id:c65d68d2 tags:
``` python
# Diese Zelle weist Jupyter an, detallierte Debugging-Informationen auszugeben, wenn ein Laufzeitfehler
# passiert. Lassen Sie sie daher laufen, bevor Sie beginnen an den Aufgaben zu arbeiten.
%xmode Verbose
```
%% Cell type:markdown id:97a0352d tags:
### Fragen Sie einen virtuellen Assistenten
Die Übungen in diesem Kapitel könnten etwas schwieriger sein, als die in vorherigen Kapiteln, daher möchte ich Sie ermutigen, einen virtuellen Assistenten um Hilfe zu fragen.
Wenn Sie schwierigere Fragen stellen könnte Ihnen auffallen, dass die Antworten beim ersten Versuch noch nicht richtig sind, daher ist dies eine gute Möglichkeit, das Schreiben von guten Prompts und nachfolgenden Verfeinerungen zu üben.
Eine Strategie, die Sie in Erwägung ziehen könnten, ist das Zerteilen von großen Problemen in kleinere Teile, die mit einfachen Funktionen gelöst werden können.
Bitten Sie einen virtuellen Assistenten darum, diese Funktionen zu schreiben und zu testen.
Dann, sobald diese funktionieren, fragen Sie nach einer Lösung für das urspüngliche Problem.
Bei einige der Aufgaben unten mache ich Vorschläge, welche Datenstrukturen oder Algorithmen sich hier eignen würden.
Sie finden die Vorschläge vielleicht hilfreich, während Sie an den Aufgaben arbeiten, diese sind aber auch gute Prompts zum Weitergeben an einen virtuellen Assistenten.
%% Cell type:markdown id:f90e011f tags:
### Aufgabe 1
In diesem Kapitel habe ich gesagt, dass Tupel als Schlüssel in assoziativen Datenfeldern genutzt werden können, weil sie unveränderlich und dadurch hashbar sind.
Das ist aber nicht immer der Fall.
Wenn ein Tupel einen veränderbaren Wert wie etwa eine Liste oder ein assoziatives Datenfeld enthält, ist es nicht mehr hashbar, da es Elemente enthält, die nicht hashbar sind. Hier ist zum Beispiel ein Tupel, das zwei Listen mit ganzen Zahlen enthält:
%% Cell type:code id:4416fe4a tags:
``` python
liste0 = [1, 2, 3]
liste1 = [4, 5]
t = (liste0, liste1)
t
```
%% Cell type:markdown id:02799077 tags:
Schreiben Sie eine Code-Zeile, die den Wert `6` an das Ende der zweiten Liste in `t` anhängt. Wenn Sie `t` ausgeben sollte das Ergebnis `([1, 2, 3], [4, 5, 6])` sein.
%% Cell type:code id:e6eda0e4 tags:
``` python
# Lösung hierhin schreiben
```
%% Cell type:markdown id:644b1dfb tags:
Versuchen Sie, ein assoziatives Datenfeld zu erstellen, das von `t` auf eine Zeichenkette verweist und überprüfen Sie, ob Sie einen `TypeError` erhalten.
%% Cell type:code id:4fae1acc tags:
``` python
# Lösung hierhin schreiben
```
%% Cell type:markdown id:fb77a352 tags:
Für mehr Informationen zu diesem Thema fragen Sie einen virtuellen Assistenten: "Sind Tupel in Python immer hashbar?".
%% Cell type:markdown id:bdfc8c27 tags:
### Aufgabe 2
In diesem Kapitel haben wir ein assoziatives Datenfeld erstellt, dass von jedem Buchstaben zu dessen Index im Alphabet verweist:
%% Cell type:code id:855c7ed2 tags:
``` python
buchstaben = 'abcdefghijklmnopqrstuvwxyz'
zahlen = range(len(buchstaben))
buchstaben_verweis = dict(zip(buchstaben, zahlen))
```
%% Cell type:markdown id:a8cd720b tags:
Der Index von `'a'` ist zum Beispiel `0`:
%% Cell type:code id:3c921f68 tags:
``` python
buchstaben_verweis['a']
```
%% Cell type:markdown id:a04c25db tags:
Um in die andere Richtung zu gehen, können wir Listen-Indexierung verwenden.
Der Buchstabe am Index `1` ist zum Beispiel `'b'`:
%% Cell type:code id:b029b0da tags:
``` python
buchstaben[1]
```
%% Cell type:markdown id:165ab770 tags:
Wir können `buchstaben_verweis` und `buchstaben` verwenden, um Wörter mittels einer Cäsar-Chiffre zu ver- und entschlüsseln.
Eine Cäsar-Chiffre ist eine schwache Form der Verschlüsselung, bei der jeder Buchstabe um eine festgelegte Zahl von Stellen im Alphabet verschoben wird. Würde eine Verschiebung über `z` hinausgehen, wird wieder bei `a` begonnen. Zum Beispiel ist `'a'` um `2` verschoben `'c'` und `'z'` um `1` verschoben ist `'a'`.
Schreiben sie eine Funktion namens `wort_verschieben`, die als Parameter eine Zeichenkette und eine ganze Zahl aufnimmt und eine neue Zeichenkette zurückgibt, die alle Buchstaben der ursprünglichen Zeichenkette verschoben um die angegebene Anzahl Stellen enthält.
Um Ihre Funktion zu testen, überprüfen Sie, ob `"cheer"` um `7` Stellen verschoben `"jolly"` und `"melon"`um `16` Stellen verschoben `"cubed"` ergibt.
Tipps: Verwenden Sie den Modulus-Operator um vom `z` wieder zu `a` zurückzuspringen.
Gehen Sie in einer Schleife die Buchstaben des Worts, verschieben Sie diese und hängen das Ergebnis an das Ende einer Liste mit Buchstaben an.
Verwenden Sie dann `join`, um die Buchstaben zu einer Zeichenkette zu konkatenieren.
%% Cell type:markdown id:e7478b18 tags:
Verwenden Sie als Starthilfe diese Gliederung:
%% Cell type:code id:1cc07036 tags:
``` python
def wort_verschieben(wort, n):
"""Verschieben die Buchstaben von `wort` um `n` Stellen.
>>> wort_verschieben('cheer', 7)
'jolly'
>>> wort_verschieben('melon', 16)
'cubed'
"""
return None
```
%% Cell type:code id:96560a0e tags:
``` python
# Lösung hierhin schreiben
```
%% Cell type:code id:c026c6d1 tags:
``` python
wort_verschieben('cheer', 7)
```
%% Cell type:code id:5814999d tags:
``` python
wort_verschieben('melon', 16)
```
%% Cell type:markdown id:39a67af9 tags:
Sie können `doctest` verwenden, um Ihre Funktion zu testen:
%% Cell type:code id:9464d140 tags:
``` python
from doctest import run_docstring_examples
def run_doctests(func):
run_docstring_examples(func, globals(), name=func.__name__)
run_doctests(wort_verschieben)
```
%% Cell type:markdown id:779f13af tags:
### Aufgabe 3
Schreiben Sie eine Funktion namens `haeufigste_buchstaben`, die eine Zeichenkette aufnimmt und die einzelnen Buchstaben in absteigender Reihenfolge ihrer Häufigkeit ausgibt.
Um die Elemente in absteigender Reihenfolge zu erhalten können Sie `reversed` zusammen mit `sorted` verwenden, oder Sie können `reverse=True` als Schlüsselwort-Parameter an `sorted` übergeben.
%% Cell type:markdown id:d71923e6 tags:
Als Einstieg können Sie diese Skizze der Funktion verwenden:
%% Cell type:code id:4309d0b5 tags:
``` python
def haeufigste_buchstaben(zeichenkette):
return None
```
%% Cell type:code id:52228828 tags:
``` python
# Lösung hierhin schreiben
```
%% Cell type:markdown id:c6354c44 tags:
Und dieses Beispiel können Sie verwenden, um Ihre Funktion zu testen:
%% Cell type:code id:3bf2aa0d tags:
``` python
haeufigste_buchstaben('brontosaurus')
```
%% Cell type:markdown id:2ca1e337 tags:
Sobald Ihre Funktion funktioniert können Sie den folgenden Code verwenden, um die häufigsten Buchstaben aus *Dracula* auszugeben (der Text kann über Projekt Gutenberg heruntergeladen werden):
%% Cell type:code id:e4fbf5d9 tags:
``` python
download('https://www.gutenberg.org/cache/epub/345/pg345.txt');
```
%% Cell type:code id:817ec689 tags:
``` python
zeichenkette = open('pg345.txt').read()
haeufigste_buchstaben(zeichenkette)
```
%% Cell type:markdown id:211c09c9 tags:
Nach Zims "Codes and Secret Writing" beginnt die Buchstabenfolge für die englische Sprache, absteigend nach Häufigkeit sortiert, mit "ETAONRISH".
Wie lässt sich diese Folge mit den Ergebnissen von *Dracula* vergleichen?
%% Cell type:markdown id:cbe9933e tags:
### Aufgabe 4
In einer vorherigen Übung haben wir getestet, ob zwei Zeichenketten Anagramme voneinander sind, indem wir die Buchstaben beider Wörter sortiert, und überprüft haben ob diese gleich sind.
Lasst uns nun das gleiche Problem etwas herausfordernder machen.
Wir werden ein Programm schreiben, das eine Wortliste aufnimmt und alle Wortgruppen daraus ausgibt, die Anagramme sind.
Der Output könnte zum Beispiel so aussehen:
['deltas', 'desalt', 'lasted', 'salted', 'slated', 'staled']
['retainers', 'ternaries']
['generating', 'greatening']
['resmelts', 'smelters', 'termless']
Tipp: Sortieren Sie für jedes Wort in der Liste die Buchstaben und verbinden Sie zu einer Zeichenkette. Erstellen Sie nun ein assoziatives Datenfeld `anagramm_dict`, das von dieser geordneten Zeichenkette auf eine Liste mit Wörtern verweist, die dessen Anagramme sind.
%% Cell type:markdown id:4b9ed2a8 tags:
Die folgende Zelle lädt `words.txt` herunter und liest die Wörter in eine Liste ein:
%% Cell type:code id:941719c1 tags:
``` python
download('https://raw.githubusercontent.com/AllenDowney/ThinkPython/v3/words.txt');
```
%% Cell type:code id:d2ec641b tags:
``` python
wort_liste = open('words.txt').read().split()
```
%% Cell type:markdown id:e4cc2c8c tags:
Hier ist die `wort_sortieren`-Funktion, die wir schon verwendet haben:
%% Cell type:code id:7ae29f73 tags:
``` python
def wort_sortieren(wort):
return ''.join(sorted(wort))
```
%% Cell type:code id:013819a5 tags:
``` python
# Lösung hierhin schreiben
```
%% Cell type:markdown id:70faa9f5 tags:
Um die längste Liste mit Anagrammen zu finden können Sie die folgende Funktion verwenden, die ein Schlüssel-Wert-Paar aufnimmt, bei dem der Schlüssel eine Zeichenkette und der Wert eine Liste mit Wörtern ist.
Sie gibt die Länge der Liste zurück:
%% Cell type:code id:fbf9ede3 tags:
``` python
def wert_laenge(paar):
schluessel, wert = paar
return len(wert)
```
%% Cell type:markdown id:dcda6e28 tags:
Wir können diese Funktion als Sortierschlüssel verwenden, um die längste Anagramm-Liste zu finden:
%% Cell type:code id:55435050 tags:
``` python
anagramm_elemente = sorted(anagramm_dict.items(), key=wert_laenge)
for schluessel, wert in anagramm_elemente[-10:]:
print(wert)
```
%% Cell type:markdown id:0b6d5add tags:
Wenn Sie die längsten Wörter, von denen es Anagramme gibt erfahren wollen, verwenden Sie die folgende Schleife um einige von ihnen auszugeben:
%% Cell type:code id:6a9320c2 tags:
``` python
laengste = 7
for schluessel, wert in anagramm_elemente:
if len(wert) > 1:
wort_laenge = len(wert[0])
if wort_laenge > laengste:
laengste = wort_laenge
print(wert)
```
%% Cell type:markdown id:4fbe939e tags:
### Aufgabe 5
Schreiben Sie eine Funktion namens `wort_distanz`, die zwei Wörter derselben Länge aufnimmt, und die Anzahl der Stellen zurückgibt, an denen sich diese unterscheiden.
Tipp: Verwenden Sie `zip`, um in einer Schleife durch die korrespondierenden Buchstaben der Wörter zu gehen.
%% Cell type:markdown id:8b48dbdc tags:
Hier ist eine Gliederung der Funktion mit Doctests, die Sie verwenden können, um Ihre Funktion zu testen:
%% Cell type:code id:3d5a75f8 tags:
``` python
def wort_distanz(wort1, wort2):
"""Berechnet die Anzahl der Stellen, an denen sich die beiden Wörter unterscheiden.
>>> wort_distanz("hello", "hxllo")
1
>>> wort_distanz("ample", "apply")
2
>>> wort_distanz("kitten", "mutton")
3
"""
return None
```
%% Cell type:code id:a9816dde tags:
``` python
# Lösung hierhin schreiben
```
%% Cell type:code id:753a23c1 tags:
``` python
from doctest import run_docstring_examples
def run_doctests(func):
run_docstring_examples(func, globals(), name=func.__name__)
run_doctests(wort_distanz)
```
%% Cell type:markdown id:066eec59 tags:
### Aufgabe 6
"Metathese“ bezeichnet das Vertauschen von Buchstaben in einem Wort.
Zwei Wörter bilden ein "Metathese-Paar“, wenn man das eine in das andere umwandeln kann, indem man zwei Buchstaben vertauscht, wie zum Beispiel bei `converse` und `conserve`.
Schreiben Sie ein Programm, das alle Metathesepaare in der Wortliste findet.
Tipp: Die Wörter in einem Metathesepaar müssen Anagramme voneinander sein.
Credit: Diese Aufgabe ist inspiriert von einem Beispiel auf <http://puzzlers.org>.
%% Cell type:code id:57649075 tags:
``` python
# Lösung hierhin schreiben
```
%% Cell type:markdown id:6a028806 tags:
### Aufgabe 7
Dies ist eine Bonus-Aufgabe, die sich nicht im Buch befindet.
Sie ist schwieriger als die anderen Übungen in diesem Kapitel, also fragen Sie vielleicht einen virtuellen Assistenten um Hilfe oder kommen Sie auf die Aufgabe zurück, nachdem Sie weitere Kapitel gelesen haben.
Hier ist ein weiterer Car Talk Puzzler
(<http://www.cartalk.com/content/puzzlers>):
> Welches ist das längste englische Wort, das ein gültiges Wort bleibt,
> nachdem man einen Buchstaben nach dem anderen entfernt hat?
>
> Buchstaben können von beiden Enden des Wortes und aus dessen Mitte entfernt werden, aber Sie dürfen
> keine der Buchstaben vertauschen. Jedes Mal wenn Sie einen Buchstaben entfernen,
> erhalten Sie ein neues Wort. Wenn Sie das eine Weile tun, enden Sie irgendwann bei einem
> einzelnen Buchstaben und auch dieser wird ein englisches Wort sein --
> eines, das im Wörterbuch steht. Ich will nun wissen, welches das längste Wort ist
> und wie viele Buchstaben dieses hat.
>
> Ich werde hierfür ein kleines Beispiel geben: "Sprite". Ok? Wir beginnen mit
> `"sprite"`, entfernen einen Buchstaben aus der Mitte des Wortes, in diesem Fall das `r`,
> und erhalten das Wort `"spite"`, davon entfernen wir das `e` und bekommen `"spit"`,
> wovon wir wiederum das `s` entfernen und `"pit"` bekommen, dann `"it"` und zuletzt `"I"`.
Schreiben Sie ein Programm, das alle Wörter findet, die auf diese Weise reduziert werden können und finden Sie von diesen das schließlich das Längste.
Diese Übung ist ein bisschen schwieriger als die meisten anderen, also sind hier einige Empfehlungen:
1. Sie sollten vielleicht eine Funktion schreiben, die für ein Wort eine Liste aller Wörter berechnet, die daraus durch Entfernen eines Buchstabens gebildet werden können. Das sind die "Kinder“ dieses Wortes.
2. Rekursiv ist ein Wort reduzierbar, wenn eines seiner Kinder reduzierbar ist. Als Basisfall können Sie die leere Zeichenkette als reduzierbar betrachten.
3. Die Wortliste, die wir bisher verwendet haben enthält keine Wörter aus einzelnen Buchstaben. Also sollten Sie vielleicht "I" und "a" hinzufügen.
4. Um die Leistung Ihres Programmes zu verbessern könnten Sie die Wörter, von denen schon bekannt ist, dass sie reduzierbar sind memoisieren.
%% Cell type:code id:c19bf833 tags:
``` python
# Lösung hierhin schreiben
```
%% Cell type:code id:2d9764d6 tags:
``` python
# Lösung hierhin schreiben
```
%% Cell type:code id:5e4f5d8e tags:
``` python
# Lösung hierhin schreiben
```
%% Cell type:code id:27d311dd tags:
``` python
# Lösung hierhin schreiben
```
%% Cell type:code id:68c27c7e tags:
``` python
# Lösung hierhin schreiben
```
%% Cell type:markdown id:e01fcbe0-9b3f-4e8f-8e8a-807c50a2154a 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:ca074907-29ea-4a54-9573-9e468d491860 tags:
![Smiley](https://upload.wikimedia.org/wikipedia/commons/3/3e/Cool-smiley.svg)
Herzlichen Glückwunsch! Sie haben das 11. Kapitel geschafft.
%% Cell type:markdown id:5cf853f4-5575-408c-8446-bc993452dc66 tags:
<img src="https://scm.cms.hu-berlin.de/ibi/python/-/raw/master/img/by-nc-sa.png" alt="CC BY-NC-SA" style="width: 150px;"/>
Der Text dieses Notebooks ist als freies Werk unter der Lizenz [CC BY-NC-SA 4.0 ](https://creativecommons.org/licenses/by-nc-sa/4.0/) verfügbar.
Der Code dieses Notebooks ist als freies Werk unter der Lizenz [MIT License](https://mit-license.org/) verfügbar.
Es handelt sich um übersetzte und leicht veränderte Notebooks von [Allen B. Downey](https://allendowney.com) aus [Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html).
%% Cell type:markdown id:59a8621b tags:
# Kapitel 12: Textanalyse und -generierung
[Chapter 12: Text Analysis and Generation](https://colab.research.google.com/github/AllenDowney/ThinkPython/blob/v3/chapters/chap12.ipynb)
Bis zu diesem Zeitpunkt haben wir uns mit den Datenstrukturen beschäftigt, die den Kern von Python bilden -- Listen, assoziative Datenfelder und Tupel -- und mit einigen Algorithmen, die diese verwenden.
In diesem Kapitel werden wir sie benutzen, um Textanalyse und Markov-Generierung zu erforschen:
* **Textanalyse** ist ein Weg, die statistischen Beziehungen zwischen Wörtern in einem Dokument zu beschreiben, also wie wahrscheinlich es zum Beispiel ist, dass ein Wort auf ein anderes folgt, und
* **Markov-Generierung** ist ein Weg, neuen Text aus Wörtern und Phrasen, die dem Original-Text ähneln zu generieren.
Diese Algorithmen ähneln in Teilen **Large Language Models** (LLM), die der Hauptbestandteil von Chatbots sind.
WIr werden damit beginnen zu zählen, wie oft jedes Wort in einem Buch vorkommt.
Dann werden wir Wortpaare betrachten und für jedes Wort eine Liste mit Wörtern, die diesem folgen anlegen.
Wir werden eine einfache Version eines Markov-Generators erstellen und in den Übungsaufgaben werden Sie die Möglichkeit haben, eine allgemeinere Version von diesem zu bauen.
### 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:
-
-
-
%% Cell type:markdown id:9a0b03e4-0e53-40b4-8850-5fa03078f99a tags:
## Herunterladen des unterstützenden Codes
Die folgende Zelle lädt eine Datei herunter und führt einen Code aus, der speziell für dieses Notebook verwendet wird. Sie müssen diesen Code nicht verstehen, aber Sie sollten die Zelle vor allen weiteren Zellen in diesem Notebook ausführen:
%% Cell type:code id:6c6265de tags:
``` python
from os.path import basename, exists
def download(url):
filename = basename(url)
if not exists(filename):
from urllib.request import urlretrieve
local, _ = urlretrieve(url, filename)
print("Downloaded " + str(local))
return filename
download('https://github.com/AllenDowney/ThinkPython/raw/v3/thinkpython.py');
download('https://github.com/AllenDowney/ThinkPython/raw/v3/diagram.py');
import thinkpython
```
%% Cell type:markdown id:0e3811b8 tags:
## Einzigartige Wörter
Lasst uns als ersten Schritt in Richtung Textanalyse ein Buch lesen -- *The Strange Case Of Dr. Jekyll And Mr. Hyde* (Deutsch: *Der seltsame Fall des Dr. Jekyll und Mr. Hyde*) von Robert Louis Stevenson -- und die Menge der einzigartigen Wörter darin zählen.
Anweisungen für das Herunterladen des Buches befinden sich im Notebook zu diesem Kapitel.
%% Cell type:markdown id:6567e1bf tags:
Die folgende Zelle lädt das Buch von Projekt Gutenberg herunter:
%% Cell type:code id:4cd1c980 tags:
``` python
download('https://www.gutenberg.org/cache/epub/43/pg43.txt');
```
%% Cell type:markdown id:5465ab1d tags:
Die Version von Projekt Gutenberg enthält am Anfang Informationen über das Buch und am Ende Lizenzinformationen.
Wir werden `datei_bereinigt` aus Kapitel 8 verwenden, um dieses Material zu entfernen und eine "bereinigte" Datei zu schreiben, die nur den Text des Buches enthält.
%% Cell type:code id:52ebfe94 tags:
``` python
def ist_spezielle_zeile(zeile):
return zeile.strip().startswith('*** ')
```
%% Cell type:code id:49cfc352 tags:
``` python
def datei_bereinigt(input_datei, output_datei):
leser = open(input_datei, encoding='utf-8')
schreiber = open(output_datei, 'w')
for zeile in leser:
if ist_spezielle_zeile(zeile):
break
for zeile in leser:
if ist_spezielle_zeile(zeile):
break
schreiber.write(zeile)
leser.close()
schreiber.close()
```
%% Cell type:code id:44e53ce6 tags:
``` python
dateiname = 'dr_jekyll.txt'
```
%% Cell type:code id:50d1fafa tags:
``` python
datei_bereinigt('pg43.txt', dateiname)
```
%% Cell type:markdown id:bc66d7e2 tags:
Wir werden eine `for`-Schleife nutzen, um die Zeilen der Datei zu lesen und `split`, um diese Zeilen in Wörter aufzuteilen.
Dann werden wir, um einen Überblick über die einzigartigen Wörter zu erhalten, jedes Wort als Schlüssel eines assoziativen Datenfelds speichern:
%% Cell type:code id:16d24028 tags:
``` python
einzigartige_woerter = {}
for zeile in open(dateiname):
seq = zeile.split()
for wort in seq:
einzigartige_woerter[wort] = 1
len(einzigartige_woerter)
```
%% Cell type:markdown id:85171a3a tags:
Die Länge des assoziativen Datenfelds ist die Anzahl der einzigartigen Wörter -- etwa `6000` wenn wir auf diese Weise zählen.
Aber bei genauerer Inspektion fällt auf, dass einige Einträge keine gültigen Wörter sind.
Lasst uns zum Beispiel die längsten Wörter in `einzigartige_woerter` betrachten.
Wir können `sorted` verwenden, um die Wörter zu sortieren und die `len`-Funktion als Schlüsselwort-Argument übergeben, sodass die Wörter nach ihrer Länge geordnet werden:
%% Cell type:code id:1668e6bd tags:
``` python
sorted(einzigartige_woerter, key=len)[-5:]
```
%% Cell type:markdown id:795f5327 tags:
Der Segment-Index, `[-5:]`, wählt die letzten `5` Elemente der sortierten Liste aus, was hier die längsten Wörter sind.
Die Liste enthält einige wirklich lange Wörter, wie `"circumscription"`, und einige Wörter mit Bindestrich, wie `"chocolate-coloured"`.
Aber einige der längsten "Wörter" sind eigentlich zwei durch einen Gedankenstrich getrennte Wörter.
Und andere Wörter enthalten Interpunktion wie Punkte, Ausrufezeichen oder Anführungszeichen.
Also müssen wir uns bevor wir weitermachen um Gedankenstriche und andere Interpunktion kümmern.
%% Cell type:markdown id:bf89fafa tags:
## Interpunktion
Um die Wörter im Text zu identifizieren, müssen wir uns um zwei Aspekte kümmern:
* Wenn ein Gedankenstrich in einer Zeile auftaucht, soll er durch ein Leerzeichen ersetzt werden -- wenn wir dann `split` verwenden, werden die Wörter getrennt.
* Nachdem wir die Wörter getrennt haben, können wir `strip` verwenden, um Interpunktion zu entfernen.
Um den ersten Aspekt zu behandeln, können wir die folgende Funktion verwenden, die eine Zeichenkette aufnimmt, Gedankenstriche mit Leerzeichen ersetzt, die Zeichenkette zerteilt und die daraus resultierende Liste zurückgibt:
%% Cell type:code id:ed5f0a43 tags:
``` python
def zeile_teilen(zeile):
return zeile.replace('', ' ').split()
```
%% Cell type:markdown id:d5decdec tags:
Beachten Sie, dass `zeile_teilen` nur Gedankenstriche ersetzt, keine Bindestriche.
Hier ist ein Beispiel:
%% Cell type:code id:a9df2aeb tags:
``` python
zeile_teilen('coolness—frightened')
```
%% Cell type:markdown id:0d9eb318 tags:
Jetzt können wir, um die Interpunktion am Anfang und Ende jedes Wortes zu entfernen, `strip` verwenden. Dafür brauchen wir aber zuerst eine Liste mit allen Zeichen, die als Interpunktion betrachtet werden.
Zeichen in Python-Zeichenketten sind in Unicode codiert, was ein internationaler Standard ist, der verwendet wird um Buchstaben aus fast jedem Alphabet, Zahlen, Symbole, Interpunktionszeichen und mehr darzustellen.
Das `unicodedata`-Modul stellt eine `category`-Funktion zur Verfügung, die wir nutzen können um zu beurteilen welche Zeichen zur Interpunktion gehören.
Wenn der Funktion ein Buchstabe übergeben wird, gibt sie einen String mit Informationen darüber, welcher Kategorie der Buchstabe angehört zurück:
%% Cell type:code id:b138b123 tags:
``` python
import unicodedata
unicodedata.category('A')
```
%% Cell type:markdown id:994835ea tags:
Die Kategorie-Zeichenkette von `'A'` ist `'Lu'` -- das `'L'` bedeutet, es ist ein Buchstabe (Enlisch: _**l**etter_) und das `'u'` sagt aus, dass dieser großgeschrieben (Englisch: _**u**ppercase_) ist.
Die Kategorie-Zeichenkette von `'.'` ist `'Po'` -- das `'P'` bedeutet, es ist Interpunktion (Englisch: _**p**unctuation_) und das `'o'` zeigt an, dass die Subkategorie "andere" (Englisch: _**o**ther_) ist.
%% Cell type:code id:fe65df44 tags:
``` python
unicodedata.category('.')
```
%% Cell type:markdown id:03773b9b tags:
Wir können die Interpunktionszeichen im Buch finden, indem wir nach den Zeichen der Kategorien, die mit `'P'` beginnen suchen.
Die folgende Schleife speichert die einzigartigen Interpunktionszeichen in einem assoziativen Datenfeld:
%% Cell type:code id:b47a87cf tags:
``` python
interp_zeichen = {}
for zeile in open(dateiname):
for zeichen in zeile:
kategorie = unicodedata.category(zeichen)
if kategorie.startswith('P'):
interp_zeichen[zeichen] = 1
```
%% Cell type:markdown id:e6741dfa tags:
Um eine Liste mit Interpunktionszeichen zu machen können wir die Schlüssel des assoziativen Datenfelds zu einer Zeichenkette zusammenfügen:
%% Cell type:code id:348949be tags:
``` python
interpunktion = ''.join(interp_zeichen)
print(interpunktion)
```
%% Cell type:markdown id:6af8d5a2 tags:
Jetzt wo wir wissen, welche der Zeichen im Buch zur Interpunktion gehören, können wir eine Funktion schreiben, die ein Wort aufnimmt, mögliche Interpunktion an dessen Anfang und Ende entfernt und es in Kleinbuchstaben konvertiert:
%% Cell type:code id:06121901 tags:
``` python
def wort_bereinigt(wort):
return wort.strip(interpunktion).lower()
```
%% Cell type:markdown id:58a78cb1 tags:
Hier ist ein Beispiel:
%% Cell type:code id:881ed9f8 tags:
``` python
wort_bereinigt('“Behold!”')
```
%% Cell type:markdown id:314e4fbd tags:
Weil `strip` Zeichen vom Anfang und Ende eines Wortes entfernt, werden Worte mit Bindestrich in Ruhe gelassen:
%% Cell type:code id:ab5d2fed tags:
``` python
wort_bereinigt('pocket-handkerchief')
```
%% Cell type:markdown id:99050f8a tags:
Hier ist nun eine Schleife, die `zeile_teilen` und `wort_bereinigt` verwendet, um die einzigartigen Wörter im Buch zu identifizieren:
%% Cell type:code id:2fdfb936 tags:
``` python
einzigartige_woerter2 = {}
for zeile in open(dateiname):
for wort in zeile_teilen(zeile):
wort = wort_bereinigt(wort)
einzigartige_woerter2[wort] = 1
len(einzigartige_woerter2)
```
%% Cell type:markdown id:992e5466 tags:
Mit dieser engeren Definition davon, was ein Wort ist, gibt es nur noch etwa 4000 verschiedene Wörter im Text.
Und wir können überprüfen, dass die Liste der längsten Wörter aufgeräumt wurde:
%% Cell type:code id:3104d191 tags:
``` python
sorted(einzigartige_woerter2, key=len)[-5:]
```
%% Cell type:markdown id:8014c330 tags:
Lasst uns jetzt schauen, wie oft jedes Wort verwendet wird.
%% Cell type:markdown id:7ef40180 tags:
## Worthäufigkeiten
Die folgende Schleife berechnet die Häufigkeit jedes einzigartigen Wortes:
%% Cell type:code id:4fba7d1c tags:
``` python
wort_zaehler = {}
for zeile in open(dateiname):
for wort in zeile_teilen(zeile):
wort = wort_bereinigt(wort)
if wort not in wort_zaehler:
wort_zaehler[wort] = 1
else:
wort_zaehler[wort] += 1
```
%% Cell type:markdown id:bd680b81 tags:
Das erste Mal wenn wir ein Wort sehen, initialisieren wir dessen Häufigkeit mit `1`. Wenn wir das gleiche Wort später noch einmal sehen, inkrementieren wir seine Häufigkeit.
Um zu sehen, welche Wörter am häufigsten vorkommen, können wir `items` verwenden und damit die Schlüssel-Wert-Paare von `wort_zaehler` erhalten, sowie diese anschließend nach dem zweiten Element des Paares, also der Häufigkeit, sortieren.
Zuerst definieren wir eine Funktion, die das zweite Element auswählt:
%% Cell type:code id:4be34c95 tags:
``` python
def zweites_element(t):
return t[1]
```
%% Cell type:markdown id:b15a5bd6 tags:
Jetzt können wir `sorted` mit zwei Schlüsselwort-Argumenten verwenden:
* `key=zweites_element` bedeutet, dass die Elemente nach der Häufigkeit der Wörter sortiert werden.
* `reverse=True` bedeutet, dass die Elemente in umgekehrter (Englisch: *reverse*) Reihenfolge sortiert werden, sodass die am häufigsten verwendeten Wörter zuerst kommen.
%% Cell type:code id:8efe7c4c tags:
``` python
elemente = sorted(wort_zaehler.items(), key=zweites_element, reverse=True)
```
%% Cell type:markdown id:db6812e2 tags:
Hier sind die fünf häufigsten Wörter:
%% Cell type:code id:79c17341 tags:
``` python
for wort, haeufigkeit in elemente[:5]:
print(haeufigkeit, wort, sep='\t')
```
%% Cell type:markdown id:551e81bb tags:
Im nächsten Abschnitt werden wir diese Schleife in eine Funktion verkapseln.
Und wir werden sie verwenden, um ein neues Feature darzustellen -- optionale Parameter.
%% Cell type:markdown id:45243ccc tags:
## Optionale Parameter
Wir haben bereits eingebaute Funktionen verwendet, die optionale Parameter aufnehmen.
`round` nimmt zum Beispiel einen optionalen Parameter namens `ndigits` auf, der angibt, wie viele Dezimalstellen behalten werden sollen:
%% Cell type:code id:838bcb4f tags:
``` python
round(3.141592653589793, ndigits=3)
```
%% Cell type:markdown id:6ae60945 tags:
Aber das geht nicht nur mit eingebauten Funktionen -- wir können auch selbst Funktionen mit optionalen Parametern schreiben.
Die folgende Funktion nimmt zum Beispiel zwei Parameter, `wort_zaehler` und `num`, auf:
%% Cell type:code id:90c45e7e tags:
``` python
def print_am_haeufigsten(wort_zaehler, num=5):
elemente = sorted(wort_zaehler.items(), key=zweites_element, reverse=True)
for wort, haeufigkeit in elemente[:num]:
print(haeufigkeit, wort, sep='\t')
```
%% Cell type:markdown id:78cb1531 tags:
Der zweite Parameter sieht wie eine Zuweisung aus, das stimmt aber nicht -- es ist ein optionaler Parameter.
Wenn wir diese Funktion mit einem Argument aufrufen, erhält `num` den **Standardwert** (Englisch: *default value*), der hier `5` ist:
%% Cell type:code id:e106be95 tags:
``` python
print_am_haeufigsten(wort_zaehler)
```
%% Cell type:markdown id:29753ad6 tags:
Wenn wir die Funktion mit zwei Argumenten aufrufen, wird `num` statt des Standardwerts das zweite Argument zugewiesen:
%% Cell type:code id:8101a510 tags:
``` python
print_am_haeufigsten(wort_zaehler, 3)
```
%% Cell type:markdown id:e9bf907b tags:
In diesem Fall würde man sagen, dass das optionale Argument den Standardwert **überschreibt** (Englisch: *override*).
Wenn eine Funktion sowohl verbindliche als auch optionale Parameter hat, müssen die verbindlichen Parameter alle zuerst kommen, gefolgt von den optionalen:
%% Cell type:code id:c046117b tags:
``` python
%%expect SyntaxError
def schlechte_funktion(n=5, wort_zaehler):
return None
```
%% Cell type:markdown id:3f450df2 tags:
## Subtraktion assoziativer Datenfelder
Nehmen wir einmal an, wir wollen eine Rechtschreibprüfung für ein Buch vornehmen -- also eine Liste von Wörtern finden, die falsch geschrieben sein könnten.
Eine Art das zu tun ist es, die Wörter im Buch zu finden, die nicht in einer Liste mit zulässigen Wörtern auftauchen.
In vorherigen Kapiteln haben wir eine Liste mit Wörtern, die für Wortspiele wie Scrabble als gültig angesehen werden, verwendet.
Jetzt werden wir diese Liste nutzen, um die Rechtschreibung von Robert Louis Stevenson zu kontrollieren.
Wir können uns dieses Problem als Mengensubtraktion vorstellen -- wir wollen alle Wörter aus einer Menge (die Wörter im Buch) finden, die in der anderen Menge (die Wörter in der Liste) nicht enthalten sind.
%% Cell type:markdown id:a3804d82 tags:
Die folgende Zelle lädt die Wortliste herunter:
%% Cell type:code id:edd8ff1c tags:
``` python
download('https://raw.githubusercontent.com/AllenDowney/ThinkPython/v3/words.txt');
```
%% Cell type:markdown id:2a46556c tags:
Wie wir es schon zuvor getan haben, können wir den Inhalt von `words.txt` lesen und in eine Liste von Zeichenketten aufteilen:
%% Cell type:code id:67ef3e08 tags:
``` python
wort_liste = open('words.txt').read().split()
```
%% Cell type:markdown id:22becbab tags:
Dann legen wir die Wörter als Schlüssel in einem assoziativen Datenfeld ab, damit wir den `in`-Operator verwenden können, um schnell zu überprüfen ob ein Wort zulässig ist:
%% Cell type:code id:471d58e9 tags:
``` python
gueltige_woerter = {}
for wort in wort_liste:
gueltige_woerter[wort] = 1
```
%% Cell type:markdown id:94cc7c61 tags:
Um jetzt Wörter zu identifizieren, die im Buch vorkommen, aber nicht in der Wortliste, werden wir `subtrahieren` verwenden, was zwei assoziative Datenfelder als Parameter aufnimmt und ein neues assoziatives Datenfeld zurückgibt, das alle Schlüssel aus dem einen Datenfeld enthält, die sich nicht im anderen befinden:
%% Cell type:code id:4d4c3538 tags:
``` python
def subtrahieren(feld1, feld2):
ergebnis = {}
for schluessel in feld1:
if schluessel not in feld2:
ergebnis[schluessel] = feld1[schluessel]
return ergebnis
```
%% Cell type:markdown id:e70c63b4 tags:
Das verwenden wir folgendermaßen:
%% Cell type:code id:8b42e014 tags:
``` python
diff = subtrahieren(wort_zaehler, gueltige_woerter)
```
%% Cell type:markdown id:f8ada7bd tags:
Um ein paar Beispiele für eventuell falschgeschriebene Wörter zu erhalten, können wir die häufigsten Wörter aus `diff` ausgeben:
%% Cell type:code id:f48be152 tags:
``` python
print_am_haeufigsten(diff)
```
%% Cell type:markdown id:deeec418 tags:
Die häufigsten "falschgeschriebenen" Wörter sind größtenteils Namen und einige einbuchstabige Wörter (Mr. Utterson ist ein Freund von Dr. Jekyll und dessen Anwalt).
Wenn wir Wörter auswählen, die nur einmal vorkommen, ist es wahrscheinlicher, dass diese tatsächliche Fehler sind.
Das können wir tun, indem wir in einer Schleife durch die Elemente gehen und eine Liste mit Wörtern der Häufigkeit `1` erstellen:
%% Cell type:code id:5716f967 tags:
``` python
einzelfaelle = []
for wort, haeufigkeit in diff.items():
if haeufigkeit == 1:
einzelfaelle.append(wort)
```
%% Cell type:markdown id:98ae9281 tags:
Hier sind die letzten paar Elemente dieser Liste:
%% Cell type:code id:b37219f5 tags:
``` python
einzelfaelle[-5:]
```
%% Cell type:markdown id:c5040834 tags:
Die meisten von ihnen sind gültige Wörter, die sich nicht in der Wortliste befinden.
Aber `'reindue'` scheint eine falschgeschriebene Version von `'reinduce'` zu sein, also haben wir zumindest einen wirklichen Fehler gefunden.
%% Cell type:markdown id:afcbbe19 tags:
## Zufallszahlen
Als einen weiteren Schritt in Richtung Markov-Text-Generierung werden wir nun eine zufällige Abfolge von Wörtern aus `wort_zaehler` erstellen.
Aber lasst uns zuerst über Zufälligkeit sprechen.
Die meisten Computer-Programme sind bei gleichen Eingaben **deterministisch**, das bedeutet sie generieren jedes Mal den gleichen Output.
Determinismus ist normalerweise eine gute Sache, da wir für gewöhnlich erwarten, dass die gleiche Berechnung das gleiche Ergebnis liefert.
Für manche Anwendungsfälle möchten wir aber, dass der Computer unvorhersehbar ist.
Spiele sind ein Beispiel dafür, es gibt aber noch mehr.
Ein Programm wirklich nicht-deterministisch zu machen, erweist sich als schwierig, aber es gibt Wege, es vorzutäuschen.
Einer ist es, Algorithmen zu verwenden, die **pseudozufällige** Zahlen generieren.
Pseudozufällige Zahlen sind nicht wirklich zufällig, weil sie durch deterministische Berechnung generiert werden, aber durch reine Betrachtung sind sie nahezu unmöglich von zufälligen Zahlen zu unterscheiden.
Das `random`-Modul stellt Funktionen zur Verfügung, die pseudozufällige Zahlen generieren -- diese werde ich von hier an einfach "zufällig" nennen.
Wir können es so importieren:
%% Cell type:code id:75b548a9 tags:
``` python
import random
```
%% Cell type:code id:2bfa31ae tags:
``` python
# diese Zelle initialisiert den Generator für Zufallszahlen so, dass dieser
# bei jedem Durchlauf des Notebooks die gleiche Folge generiert.
random.seed(4)
```
%% Cell type:markdown id:8cbbd7f8 tags:
Das `random`-Modul bietet eine Funktion namens `choice`, die zufällig ein Element aus einer Liste auswählt, wobei jedes Element mit gleicher Wahrscheinlichkeit ausgewählt werden könnte:
%% Cell type:code id:6f5d5c1c tags:
``` python
t = [1, 2, 3]
random.choice(t)
```
%% Cell type:markdown id:57c15af2 tags:
Wenn wir die Funktion erneut aufrufen, erhalten wir vielleicht wieder das gleiche Element -- oder ein anderes:
%% Cell type:code id:1445068b tags:
``` python
random.choice(t)
```
%% Cell type:markdown id:6f0c2572 tags:
Auf lange Sicht erwarten wir, dass wir jedes Element etwa gleich oft auftaucht.
Wenn wir `choice` mit einem assoziativen Datenfeld nutzen, erhalten wir einen `KeyError`:
%% Cell type:code id:4fc47ecd tags:
``` python
%%expect KeyError
random.choice(wort_zaehler)
```
%% Cell type:markdown id:592722f3 tags:
Um einen zufälligen Schlüssel auszuwählen, müssen wir zuerst die Schlüssel in einer Liste speichern und dann `choice` aufrufen:
%% Cell type:code id:91ae9d4c tags:
``` python
woerter = list(wort_zaehler)
random.choice(woerter)
```
%% Cell type:markdown id:172d72f6 tags:
Wenn wir eine zufällige Folge von Wörtern generieren, ergibt diese nicht viel Sinn:
%% Cell type:code id:8bf595c1 tags:
``` python
for i in range(6):
wort = random.choice(woerter)
print(wort, end=' ')
```
%% Cell type:markdown id:e0e2fbc4 tags:
Teil des Problems ist es, dass wir bisher nicht beachtet haben, dass einige Wörter häufiger vorkommen als andere.
Die Ergebnisse werden besser, wenn wir Wörter mit unterschiedlichem "Gewicht" auswählen, sodass manche häufiger gewählt werden als andere.
Wenn wir die Werte aus `wort_zaehler` als Gewichte verwenden, wird jedes Wort mit einer Wahrscheinlichkeit ausgewählt, die von seiner Häufigkeit abhängt:
%% Cell type:code id:22953b65 tags:
``` python
gewichte = wort_zaehler.values()
```
%% Cell type:markdown id:5098bf93 tags:
Das `random`-Modul bietet eine weitere Funktion namens `choices`, die Gewichte als optionales Argument aufnimmt:
%% Cell type:code id:1c7cdf4d tags:
``` python
random.choices(woerter, weights=gewichte)
```
%% Cell type:markdown id:a3341e84 tags:
Sie nimmt ein weiteres optionales Argument, `k`, auf, das die Anzahl der auszuwählenden Wörter vorgibt:
%% Cell type:code id:a7a3aa42 tags:
``` python
zufaellige_woerter = random.choices(woerter, weights=gewichte, k=6)
zufaellige_woerter
```
%% Cell type:markdown id:e57e6f3d tags:
Das Ergebnis ist eine Liste mit Zeichenketten, die wir zu etwas zusammenfügen können, das schon mehr nach einem Satz aussieht:
%% Cell type:code id:c4286fb3 tags:
``` python
' '.join(zufaellige_woerter)
```
%% Cell type:markdown id:c7a35dff tags:
Wenn wir die Wörter aus dem Buch zufällig auswählen, bekommen wir zwar ein Gefühl für das verwendete Vokabular, aber eine Folge von zufälligen Wörtern ergibt selten Sinn, weil keine Beziehungen zwischen den aufeinanderfolgenden Wörtern existieren.
In einem echten Satz erwarten wir zum Beispiel, dass ein Artikel wie "das" vor einem Adjektiv oder Substantiv steht, und eher nicht vor einem Verb oder Adverb.
Der nächste Schritt ist also, diese Beziehungen zwischen Wörtern zu betrachten.
%% Cell type:markdown id:0921dd53 tags:
## Bigramme
Statt uns die Wörter einzeln nacheinander anzusehen, betrachten wir nun Sequenzen aus zwei Wörtern an, die man **Bigramme** nennt.
Eine Abfolge von drei Wörtern nennt man **Trigramm** und eine Folge mit einer nicht festgelegten Anzahl an Wörtern heißt **n-gramm**.
Lasst uns ein Programm schreiben, das alle Bigramme im Buch, sowie die Anzahl der Male, die diese auftauchen findet.
Um die Ergebnisse zu speichern werden wir ein assoziatives Datenfeld verwenden, in dem...
* ... die Schlüssel Tupel aus Zeichenketten sind, die Bigramme repräsentieren und...
* ... die Werte ganze Zahlen sind, die Häufigkeiten repräsentieren.
Wir werden es `bigramm_zaehler` nennen:
%% Cell type:code id:d8ee02f6 tags:
``` python
bigramm_zaehler = {}
```
%% Cell type:markdown id:33f97a2a tags:
Die folgende Funktion nimmt eine Liste aus zwei Zeichenketten als Parameter auf.
Zuerst erstellt sie ein Tupel aus den zwei Zeichenketten, das als Schlüssel in einem assoziativen Datenfeld verwendet werden kann.
Dann fügt sie den Schlüssel zu `bigramm_zaehler` hinzu, wenn er noch nicht existiert, oder erhöht seine Häufigkeit, wenn er schon existiert:
%% Cell type:code id:bfdb1de1 tags:
``` python
def zaehle_bigramme(bigramm):
schluessel = tuple(bigramm)
if schluessel not in bigramm_zaehler:
bigramm_zaehler[schluessel] = 1
else:
bigramm_zaehler[schluessel] += 1
```
%% Cell type:markdown id:5c30f429 tags:
Während wir durch das Buch gehen, müssen wir jedes aufeinander folgende Wortpaar erfassen.
Wenn wir also die Sequenz "man is not truly one" sehen, fügen wir die Bigramme "man is", "is not", "not truly" und so weiter hinzu.
Um diese Bigramme im Blick zu behalten, werden wir eine Liste namens `fenster` verwenden, weil sie wie ein Fenster funktioniert, das sich über die Buchseiten bewegt und immer nur zwei Wörter gleichzeitig zeigt.
Zu Beginn ist `fenster` leer:
%% Cell type:code id:2e73df79 tags:
``` python
fenster = []
```
%% Cell type:markdown id:9376558c tags:
Wir werden die folgende Funktion verwenden, um die Wörter eines nach dem anderen zu verarbeiten:
%% Cell type:code id:495ad429 tags:
``` python
def wort_verarbeiten(wort):
fenster.append(wort)
if len(fenster) == 2:
zaehle_bigramme(fenster)
fenster.pop(0)
```
%% Cell type:markdown id:56895591 tags:
Das erste Mal wenn diese Funktion aufgerufen wird, hängt sie das angegebene Wort an `fenster` an.
Weil sich nur ein Wort im Fenster befindet, haben wir nur ein Bigramm und die Funktion endet.
Beim zweiten Aufruf -- und jedem weiteren danach -- hängt sie ein zweites Wort an `fenster` an.
Weil sich nur zwei Wörter im Fenster befinden, wird `zaehle_bigramme` aufgerufen, um festzustellen, wie oft jedes Bigram erscheint.
Dann verwendet die Funktion `pop`, um das erste Wort aus dem Fenster zu entfernen.
Das folgende Programm geht in einer Schleife durch die Wörter des Buchs, und verarbeitet sie eines nach dem anderen:
%% Cell type:code id:c1224061 tags:
``` python
for zeile in open(dateiname):
for wort in zeile_teilen(zeile):
wort = wort_bereinigt(wort)
wort_verarbeiten(wort)
```
%% Cell type:markdown id:20c4627a tags:
Das Ergebnis ist ein assoziatives Datenfeld, das von jedem Bigramm zu der Häufigkeit von dessen Vorkommen verweist.
Wir können `print_am_haeufigsten` verwenden, um die häufigsten Bigramme zu sehen:
%% Cell type:code id:4296485a tags:
``` python
print_am_haeufigsten(bigramm_zaehler)
```
%% Cell type:markdown id:757bd309 tags:
Wenn wir uns die Ergebnisse ansehen, können wir ein Gefühl dafür bekommen, welche Wortpaare am wahrscheinlichsten zusammen auftauchen.
Wir können die Ergebnisse auch dafür verwenden, zufälligen Text zu generieren:
%% Cell type:code id:e03fd803 tags:
``` python
random.seed(0)
```
%% Cell type:code id:f6ee1840 tags:
``` python
bigramme = list(bigramm_zaehler)
gewichte = bigramm_zaehler.values()
zufaellige_bigramme = random.choices(bigramme, weights=gewichte, k=6)
```
%% Cell type:markdown id:eda80407 tags:
`bigramme` ist eine Liste mit den Bigrammen, die im Buch vorkommen und
`gewichte` ist eine Liste mit deren Häufigkeiten, also ist `random_bigramme` ein Sample, in dem die Wahrscheinlichkeit, dass ein Bigramm ausgewählt wird, proportional zu dessen Häufigkeit ist.
Hier sind die Ergebnisse:
%% Cell type:code id:d6c65d79 tags:
``` python
for paar in zufaellige_bigramme:
print(' '.join(paar), end=' ')
```
%% Cell type:markdown id:5f24c3b6 tags:
Diese Art Text zu generieren ist besser, als zufällige Wörter auszuwählen, ergibt aber immer noch nicht viel Sinn.
%% Cell type:markdown id:a13d93b5 tags:
## Markov-Analyse
Mit einer Markov-Ketten-Textanalyse, bei der für jedes Wort in einem Text eine Liste mit Wörtern, die darauf folgen berechnet wird, können wir bessere Ergebnisse erzielen.
Als Beispiel werden wir diesen Liedtext von Monty Pythons Song *Eric, the Half a Bee* analysieren:
%% Cell type:code id:3171d592 tags:
``` python
song = """
Half a bee, philosophically,
Must, ipso facto, half not be.
But half the bee has got to be
Vis a vis, its entity. D'you see?
"""
```
%% Cell type:markdown id:583ab9f0 tags:
Um die Ergebnisse zu speichern, werden wir ein assoziatives Datenfeld verwenden, das von jedem Wort auf eine Liste mit darauffolgenden Wörtern verweist:
%% Cell type:code id:3321e6a4 tags:
``` python
nachfolger_verweis = {}
```
%% Cell type:markdown id:d5d85b09 tags:
Als Beispiel werden wir mit den ersten beiden Wörtern des Liedes beginnen:
%% Cell type:code id:e4e55c71 tags:
``` python
erstes = 'half'
zweites = 'a'
```
%% Cell type:markdown id:0349fe78 tags:
Wenn sich das erste Wort nicht in `nachfolger_verweis` befindet, müssen wir ein neues Element hinzufügen, das von dem ersten Wort zu einer Liste verweist, die das zweite Wort enthält:
%% Cell type:code id:f25dcb5e tags:
``` python
nachfolger_verweis[erstes] = [zweites]
nachfolger_verweis
```
%% Cell type:markdown id:55bb8df9 tags:
Wenn sich das erste Wort schon im assoziativen Datenfeld befindet, können wir es suchen, um die Liste mit Nachfolgern, die wir bisher gesehen haben zu bekommen und dann das neue Wort daran anhängen:
%% Cell type:code id:990354a0 tags:
``` python
erstes = 'half'
zweites = 'not'
nachfolger_verweis[erstes].append(zweites)
nachfolger_verweis
```
%% Cell type:markdown id:6289cc32 tags:
Die folgende Funktion verkapselt diese Schritte:
%% Cell type:code id:b9371452 tags:
``` python
def bigramm_hinzufuegen(bigramm):
erstes, zweites = bigramm
if erstes not in nachfolger_verweis:
nachfolger_verweis[erstes] = [zweites]
else:
nachfolger_verweis[erstes].append(zweites)
```
%% Cell type:markdown id:74a51700 tags:
Wenn das gleiche Bigramm mehr als einmal vorkommt, wird das zweite Wort mehrfach der Liste hinzugefügt.
Auf diese Art speichert `nachfolger_verweis`, wie oft jeder Nachfolger erscheint.
Wie wir es schon im vorherigen Abschnitt getan haben, werden wir eine Liste namens `fenster` verwenden, um Paare aus aufeinanderfolgende Wörtern zu speichern.
Und wir werden die folgende Funktion nutzen, um die Wörter eines nach dem anderen zu verarbeiten:
%% Cell type:code id:8c3f45c2 tags:
``` python
def wort_verarbeiten_bigramm(wort):
fenster.append(wort)
if len(fenster) == 2:
bigramm_hinzufuegen(fenster)
fenster.pop(0)
```
%% Cell type:markdown id:861a60d9 tags:
Folgendermaßen verwenden wir das, um die Wörter im Lied zu verarbeiten:
%% Cell type:code id:641990a3 tags:
``` python
nachfolger_verweis = {}
fenster = []
for wort in song.split():
wort = wort_bereinigt(wort)
wort_verarbeiten_bigramm(wort)
```
%% Cell type:markdown id:bf490d67 tags:
Und hier sind die Ergebnisse:
%% Cell type:code id:9322a49a tags:
``` python
nachfolger_verweis
```
%% Cell type:markdown id:ff7bad74 tags:
Das Wort `'half'` kann vor `'a'`, `'not'`, oder `'the'` stehen.
Das Wort `'a'` kann vor `'bee'` oder `'vis'` stehen.
Die meisten anderen Wörter kommen nur einmal vor, also folgt auf sie nur ein einzelnes Wort.
Jetzt analysieren wir das Buch:
%% Cell type:code id:45a60c52 tags:
``` python
nachfolger_verweis = {}
fenster = []
for zeile in open(dateiname):
for wort in zeile_teilen(zeile):
wort = wort_bereinigt(wort)
wort_verarbeiten_bigramm(wort)
```
%% Cell type:markdown id:2676e2fb tags:
Wir können jedes Wort suchen und dadurch die Wörter finden, die auf dieses folgen:
%% Cell type:code id:3e86102c tags:
``` python
# Ich habe diese Zelle verwendet, um einen Vorgänger mit einer großen Anzahl möglicher
# Nachfolger und mindestens einem wiederholten Wort zu finden.
def enthaelt_duplikate(t):
return len(set(t)) < len(t)
for schluessel, wert in nachfolger_verweis.items():
if len(wert) == 7 and enthaelt_duplikate(wert):
print(schluessel, wert)
```
%% Cell type:code id:e49d52f7 tags:
``` python
nachfolger_verweis['going']
```
%% Cell type:markdown id:7b777a9c tags:
In dieser Liste mit Nachfolgern fällt auf, dass das Wort `'to'` dreimal vorkommt -- die anderen Nachfolger erscheinen nur einmal.
%% Cell type:markdown id:e8bf85fc tags:
## Text generieren
Wir können die Ergebnisse des vorigen Abschnitts nutzen, um neuen Text mit den gleichen Beziehungen zwischen aufeinanderfolgenden Wörtern wie im Original zu generieren.
Das funktioniert so:
* Beginnend bei einem beliebigen Wort, das im Text vorkommt, ermitteln wir dessen mögliche Nachfolger und wählen daraus zufällig einen aus.
* Dann verwenden wir das ausgewählte Wort, um dessen mögliche Nachfolger zu ermitteln und daraus wieder einen zufällig auszusuchen.
Wir können diesen Prozess wiederholen, bis wir so viele Wörter generiert haben wie wir möchten.
Als Beispiel beginnen wir mit dem Wort `'although'`.
Hier sind die Wörter, die darauf folgen können:
%% Cell type:code id:15108884 tags:
``` python
wort = 'although'
nachfolger = nachfolger_verweis[wort]
nachfolger
```
%% Cell type:code id:747a41be tags:
``` python
# diese Zelle initialisiert den Zufallsgenerator für Zahlen, damit dieser
# bei jedem Durchlauf des Notebooks an der gleichen stelle in der Abfolge
# beginnt.
random.seed(2)
```
%% Cell type:markdown id:b26a2ead tags:
Wir können `choice` verwenden, um mit gleicher Wahrscheinlichkeit aus der Liste auszuwählen:
%% Cell type:code id:5a4682dc tags:
``` python
wort = random.choice(nachfolger)
wort
```
%% Cell type:markdown id:9741beca tags:
Wenn das gleiche Wort mehr als einmal in der Liste vorkommt, ist die Wahrscheinlichkeit, dass es ausgewählt wird höher.
Um diese Schritte zu wiederholen, können wir die folgende Schleife verwenden, die eine längere Folge generiert:
%% Cell type:code id:36ee0f76 tags:
``` python
for i in range(10):
nachfolger = nachfolger_verweis[wort]
wort = random.choice(nachfolger)
print(wort, end=' ')
```
%% Cell type:markdown id:38a2d79a tags:
Das Ergebnis klingt schon viel eher nach einem echten Satz, es ergibt aber immer noch nicht viel Sinn.
Das können wir verbessern, indem wir mehr als ein Wort als Schlüssel in `nachfolger_verweis` verwenden.
Zum Beispiel können wir ein assoziatives Datenfeld erstellen, das von jedem Bigramm -- oder Trigramm -- auf die Liste der darauffolgenden Wörter verweist.
In den Übungen werden Sie die Möglichkeit haben, diese Analyse zu implementieren und zu sehen, was die Ergebnisse davon sind.
%% Cell type:markdown id:c59dff45 tags:
## Debuggen
Inzwischen schreiben wir umfangreichere Programme und es könnte sein, dass sie dadurch mehr Zeit mit debuggen verbringen.
Wenn Sie an einem schwierigen Bug hängen bleiben, sind hier einige Dinge, die Sie versuchen könnten:
* Lesen (**R**eading): Begutachten Sie Ihren Code, lesen Sie ihn sich noch einmal durch und vergewissern Sie sich, dass er das aussagt, was Sie sagen wollten.
* Durchlaufen (**R**unning): Experimentieren Sie, indem Sie Veränderungen am Code vornehmen und verschiedene Versionen laufen lassen. Wenn man das Richtige an der richtigen Stelle im Programm anzeigt, wird das Problem oft offensichtlich, manchmal muss man aber doch ein Gerüst bauen.
* Grübeln (**R**uminating): Nehmen Sie sich etwas Zeit zum Nachdenken! Welche Art von Fehler ist es: ein Syntaxfehler, ein Laufzeitfehler oder ein semantischer Fehler? Welche Informationen können Sie aus den Fehlermeldungen oder dem Output des Programms ziehen? Welche Art von Fehler könnte für das Problem, das Sie sehen verantwortlich sein? Was haben Sie zuletzt verändert, bevor das Probelm aufgetreten ist?
* Quietscheentchen-Methode (**R**ubberducking): Wenn Sie jemand anderem das Problem erklären, finden sie manchmal die Antwort, bevor Sie überhaupt alle Fragen gestellt haben. Oft brauchen Sie dafür nichtmal eine andere Person, Sie könnten sich auch einfach mit einer Quietscheente unterhalten. Das ist der Ursprung der bekannten Strategie namens **Quietscheentchen-Debugging**. Ich habe mir das nicht ausgedacht -- lesen Sie es auf <https://de.wikipedia.org/wiki/Quietscheentchen-Debugging> nach.
* Rückzug (**R**etreat): An einem gewissen Punkt ist es das Beste, zurückzugehen -- und die letzten Änderungen rückgängig zu machen -- bis Sie wieder zu einem Programm kommen, das funktioniert. Dann können Sie mit dem Neuaufbau beginnen.
* Ausruhen (**R**esting): Wenn Sie Ihrem Gehirn eine Pause geben, wird es manchmal das Problem einfach für Sie finden.
%% Cell type:markdown id:12c2cd32 tags:
Programmieranfänger bleiben manchmal bei einer dieser Aktivitäten stecken und vergessen die anderen. Für jede Aktivität gibt es einen eigenen Fehlermodus.
Das Lesen Ihres Codes funktioniert zum Beispiel, wenn das Problem ein Tippfehler ist, aber nicht, wenn das Problem ein konzeptionelles Missverständnis ist.
Wenn Sie selbst nicht verstehen, was Ihr Programm tut, können Sie es hundert Mal lesen und werden den Fehler nie sehen, weil er in Ihrem Kopf ist.
Das Durchführen von Experimenten kann funktionieren, vor allem wenn Sie kleine, einfache Tests durchführen.
Wenn Sie jedoch Experimente durchführen, ohne nachzudenken oder Ihren Code zu lesen, kann es lange dauern, bis Sie herausfinden, was passiert.
Sie müssen sich Zeit zum Nachdenken nehmen. Debugging ist wie eine experimentelle Wissenschaft. Sie sollten mindestens eine Hypothese darüber haben, was das Problem ist. Wenn es zwei oder mehr Möglichkeiten gibt, versuchen Sie, sich einen Test auszudenken, der eine von ihnen ausschließt.
%% Cell type:markdown id:a55036e1 tags:
Aber selbst die besten Debugging-Techniken können nicht helfen, wenn es zu viele Fehler gibt oder wenn der Code, den Sie versuchen zu reparieren zu groß und kompliziert ist.
Manchmal ist die beste Option, sich zurückzuziehen und das Programm so lange zu vereinfachen, bis sie an einem Punkt ankommen, wo wieder etwas funktioniert.
Programmieranfänger zögern oft, sich zurückzuziehen, weil sie es nicht über sich bringen können, eine Codezeile zu löschen (selbst wenn sie falsch ist). Wenn Sie sich dadurch besser fühlen, kopieren Sie Ihr Programm in eine andere Datei, bevor Sie damit beginnen, es zu zerlegen. Dann können Sie die Teile nach und nach zurückkopieren.
Um einen schwierigen Bug zu finden, muss man lesen, durchlaufen, grübeln, sich zurückziehen und sich manchmal auch ausruhen.
Wenn Sie bei einer dieser Aktivitäten hängenbleiben, testen Sie die anderen.
%% Cell type:markdown id:7a113d88-a078-4b89-b887-ccaed7981eef tags:
## Glossar
Legen wir uns eine Liste mit den wichtigsten Begriffen an, die wir im Kapitel 12 gelernt haben:
- Standardwert:
- überschreiben:
- deterministisch:
- pseudozufällig:
- Bigramm:
- Trigramm:
- n-gramm:
- Quietscheentchen-Debugging:
Ergänzen Sie die Liste in eigenen Worten. Das ist eine gute Erinnerungs- und Übungsmöglichkeit.
%% Cell type:markdown id:cde18229 tags:
## Übung
%% Cell type:code id:a4e34564 tags:remove-print
``` python
# Diese Zelle weist Jupyter an, detallierte Debugging-Informationen auszugeben, wenn ein Laufzeitfehler
# passiert. Lassen Sie sie daher laufen, bevor Sie beginnen an den Aufgaben zu arbeiten.
%xmode Verbose
```
%% Cell type:markdown id:9b0efab8 tags:
### Fragen Sie einen virtuellen Assistenten
In `bigramm_hinzufuegen` erstellt die `if`-Anweisung eine neue Liste oder hängt ein Element an eine bereits existierende Liste an, je nachdem, ob sich der Schlüssel schon im assoziativen Datenfeld befindet:
%% Cell type:code id:a4365ac0 tags:
``` python
def bigramm_hinzufuegen(bigramm):
erstes, zweites = bigramm
if erstes not in nachfolger_verweis:
nachfolger_verweis[erstes] = [zweites]
else:
nachfolger_verweis[erstes].append(zweites)
```
%% Cell type:markdown id:30d9e549 tags:
Assoziative Datenfelder bieten eine Methode namens `setdefault`, das wir verwenden können, um das gleiche etwas knapper und präziser zu tun.
Fragen Sie einen virtuellen Assistenten, wie das funktioniert, oder kopieren Sie `bigramm_hinzufuegen` in einen virtuellen Assistenten und fragen Sie diesen: "Kannst du das unter Verwendung von `setdefault` umschreiben?"
In diesem Kapitel haben wir Markov-Ketten-Textanalyse und -Generierung implementiert.
Wenn Sie neugierig sind, können Sie einen virtuellen Assistenten nach mehr Informationen zu diesem Thema fragen.
Etwas, das Sie vielleicht erfahren werden ist, dass virtuelle Assistenten Algorithmen verwenden, die der Markov-Generierung recht ähnlich sind -- sich aber auch in einigen wichtigen Punkten unterscheiden.
Fragen Sie einen VA: "Was sind die Unterschiede zwischen Large Language Models wie GPT und Markov-Ketten-Textanalyse?".
%% Cell type:markdown id:060c9ef6 tags:
### Aufgabe 1
Schreiben Sie eine Funktion, die zählt wie oft jedes Trigramm (Folge von drei Wörtern) vorkommt.
Wenn Sie Ihre Funktion mit dem Text von *Dr. Jekyll and Mr. Hyde* testen, sollten Sie herausfinden, dass das häufigste Trigramm "said the lawyer" ist.
Tipp: Schreiben Sie eine Funktion namens `zaehle_trigramme` die `zaehle_bigramme` ähnelt. Schreiben Sie dann eine Funktion namens `wort_verarbeiten_trigramm`, die `wort_verarbeiten_bigramm` ähnlich ist.
%% Cell type:code id:f38a61ff tags:
``` python
# Lösung hierhin schreiben
def wort_verarbeiten_trigramm(wort):
pass
```
%% Cell type:code id:d047e546 tags:
``` python
# Lösung hierhin schreiben
```
%% Cell type:markdown id:ca1f8a79 tags:
Sie können die folgende Schleife verwenden, um das Buch zu lesen und die Wörter zu verarbeiten:
%% Cell type:code id:6b8932ee tags:
``` python
trigramm_zaehler = {}
fenster = []
for zeile in open(dateiname):
for wort in zeile_teilen(zeile):
wort = wort_bereinigt(wort)
wort_verarbeiten_trigramm(wort)
```
%% Cell type:markdown id:35d37fa1 tags:
Verwenden Sie dann `print_am_haeufigsten`, um die häufigsten Trigramme im Buch zu finden:
%% Cell type:code id:44c3f0d8 tags:
``` python
print_am_haeufigsten(trigramm_zaehler)
```
%% Cell type:markdown id:4bd07bb7 tags:
### Aufgabe 2
Lassen Sie uns nun eine Markov-Ketten-Textanalyse mit Verweisen von jedem Bigramm zu einer Liste von möglichen Nachfolgern implementieren.
Schreiben Sie, beginnend mit `bigramm_hinzufuegen`, eine Funktion namens `trigramm_hinzufuegen`, die eine Liste von drei Wörtern aufnimmt und ein Element in `nachfolger_verweis` entweder hinzufügt oder aktualisiert, wobei die ersten beiden Wörter als Schlüssel und das dritte Wort als möglicher Nachfolger verwendet werden.
%% Cell type:code id:3fcf85f4 tags:
``` python
# Lösung hierhin schreiben
```
%% Cell type:markdown id:94d683fe tags:
Hier ist eine Version von `wort_verarbeiten_trigramm`, die `trigramm_hinzufuegen` aufruft.
%% Cell type:code id:d9e554e3 tags:
``` python
def wort_verarbeiten_trigramm(wort):
fenster.append(wort)
if len(fenster) == 3:
trigramm_hinzufuegen(fenster)
fenster.pop(0)
```
%% Cell type:markdown id:82eeed41 tags:
Sie können die folgende Schleife verwenden, um Ihre Funktion mit dem Songtext von "Eric, the Half a Bee" zu testen:
%% Cell type:code id:8c2ee21c tags:
``` python
nachfolger_verweis = {}
fenster = []
for zeichenkette in song.split():
wort = zeichenkette.strip(interpunktion).lower()
wort_verarbeiten_trigramm(wort)
```
%% Cell type:markdown id:8829d4c2 tags:
Wenn Ihre Funktion funktioniert wie geplant, sollte der Vorgänger `('half', 'a')` auf eine Liste mit dem einzelnen Element `'bee'` verweisen.
Tatsächlich erscheint jedes Bigramm in diesem Lied nur einmal, also haben enthalten Werte in `nachfolger_verweis` nur ein einziges Element:
%% Cell type:code id:b13384e3 tags:
``` python
nachfolger_verweis
```
%% Cell type:markdown id:886212b5 tags:
Sie können die folgende Schleife verwenden, um Ihre Funktion mit Wörtern aus dem Buch zu testen:
%% Cell type:code id:62c2177f tags:
``` python
nachfolger_verweis = {}
fenster = []
for zeile in open(dateiname):
for wort in zeile_teilen(zeile):
wort = wort_bereinigt(wort)
wort_verarbeiten_trigramm(wort)
```
%% Cell type:markdown id:3e1d073e tags:
In der nächsten Aufgabe werden Sie die Ergebnisse verwenden, um neuen Text zufällig zu generieren.
%% Cell type:markdown id:04d7a6ee tags:
### Aufgabe 3
Für diese Aufgaben werden wir annehmen, dass `nachfolger_verweis` ein assoziatives Datenfeld ist, das von jedem Bigramm zu der Liste mit Worten, die auf dieses folgen verweist:
%% Cell type:code id:64e11f26 tags:
``` python
# diese Zelle initialisiert den Zufallsgenerator für Zahlen, damit dieser
# bei jedem Durchlauf des Notebooks an der gleichen stelle in der Abfolge
# beginnt.
random.seed(3)
```
%% Cell type:markdown id:fb0f8f7d tags:
Um zufälligen Text zu generieren, beginnen wir damit, einen zufälligen Schlüssel aus `nachfolger_verweis` auszuwählen:
%% Cell type:code id:fe2d93fa tags:
``` python
nachfolger = list(nachfolger_verweis)
bigramm = random.choice(nachfolger)
bigramm
```
%% Cell type:markdown id:83ed6c7e tags:
Schreiben Sie nun eine Schleife, die weitere 50 Wörter generiert, indem sie diesen Schritten folgt:
1. Suchen Sie in `nachfolger_verweis` die Liste mit Wörtern, die auf `bigramm` folgen können.
2. Wählen Sie eines davon zufällig und geben Sie dieses aus.
3. Erstellen Sie für die nächste Iteration ein neues Bigramm, das das zweite Wort aus `bigramm` und den ausgewählten Nachfolger enthält.
Wenn wir zum Beispiel mit dem Bigramm `('doubted', 'if')` beginnen und `'from'` als Nachfolger auswählen, dann ist das nächste Bigramm `('if', 'from')`.
%% Cell type:code id:22210a5c tags:
``` python
# Lösung hierhin schreiben
```
%% Cell type:markdown id:c71d8a89 tags:
Wenn alles funktioniert, sollten sie feststellen, dass der generierte Text dem Stil des Originals erkennbar ähnelt und manche Sätze Sinn ergeben, der Text aber möglicherweise zwischen verschiedenen Themen hin- und herspringt.
Als zusätzliche Übung, passen Sie Ihre Lösung so an die letzten beiden Übungen an, dass diese Trigramme als Schlüssel in `nachfolger_verweis` verwendet, und sehen Sie sich an, welche Auswirkungen das auf die Ergebnisse hat.
%% Cell type:code id:3d4efda7 tags:
``` python
```
%% Cell type:markdown id:aadee942-b8dd-4679-a331-e6023b569ad6 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). Rufen Sie dazu im Menü *File* den Punkt *Download as**Notebook* auf 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:3f98530e-bfe6-4319-9898-50940c840ba4 tags:
![Smiley](https://upload.wikimedia.org/wikipedia/commons/thumb/7/79/Face-smile.svg/48px-Face-smile.svg.png)
Herzlichen Glückwunsch! Sie haben das 12. Kapitel geschafft!
%% Cell type:markdown id:5cf853f4-5575-408c-8446-bc993452dc66 tags:
<img src="https://scm.cms.hu-berlin.de/ibi/python/-/raw/master/img/by-nc-sa.png" alt="CC BY-NC-SA" style="width: 150px;"/>
Der Text dieses Notebooks ist als freies Werk unter der Lizenz [CC BY-NC-SA 4.0 ](https://creativecommons.org/licenses/by-nc-sa/4.0/) verfügbar.
Der Code dieses Notebooks ist als freies Werk unter der Lizenz [MIT License](https://mit-license.org/) verfügbar.
Es handelt sich um übersetzte und leicht veränderte Notebooks von [Allen B. Downey](https://allendowney.com) aus [Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html).
%% 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 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:
<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>
%% 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.
## 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
**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
- *Shift + Tab*: Einrücken rückwärts
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, 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
- 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.
Syntax
The format of email addresses is local-part@domain where the local part may be up to 64 characters long and the domain may have a maximum of 255 characters.[4] The formal definitions are in RFC 5322 (sections 3.2.3 and 3.4.1) and RFC 5321—with a more readable form given in the informational RFC 3696[5] and the associated errata. Note that unlike the syntax of RFC 1034,[6] and RFC 1035[7] there is no trailing period in the domain name.
Local-part
The local-part of the email address may use any of these ASCII characters:
uppercase and lowercase Latin letters A to Z and a to z;
digits 0 to 9;
printable characters others than letters and digit !#$%&'*+-/=?^_`{|}~;
dot ., provided that it is not the first or last character unless quoted, and provided also that it does not appear consecutively unless quoted (e.g. John..Doe@example.com is not allowed but "John..Doe"@example.com is allowed);[8]
Note that some mail servers wildcard local parts, typically the characters following a plus and less often the characters following a minus, so fred+bah@domain and fred+foo@domain might end up in the same inbox as fred+@domain or even as fred@domain. This can be useful for tagging emails for sorting, see below, and for spam control. Braces { and } are also used in that fashion, although less often.
space and special characters "(),:;<>@[\] are allowed with restrictions (they are only allowed inside a quoted string, as described in the paragraph below, and in addition, a backslash or double-quote must be preceded by a backslash);
comments are allowed with parentheses at either end of the local-part; e.g. john.smith(comment)@example.com and (comment)john.smith@example.com are both equivalent to john.smith@example.com.
In addition to the above ASCII characters, international characters above U+007F, encoded as UTF-8, are permitted by RFC 6531, though even mail systems that support SMTPUTF8 and 8BITMIME may restrict which characters to use when assigning local-parts.
A local part is either a Dot-string or a Quoted-string; it cannot be a combination. Quoted strings and characters however, are not commonly used.[citation needed] RFC 5321 also warns that "a host that expects to receive mail SHOULD avoid defining mailboxes where the Local-part requires (or uses) the Quoted-string form".
The local-part postmaster is treated specially—it is case-insensitive, and should be forwarded to the domain email administrator. Technically all other local-parts are case-sensitive, therefore jsmith@example.com and JSmith@example.com specify different mailboxes; however, many organizations treat uppercase and lowercase letters as equivalent. Indeed, RFC 5321 warns that "a host that expects to receive mail SHOULD avoid defining mailboxes where ... the Local-part is case-sensitive".
Despite the wide range of special characters which are technically valid, organisations, mail services, mail servers and mail clients in practice often do not accept all of them. For example, Windows Live Hotmail only allows creation of email addresses using alphanumerics, dot (.), underscore (_) and hyphen (-).[9] Common advice is to avoid using some special characters to avoid the risk of rejected emails.[10]
Domain
The domain name part of an email address has to conform to strict guidelines: it must match the requirements for a hostname, a list of dot-separated DNS labels, each label being limited to a length of 63 characters and consisting of:[8]:§2
uppercase and lowercase Latin letters A to Z and a to z;
digits 0 to 9, provided that top-level domain names are not all-numeric;
hyphen -, provided that it is not the first or last character.
This rule is known as the LDH rule (letters, digits, hyphen). In addition, the domain may be an IP address literal, surrounded by square brackets [], such as jsmith@[192.168.2.1] or jsmith@[IPv6:2001:db8::1], although this is rarely seen except in email spam. Internationalized domain names (which are encoded to comply with the requirements for a hostname) allow for presentation of non-ASCII domains. In mail systems compliant with RFC 6531 and RFC 6532 an email address may be encoded as UTF-8, both a local-part as well as a domain name.
Comments are allowed in the domain as well as in the local-part; for example, john.smith@(comment)example.com and john.smith@example.com(comment) are equivalent to john.smith@example.com.
Examples
Valid email addresses
simple@example.com
very.common@example.com
disposable.style.email.with+symbol@example.com
other.email-with-hyphen@example.com
fully-qualified-domain@example.com
user.name+tag+sorting@example.com (may go to user.name@example.com inbox depending on mail server)
x@example.com (one-letter local-part)
example-indeed@strange-example.com
admin@mailserver1 (local domain name with no TLD, although ICANN highly discourages dotless email addresses)
example@s.example (see the List of Internet top-level domains)
" "@example.org (space between the quotes)
"john..doe"@example.org (quoted double dot)
Invalid email addresses
Abc.example.com (no @ character)
A@b@c@example.com (only one @ is allowed outside quotation marks)
a"b(c)d,e:f;g<h>i[j\k]l@example.com (none of the special characters in this local-part are allowed outside quotation marks)
just"not"right@example.com (quoted strings must be dot separated or the only element making up the local-part)
this is"not\allowed@example.com (spaces, quotes, and backslashes may only exist when within quoted strings and preceded by a backslash)
this\ still\"not\\allowed@example.com (even if escaped (preceded by a backslash), spaces, quotes, and backslashes must still be contained by quotes)
1234567890123456789012345678901234567890123456789012345678901234+x@example.com (local part is longer than 64 characters)
Common local-part semantics
According to RFC 5321 2.3.11 Mailbox and Address, "...the local-part MUST be interpreted and assigned semantics only by the host specified in the domain of the address." This means that no assumptions can be made about the meaning of the local-part of another mail server. It is entirely up to the configuration of the mail server.
Local-part normalization
Interpretation of the local part of an email address is dependent on the conventions and policies implemented in the mail server. For example, case sensitivity may distinguish mailboxes differing only in capitalization of characters of the local-part, although this is not very common.[11] Gmail ignores all dots in the local-part for the purposes of determining account identity.[12] This prevents the creation of user accounts your.user.name or yourusername when the account your.username already exists.
Subaddressing
Some mail services support a tag included in the local-part, such that the address is an alias to a prefix of the local part. For example, the address joeuser+tag@example.com denotes the same delivery address as joeuser@example.com. RFC 5233, refers to this convention as sub-addressing, but it is also known as plus addressing or tagged addressing.
Addresses of this form, using various separators between the base name and the tag, are supported by several email services, including Runbox (plus), Gmail (plus),[13] Rackspace Email (plus), Yahoo! Mail Plus (hyphen),[14] Apple's iCloud (plus), Outlook.com (plus),[15] ProtonMail (plus),[16] FastMail (plus and Subdomain Addressing),[17] MMDF (equals), Qmail and Courier Mail Server (hyphen).[18][19] Postfix allows configuring an arbitrary separator from the legal character set.[20]
The text of the tag may be used to apply filtering,[18] or to create single-use, or disposable email addresses.[21]
In practice, the form validation of some web sites may reject special characters such as "+" in an email address – treating them, incorrectly, as invalid characters. This can lead to an incorrect user receiving an e-mail if the "+" is silently stripped by a website without any warning or error messages. For example, an email intended for the user-entered email address foo+bar@example.com could be incorrectly sent to foobar@example.com. In other cases a poor user experience can occur if some parts of a site, such as a user registration page, allow the "+" character whilst other parts, such as a page for unsubscribing from a site's mailing list, do not.
der
die
und
in
den
von
zu
das
mit
sich
des
auf
für
ist
im
dem
nicht
ein
Die
eine
als
auch
es
an
werden
aus
er
hat
daß
sie
nach
wird
bei
einer
Der
um
am
sind
noch
wie
einem
über
einen
Das
so
Sie
zum
war
haben
nur
oder
aber
vor
zur
bis
mehr
durch
man
sein
wurde
sei
In
Prozent
hatte
kann
gegen
vom
können
schon
wenn
habe
seine
Mark
ihre
dann
unter
wir
soll
ich
eines
Es
Jahr
zwei
Jahren
diese
dieser
wieder
keine
Uhr
seiner
worden
Und
will
zwischen
Im
immer
Millionen
Ein
was
sagte
Er
gibt
alle
DM
diesem
seit
muß
wurden
beim
doch
jetzt
waren
drei
Jahre
Mit
neue
neuen
damit
bereits
da
Auch
ihr
seinen
müssen
ab
ihrer
Nach
ohne
sondern
selbst
ersten
nun
etwa
Bei
heute
ihren
weil
ihm
seien
Menschen
Deutschland
anderen
werde
Ich
sagt
Wir
Eine
rund
Für
Aber
ihn
Ende
jedoch
Zeit
sollen
ins
Wenn
So
seinem
uns
Stadt
geht
Doch
sehr
hier
ganz
erst
wollen
Berlin
vor allem
sowie
hatten
kein
deutschen
machen
lassen
Als
Unternehmen
andere
ob
dieses
steht
dabei
wegen
weiter
denn
beiden
einmal
etwas
Wie
nichts
allerdings
vier
gut
viele
wo
viel
dort
alles
Auf
wäre
SPD
kommt
vergangenen
denen
fast
fünf
könnte
nicht nur
hätten
Frau
Am
dafür
kommen
diesen
letzten
zwar
Diese
großen
dazu
Von
Mann
Da
sollte
würde
also
bisher
Leben
Milliarden
Welt
Regierung
konnte
ihrem
Frauen
während
Land
zehn
würden
stehen
ja
USA
heißt
dies
zurück
Kinder
dessen
ihnen
deren
sogar
Frage
gewesen
erste
gab
liegt
gar
davon
gestern
geben
Teil
Polizei
dass
hätte
eigenen
kaum
sieht
große
Denn
weitere
Was
sehen
macht
Angaben
weniger
gerade
läßt
Geld
München
deutsche
allen
darauf
wohl
später
könne
deshalb
aller
kam
Arbeit
mich
gegenüber
nächsten
bleibt
wenig
lange
gemacht
Wer
Dies
Fall
mir
gehen
Berliner
mal
Weg
CDU
wollte
sechs
keinen
Woche
dagegen
alten
möglich
gilt
erklärte
müsse
Dabei
könnten
Geschichte
zusammen
finden
Tag
Art
erhalten
Man
Dollar
Wochen
jeder
nie
bleiben
besonders
Jahres
Deutschen
Den
Zu
zunächst
derzeit
allein
deutlich
Entwicklung
weiß
einige
sollten
Präsident
geworden
statt
Bonn
Platz
inzwischen
Nur
Freitag
Um
pro
seines
Damit
Montag
Europa
schließlich
Sonntag
einfach
gehört
eher
oft
Zahl
neben
hält
weit
Partei
meisten
Thema
zeigt
Politik
Aus
zweiten
Januar
insgesamt
je
mußte
Anfang
hinter
ebenfalls
ging
Mitarbeiter
darüber
vielen
Ziel
darf
Seite
fest
hin
erklärt
Namen
Haus
An
Frankfurt
Gesellschaft
Mittwoch
damals
Dienstag
Hilfe
Mai
Markt
Seit
Tage
Donnerstag
halten
gleich
nehmen
solche
Entscheidung
besser
alte
Leute
Ergebnis
Samstag
Daß
sagen
System
März
tun
Monaten
kleinen
lang
Nicht
knapp
bringen
wissen
Kosten
Erfolg
bekannt
findet
daran
künftig
wer
acht
Grünen
schnell
Grund
scheint
Zukunft
Stuttgart
bin
liegen
politischen
Gruppe
Rolle
stellt
Juni
sieben
September
nämlich
Männer
Oktober
Mrd
überhaupt
eigene
Dann
gegeben
Außerdem
Stunden
eigentlich
Meter
ließ
Probleme
vielleicht
ebenso
Bereich
zum Beispiel
Bis
Höhe
Familie
Während
Bild
Ländern
Informationen
Frankreich
Tagen
schwer
zuvor
Vor
genau
April
stellen
neu
erwartet
Hamburg
sicher
führen
Mal
Über
mehrere
Wirtschaft
Mio
Programm
offenbar
Hier
weiteren
natürlich
konnten
stark
Dezember
Juli
ganze
kommenden
Kunden
bekommen
eben
kleine
trotz
wirklich
Lage
Länder
leicht
gekommen
Spiel
laut
November
kurz
politische
führt
innerhalb
unsere
meint
immer wieder
Form
Münchner
AG
anders
ihres
völlig
beispielsweise
gute
bislang
August
Hand
jede
GmbH
Film
Minuten
erreicht
beide
Musik
Kritik
Mitte
Verfügung
Buch
dürfen
Unter
jeweils
einigen
Zum
Umsatz
spielen
Daten
welche
müßten
hieß
paar
nachdem
Kunst
Euro
gebracht
Problem
Noch
jeden
Ihre
Sprecher
recht
erneut
längst
europäischen
Sein
Eltern
Beginn
besteht
Seine
mindestens
machte
Jetzt
bietet
außerdem
Bürger
Trainer
bald
Deutsche
Schon
Fragen
klar
Durch
Seiten
gehören
Dort
erstmals
Februar
zeigen
Titel
Stück
größten
FDP
setzt
Wert
Frankfurter
Staat
möchte
daher
wolle
Bundesregierung
lediglich
Nacht
Krieg
Opfer
Tod
nimmt
Firma
zuletzt
Werk
hohen
leben
unter anderem
Dieser
Kirche
weiterhin
gebe
gestellt
Mitglieder
Rahmen
zweite
Paris
Situation
gefunden
Wochenende
internationalen
Wasser
Recht
sonst
stand
Hälfte
Möglichkeit
versucht
blieb
junge
Mehrheit
Straße
Sache
arbeiten
Monate
Mutter
berichtet
letzte
Gericht
wollten
Ihr
zwölf
zumindest
Wahl
genug
Weise
Vater
Bericht
amerikanischen
hoch
beginnt
Wort
obwohl
Kopf
spielt
Interesse
Westen
verloren
Preis
Erst
jedem
erreichen
setzen
spricht
früher
teilte
Landes
zudem
einzelnen
bereit
Blick
Druck
Bayern
Kilometer
gemeinsam
Bedeutung
Chance
Politiker
Dazu
Zwei
besten
Ansicht
endlich
Stelle
direkt
Beim
Bevölkerung
Viele
solchen
Alle
solle
jungen
Einsatz
richtig
größte
sofort
neuer
ehemaligen
unserer
dürfte
schaffen
Augen
Rußland
Internet
Allerdings
Raum
Mannschaft
neun
kamen
Ausstellung
Zeiten
Dem
einzige
meine
Nun
Verfahren
Angebot
Richtung
Projekt
niemand
Kampf
weder
tatsächlich
Personen
dpa
Heute
geführt
Gespräch
Kreis
Hamburger
Schule
guten
Hauptstadt
durchaus
Zusammenarbeit
darin
Amt
Schritt
meist
groß
zufolge
Sprache
Region
Punkte
Vergleich
genommen
gleichen
du
Ob
Soldaten
Universität
verschiedenen
Kollegen
neues
Bürgermeister
Angst
stellte
Sommer
danach
anderer
gesagt
Sicherheit
Macht
Bau
handelt
Folge
Bilder
lag
Osten
Handel
sprach
Aufgabe
Chef
frei
dennoch
DDR
hohe
Firmen
bzw
Koalition
Mädchen
Zur
entwickelt
fand
Diskussion
bringt
Deshalb
Hause
Gefahr
per
zugleich
früheren
dadurch
ganzen
abend
erzählt
Streit
Vergangenheit
Parteien
Verhandlungen
jedenfalls
gesehen
französischen
Trotz
darunter
Spieler
forderte
Beispiel
Meinung
wenigen
Publikum
sowohl
meinte
mag
Auto
Lösung
Boden
Einen
Präsidenten
hinaus
Zwar
verletzt
weltweit
Sohn
bevor
Peter
mußten
keiner
Produktion
Ort
braucht
Zusammenhang
Kind
Verein
sprechen
Aktien
gleichzeitig
London
sogenannten
Richter
geplant
Italien
Mittel
her
freilich
Mensch
großer
Bonner
wenige
öffentlichen
Unterstützung
dritten
nahm
Bundesrepublik
Arbeitsplätze
bedeutet
Feld
Dr.
Bank
oben
gesetzt
Ausland
Ministerpräsident
Vertreter
z.B.
jedes
ziehen
Parlament
berichtete
Dieses
China
aufgrund
Stellen
warum
Kindern
heraus
heutigen
Anteil
Herr
Öffentlichkeit
Abend
Selbst
Liebe
Neben
rechnen
fällt
New York
Industrie
WELT
Stuttgarter
wären
Vorjahr
Sicht
Idee
Banken
verlassen
Leiter
Bühne
insbesondere
offen
stets
Theater
ändern
entschieden
Staaten
Experten
Gesetz
Geschäft
Tochter
angesichts
gelten
Mehr
erwarten
läuft
fordert
Japan
Sieg
Ist
Stimmen
wählen
russischen
gewinnen
CSU
bieten
Nähe
jährlich
Bremen
Schüler
Rede
Funktion
Zuschauer
hingegen
anderes
Führung
Besucher
Drittel
Moskau
immerhin
Vorsitzende
Urteil
Schließlich
Kultur
betonte
mittlerweile
Saison
Konzept
suchen
Zahlen
Roman
Gewalt
Köln
gesamte
indem
EU
Stunde
ehemalige
Auftrag
entscheiden
genannt
tragen
Börse
langen
häufig
Chancen
Vor allem
Position
alt
Luft
Studenten
übernehmen
stärker
ohnehin
zeigte
geplanten
Reihe
darum
verhindern
begann
Medien
verkauft
Minister
wichtig
amerikanische
sah
gesamten
einst
verwendet
vorbei
Behörden
helfen
Folgen
bezeichnet
Weil
Ihnen
zur Zeit
voll
deutscher
Worten
plötzlich
müßte
Vertrag
Staatsanwaltschaft
Monat
Oder
Herbst
Israel
zahlen
Zeitung
Grenzen
Wissenschaftler
Partner
Patienten
nutzen
Bund
setzte
Betrieb
Michael
beteiligt
Professor
Fernsehen
Künstler
mehreren
erinnert
Liste
Möglichkeiten
Autor
täglich
eingesetzt
Versuch
Alter
Autos
Kohl
außer
Hoffnung
Verkauf
nennt
erscheint
führte
Prozeß
Täter
bisherigen
länger
erkennen
treffen
Kein
unser
begonnen
Antrag
beschäftigt
Opposition
Maßnahmen
brachte
nächste
Zudem
gezeigt
Dennoch
Sinn
Erde
gefordert
Wohnung
all
Menge
gerne
Hintergrund
hören
Deutschlands
selten
Weitere
bestätigt
bestimmt
Statt
entstehen
nannte
schreibt
Union
brauchen
gewählt
Kraft
elf
trägt
zieht
Grenze
Geschäftsführer
Team
Gebäude
Tonnen
Wettbewerb
Anspruch
Polen
morgen
Bremer
Wegen
Gebiet
glaubt
Sa
Natur
Arbeiten
jene
Fällen
Jahrhundert
leisten
Zeitpunkt
internationale
mein
Konkurrenz
nach wie vor
nicht einmal
stieg
notwendig
sogenannte
fahren
kostet
entsprechenden
geplante
geschlossen
Fehler
Zweifel
Erklärung
wiederum
erschienen
gehe
Glück
erfolgreich
fehlt
Gruppen
Aktion
kündigte
meinen
manchmal
verschiedene
übernommen
möglichst
SZ
lieber
Vielleicht
Warum
Verantwortung
Gespräche
Suche
gern
fallen
Organisation
Preise
weitgehend
Basis
Computer
aufgenommen
Schutz
Eindruck
fiel
nahe
schlecht
lebt
Verhältnis
Forderung
britischen
sozialen
Technik
entstanden
Vorstand
verantwortlich
of
bestimmten
jüngsten
geboren
erhält
wobei
Gegner
Gründen
Material
Spitze
Gewinn
Punkten
vertreten
Schulen
Studie
Zeichen
gewonnen
Kurs
Washington
Türkei
Erfahrungen
wirkt
Armee
erhielt
beginnen
bißchen
entfernt
vorgesehen
Ergebnisse
zahlreiche
entgegen
Ohne
hielt
privaten
sucht
Gemeinde
Antwort
Zentrum
bilden
legen
Schweiz
gemeinsamen
weg
teilweise
Großbritannien
Licht
Hannover
Produkte
Stimme
diesmal
Schluß
gingen
angeboten
Gesicht
Treffen
Nachdem
ließen
eröffnet
versuchen
Konzern
Leistungen
Gäste
Wohnungen
möglicherweise
Dafür
wichtige
Neue
Rund
zog
geraten
Bewegung
Gegen
nötig
Mitglied
hundert
Düsseldorf
PDS
wahrscheinlich
Danach
vermutlich
selber
ständig
Senat
Branche
Journalisten
enthält
laufen
Vom
Straßen
Einführung
arbeitet
verlangt
Werke
Insgesamt
Runde
Besuch
unterstützt
Manager
Brüssel
de
schweren
sitzt
geschrieben
jemand
französische
Bereits
Wachstum
taz
bestimmte
Drei
Freiheit
entsprechende
kennt
Band
Arbeitgeber
glauben
Wege
verurteilt
tritt
Volk
Pläne
R
angekündigt
Satz
sitzen
Vorschlag
rechnet
muss
erhöht
Investitionen
Aufgaben
warten
entdeckt
wichtigsten
Heimat
verstehen
schrieb
trotzdem
erfahren
Unternehmens
frühere
bekommt
Jugendlichen
Dinge
öffentliche
Institut
Wirkung
sorgen
trifft
reden
Werte
Forscher
Wo
Sitzung
zusätzlich
vielmehr
Anlaß
Beide
gehalten
Tel.
Schweizer
beschlossen
Serben
Bundestag
Verwaltung
vorher
automatisch
betont
Leistung
abgeschlossen
Obwohl
zufrieden
Beschäftigten
Papier
Thomas
Verbindung
Sinne
ziemlich
Debatte
enthalten
ausschließlich
bestehen
Flüchtlinge
Jugendliche
Freund
A
Themen
überall
droht
Gewerkschaften
Bedingungen
Beziehungen
Text
europäische
Punkt
Erfahrung
The
I
Außenminister
soziale
russische
Tisch
Republik
höher
reicht
Million
gehabt
politisch
folgen
ähnlich
geschaffen
Schaden
erster
Körper
Amerikaner
getötet
Einige
Frieden
zählt
Beteiligung
Wagen
Bahn
vergessen
Verlust
Tiere
Museum
gegründet
daraus
Start
Kontrolle
Einfluß
Österreich
Allein
Norden
Wunsch
manche
Wahlen
Reise
steigen
gemeinsame
Darstellung
Demokratie
König
England
nennen
Teile
Jahrhunderts
denken
Name
Lehrer
S.
laufenden
verbunden
Qualität
zusätzliche
Widerstand
schön
Spanien
gegangen
Beamten
Jeder
Europas
Freunde
mitteilte
erklären
Familien
Gerade
gefallen
Aktie
Krise
Baden-Württemberg
Nummer
wies
außerhalb
gestiegen
Reform
Literatur
Arbeitslosigkeit
Lebens
Sozialdemokraten
gewann
Moment
angeblich
entsprechend
Mill
weiteres
beträgt
dritte
wesentlich
Amerika
Insel
britische
Nachfolger
entspricht
dahin
unseren
solcher
Juden
Sport
Rathaus
verkaufen
größere
Frühjahr
gebaut
Wahrheit
dar
Kommission
Polizisten
Bosnien
offensichtlich
Grundlage
relativ
Nein
Klasse
tut
hängt
wenigstens
aktuellen
Modell
Herstellung
hinzu
Gedanken
Übernahme
entwickeln
Quartal
meiner
dürften
Keine
jener
Zustimmung
legt
fordern
Einheit
Natürlich
blieben
Laut
in Zukunft
Szene
Klaus
Bundeskanzler
Schwierigkeiten
geblieben
lesen
Besonders
getroffen
keineswegs
Abschluß
Verlag
Interessen
Netz
anschließend
Plan
Ausbildung
befindet
zunehmend
verzichten
gespielt
ermittelt
legte
Ruhe
Hans
Händler
genutzt
höhere
starke
treten
Veranstaltung
Stimmung
Ärzte
erheblich
standen
Teilnehmer
möchten
starken
Forderungen
Stand
Anlage
siehe
erfolgt
Vertrieb
beste
gelungen
Ordnung
Andreas
lautet
kritisiert
Schröder
machten
verstärkt
Süden
Haltung
freien
weist
nahezu
Motto
abgelehnt
gelang
gezogen
frühen
schreiben
aufs
gleiche
öffentlich
Häuser
kleiner
folgt
Einer
Ja
Wien
möglichen
weiterer
kaufen
Gefühl
wirtschaftlichen
Initiative
hofft
dürfe
Person
Telekom
kennen
interessiert
Beitrag
Geschäftsjahr
lernen
gefragt
bezeichnete
Meister
Bücher
kürzlich
Tradition
einzelne
Vorsitzender
Verband
Grüne
überzeugt
Rückkehr
Also
schwere
falsch
unten
behandelt
indes
großes
Worte
getan
Vorstellung
somit
langsam
Wählen
gedacht
geändert
Bisher
hervor
Hessen
Städte
unbedingt
Hotel
Artikel
tätig
zahlreichen
Geburtstag
gesprochen
schließen
Engagement
Alles
Gründe
erlaubt
Kl.
Ausländer
Anleger
größer
verlieren
Verhalten
ausgesprochen
fanden
Betriebe
Praxis
ums
galt
Gemeinden
Wolfgang
Kanzler
Viertel
private
Zustand
miteinander
genauso
präsentiert
Planung
Forschung
staatlichen
Gott
einzigen
wichtigen
kosten
Verkehr
befinden
Kauf
Vorstellungen
Halle
Untersuchung
s
Rom
bessere
unserem
jeweiligen
angelegt
beendet
Fälle
Einschätzung
stehe
Dienst
herrscht
Begriff
Sekunden
Essen
ans
erfüllt
Krankenhaus
Auskunft
bauen
Rechnung
Arbeitnehmer
endgültig
Truppen
Jungen
Aufbau
leider
verpflichtet
Auffassung
komme
Karriere
bezahlen
Telefon
Rest
Umwelt
schlägt
bewußt
wichtiger
Sonne
trat
Inzwischen
gelangen
schneller
Kandidaten
Brief
folgenden
erscheinen
wirtschaftliche
Nr.
Fahrer
erforderlich
Rennen
Nachfrage
Morgen
Verdacht
eigener
Hinweis
Umgebung
bestätigte
Regelung
Fenster
dienen
modernen
zuständig
Flughafen
Generation
gelegt
ergeben
nationalen
Waffen
Schicksal
Entscheidungen
Jugend
Niederlage
Spaß
Niveau
Gelände
Trend
heißen
Tatsache
Presse
Feuer
bezahlt
Förderung
Ganz
Bildung
vorstellen
grundsätzlich
voller
Winter
italienischen
Botschaft
Investoren
Grad
Geschäfte
Leser
spielte
bayerischen
erzielt
reichen
Einrichtung
Energie
Gelegenheit
regelmäßig
übertragen
Freude
verändert
Umgang
Fans
entweder
Dauer
Finanzierung
Hersteller
Größe
eingestellt
Kontakt
früh
ursprünglich
m
Prinzip
Ausdruck
definieren
Mittelpunkt
Wunder
eindeutig
Quadratmeter
Mitarbeitern
Behandlung
größeren
Nachbarn
Gleichzeitig
Schriftsteller
Himmel
hoffen
unterstützen
Auge
Risiko
allgemeinen
verdient
Tor
Finanzminister
Maria
behauptet
Rücktritt
schwarzen
bewegen
Immerhin
plus
mögliche
passiert
Angesichts
betroffen
durchgeführt
entsteht
Vorwürfe
näher
bekam
Aussage
Verfassung
Helmut Kohl
Bewohner
vorhanden
richtige
übrigens
Kommunen
Städten
Werner
verfügt
Filme
Tabelle
historischen
Werbung
fragt
Gegenteil
Fischer
Gegensatz
Bauern
Arzt
Leitung
voraussichtlich
Dieter
besondere
Abgeordneten
sehe
DIE
Arbeiter
Beschluß
festgenommen
Ermittlungen
Minute
Anzahl
Willen
Ruf
aktiv
Zwischen
Karlsruhe
einiger
westlichen
Schweden
technischen
verwenden
Vorwurf
zwanzig
the
höheren
offiziell
tief
in der Regel
Du
Ausbau
Auswahl
Voraussetzung
Wissenschaft
richtigen
schien
festgelegt
Bilanz
erhöhen
kurzem
Fast
Gang
vorerst
Hände
wirken
Vertrauen
denkt
lösen
Positionen
zählen
Veränderungen
besitzt
Alternative
Falle
Entwurf
Ziele
sichern
ernst
positiv
Tat
ermöglicht
Ideen
Damals
ausgeschlossen
Änderung
Ebene
äußerst
Lager
zweimal
Brandenburg
Tür
dringend
Regisseur
Wechsel
Begründung
alter
Wirklichkeit
Pfennig
fehlen
links
Summe
Aktivitäten
Erinnerung
Zugang
II
praktisch
geöffnet
Leipzig
Frank
Strecke
japanischen
fährt
Wende
Herz
Autoren
fürs
übrigen
Andere
Ausgabe
Fußball
Kölner
kritisierte
Projekte
versteht
Stil
letztlich
Aussagen
Oberbürgermeister
herum
Bundeswehr
Verständnis
steigt
kämpfen
zugunsten
glaube
Fraktion
Posten
Dorf
Post
unmittelbar
Bruder
außen
welcher
Dagegen
Rang
Trotzdem
Krankheit
Heinz
eingerichtet
Auswirkungen
Strom
bloß
Auseinandersetzung
zumal
Struktur
Linie
Felder
Ministerpräsidenten
dient
Clinton
wußte
falls
entstand
Herrn
Autofahrer
Information
Erwartungen
Sitz
definiert
warf
Fusion
Untersuchungen
gaben
verlor
los
daraufhin
Zinsen
scheinen
Sowjetunion
Büro
angenommen
Ursache
Steuern
fühlen
Anlagen
Jürgen
Franzosen
allzu
liege
verteilt
soviel
Jelzin
Landtag
Nürnberg
Ab
Bereichen
stammt
Service
künftigen
Kino
Behörde
gehandelt
Nutzung
ausgerechnet
Interview
Wissen
zuerst
aufgefordert
Gewerkschaft
davor
Ausnahme
Erhöhung
wächst
gearbeitet
Rechte
eins
unterschiedlichen
Walter
geradezu
wirft
international
Zug
erreichte
Bedarf
erlebt
teuer
Kritiker
Flucht
Klage
Änderungen
u.
informiert
geschickt
Gerhard
erinnern
Männern
Unternehmer
klingt
Hinweise
kräftig
fort
rein
eigenes
Immer
spät
Eröffnung
Beratung
Franz
Gefängnis
städtischen
angezeigt
rasch
vorgestellt
erfüllen
freie
fertig
Haushalt
berücksichtigt
Dadurch
schlagen
Direktor
Realität
Falls
B
Schreiben
Sender
Provinz
Job
festgestellt
Standort
Beruf
gestorben
voraus
gesucht
überwiegend
Stellung
Einigung
Vorschläge
Texte
fühlt
Schuld
leichter
vierten
Halbjahr
Rücken
Innenminister
Karten
halben
betrachtet
schlug
geschehen
Zeitraum
vermeiden
stattfinden
prüfen
unterdessen
ausländischen
vieler
Formen
Tore
starb
Regeln
Einrichtungen
Umfang
fragen
Konflikt
Vereinigung
Vier
Je
Teilen
Vorsitzenden
Voraussetzungen
Plätze
beraten
Einwohner
Verluste
rechten
zugeordnet
tausend
gerechnet
offenen
warnte
verbessern
unterwegs
führenden
Hauses
Anbieter
übernimmt
diskutiert
Herren
Anstieg
ausländische
Objekte
Geschichten
versuchte
bisherige
beschreibt
Etwa
Hof
Serie
allem
Unterschied
weißen
türkischen
Revolution
Personal
hilft
Karl
Gründung
Martin
verboten
verhindert
nahmen
Lust
Schauspieler
Fahrt
Veranstalter
begründet
Wahlkampf
Auftritt
guter
gutes
ARD
Dichter
Vorbild
finanziellen
Allianz
zerstört
hart
rief
Einnahmen
ermöglichen
einig
Beamte
and
gelingt
in erster Linie
Status
gefährdet
Vorteil
Strukturen
rechts
staatliche
Kooperation
Spiele
Kräfte
persönlich
wachsen
Atmosphäre
Landesregierung
wann
Angriff
Müller
Regionen
Dresden
besetzt
technische
Plus
Darüber hinaus
gesichert
besonderen
gehörte
verspricht
vergeben
traf
a
wonach
Inhalt
Vorhaben
plant
Galerie
Horst
Protest
Urlaub
gelassen
Traum
Geben
steckt
Leuten
bestimmen
mehrfach
Sollte
Tätigkeit
wesentlichen
Josef
Alexander
beteiligen
unabhängig
finanzielle
Anwalt
Veranstaltungen
überraschend
gescheitert
offiziellen
pflegen
roten
bildet
solange
Erfolge
schließt
Helmut
Innenstadt
Junge
Mitteln
Peking
aufgebaut
Zeitungen
Becker
politischer
Wähler
Software
demnächst
Konsequenzen
Wird
erzeugt
retten
unterschiedliche
veröffentlicht
höchsten
stimmt
Reaktion
Bernd
halte
reduziert
moderne
mache
M.
Rückgang
schwierig
produziert
Ausgaben
hört
Kassen
Tokio
General
schloß
Günter
deswegen
organisiert
ZDF
Methode
persönlichen
Sorge
Sorgen
verfolgt
Ungarn
Nato
Messe
israelischen
vollständig
Figuren
kurzen
Fest
bosnischen
welchen
Angeklagten
Höhepunkt
künftige
finanziert
aktuelle
zeigten
bekannten
spätestens
Strategie
vorgeworfen
bemüht
sorgt
Rat
meinem
Neuen
Ostdeutschland
gegenwärtig
benötigt
Spur
Ball
Finale
keinem
schöne
reagiert
Manfred
schützen
Ernst
stammen
Rande
Schatten
verbessert
jüdischen
positive
manchen
entlassen
Phase
Vorgang
Asien
eng
halbe
beziehungsweise
Vereinigten Staaten
Gemeinschaft
Abschnitt
Verbrechen
dank
Geist
tot
eingeführt
berichten
anlegen
Kirchen
Funktionen
Sanierung
Arbeitsplatz
Sieger
Aktionen
vorgelegt
verabschiedet
Wind
vorbereitet
Fahrzeuge
Kurse
untersucht
durfte
u.a.
Maschinen
Unsere
ausgelöst
Indien
Haft
bewegt
Zweck
Währung
bitte
Jahrzehnten
Wald
wichtigste
Zimmer
Verlauf
ausgesetzt
Prüfung
Verwendung
kurze
Zunächst
Blut
Anwendung
Anhänger
Aufnahme
Sammlung
benutzt
Angebote
Einstellung
Umsetzung
Dach
Irak
gezwungen
Premiere
AP
hoher
starten
Kasse
Nichts
Hektar
persönliche
Paul
Termin
gemeldet
entwickelte
Tatsächlich
Kontakte
anbieten
Räume
Abgeordnete
stellten
Regierungschef
menschlichen
Abbau
meldete
Ton
Unfall
Touristen
englischen
Abkommen
erfaßt
Solche
Metern
selbstverständlich
Stiftung
Existenz
Zeugen
Gold
Absicht
Objekt
Anders
Anklage
Verbraucher
funktioniert
Großen
bestehenden
Einkommen
beider
sinnvoll
Abstimmung
liefern
schafft
Ecke
Siemens
Gutachten
Version
Kennzeichen
Konferenz
Pariser
Bundesliga
erhebliche
erfolgen
traditionellen
Dialog
Dutzend
abhängig
hängen
ausgegeben
Bedenken
ergibt
einschließlich
Konkurrenten
Iran
vermutet
aufnehmen
verzichtet
bundesweit
bekannte
betroffenen
befürchten
Bekl
Anerkennung
Ehe
liest
Gast
damaligen
Wiener
genügend
ersetzt
Vereine
beobachtet
notwendigen
verdienen
niemals
Brand
verstanden
stolz
reagieren
Laufe
schönen
vorgenommen
erhoben
Spuren
mitten
Reformen
erschien
Mut
grünen
Christian
verliert
Anna
Aussicht
andererseits
Staates
Charakter
Spiegel
Analyse
Kapital
Organisationen
Beschäftigung
Herzen
einiges
Landwirtschaft
bedroht
linken
Deutscher
Russen
Derzeit
stellvertretende
eingeladen
verlangen
langem
Stadtrat
Beiträge
erkannt
historische
Zuschauern
trug
Afrika
Schritte
höchste
Mord
Dortmund
Studium
erläutert
Alltag
Teilnahme
befürchtet
geschafft
Betrag
Nachmittag
solches
Betroffenen
ausdrücklich
jenen
präsentieren
Bildern
Fläche
Berichte
Wiesbaden
klassischen
heftig
äußerte
Gewinne
Gesprächen
klare
umgesetzt
Justiz
soweit
wiederholt
Bislang
durchsetzen
ausreichend
endet
Atlanta
holen
Abstand
geprägt
Nation
Meer
Berlins
keinerlei
aufgerufen
Mitgliedern
gewisse
Programme
Musiker
Unabhängigkeit
einsetzen
Aufträge
Pflege
Management
behaupten
Bier
gewinnt
Verbesserung
Jahresende
belegt
besseren
Nachrichten
beschrieben
Zuge
SAP
Saal
Berufung
schwarze
Farbe
Georg
Konzert
Umfeld
gelernt
Besitz
Wand
Anforderungen
Kabinett
Kosovo
Sachsen
Pause
erstes
Waren
Landgericht
Händen
Integration
fuhr
gebeten
gering
Vorlage
New Yorker
www
Schloß
zuständigen
Risiken
sämtliche
gelegen
Aufklärung
Fünf
Daher
erleben
Pflanzen
spüren
feiern
schwerer
draußen
Beweis
Gewicht
umgerechnet
Europäischen Union
lagen
Fonds
Kompromiß
handeln
Training
Kunde
geschlagen
hinweg
Hochschulen
Verhältnisse
gelte
Gesundheit
Nachricht
Mein
junger
Kapitel
fördern
Kamera
greifen
hierzulande
normalen
Augenblick
Waigel
werfen
Verletzungen
Äußerungen
Tausende
begleitet
üblichen
Materialien
Blatt
Bereiche
Abteilung
Arbeitsschritt
erzählen
dauert
Heinrich
belastet
Verträge
Wetter
Keller
Farben
entlang
begründete
Welche
fielen
Vereinbarung
Währungsunion
Zugleich
Sprecherin
Führer
Gegenwart
Erste
zusätzlichen
Londoner
angewiesen
Kriterien
Kurz
hergestellt
vereinbart
lasse
Ihren
Ministerium
Pfund
schlechte
Kanada
Vereinten Nationen
Bundesbank
Dividende
investiert
italienische
Gut
Südafrika
Gestern
getragen
profitieren
japanische
Internationalen
geprüft
sparen
Systems
Stadtteil
hauptsächlich
Robert
versichert
vorgeschlagen
hinein
Co
Brasilien
späten
Gesetze
Neues
irgendwann
Nordrhein-Westfalen
unseres
Maschine
ostdeutschen
beobachten
Typ
Seele
Not
Dienstleistungen
Bord
rechtzeitig
BMW
zuviel
Zentimeter
katholischen
Später
Ereignisse
offene
Identität
folgte
Bahnhof
hielten
allenfalls
spanischen
chinesischen
Anfrage
serbischen
Produkt
Australien
A.
Landschaft
Regierungen
Niedersachsen
Schmidt
beschäftigen
Große
Vorteile
leiden
arbeitete
bayerische
passieren
Regie
Eigentlich
übrig
kleines
höchstens
Bemühungen
Märkte
wert
Pfarrer
ungefähr
zentrale
warnt
beinahe
Microsoft
vor Ort
Mischung
desto
Vorgehen
Oper
zentralen
sowieso
liefert
ruft
Niemand
Weltmeister
Kern
Beziehung
jüngste
aufmerksam
seitdem
Reisen
führten
Arbeitsmarkt
Fuß
bleibe
leer
Beobachter
vermitteln
Republikaner
Verteidigung
überrascht
unverändert
Werken
klein
Manche
öffnen
schätzt
Bus
Toten
zogen
mancher
besitzen
Hotels
Rebellen
Ausgleich
gefeiert
Ereignis
Benutzer
erhöhte
Reuter
Methoden
Feuerwehr
angegeben
Darin
Reihen
erzielte
WM
übernahm
Abschied
behalten
Lande
nationale
entscheidenden
wartet
israelische
Universitäten
Stärke
nunmehr
gelegentlich
anzeigen
verändern
türkische
Bäume
finanzieren
Briten
gerät
selben
Ihrer
Vortrag
Kommunikation
bedeuten
halt
IG Metall
Analysten
Hongkong
schlechter
Vorbereitung
Davon
Katastrophe
getrennt
Figur
derart
Schlüssel
Stücke
Bündnis
geschieht
Liter
in Kraft
Mauer
Erkenntnis
paßt
Kongreß
Hoffnungen
späteren
Marke
Kenntnis
Mannes
Umständen
greift
saß
Details
unmöglich
Nachrichtenagentur
fragte
gewiß
Belastung
namens
beweisen
verfügen
Anschlag
Gebieten
zahlt
Kaum
höchst
Pressekonferenz
falschen
Bundesländer
langfristig
schlechten
Lösungen
gestartet
Andererseits
konkrete
Hat
Fortsetzung
Bundesrat
Gesellschaften
Tendenz
falsche
lehnte
zuständige
Helden
sichtbar
Aufmerksamkeit
setzten
Stefan
Regen
vorne
lief
geboten
solch
Genehmigung
Milliarde
dauern
häufiger
Kilogramm
Bereitschaft
Meine
Besitzer
eigentliche
Partie
Elisabeth
Magistrat
Unser
doppelt
Auseinandersetzungen
dich
Kollege
militärischen
ältere
fürchten
Problemen
Arten
diejenigen
Holz
Erweiterung
Denken
Bewertung
deutliche
Europäischen
entscheidende
Spielen
Landkreis
Düsseldorfer
informieren
geringer
Jede
Bundesländern
Aufgrund
Variante
Schwester
Aufsichtsrat
festlegen
fortgesetzt
Beteiligten
Bürgern
Schäden
Sind
nein
betreiben
positiven
neuen Bundesländern
übergeben
Frankreichs
Internationale
Zeitschrift
Mitteilung
Lehre
gefördert
kleinere
geeignet
Weihnachten
Umfrage
Mieter
halb
Berg
Kroatien
Herbert
nochmals
registriert
Tempo
Spannung
Klima
Alten
allgemeine
See
Bewerber
irgendwie
Freundin
Pflicht
erweitert
Papst
Widerspruch
teilnehmen
Trennung
welchem
erstellt
Nase
erklärten
unterscheiden
sicherlich
Schulden
senken
Herzog
entscheidend
Stoff
gerecht
VW
besucht
enttäuscht
Architekten
Anzeige
Überlegungen
festen
hessischen
stiegen
ersetzen
Aktionäre
verhandelt
zweiter
sorgte
Otto
Privatisierung
Auftakt
zweier
richtet
Einheiten
Versuche
Zellen
Mengen
beziehen
führende
Schiff
umfaßt
Inszenierung
Begegnung
ähnliche
Großteil
Theorie
Gerhard Schröder
denke
vermittelt
in Sachen
demokratischen
Zürich
Stellungnahme
welches
erschossen
gekauft
Maß
Dienste
gesperrt
Gestalt
Stein
Neubau
weisen
harten
forderten
feiert
extrem
allgemein
Diesen
voran
Versorgung
Eis
billiger
überprüfen
Mannheim
betrifft
verwies
Demonstranten
minus
mögen
Notwendigkeit
überlassen
lädt
schicken
vorhandenen
notwendige
Foto
Bezeichnung
finanziell
Dank
Schneider
ehe
Image
Belgien
gefährlich
betrieben
Freiburg
Steigerung
durchschnittlich
Schwerpunkt
baut
elektronischen
Rußlands
Dokumentation
Ablehnung
dargestellt
geklärt
Brücke
dreißig
Bewußtsein
glücklich
alleine
Einstellungen
ferner
gewachsen
empfiehlt
errichtet
egal
legten
Einstieg
beteiligten
Osteuropa
scheinbar
Reich
kostenlos
Anteile
älteren
geriet
Ärger
Länge
Verzicht
Elemente
gesorgt
Menschenrechte
weiße
Gestaltung
Teams
gebildet
ruhig
Premierminister
kurzfristig
Jerusalem
Geräte
Mund
Lafontaine
Vereins
gefahren
Früher
Jugoslawien
L
jenseits
wechseln
versuchten
sank
samt
polnischen
Autobahn
grüne
gehörten
Herkunft
Rückzug
David
Potsdam
Hinzu
Bill Clinton
Garten
betragen
dpa-AFX
diskutieren
Architektur
sterben
Teufel
Kommunisten
erzielen
Verteidigungsminister
Fahrzeug
Bestand
Moderne
John
Institutionen
Viel
womöglich
Lauf
beschränkt
Glas
aufgehoben
Szenen
wahr
lebenden
auftreten
Vorfeld
ansonsten
Transport
zeichnet
Strafe
hinten
jetzigen
neuesten
Bett
bestätigen
gesunken
erhielten
Parteitag
Krieges
Verbot
Beispiele
sahen
Sendung
verbreitet
erfolgreichen
Vielmehr
Eintritt
gezahlt
Belgrad
kümmern
zustande
Durchschnitt
Vordergrund
antreten
teurer
Solidarität
steigern
wünschen
Philosophie
gesetzlichen
Ganze
Türen
US-Dollar
Alfred
riesigen
vergeblich
zumeist
konzentrieren
Maler
Manchmal
raus
schlicht
bereitet
Hochschule
Bundestrainer
veranstaltet
unklar
Vorgänge
großem
Perspektive
bewertet
Kaiser
breit
lehnt
üblich
Signal
maximal
Klinik
Käufer
Dame
entschlossen
reagierte
einziger
bestehe
Auflösung
Forum
brachten
Beine
Küche
Glauben
schwierigen
Customizing
gelöst
Griff
wahren
Züge
akzeptieren
gemeint
Betreuung
gestalten
betrug
inneren
erteilt
Ausschuß
dreimal
Dax
Gedichte
investieren
verhaftet
Yen
sowjetischen
Mexiko
vorigen
abends
Palästinenser
menschliche
erwiesen
bot
Hauptversammlung
innen
Dänemark
militärische
Argument
Verantwortlichen
Haut
Angeklagte
Aufwand
reine
Distanz
einstellen
Betrieben
Zuvor
RTL
Konjunktur
Bernhard
irgendwo
Park
sagten
Damen
unterschiedlich
offizielle
umstrittenen
harte
Beschäftigte
Amtszeit
gesellschaftlichen
laufende
Hinter
Konto
International
Ursachen
im übrigen
vorn
ausgezeichnet
gelesen
teilen
akzeptiert
absolut
bestellt
verweist
vieles
Überzeugung
Vermögen
Politikern
schnellen
denkbar
Fotos
gemessen
freuen
Sprung
stimmen
reichlich
Restaurant
gestrichen
gewarnt
achten
abgeben
Friedrich
Akten
Küste
wirtschaftlich
jüngst
berufen
schnelle
Briefe
räumte
Kaffee
Gelder
Symbol
Gebühren
kleineren
Europäer
Johann
Interessenten
entscheidet
teilt
Italiener
Parameter
Freunden
verschwunden
stecken
garantiert
Zuwachs
Gerechtigkeit
Rand
Angestellten
Haushalte
weltweiten
ausgestattet
Club
nieder
bestehende
einfache
geschätzt
UNO
B.
Moskauer
Spekulationen
nachmittag
produzieren
Ebenso
Mühe
Phantasie
Berater
Medizin
geleistet
stößt
Tode
teil
vorwiegend
konzentriert
Umweltschutz
vgl
freiwillig
verursacht
H.
Alte
Steuerreform
FR
Hafen
allmählich
von Anfang an
Wirtschaftsminister
überzeugen
Kurden
teils
Diskussionen
Vorgänger
Konzentration
verschiedener
Jahrzehnte
veröffentlichten
begeistert
beenden
Richard
Tagesordnung
Fleisch
Barcelona
Schnitt
Drogen
mitgeteilt
leitet
nachts
Anwohner
Export
Regel
mittels
besuchen
Handlung
erworben
brach
breiten
Gerät
Ohren
konkreten
Würde
gäbe
Ablauf
fließen
Bezug
Ukraine
Eingang
entschied
Flugzeug
Erkenntnisse
Stock
aussehen
froh
treibt
Haben
einfachen
gepflegt
gestanden
beitragen
Zähler
beantragt
Gefühle
ergab
Wesen
betreibt
brauche
überprüft
Auflage
besetzten
Erinnerungen
Jazz
untergebracht
Stern
Mangel
interessant
Tasche
Scharping
verschoben
Hund
Barbara
volle
melden
d.h.
Demonstration
weshalb
berühmten
Dokument
Öl
EU-Kommission
anerkannt
genannten
berichteten
echte
DW
reduzieren
Bundes
komplett
Verbindungen
Mainz
sprachen
fliegen
liebsten
folgende
Maßnahme
Konzerns
Gemeinderat
Hinsicht
benutzen
richten
Mehrere
Adresse
Asylbewerber
eine Reihe von
Ludwigsburg
Meldung
Modelle
Schließung
Umbau
speziell
Vaters
verlangte
Fachleute
Chaos
Zehn
abgesehen
auf jeden Fall
Reaktionen
monatlich
Operation
geäußert
hinnehmen
gebraucht
Krankenkassen
fünfzig
bestand
Report
Türken
Kroaten
dachte
verbindet
Papiere
Liga
Mir
Kombination
Studien
Maße
einerseits
Büros
Entwicklungen
scharf
wissenschaftlichen
teure
ausgebaut
teuren
Gremium
Bildschirm
Eigenschaften
Zum Beispiel
Staatsanwalt
Geschwindigkeit
optimistisch
innere
überlegen
hoffe
dir
Sätze
gefaßt
anhand
formuliert
Chinas
räumt
Ehefrau
gewissen
morgens
erfassen
J.
Stars
Absatz
Sturm
begrenzt
im Gegensatz zu
Eigentümer
klagt
löst
Staatssekretär
Ihrem
Militärs
finde
Aufstieg
Gebiete
Genossen
Kinkel
Rente
kommende
Marktanteil
Ware
kämen
ergänzt
Genf
gestaltet
normale
Katalog
stünden
heutige
Veränderung
Systeme
vierte
Datum
Arbeitsplätzen
Finger
Zufall
Wolf
Standard
Griechenland
Rechtsanwalt
Unterschiede
verschwinden
betreut
demnach
Dokumente
Armut
verfolgen
erfolgreiche
Gebrauch
Steuer
Prag
zurückzuführen
hinterher
S
Kampagne
Tanz
bezieht
Geburt
existiert
startet
Hermann
Geheimnis
Ansprüche
Arm
Lange
wirkte
Rudolf
Arme
treiben
Umzug
Verletzung
Lasten
lässt
Theo Waigel
Premier
Scheitern
unterzeichnet
Muster
Lufthansa
befand
Sicherung
abgegeben
gewünschten
jahrelang
aufgegeben
abgebaut
Masse
Abzug
begrüßt
käme
zitiert
drücken
niedriger
kurzer
kontrolliert
Radio
verlegt
freut
Anschließend
erheblichen
versprochen
spezielle
fünften
breite
Verlängerung
Angehörigen
Star
Gegend
direkten
Karte
Schätzungen
letzter
erinnerte
Instituts
Generalsekretär
schauen
seinerzeit
Turnier
leichte
i
Technologie
Ost
Profis
Kiel
Genau
engen
absolute
Fritz
Handeln
Aufschwung
Vertretern
Nazis
Wilhelm
aufgestellt
Kilometern
gesteigert
Unterdessen
Minus
Zentrale
Paar
Religion
Seitdem
österreichischen
Beifall
Merkmale
Grundstück
TAGESSPIEGEL
halbes
Tschetschenien
Sarajewo
Kurt
Herrschaft
verbinden
wissenschaftliche
Tier
gesenkt
Verteidiger
Öffnung
drohen
einziges
umgekehrt
Konflikte
Ähnlich
Baum
Kapitän
planen
U
ots
betrachten
Front
geliefert
Gastgeber
entsprechen
Angelegenheit
Stadion
trennen
lebte
längere
Gefahren
Produkten
Senkung
kritisch
Anschluß
gegenseitig
Darmstadt
wachsenden
Böblingen
wuchs
Spenden
zugelassen
Lastwagen
klären
Ulrich
Schönheit
Antworten
Milosevic
Bezirk
Liberalen
Vielzahl
feststellen
Abschaffung
in der Tat
geringen
erkennt
Sozialhilfe
Stabilität
Einzelheiten
Orchester
Eigener
Deutsch
Sänger
durchs
Kämpfe
Fraktionen
klaren
Weiter
erzeugen
vorübergehend
Franc
beklagt
elektronische
gibt's
bezogen
Anlegen
derzeitigen
Graf
Unterricht
Stadtverwaltung
Krankheiten
Kommentar
Etat
tiefer
Minderheit
Index
Ankündigung
Brigitte
eigentlichen
beigetragen
Umsätze
tat
einstigen
durchgesetzt
seither
Aufruf
rufen
Rumänien
Augsburg
Einladung
gewährt
bewiesen
Regelungen
West
bricht
Landrat
zugute
hingewiesen
langer
versicherte
streng
Hunderte
Unterlagen
Schlag
sammeln
Instrument
Bischof
holte
Aussichten
Kredite
äußern
TV
Verteilung
achtziger Jahre
Proteste
hohem
geringe
Bestandteil
Vorschriften
Israels
Westdeutschland
Joachim
jederzeit
suchte
Botschafter
Tageszeitung
Infrastruktur
ändert
Bayerischen
NATO
verlängert
aller Welt
geworfen
Respekt
Subventionen
derartige
lieben
Ring
technisch
Plänen
angesehen
Deutsche Bank
englische
Akt
Vogel
sinken
Mercedes
Herausforderung
wenden
lsw
Frankfurt/Main
hierzu
Wandel
Angestellte
Handwerk
Tote
Stoiber
singen
Bekämpfung
Ensemble
Besetzung
Erstmals
belegen
perfekt
gemäß
gesammelt
Helfer
Definition
wider
versorgt
Jobs
Show
Volkes
Verbände
Bearbeitung
Flächen
Rainer
empfangen
konsequent
sozusagen
lauter
Datenbank
wohnen
Institute
dicht
Darauf
Delegierten
Offenbach
Alkohol
eingeleitet
Bevor
vermuten
Hanau
ca
drohte
Jan
Daneben
ehemaliger
Erzählung
Uwe
Arbeitslosen
ernsthaft
Streik
gefällt
Armen
schaut
jenem
schuldig
erfährt
Niederlanden
Statistik
Kreisen
Medikamente
Bürgerhaus
verhandeln
Gegenstand
Oberfläche
befreit
verhalten
griechischen
PC
ermordet
amerikanischer
binnen
kulturellen
Konsequenz
drängen
Heidelberg
hab
erläuterte
City
stärken
anläßlich
verkündet
Zusammen
stieß
Gas
gezielt
Quelle
Volumen
Schaffung
Malerei
Madrid
Sechs
K.
Verpflichtung
handele
Tiefe
Stufe
Mütter
Zeilen
Leider
studierte
engagiert
verweigert
Ihm
eines Tages
dran
verteidigen
stelle
Laden
daneben
einzig
Temperaturen
Preisen
bedient
rechte
rote
jüdische
Träger
genaue
überschritten
Ehre
wahre
wieviel
ausgeführt
Anträge
Esslingen
endete
Angriffe
Chemie
Serbien
mehrmals
Kleinen
Einsparungen
einander
internen
eigens
Sponsoren
Streitkräfte
leidet
vorsichtig
genauer
Klassen
Bitte
darstellen
politisches
Häusern
Truppe
bedarf
normal
Telephon
Kassel
Rundfunk
Schnee
Abrechnung
stoppen
damalige
Kriminalität
erwarteten
Thüringen
örtlichen
Schau
versehen
durchführen
speziellen
vollen
Nutzen
Hinblick
Tagung
versetzt
Zuordnung
südlich
D
schätzen
Sprachen
zurückkehren
chinesische
riesige
kämpft
Stich
Begeisterung
Innerhalb
umfassende
zustimmen
Bewegungen
Nürnberger
inszeniert
kritischen
ökologischen
zugestimmt
Tour
genehmigt
Nummer eins
Ausgang
These
Sachen
Mode
Müll
zufällig
zurückgewiesen
Absage
Sand
Profil
gerufen
Vernunft
Unglück
Entlastung
Korruption
Amsterdam
dreht
feste
Zerstörung
Rhein
Mörder
fehlte
Niederlande
All
Tourismus
Lohn
durchzusetzen
Autorin
zurückgegangen
Gottes
direkte
mittleren
Komponenten
C
Ansatz
Einzelhandel
Element
live
Historiker
frisch
kritische
singt
Last
Vielfalt
klassische
erlitten
Moral
Beschreibung
trafen
Schiedsrichter
deutsch
Vorsprung
Hitler
kulturelle
Sekunde
Erich
größter
Kandidat
enge
Fluß
ähnlichen
gefolgt
Einmal
meistens
Gegenüber
westdeutschen
passen
regionalen
Boris Jelzin
quer
Mediziner
Günther
genießen
Fortschritt
Gramm
essen
traditionelle
Prof
Marktwirtschaft
leichten
entwickelten
ursprünglichen
Militär
Überraschung
Vision
FC Bayern
Norwegen
wünscht
Stürmer
gegenwärtigen
FRANKFURT
inklusive
Journalist
Station
sozialistischen
Rolf
zuversichtlich
Zweiten Weltkrieg
geeinigt
Ferner
liebt
ausgehen
internationaler
unterscheidet
Museen
Affäre
serbische
Töne
intensiv
deutlicher
fassen
Aufführung
Zahlung
Transaktion
Prognose
War
versprach
Wein
Mailand
Uni
Ursula
evangelischen
Portugal
Vortag
Büchern
normalerweise
meldet
Motiv
ließe
Schleswig-Holstein
Durchbruch
Wünsche
erkennbar
vornehmen
erleichtert
ausgewiesen
Schumacher
Lieder
Fr
Geschehen
arabischen
drin
niedrigen
nutzt
vielfach
Christen
Wieder
Versicherungen
umstrittene
OB
Quellen
Wiedervereinigung
folgten
Fakten
aufgelöst
Ägypten
eröffnen
benötigen
gründete
vertraut
Zuschüsse
erhältlich
fortsetzen
Hals
Inseln
Zusätzlich
Bayerns
n
präsentierte
Klub
ermitteln
Buches
Therapie
öfter
verdanken
Schlagzeilen
Erwachsene
Konsens
katholische
Explosion
fügte
dunklen
beschloß
wachsende
Generationen
sobald
ungewöhnlich
öffnet
Parlaments
Jedes
schwieriger
drauf
enger
Argumente
Gipfel
erstellen
Perspektiven
Bauer
gelingen
verläßt
Kann
Parteichef
Phänomen
umstritten
scheiterte
bemerkt
Alternativen
Johannes
Gerüchte
III
Ausmaß
Treffer
Insbesondere
Lebensmittel
Stolz
IWF
heftigen
bemühen
Kammer
Schülern
globalen
Branchen
redet
Passagiere
gebunden
Rücksicht
drastisch
Option
Lieferung
Menschheit
reinen
Haare
ökologische
Schäfer
Los Angeles
entdecken
Plätzen
Durchführung
fürchtet
angeben
Jörg
beherrscht
Sturz
weitaus
sofern
existieren
reisen
organisieren
Skandal
Räumen
auseinander
zugrunde
IBM
Tieren
Nachwuchs
St.
Treffpunkt
gelangt
derweil
Sozialisten
Rollen
wendet
hinterlassen
Greenpeace
überflüssig
Lohnfortzahlung
Vorgaben
niederländischen
spielten
verringert
Abwehr
geschützt
Annahme
getrieben
erreichten
Japaner
stärksten
Kreise
Belegschaft
generell
Solange
städtische
Einsicht
Anzeigen
böse
parallel
Wagner
kontrollieren
erstenmal
Vorstandsmitglied
Fähigkeit
Anliegen
Befreiung
total
Mannschaften
Bundespräsident
Test
vorläufig
Zeile
gebucht
Abends
Mythos
Veröffentlichung
vierzig
umfassenden
Ansonsten
werben
Gehirn
erwerben
Substanz
unteren
Rostock
Überprüfung
Rentner
zweites
DGB
Vorstoß
sichergestellt
deutlichen
musste
Gesetzgeber
gleichermaßen
bewahren
Motive
erledigt
vorlegen
Kindergarten
vertritt
Deren
weiten
Sowohl
Schwarz
demokratische
Akademie
löste
aufzunehmen
Luxemburg
euch
empfehlen
linke
erwähnt
vergleichsweise
schönsten
Kleine
Entdeckung
Taten
Waffe
löschen
Golf
etliche
Zugriff
Leverkusen
einzelner
jenes
Stellvertreter
Mittlerweile
hierfür
Loch
verwandelt
kehrt
eingeräumt
Holding
Ansehen
ausfallen
Merkmal
Regierungschefs
DFB
öffentlicher
Immer wieder
Füßen
letztes
Stoffe
Regime
Schweigen
Periode
feierte
durften
for
Abenteuer
endgültige
bittet
Redaktion
Reden
Gästen
versteckt
Immobilien
Kilo
gerichtet
Ludwig
Börsen
benachbarten
echten
bezeichnen
Überblick
konservativen
Kündigung
Ausstattung
Belastungen
verarbeitet
Staatspräsident
Zumindest
Qualifikation
krank
stehenden
Faust
Freistaat
Soll
angesprochen
untersuchen
Landeshauptstadt
Fazit
jemals
Umstellung
spanische
Enttäuschung
Komponente
Verbandes
gewußt
brechen
handelte
Lediglich
berücksichtigen
rot-grünen
gerettet
veröffentlichte
müde
vorgesehenen
streiten
genügt
Kulturen
Telekommunikation
ehemals
Sachsen-Anhalt
herrschte
beschreiben
steigenden
Meldungen
Kindheit
bewölkt
Oft
freundlich
Betreiber
Hanauer
besorgt
restlichen
erlauben
Etwas
UN
gestoßen
Bibliothek
verschaffen
Berichten
kommunistischen
Gute
Lied
Agentur
christlichen
Gemeinsam
Erwerb
Sportler
Nationalspieler
geborene
Quote
berechnet
Partnerschaft
Komödie
Bürgerkrieg
religiösen
Offenbar
Münchener
Einzug
schwach
quasi
schildert
Sonst
Motor
Rettung
aufgeben
drängt
geholfen
Dialogfenster
Schuß
verglichen
Protokoll
sozial
Christine
Zunahme
Börsengang
Wohl
vermag
gestoppt
Offensive
Versprechen
gehöre
behandeln
Sogar
gelaufen
Do
Brüder
mitunter
Entlassung
Steffi Graf
aufgeführt
Inflation
Übergang
Monika
bearbeitet
Sicher
Löhne
Filmen
Arbeitsgruppe
voneinander
heimischen
Bundesverfassungsgericht
keinesfalls
gefüllt
Unrecht
eingegangen
Im übrigen
Magazin
Detail
Innenministerium
Kürzungen
begannen
begegnen
entdeckte
geholt
massiven
umgehen
Potential
einfacher
verließ
weite
Münster
Rock
Franken
Sanktionen
anfangs
jüngeren
Vizepräsident
Köpfe
Bayer
verständlich
Weniger
eingeben
zugesagt
mit Blick auf
mehrerer
Eines
Besuchern
blauen
Ehemann
Haar
hinsichtlich
Defizit
Bach
Halbfinale
Fortschritte
Fax
Zur Zeit
lebende
skeptisch
Vermittlung
reichte
Karin
Irland
Gesetzentwurf
realisiert
Verfolgung
Freundschaft
Fähigkeiten
geleitet
Tages
Reduzierung
Andrea
Senator
Optimismus
Tränen
westliche
Singapur
leeren
zwingen
zeitweise
Ersatz
to
Linken
Flügel
Erhalt
jung
stimmten
Außer
Anstrengungen
Kalifornien
Bedrohung
durchschnittliche
festgehalten
Romans
natürlichen
Versammlung
scheitern
Arbeitszeit
oberen
locker
eventuell
Impulse
Opfern
gestohlen
vorliegen
wandte
drehen
einstimmig
v.Chr.
unabhängigen
Bertelsmann
Koch
täglichen
darstellt
verteidigt
massiv
Brüsseler
verteilen
Messer
erforderlichen
entfallen
Aufhebung
klagen
Weber
Prognosen
Flugzeuge
vergangene
Karlsruher
Angehörige
geltend
Geschmack
Völker
Wall Street
derselben
Flüchtlingen
Holland
führe
Nationalmannschaft
gekennzeichnet
kommunalen
lokalen
Fassung
Nationen
PKK
Ruhestand
empfohlen
Flug
Dimension
verdoppelt
dortigen
islamischen
Films
ausgegangen
gegründete
aufbauen
angeschlossen
steigende
wohin
Gegenzug
Erbe
gesellschaftliche
Taiwan
wohnt
bearbeiten
Verarbeitung
schöner
Festival
Arbeitslose
Ausstellungen
Argentinien
Versicherung
bedeute
lautete
Sozialismus
Held
aufeinander
Auflagen
Aktienmarkt
bekanntlich
nehme
angeht
Kompetenz
Christdemokraten
im Grunde
Freizeit
Leidenschaft
stoßen
Fabrik
reiche
deutet
organisierten
Wann
überwinden
Deutschen Bank
blickt
studiert
Beratungen
lebten
Finanzen
Spielern
Chor
freier
Laufzeit
Ali
Harald
vollkommen
stattfindet
Photo
hob
Ministerin
Präsenz
ausgeliefert
angegriffen
gewohnt
Delegation
geltenden
Sonnabend
exakt
Architekt
Anton
Helga
zum anderen
Abs
heftige
schwarz
Release
Altstadt
Modernisierung
Leiden
Italiens
Schiffe
Bruch
füllen
diesjährigen
EG
unterhalten
Werden
begangen
Wohnungsbau
zugänglich
Oskar Lafontaine
Erika
Ausnahmen
Gehalt
polnische
Diesmal
N
Varianten
Nerven
Flammen
Abhängigkeit
Zeuge
befreien
zeige
europäischer
nördlich
Kandidatur
lohnt
kommentierte
steuern
Islam
still
Programms
wesentliche
Kleidung
neuerdings
anderswo
sage
Max
dorthin
verbesserte
ausländischer
gründen
errichten
Rahmenbedingungen
Märkten
Komponisten
Märchen
Inhalte
Null
Kubikmeter
Marketing
nötigen
Arbeitsamt
Planungen
Bezirksausschuß
Pressesprecher
Unterhaltung
dokumentiert
Bedingung
Tübingen
Weder
Zeichnungen
gewannen
Sabine
Dass
plädiert
Übertragung
bist
gekostet
Bearbeiten
Lesen
getreten
USD
leise
überdies
Mißbrauch
Klubs
überleben
Termine
verantworten
stirbt
Exil
kommentiert
Effekt
palästinensischen
konfrontiert
Leiche
Prozesse
dramatisch
stimmte
Stadtwerke
Lächeln
Berechnungen
fügt
negativ
griff
Verlierer
übersehen
Mitternacht
Orten
CD
Kindes
wirksam
Goethe
Instanz
fraglich
Erziehung
medizinische
Tschechien
Frist
gelöscht
Klagen
Brot
einzusetzen
Miete
Göppingen
Professoren
Wut
südlichen
schlimmer
Gesichter
Ralf
Einbruch
verraten
interne
neuem
W.
Anzeichen
eineinhalb
zuordnen
Zusammenschluß
Villa
schwierige
Sieben
Auswertung
Berechnung
Sehr
befassen
gewünschte
unabhängige
Aspekt
bekamen
Witz
Austausch
schwachen
Schäuble
demonstrieren
angemeldet
fühlte
interessieren
Konkurs
geschah
Meisterschaft
Erfüllung
Engel
Lieferanten
Neuer
Inland
massive
Gerd
angehören
aktiven
fremden
gebrochen
geregelt
Persönlichkeit
Dresdner Bank
Zwecke
gesetzliche
Daran
zugenommen
Gerichte
Jury
Humor
Entfernung
Römer
vorliegenden
genannte
angebracht
gewährleistet
Betriebsrat
Beteiligungen
gestrigen
Fraktionschef
UdSSR
Marktes
Zurückhaltung
befaßt
Außenpolitik
zurückgekehrt
wußten
Gertrud
Weiß
Disziplin
Zusammenbruch
Bestimmungen
Stahl
Center
kroatischen
bunten
Geschäftsführung
Rechner
Furcht
verzeichnet
günstig
tiefe
bewältigen
Öffnungszeiten
heiße
Autors
Bündnis 90/Die Grünen
Sehnsucht
Gefangenen
Fülle
älter
Mecklenburg-Vorpommern
weltweite
Skepsis
erweist
ganzes
ausgewählt
Magdeburg
gleichwohl
Grundgesetz
organisierte
Siegfried
Gewissen
kündigt
geschossen
bekräftigte
Mannesmann
spürbar
Spielraum
integriert
verkündete
traditionell
Syrien
fließt
Eva
installiert
Zum einen
Anwendungen
Lob
stabil
eigenem
Kinos
Gleich
starben
literarischen
aussieht
Straftaten
heran
Vorstandschef
moderner
Kürze
km
verstärken
Dresdner
Amtsgericht
Ebenfalls
ernannt
vertrieben
Planeten
illegal
digitalen
hörte
momentan
medizinischen
kalt
Vorjahres
weiblichen
brauchte
Commerzbank
Können
erheben
sozialer
Entschädigung
warnen
Juristen
besonderer
Schwäche
zweieinhalb
vermieden
Konzepte
rot-grüne
beantworten
Bombe
Spannungen
Faktoren
dahinter
via
demonstriert
Halbzeit
Ausstieg
Ausweitung
Gemälde
Opel
Empfang
aktive
entziehen
Überfall
Rendite
rückt
erhofft
Tunnel
berühmte
gelegenen
erarbeitet
messen
individuelle
schaffte
funktionieren
Behauptung
Athen
drückt
Petra
Geiseln
hast
Sachschaden
gesetzlich
Ufer
Anpassung
Gesetzes
Ohr
Überleben
ZEIT
Nahrung
Indonesien
Ergebnissen
Vergabe
vorzeitig
weitem
konkret
verwiesen
Nachfolge
kriegen
Feststellung
bestanden
versprechen
Mission
unbekannte
Situationen
Tabellen
Lärm
Erzählungen
Diplomaten
Spanier
Präsentation
leitete
Senioren
Leipziger
beeinflussen
bereiten
Gabriele
erleichtern
Amerikas
erstaunlich
Kontrollen
Beleg
Läden
erfuhr
männlichen
markiert
Business
gewidmet
R.
zum einen
Kreuz
tiefen
umfangreiche
annehmen
Hollywood
erzählte
Klarheit
enden
Erster
holt
Senats
Sitze
Wurzeln
verlaufen
Matthias
Rechten
regiert
Partnern
Vogts
Claudia
niedrig
Formel
bestraft
Grün
beauftragt
eröffnete
Renate
Signale
Olympia
gründlich
Fertigung
Athleten
Ausführung
Jungs
Knie
Gesellschafter
überaus
hebt
Errichtung
sicheren
Arafat
Institution
korrekt
Drama
kenne
Studio
verringern
aufzubauen
Konzerne
Zeitalter
Tests
Substanzen
Jedenfalls
Betten
Beute
Grundsatz
bitten
Aspekte
Umweltminister
Haß
ständigen
Königin
Erwachsenen
BGB
manches
is
erlitt
begreifen
verliehen
erhöhten
Bauch
Schrift
leiten
jährlichen
eingeschränkt
allemal
Wiederaufbau
Gisela
zunehmende
Hut
indischen
Entstehung
studieren
nachgewiesen
Angabe
orientieren
Ära
Zentralbank
Rheinland-Pfalz
Blätter
negativen
eingehen
geschlossenen
bedienen
bevorstehenden
Runden
Hoechst
benannt
weichen
Bakterien
Daniel
glaubte
Vorsitz
Konstruktion
bat
Klaus Kinkel
Balkan
beschädigt
Weltmeisterschaft
dicken
Befragten
a.
Brust
schlossen
Gewinner
römischen
Christoph
meines
erlebte
anfangen
Chirac
niemanden
wehren
bisweilen
stürzte
Leichen
Seinen
Empfehlung
erlassen
Di
gleicher
regionale
BGH
gefährden
trinken
Vorsicht
dramatischen
Englisch
lobte
Warnung
günstigen
Inc.
nachweisen
unterbrochen
Verbreitung
östlichen
Anwälte
Vorstandsvorsitzende
eingebracht
Norbert
geht's
Südwesten
Finnland
profitiert
Südkorea
markieren
Kürzung
Gleichwohl
üben
Umfragen
Ausländern
Berge
fehlende
Schrecken
Jagd
angesagt
rechtlich
sorgten
verweisen
erfordert
hessische
VfB
erweitern
Abschiebung
begegnet
Demokraten
übers
bevorzugt
dauerte
beruht
Blumen
gezählt
Ulm
Träume
einbezogen
fünfzehn
gekürzt
Photos
fester
kehrte
wechselt
Resultat
Beschwerden
zweifellos
Denkmal
zurückgezogen
Design
Erholung
gelebt
Frankfurt am Main
gedroht
Lateinamerika
Mo
Prinz
Marktplatz
Dirk
Café
Acht
unbekannten
Mandat
Haftbefehl
spätere
diente
Parkplatz
Künstlern
Materials
G.
zwangsläufig
Vögel
zählte
Busse
Video
digitale
Albert
Rezession
Pferde
Schriften
bekämpfen
Wirtschaftspolitik
Bestellung
Hunde
Quadratmetern
Orte
schlimm
Gedanke
Beste
nichts zu tun
Legislaturperiode
Interviews
fünfte
untereinander
trugen
Selbstmord
früherer
Schuhe
ausgeglichen
Unsicherheit
privat
Medium
Unbekannte
etc.
abgelegt
schwedischen
sichere
bosnische
Initiativen
Friedhof
Wände
stärkere
e.V.
Bayerische
Konten
wem
Empfänger
Renten
typisch
Arbeitsgemeinschaft
heuer
Strecken
US-Präsident
Tal
Linke
beeinflußt
Votum
natürliche
vorhandene
angemessen
komplette
Weimar
Demonstrationen
Milch
Anmeldung
vergleichen
Monats
sportlichen
chemische
Moslems
reich
Rhythmus
Werten
Japans
Glaubwürdigkeit
mangelnde
übersetzt
landen
F.
Ehepaar
wiederholen
Netanjahu
Genuß
Mängel
garantieren
Coach
Reihenfolge
Siedlung
kletterte
illegalen
schickt
Instrumente
Globalisierung
sorgfältig
Springen
Kieler
Welle
fehlten
traten
Schock
negative
nötige
Möglicherweise
RWE
Ford
Glanz
Schlacht
wirbt
kostete
Anordnung
vereinbarten
erwies
signalisiert
Bochum
Charme
begrüßte
Freilassung
Ankunft
Ingrid
Gibt
ökologisch
Bundestagswahl
Verhandlung
Klavier
Faktor
endgültigen
Bundesfinanzminister
schickte
Söhne
Liberalisierung
Verleger
Vereinbarungen
Terroristen
Toren
Pakistan
Aufregung
unterhalb
Übersetzung
Texten
strategische
Pflegeversicherung
Investor
Konditionen
vorgesehene
kannte
unbekannt
Krebs
Infotyp
Jahresbeginn
offener
Rühe
Triumph
rät
Zahlungen
Engländer
chemischen
mühsam
ausbauen
auszuschließen
konservative
E.
stattgefunden
notfalls
bedingt
umgehend
Wüste
Zuschuß
wenigsten
Kommune
Gewerbe
Experiment
Darüber
angepaßt
transportiert
indessen
D-Mark
Dortmunder
veränderten
Daraus
gänzlich
Österreicher
Dasa
bester
Zahlreiche
Interpretation
Bundestages
Daraufhin
Jahrestag
Christa
Bergen
geladen
Grundlagen
Dingen
belasten
Steine
Feldern
Landstraße
Ermittler
HSV
künstlerischen
Ausbruch
Beschlüsse
außerordentlich
anzubieten
liebe
ausgestellt
streichen
Stadthalle
Pferd
Vietnam
längeren
ausgeben
erzielten
Währungen
Darlehen
bekanntgegeben
Kälte
Tennis
EM
siebziger Jahre
Lektüre
Zelle
Chinesen
prüft
Projekts
Ermordung
Lesung
Einzelfall
Erkenntnissen
fern
heiß
vornehmlich
Logik
Gattung
Schwung
Staatschef
Stasi
Hildegard
Bestehen
derzeitige
indirekt
fällig
Aids
Anleihen
Warschau
womit
Fernseher
Weltbank
Hauptbahnhof
räumen
gedreht
stellvertretender
vor Steuern
Gedicht
Male
siebziger Jahren
beschränken
gewähren
angeordnet
Rekord
Vergnügen
Erklärungen
erfunden
beseitigt
zulässig
Koalitionspartner
Gutachter
rechtlichen
erwarte
nördlichen
Auschwitz
Europäische
beantwortet
genießt
achtziger Jahren
erfolgte
Füße
wechselte
Gerichtshof
Wichtig
anstatt
älteste
Baustelle
arbeitslos
Nord
Geduld
beweist
verbundenen
eingetragen
Dörfer
Steuerzahler
Nachbarschaft
unterschiedlicher
Muslime
Tips
Elf
Krankenhäuser
Aufnahmen
Vermarktung
Kontinent
beseitigen
billig
präsent
jetzige
musikalischen
Jahresüberschuß
ihrerseits
Ach
verwirklichen
Mainzer
Schichten
Ärzten
erwartete
Sex
Lyrik
gespeichert
Torwart
vornherein
Platte
Ressourcen
Restaurants
saßen
enorm
orientiert
Verfahrens
Knapp
Ersten
prompt
Vereinen
Markus
Differenzen
Präsidium
taucht
Bad Homburg
blockiert
hohes
Leiterin
Justizminister
Umstände
festhalten
fortan
strikt
Einwohnern
musikalische
Entsprechend
Feier
Väter
Israelis
Filialen
http
verzeichnen
asiatischen
erweisen
französischer
Ursprünglich
Deswegen
mochte
knappen
kräftigen
Bein
Klar
ökonomischen
individuellen
verkaufte
derer
Auszeichnung
Teilnehmern
Songs
beachten
gleichsam
Parlamentarier
schweigen
Schwächen
bürgerlichen
lachen
Bundesland
Stärkung
Anwender
Boeing
usw
schießen
Gebäudes
Töchter
Wäre
Chefredakteur
Absturz
mehrheitlich
Boot
Alpen
landete
Fahrbahn
verschärft
locken
Dessen
SPD-Fraktion
gewordenen
kümmert
ggf
öffentlichen Dienst
Fünftel
religiöse
Mehrzahl
Feind
beklagen
Unruhe
fühle
Dichtung
Fahrzeugen
verrät
z. B.
Nutzer
verbringen
beides
Wahrscheinlich
Priester
nutzte
armen
überlebt
Talent
österreichische
herkömmlichen
Festnahme
ältesten
einrichten
Angelika
berechtigt
Student
kauft
Kuba
angesetzt
rechtliche
Stichwort
Dynamik
Budapest
Lücke
versorgen
Übersicht
Chefs
gewaltigen
Mond
Tragödie
Kräften
Landtagswahl
Neu
Legende
niederländische
Zivilisten
Mi
Spätestens
Bosnien-Herzegowina
Volkshochschule
vergleichbar
Ruanda
Fahrrad
bescheiden
selbständig
Ankara
weibliche
Nachteil
Wenig
Staatsregierung
aktuell
identifiziert
Zulassung
Paß
Revision
mittlere
Pro
Linien
gutem
infolge
Kämpfer
Grundschule
Verzweiflung
Autonomie
Bewährung
unternommen
Erträge
umfangreichen
jüngster
bestimmter
wichtiges
Hoffmann
Eintrag
Patient
fördert
Eigentum
Grundstücke
besuchte
eingehalten
Stationen
Jubiläum
Bad
Freien
Erwartung
künstlerische
gestärkt
weitergehen
zusammengefaßt
rücken
Vorbereitungen
Biographie
annähernd
Physiker
Reporter
Strich
privater
sechsten
stärkste
strebt
Boris Becker
suchten
lernt
Bestimmung
abgesetzt
wisse
van
Rechts
ÖTV
Hunger
manuell
notiert
stört
Group
angefangen
Marktführer
Heim
Rätsel
beurteilen
Jäger
gedrängt
gedruckt
schriftlich
Installation
unternehmen
schuld
lacht
Einhaltung
Stille
Schwarzen
Lothar
gesteckt
Zuhörer
Museums
STUTTGART
Urlauber
Orientierung
nächster
bestreiten
oftmals
Bagdad
ewig
Untersuchungshaft
Roland
Prinzipien
steuert
heutzutage
unwahrscheinlich
Piloten
maßgeblich
Hubschrauber
herstellen
globale
einigermaßen
Bulgarien
geredet
Keiner
absoluten
sinkt
Eingriff
überwunden
Werkstatt
Chicago
Rentenversicherung
springen
Zusage
angesiedelt
stören
Verurteilung
interessante
verlief
Erscheinung
Birgit
Main
argumentiert
New
ergänzen
abgestimmt
Überwachung
Kapazität
Kapazitäten
Mehrwertsteuer
Größenordnung
Ertrag
bewahrt
erkannte
baden-württembergischen
anstehenden
sportliche
gefährlichen
Hilfen
Maßstab
Geste
ausgewählten
auswählen
Verwaltungsgericht
Freilich
realisieren
bestritten
gebürtige
Knoten
blicken
Zone
wen
anderthalb
Aufenthalt
Rad
Wille
richtete
versagt
Zuletzt
Exemplare
Schulter
Expansion
angetreten
gewünscht
Edmund Stoiber
begriffen
Trost
Verfasser
Zum anderen
Abitur
Wenige
lieferte
liefen
Kohle
unterschrieben
Zuschlag
Bürgerinitiative
Geschäften
Mißtrauen
Schmerzen
entlastet
Reinhard
Bayern München
Europäische Union
Tatsachen
tatsächlichen
Freiburger
wirkliche
strengen
Ironie
Asyl
ständige
unlängst
Kapitalerhöhung
träumen
praktische
moralische
deutsches
zunehmenden
bedeutendsten
Kommunalwahl
Empörung
jüngere
fehlenden
herzustellen
verteidigte
Russland
Mittelalter
Buchstaben
Zorn
Nordamerika
baute
Begriffe
angekommen
Knochen
fremde
Mieten
Konsolidierung
leistet
Produzenten
zeichnen
abgeschafft
bewirkt
Berücksichtigung
Wiesbadener
Früchte
fremd
Umwandlung
wagen
nachhaltig
K
Häftlinge
zerstören
Listen
afrikanischen
Abbruch
Richtlinien
en
niedersächsischen
Demnach
Sparte
Thailand
vorläufigen
Siehe
notierte
schwache
Aufforderung
ausschließen
Broschüre
Stuhl
lauten
Wahrscheinlichkeit
Wärme
verwirklicht
Devise
Konservativen
Kameras
ausführlich
wirklichen
Vorfall
Mafia
Ängste
Polizist
starker
Decke
auslösen
Mannheimer
freigegeben
Passanten
Bald
aufkommen
Ändern
Sollten
Bruno
beschließen
unterrichtet
Budget
Katholiken
gefährliche
sowjetische
begleiten
attraktiv
Krone
Sterne
Jahrzehnt
Wiese
jegliche
Block
Grab
entnehmen
Viertelfinale
kritisieren
dicke
Freigabe
Autorität
Streiks
soeben
dieselbe
Dilemma
Wohlstand
beruflichen
Selbstbewußtsein
Aussteller
Standorte
fängt
Fisch
Hitze
Epoche
Rückstand
entdeckten
lägen
angeklagt
benötigten
rechtfertigen
Gestalten
Plötzlich
verknüpft
Bundesamt
Erlös
Rudolf Scharping
Finanzministerium
Ost und West
real
Trio
Seoul
verläuft
klagte
Schauspielerin
Anhörung
Rasen
Prozentpunkte
Ferne
Vorrang
verfügbar
Mandanten
Cursor
Jelzins
verurteilte
Projekten
begrüßen
insofern
bedeutende
gewählten
com
Annäherung
Mindestens
La
Erfindung
Bauten
Verbesserungen
Drohung
gegründeten
verabschieden
beklagte
geistigen
längerem
protestiert
Zigaretten
Mitgliedschaft
C.
D.
bedenken
spiegelt
Verwandten
fliegt
merkt
Schulz
Gerichts
gemeinsames
vernichtet
Unruhen
Friedensprozeß
Leinwand
tödlich
ausgebildet
dunkle
bestreitet
nebenbei
Verschiebung
Ausweg
irakischen
Rot
einstige
Unterschriften
Panik
untersagt
literarische
Inhaber
Rache
Differenz
Duisburg
Priorität
Susanne
Willi
Legen
versammelt
Ebenen
Köpfen
Original
online
Ingenieure
schuf
Kirch
Gaststätte
inmitten
Beurteilung
sicherte
fehle
Kliniken
Sarajevo
Schreibtisch
gesund
stürzen
Jens
typischen
lokale
Neuwahlen
Möller
Turm
tanzen
Party
warfen
Appell
erreichbar
Albanien
VfB Stuttgart
Erwin
Meyer
Spielzeit
beliebt
Konzerte
Süd
angekündigten
X
besonderes
vorliegt
ausgerichtet
Technologien
zusammenarbeiten
bewerten
Grosny
Soldat
Hochzeit
verstärkte
umsonst
belgischen
Akteure
Intendant
Akzeptanz
überlegt
spürt
Silber
Metropole
nachträglich
Terror
Bundesverband
setze
Standards
nächstes
Krankenversicherung
gegebenenfalls
Entsorgung
antwortete
frühzeitig
Versöhnung
befanden
Fremde
Arbeitgebern
lehnen
ausgetragen
Erfurt
Lachen
Strand
mißbraucht
Gründer
Ruhm
extra
Parkett
abgebrochen
zuweilen
Wolken
Spezialisten
wählt
Datei
Areal
Stammdaten
Hang
gespart
russischer
Unter anderem
größerer
Heroin
Bestätigung
Ahnung
Beobachtung
Die Zeit
Mittelfeld
Trauer
sonstigen
Florida
töten
Toleranz
strategischen
beurteilt
Defizite
Gedächtnis
Behinderte
Antonio
Teheran
Daimler
grauen
vollzogen
Tschernobyl
auf keinen Fall
sechziger Jahren
Vorstandsvorsitzender
angehoben
Wahrnehmung
Schwestern
Weiterbildung
Kategorie
gestört
berührt
Ortsbeirat
umsetzen
Menü
gespannt
Unmut
Wohnen
o
AFP
überfallen
verabschiedete
keine Rede
radikalen
übliche
gestürzt
Zeitschriften
Olympiasieger
Erneuerung
Venedig
Axel
mittelfristig
Verordnung
moralischen
Bar
Kloster
vermißt
Einem
Staub
betreten
S-Bahn
Istanbul
illegale
angekündigte
gewährleisten
Schmerz
Zeitgenossen
Elend
Erdbeben
gewöhnt
obersten
schlugen
bestens
basiert
Summen
jeweilige
abgelöst
potentiellen
erhebt
Potsdamer
erneuten
decken
verlautete
Theaters
Wissenschaftlern
Na
Künstlerin
engagieren
scharfe
kalten
entzogen
bedeckt
Benzin
Störungen
Seither
Joschka Fischer
Diktatur
Kanal
Hansestadt
günstige
getestet
Attentat
Beck
Lübeck
Sir
Pech
verbieten
Eier
zeitlich
Libanon
angeblichen
verwaltet
vorsieht
Holocaust
Untergang
spannend
umgewandelt
zuwenig
mächtigen
P.
verwandeln
zukommen
Rentenmarkt
Komponist
Aktivität
Schwerpunkte
einbringen
Zwang
unterstellt
dauerhaft
Einträge
sichtlich
Schmuck
Romane
Atem
Uraufführung
Beträge
dasselbe
behauptete
angehört
BUND
klingen
Gene
verheiratet
Zaire
Ansätze
irgend
Archiv
BASF
Resonanz
enorme
Landwirte
Handwerker
Algerien
Reiz
Plattform
Telefonnummer
Einschränkung
Zagreb
Beweise
Erstellung
historisch
BRD
Burg
Anfragen
Kriegsende
Stockholm
Anweisung
Kreises
verpflichten
Hölle
Betrachter
Vermieter
Beitritt
Rechtsprechung
altes
Anlauf
Reichtum
Persönlichkeiten
reagierten
Blüm
fit
beherrschen
Markieren
ginge
verleihen
analysiert
Den Haag
heiligen
Eingabe
enormen
Einfluss
Konfrontation
Kairo
Kämpfen
tschechischen
beschäftigte
typische
Zuerst
Dritten Welt
Bedürfnisse
empört
Befehl
Operationen
Gemüse
Aachen
langjährige
verweigern
veränderte
zahlreicher
beendete
Massaker
Mordes
korrigiert
eingestuft
Borussia Dortmund
ausgefallen
Typen
anstelle
CDU/CSU
Illusion
Grunde
Landesbank
James
Organisatoren
Klärung
daheim
umzusetzen
Endlich
Fach
Landsleute
realen
Poesie
Bahnen
eingereicht
wirtschaftlicher
Berger
stellvertretenden
Gremien
Konzeption
Wirtschaftswachstum
Zustände
AOL
Euphorie
Libero
umgeben
langfristige
staatlicher
sexuellen
Gebäuden
bunte
Duell
Fahrgäste
Südamerika
Spektrum
verschwindet
half
Charles
olympischen
rot
Staatsbürgerschaft
Einkauf
verlegen
Traditionen
neunziger Jahre
Neuregelung
verhängt
gedrückt
Zusammensetzung
wahrgenommen
Fuchs
ordentlich
Marken
evangelische
KG
gedeckt
hierbei
überfordert
antwortet
Einordnung
Satelliten
Sektor
Paket
Charlotte
günstiger
befragt
verwickelt
freitags
allerlei
Verpflichtungen
Ministerien
geltende
iranischen
Flexibilität
problemlos
vollem
Massen
sicherer
beeindruckt
widmen
liegenden
jährliche
erwischt
entsprechender
diversen
Straßburg
drohenden
doppelte
genauen
Polizeisprecher
Sommerpause
Räuber
zwingt
Experimente
Major
allesamt
mutmaßlichen
Hamburgs
montags
Ernährung
Auftreten
Streifen
Rechnungen
Bundesstaat
Marianne
Würzburg
Fassade
Kenntnisse
gekämpft
schlimmsten
einverstanden
möge
Adressen
Beendigung
einheitliche
Baby
abgesagt
Umsatzes
Daimler-Benz
beliebig
Ferien
Griechen
Flaschen
Panzer
traurig
verdrängt
verstoßen
Ämter
Klinsmann
Labor
Noten
legendären
Nachweis
gewöhnlich
trainiert
Basel
b
betreffenden
Materie
Herausgeber
behindert
Anschläge
niedrige
Polizeiangaben
Abstieg
Rexrodt
Kindergärten
engagierte
Kreuzberg
Kreuzung
beschlossene
stützen
Wellen
dritter
Anhebung
Ermittlung
Volker
Gebühr
gewissermaßen
Treuhand
zukünftigen
Nahen Osten
Bundesrepublik Deutschland
Tagesspiegel
Großstadt
Aufsehen
Evangelischen
Experte
parlamentarischen
liberalen
kassiert
Abwesenheit
vehement
Bundesanstalt für Arbeit
Laufbahn
Reichstag
Unfälle
Darum
versuche
gleicht
Ritter
Physik
vollständige
einmalige
gerechtfertigt
präzise
biete
vorgelegten
Welten
SED
Leib
Niederlagen
Thyssen
Darunter
Schwarze
beantragen
Tatort
Objekten
juristischen
Westeuropa
gelben
Visionen
berühmt
Resolution
jemanden
eingetreten
spektakulären
Katharina
Aufstand
teilten
erwirtschaftet
mächtig
Beschwerde
jugoslawischen
festzustellen
auf den ersten Blick
Kette
zurückhaltend
Clintons
Minderheiten
Unterkunft
Gymnasium
Einstiegsbild
Profi
Bibel
Buchungskreis
beschuldigt
griechische
Muß
Meinungen
Sobald
erfolglos
anscheinend
Roth
Lippen
Möbel
Frühstück
Basler
Dritter
Bauarbeiten
verbirgt
Diepgen
bildeten
Schicht
Freie
besetzen
Leere
Klassiker
Weile
vergangener
realistisch
überzeugend
schlafen
Paradies
protestieren
Waffenstillstand
Unterschrift
Angelegenheiten
startete
Elke
ostdeutsche
dänischen
Schlange
Virus
sächsischen
Zurück
Huber
spiele
Geschenk
ausgemacht
Lizenz
aufgefallen
dramatische
Mario
Bündnisgrünen
Betracht
George
II.
mangels
Gitarre
U-Bahn
Beobachtungen
arbeiteten
bitter
anhaltenden
Brücken
Gesang
Rassismus
Löwen
oberste
Palästinensern
errechnet
Elbe
Taktik
Begegnungen
hervorragend
Verhältnissen
Fische
seitens
bewährt
Umstand
wiesen
Geräten
Funktionäre
Erhaltung
äußeren
Heiligen
bewaffneten
siegte
pflegt
geforderte
unterstrich
PS
Logistik
unzureichend
Nie
Vertreibung
belegte
Insofern
sonntags
Leid
Format
entstandenen
Bogen
E
regeln
durchzuführen
Handy
gewaltige
Kabel
dazwischen
Renaissance
Beseitigung
identisch
Gottesdienst
Anwesenheit
nah
Onkel
Berechtigung
abwarten
gewöhnlichen
Vernichtung
interessierte
Mozart
Gegenstände
Proben
Sparkassen
abgenommen
Rot-Grün
entlasten
Realisierung
IOC
verschieben
breiter
kanadischen
Schwaben
Niederländer
echt
treu
systematisch
Techniken
Stephan
führender
Jahrtausendwende
Lupe
Fluggesellschaft
Braun
Wettbewerbs
Befürchtungen
Fußgänger
Abwicklung
testen
anzunehmen
Pkw
Saarland
spontan
Nationalsozialismus
Kaiserslautern
Raketen
bösen
zulegen
geeignete
Verletzte
bedauert
Liebhaber
Henkel
Platten
Adolf
laden
worauf
Billionen
Beinen
genügen
Untergrund
Ansichten
einzustellen
Jeden
Verbrauch
wissenschaftlich
veranlaßt
wodurch
Überhaupt
Geschäftsleute
Inneren
Zumal
Nebel
Favoriten
Jahrhunderte
Vermutlich
lustig
ignoriert
Seminar
buchen
Befürworter
Landratsamt
Begleitung
bringe
wovon
begründen
Zusammenhänge
ebensowenig
offenkundig
Neigung
Jurist
bedeutenden
zurückziehen
Dimensionen
verlängern
Reiter
erspart
Entscheidend
vorbereiten
Tänzer
Parlamentswahlen
friedlich
Boom
fertiggestellt
lebendig
Harmonie
überholt
plädierte
Spalte
Siedler
Kohls
scharfen
World
Temperatur
Paare
technischer
drehte
fuhren
sauber
gesteuert
anbietet
Maske
ausmachen
ähnliches
Container
Transparenz
Werkzeuge
sechziger Jahre
schwächer
begeben
Schultern
Ding
diverse
Luftwaffe
Offiziere
Westens
Sendungen
vorgeführt
schwedische
ordnen
Belege
angebliche
bereitgestellt
zivilen
schoß
Erben
geistige
Ministeriums
Matthäus
Klein
Bekenntnis
minder
vorkommen
Insassen
in Wirklichkeit
Schild
Lehrerin
Berichterstattung
verübt
Angeboten
Verfassungsschutz
Foyer
Erfassung
verwendeten
Kundschaft
Focus
Formulierung
zulassen
Zählern
Ferrari
gültig
einzurichten
Kundgebung
frühestens
Werkes
Aufstellung
Horizont
beziffert
Innensenator
Rubel
gekündigt
bedeutete
appellierte
Semester
Kripo
verpaßt
Bescheid
erfreut
Produktivität
Kapitalismus
Abfall
Flughäfen
Königs
Multimedia
Korrektur
bekräftigt
spekuliert
Kredit
Buche
Auslieferung
Breite
aufbringen
springt
möglicher
empfunden
zu Fuß
staatlich
Flasche
langjährigen
Boris
Uns
Performance
amtlichen
Hessischen
Intelligenz
Torhüter
praktischen
Die Welt
Protagonisten
on
Olympischen Spielen
mitmachen
zukünftig
wilden
Chile
Schüsse
Kompetenzen
Irgendwann
Netzwerk
eingelegt
wenngleich
Passagen
potentielle
In der Tat
ehrlich
kontinuierlich
80er Jahre
v.
Erlebnis
unerwartet
zitierte
Schottland
verstorbenen
Gutes
Bäumen
Jahrtausend
Aufwendungen
Erstens
Vormittag
bundesdeutschen
Steuerung
faßt
Beispielsweise
Schuster
Mauern
Kreml
Slowakei
Vermutung
Wohnzimmer
westlich
radikale
Windows
solide
Investition
Comeback
Dritte
kroatische
G
Karadzic
Edith
ausgebrochen
Amerikanern
wertete
Endspiel
Bezahlung
Abgeordnetenhaus
vermeintlich
Vulkan
freute
Gehälter
deuten
so genannten
stetig
M
Joseph
neueste
Hallen
Hierzu
Kriege
Koffer
Herrscher
Laune
individuell
Brunnen
Wettbewerbsfähigkeit
langfristigen
gültigen
verschafft
wehrt
willkommen
Grundsätzlich
ansehen
geglaubt
berufliche
Audi
erschöpft
zusammengestellt
Fachhochschule
ungewöhnliche
billigen
übertroffen
Stolpe
ABAP
stehende
Hätte
BONN
Besatzung
geführten
betonen
nahen
Visier
aufrufen
Applaus
Esslinger
ertragen
Bielefeld
Blues
vorbehalten
Amtes
juristische
Nationalen
seltener
Gewiß
viermal
Körperverletzung
Entführung
beschert
gesteht
erneute
heimlich
Verabschiedung
geforderten
nannten
klarer
Stirn
Lieferungen
Wälder
Ruth
männliche
lockt
junge Mann
Schlaf
Bargeld
Motivation
Ideologie
peinlich
Urteile
Ausrichtung
anzusehen
merken
Göttingen
Standpunkt
nervös
Härte
Verstoß
entfällt
verlangten
tägliche
geflogen
Einsamkeit
Zeitplan
derartigen
schieben
äußert
Einschränkungen
Siege
Rau
Schauspiel
Festlegung
hintereinander
Vertretung
Kommunalwahlen
Simon
Seehofer
bildete
kriegt
Weichen
Werks
interpretiert
Augsburger
Verkäufer
betreffen
seiten
Margarete
aufgetreten
industriellen
Lebensjahr
ökonomische
Debatten
Wolfgang Schäuble
Ergänzung
Eisen
verdankt
Geldes
wild
Allen
Detlef
Betriebsergebnis
Publikums
beschrieb
sprang
Künftig
Staatskanzlei
vertreiben
schmalen
bloße
Abgabe
wunderbar
lernte
Umland
Lire
kaufte
Präsidentin
ideale
operativen
eingenommen
Argumentation
aufhalten
Pistole
zugelegt
Schein
Sympathie
kirchlichen
höherer
Bundesbürger
Stufen
werdenden
Flut
Rindfleisch
drohe
Künstlers
verkauften
fernen
Kanzleramt
Anblick
Ringen
Aktionären
Souveränität
verzweifelt
abgewickelt
Geschäftsjahres
Will
bedacht
tauchen
Erlöse
galten
Vorjahreszeitraum
heben
Residenz
Teilung
stammende
Doris
Einwohnerzahl
besaß
Moderator
Lutz
Auskünfte
Geheimdienst
Nordirland
Bewerbung
Elfriede
Westjordanland
Spieltag
stillen
Lehrern
Sparpaket
Auslöser
Auftraggeber
müssten
Veba
Programmen
Besteuerung
Neuordnung
Gouverneur
wertvolle
Zeug
Überall
Münchens
ausüben
in letzter Zeit
Bande
Fernsehsender
durchweg
ausführen
trainieren
öffentlich-rechtlichen
goldenen
Überstunden
Exporte
Einblick
Ausführungen
O
herausgegeben
Polens
Ausgangspunkt
Vorzüge
spezialisiert
stützt
Heike
Vergewaltigung
kalte
Echo
Witwe
Gleichgewicht
Ehrgeiz
Ehren
sozialdemokratischen
Kaufpreis
Feinde
Betrug
eingeschaltet
Skulpturen
Telecom
erobert
eingebaut
nationaler
angeregt
Arbeitskreis
Kanther
Naturschutz
Auftritte
Energien
Umweltministerium
eintreten
regelrecht
elektrischen
dankbar
Sichern
Sängerin
kompliziert
verständigt
verlagert
BA
bremsen
Unschuld
aktiviert
Palette
Kultusminister
Braunschweig
ursprüngliche
dieselben
Finanzamt
Kreativität
Nachteile
Hitlers
Gerda
Nigeria
bewirken
bezüglich
Äußerung
Hürden
Bleibt
Ostern
beeinträchtigt
Regensburg
Richtig
Glaube
Harry
automatische
Einführungsleitfaden
verbreiten
durchschnittlichen
manch
Ursprung
Oliver
erschließen
Umstrukturierung
Analysen
formulierte
erarbeiten
entfernten
rechne
Bündnis für Arbeit
sogleich
Erzähler
flog
intern
zukünftige
Volkswagen
Emotionen
Empfehlungen
virtuellen
beschleunigt
ungewöhnlichen
intensive
blaue
Konsumenten
Prinzessin
Sydney
Intellektuellen
geringere
schade
Elektronik
gewisser
teilgenommen
auswirken
samstags
Maschinenbau
Filiale
Hierarchie
abgezogen
etabliert
Verwirklichung
Shell
herangezogen
tätigen
Kids
Radfahrer
optimal
Millionenhöhe
Kuchen
Übereinstimmung
sexuelle
Mars
Gefangene
verbergen
festgelegten
Kaufmann
strenge
friedliche
Metall
Terrorismus
Kranken
identifizieren
Zähne
niemandem
schwarzer
Inflationsrate
verlorenen
ausgelegt
Berti Vogts
Maastricht
Verlage
seinerseits
wandern
gebilligt
Verwirrung
liberale
Österreichs
leere
Bemühen
Landgerichts
Einbußen
Strafen
Spitzenreiter
östlich
Verdachts
Sätzen
Eingriffe
Wänden
unterm
übt
Kommunismus
Bürgerschaft
Umweltschützer
verliebt
erfolgreicher
Deutsche Telekom
widmet
lobt
IRA
Neun
Millimeter
vorgehen
Titelverteidiger
Porsche
Spruch
Stellenwert
langweilig
schiebt
widerspricht
tödlichen
Bomben
beinhaltet
kurzerhand
Zweiter
Leistungsfähigkeit
Hörer
gestand
Einwände
jedermann
christliche
Enkel
entfernen
nachgedacht
unterhält
Paragraph
Außenministerium
unsicher
Thesen
American
San Francisco
Aufbruch
verbesserten
Buchung
Beachtung
ausgeht
Gesetzen
lebe
Strategien
Systemen
handle
Hauch
einzuführen
Fronten
Podium
einheitlichen
abgeschoben
Löcher
feinen
wagt
trage
bewegte
Mehmet
Erleichterung
Brandenburger
Jesus
Roman Herzog
Versicherten
National
zweitens
vorab
äußerten
la
Gerhardt
Ilse
amtierende
Protesten
Lernen
Klang
bemerkbar
Zeugnis
Tätigkeiten
William
ehemaligen Jugoslawien
Jena
Philosophen
ungewiß
rollen
gewertet
sonstige
verrückt
bezeichneten
gegenwärtige
Vorwürfen
souverän
geschlossene
blutigen
Güter
Lokal
ausreichen
abgerissen
Marsch
Frühling
aufhören
T
osteuropäischen
sozialistische
Verhaftung
Hahn
mutmaßliche
Optionen
Bremerhaven
erforderliche
gegeneinander
Erfinder
bewerben
ungarischen
Momente
kleinste
entführt
kräftige
V.
einnehmen
Anstalt
Körpers
frühe
Zimmermann
Mathematik
Texas
DAG
befördert
externen
Schwere
Malaysia
einseitig
vereint
Company
geeigneten
unterstützte
geübt
begraben
Volkspartei
geteilt
Prüfungen
Konsum
Arena
nachdenken
theoretisch
kg
Insekten
grundlegende
Entwürfe
empfinden
Haufen
zunehmen
Betrachtung
umfassen
Offenheit
Albaner
Szenario
kopieren
glatt
wöchentlich
verkraften
Techniker
hervorragende
saniert
Todes
dominiert
sichert
Netze
Kalkulation
Heft
Aufsteiger
veröffentlichen
Tonne
Tel
kehren
verfaßt
Champions League
Föderation
Fertigstellung
Formular
Herausforderungen
Landschaften
angegebenen
verbreitete
entworfen
Referendum
attraktiver
örtliche
warm
Niedergang
meldeten
Eintracht
verärgert
komplizierten
kommunale
Bestellungen
Spektakel
einführen
Donau
Krankenhäusern
Luxus
geringeren
Diagnose
Streß
Wiederholung
Wahlgang
Überraschungen
veranschlagt
Weiterhin
Geschäftsmann
Verfall
morgigen
toten
großzügig
Europameisterschaft
bestellen
kurdischen
Kollegin
wozu
besseres
Prozesses
Plakate
Heidelberger
Selbständigkeit
korrigieren
Tendenzen
hinauf
zerstörten
Clubs
Stamm
fein
entgehen
abgelaufenen
heftiger
SPD-Politiker
nebenan
gesunden
ausgetauscht
Bosniens
schützt
Standorten
gewaltig
Angela
Sparkasse
Duo
Bedürfnis
Friedens
Stücken
Löschen
herrschen
beschleunigen
Beamter
Nordkorea
regelmäßigen
Wörter
fliehen
transportieren
Nachdruck
Erna
Jacques Chirac
einzeln
Ausschluß
Porträt
doppelten
jedesmal
BVG
erledigen
trocken
Rückgabe
kennengelernt
Flüge
Etappe
wählte
Tochtergesellschaft
Vorurteile
reist
Eher
Mittelstand
Beton
Abfahrt
Anhängern
eindeutige
Gießen
anmelden
Tee
Spiels
Bundesinnenminister
Umlaufrendite
hinterlegt
palästinensische
ländlichen
entkommen
Sicherheitskräfte
Bürokratie
diplomatischen
Botschaften
siebten
stünde
Ausgerechnet
Wiederwahl
verstehe
Sonstige
las
Mönchengladbach
Bundesgebiet
gewartet
Regierungskoalition
Lübecker
verfehlt
Tschechen
Versuchen
Freiheitsstrafe
Hose
Schwerin
Chemnitz
ausgenommen
hiesigen
Segen
Ästhetik
Verständigung
elektrische
geschenkt
schrittweise
Somalia
Übergabe
Somit
entspreche
schier
Maus
Erkrankung
abbauen
Redner
internationales
parlamentarische
Sammler
Kommando
erregt
Bischöfe
Saarbrücken
feierten
ausgerüstet
Mr.
Unsinn
fünfziger Jahren
knappe
kritisierten
Album
Media
Durchgang
radikal
aufgestockt
Kneipe
Kopenhagen
Zweite
Dichters
anzulegen
bezweifelt
Offenbacher
Systematische
Gesundheitswesen
Funk
härter
verbrannt
Bad Vilbel
Vertrages
Corporation
Geldstrafe
überwachen
Wiederaufnahme
gelegene
künstlich
gefangen
gewordene
Bekannten
Scheidung
isoliert
rasche
bestritt
Schülerinnen
Psychologie
gewollt
veranstalten
eingegeben
qm
Zweitens
Arbeitslosenquote
Salzburg
gerissen
erobern
Verlusten
Favorit
Betroffene
empfahl
Produktionen
Sagen
Flughafens
sechzig
trieb
t
Wirtschaftsministerium
Neuseeland
Kolumbien
Aufteilung
Schritten
schönste
größtenteils
Handlungen
Hammer
denselben
Doktor
ungeachtet
Erhebung
Heimatstadt
vorrangig
Meisterschaften
Martina
Profit
Belange
net
SAP-System
verursachen
Zivilisation
umgebracht
Guten
Sohnes
Entweder
Kranke
zwingend
wofür
benötigte
sammelt
rtr
Gift
Vermittler
langsamer
Buchungen
Unterbringung
Bindung
Durchmesser
eigenständige
Richtungen
renommierten
Verdienst
pünktlich
bekanntesten
Kennzahlen
Kader
verfallen
verbraucht
friedlichen
gelandet
Sindelfingen
BSE
Jahrhundertwende
Fußballer
Handels
Intervention
Klientel
aufgeteilt
belohnt
StZ
Gefährdung
hilflos
Adam
problematisch
freiwilligen
Spaniens
null
aktivieren
abzubauen
Sports
dokumentieren
Anbau
wecken
erschüttert
westlicher
kommerziellen
beachtet
arbeite
Kugel
Töpfer
Anregungen
WDR
ewigen
gerieten
Kardinal
Afghanistan
Terrain
beschlagnahmt
bemerkte
schwebt
Überschuß
verbotenen
künstlichen
Abteilungsleiter
Krisen
Olympiastadion
Nordosten
abschließen
ausgeweitet
Reifen
Rabin
Bestände
Einspruch
fühlten
Sparen
Gärten
Vernehmen
zurückliegenden
aufweisen
Wahnsinn
versammelten
Autobahnen
birgt
Schauplatz
Folter
Bauen
interessierten
Match
Bundesstraße
Siedlungen
befunden
etablieren
Ausscheiden
Services
Indianer
Ausrüstung
AOK
Jahrhunderten
zeitgenössischen
Weißen
Mitarbeiterin
auskommen
Sat 1
blockieren
Aktiengesellschaft
verletzte
Lebensmitteln
Tragen
Kasten
besichtigen
Vorliebe
entnommen
Georgios
Halbinsel
verschwand
Hauptsache
britischer
GUS
Verzögerung
Unterzeichnung
ergaben
inhaltlich
Streichung
Ökologie
Irmgard
ergriffen
erteilen
Zielgruppe
grundsätzliche
zeichnete
reißt
Holger
gestimmt
Blüten
Pathos
gewechselt
übte
darzustellen
Ludwigsburger
Nachkriegszeit
Island
Jahrgang
intensiver
überwacht
Pflichten
verschont
operiert
künstliche
drohende
Medikamenten
aufgebracht
Sterben
Arbeitnehmern
Reserven
Strahlung
Verlagerung
bekennt
Konzernumsatz
klappt
Wortes
Versagen
Ecken
Regierungspräsidium
Rezept
Attraktivität
gestattet
Fahnen
Turbulenzen
US-Regierung
Tel Aviv
reichten
Fremden
nutzten
Warten
Johnson
grün
zügig
ähnlicher
erstreckt
Johanna
baden-württembergische
absolviert
Misere
Ingenieur
Montage
kandidieren
Gruppierungen
scheitert
Gesten
Realismus
Trends
europaweit
Volker Rühe
dumm
Briefen
Inge
psychisch
vereinbarte
Attacken
energisch
Treppe
Abteilungen
Sperre
Entspannung
Wegfall
Sehen
Todesstrafe
Händlern
gerückt
Zwölf
Einigkeit
Dublin
niedrigeren
ausreichende
vergleichbaren
alternative
Achtung
wahrnehmen
riefen
Kirchengemeinde
unglaublich
Provinzen
Freispruch
ergreifen
gezielte
qualifiziert
erfolgreichsten
spart
trauen
Vorbehalte
Jubel
Mittag
Absprache
vermehrt
rückte
bestenfalls
Ihres
Darsteller
ablehnen
vorausgesetzt
sozialdemokratische
konzipiert
Alliierten
Laien
Geister
gewählte
Gorbatschow
Ulrike
Bemerkung
abseits
kontrollierten
Außenseiter
Bauarbeiter
Weltrangliste
Erkrankungen
mahnte
Bezüge
gesunde
Geht
Anstoß
Essener
Ausstrahlung
Server
Abgaben
wundert
just
gezeichnet
Probe
Bürgermeisterin
Potsdamer Platz
Drehbuch
echter
tatsächliche
Medaille
beginnenden
ehemaligen DDR
Sekte
sonderlich
kannst
CDU-Politiker
Musical
In- und Ausland
binden
Prosa
schlechtes
freigelassen
Aufsicht
zielt
vertrat
Lieber
heiraten
Vorschrift
körperliche
lehrt
Kontinuität
verstand
hilfreich
ahnen
Hannelore
Gewebe
Verteidigungsministerium
Garantie
Darmstädter
Offizier
verbietet
vermeintlichen
schönes
Import
agieren
Kleider
Eberhard
Kulisse
Geständnis
verzeichnete
Per
Ermittlungsverfahren
Siegen
freundliche
Gentechnik
Einsätze
verleiht
andern
integrieren
herunter
verbuchen
Verringerung
Bush
gewandt
zurückgetreten
gestiegenen
übermittelt
Aufführungen
Schöne
bedrohten
verletzten
offenbart
Regierungssprecher
Begleiter
Propaganda
erschwert
kommunistische
Rüttgers
Feiern
verbreiteten
definierten
Tarife
Jahreswechsel
komisch
fähig
entsprechendes
Bands
Jeans
komplizierte
Gewerkschafter
Helsinki
Zuversicht
ärgert
Maßstäbe
Stau
geborgen
beruhigt
zurückgenommen
Nasdaq
Ausschreitungen
Anmeldungen
Stadtparlament
Gebot
äußere
verhält
Rehhagel
d.
Song
Popularität
Kategorien
Viktor
Saddam Hussein
überzogen
Reste
winzigen
spreche
Parkplätze
Atomwaffen
Wimbledon
Messungen
Studierenden
Jedoch
Einklang
verborgen
Bände
vereinbaren
Problematik
Kuwait
überschreiten
Pop
Wettkampf
Marie
absurd
irgendwelche
Zentren
Meist
Disposition
Dutzende
persönlicher
angestrebt
Oslo
Wirt
Ausflug
Verdienste
englischer
Ernte
Private
warmen
Ude
OLG
beabsichtigt
Wollen
Weltmarkt
positives
gen
Fundamentalisten
regierenden
anschließenden
Längst
leid
gentechnisch
woher
gehörende
trennt
Sternen
geistig
Tricks
Eintracht Frankfurt
Lehmann
Obst
eingebunden
Konsortium
f
Diskriminierung
Fehlen
reale
Vorschlägen
freiwillige
Höchst
Mitarbeit
Alleingang
Viren
Südosten
operative
Drohungen
Gorleben
Olympischen Spiele
Großvater
Antike
erbracht
Rivalen
F
zugegeben
Besten
aufgewachsen
Hemd
Kommt
Spree
Bundesgerichtshof
geräumt
brasilianischen
relevanten
Kontext
Springer
brutal
reißen
fasziniert
Allgemeinen
deutschsprachigen
Mitgliedsstaaten
Sicherheitsrat
Besserung
Bezirke
alternativen
Nahverkehr
einziehen
Zielen
Notenbank
Unterdrückung
erholt
Friedberg
Oldenburg
Eduard
Jugendarbeit
behält
Rückführung
Textilien
Postbank
Genfer
Treiben
Bewohnern
Verkehrsminister
willen
Viag
Besondere
Hosen
landet
Ereignissen
entstandene
Michel
Novelle
Kläger
Kapitals
Nahrungsmittel
stabile
entfielen
Frust
stießen
Norbert Blüm
beiseite
weh
Hill
menschlicher
Effekte
sofortige
Langen
Chemikalien
historischer
geführte
reserviert
überstanden
Untersuchungsausschuß
Dritten
Qualitäten
tschetschenischen
Bundesverfassungsgerichts
Auslegung
Wettbewerber
gleichnamigen
Lkw
Ökonomie
Rose
wilde
verfügbaren
verdoppeln
Eigenschaft
Oberlandesgericht
Verstärkung
stürzt
Einbrecher
Weiterentwicklung
kostenlose
Normen
begrenzen
zurecht
attraktive
Know-how
dick
anschließen
Schilling
Marokko
Kreistag
verschlechtert
Verletzten
belgische
bestätigten
lehnten
vergangen
Zehntausende
angestrebte
Nummern
irischen
niedersächsische
FC Bayern München
sogenannter
zählten
eingespart
beschlossenen
prinzipiell
aufzugeben
angemessene
Prager
Bronze
beibehalten
Hartmann
Anlegern
sprich
Transaktionen
Beratungsstelle
Landsmann
anpassen
T.
IV
abermals
regieren
Gegnern
Funktionsbaustein
unmittelbaren
Stämme
Räder
Stillstand
nirgendwo
Kartoffeln
industrielle
Kriminalpolizei
Franzose
qualifizierte
Erlaubnis
Strauß
Schwangerschaft
fing
Eberhard Diepgen
Transrapid
Fabriken
ANC
Airbus
Tagebuch
islamische
Reparatur
Befragung
geheimen
rollt
Jutta
Ulmer
Fotografen
Seen
Sozialpolitik
Überschrift
eingesetzten
angelegten
EZB
eingreifen
traut
kleinsten
Zusagen
Milieu
mithin
Hügel
anhaltende
kürzen
Faszination
Zyklus
Wolfsburg
Flüsse
betreuen
Sitzungen
Durchsetzung
Abgang
bequem
schwärmt
appelliert
Anneliese
angetan
welch
Auftragseingang
beteuert
ankommt
demselben
ausgezahlt
harter
Intel
Politische
Grafik
Anzug
iranische
Metro
verkörpert
zehnten
vorgetragen
di
meinten
Treue
erörtert
widersprach
Hunderttausende
Vorstandssprecher
flexibel
Gras
Tenor
Versionen
Kontrahenten
Nordsee
Absichten
abzugeben
schaden
Wehrmacht
Utopie
Marion
australischen
steigerte
untersuchten
Henry
dementiert
unmittelbarer
Irrtum
gleichfalls
Paragraphen
Blicke
repräsentiert
gelbe
Irene
senden
geringfügig
Dunkelheit
Vorträge
Slowenien
Referent
stationiert
Entlassungen
einigten
bunt
hoffentlich
Verbänden
entsprach
verbrachte
präsentierten
Fahne
folglich
Erscheinen
oberhalb
ägyptischen
träumt
ausgewertet
Hohe
drückte
festgeschrieben
University
verbucht
Bewag
Nordwesten
kaputt
Einbeziehung
SV
verdiente
Pilot
Großmutter
erfreulich
reiste
bundesweiten
Soweit
Lohnarten
Kokain
Pressemitteilung
nachzudenken
angebotenen
Sozialversicherung
Vernehmung
Zuständigkeit
Tempel
erschienenen
Fernsehens
Lebed
Dietrich
Repertoire
Verbündeten
frischen
Geschäftsbereich
Theologie
Zucker
schwersten
verstärkten
lächelt
Götter
Abbildung
zweitgrößte
taten
Schafe
bar
vergrößert
Philippinen
Kursen
Zimmern
Angreifer
Bundespräsidenten
Organe
Peru
mussten
lächerlich
gesungen
aufgeklärt
Getränke
externe
Fund
DDR-Zeiten
bezog
feine
Ingeborg
Territorium
Reis
Gesamtjahr
Hubert
beschließt
Beate
Gesprächspartner
Supermarkt
Sparmaßnahmen
Statistiken
bliebe
höchster
Günter Rexrodt
Geschlecht
Dom
Betreuer
zueinander
vorzubereiten
Boykott
Fachleuten
Dietmar
Computern
Marktanteile
Hartmut
Volkswirtschaft
Ostsee
bekämpft
Nähere
gescheiterten
Schiene
selbstbewußt
Bundeswirtschaftsminister
Ausschreibung
Z
irakische
Anweisungen
Verlegung
Spalten
Rio
Bauwirtschaft
Getreide
Konrad
Selektion
Litauen
Intensität
Elite
Baden-Baden
Anruf
Stärken
vernünftige
nachdrücklich
Kopie
einmalig
wundern
vernachlässigt
Plädoyer
Messen
verließen
Los
Handvoll
Sitzen
manchem
Nehmen
verhelfen
Angriffen
Peres
Sparten
indische
zivile
Symbole
gehörenden
Kommentare
Provokation
Wünschen
außerordentlichen
Wählern
auftritt
Prenzlauer Berg
herausgefunden
Arbeitskräfte
dringt
Führerschein
registrieren
befragten
runter
Dirigent
vernünftig
Schmitt
Festivals
angenehm
Wiederherstellung
virtuelle
Mustafa
Grad Celsius
nützt
Zügen
schienen
Großhandel
jüdischer
Sony
Geplant
Sondersitzung
Nagel
Einwanderer
Entschuldigung
Evangelische
Erforschung
Gulden
Ambiente
eingetroffen
Schreiber
seltsam
Kleinstadt
gelitten
mitteilt
Philips
Weißrußland
Angela Merkel
Steuerhinterziehung
Finanzpolitik
Hafenstadt
derlei
dunkel
Typs
Halt
abzusehen
Story
bevorstehende
weitergegeben
Hierbei
Mittelfeldspieler
Schmid
Kurve
engagierten
Heer
analysieren
einheimischen
Abriß
Absicherung
Besonderes
Kritikern
jeglicher
Bundesbahn
abgewiesen
Einerseits
obendrein
Wohnraum
Widersprüche
Mostar
Initiatoren
Haaren
wartete
Merkel
militärisch
Übung
tagsüber
unterliegen
Romantik
vierzehn
nebeneinander
Eroberung
Winkel
gefährlicher
Oberstaatsanwalt
Bundesaußenminister
Wahlsieg
Global
Quartett
erneuert
Grundsätze
sog
Effizienz
Philosoph
Treff
glaubten
Amtsantritt
Dörfern
Bühnen
ne
herzlich
Nachdenken
ergänzte
Sponsor
Entschluß
Behinderten
meiste
Wunden
Personalabbau
geflohen
geehrt
Höhen
gelernte
Recherchen
Helene
sportlich
angehen
etablierten
unterlag
Rinder
Dreck
Ei
e
Allgemeine
Grundgesetzes
Ostberliner
Hindernis
Technische
Repräsentanten
umgebaut
Scheibe
nominiert
Statistische
Kenia
drastische
angeführt
Überdies
Fiskus
Plastik
verbliebenen
verzichtete
Blockade
Mama
Entwicklungshilfe
Verbund
Tiger
ruhen
fortgeschrieben
mithalten
namentlich
verwandt
Engagements
Anne
absehbarer
Schluss
Konstanz
Gen
Veto
knapper
wiederholte
Scheiben
frische
verkünden
wirkten
Anbietern
mächtige
Jakob
Vorgehensweise
Haushalten
Olga
Saudi-Arabien
schätzungsweise
abgerechnet
Vorhang
Weltweit
Spaltung
Langeweile
Pleite
Innenministeriums
Symptome
Abgeordneter
bekannter
Stalin
sachlich
mittag
Tante
Drucker
Route
antiken
starkes
kompletten
Bürgermeisters
häufigsten
Börsianer
unnötig
CDU-Fraktion
Südostasien
Vorabend
hinunter
konstant
weißer
Ethik
V
Abfälle
tschechische
Mailänder
Ivan
Mohamed
Wieviel
fröhlich
Zoo
größeres
Hintergründe
Sauerstoff
Eichel
übertrieben
Stückliste
deutschem
amtierenden
sinnvolle
Bibliotheken
kämpfte
Trinkwasser
SPD-Fraktionschef
Salz
Martha
Rauch
Videos
drucken
eingeschlossen
gestützt
Plutonium
älterer
Ingolstadt
Menschlichkeit
Heimspiel
Adler
angerichtet
riß
Phasen
boten
verbracht
erweiterten
Menschenrechtsverletzungen
Nikolaus
Mitleid
Parolen
bekomme
Besser
Zusätze
abgeschnitten
arg
Routine
Tätern
Afrikas
Stadtverordnetenversammlung
Beschränkung
Morde
Erfolgen
Red
ausgeschrieben
Hebron
US
d
unverzüglich
Zunge
Nationalisten
praktiziert
wiegt
Felix
Kunststoff
Reichweite
deutete
zurückzukehren
Smith
Satzung
Ladung
Stichtag
Ltd
zugehörigen
zutiefst
eingeplant
Albrecht
Konkurrent
Motoren
Normalität
Eigenkapital
Rückschlag
griffen
erweiterte
keines
erteilte
Kalender
kühl
vage
bewies
Beachten
NRW
Personenwagen
gefertigt
begründeten
Dasein
einfallen
entfalten
fangen
Gelassenheit
demonstrierten
Psychologen
erwarb
auszubauen
juristisch
Automobilindustrie
normaler
Brille
formal
ausgleichen
mittelständischen
US-amerikanischen
Bundesanstalt
mitgebracht
rückgängig
Buben
verdammt
stärkeren
empfindet
öffnete
Lüge
Makler
flüchtete
ernsthafte
Polizeibeamte
drohten
Nächte
Mercedes-Benz
vormittag
Anschein
Öffentlichkeitsarbeit
Personalkosten
Erwin Teufel
Innovation
ausgeschieden
Befürchtung
Rufnummer
Reisenden
Verstand
Elementen
dienten
änderte
Problems
Nach wie vor
Kenner
Taxifahrer
Verfassungsgericht
Ad
dienstags
Tübinger
Komposition
Haustür
Stadtgebiet
runden
verzögert
Dateien
Dimitrios
gereicht
sanft
Gehen
Research
Oskar
Tribüne
unzufrieden
Gültigkeit
verstecken
Kunsthalle
hinterlegen
Antisemitismus
Vorfahren
Akzente
Begrenzung
Reisende
Wahlbeteiligung
de la
Schnittstelle
Jordanien
Alarm
eignet
Wirkungen
Führungskräfte
Christel
Wobei
angewandt
aufgetaucht
vielfältigen
Schätzung
Sexualität
gewürdigt
arme
Diktator
Verschärfung
Fenstern
Arnold
schießt
verkürzt
Oberbayern
vorzunehmen
Landtagswahlen
jeher
Mitgliederversammlung
Aufzeichnungen
Entwicklungsländer
Gefühlen
vwd
seltenen
et
serviert
Dahinter
Vatikan
Korrekturen
Neubauten
logische
versäumt
umzugehen
Ambitionen
geprägten
eingezogen
Bundesanwaltschaft
Analyst
zurückgehen
deine
schloss
FC
Stabilisierung
Teils
Euch
Nationale
Innere
Kabarett
Fundament
Ernennung
vertagt
Williams
Krupp
wahrlich
verwundert
Zelt
Motiven
laufe
Reichen
Lücken
Beihilfe
Bebauung
Mehrheiten
bürgerliche
Abgesehen
Sound
nächtlichen
ethnischen
mittelständische
telefonisch
Fulda
einsteigen
raten
Versicherer
Tarifverhandlungen
Gewißheit
Regisseure
Kostenstelle
Weit
Gläubiger
nochmal
Christiane
Wehr
Renovierung
gemalt
Diesem
Note
Palast
verfolgte
graue
Schröders
Nationalismus
umliegenden
Normalerweise
sauer
begnügen
Tötung
Roten
anderem
verbundene
strahlt
abgestellt
Nachbar
Libyen
verarbeiten
Talente
Gedichten
Korea
Haftstrafe
Beckenbauer
Networks
Fraktionsvorsitzende
bekennen
erstattet
Horn
bemerkenswert
Werkzeug
Trick
Rückblick
Kunstwerke
Überlebenden
regulären
Papa
Indiz
Kiew
gewagt
halbwegs
Stattdessen
schlechthin
besiegt
verschiedensten
Bemerkungen
Udo
beruhigen
toll
dotierten
vollständigen
SPD-Chef
Miami
Plakat
Süddeutschen Zeitung
Zitat
ungeklärt
Arbeitern
Einflüsse
BND
Satire
Akte
enthaltenen
Geldpolitik
durchsucht
gab's
brav
Stadtteilen
Segment
Wochenenden
aufgebrochen
geraumer
mitteilen
klang
Gepäck
effektiv
überwiesen
römische
Warnungen
Landesverband
Flagge
formulieren
Ballett
professionellen
ausgeübt
Landung
Weisheit
Slobodan Milosevic
schlichten
prophezeit
festzulegen
donnerstags
Mantel
eh
überraschenden
überein
Oberursel
liebevoll
Baden
Taschen
Werkstätten
ADAC
Flecken
verankert
Jochen
Gunst
populär
Regierungspartei
prominente
beruft
Kanäle
Allee
Abweichungen
ganzer
zurückgreifen
klug
hierher
demokratisch
eigen
Boston
Abtreibung
arabische
siebzig
Bebauungsplan
Anschlägen
wissenschaftlicher
Des
WTO
kassieren
Kriterium
Aufträgen
Tausenden
Redakteur
Klischees
Großstädten
Lehrstellen
dein
vorstellbar
Sucht
erhob
verschickt
freundlichen
umfasst
Leder
Eins
bezug
Arzneimittel
Staatspräsidenten
auszugleichen
Absolventen
Brecht
abstimmen
Straßenbahn
Nationalsozialisten
Thüringer
lieferten
dänische
entspannt
befürwortet
prognostiziert
Rektor
Beiträgen
gestritten
füllt
Ressorts
zutage
letztendlich
kürzer
dünn
Baumann
umso
Hürde
verunsichert
Technischen
Planer
Belebung
Infos
Anja
Desaster
erstens
Buenos Aires
Böse
Verknüpfung
regt
Christian Ude
lenken
Geschäftstätigkeit
ausverkauft
steigender
kündigen
besetzte
90er Jahre
gegriffen
billige
beliebten
wünsche
sang
Kultusministerium
eindrucksvoll
Zensur
Ost-Berlin
Staatsanwälte
Preußen
Johannes Rau
Marine
Erdgas
erzwingen
anwesend
Schläge
unheimlich
Pflanze
Kühe
litt
derjenigen
grünes Licht
nett
achtzig
Größen
Heilbronn
Globus
hindurch
Bodensee
Atelier
Jugendlicher
Geliebten
kopiert
Tarifvertrag
Kanzlers
angrenzenden
einmaligen
Mitarbeiters
Gehör
gemein
Fluggesellschaften
Leitungen
erstmal
Offensichtlich
eingeweiht
befindlichen
inwieweit
Konvention
auftauchen
vorsorglich
Florenz
Avantgarde
Ablösung
versichern
Teilchen
Anbindung
sicherstellen
Lee
Diana
überdurchschnittlich
professionelle
ereignete
Gesundheitsreform
Mobilität
Darstellungen
hellen
Jean
Monitor
Verspätung
Innovationen
Christina
25jährige
Holländer
abzuwarten
vorangegangenen
Neugier
mangelt
Hauptquartier
humanitäre
Kindergeld
Filmemacher
Deal
Europameister
drastischen
Kohlendioxid
erprobt
aggressiv
angestellt
De
erheblicher
Entwicklungsländern
Böden
SG
blind
innovative
zusätzlicher
Astronomen
vorgeschrieben
Augenzeugen
norwegischen
Tiergarten
regelmäßige
Kernenergie
Eisenbahn
Sensation
Bekannte
widersprechen
Zehntel
nachfolgenden
brauchten
kombiniert
Pädagogen
steuerliche
Srebrenica
fünfziger Jahre
Sozialdemokrat
Goethes
Intendanten
rutschte
Ostdeutschen
begrenzten
Bremens
wertet
Kronen
nähert
Nebenwirkungen
moralisch
Jenseits
vorweisen
Tankstelle
Bayer Leverkusen
Schwelle
liegende
begrenzte
optimale
parat
Nationalpark
Einschnitte
Interessierte
Hauptrolle
Sich
Rover
Anstalten
Raumfahrt
Steinen
Hindernisse
Entgegen
lud
Erschließung
Alptraum
herrschenden
Dayton
Sozialamt
Jahreszeit
Verwertung
angerufen
kündigten
Würden
Munition
dreieinhalb
unterliegt
Sauna
Sporthalle
Aufschrift
amtliche
Pence
In der Regel
Magen
Jude
steckte
Belgrader
Gnade
aufrechterhalten
weithin
heimische
Letzte
DTB
Unbekannten
Aufarbeitung
Reisebüros
niedrigere
Mazedonien
zentral
wiederholten
schimpft
Faschismus
Verrat
Islamisten
Bekanntgabe
rückläufig
zusammengeschlossen
orientierten
30jährige
Blättern
Mandate
buchstäblich
beträchtlich
verwalten
Zeichnung
westdeutsche
Aktienkurse
Verstöße
Friedrichstraße
Ratten
Königreich
Pension
Deckung
Erdgeschoß
unverständlich
Mythen
englisch
Lagern
Arbeitszeiten
Sozialstaat
jünger
Geruch
aufstellen
wörtlich
musikalisch
Zigarette
Hauptstraße
Entsetzen
angewendet
Le
Sprengstoff
Coup
Störung
Uniform
steigert
Seminare
Gegenspieler
Fehlern
mittelalterlichen
Orden
Thron
Agenten
spektakuläre
OSZE
Kontrast
Senders
Teppich
Titeln
EUR
Erreger
satt
Strafkammer
Ute
Julia
frage
zahlte
Prinzen
stabilen
Reports
Schade
belaufen
beantragte
Carl
Einnahme
aneinander
sid
beläuft
Fahrten
Rems-Murr-Kreis
Südafrikas
Uhren
Rosa
Brauerei
erstaunt
bescheidenen
überraschende
angefordert
Parallel
Michael Schumacher
Jordan
antworten
Araber
Bayreuth
Bundesverbandes
Beirat
ewige
Münzen
passende
profitierten
St. Pauli
packen
King
Vorgängen
Zuwachsraten
Schilderung
drüben
Archivierung
Apple
Beethoven
Ampel
Kabul
körperlich
verständigen
warteten
angestrebten
Parks
teilzunehmen
Jahresumsatz
jahrzehntelang
Obersten
Zirkus
Straßenverkehr
ausgehandelt
Wiesen
bezifferte
Renditen
Diplomat
Weite
bewegten
beschwert
Tony Blair
Kunstwerk
Banker
Baustellen
steuerlichen
BDI
vergebens
erwartenden
Minen
geschätzten
DAX
hinreichend
abgesichert
extremen
jugendlichen
Erlebnisse
Spekulation
Belohnung
Volksabstimmung
Wichtigste
komplexen
Erzeugnisse
zerstörte
Trendwende
Hamburger SV
eingeschlagen
plaziert
wechselnden
gültige
Schubert
Hoch
Vergessen
totale
psychologische
betrieblichen
Buchen
Gewinnen
Moskaus
Innern
Christopher
nützlich
orientierte
Kompositionen
bedauerte
Formel 1
nix
Käse
Erzbischof
Ausfall
Konflikts
goldene
Marx
erhoffen
protestierten
landwirtschaftlichen
längerer
Geliebte
Völlig
landesweit
Abschreibungen
dominieren
bittere
versetzen
detaillierte
abgehalten
Chemiker
einsam
Blau
Anregung
Kameraden
Kooperationen
Wilfried
Schalke
Zusatz
geschrumpft
stundenlang
unweit
Illusionen
körperlichen
bemühte
finanzieller
klares
Werder Bremen
einsparen
Anführer
Überwindung
Fliegen
bedrohte
vorläufige
Vorbilder
betonten
verfügte
Extremisten
bloßen
berät
gemerkt
verwehrt
Hütte
John Major
nebst
Theorien
Angeblich
Kaufhaus
Atlantik
Tief
Hertha
ausgewählte
gängigen
leuchtet
Berufe
Bezirken
%% 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.
%% Cell type:markdown id:ordinary-coordination tags:
# Code Review
<br/>
<br/>
Dieses Notebook finden Sie hier: https://scm.cms.hu-berlin.de/ibi/python/-/blob/master/programmierspass/Code_Review.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:median-updating tags:
## Was ist es und worum geht es?
**Code Review** soll primär **Codequalität sichern**, aber auch
- Code **verbessern**
- *Fehler* finden und beseitigen
- *Lesbarkeit* und *Verständlichkeit* prüfen und verbessern
- Code **verstehen**, **lernen**
- bessere Lösungen finden
- Gefühl gemeinsamer Verantwortung aufbauen/stärken
%% Cell type:markdown id:paperback-lottery tags:
## Code verbessern
- *Fehler* finden und beseitigen →
1. Syntaktische Fehler
2. Laufzeitfehler
3. Semantische Fehler
- *Lesbarkeit* und *Verständlichkeit* prüfen und verbessern →
1. Programmierstil
%% Cell type:markdown id:activated-immune tags:
## Methoden
1. Pair Programming → z.B. IKT-Programmierkurs
2. "The Wisdom of the Crowds" → Entwicklung Freier Software
3. [IEEE Standard for Software Reviews and Audits (IEEE STD 1028-2008)](https://doi.org/10.1109%2Fieeestd.2008.4601584):
- Management reviews
- Technical reviews
- Inspections
- Walk-throughs
- Audits
*Wir schauen uns heute viele (kleine) Codebeispiele an, um [aus deren Fehlern zu lernen](https://de.wikipedia.org/wiki/Lernen_aus_Fehlern).*
%% Cell type:markdown id:changing-appeal tags:
## Syntaktische Fehler
%% Cell type:markdown id:collaborative-imagination tags:
Beginnen wir mit ein paar Beispielen ...
%% Cell type:code id:billion-aspect tags:
```
a := 4
```
%% Cell type:code id:periodic-might tags:
```
'a' = 1
```
%% Cell type:code id:vulnerable-guyana tags:
```
a() = 1
```
%% Cell type:code id:timely-transparency tags:
```
pass = 1
```
%% Cell type:code id:active-semester tags:
```
def pass():
print("pass")
```
%% Cell type:code id:technical-forty tags:
```
import keyword
print(keyword.kwlist)
```
%% Cell type:code id:institutional-belize tags:
```
iff a == 0:
print("a ist zu klein")
```
%% Cell type:code id:certified-annex tags:
```
if a == 0:
print("a ist zu klein")
```
%% Cell type:code id:statutory-category tags:
```
if a == 0:
break
```
%% Cell type:code id:present-trash tags:
```
a = 4 * (3 + 2
```
%% Cell type:code id:judicial-approval tags:
```
a = 'Mir gefällt's hier'
```
%% Cell type:markdown id:julian-stopping tags:
![Brains aside, I wonder how many poorly-written xkcd.com-parsing scripts will break on this title (or ;;&quot;&#39;&#39;{&lt;&lt;&#5b;&#39; this mouseover text.&quot;](https://imgs.xkcd.com/comics/(.png)
[Randall Munroe](https://xkcd.com/859/) / [CC-BY-NC](https://creativecommons.org/licenses/by-nc/2.5/)
%% Cell type:markdown id:friendly-delhi tags:
**syntaktische Fehler**
- Code verstösst gegen Syntaxregeln ("Grammatik") der Sprache (Python → https://docs.python.org/3/reference/grammar.html)
- hauptsächlich bei Anfänger:innen
- häufig: fehlende/flasch gesetzte Doppelpunkte, Kommata, Klammern, etc.
- müssen beseitigt werden, damit Programm überhaupt lauffähig ist ("geparst" werden kann)
%% Cell type:markdown id:excited-harvey tags:
### Laufzeitfehler
Auch ein syntaktisch korrektes Programm kann Fehler bei der Ausführung verursachen:
%% Cell type:code id:adopted-jordan tags:
```
print(a + b)
```
%% Cell type:code id:diverse-seating tags:
```
print(Hallo)
```
%% Cell type:markdown id:alternative-tuition tags:
→ Syntaxfehler können auch zu Laufzeitfehlern führen, werden aber vom Parser nicht als Syntaxfehler erkannt.
%% Cell type:code id:plain-costa tags:
```
a = ["a", "b", "c"]
print(a[3])
```
%% Cell type:code id:completed-phrase tags:
```
a = {
"title" : "The Art of Computer Programming",
"author" : "Donald E. Knuth"
}
print(a["publisher"])
```
%% Cell type:code id:buried-chambers tags:
```
a = "Das Quadrat von 1234567 ist " + 1234567**2
```
%% Cell type:code id:olive-greene tags:
```
a = "Das Quadrat von zwei ist " + int("vier")
```
%% Cell type:code id:engaging-transformation tags:
```
23 / (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 - ((9*10)/2))
```
%% Cell type:code id:designing-schema tags:
```
def rekursion():
rekursion()
rekursion()
```
%% Cell type:code id:resistant-machinery tags:
```
while 2 == 2*1:
a = a * 2
```
%% Cell type:markdown id:nonprofit-brief tags:
## Semantische Fehler
Diese werden nicht vom Interpreter erkannt und können beliebig komplex werden:
%% Cell type:code id:signed-military tags:
```
pi = 3
```
%% Cell type:code id:composed-stocks tags:
```
wochenstunden = 40 * 4
```
%% Cell type:code id:existing-objective tags:
```
gerade_zahlen = [i for i in range(1,10,2)]
gerade_zahlen
```
%% Cell type:markdown id:desperate-solution tags:
![6uamyn5m8n721.png](attachment:6uamyn5m8n721.png)
[siehe auch](https://img.devrant.com/devrant/rant/c_844886_xA3J2.jpg)
%% Cell type:markdown id:manufactured-exclusive tags:
Ein typischer [off-by-one-Fehler](https://de.wikipedia.org/wiki/Off-by-one-Error).
%% Cell type:code id:digital-premises tags:
```
def print_boxed(s):
print("-" * len(s))
print("|", s, "|")
print("-" * len(s))
print_boxed("Hallo Welt!")
```
%% Cell type:markdown id:signal-means tags:
OK, die waren einfach. Steigern wir uns:
%% Cell type:code id:fatal-motor tags:
```
def teiler(zahlen, a):
"""Prüft, ob eine der Zahlen ein Teiler von a ist."""
for zahl in zahlen:
return a % zahl == 0
return False
def primzahlen(n):
"""Berechnet alle Primzahlen bis (einschließlich) n."""
prim = []
for i in range(2, n):
if not teiler(prim, i):
prim.append(i)
return prim
primzahlen(10)
```
%% Cell type:markdown id:ranking-cleveland tags:
<div style="float:right;">
<img src="https://amor.cms.hu-berlin.de/~jaeschkr/teaching/heisenbug.png" style="width:400px"/>
<small>
<a href="https://geek-and-poke.com/geekandpoke/2009/7/8/the-art-of-bugfixing-chapter-2.html">Geek &amp; Poke</a> / <a href="https://creativecommons.org/licenses/by/3.0/">CC-BY 3.0</a>
</small>
</div>
Diese Art von Fehlern treten bei jeder Programmausführung auf und sind vergleichsweise einfach zu entdecken.
Es gibt auch deutlich subtilere Fehler, die reproduzierbar nur unter bestimmten Bedingungen auftreten.
Und dann gibt es noch Fehler, die nur unter so seltsamen Bedingungen auftreten, dass diese praktisch nicht reproduzierbar sind. → [Heisenbugs](https://en.wikipedia.org/wiki/Heisenbug):
*A bug that disappears or alters its behavior when one attempts to probe or isolate it.* ([The Jargon File](http://catb.org/jargon/html/H/heisenbug.html))
(siehe auch: <a href="https://en.wikipedia.org/wiki/Bug_(engineering)">Bug</a>)
%% Cell type:markdown id:greenhouse-japan tags:
## Programmierstil
![I honestly didn&#39;t think you could even USE emoji in variable names. Or that there were so many different crying ones.](https://imgs.xkcd.com/comics/code_quality_2x.png)
[Randall Munroe](https://xkcd.com/1513/) / [CC-BY-NC](https://creativecommons.org/licenses/by-nc/2.5/)
(weitere:
[XKCD 1695](https://xkcd.com/1695/),
[XKCD 1833](https://xkcd.com/1833/),
[XKCD 1926](https://xkcd.com/1926/),
[XKCD 2138](https://xkcd.com/2138/),
[siehe auch](https://www.explainxkcd.com/wiki/index.php/Category:Code_Quality))
%% Cell type:markdown id:corporate-pearl tags:
Ein weites Feld ...
... zum Beispiel:
- Benennung von Variablen → https://en.wikipedia.org/wiki/Naming_convention_(programming)
- Code-Layout
- Kommentare
- Aufteilung/Umfang von Funktionen
[Style Guide for Python Code](https://peps.python.org/pep-0008/)
%% Cell type:markdown id:three-science tags:
## Die Reiskornlegende
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/0/07/Lahur_Sessa_by_Thiago_Cruz.jpg/480px-Lahur_Sessa_by_Thiago_Cruz.jpg" style="float:right; width: 400px;"/>
Mittels Iteration und Rekursion soll die Anzahl der Reiskörner auf einem Schachbrett berechnet werden, wenn Sie wie in der [Reiskornlegende](https://de.wikipedia.org/wiki/Sissa_ibn_Dahir#Legende) beschrieben verteilt werden: *auf das erste Feld ein Korn, auf das zweite Feld zwei Körner, auf das dritte Feld vier Körner ... usw. immer verdoppelnd bis zum 64. Feld*.
%% Cell type:markdown id:behind-driver tags:
### Iteration
%% Cell type:code id:extreme-angola tags:
```
def reiskoerner(i,n,j):
while (i<=n):
print ("Feld",i,"=",j,"Körner")
i=i+1
j=j*2
```
%% Cell type:markdown id:alpha-designation tags:
- funktioniert prinzipiell
- sprechendere Variablennamen
- i und j innerhalb der Funktion initialisieren
- damit die Funktionssignatur möglichst einfach ist
- weil der entscheidende Parameter die Anzahl der Tage ist
%% Cell type:code id:entire-upset tags:
```
def reiskoerner ():
reis = 0,01
while 1 <= feld >= 64
Reis verdoppeln
Feld um eins erhoehen
print Reis,Feld
```
%% Cell type:markdown id:promising-sleep tags:
- Dezimaltrennzeichen ist `.`, nicht `,`
- fehlender Doppelpunkt am Ende der `while`-Zeile
- `feld` müsste `<= 64` sein
- Notation `1 <= reis >= 64` klappt in Python nicht
%% Cell type:code id:patent-picnic tags:
```
def reiskoerner (a, b):
while (b_mehr < b * (2**a-1)):
b_mehr = b_mehr * 2
print (b_mehr)
```
%% Cell type:markdown id:decent-captain tags:
- sprechendere Variablennamen
- direkte Exponentierung unnötig, da diese durch die Schleife und sukzessive Verdopplung von durchgeführt werden könne (was effizienter wäre, als bei jedem Durchlauf erneut zu Exponentieren)
- dafür müsste `a` jeweils verdoppelt werden
- Schleife sollte dann testen, ob `a` noch innerhalb des erlaubten Bereiches ist
- `b\_mehr` muss initialisiert werden
%% Cell type:code id:affected-armenia tags:
```
def reiskoerner(t):
r = 1
while f > 1:
r = r * 2
f = f - 1
return r
```
%% Cell type:markdown id:severe-anthony tags:
- Ausgabe der Reiskörner pro Feld fehlt
- Felder würden rückwärts ausgegeben werden -- Ausgabe des Feldes müsste dann ggf. angepasst werden
%% Cell type:code id:functional-georgia tags:
```
r=1
f=1
def reis
while (f<64):
f=f+1
r=r*2
print (r)
```
%% Cell type:markdown id:smooth-prevention tags:
- Initialisierung der Variablen sollte innerhalb der Funktion erfolgen
- Syntaxfehler (z.B. Einrückung)
- Ausgabe von `r` sollte innerhalb der Schleife sein
- Maximalwert als Parameter
%% Cell type:code id:working-poker tags:
```
def reis( ):
anzahl_der_felder = 1
reiskoerner = 1
neue_reiskoerner = reiskoerner * 2
if anzahl_der_felder == 1:
print("Feld 1 : 1 Reiskorn")
else anzahl_der_felder < 65 and anzahl_der_felder > 1:
print("Feld", anzahl_der_felder, ":", neues_gehalt, "Reiskörner")
anzahl_der_felder = anzahl_der_felder + 1
reiskoerner = neue_reiskoerner
```
%% Cell type:markdown id:alert-surfing tags:
- keine Iteration, Grundidee trotzdem irgendwie da
%% Cell type:code id:identical-advance tags:
```
def iterativer_algorithmus(Feld):
while Feld <= 64:
reis=2**(Feld-1)
print(reis)
Feld += 1
```
%% Cell type:markdown id:increased-lightweight tags:
- Anzahl der Felder übergeben, Startfeld innerhalb der Funktion initialisieren
- Anzahl der Reiskoerner tatsächlich verdoppeln
%% Cell type:code id:inclusive-running tags:
```
function reiskoerner(r, f):
print (b)
while f < 30 do
a = a +1
r = b * 2
print (b)
```
%% Cell type:markdown id:burning-definition tags:
- Syntaxfehler (fehlendes `def`, `do` statt Doppelpunkt, etc.)
- Variablennamen falsch (`a` müsste `f` sein, `b` müsste `r` sein)
%% Cell type:markdown id:elegant-delicious tags:
### Rekursion
%% Cell type:code id:alive-cancer tags:
```
def reiskoerner(reis, feld):
if feld == 64:
print reis
return reis
else:
print reis
return reiskoerner(reis * 2, feld + 1)
```
%% Cell type:markdown id:identical-district tags:
- "getarnte" Iteration, keine Rekursion!
- `print` ist eine Funktion -- daher Aufruf als `print()`
%% Cell type:code id:instrumental-transsexual tags:
```
def reiskoerner (f, r):
i = 1
if i < f:
print(r)
i = i + 1
reiskoerner(f,r*2)
reiskoerner (64, 1)
```
%% Cell type:markdown id:practical-paradise tags:
- Prinzip falsch, wie vorher auch
- aber auch noch: Stackoverflow!
- denn: `i` wird nicht verwendet
%% Cell type:code id:efficient-standing tags:
```
def reiskoerner (r, f)
if f <= 64
print (r)
reis= 2* reiskoerner(f-1)
else
print (r)
```
%% Cell type:markdown id:annual-refund tags:
- Grundidee ist da
- Syntax beachten: Einrückungen und Doppelpunkte
- Funktion erwartet zwei Parameter -- nur einer wird übergeben
- in der Verzweigung müsste auf `f > 1` getestet werden
- `r` wird nicht verwendet -- stattdessen `reis`
- im `else`-Zweig müsste 1 zurückgegeben werden
- im `if`-Zweig müsste ebenfalls eine `return`-Anweisung stehen
%% Cell type:code id:elementary-broadway tags:
```
def reiskoerner_pro_feld ( anzahl_der_felder, reiskoerner ):
neue_reiskoerner = reiskoerner*2
while anzahl_der_felder <= 64:
reiskoerner_pro_feld ( anzahl_der_felder, reiskoerner)
print(anzahl_der_felder, neue_reiskoerner)
anzahl_der_felder = anzahl_der_felder + 1
reiskoerner = neue_reiskoerner + 1
reiskoerner_pro_feld (anzahl_der_felder = 1, reiskoerner = 1)
```
%% Cell type:markdown id:supreme-chinese tags:
## Weiterführende Links
- https://www.greenteapress.com/thinkpython/html/thinkpython021.html
- https://realpython.com/invalid-syntax-python/
- https://www.tutorialsteacher.com/python/error-types-in-python