Working with data
Imagine you are asked to compute the average of a list of numbers. But you need to only take the average of the positive numbers, skipping over any that are less than or equal to zero.
Here is one way to do that:
def average_positive(numbers): """ Take a list of numbers, and return the average of the positive values in the list """ total = 0 n = 0 for number in numbers: if number > 0: total = total + number n = n + 1 return total / n if __name__ == '__main__': # try it the first way result = average_positive([-100, 1, 0, 2, 3]) print(result)
Working with the data this way, we are going through the list one time and doing all our calculations as we go through the list.
TO do this, we need two variables that we use to compute the average. One is
total, which we use to calculate the total of all of the positive numbers in
numbers list. The second is
n, which we use to count how many numbers
We increment both
n only for the positive numbers. We increment
number, and we increment
If you are confused by this code, copy it into PyCharm and run it through the
debugger. Step through each line of
average_position() and notice how
number change values over time.
Here is another way to do this problem:
def only_positives(numbers): """ Take a list of numbers and return a NEW list that has only the positive numbers from the original list. """ new_list =  for number in numbers: if number > 0: new_list.append(number) return new_list def average_numbers(numbers): """ Take a list of numbers and average them. """ total = 0 for number in numbers: total = total + number return total / len(numbers) def average_positive(numbers): """ Take a list of numbers, and return the average of the positive values in the list """ # get a list of only the positive numbers new_list = only_positives(numbers) # average the list of numbers average = average_numbers(new_list) return average if __name__ == '__main__': result = average_positive2([-100, 1, 0, 2, 3]) print(result)
In this case, we first use the original list of numbers to create a new list that has only positive numbers. This is a filtering operation. Then once we have a list of only positive numbers, we take the average of them. This is a reduce operation.
Thinking about a problem this way centers the data rather than the operations on the data. The purpose of the code is to manipulate the data, one step at a time, until we have the result we need.
You may want to use this way of solving the problem if you are going to need the
basic pieces — removing negative numbers, taking an average of a list of
numbers — many more times. For example, maybe you have a problem that requires
averaging all numbers, regardless of whether they are positive or negative. Our
average_numbers() function works just fine for that. But if we used the first
solution, we would need to write some new code.
The accumulator pattern
Both solutions to this problem show examples of using the
to solve a problem. With this pattern, you initialize a variable to some value
(zero, an empty list), and then add to it (adding to a total, appending to the
list) in a loop.
In this class, you will practice these patterns repeatedly so they will become second-nature to you.