[PYTHON] Try to solve the problems / problems of "Matrix Programmer" (Chapter 0 Functions)

Introduction

While reading this book, I will try to solve problems and problems.

-O'Reilly Japan --Matrix Programmer

It's only Chapter 0, and it feels like re-studying Python.

** 2017/01/04 update **

Added the issue of "[0.6 Lab: Python and Reverse Index --- Module and Control Structure](http://qiita.com/Suna/items/881ce264cffd3301a54f#06-Lab python-and Reverse Index --- Module and Control Structure)" did.

Chapter 0 Functions (and other background on mathematics and computers)

0.5 Lab: Getting Started with Python --- Sets, Lists, Dictionaries, Comprehensions

0.5.1 Simple formula

Challenge 0.5.1

Use python to find out how many seconds a week is.

>>> 7 * 24 * 60 * 60
604800
Challenge 0.5.2

Use Python to find the remainder of 2304811 divided by 47. However, do not use% (hint: use //).

>>> 2304811 - (2304811 // 47) * 47
25
Challenge 0.5.3

Enter a Boolean expression to see if the sum of 673 and 909 is divisible by 3.

>>> (643 + 909) % 3 == 0
False

0.5.2 Assignment statement

0.5.3 Conditional expression

Challenge 0.5.4

Substitute -9 for x and 1/2 for y. Predict the value of the following formula and enter it to confirm the prediction. 2**(y+1/2) if x+10<0 else 2**(y-1/2)

Since x + 10 <0 becomes False and the else part 2 ** (y-1 / 2) is executed, it becomes "1".

>>> (lambda x, y: 2**(y+1/2) if x+10<0 else 2**(y-1/2))(-9, 1/2)
1

0.5.4 set

Challenge 0.5.5

Write a comprehension for the set {1, 2, 3, 4, 5} that returns the square of each integer.

>>> {x * x for x in {1, 2, 3, 4, 5}}
set([16, 1, 4, 25, 9])
Challenge 0.5.6

Inclusive notation for the set {0, 1, 2, 3, 4}, with each integer as an exponent of 2, that is, 2 0 </ sup>, 2 1 </ sup> Write something that returns, 2 2 </ sup>, etc.

>>> {2**x for x in {0, 1, 2, 3, 4}}
set([8, 1, 2, 4, 16])
Challenge 0.5.7

The value of the previous comprehension {x * y for x in {1, 2, 3} for y in {2, 3, 4}} is a set of seven elements. Replace {1, 2, 3} and {2, 3, 4} with separate sets of three elements so that their values are a set of nine elements.

>>> {x * y for x in {4, 5, 6} for y in {6, 7, 8}}
set([32, 35, 36, 40, 42, 48, 24, 28, 30])
Challenge 0.5.8

Replace the two sets {1, 2, 3} and {2, 3, 4} in the previous comprehension with another set of three elements so that the result is a set of five elements. However, it is assumed that the two sets to be replaced are relatively prime, that is, the elements do not overlap.

>>> {x * y for x in {4, 5, 6} for y in {7, 8, 9} if x * y < 41}
set([32, 28, 35, 36, 40])
Challenge 0.5.9

Variables S and T shall represent sets. Write a comprehension for S that returns the intersection of S and T without the operator & (hint: use a filter at the end of the comprehension and check the elements). Try the comprehensions you created with S = {1, 2, 3, 4} and T = {3, 4, 5, 6}.

>>> {s for s in {1, 2, 3, 4} for t in {3, 4, 5, 6} if s == t}
set([3, 4])

0.5.5 list

Challenge 0.5.10

Write an expression whose evaluated value is the average of the elements in the list [20, 10, 15, 75].

>>> sum([20, 10, 15, 75]) / 4
30
Challenge 0.5.11

Write a list comprehension for the list ['A','B','C'] and [1, 2, 3] whose value consists of all possible combinations of [letter, number]. That is, the value is as follows. [['A', 1], ['A', 2], ['A', 3], ['B', 1], ['B', 2], ['B', 3], ['C', 1], ['C', 2], ['C', 3]]

>>> [[a, b] for a in ['A', 'B', 'C'] for b in [1, 2, 3]]
[['A', 1], ['A', 2], ['A', 3], ['B', 1], ['B', 2], ['B', 3], ['C', 1], ['C', 2], ['C', 3]]
Challenge 0.5.12

Suppose you assign LofL a list that has a list of numbers as its elements. At this time, write a formula to calculate the sum of all the numerical values in the list. This formula has the following form and has one comprehension. sum([sum(... Substitute [[0.25, 0.75, 0.1], [-1, 0], [4, 4, 4, 4]] into LofL and try the formula you created (Note: what length is the formula you created? Make it work on the list of).

>>> sum([sum(x) for x in [[0.25, 0.75, 0.1], [-1, 0], [4, 4, 4, 4]]])
16.1
Challenge 0.5.13

See what happens if the length of the list on the left side does not match the length of the list on the right side.

>>> [x, y, z] = [4*1, 4*2, 4*3, 4*4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  ValueError: too many values to unpack

0.5.6 tuple

Challenge 0.5.14

Let S be a set of integers, eg {-4, -2, 1, 2, 5, 0}. Write a triple comprehension that, when evaluated, is a list of three-element tuples (i, j, k) that meet the following conditions: Here, it is assumed that i, j, and k are elements of S, and their sum is 0.

>>> S = {-4, -2, 1, 2, 5, 0}
>>> [(i, j, k) for i in S for j in S for k in S if i+j+k == 0]
[(0, 0, 0), (0, 2, -2), (0, -2, 2), (1, 1, -2), (1, -2, 1), (2, 0, -2), (2, 2, -4), (2, -4, 2), (2, -2, 0), (-4, 2, 2), (-2, 0, 2), (-2, 1, 1), (-2, 2, 0)]
Challenge 0.5.15

Change the inclusion notation of the previous question so that the resulting list does not include (0, 0, 0) (hint: add a filter).

>>> [(i, j, k) for i in S for j in S for k in S if i+j+k == 0 and (i != 0 or j != 0 or k != 0)]
[(0, 2, -2), (0, -2, 2), (1, 1, -2), (1, -2, 1), (2, 0, -2), (2, 2, -4), (2, -4, 2), (2, -2, 0), (-4, 2, 2), (-2, 0, 2), (-2, 1, 1), (-2, 2, 0)]
Challenge 0.5.16

Further modify the expression so that the value of the expression is the first tuple instead of the full list of tuples above.

>>> [(i, j, k) for i in S for j in S for k in S if i+j+k == 0 and (i != 0 or j != 0 or k != 0)][0]
(0, 2, -2)
Challenge 0.5.17

Find an example of list L with different len (L) and len (list (set (L))).

>>> L = [1, 1, 2, 3]
>>> len(L)
4
>>> len(list(set(L)))
3

0.5.7 Other iterative processing

Challenge 0.5.18

Write a comprehension that returns an odd set between 1 and 99 for a range of the form range (n).

>>> {x for x in range(100) if x % 2 == 1}
set([1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99])
Challenge 0.5.19

Substitute L for a list of the first five letters of the alphabet ['A','B','C','D','E']. Write an expression using L with the following list as the value. [(0, 'A'), (1, 'B'), (2, 'C'), (3, 'D'), (4, 'E')] Range and zip may be used, but not comprehensions.

>>> L = ['A', 'B', 'C', 'D', 'E']
>>> zip(range(len(L)), L)
[(0, 'A'), (1, 'B'), (2, 'C'), (3, 'D'), (4, 'E')]
Challenge 0.5.20

For the lists [10, 25, 40] and [1, 15, 20], the first element is the sum of 10 and 1, the second element is the sum of 25 and 15, and the third element is 40 and 20. Write an inclusive notation whose value is a list that is the sum of. You can use zip, but not list.

>>> [sum(a) for a in zip([10, 25, 40], [1, 15, 20])]
[11, 40, 60]

0.5.8 dictionary

Challenge 0.5.21

Let dlist be the list of dictionaries and k be the key common to all dictionaries in dlist. Write a list comprehension such that the i-th element is the value corresponding to the key k in the i-th dictionary of dlist. Try the created comprehension with some data. Example data is shown below.

dlist = [{'James':'Sean', 'director':'Terence'}, {'James':'Roger', 'director':'Lewis'}, {'James':'Pierce', 'director':'Roger'}] k = 'James'

>>> dlist = [{'James':'Sean', 'director':'Terence'}, {'James':'Roger', 'director':'Lewis'}, {'James':'Pierce', 'director':'Roger'}]
>>> k = 'James'
>>> [d[k] for d in dlist]
['Sean', 'Roger', 'Pierce']
Challenge 0.5.22

Change the inclusion notation in Exercise 0.5.21 so that it can handle some dictionaries that do not have k as a key. The i-th element of this comprehension list is the value corresponding to the key if the i-th dictionary in the dlist contains the key k, or'NOT PRESENT'if it does not. To do Test the comprehension you created for each of k ='Blibo' and k ='Frodo' using the list in the dictionary below.

dlist = [{'Blibo':'Ian', 'Frodo':'Elijah'}, {'Blibo':'Martin', 'Thorin':'Richard'}]

>>> dlist = [{'Blibo':'Ian', 'Frodo':'Elijah'}, {'Blibo':'Martin', 'Thorin':'Richard'}]
>>> k = 'Blibo'
>>> [d[k] if k in d else 'NOT PRESENT' for d in dlist]
['Ian', 'Martin']
>>> k = 'Frodo'
>>> [d[k] if k in d else 'NOT PRESENT' for d in dlist]
['Elijah', 'NOT PRESENT']
Challenge 0.5.23

Write a comprehension that is a dictionary where the key is an integer from 0 to 99 and the key value is the square of the key when evaluated using range.

>>> {x:x*x for x in range(100)}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81, 10: 100, 11: 121, 12: 144, 13: 169, 14: 196, 15: 225, 16: 256, 17: 289, 18: 324, 19: 361, 20: 400, 21: 441, 22: 484, 23: 529, 24: 576, 25: 625, 26: 676, 27: 729, 28: 784, 29: 841, 30: 900, 31: 961, 32: 1024, 33: 1089, 34: 1156, 35: 1225, 36: 1296, 37: 1369, 38: 1444, 39: 1521, 40: 1600, 41: 1681, 42: 1764, 43: 1849, 44: 1936, 45: 2025, 46: 2116, 47: 2209, 48: 2304, 49: 2401, 50: 2500, 51: 2601, 52: 2704, 53: 2809, 54: 2916, 55: 3025, 56: 3136, 57: 3249, 58: 3364, 59: 3481, 60: 3600, 61: 3721, 62: 3844, 63: 3969, 64: 4096, 65: 4225, 66: 4356, 67: 4489, 68: 4624, 69: 4761, 70: 4900, 71: 5041, 72: 5184, 73: 5329, 74: 5476, 75: 5625, 76: 5776, 77: 5929, 78: 6084, 79: 6241, 80: 6400, 81: 6561, 82: 6724, 83: 6889, 84: 7056, 85: 7225, 86: 7396, 87: 7569, 88: 7744, 89: 7921, 90: 8100, 91: 8281, 92: 8464, 93: 8649, 94: 8836, 95: 9025, 96: 9216, 97: 9409, 98: 9604, 99: 9801}
Challenge 0.5.24

Assign the appropriate set to the variable D. For example, D = {'red','white','blue'}. Write a comprehension that, when evaluated, is a dictionary representing the identity function for D.

>>> D = {'red', 'white', 'blue'}
>>> {x:x for x in D}
{'blue': 'blue', 'white': 'white', 'red': 'red'}

――Is this all right?

Challenge 0.5.25

A dictionary that maps each integer from 0 to 999 into a list of three digits representing their respective digits when the base is 10, using the variables base = 10 and digits = set (range (base)). Write the inclusion notation.

{0: [0, 0, 0], 1: [0, 0, 1], 2: [0, 0, 2], 3: [0, 0, 3], ... 10: [0, 1, 0], 11: [0, 1, 1], 12: [0, 1, 2], ... 999: [9, 9, 9]}

Make sure that the formula you create works on any bottom. For example, if 2 is assigned to base and {0, 1} is assigned to digits, the result is as follows.

{0: [0, 0, 0], 1: [0, 0, 1], 2: [0, 1, 0], ..., 7: [1, 1, 1]}

>>> base = 10
>>> digits = set(range(base))
>>> {x:[x/(base**2)%base, x/(base**1)%base, x/(base**0)%base] for x in range(110)}
{0: [0, 0, 0], 1: [0, 0, 1], 2: [0, 0, 2], 3: [0, 0, 3], 4: [0, 0, 4], 5: [0, 0, 5], 6: [0, 0, 6], 7: [0, 0, 7], 8: [0, 0, 8], 9: [0, 0, 9], 10: [0, 1, 0], 11: [0, 1, 1], 12: [0, 1, 2], 13: [0, 1, 3], 14: [0, 1, 4], 15: [0, 1, 5], 16: [0, 1, 6], 17: [0, 1, 7], 18: [0, 1, 8], 19: [0, 1, 9], 20: [0, 2, 0], 21: [0, 2, 1], 22: [0, 2, 2], 23: [0, 2, 3], 24: [0, 2, 4], 25: [0, 2, 5], 26: [0, 2, 6], 27: [0, 2, 7], 28: [0, 2, 8], 29: [0, 2, 9], 30: [0, 3, 0], 31: [0, 3, 1], 32: [0, 3, 2], 33: [0, 3, 3], 34: [0, 3, 4], 35: [0, 3, 5], 36: [0, 3, 6], 37: [0, 3, 7], 38: [0, 3, 8], 39: [0, 3, 9], 40: [0, 4, 0], 41: [0, 4, 1], 42: [0, 4, 2], 43: [0, 4, 3], 44: [0, 4, 4], 45: [0, 4, 5], 46: [0, 4, 6], 47: [0, 4, 7], 48: [0, 4, 8], 49: [0, 4, 9], 50: [0, 5, 0], 51: [0, 5, 1], 52: [0, 5, 2], 53: [0, 5, 3], 54: [0, 5, 4], 55: [0, 5, 5], 56: [0, 5, 6], 57: [0, 5, 7], 58: [0, 5, 8], 59: [0, 5, 9], 60: [0, 6, 0], 61: [0, 6, 1], 62: [0, 6, 2], 63: [0, 6, 3], 64: [0, 6, 4], 65: [0, 6, 5], 66: [0, 6, 6], 67: [0, 6, 7], 68: [0, 6, 8], 69: [0, 6, 9], 70: [0, 7, 0], 71: [0, 7, 1], 72: [0, 7, 2], 73: [0, 7, 3], 74: [0, 7, 4], 75: [0, 7, 5], 76: [0, 7, 6], 77: [0, 7, 7], 78: [0, 7, 8], 79: [0, 7, 9], 80: [0, 8, 0], 81: [0, 8, 1], 82: [0, 8, 2], 83: [0, 8, 3], 84: [0, 8, 4], 85: [0, 8, 5], 86: [0, 8, 6], 87: [0, 8, 7], 88: [0, 8, 8], 89: [0, 8, 9], 90: [0, 9, 0], 91: [0, 9, 1], 92: [0, 9, 2], 93: [0, 9, 3], 94: [0, 9, 4], 95: [0, 9, 5], 96: [0, 9, 6], 97: [0, 9, 7], 98: [0, 9, 8], 99: [0, 9, 9], 100: [1, 0, 0], 101: [1, 0, 1], 102: [1, 0, 2], 103: [1, 0, 3], 104: [1, 0, 4], 105: [1, 0, 5], 106: [1, 0, 6], 107: [1, 0, 7], 108: [1, 0, 8], 109: [1, 0, 9]}

>>> base = 2
>>> {x:[x/(base**2)%base, x/(base**1)%base, x/(base**0)%base] for x in range(8)}
{0: [0, 0, 0], 1: [0, 0, 1], 2: [0, 1, 0], 3: [0, 1, 1], 4: [1, 0, 0], 5: [1, 0, 1], 6: [1, 1, 0], 7: [1, 1, 1]}

――It's long up to 999, so hurry up to 109. --You are not using digits.

Challenge 0.5.26

Let d be a dictionary that maps employee numbers (integers between 0 and n-1) to salaries. Suppose L is a list of n elements, the i-th element being the name of the employee with employee number i. Write a dictionary comprehension that maps the employee's name to the salary. Employee names may be assumed differently. Test the created comprehension with the following data.

d = {0:1000.0, 3:990, 1:1200.50} L = ['Larry', 'Curly', '', 'Moe']

>>> d = {0:1000.0, 3:990, 1:1200.50}
>>> L = ['Larry', 'Curly', '', 'Moe']
>>> {L[k]:d[k] for k in d.keys()}
{'Larry': 1000.0, 'Moe': 990, 'Curly': 1200.5}

0.5.9 Define a one-line procedure

Challenge 0.5.27

Enter the definition of twice (z). After inputting, "..." is displayed, so press Enter. Then call the procedure with some actual arguments. It would be interesting to try it with strings and lists. Finally, evaluate the expression consisting of the variable z and make sure that z is not bound to any value.

>>> def twice(z): return 2*z
...
>>> twice(2)
4
>>> twice(4)
8
>>> z
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  NameError: name 'z' is not defined
Challenge 0.5.28

Define a one-line procedure nextInts (L) like this:

Input: List of integers L Output: A list of integers whose i-th element is 1 greater than the i-th element of L Example: Input [1, 5, 7], Output: [2, 6, 8]

>>> def nextInts(L): return [x+1 for x in L]
...
>>> nextInts([1, 5, 7])
[2, 6, 8]
Challenge 0.5.29

Define a one-line procedure cubes (L) like this:

Input: List of numbers L Output: List of numbers where the i-th element is the cube of the i-th element of L Example: Input [1, 2, 3], Output [1, 8 27]

>>> def cubes(L): return [pow(x, 3) for x in L]
...
>>> cubes([1, 2, 3])
[1, 8, 27]
Challenge 0.5.30

Define a one-line procedure dict2list (dct, keylist) like this:

Input: A list of keys from the dictionaries dct and dct keylist Output: List L such that L [i] = dct [keylist [i]] for i = 0, 1, 2, ..., len (keylist) -1 Example: Input dct = {'a':'A','b':'B','c':'C'} and keylist = ['b','c','a'], output [ 'B','C','A']

>>> def dict2list(dct, keylist): return [dct[k] for k in keylist]
...
>>> dict2list({'a':'A', 'b':'B', 'c':'C'}, ['b', 'c', 'a'])
['B', 'C', 'A']
Challenge 0.5.31

Define a one-line procedure list2dict (L, keylist) like this:

Input: List L, a list of immutable elements keylist Output: A dictionary that maps keylist [i] to L [i] for i = 0, 1, 2, ..., len (L) -1 Example: Input L = ['A','B','C'] and keylist = ['a','b','c'], Output {'a':'A','b': 'B','c':'C'}

>>> def list2dict(L, keylist): return {keylist[k]:L[k] for k in range(len(keylist))}
...
>>> list2dict(['A', 'B', 'C'], ['a', 'b', 'c'])
{'a': 'A', 'c': 'C', 'b': 'B'}
Challenge 0.5.32

Write the following procedure all_3_digit_numbers (base, digits).

Input: Positive integer base and set digits of {0, 1, 2, ..., base-1} Output: A set of numbers consisting of all three numbers with base base An example is shown below.

>>> all_3_digit_number(2, {0, 1}) {0, 1, 2, 3, 4, 5, 6, 7} >>> all_3_digit_number(3, {0, 1, 2}) {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26} >>> all_3_digit_number(10, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}) {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ..., 995, 996, 997, 998, 999}

>>> def all_3_digit_number(base, digits): return {a*pow(base, 2) + b*pow(base, 1) + c*pow(base, 0) for a in digits for b in digits for c in digits}
...
>>> all_3_digit_number(2, {0, 1})
set([0, 1, 2, 3, 4, 5, 6, 7])
>>> all_3_digit_number(3, {0, 1, 2})
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26])
>>> all_3_digit_number(10, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, (Abbreviation)..., 995, 996, 997, 998, 999])

0.6 Lab: Python and inverse index --- modules and control structures

0.6.1 Use of existing modules

Challenge 0.6.1

Import math using the following command.

>>> import math

Try using the procedure help (module name) for the imported module.

>>> help(math)

As a result, the documentation for the specified module is displayed on the console. You can use f to go down and b to go back up. You can also stop browsing the q document. Find the square root of 3 using the procedure defined in the math module, and then find its square. This result will not be what you expect. Keep in mind that Python has limited precision for non-integer real numbers. Therefore, the answer is an approximation. Next, calculate the square root of -1, cos for π, and the natural logarithm for e </ i>. The name of the function that calculates the square root is sqrt, and the qualified name is math.sqrt. cos and log are their names. Also, the names of π and e </ i> are pi and e.

>>> import math

>>> math.sqrt(3)
1.7320508075688772

>>> pow(math.sqrt(3), 2)
2.9999999999999996

>>> math.sqrt(-1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: math domain error

>>> math.cos(math.pi)
-1.0

>>> math.log(math.e)
1.0

--help is abbreviated.

Challenge 0.6.2

The random module defines the procedure randint (a, b). This is a function that randomly picks and returns an integer between {a, a + 1, ..., b}. This procedure can be imported with the following command:

>>> from random import randint

Run randint several times. Then write a one-line procedure movie_review (name) that takes the name of the movie as an argument and returns a string of reviews. However, the review string should be randomly selected from two or more candidates (review strings are "See it!", "A gem!" (Great!), "Ideological claptrap!". "(Aim for ideological humor!) And so on).

>>> from random import randint
>>> randint(0, 9)
3
>>> randint(0, 9)
1
>>> randint(0, 9)
9

>>> def movie_review(name): return ['See it!', 'A gem!', 'Ideological claptrap!'][randint(0, 2)]
...
>>> movie_review('movie_name')
'See it!'
>>> movie_review('movie_name')
'A gem!'
>>> movie_review('movie_name')
'Ideological claptrap!'
>>> movie_review('movie_name')
'A gem!'
>>> movie_review('movie_name')
'A gem!'

0.6.2 Creating a module

Challenge 0.6.3

Lab 0.5 Challenges 0.5.30 and 0.5.31 wrote procedures called dict2list (dct, keylist) and list2dict (L, keylist). Download dictutil.py from this book's website and replace the pass part in the file with the appropriate statement. Import this module and test each procedure. This module will be used in the future.

dictutil.py


def dict2list(dct, keylist): return [dct[k] for k in keylist]

def list2dict(L, keylist): return {keylist[k]:L[k] for k in range(len(keylist))}
>>> import dictutil
>>> dictutil.dict2list({'a':'A', 'b':'B', 'c':'C'}, ['b', 'c', 'a'])
['B', 'C', 'A']
>>> dictutil.list2dict(['A', 'B', 'C'], ['a', 'b', 'c'])
{'a': 'A', 'c': 'C', 'b': 'B'}
Challenge 0.6.4

Modify dictutil.py to define a procedure listrange2dict (L) with the following functionality:

Input: List L Output: A dictionary that maps i to L [i] for i = 0, 1, 2, ..., len (L) -1

This procedure can be written from scratch or using list2dict (L, keylist). You can reload the module using the following statement.

>>> reload(dictutil)

Once loaded, test listrange2dict with ['A','B','C'].

dictutil.py


...
def listrange2dict(L): return {i:L[i] for i in range(len(L))}
>>> reload(dictutil)
<module 'dictutil' from 'dictutil.py'>
>>> dictutil.listrange2dict(['A', 'B', 'C'])
{0: 'A', 1: 'B', 2: 'C'}

0.6.3 Loops and conditional statements

0.6.4 Python grouping feature with indentation

Challenge 0.6.5

Enter the above for loop into Python. When you type the first line, Python displays the ellipsis "...". This is what we expect to see indented blocks. Enter the next line with one or two spaces first. Python displays the ellipsis again. Enter one or two spaces (the same number as the previous line) and enter the next line. Python again displays the ellipsis. Press Enter to execute the loop.

>>> for x in [1, 2, 3]:
...   y = x * x
...   print(y)
...
1
4
9

Escape from the 0.6.5 loop

Reading from a 0.6.6 file

0.6.7 mini search engine

Challenge 0.6.6

Given a string (document), write a procedure makeInverseIndex (strlist) that returns a dictionary that maps a word to a set of document numbers of the document in which the word appears. This dictionary is called the inverse index (hint: use enumerate).

inverseindex.py


def makeInverseIndex(strlist):
  worddict = {}
  for no, line in enumerate(strlist):
    for word in list(set(line.split())):
      if word in worddict:
        worddict[word].add(no)
      else:
        worddict[word] = {no}
  return worddict
>>> import inverseindex
>>> f = open('stories_small.txt')
>>> stories = list(f)

>>> dict = inverseindex.makeInverseIndex(stories)

>>> dict['prep']
set([0, 17])
>>> dict['course']
set([0, 2, 3, 4, 5, 49, 9, 10, 13, 47, 17, 18, 20])
Challenge 0.6.7

Create a procedure orSearch (inverseIndex, query) that takes an inverse index inverseIndex and a list of words query and returns a set of document numbers for documents that contain any of the words in the query.

inverseindex.py


...

def orSearch(inverseIndex, query):
  result = set([])
  for k, v in inverseIndex.items():
    for q in query:
      if k == q:
		result = result | v
  return result

--Execution

>>> inverseindex.orSearch(dict, ['prep', 'course'])
set([0, 2, 3, 4, 5, 49, 9, 10, 13, 47, 17, 18, 20])
  • Verification
$ egrep -n -e ' prep ' stories_small.txt | cut -c -80
1:A prep course for the month-long World Cup soccer tournament , a worldwide phe
18:A prep course for the month-long World Cup soccer tournament , a worldwide ph

$ egrep -n -e ' course ' stories_small.txt | cut -c -80
1:A prep course for the month-long World Cup soccer tournament , a worldwide phe
3:Are frequent-flier awards worth all the trouble travelers sometimes go through
4:The State Department is taking a wait-and-see attitude after an American touri
5:I think there are several reasons why , in polite company , we rarely talk abo
6:By conventional wisdom , there are certain things you simply don't do , right
10:Llamas will carry the load on a three-day guided hiking and camping trip in t
11:Considering that the United Nations has recently created a Bosnian war-crimes
14:When I first got off the Pennsylvania Turnpike at Morgantown , I barely glanc
18:A prep course for the month-long World Cup soccer tournament , a worldwide ph
19:It is only natural that a writer make the literary most of whatever happens t
21:Step by step , President Clinton seems to be maneuvering himself into a posit
48:HOLLYWOOD When the editor of Tricycle , the Buddhist Review , one of the few
50:Eddie Murphy has been telling interviewers , in no uncertain terms , that ``
Challenge 0.6.8

Write a procedure andSearch (inverseIndex, query) that takes an inverse index inverseIndex and a list of words query and returns a set of document numbers for a document that contains all the words in the query.

inverseindex.py


...

def andSearch(inverseIndex, query):
  result = set([])
  for k, v in inverseIndex.items():
    for q in query:
      if k == q:
        if len(result) == 0:
          result = result | v
        else:
          result = result & v
  return result

--Execution

>>> inverseindex.andSearch(dict, ['prep', 'course'])
set([0, 17])
  • Verification
$ egrep -n -e ' prep ' stories_small.txt | egrep -e ' course ' | cut -c -80
1:A prep course for the month-long World Cup soccer tournament , a worldwide phe
18:A prep course for the month-long World Cup soccer tournament , a worldwide ph

Recommended Posts