how to make a person with f-strings


Since I can pass objects into a string with f-strings. I can write one function that makes a person instead of making one function for each person.


preview

I have these tests by the end of the chapter

 1import src.person
 2
 3
 4def test_joe():
 5    first_name = 'joe'
 6    last_name = 'blow'
 7    sex = 'M'
 8    year_of_birth = 1996
 9
10    reality = src.person.factory(
11        first_name=first_name,
12        last_name=last_name,
13        sex=sex,
14        year_of_birth=year_of_birth,
15    )
16    my_expectation = (
17        f'{first_name}, {last_name},'
18        f' {sex}, {year_of_birth}'
19    )
20    assert reality == my_expectation
21
22
23def test_jane():
24    first_name = 'jane'
25    last_name = 'doe'
26    sex = 'F'
27    year_of_birth = 1991
28
29    reality = src.person.factory(
30        first_name=first_name,
31        last_name=last_name,
32        sex=sex,
33        year_of_birth=year_of_birth,
34    )
35    my_expectation = (
36        f'{first_name}, {last_name},'
37        f' {sex}, {year_of_birth}'
38    )
39    assert reality == my_expectation
40
41
42def test_john():
43    first_name = 'john'
44    last_name = 'smith'
45    sex = 'M'
46    year_of_birth = 1580
47
48    reality = src.person.factory(
49        first_name=first_name,
50        last_name=last_name,
51        sex=sex,
52        year_of_birth=year_of_birth,
53    )
54    my_expectation = (
55        f'{first_name}, {last_name},'
56        f' {sex}, {year_of_birth}'
57    )
58    assert reality == my_expectation
59
60
61def test_mary():
62    first_name = 'mary'
63    last_name = 'public'
64    sex = 'F'
65    year_of_birth = 2000
66
67    reality = src.person.factory(
68        first_name=first_name,
69        last_name=last_name,
70        sex=sex,
71        year_of_birth=year_of_birth,
72    )
73    my_expectation = (
74        f'{first_name}, {last_name},'
75        f' {sex}, {year_of_birth}'
76    )
77    assert reality == my_expectation
78
79
80# Exceptions seen
81# AssertionError
82# NameError
83# TypeError
84# AttributeError

open the project

  • I open a terminal

  • I change directory to the project

    cd person
    

    the terminal shows I am in the person folder

    .../pumping_python/ove
    
  • I open test_person.py

  • I use pytest-watcher to run the tests automatically

    uv run pytest-watcher . --now
    

    the terminal shows no tests ran.


test person factory


RED: make it fail


I add an assertion to test_joe in test_person.py

17  def test_joe():
18      assert joe() == 'joe, blow, M, 1996'
19
20      reality = factory()
21      my_expectation = 'joe, blow, M, 1996'
22      assert reality == my_expectation
23
24
25  def test_jane():

the terminal is my friend, and shows NameError

NameError: name 'factory' is not defined

because I have not defined factory in test_person.py, yet.


GREEN: make it pass


I add a function definition for it

1def factory():
2    return 'joe, blow, M, 1996'
3
4
5def joe():

the test passes.


REFACTOR: make it better


  • I add an assertion with a call to the factory function in test_jane

    21def test_joe():
    22    assert joe() == 'joe, blow, M, 1996'
    23
    24    reality = factory()
    25    my_expectation = 'joe, blow, M, 1996'
    26    assert reality == my_expectation
    27
    28
    29def test_jane():
    30    assert jane() == 'jane, doe, F, 1991'
    31
    32    reality = factory()
    33    my_expectation = 'jane, doe, F, 1991'
    34    assert reality == my_expectation
    35
    36
    37def test_john():
    

    the terminal is my friend, and shows AssertionError

    AssertionError: assert 'joe, blow, M, 1996'
                        == 'jane, doe, F, 1991'
    

    because the factory function always returns joe, blow, M, 1996 when it is called. It has to return a string based on the input it gets for me to be able to use it to make more than one person.

  • I make the function take input for the first name

    1# def factory():
    2def factory(first_name):
    3    return 'joe, blow, M, 1996'
    

    the terminal is my friend, and shows TypeError

    TypeError: factory() missing
               1 required positional argument:
               'first_name'
    

    because

  • I add 'jane' to the call to the factory function in test_jane

    30def test_jane():
    31    assert jane() == 'jane, doe, F, 1991'
    32
    33    # reality = factory()
    34    reality = factory('jane')
    35    my_expectation = 'jane, doe, F, 1991'
    36    assert reality == my_expectation
    37
    38
    39def test_john():
    

    the terminal is my friend, and shows AssertionError

    AssertionError: assert 'joe, blow, M, 1996'
                        == 'jane, doe, F, 1991'
    
  • I change the return statement of the factory function to an f-string to use first_name in the output

    1# def factory():
    2def factory(first_name):
    3    # return 'joe, blow, M, 1996'
    4    return f'{first_name}, blow, M, 1996'
    5
    6
    7def joe():
    

    the terminal is my friend, and shows AssertionError

    AssertionError: assert 'jane, blow, M, 1996'
                        == 'jane, doe, F, 1991'
    

    the first names match. Progress!

  • I add last_name to the return statement

     1# def factory():
     2def factory(first_name):
     3    # return 'joe, blow, M, 1996'
     4    # return f'{first_name}, blow, M, 1996'
     5    return (
     6        f'{first_name}, {last_name},'
     7        ' M, 1996'
     8    )
     9
    10
    11def joe():
    

    the terminal is my friend, and shows NameError

    NameError: name 'last_name' is not defined
    
  • I add the name to the parentheses to define it in the factory function

     1# def factory():
     2# def factory(first_name):
     3def factory(first_name, last_name):
     4    # return 'joe, blow, M, 1996'
     5    # return f'{first_name}, blow, M, 1996'
     6    return (
     7        f'{first_name}, {last_name},'
     8        ' M, 1996'
     9    )
    10
    11
    12def joe():
    

    the terminal is my friend, and shows TypeError

    TypeError: factory() missing
               1 required positional argument:
               'last_name'
    

    because

  • I add 'doe' to the call to the factory function in test_jane

    36def test_jane():
    37    assert jane() == 'jane, doe, F, 1991'
    38
    39    # reality = factory()
    40    # reality = factory('jane')
    41    reality = factory('jane', 'doe')
    42    my_expectation = 'jane, doe, F, 1991'
    43    assert reality == my_expectation
    44
    45
    46def test_john():
    

    the terminal is my friend, and shows AssertionError

    AssertionError: assert 'jane, doe, M, 1996'
                        == 'jane, doe, F, 1991'
    

    the first and last names match. More progress.

  • I use keyword arguments with a value for sex (since I have more than two) to change the call to the factory function in test_jane

    36def test_jane():
    37    assert jane() == 'jane, doe, F, 1991'
    38
    39    # reality = factory()
    40    # reality = factory('jane')
    41    # reality = factory('jane', 'doe')
    42    reality = factory(
    43        first_name='jane',
    44        last_name='doe',
    45        sex='F',
    46    )
    47    my_expectation = 'jane, doe, F, 1991'
    48    assert reality == my_expectation
    49
    50
    51def test_john():
    

    the terminal is my friend, and shows TypeError

    TypeError: factory() got an unexpected
               keyword argument 'sex'
    

    because

  • I add sex in the parentheses of the factory function definition

     1# def factory():
     2# def factory(first_name):
     3# def factory(first_name, last_name):
     4def factory(first_name, last_name, sex):
     5    # return 'joe, blow, M, 1996'
     6    # return f'{first_name}, blow, M, 1996'
     7    return (
     8        f'{first_name}, {last_name},'
     9        ' M, 1996'
    10    )
    11
    12
    13def joe():
    

    the terminal shows the last AssertionError again.

  • I add sex to the f-string in the factory function

     1# def factory():
     2# def factory(first_name):
     3# def factory(first_name, last_name):
     4def factory(first_name, last_name, sex):
     5    # return 'joe, blow, M, 1996'
     6    # return f'{first_name}, blow, M, 1996'
     7    return (
     8        f'{first_name}, {last_name},'
     9        # ' M, 1996'
    10        f' {sex}, 1996'
    11    )
    12
    13
    14def joe():
    

    the terminal is my friend, and shows AssertionError

    AssertionError: assert 'jane, doe, F, 1996'
                        == 'jane, doe, F, 1991'
    

    the first name, last name and sex match. Yes!

  • I add year_of_birth to the return statement

     1# def factory():
     2# def factory(first_name):
     3# def factory(first_name, last_name):
     4def factory(first_name, last_name, sex):
     5    # return 'joe, blow, M, 1996'
     6    # return f'{first_name}, blow, M, 1996'
     7    return (
     8        f'{first_name}, {last_name},'
     9        # ' M, 1996'
    10        # f' {sex}, 1996'
    11        f' {sex}, {year_of_birth}'
    12    )
    13
    14
    15def joe():
    

    the terminal is my friend, and shows NameError

    NameError: name 'year_of_birth' is not defined
    
  • I add year_of_birth to the parentheses to define it in the factory function

     1# def factory():
     2# def factory(first_name):
     3# def factory(first_name, last_name):
     4# def factory(first_name, last_name, sex):
     5def factory(
     6    first_name, last_name,
     7    sex, year_of_birth
     8):
     9    # return 'joe, blow, M, 1996'
    10    # return f'{first_name}, blow, M, 1996'
    11    return (
    12        f'{first_name}, {last_name},'
    13        # ' M, 1996'
    14        # f' {sex}, 1996'
    15        f' {sex}, {year_of_birth}'
    16    )
    17
    18
    19def joe():
    

    the terminal is my friend, and shows TypeError

    TypeError: factory() missing
               1 required positional argument:
               'year_of_birth'
    

    because

  • I add year_of_birth=1996 to the call to the factory function in test_jane

    43def test_jane():
    44    assert jane() == 'jane, doe, F, 1991'
    45
    46    # reality = factory()
    47    # reality = factory('jane')
    48    # reality = factory('jane', 'doe')
    49    reality = factory(
    50        first_name='jane',
    51        last_name='doe',
    52        sex='F',
    53        year_of_birth=1991,
    54    )
    55    my_expectation = 'jane, doe, F, 1991'
    56    assert reality == my_expectation
    57
    58
    59def test_john():
    

    the terminal is my friend, and shows TypeError

    TypeError: factory() missing
               4 required positional arguments:
               'first_name', 'last_name', 'sex',
               and 'year_of_birth'
    

    because

  • Since there are more than two, I add keyword arguments to the call to the factory function in test_joe

    35def test_joe():
    36    assert joe() == 'joe, blow, M, 1996'
    37
    38    # reality = factory()
    39    reality = factory(
    40        first_name='joe',
    41        last_name='blow',
    42        sex='M',
    43        year_of_birth=1996,
    44    )
    45    my_expectation = 'joe, blow, M, 1996'
    46    assert reality == my_expectation
    47
    48
    49def test_jane():
    

    the test passes and I have one function that I can use to make any number of people.


  • I remove the commented lines from the factory function

     1def factory(
     2    first_name, last_name,
     3    sex, year_of_birth
     4):
     5    return (
     6        f'{first_name}, {last_name},'
     7        f' {sex}, {year_of_birth}'
     8    )
     9
    10
    11def joe():
    
  • I comment out the call to joe in test_joe because I no longer need it since the factory function does the same thing

    27def test_joe():
    28    # assert joe() == 'joe, blow, M, 1996'
    29
    30    reality = factory(
    31        first_name='joe',
    32        last_name='blow',
    33        sex='M',
    34        year_of_birth=1996,
    35    )
    36    my_expectation = 'joe, blow, M, 1996'
    37    assert reality == my_expectation
    38
    39
    40def test_jane():
    
  • I add a variable for 'joe' in test_joe

    27def test_joe():
    28    # assert joe() == 'joe, blow, M, 1996'
    29    first_name = 'joe'
    30
    31    reality = factory(
    32        first_name='joe',
    33        last_name='blow',
    34        sex='M',
    35        year_of_birth=1996,
    36    )
    37    my_expectation = 'joe, blow, M, 1996'
    38    assert reality == my_expectation
    39
    40
    41def test_jane():
    
  • I use the variable to remove repetition of 'joe'

    27def test_joe():
    28    # assert joe() == 'joe, blow, M, 1996'
    29    first_name = 'joe'
    30
    31    reality = factory(
    32        # first_name='joe',
    33        first_name=first_name,
    34        last_name='blow',
    35        sex='M',
    36        year_of_birth=1996,
    37    )
    38    # my_expectation = 'joe, blow, M, 1996'
    39    my_expectation = (
    40        f'{first_name}, blow,'
    41        ' M, 1996'
    42    )
    43    assert reality == my_expectation
    44
    45
    46def test_jane():
    

    the test is still green.

  • I add a variable for 'blow' in test_joe

    27def test_joe():
    28    # assert joe() == 'joe, blow, M, 1996'
    29    first_name = 'joe'
    30    last_name = 'blow'
    31
    32    reality = factory(
    33        # first_name='joe',
    34        first_name=first_name,
    35        last_name='blow',
    36        sex='M',
    37        year_of_birth=1996,
    38    )
    39    # my_expectation = 'joe, blow, M, 1996'
    40    my_expectation = (
    41        f'{first_name}, blow,'
    42        ' M, 1996'
    43    )
    44    assert reality == my_expectation
    45
    46
    47def test_jane():
    
  • I use the variable to remove repetition of 'blow'

    27def test_joe():
    28    # assert joe() == 'joe, blow, M, 1996'
    29    first_name = 'joe'
    30    last_name = 'blow'
    31
    32    reality = factory(
    33        # first_name='joe',
    34        first_name=first_name,
    35        # last_name='blow',
    36        last_name=last_name,
    37        sex='M',
    38        year_of_birth=1996,
    39    )
    40    # my_expectation = 'joe, blow, M, 1996'
    41    my_expectation = (
    42        # f'{first_name}, blow,'
    43        f'{first_name}, {last_name},'
    44        ' M, 1996'
    45    )
    46    assert reality == my_expectation
    47
    48
    49def test_jane():
    

    still green.

  • I add a variable for 'M' in test_joe

    27def test_joe():
    28    # assert joe() == 'joe, blow, M, 1996'
    29    first_name = 'joe'
    30    last_name = 'blow'
    31    sex = 'M'
    32
    33    reality = factory(
    34        # first_name='joe',
    35        first_name=first_name,
    36        # last_name='blow',
    37        last_name=last_name,
    38        sex='M',
    39        year_of_birth=1996,
    40    )
    
  • I use the variable to remove repetition of 'M'

    27def test_joe():
    28    # assert joe() == 'joe, blow, M, 1996'
    29    first_name = 'joe'
    30    last_name = 'blow'
    31    sex = 'M'
    32
    33    reality = factory(
    34        # first_name='joe',
    35        first_name=first_name,
    36        # last_name='blow',
    37        last_name=last_name,
    38        # sex='M',
    39        sex=sex,
    40        year_of_birth=1996,
    41    )
    42    # my_expectation = 'joe, blow, M, 1996'
    43    my_expectation = (
    44        # f'{first_name}, blow,'
    45        f'{first_name}, {last_name},'
    46        # ' M, 1996'
    47        f' {sex}, 1996'
    48    )
    49    assert reality == my_expectation
    50
    51
    52def test_jane():
    

    green.

  • I add a variable for 1996 in test_joe

    27def test_joe():
    28    # assert joe() == 'joe, blow, M, 1996'
    29    first_name = 'joe'
    30    last_name = 'blow'
    31    sex = 'M'
    32    year_of_birth = 1996
    33
    34    reality = factory(
    35        # first_name='joe',
    36        first_name=first_name,
    37        # last_name='blow',
    38        last_name=last_name,
    39        # sex='M',
    40        sex=sex,
    41        year_of_birth=1996,
    42    )
    
  • I use the variable to remove repetition of 1996

    27def test_joe():
    28    # assert joe() == 'joe, blow, M, 1996'
    29    first_name = 'joe'
    30    last_name = 'blow'
    31    sex = 'M'
    32    year_of_birth = 1996
    33
    34    reality = factory(
    35        # first_name='joe',
    36        first_name=first_name,
    37        # last_name='blow',
    38        last_name=last_name,
    39        # sex='M',
    40        sex=sex,
    41        # year_of_birth=1996,
    42        year_of_birth=year_of_birth,
    43    )
    44    # my_expectation = 'joe, blow, M, 1996'
    45    my_expectation = (
    46        # f'{first_name}, blow,'
    47        f'{first_name}, {last_name},'
    48        # ' M, 1996'
    49        # f' {sex}, 1996'
    50        f' {sex}, {year_of_birth}'
    51    )
    52    assert reality == my_expectation
    53
    54
    55def test_jane():
    

    still green.

  • I remove the commented lines

    27def test_joe():
    28    first_name = 'joe'
    29    last_name = 'blow'
    30    sex = 'M'
    31    year_of_birth = 1996
    32
    33    reality = factory(
    34        first_name=first_name,
    35        last_name=last_name,
    36        sex=sex,
    37        year_of_birth=year_of_birth,
    38    )
    39    my_expectation = (
    40        f'{first_name}, {last_name},'
    41        f' {sex}, {year_of_birth}'
    42    )
    43    assert reality == my_expectation
    44
    45
    46def test_jane():
    

  • I comment out the call to jane in test_jane because I no longer need it since the factory function does the same thing

    46def test_jane():
    47    # assert jane() == 'jane, doe, F, 1991'
    48
    49    # reality = factory()
    
  • I add a variable for 'jane' in test_jane

    46def test_jane():
    47    # assert jane() == 'jane, doe, F, 1991'
    48    first_name = 'jane'
    49
    50    # reality = factory()
    
  • I use the variable to remove repetition of 'jane'

    46def test_jane():
    47    # assert jane() == 'jane, doe, F, 1991'
    48    first_name = 'jane'
    49
    50    # reality = factory()
    51    # reality = factory('jane')
    52    # reality = factory('jane', 'doe')
    53    reality = factory(
    54        # first_name='jane',
    55        first_name=first_name,
    56        last_name='doe',
    57        sex='F',
    58        year_of_birth=1991,
    59    )
    60    # my_expectation = 'jane, doe, F, 1991'
    61    my_expectation = (
    62        f'{first_name}, doe,'
    63        ' F, 1991'
    64    )
    65    assert reality == my_expectation
    66
    67
    68def test_john():
    

    the test is still green.

  • I add a variable for 'doe' in test_jane

    46def test_jane():
    47    # assert jane() == 'jane, doe, F, 1991'
    48    first_name = 'jane'
    49    last_name = 'doe'
    50
    51    # reality = factory()
    
  • I use the variable to remove repetition of 'doe'

    46def test_jane():
    47    # assert jane() == 'jane, doe, F, 1991'
    48    first_name = 'jane'
    49    last_name = 'doe'
    50
    51    # reality = factory()
    52    # reality = factory('jane')
    53    # reality = factory('jane', 'doe')
    54    reality = factory(
    55        # first_name='jane',
    56        first_name=first_name,
    57        # last_name='doe',
    58        last_name=last_name,
    59        sex='F',
    60        year_of_birth=1991,
    61    )
    62    # my_expectation = 'jane, doe, F, 1991'
    63    my_expectation = (
    64        # f'{first_name}, doe,'
    65        f'{first_name}, {last_name},'
    66        ' F, 1991'
    67    )
    68    assert reality == my_expectation
    69
    70
    71def test_john():
    

    still green.

  • I add a variable for 'F' in test_jane

    46def test_jane():
    47    # assert jane() == 'jane, doe, F, 1991'
    48    first_name = 'jane'
    49    last_name = 'doe'
    50    sex = 'F'
    51
    52    # reality = factory()
    
  • I use the variable to remove repetition of 'F'

    46def test_jane():
    47    # assert jane() == 'jane, doe, F, 1991'
    48    first_name = 'jane'
    49    last_name = 'doe'
    50    sex = 'F'
    51
    52    # reality = factory()
    53    # reality = factory('jane')
    54    # reality = factory('jane', 'doe')
    55    reality = factory(
    56        # first_name='jane',
    57        first_name=first_name,
    58        # last_name='doe',
    59        last_name=last_name,
    60        # sex='F',
    61        sex=sex,
    62        year_of_birth=1991,
    63    )
    64    # my_expectation = 'jane, doe, F, 1991'
    65    my_expectation = (
    66        # f'{first_name}, doe,'
    67        f'{first_name}, {last_name},'
    68        # ' F, 1991'
    69        f' {sex}, 1991'
    70    )
    71    assert reality == my_expectation
    72
    73
    74def test_john():
    

    green.

  • I add a variable for 1991 in test_jane

    46def test_jane():
    47    # assert jane() == 'jane, doe, F, 1991'
    48    first_name = 'jane'
    49    last_name = 'doe'
    50    sex = 'F'
    51    year_of_birth = 1991
    52
    53    # reality = factory()
    
  • I use the variable to remove repetition of 1991

    46def test_jane():
    47    # assert jane() == 'jane, doe, F, 1991'
    48    first_name = 'jane'
    49    last_name = 'doe'
    50    sex = 'F'
    51    year_of_birth = 1991
    52
    53    # reality = factory()
    54    # reality = factory('jane')
    55    # reality = factory('jane', 'doe')
    56    reality = factory(
    57        # first_name='jane',
    58        first_name=first_name,
    59        # last_name='doe',
    60        last_name=last_name,
    61        # sex='F',
    62        sex=sex,
    63        # year_of_birth=1991,
    64        year_of_birth=year_of_birth,
    65    )
    66    # my_expectation = 'jane, doe, F, 1991'
    67    my_expectation = (
    68        # f'{first_name}, doe,'
    69        f'{first_name}, {last_name},'
    70        # ' F, 1991'
    71        # f' {sex}, 1991'
    72        f' {sex}, {year_of_birth}'
    73    )
    74    assert reality == my_expectation
    75
    76
    77def test_john():
    

    still green.

  • I remove the commented lines

    46def test_jane():
    47    first_name = 'jane'
    48    last_name = 'doe'
    49    sex = 'F'
    50    year_of_birth = 1991
    51
    52    reality = factory(
    53        first_name=first_name,
    54        last_name=last_name,
    55        sex=sex,
    56        year_of_birth=year_of_birth,
    57    )
    58    my_expectation = (
    59        f'{first_name}, {last_name},'
    60        f' {sex}, {year_of_birth}'
    61    )
    62    assert reality == my_expectation
    63
    64
    65def test_john():
    

  • I change the call in test_john to a call to the factory function

    65def test_john():
    66    # assert john() == 'john, smith, M, 1580'
    67    reality = factory(
    68        first_name='john',
    69        last_name='smith',
    70        sex='M',
    71        year_of_birth=1580,
    72    )
    73    my_expectation = 'jane, doe, F, 1991'
    74    assert reality == my_expectation
    75
    76
    77def test_mary():
    

    the terminal is my friend, and shows AssertionError

    AssertionError: assert 'john, smith, M, 1580'
                        == 'jane, doe, F, 1991'
    
  • I change my_expectation to match reality

    65def test_john():
    66    # assert john() == 'john, smith, M, 1580'
    67    reality = factory(
    68        first_name='john',
    69        last_name='smith',
    70        sex='M',
    71        year_of_birth=1580,
    72    )
    73    # my_expectation = 'jane, doe, F, 1991'
    74    my_expectation = 'john, smith, M, 1580'
    75    assert reality == my_expectation
    76
    77
    78def test_mary():
    

    the test passes.

  • I add a variable for 'john' in test_john

    65def test_john():
    66    # assert john() == 'john, smith, M, 1580'
    67    first_name = 'john'
    68
    69    reality = factory(
    70        first_name='john',
    71        last_name='smith',
    72        sex='M',
    73        year_of_birth=1580,
    74    )
    75    # my_expectation = 'jane, doe, F, 1991'
    76    my_expectation = 'john, smith, M, 1580'
    77    assert reality == my_expectation
    78
    79
    80def test_mary():
    
  • I use the variable to remove repetition of 'john'

    65def test_john():
    66    # assert john() == 'john, smith, M, 1580'
    67    first_name = 'john'
    68
    69    reality = factory(
    70        # first_name='john',
    71        first_name=first_name,
    72        last_name='smith',
    73        sex='M',
    74        year_of_birth=1580,
    75    )
    76    # my_expectation = 'jane, doe, F, 1991'
    77    # my_expectation = 'john, smith, M, 1580'
    78    my_expectation = (
    79        f'{first_name}, smith,'
    80        ' M, 1580'
    81    )
    82    assert reality == my_expectation
    83
    84
    85def test_mary():
    

    the test is still green.

  • I add a variable for 'smith' in test_john

    65def test_john():
    66    # assert john() == 'john, smith, M, 1580'
    67    first_name = 'john'
    68    last_name = 'smith'
    
  • I use the variable to remove repetition of 'smith'

    65def test_john():
    66    # assert john() == 'john, smith, M, 1580'
    67    first_name = 'john'
    68    last_name = 'smith'
    69
    70    reality = factory(
    71        # first_name='john',
    72        first_name=first_name,
    73        # last_name='smith',
    74        last_name=last_name,
    75        sex='M',
    76        year_of_birth=1580,
    77    )
    78    # my_expectation = 'jane, doe, F, 1991'
    79    # my_expectation = 'john, smith, M, 1580'
    80    my_expectation = (
    81        # f'{first_name}, smith,'
    82        f'{first_name}, {last_name},'
    83        ' M, 1580'
    84    )
    85    assert reality == my_expectation
    86
    87
    88def test_mary():
    

    still green.

  • I add a variable for 'M' in test_john

    65def test_john():
    66    # assert john() == 'john, smith, M, 1580'
    67    first_name = 'john'
    68    last_name = 'smith'
    69    sex = 'M'
    
  • I use the variable to remove repetition of 'M'

    65def test_john():
    66    # assert john() == 'john, smith, M, 1580'
    67    first_name = 'john'
    68    last_name = 'smith'
    69    sex = 'M'
    70
    71    reality = factory(
    72        # first_name='john',
    73        first_name=first_name,
    74        # last_name='smith',
    75        last_name=last_name,
    76        # sex='M',
    77        sex=sex,
    78        year_of_birth=1580,
    79    )
    80    # my_expectation = 'jane, doe, F, 1991'
    81    # my_expectation = 'john, smith, M, 1580'
    82    my_expectation = (
    83        # f'{first_name}, smith,'
    84        f'{first_name}, {last_name},'
    85        # ' M, 1580'
    86        f' {sex}, 1580'
    87    )
    88    assert reality == my_expectation
    89
    90
    91def test_mary():
    

    green.

  • I add a variable for 1580 in test_john

    65def test_john():
    66    # assert john() == 'john, smith, M, 1580'
    67    first_name = 'john'
    68    last_name = 'smith'
    69    sex = 'M'
    70    year_of_birth = 1580
    
  • I use the variable to remove repetition of 1580

    65def test_john():
    66    # assert john() == 'john, smith, M, 1580'
    67    first_name = 'john'
    68    last_name = 'smith'
    69    sex = 'M'
    70    year_of_birth = 1580
    71
    72    reality = factory(
    73        # first_name='john',
    74        first_name=first_name,
    75        # last_name='smith',
    76        last_name=last_name,
    77        # sex='M',
    78        sex=sex,
    79        # year_of_birth=1580,
    80        year_of_birth=year_of_birth,
    81    )
    82    # my_expectation = 'jane, doe, F, 1991'
    83    # my_expectation = 'john, smith, M, 1580'
    84    my_expectation = (
    85        # f'{first_name}, smith,'
    86        f'{first_name}, {last_name},'
    87        # ' M, 1580'
    88        # f' {sex}, 1580'
    89        f' {sex}, {year_of_birth}'
    90    )
    91    assert reality == my_expectation
    92
    93
    94def test_mary():
    

    still green.

  • I remove the commented lines

    65def test_john():
    66    first_name = 'john'
    67    last_name = 'smith'
    68    sex = 'M'
    69    year_of_birth = 1580
    70
    71    reality = factory(
    72        first_name=first_name,
    73        last_name=last_name,
    74        sex=sex,
    75        year_of_birth=year_of_birth,
    76    )
    77    my_expectation = (
    78        f'{first_name}, {last_name},'
    79        f' {sex}, {year_of_birth}'
    80    )
    81    assert reality == my_expectation
    82
    83
    84def test_mary():
    
  • I make the same change to test_mary

     84def test_mary():
     85    # assert mary() == 'mary, public, F, 2000'
     86    first_name = 'mary'
     87    last_name = 'public'
     88    sex = 'F'
     89    year_of_birth = 2000
     90
     91    reality = factory(
     92        first_name=first_name,
     93        last_name=last_name,
     94        sex=sex,
     95        year_of_birth=year_of_birth,
     96    )
     97    my_expectation = (
     98        f'{first_name}, {last_name},'
     99        f' {sex}, {year_of_birth}'
    100    )
    101    assert reality == my_expectation
    102
    103
    104# Exceptions seen
    

    the test is still green.

  • I remove the commented line

     84def test_mary():
     85    first_name = 'mary'
     86    last_name = 'public'
     87    sex = 'F'
     88    year_of_birth = 2000
     89
     90    reality = factory(
     91        first_name=first_name,
     92        last_name=last_name,
     93        sex=sex,
     94        year_of_birth=year_of_birth,
     95    )
     96    my_expectation = (
     97        f'{first_name}, {last_name},'
     98        f' {sex}, {year_of_birth}'
     99    )
    100    assert reality == my_expectation
    101
    102
    103# Exceptions seen
    
  • I remove the joe, jane, john and mary functions because they are no longer used

     1def factory(
     2    first_name, last_name,
     3    sex, year_of_birth
     4):
     5    return (
     6        f'{first_name}, {last_name},'
     7        f' {sex}, {year_of_birth}'
     8    )
     9
    10
    11def test_joe():
    

    the factory function can make a string for any person I want when I give it the first name, last name, sex and year of birth.

  • I open a new terminal then change directories to person

    cd person
    
  • I add a git commit message in the new terminal

    git commit -am 'extract factory function'
    

separate and equal


RED: make it fail


  • I go back to the terminal where the tests are running

  • I change the call to the factory function in test_joe to the factory function of the person module in the src folder instead of in the same file (test_person.py)

    11def test_joe():
    12    first_name = 'joe'
    13    last_name = 'blow'
    14    sex = 'M'
    15    year_of_birth = 1996
    16
    17    # reality = factory(
    18    reality = src.person.factory(
    19        first_name=first_name,
    20        last_name=last_name,
    21        sex=sex,
    22        year_of_birth=year_of_birth,
    23    )
    24    my_expectation = (
    25        f'{first_name}, {last_name},'
    26        f' {sex}, {year_of_birth}'
    27    )
    28    assert reality == my_expectation
    29
    30
    31def test_jane():
    

    the terminal is my friend, and shows NameError

    NameError: name 'src' is not defined
    

GREEN: make it pass


  • I add an import statement at the top of test_person.py

    1import src.person
    2
    3
    4def factory(
    5    first_name, last_name,
    6    sex, year_of_birth
    7):
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.person' has no attribute 'factory'
    

    because there is nothing named factory in person.py in the src folder.

  • I add AttributeError to the list of Exceptions seen

    90# Exceptions seen
    91# AssertionError
    92# NameError
    93# TypeError
    94# AttributeError
    
  • I open person.py from the src folder

  • I delete all the text in the file then add a copy of the factory function to person.py

    1def factory(
    2    first_name, last_name,
    3    sex, year_of_birth
    4):
    5    return (
    6        f'{first_name}, {last_name},'
    7        f' {sex}, {year_of_birth}'
    8    )
    

    the test passes because

    I think of src.person.factory like an address

    • factory is something in person, in this case it is a function in person

    • person is something in src, in this case it is person.py (a module) in the src folder

    • src is something Python can import (a module, Python package or folder)

      src
      └── person.py
          └── def factory(
                  first_name, last_name,
                  sex, year_of_birth
              ):
                  return (
                      f'{first_name}, {last_name},'
                      f' {sex}, {year_of_birth}'
                  )
      

REFACTOR: make it better


  • I remove the commented line from test_joe in test_person.py

    14def test_joe():
    15    first_name = 'joe'
    16    last_name = 'blow'
    17    sex = 'M'
    18    year_of_birth = 1996
    19
    20    reality = src.person.factory(
    21        first_name=first_name,
    22        last_name=last_name,
    23        sex=sex,
    24        year_of_birth=year_of_birth,
    25    )
    26    my_expectation = (
    27        f'{first_name}, {last_name},'
    28        f' {sex}, {year_of_birth}'
    29    )
    30    assert reality == my_expectation
    31
    32
    33def test_jane():
    
  • I change the call to the factory function in test_jane to the factory function of the person module in the src folder

    33def test_jane():
    34    first_name = 'jane'
    35    last_name = 'doe'
    36    sex = 'F'
    37    year_of_birth = 1991
    38
    39    # reality = factory(
    40    reality = src.person.factory(
    41        first_name=first_name,
    42        last_name=last_name,
    43        sex=sex,
    44        year_of_birth=year_of_birth,
    45    )
    46    my_expectation = (
    47        f'{first_name}, {last_name},'
    48        f' {sex}, {year_of_birth}'
    49    )
    50    assert reality == my_expectation
    51
    52
    53def test_john():
    

    the test is still green.

  • I remove the commented line from test_jane

    33def test_jane():
    34    first_name = 'jane'
    35    last_name = 'doe'
    36    sex = 'F'
    37    year_of_birth = 1991
    38
    39    reality = src.person.factory(
    40        first_name=first_name,
    41        last_name=last_name,
    42        sex=sex,
    43        year_of_birth=year_of_birth,
    44    )
    45    my_expectation = (
    46        f'{first_name}, {last_name},'
    47        f' {sex}, {year_of_birth}'
    48    )
    49    assert reality == my_expectation
    50
    51
    52def test_john():
    
  • I reroute the call to the factory function in test_john to the factory function of the person module in the src folder

    52def test_john():
    53    first_name = 'john'
    54    last_name = 'smith'
    55    sex = 'M'
    56    year_of_birth = 1580
    57
    58    # reality = factory(
    59    reality = src.person.factory(
    60        first_name=first_name,
    61        last_name=last_name,
    62        sex=sex,
    63        year_of_birth=year_of_birth,
    64    )
    65    my_expectation = (
    66        f'{first_name}, {last_name},'
    67        f' {sex}, {year_of_birth}'
    68    )
    69    assert reality == my_expectation
    70
    71
    72def test_mary():
    

    still green.

  • I remove the commented line

    52def test_john():
    53    first_name = 'john'
    54    last_name = 'smith'
    55    sex = 'M'
    56    year_of_birth = 1580
    57
    58    reality = src.person.factory(
    59        first_name=first_name,
    60        last_name=last_name,
    61        sex=sex,
    62        year_of_birth=year_of_birth,
    63    )
    64    my_expectation = (
    65        f'{first_name}, {last_name},'
    66        f' {sex}, {year_of_birth}'
    67    )
    68    assert reality == my_expectation
    69
    70
    71def test_mary():
    
  • I do the same thing to the call to the factory function in test_mary

    71def test_mary():
    72    first_name = 'mary'
    73    last_name = 'public'
    74    sex = 'F'
    75    year_of_birth = 2000
    76
    77    # reality = factory(
    78    reality = src.person.factory(
    79        first_name=first_name,
    80        last_name=last_name,
    81        sex=sex,
    82        year_of_birth=year_of_birth,
    83    )
    84    my_expectation = (
    85        f'{first_name}, {last_name},'
    86        f' {sex}, {year_of_birth}'
    87    )
    88    assert reality == my_expectation
    89
    90
    91# Exceptions seen
    

    green.

  • I remove the commented line

    71def test_mary():
    72    first_name = 'mary'
    73    last_name = 'public'
    74    sex = 'F'
    75    year_of_birth = 2000
    76
    77    reality = src.person.factory(
    78        first_name=first_name,
    79        last_name=last_name,
    80        sex=sex,
    81        year_of_birth=year_of_birth,
    82    )
    83    my_expectation = (
    84        f'{first_name}, {last_name},'
    85        f' {sex}, {year_of_birth}'
    86    )
    87    assert reality == my_expectation
    88
    89
    90# Exceptions seen
    91# AssertionError
    92# NameError
    93# TypeError
    94# AttributeError
    
  • I remove the factory function from test_person.py

     1import src.person
     2
     3
     4def test_joe():
     5    first_name = 'joe'
     6    last_name = 'blow'
     7    sex = 'M'
     8    year_of_birth = 1996
     9
    10    reality = src.person.factory(
    11        first_name=first_name,
    12        last_name=last_name,
    13        sex=sex,
    14        year_of_birth=year_of_birth,
    15    )
    16    my_expectation = (
    17        f'{first_name}, {last_name},'
    18        f' {sex}, {year_of_birth}'
    19    )
    20    assert reality == my_expectation
    21
    22
    23def test_jane():
    

    all the tests are still green because all the calls to the factory function that was in test_person.py are now to the factory function in person.py in the src folder. When src.person.factory is called Python follows this path

    src
    └── person.py
        └── def factory(
                first_name, last_name,
                sex, year_of_birth
            ):
                return (
                    f'{first_name}, {last_name},'
                    f' {sex}, {year_of_birth}'
                )
    
  • I add a git commit message in the other terminal

    git commit -am \
    'separate solution from tests'
    

    the terminal shows a summary of the changes then goes back to the command line.

I can write solutions in a different module from the tests.


test say_hi

I want the person I make to say hi. I can make a function that takes input about a person and returns a message.


RED: make it fail


  • I add an assertion to test_joe

     1import src.person
     2
     3
     4def test_joe():
     5    first_name = 'joe'
     6    last_name = 'blow'
     7    sex = 'M'
     8    year_of_birth = 1996
     9
    10    reality = src.person.factory(
    11        first_name=first_name,
    12        last_name=last_name,
    13        sex=sex,
    14        year_of_birth=year_of_birth,
    15    )
    16    my_expectation = (
    17        f'{first_name}, {last_name},'
    18        f' {sex}, {year_of_birth}'
    19    )
    20    assert reality == my_expectation
    21
    22    reality = say_hi(
    23        first_name=first_name,
    24        last_name=last_name,
    25        year_of_birth=year_of_birth,
    26    )
    27    my_expectation = (
    28        f'Hi, my name is {first_name}'
    29        f' {last_name} and I am'
    30        f' {2026-year_of_birth}.'
    31    )
    32    assert reality == my_expectation
    33
    34
    35def test_jane():
    

    the terminal is my friend, and shows NameError


close the project

  • I close test_person.py and person.py

  • I 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 person

    cd ..
    

    the terminal shows

    ...\pumping_python
    

    I am back in the pumping_python directory.


review

I ran tests to make a function that uses f-strings to make a string that can represent a person when I give it first_name, last_name, sex and year_of_birth.


code from the chapter

Do you want to see all the CODE I typed in this chapter?


what is next?

you know:

Would you like to test functions with input?


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.