Session 19

Going Deeper with Functions

CS 1510
Introduction to Computing

Quick Exercise

When we compute interest that is compounded daily, or population growth based on average daily changes, we need to know if a year is a leap year or not. In our calendar, a leap year is divisible by 4. However, years divisible by 100 are not leap years, with one exception: years divisible by 400 are leap years.

Write a Python function named is_leap_year() that takes a year as an argument and returns true or false as its value.

Does this work?

    def is_leap_year(year):
        if year % 4 == 0:
            return True
        if year % 100 == 0:
            return False
        if year % 400 == 0:
            return True
        return False

Why not? We have to handle the special cases first, because otherwise the normal cases return the wrong answer. Here is one solution, plus a loop for demonstrating the function. In what other ways could we have written the function?

I have tired of writing and reading the a % b == 0 construction...

Write a Python function named divisible_by() that takes a number and a divisor as arguments and returns true if the number is evenly divisible by the divisor, and false otherwise.

That's straightforward:

    def divisible_by(number, divisor):
        return number % divisor == 0

Why bother? Because now we can write is_leap_year() in a way that resembles the English definition:

    def is_leap_year(year):
        return divisible_by(year, 400) or \
               divisible_by(year, 4) and not divisible_by(year, 100)

Recall the description of a function as conceptually, a single operation. Functions let us turn ideas in the problem space into named operations in our programs. The result can be code that is easier to read!

A Look at Functions

The problem of Section 6.3.4, given on Page 267:

Find a word that contains the vowels a, e, i, o, and u in that order.

To solve this word puzzle, we need a list of words.

Now we are ready to solve the problem, but how?

    big task

       for every word in the dictionary
           if the word contains 'aeiou' in order
              print the word

      - lines read from file contain \n
      - some words are capitalized
      - any word with fewer than five characters
        can't be a solution

    improved algorithm
       for every word in the dictionary
           scrub the word
           if it has fewer than five characters
              ignore the word
           if the word contains 'aeiou' in order
              print the word

    ideally, our program will look like this!

    the code for
        scrub the word
        if the word contains 'aeiou' in order
    will be complex enough to obscure the algorithm

    so write functions for them!
      - scrub(word) → same word, no caps, no whitespace
      - contains(word, char_list) → true or false

First pass:

    word_source = open ('dictionary.txt', 'r')
    for word in word_source:
        word = scrub(word)
        if len(word) < 5:
        if contains(word, 'aeiou'):

Now write scrub(word).

And write contains(word,char_list).

This gives us Our dictionary has several more matches ('abstemious', 'arsenious', 'caesious'), plus a few words that contain more vowels, as long as 'aeiou' appear in order ('facetiousness', 'nonabstemious').

Returning from a Function

No return? A procedure. Python does return a 'special' value. But we don't care. We use procedures for their effect.

Many returns? The first one executed causes the function to stop and return. Make sure if has an else, for a default case, or a 'backstop'.

Wrap Up

Eugene Wallingford ..... ..... October 28, 2014