separate and equal functions
All the functions in the functions project were written in tests/test_functions.py. I want to move them to the functions module in the src folder so that I can keep the tests and solutions separate.
preview
I have these tests by the end of the chapter
1import src.functions
2
3
4def assert_equal(input_1, input_2):
5 assert input_1 == input_2
6
7
8def assert_is_none(something):
9 assert something is None
10
11
12def test_making_a_function_w_pass():
13 assert_is_none(src.functions.w_pass())
16def test_making_a_function_w_return():
17 assert_is_none(src.functions.w_return())
18
19
20def test_making_a_function_w_return_none():
21 assert_is_none(src.functions.w_return_none())
22
23
24def test_what_happens_after_functions_return():
25 assert_is_none(
26 src.functions.return_leaves_the_function()
27 )
30def test_constant_function():
31 assert_equal(
32 src.functions.constant(), 'the same thing'
33 )
34
35
36def test_identity_function():
37 assert_is_none(src.functions.identity(None))
38 assert_equal(
39 src.functions.identity(object), object
40 )
43def test_why_use_a_function():
44 def add_x(number):
45 return 3 + number
46
47 assert_equal(add_x(0), 3)
48 assert_equal(add_x(1), 4)
49 assert_equal(add_x(2), 5)
50 assert_equal(add_x(3), 6)
51 assert_equal(add_x(4), 7)
52 assert_equal(add_x(5), 8)
53 assert_equal(add_x(6), 9)
54 assert_equal(add_x(7), 10)
55 assert_equal(add_x(8), 11)
56 assert_equal(add_x(9), 12)
59def test_positional_arguments():
60 positional_arguments = (
61 src.functions.positional_arguments
62 )
63 first, last = 'first', 'last'
64
65 assert_equal(
66 positional_arguments(first, last),
67 (first, last)
68 )
69 assert_equal(
70 positional_arguments(last, first),
71 (last, first)
72 )
73
74 assert_equal(
75 positional_arguments(0, 1), (0, 1)
76 )
77
78 a_tuple = (0, 1, 2, 'n')
79 a_list = [0, 1, 2, 'n']
80 assert_equal(
81 positional_arguments(a_tuple, a_list),
82 (a_tuple, a_list)
83 )
84
85 a_set = {0, 1, 2, 'n'}
86 a_dictionary = {'key': 'value'}
87 assert_equal(
88 src.functions.keyword_arguments(
89 a_set, a_dictionary,
90 ),
91 (a_set, a_dictionary)
92 )
95def test_keyword_arguments():
96 keyword_arguments = (
97 src.functions.keyword_arguments
98 )
99 first, last = 'first', 'last'
100
101 assert_equal(
102 keyword_arguments(
103 first_input=first, last_input=last,
104 ),
105 (first, last)
106 )
107 assert_equal(
108 keyword_arguments(
109 last_input=last, first_input=first,
110 ),
111 (first, last)
112 )
113
114 assert_equal(
115 keyword_arguments(
116 last_input=0, first_input=1,
117 ),
118 (1, 0)
119 )
120
121 a_tuple = (0, 1, 2, 'n')
122 a_list = [0, 1, 2, 'n']
123 assert_equal(
124 keyword_arguments(
125 first_input=a_tuple,
126 last_input=a_list,
127 ),
128 (a_tuple, a_list)
129 )
130
131 a_set = {0, 1, 2, 'n'}
132 a_dictionary = {'key': 'value'}
133 assert_equal(
134 src.functions.positional_arguments(
135 last_input=a_dictionary,
136 first_input=a_set,
137 ),
138 (a_set, a_dictionary)
139 )
142def test_args_and_kwargs():
143 first, last = 'first', 'last'
144
145 assert_equal(
146 src.functions.args_and_kwargs(
147 first, last_input=last
148 ),
149 (first, last)
150 )
153def test_optional_arguments():
154 optional_arguments = (
155 src.functions.optional_arguments
156 )
157
158 first_name, last_name = 'jane', 'doe'
159 assert_equal(
160 optional_arguments(
161 first_name,
162 ),
163 (first_name, last_name)
164 )
165
166 first_name, blow = 'joe', 'blow'
167 assert_equal(
168 optional_arguments(
169 first_name, blow
170 ),
171 (first_name, blow)
172 )
173
174 first_name = 'john'
175 assert_equal(
176 optional_arguments(
177 first_input=first_name,
178 ),
179 (first_name, last_name)
180 )
181
182 last_name = 'smith'
183 assert_equal(
184 optional_arguments(
185 last_input=last_name,
186 first_input=first_name,
187 ),
188 (first_name, last_name)
189 )
192def test_unknown_number_of_arguments():
193 unknown_number_of_arguments = (
194 src.functions.unknown_number_of_arguments
195 )
196
197 a_tuple = (0, 1)
198 a_dictionary = {'a': 2, 'b': 3}
199 assert_equal(
200 unknown_number_of_arguments(
201 *a_tuple, **a_dictionary
202 ),
203 (a_tuple, a_dictionary)
204 )
205
206 a_dictionary = {'a': 2, 'b': 3, 'c': 4}
207 assert_equal(
208 unknown_number_of_arguments(
209 *a_tuple, **a_dictionary,
210 ),
211 (a_tuple, a_dictionary)
212 )
213
214 a_tuple = (0, 1, 2)
215 a_dictionary = {'a': 3, 'b': 4, 'c': 5}
216 assert_equal(
217 unknown_number_of_arguments(
218 *a_tuple, **a_dictionary
219 ),
220 (a_tuple, a_dictionary)
221 )
222
223 a_tuple = (0, 1, 2, 'n')
224 assert_equal(
225 unknown_number_of_arguments(*a_tuple),
226 (a_tuple, {})
227 )
228
229 a_dictionary = {'a': 1, 'b': 2, 'c': 3, 'd': 'n'}
230 assert_equal(
231 unknown_number_of_arguments(**a_dictionary),
232 ((), a_dictionary)
233 )
234
235 assert_equal(
236 unknown_number_of_arguments(), ((), {})
237 )
238
239
240# Exceptions seen
241# AssertionError
242# NameError
243# TypeError
244# SyntaxError
245# AttributeError
open the project
I open a terminal
I change directory to the project
the terminal shows I am in the
functionsfolder.../pumping_python/functionsI open
test_functions.pyfrom thetestsfolderI use pytest-watcher to run the tests automatically
the terminal shows
test_functions.py ............ [100%] =================== 12 passed in X.YZs ===================
move w_pass to src
RED: make it fail
I change the call in the assertion of test_making_a_function_w_pass to use the result of a call to the w_pass function of the functions module in the src folder instead of a call to the w_pass function in tests/test_functions.py
9def test_making_a_function_w_pass():
10 def w_pass():
11 pass
12
13 # assert_is_none(w_pass())
14 assert_is_none(src.functions.w_pass())
15
16
17def test_making_a_function_w_return():
the terminal is my friend, and shows NameError
NameError: name 'src' is not defined
because src is not defined in tests/test_functions.py.
GREEN: make it pass
I add an import statement at the top of
tests/test_functions.py1import src.functions 2 3 4def test_making_a_function_w_pass():the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'w_pass'because there is nothing in the
functionsmodule in thesrcfolder with the namew_pass.I add AttributeError to the list of Exceptions seen, in
tests/test_functions.pyI open
__init__.pyfrom thefunctionsfolder in thesrcfolder.I remove all the text then add a copy of the w_pass function to
src/functions/__init__.py1def w_pass(): 2 passthe test passes.
REFACTOR: make it better
I remove the commented line and the w_pass function from test_making_a_function_w_pass in
tests/test_functions.pythe test is still green because the call that was made to the w_pass function that was in
tests/test_functions.pyis now to the w_pass function in__init__.pyin thefunctionsfolder in thesrcfolder.Python follows this path when
src.functions.w_passis calledsrc.functions.w_pass src/ └── functions/ └── __init__.py └── def w_pass(): └── pass
move w_return
RED: make it fail
I go back to the terminal where the tests are running
I change the call in the assertion of test_making_a_function_w_return to use the result of a call to the w_return function of the
functionsmodule in thesrcfolder instead of a call to the w_return function intests/test_functions.pythe terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'w_return'because
__init__.pyin thefunctionsfolder in thesrcfolder does not have anything namedw_returnin it.
GREEN: make it pass
I add a copy of the w_return function to src/functions/__init__.py
1def w_pass():
2 pass
3
4
5def w_return():
6 return
the test passes.
REFACTOR: make it better
I remove the commented line and the w_return function from test_making_a_function_w_return in
tests/test_functions.pythe test is still green because the call that was made to the w_return function that was in
tests/test_functions.pyis now to the w_return function in__init__.pyin thefunctionsfolder in thesrcfolder.Python follows this path when
src.functions.w_returnis calledsrc.functions.w_return src/ └── functions/ └── __init__.py └── def w_return(): └── return
move w_return_none
RED: make it fail
I go back to the terminal where the tests are running
I change the call in the assertion of test_making_a_function_w_return_none to use the result of a call to the w_return_none function of the
functionsmodule in thesrcfolder instead of a call to the w_return_none function intests/test_functions.pythe terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'w_return_none'because
__init__.pyin thefunctionsfolder in thesrcfolder does not have anything namedw_return_nonein it.
GREEN: make it pass
I add a copy of the w_return_none function to src/functions/__init__.py
5def w_return():
6 return
7
8
9def w_return_none():
10 return None
the test passes.
REFACTOR: make it better
I remove the commented line and the w_return_none function from test_making_a_function_w_return_none in
tests/test_functions.pythe test is still green because the call that was made to the w_return_none function that was in
tests/test_functions.pyis now to the w_return_none function in__init__.pyin thefunctionsfolder in thesrcfolder.Python follows this path when
src.functions.w_return_noneis calledsrc.functions.w_return_none src/ └── functions/ └── __init__.py └── def w_return_none(): └── return None
move return_leaves_the_function
RED: make it fail
I go back to the terminal where the tests are running
I change the call in the assertion of test_what_happens_after_functions_return to use the result of a call to return_leaves_the_function of the
functionsmodule in thesrcfolder instead of a call to return_leaves_the_function intests/test_functions.pythe terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'return_leaves_the_function'because I have not added
return_leaves_the_functiontosrc/functions/__init__.py.
GREEN: make it pass
I add a copy of return_leaves_the_function to src/functions/__init__.py
9def w_return_none():
10 return None
11
12
13def return_leaves_the_function():
14 return None
15 return 'only one way for this line to run'
the test passes.
REFACTOR: make it better
I remove the commented line and return_leaves_the_function from test_what_happens_after_functions_return in
tests/test_functions.pythe test is still green because the call that was made to return_leaves_the_function that was in
tests/test_functions.pyis now to return_leaves_the_function in__init__.pyin thefunctionsfolder in thesrcfolder.Python follows this path when
src.functions.return_leaves_the_functionis calledsrc.functions.return_leaves_the_function src/ └── functions/ └── __init__.py └── def return_leaves_the_function(): └── return None
move constant function
RED: make it fail
I go back to the terminal where the tests are running
I change the call in the assertion of test_constant_function to use the result of a call to the constant function of the
functionsmodule in thesrcfolder instead of a call to the constant function intests/test_functions.pythe terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'constant'because there is nothing named
constantin__init__.pyin thefunctionsfolder in thesrcfolder.
GREEN: make it pass
I add a copy of the constant function to src/functions/__init__.py
13def return_leaves_the_function():
14 return None
15 return 'only one way for this line to run'
16
17
18def constant():
19 return 'the same thing'
the test passes.
REFACTOR: make it better
I remove the commented line and the constant function from test_constant_function in
tests/test_functions.pythe test is still green because the call that was made to the constant function that was in
tests/test_functions.pyis now to the constant function in__init__.pyin thefunctionsfolder in thesrcfolder.Python follows this path when
src.functions.constantis calledsrc.functions.constant src/ └── functions/ └── __init__.py └── def constant(): └── return 'the same thing'
move identity function
RED: make it fail
I go back to the terminal where the tests are running
I change the calls in the assertions of test_identity_function to use the results of calls to the identity function of the
functionsmodule in thesrcfolder instead of calls to the identity function intests/test_functions.pythe terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'identity'because
identityis not a name in__init__.pyin thefunctionsfolder in thesrcfolder.
GREEN: make it pass
I add a copy of the identity function to src/functions/__init__.py
18def constant():
19 return 'the same thing'
20
21
22def identity(the_input):
23 return the_input
the test passes.
REFACTOR: make it better
I remove the commented line and the identity function from test_identity_function in
tests/test_functions.pythe test is still green because the call that was made to the identity function that was in
tests/test_functions.pyis now to the identity function in__init__.pyin thefunctionsfolder in thesrcfolder.Python follows this path when
src.functions.identityis calledsrc.functions.identity src/ └── functions/ └── __init__.py └── def identity(the_input): └── return the_input
move positional_arguments
RED: make it fail
I go back to the terminal where the tests are running
I comment out the positional_arguments function in
tests/test_functions.pythe terminal is my friend, and shows NameError
NameError: name 'positional_arguments' is not defined
GREEN: make it pass
I use a variable to reroute the calls to the positional_arguments function from test_positional_arguments to the positional_arguments function of the
functionsmodule in thesrcfolderthe terminal is my friend, and shows NameError
NameError: name 'positional_arguments' is not definedbecause test_keyword_arguments also calls the positional_arguments function of
tests/test_functions.py. This is a risky change.I change the call to the positional_arguments function from test_keyword_arguments to the positional_arguments function of the
functionsmodule in thesrcfolderthe terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'positional_arguments'because
positional_argumentsdoes not exist insrc/functions/__init__.py.I add a copy of the positional_arguments function to
src/functions/__init__.pythe tests pass because the calls that were made to the positional_arguments function that was in
tests/test_functions.pyare now made to the positional_arguments function in__init__.pyin thefunctionsfolder in thesrcfolder.Python follows this path when
positional_argumentsis called in test_positional_arguments and test_keyword_argumentspositional_arguments = src.functions.positional_arguments src/ └── functions/ └── __init__.py └── def positional_arguments(first_input, last_input): └── return first_input, last_input
REFACTOR: make it better
I remove the commented positional_arguments function from
tests/test_functions.py
move keyword_arguments
RED: make it fail
I go back to the terminal where the tests are running
I comment out the keyword_arguments function in
tests/test_functions.pythe terminal is my friend, and shows NameError
NameError: name 'keyword_arguments' is not defined
GREEN: make it pass
I use a variable to reroute the calls to the keyword_arguments function from test_keyword_arguments to the keyword_arguments function of the
functionsmodule in thesrcfolderthe terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'keyword_arguments'because I have not added
keyword_argumentstosrc/functions/__init__.py, yet.I add a copy of the keyword_arguments function to
src/functions/__init__.pythe terminal is my friend, and shows NameError
NameError: name 'keyword_arguments' is not definedbecause test_positional_arguments also calls the keyword_arguments function of
tests/test_functions.py. More risky business.I change the call to the keyword_arguments function from test_positional_arguments to the keyword_arguments function of the
functionsmodule in thesrcfolderthe tests pass because the calls that were made to the keyword_arguments function that was in
tests/test_functions.pyare now made to the keyword_arguments function in__init__.pyin thefunctionsfolder in thesrcfolder.Python follows this path when
keyword_argumentsis called in test_keyword_arguments and test_positional_argumentskeyword_arguments = src.functions.keyword_arguments src/ └── functions/ └── __init__.py └── def keyword_arguments(first_input, last_input): └── return first_input, last_input
REFACTOR: make it better
I remove the commented lines from test_positional_arguments and test_keyword_arguments and the commented keyword_arguments function from
tests/test_functions.py
move args_and_kwargs
RED: make it fail
I go back to the terminal where the tests are running
I change the call in the assertion of test_args_and_kwargs to use the result of a call to the args_and_kwargs function of the
functionsmodule in thesrcfolder instead of the result of a call to the args_and_kwargs function intests/test_functions.pythe terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'args_and_kwargs'because
args_and_kwargsis not a name in__init__.pyin thefunctionsfolder in thesrcfolder.
GREEN: make it pass
I add a copy of the args_and_kwargs function to src/functions/__init__.py
30def keyword_arguments(first_input, last_input):
31 return first_input, last_input
32
33
34def args_and_kwargs(first_input, last_input):
35 return first_input, last_input
the test passes.
REFACTOR: make it better
I remove the commented line and the args_and_kwargs function from test_args_and_kwargs in
tests/test_functions.pythe test is still green because the call that was made to the args_and_kwargs function that was in
tests/test_functions.pyis now to the args_and_kwargs function in__init__.pyin thefunctionsfolder in thesrcfolder.Python follows this path when
src.functions.args_and_kwargsis calledsrc.functions.args_and_kwargs src/ └── functions/ └── __init__.py └── def args_and_kwargs(first_input, last_input): └── return first_input, last_input
move optional_arguments
RED: make it fail
I go back to the terminal where the tests are running
I comment out the optional_arguments function in test_optional_arguments in
tests/test_functions.pythe terminal is my friend, and shows NameError
NameError: name 'optional_arguments' is not defined
GREEN: make it pass
I use a variable to reroute the calls to the optional_arguments function from test_optional_arguments to the optional_arguments function of the
functionsmodule in thesrcfolderthe terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'optional_arguments'. Did you mean: 'positional_arguments'?because
optional_argumentsdoes not exist insrc/functions/__init__.py.I add a copy of the optional_arguments function to
src/functions/__init__.pythe test passes because the calls that were made to the optional_arguments function that was in
tests/test_functions.pyare now made to the optional_arguments function in__init__.pyin thefunctionsfolder in thesrcfolder.Python follows this path when
optional_argumentsis called in test_optional_argumentsoptional_arguments = src.functions.optional_arguments src/ └── functions/ └── __init__.py └── def optional_arguments( first_input, last_input='doe', ): └── return first_input, last_input
REFACTOR: make it better
I remove the commented optional_arguments function from test_optional_arguments in
tests/test_functions.py
move unknown_number_of_arguments function
RED: make it fail
I go back to the terminal where the tests are running
I comment out the unknown_number_of_arguments function in test_unknown_number_of_arguments in
tests/test_functions.pythe terminal is my friend, and shows NameError
NameError: name 'unknown_number_of_arguments' is not defined
GREEN: make it pass
I use a variable to reroute the calls to the unknown_number_of_arguments function from test_unknown_number_of_arguments to the unknown_number_of_arguments function of the
functionsmodule in thesrcfolderthe terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'unknown_number_of_arguments'because I have not yet added
unknown_number_of_argumentstosrc/functions/__init__.py.I add a copy of the unknown_number_of_arguments function to
src/functions/__init__.pythe test passes because the calls that were made to the unknown_number_of_arguments function that was in
tests/test_functions.pyare now made to the unknown_number_of_arguments function in__init__.pyin thefunctionsfolder in thesrcfolder.Python follows this path when
unknown_number_of_argumentsis called in test_unknown_number_of_argumentsunknown_number_of_arguments = ( src.functions.unknown_number_of_arguments ) src/ └── functions/ └── __init__.py └── def unknown_number_of_arguments( *positional_arguments, **keyword_arguments ): └── return positional_arguments, keyword_arguments
REFACTOR: make it better
I remove the commented unknown_number_of_arguments function from test_unknown_number_of_arguments in
tests/test_functions.py
test_functions
I can write the functions that make the tests pass (except for test_why_use_a_function which I left alone) without looking at tests/test_functions.py since the solutions are now separate from the tests.
RED: make it fail
I go back to the terminal where the tests are running
I close
tests/test_functions.pyI delete all the text in
src/functions/__init__.pyand the terminal shows 11 failures.FAILED ...::test_making_a_function_w_pass - AttributeError: module 'src.functions' has no attribute 'w_pass' FAILED ...::test_making_a_function_w_return - AttributeError: module 'src.functions' has no attribute 'w_return' FAILED ...::test_making_a_function_w_return_none - AttributeError: module 'src.functions' has no attribute 'w_return_none' FAILED ...::test_what_happens_after_functions_return - AttributeError: module 'src.functions' has no attribute 'return_lea... FAILED ...::test_constant_function - AttributeError: module 'src.functions' has no attribute 'constant' FAILED ...::test_identity_function - AttributeError: module 'src.functions' has no attribute 'identity' FAILED ...::test_positional_arguments - AttributeError: module 'src.functions' has no attribute 'positional_arguments' FAILED ...::test_keyword_arguments - AttributeError: module 'src.functions' has no attribute 'keyword_arguments' FAILED ...::test_args_and_kwargs - AttributeError: module 'src.functions' has no attribute 'args_and_kwargs' FAILED ...::test_optional_arguments - AttributeError: module 'src.functions' has no attribute 'optional_arguments' FAILED ...::test_unknown_number_of_arguments - AttributeError: module 'src.functions' has no attribute 'unknown_nu... ============= 11 failed, 1 passed in A.BCs ==============Can you make the tests pass without looking at how I solve it below? You can come back to compare solutions when you are done or if you get stuck.
GREEN: make it pass
I start with the last AttributeError and add a function definition for unknown_number_of_arguments to
src/functions/__init__.py1def unknown_number_of_arguments(): 2 return Nonethe terminal is my friend, and shows TypeError
TypeError: unknown_number_of_arguments() got an unexpected keyword argument 'a'I add
ato the parentheses1# def unknown_number_of_arguments(): 2def unknown_number_of_arguments(a): 3 return Nonethe terminal is my friend, and shows TypeError
TypeError: unknown_number_of_arguments() got multiple values for argument 'a'which means it got called with
aas a keyword argument and since I have it as the first position, Python reads it as two values for the same argument.I try another argument in the parentheses before
a1# def unknown_number_of_arguments(): 2# def unknown_number_of_arguments(a): 3def unknown_number_of_arguments(z, a): 4 return NoneI use a starred expression to make the function take any number of positional_arguments
1# def unknown_number_of_arguments(): 2# def unknown_number_of_arguments(a): 3# def unknown_number_of_arguments(z, a): 4def unknown_number_of_arguments( 5 *positional, a 6 ): 7 return Nonethe terminal is my friend, and shows TypeError
TypeError: unknown_number_of_arguments() got an unexpected keyword argument 'b'because the call uses a name (
b) that is not in the parentheses of its definition.I add
bto the parentheses1# def unknown_number_of_arguments(): 2# def unknown_number_of_arguments(a): 3# def unknown_number_of_arguments(z, a): 4def unknown_number_of_arguments( 5 # *positional, a 6 *positional, a, b 7 ): 8 return Nonethe terminal is my friend, and shows AssertionError
AssertionError: assert None == ((0, 1), {'a': 2, 'b': 3})I copy (ctrl/command+c) the tuple from the right side in the terminal then paste it (ctrl/command+v) to replace the return statement
1# def unknown_number_of_arguments(): 2# def unknown_number_of_arguments(a): 3# def unknown_number_of_arguments(z, a): 4def unknown_number_of_arguments( 5 # *positional, a 6 *positional, a, b 7 ): 8 # return None 9 return ((0, 1), {'a': 2, 'b': 3})the terminal is my friend, and shows TypeError
TypeError: unknown_number_of_arguments() got an unexpected keyword argument 'c'because the call uses a name (
c) that is not in the parentheses of its definition.I add
cto the parentheses1# def unknown_number_of_arguments(): 2# def unknown_number_of_arguments(a): 3# def unknown_number_of_arguments(z, a): 4def unknown_number_of_arguments( 5 # *positional, a 6 # *positional, a, b 7 *positional, a, b, c 8 ): 9 # return None 10 return ((0, 1), {'a': 2, 'b': 3})TypeError: unknown_number_of_arguments() missing 1 required keyword-only argument: 'c'.because something called the function without a value for
cI make
can optional argument1# def unknown_number_of_arguments(): 2# def unknown_number_of_arguments(a): 3# def unknown_number_of_arguments(z, a): 4def unknown_number_of_arguments( 5 # *positional, a 6 # *positional, a, b 7 # *positional, a, b, c 8 *positional, a, b, c=None, 9 ): 10 # return None 11 return ((0, 1), {'a': 2, 'b': 3})the terminal shows AssertionError
AssertionError: assert ((0, 1), {'a': 2, 'b': 3}) == ((0, 1), {'a'...': 3, 'c': 4})I change the return statement to see the difference between the input and the expected output
1# def unknown_number_of_arguments(): 2# def unknown_number_of_arguments(a): 3# def unknown_number_of_arguments(z, a): 4def unknown_number_of_arguments( 5 # *positional, a 6 # *positional, a, b 7 # *positional, a, b, c 8 *positional, a, b, c=None, 9 ): 10 # return None 11 # return ((0, 1), {'a': 2, 'b': 3}) 12 return positional, a, b, cthe terminal is my friend, and shows AssertionError
AssertionError: assert ((0, 1), 2, 3, None) == ((0, 1), {'a': 2, 'b': 3})I change the return statement back
1# def unknown_number_of_arguments(): 2# def unknown_number_of_arguments(a): 3# def unknown_number_of_arguments(z, a): 4def unknown_number_of_arguments( 5 # *positional, a 6 # *positional, a, b 7 # *positional, a, b, c 8 *positional, a, b, c=None, 9 ): 10 # return None 11 return ((0, 1), {'a': 2, 'b': 3}) 12 # return positional, a, b, cthe terminal is my friend, and shows AssertionError
AssertionError: assert ((0, 1), {'a': 2, 'b': 3}) == ((0, 1), {'a'...': 3, 'c': 4})the dictionaries are different.
I use a double starred expression in the parentheses to make the function take any number of keyword_arguments
1# def unknown_number_of_arguments(): 2# def unknown_number_of_arguments(a): 3# def unknown_number_of_arguments(z, a): 4def unknown_number_of_arguments( 5 # *positional, a 6 # *positional, a, b 7 # *positional, a, b, c 8 # *positional, a, b, c=None, 9 *positional, **keyword, 10 ): 11 # return None 12 return ((0, 1), {'a': 2, 'b': 3}) 13 # return positional, a, b, cthe terminal still shows AssertionError
AssertionError: assert ((0, 1), {'a': 2, 'b': 3}) == ((0, 1), {'a'...': 3, 'c': 4})I return the inputs
1# def unknown_number_of_arguments(): 2# def unknown_number_of_arguments(a): 3# def unknown_number_of_arguments(z, a): 4def unknown_number_of_arguments( 5 # *positional, a 6 # *positional, a, b 7 # *positional, a, b, c 8 # *positional, a, b, c=None, 9 *positional, **keyword, 10 ): 11 # return None 12 # return ((0, 1), {'a': 2, 'b': 3}) 13 # return positional, a, b, c 14 return positional, keywordthe terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'optional_arguments'I add a function definition for optional_arguments
the terminal is my friend, and shows TypeError
TypeError: optional_arguments() takes 0 positional arguments but 1 was givenI add a name to allow the function take input
the terminal is my friend, and shows AssertionError
AssertionError: assert None == ('jane', 'doe')I copy (ctrl/command+c) the value from the terminal and paste it (ctrl/command+v) to replace the return statement
the terminal is my friend, and shows TypeError
TypeError: optional_arguments() takes 1 positional argument but 2 were givenI add another name to the parentheses
TypeError: optional_arguments() missing 1 required positional argument: 'argument_b'I make the argument optional
the terminal is my friend, and shows AssertionError
AssertionError: assert ('jane', 'doe') == ('joe', 'blow')I change the return statement of optional_arguments to see the difference between the input and the expected output
the terminal is my friend, and shows AssertionError
AssertionError: assert ('jane', None) == ('jane', 'doe')the function returned a tuple with the first argument and the default value of
argument_b.I change the default value to
'doe'the terminal is my friend, and shows TypeError
TypeError: optional_arguments() got an unexpected keyword argument 'first_input'because the call uses a name (
first_input) that is not in the parentheses of its definition.I add the name in parentheses
the terminal is my friend, and shows SyntaxError
SyntaxError: parameter without a default follows parameter with a defaultbecause parameters without default values must come before parameters with default values.
I change the order of the arguments
the terminal is my friend, and shows TypeError
TypeError: optional_arguments() missing 1 required positional argument: 'first_input'I make
first_inputthe first argument to see if the problem is the position it is inthe terminal is my friend, and shows TypeError
TypeError: optional_arguments() missing 1 required positional argument: 'argument'I make
argumentoptionalthe terminal is my friend, and shows AssertionError
AssertionError: assert (None, 'doe') == ('jane', 'doe')the function returned a tuple with the default value of
argumentI add
first_inputto the return statementthe terminal is my friend, and shows AssertionError
AssertionError: assert ('jane', None, 'doe') == ('jane', 'doe')it looks like I do not need the
argumentparameter.I remove
argumentfrom the parentheses and return statementthe terminal is my friend, and shows TypeError
TypeError: optional_arguments() got an unexpected keyword argument 'last_input'. Did you mean 'first_input'?because the call uses a name (
last_input) that is not in the parentheses of its definition.I add the name in the parentheses
the terminal is my friend, and shows SyntaxError
SyntaxError: parameter without a default follows parameter with a defaultbecause parameters without default values must come before parameters with default values.
I give the argument a default value
the terminal is my friend, and shows AssertionError
AssertionError: assert ('john', 'doe') == ('john', 'smith')the last names are different.
I add
last_inputto the return statementthe terminal is my friend, and shows AssertionError
AssertionError: assert ('jane', 'doe', None) == ('jane', 'doe')I only need two inputs.
I remove
argument_bfrom the parentheses and return statement, then change the default value oflast_inputto'doe'the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'args_and_kwargs'I add a function definition for args_and_kwargs
the terminal is my friend, and shows TypeError
TypeError: args_and_kwargs() got an unexpected keyword argument 'last_input'I add
last_inputin parenthesesthe terminal is my friend, and shows TypeError
TypeError: args_and_kwargs() got multiple values for argument 'last_input'which means it got called with
last_inputas a positional and keyword argument. Since I have it as the first position, Python reads it as two values for the same argument.I add another name before
last_inputthe terminal is my friend, and shows AssertionError
AssertionError: assert None == ('first', 'last')I return the inputs
the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'keyword_arguments'I add a function definition for keyword_arguments
the terminal is my friend, and shows TypeError
TypeError: keyword_arguments() got an unexpected keyword argument 'first_input'because the call uses a name (
first_input) that is not in the parentheses of its definition.I add
first_inputto the parenthesesthe terminal is my friend, and shows TypeError
TypeError: keyword_arguments() got an unexpected keyword argument 'last_input'. Did you mean 'first_input'?I add
last_inputto the parenthesesthe terminal is my friend, and shows AssertionError
AssertionError: assert None == ('first', 'last')I copy and paste the tuple from the terminal as the return statement
the terminal is my friend, and shows AssertionError
AssertionError: assert ('first', 'last') == (1, 0)I change the return statement to see the difference between the inputs and the output
the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'positional_arguments'. Did you mean: 'optional_arguments'?I add a function definition for positional_arguments
the terminal is my friend, and shows TypeError
TypeError: positional_arguments() got an unexpected keyword argument 'last_input'I add the name to the parentheses in the definition
the terminal is my friend, and shows TypeError
TypeError: positional_arguments() got an unexpected keyword argument 'first_input'. Did you mean 'last_input'?because …
I add
first_inputto the parenthesesthe terminal is my friend, and shows AssertionError
AssertionError: assert None == ({3, 1, 2, 'n'}, {'key': 'value'})I copy (ctrl/command+c) and paste (ctrl/command+v) the value from the terminal to change the return statement
the terminal is my friend, and shows AssertionError
AssertionError: assert ({1, 2, 3, 'n...ey': 'value'}) == ('first', 'last')I change the return statement to see the difference between the inputs and the output
the terminal is my friend, and shows AssertionError
AssertionError: assert ({'key': 'val...3, 1, 'n', 2}) == ({3, 1, 'n', ...ey': 'value'})The order is reversed.
I change the order of the inputs in the return statement
the terminal is my friend, and shows AssertionError
AssertionError: assert ('last', 'first') == ('first', 'last')the order is reversed.
I change the order of inputs in the parentheses
the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'identity'I add a function definition for identity
the terminal is my friend, and shows TypeError
TypeError: identity() takes 0 positional arguments but 1 was givenI add a name to the function definition to make it take input
the terminal is my friend, and shows AssertionError
AssertionError: assert None == objectI change the return statement to give the test what it wants
the terminal is my friend, and shows AssertionError
AssertionError: assert <class 'object'> == NoneI return the input
the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'constant'I add a function definition for constant
the terminal is my friend, and shows AssertionError
AssertionError: assert None == 'the same thing'I copy and paste the value from the terminal as the return statement
the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'return_leaves_the_function'I add a function definition for return_leaves_the_function
the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'w_return_none'I add a function definition for w_return_none
the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'w_return'I add a function definition for w_return
the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'w_pass'I add a function definition for w_pass
all tests are passing!
REFACTOR: make it better
close the project
I close
src/functions/__init__.pyI click in the terminal where the tests are running
I use q on the keyboard to leave the tests. The terminal goes back to the command line.
I change directory to the parent of
functionsthe terminal shows
.../pumping_pythonI am back in the
pumping_pythondirectory.
review
code from the chapter
what is next?
would you like to separate the tests from the solution in the telephone project?
rate pumping python
If this has been a 7 star experience for you, please CLICK HERE to leave a 5 star review of pumping python. It helps other people get into the book too.