Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8a35945

Browse files
committedJul 5, 2017
Add lessons and challenges for Functions chapter
1 parent fe3e6c7 commit 8a35945

File tree

32 files changed

+471
-0
lines changed

32 files changed

+471
-0
lines changed
 
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
## Built-in Functions
2+
3+
The Python interpreter has a number of functions and types built into it that are always available.
4+
They are listed [here](https://docs.python.org/3/library/functions.html) in alphabetical order.
5+
Python 3's builtins module provides direct access to all of the built-in functions.
6+
You don't need to import any modules when using a built-in function, just call the function with the appropriate arguments.
7+
- https://docs.python.org/3/library/functions.html#built-in-functions
8+
- https://docs.python.org/3/library/builtins.html#module-builtins
9+
- https://github.com/python/cpython/blob/3.6/Python/bltinmodule.c
10+
```
11+
>>> print("print() is a built-in function in Python 3")
12+
print() is a built-in function in Python 3
13+
>>> type([1,2,3,4,5])
14+
<class 'list'>
15+
>>> sum([1,2,3,4,5])
16+
15
17+
>>> id(sum([1,2,3,4,5]))
18+
4412662784
19+
```
20+
**_Instructions:_**
21+
**In the console you will find a list of numbers.**
22+
**There is a built-in function that will return a new sorted list from the items in numbers.**
23+
**Find this function, call it using the variable named numbers as the argument, and assign this function call to the variable named result.**
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"lesson_title": "Built In Functions",
3+
"chapter_number": 8,
4+
"lesson_number": 1,
5+
"id": "",
6+
"repl": ""
7+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import unittest
2+
from main import *
3+
4+
class BuiltInFunctionsTests(unittest.TestCase):
5+
def test_main(self):
6+
self.assertIsInstance(result, list)
7+
self.assertNotIsInstance(result, str)
8+
self.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8])
9+
self.assertNotEqual(result, [6, 3, 1, 8, 5, 2, 4, 7])
10+
self.assertNotEqual(result, numbers)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
numbers = [6, 3, 1, 8, 5, 2, 4, 7]
2+
3+
### Assign the correct built-in function to the variable named result below: ###
4+
5+
result = "Replace this string with the correct answer"
6+
7+
### Write your code above this line
8+
print(result)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## User Defined Functions
2+
3+
The keyword `def` introduces a function definition.
4+
It must be followed by the function name and a parenthesized list of formal parameters (if any).
5+
The statements that form the body of the function start at the next line, and must be indented.
6+
After a function has been defined, it can be called by typing the function name immediately followed by parentheses that contain the function's arguments (if any).
7+
- https://docs.python.org/3/glossary.html#term-function
8+
- https://docs.python.org/3/glossary.html#term-parameter
9+
- https://docs.python.org/3/glossary.html#term-argument
10+
- https://docs.python.org/3/tutorial/controlflow.html#defining-functions
11+
- https://docs.python.org/3/reference/compound_stmts.html#def
12+
- https://docs.python.org/3/reference/expressions.html#calls
13+
- https://www.python.org/dev/peps/pep-0008/#function-names
14+
```
15+
>>> def the_truth():
16+
... return True
17+
...
18+
>>> the_truth()
19+
True
20+
```
21+
22+
**_Instructions:_**
23+
**Define a function named say_hello() that has no parameters and prints the string "Hello World!" to the console.**
24+
**Your function should not contain a return statement, only a print statement.**
25+
**After you have defined the function, call it.**
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"lesson_title": "User Defined Functions",
3+
"chapter_number": 8,
4+
"lesson_number": 2,
5+
"id": "",
6+
"repl": ""
7+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import unittest
2+
import sys
3+
from io import StringIO
4+
from main import *
5+
6+
class UserDefinedFunctionsTests(unittest.TestCase):
7+
def test_main(self):
8+
# Make sure there is no return statement.
9+
self.assertIsNone(say_hello())
10+
11+
def test_function_name(self):
12+
# Make sure that the function has the correct name.
13+
f = open('main.py')
14+
lines = str(f.readlines())
15+
f.close()
16+
self.assertRegex(lines, 'say_hello()', msg="The name of the function is incorrect.")
17+
18+
def test_output(self):
19+
# Make sure that calling say_hello() outputs the correct string.
20+
saved_stdout = sys.stdout
21+
try:
22+
out = StringIO()
23+
sys.stdout = out
24+
say_hello()
25+
output = out.getvalue().strip()
26+
assert output == "Hello World!"
27+
finally:
28+
sys.stdout = saved_stdout
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
### Define the say_hello() function and fill in the function body below this line: ###
2+
3+
4+
5+
### Call the say_hello() function below this line: ###
6+
say_hello()
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
## Function Documentation Strings
2+
3+
Function documentation strings (docstrings) offer a way to provide additional information about a function and its properties.
4+
A docstring is a string literal that occurs as the first statement in a module, function, class, or method definition.
5+
Such a docstring becomes the \_\_doc\_\_ special attribute of that object.
6+
The docstring for a function or method should summarize its behavior and document its arguments, return value(s), side effects, exceptions raised, and restrictions on when it can be called (all if applicable).
7+
Optional arguments should be indicated.
8+
There are two forms of docstrings: one-liners and multi-line docstrings.
9+
For consistency, always use """triple double quotes""" around docstrings.
10+
11+
- https://docs.python.org/3/tutorial/controlflow.html#documentation-strings
12+
- https://www.python.org/dev/peps/pep-0257/
13+
```
14+
>>> def some_function():
15+
... """
16+
... This function does nothing, but it's documented.
17+
...
18+
... Multiline docstrings are for more detailed descriptions.
19+
... """
20+
... pass
21+
...
22+
>>> print(some_function.__doc__)
23+
24+
This function does nothing, but it's documented.
25+
26+
Multiline docstrings are for more detailed descriptions.
27+
```
28+
29+
**_Instructions:_**
30+
**In the console you will find a function named docstring\_function().**
31+
**In the space between the function definition and the `pass` keyword, write any string you like using the docstring triple-double quotes convention.**
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"lesson_title": "Function Documentation Strings",
3+
"chapter_number": 8,
4+
"lesson_number": 3,
5+
"id": "",
6+
"repl": ""
7+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import unittest
2+
from main import *
3+
4+
class FunctionDocumentationStringsTests(unittest.TestCase):
5+
def test_main(self):
6+
self.assertIsNone(docstring_function())
7+
self.assertIsNotNone(docstring_function.__doc__)
8+
self.assertIsInstance(docstring_function.__doc__, str)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
def docstring_function():
2+
### Write your docstring below this line. ###
3+
4+
5+
6+
### Write your docstring above this line. ###
7+
pass
8+
9+
print(docstring_function.__doc__)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## Arguments vs Parameters
2+
3+
When dealing with functions, the terms argument and parameter are sometimes used interchangeably, but they do NOT mean the same thing.
4+
The difference between arguments and parameters can cause some confusion, especially for novice programmers.
5+
Parameters are defined by the names that appear in a function definition and define what types of arguments a function can accept.
6+
Arguments are the values actually passed to a function when calling it.
7+
When you DEFINE a function after the `def` keyword, the parameters are named inside the parentheses that follow.
8+
When you CALL a function, the arguments are assigned inside the parentheses that follow.
9+
- https://docs.python.org/3/faq/programming.html#what-is-the-difference-between-arguments-and-parameters
10+
- https://docs.python.org/3/glossary.html#term-argument
11+
- https://docs.python.org/3/glossary.html#term-parameter
12+
```
13+
# The parameters are inside the parentheses in the function definition.
14+
>>> def some_function(foo, bar=None):
15+
... return foo, bar
16+
...
17+
# The arguments are inside the parentheses in the function call.
18+
>>> some_function(42, bar='baz')
19+
(42, 'baz')
20+
```
21+
**_Instructions:_**
22+
**In the console, above the variable named result, define a function named my_function that has a single parameter named parameter.**
23+
**In the function body, tell the function to return parameter.**
24+
**After the equal sign for the variable named result, call my_function() and set the argument as the string 'argument'.**
25+
**When finished, you will have assigned the result of the my_function() call to the variable named result.**
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"lesson_title": "Arguments vs Parameters",
3+
"chapter_number": 8,
4+
"lesson_number": 4,
5+
"id": "",
6+
"repl": ""
7+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import unittest
2+
from main import *
3+
4+
class ArgumentsVsParametersTests(unittest.TestCase):
5+
def test_output(self):
6+
self.assertIsNotNone(result)
7+
self.assertIsInstance(result, str)
8+
self.assertEqual(result, 'argument')
9+
10+
def test_names_for_function_parameter_and_argument(self):
11+
f = open('main.py')
12+
lines = str(f.readlines())
13+
f.close()
14+
# The following tests only ensure that the named strings exist somewhere in the file, not that they are where they should be or have the correct values assigned.
15+
self.assertRegex(lines, 'my_function()', msg="The name of the function is incorrect.")
16+
self.assertRegex(lines, 'parameter', msg="The parameter must have the correct name.")
17+
self.assertRegex(lines, 'argument', msg="The argument must have the correct name.")
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
### Define your function with the appropriate parameter below this line: ###
2+
3+
4+
5+
### Assign the function call with the appropriate argument to the variable named result below this line: ###
6+
7+
result = "Replace this string with the correct answer"
8+
9+
print(result)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
## Default Arguments
2+
3+
When a function is defined in Python, you can specify formal parameters inside of the trailing parentheses.
4+
If any of those parameters are declared using the "argument=value" format, then you don't necessarily have to specify a value for those arguments when the function is called.
5+
If a value is not specified, then that parameter uses the default argument value when the function executes.
6+
A default value can be specified for any or all of the arguments, which creates a function that can be called with fewer arguments than it is defined to allow.
7+
- https://docs.python.org/3.6/tutorial/controlflow.html#default-argument-values
8+
```
9+
>>> def greeting(number=1, message='Hello'):
10+
... print(number, message)
11+
...
12+
>>> greeting()
13+
1 Hello
14+
>>> greeting(2, message='Ahoy There!')
15+
2 Ahoy There!
16+
>>> greeting(number='Three')
17+
Three Hello
18+
```
19+
**_Instructions:_**
20+
**In the console there is a function named favorite_python() with a single parameter named member that has a default argument of None.**
21+
**Call the function and change the default argument to a string containing the name of your favorite Monty Python member.**
22+
**Assign that function call to the variable named my_choice.**
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"lesson_title": "Default Arguments",
3+
"chapter_number": 8,
4+
"lesson_number": 5,
5+
"id": "",
6+
"repl": ""
7+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import unittest
2+
from main import *
3+
4+
class DefaultArgumentsTests(unittest.TestCase):
5+
def test_main(self):
6+
self.assertIsNotNone(my_choice)
7+
self.assertTrue(my_choice)
8+
self.assertIsInstance(my_choice, str)
9+
self.assertNotEqual(my_choice, "Replace this string with the correct function call.")
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
def favorite_python(member=None):
2+
print(member)
3+
return member
4+
5+
### Call the favorite_python() function with the default argument changed to
6+
### the name of your favorite Monty Python member, and assign that function
7+
### call to the variable named my_choice.
8+
9+
my_choice = "Replace this string with the correct function call."
10+
11+
### Call the function above this line.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## Calling Functions
2+
3+
Once a function has been defined, it must be called in order to be executed.
4+
A function is a callable object that can execute when its `__call__()` method is invoked.
5+
A function can be called by appending the arguments in parentheses to the function name.
6+
If a function has no parameters, or if the parameters have default arguments that you do not want to change, then you can invoke the call method by appending empty parentheses to the function name.
7+
- https://docs.python.org/3/reference/datamodel.html#object.\_\_call\_\_
8+
- https://docs.python.org/3.6/tutorial/controlflow.html#defining-functions
9+
- https://docs.python.org/3/library/functions.html#callable
10+
```
11+
# Define the function:
12+
>>> def call_something(something=None):
13+
... return something
14+
...
15+
# Call the function with the parameter's default argument of None:
16+
>>> call_something()
17+
# Nothing is returned.
18+
# Now call the function with an argument that changes the default:
19+
>>> call_something(something="Here's something")
20+
"Here's something"
21+
```
22+
**_Instructions:_**
23+
**In the console, there is a function named say_hello() that returns a greeting.**
24+
**Call the function and put any string you want as the greeting argument inside of the parentheses.**
25+
**Assign the function call to the variable named result in the console.**
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"lesson_title": "Calling Functions",
3+
"chapter_number": 8,
4+
"lesson_number": 6,
5+
"id": "",
6+
"repl": ""
7+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import unittest
2+
from main import *
3+
4+
class CallingFunctionsTests(unittest.TestCase):
5+
def test_output(self):
6+
self.assertIsNotNone(result)
7+
self.assertIsInstance(result, str)
8+
self.assertNotEqual(result, "Replace this string with the correct function call.")
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
def say_hello(greeting):
2+
return greeting
3+
4+
### Call the say_hello function below this line: ###
5+
6+
result = "Replace this string with the correct function call."
7+
8+
### Call the say_hello function above this line: ###
9+
print(result)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
## Keyword and Variable Keyword Arguments
2+
3+
A keyword argument can be an argument preceded by an identifier in a function call using the form `kwarg=value`.
4+
Variable keyword arguments can be passed as values in a dictionary preceded by `**`, like this:
5+
`def example(default_arguments, *args, **kwargs):`
6+
In a function call, keyword arguments must follow positional arguments, and all keyword arguments passed must match one of the arguments accepted by the function.
7+
[Here is a detailed explanation](https://docs.python.org/3/reference/expressions.html#calls) of how keyword arguments are dealt with when the function is called.
8+
- https://docs.python.org/3.6/tutorial/controlflow.html#keyword-arguments
9+
- https://docs.python.org/3.6/glossary.html#term-argument
10+
- https://docs.python.org/3/reference/expressions.html#grammar-token-keywords_arguments
11+
- https://docs.python.org/3/glossary.html#term-parameter
12+
- https://www.python.org/dev/peps/pep-0362/
13+
- https://www.python.org/dev/peps/pep-0448/
14+
- https://docs.python.org/3/reference/expressions.html#calls
15+
- https://docs.python.org/3/reference/compound_stmts.html#function-definitions
16+
```
17+
>>> # 3 and 5 are both keyword arguments in the following calls to complex()
18+
...
19+
>>> complex(real=3, imag=5)
20+
(3+5j)
21+
>>> complex(**{'real': 3, 'imag': 5})
22+
(3+5j)
23+
```
24+
```
25+
>>> # arg1 and arg2 are keyword arguments, **kwargs is for variable keyword arguments
26+
...
27+
>>> >>> def some_dr_seuss(arg1='arg1', arg2='arg2', **kwargs):
28+
... return arg1, arg2, kwargs
29+
...
30+
>>> print(some_dr_seuss(**{'arg3': 'arg_red', 'arg4': 'arg_blue'}))
31+
('arg1', 'arg2', {'arg3': 'arg_red', 'arg4': 'arg_blue'})
32+
```
33+
**_Instructions:_**
34+
**In the console there is a function named keyword_argument_example() that takes a default argument an an unspecified number of keyword arguments.**
35+
**When you call the function:**
36+
- **Enter an integer, your age, as the value for the default argument named your_age.**
37+
- **Create two keyword arguments named first and last.**
38+
- **Assign a string with your first name to first, and your last name to last.**
39+
40+
**Assign your function call to the variable named about_me.**
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"lesson_title": "Keyword Arguments",
3+
"chapter_number": 8,
4+
"lesson_number": 7,
5+
"id": "",
6+
"repl": ""
7+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import unittest
2+
from main import *
3+
4+
class KeywordArgumentsTests(unittest.TestCase):
5+
def test_main(self):
6+
self.assertIsNotNone(about_me)
7+
self.assertTrue(about_me)
8+
self.assertNotEqual(about_me, "Replace this string with the correct function call.")
9+
10+
def test_about_me_variable_has_correct_types(self):
11+
self.assertIsInstance(about_me, tuple)
12+
self.assertIsInstance(about_me[0], int)
13+
self.assertIsInstance(about_me[1], dict)
14+
15+
def test_correct_keyword_arguments(self):
16+
self.assertIn("first", about_me[1].keys())
17+
self.assertIn("last", about_me[1].keys())
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
def keyword_argument_example(your_age, **kwargs):
2+
return your_age, kwargs
3+
4+
### Write your code below this line ###
5+
6+
about_me = "Replace this string with the correct function call."
7+
8+
### Write your code above this line ###
9+
10+
print(about_me)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
## Positional and Variable Positional Arguments
2+
3+
A positional argument is, simply put, any argument that is not a keyword argument.
4+
Positional refers to the fact that the relative position, or order, of the arguments is significant when they are stored in their corresponding tuple.
5+
Positional arguments can be used to form [arbitrary argument lists](https://docs.python.org/3.6/tutorial/controlflow.html#arbitrary-argument-lists).
6+
Functions can accept a variable number of (optional) positional arguments by using the `*args` syntax in the def statement, like this:
7+
`def example(default_arguments, *args, **kwargs):`
8+
The `*` operator instructs Python to pass argument inputs to a tuple that receives any excess positional parameters, defaulting to the empty tuple.
9+
When a function is defined and the parameters are declared, variable positional arguments must follow normal/default arguments (if any) and precede any variable keyword arguments (if any).
10+
- https://docs.python.org/3.6/tutorial/controlflow.html#arbitrary-argument-lists
11+
- https://docs.python.org/3/glossary.html#term-argument
12+
- https://docs.python.org/3/reference/expressions.html#grammar-token-positional_arguments
13+
- https://www.python.org/dev/peps/pep-0362/
14+
- https://www.python.org/dev/peps/pep-0448/
15+
- https://docs.python.org/3/reference/expressions.html#calls
16+
- https://docs.python.org/3/reference/compound_stmts.html#function-definitions
17+
```
18+
>>> # 3 and 5 are both positional arguments in the following calls to complex()
19+
...
20+
>>> complex(3, 5)
21+
(3+5j)
22+
>>> complex(*(3, 5))
23+
(3+5j)
24+
```
25+
```
26+
>>> # arg1 and arg2 are positional arguments, *args is for variable positional arguments
27+
...
28+
>>> def some_dr_seuss(arg1, arg2, *args):
29+
... return arg1, arg2, args
30+
...
31+
>>> print(some_dr_seuss('arg1', 'arg2', 'arg_red', 'arg_blue'))
32+
('arg1', 'arg2', ('arg_red', 'arg_blue'))
33+
```
34+
**_Instructions:_**
35+
**In the console there is a function named positional_argument_example() that takes a default argument and an unspecified number of positional arguments.**
36+
**When you call the function:**
37+
- **Enter an integer, your age, as the value for the default argument named your_age.**
38+
- **Assign two strings, the first with your first name, the second with your last name, as the variable positional arguments**.
39+
40+
**Assign your function call to the variable named about_me.*
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"lesson_title": "Positional Arguments",
3+
"chapter_number": 8,
4+
"lesson_number": 8,
5+
"id": "",
6+
"repl": ""
7+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import unittest
2+
from main import *
3+
4+
class PositionalArgumentsTests(unittest.TestCase):
5+
def test_main(self):
6+
self.assertIsNotNone(about_me)
7+
self.assertTrue(about_me)
8+
self.assertNotEqual(about_me, "Replace this string with the correct function call.")
9+
10+
def test_correct_types(self):
11+
self.assertIsInstance(about_me, tuple)
12+
self.assertIsInstance(about_me[0], int)
13+
self.assertIsInstance(about_me[1], tuple)
14+
self.assertIsInstance(about_me[1][0], str)
15+
self.assertIsInstance(about_me[1][1], str)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
def positional_argument_example(your_age, *args):
2+
return your_age, args
3+
4+
### Write your code below this line ###
5+
6+
about_me = "Replace this string with the correct function call."
7+
8+
### Write your code above this line ###
9+
10+
print(about_me)

0 commit comments

Comments
 (0)
Please sign in to comment.