# Generalizing Functions to Be More Reusable

- February 18, 2018
- Key Terms: functions

In a previous tutorial on functions, I utilized the example below with bike trips data and a function to calculate the duration of all trips in seconds.

But, it wasn't *perfect*.

Inside the function, I utilized an index of `0`

so I could iterate over the first index of trip duration values in each inner list.

However, we can make that function better by making it more **generalizable** so the function can serve multiple purposes. To make it more **generalizable**, let's allow the function to take an additional argument for an index value of our inner lists (each representing a ride).

### Bike Trips Example¶

#### Sample Data¶

Below is a sample of data for bike trips as a list of lists. Each inner list holds the data for a trip formatted as *[duration in seconds, date]*.

```
bike_trips = [[475, '2018-02-18'],
[825, '2018-02-18'],
[1034, '2018-02-18'],
[980, '2018-02-18'],
[1350, '2018-02-19'],
[1880, '2018-02-19'],
[1950, '2018-02-19'],
[1530, '2018-02-19']
]
```

I previously created a function to find the sum of seconds biked on a given day.

#### Old function to calculate sum of trip durations on a day¶

```
# global variables below can be used in any function
index_trip_duration_seconds = 0
index_trip_date = 1
def sum_seconds_biked_day(ride_date):
"""
Find the sum of seconds biked on a given day
Keyword argument:
ride_date -- date (string in format year-month-day)
"""
sum_trips_seconds = 0
for trip in bike_trips:
if trip[index_trip_date] == ride_date:
sum_trips_seconds += trip[index_trip_duration_seconds]
return sum_trips_seconds
```

#### New more generalizable function to calculate the sum over an index in our inner lists¶

```
def sum_of_index_value(ride_date, index_value):
"""
Find the sum through iteration over an index value in a list of lists
Keyword argument:
ride_date -- date (string in format year-month-day)
index_value -- index of inner list (int)
"""
sum_values = 0
for trip in bike_trips:
if trip[index_trip_date] == ride_date:
sum_values += trip[index_value]
return sum_values
```

### Application of New Function¶

Let's say our `bike_trips`

data structure is improved upon to add miles ridden with each ride.

Each inner list now holds the data for a trip formatted as *[duration in seconds, miles ridden, date]*.

```
bike_trips = [[475, '2018-02-18', 1.8],
[825, '2018-02-18', 3.2],
[1034, '2018-02-18', 4.5],
[980, '2018-02-18', 3.9],
[1350, '2018-02-19', 5.1],
[1880, '2018-02-19', 7.3],
[1950, '2018-02-19', 6.3],
[1530, '2018-02-19', 5.4],
[1350, '2018-02-19', 4.0],
[2345, '2018-02-20', 7.0],
[2353, '2018-02-20', 6.4]
]
```

Create a new variable to assign miles ridden to an index value.

```
index_miles_ridden = 2
```

#### Apply `sum_of_index_value`

to calculate sum of trip durations¶

When a function has more than a few numeric arguments, it is easy to forget what they are, or what order they should be in. In that case it is often a good idea to include the names of the parameters in the argument list: polygon(bob, n=7, length=70) These are called keyword arguments because they include the parameter names as “key- words” (not to be confused with Python keywords like while and def). This syntax makes the program more readable. It is also a reminder about how arguments and parameters work: when you call a function, the arguments are assigned to the param- eters.

Now that are function takes two arguments, I like to include the names of the parameters in the argument list. This helps with readability.

These are called **keyword arguments** because they include the parameter names as *keywords*.

```
sum_of_index_value(ride_date='2018-02-18', index_value=index_trip_duration_seconds)
```

#### Apply `sum_of_index_value`

to calculate sum of miles ridden¶

```
sum_of_index_value(ride_date='2018-02-18', index_value=index_miles_ridden)
```

**Our new function now serves two (or more) purposes, instead of just one.**