- Startseite
- Allgemeine Informationen zur Lehrveranstaltung
- Einfaches Python Setup und Wichtige Informationen
- 0. Python Einführung und Checkup
- 1. Einführung und einfache Algorithmen
- 2. Differenzieren und Integrieren
- 3. Vektoren, Matrizen und Vektorisierung in Python
- 4. Datenanalyse bzw. Datenauswertung
- 5. Grundlagen der Optimierung und Gradient Descent
- 6. Stochastische Optimierung und Genetische Algorithmen
- 7. Monte-Carlo-Methoden – Simulation und Integration
- 8. Monte-Carlo-Methoden, Teil 2 – Monte-Carlo-Integration, Teil 2 und Random Walk
- 9. Unsupervised Machine Learning: Clustering von Daten
- 10. Supervised Machine Learning: Grundlagen
- 11. Einführung in künstliche neuronale Netzwerke
Die Jupyter-Notebooks zur Lehrveranstaltung finden Sie im zugehörigen GitHub-Repository.
0 Python Einführung und Checkup¶
Python ist eine einfach zu erlernende und benutzende Programmiersprache. Bereits mit Hilfe der Grundfunktionalität lassen sich viele Aufgaben lösen und Probleme bearbeiten.
Darüber hinaus gibt es jedoch auch noch nahezu für jeden Bereich zusätzliche Bibliotheken (Libraries), die in Python sehr einfach geladen werden können und durch die man noch weitere Funktionalität zur Verfügung hat, ohne selbst viel programmieren zu müssen.
In einer Distribution mit Paket-Management (wie Anaconda) lassen sich diese Pakete einfach installieren. Braucht man mehr bzw. verschiedene Zusammenstellungen von Paketen für verschiedene Problemstellungen, empfiehlt sich der Umgang mit Umgebungen (Environments) in Anaconda.
In diesem Jupyter-Notebook werden wir uns zur Wiederholung einmal durch die wichtigsten Python-Funktionen durcharbeiten.
Am Ende gibt es eine kurze Aufgabe, die Sie in einer halben Stunde lösen sollten.
0.1 Variablen und Funktionen in Python¶
# Definition zweier integer Variablen
var_1 = 1
var_2 = 2
# Ausgabe der Summe auf dem Bildschirm
print("Die Summe der beiden Variablen ist: ", var_1 + var_2)
Die Summe der beiden Variablen ist: 3
# Definition von String Variablen
var_1 = "Hello"
var_2 = "World!"
# Ausgabe der Summe auf dem Bildschirm
print("Der überraschende Text: ", var_1 + " " + var_2 + "\n" + "Das war überraschend!")
Der überraschende Text: Hello World! Das war überraschend!
# Definition einer Funktion
def a_function(var_1, optional_var_1 = 10):
# addiere 10 (oder einen anderen Term) zur eingegebenen Zahl
output = var_1 + optional_var_1
# was von der Funktion zurückgegeben wird
return output
# verwende die Funktion
print("Ohne optionales Argument: ", a_function(1))
print("Mit optionalem Argument: ", a_function(1,5))
Ohne optionales Argument: 11 Mit optionalem Argument: 6
0.2 Listen und Loops in Python¶
# Definition der Liste
a_list = [1,3,5,7,9]
# noch eine leere Liste
square_list = []
# For-Loop über Listen-Elemente
for an_element in a_list:
# Ausgabe von Informationen zur Variable, über die der Loop läuft
print(an_element, " zum Quadrat ist ", an_element**2)
# Hänge ein Ergebnis an eine andere Liste an
square_list.append(an_element**2)
# gib am Schluss auch die andere Liste aus
print("Die Quadrat-Liste ist jetzt ", square_list)
1 zum Quadrat ist 1 3 zum Quadrat ist 9 5 zum Quadrat ist 25 7 zum Quadrat ist 49 9 zum Quadrat ist 81 Die Quadrat-Liste ist jetzt [1, 9, 25, 49, 81]
# Eine andere Art von Loop
# initialisiere einen Zähler
a_counter = 0
# While-Loop, bis der Zähler 10 erreicht
while a_counter < 10:
# Ausgabe des Zählers
print("die nächste Zahl ist ", a_counter)
# Erhöhe den Zähler um 1
a_counter += 1
die nächste Zahl ist 0 die nächste Zahl ist 1 die nächste Zahl ist 2 die nächste Zahl ist 3 die nächste Zahl ist 4 die nächste Zahl ist 5 die nächste Zahl ist 6 die nächste Zahl ist 7 die nächste Zahl ist 8 die nächste Zahl ist 9
# Loop über Elemente und indices einer Liste
for an_index, an_element in enumerate(square_list):
# Ausgabe von Informationen, wobei man Index in der Liste und das Element nutzen kann
print("die Zahl an der Stelle ", an_index, " ist ", an_element)
die Zahl an der Stelle 0 ist 1 die Zahl an der Stelle 1 ist 9 die Zahl an der Stelle 2 ist 25 die Zahl an der Stelle 3 ist 49 die Zahl an der Stelle 4 ist 81
# Ein impliziter Loop erzeugt eine Liste
print("Die ersten paar Quadrate: ", [b**2 for b in range(100)])
Die ersten paar Quadrate: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116, 2209, 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969, 4096, 4225, 4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625, 5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056, 7225, 7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 9216, 9409, 9604, 9801]
0.3 Fallunterscheidungen in Python¶
# Variablen mit Wahrheitswert
is_it = True
it_is = False
# Ausgabe der Ergebnisse logischer Operationen
print("AND: ", it_is and is_it)
print("OR: ", it_is or is_it)
# IF-Statement, d.h. Abfrage ob etwas wahr oder falsch ist
if(it_is and is_it):
# wenn Abfrage wahr ist, tu das:
print("Kombiniert!")
# weitere Abfrage für zusätzliche Möglichkeiten
elif(it_is or is_it):
# wenn das wahr ist, dann tu das:
print("Nicht ganz!")
# und für alle andere Fälle
else:
# wenn bisher nichts zugetroffen ist, dann tu das:
print("Weder noch!")
AND: False OR: True Nicht ganz!
0.4 Dictionaries in Python¶
# Definition eines Dictionary:
# Im Prinzip eine Sammlung von Zuordnungen von "values" zu "keys"
a_dict = {"Alice": 12, "Bob": 14}
# Ausgabe von Eigenschaften/values über keys
print("So alt ist Alice: ", a_dict["Alice"])
So alt ist Alice: 12
# Einträge in Dictionaries lassen sich hinzufügen
a_dict["Frank"] = 16
# und ändern
a_dict["Alice"] = 13
# Ausgabe des aktuellen Dictionary
print("Die aktuellen Werte: ", a_dict)
Die aktuellen Werte: {'Alice': 13, 'Bob': 14, 'Frank': 16}
# values in Dictionaries können auch Dictionaries sein
another_dict = {"people": a_dict}
# so sieht ein verschachteltes Dictionary aus
print("Verschachteltes Dict: ", another_dict)
Verschachteltes Dict: {'people': {'Alice': 13, 'Bob': 14, 'Frank': 16}}
0.5 Mathematische Funktionen und Arrays in Python: Die NumPy-Bibliothek¶
# Mathematische Funktionen ohne NumPy findet man hier:
import math as m
# andere Möglichkeiten für den Import:
# import math
# from math import sin, cos, exp
# Aber Achtung: Tun Sie das nie (Lebensgefahr!):
# from math import *
# Ausgabe des Sinus von Pi
print(m.sin(m.pi/2))
# Ausgabe der Exponentialfunktion von minus ein Halb
print(m.exp(-.5))
1.0 0.6065306597126334
# NumPy stellt eine breite mathematische Funktionalität und Arrays bereit
import numpy as np
# Machen wir ein Array aus einer der Listen von oben
square_array = np.array(square_list)
# Ausgabe des Arrays
print(square_array)
[ 1 9 25 49 81]
# rechnen mit Arrays ist sehr intuitiv
# Hier die (elementweise) Multiplikation mit der Zahl 4
print(square_array*4)
# Hier das elementweise Quadrieren des Arrays
print(square_array**2)
# Hier der elementweise Logarithmus des Arrays
print(np.log(square_array))
# Hier die elementweise Exponentialfunktion des Arrays
print(np.exp(square_array))
[ 4 36 100 196 324] [ 1 81 625 2401 6561] [0. 2.19722458 3.21887582 3.8918203 4.39444915] [2.71828183e+00 8.10308393e+03 7.20048993e+10 1.90734657e+21 1.50609731e+35]
# In NumPy findet man auch Zufallszahlen (mehr dazu in einer späteren Einheit), z.B.:
# Loop über 20 Runden
for i in range(20):
# Wähle zwei Zahlen aus dem Array von vorhin, mit Zurücklegen
a_selection = np.random.choice(square_array, 2, replace=True)
# Gib das Ergebnis aus
print(a_selection)
# Überprüfe, ob die zwei gezogenen Zahlen zufällig gleich sind
if a_selection[0] == a_selection[1]:
# Wenn ja, bitte kurz jubeln!
print("Yeee-Haaaa!")
[1 9] [9 1] [1 9] [1 9] [25 1] [25 25] Yeee-Haaaa! [49 9] [49 9] [25 25] Yeee-Haaaa! [ 1 49] [1 9] [49 49] Yeee-Haaaa! [49 81] [ 1 25] [81 25] [1 9] [1 1] Yeee-Haaaa! [ 9 25] [49 49] Yeee-Haaaa! [ 9 25]
# Arrays können auch mehrdimensional sein (die gewünschte Größe wird als Tupel angegeben):
another_array = np.random.random(size=(5, 5))
# Ausgabe dieses Zufallsarrays mit gleichverteilten Zahlen zwischen 0 und 1
print(another_array)
# Ein Array mit lauter 1en
some_ones = np.ones((5, 5))
# Ein Array mit lauter 0en
some_zeros = np.zeros((5, 5))
# Hier eine Art IF-Abfrage, aber elementweise für Arrays:
# wo das "andere Array" kleiner als 0.5 ist, schreibe eine 1 in den Check,
# ansonsten schreibe dort eine 0 hinein
the_check = np.where(another_array < 0.5 * some_ones, some_ones, some_zeros)
# Ausgabe der 0en und 1en für das Check-Array
print(the_check)
# Summiere alle Fälle größer 0.5 und gib die Summe aus
print("größer als 1/2: ", np.sum(the_check))
# Die gleiche Summe, aber nur über die Spalten ausgeführt
# Die Ausgabe wird als Integer angefordert
print("pro Zeile: ", np.sum(the_check, axis=1).astype(int))
[[0.31742739 0.92173144 0.79542856 0.45284739 0.62144654] [0.69136918 0.18686608 0.04669047 0.43238899 0.53734671] [0.59476831 0.61888398 0.11266082 0.08822554 0.85670338] [0.28209592 0.00861696 0.74836811 0.66746503 0.40037377] [0.95612427 0.85250935 0.89576426 0.64496258 0.12594957]] [[1. 0. 0. 1. 0.] [0. 1. 1. 1. 0.] [0. 0. 1. 1. 0.] [1. 1. 0. 0. 1.] [0. 0. 0. 0. 1.]] größer als 1/2: 11.0 pro Zeile: [2 3 2 3 1]
0.6 Plotting in Python: Die Matplotlib-Bibliothek¶
%matplotlib inline
# die vorige Zeile stellt den Ausgabe-Modus für Plots im Jupyter-Notebook ein
# Die Standart-Art, Matplotlib zu importieren
import matplotlib.pyplot as plt
# Beginne eine neue Figur/Grafik
fig = plt.figure()
# Zeichne rote Punkte von Daten aus dem Quadrat-Array, nochmals quadriert, mit Bezeichnung
plt.plot(np.arange(len(square_array)), square_array**2, "r.", label="Squares squared")
# Zeichne eine blaue Linie für Daten aus dem Quadrat-Array, mit Bezeichnung
plt.plot(np.arange(len(square_array)), square_array, "b-", label="Just Squares")
# Setze Beschriftung für die x-Achse fest
plt.xlabel("Numbers")
# Setze Beschriftung für die y-Achse fest
plt.ylabel("Squares?")
# Setze Beschriftung für den Plot fest
plt.title("A nice plot")
# Setze Skalierung für die y-Achse auf logarithmisch
plt.yscale("log")
# Erzeuge aus den Bezeichnungen eine Legende im Plot
plt.legend(loc=0)
# Speichere die Grafik als pdf-Datei ab
plt.savefig("test_plot.pdf")
# Zeige die Grafik außerdem hier an
plt.show()
# Erzeuge noch eine Figur
fig2 = plt.figure()
# Plotte die Werte im anderen Array als farbige Bild-Punkte bzw. -Quadrate
plt.matshow(another_array)
# zeige die Figur hier an
plt.show()
<Figure size 432x288 with 0 Axes>
0.7 Input und Output in Python¶
# Direkter Input durch den User, Achtung, das Resultat ist eine String-Variable
# an dieser Stelle wartet das Programm auf eine Eingabe
a_number = int(input("Bitte eine Zahl eingeben: "))
# Ausgabe des Quadrats der Eingabe
print("Das Quadrat Ihrer Zahl ist ", a_number**2)
Bitte eine Zahl eingeben: 4 Das Quadrat Ihrer Zahl ist 16
# Schreiben in eine Datei
# Zunächst öffnen wir die Datei mit der Fähigkeit zu schreiben ("w")
out_f = open("a_text_file.csv", "w")
# Dann schreiben wir die erste Zeile (Header) in die Datei
# \n macht eine neue Zeile
out_f.write("Zahl,Quadrat\n")
# Loop über 20 Zahlen
for i in range(20):
# Schreibe die aktuelle Zahl und ihr Quadrat in die nächste Zeile
# Achtung: Das Argument der Schreib-Funktion ist ein einzelner String
out_f.write(str(i)+","+str(i**2)+"\n")
# Schließe die Datei wieder
out_f.close()
# Lesen aus einer Datei (präzise, kann aber mühsam sein)
# Zunächst öffnen wir die Datei, diesmal mit der Fähigkeit zu Lesen ("r")
in_f = open("a_text_file.csv", "r")
# Ausgabe der Zeilen in der gelesenen Datei
print(in_f.readlines())
# Schließe die Datei wieder
in_f.close()
['Zahl,Quadrat\n', '0,0\n', '1,1\n', '2,4\n', '3,9\n', '4,16\n', '5,25\n', '6,36\n', '7,49\n', '8,64\n', '9,81\n', '10,100\n', '11,121\n', '12,144\n', '13,169\n', '14,196\n', '15,225\n', '16,256\n', '17,289\n', '18,324\n', '19,361\n']
# NumPy hat eine gute und einfachere Alternative für das Einlesen
# von Dateien parat, z.B. im csv-Format:
new_array = np.genfromtxt("a_text_file.csv", dtype=int, delimiter=",", skip_header=1)
# Ausgabe des eingelesenen Dateiinhalts
print(new_array)
[[ 0 0] [ 1 1] [ 2 4] [ 3 9] [ 4 16] [ 5 25] [ 6 36] [ 7 49] [ 8 64] [ 9 81] [ 10 100] [ 11 121] [ 12 144] [ 13 169] [ 14 196] [ 15 225] [ 16 256] [ 17 289] [ 18 324] [ 19 361]]
0.8 Übungsaufgabe: Berechnung von Primzahlen¶
Berechnen Sie die ersten 1000 Primzahlen und stellen Sie deren Häufigkeit in einem Histogramm dar.
Wenn Sie das selbständig üben wollen, dann schauen Sie sich meine Beispiellösung erst etwas später an. Das ist natürlich nicht die einzige Möglichkeit, diese Aufgabe zu lösen …
# initialisiere die Liste der Primzahlen mit 2, der einzigen geraden Primzahl
list_of_primes = [2]
# Berechne die derzeitige Anzahl der Primzahlen in der Liste
total_number = len(list_of_primes)
# Setze den Wert für den ersten zusätzlichen Kandidaten nach der 2
candidate = 3
# Ein While-Loop hilft dabei, die Abbruchbedingung (1000 Zahlen) umzusetzen
while total_number < 1000:
# setzte die Eigenschaft "ist eine Primzahl" auf True
is_prime = True
# jetzt suchen wir nach Teilern, dadurch können wir diese Eigenschaft ggf. widerlegen
# Loop über alle bisher gefundenen Primzahlen (denn nur die kommen eigentlich als
# Teiler in Frage)
for a_prime in list_of_primes:
# checke, ob die momentane Primzahl größer ist als die Wurzel aus dem
# Kandidaten, denn wenn das so wäre, kann sie kein Teiler mehr sein
# (denn dann müsste es auch einen kleineren Teiler geben, und die
# haben wir alle schon überprüft)
if a_prime > np.sqrt(candidate):
# Verlasse den innersten Loop, in dem wir uns gerade befinden
break
# checke, ob die momentane Primzahl den Kandidaten teilt
if (candidate % a_prime == 0):
# wenn wir einen Teiler finden, setzen wir die Prim-Eigenschaft auf False um
is_prime = False
# nachdem jetzt alle möglichen Teiler überprüft sind, checke die Prim-Eigenschaft
if is_prime:
# ist immer noch wahr, also hängen wir den Kandidaten an die Primzahl-Liste an
list_of_primes.append(candidate)
# wenn die Eigenschaft false ist, passiert nichts
# berechne die aktuelle Anzahl der Primzahlen in der Liste
total_number = len(list_of_primes)
# Erhöhe die Kandidaten-Zahl um 2 (d.h. gehe zur nächsten ungeraden Zahl)
candidate += 2
# Gib die Primzahl-Liste aus
print(list_of_primes)
# Erzeuge eine neue Grafik
fig2 = plt.figure()
# Erzeuge ein Histogramm der ersten 1000 Primzahlen
plt.hist(list_of_primes, bins=50)
# Beschrifte die Achsen
plt.xlabel("Zahlenbereich")
plt.ylabel("Anzahl")
# Zeige die Grafik an
plt.show()
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919]