Working with Python functions is kinda what we do in this class. We know how to create them using def
and lambda
keywords. We know how to compose them by feeding the outputs of one function as the input to another lambda x: f(g(x))
. And we know how to map them, creating new columns in our dataset out of old ones df['PTS_demeaned'] = df['PTS'].map(lambda x: x-df['PTS'].mean())
We’re going to continue to add to our bag of knowledge about how to work with functions today by considering how we can partially apply functions. To make things concrete, let’s consider a function that takes hourly wage and hours worked as inputs and returns the total income, with the hourly wage multiplied by 1.5 for hours beyond 40. We can express this in Python via the following function:
def Income(wage: float, hours: int) -> float:
return wage * hours + (hours > 40)*(hours-40)*.5*wage
The signature for this function is the following. This says that Income takes a wage and an hour and returns some dollar amount.
$$ \text{Income}: \text{Wage} \times \text{Hours} \to \text{Dollars} $$
We could also think of the signature of this function as follows:
$$ \text{Income}: \text{Wage} \to \big(\text{Hours}\to \text{Dollars}\big) $$
This says that Income takes a wage and returns a function that maps from Hours to Dollars. Or stepping back, this suggests that every multi-input function can actually be understood as a single-input function that returns a function. We’ll see an example at the end of these notes that will highlight why we might want to think of functions in this way. But in terms of executing this in python, we use a function partial
which takes the function and a value for the first variable and returns the corresponding function.
hours = np.linspace(0, 80, 80)
f = partial(income, 20.0)
ys = list(map(f, hours))