{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Programming in python\n", "\n", "## Topics\n", "* Variables\n", "* Numbers\n", "* Booleans\n", "* Objects\n", "* Strings\n", "* Tuples, lists and dictionaries\n", "* Flow control, part 1\n", " * If\n", " * For\n", " * range() function" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Variables\n", "\n", "In a nutshell, a variable is a memory location where you can store a value. This value may or may not change in the future. In Python, to declare a variable, you just have to assign a variable to it." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that in a Jupyter notebook, assigning something to a variable does NOT print it out when you run the cell. To see the value of a variable, you can either use the print statement:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or you can just put the variable itself inline, and Jupyter will automatically print out the variable value for you, without using print." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that it will only print out the LAST variable in the cell, even if you put more than one variable" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x\n", "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Numbers\n", "\n", "Numbers are a set of data types that mainly have numerical values. We have 3 different data types to represent numbers — `integer`, `float`, and `complex`. We won't talk about complex numbers today but you can read about them later if you're interested!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 1\n", "type(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 1.29\n", "type(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Number operations\n", "\n", "As you saw in the previous breakout, Python typically respects the standard order of operations (PEMDAS):\n", "\n", "1. P - Parentheses\n", "1. E - Exponentiation\n", "1. M/D - Multiplication/division\n", "1. A/S - Addition/subtraction\n", "\n", "In Python, there are additional operators such as the bitwise operators we saw before. The full table looks something like this:\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = (10 + 12 * 3 % 34 / 8)\n", "b = (4 ^ 2 << 3 + 48 // 24)\n", "\n", "\n", "print(a)\n", "print(b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Booleans\n", "\n", "Booleans represent one of two values: True or False. In Python, these are the literals `True` and `False`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = True\n", "type(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You might have noticed the boolean operators and comparisons in the above table for order of operations. The results of these operations are booleans." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 1\n", "y = 2\n", "num = x < y\n", "print(num)\n", "type(num)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Note**: Comparison vs Identity Operators\n", "\n", "The following are comparison operators: `==`, `!=`, `<`, etc.\n", "\n", "The following are identity operators: `is`, `is not`\n", "\n", "Comparison and identity operators are not quite the same thing!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = 35454\n", "b = 35454" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a is b" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a == b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Objects\n", "\n", "Past this point, all of the data types we are going to talk about are actually \"objects\". Some programming languages are called \"object-oriented\" (like Python). This means that things (variables, entities, etc) within your code are actually a tiny package of both data and functionality. Think of objects like a radio: a radio has data (ie what station it is tuned to) as well as functionality associated with it (ie turn the radio on/off, change the station). When you have a variable that is an object, you can access the functionality of that variable using the `.` notation, ie `var.function()`. We saw this in the previous breakout when we accessed things on the `math` module - modules are actually objects too!\n", "\n", "Numbers and booleans are more primitive - they are data only, no associated functions." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Strings\n", "\n", "In programming, a string is a data type that is written in single `''` or double `\"\"` quotes. It can contain numbers and special characters but they will be evaluated as actual letters rather than the numerical values.\n", "\n", "Strings are **not mutable** - they cannot be changed after they have been created." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_string = \"This is a double-quoted string.\"\n", "my_string = 'This is a single-quoted string.'\n", "my_string" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "type(my_string)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "quote = \"Linus Torvalds once said, 'Any program is only as good as it is useful.'\"\n", "quote" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### String operators / functions\n", "\n", "All string methods can be found here: https://docs.python.org/3.10/library/stdtypes.html#string-methods\n", "\n", "Or you can use tab completion like we learned in the last breakout to explore what you can do with strings.\n", "\n", "For example, how could we convert a string to \"title case\" ie the first letter of each word is capitablized?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "book_title = 'the great gatsby'\n", "book_title.title()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A common NLP application is to parse sentences and break the sentences down into words (aka Tokenization)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sentence = 'this is a sentence that I want to break down!'\n", "sentence.split()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice what happened (or didn't!) to the original string after splitting:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sentence" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We often want to do this for CSV (comma-separated value) data files, where columns are separated by commas. In this case, we can also specify what delimiter we want to split the string on:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "csv_string = '1,2,3,4,name,age,value,location'\n", "csv_string.split(',')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python also has a built-in way to get the length of a string:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "len(csv_string)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Lastly, you can add strings together with the plus operator. We call this \"concatenation\", and it results in the combination of the two strings together." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "'hello' + ' DATA 515!'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### String indexing\n", "\n", "What if we want to access certain characters in a string?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a_string = 'This is a string'\n", "a_string[0] #output the 0th index (1st character) in the string from the left side" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a_string[4]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Recall that Python indexes start at 0. So the first character in a string is 0 and the last is string length - 1. You can also address from the `end` to the `front` by using negative (`-`) indexes, e.g." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a_string[-1] #output the last character in the string" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Tuples\n", "\n", "Let's begin by creating a tuple called `my_tuple` that contains three elements." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_tuple = ('I', 'like', 'cake')\n", "my_tuple" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tuples are simple containers for data. They are ordered, meaining the order the elements are in when the tuple is created are preserved. We can get values from our tuple by using array indexing, similar to what we were doing with pandas." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_tuple[0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_tuple[-1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also access a range of elements, e.g. the first two, the first three, by using the `:` to expand a range. This is called ``slicing``." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_tuple[0:2]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_tuple[0:3]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What do you notice about how the upper bound is referenced?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Without either end, the ``:`` expands to the entire list." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_tuple[1:]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_tuple[:-1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_tuple[:]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tuples have a key feature that distinguishes them from other types of object containers in Python. They are _immutable_. This means that once the values are set, they cannot change." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_tuple[2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So what happens if I decide that I really prefer pie over cake?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#my_tuple[2] = 'pie'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Facts about tuples:\n", "* You can't add elements to a tuple. Tuples have no append or extend method.\n", "* You can't remove elements from a tuple. Tuples have no remove or pop method.\n", "* You can also use the in operator to check if an element exists in the tuple.\n", "\n", "So then, what are the use cases of tuples? \n", "* Speed\n", "* `Write-protects` data that other pieces of code should not alter" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can alter the value of a tuple variable, e.g. change the tuple it holds, but you can't modify it." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_tuple" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_tuple = ('I', 'love', 'pie')\n", "my_tuple" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There is a really handy operator ``in`` that can be used with tuples that will return `True` if an element is present in a tuple and `False` otherwise." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "'love' in my_tuple" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, tuples can contain different types of data, not just strings." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import math\n", "my_second_tuple = (42, 'Elephants', 'ate', math.pi)\n", "my_second_tuple" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Numerical operators work... Sort of. What happens when you add? \n", "\n", "``my_second_tuple + 'plus'``" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Not what you expects? What about adding two tuples?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_second_tuple + my_tuple" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Other operators: -, /, *" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Questions about tuples before we move on?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "### Lists\n", "\n", "Let's begin by creating a list called `my_list` that contains three elements." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_list = ['I', 'like', 'cake']\n", "my_list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "At first glance, tuples and lists look pretty similar. Notice the lists use '[' and ']' instead of '(' and ')'. But indexing and refering to the first entry as 0 and the last as -1 still works the same." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_list[0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_list[-1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_list[0:3]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lists, however, unlike tuples, are mutable. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_list[2] = 'pie'\n", "my_list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Multiple elements in the list can even be changed at once!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_list[1:] = ['love', 'puppies']\n", "my_list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can still use the `in` operator." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "'puppies' in my_list" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "'kittens' in my_list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So when to use a tuple and when to use a list?\n", "\n", "* Use a list when you will modify it after it is created?\n", "\n", "Ways to modify a list? You have already seen by index. Let's start with an empty list." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_new_list = []\n", "my_new_list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can add to the list using the append method on it." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_new_list.append('Now')\n", "my_new_list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can use the `+` operator to create a longer list by adding the contents of two lists together." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_new_list + my_list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One of the useful things to know about a list how many elements are in it. This can be found with the `len` function." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "len(my_list)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some other handy functions with lists:\n", "* max\n", "* min" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sometimes you have a tuple and you need to make it a list. You can `cast` the tuple to a list with ``list(my_tuple)``" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "list(my_tuple)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What in the above told us it was a list? \n", "\n", "You can also use the ``type`` function to figure out the type." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "type(tuple)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "type(list(my_tuple))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are other useful methods on lists, including:\n", "\n", "| methods | description |\n", "|---|---|\n", "| list.append(obj) | Appends object obj to list |\n", "| list.count(obj)| Returns count of how many times obj occurs in list |\n", "| list.extend(seq) | Appends the contents of seq to list |\n", "| list.index(obj) | Returns the lowest index in list that obj appears |\n", "| list.insert(index, obj) | Inserts object obj into list at offset index |\n", "| list.pop(obj=list[-1]) | Removes and returns last object or obj from list |\n", "| list.remove(obj) | Removes object obj from list |\n", "| list.reverse() | Reverses objects of list in place |\n", "| list.sort([func]) | Sort objects of list, use compare func, if given |\n", "\n", "Try some of them now.\n", "\n", "```\n", "my_list.count('I')\n", "my_list\n", "\n", "my_list.append('I')\n", "my_list\n", "\n", "my_list.count('I')\n", "my_list\n", "\n", "#my_list.index(42)\n", "\n", "my_list.index('puppies')\n", "my_list\n", "\n", "my_list.insert(my_list.index('puppies'), 'furry')\n", "my_list\n", "\n", "my_list.pop()\n", "my_list\n", "\n", "my_list.remove('puppies')\n", "my_list\n", "\n", "my_list.append('cabbages')\n", "my_list\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Any questions about lists before we move on?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "### Dictionaries\n", "\n", "Dictionaries are similar to tuples and lists in that they hold a collection of objects. Dictionaries, however, allow an additional indexing mode: keys. Think of a real dictionary where the elements in it are the definitions of the words and the keys to retrieve the entries are the words themselves.\n", "\n", "| word | definition |\n", "|------|------------|\n", "| tuple | An immutable collection of ordered objects |\n", "| list | A mutable collection of ordered objects |\n", "| dictionary | A mutable collection of named objects |\n", "\n", "Let's create this data structure now. Dictionaries, like tuples and elements use a unique referencing method, '{' and its evil twin '}'." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_dict = { 'tuple' : 'An immutable collection of ordered objects',\n", " 'list' : 'A mutable collection of ordered objects',\n", " 'dictionary' : 'A mutable collection of objects' }\n", "my_dict" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We access items in the dictionary by name, e.g. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_dict['dictionary']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since the dictionary is mutable, you can change the entries." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_dict['dictionary'] = 'A mutable collection of named objects'\n", "my_dict" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### As of Python 3.7 the ordering is guaranteed to be insertion order but that does not mean alphabetical or otherwise sorted.\n", "\n", "And we can add new items to the list." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_dict['cabbage'] = 'Green leafy plant in the Brassica family'\n", "my_dict" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To delete an entry, we can't just set it to ``None``" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_dict['cabbage'] = None\n", "my_dict" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To delete it propery, we need to pop that specific entry." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_dict.pop('cabbage', None)\n", "my_dict" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Tangent:** we've also just discovered a new type in Python: `None`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "notHere = None\n", "type(notHere)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we can see, `None` has a special type just for itself. However, there's another unexpected characteristic of `None`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "alsoNotHere = None\n", "print(notHere is notHere)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When you say `None`, we are actually referring to what is called a *singleton*. Because `None` is only ever just `None`, Python only ever creates ONE of these objects. Every `None` is the same `None` in memory, so you can do `is` on two variables that store `None`. Of course, you can also use `==` if you like, but the typical Pythonic way that we test whether something is `None` is with the `is` operator." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "notHere is None" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Back to dictionaries!** You can use other objects as names, but that is a topic for another time. You can mix and match key types, e.g." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_new_dict = {}\n", "my_new_dict[1] = 'One'\n", "my_new_dict['42'] = 42\n", "my_new_dict" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can get a list of keys in the dictionary by using the ``keys`` method." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_dict.keys()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similarly the contents of the dictionary with the ``items`` method." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_dict.items()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can use the keys list for fun stuff, e.g. with the ``in`` operator." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "'dictionary' in my_dict.keys()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is a synonym for `in my_dict`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "'dictionary' in my_dict" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice, it doesn't work for elements." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "'A mutable collection of ordered objects' in my_dict" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Other dictionary methods:\n", "\n", "| methods | description |\n", "|---|---|\n", "| dict.clear() | Removes all elements from dict |\n", "| dict.get(key, default=None) | For ``key`` key, returns value or ``default`` if key doesn't exist in dict | \n", "| dict.items() | Returns a list of dicts (key, value) tuple pairs | \n", "| dict.keys() | Returns a list of dictionary keys |\n", "| dict.setdefault(key, default=None) | Similar to get, but set the value of key if it doesn't exist in dict |\n", "| dict.update(dict2) | Add the key / value pairs in dict2 to dict |\n", "| dict.values | Returns a list of dictionary values|\n", "\n", "Feel free to experiment..." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "## Flow control\n", "\n", "Flow control figure\n", "\n", "Flow control refers how to programs do loops, conditional execution, and order of functional operations. Let's start with conditionals, or the venerable ``if`` statement.\n", "\n", "Let's start with a simple list of instructors for these classes." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "instructors = ['Melissa', 'Baisakhi', 'Murf the Clown']\n", "instructors" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### If\n", "If statements can be use to execute some lines or block of code if a particular condition is satisfied. E.g. Let's print something based on the entries in the list." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "if 'Murf the Clown' in instructors:\n", " print('#fakeinstructor')" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "**Note that the indentation is really important!**\n", "\n", "Usually we want conditional logic on both sides of a binary condition, e.g. some action when ``True`` and some when ``False``" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "if 'Murf the Clown' in instructors:\n", " print('There are fake names for class instructors in your list!')\n", "else:\n", " print(\"Nothing to see here\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There is a special do nothing word: `pass` that skips over some arm of a conditional, e.g." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "if 'Baisakhi' in instructors:\n", " print(\"Congratulations! Baisakhi is teaching, your class won't stink!\")\n", "else:\n", " pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "_Note_: what have you noticed in this session about quotes? What is the difference between ``'`` and ``\"``?\n", "\n", "\n", "Another simple example:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "if True is False:\n", " print(\"I'm so confused\")\n", "else:\n", " print(\"Everything is right with the world\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is always good practice to handle all cases explicity. `Conditional fall through` is a common source of bugs.\n", "\n", "Sometimes we wish to test multiple conditions. Use `if`, `elif`, and `else`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_favorite = 'pie'\n", "\n", "if my_favorite == 'cake':\n", " print(\"He likes cake! I'll start making a double chocolate velvet cake right now!\")\n", "elif my_favorite == 'pie':\n", " print(\"He likes pie! I'll start making a cherry pie right now!\")\n", "else:\n", " print(\"He likes \" + my_favorite + \". I don't know how to make that.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Conditionals can take ``and`` and ``or`` and ``not``. E.g." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_favorite = 'pie'\n", "\n", "if my_favorite == 'cake' or my_favorite == 'pie':\n", " print(my_favorite + \" : I have a recipe for that!\")\n", "else:\n", " print(\"Ew! Who eats that?\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## For\n", "\n", "For loops are the standard loop, though `while` is also common. For has the general form:\n", "```\n", "for items in list:\n", " do stuff\n", "```\n", "\n", "For loops and collections like tuples, lists and dictionaries are natural friends." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for instructor in instructors:\n", " print(instructor)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can combine loops and conditionals:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for instructor in instructors:\n", " if instructor.endswith('Clown'):\n", " print(instructor + \" doesn't sound like a real instructor name!\")\n", " else:\n", " print(instructor + \" is so smart... all those gooey brains!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dictionaries can use the `keys` method for iterating." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for key in my_dict.keys():\n", " if len(key) > 5:\n", " print(my_dict[key])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### range()\n", "\n", "Since for operates over lists, it is common to want to do something like:\n", "```\n", "NOTE: C-like\n", "for (i = 0; i < 3; ++i) {\n", " print(i);\n", "}\n", "```\n", "\n", "The Python equivalent is:\n", "\n", "```\n", "for i in [0, 1, 2]:\n", " do something with i\n", "```\n", "\n", "What happens when the range you want to sample is big, e.g.\n", "```\n", "NOTE: C-like\n", "for (i = 0; i < 1000000000; ++i) {\n", " print(i);\n", "}\n", "```\n", "\n", "That would be a real pain in the rear to have to write out the entire list from 1 to 1000000000.\n", "\n", "Enter, the `range()` function. E.g.\n", " ```range(3) is [0, 1, 2]```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "range(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that Python (in the newest versions, e.g. 3+) has an object type that is a range. This saves memory and speeds up calculations vs. an explicit representation of a range as a list - but it can be automagically converted to a list on the fly by Python. To show the contents as a `list` we can use the type case like with the tuple above.\n", "\n", "Sometimes, in older Python docs, you will see `xrange`. This used the range object back in Python 2 and `range` returned an actual list. Beware of this!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "list(range(3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Remember earlier with slicing, the syntax `:3` meant `[0, 1, 2]`? Well, the same upper bound philosophy applies here.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for index in range(3):\n", " instructor = instructors[index]\n", " if instructor.endswith('Clown'):\n", " print(instructor + \" doesn't sound like a real instructor name!\")\n", " else:\n", " print(instructor + \" is so smart... all those gooey brains!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This would probably be better written as" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for index in range(len(instructors)):\n", " instructor = instructors[index]\n", " if instructor.endswith('Clown'):\n", " print(instructor + \" doesn't sound like a real instructor name!\")\n", " else:\n", " print(instructor + \" is so smart... all those gooey brains!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But in all, it isn't very Pythonesque to use indexes like that (unless you have another reason in the loop) and you would opt instead for the `instructor in instructors` form. \n", "\n", "More often, you are doing something with the numbers that requires them to be integers, e.g. math." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sum = 0\n", "for i in range(10):\n", " sum += i\n", "print(sum)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### For loops can be nested\n", "\n", "_Note_: for more on formatting strings, see: [https://pyformat.info](https://pyformat.info)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for i in range(1, 4):\n", " for j in range(1, 4):\n", " print('%d * %d = %d' % (i, j, i*j)) # Note string formatting here, %d means an integer" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### You can exit loops early if a condition is met:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for i in range(10):\n", " if i == 4:\n", " break\n", "i" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### You can skip stuff in a loop with `continue`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sum = 0\n", "for i in range(10):\n", " if (i == 5):\n", " continue\n", " else:\n", " sum += i\n", "print(sum)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### There is a unique language feature call ``for...else``" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sum = 0\n", "for i in range(10):\n", " sum += i\n", "else:\n", " print('final i = %d, and sum = %d' % (i, sum))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### You can iterate over letters in a string" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_string = \"DATA\"\n", "for c in my_string:\n", " print(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Exercise 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Write Python to find and print out those numbers which are divisible by 7 and multiples of 5, between 1500 and 2700 (both included)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Write your answer here\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Exercise 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Write a loop to print out the characters of the string `'reversing strings is fun'` in reverse order. Bonus: come up with at least two ways to do this." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Write your answer here\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Exercise 3\n", "\n", " Given a string (for example, `'The Great Gatsby'`), use a loop to print out whether the string is in \"title case\" or not - ie is the first letter of every word capitalized?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Write your answer here\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.11.11" }, "vscode": { "interpreter": { "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" } } }, "nbformat": 4, "nbformat_minor": 4 }