# 12-1
def faku(zahl):
# Abbruchbedingung definieren
# Das Programm gibt 1 zurück, wenn die übergebene Zahl gleich 1 oder 0 ist
if zahl == 1 or zahl == 0:
return 1
# Ansonsten wird die aktuelle Zahl mit dem um 1 verringerten Aufruf der Funktion multipliziert
else:
return zahl * faku(zahl-1)
# Wir rufen die Funktion zum Testen auf und geben das Ergebnis aus
print(faku(6))
print(faku(1))
print(faku(0))
# 12-2
def kleiner_gauss(n):
# Abbruchbedingung -> Das Programm steigt genau bis zur 1 ab und addiert die Zahlen dann Rückwärts auf
if n == 1:
return 1
else:
# Selbstaufruf wie bei der fakultät nur als Summe, nicht Produkt.
return n + kleiner_gauss(n-1)
# Wir rufen die Funktion zum Testen auf und geben das Ergebnis aus
print(kleiner_gauss(10))
# 12-3
# Unsere Funktion soll eine Zahlenliste und eine gesuchte Zahl annehmen
def zahl_in_liste(zahlenliste,suchzahl):
# Abbruchbedingung 1: Wenn die Liste komplett leer ist soll nicht weitergesucht werden und False zurückgegeben werden.
if len(zahlenliste) == 0:
return False
# Abbruchbedingung 2: Wenn das erste Element der Liste schon die geuschte Zahl ist geben wir True zurück und suchen nicht weiter.
elif zahlenliste[0] == suchzahl:
return True
# Rekursiver Aufruf: Ansonsten rufen wir die Funktion nochmal auf und werfen das erste Wort, welches im Schritt vorher verglichen wurde, aus der Liste.
# Dazu übergeben wir die Liste startend vom zweiten Element
else:
return zahl_in_liste(zahlenliste[1::], suchzahl)
# Wir rufen die Funktion zum Testen auf und geben das Ergebnis aus
testliste = [2,7,9,232,1,-2]
print(zahl_in_liste(testliste, 3))
print(zahl_in_liste(testliste, 9))
# 12-4
def produkt(a,b):
# In jedem Aufruf addieren wir ein mal die Zahl a zum Endergebnis und verringern ODER erhöhen die Zahl b um 1 bis wir genau auf 0 sind.
# Ob wir erhöhen oder verringern ist abhängig davon, ob wir eine negative Zahl b haben
# Abbruchbedingung: Wenn b gleich 0 hören wir auf
if b == 0:
return 0
else:
# b ist kleiner als Null, wir müssen erhöhen um richtung 0 zu kommen
if b < 0 and a > 0:
return -a + produkt(a, b+1)
elif b < 0 and a < 0:
return -a + produkt(a, b+1)
# b ist größer als Null, wir müssen verringern um richtung 0 zu kommen
elif b > 0 and a < 0:
return a + produkt(a, b-1)
elif b > 0 and a > 0:
return a + produkt(a, b-1)
# Wir rufen die Funktion zum Testen auf und geben das Ergebnis aus
print(produkt(0,3))
print(produkt(3,3))
print(produkt(-11,2))
print(produkt(7,-4))
# 12-5
def zweierschritte(liste):
# Wir durchlaufen die Liste von vorne bis hinten in Zweierschritten
print(liste[::2])
# Test
zweierschritte(["Hallo", "mein", "Name", "ist", "Peter"])
zweierschritte([3,2,1,7,4,123,15,2])
# 12-6
def zweierschritte_umgedreht(liste):
# Zwischenschritte: Jedes zweite Element der Liste speichern
liste_temp = liste[::2]
# Liste umdrehen
liste_temp = liste_temp[::-1]
return liste_temp
# Test
print(zweierschritte_umgedreht(["Hallo", "mein", "Name", "ist", "Peter"]))
print(zweierschritte_umgedreht([3,2,1,7,4,123,15,2]))
# 12-7
def potenz(x, y):
# x ^ 0 ist per Definition 1
if y == 0:
return 1
# Ansonsten multiplizieren wir die Basis (x) so oft mit sich selber, wie der Exponent (y) groß ist
else:
return x * potenz(x,y-1)
# Test
print(potenz(2,7))
##Aufgabe 12##
#a)
# im Terminal:
unzip 10MB_spammax-verkettet.zip
#b)
spamfile = open('10MB_spammax-verkettet.txt', 'r', encoding='iso-8859-1') # öffnet die Datei zum Lesen
spam = spamfile.read()
# der Inhalt des Filehandles wird als String in die Variable spam eingelesen
spamfile.close()
#c)
import re
def count_mails(file_string):
mailregex = re.compile(r'Return-Path: <')
# es gibt mehrere Möglichkeiten, aber 'Return-Path' ist das einzige, was sicher nur am Anfang jeder neuen Mail steht und eignet sich deshalb besonders
count = len(re.findall(mailregex, file_string))
# erstellt eine Liste aus allen Matches des Regex und gibt die Länge der Liste zurück; die Länge der Liste entspricht der Anzahl der Mails
return count # gibt die Anzahl zurück ans Hauptprogramm
#d)
def from_and_subject(file_string):
from_and_subject = open('from_and_subject.txt', 'w')
# öffnet ein Filehandle zum Schreiben, das noch nicht existiert, legt also eine neue Datei an
from_subject_regex = re.compile(r'From:(.*?)\n.*?Subject:(.*?)\n')
# matcht zwei übereinanderstehende Zeilen die mit "From:" und "Subject:" beginnen; der Inhalt des Absenders und des Betreffs werden gruppiert, um später einzeln darauf zugreifen zu können
for match in re.findall(from_subject_regex,file_string):
# erstellt eine Liste aller Matches und iteriert darüber
from_and_subject.write(match[0])
# schreibt den Text in der ersten Gruppe des Regex in die neue Datei
from_and_subject.write(' : ')
# Variabler Separator wird eingefügt
from_and_subject.write(match[1])
#schreibt den Text in der zweiten Gruppe des Regex in die Datei
from_and_subject.write('\n')
# fügt am Ende jeder Zeile einen Zeilenumbruch ein
from_and_subject.close() #schließt das Filehandle
#e)
def extract_mails(file_string):
emaildictionary = {}
# erstellt ein leeres Dictionary
addressregex = re.compile(r'([\w+.-]+@([\w-]*\.)+\w{1,3})')
# matcht auf e-mail adressen indem es buchstaben/./-/+, ein @, ein oder mehrere buchstaben/- mit einem punkt am ende ("cis.", "lmu."), und eine sequenz aus 1-3 buchstaben ("de", "com") sucht
for address in re.findall(addressregex,file_string):
# erstellt eine Liste aller Matches und iteriert darüber
if address in emaildictionary:
emaildictionary[address[0]] = emaildictionary[address]+1
# ist die Adresse schon vorhanden wird der Wert um 1 erhöht
else:
emaildictionary[address[0]] = 1
# sonst wird der Wert mit 1 initialisiert
return emaildictionary # gibt das Dictionary zurück
#f)
def extract_domains(file_string):
domaindictionary = {}
# erstellt ein leeres Dictionary
domainregex = re.compile(r'([\w+.-]+@(([\w-]*\.)+\w{1,3}))')
# der gleiche Regex, aber mit einer zusätzlichen Gruppiertung um die Domain
for domain in re.findall(domainregex, file_string):
# s.o.
if (domain[1] in domaindictionary):
# domain[1] enthält den Inhalt der Gruppierung um die Domain
domaindictionary[domain[1]] = domaindictionary[domain[1]]+1
# ist die Domain schon vorhanden wird der Wert um 1 erhöht
else:
domaindictionary[domain[1]] = 1
# sonst wird der Wert mit 1 initialisiert
return domaindictionary # gibt das Dictionary zurück
#g)
def woerter_speichern(file_string):
www_text = open('www.txt', 'w')
# öffnet ein neues Filehandle zum Schreiben
splitregex = re.compile(r'[a-zA-ZäöüÄÖÜ]+')
# matched nur Buchstaben, deshalb kann man hier nicht \w benutzen: Zahlen werden in dieser Aufgabe nicht als zu Wörtern zugehörig gezählt
for word in re.findall(splitregex,file_string):
# s.o.
word = word.strip()
# entfernt ggf.vorhandenes Whitespace
www_text.write(word)
# speichert das Wort in die neue Datei
www_text.write('\n')
# fügt nach jedem Wort einen Zeilenumbruch ein
www_text.close() # schließt das filehandle
#h)
def dreißig_häufige():
www_text = open('www.txt', 'r')
# öffnet die zuvor geschriebene Datei zum Lesen
splitregex = re.compile(r'\w+')
# matched alle Wörter (da keine Zahlen mehr enthalten sind, kann \w benutzt werden)
frequenzliste = {}
# erstellt ein leeres Dictionary
german_stopwords = ['aber', 'als', 'am', 'an', 'auch', 'auf', 'aus', 'bei', 'bin', 'bis', 'bist', 'da', 'dadurch', 'daher', 'darum', 'das', 'daß', 'dass', 'dein', 'deine', 'dem', 'den', 'der', 'des', 'dessen', 'deshalb', 'die', 'dies', 'dieser', 'dieses', 'doch', 'dort', 'du', 'durch', 'ein', 'eine', 'einem', 'einen', 'einer', 'eines', 'er', 'es', 'euer', 'eure', 'für', 'hatte', 'hatten', 'hattest', 'hattet', 'hier hinter', 'ich', 'ihr', 'ihre', 'im', 'in', 'ist', 'ja', 'jede', 'jedem', 'jeden', 'jeder', 'jedes', 'jener', 'jenes', 'jetzt', 'kann', 'kannst', 'können', 'könnt', 'machen', 'mein', 'meine', 'mit', 'muß', 'mußt', 'musst', 'müssen', 'müßt', 'nach', 'nachdem', 'nein', 'nicht', 'nun', 'oder', 'seid', 'sein', 'seine', 'sich', 'sie', 'sind', 'soll', 'sollen', 'sollst', 'sollt', 'sonst', 'soweit', 'sowie', 'und', 'unser unsere', 'unter', 'vom', 'von', 'vor', 'wann', 'warum', 'was', 'weiter', 'weitere', 'wenn', 'wer', 'werde', 'werden', 'werdet', 'weshalb', 'wie', 'wieder', 'wieso', 'wir', 'wird', 'wirst', 'wo', 'woher', 'wohin', 'zu', 'zum', 'zur', 'über']
# eleganter ist es, die Stopwortlisten als txt Dokument zu speichern und dann im Programm zu öffnen und als Liste einzulesen; allerdings lässt sich das Programm dann nicht universell ausprobieren
english_stopwords = ['a','about','above','after','again','against','all','am','an','and','any','are','aren\'t','as','at','be','because','been','before','being','below','between','both','but','by','can\'t','cannot','could','couldn\'t','did','didn\'t','do','does','doesn\'t','doing','don\'t','down','during','each','few','for','from','further','had','hadn\'t','has','hasn\'t','have','haven\'t','having','he','he\'d','he\'ll','he\'s','her','here','here\'s','hers','herself','him','himself','his','how','how\'s','i','i\'d','i\'ll','i\'m','i\'ve','if','in','into','is','isn\'t','it','it\'s','its','itself','let\'s','me','more','most','mustn\'t','my','myself','no','nor','not','of','off','on','once','only','or','other','ought','our','ours ourselves','out','over','own','same','shan\'t','she','she\'d','she\'ll','she\'s','should','shouldn\'t','so','some','such','than','that','that\'s','the','their','theirs','them','themselves','then','there','there\'s','these','they','they\'d','they\'ll','they\'re','they\'ve','this','those','through','to','too','under','until','up','very','was','wasn\'t','we','we\'d','we\'ll','we\'re','we\'ve','were','weren\'t','what','what\'s','when','when\'s','where','where\'s','which','while','who','who\'s','whom','why','why\'s','with','won\'t','would','wouldn\'t','you','you\'d','you\'ll','you\'re','you\'ve','your','yours','yourself','yourselves']
# s.o.
for word in www_text:
# iteriert über die Zeilen, in denen jeweils ein Wort steht, von www_text
word = word.strip()
# entfernt Whitespace
word = word.lower()
# konvertiert das Wort in Kleinbuchstaben
if (word in frequenzliste):
frequenzliste[word] = frequenzliste[word] + 1
else:
frequenzliste[word] = 1
#s.o.
count = 0
# Zählvariable, um nachhalten zu können, wann 30 Wörter ausgegeben wurden
for wort, frequenz in sorted(frequenzliste.items(), key=lambda x: x[1], reverse=True):
# erstellt aus dem Dictionary eine nach dem Value sortierte Liste, die Tupel aus Wort und Frequenz enthält; darüber wird iteriert
if (count < 30 and wort not in german_stopwords and wort not in english_stopwords):
# überprüft ob noch nicht 30 Wörter ausgegeben wurden und das Wort in keiner der beiden Stopwortlisten vorkommt
print(wort) # gibt das wort aus
count = count+1 # erhöht den zähler
www_text.close()
# schließt das Filehandle
# Main Programm:
print ('Die Datei enthält',count_mails(spam),'Emails.')
# ruft die Funktion count_emails auf und gibt das Ergebnis aus
from_and_subject(spam) # ruft die Funktion from_and_subject auf
all_emails = extract_mails(spam)
# ruft die Funktion extract_mails auf und speichert das Ergebnis in der Variable all_emails
for mail, frequenz in sorted(all_emails.items(), key=lambda x: x[1]):
# iteriert über die Frequenzliste der sortierten E-Mails in sortierter Reihenfolge
print (mail, frequenz)
# gibt die E-Mail Adresse und ihre Häufigkeit aus
all_domains = extract_domains(spam)
# ruft die Funktion extract_domains auf und speichert das Ergebnis in der Variable all_domains
for domain, frequenz in sorted(all_domains.items(), key=lambda x: x[1]):
# iteriert über die Frequenzliste der sortierten Domains in sortierter Reihenfolge
print (domain, frequenz)
# gibt die Domain Adresse und ihre Häufigkeit aus
woerter_speichern(spam)
# ruft die Funktion worter_speichern au,f um eine Datei zu erzeugen, die alle Wörter in der Datei enthält
dreißig_häufige()
# ruft die Funktion dreißig_häufige auf um die dreißig häufigsten Worte aus der eben erzeugten Datei auszugeben