von Patrick Gundlach |

Übungsblätter erstellen

Heute mal etwas mit einem weniger ernsten Hintergrund…

Manche (Grundschul-)Kinder sind im Mathematikunterricht eher gelangweilt und verlangen nach zusätzlichen Rechenaufgaben für zu Hause. Toll ist es natürlich, wenn man dann jemanden kennt, der auf automatisierte Textausgabe spezialisiert ist. Also musste ich mir Übungsblätter mit einfachen Rechenaufgaben überlegen (hier plus und minus).

Die Idee ist, eine Tabelle zu erzeugen, in der per Zufall Werte eingetragen werden. So soll das Ergebnis aussehen:

Damit das ganze etwas kindgerechter wirkt, nehme ich die tolle Schriftart Comic Sans und mache die Kästchen etwas krakelig.

Das Grundgerüst für das Layout sieht wie folgt aus

<Layout xmlns="urn:speedata.de:2009/publisher/en"
    xmlns:sd="urn:speedata:2009/publisher/functions/en">

    <SetGrid height="38pt" nx="3" dx="4mm" />

    <DefineGraphic name="box">
        draw box randomized 1mm withpen pencircle
             scaled 0.4mm;
    </DefineGraphic>

    <LoadFontfile
        name="ComicSansMS"
        filename="Comic Sans MS.ttf" />
    <DefineFontfamily
        fontsize="16"
        leading="28"
        name="text">
        <Regular fontface="ComicSansMS" />
    </DefineFontfamily>

    <Pagetype name="alle Seiten" test="true()">
        <PositioningArea name="text">
            <PositioningFrame
                width="1"
                height="{sd:number-of-rows()}"
                row="1"
                column="1" />
            <PositioningFrame
                width="1"
                height="{sd:number-of-rows()}"
                row="1"
                column="2" />
            <PositioningFrame
                width="1"
                height="{sd:number-of-rows()}"
                row="1"
                column="3" />
        </PositioningArea>
    </Pagetype>

    <Record element="data">
        <PlaceObject area="text">
            <Table stretch="max">
            ...
            </Table>
        </PlaceObject>
    </Record>
</Layout>

Die Tabelle wird weiter unten gezeigt.

Zur Erklärung der einzelnen Teile:

<SetGrid height="38pt" nx="3" dx="4mm" />

Hier wird ein dreispaltiges Layout mit einem Abstand von 4mm zwischen den Spalten definiert. Die 38 Punkt Zeilenhöhe sind etwas willkürlich und kommen hier durch die verwendete Schrifthöhe und den 10 Punkt Abstand über einer Tabellenzelle zustande. Damit ist jede Tabellenzelle auch in einer Rasterzelle.

Die Tabelle wird auf drei Spalten umbrochen.

<DefineGraphic name="box">
 draw box randomized 1mm withpen pencircle scaled 0.4mm;
</DefineGraphic>

Die Kästchen für die Ergebnisse entsprechen einer Zelle in der Tabelle. Es ist möglich (siehe unten), die Rahmen der Zelle mit MetaPost selber zu zeichnen. Hier wird für jedes Kästchen der Rahmen durch das Programm »box« neu gezeichnet. Es wird ein Rechteck mit den vorgegebenen Ausmaßen box gemalt, deren Ecken aber bis zu 1mm zufällig verschoben werden.

<LoadFontfile
    name="ComicSansMS"
    filename="Comic Sans MS.ttf" />

<DefineFontfamily fontsize="16" leading="28" name="text">
    <Regular fontface="ComicSansMS" />
</DefineFontfamily>

Das ist der bekannte Mechanismus um Schriftarten einzubinden. Bei macOS 11 ist die Schriftart schon im System enthalten, so dass ich beim Aufruf des Publishers

sp --systemfonts

nutzen kann, ohne die Schriftart selber noch zu installieren bzw. zu kopieren.

<Pagetype name="alle Seiten" test="true()">
    <PositioningArea name="text">
        <PositioningFrame
            width="1"
            height="{sd:number-of-rows()}"
            row="1"
            column="1" />
    </PositioningArea>
    ...
</Pagetype>

Hier werden drei Seitenbereiche definiert, in der die Tabelle später automatisch umbrechen soll. Jeder Bereich hat eine Breite von einer Rasterspalte und ist so hoch wie die Seite.

<Record element="data">
    <PlaceObject area="text">
        <Table stretch="max">
        ...
        </Table>
    </PlaceObject>
</Record>

Hier beginnt die eigentliche Datenverarbeitung. Da ich den speedata Publisher mit sp --dummy aufrufe, wird keine Datendatei benötigt bzw. es wird eine minimale Datei <data /> als Eingabe genommen. Somit startet die Datenverarbeitung mit dem <Record element="data">, da das dem Namen des Wurzelelements ist. Es wird die nachfolgende Tabelle in den Bereich »text« ausgegeben, der im <Pagetype> definiert wurde.

Die Tabelle

<Table stretch="max">
    <Columns>
        <Column width="2*" align="center" />
        <Column width="1*" align="center" />
        <Column width="2*" align="center" />
        <Column width="2*" align="center" />
        <Column width="4*" align="center" />
    </Columns>
    <Loop select="63">
        <SetVariable
            variable="a"
            select="sd:randomitem(1,2,3,4,5,6,7,8,9)" />
        <SetVariable
            variable="op"
            select="sd:randomitem('+','-')" />
        <Tr top-distance="10pt">
            <Td>
                <Paragraph>
                    <Value select="
                if ($op = '+') then
                    sd:randomitem(1,2,3,4,5,6,7,8,9) else
                    $a + sd:randomitem(1,2,3,4)"
                />
                </Paragraph>
            </Td>
            <Td>
                <Paragraph>
                    <Value select="$op"/>
                </Paragraph>
            </Td>
            <Td>
                <Paragraph>
                    <Value select="$a" />
                </Paragraph>
            </Td>
            <Td>
                <Paragraph>
                    <Value> = </Value>
                </Paragraph>
            </Td>
            <Td graphics="box">
                <Paragraph>
                    <Value />
                </Paragraph>
            </Td>
        </Tr>
    </Loop>
</Table>

Auch hier gibt es wieder eine ausführliche Erläuterung:

<Table stretch="max">

Die Tabelle wird auf die gesamte Breite des Bereichs »text« gedehnt.

<Columns>
    <Column width="2*" align="center" />
    <Column width="1*" align="center" />
    <Column width="2*" align="center" />
    <Column width="2*" align="center" />
    <Column width="4*" align="center" />
</Columns>

Die Tabelle hat fünf Spalten die sich entsprechend den *-Werten aufteilen. Jede Spalte ist zentriert.

<Loop select="63">
 ....
</Loop>

Es werden 63 Zeilen erzeugt, also 21 je Spalte. Wenn man nicht rechnen will, kann man das einfach ausprobieren.

<SetVariable
    variable="a"
    select="sd:randomitem(1,2,3,4,5,6,7,8,9)" />
<SetVariable
    variable="op"
    select="sd:randomitem('+','-')" />

Hier wird für jeden Schleifendurchlauf eine zufällige Zahl bis neun der Variablen a zugewiesen und die Variable op ist entweder auf die Zeichenkette + oder - gesetzt.

<Td>
    <Paragraph>
        <Value select="
            if ($op = '+') then
                sd:randomitem(1,2,3,4,5,6,7,8,9) else
                $a + sd:randomitem(1,2,3,4)" />
    </Paragraph>
</Td>

Bei Plus-Aufgaben dürfen die Zahlen 1–9 an erster Stelle stehen, bei Minus-Aufgaben sollten die Zahlen um 1–4 höher sein als der Inhalt der Variablen a, damit die Rechenaufgabe nicht zu schwer wird.

<Td graphics="box"><Paragraph><Value /></Paragraph></Td>

Die letzte Spalte ist eine leere Spalte. Es wird aber jedes Mal das MetaPost-Programm »box« aufgerufen, das weiter oben schon beschrieben wurde.

Download

Die Datei layout.xml, ist auch herunterladbar.

Die Datei muss in ein ansonsten leeres Verzeichnis kopiert werden und wird dort mit

sp --dummy --systemfonts

in ein PDF umgewandelt.