Chapter 5 Exercise Set 1: Doctest Exercises

Doctest practice set 1

All of the exercises below should be added to a file named ch05practice1.py that contains the following at the bottom:

if __name__ == '__main__':
    import doctest
    doctest.testmod()

After completing each exercise in turn, run the program to confirm that the doctests for your new function pass.

  1. Write a compare function that returns 1 if a > b, 0 if a == b, and -1 if a < b.

    def compare(a, b):
        """
          >>> compare(8, 4)
          1
          >>> compare(7, 7)
          0
          >>> compare(2, 9)
          -1
          >>> compare(42, 1)
          1
          >>> compare('c', 'a')
          1
          >>> compare('p', 'p')
          0
        """
        #  Your function body should begin here.
    

    Fill in the body of the function so the doctests pass.

  2. Use incremental development to write a function called hypotenuse that returns the length of the hypotenuse of a right triangle given the lengths of the two legs as parameters. Record each stage of the incremental development process as you go.

    def hypotenuse(a, b):
        """
          >>> hypotenuse(3, 4)
          5.0
          >>> hypotenuse(12, 5)
          13.0
          >>> hypotenuse(7, 24)
          25.0
          >>> hypotenuse(9, 12)
          15.0
        """
    

    When you are finished add your completed function with the doctests to ch05practice1.py and confirm that the doctests pass.

  3. Write a function slope(x1, y1, x2, y2) that returns the slope of the line through the points (x1, y1) and (x2, y2). Be sure your implementation of slope can pass the following doctests:

    def slope(x1, y1, x2, y2):
        """
          >>> slope(5, 3, 4, 2)
          1.0
          >>> slope(1, 2, 3, 2)
          0.0
          >>> slope(1, 2, 3, 3)
          0.5
          >>> slope(2, 4, 1, 2)
          2.0
        """
    

    Then a call to slope in a new function named intercept(x1, y1, x2, y2) that returns the y-intercept of the line through the points (x1, y1) and (x2, y2).

    def intercept(x1, y1, x2, y2):
        """
          >>> intercept(1, 6, 3, 12)
          3.0
          >>> intercept(6, 1, 1, 6)
          7.0
          >>> intercept(4, 6, 12, 8)
          5.0
        """
    

    intercept should pass the doctests above.

  4. Write a function called is_even(n) that takes an integer as an argument and returns True if the argument is an even number and False if it is odd.

    Add your own doctests to this function.

  5. Now write the function is_odd(n) that returns True when n is odd and False otherwise. Include doctests for this function as you write it.

    Finally, modify it so that it uses a call to is_even to determine if its argument is an odd integer.

  6. Add the following function definition header and doctests to ch05practice1.py:

    def is_factor(f, n):
        """
          >>> is_factor(3, 12)
          True
          >>> is_factor(5, 12)
          False
          >>> is_factor(7, 14)
          True
          >>> is_factor(2, 14)
          True
          >>> is_factor(7, 15)
          False
        """
    

    Add a body to is_factor to make the doctests pass.

  7. Add the following function definition header and doctests to ch05practice1.py:

    def is_multiple(m, n):
        """
          >>> is_multiple(12, 3)
          True
          >>> is_multiple(12, 4)
          True
          >>> is_multiple(12, 5)
          False
          >>> is_multiple(12, 6)
          True
          >>> is_multiple(12, 7)
          False
        """
    

    Add a body to is_multiple to make the doctests pass. Can you find a way to use is_factor in your definition of is_multiple?

  8. Add the following function definition header and doctests to ch05practice1.py:

    def f2c(t):
        """
          >>> f2c(212)
          100
          >>> f2c(32)
          0
          >>> f2c(-40)
          -40
          >>> f2c(36)
          2
          >>> f2c(37)
          3
          >>> f2c(38)
          3
          >>> f2c(39)
          4
        """
    

    Write a body for the function definition of f2c designed to return the integer value of the nearest degree Celsius for given tempurature in Fahrenheit. (hint: you may want to make use of the built-in function, round. Try printing round.__doc__ in a Python shell and experimenting with round until you are comfortable with how it works.)

  9. Add the following function definition header and doctests to ch05practice1.py:

    def c2f(t):
        """
          >>> c2f(0)
          32
          >>> c2f(100)
          212
          >>> c2f(-40)
          -40
          >>> c2f(12)
          54
          >>> c2f(18)
          64
          >>> c2f(-48)
          -54
        """
    

    Add a function body for c2f to convert from Celsius to Fahrenheit.

Chapter 5 doctest practice set 2

All of the exercises below should be added to a file named ch05practice2.py

  1. Write a function, is_prime, which takes a single integral argument and returns True when the argument is a prime number and False otherwise. Add doctests to your function as you develop it.

  2. What will num_digits(0) return? Modify it to return 1 for this case. Why does a call to num_digits(-24) result in an infinite loop (hint: -1 // 10 evaluates to -1)? Modify num_digits so that it works correctly with any integer value. Add the following to the ch06practice2.py file you created in the previous exercise:

    def num_digits(n):
        """
          >>> num_digits(12345)
          5
          >>> num_digits(0)
          1
          >>> num_digits(-12345)
          5
        """
    

    Add your function body to num_digits and confirm that it passes the doctests.

  3. Add the following to the ch05practice2.py:

    def num_even_digits(n):
        """
          >>> num_even_digits(123456)
          3
          >>> num_even_digits(2468)
          4
          >>> num_even_digits(1357)
          0
          >>> num_even_digits(2)
          1
          >>> num_even_digits(20)
          2
        """
    

    Write a body for num_even_digits so that it works as expected.

  4. Add the following to ch05practice2.py:

    def print_digits(n):
        """
          >>> print_digits(13789)
          9 8 7 3 1
          >>> print_digits(39874613)
          3 1 6 4 7 8 9 3
          >>> print_digits(213141)
          1 4 1 3 1 2
          >>> returned = print_digits(123)
          3 2 1
          >>> print(returned)
          None
        """
    

    Write a body for print_digits so that it passes the given doctests.

  5. Write a function sum_of_squares_of_digits that computes the sum of the squares of the digits of an integer passed to it. For example, sum_of_squares_of_digits(987) should return 194, since 9 ** 2 + 8 ** 2 + 7 ** 2 == 81 + 64 + 49 == 194.

    def sum_of_squares_of_digits(n):
        """
          >>> sum_of_squares_of_digits(1)
          1
          >>> sum_of_squares_of_digits(9)
          81
          >>> sum_of_squares_of_digits(11)
          2
          >>> sum_of_squares_of_digits(121)
          6
          >>> sum_of_squares_of_digits(987)
          194
        """
    

    Check your solution against the doctests above.

  6. Encapsulate

    fruit = "banana"
    count = 0
    for char in fruit:
        if char == 'a':
            count += 1
    print(count)
    

    in a function named count_letter, and generalize it so that it accepts the string, s and the letter, letter, as arguments. Make the function return the number of characters, rather than print the answer. The caller should do the printing.

    Add your own doctests and run them on your new function to make sure it behaves as you expect it to.