{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Quick note about Jupyter cells\n", "\n", "When you are editing a cell in Jupyter notebook, you need to re-run the cell by pressing **` + `**. This will allow changes you made to be available to other cells.\n", "\n", "Use **``** to make new lines inside a cell you are editing.\n", "\n", "#### Code cells\n", "\n", "Re-running will execute any statements you have written. To edit an existing code cell, click on it.\n", "\n", "#### Markdown cells\n", "\n", "Re-running will render the markdown text. To edit an existing markdown cell, double-click on it.\n", "\n", "## Common Jupyter operations\n", "\n", "> Near the top of the page, Jupyter provides a row of menu options (`File`, `Edit`, `View`, `Insert`, ...) and a row of tool bar icons (disk, plus sign, scissors, 2 files, clipboard and file, up arrow, ...).\n", "\n", "#### Inserting and removing cells\n", "\n", "- Use the \"plus sign\" icon to insert a cell below the currently selected cell\n", "- Use \"Insert\" -> \"Insert Cell Above\" from the menu to insert above\n", "\n", "#### Clear the output of all cells\n", "\n", "- Use \"Kernel\" -> \"Restart\" from the menu to restart the kernel\n", " - click on \"clear all outputs & restart\" to have all the output cleared\n", "\n", "#### Save your notebook file locally\n", "\n", "- Clear the output of all cells\n", "- Use \"File\" -> \"Download as\" -> \"IPython Notebook (.ipynb)\" to download a notebook file representing your try.jupyter.org session\n", "\n", "#### Load your notebook file in try.jupyter.org\n", "\n", "1. Visit https://try.jupyter.org\n", "2. Click the \"Upload\" button near the upper right corner\n", "3. Navigate your filesystem to find your `*.ipynb` file and click \"open\"\n", "4. Click the new \"upload\" button that appears next to your file name\n", "5. Click on your uploaded notebook file\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## References\n", "\n", "- https://try.jupyter.org\n", "- https://docs.python.org/3/tutorial/index.html\n", "- https://docs.python.org/3/tutorial/introduction.html\n", "- https://daringfireball.net/projects/markdown/syntax\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python objects and variables\n", "\n", "In Python, a **varible** is a name you specify in your code that maps to a particular **object**, object **instance**, or value. Every object in Python has a **type**.\n", "\n", "By defining variables, we can refer to things by names that make sense to us. Names for variables must start with a letter and can only contain other letters, underscores (`_`), or numbers (no spaces, dashes, or other characters).\n", "\n", "> Here, we define some variables that we can use in other cells.\n", ">\n", "> Remember to **` + `** on the cell defining the variables before trying to run other cells (or after changing a variable's definition). If you don't, a `NameError` exception will be raised saying that a variable \"is not defined\" when you try to access it, or the variable will have its old value." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Some simple variables\n", "num_1 = 55\n", "num_2 = -23\n", "num_3 = 10.11\n", "string_1 = 'this is a string'\n", "string_2 = \"this is also a string\"\n", "string_3 = \"\"\"this is a string \n", "\n", "that contains some new-line characters\"\"\"\n", "string_4 = '''this is also a string \n", "\n", "that contains some new-line characters'''\n", "string_5 = 'My name is {}'\n", "string_6 = 'My name is {name} and I like {thing}'\n", "string_7 = 'Three things are {}, {}, and {}'\n", "list_1 = [8, 7.1, -3, num_1, num_2, num_3, -99]\n", "list_2 = ['dog', 'cat', 'mouse', 55, string_2]\n", "list_3 = [8, 7.1, -3, -3, -8, num_1, num_2, num_3, -99]\n", "tuple_1 = (8, 7.1, -3, num_1, num_2, num_3, -99)\n", "tuple_2 = ('dog', 'cat', 'mouse', 55, string_2)\n", "tuple_3 = (8, 7.1, -3, -3, -8, num_1, num_2, num_3, -99)\n", "set_1 = {8, 7.1, -3, num_1, num_2, num_3, -99}\n", "set_2 = {'dog', 'cat', 'mouse', 55, string_2}\n", "set_3 = {8, 7.1, -3, -3, -8, num_1, num_2, num_3, -99}\n", "\n", "# Some more complex variables\n", "dict_1 = {'a': 1, 'b': 22, 'c': list_1, 'd': string_3}\n", "dict_2 = {\n", " 'a': 539.11,\n", " 'b': tuple_2,\n", " 'c': [set_1, set_2],\n", " ('dog', 'cat'): 'a tuple can be a \"key\" in a dictionary'\n", "}\n", "list_of_dicts_1 = [\n", " {\n", " 'a': 1,\n", " 'b': 2,\n", " 'c': -3.99,\n", " },\n", " {\n", " 'a': 4,\n", " 'b': -5.1,\n", " 'c': 6,\n", " },\n", " {\n", " 'a': 14.3,\n", " 'b': 25,\n", " 'c': -36,\n", " }\n", "]\n", "list_of_tuples_1 = [\n", " ('cat', 'mouse'),\n", " ('cheese', 'stick'),\n", " ('shoe', 'sock'),\n", " ('bear', 'cactus'),\n", " ('ring', 'rose'),\n", "]\n", "list_of_tuples_2 = [\n", " (3.2, -2, 2.9, 3),\n", " (5, 2.5, 2.4, 8.6),\n", " (4.7, -24, 2.9, 3),\n", " (12, 22, -0.9, 7),\n", " (2.76, 8, 9, -1),\n", " (-2, 12, 2.4, 13),\n", " (6, 1.5, 2.9, -7.3),\n", " (2.1, -2.2, 2.9, 3.8),\n", "]\n", "my_vars_list = [\n", " num_1, num_2, num_3, string_1, string_2, string_3, string_4, string_5,\n", " string_6, string_7, list_1, list_2, list_3, tuple_1, tuple_2, tuple_3,\n", " set_1, set_2, set_3, dict_1, dict_2, list_of_dicts_1,\n", "]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python built-in functions\n", "\n", "A function is a Python object that you can \"call\" to **perform an action**, by placing parentheses to the right of the function name. Some functions allow you to pass **arguments** inside the parentheses (separating multiple arguments with a comma). Internal to the function, these arguments are treated like variables.\n", "\n", "A Python object is a **function** if it is **callable**. You can check this by using the built-in function `callable()`, and passing in the object as an argument.\n", "\n", "Python has several useful built-in functions to help you work with different objects and/or your environment.\n", "\n", "- `help()`\n", "- `print()`\n", "- `repr()`\n", "- `dir()`\n", "- `callable()`\n", "- `type()`\n", "- `len()`\n", "- `range()`\n", "- `sorted()`\n", "- `input()`\n", "- `locals()`\n", "- `sum()`\n", "- `min()`\n", "- `max()`\n", "- `abs()`\n", "\n", "> Complete list of built-in functions: https://docs.python.org/3/library/functions.html" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Using the `help` function to get information about the `print`, `repr`, and `dir` functions\n", "help(print)\n", "help(repr)\n", "help(dir)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Print some string variables\n", "print(string_1)\n", "print(string_2)\n", "print(string_3)\n", "print(string_4)\n", "print(string_5)\n", "print(string_6)\n", "print(string_7)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Print string representations of some string variables\n", "print(repr(string_1))\n", "print(repr(string_2))\n", "print(repr(string_3))\n", "print(repr(string_4))\n", "print(repr(string_5))\n", "print(repr(string_6))\n", "print(repr(string_7))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python object attributes (methods and properties)\n", "\n", "Different types of objects in Python have different **attributes** that can be referred to by name (similar to a variable). To access an attribute of an object, use a dot (`.`) after the object, then specify the attribute (i.e. `obj.attribute`)\n", "\n", "When an attribute of an object is a callable, that attribute is called a **method**. It is the same as a function, only this function is bound to a particular object.\n", "\n", "When an attribute of an object is not a callable, that attribute is called a **property**. It is just a piece of data about the object, that is itself another object." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Is the `format` attribute on the `string_5` object a callable?\n", "callable(string_5.format)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Call the `format` method on a couple string variables\n", "# - in the first example we pass the string 'Jeff' as a POSITIONAL ARGUMENT to the format method on string_5\n", "# - in the other two examples, we pass KEYWORD ARGUMENTS to the format method on string_6\n", "print(string_5.format('Jeff'))\n", "print(string_6.format(name='Mary', thing='to dance'))\n", "print(string_6.format(name='Todd', thing='dogs'))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Call some other methods that exist on string objects\n", "print(string_1.capitalize())\n", "print(string_1.upper())\n", "print(string_1.replace('i', '!')) # two positional arguments\n", "print(string_1.replace('is', 'XX'))\n", "print(len(string_1))\n", "print(string_1.count(' '))\n", "print(string_1.startswith('this'))\n", "print(string_1.startswith('This'))\n", "print(string_1.endswith('ing'))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Show help on the `replace` method of string_1\n", "help(string_1.replace)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python lists, tuples, and sets\n", "\n", "These three are basic types of containers that can hold any other type of object (actually, sets can't contains **mutable objects** that can be changed). It is common for a collection of objects to be of the same type, but they don't have to be.\n", "\n", "For all three container types, **use a comma to separate the individual items** as you are defining them.\n", "\n", "When you define a list or a tuple with some items, those items are stored in the order that they were defined. \n", "\n", "A **set does NOT store items in the order they were defined**. A set **also does not contain duplicates** and can only contain imutable objects (objects that can't be changed). Set objects provide **set operations** (like `difference`, `intersection`, and `union`) as methods.\n", "\n", "When you have a defined list or set, you can add/remove items as you want to. A **tuple cannot be modified once it is defined**." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Print some collections of numbers\n", "# - remember, a set does not store items in the order they were defined in\n", "print(list_3)\n", "print(tuple_3)\n", "print(set_3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Print the lengths of each container (number of items)\n", "# - remember, a set does not store duplicate items\n", "print(len(list_3))\n", "print(len(tuple_3))\n", "print(len(set_3))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Print the type of each container\n", "print(type(list_3))\n", "print(type(tuple_3))\n", "print(type(set_3))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Print the sum of numbers in each container\n", "print(sum(list_3))\n", "print(sum(tuple_3))\n", "print(sum(set_3))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Print the largest number in each container\n", "print(max(list_3))\n", "print(max(tuple_3))\n", "print(max(set_3))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Print the smallest number in each container\n", "print(min(list_3))\n", "print(min(tuple_3))\n", "print(min(set_3))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Print each container in sorted order\n", "print(sorted(list_3))\n", "print(sorted(tuple_3))\n", "print(sorted(set_3))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Print each container in reverse sorted order\n", "print(sorted(list_3, reverse=True))\n", "print(sorted(tuple_3, reverse=True))\n", "print(sorted(set_3, reverse=True))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Add a single item to `list_3` and `set_3`\n", "# - remember, cannot modify a tuple\n", "# - also, notice that the method name is different between a list object and a set object\n", "list_3.append(50)\n", "set_3.add(50)\n", "print(list_3)\n", "print(set_3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Remove an item from `list_3` and `set_3`\n", "list_3.remove(50)\n", "set_3.remove(50)\n", "print(list_3)\n", "print(set_3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Add multiple items to `list_3` and `set_3`\n", "list_3.extend([6, 4, 0])\n", "set_3.update([6, 4, 0])\n", "print(list_3)\n", "print(set_3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python dictionaries\n", "\n", "A dictionary is another type of container that can hold objects. Unlike the list, tuple, and set containers that just hold objects, you must specify a **key** for every object in the dictionary.\n", "\n", "- the key is usually a string, but it may also be a tuple or other **immutable type** (an object that cannot be modified after it's created) \n", "\n", "Like a set, a dictionary has no concept of order. Also like a set you may not have duplicate keys." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Print `dict_1`\n", "print(dict_1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Print the keys of `dict_1`\n", "print(dict_1.keys())" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Print the values of `dict_1`\n", "print(dict_1.values())" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Print the items (key/value pairs) of `dict_1`\n", "print(dict_1.items())" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Create an empty dictionary, add a single key, then add multiple keys\n", "d = {}\n", "d['name'] = 'Sally'\n", "d.update({\n", " 'age': 13,\n", " 'fav_foods': ['pizza', 'sushi', 'pad thai', 'waffles'],\n", " 'fav_color': 'green',\n", " })\n", "print(d)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Update a dictionary\n", "d.update({\n", " 'age': 14,\n", " 'fav_foods': ['sushi', 'pad thai', 'waffles'],\n", " 'fav_color': 'emerald',\n", " 'num_computers': 2,\n", " })\n", "print(d)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Update a dictionary again\n", "d.update({\n", " 'fav_color': 'black',\n", " 'num_computers': 3,\n", " })\n", "print(d)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Remove a key from a dictionary\n", "del(d['fav_color'])\n", "print(d)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Update dictionary again, by modifying the value of a specific key\n", "d['fav_foods'].append('crepes')\n", "print(d)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Accessing data in Python containers\n", "\n", "Since containers are meant to hold many different objects, we need a way to select the items we are interested in from our containers.\n", "\n", "For items in lists, tuples, and dictionaries, use the **subscript operator** (square bracket notation) to access them.\n", "\n", "- lists and tuples use a **numerical index**\n", " - indexing starts at 0\n", " - negative index can be used to select an item closer to the end of the container\n", "- dictionaries use a **key** index (which is typically a string or a tuple)\n", "- sets do not support indexing, so you cannot use the subscript operator" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(list_3)\n", "print(tuple_3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Access FIRST item of a list or tuple (remember, sets have no concept of order)\n", "print(list_3[0])\n", "print(tuple_3[0])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Access second item of a list or tuple\n", "print(list_3[1])\n", "print(tuple_3[1])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Access LAST item of a list or tuple\n", "print(list_3[-1])\n", "print(tuple_3[-1])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Access a range of items from a list or tuple using \"slicing\"\n", "print(list_3[2:-2])\n", "print(tuple_3[2:-2])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Access a different range of items from a list or tuple using \"slicing\"\n", "print(list_3[:3])\n", "print(tuple_3[:3])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(dict_1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Access item with key 'c' in `dict_1` \n", "# - cannot select \"slices\" of a dictionary since the keys are not ordered\n", "print(dict_1['c'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Access the first item of the list at key 'c' in `dict_1`\n", "print(dict_1['c'][0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Arguments and keyword arguments to Python callables\n", "\n", "You can call a function/method in a number of different ways:\n", "\n", "- `func()`: Call `func` with no arguments\n", "- `func(arg)`: Call `func` with one positional argument\n", "- `func(arg1, arg2)`: Call `func` with two positional arguments\n", "- `func(arg1, arg2, ..., argn)`: Call `func` with many positional arguments\n", "- `func(kwarg=value)`: Call `func` with one keyword argument \n", "- `func(kwarg1=value1, kwarg2=value2)`: Call `func` with two keyword arguments\n", "- `func(kwarg1=value1, kwarg2=value2, ..., kwargn=valuen)`: Call `func` with many keyword arguments\n", "- `func(arg1, arg2, kwarg1=value1, kwarg2=value2)`: Call `func` with positonal arguments and keyword arguments\n", "- `obj.method()`: Same for `func`.. and every other `func` example\n", "\n", "When using **positional arguments**, you must provide them in the order that the function defined them (the function's **signature**).\n", "\n", "When using **keyword arguments**, you can provide the arguments you want, as long as you specify each argument's name.\n", "\n", "When using positional and keyword arguments, positional arguments must come first." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Function call with no arguments\n", "dict_1.keys()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Function call with one positional argument\n", "string_1.endswith('ing')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Function call with two positional arguments\n", "string_1.replace('is', 'XX')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Function call with two keyword arguments\n", "string_6.format(name='Mary', thing='to dance')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Function call with a positional argument and a keyword argument\n", "sorted(list_3, reverse=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Simple on-the-fly callable objects (lambda function)\n", "\n", "A lambda function can be used wherever a function object is required.\n", "\n", "A lambda function can only contain a single expression." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Use a lambda function to specify the \"sort key\" function argument to `sorted`\n", "# - this will cause the `sorted` function to sort `list_of_dict_1` by the value at key `b`\n", "sorted(list_of_dicts_1, key=lambda x: x['b'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Define three callable objects\n", "say_hi = lambda: print('Hi!')\n", "make_it_upper = lambda x: x.upper()\n", "do_number_stuff = lambda x, y: 2 * x + 3 * y\n", "\n", "print(callable(say_hi))\n", "print(type(say_hi))\n", "say_hi()\n", "print(make_it_upper('this is a string'))\n", "\n", "# Remember, the order of positional arguments matters (but not keyword arguments)\n", "print(do_number_stuff(1, 2))\n", "print(do_number_stuff(2, 1))\n", "print(do_number_stuff(x=0.15, y=20))\n", "print(do_number_stuff(y=20, x=0.15))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tuple assignment\n", "\n", "If you have a tuple of items, you can assign each one to a separate variable using tuple assignment (in a single statement).\n", "\n", "You can also use tuples to swap the values of multiple variables." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a, b, c = (2, 4, 6)\n", "print(a)\n", "print(b)\n", "print(c)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Swap the values of multiple variables\n", "# - `a` becomes what `b` originally was\n", "# - `c` becomes what `a` originally was\n", "# - `b` becomes what `c` originally was\n", "a, c, b = b, a, c\n", "print(a)\n", "print(b)\n", "print(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python \"for\" loops\n", "\n", "It is easy to **iterate** over a collection of items using a **for loop**. The lists, tuples, sets, and dictionaries we defined are all built-in **containers** that you can iterate over. (Actually, the strings are containers of characters that we can iterate over as well).\n", "\n", "The for loop will go through the specified container, one item at a time, and provide a temporary variable for the current item. You can use this temporary variable like a normal variable." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Iterate through `list_1` and display each item on a new line\n", "for item in list_1:\n", " print(item)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Iterate through `list_1` and display the absolute value of each item on a new line\n", "for item in list_1:\n", " print(abs(item))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Iterate through `list_1` and print a string for each item\n", "for num in list_1:\n", " print('Absolute value of {} is {}'.format(num, abs(num)))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Iterate through `string_1` and print each character on a new line\n", "for character in string_1:\n", " print(character)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Iterate through `dict_1` and display each key on a new line\n", "for key in dict_1:\n", " print(key)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Using for loops with tuple assignment\n", "\n", "You may have noticed that when you call the `.items()` method on a dictionary object, you receive a list of 2-item tuples.\n", "\n", "It is possible to iterate over this data and use tuple assignment to store the intermediate values of each key/value pair." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Iterate through `dict_1.items()` and display each key and value in a formatted string\n", "for key, value in dict_1.items():\n", " print('{} -> {}'.format(key, value))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Iterate through `dict_1.items()` and display each item (no tuple assignment)\n", "for item in dict_1.items():\n", " print(item)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python booleans and \"conditional expressions\"\n", "\n", "A boolean object has a value of `True` or `False`. A conditional expression is one that evaluates to a boolean value. This allows you to ask questions about your data so you can make a decision to \"do something\" or \"do something else\" next." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Does the key 'a' exist in the dictionary `dict_1`?\n", "'a' in dict_1" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Are there more than 5 keys in `dict_1`?\n", "len(dict_1.keys()) > 5" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Does `string_1` start with 'this'?\n", "string_1.startswith('this')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Does `string_1` start with 'This'?\n", "string_1.startswith('This')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Is the smallest item in `list_1` less than 0?\n", "min(list_1) < 0" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Is the string 'dogs' a sub-string of a longer string?\n", "'dogs' in 'there are some dogs and cats'" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Is 5 times 5 equal to 25?\n", "5 * 5 == 25" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(num_1, num_2, num_3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Is `num_1` larger than `num_2` and `num_3`?\n", "num_1 > num_2 and num_1 > num_3" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Is `num_1` less than `num_2` OR is `num_1` greater than `num_3`?\n", "num_1 < num_2 or num_1 > num_3" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Is `num_3` between `num_1` and `num_2`?\n", "num_1 > num_3 > num_2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python \"if statements\" and \"while loops\"\n", "\n", "Conditional expressions can be used with these two **conditional statements**.\n", "\n", "The **if statement** allows you to test a condition and perform some actions if the condition evaluates to `True`.\n", "\n", "The **while loop** will keep looping until its conditional expression evaluates to `False`. The **for loop** will iterate over a container of items until there are no more (no need to specify a \"stop looping\" condition).\n", "\n", "It is possible to \"loop forever\" when using a while loop with a conditional expression that never evaluates to `False` (i.e. `while True:`)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "if num_1 > num_3 > num_2:\n", " print('num_3 is between num_1 and num_2')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "if string_1.startswith('This'):\n", " print('string_1 starts with \"This\"')\n", "else:\n", " print('string_1 does not start with \"This\"')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "if num_1 < 0:\n", " print('num_1 is less than 0')\n", "elif num_1 == 0:\n", " print('num_1 is equal to 0')\n", "else:\n", " print('num_1 is greater than 0')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "thing = ''\n", "while not thing:\n", " thing = input('please type stuff and hit : ')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "thing" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Creating objects from other objects\n", "\n", "Sometimes, you will have an object of one type that you need to make into another type. Use the **type constructor** for the type of object you want to have, and pass in the object you currently have." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(int)\n", "print(float)\n", "print(str)\n", "print(list)\n", "print(tuple)\n", "print(set)\n", "print(dict)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(type(int))\n", "print(type(float))\n", "print(type(str))\n", "print(type(list))\n", "print(type(tuple))\n", "print(type(set))\n", "print(type(dict))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(float(123))\n", "print(int(1.23))\n", "print(list(string_1))\n", "print(dict(list_of_tuples_1))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Sometimes, the type of object you have may have a method to return an object of the type you want\n", "print(', '.join(['jump', 'run', 'play']))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exceptions" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Create an int from string 'stuff'\n", "int('stuff')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# If creating an int raises a `ValueError` print a message instead\n", "try:\n", " int('stuff')\n", "except ValueError:\n", " print('You cannot make an int out of that')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Catch the exception, do something, then re-raise the exception\n", "try:\n", " int('stuff')\n", "except ValueError:\n", " print('You cannot make an int out of that')\n", " raise" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Can't divide by zero\n", "1/0" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Can't reference a dictionary key that doesn't exist\n", "dict_1['not-a-real-key'] + 10" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Use the `get` method on the dictionary to fetch my key\n", "# - will return a `NoneType`, instead of raising a `KeyError`\n", "# - but a `NoneType` can't be added to an `int`, so a `TypeError` gets raised\n", "dict_1.get('not-a-real-key') + 10" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Specify a default value to return if the key doesn't exist in the dictionary\n", "dict_1.get('not-a-real-key', 0) + 10" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# There is no such variable defined called `not_a_dict`, so a `NameError` is raised\n", "not_a_dict['not-a-key']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Creating your own objects\n", "\n", "> TODO: Super brief intro to classes" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(object)\n", "print(type(object))\n", "print(dict)\n", "print(type(dict))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# `dict` is a sub-class of `object`\n", "# `set` is a sub-class of `object`\n", "# `int` is a sub-class of `object`\n", "# `set` is not a sub-class of `dict`\n", "print(issubclass(dict, object))\n", "print(issubclass(set, object))\n", "print(issubclass(int, object))\n", "print(issubclass(set, dict))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Define a new class called `Thing` that is derived from the base Python object\n", "class Thing(object):\n", " my_property = 'I am a \"Thing\"'\n", "\n", "\n", "# Define a new class called `DictThing` that is derived from the `dict` type (which is a class)\n", "class DictThing(dict):\n", " my_property = 'I am a \"DictThing\"'" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(Thing)\n", "print(type(Thing))\n", "print(DictThing)\n", "print(type(DictThing))\n", "print(issubclass(DictThing, dict))\n", "print(issubclass(DictThing, object))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Create \"instances\" of our new classes\n", "t = Thing()\n", "d = DictThing()\n", "print(t)\n", "print(type(t))\n", "print(d)\n", "print(type(d))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Interact with a DictThing instance just as you would a normal dictionary\n", "d['name'] = 'Sally'\n", "print(d)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "d.update({\n", " 'age': 13,\n", " 'fav_foods': ['pizza', 'sushi', 'pad thai', 'waffles'],\n", " 'fav_color': 'green',\n", " })\n", "print(d)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(d.my_property)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## TODO\n", "\n", "Add the following sections before \"putting things together\"\n", "\n", "- importing modules\n", "- defining functions\n", "- `__name__`\n", "- list comprehension\n", "- conditional assignment\n", "- unpacking argument lists and keywoard argument dicts\n", "- getattr" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "
\n", "# Putting things together (complex examples)\n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import sys\n", "\n", "def module_objects(module=__name__):\n", " \"\"\"Return a list of dicts with info about objects in the given module (or module name)\n", " \n", " - attr_name: name of the object\n", " - module_name: name of the module containing the object\n", " - type: type of the object\n", " - is_callable: True if the object is a function\n", " - simple_value: None, or value of the object if it is a simple type (str, int, float)\n", " \"\"\"\n", " if type(module) == str:\n", " module = sys.modules.get(module)\n", " \n", " data = []\n", " for attr_name in sorted(dir(module)):\n", " obj = getattr(module, attr_name)\n", " obj_info = {\n", " 'attr_name': attr_name,\n", " 'module_name': module.__name__,\n", " 'type': type(obj),\n", " 'is_callable': True if callable(obj) else False,\n", " 'simple_value': obj if type(obj) in (str, int, float) else None,\n", " }\n", " data.append(obj_info)\n", " \n", " return data" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "sorted(sys.modules.keys())" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "module_objects('random')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "module_objects('concurrent.futures.thread')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "[\n", " '{attr_name} from {module_name} is a {type}'.format(**thing)\n", " for thing in module_objects()\n", " if thing['is_callable']\n", "]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "[\n", " '{attr_name} from {module_name} is a {type}'.format(**thing)\n", " for thing in module_objects(sys)\n", " if thing['is_callable']\n", "]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "[\n", " '{attr_name} from {module_name} is a {type}'.format(**thing)\n", " for thing in module_objects('re')\n", " if thing['is_callable']\n", "]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "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.4.3" } }, "nbformat": 4, "nbformat_minor": 0 }