What Is a Quine?

Do you know what a quine is? Here is an example in Python:

a = 'a = %r\nprint(a %% a)'
print(a % a)

A quine is a self-reproducing program. It is a computer program that takes no input and outputs its own source code when run. The example above does exactly that.

How does this particular quine work?

In the first step, a variable “a” is defined, and the value “a = %r\nprint(a %% a)” is assigned to it. In the source it is in quotes, of course, since it is a string.

If you would then simply add a statement that prints “a”, you would get the following program.

a = 'a = %r\nprint(a %% a)'
print(a)

The output of this program is the following.

a = %r
print(a %% a)

This is not quite quine… But the assignment to “a”, the newline, and the print statement are already there.

The First Trick

The first trick is to replace the print(a) statement with print(a % a). This is an application of one of the string formatting options in Python. The meaning of the notation is “format % values”, with, in this case,

format == value == “a = %r\nprint(a %% a)”.

The Second Trick

The second trick is, you saw this coming, the “%r” in the string, of course. What %r does in a format string, is run the given value through repr(). The repr() function, (from the Python documentation) “returns a string containing a printable representation of an object”. Moreover, it tries to produce valid Python syntax that can be run through eval(). The following code shows the efffect of using repr():

a = 'abc\ndef'
print(a)
print('--')
print(repr(a))

The output of this is:

abc
def
--
'abc\ndef'

Hence, the call to repr() that is implied by the use of %r is an easy way to get the program to print both the \n and the single quotes. You are now ready to run the original quine in your mind, and really see how using %r makes the program output itself. Try it!

A Shorter Version

Just as an encore, a shorter version of the original quine is the following, with the newline replaced by a semicolon and the extraneous spaces removed.

a='a=%r;print(a%%a)';print(a%a)

Tags:

Submitted by Tom Roelandts on 11 February 2018

Add new comment