Contents i Contents 1 Introduction 6 1.1 Welcome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.2 Tutorials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.3 Tests and Exam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.4 Plagiarism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.5 Roles And Responsibilities . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.6 Intro Demo’s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2 Basic Programming 10 2.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.2 Simple Calculations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.3 Importing Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.4 Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.5 Name Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.6 Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 2.7 Displaying Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.8 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3 Basic Lists 20 3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 3.2 Memory Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3.3 List Operators and Methods . . . . . . . . . . . . . . . . . . . . . . . . 22 c University of Pretoria, Faculty of Engineering, Built Environment & IT i Contents ii 3.4 23 Range Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Recap 25 4.1 25 Types, Lists, Importing And Name Assignment . . . . . . . . . . . . . 5 Recap Quiz 5.1 Previous Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 For Loop 28 28 28 6.1 Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 6.2 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 6.3 Summations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 6.4 Products . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 6.5 Advanced Series . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 6.6 Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 6.7 Recap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 6.8 Recap Quiz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 6.8.1 40 Previous Concepts . . . . . . . . . . . . . . . . . . . . . . . . . 7 Arrays 42 7.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 7.2 Lists vs Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 7.3 Array Creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 7.4 Array Operators and Methods . . . . . . . . . . . . . . . . . . . . . . . 44 7.5 Math module vs Numpy module . . . . . . . . . . . . . . . . . . . . . . 45 c University of Pretoria, Faculty of Engineering, Built Environment & IT ii Contents iii 7.6 45 Dot product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 While Loop 47 8.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 8.2 Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 8.2.1 Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 8.3 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 8.4 Infinite Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 8.5 Multiple Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 8.6 Additional Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 8.7 Recap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 9 Recap Quiz 9.1 Previous Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 If Statement 57 57 58 10.1 Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 10.1.1 Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 10.2 Multiple Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 10.3 User Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 10.4 Multiple Decisions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 10.5 Recap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 11 Recap Quiz 11.1 Previous Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c University of Pretoria, Faculty of Engineering, Built Environment & IT 65 65 iii Contents iv 12 Nested Structures 65 12.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 12.2 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 12.3 Recap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 13 Functions 75 13.1 Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 13.2 Additional Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 14 Recap Quiz 14.1 Previous Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Plotting 89 89 90 15.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 15.2 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 15.3 Additional Types of Plots . . . . . . . . . . . . . . . . . . . . . . . . . 101 16 LibreOffice 109 16.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 16.2 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 16.3 Linear Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 16.4 Sort, Filters and Pivot Tables . . . . . . . . . . . . . . . . . . . . . . . 114 16.5 Additional LP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 16.6 Exploring spreadsheets . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 16.7 Exploring spreadsheets and extracting data . . . . . . . . . . . . . . . . 116 c University of Pretoria, Faculty of Engineering, Built Environment & IT iv Contents 5 17 File Handling 117 17.1 Test Data (From LO to Python) . . . . . . . . . . . . . . . . . . . . . . 117 17.2 LibreOffice (CSV Files) . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 17.3 Python Framework (CSV Files) . . . . . . . . . . . . . . . . . . . . . . 117 18 Arrays 119 18.1 1D Arrays (Recap) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 18.2 Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 18.3 Lists and Arrays as Function inputs . . . . . . . . . . . . . . . . . . . . 124 19 scipy 126 19.1 Linear Equations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 19.2 Nonlinear System of Equations . . . . . . . . . . . . . . . . . . . . . . 129 19.3 Integration (quad) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 19.4 Integration (dblquad) . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 19.5 Optimization (slsqp) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 19.6 Solve ODE (odeint) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 20 GUIs (Tkinter) 141 20.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 20.2 Integration GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 c University of Pretoria, Faculty of Engineering, Built Environment & IT 5 1. Introduction 1 6 Introduction 1.1 Welcome Please check ClickUP regularly for updates to the lecture notes. • Welcome and Overview • Please read the study guide • All communication via ClickUP • Software and study material → ClickUP • Lecture notes → updated weekly → ClickUP • Tutorial information and assignments → ClickUP • Software installation instructions: – Python XY → study notes – LibreOffice → LibreOffice notes 1.2 Tutorials • Tutorial Sessions – Covers the concepts discussed in class the previous week. – Not compulsory → not for marks – Interact and discuss with tutors – Get assistance with concepts and problems – Don’t expect the tutors to do the work for you !! → They are there to give guidance only → There to help you help yourself. • Tutorial Assignments – Covers the concepts discussed in class the previous week. – Compulsory → for marks – Will be uploaded to ClickUP – Due each week Friday before 17:00 c University of Pretoria, Faculty of Engineering, Built Environment & IT 6 1. Introduction 7 – Detailed instructions on ClickUP !! ∗ ∗ ∗ ∗ ∗ 1.3 All uploaded files will be checked for plagiarism All answers will be marked electronically (I.e. by a computer) All answers are graded binary (right or wrong) No queries regarding tutorial assignments will be entertained Late submissions will get 0 Tests and Exam • Closed book tests. • Writen in the computer labs, with access to a PC • Spyder, Python XY, and LibreOffice help documentation is available • Detailed test instruction → ClickUP 1.4 Plagiarism • Still an issue and not worth the risk: – Several students expelled for cheating in test and exams – Several students with strikes against their names for copying assignments (tutorial and group project) • Make sure you know what plagiarism is about: http://www.library.up.ac.za/ plagiarism/ http://www.plagiarism.org/plagiarism-101/ – Verbatim copying – Patch writing – Ghost writing – Etc. • Plagiarism degrades the integrity of your qualification at the end of the day 1.5 Roles And Responsibilities • MPR213 → Skill development based subject: • Which quadrant are you? c University of Pretoria, Faculty of Engineering, Built Environment & IT 7 1. Introduction 8 co m fo r tz on e Challenge Ability Life Long Learning (After completing MPR213) Integrated - You can integrate this skill with other skills. Training - On going skill use and practice = Life long learning Automatic - You can do it without thinking about it. Build and Develop Skill (80% of MPR213) Gain Knowledge (20% of MPR213) Training - Repetition and practice = application and skill building (78% skill retention) Awkward - You can do it, but with e ort and really have to think about it. Training - Reading and audio visual = Knowledge (10-20% skill retention) Frustrated - You become aware of the skill you don't have. - False sense of ability through worked out examples. Training - Lectures = Awareness (5% skill retention) Pool of Bliss - You don't know what you don't know, so you don't care. Training - No training = No Improvement 1.6 Intro Demo’s • Calculation Demo – vector algebra (dot and cross product) – solve linear system of equations – compute eigenvalues c University of Pretoria, Faculty of Engineering, Built Environment & IT 8 1. Introduction 9 Ability cynic super star Attitude sheep rising star • Plotting Demo • GUI Demo • Semester Project (Game) c University of Pretoria, Faculty of Engineering, Built Environment & IT 9 2. Basic Programming 2 10 Basic Programming 2.1 Introduction • Running / launching Python XY • Overview on what you see on the Python XY GUI – Running / launching Spyder – Access Python XY documentation • Overview on what you see in the Spyder IDE – Editor, Variable Explorer, Object Inspector, File Explorer and Console (Python interpreter) – How to open new Python or IPython interpreters – How to open new windows / tools: View → Windows and toolbars → select window / tool – Window placement, docking and undocking – How to fix broken / missing / messed up windows: View → Reset window layout → restart Spyder 2.2 Simple Calculations • Simple mathematics and operators (+ − ∗ / ∗ ∗) • Int vs Float division – (int / int) → int – (int / float) or (float / int) → float Code Snippet - IPython Console In [#]: 355 / 113 In [#]: 355.0 / 113 In [#]: 355 / 113.0 • Python mathematics priority and grouping – Grouping first → () – Power next → ∗∗ c University of Pretoria, Faculty of Engineering, Built Environment & IT 10 2. Basic Programming 11 – Multiplication and division next → ∗ / – Addition and subtraction next → + − • Example (Constant acceleration motion): – a(t) is constant R – v(t) = adt = v0 + at R – s(t) = v(t)dt = s0 + v0 t + 21 at2 – How long does an object fall from a 30m height? – s0 (initial height) = 30[m] – v0 (initial velocity) = 0[m/s] – a (gravitational acceleration) = −9.81[m/s2 ] – t (time) = Unknown[s] – Solve for t and check the answer • Example (Constant acceleration motion): – a(t) is constant R – v(t) = adt = v0 + at R – s(t) = v(t)dt = s0 + v0 t + 12 at2 s(t) = 30 + 0 ∗ t + 0.5 ∗ −9.81 ∗ t2 = 0 c + b ∗ t + a ∗ t2 √ −b ± b2 − 4ac t= 2a • Example Solution: Code Snippet - IPython Console In [#]: - ( - 4 * 30 * 0.5 * -9.81 )**0.5 / ( 2 * 0.5 * -9.81 ) In [#]: + ( - 4 * 30 * 0.5 * -9.81 )**0.5 / ( 2 * 0.5 * -9.81 ) • Numerical accuracy (round-off errors) – Computers have a finite amount of space to store real numbers – Real numbers are usually represented up to only 16 decimal digits – Real numbers often have small ”round-off” errors when calculated on a computer – (1.0 / 49) * 49 → 0.9999999999999999 – Important when comparing real numbers c University of Pretoria, Faculty of Engineering, Built Environment & IT 11 2. Basic Programming 2.3 12 Importing Modules • What about additional functionality? • More complex calculations? • Import modules and functions – What is a module? → visualize as a filling cabinet – Filing cabinet (module) stores or contains functions – Why are modules needed? → used to organise and store functions under a certain category → easier to find and use the correct function for a given task. – Each filing cabinet (module) contains functions for a specific category → math module has mathematical functions for scalar values • Importing the math module Code Snippet - IPython Console In [#]: import math In [#]: import math as m • Importing functions from the math module Code Snippet - IPython Console In [#]: from math import sin, cos • When to use which import style? → import the module when using many different functions from that module, import functions from the module when using specific functions many times. • Illustrative Example/s: – Double angle formulas (θ = 10 degrees) – Degrees to radians 180 . π Why? sin(2θ) = 2 sin(θ) cos(θ) cos(2θ) = cos2 (θ) − sin2 (θ) tan(2θ) = 2 tan(θ) 1 − tan2 (θ) c University of Pretoria, Faculty of Engineering, Built Environment & IT 12 2. Basic Programming 13 – Note: Grouping () can be used to split the calculation over multiple lines for easier reading. • Example Solution: Code Snippet - IPython Console In In In In [#]: import math [#]: [#]: math.sin(2 * math.radians(10)) [#]: ( 2 * math.sin(math.radians(10)) * math.cos(math.radians(10)) ) Code Snippet - IPython Console In In In In In In In 2.4 [#]: [#]: [#]: [#]: [#]: [#]: [#]: from math import cos, sin, tan, radians cos(2 * radians(10)) cos(radians(10))**2 - sin(radians(10))**2 tan(2 * radians(10)) (2 * tan(radians(10)) / (1 - tan(radians(10))**2) Documentation • How do I find all the functions available in a module? • How do I find out how to use a function and what it does? • Using the help function in Python → find all functions in the math module and documentation on each function: Code Snippet - IPython Console In [#]: math? In [#]: help(math) In [#]: help(math.sin) 2.5 Name Assignment • Example (Constant acceleration motion): – a(t) is constant – v(t) = v0 + at c University of Pretoria, Faculty of Engineering, Built Environment & IT 13 2. Basic Programming 14 – s(t) = s0 + v0 t + 12 at2 – Example of an object falling: – s0 (initial height) = 30[m] – v0 (initial velocity) = 0[m/s] – a (gravitational acceleration) = −9.81[m/s2 ] – t (time) = 1.5[s] – Calculate v(t) and s(t) without name assignment • Example Solution: Code Snippet - IPython Console In [#]: 0 + -9.81 * 1.5 In [#]: 30 + 0.5 * -9.81 * 1.5**2 • Example (Constant acceleration motion): – a(t) is constant – v(t) = v0 + at – s(t) = s0 + v0 t + 12 at2 – Example of an object falling: – s0 (initial height) = 30[m] – v0 (initial velocity) = 0[m/s] – a (gravitational acceleration) = −9.81[m/s2 ] – t (time) = 1.5[s] – Calculate v(t) and s(t) using name assignment – Definitely easier to calculate for different choices of s0 , v0 and t - less changes required • Example Solution: Code Snippet - IPython Console In In In In In In In [#]: [#]: [#]: [#]: [#]: [#]: [#]: s0 = 30 v0 = 0 g = -9.81 t = 1.5 v = v0 + g * t s = s0 + v0 * t + 0.5 * g * t**2 c University of Pretoria, Faculty of Engineering, Built Environment & IT 14 2. Basic Programming 15 In [#]: In [#]: s In [#]: v • Why use name assignment – Calculation results are lost after the computation – Reference an answer of a calculation for later use – More descriptive way to reference a value or answer of a calculation – Easier to break up a complex calculation into smaller pieces – Easier to read and understand a program / piece of code – Less chance for mistakes - requires fewer changes – Guides you to think more generally about the problem • Overview assign name to object in memory name = object using the assignment operator – LHS: chosen name (e.g. x) – RHS: known objects / values (e.g. 7 + 3.3) – RHS of = operator is calculated first according to the mathematical priority discussed previously → then LHS name is assigned to the answer – x = 10.3 not the same as 10.3 = x !!! – 10.3 = x → gives an error • Memory model c University of Pretoria, Faculty of Engineering, Built Environment & IT 15 2. Basic Programming 16 (a) Example 1 (b) Example 2 2.6 Scripts • Creating new script files • Saving / opening script files • Why use script files? – Calculations / commands are lost after restarting your PC or restarting Spyder – Re-typing all the calculations / commands in the Python interpreter is tedious and a waist of time – We can save script files containing calculations to a hard drive or flash disk – Vital for larger programs that solve complex problems – Name assignment essential when using scripts • Example (Constant acceleration motion): – a(t) is constant – v(t) = v0 + at – s(t) = s0 + v0 t + 21 at2 – Example of an object falling: – s0 (initial height) = 30[m] – v0 (initial velocity) = 0[m/s] – a (gravitational acceleration) = −9.81[m/s2 ] – t (time) = 1.5[s] – Calculate v(t) and s(t) using a script file c University of Pretoria, Faculty of Engineering, Built Environment & IT 16 2. Basic Programming 17 • Example Solution: example 2-1-1.py s0 = 30 v0 = 0 g = -9.81 t = 1.5 v = v0 + g * t s = s0 + v0 * t + 0.5 * g * t**2 • Running script files + run options – Current vs dedicated Python interpreter – Interact with Python interpreter after execution – Variable explorer with Interact mode • How Python execute a script file: – PythonTutor.com – Top to bottom (line by line) – Left to right → RHS of = sign calculated first according to the mathematical priority discussed previously → then LHS name is assigned to the answer – RHS must contain defined names !!! • Very easy to re-run / execute this problem for different y0 , v0 and t conditions. 2.7 Displaying Results • How to display the results of our calculation to the screen without interacting with the Python interpreter? • Using the print function → print information to the Python interpreter: • What about displaying more meaningful feedback? • Maybe something like: ”After 1 seconds the object’s position is 25.095m above the ground with a velocity of 0.981m/s” • For this we need to use strings and string operations. • Example Solution: c University of Pretoria, Faculty of Engineering, Built Environment & IT 17 2. Basic Programming 18 example 2-1-1.py 2.8 s0 = 30 v0 = 0 g = -9.81 t = 1.5 v = v0 + g * t s = s0 + v0 * t + 0.5 * -9.81 * t**2 print v print s Strings • String objects → Created using two quotation marks → msg = ”hello” • Used mainly for displaying feedback to the Python interpreter and for data handling (discussed much later in the course) • String operators: – Joining 2 strings together → + – Repeating a string x number of times → ∗ – Operator priority → same as mathematical priority • Illustrative Example/s: – (”Red Lorry; ” + ”Yellow Lorry; ”) * 3 – 103 * 5 vs ”103” * 5 – 43 + 72 vs ”43” + ”72” – ”43” + 72 → error – Take Note: ∗ 43 → integer object ∗ 43.0 → float object ∗ ”43” → string object • Example Solution: c University of Pretoria, Faculty of Engineering, Built Environment & IT 18 2. Basic Programming 19 Code Snippet - Python print print print print print print ("Red Lorry; " + "Yellow Lorry; ") * 3 103 * 5 "103" * 5 43 + 72 "43" + "72" "43" + 72 • string * int → repeat the string • string * float → error (TypeError) • string + string → join strings together • string + (int or float) → error (TypeError) – Only 2 strings can be joined together !! – ints or floats must first be converted to strings, by using the str() function → ”43” + str(72) → ”4372” • Example (Constant acceleration motion): – a(t) is constant – v(t) = v0 + at – s(t) = s0 + v0 t + 12 at2 – Example of an object falling: – s0 (initial height) = 30[m] – v0 (initial velocity) = 0[m/s] – a (gravitational acceleration) = −9.81[m/s2 ] – t (time) = 1.5[s] – Calculate v(t) and s(t) using a script file and – Give meaningful feedback to the user • Example Solution: example 2-1-2.py s0 = 30 v0 = 0 c University of Pretoria, Faculty of Engineering, Built Environment & IT 19 3. Basic Lists 20 g = -9.81 t = 1.5 v = v0 + g * t s = s0 + v0 * t + 0.5 * g * t**2 msg = ("After " + str(t) + " seconds, the object’s position " + "is " + str(s) + "m above the ground with a velocity " + "of " + str(v) + "m/s") print msg 3 Basic Lists 3.1 Introduction • Example (Constant acceleration motion) – What if we want to calculate the ball’s s and v at different time intervals? – We could just re-run / execute our program and change t each time. – Or we could, in our program, calculate v1, v2, v3 and s1, s2, s3 etc., for various time intervals t1, t2, t3. • Example Solution: example 2-2-1.py s0 = 30 v0 = 0 g = -9.81 t1 = 1 t2 = 2 t3 = 3 v1 = v0 + g * t1 s1 = s0 + v0 * t1 + 0.5 * g * t1**2 v2 = v0 + g * t2 s2 = s0 + v0 * t2 + 0.5 * g * t2**2 c University of Pretoria, Faculty of Engineering, Built Environment & IT 20 3. Basic Lists 21 v3 = v0 + g * t3 s3 = s0 + v0 * t3 + 0.5 * g * t3**2 msg1 = ("After " + str(t1) + " seconds, the object’s position " + "is " + str(s1) + "m above the ground with a velocity " + "of " + str(v1) + "m/s") msg2 = ("After " + str(t2) + " seconds, the object’s position " + "is " + str(s2) + "m above the ground with a velocity " + "of " + str(v2) + "m/s") msg3 = ("After " + str(t3) + " seconds, the object’s position " + "is " + str(s3) + "m above the ground with a velocity " + "of " + str(v3) + "m/s") print msg1 print msg2 print msg3 • What if we want s and v at 100+ different times? • For this we have 2 tools available to us → the list and the for loop • Lists → t = [1, 2, 3] – Created using 2 square brackets around the objects / values – Elements in the list are separated by commas – Used to group elements together under 1 name → t – Collection of objects / values – Can be visualized as a row ”post-boxes” that can only have one ”letter” (value) in each ”post-box” (element). – Each Post-box number → location in the list – The ”letter” in the post-box → the object / value in that location • Illustrative Example/s: – time = [1, 3, 5, 7, 9, 11, 13, 15] – the first position in the list (first post-box number) is 0 – the second position in the list (second post-box number) is 1, etc. Starts from 0 !!! c University of Pretoria, Faculty of Engineering, Built Environment & IT 21 3. Basic Lists 22 – time[0] → returns 1 (the ”letter” in the first post-box) – time[2] → returns 5 (the ”letter” in the third post-box) – this is called indexing → accessing the elements in the list 3.2 Memory Model 3.3 List Operators and Methods • List operators: – Similar to strings – Joining 2 lists together → + – Repeating the elements in a list x number of times → ∗ – Operator priority → same as mathematical priority • ”In-Place” Methods: – list.sort() → sort the elements of a list – list.reverse() → reverse the elements of a list c University of Pretoria, Faculty of Engineering, Built Environment & IT 22 3. Basic Lists 23 – list.insert(ind, value) → insert a value into a list at a specific location – list.append(value) → append a value to the end of a list • Functions – list.index(value) → return the location of a value in a list – list.count(value) → return the number of value entries in a list – len(list) → return the length of a list • Illustrative Example/s: – time = [12, 8, 4, 6] – time.sort() → time = [4, 6, 8, 12] – time.reverse() → time = [12, 8, 6, 4] – time.insert(1, 10) → time = [12, 10, 8, 6, 4] – time.append(2) → time = [12, 10, 8, 6, 4, 2] – time.reverse() → time = [2, 4, 6, 8, 10, 12] – time.append(4) → time = [2, 4, 6, 8, 10, 12, 4] – loc = time.index(10) → loc = 4 – num4 = time.count(4) → num4 = 2 – num = len(time) → num = 7 • How to properly read the help() information for list objects – Ignore any functions with underscores → func – If there is no ”Return” information about the function → operation is done ”In-Place” → list.reverse() – If there is ”Return” information → need name assignment for the object /value that is returned → name = list.index(value) – Anything about data / data descriptors → it is not a function or method, it is data → math.pi 3.4 Range Function • What if we want to create larger lists? • Or create lists where the elements in the list follow a simple pattern? c University of Pretoria, Faculty of Engineering, Built Environment & IT 23 3. Basic Lists 24 • Typing out all the elements in a list is tedious and a waist of time. • There are a few ways we can make large lists quite easily. • One of the ways to create a large list → using the range function: name = range(start, end, increment) • Can only be used to create integer elements in a list !!! • ”start”, ”end” and ”increment” inputs into the range function must be integer values !!! • Illustrative Example/s: – range(0, 11, 1) → time values = 0, 1, 2, · · · , 10 – range(2, 11, 2) → time values = 2, 4, 6, · · · , 10 – range(2, 12, 2) → time values = 2, 4, 6, · · · , 10 – range(1, 14, 3) → time values = 1, 4, 7, · · · , 13 – Note: ”end” input into the range function is always omitted !!! i.e. Stops before the ”end” value !!! (Start included and end excluded) – All values in the list are always less than the ”end” value – Note: ”start” input into the range function is always the first value in the list !!! – xi = ”start” + i × ”increment” ”end” for i = 0, 1, 2, · · · such that xi < • Example (Equations of motion): – v(t) = v0 + gt – s(t) = s0 + v0 t + 0.5gt2 – s0 (initial height) = 829.8[m] Burj Khalifa in Dubai – v0 (initial velocity) = 0[m/s] – g (gravitational acceleration) = −9.81[m/s2 ] – t (time) ∈ [0, 15] [s] – Calculate v(t) and s(t) for various time intervals from 0 to 15 stored in a list – To really simplify this problem → for loop • Example Solution: c University of Pretoria, Faculty of Engineering, Built Environment & IT 24 4. Recap 25 example 2-2-2.py s0 = 30 v0 = 0 g = -9.81 t = range(0, 16, 1) v = v0 + g * t[0] s = s0 + v0 * t[0] + 0.5 * g * t[0]**2 msg = ("After " + str(t[0]) + " seconds, the object’s position " + "is " + str(s) + "m above the ground with a velocity " + "of " + str(v) + "m/s") print msg v = v0 + g * t[1] s = s0 + v0 * t[1] + 0.5 * g * t[1]**2 msg = ("After " + str(t[1]) + " seconds, the object’s position " + "is " + str(s) + "m above the ground with a velocity " + "of " + str(v) + "m/s") print msg v = v0 + g * t[2] s = s0 + v0 * t[2] + 0.5 * g * t[2]**2 msg = ("After " + str(t[2]) + " seconds, the object’s position " + "is " + str(s) + "m above the ground with a velocity " + "of " + str(v) + "m/s") print msg 4 Recap 4.1 Types, Lists, Importing And Name Assignment • ints and floats – Operators: () + − ∗ / ∗ ∗ c University of Pretoria, Faculty of Engineering, Built Environment & IT 25 4. Recap 26 – Priority: () then ∗∗ then ∗/ then +− – Integer division: ∗ (int / int) → int ∗ (int / float) or (float / int) → float • strings – Operators: () + ∗ ∗ ∗ → repeat a string → ”very ” * 3 ∗ + → add to strings together → ”hello ” + ”everyone” – Priority: () then ∗ then + • lists – Operators: () + ∗ ∗ ∗ → repeat entries in a list → [1, 2, 3] * 3 ∗ + → add entries of a list together → [1, 2, 3] + [4, 5, 6] – Priority: () then ∗ then + • importing modules – import math – from math import cos, sin – add additional functions for use in the program – only import the modules / functions needed – used help function for documentation → help(math) → help(math.sin) • () brackets – Used for grouping calculations / operations together – Can be used to split long lines of code over multiple lines – Used for calling / using functions and methods → math.radians(90) • [ ] brackets – Used for creating lists → name = [12, 3.4, 55] – Used for indexing a list → name[1] → 3.4 • Name assignment – name = object c University of Pretoria, Faculty of Engineering, Built Environment & IT 26 4. Recap 27 – Used to reference on object / answer of a calculation Code Snippet - Python x = (12.3 + 4) ** 2 y = x / 2.0 msg = "x = " + x + ". y = " + y print msg • range function – Used to create integer only lists Code Snippet - Python name = range(start, end, increment) c University of Pretoria, Faculty of Engineering, Built Environment & IT 27 6. For Loop 5 28 Recap Quiz 5.1 Previous Concepts • You want to add the numbers 1 to 10, term by term using one name to reference the answer. How can you do it? • The names number1 and number2 each reference the integer objects 17 and 3 respectively. You want number1 to reference the integer object 3 and number2 to reference the integer object 17. Discuss two possible approaches to do this. 6 For Loop 6.1 Framework • Example (Equations of motion): – v(t) = v0 + gt – s(t) = s0 + v0 t + 0.5gt2 – s0 (initial height) = 829.8[m] Burj Khalifa in Dubai – v0 (initial velocity) = 0[m/s] – g (gravitational acceleration) = −9.81[m/s2 ] – t (time) ∈ [0, 15] [s] – Calculate v(t) and s(t) for various time intervals from 0 to 15 stored in a list – To really simplify the problem → for loop • Example Solution: example 3-1-1.py s0 = 829.8 v0 = 0 g = -9.81 times = range(0, 16, 3) for t in times: v = v0 + g * t c University of Pretoria, Faculty of Engineering, Built Environment & IT 28 6. For Loop 29 s = s0 + v0 * t + 0.5 * g * t**2 msg = ("After " + str(t) + " seconds, the object’s position " + "is " + str(s) + "m above the ground with a velocity " + "of " + str(v) + "m/s") print msg execute code from top to bottom (only once) for val in list: repeat indented code for every value in the list (top to bottom) execute code from top to bottom (only once) 6.2 Introduction • Executed from the top of the script to the bottom of the script • Indentation (white space) in front of the code tells Python it is part of the for-loop • The code inside the for-loop is repeated before the code below the for-loop • At each repetition of the for loop → the name val is assigned to the next value in the list • I.e. a for loop ”iterates / steps” through the values in a list from start to end • Used to repeat code a known and fixed number of times c University of Pretoria, Faculty of Engineering, Built Environment & IT 29 6. For Loop 30 • Illustrative Example/s: – Printing values in a list to the screen – Using the name in the for-loop for a calculation – Storing the result in a list of known length • Outcomes: – Understand how a for-loop works – Initialize a ”zero” list – Change / overwrite values in the list – For-loop → known number of repetitions !! • Example Solution: x_coords = [1.2, 2.4, 3.6, 4.8, 5.1] print x_coords x_coords = [1.2, 2.4, 3.6, 4.8, 5.1] print x_coords print "start" for x in x_coords: print x print "end" cnt = 0 print "start" for x in x_coords: print "Iteration:" print cnt print "Value:" print x print "" cnt = cnt + 1 print "end" c University of Pretoria, Faculty of Engineering, Built Environment & IT 30 6. For Loop 31 speed_km_h = [40, 60, 80, 100, 120] print "start" for km_h in speed_km_h: miles_h = km_h * 0.621371 print str(km_h) + " km/h = " + str(miles_h) + " miles/h" print "end" x_coords = range(0, 20, 2) y_coords = [0] * len(x_coords) ind = 0 for x in x_coords: y_coords[ind] = x_coords**2 + 5 ind = ind + 1 print "" print x_coords print y_coords • Example (Equations of motion): Index Example – v(t) = v0 + gt – s(t) = s0 + v0 t + 0.5gt2 – s0 (initial height) = 829.8[m] Burj Khalifa in Dubai – v0 (initial velocity) = 0[m/s] – g (gravitational acceleration) = −9.81[m/s2 ] – t (time) ∈ [0, 15] [s] – Calculate v(t) and s(t) for various time intervals from 0 to 15 stored in a list – Store all computed results for v(t) and s(t) in 2 new lists. • Example Solution: example 3-1-2.py s0 = 829.8 v0 = 0 c University of Pretoria, Faculty of Engineering, Built Environment & IT 31 6. For Loop 32 g = -9.81 times = range(0, 16, 3) velocities = [0] * len(times) distances = [0] * len(times) ind = 0 for t in times: velocities[ind] = v0 + g * t distances[ind] = s0 + v0 * t + 0.5 * g * t**2 print print print print print print 6.3 "Times:" times "Velocities:" velocities "Distances" distances Summations • Examples (Summation): – Sum of the first 100+ integers N X i = 1 + 2 + 3 + 4 + ··· = i=1 N (N + 1) 2 • Outcomes: – Sum basic terms – Test the solution – Solution is not unique → various strategies to calculate the summation ∗ Generate term values (Range) → step through the list ∗ Generate term values (Range) → sum(list) • Example Solution: example 3-2-1.py my_sum = 0 numbers = range(1, 101, 1) for num in numbers: my_sum = my_sum + num c University of Pretoria, Faculty of Engineering, Built Environment & IT 32 6. For Loop 33 print my_sum print 50 * (100 + 1) example 3-2-2.py numbers = range(1, 101, 1) print sum(numbers) print 50 * (100 + 1) • Examples (Summation): – Sum of the first 50+ even integers: N X 2i = 2 + 4 + 6 + 8 + · · · = N + N 2 i=1 – Sum of the first 50+ odd numbers: N X 2i − 1 = 1 + 3 + 5 + 7 + · · · i=1 • Outcomes: – Solution is not unique → various strategies to calculate the summation ∗ Generate term values (Range) → step through the list ∗ Generate term counter (Range) → calculate each term ∗ Generate term values (Range) → sum(list) • Example Solution: example 3-3-1.py my_sum = 0 numbers = range(2, 101, 2) for num in numbers: my_sum = my_sum + num print my_sum print 50 + 50**2 c University of Pretoria, Faculty of Engineering, Built Environment & IT 33 6. For Loop 34 example 3-3-2.py my_sum = 0 for i in range(1, 51, 1): term = 2*i my_sum = my_sum + term print my_sum print 50 + 50**2 example 3-3-3.py numbers = range(2, 101, 2) print sum(numbers) print 50 + 50**2 example 3-4-1.py my_sum = 0 numbers = range(1, 101, 2) for num in numbers: my_sum = my_sum + num print my_sum example 3-4-2.py my_sum = 0 for i in range(1, 51, 1): term = 2*i - 1 my_sum = my_sum + term print my_sum example 3-4-3.py numbers = range(1, 101, 2) print sum(numbers) • Examples (Summation): – More complex pattern (Sum the first 10 terms): N X 2(1 + 3i−1 ) = 4 + 8 + 20 + 56 + · · · i=1 c University of Pretoria, Faculty of Engineering, Built Environment & IT 34 6. For Loop 35 • Outcomes: – Strategy to calculate the summation ∗ Generate term counter (Range) → calculate each term ∗ Why can’t we use the other 2 strategies we have learnt? • Example Solution: example 3-5-1.py 6.4 my_sum = 0 for i in range(1, 11, 1): term = 2 * (1 + 3**(i - 1)) my_sum = my_sum + term print my_sum Products • Examples (Product): – Calculate 10! (I.e. 10 factorial): N Y i = 1 × 2 × 3 × 4 × ... i=1 • Outcomes: – Compute the product of basic terms. – Compare against math.factorial(N) – Test your code → illustrate edge cases e.g. N = 0 • Example Solution: example 3-6-1.py my_prod = 1 numbers = range(1, 11, 1) for num in numbers: my_prod = my_prod * num print my_prod c University of Pretoria, Faculty of Engineering, Built Environment & IT 35 6. For Loop 6.5 36 Advanced Series • Example (Fibonacci Series). – Print the first 10 terms of the Fibonacci series to the screen: Fk+1 = Fk + Fk−1 , k = 1, 2, 3, . . . Starting with F0 = 1 and F1 = 1, the sequence is as follows: 1, 1, 2, 3, 5, 8, 13, 21, . . . • Outcomes: – Strategy to calculate the Fibonacci series ∗ Generate term counter (Range) → calculate terms ∗ Need to keep track of the previous 2 terms → calculate the new / current term ∗ Order of updating the terms is important • Example Solution: example 3-7-1.py term_k_1 = 1 term_k = 1 print term_k_1 print term_k for i in range(1, 9, 1): fib_term = term_k + term_k_1 term_k_1 = term_k term_k = fib_term print fib_term • Example (Fibonacci Series). – Store the first 10 terms of the Fibonacci series in a list: Fk+1 = Fk + Fk−1 , k = 1, 2, 3, . . . Starting with F0 = 1 and F1 = 1, the sequence is as follows: 1, 1, 2, 3, 5, 8, 13, 21, . . . c University of Pretoria, Faculty of Engineering, Built Environment & IT 36 6. For Loop 37 • Outcomes: – Growing a list – Using a list to simplify the complexity of a problem – Method of solution dictates whether the name in the for-loop is required inside the loop. • Example Solution: example 3-7-2.py 6.6 fib_terms = [1, 1] for i in range(1, 9, 1): new_term = fib_terms[i] + fib_terms[i-1] fib_terms = fib_terms + [new_term] print fib_terms Limits • Example (Limits): – Scribbled in an old book you see: ln(2) = 1 − 1 1 1 1 + − + − ... 2 3 4 5 – How many terms are required to approximate ln(2)? • Outcomes: – Strategies to alternate the sign of terms. – Infinite terms on the computer implies infinite resources. – How well do we want to approximate ln(2) – How many terms needed to approximate ln(2) → we don’t necessarily know before hand. – Unknown number of terms (repetitions) → while-loop • Example Solution: c University of Pretoria, Faculty of Engineering, Built Environment & IT 37 6. For Loop 38 example 3-8-1.py import math num_terms = 10 my_sum = 0 for i in range(1, num_terms+1, 1): sign = (-1)**(i-1) term = 1.0 / i my_sum = my_sum + sign * term error print print print = abs(math.log(2) - my_sum) my_sum math.log(2) error • Example (Limits): – Is it true that sin(x) can be approximated by: sin(x) = x − x3 x5 x7 x9 + − + + ... 3! 5! 7! 9! – Illustrate with using math.factorial() – Illustrate without using math.factorial() • Outcomes: – Break problem down into smaller pieces → otherwise complexity may cause confusion – Understanding nested for-loops → inner loop completes for every iteration of the outer loop – Different number of terms needed for different problems – Unknown number of terms (repetitions) → while-loop • Example Solution: example 3-9-1.py import math num_terms = 10 x_val = 0.5 c University of Pretoria, Faculty of Engineering, Built Environment & IT 38 6. For Loop 39 my_sum = 0 for i in range(1, num_terms+1, 1): sign = (-1)**(i-1) odd = 2*i - 1 denom = math.factorial(odd) term = (x_val**odd) / denom my_sum = my_sum + sign * term error print print print = abs(math.sin(x_val) - my_sum) my_sum math.sin(x_val) error example 3-9-1.py 6.7 import math num_terms = 10 x_val = 0.5 my_sum = 0 for i in range(1, num_terms+1, 1): sign = (-1)**(i-1) odd = 2*i - 1 denom = 1 for j in range(1, odd+1, 1): denom = denom * j term = (x_val**odd) / denom my_sum = my_sum + sign * term error print print print = abs(math.sin(x_val) - my_sum) my_sum math.sin(x_val) error Recap • For-Loop c University of Pretoria, Faculty of Engineering, Built Environment & IT 39 6. For Loop 40 – Used to repeat code a known and fixed number of times – At each repetition of the for loop → the name val is assigned to the next value in the list – I.e. a for loop ”iterates / steps” through the values in a list from start to end • Nested For-Loops – inner for-loop is repeated for every iteration of the outer for-loop • Strategies for Sums, Series and Products: – Simple / easy pattern → Generate the term values using the range function → iterate through the list and sum terms with a for-loop; or use sum(list) – Complex pattern → Generate a term counter using the range function → calculate each term/s inside the for-loop • Complex problems – Break the problem down into smaller pieces → tackle each piece on its own 6.8 6.8.1 Recap Quiz Previous Concepts • Compute the areas of the triangles with their base width defined in a list base [m] and their heights in a list height [m]. Store the area of each triangle in a list area. – Illustrate using an index counter – Illustrate with using the + operator – Illustrate with using the append • Example Solution: example 4-1-1.py base = [5, 4, 11, 5, 19, 21, 2, 3] height = [1, 4, 2, 17, 45, 10, 13, 12] triangles = [0] * len(base) c University of Pretoria, Faculty of Engineering, Built Environment & IT 40 6. For Loop 41 for ind in range(0, len(base)): triangles[ind] = 0.5 * base[ind] * height[ind] print "The areas are " + str(triangles) example 4-1-2.py base = [5, 4, 11, 5, 19, 21, 2, 3] height = [1, 4, 2, 17, 45, 10, 13, 12] triangles = [] for ind in range(0, len(base)): triangles = triangles + [0.5 * base[ind] * height[ind]] print "The areas are " + str(triangles) example 4-1-3.py base = [5, 4, 11, 5, 19, 21, 2, 3] height = [1, 4, 2, 17, 45, 10, 13, 12] triangles = [] for ind in range(0, len(base)): triangles.append(0.5 * base[ind] * height[ind]) print "The areas are " + str(triangles) • What is wrong in the code below? term_k_1 = 1 term_k = 1 print term_k_1 print term_k for i in range(1, 9, 1): fib_term = term_k + term_k_1 term_k = fib_term term_k_1 = term_k print fib_term c University of Pretoria, Faculty of Engineering, Built Environment & IT 41 7. Arrays 7 42 Arrays 7.1 Introduction • Before moving on to the while loop → arrays can also be used to simplify a few of the previous example problems • arrays → similar to lists → list + built-in for loop • arrays → numbers only • arrays → created using the numpy module: – numpy, short for numerical python → used for creating array objects – numpy → used mainly for vector and matrix algebra – array → generic name for a vector or matrix • Example (Equations of motion): – v(t) = v0 + gt – s(t) = s0 + v0 t + 0.5gt2 – s0 (initial height) = 829.8[m] Burj Khalifa in Dubai – v0 (initial velocity) = 0[m/s] – g (gravitational acceleration) = −9.81[m/s2 ] – t (time) ∈ [0, 15] [s] – Calculate v(t) and s(t) for various time intervals from 0 to 15 stored in an array – Store all computed results for v(t) and s(t) in 2 new arrays. • Example Solution: example 9-1-0.py import numpy as np s0 = 829.8 v0 = 0 g = -9.81 times = np.array(range(0, 16, 3)) velocities = v0 + g * times c University of Pretoria, Faculty of Engineering, Built Environment & IT 42 7. Arrays 43 distances = s0 + v0 * times + 0.5 * g * times**2 print "Times:", times print "Velocities:", velocities print "Distances", distances 7.2 Lists vs Arrays • Indexing: – Elements in lists and arrays are accessed (indexed) the same way → square brackets after the name → data[ind] • List Computations: – Need to loop through a list in order to compute something using the list elements: # 0.1 * [1, 2, 3, 4] data = [1, 2, 3, 4] for i in range(0, len(data), 1): data[i] = data[i] * 0.1 print data • Array Computations: – No need to loop through an array in order to compute something using the array elements: import numpy # 0.1 * [1, 2, 3, 4] data = numpy.array([1, 2, 3, 4]) data = data * 0.1 print data – All computations are done on an element-by-element basis of the array object • Array Computations: c University of Pretoria, Faculty of Engineering, Built Environment & IT 43 7. Arrays 44 – All computations are done on an element-by-element basis of the array object: import numpy # 0.1 * [1, 2, 3, 4] data = numpy.array([1, 2, 3, 4]) scale = numpy.array([10, 2, 3, 1]) print data * scale – Arrays need to be the same length (size) 7.3 Array Creation • Similar to the range function for lists → arrays can be created in various ways: – manually: arr = np.array([1.2, 3, 5.6, 9]) – arange: arr = np.arange(1, 2, 0.1) ∗ ∗ ∗ ∗ arr = np.arange(start, stop, step) start → start value [included] stop → stop value [excluded] step → increment amount from start to stop – linspace: arr = np.linspace(1, 20, num=100) ∗ ∗ ∗ ∗ 7.4 arr = np.linspace(start, stop, num) start → start value [included] stop → stop value [included] num → num of intervals between start and stop Array Operators and Methods • Array operators: – +, −, ∗, /, ∗ ∗ , etc → same as normal number mathematics → done on an element-by-element bases – Eg. arr3 = arr1 + arr2 → arrays must be the same size !! – Operator priority → same as mathematical priority • Functions – NB !!! → arrays don’t have the same functions as lists c University of Pretoria, Faculty of Engineering, Built Environment & IT 44 7. Arrays 45 – NB !!! → no insert or append functions → array sizes must be known → cannot grow an array of values – NB !!! → most functions are ”manipulation” or ”algebra” type functions: ∗ num = array.min() → minimum number in array ∗ num = array.max() → maximum number in array ∗ arr3 = arr1.dot(arr2) → dot product of 2 arrays • Illustrative Example/s: – a1 = np.array([1, 4, 6, 3]) – a2 = np.array([5, 8, -1, 4]) – a3 = a1**2 → a3 = [1, 16, 36, 9] – a3 = a1 * a2 + a1**3 / (2 * a2) → a3 = [5, 36, -114, 15] – a1.min() → 1.0 – a2.max() → 8.0 – a2.mean() → 4.0 7.5 Math module vs Numpy module • Math module functions: – math.cos(0.5) – Used for scalar (single) number values → single ints or floats – Cannot send an array object as an input to a math module function • Numpy module functions: – numpy.cos(arr) – Used for array objects (vectors or matrices) → numpy.array([0.2, 0.5, 0.8]) – numpy module functions always return a numpy array object 7.6 Dot product • Example (Vector vector multiplication) c University of Pretoria, Faculty of Engineering, Built Environment & IT 45 7. Arrays 46 – Use python to calculate: 7.3 2.4 4.2 8.1 · 12.2 6.1 • Outcomes: – looping through 2 corresponding numpy arrays – Indexing a numpy array (accessing the elements) – numpy.dot function • Example Solution: example 9-1-1.py import numpy vec1 = numpy.array([2.4, 4.2, 8.1]) vec2 = numpy.array([7.3, 12.2, 6.1]) prod = 0 for i in range(len(vec1)): prod = prod + (vec1[i] * vec2[i]) print "Manual dot calculation: " + str(prod) print "Numpy dot calculation: " + str(numpy.dot(vec1, vec2)) c University of Pretoria, Faculty of Engineering, Built Environment & IT 46 8. While Loop 8 47 While Loop 8.1 Introduction • ln(2) approximation (10k terms) ln(2) = 1 − 1 1 1 1 + − + − ... 2 3 4 5 • sin(x) approximation (5 terms) x3 x5 x7 x9 + − + + ... 3! 5! 7! 9! sin(x) = x − • Known condition (approximation error less than 1E-6) • Unknown number of terms → depend on problem • For-loop only viable if you can determine number of iterations required • New concept to repeat code an unknown number of times based on a condition → while-loop 8.2 Framework • Example (ln(2) approximation): – ln(2) can be approximated by: ln(2) = ∞ X n=1 (n+1) (−1) 1 1 1 1 = 1 − + − + ... n 2 3 4 – Use to introduce while-loop framework • Example Solution: example 4-2-1.py import math ln_approx = 0 error = 1 ind = 1 while (error > 1E-6): c University of Pretoria, Faculty of Engineering, Built Environment & IT 47 8. While Loop 48 sign = (-1)**(ind-1) term = 1.0 / ind ln_approx = ln_approx + (sign * term) ind = ind + 1 error = abs(ln_approx - math.log(2)) print "Num Terms: " + str(ind) print "Error: " + str(error) print "ln(2) Approx: " + str(ln_approx) execute code from top to bottom (only once) initialize the condition while condition: repeat indented code while the condition is True (top to bottom) update condition execute code from top to bottom (only once) • Used to repeat code an unknown number of times for a known condition • Executed from top to the bottom of the script • Indentation (white space) of the code tells Python it is part of the while-loop • Condition has to be True to enter the while-loop • The code inside the while-loop is repeated as long as the condition is True c University of Pretoria, Faculty of Engineering, Built Environment & IT 48 8. While Loop 49 • When the condition becomes False, program continues with under while-loop with not indented code • Careful: Infinite loop when condition is not updated inside the while-loop. • Condition has to be updated inside the while-loop 8.2.1 Conditions • Conditions, Questions or Comparisons: – A > B → while A is greater than B – A < B → while A is less than B – A >= B → while A is greater than or equal to B – A <= B → while A is less than or equal to B – A == B → while A is equal to B – A ! = B → while A is not equal to B – Note: ∗ = → assignment (A = B) ∗ == → comparison (is A == B) – Conditions always evaluate to True or False – New object type bool e.g. type(4 < 6) • Illustrative Example/s: – print (10 ∗ 24 > 100) – print (10.32 < 10) – print ((1.0/49) ∗ 49 == 1.0) – print (abs(1.0 − (1.0/49) ∗ 49) <= 1E − 6) • Outcomes: – Understand how conditions work – Understand that conditions evaluate to either True or False – Understand how to compare float (real) objects – Understand the abs function c University of Pretoria, Faculty of Engineering, Built Environment & IT 49 8. While Loop 8.3 50 Overview • Example (ln(2) approximation): – ln(2) can be approximated by: ln(2) = ∞ X n=1 (n+1) (−1) 1 1 1 1 = 1 − + − + ... n 2 3 4 • Outcomes: – initializing the condition (before the while-loop) – which condition to use: ∗ ∗ ∗ ∗ error == 1e − 6 error! = 1e − 6 error > 1e − 6 error < 1e − 6 – updating the condition (in the while-loop) – no range function or for-loop index → need to create an index counter • Example Solution: example 4-2-1.py import math ln_approx = 0 error = 1 ind = 1 while (error > 1E-6): sign = (-1)**(ind-1) term = 1.0 / ind ln_approx = ln_approx + (sign * term) ind = ind + 1 error = abs(ln_approx - math.log(2)) print "Num Terms: " + str(ind) print "Error: " + str(error) print "ln(2) Approx: " + str(ln_approx) c University of Pretoria, Faculty of Engineering, Built Environment & IT 50 8. While Loop 8.4 51 Infinite Loops • Example (ln(2) approximation): – ln(2) can be approximated by: ln(2) = ∞ X (n+1) (−1) n=1 1 1 1 1 = 1 − + − + ... n 2 3 4 • Outcomes: – Infinite loop → Not updating the condition in the while-loop – CTRL-C → break the infinite loop 8.5 Multiple Conditions • Example (ln(2) approximation): – ln(2) can be approximated by: ln(2) = ∞ X n=1 (n+1) (−1) 1 1 1 1 = 1 − + − + ... n 2 3 4 • Outcomes: – Infinite loop → Not updating the condition in the while-loop – Counter limit → maximum number of iterations of the while-loop → safeguard – Combine two conditions using and keyword • Example Solution: example 4-2-2.py import math ln_approx = 0 error = 1 ind = 1 max_terms = 30 while (error > 1E-6) and (ind <= max_terms): sign = (-1)**(ind-1) term = 1.0 / ind c University of Pretoria, Faculty of Engineering, Built Environment & IT 51 8. While Loop 52 ln_approx = ln_approx + (sign * term) ind = ind + 1 error = abs(ln_approx - math.log(2)) print "Num Terms: " + str(ind) print "Error: " + str(error) print "ln(2) Approx: " + str(ln_approx) • or keyword: – cond1 or cond2 → only False when both are False – True or True → True – True or False → True – False or False → False • and keyword: – cond1 and cond2 → only true when both are true – True and True → True – True and False → False – False and False → False • Illustrative Example/s: – number < 0 or number >= 10? – number < 10 or number >= 0? – number < 0 and number >= 10? – number < 10 and number >= 0? • Outcomes: – Understand difference between combining two conditions using the and / or keywords – Able to identify appropriate conditions and combine them as part of solving a problem • Example Solution: c University of Pretoria, Faculty of Engineering, Built Environment & IT 52 8. While Loop 8.6 53 number = 8 (number < 0) or (number >= 10) (number < 10) or (number >= 0) (number < 0) and (number >= 10) (number < 10) and (number >= 0) Additional Examples • Example (Sum Random Integers): – Write a program that simulates the throw of a dice. – Add the dice throws together until the sum is greater than 50 – What is the sum of the dice throws? – How many dice throws were needed? • Outcomes: – understanding the random.randint function • Example Solution: example 4-3-1.py import random ind = 1 my_sum = 0 while my_sum <= 50: dice = random.randint(1, 6) my_sum = my_sum + dice ind = ind + 1 print "Num Terms: " + str(ind) print "Sum: " + str(my_sum) • Example (Sum Random Integers): – Write a program that simulates the throw of a dice – Add the dice throws together until the sum is greater than 50 c University of Pretoria, Faculty of Engineering, Built Environment & IT 53 8. While Loop 54 – What is the sum of the dice throws? – How many dice throws were needed? – Count how many times the dice lands on a certain number and store this information to a list • Outcomes: – Using a list with a while-loop – Enhance the understanding of lists • Example Solution: example 4-3-2.py import random ind = 1 stats = [0]*6 my_sum = 0 while my_sum <= 50: dice = random.randint(1, 6) stats[dice-1] = stats[dice-1] + 1 my_sum = my_sum + dice ind = ind + 1 print print print print print "Num Terms: " + str(ind) "Sum: " + str(my_sum) "Stats:" " Dice: " + str(range(1, 7, 1)) " Count: " + str(stats) • Example (sin(x) Approximation): – sin(x) can be approximated by: sin(x) = x − x3 x5 x7 x9 + − + + ... 3! 5! 7! 9! – Compute the sin(0.5) approximation within an error of 1E-5 – Illustrate with using math.factorial() – Illustrate without using math.factorial() • Outcomes: c University of Pretoria, Faculty of Engineering, Built Environment & IT 54 8. While Loop 55 – Break problem down into smaller pieces – Understanding nested loops → inner for-loop completes for every iteration of the outer while-loop • Example Solution: example 4-4-1.py import math x_val = 0.5 my_sum = 0 ind = 1 error = 1 while (error >= 1e-6): sign = (-1)**(ind-1) odd = 2*ind - 1 denom = math.factorial(odd) term = (x_val**odd) / denom my_sum = my_sum + (sign * term) ind = ind + 1 error = abs(math.sin(x_val) - my_sum) print "Num Terms: " + str(ind) print "Sin(0.5) Approx: " + str(my_sum) print "Error: " + str(error) example 3-9-1.py import math x_val = 0.5 my_sum = 0 ind = 1 error = 1 while (error >= 1e-6): sign = (-1)**(ind-1) odd = 2*ind - 1 denom = 1 for j in range(1, odd+1, 1): denom = denom * j c University of Pretoria, Faculty of Engineering, Built Environment & IT 55 8. While Loop 8.7 56 term = (x_val**odd) / denom my_sum = my_sum + (sign * term) ind = ind + 1 error = abs(math.sin(x_val) - my_sum) print "Num Terms: " + str(ind) print "Sin(0.5) Approx: " + str(my_sum) print "Error: " + str(error) Recap • Loops – For-Loop → Used to repeat code a known and fixed number of times – While-Loop → Used to repeat code an unknown number of times for a known condition • While-Loop – Initialize condition outside the while-loop – Take care to use the correct condition for the while-loop – Update the condition inside the while-loop • Nested Loops – inner loop (for or while) is repeated for every iteration of the outer loop (for or while) c University of Pretoria, Faculty of Engineering, Built Environment & IT 56 9. Recap Quiz 9 57 Recap Quiz 9.1 Previous Concepts • Example (Equations of motion): – s(t) = s0 + v0 t + 0.5gt2 – s0 (initial height) = 829.8[m] Burj Khalifa in Dubai – v0 (initial velocity) = 0[m/s] – g (gravitational acceleration) = −9.81[m/s2 ] – t0 (initial time) = 0[s] – t (time) = t0 + 0.2i [s] for i in 0, 1, 2, . . . • What type of loop should you use to answer the following, and why: – 1) Calculate s(t) for 100 time intervals – 2) Calculate s(t) as long as the object is above the ground • Example (Add Integers): – Illustrate how to add the first 10 integers with a for-loop – Illustrate how to add the first 10 integers with a while-loop – For-loop → convenient due to the counter / looping through lists – While-loop → more general loop structure than the for-loop • Without knowing the problem behind this code, how many mistakes can you spot? There are 7 in total. import random as rand my_sum = 1.45 while my_sum: val = random.randint(0, 10) my_sum = my_sum -1**(i-1) / val c University of Pretoria, Faculty of Engineering, Built Environment & IT 57 10. If Statement 10 10.1 58 If Statement Framework • Example (Sum Random Integers): – Write a program that simulates the throw of a dice – Add the dice throws together until the sum is greater than 50 – What is the sum of the dice throws? – How many dice throws were needed? – Count how many times the dice lands on a certain number and store this information to a list • Outcomes: – Count how many time the dice lands on a certain number: ∗ list mapping → maps nicely to the problem → used to count all the numbers ∗ if-statement → much longer to code → would generally only be used to count one or two specific numbers • Example Solution: example 5-1-1.py import random cnt1 = 0 cnt2 = 0 sum_dice = 0 while sum_dice < 50: dice = random.randint(1, 6) sum_dice = sum_dice + dice if dice == 2: cnt1 = cnt1 + 1 if dice == 2: cnt2 = cnt2 + 1 print "Landed on 1 " + str(cnt1) + " times." print "Landed on 2 " + str(cnt2) + " times." c University of Pretoria, Faculty of Engineering, Built Environment & IT 58 10. If Statement 59 execute code from top to bottom (only once) initialize test for condition1 and condition2 if condition1: A - execute code if condition1 is True (only once) elif condition2: B - skip code if A was executed, otherwise execute code if condition2 is True (only once) else: C - skip code if either A or B were execute, otherwise execute code (only once) execute code from top to bottom (only once) • Used to decide which code should be executed → branching or flow control • Executed from top to the bottom of the script • Indentation (white space) of the code tells Python it is part of the if, elif or else c University of Pretoria, Faculty of Engineering, Built Environment & IT 59 10. If Statement 60 statements • Condition has to be True to enter (execute) the code in the if or elif statement • If the condition is False then the code in the if or elif statements is skipped (not executed) • The code in the else statement is only executed when the if or elif statements are not executed • Structure of the if, elif and else statements is very problem specific – Multiple or no elif statements can occur – One or no else statements can occur 10.1.1 Conditions • Conditions, Questions or Comparisons (Same as for the while loop): – A > B → while A is greater than B – A < B → while A is less than B – A >= B → while A is greater than or equal to B – A <= B → while A is less than or equal to B – A == B → while A is equal to B – A ! = B → while A is not equal to B – Note: ∗ = → assignment (A = B) ∗ == → comparison (is A == B) – Conditions always evaluate to True or False – Object type → bool 10.2 Multiple Conditions • Same as for the while loop • or keyword: – cond1 or cond2 → only False when both are False – True or True → True c University of Pretoria, Faculty of Engineering, Built Environment & IT 60 10. If Statement 61 – True or False → True – False or False → False • and keyword: – cond1 and cond2 → only true when both are true – True and True → True – True and False → False – False and False → False 10.3 User Input • Example (print grade): – Write a program that asks the user to input a students grade. The program must then print one of the following messages to the screen, based on the students grade: ∗ 0–49 → Fail ∗ 50–74 → Pass ∗ 75–100 → Distinction – Also test the program with unexpected user input values → -60, 1003 → How would you change the program to account for this? • Outcomes: – input(msg) function → value inputs (int or float) – raw input(msg) function → string inputs (str) – Multiple elif statements – Order of elif statements • Example Solution: example 5-2-1.py grade = input("Enter students grade: ") if grade < 50: print "Fail" elif grade < 75: print "Pass" else: print "Distinction" c University of Pretoria, Faculty of Engineering, Built Environment & IT 61 10. If Statement 62 example 5-2-2.py grade = input("Enter students grade: ") if grade < 0 or grade > 100: print "Invalid grade" elif grade < 50: print "Fail" elif grade < 75: print "Pass" else: print "Distinction" 10.4 Multiple Decisions • Example (print integer information): – Write a program that asks the user to input an integer. The program must then print to the screen whether or not the integer is even or odd and whether the integer is greater than zero or not • Outcomes: – Remainder function (%) – Multiple decisions → multiple if-else blocks (statements) – Flow control and structure: ∗ ∗ ∗ ∗ ∗ 4 if blocks (single questions) vs. 2 if-else blocks vs. 4 if blocks (multiple questions) vs. 4 if blocks (single question - nested) pythontutor.com • Example Solution: example 5-3-1.py int_val = input("Enter an integer value: ") if (int_val % 2) == 1: print "Odd Number" if (int_val % 2) != 1: c University of Pretoria, Faculty of Engineering, Built Environment & IT 62 10. If Statement 63 print "Even Number" if (int_val > 0): print "Greater than 0" if (int_val < 0): print "Less than 0" example 5-3-2.py int_val = input("Enter an integer value: ") if (int_val % 2) == 1: print "Odd Number" else: print "Even Number" if (inv_val > 0): print "Greater than 0" else: print "Less than 0" example 5-3-3.py int_val = input("Enter an integer value: ") if (int_val % 2) == 1 and (int_val > 0): print "Odd Number" print "Greater than 0" if (int_val % 2) == 1 and (int_val < 0): print "Odd Number" print "Greater than 0" if (int_val % 2) != 1 and (int_val > 0): print "Even Number" print "Greater than 0" if (int_val % 2) != 1 and (int_val < 0): print "Even Number" print "Less than 0" c University of Pretoria, Faculty of Engineering, Built Environment & IT 63 10. If Statement 64 example 5-3-3.py int_val = input("Enter an integer value: ") if (int_val % 2) == 1: if (inv_val > 0): print "Odd Number" print "Greater than 0" if (int_val % 2) == 1: if (inv_val < 0): print "Odd Number" print "Less than 0" if (int_val % 2) != 1: if (inv_val > 0): print "Even Number" print "Greater than 0" if (int_val % 2) != 1: if (inv_val < 0): print "Even Number" print "Less than 0" 10.5 Recap • If-elif-else Statements – Used to decide which code should be executed → branching or flow control. – Only 1 section of code inside a if-elif-else block is executed → the first section where the condition is True → if no condition is True then only the else section is executed – Multiple decisions → require multiple if-elif-else blocks – Take care of the structure of the if-elif-else blocks → problem specific → elif and else sections may not be needed → or multiple elif section may be needed – Take care on the order in which you place if-elif-elif-else sections c University of Pretoria, Faculty of Engineering, Built Environment & IT 64 12. Nested Structures 11 65 Recap Quiz 11.1 Previous Concepts • What letter/s will get printed to the screen? val = 34 if val > 0: print ’A’ if val != 50: print ’B’ elif val > 50: print ’C’ else: print ’D’ • What letter/s will get printed to the screen? 12 12.1 val = 12.45 if val == ’a’: print ’A’ elif val > 10: if val != 20: print ’B’ if val > 12: print ’C’ elif val < 14: print ’D’ else: print ’E’ Nested Structures Introduction • Nested structures → simple structure nested inside another simple structure → for example: a for-loop nested inside a while-loop c University of Pretoria, Faculty of Engineering, Built Environment & IT 65 12. Nested Structures 66 • Examples we have seen so far: – Nested loops: for every outer loop iteration the nested inner loop (indented) is executed and does all of it’s iterations – Nested if statements: code inside inner if-elif statement executes only when both outer and inner conditions are True. • Nested structures needed to solve a given problem → problem specific → can vary from problem to problem • Different solution strategies → lead to different nested structures needed to solve the given problem 12.2 Examples • Example (Guessing game) – Write a program that throws 2 dice and adds their values together (2 + 6 = 8). The program must then ask the user to guess what the answer is. The program must give the user a max of three guesses to try answer correctly. The program must also print to the screen if the user guessed too high or too low or correctly. • Outcomes: – Break the problem down into smaller pieces – Identify what structures are needed to solve the problem – Why a while-loop and not a for-loop? – Correctly implement nested structures • Example Solution: example 6-1-1.py import random dice1 = random.randint(1, 6) dice2 = random.randint(1, 6) sum_dice = dice1 + dice2 user = 0 guess = 0 max_guess = 3 c University of Pretoria, Faculty of Engineering, Built Environment & IT 66 12. Nested Structures 67 while (user != sum_dice) and (guess < max_guess): user = input("Guess the sum of 2 dice: ") guess = guess + 1 if user == sum_dice: print "Correct" elif user > sum_dice: print "Too high" elif user < sum_dice: print "Too low" print "End" • Example (Approximate pi, R=1) R 2R • Areas: Ac πR2 /4 π = = 2 As 4R /4 4 • Approximation (Throwing darts): #darts in circle π ≈ #darts in square 4 c University of Pretoria, Faculty of Engineering, Built Environment & IT 67 12. Nested Structures 68 • Outcomes: – Break the problem down into smaller pieces – Identify what structures are needed to solve the problem – Correctly implement nested structures – Different radius → random.uniform(a, b) • Example Solution: example 6-2-1.py import math import random radius = 1 cnt_circle = cnt_square = error = 1 while (error dart_x = dart_y = 0 0 > 1E-3): random.random() random.random() dist = (dart_x**2 + dart_y**2) ** 0.5 cnt_square = cnt_square + 1 if dist < radius: cnt_circle = cnt_circle + 1 pi_approx = 4.0 * cnt_circle / cnt_square error = abs(math.pi - pi_approx) print "pi approx = " + str(pi_approx) print "pi actual = " + str(math.pi) print "num darts = " + str(cnt_square) example 6-2-2.py import math import random radius = 2 cnt_circle = 0 cnt_square = 0 error = 1 c University of Pretoria, Faculty of Engineering, Built Environment & IT 68 12. Nested Structures 69 while (error > 1E-3): dart_x = random.uniform(-radius, radius) dart_y = random.uniform(-radius, radius) dist = (dart_x**2 + dart_y**2) ** 0.5 cnt_square = cnt_square + 1 if dist < radius: cnt_circle = cnt_circle + 1 approx = 1.0 * cnt_circle / cnt_square error = abs((math.pi / 4) - approx) pi_approx = approx print "pi approx = print "pi actual = print "num darts = * " " " 4 + str(pi_approx) + str(math.pi) + str(cnt_square) • Example (Water tank) – Consider a list water flow that contains the volume of fluid (m3 ) that will flow into a tank every hour. The water in the tank must be discharged when the additional water would exceed the reservoir’s capacity of 100 m3 . The discharge is instantaneous and occurs when the valve reads a 1 from the list valve read (for the corresponding hour), otherwise it remains closed when reads a 0. – Write a program that generates the input list valveread. – Use random inflows between 0 and 50 m3 over a day. • Outcomes: – Break the problem down into smaller pieces – Identify what structures are needed to solve the problem • Example Solution: example 6-6-1.py from random import randint water_flow = [] c University of Pretoria, Faculty of Engineering, Built Environment & IT 69 12. Nested Structures 70 max_capacity = 100 for i in range(0, 24, 1): water_flow.append(randint(0, 50)) valve_read = [] tank_capacity = 0 for flow in water_flow: if (tank_capacity + flow) < max_capacity: tank_capacity = tank_capacity + flow valve_read.append(0) else: valve_read.append(1) tank_capacity = flow print "Inflows: " + str(water_flow) print "Valve Readings: " + str(valve_read) print "Number of discharges per day " + str(sum(valve_read)) • Example (Finding Prime numbers) – Write a program that finds the prime numbers from 2 to N. The program must save the prime numbers in a list. Use N = 120. • Outcomes: – Break the problem down into smaller pieces – Identify what structures are needed to solve the problem – Correctly implement nested structures – Can we improve the efficiency of the prime number test • Example Solution: example 6-3-1.py N = 120 primelist = [] for number in range(2, N+1, 1): count_divisor = 0 for divisor in range(2, number, 1): if (number % divisor) == 0: count_divisor = count_divisor + 1 c University of Pretoria, Faculty of Engineering, Built Environment & IT 70 12. Nested Structures 71 if count_divisor == 0: primelist.append(number) print "The primes found are " + str(primelist) example 6-3-2.py N = 120 primelist = [] for number in range(2, N+1, 1): count_divisor = 0 mid_number = int(number**0.5) + 1 for divisor in range(2, mid_number+1, 2): if (number % divisor) == 0: count_divisor = count_divisor + 1 if count_divisor == 0: primelist.append(number) print "The primes found are " + str(primelist) • Example (Longest Collatz sequence) – The following iterative sequence is defined for the set of positive integers: n → n/2 (n is even) n → 3n + 1 (n is odd) – Using the rule above and starting with 13, we generate the following sequence: 13, 40, 20, 10, 5, 16, 8, 4, 2, 1 – Which starting number, under 10000, produces the longest chain? • Outcomes: – Identify what structures are needed to solve the problem – Correctly implement nested structures – Break the problem down into smaller pieces – Test for and store a maximum or minimum number • Example Solution: c University of Pretoria, Faculty of Engineering, Built Environment & IT 71 12. Nested Structures 72 example 6-4-1.py N = 10000 max_chain_len = 0 for start_num in range(1, N, 1): num = start_num chain = [num] while num > 1: if (num % 2) == 0: num = num / 2 else: num = 3*num + 1 chain.append(num) if len(chain) > max_chain_len: max_chain_len = len(chain) max_chain_num = start_num print "Max chain length: " + str(max_chain_len) print "Starting number: " + str(max_chain_num) • Example (Loading cycles of a spring) – You are given a list of values representing the force acting on a spring. – You need to compute the number of load and unload cycles where ∗ load cycle → when the force is the same or consecutively increases ∗ unload cycle → when force consecutively decreases – Use a list of 10 forces where each force is a random number between 0 and 20. • Outcomes: – Break the problem down into smaller pieces – Identify the required structures to solve the problem – Correctly implement nested structures • Example Solution: example 6-5-1.py from random import randint c University of Pretoria, Faculty of Engineering, Built Environment & IT 72 12. Nested Structures 73 forces = [] for i in range(1, 10, 1): forces.append(randint(0, 20)) start_load = 0 start_unload = 0 load_counter = 0 unload_counter = 0 last_force = forces[0] for index in range(1, len(forces), 1): force = forces[index] if start_load == 0 and start_unload == 0: if force >= last_force: start_load = 1 else: start_unload = 1 else: if start_load == 1 and force < last_force: start_load = 0 start_unload = 1 load_counter = load_counter + 1 elif start_unload == 1 and force > last_force: start_unload = 0 start_load = 1 unload_counter = unload_counter + 1 last_force = force if start_load == 1: load_counter = load_counter + 1 else: unload_counter = unload_counter + 1 print "Forces " + str(forces) print "Loading cycles " + str(loadcounter) print "Unloading cycles " + str(unloadcounter) c University of Pretoria, Faculty of Engineering, Built Environment & IT 73 12. Nested Structures 12.3 74 Recap • Nested structures – Nested structures needed to solve a given problem → problem specific → can vary from problem to problem – Different solution strategies → lead to different nested structures needed to solve the given problem • How many times will Display be printed? for number1 in range(1, 5, 1): for number2 in range(1, 3, 1): if number1 > number2: print ’Display’ • How many times will Display be printed? for number1 in range(1, 5, 1): for number2 in range(1, number1, 1): print ’Display’ c University of Pretoria, Faculty of Engineering, Built Environment & IT 74 13. Functions 13 13.1 75 Functions Framework • Example (Series approximation) – Consider the following series: ∞ X 1! 2! 3! (k!)2 = + + + ... (2k)! 2! 4! 6! k=1 – Compute the value that the above series converges to, within an error of 1E-5 – Illustrate without using the math module • Outcomes: – Think about the problem in terms of functions – Test the function/s independently • Example Solution: example 7-1-1.py num = 1 approx = 0 error = 1 while error > 1E-5: fact = 1.0 for i in range(1, num+1, 1): fact = fact * i fact2 = 1.0 for i in range(1, 2*num+1, 1): fact2 = fact2 * i term = (fact**2 / fact2) approx = approx + term error = abs(term) num = num + 1 print "Approx: " + str(approx) c University of Pretoria, Faculty of Engineering, Built Environment & IT 75 13. Functions 76 example 7 1 2 mod.py def factorial(num): fact = 1 for i in range(1, num+1, 1): fact = fact * i return fact example 7-1-2.py import example_7_1_2_mod as mpr213 num = 1 approx = 0 error = 1 while error > 1E-5: fact = mpr213.factorial(num) fact2 = mpr213.factorial(2*num) term = (fact**2 / fact2) approx = approx + term error = abs(term) num = num + 1 print "Approx: " + str(approx) • Used to break a complex problem down into smaller sections / functions → easier to think about the problem in terms of functionality • Used to test smaller sections of code independently • ”Script File” used to run the program or code → does something when executed • ”Module File” used to store functions → does nothing when executed • ”Script File” imports and uses functions from the ”Module File” • ”Script File” and ”Module File” must be saved in the same location on your hard drive / flash disk • ”Script File”: c University of Pretoria, Faculty of Engineering, Built Environment & IT 76 13. Functions 77 Script Module (my_script.py) (module.py) import module execute code from top to bottom (only once) def function1(input1, input2, ...): in1 = object in2 = object out1, out2, ... = module.function1(in1, in2, ...) execute code from top to bottom (only when function1 is called) return output1, output2, ... execute code from top to bottom (only once) def function2(input1, input2, ...): execute code from top to bottom (only when function2 is called) return output1, output2, ... – Executed from top to the bottom of the script – Import ”Module Files” the same way you would the math or random modules → using the names you gave the ”Module Files” – Use functions inside the ”Module File” the same way you would the functions inside the math or random modules → using the names you gave the functions inside the ”Module File” • ”Module File”: – Indentation (white space) of the code tells Python which code is part of which function – Code inside a function is only executed when the function is called (used) – Code inside the ”Module File” cannot see code inside the ”Script File” and visa versa – Information (objects) is passed to the ”Module File” functions as inputs → only when the function is called – Information (objects) is passed back to the ”Script File” as outputs → only when the function is called • Example (Series approximation) c University of Pretoria, Faculty of Engineering, Built Environment & IT 77 13. Functions 78 – Consider the following series: ∞ X 1! 2! 3! (k!)2 = + + + ... (2k)! 2! 4! 6! n=1 – Compute the value that the above series converges to, within an error of 1E-5 – Illustrate without using the math module • Outcomes: – Think about the problem in terms of functions – Test the function/s independently – Illustrate the use of mpr213 module vs. use of the math module • Example Solution: example 7 1 2 mod.py def factorial(num): fact = 1 for i in range(1, num+1, 1): fact = fact * i return fact example 7-1-2.py import example_7_1_2_mod as mpr213 num = 1 approx = 0 error = 1 while error > 1E-5: fact = mpr213.factorial(num) fact2 = mpr213.factorial(2*num) term = (fact**2 / fact2) approx = approx + term error = abs(term) num = num + 1 c University of Pretoria, Faculty of Engineering, Built Environment & IT 78 13. Functions 13.2 79 Additional Examples • Example (Interpolation – Background): x 0 1 2 Data points: 3 4 5 6 y 0.0 0.8415 0.9093 0.1411 -0.7568 -0.9589 -0.2794 • What is the corresponding y values for the following: x = [1.2, 2.1, 2.9, 3.5, 4.8, 5.3, 5.7] • As we only have discrete data points and no known function to use, we have to estimate the y values • We will consider two ways to interpolate between the data points in order to determine the y values • Example (Interpolation – Background): • Linear interpolation: y(x) = y0 + (y1 − y0 ) x − x0 x1 − x0 • Example (Interpolation – Background): • Quadratic interpolation: y(x) = y0 (x − x1 )(x − x2 ) (x0 − x1 )(x0 − x2 ) + y1 (x − x0 )(x − x2 ) (x1 − x0 )(x1 − x2 ) + y2 (x − x0 )(x − x1 ) (x2 − x0 )(x2 − x1 ) c University of Pretoria, Faculty of Engineering, Built Environment & IT 79 13. Functions 80 1 (x0, y0) (x, y) (x1, y1) 0 1 2 3 4 5 6 -1 • Example (Interpolation – Question): – Calculate the corresponding interpolated y values, from the data points, using both linear and quadratic interpolation methods – Calculate the difference in interpolated y values between the two interpolation methods • Outcomes: – Think about the problem in terms of functions – Test the function/s independently – Generic, reusable function → interpolate for different x and y data points? → input into the function – Optional inputs (keyword inputs) • Required structures (without functions) c University of Pretoria, Faculty of Engineering, Built Environment & IT 80 13. Functions 81 1 (x , y ) 0 0 (x1, y1) (x, y) (x2, y2) 0 1 2 3 4 5 6 -1 – create x and y data points – — Linear Method — – initialize list to store y values – loop through x values – – loop through x data points test if x value is between x0 and x1 – calculate the y value from method 1 – need a index counter to manage x0 , y0 , etc – append the y value to the list • Required structures (without functions) – — Quadratic Method — – initialize list to store y values c University of Pretoria, Faculty of Engineering, Built Environment & IT 81 13. Functions 82 – loop through x values – – loop through x data points test if x value is between x0 and x2 – calculate the y value from method 2 – need a index counter to manage x0 , y0 , etc – append the y value to the list – — Compare Methods — – initialize list to store interpolated y differences – loop through interpolated y values – calculate difference – need index to access both interpolated y lists – append difference to list • Example Solution: example 7-2-1.py x_data = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0] y_data = [0.0, 0.8415, 0.9093, 0.1411, -0.7568, -0.9589, -0.2794] y_linear = [] y_quadratic = [] x_values = [0.8, 1.2, 1.6, 2.1, 2.9, 3.5, 4.8, 5.3, 5.7] for x_val in x_values: # Linear Method for i in range(0, len(x_data)-1, 1): x0 = x_data[i] x1 = x_data[i+1] if x0 <= x_val and x_val <= x1: y0 = y_data[i] y1 = y_data[i+1] y = y0 + (y1 - y0) * (x_val - x0) / (x1 - x0) y_linear.append(y) # Quadratic Method for i in range(1, len(x_data)-1, 1): x0 = x_data[i-1] x1 = x_data[i] x2 = x_data[i+1] c University of Pretoria, Faculty of Engineering, Built Environment & IT 82 13. Functions 83 if x0 <= x_val and x_val <= x2: y0 = y_data[i-1] y1 = y_data[i] y2 = y_data[i+1] y = ( y0 * (((x_val - x1)*(x_val - x2)) / ((x0 - x1)*(x0 - x2))) + y1 * (((x_val - x0)*(x_val - x2)) / ((x1 - x0)*(x1 - x2))) + y2 * (((x_val - x0)*(x_val - x1)) / ((x2 - x0)*(x2 - x1))) ) y_quadratic.append(y) # Compare Methods y_diff = [] for i in range(0, len(y_linear), 1): y_diff.append(y_linear[i] - y_quadratic[i]) print print print print print print print print print print print print "Data:" "x: " + str(x_data) "y: " + str(y_data) "Interpolation:" "X values: " + str(x_values) "Y linear: " str(y_linear) "Y quadratic: " str(y_quadratic) "Y difference: " str(y_diff) example 7 2 2 mod.py def interpolate_single_points(x_val, x_coords, y_coords): if len(x_coords) == 2: y = ( y_coords[0] + ( (y_coords[1] - y_coords[0]) * ((x_val - x_coords[0]) / (x_coords[1] - x_coords[0])) ) ) elif len(x_coords) == 3: y = ( y_coords[0] * ( c University of Pretoria, Faculty of Engineering, Built Environment & IT 83 13. Functions 84 ( (x_val ((x_coords[0] ) + y_coords[1] * ( ( (x_val ((x_coords[1] ) + y_coords[2] * ( ( (x_val ((x_coords[2] ) - x_coords[1]) * (x_val - x_coords[2])) - x_coords[1]) * (x_coords[0] - x_coords[2])) - x_coords[0]) * (x_val - x_coords[2])) - x_coords[0]) * (x_coords[1] - x_coords[2])) - x_coords[0]) * (x_val - x_coords[1])) - x_coords[0]) * (x_coords[2] - x_coords[1])) ) return y def linear_interpolate(x_val, x_data, y_data): for i in range(0, len(x_data)-1, 1): x0 = x_data[i] x1 = x_data[i+1] if x0 <= x_val and x_val <= x1: y0 = y_data[i] y1 = y_data[i+1] y = interpolate_single_points(x_val, [x0, x1], [y0, y1]) return y def quadratic_interpolate(x_val, x_data, y_data): for i in range(1, len(x_data)-1, 1): x0 = x_data[i-1] x1 = x_data[i] x2 = x_data[i+1] if x0 <= x_val and x_val <= x2: y0 = y_data[i-1] y1 = y_data[i] y2 = y_data[i+1] y = interpolate_single_points(x_val, [x0, x1, x2], [y0, y1, y2]) return y def interpolate(x_val, x_data, y_data, method=1): if method == 1: y = linear_interpolate(x_val, x_data, y_data) elif method == 2: c University of Pretoria, Faculty of Engineering, Built Environment & IT 84 13. Functions 85 y = quadratic_interpolate(x_val, x_data, y_data) return y example 7-2-2.py import example_7_2_2_mod as mpr213 x_data = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0] y_data = [0.0, 0.8415, 0.9093, 0.1411, -0.7568, -0.9589, -0.2794] y_linear = [] y_quadratic = [] x_values = [0.8, 1.2, 1.6, 2.1, 2.9, 3.5, 4.8, 5.3, 5.7] for x_val in x_values: y1 = mpr213.interpolate(x_val, x_data, y_data, method=1) y2 = mpr213.interpolate(x_val, x_data, y_data, method=2) y_linear.append(y1) y_quadratic.append(y2) # Compare Methods y_diff = [] for i in range(0, len(y_linear), 1): y_diff.append(y_linear[i] - y_quadratic[i]) print print print print print print print print print print print print "Data:" "x: " + str(x_data) "y: " + str(y_data) "Interpolation:" "X values: " + str(x_values) "Y linear: " str(y_linear) "Y quadratic: " str(y_quadratic) "Y difference: " str(y_diff) • Example (Goldbach’s other conjecture) – It was proposed by Christian Goldbach that every odd composite number can be written as the sum of a prime and twice a square (any square). 9 = 7 + 2 × 12 15 = 7 + 2 × 22 21 = 3 + 2 × 32 25 = 7 + 2 × 32 c University of Pretoria, Faculty of Engineering, Built Environment & IT 85 13. Functions 86 – It turns out that the conjecture was false. – What is the smallest odd composite that cannot be written as the sum of a prime and twice a square? • Outcomes: – Think about the problem in terms of functions – Easier to understand and develop the code with functions than without functions – Test separate functionality of a problem independently • Required structures (without functions) – loop until the conjecture is false – generate odd number – loop from 3 to odd number – – test if odd number is composite if number is odd composite – initialize a prime list – loop from 2 to odd number (generate primes) [A] – – – – loop from 2 to A test if number is prime append prime to prime list loop through prime list – test conjecture – update condition for while loop – ??? Insane complexity with out functions ??? • Example Solution: example 7-3-1.py odd_composite = 1 conjecture = True while conjecture: conjecture = False odd_composite = odd_composite + 2 prime_list = [] c University of Pretoria, Faculty of Engineering, Built Environment & IT 86 13. Functions 87 is_composite = False for num in range(3, odd_composite, 1): if odd_composite % num == 0: is_composite = True if num <= 2: prime_list.append(num) elif num % 2 == 1: is_prime = True mid_num = int(num**0.5) + 1 for i in range(3, mid_num+1, 2): if num % i == 0: is_prime = False if is_prime: prime_list.append(num) if is_composite: for prime in prime_list: number = ((odd_composite - prime) / 2.0)**0.5 error = abs(number - int(number)) if error < 1E-6: conjecture = True else: conjecture = True print ("The number " + str(odd_composite) + " cannot be expressed as " + "[prime + 2*(num**2)]") example 7 3 2 mod.py def is_prime(num): prime = True midpoint = int(num**0.5) + 1 for i in range(2, midpoint+1, 1): if num % i == 0: prime = False return prime def is_square(num): square = False if num == (int(num**0.5))**2: square = True c University of Pretoria, Faculty of Engineering, Built Environment & IT 87 13. Functions 88 return square def create_primes(num): primes = [] for i in range(2, num, 1): if is_prime(i): primes.append(i) return primes example 7-3-2.py import example_7_3_2_mod as mpr213 odd_composite = 1 conjecture = True while conjecture: conjecture = False if mpr213.is_prime(odd_composite): odd_composite = odd_composite + 2 conjecture = True else: primes = mpr213.create_primes(odd_composite) for prime in primes: sqr_num = ((odd_composite - prime) / 2.0) if mpr213.is_square(sqr_num): conjecture = True odd_composite = odd_composite + 2 print ("The number " + str(odd_composite-2) + " cannot be expressed as " + "[prime + 2*(num**2)]") c University of Pretoria, Faculty of Engineering, Built Environment & IT 88 14. Recap Quiz 14 14.1 89 Recap Quiz Previous Concepts • How many mistakes can you spot? (7 in total) script.py import mpr213 as mpr a = 12 b = "13" print mpr213.is_even(a, b) my mpr213.py def iseven(num): even = True if num % 2 == 0: even = True return num • What gets printed to the screen? script.py import mpr213 numbers = [1, 4, 3, 3, 6, 8, 3, 2, 1] a = 3 print mpr213.sum_number(numbers, a) mpr213.py def sum_number(entries, num): my_sum = 0 for val in entries: if val == num: my_sum = my_sum + num return my_sum c University of Pretoria, Faculty of Engineering, Built Environment & IT 89 15. Plotting 15 15.1 90 Plotting Overview • Done by using the matplotlib module • Types of 2D plots: from matplotlib import pyplot – pyplot.plot → line or scatter plots – pyplot.semilogx → line or scatter plots → log scale on the x axis – pyplot.semilogy → line or scatter plots → log scale on the y axis – pyplot.loglog → line or scatter plots → log scale on both the x and y axis – pyplot.bar → vertical bar chart – pyplot.barh → horizontal bar chart • See www.http://matplotlib.org for many example plots • General usage of the matplotlib module: 1. from matplotlib import pyplot 2. pyplot.figure(num) → create a blank figure canvas, given a figure number 3. pyplot.plot(xdata, ydata, plotstyle) → plot data to the figure canvas 4. pyplot.title("Title") → create a figure title 5. pyplot.xlabel("X Label") → create a x axis label 6. pyplot.ylabel("Y Label") → create a y axis label 7. pyplot.legend(loc=num) → create a legend at a given location on the figure 8. pyplot.show() → show the figure canvas with plotted data • See the help() information for more on each of the above • pyplot.plot(xdata, ydata, plotstyle): – xdata is a list of x axis data – ydata is a list of corresponding y axis data – both lists need to be the same length c University of Pretoria, Faculty of Engineering, Built Environment & IT 90 15. Plotting 91 – plotstyle → string that defines the style of the line and the markers → see help(pyplot.plot) For example ∗ pyplot.plot(xdata, ydata, "b-") → blue (”b”), solid (”-”) line ∗ pyplot.plot(xdata, ydata, "g--") → green (”g”), dashed (”--”) line ∗ pyplot.plot(xdata, ydata, "ro") → red (”r”), circle (”o”) markers 15.2 Examples • Example (Cannonball Trajectory): – A cannonball is fired from a cannon with an initial x and y velocity (Vx0 , Vy0 ). The cannonball exits the cannon at an initial x and y coordinate of x0 = 0 and y 0 = 0. – The x and y coordinates of a cannonball trajectory are updated by: xn+1 = xn + ∆t (Vxn ) y n+1 = y n + ∆t Vyn – The velocities of the cannonball are updated by: n n 2Vy 2Vx n+1 n+1 n n + 9.81 Vx = Vx − ∆t Vy = Vy − ∆t m m – where ∆t is a constant time step and m is the mass of the cannon ball. • Example (Cannonball Trajectory): – Write a python program that visualises the trajectory of the cannonball for various different masses (m) and initial conditions (x0 , y 0 , Vx0 , Vy0 ). – Take ∆t as 0.01 s • Outcomes: – Basic 2D line plotting – Figure annotation and ”fontsize” – Multiple figures – Subplots – Multiple plots on one figure – Legend and legend location • Example Solution: c University of Pretoria, Faculty of Engineering, Built Environment & IT 91 15. Plotting 92 example 8 1 1 mod.py def trajectory(mass, delta_t, x0, y0, vx0, vy0): ind = 0 yn1 = 1 x_coords = [x0] y_coords = [y0] x_velocity = [vx0] y_velocity = [vy0] while yn1 > 0: xn1 = x_coords[ind] + (delta_t * x_velocity[ind]) yn1 = y_coords[ind] + (delta_t * y_velocity[ind]) vxn1 = ( x_velocity[ind] (delta_t * (2.0 * x_velocity[ind] / mass)) ) vyn1 = ( y_velocity[ind] (delta_t * ((2.0 * y_velocity[ind] / mass) + 9.81)) ) if yn1 > 0: x_coords.append(xn1) y_coords.append(yn1) x_velocity.append(vxn1) y_velocity.append(vyn1) ind = ind + 1 return x_coords, y_coords example 8-1-1.py import math import example_8_1_1_mod as mpr213 from matplotlib import pyplot delta_t = 0.1 mass = 10 x0 = 0 y0 = 0 # Figure 1 c University of Pretoria, Faculty of Engineering, Built Environment & IT 92 15. Plotting 93 pyplot.figure(1) theta = 45 vel = 40 vx0 = vel * math.cos(math.radians(theta)) vy0 = vel * math.sin(math.radians(theta)) x_coords, y_coords = mpr213.trajectory(mass, delta_t, x0, y0, vx0, vy0) pyplot.plot(x_coords, y_coords) pyplot.title("Cannonball Trajectory", fontsize=16) pyplot.xlabel("Distance [m]", fontsize=12) pyplot.ylabel("Height [m]", fontsize=12) # Figure 2 pyplot.figure(2) theta = 25 vel = 40 vx0 = vel * math.cos(math.radians(theta)) vy0 = vel * math.sin(math.radians(theta)) x_coords, y_coords = mpr213.trajectory(mass, delta_t, x0, y0, vx0, vy0) pyplot.plot(x_coords, y_coords) pyplot.title("Cannonball Trajectory", fontsize=16) pyplot.xlabel("Distance [m]", fontsize=12) pyplot.ylabel("Height [m]", fontsize=12) pyplot.show() example 8-1-2.py import math import example_8_1_1_mod as mpr213 from matplotlib import pyplot delta_t = 0.1 mass = 10 x0 = 0 y0 = 0 c University of Pretoria, Faculty of Engineering, Built Environment & IT 93 15. Plotting 94 pyplot.figure(1) pyplot.subplot(1, 2, 1) # subplot(#rows, #cols, plotnum) theta = 45 vel = 40 vx0 = vel * math.cos(math.radians(theta)) vy0 = vel * math.sin(math.radians(theta)) x_coords, y_coords = mpr213.trajectory(mass, delta_t, x0, y0, vx0, vy0) pyplot.plot(x_coords, y_coords) pyplot.title("Cannonball Trajectory", fontsize=16) pyplot.xlabel("Distance [m]", fontsize=12) pyplot.ylabel("Height [m]", fontsize=12) pyplot.subplot(1, 2, 2) # subplot(#rows, #cols, plotnum) theta = 25 vel = 40 vx0 = vel * math.cos(math.radians(theta)) vy0 = vel * math.sin(math.radians(theta)) x_coords, y_coords = mpr213.trajectory(mass, delta_t, x0, y0, vx0, vy0) pyplot.plot(x_coords, y_coords) pyplot.title("Cannonball Trajectory", fontsize=16) pyplot.xlabel("Distance [m]", fontsize=12) pyplot.ylabel("Height [m]", fontsize=12) pyplot.show() example 8-1-3.py import math import example_8_1_1_mod as mpr213 from matplotlib import pyplot delta_t = 0.1 mass = 10 x0 = 0 c University of Pretoria, Faculty of Engineering, Built Environment & IT 94 15. Plotting 95 y0 = 0 # Figure 1 pyplot.figure(1) theta = 45 vel = 40 vx0 = vel * math.cos(math.radians(theta)) vy0 = vel * math.sin(math.radians(theta)) x_coords, y_coords = mpr213.trajectory(mass, delta_t, x0, y0, vx0, vy0) # Plot 1 pyplot.plot(x_coords, y_coords) theta = 25 vel = 40 vx0 = vel * math.cos(math.radians(theta)) vy0 = vel * math.sin(math.radians(theta)) x_coords, y_coords = mpr213.trajectory(mass, delta_t, x0, y0, vx0, vy0) # Plot 2 pyplot.plot(x_coords, y_coords) pyplot.title("Cannonball Trajectory", fontsize=16) pyplot.xlabel("Distance [m]", fontsize=12) pyplot.ylabel("Height [m]", fontsize=12) pyplot.show() example 8-1-4.py import math import example_8_1_1_mod as mpr213 from matplotlib import pyplot delta_t = 0.1 mass = 10 x0 = 0 y0 = 0 c University of Pretoria, Faculty of Engineering, Built Environment & IT 95 15. Plotting 96 # Figure 1 pyplot.figure(1) for theta in [25, 35, 45, 55, 65]: vel = 40 vx0 = vel * math.cos(math.radians(theta)) vy0 = vel * math.sin(math.radians(theta)) x_coords, y_coords = mpr213.trajectory(mass, delta_t, x0, y0, vx0, vy0) label = "Theta: " + str(theta) pyplot.plot(x_coords, y_coords, label=label) pyplot.title("Cannonball Trajectory", fontsize=16) pyplot.xlabel("Distance [m]", fontsize=12) pyplot.ylabel("Height [m]", fontsize=12) pyplot.legend(loc=1) pyplot.show() • Example (Numerical Integration): – In numerical analysis, the trapezoidal rule is a technique for approximating the definite integral: Z b f (x) dx ≈ a N −1 (b − a) X (f (xn+1 ) + f (xn )) 2N n=0 N=6 • Example (Numerical Integration): c University of Pretoria, Faculty of Engineering, Built Environment & IT 96 15. Plotting 97 – Write a python program that calculates the numerical integral of: f (x) = sin2 (x) 0.001 cos(x) between a = xl = −π and b = xu = π, using the trapezoidal rule. – The program must also create a similar graph to one shown in the previous slide, to visualize the numerical integration • Outcomes: – Using a function as an input to another function – Multiple plots on one figure – Using a function to plot data / lines • Example Solution: example 8 2 1 mod.py import math from matplotlib import pyplot def my_function(xval): fx = (math.sin(xval)**2) / (0.001 * math.cos(xval)) return fx def integrate(func, lower, upper, num): delta_x = (upper - lower) / float(num) integral = 0 for i in range(0, num, 1): xval0 = lower + (i * delta_x) xval1 = xval0 + delta_x yval0 = func(xval0) yval1 = func(xval1) area = 0.5 * delta_x * (yval1 + yval0) integral = integral + area plot_square(xval0, xval1, yval0, yval1) return integral def plot_function(func, lower, upper, num): delta_x = (upper - lower) / float(num) c University of Pretoria, Faculty of Engineering, Built Environment & IT 97 15. Plotting 98 xvals = [lower] yvals = [func(lower)] for i in range(0, num, 1): xval1 = xvals[i] + delta_x xvals.append(xval1) yvals.append(func(xval1)) pyplot.plot(xvals, yvals, ’b-’) def plot_square(x0, x1, y0, y1): pyplot.plot([x0, x1], [ 0, 0], pyplot.plot([x0, x0], [ 0, y0], pyplot.plot([x1, x1], [ 0, y1], pyplot.plot([x0, x1], [y0, y1], ’g-’) ’g-’) ’g-’) ’g-’) example 8-2-1.py import math from matplotlib import pyplot import example_8_2_1_mod as mpr213 low = math.radians(-math.pi) upp = math.radians(math.pi) num = 4 func = mpr213.my_function pyplot.figure(1) mpr213.plot_function(func, low, upp, 100) integral = mpr213.integrate(func, low, upp, num) pyplot.title("Trapezoidal Integration", fontsize=16) pyplot.xlabel("x [radians]", fontsize=12) pyplot.ylabel("f(x)", fontsize=12) pyplot.show() print "Integral: " + str(integral) • Example (Approximate pi) c University of Pretoria, Faculty of Engineering, Built Environment & IT 98 15. Plotting 99 R 2R • Areas: Ac πR2 /4 π = = 2 As 4R /4 4 • Approximation (Throwing darts): π #darts in circle ≈ #darts in square 4 • Outcomes: – numpy module and linspace function – Idea of arrays and working with arrays – Line plot with a Scatter plot – Histogram plot • Example Solution: example 8 3 1 mod.py import math import random def pi_approx(radius, tolerance=1E-3): c University of Pretoria, Faculty of Engineering, Built Environment & IT 99 15. Plotting 100 error = 1 cnt_circle = 0 cnt_square = 0 x_coords = [] y_coords = [] while (error > tolerance): dart_x = random.uniform(-radius, radius) dart_y = random.uniform(-radius, radius) x_coords.append(dart_x) y_coords.append(dart_y) dist = (dart_x**2 + dart_y**2) ** 0.5 cnt_square = cnt_square + 1 if dist < radius: cnt_circle = cnt_circle + 1 approx = 1.0 * cnt_circle / cnt_square error = abs((math.pi / 4) - approx) return 4*approx, x_coords, y_coords example 8-3-1.py import math import numpy import example_8_3_1_mod as mpr213 from matplotlib import pyplot radius = 1 api, x_coords, y_coords = mpr213.pi_approx(radius, tolerance=1E-4) pyplot.figure(1) #plot the square pyplot.plot([-radius, radius], [-radius, -radius], ’b-’) pyplot.plot([-radius, radius], [ radius, radius], ’b-’) pyplot.plot([-radius, -radius], [-radius, radius], ’b-’) pyplot.plot([ radius, radius], [-radius, radius], ’b-’) #plot the circle xvals = numpy.linspace(-radius, radius, 100) yvals = (radius**2 - xvals**2) ** 0.5 pyplot.plot(xvals, yvals, ’r-’) pyplot.plot(xvals, -yvals, ’r-’) c University of Pretoria, Faculty of Engineering, Built Environment & IT 100 15. Plotting 101 # plot each point with a color depending on if its in the circle # or not distances = [] for i in range(0, len(x_coords), 1): dist = math.hypot(x_coords[i], y_coords[i]) distances.append(dist) if dist <= radius: pyplot.plot(x_coords[i], y_coords[i], ’r*’) else: pyplot.plot(x_coords[i], y_coords[i], ’b*’) offset = radius + 0.2 pyplot.axis([-offset, offset, -offset, offset]) pyplot.title("Pi Approximation", fontsize=16) pyplot.xlabel("Width [m]", fontsize=12) pyplot.ylabel("Height [m]", fontsize=12) pyplot.grid() # create histogram pyplot.figure(2) pyplot.hist(distances, bins=20) pyplot.title("Frequency of Point From the Origin", fontsize=16) pyplot.xlabel("Distance from origin [m]", fontsize=12) pyplot.ylabel("Frequency", fontsize=12) bins = numpy.linspace(min(distances), max(distances), 20) print bins pyplot.show() 15.3 Additional Types of Plots • Example (Potential Flow Around a Cylinder): – Suppose you have a fluid flow field → Eg. fluid moving around on object → and you want to visualise this flow field at discrete points – For example → the potential flow around a cylinder is given in polar coor- c University of Pretoria, Faculty of Engineering, Built Environment & IT 101 15. Plotting 102 dinates by: R2 Vr = U 1 − 2 cos θ r Vθ = −U R2 1+ 2 r sin θ • Outcomes: – numpy module functions: ∗ linspace ∗ arange ∗ meshgrid – Quiver plot • Example Solution: example 8-4-1.py import numpy from matplotlib import pyplot radius = 1.0 U = 20 # create x, y points num = 30 x = 1.0*numpy.linspace(-3, 3, num) y = 1.0*numpy.linspace(-3, 3, num) # creat X, Y meshgrid X, Y = numpy.meshgrid(x, y) # convert X, Y meshgrid to polar R, Theta meshgrid R = (X**2 + Y**2)**0.5 Theta = numpy.arctan(1.0*Y/X) # Calculate Vr, Vt polar velocities Vr = U * (1 - (radius**2 / R**2)) * numpy.cos(Theta) Vt = -U * (1 + (radius**2 / R**2)) * numpy.sin(Theta) # Convert Vr, Vt polar valocities to Vx, Vy Cartesian velocities Vx = Vr * numpy.cos(Theta) - Vt * numpy.sin(Theta) Vy = Vr * numpy.sin(Theta) + Vt * numpy.cos(Theta) c University of Pretoria, Faculty of Engineering, Built Environment & IT 102 15. Plotting 103 # Remove vector components inside the cylinder for i in range(0, num, 1): for j in range(0, num, 1): if R[i][j] < radius: Vx[i][j] = 0 #numpy.nan Vy[i][j] = 0 #numpy.nan # Plot the cylinder xvals = numpy.linspace(-radius, radius, 100) yvals = (radius**2 - xvals**2)**0.5 pyplot.plot(xvals, yvals, ’b-’) pyplot.plot(xvals, -yvals, ’b-’) # Plot the vectors using a quiver plot quiver = pyplot.quiver(X, Y, Vx, Vy) key = pyplot.quiverkey(quiver, 0.9, 1.02, U, ’Key: 10 [m/s]’) pyplot.title("Velocity Field") pyplot.xlabel("Distance [m]") pyplot.ylabel("Height [m]") pyplot.show() • Example (Potential Flow Around a Cylinder): – Suppose you have a scalar field → Eg. fluid pressure around on object → and you want to visualise this scalar field at discrete points – For example → the pressure of the potential flow around a cylinder is given, in polar coordinates, by: 2 ρU 2 R R4 p= 2 2 cos(2θ) − 4 + p∞ 2 r r • Outcomes: – Wire frame Contour plot – Filled contour plot • Example Solution: example 8-5-1.py import numpy from matplotlib import pyplot c University of Pretoria, Faculty of Engineering, Built Environment & IT 103 15. Plotting 104 radius = 1.0 U = 20 # create x, y points num = 1000 x = 1.0*numpy.linspace(-3, 3, num) y = 1.0*numpy.linspace(-3, 3, num) # creat X, Y meshgrid X, Y = numpy.meshgrid(x, y) # convert X, Y meshgrid to polar R, Theta meshgrid R = (X**2 + Y**2)**0.5 Theta = numpy.arctan(1.0*Y/X) # Calculate the pressure field rho = 977 p_atm = 0 p = ( 0.5 * rho * (U**2) * ( (2 * radius**2 / R**2) * numpy.cos(2*Theta) (radius**4 / R**4) ) + p_atm ) # Remove vector components inside the cylinder for i in range(0, num, 1): for j in range(0, num, 1): if R[i][j] < radius: p[i][j] = numpy.nan # Plot the cylinder xvals = numpy.linspace(-radius, radius, 100) yvals = (radius**2 - xvals**2)**0.5 pyplot.plot(xvals, yvals, ’b-’) pyplot.plot(xvals, -yvals, ’b-’) # Plot the pressure field using a contour plot contour = pyplot.contourf(X, Y, p, 20) bar = pyplot.colorbar(contour) bar.ax.set_ylabel("Pressure [Pa]") c University of Pretoria, Faculty of Engineering, Built Environment & IT 104 15. Plotting 105 pyplot.title("Pressure Field") pyplot.xlabel("Distance [m]") pyplot.ylabel("Height [m]") pyplot.show() • Example (Experimental Data): – Consider an experimental setup whereby air is forced through a rectangular channel. Inside this channel there are several obsticles (cylindrical pins) that obstruct the flow. – The flow velocity and pressure is messured at 39 different points along the the channel with pressure taps – 50 data readings are taken for each of the pressure taps – Plot an error bar plot showing the statistical accuracy of the data readings for each probe • Outcomes: – Box plot (Error bar plot) • Example Solution: example 8-6-1.py import csv import numpy from matplotlib import pyplot fid = open("Experi_Data.txt", ’rb’) reader = csv.reader(fid, delimiter=’\t’) reading = 1 probe_data = [] all_probes = [] reader.next() for row in reader: probe_data.append(float(row[4])) reading = reading + 1 c University of Pretoria, Faculty of Engineering, Built Environment & IT 105 15. Plotting 106 if reading == 50: all_probes.append(probe_data) probe_data = [] reading = 1 fid.close() pyplot.figure(1) pyplot.boxplot(all_probes) pyplot.title("Error Bar Plot of Reynolds Number") pyplot.xlabel("Probe Number") pyplot.ylabel("Reynolds Number") pyplot.show() • Example (3D Visualization of a function): – Given the following function: z = sin(2x) + cos(y) where x is between 0 and 2π; and y is between −π and π. – Write a python program that visualizes this function as a 3D surface plot – The visualization must also include a 2D contour projection onto the x-y plane • Outcomes: – 3D surface plot + optional inputs (rstride, ctride, cmap) – projected 2D countour plots • Example Solution: example 8-7-1.py import numpy from matplotlib import pyplot from matplotlib import cm from mpl_toolkits.mplot3d import axes3d c University of Pretoria, Faculty of Engineering, Built Environment & IT 106 15. Plotting 107 fig = pyplot.figure() ax = fig.gca(projection=’3d’) x = numpy.linspace(0, 2*numpy.pi, 30) y = numpy.linspace(-numpy.pi, numpy.pi, 30) X, Y = numpy.meshgrid(x, y) Z = numpy.sin(2*X) + numpy.cos(Y) ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm) cset = ax.contourf(X, Y, Z, zdir=’z’, offset=-2.5, cmap=cm.coolwarm) ax.set_xlabel(r’$x [rad]$’) ax.set_ylabel(r’$y [rad]$’) ax.set_zlabel(r’$f(x, y)$’) ax.set_zlim(-2.5, 1.5) pyplot.show() • Example (3D Representation of a geometry object): – Simple geometry objects can be expressed as 1 or more 2 variable mathematical functions, thus visualizing these simple geometry objects is similar to the previous example. – Write a python program the visulizes a simple sphere (R = 2). • Outcomes: – 3D surface plot + optional inputs (rstride, ctride, color) • Example Solution: example 8-8-1.py import numpy from matplotlib import pyplot from mpl_toolkits.mplot3d import axes3d fig = pyplot.figure() ax = fig.gca(projection=’3d’) c University of Pretoria, Faculty of Engineering, Built Environment & IT 107 15. Plotting 108 # create supporting points in sherical coordinates u = numpy.linspace(0, 2*numpy.pi, 100) v = numpy.linspace(0, numpy.pi, 100) # x y z transform them to cartesian system = 10*numpy.outer(numpy.cos(u), numpy.sin(v)) = 10*numpy.outer(numpy.sin(u), numpy.sin(v)) = 10*numpy.outer(numpy.ones(numpy.size(u)), numpy.cos(v)) ax.plot_surface(x, y, z, rstride=2, cstride=2, color=’g’) ax.set_xlabel(r’$x [m]$’) ax.set_ylabel(r’$y [m]$’) ax.set_zlabel(r’$f(x, y)$’) pyplot.show() c University of Pretoria, Faculty of Engineering, Built Environment & IT 108 16. LibreOffice 16 16.1 109 LibreOffice Overview • LibreOffice → free and open source office suite → create word documents, spreadsheets, slideshows, diagrams, etc. • LibreOffice Calc → used for creating and manipulating spreadsheets → visual data processing and manipulation • Documentation on ClickUP – CalcGuide.pdf → complete guide on how to use LibreOffice Calc – calc guide information.pdf → summary document describing which sections of the CalcGuide will be covered → also includes some exercise problems – Short 5min tutorial videos → could be useful to work through • First Look at LibreOffice Calc – Workbook (spreadsheet) → consists of several sheets – Each sheet consists of cells – Each cell can store either numerical values; string data; or a formula calculation – Each cell has a column-row name (eg. D4) • Outcomes: – Opening and Saving a workbook (spreadsheet) – Workbook (spreadsheet) structure – Adding data to a cell (numerical or string data) – Adding or removing sheets – The name box and referencing a cell – Simple calculations – Power (Python) → 2**3 – Power (LibreOffice Calc) → 2ˆ3 c University of Pretoria, Faculty of Engineering, Built Environment & IT 109 16. LibreOffice 110 R 2R 16.2 Examples • Example (Approximate pi) • Areas: Ac π πR2 /4 = = 2 As 4R /4 4 • Approximation (Throwing darts): π #darts in circle ≈ #darts in square 4 • Generating the data: – random x and y coordinates → one cell for each – each row represents each dart thrown → comparable to Python’s for loop – calculate the distance from the origin → separate column – test if the dart is inside the circle → separate column • Outcomes: – Function Wizard – RAND() function c University of Pretoria, Faculty of Engineering, Built Environment & IT 110 16. LibreOffice 111 – Dragging a formula (calculation) down → or double clicking – IF() statement – SUM(), COUNTA(), and COUNTIF() functions – Conditional formatting • Keyboard Shortcuts: – Why learn keyboard shortcuts? → faster to work with spreadsheets → working with large spreadsheets is a pain if you don’t learn keyboard shortcuts – General: ∗ ∗ ∗ ∗ ∗ Ctrl Ctrl Ctrl Ctrl Ctrl + + + + + c x v z y → copy information → cut information → paste information (whatever was copied or cut) undo previous command redo what was undone • Keyboard Shortcuts: – Moving through and selecting data: ∗ Shift + arrow keys → select multiple rows and / or columns of data ∗ Ctrl + arrow keys → move through data quickly in the arrow key direction → move to the edge of the current data range ∗ Ctrl + Shift + arrow keys → move to and select data up to the edge of the current data range in the direction of the arrow key ∗ Ctrl + Home → move to the first cell in the sheet (cell A1) ∗ Ctrl + End → move to the last cell in the sheet that contains data • Keyboard Shortcuts: – Moving between sheets: ∗ Ctrl + Page Up → Move one sheet to the left ∗ Ctrl + Page Down → Move one sheet to the right – Other: ∗ F1 → opens LibreOffice Calc help documentation ∗ F9 → recalculates all the formulas in the sheet – See Appendix A of the CalcGuide for a complete list of keyboard shortcuts • Plotting of the darts: c University of Pretoria, Faculty of Engineering, Built Environment & IT 111 16. LibreOffice 112 – Scatter Plot: ∗ With and without separating the darts by colour (inside circle vs outside) – Histogram Plot → of the distance of the dart from the origin • Outcomes: – Adding a sheet + renaming a sheet + sheet colour – Referencing cells on another sheet – Splitting the y coordinate into 2 data ranges – Scatter plot + data ranges + changing the plot icon – Graph annotations – FREQUENCY() function + concept of arrays in LibreOffice Calc – Bar chart • Example (Example of motion): – An object is release from rest 20 meters above the ground. Experimental velocity readings are taken every 0.05 seconds. The experimental data is saved in a csv file. ∗ Load the experimental data into LibreOffice Calc ∗ Calculate the height of the object using s = s0 − (v + v0 )t/2 ∗ Compare the experimental data with the theoretical equations, using v(s) = gt + v0 . ∗ Visualize (plot) the comparison ∗ Use the velocity equation of motion (determined from the experimental data) and the Goal Seek tool to solve for the required height to get a final velocity of 3.5 m/s • Outcomes: – Opening a csv file – Saving the workbook as a .ods file – Plot the data (height vs time and velocity vs height) – XY Scatter plot vs a Line plot – Help documentation – Adding trend lines: ∗ Linear: y = ax + b c University of Pretoria, Faculty of Engineering, Built Environment & IT 112 16. LibreOffice 113 ∗ Log: a ln(x) + b ∗ Exp: aebx ∗ Power: axb – What is a good “fit” for a trend line? → R2 coefficient → closer to 1 the better the “fit” – Plot theoretical equation (velocity vs height) – Using the Goal Seek tool 16.3 Linear Programming A wire plant manufactures copper and aluminium wire. Every kilogram of aluminum wire requires 5 kwh of electricity and 1/4 hour of labour. Every kilogram of copper wire requires 2kwh of electricity and 1/2 hour of labour. Supply restriction limit the production of copper wire to 60 kg/day. Electricity is restricted to 500 kwh/day and labour to 40 person – hours/day. If the profit from aluminum wire is 0.25/kg and the profit from copper is 0.40/kg, how much of each should be produced to maximize profit and what is the maximum profit? [Accessed April 2014: adapted from http://www.math.ncsu.edu/ma114/PDF/2.2.pdf] • Variables: – x - kg of aluminium – y - kg of copper • Goal is to maximize 0.25x + 0.4y • Constraints: – y ≤ 60 – 5x + 2y ≤ 500 – 0.25x + 0.5y ≤ 40 – x≥0 c University of Pretoria, Faculty of Engineering, Built Environment & IT 113 16. LibreOffice 114 – y≥0 • Outcomes: – Identify appropriate variables from linear programming word problem. – Identify whether real, integer or binary variables are appropriate. – Rewrite a linear programming word problem into appropriate mathematical equations, namely cost and constraint functions. – Solve linear programming problem using < T ools− > Solver >. – Able to enable integer and binary variables in Solver. – Interpret the result. 16.4 Sort, Filters and Pivot Tables • Consider the Ideal gas law: P V = nRT • Consider a workbook containing measured data. – Analyse the data using Filters < Data− > F ilter− > AutoF ilter > – Pivot tables < Data− > P ivotT able− > Create > ∗ Which pressure has the most measurements? ∗ For which temperatures did the volume exceed 0.05 cubic meters? ∗ Do the highest and lowest pressures correspond to the expected Temperature and Volume combinations? • Outcomes: – Able to use sort, filters and pivot tables to analyse data efficiently. – Pivot tables understand various roles of page, row, column and data fields. – Understand importance of appropriate labels for data using various functions. 16.5 Additional LP A rural building matrerial factory. A rural factory produces sand, cement and bricks at a profit of R0.1 per kg of washed sand, R20.00 per bag of cement and R0.50 per brick. c University of Pretoria, Faculty of Engineering, Built Environment & IT 114 16. LibreOffice 115 Raw material Bricks (/brick) Sand (kg) 0.7 Limestone (kg) 0.5 Clay (kg) 0.5 Flyash (kg) 0.5 Water (l) 1 Cement (/bag) 1.4 15 5.3 10 5 Sand (/kg) 1.1 0 0 0 2 Table 1: Raw materials required The following materials are used to make the respective products The available resouces are 5 tons of sand, 10 tons of limestone, 1 ton of clay, 1 ton of flyash and a million litre of water. What is the maximum profit that can be made available? • Variables: – kg of sand (real parameter) – bags of cement (integer) – number of bricks (integer) • Goal is to maximize 0.10 ∗ sand + 20.00 ∗ cement + 0.5 ∗ bricks • Constraints: – 0.7timesbrick + 1.4 × cement + 1.1 × sand ≤ 5000 – 0.5 × brick + 15 × cement ≤ 10000 – 0.5 × brick + 5.3 × cement ≤ 1000 – 0.5 × brick + 10 × cement ≤ 50000 – brick + 5 × cement + 2 × sand ≤ 1000000 • Outcomes: – Identify appropriate variables from linear programming word problem. – Identify whether real, integer or binary variables are appropriate. – Rewrite a linear programming word problem into appropriate mathematical equations, namely cost and constraint functions. – Solve linear programming problem using < T ools− > Solver >. – Able to enable integer and binary variables in Solver. – Interpret the result. c University of Pretoria, Faculty of Engineering, Built Environment & IT 115 16. LibreOffice 16.6 116 Exploring spreadsheets Quickly and efficiently explore large spreadsheets that are new to you. • Window → Freeze • Window → Split – Horizontal only – Vertical only – Horizontal and vertical • Tools → Detective – Precedents – Dependents 16.7 Exploring spreadsheets and extracting data Extracting data from spreadsheets. • VLOOKUP finds the information in a table based on a unique search criterion and returns data from a column index of your choice. First column of data range has to be unique identifier. • HLOOKUP finds the information in a table based on a unique search criterion and returns data from a row index of your choice. • MATCH allows you to obtain the index of an array that matches a specific value. • INDEX allows you to obtain data stored at a specific row and column index for a data range. • Outcomes: – Efficiently familiarize and explore large spreadsheets created by other people. – Extract data from data ranges. – Use extracted data to do additional calculations. c University of Pretoria, Faculty of Engineering, Built Environment & IT 116 17. File Handling 17 17.1 117 File Handling Test Data (From LO to Python) • Recap table lookup using vlookup • Export test data from LibreOffice • Load data in Python using CSV module • Store data in a list of lists • Typecast data to a numpy array • Plot histogram of the data using 20 bins 17.2 LibreOffice (CSV Files) • Loading csv data → separator options • Saving data → ”Save As” → ”Edit Filter Settings” – Field delimiter → separates data by this character – Text delimiter → wraps text with this character – Quote all text cells → adds Text delimiter to text 17.3 Python Framework (CSV Files) • Use open to create file object in Python • CSV Module: – Create CSV reader object in Python – Reader keyword arguments: ∗ delimiter → what character the data is separated by? ∗ quoting: csv.QUOTE NONNUMERIC → is the text data wrapped by ”? – Read CSV file row-by-row, using a for-loop • How or where can we store this CSV data? – Each row is a list of separated values / text c University of Pretoria, Faculty of Engineering, Built Environment & IT 117 17. File Handling 118 – Thus we can grow a list of lists → like a matrix, just using a list of lists – Type cast list of lists to numpy.array (matrix) example 7-3-2.py import csv import numpy as np import matplotlib.pyplot as plt fileobject = open(’test_data.csv’, ’rb’) reader = csv.reader(fileobject, delimiter=’,’, quoting=csv.QUOTE_NONNUMERIC) firstline = 1 data = [] for row in reader: if firstline == 1: header = row firstline = 0 else: print row data.append(row) fileobject.close() data = np.array(data) plt.hist(data.transpose()[5], bins=range(0,105,5), histtype=’stepfilled’, align=’left’) plt.show() c University of Pretoria, Faculty of Engineering, Built Environment & IT 118 18. Arrays 18 18.1 119 Arrays 1D Arrays (Recap) • Example (Vector vector multiplication) – Use python to calculate: 7.3 2.4 4.2 8.1 · 12.2 6.1 • Outcomes: – looping through 2 corresponding numpy arrays – Indexing a numpy array (accessing the elements) – numpy.dot function • Example Solution: example 9-1-1.py import numpy vec1 = numpy.array([2.4, 4.2, 8.1]) vec2 = numpy.array([7.3, 12.2, 6.1]) prod = 0 for i in range(len(vec1)): prod = prod + (vec1[i] * vec2[i]) print "Manual dot calculation: " + str(prod) print "Numpy dot calculation: " + str(numpy.dot(vec1, vec2)) 18.2 Matrices • Example (Matrix vector multiplication) – For example use python to calculate: 2.4 4.2 8.1 7.3 9.1 3.9 7.2 · 12.2 0.2 3.9 3.0 6.1 c University of Pretoria, Faculty of Engineering, Built Environment & IT 119 18. Arrays 120 • Outcomes: – numpy.shape function – manual calculation of the dot product – looping through a matrix – Indexing a matrix (accessing the elements) – numpy.zeros function – numpy.dot function • Example Solution: example 9-2-1.py import numpy mat = numpy.array([[2.4, 4.2, [9.1, 3.9, [0.2, 3.9, vec = numpy.array([7.3, 12.2, 8.1], 7.2], 3.0]]) 6.1]) dot_prod = [] rows, cols = numpy.shape(mat) for i in range(rows): prod = 0 for j in range(cols): prod = prod + (mat[i][j] * vec[j]) dot_prod.append(prod) dot_prod = numpy.array(dot_prod) print "Manual dot calculation: " + str(dot_prod) print "Numpy dot calculation: " + str(numpy.dot(mat, vec)) example 9-2-2.py import numpy mat = numpy.array([[2.4, 4.2, [9.1, 3.9, [0.2, 3.9, vec = numpy.array([7.3, 12.2, 8.1], 7.2], 3.0]]) 6.1]) c University of Pretoria, Faculty of Engineering, Built Environment & IT 120 18. Arrays 121 rows, cols = numpy.shape(mat) dot_prod = numpy.zeros(cols) for i in range(rows): prod = 0 for j in range(cols): prod = prod + (mat[i][j] * vec[j]) dot_prod[i] = prod print "Manual dot calculation: " + str(dot_prod) print "Numpy dot calculation: " + str(numpy.dot(mat, vec)) • Example (Matrix matrix multiplication) – For example use python to calculate: 7.3 4.2 2.4 4.2 8.1 9.1 3.9 7.2 · 12.2 9.6 6.1 12.4 0.2 3.9 3.0 • Outcomes: – numpy.shape function – manual calculation of the dot product – looping through a matrix – Indexing a matrix (accessing the elements) – numpy.zeros function – numpy.dot function • Example Solution: example 9 3 1 mod.py import numpy def dot(mat1, mat2): rows1, cols1 = numpy.shape(mat1) rows2, cols2 = numpy.shape(mat2) dot_prod = numpy.zeros((rows1, cols2)) for i in range(rows1): c University of Pretoria, Faculty of Engineering, Built Environment & IT 121 18. Arrays 122 for j in range(cols2): prod = 0 for k in range(cols1): prod = prod + (mat1[i][k] * mat2[k][j]) dot_prod[i][j] = prod return dot_prod example 9 3 2 mod.py import numpy def dot(mat1, mat2): rows1, cols1 = numpy.shape(mat1) rows2, cols2 = numpy.shape(mat2) dot_prod = numpy.zeros((rows1, cols2)) for i in range(rows1): for j in range(cols2): prod = sum(mat1[i][:] * mat2[:][j]) dot_prod[i][j] = prod return dot_prod example 9-3-1.py import numpy #import example_9_3_1_mod as mpr213 import example_9_3_1_mod as mpr213 mat1 = numpy.array([[2.4, 4.2, 8.1], [9.1, 3.9, 7.2], [0.2, 3.9, 3.0]]) mat2 = numpy.array([[ 7.3, 4.2 ], [12.2, 9.6 ], [ 6.1, 12.4]]) print "Manual dot calculation: " print mpr213.dot(mat1, mat2) print "Numpy dot calculation: " c University of Pretoria, Faculty of Engineering, Built Environment & IT 122 18. Arrays 123 print numpy.dot(mat1, mat2) • Example (Upper diagonal sum versus diagonal sum) – Use python to calculate whether the sum of the upper diagonal components of a matrix is more than the diagonal components of the matrix: 2.4 4.2 8.1 9.1 3.9 7.2 0.2 3.9 3.0 • Outcomes: – numpy.shape function – looping through parts of a matrix – nested looping in which the counters are related to each other – Indexing a matrix (accessing specfic elements) • Example Solution: example 9 4 1 mod.py import numpy def sum_mat_components(mat): diag = 0 upper = 0 rows, cols = numpy.shape(mat) for i in range(rows): for j in range(i, cols): if i == j: diag = diag + mat[i][j] else: upper = upper + mat[i][j] return diag, upper example 9-4-1.py import numpy import example_9_4_1_mod as mpr213 c University of Pretoria, Faculty of Engineering, Built Environment & IT 123 18. Arrays 124 mat = numpy.array([[2.4, 4.2, 8.1], [9.1, 3.9, 7.2], [0.2, 3.9, 3.0]]) diag, upper = mpr213.sum_mat_components(mat) print "Sum of upper diag components: " + str(upper) print "Sum of diag components: " + str(diag) if upper > diag: print "The matrix is upper diagonally dominant" else: print "The matrix is not upper diagonally dominant" 18.3 Lists and Arrays as Function inputs • What will get printed to the screen? mpr213.py def foo(vec1): vec2 = vec1 vec2[0] = 10 script.py import mpr213 import numpy vec = numpy.array([1, 1, 2, 1]) mpr213.foo(vec) print vec • Objects are not copied when sent as inputs to a function • New names are assigned to the existing objects • Modifying list or array elements inside a function → modifies the list or array object sent to the function c University of Pretoria, Faculty of Engineering, Built Environment & IT 124 18. Arrays 125 • Making copies of arrays: – a = numpy.copy(arr) • Making copies of lists: – Need to type cast the list again → a = list(my list) • id() function → can be used to check if objects are the same • Make sure you understand the memory model • Example (Replace matrix values): – Write a python function that take a matrix as an input – The function must return a new matrix where: ∗ all the 1’s have been replaced by 2’s, and ∗ all the 2’s have been replaced by 1’s 0 0 – Use the following matrix to test the function: 0 2 0 1 2 0 1 1 1 2 1 1 0 0 • Outcomes: – Working with lists or arrays as function inputs – Creating a new matrix (copy of another matrix) – Not modifying the original matrix • Example Solution: example 9 5 1 mod.py import numpy def replace_vals(mat): mat_copy = numpy.copy(mat) rows, cols = numpy.shape(mat) for i in range(rows): for j in range(cols): if mat_copy[i][j] == 1: mat_copy[i][j] = 2 c University of Pretoria, Faculty of Engineering, Built Environment & IT 125 19. scipy 126 elif mat_copy[i][j] == 2: mat_copy[i][j] = 1 return mat_copy example 9-5-1.py import numpy import example_9_5_1_mod as mpr213 mat = numpy.array([[0, [0, [0, [2, 0, 1, 2, 0, 1, 1, 1, 2, 1], 1], 0], 0]]) smat = mpr213.replace_vals(mat) print "Original: " print mat print "Swop 1’s and 2’s: " print smat 19 19.1 scipy Linear Equations • Example (Solve Linear System of Equations): – Solve the following system of linear equations: 3x1 + 6x2 − 4x3 = 4 2x2 − x3 = 1 x1 + x3 = 0.25 (1) • Example (Solve Linear System of Equations): – Rewrite into Linear Algebra Form: 3 6 −4 x1 2 0 2 −1 x2 1 1 0 1 x3 0.25 c University of Pretoria, Faculty of Engineering, Built Environment & IT (2) 126 19. scipy 127 – Solve in Python: ∗ Module scipy → module linalg → function solve ∗ import scipy.linalg as la → la.solve ∗ Solves system of N × N full rank equations – Test is solution is correct: ∗ Matrix multiplication numpy.dot example 7-3-2.py import numpy as np import scipy.linalg as la A = np.array([[3, 6, -4], [0, 2, -1], [1, 0, 1]]) b = np.array([4, 1, 0.25]) x = la.solve(A, b) print x print "Is the solution accurate?" print np.allclose(np.dot(A, x), b) • Example (Fitting straight line through data points → Least Squares): – Consider a straight line y = ax + b – We want to fit it through the following points: x 0 1 2 3 4 y 2.1 2.5 2.9 3.6 3.9 (3) – Which a and b will give the best fit? Consider a straight line y = ax + b and substitute each point: a × 0 + b = 2.1 a × 1 + b = 2.5 a × 2 + b = 2.9 a × 3 + b = 3.6 a × 4 + b = 3.9 c University of Pretoria, Faculty of Engineering, Built Environment & IT (4) 127 19. scipy 128 Which a and b will give the best fit? Two unknowns and five equations. Cannot satisfy each equation - minimise error. 0 1 2.1 1 1 2.5 2 1 a = 2.9 (5) b 3 1 3.6 4 1 3.9 Cannot solve Ax = b (6) AT Ax = AT b (7) Least squares solution is given by: • Python: Plot data and the least squares line fitted through the data. • LibreOffice: Plot data and insert linear trend line through the data. • Compare the coefficients? Background on where does least squares come from? The error E = Ax − b can be written as the error squares ET E = (Ax − b)T (Ax − b) = xT AT Ax − 2AT bx Minimimum error dET E dx (8) = 2AT Ax − 2AT b = 0 AT Ax = AT b (9) example 7-3-2.py import numpy as np import scipy.linalg as la import matplotlib.pyplot as plt A = np.array([[0, 1], [1, 1], [2, 1], c University of Pretoria, Faculty of Engineering, Built Environment & IT 128 19. scipy 129 x1 y1 L3 x2 y2 2 L4 L2 y 1 3 x L1 Figure 2: Four-bar linkage. 19.2 [3, 1], [4, 1]]) b = np.array([2.1, 2.5, 2.9, 3.6, 3.9]) coefficients = la.solve(np.dot(A.transpose(), A), np.dot(A.transpose(), b)) x = np.linspace(0, 5, 20) plt.plot(x, coefficients[0]*x + coefficients[1], ’r-’, label="fitted line") plt.plot([0, 1, 2, 3, 4], [2.1, 2.5, 2.9, 3.6, 3.9], ’go’, label="data") plt.title(’Line fitted through data points’) plt.xlabel(’x’) plt.ylabel(’y’) plt.grid() plt.legend(loc=’upper left’) plt.show() Nonlinear System of Equations Example: Four-bar linkage (kinematics with L1 , L2 , L3 and L4 the length of the links. Link 1 is fixed in a horizontal position. The link lengths are L1 = 3, L2 = 0.8, L3 = 2 and L4 = 2. For a given θ1 , we can solve for θ2 and θ3 using the following two non-linear equations: L2 cos(θ1 ) + L3 cos(θ2 ) − L4 cos(θ3 ) − L1 = 0 (10) L2 sin(θ1 ) + L3 sin(θ2 ) − L4 sin(θ3 ) = 0 c University of Pretoria, Faculty of Engineering, Built Environment & IT 129 19. scipy 130 x1 y1 L3 x2 y2 2 L4 L2 y 1 3 x L1 Figure 3: Four-bar linkage. example dynamics.py def fourbartheta23(theta23): from math import sin, cos, pi length = [3.0, 0.8, 2.0, 2.0] theta = [pi/4, theta23[0], theta23[1]] R = [length[1]*cos(theta[0]) + length[2]*cos(theta[1]) length[3]*cos(theta[2]) length[0], # length[1]*sin(theta[0]) + length[2]*sin(theta[1]) length[3]*sin(theta[2])] return R example nonlinear equations.py import scipy.optimize as opt from dynamics import fourbartheta23 import matplotlib.pyplot as plt from math import pi, cos, sin X0 = [0.707, 0.707] x = opt.fsolve(fourbartheta23, X0) L = [3.0, 0.8, 2.0, 2.0] thetas = [pi/4, x[0], x[1]] plt.plot([0, c University of Pretoria, Faculty of Engineering, Built Environment & IT 130 19. scipy 131 L[1]*cos(thetas[0]), L[1]*cos(thetas[0]) + L[2]*cos(thetas[1]), L[0]], # [0, L[1]*sin(thetas[0]), L[1]*sin(thetas[0]) + L[2]*sin(thetas[1]), 0], # ’k-’) plt.show() • Works but everytime we change a length or θ1 we need to change the script and dynamics module • Improve by defining a function that returns a function. – Create a function fourbar that takes all thetas and lengths as input. – Create another function fourbar2var that only takes θ1 and all the lengths as input. These parameters are known! – fourbar2var returns a function that is only a function of the unknown parameters of fourbar i.e. θ2 and θ3 . example dynamics.py def fourbar(theta, length): from math import sin, cos R = [length[1]*cos(theta[0]) + length[2]*cos(theta[1]) length[3]*cos(theta[2]) length[0], # length[1]*sin(theta[0]) + length[2]*sin(theta[1]) length[3]*sin(theta[2])] return R def fourbar2var(theta1, lengths): def newfunction(x): return fourbar([theta1, x[0], x[1]], lengths) return newfunction c University of Pretoria, Faculty of Engineering, Built Environment & IT 131 19. scipy 132 example nonlinear equations.py import scipy.optimize as opt from dynamics import fourbar2var import matplotlib.pyplot as plt from math import pi, cos, sin theta1 = pi/2 X0 = [0.707, 0.707] L = [3.0, 0.8, 2.0, 2.0] myfourbar = fourbar2var(theta1, L) x = opt.fsolve(myfourbar, X0) thetas = [theta1, x[0], x[1]] plt.plot([0, L[1]*cos(thetas[0]), L[1]*cos(thetas[0]) + L[2]*cos(thetas[1]), L[0]], # [0, L[1]*sin(thetas[0]), L[1]*sin(thetas[0]) + L[2]*sin(thetas[1]), 0], # ’k-’) plt.show() Solve for θ2 and θ3 for θ1 between 0 and 2π using 10 linearly spaced intervals. As a guess to the solution of the non-linear system use [0.707; 0.707] for θ1 = 0. For θ1 > 0 the guess must be the solution the previously computed non-linear system. Plot then link three for the various values of θ1 and θ2 . The coordinates of link three are given by x1 = L2 cos(θ1 ) y1 = L2 sin(θ1 ) (11) x2 = L2 cos(θ1 ) + L3 cos(θ2 ) y2 = L2 sin(θ1 ) + L3 sin(θ2 ) example nonlinear equations.py import scipy.optimize as opt import numpy as np from dynamics import fourbar2var c University of Pretoria, Faculty of Engineering, Built Environment & IT 132 19. scipy 133 import matplotlib.pyplot as plt from math import pi, cos, sin X0 = [0.707, ] L = [3.,0.8,2.,2.] theta1range = np.linspace(0, 2*pi, 10) for theta1 in theta1range: currentfourbar = fourbar2var(theta1, L) x = opt.fsolve(currentfourbar, X0) thetas = [theta1, x[0], x[1]] plt.plot([0, L[1]*cos(thetas[0]), L[1]*cos(thetas[0]) + L[2]*cos(thetas[1]), L[0]], # [0, L[1]*sin(thetas[0]), L[1]*sin(thetas[0]) + L[2]*sin(thetas[1]), 0], # ’k-’) X0 = x plt.show() 19.3 Integration (quad) • Example (Single Integral) – Compute the following definite integral in python: Z 9 9 4x2 + 5 dx = 4/3x3 + 5x 2 = 996.33 2 • Outcomes: – Importing and using quad → from scipy import integrate → integrate.quad – Passing a function as an input to another function – Integrate a function from a to b – Understanding the output from the quad function • Example Solution: c University of Pretoria, Faculty of Engineering, Built Environment & IT 133 19. scipy 134 example 10 1 1 mod.py def my_function(x): return 4.0 * x**2 + 5 example 10-1-1.py from scipy import integrate import example_10_1_1_mod as mpr213 print integrate.quad(mpr213.my_function, 2, 9) • Example (Single Integral) – Compute the following integral in python: Z b Ce−x dx a – First for a = 2, b = 5 and C = 12 – Then for a = 2, b = ∞ and C = 22 • Outcomes: – Passing a function as an input to another function – Integrate a function from a to b – Integrate a function with an infinite interval – Creating an input function that has args • Example Solution: example 10 2 1 mod.py import math def my_function(x, args): C = args[0] return C * math.exp(-x) example 10-2-1.py import numpy from scipy import integrate c University of Pretoria, Faculty of Engineering, Built Environment & IT 134 19. scipy 135 import example_10_2_1_mod as mpr213 print integrate.quad(mpr213.my_function, 2, 5, args=(12, )) print integrate.quad(mpr213.my_function, 2, numpy.inf, args=(22, )) 19.4 Integration (dblquad) • Example (Double Integral) – Compute the following integral in python: Z Z xy 2 dA D – Where D is the rectangular region defined by 0 ≤ x ≤ 2 and 0 ≤ y ≤ 1: • Example (Double Integral) Z 1 Z 2 2 Z xy dx dy = 0 0 0 1 x2 2 y 2 x=2 ! Z dy = x=0 1 2y 2 dy. 0 • Outcomes: – Importing and using quad → from scipy import integrate → integrate.dblquad – Passing multiple functions as inputs to another function – Integrate a function for x ∈ [a, b] and y ∈ [c, d] – Understanding the output from the dblquad function R 2 – Why must the inner integral limits x=0 be given as functions? • Example Solution: c University of Pretoria, Faculty of Engineering, Built Environment & IT 135 19. scipy 136 example 10 3 1 mod.py def function(x, y): return x * y**2 def inner_bound_lower(x): return 0 def inner_bound_upper(x): return 2 example 10-3-1.py from scipy import integrate import example_10_3_1_mod as mpr213 print integrate.dblquad(mpr213.function, 0, 1, mpr213.inner_bound_lower, mpr213.inner_bound_upper) • Example (Double Integral - x First) – Compute the following integral in python: Z Z xy 2 dA D – Where D is the triangular region defined by 0 ≤ x ≤ 2 and 0 ≤ y ≤ x/2: • Example (Double Integral - x First) ! ZZ Z 2 Z x/2 xy 2 dA = xy 2 dy dx D 0 Z = 0 0 2 Z = 0 2 x 3 y 3 y=x/2 dx y=0 x4 dx 24 c University of Pretoria, Faculty of Engineering, Built Environment & IT 136 19. scipy 137 • Outcomes: – Passing multiple functions as inputs to another function – Integrate a function for x ∈ [a, b] and y ∈ [c, d], where c or d is a function of x – Understanding the output from the dblquad function • Example Solution: example 10 3 1 mod.py def function(y, x): return x * y**2 def inner_bound_lower(x): return 0 def inner_bound_upper(x): return x / 2.0 example 10-3-1.py from scipy import integrate import example_10_3_1_mod as mpr213 print integrate.dblquad(mpr213.function, 0, 2, mpr213.inner_bound_lower, mpr213.inner_bound_upper) • Example (Double Integral - y First) – Compute the following integral in python: Z Z xy 2 dA D – Where D is the triangular region defined by 0 ≤ y ≤ 1 and 2y ≤ x ≤ 2: • Example (Double Integral - y First) ZZ Z 1 Z 2 2 2 xy dA = xy dx dy D 0 Z = 2y Z = 0 1 x2 y 2 2 x=2 ! dy x=2y 1 2y 2 − 2y 4 dy 0 c University of Pretoria, Faculty of Engineering, Built Environment & IT 137 19. scipy 138 • Outcomes: – Passing multiple functions as inputs to another function – Integrate a function for x ∈ [a, b] and y ∈ [c, d], where a or b is a function of y – Understanding the output from the dblquad function • Example Solution: example 10 4 1 mod.py def function(x, y): return x * y**2 def inner_bound_lower(y): return 2*y def inner_bound_upper(y): return 2 example 10-4-1.py from scipy import integrate import example_10_4_1_mod as mpr213 print integrate.dblquad(mpr213.function, 0, 1, mpr213.inner_bound_lower, mpr213.inner_bound_upper) 19.5 Optimization (slsqp) • Example (Tin Can) c University of Pretoria, Faculty of Engineering, Built Environment & IT 138 19. scipy 139 – A cylindrical-shaped tin-can must have a capacity of 1000cm3 . – Determine the dimensions that require the minimum amount of tin for the can (assume no waste material) – The smallest can that the market will accept has a diameter of 6cm and a height of 4cm • Outcomes: – Importing and using fmin slsqp → from scipy.optimize import fmin slsqp – Creating the objective function and constraint functions – Passing multiple functions as inputs to another function – Understanding the output from the fmin slsqp function • Example (Tin Can Continued) – Variables: x = [x1 , x2 ] = [r, h] – Surface Area (Objective Function): A(x) = 2π x1 2 + x1 x2 – Constraints (Inequality): g1 (x) = πx1 2 x2 − 1000 >= 0 g2 (x) = x1 − 3 >= 0 g3 (x) = x2 − 4 >= 0 • Outcomes: – Non linear optimization problem – Need to write g(x) in the form g(x) >= 0 • Example Solution: example 10 5 1 mod.py import math def function(x): return math.pi * (x[0]**2 + x[0]*x[1]) def ineq_constraints(x): c University of Pretoria, Faculty of Engineering, Built Environment & IT 139 19. scipy 140 return [math.pi * (x[0]**2) * x[1] - 1000, x[0] - 3, x[1] - 4] example 10-5-1.py from scipy import optimize import example_10_5_1_mod as mpr213 print optimize.fmin_slsqp(function, [1, 1], f_ieqcons=ineq_constraints) 19.6 Solve ODE (odeint) • Example (Spring and Damper) – See study notes for now • Outcomes: – • Example Solution: example 10 6 1 mod.py example 10-6-1.py c University of Pretoria, Faculty of Engineering, Built Environment & IT 140 20. GUIs (Tkinter) 20 20.1 141 GUIs (Tkinter) Overview • Graphical User Interface (GUI): – Graphical platform that allows users to interface with electronic devices through graphical icons and visual indicators, as opposed to text-based interfaces – Almost every application (PC and Cell Phone) nowadays is a form of GUI – These GUI (programs / application) run continuously until the user closes the application – GUIs are generally action-reaction type of programs: ∗ GUI waits for an action from the user (either keyboard or mouse actions / inputs) ∗ GUI then performs a calculation, updated the display, etc. based on the type of user input ∗ GUI then waits again for an action from the user • GUIs in Python – GUIs can be create using Python along with a package called Tkinter → "Tk interface" – import Tkinter as Tk – Documentation: ∗ https://wiki.python.org/moin/TkInter 20.2 Integration GUI • Example (Integration GUI) – Create a GUI that allows the user to specify a function, a lower bound and a upper bound. The GUI must integrate the given function between the lower and upper bound once the user clicks on a button. – Example Image: • Example (Integration GUI) – First steps: c University of Pretoria, Faculty of Engineering, Built Environment & IT 141 20. GUIs (Tkinter) 142 ∗ Create the main window (canvas) → main = Tk.Tk() ∗ Execute the main event loop → main.mainloop() – Understanding the mainloop(): ∗ This is a semi-infinite loop that the GUI enters ∗ GUI waits for user inputs (Events) inside this loop ∗ Only closing the GUI will end this loop • Example (Integration GUI) – Next steps: ∗ Add objects (labels and text boxes) to the window (canvas) ∗ Labels → used to add text information on the GUI → Tk.Label(main, text="text") ∗ Text boxes → used to capture information from the user → Tk.Entry(main) • Example (Integration GUI) – Next steps: ∗ Positioning the objects on the main window (canvas) ∗ Need to plan the layout of the GUI: Roughly a 3 × 4 matrix grid • Example (Integration GUI) – Next steps: ∗ Positioning the objects on the main window (canvas) ∗ Position object on a grid → object.grid(row=r, column=c, columnspan=cs, sticky=N,E,S,W c University of Pretoria, Faculty of Engineering, Built Environment & IT 142 20. GUIs (Tkinter) ∗ ∗ ∗ ∗ 143 row → row where the object should be placed column → column where the object should be placed columnspan → the number of columns the object spans over sticky → the location of text of the object: · N, E, S, W → Top, Right, Bottom, Left • Example (Integration GUI) – Next steps: ∗ ∗ ∗ ∗ Adding the ”Integrate” button Create the button → Tk.Button(main, text="text", command=function) text → text for the button command=function → the Event Binding – Understanding Events and Bindings: ∗ Event → action from the user (Eg. left mouse click on the button) ∗ Binding → bind the event to a function call ∗ I.e. When the user gives a certain action (Event) then execute a certain function (Binding) ∗ Buttons always bind the right mouse button click to a function • Example (Integration GUI) – Next steps: ∗ Creating the function for the ”Integrate” button ∗ Function created inside the ”script” file → Only time you ever do this is when creating functions for GUI objects or you have read up on, and understand Python namespace ∗ Get information from text box objects → object.get() → always returns the users input in a text box as a string !! ∗ Integrate function, lower bound and upper bound as strings → how can we integrate a string function?? • Example (Integration GUI) – Next steps: ∗ Converting the string representation of the integration function to a proper Python function ∗ We need two tools: c University of Pretoria, Faculty of Engineering, Built Environment & IT 143 20. GUIs (Tkinter) 144 · a wrapper function that takes the string function as an input and returns a proper Python function · the eval function that evaluates the string as if it where Python code • Example (Integration GUI) – Final steps: ∗ Displaying the results of the integration → tkMessageBox.showinfo("Title", msg) ∗ Polishing up the layout of the GUI ∗ Adjust the sizes of the text boxes ∗ Add default values (entries) for the text boxes ∗ How to give a certain object focus c University of Pretoria, Faculty of Engineering, Built Environment & IT 144