“10 PRINT” in TikZ

The book 10 PRINT CHR$(205.5+RND(1)); : GOTO 10, by Nick Montfort, et. al., uses a one-line Commodore 64 BASIC program “as a gateway into a deeper understanding of how computing works in society and what the writing, reading, and execution of computer code mean” (p. 4). The focus is on the titular program, which the authors call 10 PRINT for short:

10 PRINT CHR$(205.5+RND(1)); : GOTO 10

This program prints an infinite random sequence made up of the box-drawing characters ╱ and ╲ (that’s U+2571 and U+2572, respectively, encoded in the Commodore character set PETSCII as 205 and 206.), in order to make a random maze. This produces an output similar to the following, except that the characters on a Commodore screen are more square:

(The book’s web site gives a better idea how the output on a Commodore would look.)

It’s not hard to reproduce 10 PRINT in Python, albeit using more than one line:

#! /usr/bin/env python3

import random

for j in range(0, 24):
    print("".join([random.choice(["\u2571","\u2572"])
        for k in range(0, 40)]))

(Instead of an infinite string, my program only outputs a 40 × 24 block of characters.) To get the output to look right, you might need to mess with the font settings in your Terminal. I found that that Melno Regular font on my Mac works.

But I really thought it would be more fun to obtain a 10 PRINT-like output using TikZ, as TikZ is capable of generating random numbers! Instead of using the characters ╱ and ╲, I will draw the lines directly:

\documentclass{standalone}

\usepackage{tikz}

\begin{document}

  \begin{tikzpicture}

    % Draw background
    \fill[blue!75!black] (0, 0) -- (0, 24) --
    (40, 24) -- (40, 0) -- cycle;

    % Draw maze
    \foreach \y in {0, ..., 23}{
      \foreach \x in {0, ..., 39}{

        % Randomly choose a = 0 or a = 1
        \pgfmathrandominteger{\a}{0}{1};

        % If a = 0, then will draw SW-NE line
        % If a = 1, then will draw NW-SE line
        \draw[very thick, white] (\x, \y + \a)
          -- (\x + 1, \y + 1 - \a);
      }
    }

  \end{tikzpicture}

\end{document}

I really like the output:

LaTeX mailmerge package

The LaTeX mailmerge package is super useful, especially for creating multiple versions of tests.

Before I discovered mailmerge, my workflow for writing a test was basically:

  • Write one version of the test.
  • Make a duplicate of the file.
  • Edit the file to change all the constants.

At least, that was my intended workflow. But typically I would also:

  • Realize that there was some change I wanted to make to the test.
  • Painstakingly make the same change to both versions of the test, double-checking that the wording remained consistent between versions.

Sometimes I would repeat the last two steps multiple times. This was obnoxiously inefficient.

Then I discovered the mailmerge package.

Here is a basic (silly) example illustrating how the package works:

\documentclass[letterpaper, 12pt]{amsart}

%% packages
\usepackage{mailmerge}
\usepackage{fouriernc}
\usepackage{url}
\usepackage{tikz}

\title{Some U.S.~state capital facts}

\begin{document}

  \maketitle

  \mailrepeat{
    The capital of \field{state} is \field{capital}.
    The U.S. Census Bureau estimates that in mid-2017,
    there were \field{population} people living in
    \field{capital}\footnote{\field{cite}}.

  }

  \mailfields{state,capital,population,cite}

  \mailentry{Illinois,Springfield,%
    {167,376},\url{https://goo.gl/YGDdE6}}

  %% Draw a square:
  \vskip 1 em
  \begin{tikzpicture}
    \draw (0, 0) -- (1, 0)
      -- (1, 1) -- (0, 1) -- cycle;
  \end{tikzpicture}
  \vskip 1 em

  \mailentry{Minnesota,St.~Paul,%
    {306,621},\url{https://goo.gl/F6rXZ7}}

  \mailentry{Oregon,Salem,%
    {169,798},\url{https://goo.gl/Zc4tDC}}

  \mailentry{Pennsylvania,Harrisburg,%
    {49,192},\url{https://goo.gl/NQypQG}}

\end{document}

This produces:

SOME U.S. STATE CAPITAL FACTS

The capital of Illinois is Springfield. The U.S. Census Bureau estimates that in mid-2017, there were 167,376 people living in Springfield1.

The capital of Minnesota is St. Paul. The U.S. Census Bureau estimates that in mid-2017, there were 306,621 people living in St. Paul2.

The capital of Oregon is Salem. The U.S. Census Bureau estimates that in mid-2017, there were 169,798 people living in Salem3.

The capital of Pennsylvania is Harrisburg. The U.S. Census Bureau estimates that in mid-2017, there were 49,192 people living in Harrisburg4.

This is followed by the appropriate footnotes.

Typeset output from first example.

Notice:

  • The text you want repeated is specified as the argument of the \mailrepeat macro.
  • Within the \mailrepeat, we specify the mail-merged info with \field{[field name]}
  • The names of the mail merge fields are given as a comma-delimited list with the \mailfields macro.
  • The actual mail-merge is accomplished with the \mailentry macro. The argument to this macro is a comma-delimited list of the material to place into the fields.

I put the silly TikZ square in this example to illustrate that the mail-merged text is placed where the \mailentry occurs in the code.

Spacing is significant in the \mailentry macro. If there is a space next to \field{[field name]} in the \mailrepeat and after the comma the corresponding field in the \mailentry, this will produce an awkward amount of space in the output. For example,

\mailentry{Minnesota, St.~Paul,
{306,621},\url{https://goo.gl/F6rXZ7}}

will produce:

Notice the extra space before the two instances of “St. Paul” and before the population. Compare to what is produced when there is no space before the comma and there is a % before the line break (which prevents the line break from being treated as a space):

\mailentry{Minnesota,St.~Paul,%
{306,621},\url{https://goo.gl/F6rXZ7}}


It’s very subtle, but I am a perfectionist.

If you have many fields, the comma-delimited list argument to the \mailentry can get unwieldy. One trick I use is to end each entry with a comment containing the field name:

  \mailentry{Minnesota%state
    ,St.~Paul%capital
    ,{306,621}%population
    ,\url{https://goo.gl/F6rXZ7}%cite
    }

Especially when the fields are difficult to tell apart based on content (e.g., when they are different constants for math problems), this makes it easier to know which field you are changing. Also, the comments prevent any space or line break before the comma from affecting the output.

For a test, each version would correspond to a single \mailentry. Consider this made-up quiz, which has two versions (Form A and B):

\documentclass[letterpaper, 11pt]{article}

%% packages
\usepackage{amsmath}
\usepackage{mailmerge}
\usepackage{fouriernc}
\usepackage{enumitem}
\usepackage{fullpage}

\begin{document}

  \mailrepeat{
    \setcounter{page}{1}
    \centerline{\textbf{Quiz \#1}, Form \field{form}}
    \vskip 1 em

    \begin{enumerate}
      \item (2 points) Expand
      \(\left(x^{\field{exponent1}} + 2x\right)^2\).


      \vfill

      \item (3 points) Suppose
      \(f(x) =
        \field{coeff1}x^2 + \field{coeff2}x + 1\).
      Find \(f(5)\).
      \vfill

    \end{enumerate}

    \newpage

    \begin{enumerate}[resume]
      \item (5 points) Solve for \(x\):
      \[\field{coeff3}x^4 - \field{coeff4}x^3
        = 0\]

      \vfill

    \end{enumerate}
    \newpage
  }


  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%% Mail merge info:

  \mailfields{form, coeff1, coeff2,
    coeff3, coeff4, exponent1}

  \mailentry{A%form
  ,6%coeff1
  ,8%coeff2
  ,2%coeff3
  ,7%coeff4
  ,3%exponent1
  }

  \mailentry{B%form
  ,5%coeff1
  ,9%coeff2
  ,3%coeff3
  ,5%coeff4
  ,5%exponent1
  }
\end{document}

At the start of the \mailrepeated code is the macro \setcounter{page}{1}, which resets the page number to 1; otherwise, Form B would start on Page 3. Also, I ended the \mailrepeated code with a \newpage, ensuring that each version is on a separate page.

If you print \(\lceil N/2\rceil\) copies of the resulting PDF (where N is the number of students in your course), two-sided, then the pile of quizzes will be alternated by version as they come out of the printer, ready to hand out to your class.

LaTeX menukeys package

I’d like to put in a quick word in favor the LaTeX menukeys package. This package makes really nice menu sequences, which is useful when you have to explain how to use software.

For example, \menu[>]{Tools > Web Developer > Page Source} produces:

Adventures in TikZ: tkz-graph

The other day, I was writing some lecture notes for my linear algebra class, and wanted to create the following diagram (to illustrate the concept of a Markov chain):

I had a very limited time in which to finish these notes. Fortunately, I found the tkz-graph package, which made this a snap:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{fouriernc}
\usepackage{tkz-graph}

\begin{document}
\begin{tikzpicture}
\SetGraphUnit{5}

\Vertex[x=0, y=10]{0 points};
\Vertex[x=0, y=5]{1 point};
\Vertex[x=0, y=0]{Win};
\Vertex[x=5, y=5]{Lose};

\Edge[style ={->}, label={$1/3$}]({0 points})({1 point});
\Edge[style ={->}, label={$1/3$}]({1 point})({Win});
\Edge[style ={->}, label={$1/6$}]({0 points})({Lose});
\Edge[style ={->}, label={$1/6$}]({1 point})({Lose});

\Loop[style ={->}, label={$1/2$}, labelstyle={fill=white}]({0 points});
\Loop[style ={->}, label={$1/2$}, labelstyle={fill=white}]({1 point});
\Loop[style ={->}, label={$1$}, dir=EA, labelstyle={fill=white}]({Lose});
\Loop[style ={->}, label={$1$}, labelstyle={fill=white}]({Win});

\end{tikzpicture}
\end{document}

You don’t even have to specify the locations of the vertices; you can throw caution to the wind and have LaTeX decide where to place them! (I am a bit too much of a perfectionist for that.)

One slight issue I had was that the documentation for this package (at least on my computer, as retrieved by texdoc) was in French. Fortunately, I seem to have retained enough knowledge since I took the French language exam as a grad student that I could read most of the documentation.

SageTeX is awesome!

For a long time, I have been a user of the math software system Sage, and for a longer time, I have been a user of LaTeX. So, it’s with some embarrassment that I report that I only recently discovered the awesomeness that is SageTeX, a LaTeX package that allows your LaTeX document to run Sage code and include the results.

I often use Sage to create plots for use in my lectures or printed class materials. Previously, my workflow was as follows:

  1. Create the graphic by running commands in the Sage notebook.
  2. Use the save command to save the graphic as a PDF, usually with a filename based on my LaTeX source file’s name (e.g. m160-sp13-mid2-practice-1.pdf, for use in the LaTeX document with source file m160-sp13-mid2-practice.tex).
  3. Save the file in the directory where my LaTeX source file lives.
  4. \includegraphics, FTW!

Like most teachers, every time I teach a course I’ve taught before, I like to reuse old materials, often after improving them or adjusting them to suit the new class. Therefore, it’s good to record the exact Sage commands somewhere, as opposed to just keeping the graphic file, in case I want to modify the graphic. One way you can do this is to paste the Sage commands as a comment in the LaTeX file. This has the advantage of allowing future tweaks to be recorded in your version control system. (And you really should be using a version control system, so that way you won’t be afraid to make changes to your document.) Unfortunately, modifications then mean a lot of copy-and-pasting: you have to modify the code in the Sage notebook, and then copy-and-paste the modifications to the comments in the LaTeX document, or vice-versa. And then you have to save another version of your graphic from the browser. What a headache!

SageTeX makes this a lot easier. When I want to put a Sage plot in my document, I can put the Sage commands right in the document:

\begin{sagesilent}
var('x,y')
gfx = implicit_plot((x + 1)*(x^2 + y^2) == 3*x^2, (x, -2, 2),(y, -2, 2), axes=true, frame=false)
gfx = gfx + list_plot([(1/2, -1/2)], size=50)
save(gfx, "m160-sp13-mid2-practice-1.pdf", figsize=[3, 3])
\end{sagesilent}

\item (15 points) 
Consider the curve with the equation 
$(x + 1)(x^2 + y^2) = 3x^2$ (shown below). 
Use implicit differentation to find $\tfrac{dy}{dx}$, 
and then find an equation for the tangent line 
of the curve at the point
$\left(\tfrac{1}{2},-\tfrac{1}{2}\right)$.\\
\includegraphics[width=3 in]{m160-sp13-mid2-practice-1.pdf}

When you compile your document with pdflatex, it creates a Sage script file titled (in this case) m160-sp13-mid2-practice.sagetex.py. Compiling this with Sage will create (or update) the file m160-sp13-mid2-practice-1.pdf, which you can include (or update) by running pdflatex again!

That’s pretty awesome.