├── data1.txt ├── Topic 0 Introduction to Python.ipynb ├── Topic1b Functions and Basic Operations.ipynb ├── Topic2b random numbers.ipynb └── Topic 1a Data Types.ipynb /data1.txt: -------------------------------------------------------------------------------- 1 | # here is some preamble 2 | # here is some more preamble 3 | 1.0,-0.6311688938249904,0.45488424301397556,1.4166838803401072, 4 | 1.0909090909090908,0.1836650127781727,-1.2320204754180588,1.4640662255632122, 5 | 1.1818181818181819,-1.2067884002340479,-0.9383912321268246,-1.4714065565433299, 6 | 1.2727272727272727,-0.07397985995933759,1.8395768409168949,-0.0796575263423811, 7 | 1.3636363636363638,-0.737654908251103,-1.2826141566048304,2.143318426612972, 8 | 1.4545454545454546,-0.6352094090520055,1.196605783495026,-0.5272364016024303, 9 | 1.5454545454545454,-1.3478569367857853,1.2726038119049938,-0.2387464313240688, 10 | 1.6363636363636362,1.7643027277060235,-1.3358815620673254,0.42002797035543593, 11 | 1.7272727272727273,1.1228898074019433,0.4373429207381663,-0.1053287323238627, 12 | 1.8181818181818183,-1.9235573265400396,1.0784356569475517,-0.43585645156397873, 13 | 1.9090909090909092,-2.5203822814363916,0.2925419990496477,-0.7175310482674775, 14 | 2.0,-0.20414929117298058,1.8548073032642414,-1.6689147413533778, 15 | 2.090909090909091,0.6621809483393832,-0.3051219239294479,1.1131763474375251, 16 | 2.1818181818181817,0.3182087214669058,-0.042937245099687604,1.1752070761056175, 17 | 2.2727272727272725,0.22912356066614792,0.29073506428594337,1.7818860311483344, 18 | 2.3636363636363638,-0.3829663239804597,1.2152670827311336,-0.47144795060521066, 19 | 2.4545454545454546,1.865932067710966,0.7675499181699784,0.12187118234859495, 20 | 2.5454545454545454,-0.08836032079560019,-0.1666437043109095,0.626776483177752, 21 | 2.6363636363636367,-0.1157667893960524,0.4901440432726023,0.4253528301358699, 22 | 2.7272727272727275,0.24497585695544113,2.7752811189421585,0.343931167436819, 23 | 2.8181818181818183,0.14888310641784397,0.9543988718029668,0.8880236302997588, 24 | 2.909090909090909,-0.2114497883523676,-1.688434540970014,0.27935921952965387, 25 | 3.0,1.0352247792742475,-1.0731955421188029,2.701509689543154, 26 | 3.090909090909091,-0.8537914813011567,1.7509227026567182,-0.9552216026515601, 27 | 3.1818181818181817,1.3722857219464086,-0.37647616008459883,-0.16025010581716082, 28 | 3.272727272727273,0.053927881477298795,-1.3127359490133514,2.711507312349479, 29 | 3.3636363636363638,-0.4068758845366948,0.7035038827738344,0.30365742503758647, 30 | 3.4545454545454546,-0.44478474721640066,-1.4555517678140941,2.3713902873526815, 31 | 3.5454545454545454,2.116426641034081,1.0109175166041757,1.7765903267105174, 32 | 3.6363636363636362,0.11636504326654121,-0.39359214869578835,2.032829663570117, 33 | 3.7272727272727275,0.8015329178643593,0.7273604384719508,1.227679834941189, 34 | 3.8181818181818183,0.6456429398866661,-1.352494638078151,3.1188298852583616, 35 | 3.909090909090909,1.613784466354094,0.04898448107888345,2.708345137790178, 36 | 4.0,-1.41366205041043,1.0229177097053903,1.5199421945650475, 37 | 4.090909090909091,-0.3421580136252812,-1.1187303130674546,0.7096631263875519, 38 | 4.181818181818182,0.07888321542058939,0.8636770901568209,1.2864962209751158, 39 | 4.272727272727273,1.8760741154369092,-1.3073459162098775,2.588484416332107, 40 | 4.363636363636363,0.06585764882180982,0.8705697000713934,2.124660688963388, 41 | 4.454545454545455,-0.22438214432973524,0.4027602740454191,3.066047039885218, 42 | 4.545454545454545,-2.0491518156959208,0.9922030057065043,1.4647428779952012, 43 | 4.636363636363637,0.5823994686118554,1.4178740616537855,1.1659646426268564, 44 | 4.7272727272727275,1.1174069972630207,-0.04600732058846052,2.5796909818035645, 45 | 4.818181818181818,-1.179141881111505,3.2015700262839704,0.07426732300802663, 46 | 4.909090909090909,-0.5685640147773101,0.8422491785269339,1.9361054483673024, 47 | 5.0,0.49560619172623754,1.378808545961349,2.772330131342585, 48 | 5.090909090909091,0.24585784653847198,-0.20555502242005147,1.131185156172839, 49 | 5.181818181818182,1.5643862123074455,-0.11958099935101546,1.3147100878015254, 50 | 5.2727272727272725,-1.1151867423383657,0.5168985098872407,3.1046733325611573, 51 | 5.363636363636363,-0.2726364668908259,-0.08699783939484457,3.2585070783888552, 52 | 5.454545454545455,0.9001532285209066,1.3526696413293455,1.8728542161334232, 53 | 5.545454545454546,-0.6202357596001613,2.007273180695664,1.2825433316035202, 54 | 5.636363636363637,1.1819882134237294,-0.22142023759539192,2.365387520829122, 55 | 5.7272727272727275,-0.5941962918244037,-0.14320348032695024,2.6040454782634064, 56 | 5.818181818181818,-0.02477118308961286,0.9716562819146767,2.148810432530392, 57 | 5.909090909090909,0.8327767577068002,-0.2927110377652543,3.069936739485766, 58 | 6.0,-1.1556411055077778,1.4417724412287023,3.1886656103478708, 59 | 6.090909090909091,-1.2168552986118735,0.4506696001559499,2.386898651226657, 60 | 6.181818181818182,-0.6157921010281806,-0.497108647756321,0.05661589728718264, 61 | 6.2727272727272725,-1.7671583367295978,1.135331434196452,2.817105149730652, 62 | 6.363636363636364,0.13096635693994016,-0.22052459096032073,3.160826314988174, 63 | 6.454545454545455,0.690294866968097,1.8963277920971895,4.487425364155156, 64 | 6.545454545454546,2.371694887897769,0.27960637363250584,2.3644192911897908, 65 | 6.636363636363637,1.273825402614828,0.8687499947091604,3.305655085108792, 66 | 6.7272727272727275,0.37967675226481273,-1.3159423011413678,1.661604297176963, 67 | 6.818181818181818,1.0948910337870426,1.3123807007747081,3.6798167626896023, 68 | 6.909090909090909,-1.6205454405798412,2.9248119763275087,2.3917854722312857, 69 | 7.0,0.735428855084481,1.7767204644281096,3.3694488806819884, 70 | 7.090909090909091,-0.04455145140604422,-0.1371341937628388,2.642018658136439, 71 | 7.181818181818182,-1.5357456259373374,1.604807734797527,4.412411518091927, 72 | 7.2727272727272725,-2.009658212034761,-0.7726057755922854,4.155582143990508, 73 | 7.363636363636364,2.374179182366948,1.0793284192789065,3.170149680288414, 74 | 7.454545454545455,-0.6902691820562796,0.3217260254744907,2.865907753457373, 75 | 7.545454545454546,-0.15763329565736972,-0.2569440439920063,3.368592679754569, 76 | 7.636363636363637,0.9242345372372889,0.27667266297441834,3.637880473686003, 77 | 7.7272727272727275,-3.1875997601455275,2.199806115530024,2.1096391833912675, 78 | 7.818181818181818,-1.1718948899473165,0.10319898990813686,4.576445271388832, 79 | 7.909090909090909,0.9785580968322369,0.009469202542572108,4.49391127399047, 80 | 8.0,-0.8665677410547212,-0.17314343767459317,5.313216187997888, 81 | 8.09090909090909,-1.6213716879341697,1.1684574860898165,3.19369658313685, 82 | 8.181818181818182,-0.06367514456694123,1.4356964984967884,5.912587734389751, 83 | 8.272727272727273,0.7401111090339849,0.43828138891593493,4.616231505466975, 84 | 8.363636363636363,1.446697225209474,0.2686299890785137,6.166373213464694, 85 | 8.454545454545455,2.0171465823853088,1.7122578969698194,4.543006941829624, 86 | 8.545454545454547,0.05547192247442552,-0.6291651473329716,4.507974800623014, 87 | 8.636363636363637,-0.0197020770305536,0.9233026597415765,6.920201295831565, 88 | 8.727272727272727,-0.4911129241676753,1.6061208531128814,3.8010877096815032, 89 | 8.818181818181818,2.069890341411209,-0.209459536509214,6.761139952443798, 90 | 8.90909090909091,0.032529746059397326,-1.754907126230721,5.2962287556147905, 91 | 9.0,1.4366854455763804,-0.9398701401824869,6.13375599845889, 92 | 9.090909090909092,-1.0881560738374398,0.7241679159272209,7.010425652001209, 93 | 9.181818181818182,0.4358544140396277,0.2484598305057409,4.543475541105149, 94 | 9.272727272727273,0.47595695530935767,1.8022691191471243,5.451213213875634, 95 | 9.363636363636363,0.6720375552319127,2.6861025069373134,7.9347242752625275, 96 | 9.454545454545455,0.15566217413846836,0.9488508609031605,5.960063077396186, 97 | 9.545454545454545,0.5227159219087347,-0.20599329826767998,7.820105590320214, 98 | 9.636363636363637,-0.23146925909689864,0.6207016561335794,5.959715623500961, 99 | 9.727272727272727,-0.5167395516639268,0.7343253426310082,5.3781930296290685, 100 | 9.818181818181818,-0.005145926712907867,1.8884676984294115,6.645049022367959, 101 | 9.90909090909091,2.167391340402733,1.8142239879060225,6.244150828030593, 102 | 10.0,0.7589063994652221,-0.4915403755397779,8.432902602792572, 103 | -------------------------------------------------------------------------------- /Topic 0 Introduction to Python.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "253aaaea", 6 | "metadata": {}, 7 | "source": [ 8 | "# COGS 18: Introduction to Python" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "id": "a031c5f6", 14 | "metadata": {}, 15 | "source": [ 16 | "## What is this course about?" 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "id": "3bf3cfd5", 22 | "metadata": {}, 23 | "source": [ 24 | "Computer programing / coding is a part of life for almost everyone working a STEM or STEM-adjacent fields. Of course, this is true in science for calculating things, analyzing and visualizing data (things you will likely need for future courses). But this is increasingly true in non-academic jobs of all kinds. The world is overflowing with data to the point that just collecting information and organizing it is a task for a computer. Familiarity with the basic tools and language around programming will get you a long way." 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "id": "b1137267", 30 | "metadata": {}, 31 | "source": [ 32 | "In many ways, the role of computers in STEM is similiar to the importance of reading and writing more generally. You don't have to be a professional author for it be useful to be able to write a clear and succinct email (for example). A great writer may also be able to craft an beautiful essay that if beyond your capability, but you can still understand what it means and write a something that means the same thing, even if it doesn't have the same elegance. We find ourselves in the exact same situation when it comes to writing code: an expert will be able to manipulate the (programing) language in ways that you can't envision, but that doesn't mean that you can't understand what they are doing or write a piece of code that does what you need. " 33 | ] 34 | }, 35 | { 36 | "cell_type": "markdown", 37 | "id": "d3253e19", 38 | "metadata": {}, 39 | "source": [ 40 | "I am not here to tell you about strict rules about programming a computer anymore than I am to lecture you about the correct grammatical style for writing a news story for the New York Times. Our goal is much more modest to get you started: how do we understand what the computer is doing and how do we talk to it? We will only scratch the surface of what you can do with python (not to mention all the other programming languages), but the hope if that with this introduction, you will be able to learn more about what else is out there, and apply it, on your own. " 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "id": "f1aaf667", 46 | "metadata": {}, 47 | "source": [ 48 | "Computers are incredibly powerful tools, but only if we can get it to do what we want. Just like sending a clear set of instructions in writing to someone else (e.g. like a recipe), we have to make sure we write in a way that doesn't confuse our target. The reality of computer programming is that anything you will do will be built on enormous amounts of code written by someone else. As a result, the first step to doing anything usually requires that we understand how someone else built the language / function / package so that we can use it ourselves. Unfortunately, people can make fairly illogical decisions and so there is sometimes no rhyme or reason to why the syntax of a particular language is written in a particularly way." 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "id": "6ea19a43", 54 | "metadata": {}, 55 | "source": [ 56 | "Fortunately, unlike people, computers are perfectly logical. While the person who wrote a particular piece of code might have done something for no particularly good reason, what the computer is doing underneath is often more rigid. If the computer is trying to solve an equation, regardless of the syntax of the code, the computer is probably implementing one of a handful of basic algorithms. Even though we might not know exactly what the computer is doing in detail, we can learn a lot about what our code is doing just by understanding a bit about the basics of how a computer operates." 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "id": "30bc24ca", 62 | "metadata": {}, 63 | "source": [ 64 | "## What are my goals for you?" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "id": "e30fb8ab", 70 | "metadata": {}, 71 | "source": [ 72 | "I am not a computational physicist or someone that writes professional quality code for a living. I am not going to force any style of coding upon you as if you were about to start a job as a professional software developer. My code, like yours, will be filled will all kinds of mistakes that a professional would not tolerate. Our goal is just to write code that works for now. We are going to learn to code by doing. Once you have a feel for it, you can go back and improve your technique. This strategy is similar to learning to write stories in parallel with learning grammar/spelling." 73 | ] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "id": "52258a82", 78 | "metadata": {}, 79 | "source": [ 80 | "A bit of programing knowledge will open a lot of doors for you. The key skill we are trying to develop as physicist is how to think and process information. However, at this stage of your career, many of your best opportunities will come from combining your own thinking skills with some basic computer skills. My goal is to teach you enough about the tools available to your (with python) that you can figure out the rest when you need it." 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "id": "87c9225c", 86 | "metadata": {}, 87 | "source": [ 88 | "(think of this like chess: you far from being grand masters right now, but if you know how to run any good computer chess program, you can still compete against the very best human players)" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "id": "fcb1be58", 94 | "metadata": {}, 95 | "source": [ 96 | "E.g. you have probably spent a lot of time learning how to solve integrals by hand. However, a computer can do a lot of that work for you:" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 6, 102 | "id": "d2fa792e", 103 | "metadata": {}, 104 | "outputs": [], 105 | "source": [ 106 | "import sympy" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 17, 112 | "id": "9839bc91", 113 | "metadata": {}, 114 | "outputs": [ 115 | { 116 | "data": { 117 | "image/png": "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\n", 118 | "text/latex": [ 119 | "$\\displaystyle - x^{3} \\cos{\\left(x \\right)} + 3 x^{2} \\sin{\\left(x \\right)} + 6 x \\cos{\\left(x \\right)} - 6 \\sin{\\left(x \\right)}$" 120 | ], 121 | "text/plain": [ 122 | " 3 2 \n", 123 | "- x ⋅cos(x) + 3⋅x ⋅sin(x) + 6⋅x⋅cos(x) - 6⋅sin(x)" 124 | ] 125 | }, 126 | "execution_count": 17, 127 | "metadata": {}, 128 | "output_type": "execute_result" 129 | } 130 | ], 131 | "source": [ 132 | "sympy.init_printing()\n", 133 | "x=sympy.Symbol(\"x\")\n", 134 | "sympy.integrate(x**3*sympy.sin(x),x)" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": 28, 140 | "id": "ea3160db", 141 | "metadata": {}, 142 | "outputs": [ 143 | { 144 | "data": { 145 | "image/png": "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\n", 146 | "text/latex": [ 147 | "$\\displaystyle - 3 \\sin{\\left(1 \\right)} + 5 \\cos{\\left(1 \\right)}$" 148 | ], 149 | "text/plain": [ 150 | "-3⋅sin(1) + 5⋅cos(1)" 151 | ] 152 | }, 153 | "execution_count": 28, 154 | "metadata": {}, 155 | "output_type": "execute_result" 156 | } 157 | ], 158 | "source": [ 159 | "sympy.integrate(x**3*sympy.sin(x),(x,0,1))" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 29, 165 | "id": "0e1ecea4", 166 | "metadata": {}, 167 | "outputs": [ 168 | { 169 | "data": { 170 | "image/png": "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\n", 171 | "text/latex": [ 172 | "$\\displaystyle 0.177098574917009$" 173 | ], 174 | "text/plain": [ 175 | "0.177098574917009" 176 | ] 177 | }, 178 | "execution_count": 29, 179 | "metadata": {}, 180 | "output_type": "execute_result" 181 | } 182 | ], 183 | "source": [ 184 | "sympy.integrate(x**3*sympy.sin(x),(x,0,1)).evalf()" 185 | ] 186 | }, 187 | { 188 | "cell_type": "markdown", 189 | "id": "967acc3a", 190 | "metadata": {}, 191 | "source": [ 192 | "We can also evaluate the integrals numerically:" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": 18, 198 | "id": "1404cce3", 199 | "metadata": {}, 200 | "outputs": [], 201 | "source": [ 202 | "from scipy.integrate import quad\n", 203 | "import numpy as n" 204 | ] 205 | }, 206 | { 207 | "cell_type": "code", 208 | "execution_count": 24, 209 | "id": "ad58cfac", 210 | "metadata": {}, 211 | "outputs": [ 212 | { 213 | "data": { 214 | "image/png": "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\n", 215 | "text/latex": [ 216 | "$\\displaystyle \\left( 0.177098574917009, \\ 1.96618915501167 \\cdot 10^{-15}\\right)$" 217 | ], 218 | "text/plain": [ 219 | "(0.17709857491700906, 1.9661891550116667e-15)" 220 | ] 221 | }, 222 | "execution_count": 24, 223 | "metadata": {}, 224 | "output_type": "execute_result" 225 | } 226 | ], 227 | "source": [ 228 | "quad(lambda y:y**3*np.sin(y),0,1)" 229 | ] 230 | }, 231 | { 232 | "cell_type": "markdown", 233 | "id": "de6b805c", 234 | "metadata": {}, 235 | "source": [ 236 | "Of course, knowing how to integrate is still very important; it is pretty hard to debug a computer if you don't understand what it is trying to do. Instead, the value of the computer is that it can dramatically enhance and/or speed you ability to solve problems by giving the computer the more difficult or time consuming tasks." 237 | ] 238 | }, 239 | { 240 | "cell_type": "markdown", 241 | "id": "8bd2fca5", 242 | "metadata": {}, 243 | "source": [ 244 | "With that in mind there are specific things I want for you from this course: \n", 245 | "\n", 246 | "(1) you will all be able to make a piece of python code do some basic things for you: read/sort/analyze data, calculate things you care about (integrals, solve algebraic or differential equations), make figures, etc. \n", 247 | "\n", 248 | "(2) you will be sufficiently comfortable with python that when a piece of code is not working, you can debug the problem and get it to do what you want. Debugging problems is really the key step that you will need to succeed in the world. No one ever writes code that works the first time, so identifying and fixing your own mistakes is essential to succeeding on your own. Every mistake is unique, so it isn't about memorizing a list of possible errors and checking them, but it is building the confidence that you can figure out the problem yourself." 249 | ] 250 | }, 251 | { 252 | "cell_type": "markdown", 253 | "id": "ad307a35", 254 | "metadata": {}, 255 | "source": [ 256 | "## Why Python?" 257 | ] 258 | }, 259 | { 260 | "cell_type": "markdown", 261 | "id": "a21e946a", 262 | "metadata": {}, 263 | "source": [ 264 | "#### Here are some reasons we are using python: \n", 265 | "(1) it is easy to read and write (2) it's free / open source (3) it is used by LOTS of people in both industry and academia and (4) it is versatile." 266 | ] 267 | }, 268 | { 269 | "cell_type": "markdown", 270 | "id": "519199e1", 271 | "metadata": {}, 272 | "source": [ 273 | "Confession: I learned C++ when I was in your position. It was enourmously helpful in getting research experience as an undergrad. Yet, I really didn't like dealing with C++ and I promptly forgot how to use it the second my career didn't require it. I avoided using computers in my research for about 10 years starting in grad school. Why? Because C++ is confusing to read, confusing to use and it was a lot of work to write a working piece of code even for a very small problem. There was really no point to using C++ unless your life depended on it." 274 | ] 275 | }, 276 | { 277 | "cell_type": "markdown", 278 | "id": "66aa2ab8", 279 | "metadata": {}, 280 | "source": [ 281 | "What brought me back was Python. The way the code works is pretty simple and easy to get started. It makes it easy to find your mistakes and also worth your time to write something in python even if it is just a little calculation, figure, etc. The jupyter notebook enviroment makes this even easier because you can just run the little bits of code you need without all the formal parts that go into a proper python script." 282 | ] 283 | }, 284 | { 285 | "cell_type": "markdown", 286 | "id": "791ea849", 287 | "metadata": {}, 288 | "source": [ 289 | "Here is an example. Let's say I just want to add up some numbers:" 290 | ] 291 | }, 292 | { 293 | "cell_type": "code", 294 | "execution_count": 3, 295 | "id": "b8212058", 296 | "metadata": {}, 297 | "outputs": [ 298 | { 299 | "data": { 300 | "text/plain": [ 301 | "20" 302 | ] 303 | }, 304 | "execution_count": 3, 305 | "metadata": {}, 306 | "output_type": "execute_result" 307 | } 308 | ], 309 | "source": [ 310 | "1+2+4+10+3" 311 | ] 312 | }, 313 | { 314 | "cell_type": "markdown", 315 | "id": "f4ec762e", 316 | "metadata": {}, 317 | "source": [ 318 | "Let's say I want to do a really big sum: $\\sum_{n=1}^{1000} 1/n^2$" 319 | ] 320 | }, 321 | { 322 | "cell_type": "code", 323 | "execution_count": 5, 324 | "id": "b157e84e", 325 | "metadata": {}, 326 | "outputs": [ 327 | { 328 | "name": "stdout", 329 | "output_type": "stream", 330 | "text": [ 331 | "1.6439345666815615\n" 332 | ] 333 | } 334 | ], 335 | "source": [ 336 | "sum=0\n", 337 | "for i in range(1000):\n", 338 | " sum+=1/(i+1)**2\n", 339 | "print(sum)" 340 | ] 341 | }, 342 | { 343 | "cell_type": "markdown", 344 | "id": "5dd5b4f4", 345 | "metadata": {}, 346 | "source": [ 347 | "This was really easy (a few seconds of typing). In the old days, you would have to do a lot of work to do something like this in C++." 348 | ] 349 | }, 350 | { 351 | "cell_type": "markdown", 352 | "id": "9d4a60ee", 353 | "metadata": {}, 354 | "source": [ 355 | "##### What is wrong with python?\n", 356 | "It is slow. If you need to do a very hard and time consuming calculating, python will probably be too slow. Relatedly, if you are using some big code someone else developed to solve a hard problem, it probably isn't written in python." 357 | ] 358 | }, 359 | { 360 | "cell_type": "markdown", 361 | "id": "f4fcd0e9", 362 | "metadata": {}, 363 | "source": [ 364 | "This weakness of python is really a very tiny problem: the most time consuming part of solving most problems is writing and testing the code. Python makes this part (the human part) way easier. If you reach the point that your ability to solve interesting problems is limited by python itself and not your coding and debugging skills, then I am also confident that you will have no problem learning the tools you need to speed it up using another language (there are also tools to run pieces of code written in other languages inside python so that only the part of your code that needs to be blazing fast is written in something other than python). " 365 | ] 366 | }, 367 | { 368 | "cell_type": "code", 369 | "execution_count": null, 370 | "id": "c87f384f", 371 | "metadata": {}, 372 | "outputs": [], 373 | "source": [] 374 | } 375 | ], 376 | "metadata": { 377 | "kernelspec": { 378 | "display_name": "Python 3 (ipykernel)", 379 | "language": "python", 380 | "name": "python3" 381 | }, 382 | "language_info": { 383 | "codemirror_mode": { 384 | "name": "ipython", 385 | "version": 3 386 | }, 387 | "file_extension": ".py", 388 | "mimetype": "text/x-python", 389 | "name": "python", 390 | "nbconvert_exporter": "python", 391 | "pygments_lexer": "ipython3", 392 | "version": "3.9.7" 393 | } 394 | }, 395 | "nbformat": 4, 396 | "nbformat_minor": 5 397 | } 398 | -------------------------------------------------------------------------------- /Topic1b Functions and Basic Operations.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Topic 1b: Functions and Basic Operations" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## Basics Operations" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "Now that we know the basic data structures, now what can we do with them. \n", 22 | "\n", 23 | "There are some basic logic structures that are useful: are things equal" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 7, 29 | "metadata": {}, 30 | "outputs": [ 31 | { 32 | "data": { 33 | "text/plain": [ 34 | "False" 35 | ] 36 | }, 37 | "execution_count": 7, 38 | "metadata": {}, 39 | "output_type": "execute_result" 40 | } 41 | ], 42 | "source": [ 43 | "5==4" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 8, 49 | "metadata": {}, 50 | "outputs": [ 51 | { 52 | "data": { 53 | "text/plain": [ 54 | "True" 55 | ] 56 | }, 57 | "execution_count": 8, 58 | "metadata": {}, 59 | "output_type": "execute_result" 60 | } 61 | ], 62 | "source": [ 63 | "5==5" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 9, 69 | "metadata": {}, 70 | "outputs": [ 71 | { 72 | "data": { 73 | "text/plain": [ 74 | "False" 75 | ] 76 | }, 77 | "execution_count": 9, 78 | "metadata": {}, 79 | "output_type": "execute_result" 80 | } 81 | ], 82 | "source": [ 83 | "[1,2,3]==[3,2,1]" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 10, 89 | "metadata": {}, 90 | "outputs": [ 91 | { 92 | "data": { 93 | "text/plain": [ 94 | "True" 95 | ] 96 | }, 97 | "execution_count": 10, 98 | "metadata": {}, 99 | "output_type": "execute_result" 100 | } 101 | ], 102 | "source": [ 103 | "[1,2,3]==[1,2,3]" 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "metadata": {}, 109 | "source": [ 110 | "Inequalities are also very useful. Both >,<, >=, and <= do the obvious thing" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 11, 116 | "metadata": {}, 117 | "outputs": [ 118 | { 119 | "name": "stdout", 120 | "output_type": "stream", 121 | "text": [ 122 | "True False True True\n" 123 | ] 124 | } 125 | ], 126 | "source": [ 127 | "print(5>3, 5>5, 5>=5, 5<=5)" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "metadata": {}, 133 | "source": [ 134 | "The value of the equals operation shall be pretty clear when you start running over long lists of numbers looking for something in particular." 135 | ] 136 | }, 137 | { 138 | "cell_type": "markdown", 139 | "metadata": {}, 140 | "source": [ 141 | "Already, you might also have noticed that I cheated you: True and False are data types we didn't discuss yet! True and False are the outputs of logical operations, but are also things we can save for later use:" 142 | ] 143 | }, 144 | { 145 | "cell_type": "markdown", 146 | "metadata": {}, 147 | "source": [ 148 | "The simplest possible version is if statements, which mean can be understood as \"if True: do something\":" 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": 12, 154 | "metadata": {}, 155 | "outputs": [ 156 | { 157 | "name": "stdout", 158 | "output_type": "stream", 159 | "text": [ 160 | "Get a haircut!\n" 161 | ] 162 | } 163 | ], 164 | "source": [ 165 | "Is_my_hair_too_long=True\n", 166 | "if Is_my_hair_too_long:\n", 167 | " print('Get a haircut!')\n", 168 | "else:\n", 169 | " print('continue on')" 170 | ] 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "metadata": {}, 175 | "source": [ 176 | "We also have our basic and / or statements:" 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": 13, 182 | "metadata": {}, 183 | "outputs": [ 184 | { 185 | "name": "stdout", 186 | "output_type": "stream", 187 | "text": [ 188 | "True\n", 189 | "False\n", 190 | "True\n", 191 | "True\n" 192 | ] 193 | } 194 | ], 195 | "source": [ 196 | "print(1==1 and 2==2)\n", 197 | "print(1==1 and 2==1)\n", 198 | "print(1==1 or 2==1)\n", 199 | "print(1==1 or 2==2) # notice that OR is inclusive True or True is True." 200 | ] 201 | }, 202 | { 203 | "cell_type": "markdown", 204 | "metadata": {}, 205 | "source": [ 206 | "Truth statements are particularly useful in if statements in combination with loops. For example, we can run through a list of objects but then do something only under certain conditions" 207 | ] 208 | }, 209 | { 210 | "cell_type": "code", 211 | "execution_count": 14, 212 | "metadata": {}, 213 | "outputs": [], 214 | "source": [ 215 | "list1=range(1,10) # this automatically makes a list of 1,9" 216 | ] 217 | }, 218 | { 219 | "cell_type": "markdown", 220 | "metadata": {}, 221 | "source": [ 222 | "To see how this works, let's just make a for loop and print what is happening:" 223 | ] 224 | }, 225 | { 226 | "cell_type": "code", 227 | "execution_count": 15, 228 | "metadata": {}, 229 | "outputs": [ 230 | { 231 | "name": "stdout", 232 | "output_type": "stream", 233 | "text": [ 234 | "1\n", 235 | "2\n", 236 | "3\n", 237 | "4\n", 238 | "5\n", 239 | "6\n", 240 | "7\n", 241 | "8\n", 242 | "9\n" 243 | ] 244 | } 245 | ], 246 | "source": [ 247 | "for item in list1:\n", 248 | " print(item)" 249 | ] 250 | }, 251 | { 252 | "cell_type": "markdown", 253 | "metadata": {}, 254 | "source": [ 255 | "Okay - so our for loop just picks an elements from the list, one at a time and then lets us do something with it. Now let's see what happens when we put an if statment inside the loop: " 256 | ] 257 | }, 258 | { 259 | "cell_type": "code", 260 | "execution_count": 16, 261 | "metadata": {}, 262 | "outputs": [ 263 | { 264 | "name": "stdout", 265 | "output_type": "stream", 266 | "text": [ 267 | "nay\n", 268 | "nay\n", 269 | "Yay!!\n", 270 | "nay\n", 271 | "nay\n", 272 | "nay\n", 273 | "nay\n", 274 | "nay\n", 275 | "nay\n" 276 | ] 277 | } 278 | ], 279 | "source": [ 280 | "for item in list1:\n", 281 | " if item==3:\n", 282 | " print('Yay!!')\n", 283 | " else:\n", 284 | " print('nay')" 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "execution_count": 17, 290 | "metadata": {}, 291 | "outputs": [ 292 | { 293 | "name": "stdout", 294 | "output_type": "stream", 295 | "text": [ 296 | "nay\n", 297 | "nay\n", 298 | "hmmm\n", 299 | "hmmm\n", 300 | "yay\n", 301 | "yay\n", 302 | "yay\n", 303 | "yay\n", 304 | "yay\n" 305 | ] 306 | } 307 | ], 308 | "source": [ 309 | "for item in list1:\n", 310 | " if item>4:\n", 311 | " print('yay')\n", 312 | " elif item >2:\n", 313 | " print('hmmm')\n", 314 | " else:\n", 315 | " print('nay')" 316 | ] 317 | }, 318 | { 319 | "cell_type": "markdown", 320 | "metadata": {}, 321 | "source": [ 322 | "We also have a bunch of basic math operations. The least obvious is powers:" 323 | ] 324 | }, 325 | { 326 | "cell_type": "code", 327 | "execution_count": 18, 328 | "metadata": {}, 329 | "outputs": [ 330 | { 331 | "name": "stdout", 332 | "output_type": "stream", 333 | "text": [ 334 | "16 4096 4096\n" 335 | ] 336 | } 337 | ], 338 | "source": [ 339 | "print(2**4, 2**(12), 2**12) #using backets with ** isn't necessary but highly encouraged." 340 | ] 341 | }, 342 | { 343 | "cell_type": "code", 344 | "execution_count": 19, 345 | "metadata": {}, 346 | "outputs": [ 347 | { 348 | "name": "stdout", 349 | "output_type": "stream", 350 | "text": [ 351 | "1.4142135623730951\n" 352 | ] 353 | } 354 | ], 355 | "source": [ 356 | "print(2**(1/2.))" 357 | ] 358 | }, 359 | { 360 | "cell_type": "markdown", 361 | "metadata": {}, 362 | "source": [ 363 | "There are also some nice tricks built for tasks you will use a lot. For example if I want to add up something, I can do += instead of x=x+y (which looks confusing)" 364 | ] 365 | }, 366 | { 367 | "cell_type": "code", 368 | "execution_count": 20, 369 | "metadata": {}, 370 | "outputs": [ 371 | { 372 | "name": "stdout", 373 | "output_type": "stream", 374 | "text": [ 375 | "19.1\n" 376 | ] 377 | } 378 | ], 379 | "source": [ 380 | "costs=[1.2,3.4,4.5,4.,6.]\n", 381 | "total=0\n", 382 | "for cost in costs:\n", 383 | " total+=cost\n", 384 | "print(total)" 385 | ] 386 | }, 387 | { 388 | "cell_type": "markdown", 389 | "metadata": {}, 390 | "source": [ 391 | "We can also do the same with substraction, multiplication or divisions" 392 | ] 393 | }, 394 | { 395 | "cell_type": "code", 396 | "execution_count": 21, 397 | "metadata": {}, 398 | "outputs": [ 399 | { 400 | "name": "stdout", 401 | "output_type": "stream", 402 | "text": [ 403 | "80.89999999999999\n" 404 | ] 405 | } 406 | ], 407 | "source": [ 408 | "cash=100\n", 409 | "for cost in costs:\n", 410 | " cash-=cost\n", 411 | "print(cash)" 412 | ] 413 | }, 414 | { 415 | "cell_type": "markdown", 416 | "metadata": {}, 417 | "source": [ 418 | "*Aside: Notice that we have a nice example of numerical error here! It should have been 80.1, but because of the way our floating point number is stored it isn't.*" 419 | ] 420 | }, 421 | { 422 | "cell_type": "code", 423 | "execution_count": 22, 424 | "metadata": { 425 | "scrolled": true 426 | }, 427 | "outputs": [ 428 | { 429 | "data": { 430 | "text/plain": [ 431 | "0.10000000000000142" 432 | ] 433 | }, 434 | "execution_count": 22, 435 | "metadata": {}, 436 | "output_type": "execute_result" 437 | } 438 | ], 439 | "source": [ 440 | "19.1-19" 441 | ] 442 | }, 443 | { 444 | "cell_type": "markdown", 445 | "metadata": {}, 446 | "source": [ 447 | "*What is happening here? A pretty good guess is that your computer wants to store information in binary form, which means that it works in powers of 2. I.e. $1=2^0$, $2=2^1$, $3 = 2^1 + 2^0$, $4=2^2$. For decimals, then we might expect it is storing it in terms of fractions $1/2 =2^{-1}$, $1/4 = 2^{-2}$. So we can check that is what is happening if we pick nice fractions of 2 writen as a decimal:*" 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "execution_count": 23, 453 | "metadata": {}, 454 | "outputs": [ 455 | { 456 | "data": { 457 | "text/plain": [ 458 | "0.5" 459 | ] 460 | }, 461 | "execution_count": 23, 462 | "metadata": {}, 463 | "output_type": "execute_result" 464 | } 465 | ], 466 | "source": [ 467 | "19.5-19" 468 | ] 469 | }, 470 | { 471 | "cell_type": "code", 472 | "execution_count": 24, 473 | "metadata": {}, 474 | "outputs": [ 475 | { 476 | "data": { 477 | "text/plain": [ 478 | "0.25" 479 | ] 480 | }, 481 | "execution_count": 24, 482 | "metadata": {}, 483 | "output_type": "execute_result" 484 | } 485 | ], 486 | "source": [ 487 | "19.25-19" 488 | ] 489 | }, 490 | { 491 | "cell_type": "code", 492 | "execution_count": 25, 493 | "metadata": {}, 494 | "outputs": [ 495 | { 496 | "data": { 497 | "text/plain": [ 498 | "0.125" 499 | ] 500 | }, 501 | "execution_count": 25, 502 | "metadata": {}, 503 | "output_type": "execute_result" 504 | } 505 | ], 506 | "source": [ 507 | "19.125-19" 508 | ] 509 | }, 510 | { 511 | "cell_type": "markdown", 512 | "metadata": {}, 513 | "source": [ 514 | "*Now we can look up the definition of a floating point number in python and find out that it is a 64 bit number, meaning that it contains 64 binary numbers or can represent from 1 to $2^{63}$*" 515 | ] 516 | }, 517 | { 518 | "cell_type": "code", 519 | "execution_count": 26, 520 | "metadata": {}, 521 | "outputs": [ 522 | { 523 | "data": { 524 | "text/plain": [ 525 | "1.8446744073709551" 526 | ] 527 | }, 528 | "execution_count": 26, 529 | "metadata": {}, 530 | "output_type": "execute_result" 531 | } 532 | ], 533 | "source": [ 534 | "2**(64)/10**19" 535 | ] 536 | }, 537 | { 538 | "cell_type": "markdown", 539 | "metadata": {}, 540 | "source": [ 541 | "*We see it is pretty close to our 16 decimal places from before. To udnerstand why it isn't exactly 16, we should also remember that we need to store the overall power as well (because it can store numbers much bigger or smaller than $2^{64}$, so it must be using some of the 64 bits for that as well. There is clearly a bit more going on under the hood too*" 542 | ] 543 | }, 544 | { 545 | "cell_type": "code", 546 | "execution_count": 27, 547 | "metadata": {}, 548 | "outputs": [ 549 | { 550 | "data": { 551 | "text/plain": [ 552 | "10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376" 553 | ] 554 | }, 555 | "execution_count": 27, 556 | "metadata": {}, 557 | "output_type": "execute_result" 558 | } 559 | ], 560 | "source": [ 561 | "2**(1000)" 562 | ] 563 | }, 564 | { 565 | "cell_type": "markdown", 566 | "metadata": {}, 567 | "source": [ 568 | "*End of Aside*" 569 | ] 570 | }, 571 | { 572 | "cell_type": "markdown", 573 | "metadata": {}, 574 | "source": [ 575 | "Now, for multiplication and division, we have to be very careful not to accidently multiply or divide by zero:" 576 | ] 577 | }, 578 | { 579 | "cell_type": "code", 580 | "execution_count": 28, 581 | "metadata": {}, 582 | "outputs": [ 583 | { 584 | "name": "stdout", 585 | "output_type": "stream", 586 | "text": [ 587 | "0\n" 588 | ] 589 | } 590 | ], 591 | "source": [ 592 | "factorial=1\n", 593 | "for i in range(5):\n", 594 | " factorial*=i\n", 595 | "print(factorial)" 596 | ] 597 | }, 598 | { 599 | "cell_type": "code", 600 | "execution_count": 29, 601 | "metadata": {}, 602 | "outputs": [ 603 | { 604 | "name": "stdout", 605 | "output_type": "stream", 606 | "text": [ 607 | "120\n" 608 | ] 609 | } 610 | ], 611 | "source": [ 612 | "factorial=1\n", 613 | "for i in range(5):\n", 614 | " factorial*=i+1\n", 615 | "print(factorial)" 616 | ] 617 | }, 618 | { 619 | "cell_type": "markdown", 620 | "metadata": {}, 621 | "source": [ 622 | "For division, we have to worry about division by zero:" 623 | ] 624 | }, 625 | { 626 | "cell_type": "code", 627 | "execution_count": 30, 628 | "metadata": {}, 629 | "outputs": [ 630 | { 631 | "ename": "ZeroDivisionError", 632 | "evalue": "division by zero", 633 | "output_type": "error", 634 | "traceback": [ 635 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 636 | "\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", 637 | "\u001b[0;32m/var/folders/vh/rcz751b57355h3qzj37sc3080000gp/T/ipykernel_6604/3237423217.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0minverse_factorial\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0minverse_factorial\u001b[0m\u001b[0;34m/=\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minverse_factorial\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 638 | "\u001b[0;31mZeroDivisionError\u001b[0m: division by zero" 639 | ] 640 | } 641 | ], 642 | "source": [ 643 | "inverse_factorial=1\n", 644 | "for i in range(5):\n", 645 | " inverse_factorial/=i\n", 646 | "print(inverse_factorial)" 647 | ] 648 | }, 649 | { 650 | "cell_type": "code", 651 | "execution_count": 31, 652 | "metadata": {}, 653 | "outputs": [ 654 | { 655 | "name": "stdout", 656 | "output_type": "stream", 657 | "text": [ 658 | "0.008333333333333333 120.0\n" 659 | ] 660 | } 661 | ], 662 | "source": [ 663 | "inverse_factorial=1\n", 664 | "for i in range(5):\n", 665 | " inverse_factorial/=(i+1)\n", 666 | "print(inverse_factorial,1/inverse_factorial)" 667 | ] 668 | }, 669 | { 670 | "cell_type": "markdown", 671 | "metadata": {}, 672 | "source": [ 673 | "Aside: Notice that I have been running through lists of numbers using range. In Python 2, you were told not to do this (but to use something called xrange) to avoid creating a list that is saved to memory for no reason. Range in python 3 is basically what xrange used to be an they removed the function xrange " 674 | ] 675 | }, 676 | { 677 | "cell_type": "markdown", 678 | "metadata": {}, 679 | "source": [ 680 | "Range is often useful when you running through things in a list" 681 | ] 682 | }, 683 | { 684 | "cell_type": "code", 685 | "execution_count": 32, 686 | "metadata": {}, 687 | "outputs": [ 688 | { 689 | "name": "stdout", 690 | "output_type": "stream", 691 | "text": [ 692 | "box\n", 693 | "car\n", 694 | "keys\n" 695 | ] 696 | } 697 | ], 698 | "source": [ 699 | "short_list=['box','car','keys']\n", 700 | "for i in range(3):\n", 701 | " print(short_list[i])" 702 | ] 703 | }, 704 | { 705 | "cell_type": "markdown", 706 | "metadata": {}, 707 | "source": [ 708 | "Now if you just wanted the elements in the list, you can also just call them one by one:" 709 | ] 710 | }, 711 | { 712 | "cell_type": "code", 713 | "execution_count": 33, 714 | "metadata": {}, 715 | "outputs": [ 716 | { 717 | "name": "stdout", 718 | "output_type": "stream", 719 | "text": [ 720 | "box\n", 721 | "car\n", 722 | "keys\n" 723 | ] 724 | } 725 | ], 726 | "source": [ 727 | "for item in short_list:\n", 728 | " print(item)" 729 | ] 730 | }, 731 | { 732 | "cell_type": "markdown", 733 | "metadata": {}, 734 | "source": [ 735 | "And, sometimes, you want both: you want the item in the list but you also want to know the element it came frmo. For that, you have enumerate:" 736 | ] 737 | }, 738 | { 739 | "cell_type": "code", 740 | "execution_count": 34, 741 | "metadata": {}, 742 | "outputs": [ 743 | { 744 | "name": "stdout", 745 | "output_type": "stream", 746 | "text": [ 747 | "0 0 1\n", 748 | "box\n", 749 | "1 1 2\n", 750 | "car\n", 751 | "2 4 3\n", 752 | "keys\n" 753 | ] 754 | } 755 | ], 756 | "source": [ 757 | "for i,item in enumerate(short_list):\n", 758 | " print(i, i**2, i+1) # look I can do math with the index from which each entry came\n", 759 | " print(item) # I also have actual entry in the list available to use" 760 | ] 761 | }, 762 | { 763 | "cell_type": "markdown", 764 | "metadata": {}, 765 | "source": [ 766 | "## Functions" 767 | ] 768 | }, 769 | { 770 | "cell_type": "markdown", 771 | "metadata": {}, 772 | "source": [ 773 | "That we have enough basic tools, we can start defining our own functions for our specific problems. The simpliest way to proceed is by example." 774 | ] 775 | }, 776 | { 777 | "cell_type": "markdown", 778 | "metadata": {}, 779 | "source": [ 780 | "The basic setup is as follows: we define it using def and put in some information we want to use in the function" 781 | ] 782 | }, 783 | { 784 | "cell_type": "code", 785 | "execution_count": 35, 786 | "metadata": {}, 787 | "outputs": [], 788 | "source": [ 789 | "def say_hi(name):\n", 790 | " print('Hi '+name)" 791 | ] 792 | }, 793 | { 794 | "cell_type": "code", 795 | "execution_count": 36, 796 | "metadata": {}, 797 | "outputs": [ 798 | { 799 | "name": "stdout", 800 | "output_type": "stream", 801 | "text": [ 802 | "Hi Professor Green\n" 803 | ] 804 | } 805 | ], 806 | "source": [ 807 | "say_hi('Professor Green')" 808 | ] 809 | }, 810 | { 811 | "cell_type": "markdown", 812 | "metadata": {}, 813 | "source": [ 814 | "As written, the above function looks fine, but will not work if we don't put the exact right kind of input." 815 | ] 816 | }, 817 | { 818 | "cell_type": "code", 819 | "execution_count": 37, 820 | "metadata": {}, 821 | "outputs": [ 822 | { 823 | "ename": "TypeError", 824 | "evalue": "can only concatenate str (not \"int\") to str", 825 | "output_type": "error", 826 | "traceback": [ 827 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 828 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 829 | "\u001b[0;32m/var/folders/vh/rcz751b57355h3qzj37sc3080000gp/T/ipykernel_6604/892123741.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0msay_hi\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 830 | "\u001b[0;32m/var/folders/vh/rcz751b57355h3qzj37sc3080000gp/T/ipykernel_6604/2903403830.py\u001b[0m in \u001b[0;36msay_hi\u001b[0;34m(name)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0msay_hi\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Hi '\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 831 | "\u001b[0;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" 832 | ] 833 | } 834 | ], 835 | "source": [ 836 | "say_hi(5)" 837 | ] 838 | }, 839 | { 840 | "cell_type": "markdown", 841 | "metadata": {}, 842 | "source": [ 843 | "It is usually a good habit to either (a) force the data to be the kind we want or (b) send a warning" 844 | ] 845 | }, 846 | { 847 | "cell_type": "code", 848 | "execution_count": 40, 849 | "metadata": {}, 850 | "outputs": [], 851 | "source": [ 852 | "def say_hi_2(name):\n", 853 | " print('Hi '+str(name))\n", 854 | "def say_hi_3(name):\n", 855 | " if type(name)==str:\n", 856 | " print('Hi '+name)\n", 857 | " else:\n", 858 | " print('Error: not a string')" 859 | ] 860 | }, 861 | { 862 | "cell_type": "code", 863 | "execution_count": 41, 864 | "metadata": {}, 865 | "outputs": [ 866 | { 867 | "name": "stdout", 868 | "output_type": "stream", 869 | "text": [ 870 | "Hi 5\n", 871 | "Error: not a string\n" 872 | ] 873 | } 874 | ], 875 | "source": [ 876 | "say_hi_2(5)\n", 877 | "say_hi_3(5)" 878 | ] 879 | }, 880 | { 881 | "cell_type": "markdown", 882 | "metadata": {}, 883 | "source": [ 884 | "Now let's try another example: we saw above that we can make our own verion of a factorial. So we can just define a function that does this automatically" 885 | ] 886 | }, 887 | { 888 | "cell_type": "code", 889 | "execution_count": 42, 890 | "metadata": {}, 891 | "outputs": [], 892 | "source": [ 893 | "def factorial(n):\n", 894 | " out=1\n", 895 | " if n>0: # We are going to force n>0 so that it is well defined\n", 896 | " for i in range(int(n)): ## notice that I am forcing n to be an integer to avoid problems\n", 897 | " out*=(i+1)\n", 898 | "\n", 899 | " return out\n", 900 | " " 901 | ] 902 | }, 903 | { 904 | "cell_type": "code", 905 | "execution_count": 43, 906 | "metadata": {}, 907 | "outputs": [ 908 | { 909 | "name": "stdout", 910 | "output_type": "stream", 911 | "text": [ 912 | "120 5040 1\n" 913 | ] 914 | } 915 | ], 916 | "source": [ 917 | "print(factorial(5), factorial(7), factorial(-6.6))" 918 | ] 919 | }, 920 | { 921 | "cell_type": "markdown", 922 | "metadata": {}, 923 | "source": [ 924 | "We notice a few things in this way I have implemented the code: it allows me to input non-integers but gives a integer answer. I also wrote it in this slightly awkward way of multiplying everything in a loop." 925 | ] 926 | }, 927 | { 928 | "cell_type": "markdown", 929 | "metadata": {}, 930 | "source": [ 931 | "Now here is where we get to some of the fun of coding! Just like writing, there can be more than one way to write something that accomplishes the same basic goals, but one might be far better or more elegant than the other." 932 | ] 933 | }, 934 | { 935 | "cell_type": "markdown", 936 | "metadata": {}, 937 | "source": [ 938 | "We can think about factorial by a different definition. In fact, it is the same defining feature of the Gamma function $$\\Gamma[x] = (x-1) \\Gamma[x-1]$$ and $$\\Gamma[1]=1$$ so that $\\Gamma(n) = (n-1)!$." 939 | ] 940 | }, 941 | { 942 | "cell_type": "code", 943 | "execution_count": 44, 944 | "metadata": {}, 945 | "outputs": [], 946 | "source": [ 947 | "def Gamma(n):\n", 948 | " \n", 949 | " if n<=1:\n", 950 | " #If n=0, or any value it can't determine, set to 1\n", 951 | " return 1\n", 952 | " else:\n", 953 | " #If it is greater than one, call again iteratively by definition\n", 954 | " return (n-1)*Gamma(n-1)" 955 | ] 956 | }, 957 | { 958 | "cell_type": "code", 959 | "execution_count": 45, 960 | "metadata": {}, 961 | "outputs": [ 962 | { 963 | "name": "stdout", 964 | "output_type": "stream", 965 | "text": [ 966 | "24 0.5280000000000006\n" 967 | ] 968 | } 969 | ], 970 | "source": [ 971 | "print(Gamma(5),Gamma(3.2))" 972 | ] 973 | }, 974 | { 975 | "cell_type": "markdown", 976 | "metadata": {}, 977 | "source": [ 978 | "Note that this isn't actually the true gamma function because we defined $\\Gamma(x<1) =1$ rather than just $\\Gamma(1)=1$." 979 | ] 980 | }, 981 | { 982 | "cell_type": "markdown", 983 | "metadata": {}, 984 | "source": [ 985 | "Regardless, this is a clever implementation, because it defines the factorial recursively, rather than by brute force." 986 | ] 987 | }, 988 | { 989 | "cell_type": "markdown", 990 | "metadata": {}, 991 | "source": [ 992 | "As our last example, we are going to make a sorting function. We want to take a list of numbers are reorder them from largest to smallest. " 993 | ] 994 | }, 995 | { 996 | "cell_type": "code", 997 | "execution_count": 46, 998 | "metadata": {}, 999 | "outputs": [], 1000 | "source": [ 1001 | "def dumb_sort(alist):\n", 1002 | " b=[] # I am making a place to put my numbers in order\n", 1003 | " \n", 1004 | " c=alist[:] # I am making a copy of the list so that I don't ruin my original list\n", 1005 | " \n", 1006 | " while len(c)>0: # I am going to loop over c and remove the largest each time. I stop when there is nothing left\n", 1007 | " \n", 1008 | " largest=c[0] # assume the first element is the largest\n", 1009 | " \n", 1010 | " for item in c: #now run over all the elements in the remaining list \n", 1011 | " if item>largest: # and check if any are bigger\n", 1012 | " largest=item # when you get somethign bigger, store it the biggest and continue\n", 1013 | " \n", 1014 | " b.append(largest) # after running through all the elements, add the largest to the output list\n", 1015 | " \n", 1016 | " c.pop(c.index(largest)) #remove the largest from c and repeat\n", 1017 | " \n", 1018 | " return b #when you have all the numbers in b, c=[] and the while loop will end. Output b" 1019 | ] 1020 | }, 1021 | { 1022 | "cell_type": "code", 1023 | "execution_count": 47, 1024 | "metadata": {}, 1025 | "outputs": [], 1026 | "source": [ 1027 | "unordered=[3,5,1,5,2,4,5,2,1]" 1028 | ] 1029 | }, 1030 | { 1031 | "cell_type": "code", 1032 | "execution_count": 48, 1033 | "metadata": {}, 1034 | "outputs": [ 1035 | { 1036 | "data": { 1037 | "text/plain": [ 1038 | "[5, 5, 5, 4, 3, 2, 2, 1, 1]" 1039 | ] 1040 | }, 1041 | "execution_count": 48, 1042 | "metadata": {}, 1043 | "output_type": "execute_result" 1044 | } 1045 | ], 1046 | "source": [ 1047 | "dumb_sort(unordered)" 1048 | ] 1049 | }, 1050 | { 1051 | "cell_type": "markdown", 1052 | "metadata": {}, 1053 | "source": [ 1054 | "I called the \"dumb_sort\" for a reason: it is really inefficient. I had to make multiple copies of my list and looped over the elements a lot of times. If I have a list of lenght N, I would take at least 3N space in memory and would run look at roughy N^2/2 elements in the list (I keep looking at them over and over again to compare them to the new biggest number)." 1055 | ] 1056 | }, 1057 | { 1058 | "cell_type": "code", 1059 | "execution_count": 49, 1060 | "metadata": {}, 1061 | "outputs": [ 1062 | { 1063 | "name": "stdout", 1064 | "output_type": "stream", 1065 | "text": [ 1066 | "[9, 8, 7, 5, 2, 1, 1]\n" 1067 | ] 1068 | } 1069 | ], 1070 | "source": [ 1071 | "def mysort(a):\n", 1072 | " for n in range(1,len(a)):\n", 1073 | " #Read in one element at a time, starting with second (first is sorted)\n", 1074 | " value=a[n]\n", 1075 | " #set marker for previous\n", 1076 | " i=n-1\n", 1077 | " while i>=0 and (value > a[i]):\n", 1078 | " #if i is not past the first element, but value > previous element swith the two\n", 1079 | " a[i+1]=a[i]\n", 1080 | " a[i] = value\n", 1081 | " #now move the marker one to the left and repeat\n", 1082 | " i-=1\n", 1083 | "#1st element is sorted. When we get to the nth element, the n-1 previous elements are sorted. Just need to place it in the right spot\n", 1084 | "\n", 1085 | "b=[1,5,7,8,1,9,2]\n", 1086 | "mysort(b)\n", 1087 | "print(b)" 1088 | ] 1089 | }, 1090 | { 1091 | "cell_type": "markdown", 1092 | "metadata": {}, 1093 | "source": [ 1094 | "Notice that if we give it an ordered list, it only has to check N-numbers instead of N^2/2. I.e. once we sort part of the list, we don't keep checking it. " 1095 | ] 1096 | }, 1097 | { 1098 | "cell_type": "markdown", 1099 | "metadata": {}, 1100 | "source": [ 1101 | "A very useful thing about functions is that you can given them options that come with defaults. To see this in action, suppose we want to know the position of a particle subject to an constant external force:" 1102 | ] 1103 | }, 1104 | { 1105 | "cell_type": "code", 1106 | "execution_count": 50, 1107 | "metadata": {}, 1108 | "outputs": [], 1109 | "source": [ 1110 | "def position(t,x0,v,a):\n", 1111 | " pos=x0+v*t+a*t**2/2. # solution for motion under constant acceleration\n", 1112 | " return pos # return position" 1113 | ] 1114 | }, 1115 | { 1116 | "cell_type": "code", 1117 | "execution_count": 51, 1118 | "metadata": {}, 1119 | "outputs": [ 1120 | { 1121 | "data": { 1122 | "text/plain": [ 1123 | "490.00000000000006" 1124 | ] 1125 | }, 1126 | "execution_count": 51, 1127 | "metadata": {}, 1128 | "output_type": "execute_result" 1129 | } 1130 | ], 1131 | "source": [ 1132 | "position(10,0,0,9.8)" 1133 | ] 1134 | }, 1135 | { 1136 | "cell_type": "markdown", 1137 | "metadata": {}, 1138 | "source": [ 1139 | "But maybe there are some standard choices we like, e.g. a=9.8 m/s$^2$ or x0=0. If that is a case we consider a lot, maybe we just want to assume those values, unless otherwise stated:" 1140 | ] 1141 | }, 1142 | { 1143 | "cell_type": "code", 1144 | "execution_count": 52, 1145 | "metadata": {}, 1146 | "outputs": [], 1147 | "source": [ 1148 | "def pos_short(t,x0=0,v=0,a=9.8):\n", 1149 | " pos=x0+v*t+a*t**2/2. # solution for motion under constant acceleration\n", 1150 | " return pos" 1151 | ] 1152 | }, 1153 | { 1154 | "cell_type": "code", 1155 | "execution_count": 53, 1156 | "metadata": {}, 1157 | "outputs": [ 1158 | { 1159 | "data": { 1160 | "text/plain": [ 1161 | "490.00000000000006" 1162 | ] 1163 | }, 1164 | "execution_count": 53, 1165 | "metadata": {}, 1166 | "output_type": "execute_result" 1167 | } 1168 | ], 1169 | "source": [ 1170 | "pos_short(10)" 1171 | ] 1172 | }, 1173 | { 1174 | "cell_type": "markdown", 1175 | "metadata": {}, 1176 | "source": [ 1177 | "The good part about doing it this way is that I can always put back the values if I want" 1178 | ] 1179 | }, 1180 | { 1181 | "cell_type": "code", 1182 | "execution_count": 54, 1183 | "metadata": {}, 1184 | "outputs": [ 1185 | { 1186 | "data": { 1187 | "text/plain": [ 1188 | "505.00000000000006" 1189 | ] 1190 | }, 1191 | "execution_count": 54, 1192 | "metadata": {}, 1193 | "output_type": "execute_result" 1194 | } 1195 | ], 1196 | "source": [ 1197 | "pos_short(10,x0=15)" 1198 | ] 1199 | }, 1200 | { 1201 | "cell_type": "markdown", 1202 | "metadata": {}, 1203 | "source": [ 1204 | "## Python Scripts" 1205 | ] 1206 | }, 1207 | { 1208 | "cell_type": "markdown", 1209 | "metadata": {}, 1210 | "source": [ 1211 | "Now that you have defined a function and have it working properly might want to do two things: (a) move it somewhere so that you don't accidently mess it up (b) have it available for other projects you might be working on." 1212 | ] 1213 | }, 1214 | { 1215 | "cell_type": "code", 1216 | "execution_count": 55, 1217 | "metadata": {}, 1218 | "outputs": [], 1219 | "source": [ 1220 | "import sort" 1221 | ] 1222 | }, 1223 | { 1224 | "cell_type": "code", 1225 | "execution_count": 56, 1226 | "metadata": {}, 1227 | "outputs": [ 1228 | { 1229 | "name": "stdout", 1230 | "output_type": "stream", 1231 | "text": [ 1232 | "[9, 8, 7, 5, 2, 1, 1]\n" 1233 | ] 1234 | } 1235 | ], 1236 | "source": [ 1237 | "b2=[1,5,7,8,1,9,2]\n", 1238 | "sort.mysort(b2)\n", 1239 | "print(b2)" 1240 | ] 1241 | }, 1242 | { 1243 | "cell_type": "markdown", 1244 | "metadata": {}, 1245 | "source": [ 1246 | "Notice that I can save all kinds of information this way. E.g. I can just save lists of numbers or specific numbers" 1247 | ] 1248 | }, 1249 | { 1250 | "cell_type": "code", 1251 | "execution_count": 57, 1252 | "metadata": {}, 1253 | "outputs": [ 1254 | { 1255 | "name": "stdout", 1256 | "output_type": "stream", 1257 | "text": [ 1258 | "3.141592653589793\n" 1259 | ] 1260 | } 1261 | ], 1262 | "source": [ 1263 | "print(sort.my_fav_number)" 1264 | ] 1265 | }, 1266 | { 1267 | "cell_type": "markdown", 1268 | "metadata": {}, 1269 | "source": [ 1270 | "This is the same structure we use for all kinds of things. We can make our lift easier by importing a file under a shorted name. E.g." 1271 | ] 1272 | }, 1273 | { 1274 | "cell_type": "code", 1275 | "execution_count": 58, 1276 | "metadata": {}, 1277 | "outputs": [], 1278 | "source": [ 1279 | "import numpy as np\n", 1280 | "import sort as s" 1281 | ] 1282 | }, 1283 | { 1284 | "cell_type": "code", 1285 | "execution_count": 59, 1286 | "metadata": {}, 1287 | "outputs": [ 1288 | { 1289 | "data": { 1290 | "text/plain": [ 1291 | "0.5403023058681398" 1292 | ] 1293 | }, 1294 | "execution_count": 59, 1295 | "metadata": {}, 1296 | "output_type": "execute_result" 1297 | } 1298 | ], 1299 | "source": [ 1300 | "np.cos(1.)" 1301 | ] 1302 | }, 1303 | { 1304 | "cell_type": "code", 1305 | "execution_count": 60, 1306 | "metadata": {}, 1307 | "outputs": [ 1308 | { 1309 | "name": "stdout", 1310 | "output_type": "stream", 1311 | "text": [ 1312 | "[9, 8, 7, 5, 2, 1, 1]\n" 1313 | ] 1314 | } 1315 | ], 1316 | "source": [ 1317 | "b3=[1,5,7,8,1,9,2]\n", 1318 | "s.mysort(b3)\n", 1319 | "print(b3)" 1320 | ] 1321 | }, 1322 | { 1323 | "cell_type": "markdown", 1324 | "metadata": {}, 1325 | "source": [ 1326 | "We have more than one option for how to important information. We could just import as single function, in which case you can just use the name:" 1327 | ] 1328 | }, 1329 | { 1330 | "cell_type": "code", 1331 | "execution_count": 61, 1332 | "metadata": {}, 1333 | "outputs": [], 1334 | "source": [ 1335 | "from numpy import cos" 1336 | ] 1337 | }, 1338 | { 1339 | "cell_type": "code", 1340 | "execution_count": 62, 1341 | "metadata": {}, 1342 | "outputs": [ 1343 | { 1344 | "data": { 1345 | "text/plain": [ 1346 | "0.5403023058681398" 1347 | ] 1348 | }, 1349 | "execution_count": 62, 1350 | "metadata": {}, 1351 | "output_type": "execute_result" 1352 | } 1353 | ], 1354 | "source": [ 1355 | "cos(1.)" 1356 | ] 1357 | }, 1358 | { 1359 | "cell_type": "markdown", 1360 | "metadata": {}, 1361 | "source": [ 1362 | "If you want to import all of the functions this way, you can use *, but PLEASE don't do this for things like numpy that have a LOT of functions" 1363 | ] 1364 | }, 1365 | { 1366 | "cell_type": "code", 1367 | "execution_count": 63, 1368 | "metadata": {}, 1369 | "outputs": [], 1370 | "source": [ 1371 | "from sort import *" 1372 | ] 1373 | }, 1374 | { 1375 | "cell_type": "code", 1376 | "execution_count": 64, 1377 | "metadata": {}, 1378 | "outputs": [ 1379 | { 1380 | "data": { 1381 | "text/plain": [ 1382 | "3.141592653589793" 1383 | ] 1384 | }, 1385 | "execution_count": 64, 1386 | "metadata": {}, 1387 | "output_type": "execute_result" 1388 | } 1389 | ], 1390 | "source": [ 1391 | "my_fav_number" 1392 | ] 1393 | }, 1394 | { 1395 | "cell_type": "markdown", 1396 | "metadata": {}, 1397 | "source": [ 1398 | "### Summary" 1399 | ] 1400 | }, 1401 | { 1402 | "cell_type": "markdown", 1403 | "metadata": {}, 1404 | "source": [ 1405 | "We have run through a lot of the basic functionality of python. At this level, you have all the functionality you need to do anything. You have all the basic logical and mathematical operations at your disposal and all the objects you need to store the input and output.\n", 1406 | "\n", 1407 | "Now, in practice, converting these basic operations into more advanced algorithms is a lot of work. You have the power to do it, but it would run very slow and take a lot of your time. Luckily, more skilled users of python have written a lot of that code using more advanced and elegant techniques. They probably do the same basic thing that you might, but it will run way faster and have a lot more versality (and is already debugged). From here, we are going to start learning about some of these software packages and how to understand what they are doing and why they are useful.\n" 1408 | ] 1409 | }, 1410 | { 1411 | "cell_type": "code", 1412 | "execution_count": null, 1413 | "metadata": { 1414 | "scrolled": true 1415 | }, 1416 | "outputs": [], 1417 | "source": [] 1418 | } 1419 | ], 1420 | "metadata": { 1421 | "kernelspec": { 1422 | "display_name": "Python 3 (ipykernel)", 1423 | "language": "python", 1424 | "name": "python3" 1425 | }, 1426 | "language_info": { 1427 | "codemirror_mode": { 1428 | "name": "ipython", 1429 | "version": 3 1430 | }, 1431 | "file_extension": ".py", 1432 | "mimetype": "text/x-python", 1433 | "name": "python", 1434 | "nbconvert_exporter": "python", 1435 | "pygments_lexer": "ipython3", 1436 | "version": "3.9.7" 1437 | } 1438 | }, 1439 | "nbformat": 4, 1440 | "nbformat_minor": 2 1441 | } 1442 | -------------------------------------------------------------------------------- /Topic2b random numbers.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Mathematical Operations in Numpy " 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Numpy has a lot of built in flexibility when it comes to doing math. The most obvious thing you might want to do is to treat numpy arrays as matrixes or vectors, depending on the circumstance. The recommend way to do this is to use the functions that specify vector multiplication: " 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 2, 20 | "metadata": {}, 21 | "outputs": [], 22 | "source": [ 23 | "import numpy as np" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 3, 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "A = np.linspace(1,9,9)\n", 33 | "B=A.reshape((3,3))" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 5, 39 | "metadata": {}, 40 | "outputs": [ 41 | { 42 | "name": "stdout", 43 | "output_type": "stream", 44 | "text": [ 45 | "[[1. 2. 3.]\n", 46 | " [4. 5. 6.]\n", 47 | " [7. 8. 9.]]\n", 48 | "[[ 1. 4. 9.]\n", 49 | " [16. 25. 36.]\n", 50 | " [49. 64. 81.]]\n" 51 | ] 52 | } 53 | ], 54 | "source": [ 55 | "print(B)\n", 56 | "print(B*B) # elementwise multiplication" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": 6, 62 | "metadata": {}, 63 | "outputs": [ 64 | { 65 | "name": "stdout", 66 | "output_type": "stream", 67 | "text": [ 68 | "[[ 30. 36. 42.]\n", 69 | " [ 66. 81. 96.]\n", 70 | " [102. 126. 150.]]\n" 71 | ] 72 | } 73 | ], 74 | "source": [ 75 | "print(np.dot(B,B)) #matix multiplication" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": 7, 81 | "metadata": {}, 82 | "outputs": [ 83 | { 84 | "name": "stdout", 85 | "output_type": "stream", 86 | "text": [ 87 | "285.0\n" 88 | ] 89 | } 90 | ], 91 | "source": [ 92 | "print(np.dot(A,A)) # vector dot product" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": 8, 98 | "metadata": {}, 99 | "outputs": [ 100 | { 101 | "name": "stdout", 102 | "output_type": "stream", 103 | "text": [ 104 | "[30. 36. 42.]\n" 105 | ] 106 | } 107 | ], 108 | "source": [ 109 | "print(np.dot(np.array((1,2,3)),B)) # left multiplication" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 9, 115 | "metadata": {}, 116 | "outputs": [ 117 | { 118 | "name": "stdout", 119 | "output_type": "stream", 120 | "text": [ 121 | "[14. 32. 50.]\n" 122 | ] 123 | } 124 | ], 125 | "source": [ 126 | "print(np.dot(B,np.array((1,2,3)))) # right multiplication" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": 10, 132 | "metadata": {}, 133 | "outputs": [], 134 | "source": [ 135 | "C=B+np.identity(3) # matrix addition acts as usual" 136 | ] 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "metadata": {}, 141 | "source": [ 142 | "print C\n", 143 | "print np.linalg.inv(C) # matrix inverse" 144 | ] 145 | }, 146 | { 147 | "cell_type": "code", 148 | "execution_count": 11, 149 | "metadata": {}, 150 | "outputs": [ 151 | { 152 | "data": { 153 | "text/plain": [ 154 | "array([[ 1.00000000e+00, -2.22044605e-16, 4.44089210e-16],\n", 155 | " [-1.77635684e-15, 1.00000000e+00, 8.88178420e-16],\n", 156 | " [-1.77635684e-15, 4.44089210e-16, 1.00000000e+00]])" 157 | ] 158 | }, 159 | "execution_count": 11, 160 | "metadata": {}, 161 | "output_type": "execute_result" 162 | } 163 | ], 164 | "source": [ 165 | "np.dot(C,np.linalg.inv(C))" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "metadata": {}, 171 | "source": [ 172 | "## Random Numbers" 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "metadata": {}, 178 | "source": [ 179 | "Generating random numbers is an extremely useful tool in scientific computing. We will see some applications in a second, but first let's just get the syntax. " 180 | ] 181 | }, 182 | { 183 | "cell_type": "markdown", 184 | "metadata": {}, 185 | "source": [ 186 | "The first thing you might want is a random number drawn from a uniform probability between 0 and 1" 187 | ] 188 | }, 189 | { 190 | "cell_type": "code", 191 | "execution_count": 12, 192 | "metadata": {}, 193 | "outputs": [ 194 | { 195 | "data": { 196 | "text/plain": [ 197 | "0.6016876446251747" 198 | ] 199 | }, 200 | "execution_count": 12, 201 | "metadata": {}, 202 | "output_type": "execute_result" 203 | } 204 | ], 205 | "source": [ 206 | "np.random.rand()" 207 | ] 208 | }, 209 | { 210 | "cell_type": "markdown", 211 | "metadata": {}, 212 | "source": [ 213 | "This function actually will give you a bunch of random numbers in any shape " 214 | ] 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": 13, 219 | "metadata": {}, 220 | "outputs": [ 221 | { 222 | "data": { 223 | "text/plain": [ 224 | "array([0.55722988, 0.93630618, 0.91597478, 0.75019333, 0.28416667,\n", 225 | " 0.50649391, 0.19204317, 0.29002769, 0.40983224, 0.56511915])" 226 | ] 227 | }, 228 | "execution_count": 13, 229 | "metadata": {}, 230 | "output_type": "execute_result" 231 | } 232 | ], 233 | "source": [ 234 | "np.random.rand(10)" 235 | ] 236 | }, 237 | { 238 | "cell_type": "code", 239 | "execution_count": 14, 240 | "metadata": {}, 241 | "outputs": [ 242 | { 243 | "data": { 244 | "text/plain": [ 245 | "array([[[0.26873925, 0.49868733],\n", 246 | " [0.73441629, 0.48327672]],\n", 247 | "\n", 248 | " [[0.72069766, 0.57130762],\n", 249 | " [0.67640855, 0.08804592]]])" 250 | ] 251 | }, 252 | "execution_count": 14, 253 | "metadata": {}, 254 | "output_type": "execute_result" 255 | } 256 | ], 257 | "source": [ 258 | "np.random.rand(2,2,2)" 259 | ] 260 | }, 261 | { 262 | "cell_type": "markdown", 263 | "metadata": {}, 264 | "source": [ 265 | "Given such a distribution, we can make our own function to cover any uniform distibution:" 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": 15, 271 | "metadata": {}, 272 | "outputs": [], 273 | "source": [ 274 | "def my_uniform(low,high,number):\n", 275 | " out=np.random.rand(number)\n", 276 | " out*=(high-low)\n", 277 | " out+=low\n", 278 | " return out" 279 | ] 280 | }, 281 | { 282 | "cell_type": "code", 283 | "execution_count": 16, 284 | "metadata": {}, 285 | "outputs": [ 286 | { 287 | "data": { 288 | "text/plain": [ 289 | "array([10.86609225, 10.57061903, 10.21393748, 10.77261633, 10.6479499 ,\n", 290 | " 10.54506753, 10.51962553, 10.91832482, 10.6516501 , 10.66427035,\n", 291 | " 10.12465191, 10.17885098, 10.93819946, 10.39675058, 10.36724901,\n", 292 | " 10.28285138, 10.55238656, 10.04166241, 10.02862009, 10.94183373])" 293 | ] 294 | }, 295 | "execution_count": 16, 296 | "metadata": {}, 297 | "output_type": "execute_result" 298 | } 299 | ], 300 | "source": [ 301 | "my_uniform(10,11,20)" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": 17, 307 | "metadata": {}, 308 | "outputs": [ 309 | { 310 | "data": { 311 | "text/plain": [ 312 | "array([ 6.73268147, -91.2248753 , -60.28716919, 67.99421959,\n", 313 | " 80.2550022 , -41.5117526 , 6.40308909, 84.45886703,\n", 314 | " -30.70539367, 20.6770233 , 13.84584551, -95.78011493,\n", 315 | " 4.93071698, -78.01736987, -67.83963778, 24.90153235,\n", 316 | " -90.97254368, -14.56411183, -91.43542687, -53.93503171])" 317 | ] 318 | }, 319 | "execution_count": 17, 320 | "metadata": {}, 321 | "output_type": "execute_result" 322 | } 323 | ], 324 | "source": [ 325 | "my_uniform(-102.3,99.2,20)" 326 | ] 327 | }, 328 | { 329 | "cell_type": "markdown", 330 | "metadata": {}, 331 | "source": [ 332 | "naturally, numpy has its own version of this function" 333 | ] 334 | }, 335 | { 336 | "cell_type": "code", 337 | "execution_count": 18, 338 | "metadata": {}, 339 | "outputs": [ 340 | { 341 | "data": { 342 | "text/plain": [ 343 | "array([ -63.92031063, 32.28342588, -85.41815281, -100.05150213,\n", 344 | " 22.42643583, 89.05307348, 53.10182557, 37.76677922,\n", 345 | " 14.93287387, -56.30705675, -43.56619811, 36.93817297,\n", 346 | " 80.14891659, -37.32338673, -101.04893957, -68.35358032,\n", 347 | " 9.35668409, -80.74336859, 21.38788825, 85.07600425])" 348 | ] 349 | }, 350 | "execution_count": 18, 351 | "metadata": {}, 352 | "output_type": "execute_result" 353 | } 354 | ], 355 | "source": [ 356 | "np.random.uniform(-102.3,99.2,20)" 357 | ] 358 | }, 359 | { 360 | "cell_type": "markdown", 361 | "metadata": {}, 362 | "source": [ 363 | "However, it is important to realize that once you have a source of random numbers, you can mold it to do other things you want" 364 | ] 365 | }, 366 | { 367 | "cell_type": "markdown", 368 | "metadata": {}, 369 | "source": [ 370 | "The other common kind of random number you will want is one drawn from a normal distibution. This means the probability (density) of drawing the number x is $P(x) = e^{-(x-\\mu)^2/2\\sigma^2}/\\sqrt{2\\pi \\sigma^2}$. The number $\\mu$ is called the mean and $\\sigma$ is the variance. " 371 | ] 372 | }, 373 | { 374 | "cell_type": "markdown", 375 | "metadata": {}, 376 | "source": [ 377 | "Python has a nice way of generating numbers with $\\mu =0$ and $\\sigma=1$:" 378 | ] 379 | }, 380 | { 381 | "cell_type": "code", 382 | "execution_count": 19, 383 | "metadata": {}, 384 | "outputs": [ 385 | { 386 | "data": { 387 | "text/plain": [ 388 | "array([ 1.26048954, -0.27680153, 0.84273992, 0.73759186, 0.39144814,\n", 389 | " 1.00411062, -0.06727062, -0.42714591, -1.17763563, -1.89118457])" 390 | ] 391 | }, 392 | "execution_count": 19, 393 | "metadata": {}, 394 | "output_type": "execute_result" 395 | } 396 | ], 397 | "source": [ 398 | "np.random.randn(10)" 399 | ] 400 | }, 401 | { 402 | "cell_type": "markdown", 403 | "metadata": {}, 404 | "source": [ 405 | "Let's make a histogram to see what this is doing:" 406 | ] 407 | }, 408 | { 409 | "cell_type": "code", 410 | "execution_count": 20, 411 | "metadata": {}, 412 | "outputs": [], 413 | "source": [ 414 | "import matplotlib.pyplot as plt" 415 | ] 416 | }, 417 | { 418 | "cell_type": "code", 419 | "execution_count": 21, 420 | "metadata": {}, 421 | "outputs": [ 422 | { 423 | "data": { 424 | "image/png": "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\n", 425 | "text/plain": [ 426 | "
" 427 | ] 428 | }, 429 | "metadata": { 430 | "needs_background": "light" 431 | }, 432 | "output_type": "display_data" 433 | } 434 | ], 435 | "source": [ 436 | "plt.hist(np.random.randn(1000000),bins=np.linspace(-3,3,1000))\n", 437 | "plt.show()" 438 | ] 439 | }, 440 | { 441 | "cell_type": "code", 442 | "execution_count": 23, 443 | "metadata": {}, 444 | "outputs": [ 445 | { 446 | "data": { 447 | "text/plain": [ 448 | "array([2, 1, 2, 1, 0, 2, 2, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 1, 1, 1, 2,\n", 449 | " 2, 1, 1, 2, 1, 1, 0, 2, 2, 2, 0, 2, 0, 2, 1, 0, 0, 2, 2, 0, 2, 1,\n", 450 | " 2, 2, 0, 2, 2, 0, 1, 0, 2, 2, 0, 2, 1, 2, 0, 1, 1, 0, 2, 1, 1, 0,\n", 451 | " 2, 0, 1, 0, 0, 0, 2, 0, 0, 2, 2, 1, 2, 2, 2, 2, 2, 1, 1, 1, 2, 1,\n", 452 | " 0, 1, 0, 2, 2, 1, 2, 1, 2, 1, 1, 1])" 453 | ] 454 | }, 455 | "execution_count": 23, 456 | "metadata": {}, 457 | "output_type": "execute_result" 458 | } 459 | ], 460 | "source": [ 461 | "np.random.randint(3,size=100)" 462 | ] 463 | }, 464 | { 465 | "cell_type": "code", 466 | "execution_count": 24, 467 | "metadata": {}, 468 | "outputs": [ 469 | { 470 | "data": { 471 | "text/plain": [ 472 | "6" 473 | ] 474 | }, 475 | "execution_count": 24, 476 | "metadata": {}, 477 | "output_type": "execute_result" 478 | } 479 | ], 480 | "source": [ 481 | "np.random.randint(2,size=10).sum()" 482 | ] 483 | }, 484 | { 485 | "cell_type": "code", 486 | "execution_count": 26, 487 | "metadata": {}, 488 | "outputs": [], 489 | "source": [ 490 | "number_of_flips=10\n", 491 | "number_of_trails=1000\n", 492 | "results=np.zeros(number_of_trails)\n", 493 | "for i in range(number_of_trails):\n", 494 | " results[i]=np.random.randint(2,size=number_of_flips).sum()/float(number_of_flips)" 495 | ] 496 | }, 497 | { 498 | "cell_type": "code", 499 | "execution_count": 27, 500 | "metadata": {}, 501 | "outputs": [ 502 | { 503 | "data": { 504 | "image/png": "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\n", 505 | "text/plain": [ 506 | "
" 507 | ] 508 | }, 509 | "metadata": { 510 | "needs_background": "light" 511 | }, 512 | "output_type": "display_data" 513 | } 514 | ], 515 | "source": [ 516 | "plt.hist(results,bins=np.linspace(0,1,10))\n", 517 | "plt.show()" 518 | ] 519 | }, 520 | { 521 | "cell_type": "markdown", 522 | "metadata": {}, 523 | "source": [ 524 | "## Demonstration: calculating $\\pi$" 525 | ] 526 | }, 527 | { 528 | "cell_type": "markdown", 529 | "metadata": {}, 530 | "source": [ 531 | "To get a quick sense of why this is useful, we can demonstrate how we can calculate $\\pi$ using what we have just learned. This will actually serve as an important example of a much broader and more powerful set of techniques later in the course, but for now it is just to give you a taste of how these things can work for you." 532 | ] 533 | }, 534 | { 535 | "cell_type": "markdown", 536 | "metadata": {}, 537 | "source": [ 538 | "The idea is the following: image you pick a point randomly inside a square of length 2 on each side. The area of this square is 4. I circle placed within the square with radius 1 has area $\\pi$. If a random draw numbers that land inside the square with a uniform probability, then $\\pi/4$ of them (on average) should also be inside the circle. Said different, after picking a point in the square, we ask if it is also in the circle and keep track. At the end we take number in circle / total we have caculated $\\pi/4$" 539 | ] 540 | }, 541 | { 542 | "cell_type": "code", 543 | "execution_count": 28, 544 | "metadata": {}, 545 | "outputs": [], 546 | "source": [ 547 | "def pi_calculator(N):\n", 548 | " x=np.random.uniform(-1,1,N) # make a list of N random numbers of x-axis of box\n", 549 | " y=np.random.uniform(-1,1,N) # make a list of N random numbers of y-axis of box\n", 550 | " z=(x**2+y**2<1) # make a list of every time x^2 + y^2 < 1 (inside the cicle)\n", 551 | " return z.sum()/float(N)*4 # add all the points in the circle up and return 4*cicle/N" 552 | ] 553 | }, 554 | { 555 | "cell_type": "code", 556 | "execution_count": 29, 557 | "metadata": {}, 558 | "outputs": [ 559 | { 560 | "data": { 561 | "text/plain": [ 562 | "3.142122" 563 | ] 564 | }, 565 | "execution_count": 29, 566 | "metadata": {}, 567 | "output_type": "execute_result" 568 | } 569 | ], 570 | "source": [ 571 | "pi_calculator(10**7)" 572 | ] 573 | }, 574 | { 575 | "cell_type": "code", 576 | "execution_count": 30, 577 | "metadata": {}, 578 | "outputs": [ 579 | { 580 | "data": { 581 | "text/plain": [ 582 | "3.14184244" 583 | ] 584 | }, 585 | "execution_count": 30, 586 | "metadata": {}, 587 | "output_type": "execute_result" 588 | } 589 | ], 590 | "source": [ 591 | "pi_calculator(10**8)" 592 | ] 593 | }, 594 | { 595 | "cell_type": "code", 596 | "execution_count": 31, 597 | "metadata": {}, 598 | "outputs": [ 599 | { 600 | "data": { 601 | "text/plain": [ 602 | "3.141648488" 603 | ] 604 | }, 605 | "execution_count": 31, 606 | "metadata": {}, 607 | "output_type": "execute_result" 608 | } 609 | ], 610 | "source": [ 611 | "pi_calculator(10**9)" 612 | ] 613 | }, 614 | { 615 | "cell_type": "code", 616 | "execution_count": 39, 617 | "metadata": {}, 618 | "outputs": [], 619 | "source": [ 620 | "x=np.random.uniform(-1,1,5)\n", 621 | "y=np.random.uniform(-1,1,5)\n", 622 | "z=(x**2+y**2<1)" 623 | ] 624 | }, 625 | { 626 | "cell_type": "code", 627 | "execution_count": 43, 628 | "metadata": {}, 629 | "outputs": [ 630 | { 631 | "name": "stdout", 632 | "output_type": "stream", 633 | "text": [ 634 | "[-0.46261577 0.93124438 0.74169432 0.45117097 0.1718111 ] [ 0.89592606 0.11286007 -0.40097035 0.9466685 -0.91434233]\n", 635 | "[1.01669686 0.87995349 0.71088768 1.09973649 0.86554094]\n", 636 | "[False True True False True]\n" 637 | ] 638 | } 639 | ], 640 | "source": [ 641 | "print(x,y)\n", 642 | "print(x**2+y**2)\n", 643 | "print(z)" 644 | ] 645 | }, 646 | { 647 | "cell_type": "code", 648 | "execution_count": 44, 649 | "metadata": {}, 650 | "outputs": [ 651 | { 652 | "data": { 653 | "text/plain": [ 654 | "3" 655 | ] 656 | }, 657 | "execution_count": 44, 658 | "metadata": {}, 659 | "output_type": "execute_result" 660 | } 661 | ], 662 | "source": [ 663 | "z.sum()" 664 | ] 665 | }, 666 | { 667 | "cell_type": "markdown", 668 | "metadata": {}, 669 | "source": [ 670 | "To see how this is working, let's write a slower version to see the steps" 671 | ] 672 | }, 673 | { 674 | "cell_type": "code", 675 | "execution_count": 45, 676 | "metadata": {}, 677 | "outputs": [], 678 | "source": [ 679 | "def pi_slow(N):\n", 680 | " circle=0\n", 681 | " for i in range(N):\n", 682 | " x=np.random.uniform(-1,1,1) # pick a x coordinate in the box\n", 683 | " y=np.random.uniform(-1,1,1) # pick a y coordinate in the box\n", 684 | " if x**2+y**2<1: # make a list of every time x^2 + y^2 < 1 (inside the cicle)\n", 685 | " circle+=1 \n", 686 | " return 4*circle/N # add all the points in the circle up and return 4*cicle/N" 687 | ] 688 | }, 689 | { 690 | "cell_type": "code", 691 | "execution_count": 46, 692 | "metadata": {}, 693 | "outputs": [ 694 | { 695 | "data": { 696 | "text/plain": [ 697 | "3.14284" 698 | ] 699 | }, 700 | "execution_count": 46, 701 | "metadata": {}, 702 | "output_type": "execute_result" 703 | } 704 | ], 705 | "source": [ 706 | "pi_slow(10**6)" 707 | ] 708 | }, 709 | { 710 | "cell_type": "code", 711 | "execution_count": 47, 712 | "metadata": {}, 713 | "outputs": [ 714 | { 715 | "data": { 716 | "text/plain": [ 717 | "3.14165004" 718 | ] 719 | }, 720 | "execution_count": 47, 721 | "metadata": {}, 722 | "output_type": "execute_result" 723 | } 724 | ], 725 | "source": [ 726 | "pi_calculator(10**8)" 727 | ] 728 | }, 729 | { 730 | "cell_type": "markdown", 731 | "metadata": {}, 732 | "source": [ 733 | "The slow implementation makes it clear what we are doing, but it clearly takes much longer." 734 | ] 735 | }, 736 | { 737 | "cell_type": "code", 738 | "execution_count": 48, 739 | "metadata": {}, 740 | "outputs": [], 741 | "source": [ 742 | "import time" 743 | ] 744 | }, 745 | { 746 | "cell_type": "code", 747 | "execution_count": 50, 748 | "metadata": {}, 749 | "outputs": [ 750 | { 751 | "name": "stdout", 752 | "output_type": "stream", 753 | "text": [ 754 | "9.319647073745728\n" 755 | ] 756 | } 757 | ], 758 | "source": [ 759 | "t1 = time.time()\n", 760 | "pi_slow(1000000)\n", 761 | "print(time.time() - t1)" 762 | ] 763 | }, 764 | { 765 | "cell_type": "code", 766 | "execution_count": 51, 767 | "metadata": {}, 768 | "outputs": [ 769 | { 770 | "name": "stdout", 771 | "output_type": "stream", 772 | "text": [ 773 | "0.0646061897277832\n" 774 | ] 775 | } 776 | ], 777 | "source": [ 778 | "t1 = time.time()\n", 779 | "pi_calculator(1000000)\n", 780 | "print(time.time() - t1)" 781 | ] 782 | }, 783 | { 784 | "cell_type": "markdown", 785 | "metadata": {}, 786 | "source": [ 787 | "Anticipating something we will discuss later, now let's see how our error in the measurement of pi scales with the number of random points we pick" 788 | ] 789 | }, 790 | { 791 | "cell_type": "code", 792 | "execution_count": 52, 793 | "metadata": {}, 794 | "outputs": [], 795 | "source": [ 796 | "short=int(10**6)\n", 797 | "medium=int(10**7)\n", 798 | "Long=int(10**(8))\n", 799 | "trials=100\n", 800 | "pi_list_short=np.zeros(trials)\n", 801 | "pi_list_medium=np.zeros(trials)\n", 802 | "pi_list_Long=np.zeros(trials)\n", 803 | "for i in range(trials):\n", 804 | " pi_list_short[i]=pi_calculator(short)\n", 805 | " pi_list_medium[i]=pi_calculator(medium)\n", 806 | " pi_list_Long[i]=pi_calculator(Long)" 807 | ] 808 | }, 809 | { 810 | "cell_type": "code", 811 | "execution_count": 58, 812 | "metadata": {}, 813 | "outputs": [ 814 | { 815 | "data": { 816 | "image/png": "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\n", 817 | "text/plain": [ 818 | "
" 819 | ] 820 | }, 821 | "metadata": { 822 | "needs_background": "light" 823 | }, 824 | "output_type": "display_data" 825 | } 826 | ], 827 | "source": [ 828 | "fig, ax = plt.subplots()\n", 829 | "p1=ax.hist(pi_list_short,bins=np.linspace(3.13,3.15,100),label='$10^6$')\n", 830 | "p2=ax.hist(pi_list_medium,bins=np.linspace(3.13,3.15,100),label='$10^7$')\n", 831 | "p3=ax.hist(pi_list_Long,bins=np.linspace(3.13,3.15,100),label='$10^8$')\n", 832 | "ax.plot([np.pi,np.pi],[0,40])\n", 833 | "plt.ylim(0,40)\n", 834 | "plt.xlim(3.1375,3.145)\n", 835 | "leg = ax.legend()\n", 836 | "plt.show()" 837 | ] 838 | }, 839 | { 840 | "cell_type": "markdown", 841 | "metadata": {}, 842 | "source": [ 843 | "By eye, it looks like the blue is a approximately 10 times wider than the green. This would make sense if the error on the value of $\\pi$ decreased by $1/\\sqrt{N}$ where $N$ is the number of random points used in the calculation. This is indeed what is going on and is a much more general fact about random numbers." 844 | ] 845 | }, 846 | { 847 | "cell_type": "markdown", 848 | "metadata": {}, 849 | "source": [ 850 | "### Summary" 851 | ] 852 | }, 853 | { 854 | "cell_type": "markdown", 855 | "metadata": {}, 856 | "source": [ 857 | "Numpy has a number of basic math operations we will make a lot of use off. Random numbers are a particularly valuable tool that is employed in all areas of science and engineering. E.g. simulating the behavior of any measurement involves adding random numbers to you signal. We can always use the output of the random number library to create the type of noise we want for a given application. " 858 | ] 859 | }, 860 | { 861 | "cell_type": "code", 862 | "execution_count": null, 863 | "metadata": {}, 864 | "outputs": [], 865 | "source": [] 866 | } 867 | ], 868 | "metadata": { 869 | "kernelspec": { 870 | "display_name": "Python 3 (ipykernel)", 871 | "language": "python", 872 | "name": "python3" 873 | }, 874 | "language_info": { 875 | "codemirror_mode": { 876 | "name": "ipython", 877 | "version": 3 878 | }, 879 | "file_extension": ".py", 880 | "mimetype": "text/x-python", 881 | "name": "python", 882 | "nbconvert_exporter": "python", 883 | "pygments_lexer": "ipython3", 884 | "version": "3.9.7" 885 | } 886 | }, 887 | "nbformat": 4, 888 | "nbformat_minor": 2 889 | } 890 | -------------------------------------------------------------------------------- /Topic 1a Data Types.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Topic 1: Basics of Python" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "This is a jupyter notebook. It is a coding enviroment that is useful for developing, testing code, doing short caluclations, making figures etc. We will start doing everything here so that we can see what we are doing as we go along. Later in the course, we will talk about how to write you code into python scripts that live outside of jupyter." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "A juypter notebook works the same as any python code but you can run small pieces of it at a time. There is also the markdown option so that you can write explainations in latex (like this one). You can also comment your code directly in line," 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 1, 27 | "metadata": {}, 28 | "outputs": [ 29 | { 30 | "name": "stdout", 31 | "output_type": "stream", 32 | "text": [ 33 | "hi\n" 34 | ] 35 | } 36 | ], 37 | "source": [ 38 | "print(\"hi\") # this is a comment inside of a piece of code. See, python ignores everything after the #" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": {}, 44 | "source": [ 45 | "The notebook format is useful because you run just bits of code and you can keep trying it until it works. Unlike a script, it will also output some of the results, even if you don't ask it to print them. E.g." 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 2, 51 | "metadata": {}, 52 | "outputs": [ 53 | { 54 | "data": { 55 | "text/plain": [ 56 | "10" 57 | ] 58 | }, 59 | "execution_count": 2, 60 | "metadata": {}, 61 | "output_type": "execute_result" 62 | } 63 | ], 64 | "source": [ 65 | "5+5" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "We can run what is in each box by pressing \"shift-enter\" (at same time). You can also go to \"Cell\" a run that cell, a few cells or the entire notebook." 73 | ] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "metadata": {}, 78 | "source": [ 79 | "There is one big danger of notebooks that doesn't happen in a script: the computer is running it in the order you choose, not the order on the page. This means you might accidently redefine a variable without noticing. It also means that you code could be working fine and then when you try to rerun it, it doesn't work anymore. E.g." 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 3, 85 | "metadata": {}, 86 | "outputs": [], 87 | "source": [ 88 | "a=5\n", 89 | "b=6\n", 90 | "c=7" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 6, 96 | "metadata": {}, 97 | "outputs": [ 98 | { 99 | "data": { 100 | "text/plain": [ 101 | "11" 102 | ] 103 | }, 104 | "execution_count": 6, 105 | "metadata": {}, 106 | "output_type": "execute_result" 107 | } 108 | ], 109 | "source": [ 110 | "a+b+c # The number to the left of this box tells you what order I ran it in " 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 5, 116 | "metadata": {}, 117 | "outputs": [], 118 | "source": [ 119 | "c=0" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "The way we can avoid this problem is if (a) you are careful to pick good names and not repeat them (b) document your code so that you know what you are doing and why at each step. Alternatively, if you are just using a variable temporarily, you can delete the variable name after you use it" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": 7, 132 | "metadata": {}, 133 | "outputs": [], 134 | "source": [ 135 | "del a\n", 136 | "del b\n", 137 | "del c" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": 8, 143 | "metadata": {}, 144 | "outputs": [ 145 | { 146 | "ename": "NameError", 147 | "evalue": "name 'a' is not defined", 148 | "output_type": "error", 149 | "traceback": [ 150 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 151 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", 152 | "\u001b[0;32m/var/folders/vh/rcz751b57355h3qzj37sc3080000gp/T/ipykernel_1213/2167009006.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 153 | "\u001b[0;31mNameError\u001b[0m: name 'a' is not defined" 154 | ] 155 | } 156 | ], 157 | "source": [ 158 | "a" 159 | ] 160 | }, 161 | { 162 | "cell_type": "markdown", 163 | "metadata": {}, 164 | "source": [ 165 | "## Topic 1a: Basic Objects" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "metadata": {}, 171 | "source": [ 172 | "### Data types" 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "metadata": {}, 178 | "source": [ 179 | "The most basic data types we can use throughout python are the integers (int), floating point numbers (float), strings (str), and complex " 180 | ] 181 | }, 182 | { 183 | "cell_type": "markdown", 184 | "metadata": {}, 185 | "source": [ 186 | "Here is an some integers (int):" 187 | ] 188 | }, 189 | { 190 | "cell_type": "code", 191 | "execution_count": 9, 192 | "metadata": {}, 193 | "outputs": [], 194 | "source": [ 195 | "a = 2\n", 196 | "b = 3" 197 | ] 198 | }, 199 | { 200 | "cell_type": "markdown", 201 | "metadata": {}, 202 | "source": [ 203 | "Here is an some floating point numbers (float), think of these as number represented as a decimal:" 204 | ] 205 | }, 206 | { 207 | "cell_type": "code", 208 | "execution_count": 10, 209 | "metadata": {}, 210 | "outputs": [], 211 | "source": [ 212 | "c = 2.\n", 213 | "d = 3.\n", 214 | "e = 3.14" 215 | ] 216 | }, 217 | { 218 | "cell_type": "markdown", 219 | "metadata": {}, 220 | "source": [ 221 | "Here are some strings (str), basically anything we want to treate like words:" 222 | ] 223 | }, 224 | { 225 | "cell_type": "code", 226 | "execution_count": 11, 227 | "metadata": {}, 228 | "outputs": [], 229 | "source": [ 230 | "f='2'\n", 231 | "g='hi'\n", 232 | "h='hello'" 233 | ] 234 | }, 235 | { 236 | "cell_type": "markdown", 237 | "metadata": {}, 238 | "source": [ 239 | "What makes these structures different is how basic operations in python treat them. We can start with basic math operations. Let's start with integer operations." 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": 12, 245 | "metadata": {}, 246 | "outputs": [ 247 | { 248 | "name": "stdout", 249 | "output_type": "stream", 250 | "text": [ 251 | "0.6666666666666666\n", 252 | "5\n", 253 | "-1\n", 254 | "6\n", 255 | "0.4\n" 256 | ] 257 | } 258 | ], 259 | "source": [ 260 | "print(a/b)\n", 261 | "print(a+b)\n", 262 | "print(a-b)\n", 263 | "print(a*b)\n", 264 | "print(a/(a+b))" 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": 13, 270 | "metadata": {}, 271 | "outputs": [ 272 | { 273 | "name": "stdout", 274 | "output_type": "stream", 275 | "text": [ 276 | "0.6666666666666666\n", 277 | "5.0\n", 278 | "-1.0\n", 279 | "6.0\n", 280 | "0.4\n" 281 | ] 282 | } 283 | ], 284 | "source": [ 285 | "print(c/d)\n", 286 | "print(c+d)\n", 287 | "print(c-d)\n", 288 | "print(c*d)\n", 289 | "print(c/(c+d))" 290 | ] 291 | }, 292 | { 293 | "cell_type": "markdown", 294 | "metadata": {}, 295 | "source": [ 296 | "At this point, there isn't much difference between a float and integer. However, other objects in python care about the type of data that you feed them and won't accept a float in place of an int. E.g. here we have a list of objects (we'll explain lists in a second)" 297 | ] 298 | }, 299 | { 300 | "cell_type": "code", 301 | "execution_count": 14, 302 | "metadata": {}, 303 | "outputs": [], 304 | "source": [ 305 | "list=['this','is','a','list'] # this is a list" 306 | ] 307 | }, 308 | { 309 | "cell_type": "markdown", 310 | "metadata": {}, 311 | "source": [ 312 | "Let's see what happens when we ask for an element of this list using a int or a float. Let's use our old variables" 313 | ] 314 | }, 315 | { 316 | "cell_type": "code", 317 | "execution_count": 15, 318 | "metadata": {}, 319 | "outputs": [ 320 | { 321 | "name": "stdout", 322 | "output_type": "stream", 323 | "text": [ 324 | "3 3.0\n" 325 | ] 326 | } 327 | ], 328 | "source": [ 329 | "print(b,d) # b and d are both 3 but one is an int and the other is a float" 330 | ] 331 | }, 332 | { 333 | "cell_type": "markdown", 334 | "metadata": {}, 335 | "source": [ 336 | "Now let's ask to see an entry (the one labeled by the number three) in our list" 337 | ] 338 | }, 339 | { 340 | "cell_type": "code", 341 | "execution_count": 16, 342 | "metadata": {}, 343 | "outputs": [ 344 | { 345 | "data": { 346 | "text/plain": [ 347 | "'list'" 348 | ] 349 | }, 350 | "execution_count": 16, 351 | "metadata": {}, 352 | "output_type": "execute_result" 353 | } 354 | ], 355 | "source": [ 356 | "list[b]" 357 | ] 358 | }, 359 | { 360 | "cell_type": "code", 361 | "execution_count": 17, 362 | "metadata": {}, 363 | "outputs": [ 364 | { 365 | "ename": "TypeError", 366 | "evalue": "list indices must be integers or slices, not float", 367 | "output_type": "error", 368 | "traceback": [ 369 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 370 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 371 | "\u001b[0;32m/var/folders/vh/rcz751b57355h3qzj37sc3080000gp/T/ipykernel_1213/1439936676.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mlist\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0md\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 372 | "\u001b[0;31mTypeError\u001b[0m: list indices must be integers or slices, not float" 373 | ] 374 | } 375 | ], 376 | "source": [ 377 | "list[d]" 378 | ] 379 | }, 380 | { 381 | "cell_type": "markdown", 382 | "metadata": {}, 383 | "source": [ 384 | "We see why it was important that b is an integer: the list new it was an integer so it knows what entry 3 means, not 3.0. (You might also have noticed something a bit odd about the fact it returned 'list', don't worry, we'll talk about that in a second)\n", 385 | "\n", 386 | "We can solve this issue by forcing d to be an integer" 387 | ] 388 | }, 389 | { 390 | "cell_type": "code", 391 | "execution_count": 18, 392 | "metadata": {}, 393 | "outputs": [ 394 | { 395 | "data": { 396 | "text/plain": [ 397 | "'list'" 398 | ] 399 | }, 400 | "execution_count": 18, 401 | "metadata": {}, 402 | "output_type": "execute_result" 403 | } 404 | ], 405 | "source": [ 406 | "list[int(d)]" 407 | ] 408 | }, 409 | { 410 | "cell_type": "code", 411 | "execution_count": 19, 412 | "metadata": {}, 413 | "outputs": [ 414 | { 415 | "name": "stdout", 416 | "output_type": "stream", 417 | "text": [ 418 | "3 3 3\n" 419 | ] 420 | } 421 | ], 422 | "source": [ 423 | "print(int(d),int(3.12),int(3.91))" 424 | ] 425 | }, 426 | { 427 | "cell_type": "markdown", 428 | "metadata": {}, 429 | "source": [ 430 | "This maybe isn't quite what you expected, it just strips off all the decimals, but it does returna an integer." 431 | ] 432 | }, 433 | { 434 | "cell_type": "markdown", 435 | "metadata": {}, 436 | "source": [ 437 | "Side note: In Python 2.7, a/b would have been considered integer division. Integer division is confusing because it forces the result to be an integer by striping off the decimal points. I.e. it doesn't round up, it always rounds down. In python 3, integer division has its own syntax" 438 | ] 439 | }, 440 | { 441 | "cell_type": "code", 442 | "execution_count": 20, 443 | "metadata": {}, 444 | "outputs": [ 445 | { 446 | "data": { 447 | "text/plain": [ 448 | "0" 449 | ] 450 | }, 451 | "execution_count": 20, 452 | "metadata": {}, 453 | "output_type": "execute_result" 454 | } 455 | ], 456 | "source": [ 457 | "999//1000" 458 | ] 459 | }, 460 | { 461 | "cell_type": "markdown", 462 | "metadata": {}, 463 | "source": [ 464 | "Fortunately, in Python 3 you won't do this by accident. With that said, the idea that you want to have integer division for integers is not a bad idea. We will see very soon that there are situations where it only makes sense to use an integer and so it is essential that it knows 4/2 is an integer and not a float (for example). " 465 | ] 466 | }, 467 | { 468 | "cell_type": "markdown", 469 | "metadata": {}, 470 | "source": [ 471 | "We can also force on type to become another type " 472 | ] 473 | }, 474 | { 475 | "cell_type": "code", 476 | "execution_count": 21, 477 | "metadata": {}, 478 | "outputs": [ 479 | { 480 | "name": "stdout", 481 | "output_type": "stream", 482 | "text": [ 483 | "5.0\n", 484 | "4.0\n", 485 | "4\n" 486 | ] 487 | } 488 | ], 489 | "source": [ 490 | "print(a+float(b))\n", 491 | "print(a+float(f)) # remember f is a string that happens to be a number\n", 492 | "print(a+int(f))" 493 | ] 494 | }, 495 | { 496 | "cell_type": "markdown", 497 | "metadata": {}, 498 | "source": [ 499 | "Of course it can't work miracles" 500 | ] 501 | }, 502 | { 503 | "cell_type": "code", 504 | "execution_count": 22, 505 | "metadata": {}, 506 | "outputs": [ 507 | { 508 | "ename": "ValueError", 509 | "evalue": "could not convert string to float: 'hi'", 510 | "output_type": "error", 511 | "traceback": [ 512 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 513 | "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", 514 | "\u001b[0;32m/var/folders/vh/rcz751b57355h3qzj37sc3080000gp/T/ipykernel_1213/1428804385.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mg\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# g='hi' can't become a float\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 515 | "\u001b[0;31mValueError\u001b[0m: could not convert string to float: 'hi'" 516 | ] 517 | } 518 | ], 519 | "source": [ 520 | "float(g) # g='hi' can't become a float" 521 | ] 522 | }, 523 | { 524 | "cell_type": "markdown", 525 | "metadata": {}, 526 | "source": [ 527 | "Now, when you mix floats and integers you always get float out:" 528 | ] 529 | }, 530 | { 531 | "cell_type": "code", 532 | "execution_count": 23, 533 | "metadata": {}, 534 | "outputs": [ 535 | { 536 | "name": "stdout", 537 | "output_type": "stream", 538 | "text": [ 539 | "0.6666666666666666\n", 540 | "5.0\n", 541 | "-1.0\n", 542 | "6.0\n", 543 | "0.4\n" 544 | ] 545 | } 546 | ], 547 | "source": [ 548 | "print(a/d)\n", 549 | "print(a+d)\n", 550 | "print(a-d)\n", 551 | "print(a*d)\n", 552 | "print(a/(c+b))" 553 | ] 554 | }, 555 | { 556 | "cell_type": "markdown", 557 | "metadata": {}, 558 | "source": [ 559 | "I have taken it as self evident what a string (word) and an integer are. This is probably a good time to pause and ask, what is a floating point number? From the looks of it, it is some kind of number with decimals. Of course, in math a decimal can go on forever. Our computer, as a default, does not give unlimited space to store numbers. \n", 560 | "\n", 561 | "Let me prove to you that for a float, the computer is only storing some of the digits:" 562 | ] 563 | }, 564 | { 565 | "cell_type": "code", 566 | "execution_count": 26, 567 | "metadata": {}, 568 | "outputs": [], 569 | "source": [ 570 | "x=12.+0.0000000000000000000001" 571 | ] 572 | }, 573 | { 574 | "cell_type": "code", 575 | "execution_count": 27, 576 | "metadata": {}, 577 | "outputs": [ 578 | { 579 | "data": { 580 | "text/plain": [ 581 | "0.0" 582 | ] 583 | }, 584 | "execution_count": 27, 585 | "metadata": {}, 586 | "output_type": "execute_result" 587 | } 588 | ], 589 | "source": [ 590 | "(x-12.)*100000000000000000000000000000" 591 | ] 592 | }, 593 | { 594 | "cell_type": "markdown", 595 | "metadata": {}, 596 | "source": [ 597 | "But a floating point number can remember small numbers " 598 | ] 599 | }, 600 | { 601 | "cell_type": "code", 602 | "execution_count": 28, 603 | "metadata": {}, 604 | "outputs": [ 605 | { 606 | "data": { 607 | "text/plain": [ 608 | "1e-33" 609 | ] 610 | }, 611 | "execution_count": 28, 612 | "metadata": {}, 613 | "output_type": "execute_result" 614 | } 615 | ], 616 | "source": [ 617 | "0.000000000000000000000000000000001" 618 | ] 619 | }, 620 | { 621 | "cell_type": "code", 622 | "execution_count": 29, 623 | "metadata": {}, 624 | "outputs": [ 625 | { 626 | "data": { 627 | "text/plain": [ 628 | "100000.0" 629 | ] 630 | }, 631 | "execution_count": 29, 632 | "metadata": {}, 633 | "output_type": "execute_result" 634 | } 635 | ], 636 | "source": [ 637 | "0.000000000000000000000000000000001*100000000000000000000000000000000000000" 638 | ] 639 | }, 640 | { 641 | "cell_type": "markdown", 642 | "metadata": {}, 643 | "source": [ 644 | "Clearly the problem is not the size of the number but how many decimal places. We can figure this out for ourselves" 645 | ] 646 | }, 647 | { 648 | "cell_type": "code", 649 | "execution_count": 30, 650 | "metadata": {}, 651 | "outputs": [ 652 | { 653 | "data": { 654 | "text/plain": [ 655 | "111022.30246251565" 656 | ] 657 | }, 658 | "execution_count": 30, 659 | "metadata": {}, 660 | "output_type": "execute_result" 661 | } 662 | ], 663 | "source": [ 664 | "x=1.+0.000000000000001\n", 665 | "(x-1.)*100000000000000000000" 666 | ] 667 | }, 668 | { 669 | "cell_type": "code", 670 | "execution_count": 31, 671 | "metadata": {}, 672 | "outputs": [ 673 | { 674 | "data": { 675 | "text/plain": [ 676 | "0.0" 677 | ] 678 | }, 679 | "execution_count": 31, 680 | "metadata": {}, 681 | "output_type": "execute_result" 682 | } 683 | ], 684 | "source": [ 685 | "x=1.+0.0000000000000001\n", 686 | "(x-1.)*1000000000000000000000000" 687 | ] 688 | }, 689 | { 690 | "cell_type": "markdown", 691 | "metadata": {}, 692 | "source": [ 693 | "By my count, this fails when I move it to the 16th decimal place. Since the leading number is 1 that means a float is carrying 16 digits, and when I move the number to the 17th digit, it effectively vanishes. This correct: a float is bascially a 16 digit number in scientific notation (i.e. we store 16 digits times a power of 10)." 694 | ] 695 | }, 696 | { 697 | "cell_type": "code", 698 | "execution_count": 35, 699 | "metadata": {}, 700 | "outputs": [ 701 | { 702 | "data": { 703 | "text/plain": [ 704 | "1323488980084844.2" 705 | ] 706 | }, 707 | "execution_count": 35, 708 | "metadata": {}, 709 | "output_type": "execute_result" 710 | } 711 | ], 712 | "source": [ 713 | "x=.0000001+0.00000000000000000000001\n", 714 | "(x-0.0000001)*100000000000000000000000000000000000000" 715 | ] 716 | }, 717 | { 718 | "cell_type": "code", 719 | "execution_count": 36, 720 | "metadata": {}, 721 | "outputs": [ 722 | { 723 | "data": { 724 | "text/plain": [ 725 | "0.0" 726 | ] 727 | }, 728 | "execution_count": 36, 729 | "metadata": {}, 730 | "output_type": "execute_result" 731 | } 732 | ], 733 | "source": [ 734 | "x=.0000001+0.000000000000000000000001\n", 735 | "(x-0.0000001)*100000000000000000000000000000000000000" 736 | ] 737 | }, 738 | { 739 | "cell_type": "markdown", 740 | "metadata": {}, 741 | "source": [ 742 | "Finally, a string is like a word, math operations don't work on it except addition, which just joins the letters" 743 | ] 744 | }, 745 | { 746 | "cell_type": "code", 747 | "execution_count": 32, 748 | "metadata": {}, 749 | "outputs": [ 750 | { 751 | "data": { 752 | "text/plain": [ 753 | "'2hihello'" 754 | ] 755 | }, 756 | "execution_count": 32, 757 | "metadata": {}, 758 | "output_type": "execute_result" 759 | } 760 | ], 761 | "source": [ 762 | "f+g+h" 763 | ] 764 | }, 765 | { 766 | "cell_type": "code", 767 | "execution_count": 33, 768 | "metadata": {}, 769 | "outputs": [ 770 | { 771 | "data": { 772 | "text/plain": [ 773 | "'2hi'" 774 | ] 775 | }, 776 | "execution_count": 33, 777 | "metadata": {}, 778 | "output_type": "execute_result" 779 | } 780 | ], 781 | "source": [ 782 | "str(a)+g" 783 | ] 784 | }, 785 | { 786 | "cell_type": "code", 787 | "execution_count": 34, 788 | "metadata": {}, 789 | "outputs": [ 790 | { 791 | "ename": "TypeError", 792 | "evalue": "unsupported operand type(s) for /: 'int' and 'str'", 793 | "output_type": "error", 794 | "traceback": [ 795 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 796 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 797 | "\u001b[0;32m/var/folders/vh/rcz751b57355h3qzj37sc3080000gp/T/ipykernel_1213/3232785189.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 798 | "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for /: 'int' and 'str'" 799 | ] 800 | } 801 | ], 802 | "source": [ 803 | "a/f" 804 | ] 805 | }, 806 | { 807 | "cell_type": "markdown", 808 | "metadata": {}, 809 | "source": [ 810 | "Lastly, there are complex numbers, which act like two floats for the real and imaginary parts. It uses the engineering notation of j instead of i:" 811 | ] 812 | }, 813 | { 814 | "cell_type": "code", 815 | "execution_count": 35, 816 | "metadata": {}, 817 | "outputs": [], 818 | "source": [ 819 | "z=1+2j" 820 | ] 821 | }, 822 | { 823 | "cell_type": "code", 824 | "execution_count": 36, 825 | "metadata": {}, 826 | "outputs": [ 827 | { 828 | "data": { 829 | "text/plain": [ 830 | "(0.3333333333333333+0.6666666666666666j)" 831 | ] 832 | }, 833 | "execution_count": 36, 834 | "metadata": {}, 835 | "output_type": "execute_result" 836 | } 837 | ], 838 | "source": [ 839 | "z/3" 840 | ] 841 | }, 842 | { 843 | "cell_type": "markdown", 844 | "metadata": {}, 845 | "source": [ 846 | "It this bothers you, you can also define them by" 847 | ] 848 | }, 849 | { 850 | "cell_type": "code", 851 | "execution_count": 37, 852 | "metadata": {}, 853 | "outputs": [], 854 | "source": [ 855 | "zz=complex(1,2)" 856 | ] 857 | }, 858 | { 859 | "cell_type": "code", 860 | "execution_count": 38, 861 | "metadata": {}, 862 | "outputs": [ 863 | { 864 | "data": { 865 | "text/plain": [ 866 | "(1+0j)" 867 | ] 868 | }, 869 | "execution_count": 38, 870 | "metadata": {}, 871 | "output_type": "execute_result" 872 | } 873 | ], 874 | "source": [ 875 | "z/zz" 876 | ] 877 | }, 878 | { 879 | "cell_type": "markdown", 880 | "metadata": {}, 881 | "source": [ 882 | "## Lists, Tuples and Dictionaries" 883 | ] 884 | }, 885 | { 886 | "cell_type": "markdown", 887 | "metadata": {}, 888 | "source": [ 889 | "In a large number of situations, we will want more than just a single number, word, etc but collections of pieces of information (data) organized in various ways. The basic structures in python are lists, tuples and dictionaries." 890 | ] 891 | }, 892 | { 893 | "cell_type": "markdown", 894 | "metadata": {}, 895 | "source": [ 896 | "### Lists" 897 | ] 898 | }, 899 | { 900 | "cell_type": "markdown", 901 | "metadata": {}, 902 | "source": [ 903 | "A list of is an ordered group of objects. They can really be anything. " 904 | ] 905 | }, 906 | { 907 | "cell_type": "code", 908 | "execution_count": 40, 909 | "metadata": {}, 910 | "outputs": [], 911 | "source": [ 912 | "list1=[1,2,3,'hi',4,5,6,7]" 913 | ] 914 | }, 915 | { 916 | "cell_type": "markdown", 917 | "metadata": {}, 918 | "source": [ 919 | "Now it is generally a good idea to make your lists out of a single common data type." 920 | ] 921 | }, 922 | { 923 | "cell_type": "markdown", 924 | "metadata": {}, 925 | "source": [ 926 | "Now we reach the point where we have to talk about how python organizes lists, which is somethign that drives may people crazy. You can isolate a signel element using square brackes:" 927 | ] 928 | }, 929 | { 930 | "cell_type": "code", 931 | "execution_count": 42, 932 | "metadata": {}, 933 | "outputs": [ 934 | { 935 | "name": "stdout", 936 | "output_type": "stream", 937 | "text": [ 938 | "1 hi\n" 939 | ] 940 | } 941 | ], 942 | "source": [ 943 | "print(list1[0],list1[3])" 944 | ] 945 | }, 946 | { 947 | "cell_type": "markdown", 948 | "metadata": {}, 949 | "source": [ 950 | "Notice that the entry is counted starting at 0. I.e. the nth entry is listed by list1[n-1]. This takes some getting used to. You can also run through the elements of a list as follows" 951 | ] 952 | }, 953 | { 954 | "cell_type": "code", 955 | "execution_count": 43, 956 | "metadata": {}, 957 | "outputs": [ 958 | { 959 | "name": "stdout", 960 | "output_type": "stream", 961 | "text": [ 962 | "1\n", 963 | "2\n", 964 | "3\n", 965 | "hi\n", 966 | "4\n", 967 | "5\n", 968 | "6\n", 969 | "7\n" 970 | ] 971 | } 972 | ], 973 | "source": [ 974 | "for item in list1:\n", 975 | " print(item) # notice that the stuff inside the loop is indented with a tab" 976 | ] 977 | }, 978 | { 979 | "cell_type": "markdown", 980 | "metadata": {}, 981 | "source": [ 982 | "This is our first encounter with the \"for loop\" and the indented structure. Python understands order of operations by the formating. Notice that there is a tab/indent for the thing we want to do as it runs through elements of the list. We can nest loops inside of each other too" 983 | ] 984 | }, 985 | { 986 | "cell_type": "code", 987 | "execution_count": 44, 988 | "metadata": {}, 989 | "outputs": [ 990 | { 991 | "name": "stdout", 992 | "output_type": "stream", 993 | "text": [ 994 | "item 1 and 2: 1 1\n", 995 | "item 1 and 2: 1 b\n", 996 | "item 1 and 2: 1 3\n", 997 | "item 1: 1\n", 998 | "item 1 and 2: b 1\n", 999 | "item 1 and 2: b b\n", 1000 | "item 1 and 2: b 3\n", 1001 | "item 1: b\n", 1002 | "item 1 and 2: 3 1\n", 1003 | "item 1 and 2: 3 b\n", 1004 | "item 1 and 2: 3 3\n", 1005 | "item 1: 3\n", 1006 | "all done\n" 1007 | ] 1008 | } 1009 | ], 1010 | "source": [ 1011 | "list2=[1,'b',3]\n", 1012 | "for item1 in list2:\n", 1013 | " for item2 in list2: # notice the tap\n", 1014 | " print('item 1 and 2: '+str(item1)+' '+str(item2))\n", 1015 | " print('item 1: '+str(item1)) \n", 1016 | "print('all done')" 1017 | ] 1018 | }, 1019 | { 1020 | "cell_type": "markdown", 1021 | "metadata": {}, 1022 | "source": [ 1023 | "You can pick out some of the elements in a list a few different ways. You can pick a range you want" 1024 | ] 1025 | }, 1026 | { 1027 | "cell_type": "code", 1028 | "execution_count": 47, 1029 | "metadata": {}, 1030 | "outputs": [ 1031 | { 1032 | "name": "stdout", 1033 | "output_type": "stream", 1034 | "text": [ 1035 | "[3, 'hi', 4] 5\n" 1036 | ] 1037 | } 1038 | ], 1039 | "source": [ 1040 | "print(list1[2:5],list1[5]) # notice that is starts at list1[2] but ends without including list[5]" 1041 | ] 1042 | }, 1043 | { 1044 | "cell_type": "markdown", 1045 | "metadata": {}, 1046 | "source": [ 1047 | "We notice also that lis1[2:5] returns the output as a new list. I.e. only when we isolate a single element does it return it as something other than a list." 1048 | ] 1049 | }, 1050 | { 1051 | "cell_type": "markdown", 1052 | "metadata": {}, 1053 | "source": [ 1054 | "You can also go from the beginning to a given number or a given point to then end" 1055 | ] 1056 | }, 1057 | { 1058 | "cell_type": "code", 1059 | "execution_count": 48, 1060 | "metadata": {}, 1061 | "outputs": [ 1062 | { 1063 | "name": "stdout", 1064 | "output_type": "stream", 1065 | "text": [ 1066 | "[1, 2, 3, 'hi', 4]\n", 1067 | "['hi', 4, 5, 6, 7]\n" 1068 | ] 1069 | } 1070 | ], 1071 | "source": [ 1072 | "print(list1[:5])\n", 1073 | "print(list1[3:])" 1074 | ] 1075 | }, 1076 | { 1077 | "cell_type": "markdown", 1078 | "metadata": {}, 1079 | "source": [ 1080 | "We can also pick every nth elements using :: " 1081 | ] 1082 | }, 1083 | { 1084 | "cell_type": "code", 1085 | "execution_count": 98, 1086 | "metadata": {}, 1087 | "outputs": [ 1088 | { 1089 | "name": "stdout", 1090 | "output_type": "stream", 1091 | "text": [ 1092 | "[1, 3, 4, 6]\n", 1093 | "[1, 'hi', 6]\n", 1094 | "[3, 5]\n" 1095 | ] 1096 | } 1097 | ], 1098 | "source": [ 1099 | "print(list1[::2])\n", 1100 | "print(list1[::3])\n", 1101 | "print(list1[2::3])" 1102 | ] 1103 | }, 1104 | { 1105 | "cell_type": "markdown", 1106 | "metadata": {}, 1107 | "source": [ 1108 | "You can also count from the end using negative numbers" 1109 | ] 1110 | }, 1111 | { 1112 | "cell_type": "code", 1113 | "execution_count": 49, 1114 | "metadata": {}, 1115 | "outputs": [ 1116 | { 1117 | "name": "stdout", 1118 | "output_type": "stream", 1119 | "text": [ 1120 | "7\n", 1121 | "6\n", 1122 | "[3, 'hi', 4, 5]\n" 1123 | ] 1124 | } 1125 | ], 1126 | "source": [ 1127 | "print(list1[-1])\n", 1128 | "print(list1[-2])\n", 1129 | "print(list1[2:-2])" 1130 | ] 1131 | }, 1132 | { 1133 | "cell_type": "markdown", 1134 | "metadata": {}, 1135 | "source": [ 1136 | "This also gives us a funny way to print a list backwards" 1137 | ] 1138 | }, 1139 | { 1140 | "cell_type": "code", 1141 | "execution_count": 50, 1142 | "metadata": {}, 1143 | "outputs": [ 1144 | { 1145 | "name": "stdout", 1146 | "output_type": "stream", 1147 | "text": [ 1148 | "[7, 6, 5, 4, 'hi', 3, 2, 1]\n", 1149 | "[7, 5, 'hi', 2]\n" 1150 | ] 1151 | } 1152 | ], 1153 | "source": [ 1154 | "print(list1[::-1])\n", 1155 | "print(list1[::-2])" 1156 | ] 1157 | }, 1158 | { 1159 | "cell_type": "markdown", 1160 | "metadata": {}, 1161 | "source": [ 1162 | "We will get to know lists and their cousins very well in this course, so this is just the starting point. One key aspect of lists is that they can be changed:" 1163 | ] 1164 | }, 1165 | { 1166 | "cell_type": "code", 1167 | "execution_count": 51, 1168 | "metadata": {}, 1169 | "outputs": [ 1170 | { 1171 | "name": "stdout", 1172 | "output_type": "stream", 1173 | "text": [ 1174 | "['k', 2, 3, 'hi', 4, 5, 6, 7]\n" 1175 | ] 1176 | } 1177 | ], 1178 | "source": [ 1179 | "list1[0]='k'\n", 1180 | "print(list1)" 1181 | ] 1182 | }, 1183 | { 1184 | "cell_type": "markdown", 1185 | "metadata": {}, 1186 | "source": [ 1187 | "Now comes the scary part of the fact that lists can change: if you make a list equal to another list, you are just telling the computer to point to the first list. This is best shown with an example:" 1188 | ] 1189 | }, 1190 | { 1191 | "cell_type": "code", 1192 | "execution_count": 52, 1193 | "metadata": {}, 1194 | "outputs": [ 1195 | { 1196 | "name": "stdout", 1197 | "output_type": "stream", 1198 | "text": [ 1199 | "['k', 2, 3, 'hi', 4, 5, 6, 7]\n" 1200 | ] 1201 | } 1202 | ], 1203 | "source": [ 1204 | "list3=list1 # make list3=list1\n", 1205 | "print(list3) # see they are equal" 1206 | ] 1207 | }, 1208 | { 1209 | "cell_type": "code", 1210 | "execution_count": 65, 1211 | "metadata": {}, 1212 | "outputs": [ 1213 | { 1214 | "name": "stdout", 1215 | "output_type": "stream", 1216 | "text": [ 1217 | "[1, 2, 3, 'hi', 4, 5, 6, 7]\n" 1218 | ] 1219 | } 1220 | ], 1221 | "source": [ 1222 | "list1[0]=1 #now change list1\n", 1223 | "print(list3) # see list3 changed too!" 1224 | ] 1225 | }, 1226 | { 1227 | "cell_type": "markdown", 1228 | "metadata": {}, 1229 | "source": [ 1230 | "If you want to save a record of list1 before you change it, you need to make a copy. One way to do this is to tell it you want the list to be equal to the elements of the list. This also shows us that if we take only a subset of elements in the list, we also won't have this pointing issue. If you are using the full list, you can also use copy:" 1231 | ] 1232 | }, 1233 | { 1234 | "cell_type": "code", 1235 | "execution_count": 66, 1236 | "metadata": {}, 1237 | "outputs": [ 1238 | { 1239 | "name": "stdout", 1240 | "output_type": "stream", 1241 | "text": [ 1242 | "[1, 2, 3, 'hi', 4, 5, 6, 7] [1, 2, 3, 'hi', 4, 5, 6, 7]\n" 1243 | ] 1244 | } 1245 | ], 1246 | "source": [ 1247 | "list4=list1[:]\n", 1248 | "list5=list1.copy()\n", 1249 | "print(list4,list5)" 1250 | ] 1251 | }, 1252 | { 1253 | "cell_type": "code", 1254 | "execution_count": 67, 1255 | "metadata": {}, 1256 | "outputs": [ 1257 | { 1258 | "name": "stdout", 1259 | "output_type": "stream", 1260 | "text": [ 1261 | "['hello', 2, 3, 'hi', 4, 5, 6, 7] [1, 2, 3, 'hi', 4, 5, 6, 7] [1, 2, 3, 'hi', 4, 5, 6, 7]\n" 1262 | ] 1263 | } 1264 | ], 1265 | "source": [ 1266 | "list1[0]='hello'\n", 1267 | "print(list1,list4,list5)" 1268 | ] 1269 | }, 1270 | { 1271 | "cell_type": "markdown", 1272 | "metadata": {}, 1273 | "source": [ 1274 | "You can combine lists using addition, so that" 1275 | ] 1276 | }, 1277 | { 1278 | "cell_type": "code", 1279 | "execution_count": 68, 1280 | "metadata": {}, 1281 | "outputs": [ 1282 | { 1283 | "data": { 1284 | "text/plain": [ 1285 | "[1, 2, 3, 'hi', 4, 5, 6, 7, 8, 9, 10]" 1286 | ] 1287 | }, 1288 | "execution_count": 68, 1289 | "metadata": {}, 1290 | "output_type": "execute_result" 1291 | } 1292 | ], 1293 | "source": [ 1294 | "list4+[8,9,10]" 1295 | ] 1296 | }, 1297 | { 1298 | "cell_type": "markdown", 1299 | "metadata": {}, 1300 | "source": [ 1301 | "This does not change list4, it just output the combined list. If you want to keep this list you need to give it a new name." 1302 | ] 1303 | }, 1304 | { 1305 | "cell_type": "markdown", 1306 | "metadata": {}, 1307 | "source": [ 1308 | "You might have a number or string you want to add to a list without making a new list, in which case append is more useful " 1309 | ] 1310 | }, 1311 | { 1312 | "cell_type": "code", 1313 | "execution_count": 70, 1314 | "metadata": {}, 1315 | "outputs": [ 1316 | { 1317 | "name": "stdout", 1318 | "output_type": "stream", 1319 | "text": [ 1320 | "[1, 2, 3, 'hi', 4, 5, 6, 7, 11]\n" 1321 | ] 1322 | } 1323 | ], 1324 | "source": [ 1325 | "list4.append(11)\n", 1326 | "print(list4)" 1327 | ] 1328 | }, 1329 | { 1330 | "cell_type": "markdown", 1331 | "metadata": {}, 1332 | "source": [ 1333 | "We can also remove entries in the list as follows:" 1334 | ] 1335 | }, 1336 | { 1337 | "cell_type": "code", 1338 | "execution_count": 71, 1339 | "metadata": { 1340 | "scrolled": true 1341 | }, 1342 | "outputs": [ 1343 | { 1344 | "name": "stdout", 1345 | "output_type": "stream", 1346 | "text": [ 1347 | "['hello', 2, 3, 'hi', 4, 5, 6, 7]\n", 1348 | "['hello', 2, 3, 4, 5, 6, 7]\n" 1349 | ] 1350 | } 1351 | ], 1352 | "source": [ 1353 | "print(list1)\n", 1354 | "del list1[3]\n", 1355 | "print(list1)" 1356 | ] 1357 | }, 1358 | { 1359 | "cell_type": "markdown", 1360 | "metadata": {}, 1361 | "source": [ 1362 | "There are lots of other useful tools we have. For example, you might like to know the length of a list, it largest or smallest values, etc." 1363 | ] 1364 | }, 1365 | { 1366 | "cell_type": "code", 1367 | "execution_count": 72, 1368 | "metadata": {}, 1369 | "outputs": [ 1370 | { 1371 | "name": "stdout", 1372 | "output_type": "stream", 1373 | "text": [ 1374 | "9 1 11\n" 1375 | ] 1376 | } 1377 | ], 1378 | "source": [ 1379 | "print(len(list4),min([2,5,1,11]),max([2,5,1,11]))" 1380 | ] 1381 | }, 1382 | { 1383 | "cell_type": "markdown", 1384 | "metadata": {}, 1385 | "source": [ 1386 | "The elements of a list can be lists themselves. When we start using some of pythons mode powerful computational tools, this structure will we be very important." 1387 | ] 1388 | }, 1389 | { 1390 | "cell_type": "code", 1391 | "execution_count": 88, 1392 | "metadata": {}, 1393 | "outputs": [], 1394 | "source": [ 1395 | "listarray=[[1,2],[3,4]]" 1396 | ] 1397 | }, 1398 | { 1399 | "cell_type": "code", 1400 | "execution_count": 89, 1401 | "metadata": {}, 1402 | "outputs": [ 1403 | { 1404 | "data": { 1405 | "text/plain": [ 1406 | "[3, 4]" 1407 | ] 1408 | }, 1409 | "execution_count": 89, 1410 | "metadata": {}, 1411 | "output_type": "execute_result" 1412 | } 1413 | ], 1414 | "source": [ 1415 | "listarray[1]" 1416 | ] 1417 | }, 1418 | { 1419 | "cell_type": "code", 1420 | "execution_count": 91, 1421 | "metadata": {}, 1422 | "outputs": [ 1423 | { 1424 | "data": { 1425 | "text/plain": [ 1426 | "4" 1427 | ] 1428 | }, 1429 | "execution_count": 91, 1430 | "metadata": {}, 1431 | "output_type": "execute_result" 1432 | } 1433 | ], 1434 | "source": [ 1435 | "listarray[1][1]" 1436 | ] 1437 | }, 1438 | { 1439 | "cell_type": "markdown", 1440 | "metadata": {}, 1441 | "source": [ 1442 | "Might like this to work like a matrix, but we will have to way for numpy array for that. I.e. lists don't treat columns and rows in the same way" 1443 | ] 1444 | }, 1445 | { 1446 | "cell_type": "code", 1447 | "execution_count": 101, 1448 | "metadata": {}, 1449 | "outputs": [ 1450 | { 1451 | "name": "stdout", 1452 | "output_type": "stream", 1453 | "text": [ 1454 | "[1, 2] [1, 2]\n" 1455 | ] 1456 | } 1457 | ], 1458 | "source": [ 1459 | "print(listarray[0][:],listarray[:][0])" 1460 | ] 1461 | }, 1462 | { 1463 | "cell_type": "markdown", 1464 | "metadata": {}, 1465 | "source": [ 1466 | "### Tuple" 1467 | ] 1468 | }, 1469 | { 1470 | "cell_type": "markdown", 1471 | "metadata": {}, 1472 | "source": [ 1473 | "Now we come to the tuple. This is very much like a list but we used () instead of []" 1474 | ] 1475 | }, 1476 | { 1477 | "cell_type": "code", 1478 | "execution_count": 102, 1479 | "metadata": {}, 1480 | "outputs": [], 1481 | "source": [ 1482 | "tuple1=(1,2,3,'hi')" 1483 | ] 1484 | }, 1485 | { 1486 | "cell_type": "code", 1487 | "execution_count": 103, 1488 | "metadata": {}, 1489 | "outputs": [ 1490 | { 1491 | "name": "stdout", 1492 | "output_type": "stream", 1493 | "text": [ 1494 | "1\n", 1495 | "(1, 3)\n" 1496 | ] 1497 | } 1498 | ], 1499 | "source": [ 1500 | "print(tuple1[0])\n", 1501 | "print(tuple1[::2])" 1502 | ] 1503 | }, 1504 | { 1505 | "cell_type": "markdown", 1506 | "metadata": {}, 1507 | "source": [ 1508 | "But the key difference is that you can't change the individual entries" 1509 | ] 1510 | }, 1511 | { 1512 | "cell_type": "code", 1513 | "execution_count": 104, 1514 | "metadata": {}, 1515 | "outputs": [ 1516 | { 1517 | "ename": "TypeError", 1518 | "evalue": "'tuple' object does not support item assignment", 1519 | "output_type": "error", 1520 | "traceback": [ 1521 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 1522 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 1523 | "\u001b[0;32m/var/folders/vh/rcz751b57355h3qzj37sc3080000gp/T/ipykernel_1213/1154119841.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mtuple1\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 1524 | "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" 1525 | ] 1526 | } 1527 | ], 1528 | "source": [ 1529 | "tuple1[0]=5" 1530 | ] 1531 | }, 1532 | { 1533 | "cell_type": "markdown", 1534 | "metadata": {}, 1535 | "source": [ 1536 | "The tuple is useful for the reason I mentioned above with lists - it is scary that you might accidently change the values in your list in the middle of your code. The tuple has some inherent value just from the fact that you can't accidently erase your data. " 1537 | ] 1538 | }, 1539 | { 1540 | "cell_type": "markdown", 1541 | "metadata": {}, 1542 | "source": [ 1543 | "Finally, we come to dictionaries. These are interesting objects because want to organize information by name. There are a few ways to define a dictionary:" 1544 | ] 1545 | }, 1546 | { 1547 | "cell_type": "code", 1548 | "execution_count": 105, 1549 | "metadata": {}, 1550 | "outputs": [], 1551 | "source": [ 1552 | "dict1={'bob': 12,'alice': 2}" 1553 | ] 1554 | }, 1555 | { 1556 | "cell_type": "code", 1557 | "execution_count": 106, 1558 | "metadata": {}, 1559 | "outputs": [], 1560 | "source": [ 1561 | "dict2={}\n", 1562 | "dict2['bob']=[1,2,3]\n", 1563 | "dict2['alice']=[4,5,6]" 1564 | ] 1565 | }, 1566 | { 1567 | "cell_type": "code", 1568 | "execution_count": 107, 1569 | "metadata": {}, 1570 | "outputs": [ 1571 | { 1572 | "data": { 1573 | "text/plain": [ 1574 | "{'bob': [1, 2, 3], 'alice': [4, 5, 6]}" 1575 | ] 1576 | }, 1577 | "execution_count": 107, 1578 | "metadata": {}, 1579 | "output_type": "execute_result" 1580 | } 1581 | ], 1582 | "source": [ 1583 | "dict2" 1584 | ] 1585 | }, 1586 | { 1587 | "cell_type": "markdown", 1588 | "metadata": {}, 1589 | "source": [ 1590 | "The list of names are called the keys, and we can recover them by " 1591 | ] 1592 | }, 1593 | { 1594 | "cell_type": "code", 1595 | "execution_count": 108, 1596 | "metadata": {}, 1597 | "outputs": [ 1598 | { 1599 | "data": { 1600 | "text/plain": [ 1601 | "dict_keys(['bob', 'alice'])" 1602 | ] 1603 | }, 1604 | "execution_count": 108, 1605 | "metadata": {}, 1606 | "output_type": "execute_result" 1607 | } 1608 | ], 1609 | "source": [ 1610 | "dict2.keys()" 1611 | ] 1612 | }, 1613 | { 1614 | "cell_type": "markdown", 1615 | "metadata": {}, 1616 | "source": [ 1617 | "This is a very helpful tool when you get to large data sets. Some programs will output data in the form of a dictionary with a huge numbers of keys. Being able to make a list of just the keys quickly and easily is a suprisingly useful tool." 1618 | ] 1619 | }, 1620 | { 1621 | "cell_type": "markdown", 1622 | "metadata": {}, 1623 | "source": [ 1624 | "Every entry in a dictionary can be a unique type of data. It is just a way of grouping things together:" 1625 | ] 1626 | }, 1627 | { 1628 | "cell_type": "code", 1629 | "execution_count": 109, 1630 | "metadata": {}, 1631 | "outputs": [], 1632 | "source": [ 1633 | "dict3={'bob': [1,2,3], 'alice':'my name is alice','number':41}" 1634 | ] 1635 | }, 1636 | { 1637 | "cell_type": "code", 1638 | "execution_count": 110, 1639 | "metadata": {}, 1640 | "outputs": [ 1641 | { 1642 | "name": "stdout", 1643 | "output_type": "stream", 1644 | "text": [ 1645 | "[1, 2, 3]\n", 1646 | "my name is alice\n", 1647 | "41\n" 1648 | ] 1649 | } 1650 | ], 1651 | "source": [ 1652 | "for key in dict3.keys():\n", 1653 | " print(dict3[key])" 1654 | ] 1655 | }, 1656 | { 1657 | "cell_type": "markdown", 1658 | "metadata": {}, 1659 | "source": [ 1660 | "### Summary" 1661 | ] 1662 | }, 1663 | { 1664 | "cell_type": "markdown", 1665 | "metadata": {}, 1666 | "source": [ 1667 | "We introduced the basic objects that python employs to read in and output information. We also saw the most basic mathematical operations and how they work on these different objects. The next step is to fill out the set of operators so that we can start doing more exciting stuff. " 1668 | ] 1669 | } 1670 | ], 1671 | "metadata": { 1672 | "kernelspec": { 1673 | "display_name": "Python 3 (ipykernel)", 1674 | "language": "python", 1675 | "name": "python3" 1676 | }, 1677 | "language_info": { 1678 | "codemirror_mode": { 1679 | "name": "ipython", 1680 | "version": 3 1681 | }, 1682 | "file_extension": ".py", 1683 | "mimetype": "text/x-python", 1684 | "name": "python", 1685 | "nbconvert_exporter": "python", 1686 | "pygments_lexer": "ipython3", 1687 | "version": "3.9.7" 1688 | } 1689 | }, 1690 | "nbformat": 4, 1691 | "nbformat_minor": 2 1692 | } 1693 | --------------------------------------------------------------------------------