Created
February 1, 2025 17:40
-
-
Save drn1998/52942bd304c08c6f8e72e3fb711a3f25 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% This PHP script is licensed according to the GNU AGPL v3. It uses a data format from the | |
% Open Knowledge Foundation Deutschland e.V. whos content is commonly distributed according to the | |
% CC-BY-SA-4.0 and therefore incorporates said licensing information into the output document. | |
% Please check this before distributing a document created with this script. | |
% | |
% © 2025 - Darius Runge (licensed according to GNU AGPL v3) | |
% | |
% Darius Runge, Postfach 7, 72669 Unterensingen | |
% Tel: +49 7022 5064970 | |
% Fax: +49 7022 5064971 | |
% | |
% Permanently updated contact data at: http://darius-runge.eu (or HTTPS) | |
<?php | |
function latexesc($string) { | |
$map = array( | |
"#" => "\\#", | |
"$" => "\\$", | |
"%" => "\\%", | |
"&" => "\\&", | |
"~" => "\\~{}", | |
"_" => "\\_", | |
"^" => "\\^{}", | |
"\\" => "\\textbackslash", | |
"{" => "\\{", | |
"}" => "\\}", | |
); | |
return preg_replace_callback( | |
"/([\^\%~\\\\#\$%&_\{\}])/", | |
function ($matches) use ($map) { | |
return $map[$matches[1]]; | |
}, | |
$string | |
); | |
} | |
function no_party_opt($obj, $opt): int { | |
$res = 1; | |
foreach ($obj["answers"] as $aw) | |
if($aw["answer"] == $opt) $res = 0; | |
return $res; | |
} | |
function conv_party_opt($obj): string { | |
switch($obj["answer"]) { | |
case "richtig": return latexesc('!'); | |
case "zu weit": return latexesc('-'); | |
case "nicht weit genug": return latexesc('+'); | |
case "/": return latexesc('#'); | |
} | |
return "ERROR"; | |
} | |
$real_o_mat = json_decode(file_get_contents("real-o-mat.json"), true); | |
?> | |
\documentclass[parskip=full]{scrartcl} | |
\usepackage{tikz} | |
\usepackage{setspace} | |
\usepackage{graphicx} | |
\usepackage{scrlayer-scrpage} | |
\usepackage[a4paper, margin=1in]{geometry} | |
\usepackage{tabularx} | |
\usepackage{longtable} | |
\usepackage{csquotes} | |
\renewcommand{\familydefault}{\sfdefault} | |
\newcommand{\mktitle}[1]{% | |
\begin{center} | |
\Huge \textbf{#1} \\[1em] | |
\end{center} | |
} | |
\newcommand{\mkcatlabel}[1]{% | |
\begin{center} | |
\Large #1 \\[1em] | |
\end{center} | |
} | |
\newcommand{\mksection}[1]{% | |
\begin{flushleft} | |
\Large \textbf{#1} \\[1em] | |
\end{flushleft} | |
} | |
\newenvironment{unbreak} | |
{\par\nobreak\vfil\penalty0\vfilneg | |
\vtop\bgroup} | |
{\par\xdef\tpd{\the\prevdepth}\egroup | |
\prevdepth=\tpd} | |
\newcommand{\radiosize}{0.42cm} | |
\newcolumntype{L}{>{\raggedright\arraybackslash}X} | |
\newcommand{\checkboxheaders}{% | |
\noindent\textbf{ | |
\begin{tabularx}{\textwidth}{Lccc} | |
Thesenwahl & \makebox[\radiosize][l]{-} & \makebox[\radiosize][l]{!} & \makebox[\radiosize][l]{+} \\ | |
\hline | |
\end{tabularx}% | |
} | |
} | |
\newcounter{checkboxrowcounter} | |
\setcounter{checkboxrowcounter}{1} | |
\newcommand{\checkboxrow}[4]{% | |
\begin{tabularx}{\textwidth}{Lccc} | |
\thecheckboxrowcounter. #1 & % Add the counter number here | |
\begin{tikzpicture}[baseline=(box.base)] | |
\ifnum#2=1 | |
\node[draw, thick, fill=gray!30, minimum width=\radiosize, minimum height=\radiosize] (box) {}; | |
\else | |
\node[draw, thick, minimum width=\radiosize, minimum height=\radiosize] (box) {}; | |
\fi | |
\end{tikzpicture} & | |
\begin{tikzpicture}[baseline=(box.base)] | |
\ifnum#3=1 | |
\node[draw, thick, fill=gray!30, minimum width=\radiosize, minimum height=\radiosize] (box) {}; | |
\else | |
\node[draw, thick, minimum width=\radiosize, minimum height=\radiosize] (box) {}; | |
\fi | |
\end{tikzpicture} & | |
\begin{tikzpicture}[baseline=(box.base)] | |
\ifnum#4=1 | |
\node[draw, thick, fill=gray!30, minimum width=\radiosize, minimum height=\radiosize] (box) {}; | |
\else | |
\node[draw, thick, minimum width=\radiosize, minimum height=\radiosize] (box) {}; | |
\fi | |
\end{tikzpicture} \\ | |
\end{tabularx}% | |
\stepcounter{checkboxrowcounter} % Increment the counter after each row | |
} | |
\newcommand{\resultbox}[1] {% | |
\makebox[\textwidth][l]{ | |
\fbox{ | |
\begin{minipage}[t]{\textwidth} | |
\vspace{1em} % some padding | |
#1 | |
\vspace{1em} % some padding | |
\end{minipage} | |
} | |
\vspace{2em} | |
} | |
} | |
\emergencystretch 3em | |
\pagestyle{scrheadings} % Use the scrheadings page style (for header/footer control) | |
\begin{document} | |
\mktitle{Real-o-Mat Bundestagswahl 2025} | |
Diese Druckausgabe dient dem Interesse der transparenten Datenverarbeitung, ohne das Vertrauen in einen Computer die Berechnungen analog zu jener der Web-App durchführen zu können. Wir möchten damit nicht den Vorwurf erheben, das Angebot von Frag-den-Staat selbst sei bösartig in Bezug auf das Persönlichkeitsrecht. Vielmehr soll so eine Ausgabe geschaffen werden, die gänzlich resistent gegen Cyberangriffe ist, auch welche, die jenseits des Einflusses von Frag-den-Staat liegen (Schadsoftware auf dem Client oder Cyber-Angriffe gegen die Netzwerkcomputer durch Dritte), und dies dem Anwender plausibel nachvollziehbar demonstriert. | |
\textbf{Der Herausgeber der Daten in Druckfassung (Vorname Nachname des Herausgebers) steht in keinem Zusammenhang mit Frag-den-Staat oder der Open Knowledge Foundation Deutschland~e.V. Ich verwende lediglich deren Daten, die unter einer freizügigen Lizenz (CC~BY-SA~4.0) freigegeben wurden. Entsprechend gebe ich auch dieses Dokument unter der Lizenz weiter. Das Script, das aus den Strukturdaten die Druckdaten generiert, steht unter der Lizenz GNU~AGPL~v3.} | |
Bitte beachten Sie folgende Ausfüllhinweise: | |
\begin{enumerate} | |
\item Nutzen Sie einen konsistent schreibenden Stift, etwa einen (nicht zu alten) Fineliner, Kugelschreiber oder regelmäßig angespitzten Bleistift (wenn auch Radiergummi verfügbar). | |
\item Jede These hat drei Auswahlfelder, von denen \textbf{eines} angekreuzt werden soll (oder keines, dies entspricht dem \textit{Überspringen der These} in der Webanwendung). \textbf{Kreuzen Sie das Feld an.} Nutzen Sie keine anderen Markierungen wie Häkchen oder Ausmalen. Graue Felder sind nicht auswählbar, da keine der ausgewerteten Parteien dieser Haltung entsprechen. Kreuzen Sie minus (links) an, wenn ihnen die These zu weit geht, Ausrufezeichen (mittig), wenn Sie zustimmen, und plus (rechts), wenn Ihnen die These nicht weit genug geht. | |
\item Sobald Sie sich mit allen Thesen auseinandergesetz haben, lesen Sie aus der Auswertungstabelle für jede Partei ab, ob das Abstimmungsverhalten mit Ihren Angaben übereinstimmt. In der Ergebnistabelle haben Sie für jede Partei ein Feld für eine Strichliste. Zählen Sie am Ende die Anzahl an Übereinstimmungen. Ist Ihnen die These besonders wichtig, notieren Sie bei Übereinstimmung zwei Striche. | |
\item \textbf{Bevor Sie die Bögen entsorgen}, kreuzen Sie alle anderen Felder mit dem selben Stift an. Haben Sie einen Bleistift verwendet, sollten Sie außerdem, nachdem Sie alle Felder ausgefüllt haben, sämtliche wieder ausradieren. Zerstören Sie nun das Papier vorzugsweise durch einen Aktenvernichter. Durch dieses Vorgehen sollen Rückschlüsse auf die einstigen Angaben bei Missbrauch des Papierabfalls vermieden werden. | |
\end{enumerate} | |
Für Fragen oder Rückmeldungen erreichen Sie mich per Telefax (Rufnummer Telefaxanschluss) oder Post (Postanschrift bzw. Postfach des Herausgebers). Bitte denken Sie daran, Ihre Fragen abstrakt zu formulieren, um keine Rückschlüsse auf Ihren politischen Willen zu ermöglichen (genau das ist ja Sinn dieses Systems). \textbf{Senden Sie in keinem Fall ausgefüllte Formulare mit.} Wir beantworten auch Sendungen, deren Antwortadresse postlagernd/mit Kennwort ist. Bitte richten Sie keine Fragen, die speziell die Druckfassung betreffen, an Frag-den-Staat. | |
Dieses Angebot ist \textit{ohne jegliche Haftung}, insbesondere dafür, ob ein korrektes Befolgen der Anleitung zu richtigen bzw.~mit der Webanwendung von Frag-den-Staat übereinstimmenden Ergebnissen oder der Gewährleistung von Vertraulichkeit führt. | |
\newpage | |
\checkboxheaders | |
<?php | |
$cat = ""; | |
foreach($real_o_mat["data"] as $entry) { | |
echo '\\vspace{0.2em}' . PHP_EOL; | |
$cont = false; | |
if($cat != $entry["category"]) { | |
$cat = $entry["category"]; | |
echo '\\begin{unbreak}' . PHP_EOL; | |
echo '\\mkcatlabel{' . latexesc($cat) . '}' . PHP_EOL; | |
$cont = true; | |
} | |
echo '\\checkboxrow{' . latexesc(trim($entry["thesis"])) . '}{' . no_party_opt($entry, "zu weit") . '}{' . no_party_opt($entry, "richtig") . '}{' . no_party_opt($entry, "nicht weit genug") . '}' . PHP_EOL . PHP_EOL; | |
if($cont) { | |
echo '\\end{unbreak}' . PHP_EOL; | |
} | |
} | |
?> | |
\newpage | |
\mksection{Auswertungstabelle} | |
\begin{longtable}{|c|c|c|c|c|c|c|c|c|} | |
\hline | |
\textbf{Nr.} & \textbf{SPD} & \textbf{CDU} & \textbf{FDP} & \textbf{Grüne} & \textbf{BSW} & \textbf{Linke} & \textbf{AfD} & \textbf{Nr.} \\ | |
\hline | |
\endfirsthead | |
\hline | |
\textbf{Nr.} & \textbf{SPD} & \textbf{CDU} & \textbf{FDP} & \textbf{Grüne} & \textbf{BSW} & \textbf{Linke} & \textbf{AfD} & \textbf{Nr.} \\ | |
\hline | |
\endhead | |
\hline | |
\endfoot | |
\hline | |
\endlastfoot | |
<?php | |
$counter = 1; | |
foreach ($real_o_mat["data"] as $entry) { | |
$answer = $entry["answers"]; | |
echo '\\hline' . PHP_EOL; | |
echo $counter . ' & ' . conv_party_opt($answer[0]) . ' & ' . conv_party_opt($answer[1]) . ' & ' . conv_party_opt($answer[2]) . ' & ' . conv_party_opt($answer[3]) . ' & ' . conv_party_opt($answer[4]) . ' & ' . conv_party_opt($answer[5]) . ' & ' . conv_party_opt($answer[6]) . ' & ' . $counter . '\\\\' . PHP_EOL; | |
$counter++; | |
} | |
?> | |
\hline | |
\textbf{Nr.} & \textbf{SPD} & \textbf{CDU} & \textbf{FDP} & \textbf{Grüne} & \textbf{BSW} & \textbf{Linke} & \textbf{AfD} & \textbf{Nr.} \\ | |
\hline | |
\end{longtable} | |
Ich zitiere zwei Stellen aus der \textit{Methodik}\footnote{https://real-o-mat.de/methodik/ (30.01.2025 um 18:05 Uhr)} des Real-o-Mat: | |
\begin{displayquote} | |
Da das Bündnis Sahra Wagenknecht erst ab Ende 2023 bzw. Anfang 2024 im Bundestag vertreten war, hat das BSW über einen großen Teil der Anträge nicht mit abgestimmt. In diesen Fällen ist eine Übereinstimmung mit dem BSW nicht möglich. | |
\end{displayquote} | |
\begin{displayquote} | |
Der Real-O-Mat betrachtet das Abstimmungsverhalten der sieben Bundestagsfraktionen SPD, FDP, Bündnis 90/Die Grünen, CDU/CSU, Die Linke, BSW und AfD. Im Dezember~2023 löste sich die Fraktion Die Linke auf. Die Abgeordneten waren bis Januar~2024 fraktionslos im Bundestag vertreten. Ab dem 2.~Februar~2024 bildete sich im Bundestag die Gruppe Die Linke und das Bündnis Sahra Wagenknecht (BSW). Bei Abstimmungen, die zwischen dem 7.~Dezember~2023 und dem 31.~Januar~2024 stattfanden, wurden die Abgeordneten der Partei zugeordnet, der sie ab Februar~2024 angehörten. | |
Eine 100\%ige Übereinstimmung mit einer Partei ist nur dann möglich, wenn man ausschließlich zu Forderungen abstimmt, bei denen auch die jeweilige Partei eine wertbare Position hat (und nicht wertbare übersprungen werden). | |
\end{displayquote} | |
\newpage | |
\mksection{Ergebnistabelle} | |
Bei Übereinstimmung mit einer These geben Sie je Partei einen Punkt als Strichliste (bei einer wichtigen These zwei). | |
<?php | |
$party = ["SPD", "CDU", "FDP", "Grüne", "BSW", "Linke", "AfD"]; | |
foreach ($party as $p) { | |
echo '\resultbox{' . latexesc($p) . '}' . PHP_EOL; | |
} | |
?> | |
Lesen Sie nun ab, wie viele Punkte die Partei jeweils hat. Je höher der Wert relativ zu den anderen, desto mehr Zustimmung ergibt sich auf Grundlage der vorgestellten Thesen. \textbf{Füllen Sie vor der Entsorgung sämtliche Strichlisten auf 40~Einträge auf, sodass nicht mehr erkennbar ist, wie viele Striche es ursprünglich waren.} | |
\end{document} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment