Python Programming Module 4 PDF
Document Details
Uploaded by MarvelousNurture
Lukas Fässler, David Sichau
Tags
Summary
This document is a Python programming module, focusing on functions, modules, and simulations. It includes theoretical content and explores topics such as modular programming, functions, function types, parameters, variable scope, recursion, and modules including the standard library.
Full Transcript
Programming with Python module 4 Functions, Modules, Simulations Theoretical part Contents 1 Module overview 3 2 Functions...
Programming with Python module 4 Functions, Modules, Simulations Theoretical part Contents 1 Module overview 3 2 Functions 3 2.1 Functions without return value (procedures)................ 3 2.2 Functions with parameters.......................... 4 2.3 Functions with return value......................... 5 2.4 Scope of variables............................... 6 2.5 Recursion................................... 8 2.5.1 Example 1: Factorial......................... 8 2.5.2 Example 2: Fibonacci......................... 8 3 Modules 9 3.1 Python standard modules.......................... 10 3.1.1 Module random............................ 10 3.1.2 Modul statistics............................ 11 3.1.3 Modul time.............................. 11 3.1.4 Module os............................... 12 3.1.5 Module csv.............................. 12 3.2 Non standard modules............................ 13 3.2.1 Modules of the library NumPy.................... 14 3.2.2 Module pyplot of the library matplotlib............... 15 4 Models and simulation 16 4.1 Model..................................... 16 4.2 Simulation................................... 17 4.2.1 Simulation pipeline.......................... 19 4.3 Cellular Automaton as a simulation tool.................. 19 Keywords Modularity Return value Scope of variables Subroutine Recursion Model Procedure Module Animations Function Library Parameter Random number Cellular Automata Authors: Lukas Fässler, David Sichau E-Mail: [email protected] Date: 13 September 2024 Version: 1.1 Hash: 66a5150 The authors try the best to provide an error free work, however there still might be some errors. The Authors are thankful for your feedback and suggestions. This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/ 2 1 Module overview This module deals with the following topics: 1. Modularity: An entire problem is broken down into separate parts by the modu- lar concept. In this module, you will learn how commands can be combined into subprograms (or subroutines). Subprograms are functional units which can be called from several positions in a program. This way, a program part only has to be developed and tested once whereby the programming effort is reduced and the program code is shortened. If data are passed when the subprogram is called, they are referred to as parameters. In many programming languages, two variants of subprograms are distinguished: those with a return value (functions) and those without a return value (procedures). In Python, all subroutines are referred to as functions. Often you want to use functions and instructions in several programs. To avoid having to copy them into each program, they can be saved as files. In Python, such a file is called module. If you want to use a module in a program, it must first be imported. 2. Models and simulations in science: In this module, you can practise your programming skills by implementing models from biology as simulations. In this document, you will find a general introduction about the purpose of models and simulations in science, which will be continued in the following modules. As a simulation tool, you will learn about cellular automata in this module. 2 Functions Up to this point you have already used some Python functions, for example print(), input() or len(). In this module you will learn how to write and use functions yourself. Reasons to use functions are: Structuring: Groups of instructions can be stored under a name and called as often as desired. Readability: The choice of appropriate function names can help programs become more readable and understandable. Avoid code redundancy: If instructions have to be executed more than once, the code sequence can be moved out into a function and called by its name. The code sequence then only needs to be maintained once. 2.1 Functions without return value (procedures) In Python, a function is defined by the command def followed by the procedure name and round brackets (). As with control structures, the line is terminated with a double 3 colon (:) and all subsequent lines of the function must be indented. A function always has to be definied before it is called. Notation def blubb(): # Definition of the function blubb # Commands of the function indented with tab In this example, the function blubb()is defined. The empty brackets mean that no parameters are passed. Example The following Python program contains the function output which is called three times when starting the program: def output(): print("The function was executed.") # Program starts here for i in range(0,3): output() # Console output: # The function was executed. # The function was executed. # The function was executed. 2.2 Functions with parameters We can also pass values to functions. Such values passed to a function are called param- eters. We have to declare the variables received (input variable) in the heade of the function definition to be able to pass values to your function. When calling the function, the parameter is passed to the input variable. Notation and example The following function addAndOutput has two transfer pa- rameters x and y. def addAndOutput(x, y): z = x + y print("Sum: ", z) This function can be invoked, for example, with the values 3 and 2: 4 addAndOutput(3,2) # Console output: # Sum: 5 The value 3 is passed to the variable x and 2 is passed to y. The order in which the values are passed therefore plays a role. There is also the possibility to specify default values for parameters. If no value is specified when the function is called, the default value is used. Example: # default values are used for x and y. def addAndOutput(x=3, y=2): z = x + y print("Sum: ", z) # a value is specified for x when the function is called. # for y the default value is used. addAndOutput(4) # Console output: # Sum: 6 2.3 Functions with return value In the example above, the results of the function were printed directly to the console. However, if we want to use the results in the further program flow, we have the possibility to return the values as return value to the location of the function call. This is done with the keyword return. The return statement terminates the execution of the function. Notation and example def addAndReturn(x, y): z = x + y return z This function can be called by specifying two parameters. The variable result stores the result of the return value of the function. 5 result = addAndReturn(3, 2) print(result) If the return statement does not contain a value, None is returned. It has to be taken into account that it is mandatory to return a value in each case in functions with return value. def hello(): i = 1 if (i == 1): return true else: print("will never occur") Even if the else-case will never occur, you have to bear in mind that something would also be returned in this case. Correct would be: def hello(): i=1 if (i == 1): return true else: print("will never occur") return false 2.4 Scope of variables Variables have a limited lifetime. Some variables are only deleted when the program is terminated, others earlier. The time in which a variable exists is called its lifetime, the range of its valitity the scope. By default, variables are only locally visible in functions. This means that they are not visible outside the function. In the following example the variable a is only visible within the function f() and will be deleted afterwards: def f(): a = "red" # locally defined variable a. print(a) f() print(a) # Variable a is not visible. # Output: # red # Error message: NameError: name a is not defined 6 Conversely, globally visible variables within a function can be read accessed, as the following example shows: def f(): print(a) a = "blue" # globally defined variable a. f() print(a) # Output: # blue # blue Care should be taken if local and global variables have the same name. The following example contains two different variables with the name a. One is visible in the whole program, the other only inside the function f(): def f(): a ="red" # locally defined variable a. print(a) a = "blue" # globally defined variable a. f() print(a) # Output: # red # blue If you want to have write access to a variable within a function, you can explicitly specify it as global. def f(): global a # globally defined variable a. a = "red" print(a) a = "blue" f() print(a) # Output: # red # red functions should be avoided because this can cause errors and side effects. Instead, one should choose the way via function parameters and by return via return statement. This 7 means that any variable that one defines within a function is automatically only valid locally and thus has no influence on other variables outside the function, even if it has the same name. 2.5 Recursion A recursion is a function which calls itself. To avoid that the function calls itself infinitely, which has the same consequences as an infinite loop, a termination condition which stops the self-invoking is necessary. To programme a recursion, you have to determine two elements: Basic case: in this case, the result of the calculation is already known. This case corresponds to the termination condition of the recursion. Recursive call: you have to determine how the recursive call shall be done. 2.5.1 Example 1: Factorial The calculation of the factorial f (x) = x! of x can be realized by using a recursive method. Basic case: the factorial of the values 0 and 1 is 1. Recursion: x! = x · (x − 1)! for x > 1 def factorial(x): if (x == 0) or (x == 1): # Basic case return 1 else: return x * factorial(x-1) # Recursive call The function can be invoked as follows, for example result = factorial(9) print(result) # output: 362’880 2.5.2 Example 2: Fibonacci A further popular example is the recursion of the Fibonacci sequence. This infinite sequence of integers starts with 0 and 1. The next number results from the sum of the two preciding numbers: Therefore, the sequence is 0, 1, 1, 2, 3, 5, 8,... For the Fibonacci sequence, two recursive calls are necessary in each step: f (n) = f (n − 1) + f (n − 2) for n ≥ 2 with the start values f (1) = 1 and f (0) = 0. 8 Basic case: for the case that n is equal to 1 or 0, we know that 0 and 1, respectively, has to be returned. Recursion: we call the function again for all the other case whereby we decrease the passed values by 1 and 2. def fibonacci(n): if (n == 0): # Basic case 1 return 0 elif (n == 1): # Basic case 2 return 1 else: # recursive call twice return (fibonacci(n-1) + fibonacci(n-2)) The function can be invoked as follows, for example: result = fibonacci(0): print(result) # output: 0 result = fibonacci(6): print(result) # output: 8 3 Modules To be able to use useful functions and instructions in several programs and projects, it is possible to store them in a file without having to define them again in each program. In Python such a file is called a module. If we save our last function fibonacci as a module with the self-chosen name myModule.py, it can be imported and called as follows: # import the modul myModule.py. import myModule # calls the function fibonacci from the module myModule result = myModule.fibonacci(6) print(result) # Output: # 8 9 3.1 Python standard modules Python has a library of standard modules. If you want to use a module from this library, it must be imported first. At this point a small selection of modules are mentioned as examples. A complete list of the standard Python modules can be found on the Internet (e.g. at https://docs.python.org/3/library/). 3.1.1 Module random A frequently used function is random from the random module. It returns a pseudo- random number in a defined range. With the following function call a pseudo-random number between 0 and 1 can be generated and used in a program: # imports the module random from the standard library. import random # returns a pseudo-random number between 0 and 1. r = random.random() print(r) # Possible output: # 0.7657187611883208 Often one needs integer random numbers, which is provided by the function randint: import random # returns a pseudo-random number between 1 and 6. r = random.randint(1,6) print(r) # Possible output: # 6 10 3.1.2 Modul statistics The module statistics provides functions for statistical evaluations. For example, the following program outputs the mean value (mean) of the list a: # imports the module statistics from the standard library. import statistics a = [5.0,4.75,5.5,4.5,5.5] # returns the statistical mean value of a. print(statistics.mean(a)) # Output: # 5.05 3.1.3 Modul time The module time provides various time-related functions. For example, the function localtime from the module time provides the current date with time: # imports the module time from the standard library. import time # returns the current date and time. print(time.localtime()) With the module time time measurements can be carried out for runtime studies of program sections: import time # measures the starting point of the time measurement. start = time.time() # Code whose runtime is to be measured. # measures the end point of the time measurement. end = time.time() # returns the runtime. print(end-start, "s") With the function sleep from the module time the program flow can be delayed by a certain time. 11 import time print("Please wait...") # delays the program flow by 5 seconds. time.sleep(5.0) # is only executed after 5 seconds. print("done!") 3.1.4 Module os The module os gives access to some functions of the used operating system. For example, the following lines can be used to retrieve which operating system is currently running Python: ~~{.python} # imports the default os module. import os print(os.name) # output posix for Linux, Unix and Mac. # output nt for Windows. ~~~ getcwd() shows the current working directory and listdir() lists the file names contained in it. ~~{.python} import os print(os.getcwd()) print(os.listdir()) # Current working directory e.g. /Users/projectfiles. # List of all files in this directory. ~~~ os.system() can be used to execute a command on the command line. For example, os.system('clear') can be called to clear the console output. 3.1.5 Module csv The exchange of information via text files is a widely used method of exchanging infor- mation between programs. By storing information in files, data can be retained beyond the runtime of a program. One of the most popular formats for data exchange is the so-called CSV format (Comma Separated Values). This allows data to be imported and exported from spreadsheets and databases, for example. Example CSV format: In the CSV form, data is arranged line by line and the individual elements are separated by a character (often a comma or semicolon). The following example shows 3 times 3 elements stored in the file example.csv: 1.2.2019,5,red 1.3.2019,6,black 1.4.2019,9,blue 12 With the following lines the data of the CSV file can be read into a Python program: # imports the module csv from the standard library. import csv # opens the file example.csv with the function open(). with open('example.csv') as csvfile: readCSV = csv.reader(csvfile, delimiter=',') for row in readCSV: print(row,row,row) # Output: 1.2.2019 5 red 1.3.2019 6 black 1.4.2019 9 blue First the CSV file is opened with the function open(). In the next line the lines are stored in a reader object and the separators (here delimeter= ',') are removed. A loop is then used to access the individual elements line by line. 3.2 Non standard modules Programming projects often involve modules that are not installed with a standard Python installation. These are provided in libraries and must be installed separately. Two libraries widely used in the scientific world are NumPy and matplotlib. 13 3.2.1 Modules of the library NumPy The Python library NumPy (Numeric Python) provides numerous functions for efficient working with large arrays and matrices. This extension makes Python comparable to MATLAB®. The documentation of NumPy can be found at https://numpy.org/doc/. The library NumPy will be introduced in detail in the next module. With NumPy a matrix can be created as follows: # imports NumPy and renames it to np. import numpy as np # creates a matrix of the size 4x3 of the data type integer # and initializes all elements with 0. myMatrix = np.zeros((4,3),int) # stores in the matrix elements of the top row # the values 5, 4 and 2. myMatrix[0,0] = 5 myMatrix[0,1] = 4 myMatrix[0,2] = 2 # Output of the matrix in the console print(myMatrix) When you run the program, the 4x3 matrix appears in the console as follows: [[5 4 2] [0 0 0] [0 0 0] [0 0 0]] 14 3.2.2 Module pyplot of the library matplotlib The Python library matplotlib allows to create different graphical representations. With the pyplot module of the matplotlib library, a plot can be created as follows (Figure 1): # imports pyplot from the library matplotlib # and renames it to plt. import matplotlib.pyplot as plt # creates a plot from the data series. plt.plot([20.3, 21.5, 22.1, 20.8, 21.3, 22.9]) # labels the axes of the plot. plt.xlabel('time') plt.ylabel('temperature') # displays the finished plot on the screen. plt.show() Figure 1: Example of a plot with the module pyplot. 15 Note to Code Expert users In Code Expert the function show() cannot be used. The plot is saved with the function savefig() instead. import matplotlib.pyplot as plt plt.plot([20.3, 21.5, 22.1, 20.8, 21.3, 22.9]) plt.xlabel('time') plt.ylabel('temperature') # saves the diagram in a png file. plt.savefig("cx_out/out.png") 4 Models and simulation One goal of science is to learn more about complex systems such as the weather, the ecosystem lake, the human brain or the economy of a country and to predict their reactions to certain influences. To learn more about this, it is necessary to expose the system to different conditions in the experiment. However, it is not always possible to perform these experiments directly on the real objects. If the system to be analyzed has, for example, the size of planets or it is as small as a molecule, if changes take as long as certain evolutionary processes or are as quick as neuronal circuits in the brain, we have the option to represent the real world in a computer model. Modification of such a model which influence the modelling time and space are covered by the term simulation. 4.1 Model The term model denotes an interpretation or abstraction of the real world. It is necessary for computer simulation to create mathematical models in which an abstraction of the real world in a mathematical notation is required. However, since the world is very complex we have to make assumptions and simplifications in the process of modelling. This implies that all models are limited, i.e. they are not able to model the real world in an exact way. Therefore, we often speak of generating a model of a system. The term system refers to a closed collection of elements that are connected to one another. Examples for systems can be the earth, a fish or a protein. Since only a section of the real world is modelled, the modelling becomes easier. Mathematical models were developed before their simulation on a computer was possible. 16 However, understanding such models and their behaviour in detail does have its limits. Thus, the behaviour of certain mathematical models, such as nonlinear dynamical models, cannot be analysed completely without simulation. A further example are chaotic models in which randomness plays an important role. They are not completely analysable without the help of simulations. 4.2 Simulation To perform computer simulations, interdisciplinary cooperation is necessary.The model has to be described mathematically since otherwise it could not be implemented as a simulation by means of informatics. In addition to the knowledge in mathematics and informatics, a profound understanding of the discipline in which you want to simulate is essential. After all, without knowledge of this discipline, it is difficult to generate the model correctly or to interpret the results of the simulation. Figure 2 shows which disciplines are involved in which parts of the simulation. Figure 2: Modelling and simulation of real systems. Simulations are used to analyse the behaviour of systems. For this purpose, we first have to generate a mathematical model of this system. Then, this mathematical model can be implemented as a simulation. When implementing a model, the mathematical language has to be changed into a notation interpretable by the computer. This can be a representation of a model in a programming language (e.g. Python). After implementing the mathematical model in the computer, it can be simulated. Thereby, the mathematical model is started with different input parameters to analyse the behaviour of the system 17 over time. A simulation is therefore defined by the input parameters and the implemented mathematical model. The simulation is performed automatically by the computer whereby the results are protocolled so that they can be analysed afterwards. To visually analyse the behaviour of the system, suitable visual representations of the results are employed. The objective of the simulation can be a better understanding of the behaviour of the modelled system or a comparison of different strategies for the functionality of the system. After performing a simulation, it is necessary to validate the data of the simulation. One possibility for validating the data is the comparison with data gained from the experiment. This interaction is represented in figure 3. The data validation is necessary to avoid false interpretation or over- interpretation of the results and to recognize the limits of the simulation and the model. The methodology of modelling and simulating has several sources of error which have to be taken into account. The main source of error is the process of modelling. We have to bear in mind that a model is only a reduced representation of reality. Therefore, a model is only able to provide information about the aspects that were taken into account in the model. A further source of error can lie in the implementation of the mathematical model because computers involve limitations. For example, the numerical range that can be used by a computer is finite which can lead to different numerical problems. The number 0.2, for example, is finite in the decimal system but in the binary system it becomes the periodic number 0.00110011... which constitutes a risk of rounding errors in calculations. Figure 3: Interaction of simulation and experiment. 18 4.2.1 Simulation pipeline Building a simulation is a complex process that consists of several steps, which typically have to be gone through several times1 : 1. Modeling: A part of the real world is defined and described as a model with words. 2. Calculation: The model is processed (e.g. discretized). Thereby it becomes math- ematically computable. 3. Implementation: The calculations are implemented and written as code. 4. Visualization: The results of the various simulation runs are visualized and inter- preted. 5. Validation: The simulation results must be critically checked for reliability and sources of error must be identified. These can be e.g. in the model, in the algorithm, in the code or in the interpretation of the results. This may be a comparison with real experimental data or other models. 6. Integration: Simulations usually take place in a context (e.g. research, production, etc.) and must be integrated into this context. 4.3 Cellular Automaton as a simulation tool Cellular Automaton or CA are used for randomized modeling and simulation of dy- namical systems and are applied in many disciplines (biology, physics, economics, etc.). A great advantage of cellular automata is that even complex phenomena can be simulated without in-depth mathematical knowledge in the field of partial differential equations. Cellular automata typically consist of the following elements2 : 1. Playing field of cells: In the simplest case, square cells are arranged two-dimensionally similar to a chessboard. Cells can be occupied by game figures. These game figures are representatives for living organisms, molecules, vehicles, etc. 2. States: Each cell has a certain state at any time. In the simplest case there are only two states 0 or 1 (e.g. for healthy/sick, alive/dead, etc.). 3. Start configuration: When the simulation starts, the cells of the playing field are assigned states. This starting point of the simulation is also called generation 0. 4. Neighborhood: Rules for changing cell states (transition from one state to another) is determined by the neighborhood and remain the same throughout the simulation. In the simplest case, a cell is affected by the four directly adjacent cells. Special rules apply to the border cells. 5. Multiple Generations: Starting from generation 0, a simulation runs for a certain time and produces a certain number of generations. 1 H.-J. Bungartz, S. Zimmer, M. Buchholz und D. Pflüger, Modellbildung und Simulation, Heidelberg: Springer Spektrum, 2013. 2 D. Scholz, Pixelspiele, Berlin Heidelberg: Springer Spektrum, 2014 19 In figure 4 you can see an example of a cellular automaton which could simulate the heat propagation in a metal rod (task from module 5 “Matrix Calculations”). Figure 4: Example of a cellular automaton. Each cell has a certain temperature as its state (e.g. 20 degrees, certain cells near the heat source 90 degrees). The temperature is influenced by the four directly neighboring cells. The temperature of the black colored cell will therefore increase in the next cycle. 20