Rules of Python
To help you understand how Python works, this document explains the rules that Python follows when running your code. Note that as we cover more advanced topics, we will teach you about new rules, but the basic rules are quite simple.
Core rules
When you press the "run" button in Thonny to run a file, or the "run" button in a Jupyter notebook to run a cell, here are the rules that Python follows:
- Start at the very first line of code.
- When running a line of code, first simplify any expressions on
that line. To simplify an expression, Python simplifies things one
step at a time, and the possible simplification steps are as follows:
- Replace a variable name with the current value of that variable.
- Combine two values using an operator. The two values to be combined must already be fully simplified.
- Replace a function call whose argument(s) have been completely simplified with the result of that function call. Note that during this step, the function being called may produce side effects. Note that each built-in function has its own rules for what the result will be (and for what side effect(s) will occur) based on the argument(s) you give it.
- Once all expressions have been fully simplified down to individual values, if the line of code is an assignment statement, the value of the variable named in the assignment statement will be updated. If that variable already existed, its old value will be forgotten, or if not, that variable will be created. Either way, the simplified value of the expression on the right-hand side of the equals sign becomes the new value of the variable named on the left-hand side of the equals sign.
- After all expressions have been simplified into values, and an assignment has been made (if there was one) Python moves on to the next line of code in the file or notebook cell and repeats this process. When the last line of code has finished executing, the program stops.
Additional notes:
- If you are running code in a notebook cell and the last line of that code is not an assignment statement, Jupyter will create an "Out []" box to display the value of the expression on the last line of code.
- If you are typing code in the Thonny shell, as soon as you press "enter" Python will execute the line of code that you typed according to the rules above, but like in the notebook, it will also display the fully-simplified value if that line of code was an expression and not an assignment statement.
- For both of the special cases above where values are displayed, nothing
will be displayed when the simplified value of the expression is
the special value
None
.
Tips for programming
Based on these rules, here are some important ideas to keep in mind:
- Usually, your goal in a problem set or exercise will be to either store a specific value in a variable, or more often, to produce a certain series of side effects (for example, a particular series of printed messages).
- If a line of code just contains an expression and it is not an assignment statement, then that expression should normally involve at least one function which produces one or more side effects. Otherwise (if there are no side effects and you are not storing the result in a variable), that line of code is redundant and can be removed (so you've probably done something wrong).
- As a corollary to the above, every line of code should be an assignment statement unless it contains a function call that has side effects.
- Of the functions we have learned about so far, here is the list of
functions that have side effects:
print
(side effect: displays output)input
(side effect: displays a prompt, and pauses until input is given. Note thatinput
also has a result value, which is the string of text that was typed after the prompt.)- The
turtle
andturtleBeads
drawing functions each have a side effect of moving the turtle and/or adding to the drawing in progress.
- Note that the conversion functions
int
,float
, andstr
as well as theround
function are not on the above list: they do not have side effects. Instead, their result is the converted value, and to use them properly, we generally want to store that result in a variable.
Rules for functions
The def
statement adds to the core rules above in the following ways:
-
In rule #2, for running a line of code, if that line of code is a function definition (i.e., if it starts with the keyword
def
), instead of applying the normal simplification/assignment process, Python does the following:- It gathers all of the lines of code which are indented at the
same level as the first line of code following the
def
line (including that first line of code). - Without simplifying anything or running any of that code, Python
stores that code into a box (just like variable assignment) and
names that box according to the function name which appears after
the
def
keyword. Python also remembers the parameter names and the order of parameters which are specified on the definition line. - Python then proceeds to execute the next line of code that comes
after all of the indented code that it collected; that line of
code must match the indentation level of the
def
statement, or anIndentationError
will occur.
- It gathers all of the lines of code which are indented at the
same level as the first line of code following the
- In addition to the above process for gathering and storing code,
rule #2 part 3 now includes the idea of simplifying a function call to a
custom function that's been defined using
def
. When simplifying a custom function call, we follow the following rules to figure out the result value which will replace the function call in the expression we're simplifying:- First, Python creates a new function call frame for processing the custom function, which is a special zone that can store temporary variables which will only be available during the processing of that function.
- Second, Python takes each argument value from the function call that we want to simplify, and based on its order among the arguments, it figures out which parameter of the function it is calling that argument corresponds to. For each of these parameters, an assignment is made within the new function call frame that assigns that parameter to hold the associated argument value.
- Next, Python executes each line of code that was stored when the function was defined, according to all of the normal rules for running code. During this process, any assignments that are made create or modify variables that are in the current function call frame, although variables from the whole program context can still be used as part of an expression (they just can't be modified).
- If Python encounters a
return
statement (a line of code that starts with the keywordreturn
) it first fully simplifies the expression that follows thereturn
keyword (if there is one), and then the simplified value of that expression becomes the result of the function call (no further lines of code will be executed). If there is no expression after thereturn
keyword, then the result value will be the special valueNone
. - If there is no
return
statement, when the last line of code in the stored function is completed, the special valueNone
becomes the result value.
Notes:
- An attempt to assign a new value to a variable defined outside the current function call frame will simply create a new separate variable with that same name inside of the current function call frame, and any future references to that variable within the current function call frame will refer to that variable.
Rule for conditionals
The if
statement adds to the core rules above in the following ways:
- In rule #2, for running a line of code, if that line of code is a
conditional (i.e., if it starts with the keyword
if
), instead of applying the normal simplification/assignment process, Python does the following:- It gathers all of the lines of code which are indented at the
same level as the first line of code following the
if
line (including that first line of code). - If simplifies the condition part of the conditional (the
expression between the
if
and the colon at the end of the line) and determines whether that simplified value is "truthy" or "falsey" (see below). - If the condition's simplified value is truthy, the lines of code that were collected in step 1 are executed per all of the usual rules of Python (including these rules). However, if the simplified condition value is falsey, those lines of code are skipped.
- If the line of code following the indented block is just
else:
, then the indented block of code following thatelse
will be skipped if the first block of code was executed, or executed if the first block of code was skipped (the two blocks are mutually exclusive). If there are multipleelif
blocks above anelse
, theelse
is only executed if all of them are skipped. - If the line of code following an
if
(orelif
) block starts withelif
, the condition on that line will be simplified only if all connectedif
andelif
blocks above it were skipped, and that condition's truthy/falsey status will determine whether we execute or skip the block underneath it.
- It gathers all of the lines of code which are indented at the
same level as the first line of code following the
For the purposes of conditional choices, "truthy" and "falsey" values are defined as follows:
- The boolean value
True
is truthy and the valueFalse
is falsey. None
is falsey.- The numbers
0
and0.0
are falsey; all other integers and floating point values are truthy. - Empty strings (strings of length 0; strings with spaces in them aren't considered empty) are falsey, and all other strings are truthy.
- Empty lists (and most empty data types) are falsey, and non-empty lists are truthy, even if they contain only falsey values.
- Empty ranges are falsey, but any range that includes at least one number is truthy.
Rules for loops
The while
and for
statements add to the core rules above in the
following ways:
-
In rule #2, for running a line of code, if that line of code is a while loop (i.e., if it starts with the keyword
while
), instead of applying the normal simplification/assignment process, Python does the following:- It gathers all of the lines of code which are indented at the
same level as the first line of code following the
while
line (including that first line of code). This is the loop body. - It simplifies the condition expression which follows the keyword
while
(this is the loop condition). If the simplified value of that expression is truthy, the loop body is executed using all of the normal rules for executing code, including these rules about loops. Otherwise, the loop body is skipped and execution continues after it. - If the loop body was not skipped, when it is finished
(assuming it was not interrupted by something like a
return
) the loop condition is simplified again, and if it still simplifies to a truthy value, the loop body is run again. This process continues until the loop condition simplifies to a falsey value, at which point the loop body is skipped and the loop ends. If the loop condition never becomes falsey, the loop will continue indefinitely.
- It gathers all of the lines of code which are indented at the
same level as the first line of code following the
- In rule #2, for running a line of code, if that line of code is a
for loop (i.e., if it starts with the keyword
for
), instead of applying the normal simplification/assignment process, Python does the following:- It gathers all of the lines of code which are indented at the
same level as the first line of code following the
for
line (including that first line of code). This is the loop body. - The
for
line must name a loop variable, followed by thein
keyword, and then the loop expression. Python simplifies the loop expression once, and the result must be a sequence (which we call the loop sequence). Note that the loop expression is simplified only once, unlike the loop condition in awhile
loop. - Once the loop sequence has been determined, Python assigns the
first item in the loop sequence as the value of the loop
variable and then executes the entire loop body following
all of the normal rules of Python, including these ones. When the
loop body is finished (as long as it was not interrupted, e.g.
via
return
), Python will assign the second item from the loop sequence into the loop variable and execute the loop body again, repeating the entire process for each of the items in the loop sequence. (If the loop sequence is an empty sequence, then the loop body is never executed). Each execution of the loop body is called an iteration. - Once all iterations of the loop have finished, execution continues with the code that comes after the indented loop body.
- It gathers all of the lines of code which are indented at the
same level as the first line of code following the