Archive for the ‘Programmierung’ Category.

Ordner anlegen mit Python und Excel

Für das Github-Repository der Vorträge von Dante e.V. Vereinstagungen habe ich heute eine Menge Unterordner nebst entsprechenden README-Dateien anlegen dürfen. Da die manuelle Anlage zu lange gedauert hätte (und Verschwendung wertvoller Lebenszeit bedeutet hätte), habe ich ein kleines Python-Skript genutzt, das sich die Daten aus einer Excel-Datei geholt hat.

Die Excel-Datei Daten.xlsx hatte dabei den folgenden Aufbau:

Mit dem folgenden Skript habe ich pro Jahr jeweils zwei Unterordner angelegt und die README-Datei jeweils mit dem passenden Titel versorgt. Man hätte es noch schöner schreiben können, für einen Quick und Dirty Hack war es aber mehr als ausreichend.

import pandas as pd
import os
 
df = pd.read_excel('Daten.xlsx')
 
for index, row in df.iterrows():
    jahr = str(row['Year'])
 
    f1 = jahr + '-Frühling'
    f2 = jahr + '-Herbst'
    spring = row['Spring']
    autumn = row['Autumn']
 
    try:
        if not os.path.exists(f1):
            os.makedirs(f1)
    except OSError:
        print ('Fehler bei Verzeichnis ' +  directory)
 
    with open(f1+'/README.md', 'wt') as file:
        file.write('# Vorträge der Dante e.V. Frühjahrstagung '+jahr + '\n\n')
        file.write('Datum: \n')
        file.write('Veranstaltungsort: ' + spring +'\n')
 
    try:
        if not os.path.exists(f2):
            os.makedirs(f2)
    except OSError:
        print ('Fehler bei Verzeichnis ' +  directory)
 
 
    with open(f2+'/README.md','wt') as file:
        file.write('# Vorträge der Dante e.V. Herbsttagung '+jahr + '\n\n')
        file.write('Datum: \n')
        file.write('Veranstaltungsort: ' + autumn +'\n')

Uwe

Uwe Ziegenhagen mag LaTeX und Python, auch gern in Kombination. Hat Dir dieser Beitrag geholfen und möchtest Du Dich dafür bedanken? Dann unterstütze doch vielleicht die Dingfabrik Köln e.V. mit einem kleinen Beitrag. Details zur Bezahlung findest Du unter Spenden für die Dingfabrik.

More Posts - Website

Python-Übungsaufgabe: MD5-Hashes

Hier eine Übungsaufgabe, die ich mir heute basierend auf https://www.programmieraufgaben.ch/aufgabe/baeckerei-b-rot/xyikp5d5 ausgedacht habe:

Eine Firma hat sich im Streit von ihrem alten Administrator getrennt und hat jetzt ein Problem. Das Passwort für das Lohnzahlungssystem hatte nur der Admin, man kann es nicht zurücksetzen und sollte es einmal falsch eingegeben werden, werden alle Daten der letzten zehn Jahre gelöscht.

Studentin Susanne, die gerade ein Praktikum bei der Firma macht, findet im Dateisystem des Rechners eine Datei, die einen MD5-Hash vom Passwort enthält. Zusätzlich ist bekannt, dass es sich beim Passwort um (verschiedene Fälle mit steigender Komplexität)

* eine vierstellige Zahl (Hash lautet \texttt{48c8c3963853fff20bd9e8bee9bd4c07})
* eine fünfstellige Zahl (Hash selbst ausdenken) oder
* eine sechsstellige Zahl oder
* einen String aus vier (oder fünf oder sechs) Ziffern und Kleinbuchstaben (super als Hausaufgabe!)

handelt. Schreiben Sie ein Programm, das das Passwort im Klartext auf Basis des MD5-Hash ausgibt.

Für die Bestimmung des MD5-Hash nutzen Sie eine passende Bibliothek, eine Implementierung des Algorithmus ist natürlich nicht notwendig.

Uwe

Uwe Ziegenhagen mag LaTeX und Python, auch gern in Kombination. Hat Dir dieser Beitrag geholfen und möchtest Du Dich dafür bedanken? Dann unterstütze doch vielleicht die Dingfabrik Köln e.V. mit einem kleinen Beitrag. Details zur Bezahlung findest Du unter Spenden für die Dingfabrik.

More Posts - Website

Zwei Aufgabenblätter auf einer Seite mit LaTeX

Für meine Studierenden erstelle ich diverse Übungsblätter, damit das Thema „Python“ etwas anschaulicher wird. Dazu nutze ich ein angepasstes LaTeX-Template, mit dem ich die Seite dupliziere und in verkleinerter Form auf das DIN A4-Blatt bringe.

%!TEX TS-program = Arara
% arara: pdflatex: {shell: yes}
% arara: pdflatex: {shell: yes}
% arara: clean: { extensions: [ log, aux, nav, out, snm, vrb, toc ] }
 
\documentclass[a4paper,ngerman,12pt]{exam} 
 
\usepackage{babel}
\usepackage[a4paper,top=2.5cm,bottom=3cm,left=2.5cm,right=2cm]{geometry}
\usepackage[T1]{fontenc}
\usepackage{booktabs}
\usepackage{graphicx}
\usepackage{csquotes}
\usepackage{paralist}
\usepackage[math]{iwona}
\usepackage{textcomp}
\usepackage{listings}
\usepackage{xcolor}
 
\pointpoints{Punkt}{Punkte}
\bonuspointpoints{Bonuspunkt}{Bonuspunkte}
\renewcommand{\solutiontitle}{\noindent\textbf{Lösung:}\enspace}
 
\chqword{Frage}   
\chpgword{Seite} 
\chpword{Punkte}   
\chbpword{Bonus Punkte} 
\chsword{Erreicht}   
\chtword{Gesamt}
 
\pagestyle{headandfoot}
\runningheadrule
 
%%%%%%%
\definecolor{hellgelb}{rgb}{1,1,0.8}
\definecolor{lightgelb}{rgb}{1,1,0.8}
\definecolor{colKeys}{rgb}{0,0,1}
\definecolor{colIdentifier}{rgb}{0,0,0}
\definecolor{colComments}{rgb}{1,0,0}
\definecolor{colString}{rgb}{0,0.5,0}
 
\usepackage{listings}
\lstset{%
    float=hbp,%
    basicstyle=\ttfamily\footnotesize, %
    identifierstyle=\color{colIdentifier}, %
    keywordstyle=\color{colKeys}, %
    stringstyle=\color{colString}, %
    commentstyle=\color{colComments}, %
    columns=flexible, %
    tabsize=2, %
    frame=single, %
    upquote=true,%
    extendedchars=true, %
    showspaces=false, %
    showstringspaces=false, %
    numbers=left, %
    numberstyle=\tiny, %
    breaklines=true, %
    backgroundcolor=\color{hellgelb}, %
    breakautoindent=true, %
    captionpos=b%
}
 
%%%%%%%%%%%%
\lstset{literate=%
    {Ö}{{\"O}}1
    {Ä}{{\"A}}1
    {Ü}{{\"U}}1
    {ß}{{\ss}}1
    {ü}{{\"u}}1
    {ä}{{\"a}}1
    {ö}{{\"o}}1
    {~}{{\textasciitilde}}1
}
 
 
 
\usepackage{pgfpages}                                 % <— load the package
\usepackage{atbegshi}
 
\newcommand{\twoonone}{% 
  \pgfpagesuselayout{2 on 1}[a4paper,landscape,border shrink=5mm] % <— set options
  % duplicate the content at shipout time
  \AtBeginShipout{%
    \pgfpagesshipoutlogicalpage{1}\copy\AtBeginShipoutBox%
    \pgfpagesshipoutlogicalpage{2}\box\AtBeginShipoutBox%
    \pgfshipoutphysicalpage%
  }}
 
 
 
\firstpageheader{WS~2018/2019}{Skriptsprachenprogrammierung}{Dr.~Uwe Ziegenhagen}
\runningheader{WS~2018/2019}{Skriptsprachenprogrammierung}{Dr.~Uwe Ziegenhagen}
\firstpagefooter{\today}{}{\thepage\,/\,\numpages}
\runningfooter{\today}{Mitte unten}{\thepage\,/\,\numpages}
 
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt}
 
 
\twoonone % two pages on one
 
\begin{document}
 
\vspace*{0.5cm}
\begin{center}
\huge\bfseries Arbeitsblatt 02: Datentypen
\end{center}
\vspace*{0.5cm}
 
\section*{Aufgaben}
 
\begin{questions}
\question Welche Datentypen kennen Sie in Python?
 
\begin{itemize}
	\item 
	\item 
	\item 
	\item 
	\item 
\end{itemize}
 
\question Erstellen Sie verschiedene Variablen mit unterschiedlichen Datentypen! Führen Sie verschiedene Grundrechenarten mit den Datentypen durch.
 
\question Satz des Pythagoras: Berechnen Sie mittels Python die Hypotenuse eines Dreiecks, dessen Katheten 3 und 4 Zentimeter lang sind. Prüfen Sie die Datentypen der Variablen mittels \texttt{type()} Funktion! Warum gibt es Unterschiede in den Typen?
 
\question Richten Sie einen String beliebiger Länge bei der Ausgabe auf der Kommandozeile rechtsbündig aus! Hinweise: Gehen Sie von einer Zeilenbreite von 60 Zeichen aus. Benutzen Sie die \texttt{len()} Funktion, um die Länge der Zeichenkette zu bestimmen.
 
\question Nutzen Sie die \texttt{int()}, \texttt{float()} und \texttt{str()} Funktion, um verschiedene Datentypen umzuwandeln!
 
\question Hier kommt ein Listing
 
\begin{lstlisting}[language={Python}]
def create_bruch():
    zahlen = list(range(1,13))
    zaehler = random.choice(zahlen)
    zahlen.remove(zaehler)
    nenner = random.choice(zahlen)
    return 1234
\end{lstlisting}
 
\end{questions}
 
\end{document}

Uwe

Uwe Ziegenhagen mag LaTeX und Python, auch gern in Kombination. Hat Dir dieser Beitrag geholfen und möchtest Du Dich dafür bedanken? Dann unterstütze doch vielleicht die Dingfabrik Köln e.V. mit einem kleinen Beitrag. Details zur Bezahlung findest Du unter Spenden für die Dingfabrik.

More Posts - Website

Adressen parsen mit Python und libpostal/pypostal

Beim letzten Treffen der PyCologne habe ich meinen Ansatz vorgestellt, um „Straße Hausnummer“ Kombinationen aus verschiedenen Ländern zu parsen. Jemand in der Gruppe gab mir dann den Hinweis auf libpostal und seine Python-Bindings.

Unter Windows habe ich es nicht zum Laufen bekommen, die Installationsroutine setzt noch diverse Compiler voraus. Unter Linux klappt die Installation, wenn man sich genau an die Anleitung unter https://github.com/openvenues/pypostal hält.

Dann kann man mittels parse_address() die Adressdaten verarbeiten.

(base) uwe@Micro:~$ python
Python 3.7.4 (default, Aug 13 2019, 20:35:49)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from postal.parser import parse_address
>>> parse_address("Meisenweg 1")
[('meisenweg', 'road'), ('1', 'house_number')]
>>> parse_address("10 Downing Street")
[('10', 'house_number'), ('downing street', 'road')]
>>> parse_address("10, Rue de Pommes Frites")
[('10', 'house_number'), ('rue de pommes frites', 'road')]
>>> parse_address("Am Geldspeicher 1, 12345 Entenhausen")
[('am geldspeicher', 'road'), ('1', 'house_number'), ('12345', 'postcode'), ('entenhausen', 'city')]
>>>

Uwe

Uwe Ziegenhagen mag LaTeX und Python, auch gern in Kombination. Hat Dir dieser Beitrag geholfen und möchtest Du Dich dafür bedanken? Dann unterstütze doch vielleicht die Dingfabrik Köln e.V. mit einem kleinen Beitrag. Details zur Bezahlung findest Du unter Spenden für die Dingfabrik.

More Posts - Website

Vortragsfolien zum Thema „TDD mit Python“

Hier die Folien einer Präsentation, die ich auf den Python-Stammtischen in Düsseldorf und Köln gehalten habe.

PyDDF-TDD-UweZiegenhagen.pdf

Uwe

Uwe Ziegenhagen mag LaTeX und Python, auch gern in Kombination. Hat Dir dieser Beitrag geholfen und möchtest Du Dich dafür bedanken? Dann unterstütze doch vielleicht die Dingfabrik Köln e.V. mit einem kleinen Beitrag. Details zur Bezahlung findest Du unter Spenden für die Dingfabrik.

More Posts - Website

Fake-Adressen in Python erstellen

Für eine Übungsaufgabe meiner Skriptsprachen-Vorlesung an der FOM in Köln benötigte ich eine große Menge an „Straße Hausnummer“ Kombinationen. Mit faker gibt es ein Python-Modul, das nicht nur diese Adressen, sondern auch Namen, E-Mail-Adressen, ISBNs, etc. für diverse Locales schnell erzeugen kann.

Den folgenden Code habe ich benutzt:

from faker import Faker
 
locales = ['de_DE', 'cs_CS', 'nl_NL', 'pl_PL', 'fr_FR', 'dk_DK', 'en_US']
 
with open('musteradressen.txt','wt', encoding='utf-8') as file:
    for i in locales:
        fake = Faker(i)
 
        for j in range(100):
            t = fake.address()
            print(t)
            if '\n' in t:
                t = t[:t.index('\n'):]
            file.write(t + '\n')

Da ich nur die Straßennamen mit Hausnummern benötigte, habe ich jeweils die PLZ und Ortsinformation zusammen mit dem Zeilenumbruch gelöscht.

Händisch wurden dann US-Schiffsangaben und Unit/PO-BOX Angaben gelöscht.

Uwe

Uwe Ziegenhagen mag LaTeX und Python, auch gern in Kombination. Hat Dir dieser Beitrag geholfen und möchtest Du Dich dafür bedanken? Dann unterstütze doch vielleicht die Dingfabrik Köln e.V. mit einem kleinen Beitrag. Details zur Bezahlung findest Du unter Spenden für die Dingfabrik.

More Posts - Website

Und() und Oder() in Excel-Formeln nutzen

Hier ein anschauliches Beispiel für die Nutzung der Und() und Oder() Formel in Excel.

Gesucht werden die Zeilen, in denen Spalte A gleiche Werte aufweist, in Spalte B jedoch nicht.

Die Lösung dafür liegt in einer verschachtelten Und()/Oder() Funktion, schauen wir uns das mal für die Zeile 6 an:

Ich suche die Zeilen, in denen der Wert von Spalte A (also A6) dem Wert der vorigen Zeile (also A5) entspricht UND gleichzeitig der Wert aus Spalte B nicht dem Wert aus der vorigen Zelle entspricht.

Dies resultiert in der Formel: UND(A6=A5;B6<>B5)

Ich muss jedoch nicht nur die vorherige Zeile prüfen, sondern auch die folgende. Analog Prüfung auf die vorherige Zeile ergibt sich: UND(A6=A7;B6<>B7)

Da ich die Zeilen suche, in der die eine oder die andere Bedingung gilt, verpacke ich die beiden Formeln in eine Oder() Funktion: =ODER(UND(A6=A5;B6<>B5);UND(A6=A7;B6<>B7)). Das Oder() ist dabei nicht exklusiv, es können auch beide Teile WAHR ergeben, damit die Oder() Funktion ein WAHR zurückgibt. (Für unseren Zweck ist das egal, bei drei in Spalte A gleichen/in Spalte B ungleichen Zeilen könnte das einen Unterschied machen)

Uwe

Uwe Ziegenhagen mag LaTeX und Python, auch gern in Kombination. Hat Dir dieser Beitrag geholfen und möchtest Du Dich dafür bedanken? Dann unterstütze doch vielleicht die Dingfabrik Köln e.V. mit einem kleinen Beitrag. Details zur Bezahlung findest Du unter Spenden für die Dingfabrik.

More Posts - Website

Aufgaben zum Bruchrechnen erstellen mit LaTeX und Python

Hier ein kurzes Beispiel, wie man mit Python eine TeX-Datei mit vielen Brüchen erzeugen kann. Nützlich, wenn Kinder Brüche kürzen oder erweitern sollen. In der nächsten Zeit werde ich sicher noch entsprechende Anpassungen für das Rechnen mit Brüchen hinzufügen.

EDIT: Erweitert um das Löschen der Hilfsdateien.

import os
import random
 
 
head = """
\\documentclass[14pt, twocolumn]{scrartcl}
\\usepackage[utf8]{inputenc}
\\usepackage[T1]{fontenc}
\\pagestyle{empty}
 
\\begin{document}
 
\\begin{itemize}"""
 
foot = """
\\end{itemize}
\\end{document}
"""
 
def create_bruch():
    zahlen = list(range(1,13))
    zaehler = random.choice(zahlen)
    zahlen.remove(zaehler)
    nenner = random.choice(zahlen)
    return '\\item \\( \\frac{'+ str(zaehler) + '}{' + str(nenner) + '} \\)\\vspace{1em}'
 
 
with open("Brueche.tex", "w") as document:
    document.write(head);
    for i in range(32):
        document.write(create_bruch());
    document.write(foot);
    document.close();
 
os.system("pdflatex Brueche.tex")
os.unlink("Brueche.log")
os.unlink("Brueche.aux")
os.unlink("Brueche.tex")

Brueche

Uwe

Uwe Ziegenhagen mag LaTeX und Python, auch gern in Kombination. Hat Dir dieser Beitrag geholfen und möchtest Du Dich dafür bedanken? Dann unterstütze doch vielleicht die Dingfabrik Köln e.V. mit einem kleinen Beitrag. Details zur Bezahlung findest Du unter Spenden für die Dingfabrik.

More Posts - Website

Slides for my TUG 2019 presentations in Palo Alto

This year I was able to visit the TUG 2019 meeting in Palo Alto, California. I gave two talks, one on LaTeX & Python, the other one on the creation of exams using the exam class. Find below the slides, all sources are included in the PDF and accessible at least via Adobe Reader.

Uwe

Uwe Ziegenhagen mag LaTeX und Python, auch gern in Kombination. Hat Dir dieser Beitrag geholfen und möchtest Du Dich dafür bedanken? Dann unterstütze doch vielleicht die Dingfabrik Köln e.V. mit einem kleinen Beitrag. Details zur Bezahlung findest Du unter Spenden für die Dingfabrik.

More Posts - Website

Kredit-Tilgungspläne mit Python und numpy/pandas erstellen

Als der Kauf unserer Wohnung anstand, wollte ich die entsprechende Angebote der Banken nachrechnen und habe mir ein Python-Skript geschrieben, das die entsprechenden Berechnungen vornimmt. Berücksichtigt werden dabei auch Sondertilgungen im Dezember eines Jahres sowie eine Wartezeit von n Jahren ohne Sondertilgung.

Bei Fragen dazu fragt mich ruhig per E-Mail an @gmail.com

Hier jetzt das Skript:

# -*- coding: utf-8 -*-
 
import pandas as pd
import numpy as np
 
 
def berechne_jaehrliche_Annuitaet(kreditsumme, nominalzins_prozent, tilgungssatz_prozent):
    """ Berechnet die _jährliche_ Annuität.
        Jährliche_Rate = (nominalzins + tilgungssatz) * Kreditsumme
        Quelle: https://de.wikipedia.org/wiki/Annuit%C3%A4tendarlehen
    """ 
 
    zinssatz = nominalzins_prozent / 100
    tilgung = tilgungssatz_prozent / 100
    return round(kreditsumme * (zinssatz + tilgung), 2)
 
 
def berechne_monatliche_Annuitaet(kreditsumme, nominalzins_prozent, tilgungssatz_prozent):
    """ Berechnet die _monatliche_ Annuität.
        Jährliche_Rate = (nominalzins + tilgungssatz) * Kreditsumme
        Monatliche_Rate = Jährliche_Rate / 12
    """ 
 
    zinssatz = nominalzins_prozent / 100
    tilgung = tilgungssatz_prozent / 100
    return round(kreditsumme * (zinssatz + tilgung) / 12, 2)
 
def tilgungsplan_df(kreditsumme, nominalzins_prozent, tilgungssatz_prozent, sondert, wartezeit, monate):
    """ 
        Gibt DataFrame der monatlichen Tilgungen zurück
 
        "monate" für wieviele Monate wird der Tilgungsplan erstellt
        "sondert" Betrag der jährlichen Sondertilgung
        "wartezeit" Anzahl der Jahre ohne Sondertilgung
    """
 
    df = pd.DataFrame()
    restschuld = kreditsumme # Am Anfang entspricht die Restschuld der Kreditsumme
    zinssatz = nominalzins_prozent / 100
    tilgung = tilgungssatz_prozent / 100
 
    annuitaet = berechne_monatliche_Annuitaet(kreditsumme, nominalzins_prozent, tilgungssatz_prozent)
    zinsen = 0
 
    for j in range(1,monate+1):
        # Split der Annuität in ihre Komponenten Zinslast und Tilgung
        zinsen = restschuld * zinssatz / 12 
        # Wenn Restschuld kleiner Annuität, dann wird die komplette 
        # Restschuld getilgt
        tilgung = restschuld if restschuld < annuitaet else annuitaet - zinsen    
 
        anfangsschuld = restschuld
        jahr = ((j-1) // 12) + 1 # in welchem Monat befinden wir uns
 
        # Sondertilgungen im Dezember eines Jahres, wenn wir 
        # nicht in der Wartezeit sind
        if j % 12 == 0 and anfangsschuld > 0 and jahr > wartezeit:
            sondertilgung = sondert
        else:
            sondertilgung = 0
 
        # Restschuld_neu = Restschuld_alt minus Tilgung minus Sondertilgung
        restschuld = restschuld - tilgung - sondertilgung
 
        # Dataframe befüllen
        df = df.append({'Monat': j, 'Jahr': jahr,'Anfangsschuld': anfangsschuld, 
        'Zinsen':zinsen, 'Tilgung': tilgung, 'Sondertilgung': sondertilgung,
        'Restschuld': restschuld}, ignore_index=True)    
 
    # Indikatorspalte, "1" wenn der Kredit noch nicht abbezahlt ist, sonst "0"
    df['Indikator'] = np.where(df['Anfangsschuld']>0, 1, 0)
    # Umsortieren der Spalten
    df = df[['Monat', 'Jahr', 'Anfangsschuld', 'Zinsen', 'Tilgung', 'Sondertilgung', 'Restschuld', 'Indikator']]
 
    # Runden auf 2 Nachkommastellen
    for i in ['Anfangsschuld', 'Zinsen', 'Tilgung', 'Restschuld']:
        df[i] = df[i].apply(lambda x: round(x, 2))    
 
    # Monat als Index nutzen
    df.set_index('Monat', inplace=True)
    return df
 
print(berechne_jaehrliche_Annuitaet(200000, 2.0, 3.0), 'jährliche Annuität')
print(berechne_monatliche_Annuitaet(200000, 2.0, 3.0), 'monatliche Annuität')
 
tilgungsplan = tilgungsplan_df(200000, 2.0, 3.0, 5000, 0, 200)
#Wie lange läuft der Kredit
print('Gesamtlaufzeit:', round(tilgungsplan['Indikator'].sum(),1), 'Monate')
 
tilgungsplan.to_excel('tilgungsplan_gesamt.xlsx')

Uwe

Uwe Ziegenhagen mag LaTeX und Python, auch gern in Kombination. Hat Dir dieser Beitrag geholfen und möchtest Du Dich dafür bedanken? Dann unterstütze doch vielleicht die Dingfabrik Köln e.V. mit einem kleinen Beitrag. Details zur Bezahlung findest Du unter Spenden für die Dingfabrik.

More Posts - Website