Getting Started with Python

Why should system dynamicists learn to code?

There is a whole world of computational and analysis tools being developed in the larger data science community. If system dynamicists want to take advantage of these tools, we have two options:

  1. we can replicate each of them within one of the system dynamics modeling tools we are familiar with

  2. we can bring system dynamics models to the environment where these tools already exist.

PySD and this cookbook are an outgrowth of the belief that this second path is the best use of our time. Bringing the tools of system dynamics to the wider world of data science allows us to operate within our core competency as model builders, and avoids doubled effort. It allows those who are familiar with programming to explore using system dynamics in their own projects, and ensures that the learning system dynamicists do to use these external tools will have application in the wider world.

Why Python?

Python is a high-level programming language that allows users to write code quickly and spend less time mucking about with the boring bits of programming. As a result, it is becoming increasingly popular and is the focus for development of a wealth of data science tools.

In the pen-strokes of xkcd: xkcd python

A (very) brief intro to programming in python

Basic Python Data Structures

  • Everything in python is an object.

  • Objects have different ‘types’.

  • Objects can be made up of other objects.

  • Variable names are just labels assigned to point to specific objects.


Variables are created by assigning a value to a label.

a = 3  # this will be an integer
b = "bob"  # this will be a string
c = 23.987  # this will be a float

print(a, b, c)
3 bob 23.987


Lists are ordered collections of objects (and are objects themselves).

my_list = [1, 2, a]
[1, 2, 3]

Elements of the list can be accessed or modified by position, with the first element having the index 0.

my_list[2] = 4
[1, 2, 4]


A tuple is an ordered list of python objects that is immutable, meaning that once defined they can’t be added to or changed. They are useful for things like sets of coordinates, where it doesn’t make sense to ‘add another dimension’.

From a pragmatic point of view, its mostly important to understand that they are created with (parentheses) and are often used in function calls and returns.

my_tuple = (3, 4, 'hi')
my_tuple = (2,4,6)
my_tuple[2] = 'bye'

TypeError                                 Traceback (most recent call last)

/tmp/ipykernel_21689/ in <module>
----> 1 my_tuple[2] = 'bye'

TypeError: 'tuple' object does not support item assignment


Dictionaries are named collections of objects which can be accessed by their label:

my_dictionary = {'key 1': 1, 'key 2': b}
print(my_dictionary['key 2'])

You can add elements to a dictionary by assigning to an undefined element

my_dictionary['key 3'] = 27
{'key 1': 1, 'key 2': 'bob', 'key 3': 27}

Python Control Flow

if statements

The body of an if statement must be indented - standard practice is 4 spaces.

if True:
    print('Inside the if statement')
Inside the if statement
if 5 < 3:
    print('In the if')
    if 5 > 3:
        print('in the elif')
        print('In the else' )
in the elif
if 5 < 3:
    print('In the if')
elif 5 >= 3:
    print('in the elif')
    print('in the else')
in the elif

for loops

For loops allow you to iterate over lists.

my_list = [1, 2, 3, 'bob']

for emile in my_list:

If we want to iterate over a list of numbers, as is often the case with a for loop, we can use the range function to construct the list for us:

for i in range(0, 10):
    if i > 3:

Python Functions

Functions are defined using the syntax below. As with if and for, indentation specifies the scope of the function.

def my_function(param1, param2):
    result = param1 + param2
    return result

print(my_function(3, 4))

Functions can have default arguments, making them optional to use in the function call:

def my_other_function(param1=5, param2=10):
    return param1 * param2


Methods and Attributes of Objects

Many python objects have their own methods, which are functions that apply specifically to the object, as in the string manipulation functions below:

my_string = 'How about a beer?'
print(my_string.upper().rjust(30))  # chained call to method
print(my_string.replace('?', '!'))
how about a beer?
             HOW ABOUT A BEER?
How about a beer!

Some objects have attributes which are not functions that act upon the object, but components of the object’s internal representation.

In the example below, we define a complex number, which has both a real part and a complex part, which we can access as an attribute.

my_variable = 12.3 + 4j

Resources for learning to program using Python.

and finally…

import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than right now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!