separate and equal functions
All the functions in the functions project were written in test_functions.py. I want to move them to functions.py in the src folder so that I can keep the tests and solutions separate like I did with the other projects.
preview
I have these tests by the end of the chapter
1import src.functions
2
3
4def test_making_a_function_w_pass():
5 assert src.functions.w_pass() is None
6
7
8def test_making_a_function_w_return():
9 assert src.functions.w_return() is None
10
11
12def test_making_a_function_w_return_none():
13 assert src.functions.w_return_none() is None
14
15
16def test_what_happens_after_functions_return():
17 assert (
18 src.functions
19 .return_leaves_the_function()
20 ) is None
21
22
23def test_constant_function():
24 assert src.functions.constant() == 'the same thing'
25
26
27def test_identity_function():
28 assert src.functions.identity(None) == None
29 assert src.functions.identity(object) == object
30
31
32def test_why_use_a_function():
33 def add_x(number):
34 return 3 + number
35
36 assert add_x(0) == 3
37 assert add_x(1) == 4
38 assert add_x(2) == 5
39 assert add_x(3) == 6
40 assert add_x(4) == 7
41 assert add_x(5) == 8
42 assert add_x(6) == 9
43 assert add_x(7) == 10
44 assert add_x(8) == 11
45 assert add_x(9) == 12
46
47
48def test_positional_arguments():
49 positional_arguments = (
50 src.functions.positional_arguments
51 )
52 first, last = 'first', 'last'
53
54 assert (
55 positional_arguments(first, last)
56 == (first, last)
57 )
58 assert (
59 positional_arguments(last, first)
60 == (last, first)
61 )
62 assert (
63 positional_arguments(0, 1)
64 == (0, 1)
65 )
66
67 a_tuple = (1, 2, 3, 'n')
68 a_list = [1, 2, 3, 'n']
69 assert (
70 positional_arguments(a_tuple, a_list)
71 == (a_tuple, a_list)
72 )
73
74 keyword_arguments = (
75 src.functions.keyword_arguments
76 )
77 a_set = {1, 2, 3, 'n'}
78 a_dictionary = {'key': 'value'}
79 assert (
80 keyword_arguments(
81 a_set, a_dictionary,
82 )
83 == (a_set, a_dictionary)
84 )
85
86
87def test_keyword_arguments():
88 keyword_arguments = (
89 src.functions.keyword_arguments
90 )
91 first, last = 'first', 'last'
92
93 assert (
94 keyword_arguments(
95 first_input=first, last_input=last,
96 )
97 == (first, last)
98 )
99 assert (
100 keyword_arguments(
101 last_input=last, first_input=first,
102 )
103 == (first, last)
104 )
105 assert (
106 keyword_arguments(
107 last_input=0, first_input=1,
108 )
109 == (1, 0)
110 )
111
112 a_tuple = (1, 2, 3, 'n')
113 a_list = [1, 2, 3, 'n']
114 assert (
115 keyword_arguments(
116 first_input=a_tuple,
117 last_input=a_list,
118 )
119 == (a_tuple, a_list)
120 )
121
122 positional_arguments = (
123 src.functions.positional_arguments
124 )
125 a_set = {1, 2, 3, 'n'}
126 a_dictionary = {'key': 'value'}
127 assert (
128 positional_arguments(
129 last_input=a_dictionary,
130 first_input=a_set,
131 )
132 == (a_set, a_dictionary)
133 )
134
135
136def test_args_and_kwargs():
137 first, last = 'first', 'last'
138
139 assert (
140 src.functions.args_and_kwargs(
141 first, last_input=last,
142 )
143 == (first, last)
144 )
145
146
147def test_optional_arguments():
148 optional_arguments = (
149 src.functions.optional_arguments
150 )
151
152 first_name, last_name = 'jane', 'doe'
153
154 assert (
155 optional_arguments(
156 first_name,
157 )
158 == (first_name, last_name)
159 )
160
161 first_name, blow = 'joe', 'blow'
162 assert (
163 optional_arguments(
164 first_name, blow
165 )
166 == (first_name, blow)
167 )
168
169 first_name = 'john'
170 assert (
171 optional_arguments(
172 first_input=first_name
173 )
174 == (first_name, last_name)
175 )
176
177 last_name = 'smith'
178 assert (
179 optional_arguments(
180 last_input=last_name,
181 first_input=first_name,
182 )
183 == (first_name, last_name)
184 )
185
186
187def test_unknown_number_of_arguments():
188 unknown_number_of_arguments = (
189 src.functions.unknown_number_of_arguments
190 )
191
192 a_tuple = (0, 1)
193 a_dictionary = {'a': 2, 'b': 3}
194 assert (
195 unknown_number_of_arguments(
196 *a_tuple, **a_dictionary
197 )
198 == (a_tuple, a_dictionary)
199 )
200
201 a_tuple = (0, 1)
202 a_dictionary = {'a': 2, 'b': 3, 'c': 4}
203 assert (
204 unknown_number_of_arguments(
205 *a_tuple, **a_dictionary
206 )
207 == (a_tuple, a_dictionary)
208 )
209
210 a_tuple = (0, 1, 2)
211 a_dictionary = {'a': 3, 'b': 4, 'c': 5}
212 assert (
213 unknown_number_of_arguments(
214 *a_tuple, **a_dictionary
215 )
216 == (a_tuple, a_dictionary)
217 )
218
219 a_tuple = (1, 2, 3, 'n')
220 assert (
221 unknown_number_of_arguments(*a_tuple)
222 == (a_tuple, {})
223 )
224
225 a_dictionary = {'a': 1, 'b': 2, 'c': 3, 'd': 'n'}
226 assert (
227 unknown_number_of_arguments(**a_dictionary)
228 == ((), a_dictionary)
229 )
230
231 assert (
232 unknown_number_of_arguments()
233 == ((), {})
234 )
235
236
237# Exceptions seen
238# AssertionError
239# NameError
240# TypeError
241# SyntaxError
242# ModuleNotFoundError
243# AttributeError
open the project
I open a terminal
I change directory to the project
cd functionsthe terminal shows I am in the
functionsfolder.../pumping_python/functionsI open
test_functions.pyI use pytest-watcher to run the tests automatically
uv run pytest-watcher . --nowthe terminal shows
test_functions.py ............ [100%] =================== 12 passed in X.YZs ===================
move w_pass
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 test_functions.py
1def test_making_a_function_w_pass():
2 def w_pass():
3 pass
4
5 # assert w_pass() is None
6 assert src.functions.w_pass() is None
7
8
9def 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 test_functions.py.
GREEN: make it pass
I add an import statement at the top of
test_functions.py1import src.functions 2 3 4def test_making_a_function_w_pass():the terminal is my friend, and shows ModuleNotFoundError
ModuleNotFoundError: No module named 'src'because there is nothing named
srcin this project.I add ModuleNotFoundError to the list of Exceptions seen
230# Exceptions seen 231# AssertionError 232# NameError 233# TypeError 234# SyntaxError 235# ModuleNotFoundErrorI open another terminal then make sure I am in the
functionsfolderI use mkdir to make a folder named
srcmkdir srcI go back to the terminal where the tests are running.
I use ctrl/command+s (Windows & Linux/MacOS) on the keyboard in
test_functions.pyto run the test again and it shows ModuleNotFoundErrorModuleNotFoundError: No module named 'src.functions'because there is nothing in the
srcfolder namedfunctions.I go to the second terminal I opened, then use touch to make
functions.pyin thesrcfoldertouch src/functions.pyI go back to the terminal where the tests are running and it shows AttributeError
AttributeError: module 'src.functions' has no attribute 'w_pass'because there is nothing in
functions.pyin thesrcfolder with the namew_pass.I add AttributeError to the list of Exceptions seen, in
test_functions.py230# Exceptions seen 231# AssertionError 232# NameError 233# TypeError 234# SyntaxError 235# ModuleNotFoundError 236# AttributeErrorI open
functions.pyfrom thesrcfolder.I add a copy of the w_pass function to
functions.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
test_functions.py1import src.functions 2 3 4def test_making_a_function_w_pass(): 5 assert src.functions.w_pass() is None 6 7 8def test_making_a_function_w_return():the test is still green because the call that was made to the w_pass function that was in
test_functions.pyis now to the w_pass function infunctions.pyin thesrcfolder. Whensrc.functions.w_passis called, Python follows this pathsrc └── functions.py └── def w_pass(): passI add a git commit message in the other terminal
git commit -am \ 'move w_pass to functions.py'
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 intest_functions.py8def test_making_a_function_w_return(): 9 def w_return(): 10 return 11 12 # assert w_return() is None 13 assert src.functions.w_return() is None 14 15 16def test_making_a_function_w_return_none():the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'w_return'because
functions.pyin thesrcfolder does not have anything namedw_returnin it.
GREEN: make it pass
I add a copy of the w_return function to functions.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
test_functions.py8def test_making_a_function_w_return(): 9 assert src.functions.w_return() is None 10 11 12def test_making_a_function_w_return_none():the test is still green because the call that was made to the w_return function that was in
test_functions.pyis now to the w_return function infunctions.pyin thesrcfolder. Whensrc.functions.w_returnis called, Python follows this pathsrc └── functions.py └── def w_return(): returnI add a git commit message in the other terminal
git commit -am \ 'move w_return to functions.py'
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 intest_functions.py12def test_making_a_function_w_return_none(): 13 def w_return_none(): 14 return None 15 16 # assert w_return_none() is None 17 assert src.functions.w_return_none() is None 18 19 20def test_what_happens_after_functions_return():the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'w_return_none'because
functions.pyin thesrcfolder does not have anything namedw_return_nonein it.
GREEN: make it pass
I add a copy of the w_return_none function to functions.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
test_functions.py12def test_making_a_function_w_return_none(): 13 assert src.functions.w_return_none() is None 14 15 16def test_what_happens_after_functions_return():the test is still green because the call that was made to the w_return_none function that was in
test_functions.pyis now to the w_return_none function infunctions.pyin thesrcfolder. Whensrc.functions.w_return_noneis called, Python follows this pathsrc └── functions.py └── def w_return_none(): return NoneI add a git commit message in the other terminal
git commit -am \ 'move w_return_none to functions.py'
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 intest_functions.py16def test_what_happens_after_functions_return(): 17 def return_leaves_the_function(): 18 return None 19 return 'only one way for this line to run' 20 21 # assert return_leaves_the_function() is None 22 assert ( 23 src.functions 24 .return_leaves_the_function() 25 ) is None 26 27 28def test_constant_function():the 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_functiontofunctions.pyin thesrcfolder.
GREEN: make it pass
I add a copy of return_leaves_the_function to functions.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
test_functions.py16def test_what_happens_after_functions_return(): 17 assert ( 18 src.functions 19 .return_leaves_the_function() 20 ) is None 21 22 23def test_constant_function():the test is still green because the call that was made to return_leaves_the_function that was in
test_functions.pyis now to return_leaves_the_function infunctions.pyin thesrcfolder. Whensrc.functions.return_leaves_the_functionis called, Python follows this pathsrc └── functions.py └── def return_leaves_the_function(): return NoneI add a git commit message in the other terminal
git commit -am \ 'move return_leaves_the_function to functions.py'
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 intest_functions.py23def test_constant_function(): 24 def constant(): 25 return 'the same thing' 26 27 # assert constant() == 'the same thing' 28 assert src.functions.constant() == 'the same thing' 29 30 31def test_identity_function():the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'constant'because there is nothing named
constantinfunctions.pyin thesrcfolder.
GREEN: make it pass
I add a copy of the constant function to functions.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
test_functions.py23def test_constant_function(): 24 assert src.functions.constant() == 'the same thing' 25 26 27def test_identity_function():the test is still green because the call that was made to the constant function that was in
test_functions.pyis now to the constant function infunctions.pyin thesrcfolder. Whensrc.functions.constantis called, Python follows this pathsrc └── functions.py └── def constant(): return 'the same thing'I add a git commit message in the other terminal
git commit -am \ 'move constant function to functions.py'
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 intest_functions.py27def test_identity_function(): 28 def identity(the_input): 29 return the_input 30 31 # assert identity(None) == None 32 # assert identity(object) == object 33 assert src.functions.identity(None) == None 34 assert src.functions.identity(object) == object 35 36 37def test_why_use_a_function():the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'identity'because
identityis not a name infunctions.pyin thesrcfolder.
GREEN: make it pass
I add a copy of the identity function to functions.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
test_functions.py23def test_identity_function(): 24 assert src.functions.identity(None) == None 25 assert src.functions.identity(object) == object 26 27 28def test_why_use_a_function():the test is still green because the call that was made to the identity function that was in
test_functions.pyis now to the identity function infunctions.pyin thesrcfolder. Whensrc.functions.identityis called, Python follows this pathsrc └── functions.py └── def identity(the_input): return the_inputI add a git commit message in the other terminal
git commit -am \ 'move identity function to functions.py'
move positional_arguments function
RED: make it fail
I go back to the terminal where the tests are running.
I comment out the positional_arguments function in
test_functions.py32def test_why_use_a_function(): 33 def add_x(number): 34 return 3 + number 35 36 assert add_x(0) == 3 37 assert add_x(1) == 4 38 assert add_x(2) == 5 39 assert add_x(3) == 6 40 assert add_x(4) == 7 41 assert add_x(5) == 8 42 assert add_x(6) == 9 43 assert add_x(7) == 10 44 assert add_x(8) == 11 45 assert add_x(9) == 12 46 47 48# def positional_arguments(first_input, last_input): 49# return first_input, last_input 50 51 52def test_positional_arguments():the 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 thesrcfolder52def test_positional_arguments(): 53 positional_arguments = ( 54 src.functions.positional_arguments 55 ) 56 first, last = 'first', 'last'the terminal is my friend, and shows NameError
NameError: name 'positional_arguments' is not definedbecause test_keyword_arguments also calls the positional_arguments function of
test_functions.py. This is a risky change.I use a variable to reroute the call to the positional_arguments function from test_keyword_arguments to the positional_arguments function of the
functionsmodule in thesrcfolder114 a_tuple = (1, 2, 3, 'n') 115 a_list = [1, 2, 3, 'n'] 116 assert ( 117 keyword_arguments( 118 first_input=a_tuple, 119 last_input=a_list, 120 ) 121 == (a_tuple, a_list) 122 ) 123 124 positional_arguments = ( 125 src.functions.positional_arguments 126 ) 127 a_set = {1, 2, 3, 'n'} 128 a_dictionary = {'key': 'value'} 129 assert ( 130 positional_arguments( 131 last_input=a_dictionary, 132 first_input=a_set, 133 ) 134 == (a_set, a_dictionary) 135 ) 136 137 138def test_args_and_kwargs():the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'positional_arguments'because
positional_argumentsdoes not exist infunctions.py.I add a copy of the positional_arguments function to
functions.py22def identity(the_input): 23 return the_input 24 25 26def positional_arguments(first_input, last_input): 27 return first_input, last_inputthe test passes because the calls that were made to the positional_arguments function that was in
test_functions.pyare now to the positional_arguments function infunctions.pyin thesrcfolder.When
positional_argumentsis called in test_positional_arguments and test_keyword_arguments, Python follows this pathpositional_arguments = src.functions.positional_arguments src └── functions.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
test_functions.py32def test_why_use_a_function(): 33 def add_x(number): 34 return 3 + number 35 36 assert add_x(0) == 3 37 assert add_x(1) == 4 38 assert add_x(2) == 5 39 assert add_x(3) == 6 40 assert add_x(4) == 7 41 assert add_x(5) == 8 42 assert add_x(6) == 9 43 assert add_x(7) == 10 44 assert add_x(8) == 11 45 assert add_x(9) == 12 46 47 48def test_positional_arguments():I add a git commit message in the other terminal
git commit -am \ 'move positional_arguments to functions.py'
move keyword_arguments function
RED: make it fail
I go back to the terminal where the tests are running.
I comment out the keyword_arguments function in
test_functions.py74 a_set = {1, 2, 3, 'n'} 75 a_dictionary = {'key': 'value'} 76 assert ( 77 keyword_arguments( 78 a_set, a_dictionary, 79 ) 80 == (a_set, a_dictionary) 81 ) 82 83 84# def keyword_arguments(first_input, last_input): 85# return first_input, last_input 86 87 88def test_keyword_arguments():the 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 thesrcfolder88def test_keyword_arguments(): 89 keyword_arguments = ( 90 src.functions.keyword_arguments 91 ) 92 first, last = 'first', 'last' 93 94 assert ( 95 keyword_arguments( 96 first_input=first, last_input=last, 97 ) 98 == (first, last) 99 ) 100 assert ( 101 keyword_arguments( 102 last_input=last, first_input=first, 103 ) 104 == (first, last) 105 ) 106 assert ( 107 keyword_arguments( 108 last_input=0, first_input=1, 109 ) 110 == (1, 0) 111 ) 112 113 a_tuple = (1, 2, 3, 'n') 114 a_list = [1, 2, 3, 'n'] 115 assert ( 116 keyword_arguments( 117 first_input=a_tuple, 118 last_input=a_list, 119 ) 120 == (a_tuple, a_list) 121 ) 122 123 positional_arguments = ( 124 src.functions.positional_arguments 125 ) 126 a_set = {1, 2, 3, 'n'} 127 a_dictionary = {'key': 'value'} 128 assert ( 129 positional_arguments( 130 last_input=a_dictionary, 131 first_input=a_set, 132 ) 133 == (a_set, a_dictionary) 134 ) 135 136 137def test_args_and_kwargs():the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'keyword_arguments'because I have not added
keyword_argumentstofunctions.py, yet.I add a copy of the keyword_arguments function to
functions.py26def positional_arguments(first_input, last_input): 27 return first_input, last_input 28 29 30def keyword_arguments(first_input, last_input): 31 return first_input, last_inputthe terminal is my friend, and shows NameError
NameError: name 'keyword_arguments' is not definedbecause test_positional_arguments also calls the keyword_arguments function of
test_functions.py. Risky business.I use a variable to reroute the calls to the keyword_arguments function from test_positional_arguments to the keyword_arguments function of the
functionsmodule in thesrcfolder67 a_tuple = (1, 2, 3, 'n') 68 a_list = [1, 2, 3, 'n'] 69 assert ( 70 positional_arguments(a_tuple, a_list) 71 == (a_tuple, a_list) 72 ) 73 74 keyword_arguments = ( 75 src.functions.keyword_arguments 76 ) 77 a_set = {1, 2, 3, 'n'} 78 a_dictionary = {'key': 'value'} 79 assert ( 80 keyword_arguments( 81 a_set, a_dictionary, 82 ) 83 == (a_set, a_dictionary) 84 ) 85 86 87# def keyword_arguments(first_input, last_input): 88# return first_input, last_input 89 90 91def test_keyword_arguments():the test passes because the calls that were made to the keyword_arguments function that was in
test_functions.pyare now to the keyword_arguments function infunctions.pyin thesrcfolder.When
keyword_argumentsis called in test_keyword_arguments and test_positional_arguments, Python follows this pathkeyword_arguments = src.functions.keyword_arguments src └── functions.py └── def keyword_arguments(first_input, last_input): return first_input, last_input
REFACTOR: make it better
I remove the commented keyword_arguments function from
test_functions.py48def test_positional_arguments(): 49 positional_arguments = ( 50 src.functions.positional_arguments 51 ) 52 first, last = 'first', 'last' 53 54 assert ( 55 positional_arguments(first, last) 56 == (first, last) 57 ) 58 assert ( 59 positional_arguments(last, first) 60 == (last, first) 61 ) 62 assert ( 63 positional_arguments(0, 1) 64 == (0, 1) 65 ) 66 67 a_tuple = (1, 2, 3, 'n') 68 a_list = [1, 2, 3, 'n'] 69 assert ( 70 positional_arguments(a_tuple, a_list) 71 == (a_tuple, a_list) 72 ) 73 74 keyword_arguments = ( 75 src.functions.keyword_arguments 76 ) 77 a_set = {1, 2, 3, 'n'} 78 a_dictionary = {'key': 'value'} 79 assert ( 80 keyword_arguments( 81 a_set, a_dictionary, 82 ) 83 == (a_set, a_dictionary) 84 ) 85 86 87def test_keyword_arguments():I add a git commit message in the other terminal
git commit -am \ 'move keyword_arguments to functions.py'
move args_and_kwargs 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_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 intest_functions.py136def test_args_and_kwargs(): 137 def args_and_kwargs(first_input, last_input): 138 return first_input, last_input 139 140 first, last = 'first', 'last' 141 142 assert ( 143 # args_and_kwargs( 144 src.functions.args_and_kwargs( 145 first, last_input=last, 146 ) 147 == (first, last) 148 ) 149 150 151def test_optional_arguments():the terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'args_and_kwargs'because
args_and_kwargsis not a name infunctions.pyin thesrcfolder.
GREEN: make it pass
I add a copy of the args_and_kwargs function to functions.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
test_functions.py136def test_args_and_kwargs(): 137 first, last = 'first', 'last' 138 139 assert ( 140 src.functions.args_and_kwargs( 141 first, last_input=last, 142 ) 143 == (first, last) 144 ) 145 146 147def test_optional_arguments():the test is still green because the call that was made to the args_and_kwargs function that was in
test_functions.pyis now to the args_and_kwargs function infunctions.pyin thesrcfolder. Whensrc.functions.args_and_kwargsis called, Python follows this pathsrc └── functions.py └── def args_and_kwargs(first_input, last_input): return first_input, last_inputI add a git commit message in the other terminal
git commit -am \ 'move args_and_kwargs to functions.py'
move optional_arguments function
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
test_functions.py147def test_optional_arguments(): 148 # def optional_arguments( 149 # first_input, last_input='doe', 150 # ): 151 # return first_input, last_input 152 153 first_name, last_name = 'jane', 'doe'the 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 thesrcfolder147def test_optional_arguments(): 148 # def optional_arguments( 149 # first_input, last_input='doe', 150 # ): 151 # return first_input, last_input 152 optional_arguments = ( 153 src.functions.optional_arguments 154 ) 155 156 first_name, last_name = 'jane', 'doe'the 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 infunctions.py.I add a copy of the optional_arguments function to
functions.py34def args_and_kwargs(first_input, last_input): 35 return first_input, last_input 36 37 38def optional_arguments( 39 first_input, last_input='doe', 40): 41 return first_input, last_inputthe test passes because the calls that were made to the optional_arguments function that was in
test_functions.pyare now to the optional_arguments function infunctions.pyin thesrcfolder.When
optional_argumentsis called in test_optional_arguments, Python follows this pathoptional_arguments = src.functions.optional_arguments src └── functions.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
test_functions.py147def test_optional_arguments(): 148 optional_arguments = ( 149 src.functions.optional_arguments 150 ) 151 152 first_name, last_name = 'jane', 'doe' 153 154 assert ( 155 optional_arguments( 156 first_name, 157 ) 158 == (first_name, last_name) 159 ) 160 161 first_name, blow = 'joe', 'blow' 162 assert ( 163 optional_arguments( 164 first_name, blow 165 ) 166 == (first_name, blow) 167 ) 168 169 first_name = 'john' 170 assert ( 171 optional_arguments( 172 first_input=first_name 173 ) 174 == (first_name, last_name) 175 ) 176 177 last_name = 'smith' 178 assert ( 179 optional_arguments( 180 last_input=last_name, 181 first_input=first_name, 182 ) 183 == (first_name, last_name) 184 ) 185 186 187def test_unknown_number_of_arguments():I add a git commit message in the other terminal
git commit -am \ 'move optional_arguments to 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
test_functions.py187def test_unknown_number_of_arguments(): 188 # def unknown_number_of_arguments( 189 # *positional_arguments, **keyword_arguments 190 # ): 191 # return positional_arguments, keyword_arguments 192 193 a_tuple = (0, 1)the 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 thesrcfolder187def test_unknown_number_of_arguments(): 188 # def unknown_number_of_arguments( 189 # *positional_arguments, **keyword_arguments 190 # ): 191 # return positional_arguments, keyword_arguments 192 unknown_number_of_arguments = ( 193 src.functions.unknown_number_of_arguments 194 ) 195 196 a_tuple = (0, 1)the 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_argumentstofunctions.py.I add a copy of the unknown_number_of_arguments function to
functions.py38def optional_arguments( 39 first_input, last_input='doe', 40): 41 return first_input, last_input 42 43 44def unknown_number_of_arguments( 45 *positional_arguments, **keyword_arguments 46): 47 return positional_arguments, keyword_argumentsthe test passes because the calls that were made to the unknown_number_of_arguments function that was in
test_functions.pyare now to the unknown_number_of_arguments function infunctions.pyin thesrcfolder.When
unknown_number_of_argumentsis called in test_unknown_number_of_arguments, Python follows this pathunknown_number_of_arguments = ( src.functions.unknown_number_of_arguments ) src └── functions.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
test_functions.py187def test_unknown_number_of_arguments(): 188 unknown_number_of_arguments = ( 189 src.functions.unknown_number_of_arguments 190 ) 191 192 a_tuple = (0, 1) 193 a_dictionary = {'a': 2, 'b': 3} 194 assert ( 195 unknown_number_of_arguments( 196 *a_tuple, **a_dictionary 197 ) 198 == (a_tuple, a_dictionary) 199 ) 200 201 a_tuple = (0, 1) 202 a_dictionary = {'a': 2, 'b': 3, 'c': 4} 203 assert ( 204 unknown_number_of_arguments( 205 *a_tuple, **a_dictionary 206 ) 207 == (a_tuple, a_dictionary) 208 ) 209 210 a_tuple = (0, 1, 2) 211 a_dictionary = {'a': 3, 'b': 4, 'c': 5} 212 assert ( 213 unknown_number_of_arguments( 214 *a_tuple, **a_dictionary 215 ) 216 == (a_tuple, a_dictionary) 217 ) 218 219 a_tuple = (1, 2, 3, 'n') 220 assert ( 221 unknown_number_of_arguments(*a_tuple) 222 == (a_tuple, {}) 223 ) 224 225 a_dictionary = {'a': 1, 'b': 2, 'c': 3, 'd': 'n'} 226 assert ( 227 unknown_number_of_arguments(**a_dictionary) 228 == ((), a_dictionary) 229 ) 230 231 assert ( 232 unknown_number_of_arguments() 233 == ((), {}) 234 ) 235 236 237# Exceptions seen 238# AssertionError 239# NameError 240# TypeError 241# SyntaxError 242# ModuleNotFoundError 243# AttributeErrorI add a git commit message in the other terminal
git commit -am \ 'move unknown_number_of_arguments to 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 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
test_functions.pyI delete all the text in
functions.pyand the terminal shows 11 failures. I start with the last AttributeErrorFAILED ...::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
Starting with the last Exception, I add a function definition for unknown_number_of_arguments to
functions.pyin thesrcfolder1def 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 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'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'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
14 return positional, keyword 15 16 17def optional_arguments(): 18 return Nonethe 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
17# def optional_arguments(): 18def optional_arguments(argument): 19 return Nonethe 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
17# def optional_arguments(): 18def optional_arguments(argument): 19 # return None 20 return ('jane', 'doe')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
17# def optional_arguments(): 18# def optional_arguments(argument): 19def optional_arguments(argument, argument_b): 20 # return None 21 return ('jane', 'doe')TypeError: optional_arguments() missing 1 required positional argument: 'argument_b'I make the argument optional
17# def optional_arguments(): 18# def optional_arguments(argument): 19# def optional_arguments(argument, argument_b): 20def optional_arguments(argument, argument_b=None): 21 # return None 22 return ('jane', 'doe')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'17# def optional_arguments(): 18# def optional_arguments(argument): 19# def optional_arguments(argument, argument_b): 20# def optional_arguments(argument, argument_b=None): 21def optional_arguments(argument, argument_b='doe'): 22 # return None 23 # return ('jane', 'doe') 24 return argument, argument_bthe terminal is my friend, and shows TypeError
TypeError: optional_arguments() got an unexpected keyword argument 'first_input'I add the name in parentheses
17# def optional_arguments(): 18# def optional_arguments(argument): 19# def optional_arguments(argument, argument_b): 20# def optional_arguments(argument, argument_b=None): 21# def optional_arguments(argument, argument_b='doe'): 22def optional_arguments( 23 argument, argument_b='doe', first_input 24): 25 # return None 26 # return ('jane', 'doe') 27 return argument, argument_bthe 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
17# def optional_arguments(): 18# def optional_arguments(argument): 19# def optional_arguments(argument, argument_b): 20# def optional_arguments(argument, argument_b=None): 21# def optional_arguments(argument, argument_b='doe'): 22def optional_arguments( 23 # argument, argument_b='doe', first_input 24 argument, first_input, 25 argument_b='doe', 26): 27 # return None 28 # return ('jane', 'doe') 29 return argument, argument_bthe 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 in17# def optional_arguments(): 18# def optional_arguments(argument): 19# def optional_arguments(argument, argument_b): 20# def optional_arguments(argument, argument_b=None): 21# def optional_arguments(argument, argument_b='doe'): 22def optional_arguments( 23 # argument, argument_b='doe', first_input 24 # argument, first_input, 25 first_input, argument, 26 argument_b='doe', 27): 28 # return None 29 # return ('jane', 'doe') 30 return argument, argument_bthe terminal is my friend, and shows TypeError
TypeError: optional_arguments() missing 1 required positional argument: 'argument'I make
argumentoptional17# def optional_arguments(): 18# def optional_arguments(argument): 19# def optional_arguments(argument, argument_b): 20# def optional_arguments(argument, argument_b=None): 21# def optional_arguments(argument, argument_b='doe'): 22def optional_arguments( 23 # argument, argument_b='doe', first_input 24 # argument, first_input, 25 # first_input, argument, 26 first_input, argument=None, 27 argument_b='doe', 28): 29 # return None 30 # return ('jane', 'doe') 31 return argument, argument_bthe 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 statement17# def optional_arguments(): 18# def optional_arguments(argument): 19# def optional_arguments(argument, argument_b): 20# def optional_arguments(argument, argument_b=None): 21# def optional_arguments(argument, argument_b='doe'): 22def optional_arguments( 23 # argument, argument_b='doe', first_input 24 # argument, first_input, 25 # first_input, argument, 26 first_input, argument=None, 27 argument_b='doe', 28): 29 # return None 30 # return ('jane', 'doe') 31 # return argument, argument_b 32 return first_input, argument, argument_bthe 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 statement17# def optional_arguments(): 18# def optional_arguments(argument): 19# def optional_arguments(argument, argument_b): 20# def optional_arguments(argument, argument_b=None): 21# def optional_arguments(argument, argument_b='doe'): 22def optional_arguments( 23 # argument, argument_b='doe', first_input 24 # argument, first_input, 25 # first_input, argument, 26 # first_input, argument=None, 27 first_input, 28 argument_b='doe', 29): 30 # return None 31 # return ('jane', 'doe') 32 # return argument, argument_b 33 # return first_input, argument, argument_b 34 return first_input, argument_bthe terminal is my friend, and shows TypeError
TypeError: optional_arguments() got an unexpected keyword argument 'last_input'. Did you mean 'first_input'?I add the name in the parentheses
17# def optional_arguments(): 18# def optional_arguments(argument): 19# def optional_arguments(argument, argument_b): 20# def optional_arguments(argument, argument_b=None): 21# def optional_arguments(argument, argument_b='doe'): 22def optional_arguments( 23 # argument, argument_b='doe', first_input 24 # argument, first_input, 25 # first_input, argument, 26 # first_input, argument=None, 27 first_input, 28 # argument_b='doe', 29 argument_b='doe', last_input, 30): 31 # return None 32 # return ('jane', 'doe') 33 # return argument, argument_b 34 # return first_input, argument, argument_b 35 return first_input, argument_bthe 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
17# def optional_arguments(): 18# def optional_arguments(argument): 19# def optional_arguments(argument, argument_b): 20# def optional_arguments(argument, argument_b=None): 21# def optional_arguments(argument, argument_b='doe'): 22def optional_arguments( 23 # argument, argument_b='doe', first_input 24 # argument, first_input, 25 # first_input, argument, 26 # first_input, argument=None, 27 first_input, 28 # argument_b='doe', 29 # argument_b='doe', last_input, 30 argument_b='doe', last_input=None, 31): 32 # return None 33 # return ('jane', 'doe') 34 # return argument, argument_b 35 # return first_input, argument, argument_b 36 return first_input, argument_bthe terminal is my friend, and shows AssertionError
AssertionError: assert ('john', 'doe') == ('john', 'smith')the last names are different.
I add
last_inputto the return statement17# def optional_arguments(): 18# def optional_arguments(argument): 19# def optional_arguments(argument, argument_b): 20# def optional_arguments(argument, argument_b=None): 21# def optional_arguments(argument, argument_b='doe'): 22def optional_arguments( 23 # argument, argument_b='doe', first_input 24 # argument, first_input, 25 # first_input, argument, 26 # first_input, argument=None, 27 first_input, 28 # argument_b='doe', 29 # argument_b='doe', last_input, 30 argument_b='doe', last_input=None, 31): 32 # return None 33 # return ('jane', 'doe') 34 # return argument, argument_b 35 # return first_input, argument, argument_b 36 # return first_input, argument_b 37 return first_input, argument_b, last_inputthe 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'17# def optional_arguments(): 18# def optional_arguments(argument): 19# def optional_arguments(argument, argument_b): 20# def optional_arguments(argument, argument_b=None): 21# def optional_arguments(argument, argument_b='doe'): 22def optional_arguments( 23 # argument, argument_b='doe', first_input 24 # argument, first_input, 25 # first_input, argument, 26 # first_input, argument=None, 27 first_input, 28 # argument_b='doe', 29 # argument_b='doe', last_input, 30 # argument_b='doe', last_input=None, 31 last_input='doe', 32): 33 # return None 34 # return ('jane', 'doe') 35 # return argument, argument_b 36 # return first_input, argument, argument_b 37 # return first_input, argument_b 38 # return first_input, argument_b, last_input 39 return first_input, last_inputthe 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
39 return first_input, last_input 40 41 42def args_and_kwargs(): 43 return Nonethe terminal is my friend, and shows TypeError
TypeError: args_and_kwargs() got an unexpected keyword argument 'last_input'I add
last_inputin parentheses42# def args_and_kwargs(): 43def args_and_kwargs(last_input): 44 return Nonethe 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_input42# def args_and_kwargs(): 43# def args_and_kwargs(last_input): 44def args_and_kwargs(argument, last_input): 45 return Nonethe terminal is my friend, and shows AssertionError
AssertionError: assert None == ('first', 'last')I return the inputs
42# def args_and_kwargs(): 43# def args_and_kwargs(last_input): 44def args_and_kwargs(argument, last_input): 45 # return None 46 return argument, last_inputthe terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'keyword_arguments'I add a function definition for keyword_arguments
46 return argument, last_input 47 48 49def keyword_arguments(): 50 return Nonethe terminal is my friend, and shows TypeError
TypeError: keyword_arguments() got an unexpected keyword argument 'first_input'I add
first_inputto the parentheses49# def keyword_arguments(): 50def keyword_arguments(first_input): 51 return Nonethe 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 parentheses49# def keyword_arguments(): 50# def keyword_arguments(first_input): 51def keyword_arguments(first_input, last_input): 52 return Nonethe terminal is my friend, and shows AssertionError
AssertionError: assert None == ('first', 'last')0I copy and paste the tuple from the terminal as the return statement
49# def keyword_arguments(): 50# def keyword_arguments(first_input): 51def keyword_arguments(first_input, last_input): 52 # return None 53 return ('first', 'last')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
49# def keyword_arguments(): 50# def keyword_arguments(first_input): 51def keyword_arguments(first_input, last_input): 52 # return None 53 # return ('first', 'last') 54 return first_input, last_inputthe 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
54 return first_input, last_input 55 56 57def positional_arguments(): 58 return Nonethe 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
57# def positional_arguments(): 58def positional_arguments(last_input): 59 return Nonethe terminal is my friend, and shows TypeError
TypeError: positional_arguments() got an unexpected keyword argument 'first_input'. Did you mean 'last_input'?I add
last_inputto the parentheses57# def positional_arguments(): 58# def positional_arguments(last_input): 59def positional_arguments(last_input, first_input): 60 return Nonethe 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
57# def positional_arguments(): 58# def positional_arguments(last_input): 59def positional_arguments(last_input, first_input): 60 # return None 61 return ({3, 1, 2, 'n'}, {'key': 'value'})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 output
57# def positional_arguments(): 58# def positional_arguments(last_input): 59def positional_arguments(last_input, first_input): 60 # return None 61 # return ({3, 1, 2, 'n'}, {'key': 'value'}) 62 return last_input, first_inputthe 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 want better error messages.
I change the order of the inputs in the the return statement
57# def positional_arguments(): 58# def positional_arguments(last_input): 59def positional_arguments(last_input, first_input): 60 # return None 61 # return ({3, 1, 2, 'n'}, {'key': 'value'}) 62 # return last_input, first_input 63 return first_input, last_inputthe 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
57# def positional_arguments(): 58# def positional_arguments(last_input): 59# def positional_arguments(last_input, first_input): 60def positional_arguments(first_input, last_input): 61 # return None 62 # return ({3, 1, 2, 'n'}, {'key': 'value'}) 63 # return last_input, first_input 64 return first_input, last_inputthe terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'identity'I add a function definition for identity
64 return first_input, last_input 65 66 67def identity(): 68 return Nonethe 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
67# def identity(): 68def identity(argument): 69 return Nonethe terminal is my friend, and shows AssertionError
AssertionError: assert None == objectI change the return statement to give the test what it wants
67# def identity(): 68def identity(argument): 69 # return None 70 return objectthe terminal is my friend, and shows AssertionError
AssertionError: assert <class 'object'> == NoneI return the input
67# def identity(): 68def identity(argument): 69 # return None 70 # return object 71 return argumentthe terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'constant'I add a function definition for constant
71 return argument 72 73 74def constant(): 75 return Nonethe 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
74def constant(): 75 # return None 76 return 'the same thing'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
76 return 'the same thing' 77 78 79def return_leaves_the_function(): 80 return Nonethe 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
79def return_leaves_the_function(): 80 return None 81 82 83def w_return_none(): 84 return Nonethe terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'w_return'I add a function definition for w_return
83def w_return_none(): 84 return None 85 86 87def w_return(): 88 return Nonethe terminal is my friend, and shows AttributeError
AttributeError: module 'src.functions' has no attribute 'w_pass'I add a function definition for w_pass
87def w_return(): 88 return None 89 90 91def w_pass(): 92 return Noneall tests are passing!
REFACTOR: make it better
close the project
I close
functions.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
functionscd ..the terminal shows
.../pumping_pythonI am back in the
pumping_pythondirectory.
review
code from the chapter
what is next?
So far, you know
Would you like to test using a class to remove repetition of inputs from functions?
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.