{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Basic introduction of python" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Setting the environment for Python\n", "* [Anaconda](https://www.anaconda.com/products/individual) : Include essential packages for basic scientific computation. It is easy to install it just follow the instruction.\n", "* Not required, but easy to use for beginners." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Why numerical approach? \n", "\n", "### Need to confirm the mechanism of your idea \n", " - An idea for the novel physics\n", " - Numerical experiments driven by scientific ideas\n", " - Numerical experiments driven theoretical ideas\n", "\n", "### Need to connect with real experiments \n", " - To strenthen the abstract idea and connect with real world\n", " - Get additional information that is difficult to access in experiments and make prediction that is accessible for experiments\n", "\n", "### Numerics for many body physics is non-trivial! \n", " - The problem itself is a intelletral challenging and interesting discrete mathmetical problems. \n", " - Hardware limitation force one to think in a smart way\n", " \n", "### Generate data to convey what you mean\n", " - Statistics\n", " - Plots\n", "\n", "## My point of view of numerical approaches\n", "\n", "### Level of numerical loading\n", "\n", "* Light: Mathematica, Python, matlab (For quick checking and benchmark. Once the simple concept passes, use the medium or heavy numerical approach)\n", "* Heavy: C/C++, Fortran\n", "\n", "\n", "## Why Python? \n", "\n", "### Simple, well-structured, general-purpose language\n", " - Readability great for quality control and collaboration\n", " - Code how you think: many books now use python as pseudocode\n", " \n", "### High-level \n", " - Rapid development\n", " - Do complicated things in few lines\n", "\n", "### Interactive \n", " - Rapid development and exploration\n", " - No need to compile, run, debug, revise, compile\n", " - Data collection, generation, analysis and publication plotting in one place\n", "\n", "### Speed\n", " - Usually plenty fast -- will discuss more\n", " - Your development time is more important than CPU time\n", " - Not as fast as C, C++, Fortran but these can be easily woven in where necessary\n", "\n", "### Vibrant community\n", " - Great online documentation / help available\n", " - Open source\n", " \n", "### Rich scientific computing libraries\n", " - Don't reinvent the wheel. Only reinvent important wheels!\n", " \n", "### Accessible for everyone. No need to pay money\n", "\n", "\n", "\n", "\n", "\n", "## Scientific Python Key Components\n", "\n", "The core pieces of the scientific Python platform are:\n", "\n", "**[Python](http://www.python.org)**, the language interpreter \n", " - Many standard data types, libraries, etc\n", " - Python 3.7 is the current version; use this\n", " - Python 2.7 (released 2010) is still maintained but will die in 2020\n", "\n", "**[Jupyter](http://www.jupyter.org)**: notebook based (in browser) interface\n", " - Builds on **[IPython](http://www.ipython.org)**, the interactive Python shell\n", " - Interactive manipulation of plots\n", " - Easy to use basic parallelization\n", " - Lots of useful extra bells and whistles for Python\n", " \n", "**[Numpy](http://www.numpy.org)**, powerful numerical array objects, and routines to manipulate them. \n", " - Work horse for scientific computing\n", " - Basic linear algebra (np.linalg)\n", " - Random numbers (np.random)\n", " \n", "**[Scipy](http://www.scipy.org)**, high-level data processing routines. \n", " - Signal processing (scipy.signal)\n", " - Optimization (scipy.optimize)\n", " - Special functions (scipy.special)\n", " - Sparse matrices and linear algebra\n", "\n", "**[Matplotlib](http://www.matplotlib.org)**, plotting and visualization\n", " - 2-D and basic 3-D interactive visualization\n", " - “Publication-ready” plots\n", " - LaTeX labels/annotations automagically\n", "\n", "**[Pandas](https://pandas.pydata.org)**, data analysis/management\n", " - data structures for relational data manipulation\n", " - useful in observational/numerical analysis\n", " - Won't discuss here\n", "\n", "**[Mayavi](http://code.enthought.com/projects/mayavi/)**, 3-D visualization\n", " - For more sophisticated 3-D needs (won't discuss)\n", "\n", "## Jupyter Workflow\n", "\n", "### Two primary workflows:\n", "\n", "1. Work in a Jupyter/IPython notebook. Write code in cells, analyze, plot, etc. Everything stored in **.ipynb** file.\n", "2. Write code in **.py** files using a text editor and run those within the IPython notebook or from the shell.\n", "\n", "We still stick to the first. \n", "\n", "While you are using a notebook, there is a **kernel** running which actually executes your commands and stores your variables, etc. If you quit/restart the kernel, all variables will be forgotten and you will need to re-execute the commands that set them up. This can be useful if you want to reset things. The input and output that is visible in the notebook is saved in the notebook file.\n", "\n", "*Note:* .py files are called **scripts** if they consist primarily of a sequence of commands to be run and **modules** if they consist primarily of function definitions for import into other scripts/notebooks. \n", "\n", "### Notebook Usage\n", "\n", "Two modes: editing and command mode.\n", "\n", "Press escape to go to command mode.\n", "Press return to go into editing mode on selected cell.\n", "\n", "In command mode:\n", "1. Press h for a list of keyboard commands.\n", "2. Press a or b to create a new cell above or below the current.\n", "3. Press m or y to convert the current cell to markdown or code.\n", "4. Press shift-enter to execute.\n", "5. Press d d to delete the current cell. (Careful!)\n", "\n", "In editing mode:\n", "1. Press tab for autocomplete\n", "2. Press shift-tab for help on current object\n", "3. Shift-enter to execute current cell\n", "\n", "Two types of cells:\n", "1. Markdown for notes (like this)\n", "2. Code for things to execute\n", "\n", "\n", "\n", "**Exercise**\n", "\n", "Try editing this markdown block to make it more interesting. For example, type in some equations $e^{i\\pi}+1=0$.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise**\n", "\n", "Execute the next block and then create a new block, type x. and press tab and shift-tab." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "x = 10" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise**\n", "\n", "Run this stuff." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello, world!\n" ] } ], "source": [ "print('Hello, world!')" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Hello, world!'" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"Hello, world!\"" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "7.5" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2.5 * 3" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "27" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3**3" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3 + 3" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'abcd'" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"ab\" + \"cd\"" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"Hello\" == 'Hello'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Variables and Objects\n", "\n", "Everything in memory in Python is an object. Every object has a type such as int (for integer), str (for strings) or ndarray (for numpy arrays). Variables can reference objects of any type and that type can change.\n", "\n", "The equals sign in programming does not mean 'is equal to' as in math. It means **'assign the object on the right to the variable on the left'**.\n" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "a = 3" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "int" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(a)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a+a" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2+a" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "a = np.array([1,2])" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1, 2])" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "numpy.ndarray" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(a)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(2,)" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# All objects have properties, accessible with a .\n", "a.shape" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([2, 4])" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a+a" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([3, 4])" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2+a" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "a = \"Hello, world!\"" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Hello, world!'" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "str" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(a)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Hello, world!Hello, world!'" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a+a" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "unsupported operand type(s) for +: 'int' and 'str'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m/tmp/ipykernel_128278/1750888518.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;36m2\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for +: 'int' and 'str'" ] } ], "source": [ "2+a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Overloading \n", "\n", "Operators and functions will try to execute no matter what type of objects are passed to them, but they may do different things depending on the type. + adds numbers and concatenates strings." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Variables as References\n", "\n", "All variables are **references** to the objects they contain. Assignment does not make copies of objects." ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1, 2])" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.array([1,2])\n", "a" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1, 2])" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = a\n", "b" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0, 2])" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b[0] = 0\n", "b" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0, 2])" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Types of Objects\n", "\n", "### Basic Types\n", "\n", "1. Numeric, Immutable\n", " 1. Integer: -1, 0, 1, 2, ...\n", " 2. Float: 1.2, 1e8\n", " 3. Complex: 1j, 1. + 2.j\n", " 4. Boolean: True, False\n", "2. Strings, \"hi\"\n", "3. Tuples, (2,7, \"hi\")\n", " - Ordered collection of other objects, represented by parentheses\n", " - can't change after creation (*immutable*)\n", "3. Lists, [0,1,2,\"hi\", 4]\n", " - Ordered collection of other objects, represented by square brackets\n", " - can add/remove/change elements after creation (*mutable*)\n", "4. Dictionaries, {'hi': 3, 4: 7, 'key': 'value'}\n", "5. Functions, def func()\n", "\n", "### Common Scientific Types \n", "\n", "6. NumPy arrays, array([1,2,3])\n", " - Like lists but all entries have same type\n", "7. Sparse arrays, scipy.sparse\n", "8. Pandas DataFrames, high level 'table' a bit like an excel spreadsheet" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Basic Types: Numeric\n", "\n", "There are 4 numeric types: \n", "- int: positive or negative integer\n", "- float: a 'floating point' number is a real number like 3.1415 with a finite precision\n", "- complex: has real and imaginary part, each of which is a float\n", "- bool: two 'Boolean' values, True or False\n" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "int" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 4\n", "type(a)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "float" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c = 4.\n", "type(c)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "complex" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 1.5 + 0.1j\n", "type(a)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.5" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.real" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.1" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.imag" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "flag = (3>4)\n", "flag" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "bool" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(flag)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "bool" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(True)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Type conversion\n", "float(1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Careful with integer division!\n", "\n", "In Python 3, dividing integers promotes to a float. Use // for integer division." ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.5" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3/2" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.5" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3/2." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***Force integer division:***" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3//2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Basic Types: Strings\n", "\n", "Strings are **immutable** sequences of characters. This means you can't change a character in the middle of a string, you have to create a new string. \n", "\n", "Literal strings can be written with single or double-quotes. Multi-line strings with triple quotes. 'Raw' strings are useful for embedding LaTeX because they treat backslashes differently." ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'Hello' == \"Hello\"" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [], "source": [ "a = \"\"\"This is a multiline string.\n", "Nifty, huh?\"\"\"" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'This is a multiline string.\\nNifty, huh?'" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "u\n" ] } ], "source": [ "print(\"\\nu\")" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\\nu\n" ] } ], "source": [ "print(r\"\\nu\")" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [], "source": [ "a = 3.1415" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Blah 3.1415'" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Simple formatting (type convert to string)\n", "\"Blah \" + str(a)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Blah 3.14, hi'" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Old style string formatting (ala sprintf in C)\n", "\"Blah %1.2f, %s\" % (a, \"hi\")" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Blah 3.14, hi'" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# New style string formatting \n", "\"Blah {:1.2f}, {}\".format(a, \"hi\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Basic Types: Lists\n", "\n", "Python lists store **ordered** collections of arbitrary objects. They are efficient maps **from index to values**. Lists are represented by square brackets [ ]. \n", "\n", "Lists are **mutable**: their contents can be changed after they are created.\n", "\n", "It takes time O(1) to:\n", "1. Lookup an entry at given index.\n", "2. Change an item at a given index.\n", "3. Append or remove (pop) from the end of the list. \n", "\n", "It takes time O(N) to:\n", "1. Find items by value if you don't know where they are.\n", "2. Remove items from near the beginning of the list.\n", "\n", "You can also grab arbitrary **slices** from a list efficiently.\n", "\n", "Lists are 0-indexed. This means that the first item in the list is at position 0 and the\n", "last item is at position N-1 where N is the length of the list." ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [], "source": [ "days_of_the_week = [\"Sunday\",\"Monday\",\"Tuesday\",\n", " \"Wednesday\",\"Thursday\",\"Friday\"]" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Sunday'" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "days_of_the_week[0]" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Tuesday', 'Wednesday', 'Thursday']" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# The slice from 2 to 5 (inclusive bottom, exclusive top)\n", "days_of_the_week[2:5]" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Friday'" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "days_of_the_week[-1]" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Sunday', 'Tuesday', 'Thursday']" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# every other day\n", "days_of_the_week[0:-1:2]" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Sunday', 'Tuesday', 'Thursday']" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# every other day (shorter)\n", "days_of_the_week[::2]" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [], "source": [ "# Oops!\n", "days_of_the_week.append(\"Saturday\")" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Saturday'" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "days_of_the_week[-1]" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [], "source": [ "days_of_the_week[5] = \"Casual Friday\"" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Sunday',\n", " 'Monday',\n", " 'Tuesday',\n", " 'Wednesday',\n", " 'Thursday',\n", " 'Casual Friday',\n", " 'Saturday']" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "days_of_the_week" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "7" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Get the length of the list\n", "len(days_of_the_week)" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [], "source": [ "# Sort the list in place\n", "days_of_the_week.sort()" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Casual Friday',\n", " 'Monday',\n", " 'Saturday',\n", " 'Sunday',\n", " 'Thursday',\n", " 'Tuesday',\n", " 'Wednesday']" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "days_of_the_week" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Remember tab completion** Every thing in Python (even the number 10) is an object. Objects can have methods which can be accessed by the notation a.method(). Typing a. allows you to see what methods an object a supports. Try it now with days_of_the_week:\n" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "ename": "SyntaxError", "evalue": "invalid syntax (, line 1)", "output_type": "error", "traceback": [ "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m days_of_the_week.\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" ] } ], "source": [ "days_of_the_week." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Each item is arbitrary**: You can have lists of lists or lists of different types of objects." ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['zero', 1, 'two', 3.0, (4+0j)]" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "aList = [\"zero\", 1, \"two\", 3., 4.+0j]\n", "aList" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [], "source": [ "listOfLists = [[1,2], [3,4], [5,6,7], 'Hi']" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "listOfLists[2][1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Basic Types: Dictionaries\n", "\n", "A dictionary is an efficient map **from keys to values**. They are represented by curly brackets {}. \n", "\n", "Dictionaries are **mutable** but all **keys must be immutable**. IE. keys can be strings, numbers, or tuples thereof but not lists or other dictionaries. Values can be anything.\n", "\n", "It is unordered but takes time O(1) to:\n", "1. Lookup a value from a key\n", "2. Add a key, value pair\n", "3. Remove a key, value pair\n", "\n", "It takes time O(N) to find an entry with a particular value.\n", "\n", "You can iterate through all the entries efficiently O(N)." ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [], "source": [ "tel = {'emmanuelle': 5752, 'sebastian': 5578}\n", "tel['francis'] = 5915" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'emmanuelle': 5752, 'sebastian': 5578, 'francis': 5915}" ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tel" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5578" ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tel['sebastian']" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dict_keys(['emmanuelle', 'sebastian', 'francis'])" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tel.keys()" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dict_values([5752, 5578, 5915])" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tel.values()" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(tel)" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'francis' in tel" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [], "source": [ "del tel['francis']" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'emmanuelle': 5752, 'sebastian': 5578}" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tel" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Basic Types: Tuples\n", "\n", "A tuple is an **ordered** collection of objects. They are represented by round parantheses ().\n", "\n", "Tuples are almost like lists but they are **immutable**. This means that they cannot be changed once they are created. " ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 2, 3, 'Hi')" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t = (1,2,3,'Hi')\n", "t" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "'tuple' object does not support item assignment", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# IMMUTABLE !\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[0mt\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" ] } ], "source": [ "# IMMUTABLE !\n", "t[0] = 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The empty tuple and length 1 tuples have special notation since parentheses can also represent grouping." ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "()" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "emptyTuple = ()\n", "emptyTuple" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('hi',)" ] }, "execution_count": 80, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lengthOne = ('hi',)\n", "lengthOne" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'hi'" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" } ], "source": [ "notLengthOne = ('hi')\n", "notLengthOne" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'h'" ] }, "execution_count": 82, "metadata": {}, "output_type": "execute_result" } ], "source": [ "notLengthOne[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Control Flow\n", "\n", "The flow of a program is the order in which the computer executes the statements in the code. Typically, this is in order from top to bottom. However, there are many cases where we want to change the flow in some way. For example, we might want to divide two numbers but only if the divisor is not zero. Or we might want to iterate: repeat a block of code many times for each value in some list. The commands which allow these are called control flow commands.\n", "\n", "**WARNING**: Python cares about **white space**! You must **INDENT CORRECTLY** because that's how Python knows when a block of code ends. \n", "\n", "Typically, people indent with 4 spaces per block but 2 spaces or tabs are okay. They must be consistent in any block." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### If/elif/else" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Not\n", "At all\n" ] } ], "source": [ "if 2>3:\n", " print(\"Yep\")\n", " print(\"It is\")\n", "\n", "elif 3>4:\n", " print(\"Not this one either.\")\n", " \n", "else:\n", " print(\"Not\")\n", " print(\"At all\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### For Loops ###\n", "\n", "For loops *iterate* through elements in a collection. This can be a list, tuple, dictionary, array or any other such collection. \n", "\n", "These are the most *Pythonic* way to think about iterations." ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The cube of 0 is 0\n", "The cube of 1 is 1\n", "The cube of 2 is 8\n", "The cube of 3 is 27\n", "The cube of 4 is 64\n" ] } ], "source": [ "for i in range(5):\n", " j = i**3\n", " print(\"The cube of \" + str(i) + \" is \" + str(j))" ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Today is Casual Friday\n", "Today is Monday\n", "Today is Saturday\n", "Today is Sunday\n", "Today is Thursday\n", "Today is Tuesday\n", "Today is Wednesday\n" ] } ], "source": [ "for day in days_of_the_week:\n", " print(\"Today is \" + day)" ] }, { "cell_type": "code", "execution_count": 86, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "emmanuelle's telephone number is 5752\n", "sebastian's telephone number is 5578\n" ] } ], "source": [ "for key in tel:\n", " print(key + \"'s telephone number is \" + str(tel[key]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Enumerate** to get index and value of iteration element" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 your\n", "1 face\n", "2 is\n", "3 beautiful\n" ] } ], "source": [ "words = ('your', 'face', 'is', 'beautiful')\n", "\n", "for (i, word) in enumerate(words):\n", " print(i, word)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### While Loops\n", "\n", "Repeats a block of code while a condition holds true." ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Bark 5\n", "Bark 4\n", "Bark 3\n", "Bark 2\n", "Bark 1\n" ] } ], "source": [ "x = 5\n", "\n", "while x > 0:\n", " print(\"Bark \" + str(x))\n", " x -= 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Functions\n", "\n", "Any code that you call multiple times with different values should be wrapped up in a function. For example:" ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [], "source": [ "def square(x):\n", " \"\"\"Return the square of x.\"\"\"\n", " return x*x" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [], "source": [ "square?" ] }, { "cell_type": "code", "execution_count": 91, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "81" ] }, "execution_count": 91, "metadata": {}, "output_type": "execute_result" } ], "source": [ "square(9)" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [], "source": [ "def printAndSquare(x):\n", " \"\"\"Print the square of x and return it.\"\"\"\n", " y = x**2\n", " print(y)\n", " return y" ] }, { "cell_type": "code", "execution_count": 93, "metadata": {}, "outputs": [], "source": [ "printAndSquare?" ] }, { "cell_type": "code", "execution_count": 94, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "64\n" ] }, { "data": { "text/plain": [ "64" ] }, "execution_count": 94, "metadata": {}, "output_type": "execute_result" } ], "source": [ "printAndSquare(8)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Functions are Objects ###\n", "\n", "Functions are just like any object in Python:" ] }, { "cell_type": "code", "execution_count": 95, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "function" ] }, "execution_count": 95, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(square)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Make another variable refer to the same function:" ] }, { "cell_type": "code", "execution_count": 96, "metadata": {}, "outputs": [], "source": [ "a = square" ] }, { "cell_type": "code", "execution_count": 97, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "25" ] }, "execution_count": 97, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a(5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A function being passed to another function." ] }, { "cell_type": "code", "execution_count": 98, "metadata": {}, "outputs": [], "source": [ "def test():\n", " print(\"In Test!\")\n", " return\n", "\n", "def callIt(fun):\n", " print(\"In callIt!\")\n", " fun()\n", " return" ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "In callIt!\n", "In Test!\n" ] } ], "source": [ "callIt(test)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "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.8.8" } }, "nbformat": 4, "nbformat_minor": 1 }