2025-03-15, 21:35
Mit dem listofitems
-Paket lassen sich recht einfach „for jeden Eintrag in Liste“ Schleifen in LaTeX umsetzen. Hier ein Beispiel für das Setzen einer 10m Zielscheibe für Luftpistolen mit TikZ.
\documentclass[tikz,border=0.5cm]{standalone}
\usetikzlibrary{positioning}
\renewcommand\familydefault{\sfdefault}
\usepackage{listofitems}
\setsepchar{;}
\begin{document}
\begin{tikzpicture}[font=\bfseries,thick]
%\draw[step=0.5cm,lightgray,thin] (0,0) grid (16,16);
\coordinate (o) at (8,8);
\draw[black,thick,fill=lightgray] (8,8) circle (29.75mm);
\readlist\distances{77.5;69.75;61.75;53.75;45.75;37.75;21.75;13.75;5.75}
\foreachitem\distance\in\distances{
\draw[black] (8,8) circle (\distance mm);
}
\readlist\distances{7.1;6.3;5.5;4.7;3.9;3.1;2.3;1.5;0.7}
\readlist\directions{right;above;left;below}
\foreachitem\direction\in\directions{
\foreachitem\distance\in\distances{
\node[\direction=\distance cm of o] {\distancecnt};
}
}
\end{tikzpicture}
\end{document} |
\documentclass[tikz,border=0.5cm]{standalone}
\usetikzlibrary{positioning}
\renewcommand\familydefault{\sfdefault}
\usepackage{listofitems}
\setsepchar{;}
\begin{document}
\begin{tikzpicture}[font=\bfseries,thick]
%\draw[step=0.5cm,lightgray,thin] (0,0) grid (16,16);
\coordinate (o) at (8,8);
\draw[black,thick,fill=lightgray] (8,8) circle (29.75mm);
\readlist\distances{77.5;69.75;61.75;53.75;45.75;37.75;21.75;13.75;5.75}
\foreachitem\distance\in\distances{
\draw[black] (8,8) circle (\distance mm);
}
\readlist\distances{7.1;6.3;5.5;4.7;3.9;3.1;2.3;1.5;0.7}
\readlist\directions{right;above;left;below}
\foreachitem\direction\in\directions{
\foreachitem\distance\in\distances{
\node[\direction=\distance cm of o] {\distancecnt};
}
}
\end{tikzpicture}
\end{document}
PDF
Lupi-10-1
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
Category:
Allgemein |
Kommentare deaktiviert für Foreach-Schleifen in LaTeX TikZ
2025-03-06, 21:24
Hier ein einfacher Code-Schnipsel, um aus CSV-Dateien Excel-Dateien zu machen.
Es empfiehlt sich auch, die Engine explizit zu setzen, mit der die Excel-Datei geschrieben wird. Standardmäßig nutzt pandas openpyxl, xlsxwriter scheint nach meinen Tests aber um ca. 30% schneller zu sein.
import pandas as pd
from openpyxl import Workbook
from openpyxl.utils.dataframe import dataframe_to_rows
# output control
files = ['']
wb = Workbook()
wb.remove(wb['Sheet'])
for index, file in enumerate(files,0):
temp = pd.read_csv(file + '.csv',sep='\t')
ws1 = wb.create_sheet()
ws1.title = file
rows = dataframe_to_rows(temp, index=False, header=True)
for r_idx, row in enumerate(rows, 1):
for c_idx, value in enumerate(row, 1):
ws1.cell(row=r_idx, column=c_idx, value=value)
wb.save('files45646.xlsx')
wb.close() |
import pandas as pd
from openpyxl import Workbook
from openpyxl.utils.dataframe import dataframe_to_rows
# output control
files = ['']
wb = Workbook()
wb.remove(wb['Sheet'])
for index, file in enumerate(files,0):
temp = pd.read_csv(file + '.csv',sep='\t')
ws1 = wb.create_sheet()
ws1.title = file
rows = dataframe_to_rows(temp, index=False, header=True)
for r_idx, row in enumerate(rows, 1):
for c_idx, value in enumerate(row, 1):
ws1.cell(row=r_idx, column=c_idx, value=value)
wb.save('files45646.xlsx')
wb.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
2025-02-27, 21:52
Aus aktuellem Anlass hier ein einfaches Beispiel, wie man Werte in pandas Dataframes ersetzen kann:
import pandas as pd
# initialize data of lists.
data = {'Hersteller': ['VW', 'BMW', 'VW', 'Porsche'],
'Modell': ['Golf', '1er', 'Polo', '911']}
df = pd.DataFrame(data)
print(df,'\n')
df['Hersteller'] = df['Hersteller'].replace(
{"VW": "Volkswagen", "Horch": "Audi"})
print(df) |
import pandas as pd
# initialize data of lists.
data = {'Hersteller': ['VW', 'BMW', 'VW', 'Porsche'],
'Modell': ['Golf', '1er', 'Polo', '911']}
df = pd.DataFrame(data)
print(df,'\n')
df['Hersteller'] = df['Hersteller'].replace(
{"VW": "Volkswagen", "Horch": "Audi"})
print(df)
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
2025-02-08, 18:29
Hier ein Code-Beispiel für die wichtigsten Funktionen von DuckDB.
import duckdb as ddb
import pandas as pd
con = ddb.connect(':memory:')
con_p = ddb.connect('my_database.db')
con_p.execute('CREATE OR REPLACE TABLE telefonnummern(fullname VARCHAR,phone VARCHAR);')
con_p.execute("INSERT INTO telefonnummern VALUES ('Max Mustermann', '0123-4567890')")
print(con_p.sql('SHOW ALL TABLES'))
print(con_p.sql('SELECT * FROM telefonnummern;'))
ddb_object = con_p.sql('SELECT * FROM telefonnummern;')
df = ddb_object.to_df()
ddb_tuple = ddb_object.fetchall()
print(df)
print(ddb_tuple) |
import duckdb as ddb
import pandas as pd
con = ddb.connect(':memory:')
con_p = ddb.connect('my_database.db')
con_p.execute('CREATE OR REPLACE TABLE telefonnummern(fullname VARCHAR,phone VARCHAR);')
con_p.execute("INSERT INTO telefonnummern VALUES ('Max Mustermann', '0123-4567890')")
print(con_p.sql('SHOW ALL TABLES'))
print(con_p.sql('SELECT * FROM telefonnummern;'))
ddb_object = con_p.sql('SELECT * FROM telefonnummern;')
df = ddb_object.to_df()
ddb_tuple = ddb_object.fetchall()
print(df)
print(ddb_tuple)
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
2024-12-14, 11:18
Hier ein paar Beispiele, wie man mit icecream print() Ausgaben ersetzen kann.
"""
icecream examples
"""
from icecream import ic
# define some function
def addiere(x, y):
return x + y
# call ice
ic(addiere(1, 2))
# Output:
# ic| addiere(1, 2): 3
d = {'i': 2, 'j': 3, 'k': 4711}
ic(d['k'])
struct = {
"hersteller": "VW",
"modell": "Golf",
"Farben": ["gelb", "rot"]
}
ic(struct)
ic.disable()
ic(struct) # no output
ic.enable()
def logstuff(text):
# log to output file
print(text)
ic.configureOutput(prefix="Hallo| ", outputFunction=logstuff)
ic(addiere(7, 7))
ic.configureOutput(prefix="Welt| ", outputFunction=logstuff)
ic(addiere(7, 7)) |
"""
icecream examples
"""
from icecream import ic
# define some function
def addiere(x, y):
return x + y
# call ice
ic(addiere(1, 2))
# Output:
# ic| addiere(1, 2): 3
d = {'i': 2, 'j': 3, 'k': 4711}
ic(d['k'])
struct = {
"hersteller": "VW",
"modell": "Golf",
"Farben": ["gelb", "rot"]
}
ic(struct)
ic.disable()
ic(struct) # no output
ic.enable()
def logstuff(text):
# log to output file
print(text)
ic.configureOutput(prefix="Hallo| ", outputFunction=logstuff)
ic(addiere(7, 7))
ic.configureOutput(prefix="Welt| ", outputFunction=logstuff)
ic(addiere(7, 7))
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
2024-11-04, 21:41
Hier ein Beispiel aus der gridpapers
Doku, wie man mit LaTeX isometrische Papiere gestalten kann.
\documentclass{article}
\usepackage[pattern=iso, %tri für senkrecht
patternsize=0.5cm,
textarea,
bgcolor=white,
%majorcolor={green},
minorcolor={lightgray},
geometry={a4paper, margin=1cm}]{gridpapers}
\begin{document}
\thispagestyle{empty}
~
\end{document} |
\documentclass{article}
\usepackage[pattern=iso, %tri für senkrecht
patternsize=0.5cm,
textarea,
bgcolor=white,
%majorcolor={green},
minorcolor={lightgray},
geometry={a4paper, margin=1cm}]{gridpapers}
\begin{document}
\thispagestyle{empty}
~
\end{document}
gridpapers-iso
gridpapers-tri
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
Category:
LaTeX,
Pakete,
Artikel |
Kommentare deaktiviert für Iso-Papier mit LaTeX und dem gridpapers Paket
2024-11-04, 21:05
Hier ein erster Entwurf, wie man mit LaTeX Drum Patters setzen kann.
\documentclass[12pt,ngerman]{scrartcl}
\usepackage[margin=1cm]{geometry}
\usepackage[T1]{fontenc}
\usepackage{babel}
\usepackage{graphicx}
\usepackage{xcolor}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
% Define the pattern as a comma-separated list
\def\pattern{x,-,-,-,-,x,x,-,-,-,x,x,-,-,-,x}
\def\cellsizex{1cm}
\def\cellsizey{0.5cm}
\node[draw, rectangle,minimum width = \cellsizex, align=left,minimum height=\cellsizey] (a) at (\cellsizex/2,\cellsizey/2){\tiny 1};
% Loop through each character in the pattern
\foreach \cell [count=\index from 1] in \pattern {
% If 'x' fill the cell, otherwise leave it empty
\if\cell x
\fill[gray,draw=black] ({\index*\cellsizex}, 0) rectangle ++(\cellsizex, \cellsizey);
\else
\draw ({\index*\cellsizex}, 0) rectangle ++(\cellsizex, \cellsizey);
\fi
}
\end{tikzpicture} |
\documentclass[12pt,ngerman]{scrartcl}
\usepackage[margin=1cm]{geometry}
\usepackage[T1]{fontenc}
\usepackage{babel}
\usepackage{graphicx}
\usepackage{xcolor}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
% Define the pattern as a comma-separated list
\def\pattern{x,-,-,-,-,x,x,-,-,-,x,x,-,-,-,x}
\def\cellsizex{1cm}
\def\cellsizey{0.5cm}
\node[draw, rectangle,minimum width = \cellsizex, align=left,minimum height=\cellsizey] (a) at (\cellsizex/2,\cellsizey/2){\tiny 1};
% Loop through each character in the pattern
\foreach \cell [count=\index from 1] in \pattern {
% If 'x' fill the cell, otherwise leave it empty
\if\cell x
\fill[gray,draw=black] ({\index*\cellsizex}, 0) rectangle ++(\cellsizex, \cellsizey);
\else
\draw ({\index*\cellsizex}, 0) rectangle ++(\cellsizex, \cellsizey);
\fi
}
\end{tikzpicture}
drumbrute_pattern
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
2024-10-25, 19:14
Ich bin vor einigen Tagen gefragt worden, ob ich nicht das passende Equipment hätte, um eine VHS Kassette zu digitalisieren. Recht blauäugig hab ich sofort „klar“ gesagt, denn einiges habe ich in der Tat:
- eine AverMedia HDMI Capture Karte für den PC
- zwei Elgato HDMI-Grabber für USB
- ein Kaico Edition OSSC Konverter, der aus SCART HDMI zaubert
Theoretisch war also alles vorhanden, doch grau ist alle Theorie!
Versuch Nummer 1
Meine Idee war, einfach den geborgten Video-Recorder an den OSSC anzuschließen, um von dort das Bild mit der Capture-Karte und OBS aufzunehmen. Es tat sich genau nichts, es gab kein Bild. Des Rätsels Lösung war, dass der Video-Recorder ein Composite-Videosignal ausgibt, mit dem der OSSC Konverter leider nichts anfangen kann. Das Ding ist nur für alte Konsolen und Heim-PCs gemacht, aber nicht für VHS.
Versuch Nummer 2
Weg mit dem Kaico, her mit einem SCART-auf-HDMI Adapter vom großen A, Kostenpunkt knapp 7 (!) Euro. Audio kam an, aber das Bild war meist kaputt: „No Signal“. Des Rätsels Lösung war, dass das Video-Signal leider zu schlecht war und immer wieder zusammenbrach. Damit kam der günstige Adapter leider nicht klar.
Versuch Nummer 3
Versuch Nummer 3 brachte dann den Erfolg. Zusammen mit dem Video-Recorder hatte ich auch noch einen „Canopus ADVC-300 Advanced Digital Video Converter“ in die Hand gedrückt bekommen, den ich erst komplett ignoriert hatte. Damit lassen sich analoge Videos per FireWire auf den Rechner sichern. FireWire Hardware hab ich zwar vielleicht noch rumliegen, aber nicht mehr aktiv im Einsatz. Jedoch ist FireWire nicht die einzige Schnittstelle, das Ding nimmt analoge Videos nicht nur an sondern kann diese auch wieder analog ausgeben. Dabei wird das Videosignal so weit stabilisiert, dass der Scart-auf-HDMI Adapter nichts zu nörgeln hatte.
Der finale Prozess sah daher so aus:
- VHS Videorecorder
- mit drei CINCH-Kabeln dann in den Canopus
- mit drei CINCH-Kabeln dann vom Canopus in einen 3-Cinch auf SCART-Adapter
- mit dem SCART-Adapter dann in den sehr preiswerten SCART-auf-HDMI Adapter
- vom SCART-auf-HDMI Adapter per HDMI in den HDMI Grabber (AverMedia LiveGamer 2)
- in OBS dann dann von der Grabber-Karte aufnehmen, vorher Leinwand auf 4:3 anpassen
- als Ausgabeformat wird MKV empfohlen, alle Audioquellen außer die Grabber-Karte wurden aktiv deaktiviert (mute)
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
2024-09-07, 09:23
Für Dante e.V. bestand die Notwendigkeit, aus MT940 Dateien moderne CAMT.053 zu erzeugen, dank Python wurde das eine lösbare Aufgabe.
Schritt 1
Die MT940 Datei parsen und die Transaktionen in einen pandas DataFrame überführen.
import mt940
import pprint
import pandas as pd
df = pd.DataFrame()
transactions = mt940.parse('Umsaetze_2310007_22.07.2024.mta')
print('Transactions:')
pprint.pprint(transactions.data)
for transaction in transactions:
print('Transaction: ', transaction)
pprint.pprint(transaction.data)
t = transaction.data
tt = pd.DataFrame(t, index=[0])
df = pd.concat([df,tt],ignore_index=True)
df.to_excel('AllBookings.xlsx',index=False)
Schritt 2
Aus dem DataFrame das XML befüllen, die für den Kopf der XML-Datei notwendigen Kontostandsinformationen holen ich dazu aus der MT940 Datei.
import pandas as pd # data wrangling
import jinja2 # template engine
import os # for file-related stuff
import mt940
from datetime import datetime
today = datetime.today()
now = today.strftime("%Y-%m-%d")
transactions = mt940.parse('Umsaetze_2310007_22.07.2024.mta')
opening = transactions.data['final_opening_balance']
openingamount = str(opening.amount)[:-4]
openingdate = opening.date
closing = transactions.data['final_closing_balance']
closingamount = str(closing.amount)[:-4]
closingdate = closing.date
# create jinja env that can load template from filesystem
jinja_env = jinja2.Environment(loader = jinja2.FileSystemLoader(os.path.abspath('.')))
df = pd.read_excel('AllBookings.xlsx', dtype={'date': str,'amount':str})
df['CreditDebit'] = ''
df['CreditDebit'] = df['CreditDebit'].where(df['amount'].str.get(0).isin(['-']), 'CRDT')
df['CreditDebit'] = df['CreditDebit'].where(~df['amount'].str.get(0).isin(['-']), 'DBIT')
df['date'] = df['date'].str[:-9]
# Währung weg
df['amount'] = df['amount'].str[:-4]
# Vorzeichen weg
df['amount'] = df['amount'].str.replace('-','')
#df['amount'].replace('-','',inplace=True)
#df["amount"] = df["amount"].apply(lambda x: x.str.replace("-", ""))
template = jinja_env.get_template('Ntry.xml')
with open('FertigesXML.xml','w') as output:
output.write(template.render(data=df,
openingamount=openingamount,
openingdate=openingdate,
closingamount=closingamount,
closingdate=closingdate
))
Jinja2 XML-Template
Das XML-Template für Jinja2 findet ihr hier:
Ntry_blog
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
2024-05-05, 17:17
Ich experimentiere aktuell mit paperless-ngx, in der c’t war eine passende Anleitung für Docker auf Synology NAS, der ich gefolgt bin.
Um Bögen mit Archive Serial Numbers zu erstellen, will ich natürlich LaTeX nutzen, ticket.sty
heißt hier das Zauberwort. (Es gibt auch web-basierte Generatoren, siehe https://tobiasmaier.info/asn-qr-code-label-generator/)
PDF Beispiel
Anbei der Quellcode für LaTeX, für den Druck auf andere Bögen als Avery Zweckform 4736 muss man das Format der Labels anpassen. Dann ist die LaTeX-Datei zweimal zu übersetzen.
\documentclass[a4paper,12pt]{scrartcl}
\usepackage[total={210mm,297mm},top=0mm,left=0mm,bottom=0mm,includefoot]{geometry}
\usepackage[ASN]{ticket} %boxed,cutmark during development
\usepackage{qrcode}
\usepackage{forloop}
\usepackage[T1]{fontenc}
% https://tex.stackexchange.com/questions/716116/generate-sequential-padded-barcodes-with-qrcode?noredirect=1#comment1780003_716116
\makeatletter
\newcommand{\padnum}[2]{%
\ifnum#1>1 \ifnum#2<10 0\fi
\ifnum#1>2 \ifnum#2<100 0\fi
\ifnum#1>3 \ifnum#2<1000 0\fi
\ifnum#1>4 \ifnum#2<10000 0\fi
\ifnum#1>5 \ifnum#2<100000 0\fi
\ifnum#1>6 \ifnum#2<1000000 0\fi
\ifnum#1>7 \ifnum#2<10000000 0\fi
\ifnum#1>8 \ifnum#2<100000000 0\fi
\ifnum#1>9 \ifnum#2<1000000000 0\fi
\fi\fi\fi\fi\fi\fi\fi\fi\fi
\expandafter\@firstofone\expandafter{\number#2}%
}
\makeatother
\begin{filecontents*}[overwrite]{ASN.tdf}
\unitlength=1mm
\hoffset=-16mm
\voffset=-8mm
\ticketNumbers{4}{12}
\ticketSize{45.7}{21.2} % Breite und Höhe der Labels in mm
\ticketDistance{2.5}{0} % Abstand der Labels
\end{filecontents*}
%reset background
\renewcommand{\ticketdefault}{}%
\newcounter{asn}
% start value of the labels
\setcounter{asn}{1}
\newcommand{\mylabel}{
\ticket{%
\hspace*{4mm}\raisebox{9mm}[4mm][2mm]{%
\qrcode[height=1.4cm]{ASN\padnum{5}{\value{asn}}}%
~\texttt{\large ASN\padnum{5}{\value{asn}}}
}
\stepcounter{asn}
}
}
\begin{document}
% just for the loop
\newcounter{x}
% create 48 labels
\forloop{x}{1}{\value{x} < 49}{
\mylabel%
}
%print on Avery Zweckform 4736
% in original size, not scaled to fit page
\end{document} |
\documentclass[a4paper,12pt]{scrartcl}
\usepackage[total={210mm,297mm},top=0mm,left=0mm,bottom=0mm,includefoot]{geometry}
\usepackage[ASN]{ticket} %boxed,cutmark during development
\usepackage{qrcode}
\usepackage{forloop}
\usepackage[T1]{fontenc}
% https://tex.stackexchange.com/questions/716116/generate-sequential-padded-barcodes-with-qrcode?noredirect=1#comment1780003_716116
\makeatletter
\newcommand{\padnum}[2]{%
\ifnum#1>1 \ifnum#2<10 0\fi
\ifnum#1>2 \ifnum#2<100 0\fi
\ifnum#1>3 \ifnum#2<1000 0\fi
\ifnum#1>4 \ifnum#2<10000 0\fi
\ifnum#1>5 \ifnum#2<100000 0\fi
\ifnum#1>6 \ifnum#2<1000000 0\fi
\ifnum#1>7 \ifnum#2<10000000 0\fi
\ifnum#1>8 \ifnum#2<100000000 0\fi
\ifnum#1>9 \ifnum#2<1000000000 0\fi
\fi\fi\fi\fi\fi\fi\fi\fi\fi
\expandafter\@firstofone\expandafter{\number#2}%
}
\makeatother
\begin{filecontents*}[overwrite]{ASN.tdf}
\unitlength=1mm
\hoffset=-16mm
\voffset=-8mm
\ticketNumbers{4}{12}
\ticketSize{45.7}{21.2} % Breite und Höhe der Labels in mm
\ticketDistance{2.5}{0} % Abstand der Labels
\end{filecontents*}
%reset background
\renewcommand{\ticketdefault}{}%
\newcounter{asn}
% start value of the labels
\setcounter{asn}{1}
\newcommand{\mylabel}{
\ticket{%
\hspace*{4mm}\raisebox{9mm}[4mm][2mm]{%
\qrcode[height=1.4cm]{ASN\padnum{5}{\value{asn}}}%
~\texttt{\large ASN\padnum{5}{\value{asn}}}
}
\stepcounter{asn}
}
}
\begin{document}
% just for the loop
\newcounter{x}
% create 48 labels
\forloop{x}{1}{\value{x} < 49}{
\mylabel%
}
%print on Avery Zweckform 4736
% in original size, not scaled to fit page
\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