Skip to content

Instantly share code, notes, and snippets.

@frainfreeze
Created September 29, 2018 11:37
Show Gist options
  • Save frainfreeze/611262d0af123e14a4c94d0864bc3050 to your computer and use it in GitHub Desktop.
Save frainfreeze/611262d0af123e14a4c94d0864bc3050 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Test your knowledge: Part II exercises\n",
"## 1. The basics\n",
"Run each of the following expressions, and try to\n",
"explain what’s happening in each case. Note that the semicolon in some of these\n",
"is being used as a statement separator, to squeeze multiple statements onto a single\n",
"line: for example, X=1;X assigns and then prints a variable. Also remember that a comma between expressions usually builds a tuple, even if there are no enclosing parentheses: X,Y,Z\n",
"is a three-item tuple, which Python prints back to you in parentheses."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"2 ** 16"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"2 / 5, 2 / 5.0"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\"spam\" + \"eggs\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"S = \"ham\"\n",
"\"eggs \" + S"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"S * 5"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"S[:0]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\"green %s and %s\" % (\"eggs\", S)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"'green {0} and {1}'.format('eggs', S)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"('x',)[0]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"('x', 'y')[1]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"L = [1,2,3] + [4,5,6]\n",
"L, L[:], L[:0], L[-2], L[-2:]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"([1,2,3] + [4,5,6])[2:4]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"[L[2], L[3]]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"L.reverse(); L"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"L.sort(); L"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"L.index(4)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"{'a':1, 'b':2}['b']"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"D = {'x':1, 'y':2, 'z':3}\n",
"D['w'] = 0\n",
"D"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"D['x'] + D['w']\n",
"D"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"D[(1,2,3)] = 4\n",
"D"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"list(D.keys()), list(D.values()), (1,2,3) in D"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"[[]], [\"\",[],(),{},None]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Indexing and slicing\n",
"At the interactive prompt, define a list named L that contains\n",
"four strings or numbers (e.g., L=[0,1,2,3] ). Then, experiment with the following\n",
"boundary cases. You may never see these cases in real programs (especially not in\n",
"the bizarre ways they appear here!), but they are intended to make you think about\n",
"the underlying model, and some may be useful in less artificial forms—slicing out\n",
"of bounds can help, for example, if a sequence is as long as you expect:\n",
"- What happens when you try to index out of bounds (e.g., L[4] )?\n",
"- What about slicing out of bounds (e.g., L[−1000:100] )?\n",
"- Finally, how does Python handle it if you try to extract a sequence in reverse,\n",
"with the lower bound greater than the higher bound (e.g., L[3:1] )? Hint: try\n",
"assigning to this slice ( L[3:1]=['?'] ), and see where the value is put. Do you\n",
"think this may be the same phenomenon you saw when slicing out of bounds?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Indexing, slicing and del\n",
"Define another list L with four items, and assign an empty\n",
"list to one of its offsets (e.g., L[2]=[] ). What happens? Then, assign an empty list\n",
"to a slice ( L[2:3]=[] ). What happens now? Recall that slice assignment deletes the\n",
"slice and inserts the new value where it used to be.\n",
"The del statement deletes offsets, keys, attributes, and names. Use it on your list\n",
"to delete an item (e.g., del L[0] ). What happens if you delete an entire slice ( del\n",
"L[1:] )? What happens when you assign a nonsequence to a slice ( L[1:2]=1 )?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. Tuple assignment\n",
"What do you think is happening to X and Y when you run following sequence?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"X = 'spam'\n",
"Y = 'eggs'\n",
"X, Y = Y, X"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5. Dictionary keys.\n",
"You’ve learned that dictionaries aren’t accessed by offsets, so what’s going on here?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"D = {}\n",
"D[1] = 'a'\n",
"D[2] = 'b'\n",
"D"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Does the following shed any light on the subject? (Hint: strings, integers, and tuples\n",
"share which type category?)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"D[(1, 2, 3)] = 'c'\n",
"D"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 6. Dictionary indexing. \n",
"Create a dictionary named D with three entries, for keys 'a' ,\n",
"'b' , and 'c' . What happens if you try to index a nonexistent key ( D['d'] )? What\n",
"does Python do if you try to assign to a nonexistent key 'd' (e.g., D['d']='spam' )?\n",
"How does this compare to out-of-bounds assignments and references for lists?\n",
"Does this sound like the rule for variable names?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 7. Generic operations. \n",
"Run interactive tests to answer the following questions:\n",
"- What happens when you try to use the + operator on different/mixed types\n",
"(e.g., string + list, list + tuple)?\n",
"- Does + work when one of the operands is a dictionary?\n",
"- Does the append method work for both lists and strings? How about using the\n",
"keys method on lists? (Hint: what does append assume about its subject object?)\n",
"- Finally, what type of object do you get back when you slice or concatenate two\n",
"lists or two strings?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 8. String indexing. \n",
"Define a string S of four characters: S = \"spam\" . Then type the\n",
"following expression: S[0][0][0][0][0] . Any clue as to what’s happening this time?\n",
"(Hint: recall that a string is a collection of characters, but Python characters are\n",
"one-character strings.) Does this indexing expression still work if you apply it to a\n",
"list such as ['s', 'p', 'a', 'm'] ? Why?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 9. Immutable types. \n",
"Define a string S of four characters again: S = \"spam\" . Write an\n",
"assignment that changes the string to \"slam\" , using only slicing and concatenation.\n",
"Could you perform the same operation using just indexing and concatenation?\n",
"How about index assignment?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 10. Nesting. \n",
"Write a data structure that represents your personal information: name\n",
"(first, middle, last), age, job, address, email address, and phone number. You may\n",
"build the data structure with any combination of built-in object types you like (lists,\n",
"tuples, dictionaries, strings, numbers). Then, access the individual components of\n",
"your data structures by indexing. Do some structures make more sense than others\n",
"for this object?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 11. Files\n",
"Write a script that creates a new output file called myfile.txt and writes the\n",
"string \"Hello file world!\" into it. Then write another script that opens my-\n",
"file.txt and reads and prints its contents. Does the new file show up in the directory where you ran your\n",
"scripts? What if you add a different directory path to the filename passed to open ?\n",
"Note: file write methods do not add newline characters to your strings; add an\n",
"explicit \\n at the end of the string if you want to fully terminate the line in the file."
]
},
{
"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": [
"!ls"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Test your knowledge: Part III exercises\n",
"## 1. Coding basic loops\n",
"- Write a for loop that prints the ASCII code of each character in a string named S. Use the built-in function ord(character) to convert each character to an\n",
"ASCII integer. This function technically returns a Unicode code point in\n",
"Python 3.X, but if you restrict its content to ASCII characters, you’ll get back\n",
"ASCII codes. (Test it interactively to see how it works.)\n",
"- Next, change your loop to compute the sum of the ASCII codes of all the\n",
"characters in a string.\n",
"- Finally, modify your code again to return a new list that contains the ASCII\n",
"codes of each character in the string. Does the expression map(ord, S) have a\n",
"similar effect? How about [ord(c) for c in S] ? Why? (Hint: see Chapter 14.)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Backslash characters\n",
"What happens on your machine when you type the following\n",
"code interactively?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for i in range(5):\n",
" print('hello %d\\n\\a' % i, end=\"\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Sorting dictionaries. \n",
"In Chapter 8, we saw that dictionaries are unordered collections. Write a for loop that prints a dictionary’s items in sorted (ascending) order. (Hint: use the dictionary keys and list sort methods, or the newer sorted built-in function.)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. Program logic alternatives. \n",
"Consider the following code, which uses a while loop and found flag to search a list of powers of 2 for the value of 2 raised to the fifth power (32).\n",
"```python\n",
"L = [1, 2, 4, 8, 16, 32, 64]\n",
"X = 5\n",
"\n",
"found = False\n",
"i = 0\n",
"while not found and i < len(L):\n",
" if 2 ** X == L[i]:\n",
" found = True\n",
" else:\n",
" i = i+1\n",
" \n",
"if found:\n",
" print('at index', i)\n",
"else:\n",
" print(X, 'not found') \n",
"```\n",
"\n",
"As is, the example doesn’t follow normal Python coding techniques. Follow the steps outlined here to improve it:\n",
"- First, rewrite this code with a while loop else clause to eliminate the found flag and final if statement.\n",
"- Next, rewrite the example to use a for loop with an else clause, to eliminate the explicit list-indexing logic. (Hint: to get the index of an item, use the list index method— L.index(X) returns the offset of the first X in list L .)\n",
"- Next, remove the loop completely by rewriting the example with a simple in operator membership expression. (See Chapter 8 for more details, or type this to test: 2 in [1,2,3] .)\n",
"- Finally, use a for loop and the list append method to generate the powers-of-2 list ( L ) instead of hardcoding a list literal."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Deeper thoughts:\n",
"- Do you think it would improve performance to move the 2 ** X expression outside the loops? How would you code that?\n",
"- As we saw in exercise 1, Python includes a map(function, list) tool that can generate a powers-of-2 list, too: `map(lambda x: 2 ** x, range(7))`. Try typing this code interactively; we’ll meet lambda more formally in the next part of this book, especially in Chapter 19. Would a list comprehension help here (see Chapter 14)?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5. Code maintenance. \n",
"If you haven’t already done so, experiment with making the code changes suggested in this chapter’s sidebar “Changing PyDoc’s Colors” on page 456. Much of the work of real software development is in changing existing code, so the sooner you begin doing so, the better. For reference, my edited copy of PyDoc is in the book’s examples package, named mypydoc.py; to see how it differs, you can run a file compare (fc on Windows) with the original pydoc.py in 3.3 (also included, lest it change radically in 3.4 as the sidebar describes). If PyDoc is more easily customized by the time you read these words, customize colors per its current convention instead; if this involves changing a CSS file, let’s\n",
"hope the procedure will be well documented in Python’s manuals."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Test Your Knowledge: Part IV Exercises\n",
"## 1. The basics. \n",
"At the Python interactive prompt, write a function that prints its single\n",
"argument to the screen and call it interactively, passing a variety of object types:\n",
"string, integer, list, dictionary. Then, try calling it without passing any argument.\n",
"What happens? What happens when you pass two arguments?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Arguments. \n",
"Write a function called adder in a Python module file. The function\n",
"should accept two arguments and return the sum (or concatenation) of the two.\n",
"Then, add code at the bottom of the file to call the adder function with a variety of\n",
"object types (two strings, two lists, two floating points), and run this file as a script\n",
"from the system command line. Do you have to print the call statement results to\n",
"see results on your screen?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. varargs. \n",
"Generalize the adder function you wrote in the last exercise to compute\n",
"the sum of an arbitrary number of arguments, and change the calls to pass more\n",
"or fewer than two arguments. What type is the return value sum? (Hints: a slice\n",
"such as S[:0] returns an empty sequence of the same type as S , and the type built-\n",
"in function can test types; but see the manually coded min examples in Chapter 18 for a simpler approach.) What happens if you pass in arguments of different\n",
"types? What about passing in dictionaries?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. Keywords. \n",
"Change the adder function from exercise 2 to accept and sum/concatenate three arguments: def adder(good, bad, ugly). Now, provide default values\n",
"for each argument, and experiment with calling the function interactively. Try\n",
"passing one, two, three, and four arguments. Then, try passing keyword arguments. Does the call adder(ugly=1, good=2) work? Why? Finally, generalize the\n",
"new adder to accept and sum/concatenate an arbitrary number of keyword arguments. This is similar to what you did in exercise 3, but you’ll need to iterate over\n",
"a dictionary, not a tuple. (Hint: the dict.keys method returns a list you can step\n",
"through with a for or while , but be sure to wrap it in a list call to index it in 3.X;\n",
"dict.values may help here too.)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5. Dictionary tools. \n",
"Write a function called copyDict(dict) that copies its dictionary\n",
"argument. It should return a new dictionary containing all the items in its argument. Use the dictionary keys method to iterate (or, in Python 2.2 and later, step\n",
"over a dictionary’s keys without calling keys ). Copying sequences is easy ( X[:]\n",
"makes a top-level copy); does this work for dictionaries, too? As explained in this\n",
"exercise’s solution, because dictionaries now come with similar tools, this and the\n",
"next exercise are just coding exercises but still serve as representative function\n",
"examples."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 6. Dictionary tools. \n",
"Write a function called addDict(dict1, dict2) that computes the\n",
"union of two dictionaries. It should return a new dictionary containing all the items\n",
"in both its arguments (which are assumed to be dictionaries). If the same key appears in both arguments, feel free to pick a value from either. Test your function\n",
"by writing it in a file and running the file as a script. What happens if you pass lists\n",
"instead of dictionaries? How could you generalize your function to handle this case,\n",
"too? (Hint: see the type built-in function used earlier.) Does the order of the arguments passed in matter?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 7. More argument-matching examples."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def f1(a, b): print(a, b) # Normal args\n",
"def f2(a, *b): print(a, b) # Positional varargs\n",
"def f3(a, **b): print(a, b) # Keyword varargs\n",
"def f4(a, *b, **c): print(a, b, c) # Mixed modes\n",
"def f5(a, b=2, c=3): print(a, b, c) # Defaults\n",
"def f6(a, b=2, *c): print(a, b, c) # Defaults and positional varargs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Test the following calls interactively, and try to explain each result; in some\n",
"cases, you’ll probably need to fall back on the matching algorithm shown in Chapter 18. Do you think mixing matching modes is a good idea in general? Can you think of cases where it would be useful?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"f1(1, 2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"f1(b=2, a=1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"f2(1, 2, 3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"f3(1, x=2, y=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"f4(1, 2, 3, x=2, y=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"f5(1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"f5(1, 4)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"f6(1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"f6(1, 3, 4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 8. Primes revisited. \n",
"Recall the following code snippet from Chapter 13, which simplistically determines whether a positive integer is prime:\n",
"```python\n",
"x = y // 2 # For some y > 1\n",
"while x > 1:\n",
" if y % x == 0: # Remainder\n",
" print(y, 'has factor', x)\n",
" break # Skip else\n",
" x -= 1\n",
"else: # Normal exit\n",
" print(y, 'is prime')\n",
"```\n",
"Package this code as a reusable function, add some calls to the function. While you’re at it, experiment with replacing the first line’s // operator with / to see how true division changes the / operator in Python 3.X and breaks this code (refer back to Chapter 5 if you need a reminder). What can you do about negatives, and the values 0 and 1 ? How about speeding this up? Your outputs should look something like this:\n",
"```\n",
"13 is prime\n",
"13.0 is prime\n",
"15 has factor 5\n",
"15.0 has factor 5.0\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 9. Iterations and comprehensions. \n",
"Write code to build a new list containing the square roots of all the numbers in this list: `[2, 4, 9, 16, 25]`. Code this as a for loop first,\n",
"then as a map call, then as a list comprehension, and finally as a generator expression. Use the sqrt function in the built-in math module to do the calculation (i.e.,\n",
"`import math` and say `math.sqrt(x)` ). Of the four, which approach do you like best?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 10. Timing tools. \n",
"In Chapter 5, we saw three ways to compute square roots:\n",
"`math.sqrt(X)` , `X ** .5` , and `pow(X, .5)` . If your programs run a lot of these, their\n",
"relative performance might become important. To see which is quickest, repurpose\n",
"the timerseqs.py script we wrote in this chapter to time each of these three tools.\n",
"Use the bestof or bestoftotal functions in one of this chapter’s timer modules to\n",
"test (you can use either the original, the 3.X-only keyword-only variant, or the 2.X/\n",
"3.X version, and may use Python’s timeit module as well). You might also want\n",
"to repackage the testing code in this script for better reusability—by passing a test\n",
"functions tuple to a general tester function, for example (for this exercise a copy-\n",
"and-modify approach is fine). Which of the three square root tools seems to run\n",
"fastest on your machine and Python in general? Finally, how might you go about\n",
"interactively timing the speed of dictionary comprehensions versus for loops?\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 11. Recursive functions.\n",
"Write a simple recursion function named countdown that prints\n",
"numbers as it counts down to zero. For example, a call `countdown(5)` will print: `5\n",
"4 3 2 1 stop`. There’s no obvious reason to code this with an explicit stack or\n",
"queue, but what about a nonfunction approach? Would a generator make sense\n",
"here?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 12. Computing factorials. \n",
"Finally, a computer science classic (but demonstrative nonetheless). We employed the notion of factorials in Chapter 20’s coverage of permutations: N! , computed as N\\*(N-1)\\*(N-2)\\*...1 . For instance, 6! is 6\\*5\\*4*\\3\\*2\\*1 , or\n",
"720 . Code and time four functions that, for a call fact(N) , each return N! . Code these four functions (1) as a recursive countdown per Chapter 19; (2) using the\n",
"functional reduce call per Chapter 19; (3) with a simple iterative counter loop per\n",
"Chapter 13; and (4) using the math.factorial library tool per Chapter 20. Use\n",
"Chapter 21’s timeit to time each of your functions. What conclusions can you\n",
"draw from your results?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"celltoolbar": "Raw Cell Format",
"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.5.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment