class: big, middle # Engineering 1020: Introduction to Programming .title[ .lecture[Lecture \13\:] .title[Functions] ] .footer[[/lecture/13/](/lecture/13/)] --- # The story so far -- .floatleft[ * Computation * Expressions * Variables ] -- .floatleft[ * Flow control: * `if` statements * loops: `while`, `for` and iteration ] -- * Function definition -- * Later: objects, modules, more types, numbers... --- # Today ### Functions -- (with a bit more structure) -- : * Semantics -- * Syntax (both call _and_ definition) -- * Parameters and arguments --- # Don't repeat yourself! .floatright[ ```python count = 0 if name[0] == 'e': count += 1 if name[1] == 'e': count += 1 if name[2] == 'e': count += 1 if name[3] == 'e': count += 1 # ... ``` ] ### What's wrong with this code? -- * technically nothing -- **iff** we know how many characters are in `name` -- * but we **don't** always know -- * also... ick! ??? This code, in addition to being inflexible, offends our programmer's sense of aesthetics. Programmers are **lazy in a good way**: we don't like to repeat ourselves! --- # More repetition .floatright[ ```python for i in range(word_lenth): if word_a[i] < word_b[i]: print(word_a, '<', word_b) break if word_b[i] < word_a[i]: print(word_b, '<', word_a) break for i in range(word_lenth): if word_b[i] < word_c[i]: print(word_b, '<', word_c) break if word_c[i] < word_b[i]: print(word_c, '<', word_b) break ``` ] ### What's wrong here? * lexical ordering of words -- * comparing word A to B is fine -- * comparing A to B and B to C is repetitive -- * what if we need to compare lots of words in a game? --- # Functions ### A way of creating _abstractions_ -- ### A procedure that we can: -- * define once -- * use many times -- ## Help us stay DRY -- (don't repeat yourself) --- # Function call ### We've been using this for a while: ```python print('hello') ``` -- A function call is an _expression_ that _evaluates_ to something: ```python a = analog_read(2) ``` -- A call can take multiple _arguments:_ ```python digital_write(4, True) ``` --- # Function definition .floatright[ ```python def any_valid_name(x, y, z): """Example of function documentation. It's common to start a function with a description in a Python "docstring". """ # we can return any expression, or None return x + y * z ``` ] -- * `def` keyword -- * function name ("valid"?) -- * parameters -- * docstring* .footnote[ * A _triple-quoted_ string can have **multiple lines** in it, and, it's safe to use either single (`'`) or double (`"`) quotes without causing confusion ("is this the end of the string?"). ] -- * function _body_ --- # Parameters vs arguments -- ### Parameters: _variables_ initialized by arguments ```python def abs(x): if x >= 0: positive = x else: positive = -x return positive ``` -- ### Arguments: _values_ passed into functions ```python abs(-2) ``` --- # Function docstrings .floatright[ ```python def any_valid_name(x, y, z): """Example of function documentation. It's common to start a function with a description in a Python "docstring". """ # we can return any expression, or None return x + y * z ``` ] * description of function * like a comment: for people, not the computer * often _triple-quoted*_ .footnote[ * A _triple-quoted_ string can have **multiple lines** in it, and, it's safe to use either single (`'`) or double (`"`) quotes without causing confusion ("is this the end of the string?"). ] --- # Function body .floatright[ ```python def any_valid_name(x, y, z): """Example of function documentation. It's common to start a function with a description in a Python "docstring". """ # we can return any expression, or None return x + y * z ``` ] * one or more statements -- * can be _any_ statement ??? A function body can include any kind of statement: assignment, `if` statement, loop... -- * can be `pass` ??? A function body must have **at least** one statement in it. However, that statement can be `pass`, which means "do nothing". --- # Return value .floatright[ ```python def any_valid_name(x, y, z): """Example of function documentation. It's common to start a function with a description in a Python "docstring". """ # we can return any expression, or None return x + y * z ``` ] * a function's "output" -- * input: arguments to parameters -- * output: `return` value -- * can be any value -- * can be `None` ??? A function with no `return` statement implicitly returns **`None`**. --- class: big, middle (here endeth the lesson)