@@ -171,6 +171,135 @@ print(new_abs_function(3))
171171print(new_abs_function(-3))
172172```
173173174+### Keyword Arguments
175+176+```{index} single: Python; keyword arguments
177+```
178+179+In a {ref}`previous lecture <python_by_example>`, you came across the statement
180+181+```{code-block} python3
182+:class: no-execute
183+184+plt.plot(x, 'b-', label="white noise")
185+```
186+187+In this call to Matplotlib's `plot` function, notice that the last argument is passed in `name=argument` syntax.
188+189+This is called a *keyword argument*, with `label` being the keyword.
190+191+Non-keyword arguments are called *positional arguments*, since their meaning
192+is determined by order
193+194+* `plot(x, 'b-', label="white noise")` is different from `plot('b-', x, label="white noise")`
195+196+Keyword arguments are particularly useful when a function has a lot of arguments, in which case it's hard to remember the right order.
197+198+You can adopt keyword arguments in user-defined functions with no difficulty.
199+200+The next example illustrates the syntax
201+202+```{code-cell} python3
203+def f(x, a=1, b=1):
204+ return a + b * x
205+```
206+207+The keyword argument values we supplied in the definition of `f` become the default values
208+209+```{code-cell} python3
210+f(2)
211+```
212+213+They can be modified as follows
214+215+```{code-cell} python3
216+f(2, a=4, b=5)
217+```
218+219+### The Flexibility of Python Functions
220+221+As we discussed in the {ref}`previous lecture <python_by_example>`, Python functions are very flexible.
222+223+In particular
224+225+* Any number of functions can be defined in a given file.
226+* Functions can be (and often are) defined inside other functions.
227+* Any object can be passed to a function as an argument, including other functions.
228+* A function can return any kind of object, including functions.
229+230+We already {ref}`gave an example <test_program_6>` of how straightforward it is to pass a function to
231+a function.
232+233+Note that a function can have arbitrarily many `return` statements (including zero).
234+235+Execution of the function terminates when the first return is hit, allowing
236+code like the following example
237+238+```{code-cell} python3
239+def f(x):
240+ if x < 0:
241+ return 'negative'
242+ return 'nonnegative'
243+```
244+245+Functions without a return statement automatically return the special Python object `None`.
246+247+248+### Docstrings
249+250+```{index} single: Python; Docstrings
251+```
252+253+Python has a system for adding comments to functions, modules, etc. called *docstrings*.
254+255+The nice thing about docstrings is that they are available at run-time.
256+257+Try running this
258+259+```{code-cell} python3
260+def f(x):
261+ """
262+ This function squares its argument
263+ """
264+ return x**2
265+```
266+267+After running this code, the docstring is available
268+269+```{code-cell} ipython
270+f?
271+```
272+273+```{code-block} ipython
274+:class: no-execute
275+276+Type: function
277+String Form:<function f at 0x2223320>
278+File: /home/john/temp/temp.py
279+Definition: f(x)
280+Docstring: This function squares its argument
281+```
282+283+```{code-cell} ipython
284+f??
285+```
286+287+```{code-block} ipython
288+:class: no-execute
289+290+Type: function
291+String Form:<function f at 0x2223320>
292+File: /home/john/temp/temp.py
293+Definition: f(x)
294+Source:
295+def f(x):
296+ """
297+ This function squares its argument
298+ """
299+ return x**2
300+```
301+302+With one question mark we bring up the docstring, and with two we get the source code as well.
174303175304### One-Line Functions: `lambda`
176305@@ -351,6 +480,7 @@ In the context of our program, the ability to bind new names to functions
351480means that there is no problem *passing a function as an argument to another
352481function*---as we did above.
353482483+354484## Exercises
355485356486```{exercise}