Exercises
2.1.1 Compose a function max3() that takes three int or float arguments and returns the largest one.
2.1.2 Compose a function odd() that takes three bool arguments and returns True if an odd number of arguments are True, and False otherwise.
2.1.3 Compose a function majority() that takes three bool arguments and returns True if at least two of the arguments are True, and False otherwise. Do not use an if statement.
2.1.4 Compose a function areTriangular() that takes three numbers as arguments and returns True if they could be lengths of the sides of a triangle (none of them is greater than or equal to the sum of the other two), and False otherwise.
2.1.5 Compose a function sigmoid() that takes a float argument x and returns the float obtained from the formula 1 / (1+e−x).
2.1.6 Compose a function lg() that takes an integer n as an argument and returns the base-2 logarithm of n. You may use Python’s math module.
2.1.7 Compose a function lg() that takes an integer n as an argument and returns the largest integer not larger than the base-2 logarithm of n. Do not use the math module.
2.1.8 Compose a function signum() that takes a float argument n and returns -1 if n is less than 0, 0 if n is equal to 0, and +1 if n is greater than 0.
2.1.9 Consider this function duplicate():
def duplicate(s): t = s + s
What does the following code fragment write?
s = 'Hello' s = duplicate(s) t = 'Bye' t = duplicate(duplicate(duplicate(t))) stdio.writeln(s + t)
2.1.10 Consider this function cube():
def cube(i): i = i * i * i
How many times is the following while loop iterated?
i = 0 while i < 1000: cube(i) i += 1
Solution: Just 1,000 times. A call to cube() has no effect on the client code. It changes the parameter variable i, but that change has no effect on the variable i in the while loop, which is a different variable. If you replace the call to cube(i) with the statement i = i * i * i (maybe that was what you were thinking), then the loop is iterated five times, with i taking on the values 0, 1, 2, 9, and 730 at the beginning of the five iterations.
2.1.11 What does the following code fragment write?
for i in range(5): stdio.write(i) for j in range(5): stdio.write(i)
Solution: 0123444444. Note that the second call to stdio.write() uses i, not j. Unlike analogous loops in many other programming languages, when the first for loop terminates, the variable i is 4 and it remains in scope.
2.1.12 The following checksum formula is widely used by banks and credit card companies to validate legal account numbers:
- d0 + f(d1) + d2 + f(d3) + d4 + f (d5) + . . . = 0 (mod 10)
The di are the decimal digits of the account number and f(d) is the sum of the decimal digits of 2d (for example, f(7) = 5 because 2 × 7 = 14 and 1 + 4 = 5). For example 17327 is valid because 1 + 5 + 3 + 4 + 7 = 20, which is a multiple of 10. Implement the function f and compose a program to take a 10-digit integer as a command-line argument and write a valid 11-digit number with the given integer as its first 10 digits and the checksum as the last digit.
2.1.13 Given two stars with angles of declination and right ascension (d1, a1) and (d2, a2), respectively, the angle they subtend is given by the formula
- 2 arcsin((sin2(d/2) + cos (d1)cos(d2)sin2(a/2))1/2),
where a1 and a2 are angles between −180 and 180 degrees, d1 and d2 are angles between −90 and 90 degrees, a = a2 − a1, and d = d2 −d1. Compose a program to take the declination and right ascension of two stars as command-line arguments and write the angle they subtend. Hint : Be careful about converting from degrees to radians.
2.1.14 Compose a readBool2D() function that reads a two-dimensional matrix of 0 and 1 values (with dimensions) into an array of booleans.
Solution: The body of the function is virtually the same as for the corresponding function given in the table in the text for two-dimensional arrays of floats:
def readBool2D(): m = stdio.readInt() n = stdio.readInt() a = stdarray.create2D(m, n, False) for i in range(m): for j in range(n): a[i][j] = stdio.readBool() return a
2.1.15 Compose a function that takes an array a[] of strictly positive floats as its argument and rescales the array so that each element is between 0 and 1 (by subtracting the minimum value from each element and then dividing each element by the difference between the minimum and maximum values). Use the built-in max() and min() functions.
2.1.16 Compose a function histogram() that takes an array a[] of integers and an integer m as arguments and returns an array of length m whose ith element is the number of times the integer i appears in the argument array. Assume that the values in a[] are all between 0 and m-1, so that the sum of the values in the returned array should be equal to len(a).
2.1.17 Assemble code fragments in this section and in SECTION 1.4 to develop a program that takes an integer n from the command line and writes n five-card hands, separated by blank lines, drawn from a randomly shuffled card deck, one card per line using card names like Ace of Clubs.
2.1.18 Compose a function multiply() that takes two square matrices of the same dimension as arguments and returns their product (another square matrix of that same dimension). Extra credit : Make your program work whenever the number of columns in the first matrix is equal to the number of rows in the second matrix.
2.1.19 Compose a function any() that takes an array of booleans as an argument and returns True if any of the elements in the array is True, and False otherwise. Compose a function all() that takes an array of booleans as an argument and returns True if all of the elements in the array are True, and False otherwise. Note that all() and any() are built-in Python functions; the goal of this exercise is to understand them better by creating your own versions.
2.1.20 Develop a version of getCoupon() that better models the situation when one of the n coupons is rare: choose one value at random, return that value with probability 1/(1000n), and return all other values with equal probability. Extra credit: How does this change affect the average value of the coupon collector function?
2.1.21 Modify playthattune.py to add harmonics two octaves away from each note, with half the weight of the one-octave harmonics.