Python the essentials: A minimal introduction

Introduction to GIS scripting
May, 2017

© 2017, Stijn Van Hoey (mailto:stijnvanhoey@gmail.com). Licensed under CC BY 4.0 Creative Commons

First steps

the obligatory...


In [ ]:
print("Hello INBO_course!") # python 3(!)

Python is a calculator


In [ ]:
4*5

In [ ]:
3**2

In [ ]:
(3 + 4)/2, 3 + 4/2,

In [ ]:
21//5, 21%5  # floor division, modulo

also logical operators:


In [ ]:
3 > 4, 3 != 4, 3 == 4

Variable assignment


In [ ]:
my_variable_name = 'DS_course'
my_variable_name

In [ ]:
name, age = 'John', 30
print('The age of {} is {:d}'.format(name, age))

More information on print format: https://pyformat.info/

REMEMBER:

  • Use relevant variable names, e.g. `name` instead of `n`
  • Keep variable names lowercase, with underscore for clarity, e.g. `darwin_core` instead of `DarwinCore`
  • Loading functionalities

    
    
    In [ ]:
    import os
    
    R comparison:

    You would load a library (`library("ggplot2")`) instead of importing a package

    
    
    In [ ]:
    os.listdir()
    

    Loading with defined short name (community agreement)

    
    
    In [ ]:
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    

    Loading functions from any file/module/package:

    
    
    In [ ]:
    %%file rehears1.py  
    #this writes a file in your directory, check it(!)
    
    "A demo module."
    
    def print_it():
        """Dummy function to print the string it"""
        print('it')
    
    
    
    In [ ]:
    import rehears1
    
    
    
    In [ ]:
    rehears1.print_it()
    
    
    
    In [ ]:
    %%file rehears2.py  
    #this writes a file in your directory, check it(!)
    
    "A demo module."
    
    def print_it():
        """Dummy function to print the string it"""
        print('it')
    
    def print_custom(my_input):
        """Dummy function to print the string that"""
        print(my_input)
    
    
    
    In [ ]:
    from rehears2 import print_it, print_custom
    
    
    
    In [ ]:
    print_custom('DS_course')
    
    REMEMBER:

    Importing **packages** is always the first thing you do in python, since it offers the functionalities to work with!

    Different options are available:

    • import package-name
      importing all functionalities as such
    • from package-name import specific function
      importing a specific function or subset of the package
    • import package-name as short-package-name
      Very good way to keep a good insight in where you use what package
    DON'T: `from os import *`. Just don't!

    Datatypes

    Numerical

    floats

    
    
    In [ ]:
    a_float = 5.
    
    
    
    In [ ]:
    type(a_float)
    

    integers

    
    
    In [ ]:
    an_integer = 4
    
    
    
    In [ ]:
    type(an_integer)
    

    booleans

    
    
    In [ ]:
    a_boolean = True
    a_boolean
    
    
    
    In [ ]:
    type(a_boolean)
    
    
    
    In [ ]:
    3 > 4 # results in boolean
    
    R comparison:

    Booleans are written as False or True, NOT as FALSE/TRUE

    
    
    In [ ]:
    print(False) # test yourself with FALSE
    

    Containers

    Strings

    
    
    In [ ]:
    a_string = "abcde"
    a_string
    

    A string is a collection of characters...

    
    
    In [ ]:
    a_string.capitalize(), a_string.upper(), a_string.endswith('f') # Check the other available methods for a_string yourself!
    
    
    
    In [ ]:
    a_string.upper().replace('B', 'A')
    
    
    
    In [ ]:
    a_string + a_string
    
    
    
    In [ ]:
    a_string * 5
    

    Lists

    A list can contain mixed data types (character, float, int, other lists,...)

    
    
    In [ ]:
    a_list = [1, 'a', 3, 4]
    a_list
    
    
    
    In [ ]:
    another_list = [1, 'a', 8.2, 4, ['z', 'y']]
    another_list
    
    
    
    In [ ]:
    a_list.append(8.2)
    a_list
    
    
    
    In [ ]:
    a_list.reverse()
    a_list
    
    REMEMBER:

    The list is updated in-place; a_list.reverse() does not return anything, it updates the list
    
    
    In [ ]:
    a_list + ['b', 5]
    

    ADVANCED users area: list comprehensions

    
    
    In [ ]:
    [el*2 for el in a_list]  # list comprehensions...a short for-loop
    

    list comprehensions are basically a short-handed version of a for-loop inside a list. Hence, the previous action is similar to:

    
    
    In [ ]:
    new_list = []
    for element in a_list:
        new_list.append(element*2)
    print(new_list)
    

    Another example checks the methods available for the list data type:

    
    
    In [ ]:
    [el for el in dir(list) if not el[0] == '_']
    
    EXERCISE:
    • Rewrite the previous list comprehension by using a builtin string method to test if the element starts with an underscore
    
    
    In [ ]:
    # %load ../notebooks/_solutions/01-python-introduction75.py
    
    EXERCISE:
    • Given the sentence `the quick brown fox jumps over the lazy dog`, split the sentence in words and put all the word-lengths in a list.
    
    
    In [ ]:
    sentence = "the quick brown fox jumps over the lazy dog"
    
    
    
    In [ ]:
    # %load ../notebooks/_solutions/01-python-introduction82.py
    

    R comparison:

    R also has lists as data type, e.g. `list(c(2, 5, 3), 21.3, "a")`

    Dictionary

    A dictionary is basically an efficient table that maps keys to values. It is an unordered container

    It can be used to conveniently store and retrieve values associated with a name

    
    
    In [ ]:
    a_dict = {'a': 1, 'b': 2}
    
    
    
    In [ ]:
    a_dict['c'] = 3
    a_dict['a'] = 5
    
    
    
    In [ ]:
    a_dict
    
    
    
    In [ ]:
    a_dict.keys(), a_dict.values(), a_dict.items()
    
    
    
    In [ ]:
    an_empty_dic = dict() # or just {}
    an_empty_dic
    
    
    
    In [ ]:
    example_dict = {"timeseries": [2, 5, 3], 
                    "parameter": 21.3,
                    "scenario": "a"}
    example_dict
    
    R comparison:

    R also has a dictionary like data type, e.g.

    > example_dict <- list(c(2,5,3),21.3,"a")
    > names(example_dict) <- c("timeseries", "parameter", "scenario")
    > example_dict
    $timeseries
    [1] 2 5 3
    
    $parameter
    [1] 21.3
    
    $scenario
    [1] "a"
    

    Tuple

    
    
    In [ ]:
    a_tuple = (1, 2, 4)
    
    REMEMBER:

    The type of brackets - (), [], {} - to use depends from the data type you want to create!
  • [] -> list
  • () -> tuple
  • {} -> dictionary
  • 
    
    In [ ]:
    collect = a_list, a_dict
    
    
    
    In [ ]:
    type(collect)
    
    
    
    In [ ]:
    serie_of_numbers = 3, 4, 5
    
    
    
    In [ ]:
    # Using tuples on the left-hand side of assignment allows you to extract fields
    a, b, c = serie_of_numbers
    
    
    
    In [ ]:
    print(c, b, a)
    

    Accessing container values

    
    
    In [ ]:
    grades = [88, 72, 93, 94]
    
    
    
    In [ ]:
    from IPython.display import SVG, display
    display(SVG("../img/slicing-indexing.svg"))
    
    
    
    In [ ]:
    grades[2]
    
    REMEMBER:
    • Python starts counting from 0 !
    
    
    In [ ]:
    from IPython.display import SVG, display
    display(SVG("../img/slicing-slicing.svg"))
    
    
    
    In [ ]:
    grades[1:3]
    
    
    
    In [ ]:
    a_list = [1, 'a', 8.2, 4]
    
    
    
    In [ ]:
    a_list[0], a_list[2]
    

    Select from...till

    
    
    In [ ]:
    a_string = "abcde"
    a_string
    
    
    
    In [ ]:
    a_string[2:4]
    

    Select, counting backward:

    
    
    In [ ]:
    a_list[-2]
    
    R comparison:

    The `-` symbol in R has a completely different meaning: `NOT`

    > test <- c(1, 2, 3, 4, 5, 6)
    > test[-2]
    [1] 1 3 4 5 6
    
    
    
    In [ ]:
    a_list = [0, 1, 2, 3]
    

    From the first element until a given index:

    
    
    In [ ]:
    a_list[:3]
    
    
    
    In [ ]:
    a_list[::2]
    

    Dictionaries

    
    
    In [ ]:
    a_dict = {'a': 1, 'b': 2}
    a_dict['a']
    

    Tuples

    
    
    In [ ]:
    a_tuple = (1, 2, 4)
    a_tuple[1]
    
    REMEMBER:
    • [] for accessing elements
    • Note that L[start:stop] contains the elements with indices i such as start <= i < stop
    • (i ranging from start to stop-1). Therefore, L[start:stop] has (stop-start) elements.
    • Slicing syntax: L[start:stop:stride]
    • all slicing parameters are optional

    Assigning new values to items -> mutable vs immutable

    
    
    In [ ]:
    a_list
    
    
    
    In [ ]:
    a_list[2] = 10 # element 2 changed -- mutable
    a_list
    
    
    
    In [ ]:
    a_tuple[1] = 10 # cfr. a_string -- immutable
    a_string[3] = 'q'
    

    Control flows (optional)

    for-loop

    
    
    In [ ]:
    for i in [1, 2, 3, 4]:
        print(i)
    
    **Indentation** is VERY IMPORTANT in Python. Note that the second line in the example above is indented
    
    
    In [ ]:
    
    
    
    
    In [ ]:
    for i in a_list: # anything that is a collection/container can be looped
        print(i)
    
    EXERCISE:
    • Loop through the characters of the string `Hello DS` and print each character separately within the loop
    
    
    In [ ]:
    # %load ../notebooks/_solutions/01-python-introduction172.py
    
    
    
    In [ ]:
    for i in a_dict: # items, keys, values
        print(i)
    
    
    
    In [ ]:
    for j, key in enumerate(a_dict.keys()):
        print(j, key)
    
    REMEMBER:

    When needing a iterator to count, just use `enumerate`. you mostly do not need i = 0 for... i = i +1.
    Check [itertools](http://pymotw.com/2/itertools/) as well...

    while

    
    
    In [ ]:
    b = 7
    while b < 10:
        b+=1
        print(b)
    

    if statement

    
    
    In [ ]:
    if 'a' in a_dict:
        print('a is in!')
    
    
    
    In [ ]:
    if 3 > 4:
        print('This is valid')
    
    
    
    In [ ]:
    testvalue = False  # 0, 1, None, False, 4 > 3
    if testvalue:
        print('valid')
    else:
        raise Exception("Not valid!")
    
    
    
    In [ ]:
    myvalue = 3
    if isinstance(myvalue, str):
        print('this is a string')
    elif isinstance(myvalue, float):
        print('this is a float')
    elif isinstance(myvalue, list):
        print('this is a list')
    else:
        print('no idea actually')
    

    Functions

    We've been using functions the whole time...

    
    
    In [ ]:
    len(a_list)
    
    It is all about calling a **method/function** on an **object**!
    
    
    In [ ]:
    a_list.reverse()
    a_list
    
    REMEMBER:

    Getting an overview of the available methods on the variable (i.e. object):

    Defining a function:

    
    
    In [ ]:
    def custom_sum(a, b, verbose=False):
        """custom summation function
        
        Parameters
        ----------
        a : number
            first number to sum
        b : number
            second number to sum   
        verbose: boolean
            require additional information (True) or not (False)
        
        Returns
        -------
        my_sum : number
            sum of the provided two input elements
        """
        
        if verbose:
            print('print a lot of information to the user')
            
        my_sum = a + b    
        
        return my_sum
    

    Setup of a function:

    • definition starts with def
    • function body is indented
    • return keyword precedes returned value
    **Indentation** is VERY IMPORTANT in Python. Note that the second line in the example above is indented
    
    
    In [ ]:
    custom_sum(2, 3, verbose=False)  # [3], '4'
    
    EXERCISE:
    • Try **SHIFT-TAB** combination to read your own documentation!
    REMEMBER:

    () for calling functions!

    ADVANCED users area:

    Functions are objects as well... (!)

    
    
    In [ ]:
    def f1():
        print('this is function 1 speaking...')
    
    def f2():
        print('this is function 2 speaking...')
    
    
    
    In [ ]:
    def function_of_functions(inputfunction):
        return inputfunction()
    
    
    
    In [ ]:
    function_of_functions(f1)
    

    Anonymous functions (lambda)

    
    
    In [ ]:
    add_two = (lambda x: x + 2)
    
    
    
    In [ ]:
    add_two(10)
    

    Ready for some real Python power: Numpy/Pandas