Python for Designers

by Roberto Arista

Fork me on GitHub

The Elements of a Python Program

Programming is a peculiar way of writing. Using a specific language, it is possible to instruct a machine to execute some actions. This process has many analogies with choreography and theatre writing. A director needs to write instructions with clarity, leaving ambiguities as much as possible outside of them. The computer is an actor and programming means composing choreographies for it. You have to tell it what it needs to do, but you must remember that a machine is less capable of interpretation than a human being. In fact, it is not capable at all. Moreover, writing a text which is entirely understandable by a machine without some translation or adaptation is very difficult and tedious. You do not want to write only 0’s and 1’s, do you? Low-level languages are verbose and used for a specific application. Luckily, a vast variety of high-level programming languages were created in the last decades. They make instructing machines much more pleasant and fun. Like any tool, programming languages bring along with them specific purposes and views of the world, so choosing the right one is a crucial factor. Python came out in the ’90s and in a few years became widely used in many fields, such as education.

exercise 3.1

Many well-known companies use Python to provide digital services that you probably use on a daily basis. Check on the web and find out which ones I am referring to. You will be amazed.

Python is an interpreted language. It means that the instructions contained in a script are read line by line and immediately executed. The program devoted to the interpretation and execution of commands is the Python Interpreter. This interpreter can be used interactively (just open terminal, write 'python' and hit enter) or be called to read a text file with .py extension.

On the contrary, languages as C++ or Java are compiled, meaning that the source code is first transformed into object code and only then is executed. The advantage of this process is that the translation from high-level to low-level code is done only once; therefore the object code execution will probably be faster. This is how the applications installed on your machine generally work. Their source code is stored on the developer’s computer, and only the object code is then distributed to the users, who sometimes buy it.

Python syntax relies heavily on whitespace. Which means that both the vertical and the horizontal axis of the writing field are meaningful to the interpreter.

Stefan Themerson, poetic semantic translation of Drinking under the moon by Li Bo, Bayamus, 1949

This feature has two important positive consequences:

  • if you have a background in visual art, you are probably aware that fill has meaning as much as void. Similarly musicians are aware of the value of silence. Employing monospaced fonts the code editor becomes a typographical matrix where, like in poetry, the vertical axis of the composition is activated
  • If you give a look into a piece of Java or C++, you will immediately spot a lot more punctuation. These two languages do not rely on whitespace to organize code blocks, instead they use semicolons ; and brackets {}

Python has been designed with readability in mind. Any designer should be aware of how slippery that notion can be, but generally we can say that it has been conceived with one simple assumption: code is executed by machines, but it is read by humans. Source code is usually the best study resource you have. Where manuals and documentation do not arrive, source code does.

In Python, individual statements finish at the end of the line, although in a few cases – when it is practical – they can extend for more than one line. White space is used to define the blocks of code structure. To put it differently, white space defines the hierarchy of our choreographies.

Programming languages are formal languages. It means they are specifically designed with a purpose in mind, instructing machines. On the contrary, natural languages evolve autonomously: they have multiple rules that often clash. The interpretation skills of the receiver is a key factor in solving these kind of conflicts. Instead formal languages have strict syntax rules because they aim at having the smallest amount of exceptions. Given that the Python interpreter is not able to handle conflicts and ambiguity, syntax errors in the code are just not admitted.

exercise 3.2

Can you point to a sentence in your natural language which was once considered a mistake but is now accepted as correct?

These errors can concern two different aspects. For example, token errors like:

  • w£rd
  • 3width

or structure errors, like:

  • 3 $ 4
  • + rectWidth %

Let’s make some examples using a simple English sentence:

  • The cat is on the table (correct)
  • The c@t is 0n the t4bl& (wrong tokens)
  • Cat is the on table the (wrong structure)

Even if there are mistakes, the meaning is still easy to understand.

Similarly, in Python we would have (I am going to explain later why):

  • rectWidth = 86 (correct)
  • 3rectWidth = 86 (wrong token)
  • = rectWidth 86 (wrong structure)

But, here the Python interpreter will stop its routines, because, without proper instructions, it is not able to handle these exceptions.

A program is a collection of statements. When these are combined they describe a choreography performed by a machine. Formal language can be very dense and hard to read for a human. This is why programming languages allows you to write human-friendly annotations which are ignored by the compiler/interpreter. The Python syntax for comments is the number sign character: #. Each character following the number sign in the same line will be ignored by the Python interpreter.

You should avoid using comments to state the obvious, instead you should explain your intentions when writing a specific statement or code block, maybe keeping in mind that someone else might read them. The following is obvious:

# assigning the variable called rectWidth to 86
rectWidth = 86

This is less obvious:

# should not be larger than the oval
rectWidth = 86

Keep in mind that the first reader of your code is yourself in the future. So, write comments while you are programming, because you still know what you are doing. Later in the future, without annotations, it would be much more difficult to recall the meaning of some obscure code lines.

Going back to our first statement, here we are using a very important operator: the assignment operator. It will be everywhere in our programs. So, a statement like

rectWidth = 86

establishes rectWidth as an identifier (also known as a name) and associates it to an integer (whole number) value of 86. The assignment operator works in a left-to-right direction, linking the identifier of the left to the value on the right. If the assignment operator is followed by any kind of expression, this will be solved first, then the assignment itself. We can translate this statement in a stack diagram.

Identifiers are a very important kind of token in Python. They have some specific, yet very simple rules:

  • they are case sensitive (rectWidth is different from rectwidth or RectWidth)
  • they can include letters (A-Z, a-z), digits (0-9) and underscore characters (_)
  • they cannot start with a digit (ok: my3sidePolygon, not ok: 3sidePolygon)
  • there is a restricted number of keywords that cannot be used as identifiers

Let’s directly ask Python for these reserved keywords. It’s a good opportunity to use Python’s interactive interpreter. Open the terminal (Terminal.app on Mac), write python and hit return. The character before your cursor should have changed from $ to >>> (also called chevron). Now you are using the Python interactive interpreter. These are the statements you need to type in the interpreter’s console to get the keywords we are looking for:

>>> import keyword
>>> print(keyword.kwlist)

The list includes 'global', doesn't it? You just executed your first import and print statements. Well done. We will go more into these later on.

exercise 3.3

Open up your terminal, define a variable and print it to the console

Programming languages are designed with efficiency in mind. They offer various ways to assemble statements and avoid redundancy. The most common one is defining functions. A function is a named sequence of statements that performs a series of operations. A function can “take” some values in and it can provide some values back. The first ones are called arguments, the latter are the return values. In order to use a function you have to define its name so that you can “call” the function by name afterwards.

Here is a very simple function definition:

def interpolateValue(a, b, factor):
    aValue = a + (b - a) * factor
    return aValue

Let’s observe the anatomy of what we have executed:

Remember that functions collect a sequence of statements. Grouping basic commands, they facilitate more articulated actions. So, when you have to choose a name for the function identifier, my advice is to go for a verb form. A verb could make the name a bit longer, but at the beginning it will help a lot distinguish what is what. A pseudo-code example inspired by real life:

def walk(distance, stepLength):
    walkedDistance = 0
    while distance > walkedDistance :
        oneStepForward(stepLength)
        walkedDistance += stepLength

walk(100, 5)

Let’s go back to our previous working example. Once the definition is created we can invoke the function using the following statement:

myValue = interpolateValue(10, 20, .5)
print(myValue)

As we could expect, the value linked to the myValue identifier is 15.

Let’s observe the anatomy of the calling statement:

Great, now it’s time to dive into DrawBot.