{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Notebook 2\n", "\n", "Run each command and try to understand why certain operations behave the way they do before looking at the answers." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Strings \n", "\n", "`word = 'Supercalifragilisticexpialidocious'` \n", "`word[5]` \n", "`word[0]` \n", "`word[-1]` \n", "`word[2000]` \n", "`word[0] = 's'`\n", "\n", "How many characters are there in `word?` \n", "What are the first 5 characters in `word?` \n", "What are the last 3 characters in `word?` \n", "Reverse the order of characters in `word` " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Strings - Answers" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'c'" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "word = 'Supercalifragilisticexpialidocious' \n", "word[5] " ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'S'" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "word[0] " ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'s'" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "word[-1]" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "ename": "IndexError", "evalue": "string index out of range", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mIndexError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mword\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m2000\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;31m# Python returns an IndexError when the index is out of range\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mIndexError\u001b[0m: string index out of range" ] } ], "source": [ "word[2000] # Python returns an IndexError when the index is out of range" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "'str' object does not support item assignment", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mword\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m's'\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mTypeError\u001b[0m: 'str' object does not support item assignment" ] } ], "source": [ "word[0] = 's'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python uses 0-based indexing for accessing elements in strings or lists. word[0] will access the first element of the string, while word[-1] will access the last element. Trying to access elements outside the range of the index will result in an IndexError. String are immutable, meaning we cannot assign new values to elements in the string, as demonstrated above" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\"Drawing\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "How many characters are there in word?\n", "\n", "\\- Use the len() function to get the length of a string or list" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "34" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(word)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What are the first 5 characters in word?\n", "\n", "\\- Remember that the slicing does not include the last element specified, but stops one element before. So the below would include elements from index 0,1,2,3,and 4, but not element at position 5." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Super'" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "word[0:5]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What are the last 3 characters in word?\n", "\n", "\\- As slicing does not include the last element specified, we cannot write word[-3:-1]. Instead, we omit the element to the right of : to indicate that we want the rest of the list. The same principle applies to omitting the element to the left of the : thus including everything from the start until but not including the element specified to the right of :" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'ous'" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "word[-3:]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Reverse the order of characters in word\n", "\n", "\\- Here we use the extended slicing with the form word[begin:end:step]. By omitting the begin and end part, and defining step as -1, we tell it to take the whole string, and go one step back at the time." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'suoicodilaipxecitsiligarfilacrepuS'" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "word[::-1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Lists\n", "\n", "`squares = [1, 4, 9, 16, 25]` \n", "\n", "`squares[0]` \n", "`squares[-1]` \n", "\n", "`squares[1] = 16` \n", "`squares`\n", "\n", "Add 36 to the list `square` \n", "You changed your mind, remove 36 from the list again \n", "Reverse the order of items in the list\n", "\n", "`justsaying = [\"Grammar, \", \"the difference between \", \"knowing you're shit and \",\"... \", \"knowing your shit\"]` \n", "`\"\".join(justsaying)`\n", "\n", "Make a list named `snplist` that contains rs2354, rs325678, rs32468, rs215456 \n", "Find out how long this list is \n", "\n", "Make a list with 5 random numbers (you can mix integers and floats) \n", "What is the maximum and minimum value in the list? \n", "What happens if you summarize all the values in the list? \n", "Is the result an int or float? Why?\n", "\n", "`cubes = [1, 8, 27, 64]` \n", "print appropriately to output the text `'This list has the length 4 and maximum value 64'`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Lists - Answers\n", "\n", "Lists are similar to strings and many operations can be performed similarly in both. They are both indexed in the same way, and can be manipulated in much the same ways. " ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "25\n" ] } ], "source": [ "squares = [1, 4, 9, 16, 25] \n", "\n", "print(squares[0])\n", "print(squares[-1])" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 16, 9, 16, 25]" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "squares[1] = 16\n", "squares" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One large difference between strings and lists is that lists are mutable. You can easily replace an item in a list using indexing, as shown above." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add 36 to the list squares\n", "\n", "\\- Use the append() method to add items to the end of a list. The append() method adds an item to the list in question, without having to re-assign the list to a new variable." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 16, 9, 16, 25, 36]" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "squares.append(36)\n", "squares" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Remove 36 from the list again\n", "\n", "\\- Easiest here is to use the pop() method, that removes the last item in a list. However, there are other options, both squares.remove(36) and del squares[5] will remove 36 from the list. squares.remove(36) will remove only the first instance of 36 in the list, while del square[5] will delete the item with index position 5." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 16, 9, 16, 25]" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "squares.pop()\n", "squares" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Reverse the order of the list\n", "\n", "\\- Here we have two options in contrast to when reversing the order of a string. We can both use squares[::-1], and squares.reverse(), which is a method that only works on lists. NOTE! While using squares[::-1] only displays the list in reverse order, squares.reverse() reverses it in place." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 16, 9, 16, 25]\n", "[25, 16, 9, 16, 1]\n", "[1, 16, 9, 16, 25]\n", "[25, 16, 9, 16, 1]\n" ] } ], "source": [ "print(squares)\n", "print(squares[::-1])\n", "print(squares)\n", "squares.reverse()\n", "print(squares)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"Grammar, the difference between knowing you're shit and ... knowing your shit\"" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "justsaying = [\"Grammar, \", \"the difference between \", \"knowing you're shit and \",\"... \", \"knowing your shit\"]\n", "\"\".join(justsaying)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Above we take all items in a list and join them together to a string using the join() method. The first string defines how to join the item, here the '' means no space in between when joining items." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Make a list with 5 random numbers (you can mix integers and floats) \n", "What is the maximum and minimum value in the list? \n", "What happens if you summarize all the values in the list? \n", "Is the result an int or float? Why? " ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "6.8 1\n", "19.94\n", "\n" ] } ], "source": [ "random = [1, 5, 4, 6.8, 3.14]\n", "print(max(random),min(random))\n", "print(sum(random))\n", "print(type(sum(random)))\n", "\n", "# In this example the summarized value is a float, as there are floats present in the list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Print appropriately to output the text 'This list has the length 4 and maximum value 64'" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This list has the length 4 and maximum value 64\n" ] } ], "source": [ "cubes = [1, 8, 27, 64]\n", "print('This list has the length '+str(len(cubes))+' and maximum value '+str(max(cubes)))\n", "\n", "# Don't forget to turn the integers into strings when concatenating with other strings" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Operators\n", "\n", "`5 > 3` \n", "`34 == 34.0` \n", "`4 + 5 >= 10 - 1` \n", "`9 != 9` \n", "`3.14 + 1 == 4.14` \n", "\n", "`x = 3.14` \n", "`y = 2` \n", "`z = [2,4,5,7,0]` \n", "\n", "`'a' in z` \n", "`y in z` \n", "\n", "`'a' not in z` \n", "\n", "`2 in z and y == 2` \n", "`4 in z and 9 in z` \n", "`2 in z or w == 5` \n", "`8 in z and w == 5` \n", "\n", "`2 in z and y == 2 or 1 in z` \n", "`2 in z or 4 in z and w == 2` " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Operators - Answers" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "5 > 3" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "34 == 34.0 # Comparing a float and an int like this will always be true" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "4 + 5 >= 10 - 1 # Remember order of precedence? addition is evaluated before the comparator" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "9 != 9 # Here we are claiming that 9 is not equal 9, which of course is False, as 9 equals 9" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3.14 + 1 == 4.14 # Watch out for this one! Remember how python approximates floats? This is such occasion to be aware of" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = 3.14\n", "y = 2\n", "z = [2,4,5,7,0]\n", "\n", "'a' in z # No strings in the list z" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y in z # Is 2 in the list with [2,4,5,7,0], which it is" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'a' not in z # As 'a' is not in the list, this evaluates to True" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 in z and y == 2 # Is the same as writing:\n", "True and y == 2 \n", "True and True # True and True will evaluate to True" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "4 in z and 9 in z # Is the same as writing:\n", "True and False" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 in z or w == 5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Above is an interesting example! We haven't even defined w, why doesn't python complain? Python uses a lazy approach called short-circuit evaluation when evaluating logical operators. If the left hand side of an OR statement evaluates to True, the entire statement must be true regardless of what the right side evaluates to. In this case python doesn't bother to evaluate the right hand side, meaning it never reads w == 5, thereby not caring that w is not defined. The case is the same for the AND statement as illustrated below. Here python evaluates 8 in z to False, meaning the entire expression has to be false, therefore not bothering to evaluate the right hand side with the undefined variable in." ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "8 in z and w == 5" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 in z and y == 2 or 1 in z" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 in z or 4 in z and w == 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the example above we have both AND and OR operators. In this case the AND operator has higher precedence than the OR operator. The above example would be the equivalent of writing:" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 in z or (4 in z and w == 2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The point to remember here is that the whole expression is still evaluated left to right. So, step by step it would be:" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 in z or 4 in z and w == 2\n", "2 in z or (4 in z and w == 2)\n", "True or (4 in z and w == 2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And as the expression left of the OR operator evaluates to True, the entire expression must be true, and the right side is never evaluated." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## A good Day\n", "\n", "1. Your task here is to decide if today is a good day. There are certain criterias that has to be fulfilled for a day to be classified as good:\n", "\n", " - Days on a weekend are always good \n", " - Weekdays are good if it's no earlier than 10 \n", " - If there's coffee in the kitchen, it makes a weekday good \n", "\n", "  Complete the below code using AND and OR statements to find out if today is a good day, and print the results:\n", "\n", "  `day = \"Monday\"` \n", "  `time = 7` \n", "  `coffee = True` \n", "\n", "  `todayIsAGoodDay = ....`\n", "\n", "\n", "\n", "2. Modify your code so coffee only makes a weekday good if there is no rain" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### A good Day - Answers\n", "\n", "There are a few slightly different ways you can write the code for this. Here we present one solution, if you have written something else that's not wrong. Just make sure to test that your code actually does what you intend it to do." ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Today is a good day: True\n" ] } ], "source": [ "day = \"Monday\"\n", "time = 7\n", "coffee = True\n", "\n", "todayIsAGoodDay = day in [\"Saturday\", \"Sunday\"] or time >= 10 or coffee\n", "\n", "print('Today is a good day: ' + str(todayIsAGoodDay))" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Today is a good day: False\n" ] } ], "source": [ "day = \"Monday\"\n", "time = 7\n", "coffee = True\n", "rain = True\n", "\n", "todayIsAGoodDay = day in [\"Saturday\", \"Sunday\"] or time >= 10 or coffee and not rain\n", "\n", "print('Today is a good day: ' + str(todayIsAGoodDay))" ] } ], "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.6.2" } }, "nbformat": 4, "nbformat_minor": 2 }