{ "cells": [ { "cell_type": "markdown", "metadata": { "lines_to_next_cell": 2 }, "source": [ "# Introduction to Python\n", "\n", "*** \n", "### Authors: \n", "- Christian Michelsen (Niels Bohr Institute)\n", "- Troels C. Petersen (Niels Bohr Institute)\n", "\n", "### Date: \n", "- 24-09-2018 (latest update)\n", "***\n", "\n", "This is a Jupyter notebook. This is a smart and easy way to run Python-code interactively in the browser. The term *interactively* means that we at any time can stop the process and see the individual outputs, change variable expressions or plot the intermediate results. This notebook is run on ERDA which means that you do not have to have Python installed on your own computer to run the files, although we recommend also having a local installation up and running. \n", "\n", "***\n", "\n", "This notebook is meant as a very basic introduction to Python. It introduces how to load packages, declare variables, print output, how to use lists, strings, numpy arrays, and different kinds of loops. Finally it also shows how to define and use functions and how to load and save files. \n", "\n", "***\n", "\n", "In the section below, we tell Python which modules it should load. " ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can now access the functionality of e.g. numpy by `np.sqrt(number)` to get the square root etc. You can see some of Numpy's mathematical functions __[here](https://docs.scipy.org/doc/numpy-1.13.0/reference/routines.math.html)__." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Variable declaration\n", "\n", "Below we show how to declare integers and floats:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# Declare an integer\n", "myint = 1" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Declare a float\n", "myfloat = 1.0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice the difference in the declaration. Be carefull of the difference. Also notice that you can add comments in Python by using `#`. \n", "One common error is if you want to compare your variables to a number: `myint == 1` Is true no matter what. `myfloat == 1.0` could be true. `myfloat` is a number with ??? digits, it could be either 0.9999999999999999999998 or 1.000000000000000001. \n", "\n", "Below some simple rules: " ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2.0" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "another_float = myint * 2.0 # int comined with float gives float\n", "another_float" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "another_int = int(myfloat + 0.5) # Rounding floats to int\n", " # When rounding, you will always get the closest int lower\n", " # than the float. Thus if you add 0.5 before rounding, you\n", " # will always get the closest int to the original float\n", "another_int" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One important operater you will use from time to time is the modulus operator `%`.\n", "`a % b` returns the remainder when deviding the integer `a` with the integer `b`. \n", "So if you wish to find out if 9312312 is divisible by 17, you can check this\n", "by asking if 93112312 % 17 is zero. More on this below.\n", "\n", "## Strings:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Of course Python can also handle letters in addition to just numbers. These are called strings. We will not go too much into depth with strings right now. " ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'This is a string'" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Strings\n", "mystring = \"This is a string\" # Use strings to store strings of letters\n", "mystring" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Printing output\n", "\n", "You can use the print statement to print the output of your script:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is an int 1\n", "This is a float 1.0\n", "This is a string\n" ] } ], "source": [ "print(\"This is an int\", myint)\n", "print(\"This is a float\", myfloat)\n", "print(mystring)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In Jupyter notebooks you can also just simply type the variable name to see its value:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "myint" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The print-method works more generally and allows us to also write a description (string) together with the variable which makes the reading of the output easier." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is an int 1 . This is a float 2.0\n" ] } ], "source": [ "print(\"This is an int\", another_int, \". This is a float\", another_float)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This way of writing quickly becomes difficult to customize to ones specific needs. Therefore Python also comes with more advances string formatting options. The newest and preferable way of writing modern Python strings are with so-called f-strings. They work in the following way:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is an int 1. This is a float 2.0\n" ] } ], "source": [ "string = f'This is an int {another_int}. This is a float {another_float}'\n", "print(string)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that Python accepts both `'` and `\"` as quotes (but you have to finish the quote with the same symbol as you started it with). \n", "First of all f-strings (named so due to the `f` before the the actual string) are easy to read since you can simply input the variable name in the string by using `{}` brackets. f-strings also allows further customization by using `:` as a string formatter: " ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is an int 1. This is a float 2.000\n" ] } ], "source": [ "string = f'This is an int {another_int:2d}. This is a float {another_float:7.3f}'\n", "print(string)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Can you see what happened here? \n", "\n", "\n", "For the integer why specify that it is a single digit using `d`. The `2d` then means that the width in the string should be 2 characters, therefore introducing the space in from of the 1. This is useful if you are counting to e.g. 15 and want the spacing to be the same (do not worry about the structure of the code here, we will return to loops below): \n" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is an int 1\n", "This is an int 2\n", "This is an int 3\n", "This is an int 4\n", "This is an int 5\n", "This is an int 6\n", "This is an int 7\n", "This is an int 8\n", "This is an int 9\n", "This is an int 10\n", "This is an int 11\n", "This is an int 12\n", "This is an int 13\n", "This is an int 14\n", "This is an int 15\n" ] } ], "source": [ "for i in range(1, 15+1):\n", " print(f'This is an int {i:2d}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Looking back at the float above we first of all use the float formatter `f`. `7.3f` then means that it should have a width of 7 spaces and 3 digits after the decimal point. It is printed as `__2.000` (where `_` should be a space). The space in front of the float in the string is then 1 because 7 (width) - 3 (the \"`000`\") - 1 (the \"`2`\") - 1 (the \"`.`\") = 1 space left. \n", "\n", "For completeness we show below the two older, and still valid, ways of writing the same expression:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is an int 1, This is a float 2.000\n", "This is an int 1, This is a float 2.000\n", "This is an int 1. This is a float 2.000\n" ] } ], "source": [ "string_percentsign = \"This is an int %2d, This is a float %7.3f\" % (another_int, another_float)\n", "string_format = \"This is an int {0:2d}, This is a float {1:7.3f}\".format(another_int, another_float)\n", "string_f = f'This is an int {another_int:2d}. This is a float {another_float:7.3f}'\n", "\n", "print(string_percentsign)\n", "print(string_format)\n", "print(string_f)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Of course you can also include line breaks and tabulate parts of a string. This is done using `\\n` for new line and `\\t`for tabulation:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "lines_to_next_cell": 2 }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Line \n", " new line starts here \t and is tabulated\n", "\n", "This is an int \t\t1. \n", "This is a float \t2.0\n" ] } ], "source": [ "print(\"Line \\n new line starts here \\t and is tabulated\") \n", "print(\"\") # Print an empty line\n", "\n", "string = f'This is an int \\t\\t{another_int}. \\nThis is a float \\t{another_float}'\n", "print(string)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that you have to write `\\nNew Text Here` and not `\\n New Text Here` unless you want to start the new line with a space. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Lists " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Often you want to store a large number of variables together, intead of having to declare them one by one. \n", "The list offers a simple way of organising these:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0.0, 0.0, 13.0, 0.0, 0.0]" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "simplelist = [0.0, 0.0, 0.0, 0.0, 0.0] # List of 5 floating point zeros\n", "simplelist[2] = 13.0 # Assign the '2' entry to 13.0.\n", "simplelist" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "NOTE: As in most modern programming languages, you count from zero, which is why it is the third element that is now 13.0 and not the second. For a short argument as to why this is, see https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html, and for a short description its history in Python, see https://python-history.blogspot.com/2013/10/why-python-uses-0-based-indexing.html. \n", "\n", "We can of course also append new numbers to the list (as lists are mutable):" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0.0, 0.0, 13.0, 0.0, 0.0, 1.0, 5.0, 3.0]" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "simplelist.append(1.0) \n", "simplelist.append(5.0)\n", "simplelist.append(3.0)\n", "simplelist" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One good thing to remember with Python lists is that they are cyclical, which means\n", "you can also access the numbers in the following way:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```Entry number: -8 -7 -6 -5 -4 -3 -2 -1 ``` \n", "```simplelist = [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 5.0, 3.0]``` " ] }, { "cell_type": "markdown", "metadata": { "lines_to_next_cell": 2 }, "source": [ "The reason this is smart is that if you use the append function and want to access the last appended value, you can use `simplelist[-1]` instead of `simplelist[len(simplelist)-1]`, where `len(list)` is the function that gives you the length of a list." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A lot of times it is cumbersome to declare each entry in the list by hand.\n", "If it is for instance necessary to store 100 numbers in your analysis, you can declare a list to contain them in the following way (if you are a Python\n", "expert you probably know 10 other ways of doing this)." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0,\n", " 0.0]" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "alotofzeros = [0.0]*100\n", "alotofzeros" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In case you want to have have a list of only numbers, you can take advantage of a \n", "Numpy array. These are more similar to Matlab lists in a lot of ways." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "numpyarray = np.array([0., 21., 10., -4., 1/5.])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Numpy arrays allow you to do the following:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 1. , 22. , 11. , -3. , 1.2])" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "numpyarray_2 = numpyarray + 1\n", "numpyarray_2" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0. , 260.4 , 124. , -49.6 , 2.48])" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "numpyarray_3 = numpyarray*12.4\n", "numpyarray_3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Numpy also has a lot of convience functions for creating specific types of arrays. For example if you want to create an array numbers from 0 to 4 (the first 5 numbers), this is called a range:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0, 1, 2, 3, 4])" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "numpyrange = np.arange(5)\n", "numpyrange" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another type of array needed could be the evenly spaced ranges from 0 to 5 in 10 intervals:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5, 5. ])" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "numpylinspace = np.linspace(0, 5, 10+1) # can you see why we need a +1 here?\n", "numpylinspace" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also initialize an empty list of zeros (or ones):" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0., 0., 0., ..., 0., 0., 0.])" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "numpyzeros = np.zeros(10000)\n", "numpyzeros" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1., 1., 1., ..., 1., 1., 1.])" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "numpyones = np.ones(10000)\n", "numpyones" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can of course print both normal Python lists and Numpy arrays:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "lines_to_next_cell": 2 }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "My simple list : [0.0, 0.0, 13.0, 0.0, 0.0, 1.0, 5.0, 3.0]\n", "Which has : 8 Entries\n", "The first entry is: 0.0\n", "The last entry is : 3.0 3.0\n", "\n", "A large list: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]\n", "\n", "A numpy array : [ 0. 21. 10. -4. 0.2]\n", "A numpy range : [0 1 2 3 4]\n", "A numpy linearly spaced range: [0. 0.5 1. 1.5 2. 2.5 3. 3.5 4. 4.5 5. ]\n", "An array of zeroes : [0. 0. 0. ... 0. 0. 0.]\n", "\n" ] } ], "source": [ "print(\"My simple list : \", simplelist) \n", "print(\"Which has : \", len(simplelist), \"Entries\")\n", "print(\"The first entry is: \", simplelist[1])\n", "print(\"The last entry is : \", simplelist[-1], simplelist[len(simplelist)-1])\n", "print(\"\") \n", "print(\"A large list: \", alotofzeros) # Not so nice output, will be adressed below.\n", "print(\"\")\n", "print(\"A numpy array :\", numpyarray) \n", "print(\"A numpy range :\", numpyrange) \n", "print(\"A numpy linearly spaced range:\", numpylinspace) \n", "print(\"An array of zeroes :\", numpyzeros) \n", "print(\"\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A great strenght of the python list is that you can store just about everything you want to\n", "in them. Say if you want to store a name and a score for some persons : " ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[['Max', 7], ['John', 12], ['Nick', -3], ['Niels', 10]]" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mixedlist = [ [\"Max\" , 7 ] , # This is a list of lists, each containing a string and an integer \n", " [\"John\" , 12] , \n", " [\"Nick\" , -3 ] ,\n", " [\"Niels\", 10] ]\n", "mixedlist" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you want to sort by score you can use the sorting function: " ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[['Nick', -3], ['Max', 7], ['Niels', 10], ['John', 12]]" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sortedlist = sorted(mixedlist, key=lambda column: column[1])\n", "sortedlist" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is a bit more advanced since, you have to tell Python that it should sort it by the 'second entry' in each list (i.e. column 1)\n", "If you only have a list with numbers `thelist = [0, -214, 35, 12, 343, 1224]`, you can simply use `sorted(thelist)` or `thelist.sort()`.\n", "\n", "If instead you wanted to sort by name and not score (i.e. the first column), you would do:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[['John', 12], ['Max', 7], ['Nick', -3], ['Niels', 10]]" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sortedlist_v2 = sorted( mixedlist, key=lambda column : column[0])\n", "sortedlist_v2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The printed output is not very nice/readable, but more on that just below!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Looping and logical statemants" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A lot of times you want to repeat a calculation with some different initial parameters\n", "which is where the loop comes in handy:" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Counting to ten: 0\n", "Counting to ten: 1\n", "Counting to ten: 2\n", "Counting to ten: 3\n", "Counting to ten: 4\n", "Counting to ten: 5\n", "Counting to ten: 6\n", "Counting to ten: 7\n", "Counting to ten: 8\n", "Counting to ten: 9\n" ] } ], "source": [ "# This is a simple loop\n", "for i in range(10) : \n", " # This is the block within the loop\n", " print(f\"Counting to ten: {i}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This will tell the intepreter that it should make a list with the numbers 0, ..., 9. \n", "For each of these numbers, it will assign `i` to the given value and perform whatever is inside the 'loop block' with that specific value of `i`. \n", "\n", "If you want to \"control\" the loop range more, options are:" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Counting from four to ten: 4\n", "Counting from four to ten: 5\n", "Counting from four to ten: 6\n", "Counting from four to ten: 7\n", "Counting from four to ten: 8\n", "Counting from four to ten: 9\n", "Counting every second number from four to ten: 4\n", "Counting every second number from four to ten: 6\n", "Counting every second number from four to ten: 8\n" ] } ], "source": [ "for i in range(4, 10): \n", " print(f\"Counting from four to ten: {i}\")\n", "for i in range(4, 10, 2):\n", " print(f\"Counting every second number from four to ten: {i}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that Python uses half-open intervals and thus does not include the end point the range. \n", "\n", "In addition to the `range` method of looping, Python also allows us to loop over a list directly:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.0\n", "0.0\n", "13.0\n", "0.0\n", "0.0\n", "1.0\n", "5.0\n", "3.0\n" ] } ], "source": [ "for val in simplelist:\n", " print(val)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In case we need both the index and the value of a list, we can use `enumerate`:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "index: 0, value: 0.0\n", "index: 1, value: 0.0\n", "index: 2, value: 13.0\n", "index: 3, value: 0.0\n", "index: 4, value: 0.0\n", "index: 5, value: 1.0\n", "index: 6, value: 5.0\n", "index: 7, value: 3.0\n" ] } ], "source": [ "for index, val in enumerate(simplelist):\n", " print(f'index: {index}, value: {val}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can now return to how you can print list more nicely:" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "lines_to_next_cell": 2 }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Name: Max \t -> \t Score: 7\n", "Name: John \t -> \t Score: 12\n", "Name: Nick \t -> \t Score: -3\n", "Name: Niels \t -> \t Score: 10\n" ] } ], "source": [ "for name, score in mixedlist :\n", " print(f'Name: {name} \\t -> \\t Score: {score:3d}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Even though `mixedlist` contains both name and score, we can still use `enumerate` to get the index:" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Counter: 0 \t Name: Max \t -> \t Score: 7\n", "Counter: 1 \t Name: John \t -> \t Score: 12\n", "Counter: 2 \t Name: Nick \t -> \t Score: -3\n", "Counter: 3 \t Name: Niels \t -> \t Score: 10\n" ] } ], "source": [ "for index, (name, score) in enumerate(mixedlist):\n", " print(f'Counter: {index} \\t Name: {name} \\t -> \\t Score: {score:3d}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## A note on programming blocks" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As is the case with programming, you will structure your code as blocks:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```\n", "statement1 : \n", " \n", " This is coding block1\n", "\n", " statement2 : \n", " \n", " This is the coding block2\n", "\n", " ...\n", " \n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that all the variables you declare in statement2 is only known in coding block2, but everything you define in statement1 is also known in statement2. \n", "Most programming languages you have probably seen incloses the statements with brackets or curly braces. In Python this is done solely by indention \n", "(The recommeded pratice is to use four __[spaces](https://www.python.org/dev/peps/pep-0008/?#tabs-or-spaces)__. This means that the interpreter knows where e.g. coding block2 is (8 spaces) and when it stops (when you are back\n", "to 4 spaces). \n", "\n", "To learn more about the Python development team's stance on braces, try to import: `from __future__ import braces`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Back to looping and logical statemants\n", "\n", "To compare values, you can use the if statement:" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The integer value is three \n" ] } ], "source": [ "anint = 3\n", "afloat = 314.0\n", "astring = \"string\"\n", "\n", "if anint == 3: \n", " print(\"The integer value is three \")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that when making boolean comparisons you use double equal signs, `==` and not single (which is used for assigment). In addition to `if` there is also `elif` (else if) and `else`:" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The float value is somewhere between 100. and 500.\n" ] } ], "source": [ "if afloat > 1000.0: \n", " print(\"The float value is greater than 1000\")\n", "elif 100.0 < afloat < 500.0: \n", " print(\"The float value is somewhere between 100. and 500.\")\n", "else: \n", " print(\"The float is neither > 1000 nor in the range [100,500]\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The negation comparison is `!=`:" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "'astring' says string\n", "'astring' does not say 'blah'\n" ] } ], "source": [ "if astring == \"string\": \n", " print(\"'astring' says\", astring)\n", "\n", "if astring != \"blah\": \n", " print(\"'astring' does not say 'blah'\") " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One very nice thing with python is that you can combine lists, for loops and if statements in an intuitive way. \n", "If you e.g. want a list containing the first 20 square numbers, you can use what is called a list comprehension: " ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sqrnumbers = [i*i for i in range(10)]\n", "sqrnumbers" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is a square number 0\n", "This is a square number 1\n", "This is a square number 4\n", "This is a square number 9\n", "This is a square number 16\n", "This is a square number 25\n", "This is a square number 36\n", "This is a square number 49\n", "This is a square number 64\n", "This is a square number 81\n" ] } ], "source": [ "for i in sqrnumbers:\n", " print(f\"This is a square number {i}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you only want the even square numbers, you can use the modulus operator (`%`):" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "lines_to_next_cell": 2 }, "outputs": [ { "data": { "text/plain": [ "[0, 4, 16, 36, 64]" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "evensqrnumbers = [i*i for i in range(10) if i%2 == 0]\n", "evensqrnumbers" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is an even square number 0\n", "This is an even square number 4\n", "This is an even square number 16\n", "This is an even square number 36\n", "This is an even square number 64\n", "\n" ] } ], "source": [ "for i in evensqrnumbers :\n", " print(f\"This is an even square number {i}\")\n", "print(\"\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another form of loop is the while statement:" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 1.570 is the first value whose tangent is greater than 1000 (1061.033) (in steps of pi/10000). \n" ] } ], "source": [ "whilevar = 0.0\n", "while (np.tan(whilevar) < 1000.0): \n", " whilevar += 3.1415926535897932385 / 10000\n", "# whilevar += np.pi / 10000\n", "\n", "print(f\"{whilevar:6.3f} is the first value whose tangent is greater than 1000 ({np.tan(whilevar):8.3f}) (in steps of pi/10000). \")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Above while loop test weather `tan(whilevar)` is less than 1000. If it is greater than 1000 it will exit the loop. \n", "In the block inside the loop it will increment `whilevar` with pi/10000 and run the test again.\n", "\n", "Notice also that you can have whole expressions in f-strings, `{np.tan(whilevar)}`. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Random numbers" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To generate some randoms numbers, we will use the numpys class random, which is both\n", "very efficient, and produces high quality random numbers (think about what that means!)." ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "lines_to_next_cell": 2 }, "outputs": [], "source": [ "# Get the object from the numpy random module\n", "r = np.random\n", "r.seed(42) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you don't set any value you get a new (series of) random number(s) every time you run. \n", "With a specified seed, you get the same (series of) random number(s). \n", "\n", "Print some random numbers uniformely distributed between 0 and 1:" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "lines_to_next_cell": 2 }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is a uniformly generated number: 0.3745401188473625\n", "This is a uniformly generated number: 0.9507143064099162\n", "This is a uniformly generated number: 0.7319939418114051\n", "This is a uniformly generated number: 0.5986584841970366\n", "This is a uniformly generated number: 0.15601864044243652\n", "This is a uniformly generated number: 0.15599452033620265\n", "This is a uniformly generated number: 0.05808361216819946\n", "This is a uniformly generated number: 0.8661761457749352\n", "This is a uniformly generated number: 0.6011150117432088\n", "This is a uniformly generated number: 0.7080725777960455\n" ] } ], "source": [ "for i in range(10): \n", " print(f\"This is a uniformly generated number: {r.uniform()}\") # Calls the uniform function" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "See the behaviour of setting a specific seed:" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is a uniformly generated number: 0.3745401188473625\n", "This is a uniformly generated number: 0.9507143064099162\n", "This is a uniformly generated number: 0.7319939418114051\n", "This is a uniformly generated number: 0.5986584841970366\n", "This is a uniformly generated number: 0.15601864044243652\n", "This is a uniformly generated number: 0.15599452033620265\n", "This is a uniformly generated number: 0.05808361216819946\n", "This is a uniformly generated number: 0.8661761457749352\n", "This is a uniformly generated number: 0.6011150117432088\n", "This is a uniformly generated number: 0.7080725777960455\n" ] } ], "source": [ "r.seed(42)\n", "for i in range(10): \n", " print(f\"This is a uniformly generated number: {r.uniform()}\") # Calls the uniform function" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create some lists/arrays containing 1000 uniformly distributed random numbers:" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0.020584494295802447, 0.9699098521619943, 0.8324426408004217, 0.21233911067827616, 0.18182496720710062, 0.18340450985343382, 0.3042422429595377, 0.5247564316322378, 0.43194501864211576, 0.2912291401980419]\n", "\n", "[0.22120944 0.98766801 0.94405934 0.03942681 0.70557517 0.92524832\n", " 0.18057535 0.56794523 0.9154883 0.03394598]\n" ] } ], "source": [ "uni_list = [r.uniform() for i in range(1000)] \n", "uni_array = r.uniform(size=1000)\n", "\n", "print(uni_list[:10])\n", "print(\"\")\n", "print(uni_array[:10])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Above we have shown how to create the random numbers in two ways. The first is by using list comprehension and is thus a normal Python list. \n", "The other is by using Numpy directly, which is both simpler to write and computationally more efficient. \n", "\n", "\n", "In addition to creating uniform numbers we can also create normally (Gaussianly) distributed random numbers:" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[-2.42424026 0.8840454 0.7368439 -0.28132756 0.06699072 0.51593922\n", " -1.56254586 -0.52905268 0.79426468 -1.25428942]\n" ] } ], "source": [ "# List with 1000 unit normally (Gaussianly) distributed random numbers:\n", "gauss_array = r.normal(0.0, 1.0, 1000)\n", "print(gauss_array[:10])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Where `0` is the mean, `1` is the standard deviation and `1000` is the number of random numbers created. \n", "\n", "Print a couple of numbers from the list:" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "lines_to_next_cell": 2 }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Uniform number 0.221 \t Gaussian number -2.424\n", "Uniform number 0.988 \t Gaussian number +0.884\n", "Uniform number 0.944 \t Gaussian number +0.737\n", "Uniform number 0.039 \t Gaussian number -0.281\n", "Uniform number 0.706 \t Gaussian number +0.067\n", "Uniform number 0.925 \t Gaussian number +0.516\n", "Uniform number 0.181 \t Gaussian number -1.563\n", "Uniform number 0.568 \t Gaussian number -0.529\n", "Uniform number 0.915 \t Gaussian number +0.794\n", "Uniform number 0.034 \t Gaussian number -1.254\n" ] } ], "source": [ "for single_uni, single_gauss in zip(uni_array[:10], gauss_array[:10]): \n", " print(f\"Uniform number {single_uni:5.3f} \\t Gaussian number {single_gauss:+5.3f}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we have introduced 2 new things:\n", "\n", "1. the `zip` operator. This allows us to loop over two (or more!) lists, arrays or anything else that can be iterated over. Here we iterate over the first 10 elements of `uni_array` and `gauss_array`. Doing it this ways allows us to not have to use index notation, `uni_array[i]` and `gauss_array[i]`, but instead using the variables `single_uni` and `single_gauss`.\n", "\n", "2. the `+` in our string formatter in the f-string. This simply shows the sign of the number (in this case a float) which make the output aling out nicely when printed. Another way of doing this would simply to use: `{single_gauss:6.3f}` which would then leave a space instead of a plus." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Functions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To define a function, use the following structure\n", "\n", "```\n", "def(input):\n", " ... \n", " function block \n", " ... \n", " return value\n", "```\n", "\n", "\n", "Normally, it is good pratice to put this in the beginning of your script, but can be done anywhere, and for the sake of readability we will just do\n", "it here in this case. \n", "\n", "Define a function that returns the square of a number:" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [], "source": [ "def sqr(a): \n", " return a**2 # or a*a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Print the square of some of your random numbers: " ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Uniform: 0.221^2 = 0.049 \t Gaussian: -2.424^2 = 5.877\n", "Uniform: 0.988^2 = 0.975 \t Gaussian: 0.884^2 = 0.782\n", "Uniform: 0.944^2 = 0.891 \t Gaussian: 0.737^2 = 0.543\n", "Uniform: 0.039^2 = 0.002 \t Gaussian: -0.281^2 = 0.079\n", "Uniform: 0.706^2 = 0.498 \t Gaussian: 0.067^2 = 0.004\n", "Uniform: 0.925^2 = 0.856 \t Gaussian: 0.516^2 = 0.266\n", "Uniform: 0.181^2 = 0.033 \t Gaussian: -1.563^2 = 2.442\n", "Uniform: 0.568^2 = 0.323 \t Gaussian: -0.529^2 = 0.280\n", "Uniform: 0.915^2 = 0.838 \t Gaussian: 0.794^2 = 0.631\n", "Uniform: 0.034^2 = 0.001 \t Gaussian: -1.254^2 = 1.573\n" ] } ], "source": [ "for single_uni, single_gauss in zip(uni_array[:10], gauss_array[:10]): \n", " print(f\"Uniform: {single_uni:5.3f}^2 = {sqr(single_uni):5.3f} \\t Gaussian: {single_gauss:6.3f}^2 = {sqr(single_gauss):5.3f}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define a more complicated function that calculates the mean and RMS of the values in a list." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Can you define it yourself?" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "lines_to_next_cell": 2 }, "outputs": [], "source": [ "def MeanAndRMS(inlist): \n", "\n", " if len(inlist) == 0: \n", " print(\"Ups, called function with an empty list. \\nIf I don't exit now, I will divide by zero when calculating the mean\")\n", " return [-9999999999.9, -99999999999.9]\n", "\n", " elif len(inlist) == 1: \n", " print(\"Ups, called function with a list of length one. \\nIf I don't exit now, I will divide by zero when calculating the RMS\")\n", " return [inlist[0], -99999999999.9]\n", "\n", " # Find the mean:\n", " mu = 0.0 # fill this out yourself\n", "\n", " # Find the standard deviation (RMS):\n", " rms = 0.0 # fill this out yourself\n", "\n", " return [mu, rms] # Return a list with two values: [mean, rms]" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [], "source": [ "# Calculate the mean and rms of the values in your two lists with random numbers :\n", "mu_sigma_uni = MeanAndRMS(uni_array)\n", "mu_sigma_gauss = MeanAndRMS(gauss_array)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Print the results. Do these values make sense?" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "lines_to_next_cell": 2 }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "For 1000 uniformely distributed numbers: mu = 0.000 rms = 0.000\n", "For 1000 Gaussianly distributed numbers: mu = 0.000 rms = 0.000\n", "Is this what you would expect? \n", "\n" ] } ], "source": [ "print(f\"For 1000 uniformely distributed numbers: mu = {mu_sigma_uni[0]:5.3f} rms = {mu_sigma_uni[1]:5.3f}\")\n", "print(f\"For 1000 Gaussianly distributed numbers: mu = {mu_sigma_gauss[0]:5.3f} rms = {mu_sigma_gauss[1]:5.3f}\")\n", "print(\"Is this what you would expect? \\n\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Writing and reading files" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Often you will have to read and write ascii files (i.e. human readable text files). \n", "We start with writing a file randomnumbers.dat containing some random numbers. \n", "\n", "First we open `randomnumbers.dat` in write mode. Note that the file is only open in the block opened by the `with ... as file` statement. \n", "Afterwards we fill the file with random numbers." ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "lines_to_next_cell": 2 }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Uniform \t Gaussian \t Poisson \t Exponential \t Power\n", " 0.6056 \t -0.3357 \t 6 \t 0.2310 \t 0.3919\n", " 0.8957 \t -0.7894 \t 7 \t 0.5435 \t 0.0181\n", " 0.7928 \t -0.0457 \t 11 \t 1.1668 \t 0.2533\n", " 0.0100 \t -0.7650 \t 12 \t 1.8086 \t 0.8214\n", " 0.8433 \t -2.0858 \t 13 \t 0.2027 \t 0.8550\n", " 0.8826 \t -0.1869 \t 10 \t 0.4907 \t 0.8035\n", " 0.9018 \t -0.2757 \t 4 \t 0.0770 \t 0.3755\n", " 0.8038 \t 0.9407 \t 11 \t 0.2486 \t 0.3505\n", " 0.3725 \t -0.1868 \t 10 \t 1.0692 \t 0.7088\n", " 0.0084 \t -0.6176 \t 7 \t 0.6616 \t 0.0053\n", " 0.8045 \t 0.2685 \t 11 \t 1.3933 \t 0.8030\n", " 0.5180 \t 1.5130 \t 6 \t 0.9688 \t 0.7423\n", " 0.1699 \t 0.1509 \t 13 \t 1.0617 \t 0.8891\n", " 0.5788 \t -0.1179 \t 11 \t 0.6423 \t 0.7164\n", " 0.2709 \t -0.6303 \t 7 \t 0.5531 \t 0.9078\n", " 0.5071 \t -1.0081 \t 7 \t 1.1912 \t 0.3828\n", " 0.8218 \t 1.1083 \t 8 \t 0.3066 \t 0.9391\n", " 0.6364 \t 0.5968 \t 8 \t 0.2119 \t 0.6946\n", " 0.2187 \t -1.5259 \t 7 \t 1.2005 \t 0.3683\n", " 0.4323 \t 0.6179 \t 7 \t 0.0398 \t 0.6668\n", " 0.3230 \t 0.6707 \t 14 \t 0.8597 \t 0.0673\n", " 0.0949 \t -0.2923 \t 12 \t 1.9521 \t 0.9976\n", " 0.2415 \t -0.0973 \t 6 \t 0.4470 \t 0.7837\n", " 0.5662 \t -0.5038 \t 8 \t 0.2640 \t 0.0144\n", " 0.7644 \t 1.3349 \t 11 \t 0.9798 \t 0.8644\n" ] } ], "source": [ "with open('randomnumbers.dat', 'w' ) as file: \n", " \n", " outline = f\"Uniform \\t Gaussian \\t Poisson \\t Exponential \\t Power \\n\" \n", " print(outline[:-2]) # do not print the '\\n'\n", " file.write(outline)\n", " \n", " for i in range(25): \n", "\n", " # Numbers distributed according to the following pdfs: uniform, gaussian, poissonian, exponential, power\n", " outline = f\"{r.uniform():9.4f} \\t {r.normal():9.4f} \\t {r.poisson(10.0):9.0f} \\t {r.exponential():9.4f} \\t {r.power(1):9.4f} \\n\"\n", " print(outline[:-2]) # do not print the '\\n'\n", " file.write(outline)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***\n", "Now we will read the same file in again. \n", "\n", "First we define lists that can contain the table of random numbers:" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [], "source": [ "uni = []\n", "gauss = []\n", "pois = []\n", "exp = []\n", "power = []" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1. We open (read) the file, skip the first line (header) with the `next` command, and then read each line. For each line the whole line in string format, but want it back in floating point format. \n", "\n", "2. Take `line` and strip it of '\\n and \\t' (i.e. newlines and tabulations) using `line.strip()`\n", "3. Split the line into a list using `strip_line.split()`\n", "4. Append each of the elements in `format_line` to the empty lists created in the cell above" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0.6056, 0.8957, 0.7928, 0.01, 0.8433, 0.8826, 0.9018, 0.8038, 0.3725, 0.0084, 0.8045, 0.518, 0.1699, 0.5788, 0.2709, 0.5071, 0.8218, 0.6364, 0.2187, 0.4323, 0.323, 0.0949, 0.2415, 0.5662, 0.7644]\n" ] } ], "source": [ "with open('randomnumbers.dat', 'r' ) as file: \n", " \n", " next(file)\n", " \n", " # Loop through each line in the file\n", " for line in file: \n", "\n", " strip_line = line.strip()\n", " format_line = strip_line.split()\n", "\n", " uni.append( float(format_line[0]) ) # Now \"uni\" gets the first number in the line.\n", " gauss.append( float(format_line[1]) ) # Now \"gauss\" gets the second numb...\n", " pois.append( float(format_line[2]) )\n", " exp.append( float(format_line[3]) )\n", " power.append( float(format_line[4]) )\n", " \n", " \n", " # alternative way using list comprehension:\n", " # format_line = [float(ientry) for ientry in iline.strip().split()]\n", " \n", "print(uni)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Again, this could have been done simpler using Numpy. Numpy provides the method `np.loadtxt`: " ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0.6056 0.8957 0.7928 0.01 0.8433 0.8826 0.9018 0.8038 0.3725 0.0084\n", " 0.8045 0.518 0.1699 0.5788 0.2709 0.5071 0.8218 0.6364 0.2187 0.4323\n", " 0.323 0.0949 0.2415 0.5662 0.7644]\n" ] } ], "source": [ "uni_np, gauss_np, pois_np, exp_np, power_np = np.loadtxt('randomnumbers.dat', unpack=True, skiprows=1)\n", "print(uni_np)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We see that we get the same output whether or not we use the Numpy version. In case you are unsure about what the keywords `unpack` and `skiprows` does, try to type: `?np.loadtxt` in the cell below here:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To check that the import fully worked, print the lines 10 to 19: " ] }, { "cell_type": "code", "execution_count": 58, "metadata": { "lines_to_next_cell": 2 }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Random numbers (range 10-19 read from file): \n", " 0.8045 \t 0.2685 11.0000 \t 1.3933 \t 0.8030\n", " 0.5180 \t 1.5130 6.0000 \t 0.9688 \t 0.7423\n", " 0.1699 \t 0.1509 13.0000 \t 1.0617 \t 0.8891\n", " 0.5788 \t -0.1179 11.0000 \t 0.6423 \t 0.7164\n", " 0.2709 \t -0.6303 7.0000 \t 0.5531 \t 0.9078\n", " 0.5071 \t -1.0081 7.0000 \t 1.1912 \t 0.3828\n", " 0.8218 \t 1.1083 8.0000 \t 0.3066 \t 0.9391\n", " 0.6364 \t 0.5968 8.0000 \t 0.2119 \t 0.6946\n", " 0.2187 \t -1.5259 7.0000 \t 1.2005 \t 0.3683\n", " 0.4323 \t 0.6179 7.0000 \t 0.0398 \t 0.6668\n" ] } ], "source": [ "print(\"\\nRandom numbers (range 10-19 read from file): \")\n", "for i in range(10, 20) : \n", " print(f\"{uni[i]:8.4f} \\t {gauss[i]:8.4f} {pois[i]:8.4f} \\t {exp[i]:8.4f} \\t {power[i]:8.4f}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lastly create a latex table you can copy paste into your paper/thesis with the mean and rms of the numbers you have genereated:" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\\begin{tabular}{|l|cc|}\n", "\t \\hline\n", "\t \\multicolumn{3}{|c|}{PDF Means and RMS}\n", "\t \\hline\n", "\t pdf & $\\mu$ & $\\sigma$\\\\\n", "\t \\hline\n", "\t Uniform & 0.000 & 0.000 \\\\\n", "\t Gaussian & 0.000 & 0.000 \\\\\n", "\t Poissonian & 0.000 & 0.000 \\\\\n", "\t Exponential & 0.000 & 0.000 \\\\\n", "\t Power & 0.000 & 0.000 \\\\\n", "\t \\hline\n", "\\end{tabular}\n", "\n" ] } ], "source": [ "print(\"\\\\begin{tabular}{|l|cc|}\")\n", "print(\"\\t \\\\hline\")\n", "print(\"\\t \\\\multicolumn{3}{|c|}{PDF Means and RMS}\")\n", "print(\"\\t \\\\hline\")\n", "print(\"\\t {0:15s} & {1:7s} & {2:7s}\\\\\\\\\".format( \"pdf\", \"$\\\\mu$\", \"$\\\\sigma$\" ))\n", "print(\"\\t \\\\hline\")\n", "\n", "for name, mu_sigma in zip(['Uniform', 'Gaussian', 'Poissonian', 'Exponential', 'Power'], \n", " [MeanAndRMS(lst) for lst in [uni, gauss, pois, exp, power]]):\n", " print(f\"\\t {name:15s} & {mu_sigma[0]:7.3f} & {mu_sigma[1]:7.3f} \\\\\\\\\")\n", "\n", "print(\"\\t \\\\hline\")\n", "print(\"\\\\end{tabular}\")\n", "print(\"\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This can be quite useful, when the result of code needs to go into a document (thesis?). Try yourself to write the above LaTeX table into a file, which could then be included by your LaTeX code.\n", "\n", "*** \n", "\n", "In case you want to export the notebook to a normal python file (.py), you can uncomment the command below (but keep the \"`!`\") and run the cell. This exports the notebook to a Python file." ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [], "source": [ "#!jupyter nbconvert --to script PythonIntro.ipynb" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(In the case that you want to convert back from .py to Notebook.ipynb file, run the following command:\n", "`jupyter nbconvert --to notebook PythonIntro.py` in a terminal. In case you want to do it automatically in the Python script, add the line `os.system(\"jupyter nbconvert --to notebook PythonIntro.py\")`" ] } ], "metadata": { "executable": "/usr/bin/env python", "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.6.6" }, "main_language": "python" }, "nbformat": 4, "nbformat_minor": 2 }