2021-02-14, 13:09
Hier ein einfaches Beispiel, wie man mit Python und LaTeX ein PDF mit Kursinformationen erstellen kann.
Zuerst der Python-Teil, der die Apple-Kursdaten seit dem 1.1.2021 in einen Dataframe lädt und dann in eine LaTeX-Tabelle schreibt:
import pandas
import pandas_datareader.data as web
YAHOO_TODAY="http://download.finance.yahoo.com/d/quotes.csv?s=%s&f=sd1ohgl1vl1"
history = web.DataReader('AAPL', "yahoo", start="2021-1-1")
history.to_latex('aapl.tex') |
import pandas
import pandas_datareader.data as web
YAHOO_TODAY="http://download.finance.yahoo.com/d/quotes.csv?s=%s&f=sd1ohgl1vl1"
history = web.DataReader('AAPL', "yahoo", start="2021-1-1")
history.to_latex('aapl.tex')
Dann noch der LaTeX-Teil, der a) den Python-Code aus dem LaTeX-Lauf heraus ausführt und b) die erzeugte Tabellen-Datei nur dann einbindet, wenn sie wirklich auch erzeugt wurde.
\documentclass[12pt,ngerman]{scrartcl}
\usepackage[a4paper, top=1cm,bottom=1cm,left=1cm, right=1cm]{geometry}
\usepackage[T1]{fontenc}
\usepackage{booktabs}
\makeatletter
\newcommand{\testfileexists}[1]{%
\IfFileExists{#1}%
{\def\inputtestedfile{\@@input #1 }}
{\let\inputtestedfile\@empty}%
}
\makeatother
\begin{document}
\write18{python runpy.py}
\testfileexists{aapl}
\inputtestedfile
\end{document} |
\documentclass[12pt,ngerman]{scrartcl}
\usepackage[a4paper, top=1cm,bottom=1cm,left=1cm, right=1cm]{geometry}
\usepackage[T1]{fontenc}
\usepackage{booktabs}
\makeatletter
\newcommand{\testfileexists}[1]{%
\IfFileExists{#1}%
{\def\inputtestedfile{\@@input #1 }}
{\let\inputtestedfile\@empty}%
}
\makeatother
\begin{document}
\write18{python runpy.py}
\testfileexists{aapl}
\inputtestedfile
\end{document}
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
2021-01-17, 11:58
Hier ein Beispiel, wie man Bilder für eine Animation mit matplotlib erstellen kann, adaptiert von im Netz gefundenen Code
Der folgende Python-Code erzeugt 720 einzelne Bilder und legt diese im Dateisystem ab. Mittels magick -quality 100 *.png outputfile.mpeg
werden dann die Bilder zu einem MPEG-Video kombiniert. Hinweis: Nur unter Windows heißt der Befehl „magick“ da „convert“ auch ein Systemprogramm ist.
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from mpl_toolkits.mplot3d import Axes3D
df = sns.load_dataset('iris')
sns.set(style = "darkgrid")
fig = plt.figure()
fig.set_size_inches(16, 9)
ax = fig.add_subplot(111, projection = '3d')
x = df['sepal_width']
y = df['sepal_length']
z = df['petal_width']
ax.set_xlabel("sepal_width")
ax.set_ylabel("sepal_lesngth")
ax.set_zlabel("petal_width")
c = {'setosa':'red', 'versicolor':'blue', 'virginica':'green'}
ax.scatter(x, y, z,c=df['species'].apply(lambda x: c[x]))
for angle in range(0, 720):
ax.view_init((angle+1)/10, angle)
plt.draw()
plt.savefig('r:/'+str(angle).zfill(3)+'.png')
Eine kürzere Version der Animation habe ich unter https://www.youtube.com/watch?v=gdgvXpq4k1w abgelegt.
Hinweise zu anderen Konvertierungsprogrammen gibt es unter anderem hier: https://www.andrewnoske.com/wiki/Convert_an_image_sequence_to_a_movie
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
2021-01-16, 20:49
Ich habe heute auf einer meiner Linux-Maschinen Jupyter Notebook installiert. Um die — für die Arbeit im lokalen Netz lästigen — Sicherheitsabfragen zu umgehen, habe ich mir ausgehend von https://stackoverflow.com/questions/41159797/how-to-disable-password-request-for-a-jupyter-notebook-session ein kleines Startskript geschrieben:
#! /bin/bash
jupyter notebook --ip='*' --NotebookApp.token='' --NotebookApp.password='' |
#! /bin/bash
jupyter notebook --ip='*' --NotebookApp.token='' --NotebookApp.password=''
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
2021-01-16, 20:45
Mit cudf gibt es ein Paket, das pandas Datenstrukturen auf nvidia-Grafikkarten verarbeiten kann. Einen i7 3770 mit 24 GB RAM habe ich jetzt mit einer CUDA-fähigen Grafikkarte (Typ Quadro P400) ausgestattet, damit ich damit rumspielen arbeiten kann. Unter https://towardsdatascience.com/heres-how-you-can-speedup-pandas-with-cudf-and-gpus-9ddc1716d5f2 findet man passende Beispiele, diese habe ich in einem Jupyter-Notebook laufenlassen.

Ein Geschwindigkeitszuwachs ist erkennbar, insbesondere bei der Matrix-Größe aus dem verlinkten Beispiel war die CUDA-Variante mehr als 3x so schnell wie die CPU-Variante. Das Merge mit der vollen Matrix-Größe lief bei mir leider nicht, da limitieren vermutlich die 2 GB RAM, die die P400 bietet.
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
2021-01-09, 20:37
Hier ein einfaches Beispiel für einen Scatterplot mit Python und dem Seaborn Modul. Das Beispiel nutzt den bekannten Iris-Datensatz von R. Fisher, der gut für Klassifikationstechniken genutzt werden kann.
import seaborn as sns
iris=sns.load_dataset('iris')
sns.scatterplot(x=iris['sepal_width'],y=iris['sepal_length'],hue=iris['species']) |
import seaborn as sns
iris=sns.load_dataset('iris')
sns.scatterplot(x=iris['sepal_width'],y=iris['sepal_length'],hue=iris['species'])

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
2020-12-26, 18:46
Nachdem wir bereits mit Excel und VBA Platzhalter in CSV Dateien gesucht und mit Inhalten ersetzt haben heute das ganze mit Python und OpenPyxl.
Ausgangspunkt ist eine Exceldatei „python_test.xlsx“ mit einer Named Range „Felder“ im Tabellenblatt „Tabelle2“.

Mit der openpyxl
Bibliothek laden wir das Excel-Blatt und holen uns die Inhalte der Range in ein Dictionary. Jeden der Keys aus dem Dictionary suchen wir dann in der CSV Datei und ersetzen ihn gegen den Wert aus der Excel-Datei.
# -*- coding: utf-8 -*-
import openpyxl
path = "python_test.xlsx"
workbook = openpyxl.load_workbook(path)
def get_sheet_and_location(workbook, named_range):
x = list(workbook.defined_names['Felder'].destinations)[0]
return x[0], x[1].replace('$','').split(':')[0],x[1].replace('$','').split(':')[1]
sheet, start, stop = get_sheet_and_location(workbook,'Felder')
worksheet = workbook[sheet]
rng=worksheet[start:stop]
replacements = {}
for row in rng:
c1, c2 = row
replacements[c1.value] = c2.value
with open('Python_test.txt') as input_file:
text = input_file.read()
for key in replacements:
text = text.replace(key,str(replacements[key]))
with open('Python_test_output.txt','w') as output_file:
output_file.write(text) |
# -*- coding: utf-8 -*-
import openpyxl
path = "python_test.xlsx"
workbook = openpyxl.load_workbook(path)
def get_sheet_and_location(workbook, named_range):
x = list(workbook.defined_names['Felder'].destinations)[0]
return x[0], x[1].replace('$','').split(':')[0],x[1].replace('$','').split(':')[1]
sheet, start, stop = get_sheet_and_location(workbook,'Felder')
worksheet = workbook[sheet]
rng=worksheet[start:stop]
replacements = {}
for row in rng:
c1, c2 = row
replacements[c1.value] = c2.value
with open('Python_test.txt') as input_file:
text = input_file.read()
for key in replacements:
text = text.replace(key,str(replacements[key]))
with open('Python_test_output.txt','w') as output_file:
output_file.write(text)
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
2020-10-25, 07:43
Ausgehend von meinem ersten Artikel zu diesem Thema habe ich jetzt noch eine Erweiterung des Skripts vorgenommen. Als Spammer erkannte E-Mail-Adressen werden jetzt auch automatisch geblockt.
Dazu suche ich alle „Dauerhaft von der Liste verbannen“ Checkboxen — ihre Namen beginnen alle mit „ban-“ — und klicke sie.
from selenium.webdriver import Firefox
from selenium.webdriver.firefox.options import Options
from selenium.common.exceptions import NoSuchElementException
opts = Options()
browser = Firefox(executable_path=r"C:\geckodriver-v0.27.0\geckodriver.exe",
options=opts)
browser.implicitly_wait(3)
browser.get('<url>')
search_form = browser.find_element_by_name('adminpw')
search_form.send_keys('<password>')
search_form.submit()
try:
field = browser.find_element_by_name('discardalldefersp')
field.click()
browser.implicitly_wait(3)
submit = browser.find_element_by_name('submit')
submit.click()
except NoSuchElementException:
print('No new messages to be discarded')
browser.implicitly_wait(3)
fields = browser.find_elements_by_xpath("//input[@value='3']")
emails = browser.find_elements_by_xpath('//td[contains(text(),"@")]')
banfields = browser.find_elements_by_xpath('//input[contains(@name,"ban-")]')
if len(fields) == 0:
print('No new requests to be discarded, closing browser')
browser.close()
else:
if len(fields) == len(emails) and len(fields) == len(banfields) :
zipped_list = list(zip(emails, fields, banfields))
for i in zipped_list:
email, field, banfield = i
if not email.text.endswith(')'):
field.click()
banfield.click() |
from selenium.webdriver import Firefox
from selenium.webdriver.firefox.options import Options
from selenium.common.exceptions import NoSuchElementException
opts = Options()
browser = Firefox(executable_path=r"C:\geckodriver-v0.27.0\geckodriver.exe",
options=opts)
browser.implicitly_wait(3)
browser.get('<url>')
search_form = browser.find_element_by_name('adminpw')
search_form.send_keys('<password>')
search_form.submit()
try:
field = browser.find_element_by_name('discardalldefersp')
field.click()
browser.implicitly_wait(3)
submit = browser.find_element_by_name('submit')
submit.click()
except NoSuchElementException:
print('No new messages to be discarded')
browser.implicitly_wait(3)
fields = browser.find_elements_by_xpath("//input[@value='3']")
emails = browser.find_elements_by_xpath('//td[contains(text(),"@")]')
banfields = browser.find_elements_by_xpath('//input[contains(@name,"ban-")]')
if len(fields) == 0:
print('No new requests to be discarded, closing browser')
browser.close()
else:
if len(fields) == len(emails) and len(fields) == len(banfields) :
zipped_list = list(zip(emails, fields, banfields))
for i in zipped_list:
email, field, banfield = i
if not email.text.endswith(')'):
field.click()
banfield.click()
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
2020-10-04, 18:04
Vor einigen Monaten habe ich mir günstig auf Ebay ein Siemens Nixdorf BA 63 USB Display gekauft, das VFD (vacuum fluorescent display) Technologie für die Anzeige nutzt und 2×20 Zeichen bietet.
Als passendste Python-Bibliothek nutze ich https://github.com/stephanemouton/VFD-WCN, die Anleitung zur Einrichtung wird im github sehr gut beschrieben.
Hier der Quellcode, der die Ausgabe im Bild erzeugt:
from vfdpos import *
factory=WincorNixdorfDisplayFactory()
VFDs = factory.get_vfd_pos()
MyVFD = VFDs[0]
MyVFD.clearscreen()
MyVFD.poscur(1, 1)
MyVFD.write_msg("Hallo")
MyVFD.write_msg("Welt")
MyVFD.write_msg("1234567abcd\r")
MyVFD.poscur(2, 1)
MyVFD.write_msg("ABCDEFüäößi")
MyVFD.close()

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
2020-09-27, 17:55
Vermutlich ist es nicht so bekannt, dass man LaTeX-Pakete auch per REST-API auf CTAN hochladen kann. Das ist insbesondere dann praktisch, wenn man öfter Pakete aktualisieren muss, wie ich es beispielsweise mit der DTK Bibliografie mehrmals im Jahr mache.
Manfred Lotz vom CTAN-Team hat dazu ein Python-Skript geschrieben (https://gitlab.com/Lotz/pkgcheck/blob/master/ctan_upload.py), das diese API befüttert.
Ich habe sein Skript noch ein wenig angepasst (ich erstelle auch die ZIP-Datei damit und kopiere die richtigen Dateien an ihren Platz), mein Skript findet ihr im Github unter https://github.com/dante-ev/dtk-bibliography/blob/master/pack_and_upload_to_ctan.py. Für den Upload selbst benötigt man noch eine TOML-Datei, in der die Upload-Informationen als Key-Value-Paare stehen. Ein Beispiel für eine solche TOML-Datei findet ihr bei Manfred unter https://gitlab.com/Lotz/pkgcheck/-/blob/master/pkgcheck.toml.
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
2020-09-26, 19:53
Hier ein kurzes Beispiel, wie man mit Python-Modulen Dateien kopieren, zippen und löschen kann.
import zipfile
from shutil import copyfile
from os import unlink
# copy file
copyfile('dtk-authoryear.bbx' , './dtk-bibliography/dtk-authoryear.bbx')
copyfile('dtk-authoryear.dbx' , './dtk-bibliography/dtk-authoryear.dbx')
copyfile('dtk-bibliography.pdf', './dtk-bibliography/dtk-bibliography.pdf')
copyfile('dtk-bibliography.tex', './dtk-bibliography/dtk-bibliography.tex')
# create the zip file
with zipfile.ZipFile('dtk-bibliography.zip', 'w', zipfile.ZIP_DEFLATED) as z:
z.write('./dtk-bibliography/README.md')
z.write('./dtk-bibliography/dtk-authoryear.bbx')
z.write('./dtk-bibliography/dtk-authoryear.dbx')
z.write('./dtk-bibliography/dtk-bibliography.pdf')
z.write('./dtk-bibliography/dtk-bibliography.tex')
# delete copied files
unlink('./dtk-bibliography/dtk-authoryear.bbx')
unlink('./dtk-bibliography/dtk-authoryear.dbx')
unlink('./dtk-bibliography/dtk-bibliography.pdf')
unlink('./dtk-bibliography/dtk-bibliography.tex') |
import zipfile
from shutil import copyfile
from os import unlink
# copy file
copyfile('dtk-authoryear.bbx' , './dtk-bibliography/dtk-authoryear.bbx')
copyfile('dtk-authoryear.dbx' , './dtk-bibliography/dtk-authoryear.dbx')
copyfile('dtk-bibliography.pdf', './dtk-bibliography/dtk-bibliography.pdf')
copyfile('dtk-bibliography.tex', './dtk-bibliography/dtk-bibliography.tex')
# create the zip file
with zipfile.ZipFile('dtk-bibliography.zip', 'w', zipfile.ZIP_DEFLATED) as z:
z.write('./dtk-bibliography/README.md')
z.write('./dtk-bibliography/dtk-authoryear.bbx')
z.write('./dtk-bibliography/dtk-authoryear.dbx')
z.write('./dtk-bibliography/dtk-bibliography.pdf')
z.write('./dtk-bibliography/dtk-bibliography.tex')
# delete copied files
unlink('./dtk-bibliography/dtk-authoryear.bbx')
unlink('./dtk-bibliography/dtk-authoryear.dbx')
unlink('./dtk-bibliography/dtk-bibliography.pdf')
unlink('./dtk-bibliography/dtk-bibliography.tex')
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