Learn Enough to Be Dangerous
You have to make a choice. Choose...wisely.

Get occasional notifications about things like product discounts, blog posts, and new or updated tutorials. Unsubscribe at any time.

Gift Delivery Options
Quick Checkout
or Pay by Credit Card
Error processing your payment
  • You didn't choose whether or not to be added to the mailing list
Confirm
$0.00

Payments and credit card details are securely managed and protected by Learn Enough's payment processor, Stripe. More information on their site:

CART
Total
$0.00

Your Cart is Empty

$30
$300
$300
$XY
$XY
1234
  • Python

Learn Enough Society

Certificate of Course Completion

This page certifies that actionjdjackson has completed Learn Enough Python to Be Dangerous! 🎉

About the tutorial
Learn Enough Python to Be Dangerous teaches you to write practical and modern programs in Python, one of the most popular programming languages in the world. Learn the Python interpreter, shell scripting, testing and test-driven development, package creation, beginning web development, and Python tools for data science. Read full post
14 Nov 13:16, 2020
1 Mar 14:28, 2023
Exercise Answers
Exercise Question:
  • Assign variables city and state to your current city and state of residence. (If residing outside the U.S., substitute the analogous quantities.) Using interpolation, print a string consisting of the city and state separated by a comma and a space, as in “Los Angeles, CA”.
  • actionjdjackson's Answer:
    Exercise Question:
  • Repeat the previous exercise but with the city and state separated by a tab character.
  • actionjdjackson's Answer:
    Exercise Question:
  • Do triple-quoted strings (Section 2.1) support interpolation?
  • actionjdjackson's Answer:
    Exercise Question:
  • If x is "foo" and y is "" (the empty string), what is the value of x and y? Verify using bool() that x and y is true in a boolean context.
  • actionjdjackson's Answer:
    Exercise Question:
  • Show that we can define a string of length 50 using the convenient code in Listing 2.20, which uses the asterisk * to “multiply” the string "a" by 50. Go through the steps in Listing 2.10 again with the new password to verify that Python prints out “Password is too long.”
  • actionjdjackson's Answer:
    Exercise Question:
  • Write the Python code to test whether the string “hoNeY BaDGer” includes the string “badger” without regard to case.
  • actionjdjackson's Answer:
    Exercise Question:
  • What is the Python method for stripping leading and trailing whitespace from a string? The result should be as shown in Listing 2.22 with FILL_IN replaced by the method name.
  • actionjdjackson's Answer:
    Exercise Question:
  • Write a for loop that prints out the characters of soliloquy in reverse order. Hint: What is the effect of the reversed() function on a string?
  • actionjdjackson's Answer:
    Exercise Question:
  • One disadvantage of the plain for loop in Listing 2.27 is that we no longer have access to the index value itself. We could solve this as in Listing 2.28, but the Pythonic way to do it is to use the enumerate() function to gain access to the index and the element at the same time. Confirm that you can use enumerate() to obtain the result shown in Listing 2.29.
  • actionjdjackson's Answer:
    Exercise Question:
  • Assign a to the result of splitting the string “A man, a plan, a canal, Panama” on comma-space. How many elements does the resulting list have?
  • actionjdjackson's Answer:
    Exercise Question:
  • Can you guess the method to reverse a in place? (Google around if necessary.)
  • actionjdjackson's Answer:
    Exercise Question:
  • We’ve seen that list(str) returns a list of the characters in a string. How can we make a list consisting of the numbers in the range 0–4? Hint: Recall the range() function first encountered in Listing 2.24.
  • actionjdjackson's Answer:
    Exercise Question:
  • Show that you can create a list of numbers in the range 17–41 using list() with range(17, 42).
  • actionjdjackson's Answer:
    Exercise Question:
  • Define a list with the numbers 0 through 9. Use slicing and len() to select the third element through the third-to-last. Accomplish the same task using a negative index.
  • actionjdjackson's Answer:
    Exercise Question:
  • Show that strings also support slicing by selecting just "bat" from the string "ant bat cat". (You might have to experiment a little to get the indices just right.)
  • actionjdjackson's Answer:
    Exercise Question:
  • To sort a list in reverse order, it’s possible to sort and then reverse, but the combined operation is so useful that both sort() and sorted() support a keyword argument (Section 5.1.2) that does it automatically. Confirm that a.sort(reverse=True) and sorted(a, reverse=True) both have the effect of sorting and reversing at the same time.
  • actionjdjackson's Answer:
    Exercise Question:
  • Using the list documentation, figure out how to insert an element at the beginning of a list.
  • actionjdjackson's Answer:
    Exercise Question:
  • Combine the two lists shown in Listing 3.7 into a single list using the extend() method. Does extend() mutate a1? Does it mutate a2?
  • actionjdjackson's Answer:
    Exercise Question:
  • Use reversed() to print out a list’s elements in reverse order.
  • actionjdjackson's Answer:
    Exercise Question:
  • We saw in Listing 3.10 that interpolating the values of the list into the string led to printing out, say, ant instead of "ant". We could put the quote marks in by hand, but then that would print 42 out as "42", which is also wrong. Solve this conundrum using the repr() function (Section 2.3) to interpolate a representation of each list element, as shown in Listing 3.12.
  • actionjdjackson's Answer:
    Exercise Question:
  • Confirm the existence of a tuple() function by converting sorted(t) from a list to a tuple.
  • actionjdjackson's Answer:
    Exercise Question:
  • Create a set with numbers in the range 0–4 by combining set() with range(). (Recall the use of range() in Listing 2.24.) Confirm that the pop() method mentioned in Section 3.4.3 allows you to remove one element at a time.
  • actionjdjackson's Answer:
    Exercise Question:
  • What happens when you call float() on the string "1.24e6"? What about if you call str() on the result?
  • actionjdjackson's Answer:
    Exercise Question:
  • Show that int(6.28) and int(6.98) both equal 6. This is the same behavior as the floor function (written in mathematics as \( \lfloor x \rfloor \)). Show that Python’s math module has a floor() function with the same effect as int().
  • actionjdjackson's Answer:
    Exercise Question:
  • Use Python to calculate how many seconds after the Moon landing you were born. (Or maybe you were even born before the Moon landing—in which case, lucky you! I hope you got to watch it on TV.)
  • actionjdjackson's Answer:
    Exercise Question:
  • Show that Listing 4.3 works even if you pull DAYNAMES out of the hello_world function, as shown in Listing 4.4. (This is the preferred location for constants in general—under library imports and separated from the rest of the file by two newlines.) Then use the calendar module to eliminate the constant entirely (Listing 4.5).
  • actionjdjackson's Answer:
    Exercise Question:
  • Write a regex that matches the extended-format ZIP code consisting of five digits, a hyphen, and a four-digit extension (such as 10118-0110). Confirm that it works using re.search() and the caption in Figure 4.8.6
  • actionjdjackson's Answer:
    Exercise Question:
  • Write a regex that splits only on newlines. Such regexes are useful for splitting a block of text into separate lines. In particular, test your regex by pasting the poem in Listing 4.6 into the console and using sonnet.split(/your regex/). What is the length of the resulting list?
  • actionjdjackson's Answer:
    Exercise Question:
  • Define a dictionary for a user with three attributes (keys): "username", "password", and "password_confirmation". How would you test if the password matches the confirmation?
  • actionjdjackson's Answer:
    Exercise Question:
  • We’ve seen in Listing 2.29 and Listing 3.10 that Python strings and lists support an enumerate() function in cases where we need the iteration index. Confirm that we can do the same thing with dictionaries using code like Listing 4.9.
  • actionjdjackson's Answer:
    Exercise Question:
  • By reversing the elements in Listing 4.8, show that dictionary merges aren’t symmetric, so d1 | d2 is not in general the same as d2 | d1. When are they the same?
  • actionjdjackson's Answer:
    Exercise Question:
  • Extend the regex used in Listing 4.12 to include an apostrophe, so it matches, e.g., “wand’ring”. Hint: Combine the first reference regex at regex101 (Figure 4.10) with \w, an apostrophe, and the plus operator +.
  • actionjdjackson's Answer:
    Exercise Question:
  • By running the code in Listing 4.13, show that we can effectively replicate the results of Listing 4.12 using the powerful Counter() function from the Python collections module. See this excellent video for more detail on this subject.
  • actionjdjackson's Answer:
    Exercise Question:
  • Run help(len) in the Python interpreter to confirm that help() works on built-in functions as well. What is the result of running the command help(print)? (The result in this case is called a multi-line docstring.)
  • actionjdjackson's Answer:
    Exercise Question:
  • Define a deriver() function as shown in Listing 5.5 that takes in a function and returns how much it changes over a small interval h. Confirm that you get the result shown for the square() function mentioned at the beginning of Section 5.1.1 (which was first defined in Listing 5.1). What is the result of evaluating deriver(math.cos, math.tau/2)?5
  • actionjdjackson's Answer:
    Exercise Question:
  • Define a function foo() with both *args and **kwargs as shown in Listing 5.6. What do you get when you execute the function as shown in the final statement of Listing 5.6? (Note that you should not type ... in the call to foo(); as we have seen when defining functions, those are continuation characters added automatically by the Python interpreter.)
  • actionjdjackson's Answer:
    Exercise Question:
  • Let’s replace the interpolated string in Listing 5.11 with a greeting() function in day.py. Fill in the code labeled FILL_IN in Listing 5.13 to get Listing 5.14 to work.
  • actionjdjackson's Answer:
    Exercise Question:
  • Using the Python interpreter, determine whether or not your system supports using the ispalindrome() function from Listing 5.17 on emojis. (You may find the Emojipedia links to the racing car and fox face emojis helpful.) If your system supports emojis in this context, the result should look something like Figure 5.8. (Note that an emoji is a “palindrome” if it’s the same when you flip it horizontally, so the fox-face emoji is a palindrome but the racecar emoji isn’t, even though the word “racecar” is a palindrome.)
  • actionjdjackson's Answer:
    Exercise Question:
  • Using the code in Listing 5.22, show that it’s possible to express the ispalindrome() function in one line using the advanced slice operator [::-1] discussed in Section 3.3. (Some Python programmers may prefer this approach, but I believe the decrease in length doesn’t justify the loss in clarity.)
  • actionjdjackson's Answer:
    Exercise Question:
  • Write a generator function that returns the first 50 even numbers.
  • actionjdjackson's Answer:
    Exercise Question:
  • Using a list comprehension, write a function that takes in the states variable and returns a list of URLs of the form https://example.com/<urlified form>.
  • actionjdjackson's Answer:
    Exercise Question:
  • Write two equivalent list comprehensions that return the Dakotas: one using in (Section 2.5) to test for the presence of the string “Dakota” and one that tests for the length of the split list being 2.
  • actionjdjackson's Answer:
    Exercise Question:
  • Using a dictionary comprehension, write a function that associates each element in states with its URL-compatible versions. Hint: Reuse the urlify() function defined in Listing 6.3.
  • actionjdjackson's Answer:
    Exercise Question:
  • Write a generator comprehension that returns the first 50 even numbers.
  • actionjdjackson's Answer:
    Exercise Question:
  • Use math.prod() to find the product of the numbers in the range 1–10. How does this compare to math.factorial(10)?
  • actionjdjackson's Answer:
    Exercise Question:
  • By filling in the code in Listing 7.6, add a louder method to the Phrase object that returns a LOUDER (all-caps) version of the content. Confirm in the REPL that the result appears as in Listing 7.7. Hint: Use the appropriate string method from Section 2.5.
  • actionjdjackson's Answer:
    Exercise Question:
  • Using the REPL, determine if list(phrase) works after the custom iterator has been defined as in Listing 7.8. What about joining on the empty string using "".join(phrase)?
  • actionjdjackson's Answer:
    Exercise Question:
  • What are the class hierarchies for lists and dictionaries?
  • actionjdjackson's Answer:
    Exercise Question:
  • You may have noticed that the processed_content() method is only used internally to the classes. Many object-oriented languages have a way of designating such methods as private, a practice known as encapsulation. Python doesn’t have truly private methods, but it does have a convention for indicating them using a leading underscore. Confirm that the classes still work after changing processed_content() to _processed_content() as shown in Listing 7.15. Note: Python has a second convention, known as name mangling, that uses two leading underscores. With this convention, Python automatically changes the name of the method in a standard way so that it can’t be easily accessed through an object instance.
  • actionjdjackson's Answer:
    Exercise Question:
  • It might make sense when iterating over a TranslatedPhrase to use the translation instead of the untranslated content. Arrange for this by overriding the __iter__ method in the derived class (Listing 7.16). Confirm using the Python interpreter that the updated iterator works as expected. (Note that Listing 7.16 incorporates the private method convention from the previous exercise.)
  • actionjdjackson's Answer:
    Exercise Question:
  • By filling in the code in Listing 8.23, add a test for a mixed-case palindrome like “RaceCar”. Is the test suite still green (or yellow)?
  • actionjdjackson's Answer:
    Exercise Question:
  • In order to make 100% sure that the tests are testing what we think they’re testing, it’s a good practice to get to a failing state (red) by intentionally breaking the tests. Change the application code to break each of the existing tests in turn, and then confirm that they are green again once the original code has been restored. An example of code that breaks the test in the previous exercise (but not the other tests) appears in Listing 8.24. (One advantage of writing the tests first is that this red–green cycle happens automatically.)
  • actionjdjackson's Answer:
    Exercise Question:
  • Confirm that commenting out the letters() stub in Listing 8.28 yields a failing state rather than an error state. (This behavior is relatively unusual, with many other languages distinguishing between a non-working method and one that’s missing altogether. In Python, though, the result is the same failing state in either case.)
  • actionjdjackson's Answer:
    Exercise Question:
  • Using the same code shown in Listing 8.16, import the Phrase class into the Python REPL and confirm directly that ispalindrome() can successfully detect palindromes of the form “Madam, I’m Adam.”
  • actionjdjackson's Answer:
    Exercise Question:
  • Let’s generalize our palindrome detector by adding the capability to detect integer palindromes like 12321. By filling in FILL_IN in Listing 8.38, write tests for integer non-palindromes and palindromes. Get both tests to green using the code in Listing 8.39, which adds a call to str to ensure the content is a string and includes \d in the regex to match digits as well as letters. (Note that we have updated the name of the letters() method accordingly.)
  • actionjdjackson's Answer:
    Exercise Question:
  • Bump the version number in pyproject.toml, commit and push your changes, build your package with build, and upload it with twine. In your temp directory, upgrade your package using the command in Listing 8.40 and confirm in the REPL that integer-palindrome detection is working. Note: The backslash \ in Listing 8.40 is a continuation character and should be typed literally, but the right angle bracket > should be added by your shell program automatically and should not be typed.
  • actionjdjackson's Answer:
    Exercise Question:
  • If you haven’t already, update Listing 8.3 with the right package name and fill the url and Bug Tracker fields with the corresponding GitHub URLs (the tracker URL is just the base URL plus /issues). Likewise, update the license template in Listing 8.5 with your name and the current year. Commit and push your changes up to GitHub.
  • actionjdjackson's Answer:
    Exercise Question:
  • You may have noticed some duplication in Listing 9.6: we first detect all palindromes, writing them out one at a time, and then find a list of all palindromes again (using a list comprehension). Show that we can eliminate this duplication by replacing the whole file with the more compact code shown in Listing 9.7. (Because the palindrome content itself already ends with a newline, Listing 9.7 calls print() with the end="" option mentioned in Section 2.3 to prevent a duplicate newline.)
  • actionjdjackson's Answer:
    Exercise Question:
  • One common pattern in Python shell scripts is to put the main steps in a separate function (often called main()) and then call the function only when the file itself is called as a shell script. (See this video for more.) Using the special syntax introduced in Section 7.1, show that the shell script in Listing 9.7 can be converted to Listing 9.8. Does it give the same result when executed at the command line?
  • actionjdjackson's Answer:
    Exercise Question:
  • Some Python programmers even prefer to put the content of the script in a different function and then have main() call that function, as seen in Listing 9.9. Show that this code still produces the same output as before.
  • actionjdjackson's Answer:
    Exercise Question:
  • In analogy with Listing 9.6, add code to Listing 9.10 that writes out a file called palindromes_url.txt. Confirm using the diff utility that the output is identical to the palindromes_file.txt file from Section 9.1.
  • actionjdjackson's Answer:
    Exercise Question:
  • Modify Listing 9.10 to use the more compact programming style seen in Listing 9.7 (including the step to write out the file).
  • actionjdjackson's Answer:
    Exercise Question:
  • By moving the file or changing your system’s configuration, add the wikp script to your environment’s PATH. (You may find the steps in Learn Enough Text Editor to Be Dangerous helpful.) Confirm that you can run wikp without prepending ./ to the command name. Note: If you have a conflicting wikp program from following Learn Enough JavaScript to Be Dangerous or Learn Enough Ruby to Be Dangerous, I suggest replacing it—thus demonstrating the principle that the file’s name is the user interface, and the implementation can change language without affecting users.
  • actionjdjackson's Answer:
    Exercise Question:
  • What happens if you run wikp with no argument? Add code to your script to detect the absence of a command-line argument and output an appropriate usage statement. Hint: After printing out the usage statement, you will have to exit, which you can learn how to do with the search python how to exit script.
  • actionjdjackson's Answer:
    Exercise Question:
  • The “pipe to pbcopy” trick mentioned in the text works only on macOS, but any Unix-compatible system can redirect the output to a file. What’s the command to redirect the output of wikp to a file called article.txt? (You could then open this file, select all, and copy the contents, which has the same basic result as piping to pbcopy.)
  • actionjdjackson's Answer:
    Exercise Question:
  • There’s a nice trick for installing all of an app’s requirements from a generated requirements.txt file using pip -r. Confirm that the sequence shown in Listing 10.10 results in a restored and working app.
  • actionjdjackson's Answer:
    Exercise Question:
  • Visit the /palindrome URL and confirm that the CSS and images are working.
  • actionjdjackson's Answer:
    Exercise Question:
  • Make a commit and deploy the changes.
  • actionjdjackson's Answer:
    Exercise Question:
  • As you can confirm by running the source of any page through an HTML validator, the current pages are valid HTML, but there’s a warning with a suggestion to add a lang (language) attribute to the html tag. Add the attribute lang="en" (for “English”) to the html tag in Listing 10.22 and confirm using a web inspector that it appears correctly on all three pages.
  • actionjdjackson's Answer:
    Exercise Question:
  • Make a commit and deploy the changes.
  • actionjdjackson's Answer:
    Exercise Question:
  • We can eliminate some duplication in Listing 10.29 by creating a function that returns the base title, as shown in Listing 10.42. Confirm that this code still gives a green test suite.
  • actionjdjackson's Answer:
    Exercise Question:
  • Make a commit and deploy the changes.
  • actionjdjackson's Answer:
    Exercise Question:
  • Confirm by submitting an empty textarea that the palindrome detector currently returns True for the empty string, which is a flaw in the palindrome package itself. What happens if you submit a bunch of spaces?
  • actionjdjackson's Answer:
    Exercise Question:
  • In the palindrome package, write tests asserting that the empty string and a string of spaces aren’t palindromes (red). Then write the application code necessary to get the tests to green. (It’s worth noting that the processed_content() method already filters out spaces, so in the application code you need only consider the case of the empty string, whose boolean value is False (Section 2.4.2).) Bump the version number and publish your package as in Section 8.5.1. (You can refer to my version if you’d like some help.)
  • actionjdjackson's Answer:
    Exercise Question:
  • Upgrade the test package in your web app directory using Listing 10.64 as a template and confirm that it’s working by submitting empty and blank phrases in the browser. (Recall that you should type the continuation character \ in Listing 10.64 but not the right angle bracket > since the latter will be inserted automatically by your shell program.)
  • actionjdjackson's Answer:
    Exercise Question:
  • Make a commit and deploy the changes. Confirm the correct behavior in the live app.
  • actionjdjackson's Answer:
    Exercise Question:
  • What happens if the dimensions in reshape() don’t match the array size (e.g., np.arange(16).reshape((4, 17)))?
  • actionjdjackson's Answer:
    Exercise Question:
  • Confirm that A = np.random.rand(5, 5) lets you define a \( 5\times5 \) random matrix.
  • actionjdjackson's Answer:
    Exercise Question:
  • Find the inverse Ainv of the \( 5\times5 \) matrix in the previous exercise. (Calculating the inverse of a \( 2\times2 \) matrix as in Section 11.2.2 is fairly simple by hand, but the task rapidly gets harder as the matrix size increases, in which case a computational system like NumPy is indispensable.)
  • actionjdjackson's Answer:
    Exercise Question:
  • What is the matrix product I = A @ Ainv of the matrices in the previous two exercises? Use the same isclose() trick from Listing 11.7 to zero out the elements of I close to zero and confirm that the resulting matrix is indeed the \( 5\times5 \) identity matrix.
  • actionjdjackson's Answer:
    Exercise Question:
  • Add a title and axis labels to the plot shown in Figure 11.15.
  • actionjdjackson's Answer:
    Exercise Question:
  • One common plotting task is including multiple subplots in the same figure. Show that the code in Listing 11.10 creates vertically stacked subplots, as shown in Figure 11.18. (Here the suptitle() method produces a “supertitle” that sits above both plots. See the Matplotlib documentation on subplots for other ways to create multiple subplots.)
  • actionjdjackson's Answer:
    Exercise Question:
  • Add a plot of the function \( \cos (x - \tau/8) \) to the plot in Figure 11.14 with color "orange" and linestyle "dashdot". Extra credit: Add an annotation as well. (The extra-credit step is much easier in an interactive Jupyter notebook, especially when finding the right coordinates for the annotation label and arrow.)
  • actionjdjackson's Answer:
    Exercise Question:
  • Add titles to the histograms in Section 11.3.3.
  • actionjdjackson's Answer:
    Exercise Question:
  • Confirm that FrĂ©dĂ©ric Joliot-Curie, who shared the 1935 Nobel Prize for Chemistry with his wife IrĂšne, appears in the laureates.csv dataset. Why did we miss him when we searched for Curies in Listing 11.15? Hint: Search for an entry with "firstname" equal to "FrĂ©dĂ©ric" (making sure to include the proper accents).
  • actionjdjackson's Answer:
    Exercise Question:
  • Verify that the Nobel Prize categories cited after Listing 11.16 are correct (e.g., that Frederick Sanger’s Nobel Prizes really were for Chemistry, etc.).
  • actionjdjackson's Answer:
    Exercise Question:
  • In Listing 11.17, what happens if you just call nobel.hist(), with no column specified?
  • actionjdjackson's Answer:
    Exercise Question:
  • Confirm using the code in Listing 11.21 that the Titanic survival rate for female passengers in third class was 50%. How does this compare to the survival rate for male passengers in first class?
  • actionjdjackson's Answer:
    Exercise Question:
  • Make two versions of the bar chart for Titanic survival rates by age shown in Figure 11.31, one each for male passengers and female passengers. Hint: Define sex-specific variables as shown in Listing 11.22 and redo the analysis after Listing 11.20 separately for the male_ and female_ variables.
  • actionjdjackson's Answer:
    Exercise Question:
  • The RandomForestClassifier() function takes a keyword argument called n_estimators that represents the “number of trees in the forest”. According to the documentation, what is the default value for n_estimators? Use random_state=1.
  • actionjdjackson's Answer:
    Exercise Question:
  • By varying n_estimators in the call to RandomForestClassifier(), determine the approximate value where the Random Forest classifier is less accurate than Decision Tree. Use random_state=1.
  • actionjdjackson's Answer:
    Exercise Question:
  • By rerunning the steps in Section 11.7.2 using a few different values of random_state, verify that the ordering is not always the same as shown in Listing 11.25. Hint: Try values like 0, 2, 3, and 4.
  • actionjdjackson's Answer:
    Exercise Question:
  • Repeat the clustering steps in Section 11.7.3 using two clusters and eight clusters. Does the algorithm still work well in both cases?
  • actionjdjackson's Answer:

    Join the Mailing List

    Get occasional notifications about things like product discounts, blog posts, and new or updated tutorials. Unsubscribe at any time.