“10 PRINT” in PostScript

Back in May, I posted a LaTeX document using TikZ to implement the Commodore 64 BASIC program:

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

The amusement factor (for me) is due to LaTeX's ability to generate pseudorandom numbers, which may be surprising to some, especially those who think of LaTeX documents as static (deterministic) documents and not computer programs.

PostScript can also generate pseudorandom numbers, and hence I present "10 PRINT" in PostScript:


% Implementation of "10 PRINT" in PostScript
% Christopher Phan, cphan@chrisphan.com
% 2019-02-17

% Draw frame around page

  36 36 moveto % 36 pt = 0.5 in
  36 756 lineto % 756 pt = 10.5 in
  576 756 lineto % 576 pt = 8 in
  576 36 lineto

% each slash will occupy a 0.25 in x 0.25 in square

36 18 558 { % 18 pt = 0.25 in
  /x exch def
  36 18 738 {
    /y exch def
      /u rand 2 mod 18 mul def
      x y u add moveto
      x 18 add y 18 u sub add lineto
    closepath stroke
  } for
} for


Example output:

“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):
        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:





    % 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

        % 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);



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

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



    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




  %% Draw a square:
  \vskip 1 em
    \draw (0, 0) -- (1, 0)
      -- (1, 1) -- (0, 1) -- cycle;
  \vskip 1 em





This produces:


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.


  • 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,

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):


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:


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


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

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


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



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



  %%% Mail merge info:

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



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:

Why I use version control

Christophers-MacBook-Pro:t_test chris$ cp t_test3.pg inclass_t_test2.pg

Oh, crap! I wanted to copy that to inclass_t_test3.pg, not overwrite inclass_t_test2.pg!

Christophers-MacBook-Pro:t_test chris$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

        modified: inclass_t_test2.pg

no changes added to commit (use "git add" and/or "git commit -a")
Christophers-MacBook-Pro:t_test chris$ git checkout -- inclass_t_test2.pg
Christophers-MacBook-Pro:t_test chris$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean


Christophers-MacBook-Pro:t_test chris$ cp t_test3.pg inclass_t_test3.pg

I’ve (mostly) stopped using Facebook

I have mostly stopped using Facebook. I’ve only made two posts to my own timeline since the beginning of the year, and one was to update my bio with a message explaining that I’ve stopped using Facebook (which I will probably edit to include a link to this post). I’m not a “Facebook vegan”: I still log in (occasionally) and comment or like others’ posts (even less occasionally). I also occasionally make posts for various organizations with which I’m involved (but I post them to those organizations’ pages). But I don’t log in daily (or even weekly), as I used to do.

At this moment, I’m not going to write a long essay about why I’ve (mostly) stopped using Facebook, and I’m not going to tell everyone else they should, either. It’s true that I have some serious concerns about Facebook and its impact on the world, many of which have been explained by Cory Doctorow better than I could. However, my main reason for (mostly) eschewing Facebook is personal: I became convinced late last year that my use of Facebook was harmful to my mental health, and drastically reducing my participation with Facebook has been a positive change for me.

So, please don’t take it personally if I don’t respond to your friend request, comment, or post in which you tagged me. (It’s likely I didn’t see it) And if you want to communicate with me, you’ll have much better luck if you use email or phone, rather than Facebook.

Some politics observations, 2017-02-28

Some observations:

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:



\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});


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.

It’s been a long time

It’s been a long time (over a year) since I’ve posted on this blog, because I have (to put it mildly) been very busy with other responsibilities and passions that have taken me away from blogging. Also, I serve as a (low-level, volunteer-basis) officer in a political party, and as a result, I am sometimes reluctant to post my opinions in public, for fear that they might be taken (or portrayed) as official statements, despite my disclaimer (which, to be clear, says that everything written here is my personal opinion and does not reflect the position of my employer or any organization of which I am a member).

However, we are now facing a national emergency, and it is important for people to speak out. And I’ve decided that I distrust Twitter and Facebook as platforms for doing so (a topic on which I will elaborate later), leading to my desire to start writing again here. I certainly don’t have time for this, but I am going to try to make the time, hopefully posting here more frequently than once every two years.

I have also added https/SSL to this blog, using Let’s Encrypt. I took this step a few months ago, right as the national emergency began, and promptly could not log into the interface for this blog. Because I was (and continue to be) so busy, I put off fixing the problem, only to discover that the problem seems to have fixed itself. Go figure.

While I do plan on talking about politics on this blog, I also have other interests (mathematics, for example), and so I will be posting on these as well.

By the way, I don’t have time for comment moderation, so I don’t plan to enable comments on my posts.

Book recommendation: How Not to Be Wrong

Today, I finished reading How Not to Be Wrong: The Power of Mathematical Thinking by Jordan Ellenberg. This is a very enjoyable, very well-written, general-audience book about mathematics, which I recommend whole-heartedly.

Ellenberg, a math professor at the University of Wisconsin, does a great job weaving together a plethora of mathematical topics, including non-Euclidean geometry, probability, statistics, and mathematical analysis of voting systems. He writes in a way that someone who only vaguely remembers—or never really understood—high school algebra would be able to follow and enjoy. His exposition is made more lively by a cast of historical and contemporary characters, some famous and some primarily known only to mathematicians, including Abraham Wald, Bernhard Riemann, Teddy Roosevelt, Francis Galton, Voltaire, Nicolas de Condorcet, David Hilbert, Ronald Fisher, Antonin Scalia, and Nate Silver. (My favorite line in the book is the one in which Ellenberg describes Silver as a “Kurt Cobain of probability.”)

The best part of the book is about how the Massachusetts Lottery ran a game in which it was occasionally profitable to play (that is, there were some drawings in which the expected value of a ticket’s winnings was higher than the price of a ticket). Of course, some smart people (e.g. an MIT student) figured this out and recruited investors to buy absurd numbers of tickets for the profitable drawings. In the course of telling this story, Ellenberg weaves in discussions of finite geometries and error-correcting codes, both of which are relevant in describing how one buys thousands of lottery tickets without accidentally having to split winnings with yourself.

I think it would be awesome to use this book in a gen-ed math class.