{"nbformat":4,"nbformat_minor":0,"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.5.4"},"colab":{"name":"Day1.ipynb","provenance":[],"collapsed_sections":[]}},"cells":[{"cell_type":"markdown","metadata":{"id":"npyIfosog6Ry"},"source":["\n","# Introduction to Python Day 1: Basic Syntax, Variables & Arrays\n","\n","### written by Jackie Champagne (UT Austin), adapted by Hannah Hasson (U of Rochester) \n","\n","\n","Before we start: [Code of conduct](https://docs.google.com/presentation/d/1UiBbQLGCZ_8VTTufJGitjnfz2Lj12TzAPuvHLvRLMhk/edit?usp=sharing)\n","\n","\n","\n","---\n","\n"]},{"cell_type":"markdown","metadata":{"id":"M4Z5ZR2Ig6R0"},"source":["Hi there! Welcome to our brief introductory Python course for scientific coding. We will be teaching you skills ranging from the most basic tasks to some more advanced plotting techniques that will be helpful to you in research. \n","\n"," \n","\n","These Colab notebooks work the same as [**Jupyter notebooks**](https://jupyter-notebook.readthedocs.io/en/stable/), which is a code editor you can use offline. They have a mix of text cells and code cells, the latter of which you can execute by clicking the \"play\" button in the top left of the cell, or by hitting **Shift+Enter**. \n","\n"," \n","\n","**Make sure to execute all the code cells as we go through the lesson!**\n","\n"," \n","\n","The whole notebook is automatically saved periodically, but you can also save the outputs from your code as text files, plots, or images separate from the notebook. It is a great tool when you are building code from scratch and want to troubleshoot it or make a quick plot.\n","\n"," \n","\n","If you are attending this workshop live, the Questions in this notebook are meant to be a short few lines of code which you will do during the workshop. The Exercises, in a separate notebook, are longer problems you will work on after lecture, with the expectation of having all exercises finished by the end of the course. You are encouraged to work collaboratively.\n"," \n","Let's get started!\n","\n","  \n","\n","## **Importing packages**\n","\n","The first thing you'll need to do when writing any code is import the **packages** you expect to use. Packages are groups of functions and keywords for some purpose. For example, the **numpy** package has mathematical functions like $sine$ (`numpy.sin`) and constants like $\\pi$ (`numpy.pi`).\n","\n"," \n","\n","You can put your **import statement** anywhere in your code, as long as it's written before you call anything from the package. But it's cleaner to put them all at the top, so that's what we'll do.\n","\n"," \n","\n","For this tutorial, let's load up numpy and a couple other useful examples. **To run the code in a cell, click on the cell and press SHIFT+ENTER or click the play button at the top left of the cell.** To add *comments* to your code, put a hashtag `#` in front of each line of your comment. Do this to add notes explaining your code.\n","\n"," \n","\n","Some examples of imports and commenting:"]},{"cell_type":"code","metadata":{"id":"woeqobz4g6R1"},"source":["import numpy as np #'import' loads up the package. \n","\n","# you can use 'as' to define a shortcut so you don't need to type\n","# numpy before every use of the package. Most people use 'np'.\n","\n","import matplotlib.pyplot as plt\n","\n","from scipy import integrate #'from' allows you to import a specific sub-package"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"w6CuNL0c2OKT"},"source":["Now we don't have to import these packages again for the rest of our notebook! Calling a function or constant from one of your imported packages is simple. \n","\n","**function**:\n","\n"," nameofpackage.somefunction(arguments,go,here)\n","or \n","\n","**constant**:\n","\n"," nameofpackage.someconstant"]},{"cell_type":"markdown","metadata":{"id":"qSa_HuU22-MP"},"source":["Execute the example below to call the constant pi"]},{"cell_type":"code","metadata":{"id":"yomiUqLX3N3q"},"source":["np.pi #remember we renamed numpy as np"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"hGXWFPde3X0p"},"source":["If you try to use something from a package without importing it first, you will get a sassy little error message"]},{"cell_type":"code","metadata":{"id":"35pGGhZ_3wox"},"source":["pandas.read_csv(\"some_filename.pdf\")"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"IcoLHxmu30L1"},"source":[" "]},{"cell_type":"markdown","metadata":{"id":"k3ocSVXlg6R6"},"source":["## **Setting Variables**\n","\n","Variables are a way to store information that you can later access or modify. The information stored may be numbers, characters, or lists of either. Variables are typically given descriptive names to help us and others understand what our code is doing.\n","\n"," \n","\n","To define a variable, use the `=` sign. \n","\n","The variable gets assigned the value of whatever you put to the right of the equal sign. This can be a number, text, or many other data types."]},{"cell_type":"code","metadata":{"id":"oinqvfsxg6R7"},"source":["a = 1\n","b = 2"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"hBL0fZmEg6R_"},"source":["Now Python will always know that `a` is 1 in this notebook. Setting variables is useful for things like constants, such as g=9.8 (acceleration of gravity in $m/s^2$). Note that you can't start a variable name with a number!\n","\n"," \n","\n","To check that this worked, we can print it out. The syntax for printing something is `print(thing_you_want_to_print)`."]},{"cell_type":"code","metadata":{"id":"40r_UmsDg6SA"},"source":["print(a) #this prints the value of a\n","print(\"a\") #this prints the letter a"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"s-zp0w2b3Vaw"},"source":["Every new print statement goes to a new line. If you want to print multiple things together on the same line, you can just separate them by a comma in your print function."]},{"cell_type":"code","metadata":{"id":"9MZRMdidCYAq"},"source":["print(\"a equals\", a, \"and a+b is\", a+b)"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"GORBHLDtg6SE"},"source":[" \n","\n","##**Boolean logic: comparing variables**\n","\n","The double equals sign, `==`, represents the comparison operator in **boolean logic**. This refers to comparing values and seeing if a relationship is **true or false**. This will come in handy when you write code where your data must meet a certain condition. \n","\n","Remembering that we set a=1 earlier:\n"]},{"cell_type":"code","metadata":{"id":"OkCxekjkg6SF"},"source":["a == 1 #check if a is equal to 1"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"pQzU8XhHg6SI"},"source":["a == 2 #check if a is equal to 2"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"cGlLnH9zI2qP"},"source":["Do NOT confuse the single equals `=` (assign variable) with the double `==` (check if two things are equal).\n","\n","  \n","\n","We can create criteria with multiple booleans:\n","\n","\n","\n","OR statements (`or`): statement is TRUE if **either** A or B are true (or if both are true); statement is FALSE if both statements A and B are false.\n","\n","AND statements (`and`): statement is TRUE if and only if **both** A and B are true; statement is FALSE if one or both is false.\n","\n"," \n","\n","In Python, the phrase `a == 1 or 2` does not make sense. The full statement must be `a == 1 or a == 2` so that each piece of logic is separate."]},{"cell_type":"code","metadata":{"id":"kRe2Tqddg6SM"},"source":["a == 1 or a == 2 #True OR False"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"ZFIwiDd9g6SS"},"source":["a == 1 or b == 2 #True OR True"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"I5DWldVhg6SP"},"source":["a == 1 and a == 2 #True AND False"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"wuv2EReHuuXo"},"source":["a == 1 and b == 2 #True AND True"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"NTLHqWsQHZhT"},"source":["There are also other comparison operators. Here are all the basic ones you will use:\n"," \n"," == equal to\n"," != not equal to\n"," < less than\n"," <= less than or equal to\n"," > greater than\n"," >= greater than or equal to\n","\n"]},{"cell_type":"code","metadata":{"id":"JeC5ogUbssVM"},"source":["a >= 0"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"Yg-tg-DYP5ws"},"source":["a < 1"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"pXxefVT8g6SV"},"source":["## **Variable types**\n","\n","There are 3 kinds of basic variables in Python: **floats, integers, and strings**. \n","\n","  \n","\n","A floating point value (**float**) is a number with a decimal point. An **integer** is a whole number. A **string** has quotes around it and is treated as a word rather than a numeric value.\n","\n"," \n","\n","### Question 1: What kinds of variables are the following? Fill it in as a comment on each line."]},{"cell_type":"code","metadata":{"id":"SsYHX2z_g6SW"},"source":["i = 1 # type here\n","j = 2.43 #\n","k = 'Hello world!' # \n","L = 3. #\n","m = \"123456\" # "],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"D_wBDv-pt9NQ"},"source":["Notice that this next line gives you an error. Why?"]},{"cell_type":"code","metadata":{"id":"QX7tA9RLZnCr"},"source":["n = Hello world!"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"NanpfZCMg6SZ"},"source":[" \n","\n","You can **convert between variable types** if necessary, using the following commands:\n","\n"," int()\n"," float()\n"," str()\n"," \n"," \n","\n","`int()` will print the whole number value of the float and *chops off everything after the decimal*. `float()` will follow an integer with a .0, which sounds pointless but is sometimes necessary for Python arithmetic. `str()` will put quotes around it so that Python reads it literally rather than numerically.\n","\n"," \n","\n","Check out what each of these does to L (which we defined above as 3.):\n"]},{"cell_type":"code","metadata":{"id":"X5gP5geQvHlD"},"source":["print(int(L)) #make it an integer\n","print(float(L)) #it's already a float\n","print(str(L)) #make it a string"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"aN5xsfOMvErn"},"source":["\n","### Question 2: Convert `i` (defined in the previous example) to a float and to a string, assigning each to a new variable name. Convert `j` into an integer and assign it to a variable. Use `print(type(variable_name))` to check each answer."]},{"cell_type":"code","metadata":{"id":"jN_Sx3vvg6Sa"},"source":["# solution here"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"Mo0swcrvg6Sd"},"source":["### Now convert k to an integer. What happens? "]},{"cell_type":"code","metadata":{"id":"bsBOunDWg6Se"},"source":["# solution here"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"32GbnYMeQBwB"},"source":["### Finally, convert m to an integer. Then check its type with the command `type(new_variable_name)`."]},{"cell_type":"code","metadata":{"id":"sRpd8fyBQTnZ"},"source":["# solution here"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"7oWyeWG-g6Sl"},"source":[" \n","\n","## **Python arithmetic**\n","\n","The syntax for doing arithmetic is the following:\n","\n"," + add\n"," - subtract\n"," * multiply\n"," / divide\n"," ** power\n"," np.log() log-base e (natural log)\n"," np.log10() log-base 10\n"," np.exp() exponential"]},{"cell_type":"code","source":["3**2"],"metadata":{"id":"1LWJrdl6DKvV"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["8 + 9"],"metadata":{"id":"sCM6e9w5Axeq"},"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"j5OMX7tog6Sp"},"source":["i + j"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"W4RT7H-kg6Sr"},"source":["i * j"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"mcgg1ChTg6Su"},"source":["j - i"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"P3pwPBrgg6Sx"},"source":["i / j "],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"hT8yy-DeQ6DE"},"source":["Wait a minute.... where did that extra 0.0000000000000002 come from when we subtracted?? This is due to something called [**floating-point error**](https://www.geeksforgeeks.org/floating-point-error-in-python/), which happens because the computer actually converts these numbers into binary (0's and 1's) before doing the subtraction. Because some decimals are hard to represent with binary, you get little errors introduced.\n","\n"," "]},{"cell_type":"markdown","metadata":{"id":"afR8Ctt7g6S0"},"source":["## **Arrays and Lists**\n","\n","When working with data, you usually won't be dealing with just one number, but a collection of values. These collections can consist of floats, integers, strings, or a combination of them. We distinguish here two types of data structures: **lists** and **arrays**. \n","\n"," \n","\n","A list is denoted by brackets: `[ ]`, while an array must be defined with `np.array()`. The prefix \"np\" is required because `array` is a function of the `numpy` package, which we imported as `np`.\n","\n"," \n","\n","We talk about the size of 2D arrays in terms of their **dimensions**: (rows, columns). You will later reference a specific element in an array by its (row, column) coordinate in the array. This is called **indexing**.\n","\n"," \n","\n","The following is a 1D list:"]},{"cell_type":"code","metadata":{"id":"XbGSaae-g6S1"},"source":["beemovie = ['Barry B. Benson', 'Vanessa Bloome', 'Ray Liotta as Ray Liotta']\n","print(beemovie)"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"onSkxsHqg6S3"},"source":[" \n","\n","For strings, this is fine, but **you will need to use *arrays* in order to manipulate them mathematically**. The array function is built into numpy. Here are a 1D array and a 2D array:"]},{"cell_type":"code","metadata":{"id":"UxZ3EmXYg6S4"},"source":["myarray = np.array([1, 2, 3]) #1D\n","my2darray = np.array([[1, 2], [1, 2]]) #2D\n","print(myarray)\n","print(my2darray)"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"0oL9xFSdOFyC"},"source":["Recall that in the beginning we imported numpy as np, so when we call the 'array' function from numpy we write `np.array()`."]},{"cell_type":"markdown","metadata":{"id":"1ZlGLI5Wg6S7"},"source":["Notice the array function has parentheses (), and then the whole array must be enclosed in a set of brackets [ ] inside that. Within that, each row of the array should be in its own set of brackets, separated by commas.\n","\n"," \n","\n","### Question 3: Create the following 2D array and then print it:\n","\n"," 1 2 3\n"," 4 5 6"]},{"cell_type":"code","metadata":{"id":"lKh2LkoPg6S7"},"source":["#solution here"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"tvy7ACFqg6S_"},"source":["  \n","\n","## **Populating Arrays**\n","\n","You don't always have to put values into your array manually, especially if, for example, you want an array of evenly spaced numbers to apply some function to. \n","\n"," \n","\n","Here are two ways to make arrays of evenly spaced numbers:\n","\n","\n","-------\n","\n","\n","\n","The first is [`np.linspace()`](https://numpy.org/doc/stable/reference/generated/numpy.linspace.html) and the second is [`np.arange()`](https://numpy.org/doc/stable/reference/generated/numpy.arange.html). Both give you an array with numbers between two values that are linearly spaced (e.g. 2, 4, 6, 8, 10), but they do it slightly differently.\n","\n","\n"," \n"," \n","The syntax is the following:\n","\n"," np.linspace(beginning_number, end_number, number_of_points)\n"," np.arange(beginning_number, end_number, step_size)\n","\n","The `step_size` here corresponds to the difference between one point and the next in your array of values.\n","\n"," \n","\n","Typically `np.linspace` is used when you know how many datapoints you need, and `np.arange` is used when you want to jump by a certain amount between each number. This just saves you some mental math when you know only how many points you want or only the spacing.\n"," \n"," \n","\n","An important note is that `np.linspace` is an *inclusive* function, meaning that the end number you give is included in the output array. However, `np.arange` is *exclusive*, meaning the end number is not included. Keep this in mind as we move forward!\n","\n","\n"]},{"cell_type":"markdown","metadata":{"id":"ymI8ZUt9TgxS"},"source":["### Question 4: Create a `linspace` array with ten entries between 1 and 100. Create an `arange` array from 100 to 200 (with 200 included!) spaced by 10s. Print them to check :)"]},{"cell_type":"code","metadata":{"id":"ArwMCOBGg6S_"},"source":["# solution here"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"WUWG1Nqdg6TJ"},"source":["  \n","\n","Another quick way to create an array is through np.zeros. This populates an array with, well, zeros. It might sound useless at first, but it's an easy way to make an array that you will later replace with different values. It helps keep arrays at a fixed length, for instance. More on that later.\n","\n"," \n","\n","The syntax is simply number of rows, number of columns. If it's 1D, then it can just be:\n","\n"," np.zeros(3) #1x3 array of zeros\n"," \n","If it's larger than 1D, you need two sets of parentheses:\n","\n"," np.zeros((rows, columns))\n"," \n"," \n"," \n","### Question 5: Create a 3x3 array of zeros (and print it out)"]},{"cell_type":"code","metadata":{"id":"2gY7couMg6TK"},"source":["#solution here"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"qRl9OzrgaFJ8"},"source":["  \n","  \n","-------\n","#PAUSE HERE AND TAKE A BREAK!\n","-------"]},{"cell_type":"markdown","metadata":{"id":"SArwaM5Ug6TM"},"source":["  \n","\n","## **Indexing**\n","\n","An index is the position of some element in an array. Remember above we talked about using the coordinates (row, column) of an element in an array to get its value? \n","\n","###Note that **Python uses zero-based indexing!!**\n","\n","This means that the first value of an array is the 0th index. Repeating that: **the first value in an array is the zeroth index**. So the second element has index 1, the third has index 2, and so on...\n","\n"," \n","\n","To call a certain value from an array, call the array name followed by brackets containing the index of the value you want:\n","\n"," arrayname[0]\n","\n","Here is a quick example:"]},{"cell_type":"code","metadata":{"id":"NzYq0NWVW3Ac"},"source":["hi = np.array([92, 73, 85, 61])\n","hi[2] #get the 3rd element of the array"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"h7aPPyuBW3op"},"source":["The value inside the brackets can also be a variable, so long as the variable is an **integer**. You can't have the 1.5th element of a list.\n","\n","To index a 2D array, you would give the row and column indices:\n","\n"," arrayname[0,0] # again in row, col notation\n"," \n","For example:\n","\n"]},{"cell_type":"code","metadata":{"id":"T-hveUhGYJfj"},"source":["hello = np.array([[\"who\", \"what\", \"when\"], \n"," [\"where\", \"why\", \"how\"]])\n","\n","hello[1,2] #get the element in the 2nd row & 3rd column"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"KP-EvxC2YI_i"},"source":[" \n","\n","A helpful shortcut is that you can also count backwards in your array with a negative sign, so **the last value in your array is always array[-1]**."]},{"cell_type":"markdown","metadata":{"id":"BINNJT38TU3Y"},"source":["###Question 6: Print out the first and last value in your linspace array.\n","\n"]},{"cell_type":"code","metadata":{"id":"ygJAGuvfg6TN"},"source":["#solution here"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"ous553lZg6TP"},"source":["  \n","###**Slicing arrays**\n","\n","Finally, you can also grab **slices** of arrays between certain index values. This is helpful if you want to plot only a small subsample of your data, for example.\n","\n"," \n","\n","For slicing, use a colon. Syntax:\n","\n"," :x - from beginning to index x\n"," x: - from index x until the end\n"," a:b - from index a to b\n"," a:b:c - every c'th entry between indices a and b\n"," \n","These can be combined, e.g. a::c goes from index a until the end in steps of c.\n","\n"," \n","\n","Slicing is *exclusive*, so the last index of a range isn't included. For example, if you want to take index two through six of an array you should do:\n","\n"," array[2:7]\n","\n","You can also slice a 2D matrix, which just has two slicing arguments:\n","\n"," array_2D[3:10,4:30]\n","\n"," \n","\n","### Question 7: Print out the following: \n","###a) your linspace array through (including) index 5; \n","###b) your arange array beginning at index 1; \n","###c) your linspace array for indices 4 through 8; and \n","###d) your full arange array in steps of 2 indices."]},{"cell_type":"code","metadata":{"id":"3g5_AJLSg6TP"},"source":["#solution here"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"MyHdzXzkg6TU"},"source":["  \n","\n","## **Array Manipulation and Attributes**\n","\n","You can manipulate all elements of an array with one statement. Check it out:\n","\n","### Question 8: Create a new array which is your `arange` array divided by 2. Create another new array which is your `linspace` array + 2."]},{"cell_type":"code","metadata":{"id":"6pWCB8MHg6TV"},"source":["#solution here\n"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"EpyJiUwbg6TY"},"source":["  \n","\n","You can **add values to the end of an array** using np.append(). Use it like this:\n","\n"," np.append(array, something_appended)\n"," \n","You can even append another array, like this:\n","\n"," np.append(array, [5, 6])\n"," np.append(array1, array2)\n","\n"," \n"," \n","### Question 9: Create a new array which is another linear array from 100 to 200 and append it to your linspace array."]},{"cell_type":"code","metadata":{"id":"xEcCM2shg6TY"},"source":["#solution here"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"I_yDyWXfg6Tb"},"source":["  \n","\n","The last part of today will be showing you how to acquire different information from an array. Some of these are attributes of the array, and some of them are attributes of np itself, so you may need to look this up again in the future.\n","\n"," \n","\n","Attributes of the array means that you call this by `nameofarray.command`:\n"," \n"," ndim - prints dimensions of your array\n"," size - number of elements in n-dimensional array\n"," shape - shape given by (rows, columns)\n"," flatten() - collapses the array along one axis\n"," T - transpose the matrix\n"," reshape(x, y) - change the dimensions of the array to x, y -- the total number of elements (x*y) MUST match\n"," \n","Attributes of numpy, meaning that you call it by `np.command(nameofarray)`:\n","\n"," sum - sum all the elements in the array\n"," min - print minimum value in array\n"," max - print maximum value\n"," sort - print array in ascending order\n"," len - print number of elements along the row axis\n"," dot - matrix multiplication\n","\n","\n","###Question 10: Find the shape of your last array, and then print the sum of that array\n"," "]},{"cell_type":"code","metadata":{"id":"z6cXwWLkYHBv"},"source":["#solution here"],"execution_count":null,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"8Po6uEVmg6Tb"},"source":["  \n","\n","### You will have received a link to exercises to do at the end of each day's lesson (Exercises.ipynb). Please do the Day 1 exercises with your fellow students before the start of the next session!"]}]}