{ "cells": [ { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "
\n", "\n", "## Logic with Lists and Dictionaries \n", "\n", "Python allows the use of logic and decisions in many useful ways and in many useful contexts. For example, __list comprehension__ is the creation of a list using the structure\n", "\n", "```python\n", " [ FunctionOfValue for Value in Iterable if BooleanStatement ]\n", "```\n", "\n", "Let's look at an example. " ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]" ] }, "execution_count": 36, "metadata": { }, "output_type": "execute_result" } ], "source": [ "## First 10 squared positive integers \n", "[n**2 for n in range(1,11) ]" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "Indeed, suppose we wanted to create a __numpy array__ of numbers between 1 and 100 that do __not__ have a factor of 7. This turns out to be quite easy using list comprehension inside of the __array__ command in numpy. " ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15,\n", " 16, 17, 18, 19, 20, 22, 23, 24, 25, 26, 27, 29, 30,\n", " 31, 32, 33, 34, 36, 37, 38, 39, 40, 41, 43, 44, 45,\n", " 46, 47, 48, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60,\n", " 61, 62, 64, 65, 66, 67, 68, 69, 71, 72, 73, 74, 75,\n", " 76, 78, 79, 80, 81, 82, 83, 85, 86, 87, 88, 89, 90,\n", " 92, 93, 94, 95, 96, 97, 99, 100])" ] }, "execution_count": 37, "metadata": { }, "output_type": "execute_result" } ], "source": [ "np.array( [n for n in range(1,101) if n % 7 != 0 ] )" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "Finally, there is a very useful structure for writing algorithms called a __dictionary__, where a __dictionary__ is a __set__ of __key, value__ pairs. \n", "\n", "We can create dictionaries in many ways in Python, but the method we use most often is as a set of key-value pairs: \n", "```python \n", "# the following is a dictionary in Python\n", "ADictionary = { 'key1':value1, 'key2':value2, ..., 'keyn':valuen } \n", "``` \n", "\n", "The __dict__ command can also be used to create dictionaries. " ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "{'firstlight': 7, 'midnight': 0, 'noon': 12, 'sundown': 19}" ] }, "execution_count": 38, "metadata": { }, "output_type": "execute_result" } ], "source": [ "SpecialHours = { 'noon': 12, 'midnight': 0, 'firstlight': 7, 'sundown':19 }\n", "SpecialHours" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "Because a dictionary is a _set_ of key-value pairs, the order in which they are stored is not preserved (i.e., Python decides). \n", "\n", "However, we can access values using keys. " ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 39, "metadata": { }, "output_type": "execute_result" } ], "source": [ "SpecialHours['midnight']" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "12" ] }, "execution_count": 40, "metadata": { }, "output_type": "execute_result" } ], "source": [ "SpecialHours['noon']" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "{'firstlight': 7, 'midnight': 0, 'noon': 12, 'sundown': 19, 'workStarts': 8}" ] }, "execution_count": 41, "metadata": { }, "output_type": "execute_result" } ], "source": [ "SpecialHours['workStarts'] = 8\n", "SpecialHours" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "Once a dictionary is created, we can access its keys with the __keys__ command; and we can get its values using the __values__ command. " ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "dict_keys(['firstlight', 'midnight', 'noon', 'workStarts', 'sundown'])" ] }, "execution_count": 43, "metadata": { }, "output_type": "execute_result" } ], "source": [ "SpecialHours.keys()" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "dict_values([7, 0, 12, 8, 19])" ] }, "execution_count": 44, "metadata": { }, "output_type": "execute_result" } ], "source": [ "SpecialHours.values()" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "If we loop over a dictionary, then we are getting the __keys__ one at a time: " ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "firstlight 7\n", "midnight 0\n", "noon 12\n", "workStarts 8\n", "sundown 19\n" ] } ], "source": [ "for key in SpecialHours:\n", " print(key, SpecialHours[key] )" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "Dictionaries can be very useful when logic is involved when designing algorithms. \n", "\n", "For example, let's consider how a dictionary can greatly \"clean up\" the code for the _Making Change_ example, which we repeat below: " ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Change is \n", "3 dollars and \n", "2 quarters and \n", "1 dimes and \n", "4 pennies\n" ] } ], "source": [ "Price = 1.36\n", "AmountPaid = 5.00 \n", "\n", "assert AmountPaid >= Price, \"Must pay at least the price\"\n", "\n", "Return = AmountPaid - Price\n", "\n", "print(\"Change is \")\n", "if( Return / 1 >= 1 ): \n", " NumDollars = int( Return/1 )\n", " print(\"{0} dollars and \".format(NumDollars))\n", " Return = Return - NumDollars*1\n", "if( Return / 0.25 >= 1 ):\n", " NumQuarters = int(Return/0.25)\n", " print(\"{0} quarters and \".format(NumQuarters))\n", " Return = Return - NumQuarters*0.25\n", "if( Return / 0.10 >= 1 ):\n", " NumDimes = int(Return/0.10)\n", " print(\"{0} dimes and \".format(NumDimes))\n", " Return = Return - NumDimes*0.10\n", "if( Return / 0.05 >= 1 ):\n", " NumNickels = int(Return/0.25)\n", " print(\"{0} nickels and \".format(NumNickels))\n", " Return = Return - NumNickels*0.05\n", "print(\"{0} pennies\".format( round(100*Return) ) )" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "Notice that we are repeating the same \"if\" statement several times, each time for a different type of coin (assuming dollar coins!). So first off, let's create a coin dictionary whose keys are the coin names and whose values are the coin values. " ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "{'dime': 0.1, 'dollar': 1, 'nickel': 0.05, 'quarter': 0.25}" ] }, "execution_count": 48, "metadata": { }, "output_type": "execute_result" } ], "source": [ "CoinDictionary = { 'dollar':1, 'quarter':0.25, 'dime':0.10, 'nickel':0.05 }\n", "CoinDictionary" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "Once we need to make change, we can simply loop over a list of coin names in the order they need to be considered. " ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Change is \n", "3 dollars and \n", "2 quarters and \n", "1 dimes and \n", "4 pennies\n" ] } ], "source": [ "Price = 1.36\n", "AmountPaid = 5.00 \n", "\n", "assert AmountPaid >= Price, \"Must pay at least the price\"\n", "\n", "Return = AmountPaid - Price\n", "\n", "print(\"Change is \")\n", "for coinName in ['dollar','quarter','dime','nickel']:\n", " coinValue = CoinDictionary[coinName]\n", " if( Return / coinValue >= 1 ): \n", " NumCoins = int( Return/coinValue )\n", " print(\"{0} {1}s and \".format(NumCoins, coinName) )\n", " Return = Return - NumCoins*coinValue\n", "print(\"{0} pennies\".format( round(100*Return) ) )" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "
\n", "\n", "## Assignment 3\n", "\n", "In the exercises below, $a,b,c,d$ are the last 4 __ _nonzero_ __ digits of your student number in _nondescending order_ ( $a \\le b \\le c \\le d$ ). Also, __EnumberLast3NonzeroDigits__ is the last 3 nonzero digits of your Enumber. For example, if your enumber was E12375609, then \n", "$$ a = 5, \\quad b = 6, \\quad c = 7, \\quad \\mathrm{and} \\quad d = 9$$ \n", "and __EnumberLast3NonzeroDigits__ is 569. \n", "\n", "__1.__ (0.25 points) Execute the following and describe in the Raw NBconvert cell what list it produced. \n", "```python \n", "list(range(c+d, a, -1) )\n", "```" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6]" ] }, "execution_count": 7, "metadata": { }, "output_type": "execute_result" } ], "source": [ "a,b,c,d=5,6,7,9\n", "list (range(c+d, a, -1))" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "The output does describes a list of eleven positive integers all in order with a range between [6 and 16] starting at 16 and ending at 6." ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "__2.__ (0.25 points) Execute the following and describe in the Raw NBconvert cell what list it produced. \n", "```python \n", "[n**2 for n in range(b+c, a, -1) if n % 2 == 1 ]\n", "```" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[169, 121, 81, 49]" ] }, "execution_count": 8, "metadata": { }, "output_type": "execute_result" } ], "source": [ "a,b,c,d=5,6,7,9\n", "[n**2 for n in range (b+c, a, -1) if n % 2 ==1 ]" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "A list of four positive integers which represent the squared product of four odd numbers [13,11,9,7]" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "__3.__ (0.5 points) Determine if the following __BooleanStatement__ is __True__ or __False__ for your values of _a,b,c,d_. \n", "