telephone
Part of Computer Programming is sending input data to a process and getting output data back
input_object -> process -> output_object
I send things (input data) to a program to test it, and check if what I think will happen (my expectation) is the same as the results I get (reality). This helps me answer two questions:
what is the same?
what is different?
The difference helps me know what to change to get what I want. I use assertions to test if the result of a call to a function with input is the same as my expectation.
assert reality == my_expectation
where
reality is what happens when I do something with code
my expectation is what I think will happen when I do something with code
The exercises in this chapter show how I can pass objects to a function and use it to make a string (anything in quotes).
preview
I have these tests by the end of the chapter
1def text(the_input):
2 return f'I got: {the_input}'
3
4
5def test_passing_none():
6 assert text(None) == 'I got: None'
7
8
9def test_passing_booleans():
10 assert text(False) == 'I got: False'
11 assert text(True) == 'I got: True'
12
13
14def test_passing_an_integer():
15 an_integer = 1234
16 assert text(an_integer) == f'I got: {an_integer}'
17
18
19def test_passing_a_float():
20 a_float = 5.678
21 assert text(a_float) == f'I got: {a_float}'
22
23
24def test_passing_a_string():
25 a_string = 'hello'
26 assert text(a_string) == f'I got: {a_string}'
27
28
29def test_passing_a_tuple():
30 a_tuple = (0, 1, 2, 'n')
31 assert text(a_tuple) == f'I got: {a_tuple}'
32
33
34def test_passing_a_list():
35 a_list = [0, 1, 2, 'n']
36 assert text(a_list) == f'I got: {a_list}'
37
38
39def test_passing_a_set():
40 a_set = {0, 1, 2, 'n'}
41 assert text(a_set) == f"I got: {a_set}"
42
43
44def test_passing_a_dictionary():
45 a_dictionary = {
46 'key0': 'value0',
47 'keyN': [0, 1, 2, 'n'],
48 }
49 reality = text(a_dictionary)
50 my_expectation = f'I got: {a_dictionary}'
51 assert reality == my_expectation
52
53
54def test_passing_a_class():
55 assert text(object) == "I got: <class 'object'>"
56 assert text(bool) == "I got: <class 'bool'>"
57 assert text(int) == "I got: <class 'int'>"
58 assert text(float) == "I got: <class 'float'>"
59 assert text(str) == "I got: <class 'str'>"
60 assert text(tuple) == "I got: <class 'tuple'>"
61 assert text(list) == "I got: <class 'list'>"
62 assert text(set) == "I got: <class 'set'>"
63 assert text(dict) == "I got: <class 'dict'>"
64
65
66# Exceptions seen
67# AssertionError
68# NameError
69# TypeError
start the project
I name this project
telephoneI open a terminal
I use uv to make a directory for the project and initialize it
uv init telephonethe terminal shows
Initialized project `telephone` at `.../pumping_python/telephone`then goes back to the command line.
I change directory to the project
cd telephonethe terminal shows I am in the
telephonefolder.../pumping_python/telephoneI make a directory for the tests
mkdir teststhe terminal goes back to the command line.
I make the
testsdirectory a Python packageDanger
use 2 underscores (__) before and after
initfor__init__.pynot_init_.pytouch tests/__init__.pyNew-Item tests/__init__.pythe terminal goes back to the command line.
I use the mv program to change the name of
main.pytotest_telephone.pyand move it to thetestsfoldermv main.py tests/test_telephone.pyMove-Item main.py tests/test_telephone.pythe terminal goes back to the command line.
I open
test_telephone.pyI delete all the text then add the first failing test to
test_telephone.py1def test_failure(): 2 assert False is TrueI go back to the terminal to make a requirements file for the Python packages I need
echo "pytest" > requirements.txtthe terminal goes back to the command line.
I add pytest-watcher to the requirements file
echo "pytest-watcher" >> requirements.txtthe terminal goes back to the command line.
I use uv to install pytest-watcher with the requirements file
uv add --requirement requirements.txtthe terminal shows that it installed pytest-watcher and its dependencies.
I add the new files and folders to git for tracking
git add .the terminal goes back to the command line.
I add a git commit message
git commit --all --message 'setup project'the terminal shows
[main (root-commit) a0b12c3] setup project 8 files changed, X insertions(+) create mode 100644 .gitignore create mode 100644 .python-version create mode 100644 README.md create mode 100644 pyproject.toml create mode 100644 requirements.txt create mode 100644 tests/__init__.py create mode 100644 tests/test_telephone.py create mode 100644 uv.lockthen goes back to the command line.
I use pytest-watcher to run the tests automatically
uv run pytest-watcher . --nowthe terminal is my friend, and shows AssertionError
======================== FAILURES ======================== ______________________ test_failure ______________________ def test_failure(): > assert False is True E assert False is True test_telephone.py:2: AssertionError ================ short test summary info ================= FAILED test_telephone.py::test_failure - assert False is True =================== 1 failed in X.YZs ====================if the terminal does not show the same error, then check if
your
tests/__init__.pyhas two underscores (__) before and afterinitfor__init__.pynot_init_.pyyou ran
echo "pytest-watcher" >> requirements.txt, to addpytest-watcherto the requirements file
and try
uv run pytest-watcher . --nowagainI add AssertionError to the list of Exceptions seen in
test_telephone.py1def test_failure(): 2 assert False is True 3 4 5# Exceptions seen 6# AssertionErrorI change True to False in the assertion
1def test_failure(): 2 # assert False is True 3 assert False is False 4 5 6# Exceptions seen 7# AssertionErrorthe test passes.
test_passing_none
Can I pass None (the simplest object) as input to a function?
RED: make it fail
I change
test_failureto test_passing_none with an assertion for a function call with None (the simplest Python data structure) as input, intest_telephone.py1def test_passing_none(): 2 assert text(None) == 'I got: None' 3 4 5# Exceptions seen 6# AssertionErrorthe terminal is my friend, and shows NameError
NameError: name 'text' is not definedbecause I have not defined the function yet.
I add NameError to the list of Exceptions seen
5# Exceptions seen 6# AssertionError 7# NameError
GREEN: make it pass
I add the function
1def test_passing_none(): 2 def text(): 3 return None 4 5 assert text(None) == 'I got: None' 6 7 8# Exceptions seenthe terminal is my friend, and shows TypeError
TypeError: test_passing_none.<locals>.text() takes 0 positional arguments but 1 was givenbecause the assertion called the
textfunction which belongs to test_passing_none with input (None) and the function definition does not allow any inputs, the parentheses are empty.I add TypeError to the list of Exceptions seen
8# Exceptions seen 9# AssertionError 10# NameError 11# TypeErrorI add a name to the function definition
1def test_passing_none(): 2 # def text(): 3 def text(the_input): 4 return None 5 6 assert text(None) == 'I got: None' 7 8 9# Exceptions seenthe_inputis the name I used for the input, I can use any name I want.the terminal is my friend, and shows AssertionError
E assert None == 'I got: None'
because the assertion expects
'I got: None'and thetextfunction returns None.I copy the string from the terminal and paste it in the return statement to replace None
1def test_passing_none(): 2 # def text(): 3 def text(the_input): 4 # return None 5 return 'I got: None' 6 7 assert text(None) == 'I got: None' 8 9 10# Exceptions seenthe test passes.
REFACTOR: make it better
I remove the commented lines
1def test_passing_none(): 2 def text(the_input): 3 return 'I got: None' 4 5 assert text(None) == 'I got: None' 6 7 8# Exceptions seenI open a new terminal then change directories to
telephonecd telephonethe terminal shows I am in the
telephonefolder.../pumping_python/telephoneI add a git commit message in the new terminal
git commit -am 'add test_passing_none'the terminal shows a summary of the changes then goes back to the command line.
I can pass None as input to a function.
The problem with this solution is that the text function does not care about what it gets, it always returns 'I got: None' when it is called. I want it to return the object it gets as part of the string.
test_passing_booleans
Can I pass booleans from a test to a function?
RED: make it fail
I go back to the terminal where the tests are running
I add a test for booleans (there are only two), first with an assertion for False
1def test_passing_none(): 2 def text(the_input): 3 return 'I got: None' 4 5 assert text(None) == 'I got: None' 6 7 8def test_passing_booleans(): 9 assert text(False) == 'I got: False' 10 11 12# Exceptions seenthe terminal is my friend, and shows NameError
NameError: name 'text' is not definedbecause the
textfunction belongs to the test_passing_none function and I cannot reach it from outside.
GREEN: make it pass
I move the
textfunction out of test_passing_none so that it can be called from anywhere in the file1def text(the_input): 2 return 'I got: None' 3 4 5def test_passing_none(): 6 assert text(None) == 'I got: None' 7 8 9def test_passing_booleans():the terminal is my friend, and shows AssertionError
AssertionError: assert 'I got: None' == 'I got: False'because the
textfunction always returns'I got: None'and this assertion expects'I got: False'.I change the return statement to give the test what it wants
1def text(the_input): 2 # return 'I got: None' 3 return 'I got: False' 4 5 6def test_passing_none():the terminal is my friend, and shows AssertionError
AssertionError: assert 'I got: False' == 'I got: None'because the
textfunction now always returns'I got: False'and the assertion in test_passing_none expects'I got: None'. My change broke the assertion that was passing before.The return statement has to use the input it gets as part of the output.
what is string interpolation?
String Interpolation is how to place objects in strings. It allows me to make one string that can have values that change.
I can use an f-string (short for formatted string literal) for string interpolation.
A string is anything inside quotes, for example
'single quotes''''triple single quotes'''"double quotes""""triple double quotes"""
how to write an f-string
f'characters {object} more characters'
I add
the_inputto the string in the return statement1def text(the_input): 2 # return 'I got: None' 3 # return 'I got: False' 4 return 'I got: {the_input}'the terminal is my friend, and shows AssertionError
AssertionError: assert 'I got: {the_input}' == 'I got: False'I change the return statement to an f-string
1def text(the_input): 2 # return 'I got: None' 3 # return 'I got: False' 4 # return 'I got: {the_input}' 5 return f'I got: {the_input}' 6 7 8def test_passing_none():the test passes because Python uses the string representation of the object in the curly braces
{ }text(None) text(the_input) the_input = None return f'I got: {the_input}' return 'I got: None 'text(False) text(the_input) the_input = False return f'I got: {the_input}' return 'I got: False '
REFACTOR: make it better
I remove the commented lines
1def text(the_input): 2 return f'I got: {the_input}' 3 4 5def test_passing_none():I add an assertion for True (the other boolean) to test_passing_booleans
9def test_passing_booleans(): 10 assert text(False) == 'I got: False' 11 assert text(True) == 'I got: "True"' 12 13 14# Exceptions seenthe terminal is my friend, and shows AssertionError
E assert 'I got: True' == 'I got: "True"I remove the quotes around True in my expectation
9def test_passing_booleans(): 10 assert text(False) == 'I got: False' 11 # assert text(True) == 'I got: "True"' 12 assert text(True) == 'I got: True' 13 14 15# Exceptions seenthe test passes because Python uses the string representation of the object in the curly braces
{ }text(True) text(the_input) the_input = True return f'I got: {the_input}' return 'I got: True 'I remove the commented line
9def test_passing_booleans(): 10 assert text(False) == 'I got: False' 11 assert text(True) == 'I got: True' 12 13 14# Exceptions seenI add a git commit message in the other terminal
git commit --all --message \ 'add test_passing_booleans'the terminal shows a summary of the changes then goes back to the command line.
test_passing_an_integer
Can I pass an integer (a whole number without decimals) as input to a function?
RED: make it fail
I go back to the terminal where the tests are running
I add a test for an integer
9def test_passing_booleans(): 10 assert text(False) == 'I got: False' 11 assert text(True) == 'I got: True' 12 13 14def test_passing_an_integer(): 15 assert text(1234) == 'I got: "1234"' 16 17 18# Exceptions seenthe terminal is my friend, and shows AssertionError
E assert 'I got: 1234' == 'I got: "1234"'
GREEN: make it pass
I remove the quotes around the integer in my expectation
14def test_passing_an_integer():
15 # assert text(1234) == 'I got: "1234"'
16 assert text(1234) == 'I got: 1234'
17
18
19# Exceptions seen
the test passes because Python uses the string representation of the object in the curly braces { }
text(1234)
text(the_input)
the_input = 1234
return f'I got: {the_input}'
return 'I got: 1234 '
REFACTOR: make it better
I add a variable for
123414def test_passing_an_integer(): 15 an_integer = 1234 16 # assert text(1234) == 'I got: "1234"' 17 assert text(1234) == 'I got: 1234' 18 19 20# Exceptions seenI use the variable and an f-string to remove repetition of
123414def test_passing_an_integer(): 15 an_integer = 1234 16 # assert text(1234) == 'I got: "1234"' 17 # assert text(1234) == 'I got: 1234' 18 assert text(an_integer) == f'I got: {an_integer}' 19 20 21# Exceptions seenthe test is still green.
I remove the commented lines
14def test_passing_an_integer(): 15 an_integer = 1234 16 assert text(an_integer) == f'I got: {an_integer}' 17 18 19# Exceptions seenI add a git commit message in the other terminal
git commit -am 'add test_passing_an_integer'the terminal shows a summary of the changes then goes back to the command line.
test_passing_a_float
Can I pass a float (binary floating point decimal number) as input to a function?
RED: make it fail
I go back to the terminal where the tests are running
I add a test for a float (binary floating point decimal numbers)
14def test_passing_an_integer(): 15 an_integer = 1234 16 assert text(an_integer) == f'I got: {an_integer}' 17 18 19def test_passing_a_float(): 20 assert text(5.678) == 'I got: "5.678"' 21 22 23# Exceptions seenthe terminal is my friend, and shows AssertionError
E assert 'I got: 5.678' == 'I got: "5.678"'
GREEN: make it pass
I remove the quotes around the float in my expectation
19def test_passing_a_float():
20 # assert text(5.678) == 'I got: "5.678"'
21 assert text(5.678) == 'I got: 5.678'
22
23
24# Exceptions seen
the test passes because Python uses the string representation of the object in the curly braces { }
text(5.678)
text(the_input)
the_input = 5.678
return f'I got: {the_input}'
return 'I got: 5.678 '
REFACTOR: make it better
I add a variable for
5.67819def test_passing_a_float(): 20 a_float = 5.678 21 # assert text(5.678) == 'I got: "5.678"' 22 assert text(5.678) == 'I got: 5.678' 23 24 25# Exceptions seenI use the variable and an f-string to remove repetition of
5.67819def test_passing_a_float(): 20 a_float = 5.678 21 # assert text(5.678) == 'I got: "5.678"' 22 # assert text(5.678) == 'I got: 5.678' 23 assert text(a_float) == f'I got: {a_float}' 24 25 26# Exceptions seenthe test is still green.
I remove the commented lines
19def test_passing_a_float(): 20 a_float = 5.678 21 assert text(a_float) == f'I got: {a_float}' 22 23 24# Exceptions seenI add a git commit message in the other terminal
git commit --all --message \ 'add test_passing_a_float'the terminal shows a summary of the changes then goes back to the command line.
test_passing_a_string
Can I pass a string as input to a function?
RED: make it fail
I go back to the terminal where the tests are running
I add a test for a string (anything in quotes)
19def test_passing_a_float(): 20 a_float = 5.678 21 assert text(a_float) == f'I got: {a_float}' 22 23 24def test_passing_a_string(): 25 assert text('hello') == 'I got: hi' 26 27 28# Exceptions seenthe terminal is my friend, and shows AssertionError
AssertionError: assert 'I got: hello' == 'I got: hi'
GREEN: make it pass
I change my expectation to match reality
24def test_passing_a_string():
25 # assert text('hello') == 'I got: hi'
26 assert text('hello') == 'I got: hello'
27
28
29# Exceptions seen
the test passes because Python uses the string representation of the object in the curly braces { }
text('hello')
text(the_input)
the_input = 'hello'
return f'I got: {the_input}'
return 'I got: hello '
REFACTOR: make it better
I add a variable for
'hello'24def test_passing_a_string(): 25 a_string = 'hello' 26 # assert text('hello') == 'I got: hi' 27 assert text('hello') == 'I got: hello' 28 29 30# Exceptions seenI use the variable and an f-string to remove repetition of
'hello'24def test_passing_a_string(): 25 a_string = 'hello' 26 # assert text('hello') == 'I got: hi' 27 # assert text('hello') == 'I got: hello' 28 assert text('hello') == f'I got: {a_string}' 29 30 31# Exceptions seenthe test is still green.
I remove the commented lines
24def test_passing_a_string(): 25 a_string = 'hello' 26 assert text(a_string) == f'I got: {a_string}' 27 28 29# Exceptions seenI add a git commit message in the other terminal
git commit -am 'add test_passing_a_string'the terminal shows a summary of the changes then goes back to the command line.
test_passing_a_tuple
Can I pass a tuple (anything in parentheses ( ) separated by a comma) as input to a function?
RED: make it fail
I go back to the terminal where the tests are running
I add a test for a tuple
24def test_passing_a_string(): 25 a_string = 'hello' 26 assert text('hello') == f'I got: {a_string}' 27 28 29def test_passing_a_tuple(): 30 assert text((0, 1, 2, 'n')) == 'I got: (0, 1, 2, n)' 31 32 33# Exceptions seenthe terminal is my friend, and shows AssertionError
E assert "I got: (0, 1, 2, 'n')" == 'I got: (0, 1, 2, n)'
GREEN: make it pass
I change the tuple in my expectation to match reality
29def test_passing_a_tuple():
30 # assert text((0, 1, 2, 'n')) == 'I got: (0, 1, 2, n)'
31 assert text((0, 1, 2, 'n')) == "I got: (0, 1, 2, 'n')"
32
33
34# Exceptions seen
the test passes because Python uses the string representation of the object in the curly braces { }
text((0, 1, 2, 'n'))
text(the_input)
the_input = (0, 1, 2, 'n')
return f'I got: {the_input }'
return 'I got: (0, 1, 2, 'n')'
REFACTOR: make it better
I add a variable for
(0, 1, 2, 'n')29def test_passing_a_tuple(): 30 a_tuple = (0, 1, 2, 'n') 31 # assert text((0, 1, 2, 'n')) == 'I got: (0, 1, 2, n)' 32 assert text((0, 1, 2, 'n')) == "I got: (0, 1, 2, 'n')" 33 34 35# Exceptions seenI use the variable and an f-string to remove repetition of
(0, 1, 2, 'n')29def test_passing_a_tuple(): 30 a_tuple = (0, 1, 2, 'n') 31 # assert text((0, 1, 2, 'n')) == 'I got: (0, 1, 2, n)' 32 # assert text((0, 1, 2, 'n')) == "I got: (0, 1, 2, 'n')" 33 assert text(a_tuple) == f'I got: {a_tuple}' 34 35 36# Exceptions seenthe test is still green.
I remove the commented lines
29def test_passing_a_tuple(): 30 a_tuple = (0, 1, 2, 'n') 31 assert text(a_tuple) == f'I got: {a_tuple}' 32 33 34# Exceptions seenI add a git commit message in the other terminal
git commit --all --message \ 'add test_passing_a_tuple'the terminal shows a summary of the changes then goes back to the command line.
test_passing_a_list
Can I pass a list (anything in square brackets [ ]) from a test to a function?
RED: make it fail
I go back to the terminal where the tests are running
I add a test for a list
29def test_passing_a_tuple(): 30 a_tuple = (0, 1, 2, 'n') 31 assert text(a_tuple) == f'I got: {a_tuple}' 32 33 34def test_passing_a_list(): 35 assert text([0, 1, 2, 'n']) == 'I got: [0, 1, 2, "n"]' 36 37 38# Exceptions seenthe terminal is my friend, and shows AssertionError
assert "I got: [0, 1, 2, 'n']" == 'I got: [0, 1, 2, "n"]'
GREEN: make it pass
I change the list in my expectation to match reality
34def test_passing_a_list():
35 # assert text([0, 1, 2, 'n']) == 'I got: [0, 1, 2, "n"]'
36 assert text([0, 1, 2, 'n']) == "I got: [0, 1, 2, 'n']"
37
38
39# Exceptions seen
the test passes because Python uses the string representation of the object in the curly braces { }
text([0, 1, 2, 'n'])
text(the_input)
the_input = [0, 1, 2, 'n']
return f'I got: {the_input }'
return 'I got: [0, 1, 2, 'n']'
Python changed the double quotes (") in the list to a single quote (').
REFACTOR: make it better
I add a variable for
[0, 1, 2, 'n']34def test_passing_a_list(): 35 a_list = [0, 1, 2, 'n'] 36 # assert text([0, 1, 2, 'n']) == 'I got: [0, 1, 2, "n"]' 37 assert text([0, 1, 2, 'n']) == "I got: [0, 1, 2, 'n']" 38 39 40# Exceptions seenI use the variable and an f-string to remove repetition of
[0, 1, 2, 'n']34def test_passing_a_list(): 35 a_list = [0, 1, 2, 'n'] 36 # assert text([0, 1, 2, 'n']) == 'I got: [0, 1, 2, "n"]' 37 # assert text([0, 1, 2, 'n']) == "I got: [0, 1, 2, 'n']" 38 assert text(a_list) == f'I got: {a_list}' 39 40 41# Exceptions seenthe test is still green.
I remove the commented lines
34def test_passing_a_list(): 35 a_list = [0, 1, 2, 'n'] 36 assert text(a_list) == f'I got: {a_list}' 37 38 39# Exceptions seenI add a git commit message in the other terminal
git commit -am 'add test_passing_a_list'the terminal shows a summary of the changes then goes back to the command line.
test_passing_a_set
Can I pass a set (anything in curly braces { }, not key-value pairs) from a test to a function?
RED: make it fail
I go back to the terminal where the tests are running
I add a test for a set
34def test_passing_a_list(): 35 a_list = [0, 1, 2, 'n'] 36 assert text(a_list) == f'I got: {a_list}' 37 38 39def test_passing_a_set(): 40 assert text({0, 1, 2, 'n'}) == 'I got: {0, 1, 2, "n"}' 41 42 43# Exceptions seenthe terminal is my friend, and shows AssertionError
E assert "I got: {0, 1, 2, 'n'}" == 'I got: {0, 1, 2, "n"}'
GREEN: make it pass
I change the set in my expectation to match reality
39def test_passing_a_set(): 40 # assert text({0, 1, 2, 'n'}) == 'I got: {0, 1, 2, "n"}' 41 assert text({0, 1, 2, 'n'}) == "I got: {0, 1, 2, 'n'}" 42 43 44# Exceptions seenI use ctrl/command+s (Windows & Linux/MacOS) to run the test a few times
if the result of
text({0, 1, 2, 'n'})is equal to"I got: {0, 1, 2, 'n'}"the test passes because Python uses the string representation of the object in the curly braces{ }text({0, 1, 2, 'n'}) text(the_input) the_input = {0, 1, 2, 'n'} return f'I got: {the_input }' return 'I got: {0, 1, 2, 'n'}'if the result of
text({0, 1, 2, 'n'})is NOT equal to"I got: {0, 1, 2, 'n'}", the terminal shows AssertionErrorE assert "I got: {0, 'n', 2, 1}" == "I got: {0, 1, 2, 'n'}"
Python cannot guarantee the order of the things in the set and the order matters for the assertion that is comparing the strings because
these two are the same set
{0, 'n', 2, 1} == {0, 1, 2, 'n'}these two are not the same string
"{0, 'n', 2, 1}" != "{0, 1, 2, 'n'}"
I add a variable for
{0, 1, 2, 'n'}39def test_passing_a_set(): 40 a_set = {0, 1, 2, 'n'} 41 # assert text({0, 1, 2, 'n'}) == 'I got: {0, 1, 2, "n"}' 42 assert text({0, 1, 2, 'n'}) == "I got: {0, 1, 2, 'n'}" 43 44 45# Exceptions seenI use the variable and an f-string to remove repetition of
{0, 1, 2, 'n'}39def test_passing_a_set(): 40 a_set = {0, 1, 2, 'n'} 41 # assert text({0, 1, 2, 'n'}) == 'I got: {0, 1, 2, "n"}' 42 # assert text({0, 1, 2, 'n'}) == "I got: {0, 1, 2, 'n'}" 43 assert text(a_set) == f"I got: {a_set}" 44 45 46# Exceptions seenI use ctrl/command+s (Windows & Linux/MacOS) to run the test a few times and the test stays green with no random failures because Python uses the string representation of the object in the curly braces
{ }.It can guarantee the order when I use a variable and the f-string to refer to the same exact set.
REFACTOR: make it better
I remove the commented lines
39def test_passing_a_set(): 40 a_set = {0, 1, 2, 'n'} 41 assert text(a_set) == f"I got: {a_set}" 42 43 44# Exceptions seenI add a git commit message in the other terminal
git commit --all --message \ 'add test_passing_a_set'the terminal shows a summary of the changes then goes back to the command line.
test_passing_a_dictionary
Can I pass a dictionary (any key-value pairs in curly braces ‘{ }’ separated by commas) as input to a function?
RED: make it fail
I go back to the terminal where the tests are running
I add a test for a dictionary
39def test_passing_a_set(): 40 a_set = {0, 1, 2, 'n'} 41 assert text(a_set) == f"I got: {a_set}" 42 43 44def test_passing_a_dictionary(): 45 reality = text({ 46 'key0': 'value0', 47 'keyN': [0, 1, 2, 'n'], 48 }) 49 my_expectation = ( 50 "I got: " 51 "{key0: value0, keyN: [0, 1, 2, n]}" 52 ) 53 assert reality == my_expectation 54 55 56# Exceptions seenthe terminal is my friend, and shows AssertionError
assert "I got: {'key..., 1, 2, 'n']}" == 'I got: {key0...[0, 1, 2, n]}'
GREEN: make it pass
I change my_expectation to match reality
44def test_passing_a_dictionary():
45 reality = text({
46 'key0': 'value0',
47 'keyN': [0, 1, 2, 'n'],
48 })
49 my_expectation = (
50 "I got: "
51 # "{key0: value0, keyN: [0, 1, 2, n]}"
52 "{'key0': 'value0', 'keyN': [0, 1, 2, 'n']}"
53 )
54 assert reality == my_expectation
55
56
57# Exceptions seen
the test passes because Python uses the string representation of the object in the curly braces { }
text({'key0': 'value0', 'keyN': [0, 1, 2, 'n'],})
text(the_input)
the_input = {'key0': 'value0', 'keyN': [0, 1, 2, 'n']}
return f'I got: {the_input}'
return ("I got: {'key0': 'value0',"
'keyN': [0, 1, 2, 'n']}")
REFACTOR: make it better
I add a variable for
{'key0': 'value0', 'keyN': [0, 1, 2, 'n'],}44def test_passing_a_dictionary(): 45 a_dictionary = { 46 'key0': 'value0', 47 'keyN': [0, 1, 2, 'n'], 48 } 49 reality = text({ 50 'key0': 'value0', 51 'keyN': [0, 1, 2, 'n'], 52 }) 53 my_expectation = ( 54 "I got: " 55 # "{key0: value0, keyN: [0, 1, 2, n]}" 56 "{'key0': 'value0', 'keyN': [0, 1, 2, 'n']}" 57 ) 58 assert reality == my_expectation 59 60 61# Exceptions seenI use the variable and an f-string to remove repetition of
{'key0': 'value0', 'keyN': [0, 1, 2, 'n'],}44def test_passing_a_dictionary(): 45 a_dictionary = { 46 'key0': 'value0', 47 'keyN': [0, 1, 2, 'n'], 48 } 49 # reality = text({ 50 # 'key0': 'value0', 51 # 'keyN': [0, 1, 2, 'n'], 52 # }) 53 # my_expectation = ( 54 # "I got: " 55 # # "{key0: value0, keyN: [0, 1, 2, n]}" 56 # "{'key0': 'value0', 'keyN': [0, 1, 2, 'n']}" 57 # ) 58 reality = text(a_dictionary) 59 my_expectation = f'I got: {a_dictionary}' 60 assert reality == my_expectation 61 62 63# Exceptions seenthe test is still green.
I remove the commented lines
44def test_passing_a_dictionary(): 45 a_dictionary = { 46 'key0': 'value0', 47 'keyN': [0, 1, 2, 'n'], 48 } 49 reality = text(a_dictionary) 50 my_expectation = f'I got: {a_dictionary}' 51 assert reality == my_expectation 52 53 54# Exceptions seenI add a git commit message in the other terminal
git commit -am \ 'add test_passing_a_dictionary'the terminal shows a summary of the changes then goes back to the command line.
test_passing_a_class
Can I pass any object as input to a function?
RED: make it fail
I go back to the terminal where the tests are running
I add a failing test to see what happens when I pass a class from a test to the
textfunction, intest_telephone.py44def test_passing_a_dictionary(): 45 a_dictionary = { 46 'key0': 'value0', 47 'keyN': [0, 1, 2, 'n'], 48 } 49 reality = text(a_dictionary) 50 my_expectation = f'I got: {a_dictionary}' 51 assert reality == my_expectation 52 53 54def test_passing_a_class(): 55 assert text(object) == 'I got: object' 56 57 58# Exceptions seenthe terminal is my friend, and shows AssertionError
E assert "I got: <class 'object'>" == 'I got: object'object is the mother class that all Python classes come from because everything in Python is an object.
GREEN: make it pass
I change my expectation to match reality
54def test_passing_a_class():
55 # assert text(object) == 'I got: object'
56 assert text(object) == "I got: <class 'object'>"
57
58
59# Exceptions seen
the test passes because Python uses the string representation of the object in the curly braces { }
text(object)
text(the_input)
the_input = object
return f'I got: {the_input }'
return "I got: <class 'object'> "
REFACTOR: make it better
I add an assertion for bool (the class for booleans)
54def test_passing_a_class(): 55 # assert text(object) == 'I got: object' 56 assert text(object) == "I got: <class 'object'>" 57 assert text(bool) == 'I got: bool' 58 59 60# Exceptions seenthe terminal is my friend, and shows AssertionError
E assert "I got: <class 'bool'>" == 'I got: bool'I change my expectation to match reality
54def test_passing_a_class(): 55 # assert text(object) == 'I got: object' 56 assert text(object) == "I got: <class 'object'>" 57 # assert text(bool) == 'I got: bool' 58 assert text(bool) == "I got: <class 'bool'>" 59 60 61# Exceptions seenthe test passes.
I add an assertion for int (the class for whole numbers without decimals)
54def test_passing_a_class(): 55 # assert text(object) == 'I got: object' 56 assert text(object) == "I got: <class 'object'>" 57 # assert text(bool) == 'I got: bool' 58 assert text(bool) == "I got: <class 'bool'>" 59 assert text(int) == 'I got: int' 60 61 62# Exceptions seenthe terminal is my friend, and shows AssertionError
E assert "I got: <class 'int'>" == 'I got: int'I change my expectation to match reality
54def test_passing_a_class(): 55 # assert text(object) == 'I got: object' 56 assert text(object) == "I got: <class 'object'>" 57 # assert text(bool) == 'I got: bool' 58 assert text(bool) == "I got: <class 'bool'>" 59 # assert text(int) == "I got: int" 60 assert text(int) == "I got: <class 'int'>" 61 62 63# Exceptions seenthe test passes.
I add an assertion for float (the class for binary floating point decimal numbers)
54def test_passing_a_class(): 55 # assert text(object) == 'I got: object' 56 assert text(object) == "I got: <class 'object'>" 57 # assert text(bool) == 'I got: bool' 58 assert text(bool) == "I got: <class 'bool'>" 59 # assert text(int) == "I got: int" 60 assert text(int) == "I got: <class 'int'>" 61 assert text(float) == 'I got: float' 62 63 64# Exceptions seenthe terminal is my friend, and shows AssertionError
E assert "I got: <class 'float'>" == 'I got: float'I change my expectation to match reality
54def test_passing_a_class(): 55 # assert text(object) == 'I got: object' 56 assert text(object) == "I got: <class 'object'>" 57 # assert text(bool) == 'I got: bool' 58 assert text(bool) == "I got: <class 'bool'>" 59 # assert text(int) == "I got: int" 60 assert text(int) == "I got: <class 'int'>" 61 # assert text(float) == 'I got: float' 62 assert text(float) == "I got: <class 'float'>" 63 64 65# Exceptions seenthe test passes.
I add an assertion for str (the class for anything in quotes)
54def test_passing_a_class(): 55 # assert text(object) == 'I got: object' 56 assert text(object) == "I got: <class 'object'>" 57 # assert text(bool) == 'I got: bool' 58 assert text(bool) == "I got: <class 'bool'>" 59 # assert text(int) == "I got: int" 60 assert text(int) == "I got: <class 'int'>" 61 # assert text(float) == 'I got: float' 62 assert text(float) == "I got: <class 'float'>" 63 assert text(str) == 'I got: str' 64 65 66# Exceptions seenthe terminal is my friend, and shows AssertionError
E assert "I got: <class 'str'>" == 'I got: str'I change my expectation to match reality
54def test_passing_a_class(): 55 # assert text(object) == 'I got: object' 56 assert text(object) == "I got: <class 'object'>" 57 # assert text(bool) == 'I got: bool' 58 assert text(bool) == "I got: <class 'bool'>" 59 # assert text(int) == "I got: int" 60 assert text(int) == "I got: <class 'int'>" 61 # assert text(float) == 'I got: float' 62 assert text(float) == "I got: <class 'float'>" 63 # assert text(str) == 'I got: str' 64 assert text(str) == "I got: <class 'str'>" 65 66 67# Exceptions seenthe test passes.
I add an assertion for tuple (the class for anything in parentheses
( )separated by a comma)54def test_passing_a_class(): 55 # assert text(object) == 'I got: object' 56 assert text(object) == "I got: <class 'object'>" 57 # assert text(bool) == 'I got: bool' 58 assert text(bool) == "I got: <class 'bool'>" 59 # assert text(int) == "I got: int" 60 assert text(int) == "I got: <class 'int'>" 61 # assert text(float) == 'I got: float' 62 assert text(float) == "I got: <class 'float'>" 63 # assert text(str) == 'I got: str' 64 assert text(str) == "I got: <class 'str'>" 65 assert text(tuple) == 'I got: tuple' 66 67 68# Exceptions seenthe terminal is my friend, and shows AssertionError
E assert "I got: <class 'tuple'>" == 'I got: tuple'I change my expectation to match reality
54def test_passing_a_class(): 55 # assert text(object) == 'I got: object' 56 assert text(object) == "I got: <class 'object'>" 57 # assert text(bool) == 'I got: bool' 58 assert text(bool) == "I got: <class 'bool'>" 59 # assert text(int) == "I got: int" 60 assert text(int) == "I got: <class 'int'>" 61 # assert text(float) == 'I got: float' 62 assert text(float) == "I got: <class 'float'>" 63 # assert text(str) == 'I got: str' 64 assert text(str) == "I got: <class 'str'>" 65 # assert text(tuple) == 'I got: tuple' 66 assert text(tuple) == "I got: <class 'tuple'>" 67 68 69# Exceptions seenthe test passes.
I add an assertion for list (the class for anything in square brackets ‘[ ]’)
54def test_passing_a_class(): 55 # assert text(object) == 'I got: object' 56 assert text(object) == "I got: <class 'object'>" 57 # assert text(bool) == 'I got: bool' 58 assert text(bool) == "I got: <class 'bool'>" 59 # assert text(int) == "I got: int" 60 assert text(int) == "I got: <class 'int'>" 61 # assert text(float) == 'I got: float' 62 assert text(float) == "I got: <class 'float'>" 63 # assert text(str) == 'I got: str' 64 assert text(str) == "I got: <class 'str'>" 65 # assert text(tuple) == 'I got: tuple' 66 assert text(tuple) == "I got: <class 'tuple'>" 67 assert text(list) == 'I got: list' 68 69 70# Exceptions seenthe terminal is my friend, and shows AssertionError
E assert "I got: <class 'list'>" == 'I got: list'I change my expectation to match reality
54def test_passing_a_class(): 55 # assert text(object) == 'I got: object' 56 assert text(object) == "I got: <class 'object'>" 57 # assert text(bool) == 'I got: bool' 58 assert text(bool) == "I got: <class 'bool'>" 59 # assert text(int) == "I got: int" 60 assert text(int) == "I got: <class 'int'>" 61 # assert text(float) == 'I got: float' 62 assert text(float) == "I got: <class 'float'>" 63 # assert text(str) == 'I got: str' 64 assert text(str) == "I got: <class 'str'>" 65 # assert text(tuple) == 'I got: tuple' 66 assert text(tuple) == "I got: <class 'tuple'>" 67 # assert text(list) == 'I got: list' 68 assert text(list) == "I got: <class 'list'>" 69 70 71# Exceptions seenthe test passes.
I add an assertion for set (the class anything in curly braces
{ }, not key-value pairs)54def test_passing_a_class(): 55 # assert text(object) == 'I got: object' 56 assert text(object) == "I got: <class 'object'>" 57 # assert text(bool) == 'I got: bool' 58 assert text(bool) == "I got: <class 'bool'>" 59 # assert text(int) == "I got: int" 60 assert text(int) == "I got: <class 'int'>" 61 # assert text(float) == 'I got: float' 62 assert text(float) == "I got: <class 'float'>" 63 # assert text(str) == 'I got: str' 64 assert text(str) == "I got: <class 'str'>" 65 # assert text(tuple) == 'I got: tuple' 66 assert text(tuple) == "I got: <class 'tuple'>" 67 # assert text(list) == 'I got: list' 68 assert text(list) == "I got: <class 'list'>" 69 assert text(set) == 'I got: set' 70 71 72# Exceptions seenthe terminal is my friend, and shows AssertionError
E assert "I got: <class 'set'>" == 'I got: set'I change my expectation to match reality
54def test_passing_a_class(): 55 # assert text(object) == 'I got: object' 56 assert text(object) == "I got: <class 'object'>" 57 # assert text(bool) == 'I got: bool' 58 assert text(bool) == "I got: <class 'bool'>" 59 # assert text(int) == "I got: int" 60 assert text(int) == "I got: <class 'int'>" 61 # assert text(float) == 'I got: float' 62 assert text(float) == "I got: <class 'float'>" 63 # assert text(str) == 'I got: str' 64 assert text(str) == "I got: <class 'str'>" 65 # assert text(tuple) == 'I got: tuple' 66 assert text(tuple) == "I got: <class 'tuple'>" 67 # assert text(list) == 'I got: list' 68 assert text(list) == "I got: <class 'list'>" 69 # assert text(set) == 'I got: set' 70 assert text(set) == "I got: <class 'set'>" 71 72 73# Exceptions seenthe test passes.
I add an assertion for dict (the class for key-value pairs in curly braces ‘{ }’ separated by commas)
54def test_passing_a_class(): 55 # assert text(object) == 'I got: object' 56 assert text(object) == "I got: <class 'object'>" 57 # assert text(bool) == 'I got: bool' 58 assert text(bool) == "I got: <class 'bool'>" 59 # assert text(int) == "I got: int" 60 assert text(int) == "I got: <class 'int'>" 61 # assert text(float) == 'I got: float' 62 assert text(float) == "I got: <class 'float'>" 63 # assert text(str) == 'I got: str' 64 assert text(str) == "I got: <class 'str'>" 65 # assert text(tuple) == 'I got: tuple' 66 assert text(tuple) == "I got: <class 'tuple'>" 67 # assert text(list) == 'I got: list' 68 assert text(list) == "I got: <class 'list'>" 69 # assert text(set) == 'I got: set' 70 assert text(set) == "I got: <class 'set'>" 71 assert text(dict) == 'I got: dict' 72 73 74# Exceptions seenthe terminal is my friend, and shows AssertionError
E assert "I got: <class 'dict'>" == 'I got: dict'I change my expectation to match reality
54def test_passing_a_class(): 55 # assert text(object) == 'I got: object' 56 assert text(object) == "I got: <class 'object'>" 57 # assert text(bool) == 'I got: bool' 58 assert text(bool) == "I got: <class 'bool'>" 59 # assert text(int) == "I got: int" 60 assert text(int) == "I got: <class 'int'>" 61 # assert text(float) == 'I got: float' 62 assert text(float) == "I got: <class 'float'>" 63 # assert text(str) == 'I got: str' 64 assert text(str) == "I got: <class 'str'>" 65 # assert text(tuple) == 'I got: tuple' 66 assert text(tuple) == "I got: <class 'tuple'>" 67 # assert text(list) == 'I got: list' 68 assert text(list) == "I got: <class 'list'>" 69 # assert text(set) == 'I got: set' 70 assert text(set) == "I got: <class 'set'>" 71 # assert text(dict) == 'I got: dict' 72 assert text(dict) == "I got: <class 'dict'>" 73 74 75# Exceptions seenthe test passes because Python uses the string representation of the object in the curly braces
{ }text(dict) text(the_input) the_input = dict return f'I got: {the_input }' return "I got: <class 'dict'> "I remove the commented lines
54def test_passing_a_class(): 55 assert text(object) == "I got: <class 'object'>" 56 assert text(bool) == "I got: <class 'bool'>" 57 assert text(int) == "I got: <class 'int'>" 58 assert text(float) == "I got: <class 'float'>" 59 assert text(str) == "I got: <class 'str'>" 60 assert text(tuple) == "I got: <class 'tuple'>" 61 assert text(list) == "I got: <class 'list'>" 62 assert text(set) == "I got: <class 'set'>" 63 assert text(dict) == "I got: <class 'dict'>" 64 65 66# Exceptions seen 67# AssertionError 68# NameError 69# TypeErrorI add a git commit message in the other terminal
git commit --all --message \ 'add test_passing_a_class'the terminal shows a summary of the changes then goes back to the command line.
close the project
I close
test_telephone.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
telephonecd ..the terminal shows
.../pumping_pythonI am back in the
pumping_pythondirectory.
review
Here are the tests I ran to see what happens when I pass objects from a test to a program and place them in an f-string which is one way to do string interpolation
I also saw these Exceptions
code from the chapter
what is next?
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.