# Chapter 5 exercise set 1¶

## `count_letter(letter, s)`¶

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.

## 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.