{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Getting Started with Python \n", "\n", "### © Marko Petrović and Branislav K. Nikolić, University of Delaware\n", "[PHYS824: Nanophysics & Nanotechnology](https://wiki.physics.udel.edu/phys824) \n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## What is Python?\n", "\n", "\n", "Python is an interpreted high-level programming language for general-purpose programming.\n", "\n", "#### Python features:\n", " - dynamic types \n", " - object-oriented, functional and procedural \n", " - large standard library and a lot of external packages\n", " \n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Different versions of Python\n", "\n", "- Python 2.x or 3.x \n", "\n", "#### Writing and running Python\n", "\n", "- Terminal (text scripts or interactively).\n", "- Notebooks ([Jupyter](http://jupyter.org/index.html)). To run this notebook you also need to install Python's [matplotlib](https://matplotlib.org/) and [numpy](http://www.numpy.org/) packages. \n", "- IDE (e.g. [Spyder](https://www.spyder-ide.org/), [PyCharm](https://www.spyder-ide.org/))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## What is covered in this notebook\n", "- Basic data types in Python\n", "- Data containers (lists, tuples, dictionaries)\n", "- Control flow (if statements, loops, functions)\n", "- Built-in functions\n", "- Numpy arrays" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Basic data types in Python" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Most commonly used data types in Python are: integer, float, string, and boolean. " ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "hbar = 6.582119514e-34 # Reduced Plank constant (eV*s)\n", "n_spins = 5 # Integer\n", "phi = 0.1234 # Float \n", "z = 1 + 2j # Complex\n", "xlabel = 'System Size (nm)' # String \n", "test_failed = True # Boolean (True or False)\n", "is_phi_positive = phi > 0 # Boolean\n", "xyz = None # (None is not equal to zero)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1+2j)\n", "RE: 1.00 IM: 2.00e+00 \n" ] } ], "source": [ "print(z)\n", "print(\"RE: %5.2f IM: %5.2e \" % (z.real, z.imag))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Python is dynamically typed language\n", "- Variable type doesn't depend on its name but on its current value. \n", "- Variable type can change with every new value assignment. \n", "- There are no constants in Python " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Example of a variable changing type\n", "\n", "You can check the type of a variable with the built-in type() function." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5 \n", "Hello! \n" ] } ], "source": [ "x = 5 \n", "print(x, type(x))\n", "\n", "x = \"Hello!\" \n", "print(x, type(x))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Convention for constants\n", "\n", "Use all capital letters as a reminder to keep a value constant. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "hbar = 6.582119514e-34 # We want this to be constant \n", "hbar = 2 # Problem: We just changed it!\n", "print('hbar = ', hbar)\n", "NEW_HBAR = 6.582119514e-34 # Constant (still can be changed!)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Operators" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "scrolled": true, "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Addition: 14.7\n", "Subtraction: 9.3\n", "Multiplication: 32.400000000000006\n", "Power: 819.9537649223419\n", "Division: 4.444444444444444\n", "Floor division: 4.0\n", "Remainder: 1.1999999999999993\n", "String concatenation ABCDEFGH\n" ] } ], "source": [ "x = 12\n", "y = 2.7\n", "print('Addition: ', x + y)\n", "print('Subtraction: ', x - y)\n", "print('Multiplication: ', x * y)\n", "print('Power: ', x**y)\n", "print('Division: ', x / y)\n", "print('Floor division: ', x // y)\n", "print('Remainder: ', x % y)\n", "print('String concatenation', 'ABCD' + 'EFGH')" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Logical operators" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Equality: False\n", "Non-equality: True\n", "Less than: True\n", "Greater than or equal: False\n", "Negation: True\n", "Composition: False\n" ] } ], "source": [ "x = 2\n", "y = 7\n", "print('Equality: ', x == y)\n", "print('Non-equality: ', x != y)\n", "print('Less than: ', x < y)\n", "print('Greater than or equal: ', x >= y)\n", "print('Negation: ', not x >= y)\n", "print('Composition: ', ((x > y) and (y < 5)) or (x > 5))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Data containers" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "\n", "Data containers are used to group variables and literals. \n", "\n", "Four major container types are:\n", "- lists\n", "- tuples\n", "- sets \n", "- dictionaries" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Lists\n", "List are mutable (the number of their elements can change after they are created) and ordered data containers which can hold any data type." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "data": { "text/plain": [ "list" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "grocery = ['milk', 'wine', 'cheese'] \n", "random_stuff = ['ABC', 3.14, None, grocery] \n", "energies = [0.1, 0.2, 0.3]\n", "\n", "type(random_stuff) " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Appending lists" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0, 1, 1, 2]\n" ] } ], "source": [ "fibonacci = []\n", "fibonacci.append(0)\n", "fibonacci.append(1)\n", "fibonacci.append(1)\n", "fibonacci.append(2)\n", "print(fibonacci)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Extending lists" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['bread', 'soup', 'cheese', 'beer', 'wine', 'soda']\n", "6\n" ] } ], "source": [ "grocery = ['bread', 'soup', 'cheese']\n", "drinks = ['beer', 'wine', 'soda']\n", "grocery.extend(drinks)\n", "print(grocery)\n", "print(len(grocery))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Selecting list elements" ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "bread\n", "soup soda\n", "['soup', 'cheese']\n" ] } ], "source": [ "grocery = ['bread', 'soup', 'cheese', 'beer', 'wine', 'soda']\n", "print(grocery[0])\n", "print(grocery[1], grocery[-1])\n", "print(grocery[1:3])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Changing list elements " ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['milk', 'soup', 'cheese']\n", "['milk', 'soup', 'coffee']\n", "['milk', 'coffee']\n" ] } ], "source": [ "grocery = ['milk', 'soup', 'cheese']\n", "print(grocery)\n", "grocery[2] = 'coffee' # Change the third element\n", "print(grocery)\n", "del grocery[1] # Delete the second element\n", "print(grocery)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Tuples\n", "\n", "- Tuples are similar to lists, but they are immutable.\n", "- Their elemtents can't change after a tuple is being created.\n", "- They are set with commas, with or without parentheses. \n", "- Good for returning multiple values from a function." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "data": { "text/plain": [ "'Tue'" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "days = 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'\n", "x = (1, 2, 3)\n", "days[1]" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Unpacking tuples" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5.4\n" ] } ], "source": [ "x = (2.5, 5.4, 0.5)\n", "energy, volume, bias = x\n", "print(volume)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Dictionaries\n", "Dictionaries are mutable collections of key/value pairs.\n", "\n", "\n", " " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "temp_F = {} # An empty dictionary\n", "temp_F['Boston'] = 70.\n", "temp_F['New York'] = 72. \n", "temp_F['Newark'] = 75. \n", "print(temp_F['Boston'])" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "'123-4444-843'" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "phone = {'Alice': '123-4567-890',\n", " 'Bob': '123-4444-843',\n", " 'Tom': '843-4342-434'}\n", "\n", "phone['Bob']" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Control flow\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### The if statement\n", "\n", "Indentation plays a very important role in determining how code is executed. Same code with different indentation will do different things. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "x = 1 # Asignment\n", "if x == 1: # Conditional\n", " print('x is equal to one') # Beginning of a if-block\n", " x = 2 # End of the if-block. \n", "print(x) # This line is outside of the if-block " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### If..elif..else statements" ] }, { "cell_type": "code", "execution_count": 58, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Element 6: carbon\n" ] } ], "source": [ "element = 'C'\n", "\n", "if element == 'C': \n", " atm_number = 6\n", " name = 'carbon'\n", "elif element == 'O':\n", " atm_number = 8\n", " name = 'oxygen'\n", "else:\n", " atm_number = -1\n", " name = 'undefined'\n", "\n", "print('Element %d: %s' % (atm_number, name))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Loops " ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The energy is 1.000000e-01 \n", "End\n", "The energy is 2.000000e-01 \n", "End\n", "The energy is 3.000000e-01 \n", "End\n", "The energy is 4.000000e-01 \n", "End\n" ] } ], "source": [ "energies = [0.1, 0.2, 0.3, 0.4] \n", "\n", "for energy in energies:\n", " print('The energy is %e ' % energy)\n", " print(\"End\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### while loops" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "code_folding": [], "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "3\n", "4\n", "5\n" ] } ], "source": [ "count = 0\n", "while (count < 5):\n", " count = count + 1\n", " print(count)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Using function range() to iterate over integers\n", "\n", "NOTE: To create an array of floating point numbers it is better to use the numpy library." ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 0\n", "1 1\n", "2 4\n", "j = 2\n", "j = 9\n", "j = 16\n" ] } ], "source": [ "for i in range(3):\n", " print(i, i**2)\n", "\n", "for j in range(2, 20, 7):\n", " print('j = ', j)\n", " " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Using enumerate() to get the index or an element\n", "\n", "Enumerate returns next element and its index" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 A\n", "1 B\n", "2 C\n", "3 D\n" ] } ], "source": [ "chars = ['A', 'B', 'C', 'D']\n", "\n", "for index, e in enumerate(chars):\n", " print(index, e)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### List comprehensions\n", "\n", "Perform some operation on a list in a single line" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1.0, 4.0, 16.0, 16.0]\n" ] } ], "source": [ "potentials = [1.0, 2.0, 4.0, 4.0] \n", "\n", "pot2 = [pot**2 for pot in potentials]\n", "print(pot2)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['pot_1.0.txt', 'pot_2.0.txt', 'pot_4.0.txt', 'pot_4.0.txt']\n" ] } ], "source": [ "out_files = ['pot_%0.1f.txt' % pot for pot in potentials]\n", "print(out_files)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Functions \n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Functions without arguments" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello\n", "2\n" ] } ], "source": [ "def some_function():\n", " print(\"Hello\")\n", " x = 2\n", " return # By default function returns None\n", "\n", "print(some_function())" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Functions with positional arguments" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "data": { "text/plain": [ "12.2" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def add(x, y):\n", " result = x + y\n", " return result\n", "\n", "add(5, 7.2)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def circle(x, y):\n", " radius = 8.0\n", " in_circle = (x**2 + y**2 < radius**2)\n", " return in_circle\n", "\n", "circle(0, 9)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Functions with keyword arguments" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "def circle(x, y, x0=0, y0=0, radius=8):\n", " in_circle = ((x-x0)**2 + (y-y0)**2 < radius**2)\n", " return in_circle \n", "\n", "circle(2, 3) \n", " " ] }, { "cell_type": "code", "execution_count": 86, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "In circle\n" ] }, { "data": { "text/plain": [ "True" ] }, "execution_count": 86, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circle(2, 3, radius=10) # Changing a single keyword argument" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Functions returning multiple values" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3 9 27\n" ] } ], "source": [ "def f(x):\n", " return x, x**2, x**3\n", "\n", "a, b, c = f(3)\n", "print(a, b, c)" ] }, { "cell_type": "code", "execution_count": 88, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "25\n" ] } ], "source": [ "m = f(5)\n", "print(m[1])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Built-in math functions\n", "\n", "NOTE: Most of these functions operate on a single number. There are their\n", "alternatives in numpy package which operate on entire arrays." ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "(0.49999999999999994, 0.8660254037844387, 1.6880917949644685, 5)" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from math import sin, cos, exp, tan\n", "from math import pi \n", "\n", "alpha = 30.0 \n", "alpha_rad = alpha * pi / 180\n", "sin(alpha_rad), cos(alpha_rad), exp(alpha_rad), abs(-5)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Numpy arrays" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Creating 1D arrays" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0. 0.5 1. 1.5]\n" ] }, { "data": { "text/plain": [ "numpy.ndarray" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "\n", "energies = np.arange(0, 2.0, 0.5) # start, end, step\n", "print(energies)\n", "type(energies)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "potentials = np.linspace(0, 1., 7) # start, end, number of points" ] }, { "cell_type": "code", "execution_count": 99, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[5. 5. 5. 5. 5.]\n" ] } ], "source": [ "uniform = 5 * np.ones(5)\n", "print(uniform)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Creating 2D arrays" ] }, { "cell_type": "code", "execution_count": 115, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1. 0. 0. 0.]\n", " [0. 1. 0. 0.]\n", " [0. 0. 1. 0.]\n", " [0. 0. 0. 1.]]\n", "\n", "[[ 0. -1. 0. 0.]\n", " [ 0. 0. -1. 0.]\n", " [ 0. 0. 0. -1.]\n", " [ 0. 0. 0. 0.]]\n" ] } ], "source": [ "i5 = np.eye(4) # Create a unit matrix of five elements\n", "t_up = np.diag(np.ones(3), k=1) # Create a hopping matrix on upper diagonal\n", "t_down = np.diag(-np.ones(3), k=-1) # Create a hopping matrix on the lower diagonal\n", "print(i5)\n", "print()\n", "print(t_down.T) # Transpose operation" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Operations on numpy arrays\n" ] }, { "cell_type": "code", "execution_count": 121, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[2. 3.]\n", " [4. 5.]]\n", "[[0. 0.]\n", " [0. 0.]]\n" ] } ], "source": [ "a = np.array([[1, 2], [3, 4]]) # Numpy arrays can also be defined using lists or tuples\n", "b = np.ones((2, 2), dtype=complex) # The type can be float, complex, and object\n", "b0 = np.zeros((3, 5), dtype=float)\n", "\n", "# Elementwise operations\n", "c = a + b**2\n", "e = np.sqrt(a)\n", "f = np.exp(c)\n", "\n", "d = np.matmul(a, b)\n", "\n", "print(c.real)\n", "print(d.imag)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Send corrections to petrovic@udel.edu" ] } ], "metadata": { "celltoolbar": "Slideshow", "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.3" } }, "nbformat": 4, "nbformat_minor": 2 }