<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="../feed.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Susam's Python Pages</title>
  <subtitle>Feed for Susam's Python Pages</subtitle>
  <link href="https://susam.net/"/>
  <link href="https://susam.net/tag/python.xml" rel="self"/>
  <id>https://susam.net/tag/python.xml</id>
  <updated>2025-12-14T00:00:00Z</updated>
  <author><name>Susam Pal</name></author>
  <entry>
    <title>Mark V. Shaney Junior 0.2.0</title>
    <link href="https://susam.net/code/news/mvs/0.2.0.html"/>
    <id>urn:uuid:e8c48bfa-5413-4d14-8129-748092bdabee</id>
    <updated>2025-12-14T00:00:00Z</updated>
    <content type="html">
<!-- BEGIN HTML -->
&lt;p&gt;
  Mark V. Shaney Junior 0.2.0 is the second release of this little
  Markov gibberish generator.  This release brings two small changes.
  First, it now reads the training data from standard input instead of
  a hardcoded file.  Second, the program filename has been changed
  from &lt;code&gt;mvs.py&lt;/code&gt; to &lt;code&gt;mvs&lt;/code&gt; to reflect that it is
  an executable file and can be run as &lt;code&gt;./mvs&lt;/code&gt; on most Unix
  and Linux systems.
&lt;/p&gt;
&lt;p&gt;
  The source and a detailed documentation for this project are
  available at &lt;a href=&quot;https://github.com/susam/mvs&quot;&gt;github.com/susam/mvs&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
  See also
  &lt;a href=&quot;https://susam.net/fed-24-years-of-posts-to-markov-model.html&quot;&gt;this
  related blog post&lt;/a&gt; and a
  &lt;a href=&quot;https://news.ycombinator.com/item?id=46257607&quot;&gt;discussion
  on Hacker News&lt;/a&gt; about it.
&lt;/p&gt;
<!-- ### -->
&lt;p&gt;
  &lt;a href="https://susam.net/code/news/mvs/0.2.0.html"&gt;Read on website&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/python.html&quot;&gt;#python&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/programming.html&quot;&gt;#programming&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/technology.html&quot;&gt;#technology&lt;/a&gt;
&lt;/p&gt;
<!-- END HTML -->
    </content>
  </entry>
  <entry>
    <title>Fed 24 Years of My Blog Posts to a Markov Model</title>
    <link href="https://susam.net/fed-24-years-of-posts-to-markov-model.html"/>
    <id>urn:uuid:4501f3b3-7e6c-4109-b15c-c38627658cff</id>
    <updated>2025-12-13T00:00:00Z</updated>
    <content type="html">
<!-- BEGIN HTML -->
&lt;p&gt;
  Yesterday I shared a little program called &lt;em&gt;Mark V. Shaney
  Junior&lt;/em&gt; at
  &lt;a href=&quot;https://github.com/susam/mvs&quot;&gt;github.com/susam/mvs&lt;/a&gt;.  It
  is a minimal implementation of a Markov text generator inspired by
  the legendary Mark V. Shaney program from the 1980s.  Mark V. Shaney
  was a synthetic Usenet user that posted messages to various
  newsgroups using text generated by a Markov model.  See the
  Wikipedia article
  &lt;a href=&quot;https://en.wikipedia.org/wiki/Mark_V._Shaney&quot;&gt;Mark
  V. Shaney&lt;/a&gt; for more details about it.  In this post, I will
  discuss my implementation of the model, explain how it works and
  share some of the results produced by it.
&lt;/p&gt;
&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#recreational-programming&quot;&gt;Recreational Programming&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#gibberish&quot;&gt;Gibberish&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#markov-property&quot;&gt;The Markov Property&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#some-more-gibberish&quot;&gt;Some More Gibberish&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;recreational-programming&quot;&gt;Recreational Programming&lt;/h2&gt;
&lt;p&gt;
  The program I shared yesterday has only about
  &lt;a href=&quot;https://github.com/susam/mvs/blob/main/mvs&quot;&gt;30 lines of
  Python&lt;/a&gt; and favours simplicity over efficiency.  Even if you have
  never worked with Markov models before, as long as you know some
  Python programming, I am quite confident that it will take you less
  than 20 minutes to understand the whole program and make complete
  sense of it.  I also offer an explanation
  &lt;a href=&quot;#the-markov-property&quot;&gt;further below&lt;/a&gt; in this post.
&lt;/p&gt;
&lt;p&gt;
  As a hobby, I often engage in exploratory programming where I write
  computer programs not to solve a specific problem but simply to
  explore a particular idea or topic for the sole purpose of
  recreation.  I must have written small programs to explore Markov
  chains for various kinds of state spaces over a dozen times by now.
  Every time, I just pick my last experimental code and edit it to
  encode the new state space I am exploring.  That&apos;s usually my
  general approach to such one-off programs.  I have hundreds of tiny
  little experimental programs lying on my disk at any given time.
&lt;/p&gt;
&lt;p&gt;
  Once in a while, I get the itch to take one of those exploratory
  programs, give it some finishing touches, wrap it up in a nice Git
  repo along with a &lt;code&gt;README.md&lt;/code&gt;, &lt;code&gt;CHANGES.md&lt;/code&gt;
  and the whole shebang and share it on
  &lt;a href=&quot;https://github.com/susam&quot;&gt;github.com/susam&lt;/a&gt; and
  &lt;a href=&quot;https://codeberg.org/susam&quot;&gt;codeberg.org/susam&lt;/a&gt;.  The
  Mark V. Shaney Junior program that I shared yesterday happened to be
  one such exercise.
&lt;/p&gt;
&lt;h2 id=&quot;gibberish&quot;&gt;Gibberish&lt;/h2&gt;
&lt;p&gt;
  If you scroll down the
  &lt;a href=&quot;https://github.com/susam/mvs#readme&quot;&gt;README&lt;/a&gt; of this
  project, you&apos;ll find some nice examples of the gibberish produced by
  this program.  The first few examples there are the result of
  training the model on &lt;em&gt;A Christmas Carol&lt;/em&gt; by Charles Dickens,
  one of my favourite authors.  It is often said that Dickens never
  used fewer words when more would suffice.  So I thought there
  couldn&apos;t be a better piece of text when it comes to testing out my
  tiny Markov model.  I&apos;ll not reproduce the generated text examples
  here for the sake of brevity.  If you are interested to take a look,
  just head over to the
  &lt;a href=&quot;https://github.com/susam/mvs#gibberish&quot;&gt;Gibberish&lt;/a&gt;
  section of the README.
&lt;/p&gt;
&lt;p&gt;
  Soon after sharing the project, I wondered what kind of gibberish it
  would produce if I fed all 24 years of my blog
  &lt;a href=&quot;pages.html&quot;&gt;posts and pages&lt;/a&gt; into the program.
  Well, here&apos;s one of the results:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;./mvs &amp;lt; susam.txt&lt;/kbd&gt;
while a query replace operation is approved by the user. The above
variable defines the build job. It can be incredibly useful while
working on assembly language and machine code. In fact, all internal
resources like the result to refine the search prompt changes from
bck-i-search: to fwd-i-search:. Now type C-SPC (i.e. ctrl+space) to
set a mark causes Emacs to use 32-bit registers like EBP, ESP,
etc. Thus the behaviour is undefined. Such code may behave differently
when compiled with the readily available GNU tools like the shape
of 8. Flipping &quot;P&quot; horizontally makes it a proper quine: cat $0&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  This is the text that comes out after the program consumes over 200
  posts consisting of about 200,000 words.  My blog also has
  a &lt;a href=&quot;comments/&quot;&gt;comments section&lt;/a&gt; with over 500
  comments consisting of about 40,000 words.  All comments were
  excluded while training the model.  Here is another output example:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;./mvs &amp;lt; susam.txt&lt;/kbd&gt;
enjoy asking &quot;what happens if&quot; and then type M-x zap-up-to-char RET
b. The buffer for this specific video, the actual fare for 8.3 km and
11 are all written from scratch. No prior knowledge is expected to
slow down in future. For now, I will add a statement like x =
0.999..., the inner corner square as discussed in the code segment
into the REPL window. Unlike Slimv, Vlime can work with and debug
executable files, it can be more convenient. M-x: Execute Extended
Command The key sequence M-q invokes the command cat and type TAB to
indent the current&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  Here is a particularly incoherent but amusing one:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;./mvs &amp;lt; susam.txt&lt;/kbd&gt;
Then open a new Lisp source file and the exact answer could harm
students&apos; self-esteem. Scientists have arbitrarily assumed that an
integral domain. However, the string and comment text. To demonstrate
how a build job can trigger itself, pass input to standard output or
standard error), Eshell automatically runs the following command in
Vim and Emacs will copy the message length limit of 512 characters,
etc. For example, while learning to play the game between normal mode
to move the point is on an old dictionary lying around our house and
that is moving to the small and supportive community&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  No, I have never said anywhere that opening a Lisp source file could
  harm anyone&apos;s self-esteem.  The text generator has picked up the
  &apos;Lisp source file&apos; phrase from my
  &lt;a href=&quot;lisp-in-vim.html&quot;&gt;Lisp in Vim&lt;/a&gt; post and the
  &apos;self-esteem&apos; bit from the &lt;a href=&quot;from-perl-to-pi.html&quot;&gt;From Perl
  to Pi&lt;/a&gt; post.
&lt;/p&gt;
&lt;h2 id=&quot;markov-property&quot;&gt;The Markov Property&lt;/h2&gt;
&lt;p&gt;
  By default, this program looks at trigrams (all sequences of three
  adjacent words) and creates a map where the first two words of the
  trigram are inserted as the key and the third word is appended to
  its list value.  This map is the model.  In this way, the model
  captures each pair of adjacent words along with the words that
  immediately follow each pair.  The text generator first chooses a
  key (a pair of words) at random and selects a word that follows.  If
  there are multiple followers, it picks one uniformly at random.  It
  then repeats this process with the most recent pair of words,
  consisting of one word from the previous pair and the word that was
  just picked.  It continues to do this until it can no longer find a
  follower or a fixed word limit (100 by default) is reached.  That is
  pretty much the whole algorithm.  There isn&apos;t much more to it.  It
  is as simple as it gets.  For that reason, I often describe a simple
  Markov model like this as the &apos;hello, world&apos; for language models.
&lt;/p&gt;
&lt;p&gt;
  If the same trigram occurs multiple times in the training data, the
  model records the follower word (the third word) multiple times in
  the list associated with the key (the first two words).  This
  representation can be optimised, of course, by keeping frequencies
  of the follower words rather than duplicating them in the list, but
  that is left as an exercise to the reader.  In any case, when the
  text generator chooses a follower for a given pair of words, a
  follower that occurs more frequently after that pair has a higher
  probability of being chosen.  In effect, the next word is sampled
  based only on the previous two words and not on the full history of
  the generated text.  This memoryless dependence on the current state
  is what makes the generator Markov.  Formally, for a discrete-time
  stochastic process, the Markov property can be expressed as

  \[
    P(X_{n+1} \mid X_n, X_{n-1}, \ldots, X_1) = P(X_{n+1} \mid X_n).
  \]

  where \( X_n \) represents the \( n \)th state.  In our case, each
  state \( X_n \) is a pair of words \( (w_{n-1}, w_{n}) \) but the
  state space could just as well consist of other objects, such as a
  pair of characters, pixel values or musical notes.  The sequence of
  states \( (X_1, X_2, \dots) \) visited by the program forms a Markov
  chain.  The left-hand side of the equation denotes the conditional
  distribution of the next state \( X_{n+1} \) given the entire
  history of states \( X_1, X_2, \dots, X_n, \) while the right-hand
  side conditions only on the current state \( X_n.  \)  When both are
  equal, it means that the probability of the next state depends only
  on the current state and not on the earlier states.  This is the
  Markov property.  It applies to the text generation process only,
  not the training data.  The training data is used only to estimate
  the transition probabilities of the model.
&lt;/p&gt;
&lt;h2 id=&quot;some-more-gibberish&quot;&gt;Some More Gibberish&lt;/h2&gt;
&lt;p&gt;
  In 2025, given the overwhelming popularity of large language models
  (LLMs), Markov models like this look unimpressive.  Unlike LLMs, a
  simple Markov model cannot capture global structure or long-range
  dependencies within the text.  It relies entirely on local word
  transition statistics.  Also, these days, one hardly needs a Markov
  model to generate gibberish; social media provides an ample supply.
  Nevertheless, I think the simplicity of its design and
  implementation serves as a good entry point into language models.
&lt;/p&gt;
&lt;p&gt;
  In my implementation, the number of words in the key of the map can
  be set via command line arguments.  By default, it is 2 as described
  above.  This value is also known as the order of the model.  So by
  default the order is 2.  If we increase it to, say, 3 or 4, the
  generated text becomes a little more coherent.  Here is one such
  example:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;./mvs 4 &amp;lt; susam.txt&lt;/kbd&gt;
It is also possible to search for channels by channel names. For
example, on Libera Chat, to search for all channels with &apos;python&apos; in
its name, enter the IRC command: /msg alis list python. Although I
have used Libera Chat in the examples above, there are plenty of
infinite fields, so they must all be integral domains too. Consider
the field of rational numbers Q. Another quick way to arrive at this
fact is to observe that when one knight is placed on a type D square,
only two positions for the second knight such that the two knights
attack&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  Except for a couple of abrupt and meaningless transitions, the text
  is mostly coherent.  We need to be careful about not increasing the
  order too much.  In fact, if we increase the order of the model to
  5, the generated text becomes very dry and factual because it begins
  to quote large portions of the blog posts verbatim.  Not much fun
  can be had with that.
&lt;/p&gt;
&lt;p&gt;
  Before I end this post, let me present one final example where I ask
  it to generate text from an initial prompt:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;./mvs 2 100 &apos;Finally we&apos; &amp;lt; susam.txt&lt;/kbd&gt;
Finally we divide this number by a feed aggregrator for Emacs-related
blogs. The following complete key sequences describe the effects of
previous evaluations shall have taken a simple and small to contain
bad content. This provides an interactive byte-compiled Lisp function
in MATLAB and GNU bash 5.1.4 on Debian is easily reproducible in
Windows XP. Older versions might be able to run that server for me it
played a significant burden on me as soon as possible. C-u F: Visit
the marked files or directories in the sense that it was already
initiated and we were to complete the proof.&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  Apparently, this is how I would sound if I ever took up speaking
  gibberish!
&lt;/p&gt;
<!-- ### -->
&lt;p&gt;
  &lt;a href="https://susam.net/fed-24-years-of-posts-to-markov-model.html"&gt;Read on website&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/python.html&quot;&gt;#python&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/programming.html&quot;&gt;#programming&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/technology.html&quot;&gt;#technology&lt;/a&gt;
&lt;/p&gt;
<!-- END HTML -->
    </content>
  </entry>
  <entry>
    <title>Mark V. Shaney Junior 0.1.0</title>
    <link href="https://susam.net/code/news/mvs/0.1.0.html"/>
    <id>urn:uuid:0c29c75e-7019-45d9-a4bf-8c397533b11a</id>
    <updated>2025-12-12T00:00:00Z</updated>
    <content type="html">
<!-- BEGIN HTML -->
&lt;p&gt;
  Mark V. Shaney Junior is a minimal implementation of a Markov
  gibberish generator inspired by the legendary Mark V. Shaney program
  from the 1980s.  Mark V. Shaney was a synthetic Usenet user in the
  1980s that posted messages to newsgroups using text generated by a
  Markov chain program.  See the Wikipedia
  article &lt;a href=&quot;https://en.wikipedia.org/wiki/Mark_V._Shaney&quot;&gt;Mark
  V. Shaney&lt;/a&gt; for more details.
&lt;/p&gt;
&lt;p&gt;
  This release introduces the program
  &lt;a href=&quot;https://github.com/susam/mvs/blob/main/mvs.py&quot;&gt;mvs.py&lt;/a&gt;
  that implements a similar Markov text generator.  It reads a text
  corpus of text from standard input, build an internal Markov model
  and then generate text using the model.
&lt;/p&gt;
&lt;p&gt;
  Please visit
  &lt;a href=&quot;https://github.com/susam/mvs&quot;&gt;github.com/susam/mvs&lt;/a&gt;
  for the source code and some output examples.
&lt;/p&gt;
<!-- ### -->
&lt;p&gt;
  &lt;a href="https://susam.net/code/news/mvs/0.1.0.html"&gt;Read on website&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/python.html&quot;&gt;#python&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/programming.html&quot;&gt;#programming&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/technology.html&quot;&gt;#technology&lt;/a&gt;
&lt;/p&gt;
<!-- END HTML -->
    </content>
  </entry>
  <entry>
    <title>Fizz Buzz with Cosines</title>
    <link href="https://susam.net/fizz-buzz-with-cosines.html"/>
    <id>urn:uuid:91190abf-f9ce-4d98-82b9-7fabd6bbdb14</id>
    <updated>2025-11-20T00:00:00Z</updated>
    <content type="html">
<!-- BEGIN HTML -->
&lt;p&gt;
  Fizz Buzz is a counting game that has become oddly popular in the
  world of computer programming as a simple test of basic programming
  skills.  The rules of the game are straightforward.  Players say the
  numbers aloud in order beginning with one.  Whenever a number is
  divisible by 3, they say &apos;Fizz&apos; instead.  If it is divisible by 5,
  they say &apos;Buzz&apos;.  If it is divisible by both 3 and 5, the player
  says both &apos;Fizz&apos; and &apos;Buzz&apos;.  Here is a typical Python program that
  prints this sequence:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for n in range(1, 101):
    if n % 15 == 0:
        print(&apos;FizzBuzz&apos;)
    elif n % 3 == 0:
        print(&apos;Fizz&apos;)
    elif n % 5 == 0:
        print(&apos;Buzz&apos;)
    else:
        print(n)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  Here is the output:
  &lt;a href=&quot;files/blog/fizz-buzz.txt&quot;&gt;fizz-buzz.txt&lt;/a&gt;.  Can we make
  the program more complicated?  The words &apos;Fizz&apos;, &apos;Buzz&apos; and
  &apos;FizzBuzz&apos; repeat in a periodic manner throughout the sequence.
  What else is periodic?  Trigonometric functions!  Perhaps we can use
  trigonometric functions to encode all four rules of the sequence in
  a single closed-form expression.  That is what we are going to
  explore in this article, for fun and no profit.
&lt;/p&gt;
&lt;p&gt;
  By the end, we will obtain a discrete Fourier series that can take
  any integer \( n \) and select the corresponding text to be printed.
  In fact, we will derive it using two different methods.  First, we
  will follow a long-winded but hopefully enjoyable approach that
  relies on a basic understanding of complex exponentiation, geometric
  series and trigonometric functions.  Then, we will obtain the same
  result through a direct application of the discrete Fourier
  transform.
&lt;/p&gt;
&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#definitions&quot;&gt;Definitions&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#symbol-functions&quot;&gt;Symbol Functions&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#index-function&quot;&gt;Index Function&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#fizz-buzz-sequence&quot;&gt;Fizz Buzz Sequence&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#from-indicator-functions-to-cosines&quot;&gt;From Indicator Functions to Cosines&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#indicator-functions&quot;&gt;Indicator Functions&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#complex-exponentials&quot;&gt;Complex Exponentials&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#cosines&quot;&gt;Cosines&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#dft&quot;&gt;Discrete Fourier Transform&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#one-period-of-fizz-buzz&quot;&gt;One Period of Fizz Buzz&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#fourier-coefficients&quot;&gt;Fourier Coefficients&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#inverse-transform&quot;&gt;Inverse Transform&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;definitions&quot;&gt;Definitions&lt;/h2&gt;
&lt;p&gt;
  Before going any further, we establish a precise mathematical
  definition for the Fizz Buzz sequence.  We begin by introducing a
  few functions that will help us define the Fizz Buzz sequence later.
&lt;/p&gt;
&lt;h3 id=&quot;symbol-functions&quot;&gt;Symbol Functions&lt;/h3&gt;
&lt;p&gt;
  We define a set of four functions \( \{ s_0, s_1, s_2, s_3 \} \) for
  integers \( n \) by:

  \begin{align*}
    s_0(n) &amp;amp;= n, \\
    s_1(n) &amp;amp;= \mathtt{Fizz}, \\
    s_2(n) &amp;amp;= \mathtt{Buzz}, \\
    s_3(n) &amp;amp;= \mathtt{FizzBuzz}.
  \end{align*}

  We call these the symbol functions because they produce every term
  that appears in the Fizz Buzz sequence.  The symbol function \( s_0
  \) returns \( n \) itself.  The functions \( s_1, \) \( s_2 \) and
  \( s_3 \) are constant functions that always return the literal
  words \( \mathtt{Fizz}, \) \( \mathtt{Buzz} \) and \(
  \mathtt{FizzBuzz} \) respectively, no matter what the value of \( n
  \) is.
&lt;/p&gt;
&lt;h3 id=&quot;index-function&quot;&gt;Index Function&lt;/h3&gt;
&lt;p&gt;
  We define a function \( f(n) \) for integer \( n \) by

  \[
    f(n) = \begin{cases}
      1 &amp;amp; \text{if } 3 \mid n \text{ and } 5 \nmid n, \\
      2 &amp;amp; \text{if } 3 \nmid n \text{ and } 5 \mid n, \\
      3 &amp;amp; \text{if } 3 \mid n \text{ and } 5 \mid n, \\
      0 &amp;amp; \text{otherwise}.
    \end{cases}
  \]

  The notation \( m \mid n \) means that the integer \( m \) divides
  the integer \( n, \) i.e. \( n \) is a multiple of \( m.  \)
  Equivalently, there exists an integer \( c \) such that \( n = cm
 .  \)  Similarly, \( m \nmid n \) means that \( m \) does not divide
  \( n, \) i.e. \( n \) is not a multiple of \( m.  \)
&lt;/p&gt;
&lt;p&gt;
  This function covers all four conditions involved in choosing the \(
  n \)th item of the Fizz Buzz sequence.  As we will soon see, this
  function tells us which of the four symbol functions produces the \(
  n \)th item of the Fizz Buzz sequence.  For this reason, we call \(
  f(n) \) the index function.
&lt;/p&gt;
&lt;h3 id=&quot;fizz-buzz-sequence&quot;&gt;Fizz Buzz Sequence&lt;/h3&gt;
&lt;p&gt;
  We now define the Fizz Buzz sequence as the sequence

  \[
    (s_{f(n)}(n))_{n = 1}^{\infty}
  \]

  We can expand the first few terms of the sequence explicitly as
  follows:

  \begin{align*}
    (s_{f(n)}(n))_{n = 1}^{\infty}
    &amp;amp;= (s_{f(1)}(1), \; s_{f(2)}(2), \; s_{f(3)}(3), \; s_{f(4)}(4), \;
            s_{f(5)}(5), \; s_{f(6)}(6), \; s_{f(7)}(7), \; \dots) \\
    &amp;amp;= (s_0(1), \; s_0(2), \; s_1(3), \; s_0(4),
            s_2(5), \; s_1(6), \; s_0(7), \; \dots) \\
    &amp;amp;= (1, \; 2, \; \mathtt{Fizz}, \; 4, \;
            \mathtt{Buzz}, \; \mathtt{Fizz}, \; 7, \; \dots).
  \end{align*}

  Note how the function \( f(n) \) produces an index \( i \) which we
  then use to select the symbol function \( s_i(n) \) to produce the
  \( n \)th term of the sequence.  This is precisely why we decided to
  call \( f(n) \) the index function while defining it in the previous
  section.
&lt;/p&gt;
&lt;h2 id=&quot;from-indicator-functions-to-cosines&quot;&gt;From Indicator Functions to Cosines&lt;/h2&gt;
&lt;p&gt;
  Here we discuss the first method of deriving our closed form
  expression, starting with indicator functions and rewriting them
  using complex exponentials and cosines.
&lt;/p&gt;
&lt;h3 id=&quot;indicator-functions&quot;&gt;Indicator Functions&lt;/h3&gt;
&lt;p&gt;
  Here is the index function \( f(n) \) from the previous section with
  its cases and conditions rearranged to make it easier to spot
  interesting patterns:

  \[
    f(n) = \begin{cases}
      0 &amp;amp; \text{if } 5 \nmid n \text{ and } 3 \nmid n, \\
      1 &amp;amp; \text{if } 5 \nmid n \text{ and } 3 \mid n, \\
      2 &amp;amp; \text{if } 5 \mid n \text{ and } 3 \nmid n, \\
      3 &amp;amp; \text{if } 5 \mid n \text{ and } 3 \mid n.
    \end{cases}
  \]

  This function helps us select another function \( s_{f(n)}(n) \)
  which in turn determines the \( n \)th term of the Fizz Buzz
  sequence.  Our goal now is to replace this piecewise formula with a
  single closed-form expression.  To do so, we first define indicator
  functions \( I_m(n) \) as follows:

  \[
    I_m(n) = \begin{cases}
      1 &amp;amp; \text{if } m \mid n, \\
      0 &amp;amp; \text{if } m \nmid n.
    \end{cases}
  \]

  The formula for \( f(n) \) can now be written as:

  \[
    f(n) = \begin{cases}
      0 &amp;amp; \text{if } I_5(n) = 0 \text{ and } I_3(n) = 0, \\
      1 &amp;amp; \text{if } I_5(n) = 0 \text{ and } I_3(n) = 1, \\
      2 &amp;amp; \text{if } I_5(n) = 1 \text{ and } I_3(n) = 0, \\
      3 &amp;amp; \text{if } I_5(n) = 1 \text{ and } I_3(n) = 1.
    \end{cases}
  \]

  Do you see a pattern?  Here is the same function written as a table:
&lt;/p&gt;
&lt;table class=&quot;grid center textcenter&quot;&gt;
  &lt;tr&gt;
    &lt;th&gt;\( I_5(n) \)&lt;/th&gt;
    &lt;th&gt;\( I_3(n) \)&lt;/th&gt;
    &lt;th&gt;\( f(n) \)&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;\( 0 \)&lt;/td&gt;
    &lt;td&gt;\( 0 \)&lt;/td&gt;
    &lt;td&gt;\( 0 \)&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;\( 0 \)&lt;/td&gt;
    &lt;td&gt;\( 1 \)&lt;/td&gt;
    &lt;td&gt;\( 1 \)&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;\( 1 \)&lt;/td&gt;
    &lt;td&gt;\( 0 \)&lt;/td&gt;
    &lt;td&gt;\( 2 \)&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;\( 1 \)&lt;/td&gt;
    &lt;td&gt;\( 1 \)&lt;/td&gt;
    &lt;td&gt;\( 3 \)&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;
  Do you see it now?  If we treat the values in the first two columns
  as binary digits and the values in the third column as decimal
  numbers, then in each row the first two columns give the binary
  representation of the number in the third column.  For example, \(
  3_{10} = 11_2 \) and indeed in the last row of the table, we see the
  bits \( 1 \) and \( 1 \) in the first two columns and the number \(
  3 \) in the last column.  In other words, writing the binary digits
  \( I_5(n) \) and \( I_3(n) \) side by side gives us the binary
  representation of \( f(n).  \)  Therefore

  \[
    f(n) = 2 \, I_5(n) + I_3(n).
  \]

  We can now write a small program to demonstrate this formula:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for n in range(1, 101):
    s = [n, &apos;Fizz&apos;, &apos;Buzz&apos;, &apos;FizzBuzz&apos;]
    i = (n % 3 == 0) + 2 * (n % 5 == 0)
    print(s[i])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  We can make it even shorter at the cost of some clarity:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for n in range(1, 101):
    print([n, &apos;Fizz&apos;, &apos;Buzz&apos;, &apos;FizzBuzz&apos;][(n % 3 == 0) + 2 * (n % 5 == 0)])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  What we have obtained so far is pretty good.  While there is no
  universal definition of a closed-form expression, I think most
  people would agree that the indicator functions as defined above are
  simple enough to be permitted in a closed-form expression.
&lt;/p&gt;
&lt;h3 id=&quot;complex-exponentials&quot;&gt;Complex Exponentials&lt;/h3&gt;
&lt;p&gt;
  In the previous section, we obtained the formula

  \[
    f(n) = I_3(n) + 2 \, I_5(n)
  \]

  which we then used as an index to look up the text to be printed.
  We also argued that this is a pretty good closed-form expression
  already.
&lt;/p&gt;
&lt;p&gt;
  However, in the interest of making things more complicated, we must
  ask ourselves: What if we are not allowed to use the indicator
  functions?  What if we must adhere to the commonly accepted meaning
  of a closed-form expression which allows only finite combinations of
  basic operations such as addition, subtraction, multiplication,
  division, integer exponents and roots with integer index as well as
  functions such as exponentials, logarithms and trigonometric
  functions.  It turns out that the above formula can be rewritten
  using only addition, multiplication, division and the cosine
  function.  Let us begin the translation.  Consider the sum

  \[
    S_m(n) = \sum_{k = 0}^{m - 1} e^{i 2 \pi k n / m},
  \]

  where \( i \) is the imaginary unit and \( n \) and \( m \) are
  integers.  This is a geometric series in the complex plane with
  ratio \( r = e^{i 2 \pi n / m}.  \)  If \( n \) is a multiple of \( m
 , \) then \( n = cm \) for some integer \( c \) and we get

  \[
    r
    = e^{i 2 \pi n / m}
    = e^{i 2 \pi c}
    = 1.
  \]

  Therefore, when \( n \) is a multiple of \( m, \) we get

  \[
    S_m(n)
    = \sum_{k = 0}^{m - 1} e^{i 2 \pi k n / m}
    = \sum_{k = 0}^{m - 1} 1^k
    = m.
  \]

  If \( n \) is not a multiple of \( m, \) then \( r \ne 1 \) and the
  geometric series becomes

  \[
    S_m(n)
    = \frac{r^m - 1}{r - 1}
    = \frac{e^{i 2 \pi n} - 1}{e^{i 2 \pi n / m} - 1}
    = 0.
  \]

  Therefore,

  \[
    S_m(n) = \begin{cases}
      m &amp;amp; \text{if } m \mid n, \\
      0 &amp;amp; \text{if } m \nmid n.
    \end{cases}
  \]

  Dividing both sides by \( m, \) we get

  \[
    \frac{S_m(n)}{m} = \begin{cases}
      1 &amp;amp; \text{if } m \mid n, \\
      0 &amp;amp; \text{if } m \nmid n.
    \end{cases}
  \]

  But the right-hand side is \( I_m(n).  \)  Therefore

  \[
    I_m(n)
    = \frac{S_m(n)}{m}
    = \frac{1}{m} \sum_{k = 0}^{m - 1} e^{i 2 \pi k n / m}.
  \]
&lt;/p&gt;
&lt;h3 id=&quot;cosines&quot;&gt;Cosines&lt;/h3&gt;
&lt;p&gt;
  We begin with Euler&apos;s formula

  \[
    e^{i x} = \cos x + i \sin x
  \]

  where \( x \) is a real number.  From this formula, we get

  \[
    e^{i x} + e^{-i x} = 2 \cos x.
  \]

  Therefore

  \begin{align*}
    I_3(n)
    &amp;amp;= \frac{1}{3} \sum_{k = 0}^2 e^{i 2 \pi k n / 3} \\
    &amp;amp;= \frac{1}{3} \left( 1 + e^{i 2 \pi n / 3} +
                                  e^{i 4 \pi n / 3} \right) \\
    &amp;amp;= \frac{1}{3} \left( 1 + e^{i 2 \pi n / 3} +
                                  e^{-i 2 \pi n / 3} \right) \\
    &amp;amp;= \frac{1}{3} + \frac{2}{3} \cos \left( \frac{2 \pi n}{3} \right).
  \end{align*}

  The third equality above follows from the fact that \( e^{i 4 \pi n
  / 3} = e^{i 6 \pi n / 3} e^{-i 2 \pi n / 3} = e^{i 2 \pi n} e^{-i 2
  \pi n/3} = e^{-i 2 \pi n / 3} \) when \( n \) is an integer.
&lt;/p&gt;
&lt;p&gt;
  The function above is defined for integer values of \( n \) but we
  can extend its formula to real \( x \) and plot it to observe its
  shape between integers.  As expected, the function takes the value
  \( 1 \) whenever \( x \) is an integer multiple of \( 3 \) and \( 0
  \) whenever \( x \) is an integer not divisible by \( 3.  \)
&lt;/p&gt;
&lt;figure class=&quot;soft&quot;&gt;
  &lt;img src=&quot;files/blog/fizz-buzz-i3.png&quot; alt=&quot;Graph&quot;&gt;
  &lt;figcaption&gt;
    Graph of \( \frac{1}{3} + \frac{2}{3} \cos \left( \frac{2 \pi x}{3} \right) \)
  &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;
  Similarly,

  \begin{align*}
    I_5(n)
    &amp;amp;= \frac{1}{5} \sum_{k = 0}^4 e^{i 2 \pi k n / 5} \\
    &amp;amp;= \frac{1}{5} \left( 1 + e^{i 2 \pi n / 5}
                                + e^{i 4 \pi n / 5}
                                + e^{i 6 \pi n / 5}
                                + e^{i 8 \pi n / 5} \right) \\
    &amp;amp;= \frac{1}{5} \left( 1 + e^{i 2 \pi n / 5}
                                + e^{i 4 \pi n / 5}
                                + e^{-i 4 \pi n / 5}
                                + e^{-i 2 \pi n / 5} \right) \\
    &amp;amp;= \frac{1}{5} + \frac{2}{5} \cos \left( \frac{2 \pi n}{5} \right)
                       + \frac{2}{5} \cos \left( \frac{4 \pi n}{5} \right).
  \end{align*}

  Extending this expression to real values of \( x \) allows us to
  plot its shape as well.  Once again, the function takes the value \(
  1 \) at integer multiples of \( 5 \) and \( 0 \) at integers not
  divisible by \( 5.  \)
&lt;/p&gt;
&lt;figure class=&quot;soft&quot;&gt;
  &lt;img src=&quot;files/blog/fizz-buzz-i5.png&quot; alt=&quot;Graph&quot;&gt;
  &lt;figcaption&gt;
    Graph of \(
      \frac{1}{5}
      + \frac{2}{5} \cos \left( \frac{2 \pi x}{5} \right)
      + \frac{2}{5} \cos \left( \frac{4 \pi x}{5} \right)
    \)
  &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;
  Recall that we expressed \( f(n) \) as

  \[
    f(n) = I_3(n) + 2 \, I_5(n).
  \]

  Substituting these trigonometric expressions yields

  \[
    f(n)
    = \frac{1}{3}
      + \frac{2}{3} \cos \left( \frac{2 \pi n}{3} \right)
      + 2 \cdot \left(
        \frac{1}{5}
        + \frac{2}{5} \cos \left( \frac{2 \pi n}{5} \right)
        + \frac{2}{5} \cos \left( \frac{4 \pi n}{5} \right)
      \right).
  \]

  A straightforward simplification gives

  \[
    f(n)
    = \frac{11}{15}
      + \frac{2}{3} \cos \left( \frac{2 \pi n}{3} \right)
      + \frac{4}{5} \cos \left( \frac{2 \pi n}{5} \right)
      + \frac{4}{5} \cos \left( \frac{4 \pi n}{5} \right).
  \]

  We can extend this expression to real \( x \) and plot it as well.
  The resulting curve takes the values \( 0, 1, 2 \) and \( 3 \) at
  integer points, as desired.
&lt;/p&gt;
&lt;figure class=&quot;soft&quot;&gt;
  &lt;img src=&quot;files/blog/fizz-buzz-f.png&quot; alt=&quot;Graph&quot;&gt;
  &lt;figcaption&gt;
    Graph of \(
      \frac{11}{15} +
      \frac{2}{3} \cos \left( \frac{2 \pi x}{3} \right) +
      \frac{4}{5} \cos \left( \frac{2 \pi x}{5} \right) +
      \frac{4}{5} \cos \left( \frac{4 \pi x}{5} \right)
    \)
  &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;
  Now we can write our Python program as follows:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from math import cos, pi
for n in range(1, 101):
    s = [n, &apos;Fizz&apos;, &apos;Buzz&apos;, &apos;FizzBuzz&apos;]
    i = round(11 / 15 + (2 / 3) * cos(2 * pi * n / 3)
                      + (4 / 5) * cos(2 * pi * n / 5)
                      + (4 / 5) * cos(4 * pi * n / 5))
    print(s[i])&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;dft&quot;&gt;Discrete Fourier Transform&lt;/h2&gt;
&lt;p&gt;
  The keen-eyed might notice that the expression we obtained for \(
  f(n) \) is a discrete Fourier series.  This is not surprising, since
  the output of a Fizz Buzz program depends only on \( n \bmod 15.  \)
  Any function on a finite cyclic group can be written exactly as a
  finite Fourier expansion.  In this section, we obtain \( f(n) \)
  using the discrete Fourier transform.  It is worth mentioning that
  the calculations presented here are quite tedious to do by hand.
  Nevertheless, this section offers a glimpse of how such calculations
  are performed.  By the end, we will arrive at exactly the same \(
  f(n) \) as before.  There is nothing new to discover here.  We
  simply obtain the same result by a more direct but more laborious
  method.  If this doesn&apos;t sound interesting, you may safely skip the
  subsections that follow.
&lt;/p&gt;
&lt;h3 id=&quot;one-period-of-fizz-buzz&quot;&gt;One Period of Fizz Buzz&lt;/h3&gt;
&lt;div style=&quot;display: none&quot;&gt;\( \gdef\arraystretch{1.2} \)&lt;/div&gt;
&lt;p&gt;
  We know that \( f(n) \) is a periodic function with period \( 15.  \)
  To apply the discrete Fourier transform, we look at one complete
  period of the function using the values \( n = 0, 1, \dots, 14.  \)
  Over this period, we have:

  \begin{array}{c|ccccccccccccccc}
      n &amp;amp;  0 &amp;amp;  1 &amp;amp;  2 &amp;amp;  3 &amp;amp;  4
        &amp;amp;  5 &amp;amp;  6 &amp;amp;  7 &amp;amp;  8 &amp;amp;  9
        &amp;amp; 10 &amp;amp; 11 &amp;amp; 12 &amp;amp; 13 &amp;amp; 14 \\
    \hline
    f(n) &amp;amp; 3 &amp;amp;  0 &amp;amp;  0 &amp;amp;  1 &amp;amp;  0
         &amp;amp; 2 &amp;amp;  1 &amp;amp;  0 &amp;amp;  0 &amp;amp;  1
         &amp;amp; 2 &amp;amp;  0 &amp;amp;  1 &amp;amp;  0 &amp;amp;  0
  \end{array}

  The discrete Fourier series of \( f(n) \) is

  \[
    f(n) = \sum_{k = 0}^{14} c_k \, e^{i 2 \pi k n / 15}
  \]

  where the Fourier coefficients \( c_k \) are given by the discrete
  Fourier transform

  \[
    c_k = \frac{1}{15} \sum_{n = 0}^{14} f(n) e^{-i 2 \pi k n / 15}.
  \]

  for \( k = 0, 1, \dots, 14.  \)  The formula for \( c_k \) is called
  the discrete Fourier transform (DFT).  The formula for \( f(n) \) is
  called the inverse discrete Fourier transform (IDFT).
&lt;/p&gt;
&lt;h3 id=&quot;fourier-coefficients&quot;&gt;Fourier Coefficients&lt;/h3&gt;
&lt;p&gt;
  Let \( \omega = e^{-i 2 \pi / 15}.  \)  Then using the values of \(
  f(n) \) from the table above, the DFT becomes:

  \[
    c_k = \frac{3 + \omega^{3k} + 2 \omega^{5k} + \omega^{6k}
                  + \omega^{9k} + 2 \omega^{10k} + \omega^{12k}}{15}.
  \]

  Substituting \( k = 0, 1, 2, \dots, 14 \) into the above equation
  gives us the following Fourier coefficients:

  \begin{align*}
    c_{0}  &amp;amp;= \frac{11}{15}, \\
    c_{3}  &amp;amp;= c_{6} = c_{9} = c_{12} = \frac{2}{5}, \\
    c_{5}  &amp;amp;= c_{10} = \frac{1}{3}, \\
    c_{1}  &amp;amp;= c_{2} = c_{4} = c_{7} = c_{8} = c_{11} = c_{13} = c_{14} = 0.
  \end{align*}

  Calculating these Fourier coefficients by hand can be rather
  tedious.  In practice they are almost always calculated using
  numerical software, computer algebra systems or even simple code
  such as the example here:
  &lt;a href=&quot;code/fizz-buzz-fourier/fizz-buzz-fourier.py&quot;&gt;fizz-buzz-fourier.py&lt;/a&gt;.
&lt;/p&gt;
&lt;h3 id=&quot;inverse-transform&quot;&gt;Inverse Transform&lt;/h3&gt;
&lt;p&gt;
  Once the coefficients are known, we can substitute them into the
  inverse transform introduced earlier to obtain

  \begin{align*}
    f(n)
    &amp;amp;= \sum_{k = 0}^{14} c_k \, e^{i 2 \pi k n / 15} \\[1.5em]
    &amp;amp;= \frac{11}{15}
           + \frac{2}{5} \left(
             e^{i 2 \pi \cdot 3n / 15}
             + e^{i 2 \pi \cdot 6n / 15}
             + e^{i 2 \pi \cdot 9n / 15}
             + e^{i 2 \pi \cdot 12n / 15}
           \right) \\
           &amp;amp; \phantom{=\frac{11}{15}}
           + \frac{1}{3} \left(
             e^{i 2 \pi \cdot 5n / 15}
             + e^{i 2 \pi \cdot 10n / 15}
           \right) \\[1em]
    &amp;amp;= \frac{11}{15}
           + \frac{2}{5} \left(
             e^{i 2 \pi \cdot 3n / 15}
             + e^{i 2 \pi \cdot 6n / 15}
             + e^{-i 2 \pi \cdot 6n / 15}
             + e^{-i 2 \pi \cdot 3n / 15}
           \right) \\
           &amp;amp; \phantom{=\frac{11}{15}}
           + \frac{1}{3} \left(
             e^{i 2 \pi \cdot 5n / 15}
             + e^{-i 2 \pi \cdot 5n / 15}
           \right) \\[1em]
    &amp;amp;= \frac{11}{15}
       + \frac{2}{5} \left(
         2 \cos \left( \frac{2 \pi n}{5} \right)
         + 2 \cos \left( \frac{4 \pi n}{5} \right)
       \right) \\
       &amp;amp; \phantom{=\frac{11}{15}}
       + \frac{1}{3} \left(
         2 \cos \left( \frac{2 \pi n}{3} \right)
       \right) \\[1em]
    &amp;amp;= \frac{11}{15} +
       \frac{4}{5} \cos \left( \frac{2 \pi n}{5} \right) +
       \frac{4}{5} \cos \left( \frac{4 \pi n}{5} \right) +
       \frac{2}{3} \cos \left( \frac{2 \pi n}{3} \right).
  \end{align*}

  This is exactly the same expression for \( f(n) \) we obtained in
  the previous section.  We see that the Fizz Buzz index function \(
  f(n) \) can be expressed precisely using the machinery of Fourier
  analysis.
&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;
  To summarise, we have defined the Fizz Buzz sequence as

  \[
    (s_{f(n)}(n))_{n = 1}^{\infty}
  \]

  where

  \[
    f(n)
    = \frac{11}{15} +
      \frac{2}{3} \cos \left( \frac{2 \pi n}{3} \right) +
      \frac{4}{5} \cos \left( \frac{2 \pi n}{5} \right) +
      \frac{4}{5} \cos \left( \frac{4 \pi n}{5} \right).
  \]

  and \( s_0(n) = n, \) \( s_1(n) = \mathtt{Fizz}, \) \( s_2(n) =
  \mathtt{Buzz} \) and \( s_3(n) = \mathtt{FizzBuzz}.  \)  A Python
  program to print the Fizz Buzz sequence based on this definition was
  presented earlier.  That program can be written more succinctly as
  follows:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from math import cos, pi
for n in range(1, 101):
    print([n, &apos;Fizz&apos;, &apos;Buzz&apos;, &apos;FizzBuzz&apos;][round(11 / 15 + (2 / 3) * cos(2 * pi * n / 3) + (4 / 5) * (cos(2 * pi * n / 5) + cos(4 * pi * n / 5)))])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  We can also wrap this up nicely in a shell one-liner, in case you
  want to share it with your friends and family and surprise them:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python3 -c &apos;from math import cos, pi; [print([n, &quot;Fizz&quot;, &quot;Buzz&quot;, &quot;FizzBuzz&quot;][round(11/15 + (2/3) * cos(2*pi*n/3) + (4/5) * (cos(2*pi*n/5) + cos(4*pi*n/5)))]) for n in range(1, 101)]&apos;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  We have taken a simple counting game and turned it into a
  trigonometric construction consisting of a discrete Fourier series
  with three cosine terms and four coefficients.  None of this makes
  Fizz Buzz any easier.  Quite the contrary.  But it does show that
  every \( \mathtt{Fizz} \) and \( \mathtt{Buzz} \) now owes its
  existence to a particular set of Fourier coefficients.  We began
  with the modest goal of making this simple problem more complicated.
  I think it is safe to say that we did not fall short.
&lt;/p&gt;
<!-- ### -->
&lt;p&gt;
  &lt;a href="https://susam.net/fizz-buzz-with-cosines.html"&gt;Read on website&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/absurd.html&quot;&gt;#absurd&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/python.html&quot;&gt;#python&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/programming.html&quot;&gt;#programming&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/technology.html&quot;&gt;#technology&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/mathematics.html&quot;&gt;#mathematics&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/puzzle.html&quot;&gt;#puzzle&lt;/a&gt;
&lt;/p&gt;
<!-- END HTML -->
    </content>
  </entry>
  <entry>
    <title>Elliptical Python Programming</title>
    <link href="https://susam.net/elliptical-python-programming.html"/>
    <id>urn:uuid:9df19673-f0cf-459e-97cb-f300fe3100e8</id>
    <updated>2025-04-10T00:00:00Z</updated>
    <content type="html">
<!-- BEGIN HTML -->
&lt;p&gt;
  One thing I love about Python is how it comes with its very own
  built-in zen.  In moments of tribulations, when I am wrestling with
  crooked code and tangled thoughts, I often find solace in its
  timeless wisdom.  Here&apos;s a glimpse of the clarity it provides:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;python3 -m this | grep e-&lt;/kbd&gt;
There should be one-- and preferably only one --obvious way to do it.&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  Indeed, there is one and only one &lt;em&gt;obvious&lt;/em&gt; way to write the
  number 1 in Python, like so:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;--(...==...)&lt;/kbd&gt;
1&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  You may, quite naturally, place several ones adjacently to produce
  larger integers:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;--(...==...)--(...==...)&lt;/kbd&gt;
2&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  And so on ad infinitum or until your heap collapses like a poorly
  made souffl&amp;eacute;.  Now, the &apos;pre-decrement operator&apos; at the
  beginning is entirely optional, much like the plus sign when you
  write &apos;+5 biscuits&apos; in a letter to your grandmother.  It&apos;s not
  wrong, but it is unnecessary.  So unless you want to look peculiar
  to your colleagues, you would likely want to adopt a more
  conventional style, such as this:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;(...==...)--(...==...)--(...==...)&lt;/kbd&gt;
3&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  Now, all computer programs are, in some sense, just a long, earnest
  stream of bits.  It is currently fashionable to bundle these bits
  into groups of eight and write them as integers.  Following this
  trend, we can compute absolutely anything that is computable as long
  as we know exactly what integers to write.  Now, I wouldn&apos;t want to
  bore you with the finer details of computer science, not in this day
  and age, fascinating as they may be.  I trust you are quite capable
  of drawing the rest of the f... well, &lt;em&gt;feathered&lt;/em&gt;, nocturnal
  bird.  Once you&apos;ve grasped the basics, a typical first Python
  program might look something like this:
&lt;/p&gt;
&lt;pre class=&quot;wrap&quot;&gt;&lt;code&gt;exec(&apos;%c&apos;*((...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))%(((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))--((...==...)--(...==...)),((...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...))**((...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...))--((...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...))**((...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))--((...==...)--(...==...)--(...==...)--(...==...)),((...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))**((...==...)--(...==...))--((...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...))**((...==...)--(...==...))--((...==...)--(...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...))**((...==...)--(...==...))--(...==...),*(((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...))**((...==...)--(...==...)--(...==...)),)*((...==...)--(...==...)),((...==...)--(...==...)--(...==...))**((...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...))--((...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))--((...==...)--(...==...)),((...==...)--(...==...))**((...==...)--(...==...)--(...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...))**((...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))--((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...))**((...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...))--((...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))--((...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...))**((...==...)--(...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...))**((...==...)--(...==...)),((...==...)--(...==...)--(...==...)--(...==...)--(...==...)--(...==...))**((...==...)--(...==...))--((...==...)--(...==...)--(...==...)),((...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...))*((...==...)--(...==...)--(...==...)--(...==...)--(...==...))--(...==...)))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  Now you might be wondering if this is &lt;em&gt;really&lt;/em&gt; the way one
  ought to write production Python code.  Isn&apos;t it too much trouble to
  type those dots over and over again?  Not if you remap your
  &lt;kbd&gt;tab&lt;/kbd&gt; key to type three dots, of course.  But I understand
  not everyone likes to remap their keys like this.  In particular,
  there exists a peculiar species of mammal known to remap their
  &lt;kbd&gt;tab&lt;/kbd&gt; key to parentheses.  They claim it leads to
  enlightenment.  Such enlightened living forms may find the following
  program more convenient to type:
&lt;/p&gt;
&lt;pre class=&quot;wrap&quot;&gt;&lt;code&gt;exec(&apos;%c&apos;*((()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==()))%(((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==())),((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==()))--((()==())--(()==())),((()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==())),((()==())--(()==())--(()==()))**((()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==()))--((()==())--(()==())),((()==())--(()==())--(()==())--(()==()))**((()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==()))--((()==())--(()==())--(()==())--(()==())),((()==())--(()==()))*((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())),((()==())--(()==())--(()==())--(()==())--(()==())--(()==()))**((()==())--(()==()))--((()==())--(()==())--(()==())),((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==()))**((()==())--(()==()))--((()==())--(()==())--(()==())--(()==())),((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==()))**((()==())--(()==()))--(()==()),*(((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==()))**((()==())--(()==())--(()==())),)*((()==())--(()==())),((()==())--(()==())--(()==()))**((()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==()))--((()==())--(()==())--(()==())),((()==())--(()==())--(()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==()))--((()==())--(()==())),((()==())--(()==()))**((()==())--(()==())--(()==())--(()==())--(()==())),((()==())--(()==())--(()==())--(()==()))**((()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==()))--((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==())),((()==())--(()==())--(()==()))**((()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==()))--((()==())--(()==())--(()==())),((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==())--(()==())--(()==()))--((()==())--(()==())),((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==()))**((()==())--(()==())--(()==())),((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==()))**((()==())--(()==())),((()==())--(()==())--(()==())--(()==())--(()==())--(()==()))**((()==())--(()==()))--((()==())--(()==())--(()==())),((()==())--(()==()))*((()==())--(()==())--(()==())--(()==()))*((()==())--(()==())--(()==())--(()==())--(()==()))--(()==())))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  This program is functionally equivalent to the earlier one.  But
  Python isn&apos;t meant for enlightenment.  It&apos;s meant for getting things
  done.  And to get things done, code should be readable, maintainable
  and ideally not resemble an ancient summoning ritual.  That&apos;s why I
  personally prefer the earlier style, the one with the ellipses.  It
  gracefully avoids the disconcerting void that lurks within the
  parentheses.  After all, programs must be written for people to read
  and only incidentally for machines to execute.
&lt;/p&gt;
&lt;p&gt;
  Finally, I must emphasise that you should never deploy code like
  this in production.  If you plan to write code like this for your
  production CGI scripts, I implore you to add some ellipses for
  logging.  When dung inevitably collides with the fan, you&apos;ll be
  immensely glad you scattered some useful logs amidst the ellipses
  that hold together your business logic.  With that small piece of
  unsolicited advice, I&apos;ll end this brief distraction from scrolling
  through endless arguments on Internet forums.  Happy coding and may
  your parentheses stay balanced (and may your ellipses be the
  punctuation that ...
  &lt;!-- ).  Now, I can sleep peacefully!  --&gt;
&lt;/p&gt;
&lt;!--
  For the enlightened folks who are offended by the penultimate
  paragraph, lighten up!  I am no stranger to the fine art of nested
  parentheses.  This very blog is crafted with an abundance of them,
  all forged through the mighty steel and bank machinery.
--&gt;
<!-- ### -->
&lt;p&gt;
  &lt;a href="https://susam.net/elliptical-python-programming.html"&gt;Read on website&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/absurd.html&quot;&gt;#absurd&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/python.html&quot;&gt;#python&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/programming.html&quot;&gt;#programming&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/humour.html&quot;&gt;#humour&lt;/a&gt;
&lt;/p&gt;
<!-- END HTML -->
    </content>
  </entry>
  <entry>
    <title>Negative Lookahead Assertion</title>
    <link href="https://susam.net/negative-lookahead-assertion.html"/>
    <id>urn:uuid:961fb3ca-143e-4280-9ac7-a1a2c22d226d</id>
    <updated>2024-11-20T00:00:00Z</updated>
    <content type="html">
<!-- BEGIN HTML -->
&lt;p&gt;
  Here is an example of negative lookahead assertion in regular
  expression using Python:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import re
strings = [&apos;foo&apos;, &apos;bar&apos;, &apos;baz&apos;, &apos;foo-bar&apos;, &apos;bar-baz&apos;, &apos;baz-foo&apos;]
matches = [s for s in strings if re.search(&apos;^(?!.*foo)&apos;, s)]
print(matches)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  The regular expression &lt;code&gt;^(?!.*foo)&lt;/code&gt; in the above example
  matches strings that do not contain the pattern &lt;code&gt;foo&lt;/code&gt;.
  The above code example produces the following output:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;[&apos;bar&apos;, &apos;baz&apos;, &apos;bar-baz&apos;]&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  Of course, it is much simpler to use an ordinary regular expression
  that matches &lt;code&gt;foo&lt;/code&gt; and then invert the result of the
  match to ignore strings that contain &lt;code&gt;foo&lt;/code&gt;.  For example,
  consider the following straightforward solution:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matches = [s for s in strings if not re.search(&apos;foo&apos;, s)]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  This example produces the same result as the earlier example but
  with less complexity.  However, there are situations where, as a
  user of certain software tool, we might not have control over how
  the tool applies the regular expression.  Some tools only allow us
  to provide a pattern and then they automatically select strings that
  match the pattern.  In such cases, if we need to select strings
  that &lt;em&gt;do not&lt;/em&gt; match a given pattern, negative lookahead
  assertions become quite useful, provided the regular expression
  flavour supported by the tool allows the use of negative lookahead
  assertions.
&lt;/p&gt;
<!-- ### -->
&lt;p&gt;
  &lt;a href="https://susam.net/negative-lookahead-assertion.html"&gt;Read on website&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/python.html&quot;&gt;#python&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/programming.html&quot;&gt;#programming&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/technology.html&quot;&gt;#technology&lt;/a&gt;
&lt;/p&gt;
<!-- END HTML -->
    </content>
  </entry>
  <entry>
    <title>Import Readline</title>
    <link href="https://susam.net/import-readline.html"/>
    <id>urn:uuid:b72dd7ff-cb09-4101-94df-6da8f7572cb2</id>
    <updated>2022-02-24T00:00:00Z</updated>
    <content type="html">
<!-- BEGIN HTML -->
&lt;h2 id=&quot;toy-repl&quot;&gt;Toy REPL&lt;/h2&gt;
&lt;p&gt;
  Let us first write a tiny Python program to create a toy
  read-eval-print-loop (REPL) that does only one thing: add all
  integers entered as input into the REPL prompt.  Here is the
  program:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;while True:
    try:
        line = input(&apos;&amp;gt; &apos;)
        print(sum([int(n) for n in line.split()]))
    except ValueError as e:
        print(&apos;error:&apos;, e)
    except (KeyboardInterrupt, EOFError):
        break&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  Here is how it works:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;python3 repl.py&lt;/kbd&gt;
&amp;gt; &lt;kbd&gt;10 20 30&lt;/kbd&gt;
60
&amp;gt; &lt;kbd&gt;40 50 60&lt;/kbd&gt;
150
&amp;gt; &lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  If we now type &lt;kbd&gt;&amp;uarr;&lt;/kbd&gt; (the up arrow key)
  or &lt;kbd&gt;ctrl&lt;/kbd&gt;+&lt;kbd&gt;p&lt;/kbd&gt; to bring back the previous input, we
  see something like the following instead:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt; &lt;kbd&gt;^[[A^[[A^P^P&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  It shows the keys typed literally rather than bringing up previous
  input like most other interactive programs with a command-line
  interface do.  The other programs that do bring up the previous
  input are able to do so because they provide line editing and
  history capability, often with the help of a line editing and
  history library like GNU Readline (libreadline) or BSD Editline
  (libedit).
&lt;/p&gt;
&lt;p&gt;
  Can we have a similar line editing and history capability for our
  toy REPL?  After all, the Python REPL itself offers such a line
  editing facility.  Surely there must be a way to have this facility
  for our own programs too.  Indeed there is!
&lt;/p&gt;
&lt;h2 id=&quot;line-editing-and-history&quot;&gt;Line Editing and History&lt;/h2&gt;
&lt;p&gt;
  To enable line editing and history in our toy REPL, we just need to
  add &lt;code&gt;import readline&lt;/code&gt; to our program.  Here is how our
  program would look:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import readline

while True:
    try:
        line = input(&apos;&amp;gt; &apos;)
        print(sum([int(n) for n in line.split()]))
    except ValueError as e:
        print(&apos;error:&apos;, e)
    except (KeyboardInterrupt, EOFError):
        break&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  Now &lt;kbd&gt;&amp;uarr;&lt;/kbd&gt;, &lt;kbd&gt;ctrl&lt;/kbd&gt;+&lt;kbd&gt;p&lt;/kbd&gt;, etc. work as
  expected.
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;python3 repl.py&lt;/kbd&gt;
&amp;gt; &lt;kbd&gt;10 20 30&lt;/kbd&gt;
60
&amp;gt; &lt;kbd&gt;40 50 60&lt;/kbd&gt;
150
&amp;gt; &lt;kbd&gt;40 50 60&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  The last line of input in the example above is obtained by typing
  either &lt;kbd&gt;&amp;uarr;&lt;/kbd&gt; or &lt;kbd&gt;ctrl&lt;/kbd&gt;+&lt;kbd&gt;p&lt;/kbd&gt;.  In fact,
  all of the line editing keys like &lt;kbd&gt;ctrl&lt;/kbd&gt;+&lt;kbd&gt;a&lt;/kbd&gt; to go
  to the beginning of the line, &lt;kbd&gt;ctrl&lt;/kbd&gt;+&lt;kbd&gt;k&lt;/kbd&gt; to kill
  the line after the cursor, etc. work as expected.  The exact list of
  default key-bindings supported depends on the underlying line
  editing library being used by the &lt;code&gt;readline&lt;/code&gt; module.  The
  underlying library may be either the GNU Readline library or the BSD
  Editline library.  There are some minor differences regarding the
  list of default key-bindings between these two libraries.
&lt;/p&gt;
&lt;h2 id=&quot;history-file&quot;&gt;History File&lt;/h2&gt;
&lt;p&gt;
  What we have done so far achieves the goal of bringing up previous
  inputs from the history.  However, it does not bring back inputs
  from a previous invocation of the REPL.  For example, if we start
  our toy REPL, enter some inputs, then quit it (say, by
  typing &lt;kbd&gt;ctrl&lt;/kbd&gt;+&lt;kbd&gt;c&lt;/kbd&gt;), start our toy REPL again and
  type &lt;kbd&gt;&amp;uarr;&lt;/kbd&gt; or &lt;kbd&gt;ctrl&lt;/kbd&gt;+&lt;kbd&gt;p&lt;/kbd&gt;, it does not
  bring back the input from the previous invocation.  For a full-blown
  REPL meant for sophisicated usage, we may want to preserve the
  history between different invocations of the REPL.  This can be
  achieved by using the &lt;code&gt;read_history_file()&lt;/code&gt;
  and &lt;code&gt;write_history_file()&lt;/code&gt; functions as shown below:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import readline
import os

HISTORY_FILE = os.path.expanduser(&apos;~/.repl_history&apos;)
if os.path.exists(HISTORY_FILE):
    readline.read_history_file(HISTORY_FILE)

while True:
    try:
        line = input(&apos;&amp;gt; &apos;)
        readline.write_history_file(HISTORY_FILE)
        print(sum([int(n) for n in line.split()]))
    except ValueError as e:
        print(&apos;error:&apos;, e)
    except (KeyboardInterrupt, EOFError):
        break&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  For more information on how to use this module, see the
  Python &lt;a href=&quot;https://docs.python.org/3/library/readline.html&quot;&gt;readline
  documentation&lt;/a&gt;.
&lt;/p&gt;
&lt;h2 id=&quot;rlwrap&quot;&gt;Readline Wrapper&lt;/h2&gt;
&lt;p&gt;
  At this point, it is worth mentioning that there are many
  interactive CLI tools that do not have line editing and history
  capabilities.  They behave like our first toy REPL example in this
  post.  Fortunately, there is the wonderful readline wrapper utility
  known as &lt;code&gt;rlwrap&lt;/code&gt; that can be used to enable line editing
  and history in such tools.  This utility can often be easily
  installed from package repositories of various operating systems.
  Here is a demonstration of this tool:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;rlwrap cat&lt;/kbd&gt;
&lt;kbd&gt;hello&lt;/kbd&gt;
hello
&lt;kbd&gt;world&lt;/kbd&gt;
world
&lt;kbd&gt;world&lt;/kbd&gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  The last line of input in the example above is obtained by typing
  either &lt;kbd&gt;&amp;uarr;&lt;/kbd&gt; or &lt;kbd&gt;ctrl&lt;/kbd&gt;+&lt;kbd&gt;p&lt;/kbd&gt;.  In the
  above example, the input history is automatically saved
  to &lt;code&gt;~/.cat_history&lt;/code&gt;, so it is possible to bring back
  inputs from a previous invocation of the command.
&lt;/p&gt;
&lt;h2 id=&quot;obligatory-joke&quot;&gt;Obligatory Joke&lt;/h2&gt;
&lt;p&gt;
  Finally, an obligatory XKCD comic to conclude this post:
&lt;/p&gt;
&lt;figure class=&quot;soft&quot;&gt;
  &lt;img src=&quot;files/blog/xkcd-353-python.png&quot; alt=&quot;XKCD comic on Python&quot;
       title=&quot;Original title text: I wrote 20 short programs in Python yesterday.  It was wonderful.  Perl, I&apos;m leaving you.&quot;&gt;
  &lt;figcaption&gt;
    &lt;em&gt;Python&lt;/em&gt; by Randall Munroe
    (Source: &lt;a href=&quot;https://xkcd.com/353/&quot;&gt;https://xkcd.com/353/&lt;/a&gt;)
  &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;
  While the days of achieving air flight with a
  single &lt;code&gt;import&lt;/code&gt; statement might still be a few decades
  away, we do have the luxury to enable line editing and history in
  our REPLs with a single such statement right now.
&lt;/p&gt;
<!-- ### -->
&lt;p&gt;
  &lt;a href="https://susam.net/import-readline.html"&gt;Read on website&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/python.html&quot;&gt;#python&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/programming.html&quot;&gt;#programming&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/technology.html&quot;&gt;#technology&lt;/a&gt;
&lt;/p&gt;
<!-- END HTML -->
    </content>
  </entry>
  <entry>
    <title>Unix Timestamp 1600000000</title>
    <link href="https://susam.net/unix-timestamp-1600000000.html"/>
    <id>urn:uuid:6e3c2f3d-6dec-4215-909c-f19ab0a4f4ac</id>
    <updated>2020-09-12T00:00:00Z</updated>
    <content type="html">
<!-- BEGIN HTML -->
&lt;p&gt;
  At 2020-09-13 12:26:40 UTC, the Unix timestamp is going to turn
  1600000000.
&lt;/p&gt;
&lt;h2 id=&quot;unix-timestamp-conversion&quot;&gt;Unix Timestamp Conversion&lt;/h2&gt;
&lt;p&gt;
  The following subsections show a few examples of converting the Unix
  timestamp to a human-readable date.
&lt;/p&gt;
&lt;h3 id=&quot;python&quot;&gt;Python&lt;/h3&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;python3 -q&lt;/kbd&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;from datetime import datetime&lt;/kbd&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;datetime.utcfromtimestamp(1_600_000_000)&lt;/kbd&gt;
datetime.datetime(2020, 9, 13, 12, 26, 40)&lt;/samp&gt;&lt;/pre&gt;
&lt;h3 id=&quot;gnu-date&quot;&gt;GNU date (Linux)&lt;/h3&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;date -ud @1600000000&lt;/kbd&gt;
Sun Sep 13 12:26:40 UTC 2020&lt;/samp&gt;&lt;/pre&gt;
&lt;h3 id=&quot;bsd-date&quot;&gt;BSD date (macOS, FreeBSD, OpenBSD, etc.)&lt;/h3&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;date -ur 1600000000&lt;/kbd&gt;
Sun Sep 13 12:26:40 UTC 2020&lt;/samp&gt;&lt;/pre&gt;
&lt;h2 id=&quot;other-such-dates&quot;&gt;Other Such Dates&lt;/h2&gt;
&lt;p&gt;
  All such dates (in UTC) until the end of the current century:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;python3 -q&lt;/kbd&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;from datetime import datetime&lt;/kbd&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;for t in range(0, 4_200_000_000, 100_000_000):&lt;/kbd&gt;
... &lt;kbd&gt;    print(f&apos;{t:13_d} - {datetime.utcfromtimestamp(t)}&apos;)&lt;/kbd&gt;
...
            0 - 1970-01-01 00:00:00
  100_000_000 - 1973-03-03 09:46:40
  200_000_000 - 1976-05-03 19:33:20
  300_000_000 - 1979-07-05 05:20:00
  400_000_000 - 1982-09-04 15:06:40
  500_000_000 - 1985-11-05 00:53:20
  600_000_000 - 1989-01-05 10:40:00
  700_000_000 - 1992-03-07 20:26:40
  800_000_000 - 1995-05-09 06:13:20
  900_000_000 - 1998-07-09 16:00:00
1_000_000_000 - 2001-09-09 01:46:40
1_100_000_000 - 2004-11-09 11:33:20
1_200_000_000 - 2008-01-10 21:20:00
1_300_000_000 - 2011-03-13 07:06:40
1_400_000_000 - 2014-05-13 16:53:20
1_500_000_000 - 2017-07-14 02:40:00
1_600_000_000 - 2020-09-13 12:26:40
1_700_000_000 - 2023-11-14 22:13:20
1_800_000_000 - 2027-01-15 08:00:00
1_900_000_000 - 2030-03-17 17:46:40
2_000_000_000 - 2033-05-18 03:33:20
2_100_000_000 - 2036-07-18 13:20:00
2_200_000_000 - 2039-09-18 23:06:40
2_300_000_000 - 2042-11-19 08:53:20
2_400_000_000 - 2046-01-19 18:40:00
2_500_000_000 - 2049-03-22 04:26:40
2_600_000_000 - 2052-05-22 14:13:20
2_700_000_000 - 2055-07-24 00:00:00
2_800_000_000 - 2058-09-23 09:46:40
2_900_000_000 - 2061-11-23 19:33:20
3_000_000_000 - 2065-01-24 05:20:00
3_100_000_000 - 2068-03-26 15:06:40
3_200_000_000 - 2071-05-28 00:53:20
3_300_000_000 - 2074-07-28 10:40:00
3_400_000_000 - 2077-09-27 20:26:40
3_500_000_000 - 2080-11-28 06:13:20
3_600_000_000 - 2084-01-29 16:00:00
3_700_000_000 - 2087-04-01 01:46:40
3_800_000_000 - 2090-06-01 11:33:20
3_900_000_000 - 2093-08-01 21:20:00
4_000_000_000 - 2096-10-02 07:06:40
4_100_000_000 - 2099-12-03 16:53:20&lt;/samp&gt;&lt;/pre&gt;
&lt;h2 id=&quot;update&quot;&gt;Update&lt;/h2&gt;
&lt;p&gt;
  Here is a screenshot I took at Unix timestamp 1600000000:
  &lt;a href=&quot;https://twitter.com/susam/status/1305120936098627589&quot;&gt;twitter.com/susam/status/130512093609862758&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
  Reproduced as text below:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;date -u; date; date +%s&lt;/kbd&gt;
Sun Sep 13 12:26:39 UTC 2020
Sun Sep 13 17:56:39 IST 2020
1599999999
$ &lt;kbd&gt;date -u; date; date +%s&lt;/kbd&gt;
Sun Sep 13 12:26:40 UTC 2020
Sun Sep 13 17:56:40 IST 2020
1600000000&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  An important point worth noting from the POSIX.1-2008 specification:
&lt;/p&gt;
&lt;blockquote&gt;
  Coordinated Universal Time (UTC) includes leap seconds.  However, in
  POSIX time (seconds since the Epoch), leap seconds are ignored (not
  applied) to provide an easy and compatible method of computing time
  differences.  Broken-down POSIX time is therefore not necessarily
  UTC, despite its appearance.
&lt;/blockquote&gt;
&lt;p&gt;
  See &lt;a href=&quot;https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16&quot;&gt;&amp;sect; A.4.16&lt;/a&gt;
  of the POSIX.1-2008 specification for more details.
&lt;/p&gt;
<!-- ### -->
&lt;p&gt;
  &lt;a href="https://susam.net/unix-timestamp-1600000000.html"&gt;Read on website&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/unix.html&quot;&gt;#unix&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/shell.html&quot;&gt;#shell&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/python.html&quot;&gt;#python&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/programming.html&quot;&gt;#programming&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/technology.html&quot;&gt;#technology&lt;/a&gt;
&lt;/p&gt;
<!-- END HTML -->
    </content>
  </entry>
  <entry>
    <title>Peculiar Self-References</title>
    <link href="https://susam.net/peculiar-self-references.html"/>
    <id>urn:uuid:9f19659e-0675-4ca8-b331-b4f06af2bc21</id>
    <updated>2019-02-21T00:00:00Z</updated>
    <content type="html">
<!-- BEGIN HTML -->
&lt;h2 id=&quot;self-referential-lists&quot;&gt;Peculiar Results&lt;/h2&gt;
&lt;p&gt;
  Here is a tiny Python example that creates a self-referential list
  and demonstrates the self-reference:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;a = a[0] = [0]&lt;/kbd&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;a&lt;/kbd&gt;
[[...]]
&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;a[0]&lt;/kbd&gt;
[[...]]
&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;a[0][0]&lt;/kbd&gt;
[[...]]
&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;a is a[0]&lt;/kbd&gt;
True&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  The output shows that &lt;code&gt;a[0]&lt;/code&gt; refers to &lt;code&gt;a&lt;/code&gt;
  itself which makes it a self-referential list.  Why does this simple
  code create a self-referential list?  Should it not have failed
  with &lt;code&gt;NameError&lt;/code&gt; because &lt;code&gt;a&lt;/code&gt; is not yet
  defined while assigning the list &lt;code&gt;[0]&lt;/code&gt;
  to &lt;code&gt;a[0]&lt;/code&gt;?
&lt;/p&gt;
&lt;p&gt;
  Here is another similar example that creates a self-referential list
  too:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;a = a[0] = [0, 0]&lt;/kbd&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;a&lt;/kbd&gt;
[[...], 0]&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  Here is a similar example for dictionary:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;a = a[0] = {}&lt;/kbd&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;a&lt;/kbd&gt;
{0: {...}}&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
   Note that &lt;code&gt;0&lt;/code&gt; is used as a dictionary key in the above
  example.  Here is another very simple example that uses a string
  key:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;a = a[&apos;k&apos;] = {}&lt;/kbd&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;a&lt;/kbd&gt;
{&apos;k&apos;: {...}}&lt;/samp&gt;&lt;/pre&gt;
&lt;h2 id=&quot;language-reference&quot;&gt;The Language Reference&lt;/h2&gt;
&lt;p&gt;
  My first guess was that the statement
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;a = a[0] = [0]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  behaves like
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;new = [0]
a = new
a[0] = new&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  which would indeed create a self-referential list.
&lt;/p&gt;
&lt;p&gt;
  &lt;a href=&quot;https://docs.python.org/3.7/reference/simple_stmts.html#assignment-statements&quot;&gt;Section
  7.2 (Assignment statements)&lt;/a&gt; of &lt;em&gt;The Python Language
  Reference&lt;/em&gt; confirms this behaviour.  Quoting the relevant part
  from this section here:
&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;
    Assignment statements are used to (re)bind names to values and to
    modify attributes or items of mutable objects:
  &lt;/p&gt;
  &lt;pre&gt;&lt;code&gt;assignment_stmt ::=  (target_list &quot;=&quot;)+ (starred_expression | yield_expression)
target_list     ::=  target (&quot;,&quot; target)* [&quot;,&quot;]
target          ::=  identifier
                     | &quot;(&quot; [target_list] &quot;)&quot;
                     | &quot;[&quot; [target_list] &quot;]&quot;
                     | attributeref
                     | subscription
                     | slicing
                     | &quot;*&quot; target&lt;/code&gt;&lt;/pre&gt;
  &lt;p&gt;
    (See section
    &lt;a href=&quot;https://docs.python.org/3.7/reference/expressions.html#primaries&quot;&gt;Primaries&lt;/a&gt;
    for the syntax definitions for attributeref, subscription and
    slicing.)
  &lt;/p&gt;
  &lt;p&gt;
    An assignment statement evaluates the expression list (remember
    that this can be a single expression or a comma-separated list,
    the latter yielding a tuple) and assigns the single resulting
    object to each of the target lists, from left to right.
  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
  We see that the assignment statement is defined as follows:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;assignment_stmt ::=  (target_list &quot;=&quot;)+ (starred_expression | yield_expression)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  Thus the statement
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;a = a[0] = [0]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  has two &lt;code&gt;target_list&lt;/code&gt; elements (&lt;code&gt;a&lt;/code&gt;
  and &lt;code&gt;a[0]&lt;/code&gt;) and a &lt;code&gt;starred_expression&lt;/code&gt; element
  (&lt;code&gt;[0]&lt;/code&gt;).  As a result, the same list on the
  right-hand-side is assigned to both &lt;code&gt;a&lt;/code&gt;
  and &lt;code&gt;a[0]&lt;/code&gt;, from left to right, i.e. the
  list &lt;code&gt;[0]&lt;/code&gt; is first assigned to &lt;code&gt;a&lt;/code&gt;,
  then &lt;code&gt;a[0]&lt;/code&gt; is set to the &lt;em&gt;same&lt;/em&gt; list.  As a
  result, &lt;code&gt;a[0]&lt;/code&gt; is set to &lt;code&gt;a&lt;/code&gt; itself.
&lt;/p&gt;
&lt;p&gt;
  The behaviour of the statement
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;a = a[0] = {}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  can be explained in a similar way.  The dictionary object on the
  right-hand-side is first assigned to &lt;code&gt;a&lt;/code&gt;.  Then a
  key &lt;code&gt;0&lt;/code&gt; is inserted within the &lt;em&gt;same&lt;/em&gt; dictionary.
  Finally the value of &lt;code&gt;a[0]&lt;/code&gt; is set to the &lt;em&gt;same&lt;/em&gt;
  dictionary.  In other words, &lt;code&gt;a[0]&lt;/code&gt; is set
  to &lt;code&gt;a&lt;/code&gt; itself.
&lt;/p&gt;
&lt;h2 id=&quot;more-experiments&quot;&gt;More Experiments&lt;/h2&gt;
&lt;p&gt;
  The evaluation of the expression list on the right hand side first
  and then assigning the result to each target list from left to right
  explains the behaviour we observed in the previous sections.  This
  left-to-right assignment is quite uncommon among mainstream
  programming languages.  For example, in C, C++, Java and JavaScript
  the simple assignment operator (&lt;code&gt;=&lt;/code&gt;) has right-to-left
  associativity.  The left-to-right assignment in Python can be
  further demonstrated with some intentional errors.  Here is an
  example:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;a[0] = a = [0]&lt;/kbd&gt;
Traceback (most recent call last):
  File &quot;&amp;lt;stdin&amp;gt;&quot;, line 1, in &amp;lt;module&amp;gt;
NameError: name &apos;a&apos; is not defined&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  In this example, when the assignment to &lt;code&gt;a[0]&lt;/code&gt; occurs,
  the variable named &lt;code&gt;a&lt;/code&gt; is not defined yet, so it leads
  to &lt;code&gt;NameError&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
  Here is another example:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;a = a[0] = 0&lt;/kbd&gt;
Traceback (most recent call last):
  File &quot;&amp;lt;stdin&amp;gt;&quot;, line 1, in &amp;lt;module&amp;gt;
TypeError: &apos;int&apos; object does not support item assignment&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  In this example, &lt;code&gt;0&lt;/code&gt; is first assigned to &lt;code&gt;a&lt;/code&gt;.
  Then &lt;code&gt;a[0]&lt;/code&gt; needs to be evaluated before &lt;code&gt;0&lt;/code&gt;
  can be assigned to it but this evaluation fails
  because &lt;code&gt;a&lt;/code&gt; is an &lt;code&gt;int&lt;/code&gt;, a type that does not
  support
  &lt;a href=&quot;https://docs.python.org/3.7/reference/expressions.html#subscriptions&quot;&gt;subscription&lt;/a&gt;
  (also known as indexing), so it fails with &lt;code&gt;TypeError&lt;/code&gt;.
&lt;/p&gt;
<!-- ### -->
&lt;p&gt;
  &lt;a href="https://susam.net/peculiar-self-references.html"&gt;Read on website&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/python.html&quot;&gt;#python&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/programming.html&quot;&gt;#programming&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/technology.html&quot;&gt;#technology&lt;/a&gt;
&lt;/p&gt;
<!-- END HTML -->
    </content>
  </entry>
  <entry>
    <title>Fixed Bits of Version 4 UUID</title>
    <link href="https://susam.net/fixed-bits-of-version-4-uuid.html"/>
    <id>urn:uuid:28a2a6ba-ea53-41df-bd51-01e6327e8c58</id>
    <updated>2015-04-10T00:00:00Z</updated>
    <content type="html">
<!-- BEGIN HTML -->
&lt;p&gt;
  &lt;em&gt;Universally Unique Identifiers&lt;/em&gt; or UUIDs are a popular way
  of creating identifiers that are unique for &lt;em&gt;practical&lt;/em&gt;
  purposes.  Quoting from
  &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc4122&quot;&gt;RFC 4122&lt;/a&gt;
  below:
&lt;/p&gt;
&lt;blockquote&gt;
  This specification defines a Uniform Resource Name namespace for
  UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally
  Unique IDentifier).  A UUID is 128 bits long and requires no central
  registration process.
&lt;/blockquote&gt;
&lt;p&gt;
  These 128-bit identifiers are typically represented as 32
  hexadecimal digits, displayed in five groups separated by hyphens.
  There are various variants and versions of UUIDs which differ in how
  the identifiers are encoded in binary and how they are generated.
  In this post, we are going to focus only on variant 1 of version 4
  UUIDs, also known simply as version 4 UUIDs or random UUIDs.  Here
  are a couple examples of version 4 UUIDs generated using Python:
&lt;/p&gt;
&lt;pre&gt;&lt;samp&gt;&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;import uuid&lt;/kbd&gt;
&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;str(uuid.uuid4())&lt;/kbd&gt;
&apos;980ddc6a-2c56-44da-ac71-9e6bfc924e25&apos;
&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;str(uuid.uuid4())&lt;/kbd&gt;
&apos;10c3fcde-96a0-4c9e-905b-443b00ceeb01&apos;&lt;/samp&gt;&lt;/pre&gt;
&lt;p&gt;
  Version 4 UUID is one of the most popular type of UUIDs in use
  today.  Unlike the other versions, this version does not require
  external inputs like MAC address, sequence number, current time,
  etc.  All except six bits are generated randomly in version 4 UUIDs.
  The six non-random bits are fixed.  They represent the version and
  variant of the UUID.  Here is a tiny Python program that
  demonstrates the first set of fixed bits:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;while str(uuid.uuid4())[14] == &apos;4&apos;: pass&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  The above program is an infinite loop.  So is this:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;while str(uuid.uuid4())[19] in [&apos;8&apos;, &apos;9&apos;, &apos;a&apos;, &apos;b&apos;]: pass&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  The above infinite loops show that the hexademical digit at index 14
  must always be 4.  Similarly, the hexadecimal digit at index 19 must
  always be one of 8, 9, a and b.  We can see the two examples of
  version 4 UUIDs mentioned earlier and confirm that this is indeed
  the case.  Here are a few more examples that illustrate this
  pattern:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;527218be-a09e-&lt;span class=&quot;hl&quot;&gt;4&lt;/span&gt;d0e-&lt;span class=&quot;hl&quot;&gt;8&lt;/span&gt;6ce-c39d1348d953
14163389-2eea-&lt;span class=&quot;hl&quot;&gt;4&lt;/span&gt;e30-&lt;span class=&quot;hl&quot;&gt;9&lt;/span&gt;124-fcf2451eb9fc
c21b57cc-2a4e-&lt;span class=&quot;hl&quot;&gt;4&lt;/span&gt;425-&lt;span class=&quot;hl&quot;&gt;a&lt;/span&gt;2f4-129256562599
37700270-6deb-&lt;span class=&quot;hl&quot;&gt;4&lt;/span&gt;a73-&lt;span class=&quot;hl&quot;&gt;b&lt;/span&gt;bcd-d47c6e20b567&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  The digit after the second hyphen is at index 14 and indeed this
  digit is always 4.  Similarly, the hexadecimal digit after the third
  hyphen is at index 19 and indeed it is always one of 8, 9, a and b.
&lt;/p&gt;
&lt;p&gt;
  If we number the octets in the identifiers as 0, 1, 2, etc. where 0
  represents the most significant octet (the leftmost pair of
  hexadecimal digits in the string representations above), then with a
  careful study of
  &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc4122#section-4.1.1&quot;&gt;section
  4.1.1&lt;/a&gt; of RFC 4122 we know that the first two most significant
  bits of octet 8 represent the variant number.  Since we are working
  with variant 1 of version 4 UUIDs, these two bits must be 1 and 0.
  As a result, octet 8 must be of the form 10xx xxxx in binary where
  each x represents an independent random bit.  Thus, in binary, the
  four most significant bits of octet 8 must be one of 1000, 1001,
  1010 and 1011.  This explains why we always see the hexadecimal
  digit 8, 9, a or b at this position.
&lt;/p&gt;
&lt;p&gt;
  Similarly, a study of
  &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc4122#section-4.1.2&quot;&gt;section 4.1.2&lt;/a&gt;
  and &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc4122#section-4.1.3&quot;&gt;section 4.1.3&lt;/a&gt;
  of the RFC shows that the four most significant bits of octet 6 must
  be set to 0100 to represent the version number 4.  This explains why
  we always see the hexadecimal digit 4 here.
&lt;/p&gt;
&lt;p&gt;
  &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc4122#section-4.4&quot;&gt;Section
  4.4&lt;/a&gt; of RFC 4122 further summarises these points.  To summarise,
  version 4 UUIDs, although 128 bits in length, have 122 bits of
  randomness.  They have six fixed bits that represent its version and
  variant.
&lt;/p&gt;
<!-- ### -->
&lt;p&gt;
  &lt;a href="https://susam.net/fixed-bits-of-version-4-uuid.html"&gt;Read on website&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/python.html&quot;&gt;#python&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/programming.html&quot;&gt;#programming&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/technology.html&quot;&gt;#technology&lt;/a&gt;
&lt;/p&gt;
<!-- END HTML -->
    </content>
  </entry>
  <entry>
    <title>Zero Length Regular Expression</title>
    <link href="https://susam.net/zero-length-regular-expression.html"/>
    <id>urn:uuid:fd6a0f03-eb89-4f61-952f-8621ca13d8be</id>
    <updated>2010-05-03T00:00:00Z</updated>
    <content type="html">
<!-- BEGIN HTML -->
&lt;p&gt;
  This post presents a list of how zero length regular expression is
  handled in various tools and programming languages.  All of them
  compile the zero length regular expression pattern and the regular
  expression matches all strings.
&lt;/p&gt;
&lt;h2 id=&quot;gnu-grep&quot;&gt;GNU grep&lt;/h2&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;printf &quot;foo\nbar\n&quot; | grep &quot;&quot;&lt;/kbd&gt;
foo
bar&lt;/samp&gt;&lt;/pre&gt;
&lt;h2 id=&quot;bsd-grep&quot;&gt;BSD grep&lt;/h2&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;printf &quot;foo\nbar\n&quot; | grep &quot;&quot;&lt;/kbd&gt;
foo
bar&lt;/samp&gt;&lt;/pre&gt;
&lt;h2 id=&quot;perl&quot;&gt;Perl&lt;/h2&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;perl -e &apos;print((&quot;foo&quot; =~ //) . &quot;\n&quot;)&apos;&lt;/kbd&gt;
1&lt;/samp&gt;&lt;/pre&gt;
&lt;h2 id=&quot;python&quot;&gt;Python&lt;/h2&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;python&lt;/kbd&gt;
Python 2.5.2 (r252:60911, Jan  4 2009, 21:59:32)
[GCC 4.3.2] on linux2
Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
&amp;gt;&amp;gt;&amp;gt; &lt;kbd&gt;import re; re.compile(&apos;&apos;).search(&apos;foo&apos;)&lt;/kbd&gt;
&amp;lt;_sre.SRE_Match object at 0x7fc6c5a2c510&amp;gt;&lt;/samp&gt;&lt;/pre&gt;
&lt;h2 id=&quot;java&quot;&gt;Java&lt;/h2&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;cat RegexExperiment.java&lt;/kbd&gt;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class RegexExperiment
{
    public static void main(String[] args)
    {
        System.out.println(Pattern.compile(&quot;&quot;).matcher(&quot;foo&quot;).find());
    }
}
$ &lt;kbd&gt;javac RegexExperiment.java &amp;amp;&amp;amp; java RegexExperiment&lt;/kbd&gt;
true&lt;/samp&gt;&lt;/pre&gt;
&lt;h2 id=&quot;mzscheme&quot;&gt;MzScheme&lt;/h2&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;mzscheme&lt;/kbd&gt;
Welcome to MzScheme v4.0.1 [3m], Copyright (c) 2004-2008 PLT Scheme Inc.
&amp;gt; &lt;kbd&gt;(regexp-match &quot;&quot; &quot;foo&quot;)&lt;/kbd&gt;
(&quot;&quot;)&lt;/samp&gt;&lt;/pre&gt;
&lt;h2 id=&quot;clisp&quot;&gt;CLISP&lt;/h2&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;clisp&lt;/kbd&gt;
  i i i i i i i       ooooo    o        ooooooo   ooooo   ooooo
  I I I I I I I      8     8   8           8     8     o  8    8
  I  \ `+&apos; /  I      8         8           8     8        8    8
   \  `-+-&apos;  /       8         8           8      ooooo   8oooo
    `-__|__-&apos;        8         8           8           8  8
        |            8     o   8           8     o     8  8
  ------+------       ooooo    8oooooo  ooo8ooo   ooooo   8

Welcome to GNU CLISP 2.44.1 (2008-02-23) &amp;lt;http://clisp.cons.org/&amp;gt;

Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2000
Copyright (c) Sam Steingold, Bruno Haible 2001-2008

Type :h and hit Enter for context help.

[1]&amp;gt; &lt;kbd&gt;(regexp:match &quot;&quot; &quot;foo&quot;)&lt;/kbd&gt;
#S(REGEXP:MATCH :START 0 :END 0)&lt;/samp&gt;&lt;/pre&gt;
&lt;h2 id=&quot;c&quot;&gt;C&lt;/h2&gt;
&lt;pre&gt;&lt;samp&gt;$ &lt;kbd&gt;ls -l /usr/lib/libpcre.so*&lt;/kbd&gt;
lrwxrwxrwx 1 root root     17 May  3 15:15 /usr/lib/libpcre.so -&amp;gt; libpcre.so.3.12.1
lrwxrwxrwx 1 root root     17 Jan  6 14:57 /usr/lib/libpcre.so.3 -&amp;gt; libpcre.so.3.12.1
-rw-r--r-- 1 root root 162816 Jul 14  2008 /usr/lib/libpcre.so.3.12.1
susam@swift:~$ &lt;kbd&gt;cat pcre.c&lt;/kbd&gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;pcre.h&amp;gt;

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;pcre.h&amp;gt;

int main(int argc, char **argv)
{
    pcre *p;
    char *re = &quot;&quot;;
    char *s  = &quot;foo&quot;;
    const char *errmsg;
    int errpos;
    int ovector[10];
    int ret;

    p = pcre_compile(re, 0, &amp;amp;errmsg, &amp;amp;errpos, NULL);
    ret = pcre_exec(p, NULL, s, strlen(s), 0, 0,
                    ovector, sizeof ovector / sizeof *ovector);

    printf(ret &amp;lt; 0 ? &quot;no match\n&quot; : &quot;match\n&quot;);
}
$ &lt;kbd&gt;cc -lpcre pcre.c &amp;amp;&amp;amp; ./a.out&lt;/kbd&gt;
match&lt;/samp&gt;&lt;/pre&gt;
<!-- ### -->
&lt;p&gt;
  &lt;a href="https://susam.net/zero-length-regular-expression.html"&gt;Read on website&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/perl.html&quot;&gt;#perl&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/python.html&quot;&gt;#python&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/java.html&quot;&gt;#java&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/lisp.html&quot;&gt;#lisp&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/programming.html&quot;&gt;#programming&lt;/a&gt; |
  &lt;a href=&quot;https://susam.net/tag/technology.html&quot;&gt;#technology&lt;/a&gt;
&lt;/p&gt;
<!-- END HTML -->
    </content>
  </entry>
</feed>
