Author Archive

Erste Schritte mit Python und Qt 5

Hier ein einfaches Beispiel, wie man mit Python und Qt 5 Desktop-Anwendungen bauen kann. Ich persönlich nutze Anaconda3, hier ist alles bei, was man dafür braucht.

Im Qt Designer (unter Anaconda3\Library\bin) erstellen wir ein neues GUI auf Basis von „Main Window“ und setzen einen Button und ein Label rauf. Das ganze wird dann abgespeichert, anschließend erstellen wir den notwendigen Python-Code.

# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5 import uic
 
Ui_MainWindow, QtBaseClass = uic.loadUiType('test.ui')
 
class MyApp(QMainWindow):
    def __init__(self):
        super(MyApp, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.pushButton.clicked.connect(self.changeLabel)
 
    def changeLabel(self):
        self.ui.label.setText('Hello World')
 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())

Uwe

Uwe Ziegenhagen likes LaTeX and Python, sometimes even combined. Do you like my content and would like to thank me for it? Consider making a small donation to my local fablab, the Dingfabrik Köln. Details on how to donate can be found here Spenden für die Dingfabrik.

More Posts - Website

Daten arrangieren mit pandas melt

Hier ein kurzes Beispiel, wie man mittels melt bestimmte Daten in die richtige Form bekommt.

Ausgangspunkt ist der folgende Datensatz:

Zum Auswerten ist der nicht optimal, ich möchte die Monatswerte gern untereinander haben. Mittels melt geht das ganz einfach:

# -*- coding: utf-8 -*-
 
import pandas as pd
 
data = pd.read_excel('meltdata.xlsx')
 
print(data.shape[1], 'columns and', data.shape[0], 'rows')
 
print(list(data))
 
melted = pd.melt(data, id_vars=['Name', 'ColumnB', 'ColumnC'], 
                 value_vars=['Januar', 'Februar', 'März', 'April', 'Mai', 
                 'Juni', 'Juli', 'August', 'September', 'Oktober', 
                 'November', 'Dezember'])
 
print(melted)
      Name    ColumnB ColumnC   variable  value
0 Donald 1978-09-03 Hello Januar 98
1 Micky 1945-05-04 World Januar 29
2 Minnie 1946-07-05 Foo Januar 57
3 Pluto 1998-07-08 Bar Januar 28
4 Donald 1978-09-03 Hello Februar 31
5 Micky 1945-05-04 World Februar 41
6 Minnie 1946-07-05 Foo Februar 24
...

Uwe

Uwe Ziegenhagen likes LaTeX and Python, sometimes even combined. Do you like my content and would like to thank me for it? Consider making a small donation to my local fablab, the Dingfabrik Köln. Details on how to donate can be found here Spenden für die Dingfabrik.

More Posts - Website

LaTeX-Dateien vergleich mit latexdiff

latexdiff ist Bestandteil von TeX Live und erlaubt es, die Unterschiede zwischen zwei LaTeX-Dateien hervorzuheben. Hier ein Beispiel mit einem kurzen Textschnipsel aus der Wikipedia:

Das Original (Giraffe1.tex)

\documentclass[12pt,ngerman]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{babel}
\usepackage{csquotes}
\begin{document}
 
Die Giraffen (Giraffa) sind eine Gattung der Säugetiere aus der Ordnung der Paarhufer. Ursprünglich wurden ihr mit Giraffa camelopardalis und der Trivialbezeichnung \enquote{Giraffe} nur eine einzige Art zugewiesen. Molekulargenetische Untersuchungen aus dem Jahr 2016 zeigen jedoch, dass die Gattung wenigstens vier Arten mit sieben eigenständigen Populationen umfasst. Die Giraffen stellen die höchsten landlebenden Tiere der Welt. Zur Unterscheidung vom verwandten Okapi (sogenannte \enquote{Waldgiraffe}) werden sie auch als Steppengiraffen bezeichnet.
 
\end{document}

Eine Version mit leichten Änderungen (Giraffe2.tex)

\documentclass[12pt,ngerman]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{babel}
\usepackage{csquotes}
\begin{document}
 
Die Giraffen (Giraffa) sind eine Gattung der Säugetiere aus der Ordnung der Paarhufer. Ursprünglich wurden ihr mit Giraffa camelopardalis und der Trivialbezeichnung \enquote{Giraffe} nur eine einzige Art zugewiesen. Untersuchungen aus dem Jahr 2016 zeigten jedoch, dass die Gattung wenigstens 4 Arten mit 7 eigenständigen Populationen umfasst. Die Giraffen stellen die höchsten landlebenden Tiere der Welt. Zur Unterscheidung vom verwandten Okapi (der sogenannten \enquote{Waldgiraffe}) werden sie auch als Steppengiraffen bezeichnet.
 
\end{document}

Auf der Kommandozeile ruft man jetzt auf latexdiff Giraffe1.tex Giraffe2.tex > Giraffediff.tex und übersetzt die neu erzeugte Datei nach PDF, das dann wie folgt aussieht:

Uwe

Uwe Ziegenhagen likes LaTeX and Python, sometimes even combined. Do you like my content and would like to thank me for it? Consider making a small donation to my local fablab, the Dingfabrik Köln. Details on how to donate can be found here Spenden für die Dingfabrik.

More Posts - Website

Auto-Documenting Python Code

A while ago I thought about auto-documenting Python code, here’s what resulted from those experiments. (It’s far away from production quality, so use at your own risk)#

Let’s assume we have a Python file without docstrings:

class HalloWelt:
 
	def Hallo(welt):
		return welt
 
 
print(HalloWelt.Hallo("Welt"))

My experimental Python code:

import re
 
class Dokumenter:
	"""
	Fügt einer bestehenden Python-Datei Docstrings hinzu, falls keine vorhanden sind.
	"""
 
	def dokumentme(filename):
		print(">> Prüfe",filename,"auf Docstrings\n")
 
		with open(filename+"_bak", 'w') as outfile:
			with open(filename, 'r') as infile:
				rowIter= iter(infile)
				for row in rowIter:
					# schreibe die Zeile auf jeden Fall in die Zieldatei
					outfile.write(row)
					# Ist in der Zeile ein 'def ' vorhanden?
					if "def " in row:
						# suche erstes Zeichen, das kein Docstring ist
						index = re.search('\S', row).start()
						whitespace = row[:index]
						whitespaceLen = len(whitespace)
						if " " in whitespace:
							blanks = True
						else:
							blanks = False					
						print(whitespaceLen,blanks)	
 
 
						print(">> Funktionsdefinition gefunden")
						print(">> Schreibe Docstring")
						print(">> Whitespaces",index)
						outfile.write('"""\nHallo Welt\n"""\n')
					print(row)
 
Dokumenter.dokumentme("dokme.py")
# Tests, Datei mit und ohne Dokstring,unterschiedliche Einrückungstiefe
# extrahiere die Parameter

Output:

class HalloWelt:
 
	def Hallo(welt):
"""
Hallo Welt
"""
		return welt
 
 
print(HalloWelt.Hallo("Welt"))

Uwe

Uwe Ziegenhagen likes LaTeX and Python, sometimes even combined. Do you like my content and would like to thank me for it? Consider making a small donation to my local fablab, the Dingfabrik Köln. Details on how to donate can be found here Spenden für die Dingfabrik.

More Posts - Website

Sichere (deutsche) Passwörter mit Python und xkcdpass

Menschen sind schlecht darin, sich gute lange Passwörter zu merken. Computer sind dafür prädestiniert, schlechte (weil kurze) Passwörter zu knacken. Randall Munroe hat das in einem recht bekannten XKCD Comic dargestellt.

Mit xkcdpass (Link) gibt es ein Python-Modul zur Erstellung von Passwörtern nach dem „xkcd-Schema“, das sich mittels pip install xkcdpass einfach installieren lässt.

Startet man xkcdpass ohne weitere Parameter, so spuckt es einfach eine Reihe englischer Wörter aus:

C:\Users\Uwe>xkcdpass
tackle tonsorial satisfied gecko fission decor

Um xkcdpass die Ausgabe deutscher Passwörter beizubringen, geht man wie folgt vor.

1) Mittels --help Parameter kommt man an die Liste aller Optionen, hier ist besonders -w für die Angabe der Wortdatei spannend.

C:\Users\Uwe>xkcdpass --help
usage: xkcdpass [-h] [-w WORDFILE] [--min MIN_LENGTH] [--max MAX_LENGTH]
                [-n NUM_WORDS] [-i] [-v VALID_CHARS] [-V] [-a ACROSTIC]
                [-c COUNT] [-d DELIM] [--allow-weak-rng]

optional arguments:
  -h, --help            show this help message and exit
  -w WORDFILE, --wordfile WORDFILE
                        Specify that the file WORDFILE contains the list of
                        valid words from which to generate passphrases.
  --min MIN_LENGTH      Generate passphrases containing at least MIN_LENGTH
                        words.
  --max MAX_LENGTH      Generate passphrases containing at most MAX_LENGTH
                        words.
  -n NUM_WORDS, --numwords NUM_WORDS
                        Generate passphrases containing exactly NUM_WORDS
                        words.
  -i, --interactive     Generate and output a passphrase, query the user to
                        accept it, and loop until one is accepted.
  -v VALID_CHARS, --valid-chars VALID_CHARS
                        Limit passphrases to only include words matching the
                        regex pattern VALID_CHARS (e.g. '[a-z]').
  -V, --verbose         Report various metrics for given options.
  -a ACROSTIC, --acrostic ACROSTIC
                        Generate passphrases with an acrostic matching
                        ACROSTIC.
  -c COUNT, --count COUNT
                        Generate COUNT passphrases.
  -d DELIM, --delimiter DELIM
                        Separate words within a passphrase with DELIM.
  --allow-weak-rng      Allow fallback to weak RNG if the system does not
                        support cryptographically secure RNG. Only use this if
                        you know what you are doing.

2) Man besorgt sich eine Datei mit dem deutschen Wortschatz, per Google bin ich auf die folgende Seite der Uni Leipzig gestoßen: http://wortschatz.uni-leipzig.de/html/wliste.html. Hier gibt es Listen für die häufigsten 100, 1000 und 10’000 Wörter der deutschen Sprache (sowie auch für französisch, englisch und niederländisch). Die Liste mit den 10’000 häufigsten Wörtern speichern wir ab.

Ein Hinweis noch zur sprachlichen Einschätzung der 10000 Wörter: Der Duden geht davon aus, dass ein durchschnittlicher Deutsch-Sprecher zwischen 12’000 und 16’000 Wörter spricht, aber rund 50’000 deutsche Worte versteht.

3) Mit der Wortschatzdatei auf der Festplatte können wir jetzt einfach wieder xkcdpass aufrufen und nutzen gleich noch -c 10 für die Erzeugung von 10 Zeilen mit jeweils sechs Passwörtern:

C:\Users\Uwe>xkcdpass -c 10 -w e:\top10000de.txt
Munition Alexander Bernhard Wissen Erstmals geraumer
wissen genießt wenigen Verlierer wunderbar Teufel
Wiesen Hartmut länger römische älter Stimme
irgendwie Monitor operative läuft Vertrieb Optionen
Stahl Brust Polizei Hoffnung Verlauf runden
Ärzte Mafia Dieter Pakistan Systems Areal
trieb hinweg Kanzlers unterlag zweimal zuviel
vollzogen Sparen zwölf verlieren Dutzende Länge
Infotyp beliebten gewisser Malerei gefunden Blätter
Peking äußerten fährt Einblick Interesse schwach

Uwe

Uwe Ziegenhagen likes LaTeX and Python, sometimes even combined. Do you like my content and would like to thank me for it? Consider making a small donation to my local fablab, the Dingfabrik Köln. Details on how to donate can be found here Spenden für die Dingfabrik.

More Posts - Website

Mit Python rekursiv Verzeichnisse auswerten

Hier ein kurzer Code-Schnipsel (basierend auf https://www.tutorialspoint.com/python/os_walk.htm), der Verzeichnisse rekursiv durchläuft und jeweils den kompletten Pfad in einem pandas DataFrame speichert. Dateien werden ignoriert, dies kann durch die Überarbeitung des „pass“ Teils angepasst werden.

import os
import sys
import pandas as pd
 
paths = pd.DataFrame(columns={'Path'})
 
rootdir = 'somepath’
 
for root, directories, filenames in os.walk(rootdir):
    for directory in directories:
        paths = paths.append({'Path':(os.path.join(root, directory)).replace('\\','/')},ignore_index=True)
    for filename in filenames:
        pass
 
paths.to_clipboard()

Uwe

Uwe Ziegenhagen likes LaTeX and Python, sometimes even combined. Do you like my content and would like to thank me for it? Consider making a small donation to my local fablab, the Dingfabrik Köln. Details on how to donate can be found here Spenden für die Dingfabrik.

More Posts - Website

Example for pandas Merge

Here’s an example for the merge capabilities of pandas, which allow the user to work with DataFrames just like in SQL.

import pandas as pd
 
dfA = pd.DataFrame({'A': ['A0','A1','A2','A3'], 'Key': ['K0','K1','K2','K4']})
dfB = pd.DataFrame({'B': ['B0','B1','B2','B3'], 'Key': ['K0','K1','K2','K5']})
 
print('\nDaten\n')
print(dfA,'\n')
 
print(dfB,'\n')
 
dfInner = dfA.merge(dfB,how='inner',left_on='Key',right_on='Key')
 
print('Inner:\n', dfInner, '\n')
 
dfLeft = dfA.merge(dfB,how='left',left_on='Key',right_on='Key')
 
print('Left:\n', dfLeft, '\n')
 
dfRight = dfA.merge(dfB,how='right',left_on='Key',right_on='Key')
 
print('Right:\n', dfRight, '\n')
 
dfOuter = dfA.merge(dfB,how='outer',left_on='Key',right_on='Key')
 
print('Outer:\n', dfOuter, '\n')

Uwe

Uwe Ziegenhagen likes LaTeX and Python, sometimes even combined. Do you like my content and would like to thank me for it? Consider making a small donation to my local fablab, the Dingfabrik Köln. Details on how to donate can be found here Spenden für die Dingfabrik.

More Posts - Website

Time in Python

A short summary on Python’s timestamps:

import datetime
 
now = datetime.datetime.now()
 
print(now.strftime('%Y-%m-%d %H:%M'))
print(now.isoformat())

From the module’s documentation:

Directive Meaning
%a Locale’s abbreviated weekday name.
%A Locale’s full weekday name.
%b Locale’s abbreviated month name.
%B Locale’s full month name.
%c Locale’s appropriate date and time
representation.
%d Day of the month as a decimal number [01,31].
%H Hour (24-hour clock) as a decimal number
[00,23].
%I Hour (12-hour clock) as a decimal number
[01,12].
%j Day of the year as a decimal number [001,366].
%m Month as a decimal number [01,12].
%M Minute as a decimal number [00,59].
%p Locale’s equivalent of either AM or PM.
%S Second as a decimal number [00,61].
%U Week number of the year (Sunday as the first
day of the week) as a decimal number [00,53].
All days in a new year preceding the first
Sunday are considered to be in week 0.
%w Weekday as a decimal number [0(Sunday),6].
%W Week number of the year (Monday as the first
day of the week) as a decimal number [00,53].
All days in a new year preceding the first
Monday are considered to be in week 0.
%x Locale’s appropriate date representation.
%X Locale’s appropriate time representation.
%y Year without century as a decimal number
[00,99].
%Y Year with century as a decimal number.
%z Time zone offset indicating a positive or
negative time difference from UTC/GMT of the
form +HHMM or -HHMM, where H represents decimal
hour digits and M represents decimal minute
digits [-23:59, +23:59].
%Z Time zone name (no characters if no time zone
exists).
%% A literal '%' character.

Uwe

Uwe Ziegenhagen likes LaTeX and Python, sometimes even combined. Do you like my content and would like to thank me for it? Consider making a small donation to my local fablab, the Dingfabrik Köln. Details on how to donate can be found here Spenden für die Dingfabrik.

More Posts - Website

Slides from my 2016 Froscon Presentation „Using Python for Scientific Research“

Here are my slides from the Froscon 2016 presentation „Using Python for Scientific Research“.

Slides: Froscon_Slides_2016

Video: Video Recording (The screen was flickering most of the time, pretty annoying and distracting)

I will continously update and expand this presentation during the next months, if you want to receive updates follow the GitHub repository: https://github.com/UweZiegenhagen/2016-Python-Data-Analysis-Slides/

Uwe

Uwe Ziegenhagen likes LaTeX and Python, sometimes even combined. Do you like my content and would like to thank me for it? Consider making a small donation to my local fablab, the Dingfabrik Köln. Details on how to donate can be found here Spenden für die Dingfabrik.

More Posts - Website

Parsing Emacs Orgmode files with Python

Here’s some experimental (alpha) code to parse Emacs Orgmode files. It’s far from complete, I only aim at parsing basic TODO strings with level (**), status (TODO, DONE), priority (#A, #B, #C), task and tags.

2016-09-03: It takes my actual orgmode file, so it’s working fine.

2016-09-04: I created a github repo, code updates will be added there, only: https://github.com/UweZiegenhagen/python-orgmode-parser

# -*- coding: utf-8 -*-
import re
 
def parseEmaceOrgmode(s):
    r = '^([\*]+)?\s?(TODO|PROGRESSING|FEEDBACK|VERIFY|POSTPONED|DELEGATED|CANCELLED|DONE)?\s?(\[#[A|B|C]\])?\s?(.*?)\s*(:(.*):)?$'    
    m = re.search(r,s)
    level = m.group(1)
    if (level is not None):
        level = len(level)
    prio = m.group(3)
    if (prio is not None):
        prio = prio[2:3]
    tags = []
    a = m.group(5)
    if a != None:
        b = len(a)-1
        a= a[1:b]
        a = a.split(':')
    tags.append(a)
    return(level, m.group(2), prio, m.group(4), tags)
 
with open("../orgmode.org", "r") as ins:
    for line in ins:
        level, status, priority, task, tags = parseEmaceOrgmode(line)
        if level is not None:        
            print('Level:', level)
            print('Status:', status)
            print('Priority:', priority)
            print('Task:', task)
            print('Tags:',tags,'\n\n')

Uwe

Uwe Ziegenhagen likes LaTeX and Python, sometimes even combined. Do you like my content and would like to thank me for it? Consider making a small donation to my local fablab, the Dingfabrik Köln. Details on how to donate can be found here Spenden für die Dingfabrik.

More Posts - Website