how to make a person with variables


I want to make a contact list of people. I can use variables to represent a person, for example

  • First Name

  • Last Name (Surname)

  • Sex

  • Year of Birth

can be placed in a string (anything in quotes).


preview

I have these tests by the end of the chapter

 1def joe():
 2    return 'joe, blow, M, 1996'
 3
 4
 5def jane():
 6    return 'jane, doe, F, 1991'
 7
 8
 9def john():
10    return 'john, smith, M, 1580'
11
12
13def mary():
14    return 'mary, public, F, 2000'
15
16
17def test_joe():
18    assert joe() == 'joe, blow, M, 1996'
19
20
21def test_jane():
22    assert jane() == 'jane, doe, F, 1991'
23
24
25def test_john():
26    assert john() == 'john, smith, M, 1580'
27
28
29def test_mary():
30    assert mary() == 'mary, public, F, 2000'
31
32
33# Exceptions seen
34# AssertionError
35# NameError
36# TypeError

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/person
    
  • 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_joe


RED: make it fail


  • I remove the assertion and comments then add a new test function

    1def test_joe():
    2    assert joe() == 'joe, blow, M, 1996'
    3
    4
    5# Exceptions seen
    6# AssertionError
    

    the terminal is my friend, and shows NameError

    NameError: name 'joe' is not defined
    

    because there is no definition for joe in test_person.py.

  • I add NameError to the list of Exceptions seen

    5# Exceptions seen
    6# AssertionError
    7# NameError
    

GREEN: make it pass


  • I add a variable for joe and point it to None

    1joe = None
    2
    3
    4def test_joe():
    5    assert joe() == 'joe, blow, M, 1996'
    6
    7
    8# Exceptions seen
    

    the terminal is my friend, and shows TypeError

    TypeError: 'NoneType' object is not callable
    

    because I called joe which points to None and I cannot call None like a function. Using substitution

    joe = None # point the name to the object
    joe()      # call the name
    None()     # substitute the value for the name
    

    None() raises TypeError.

  • I add TypeError to the list of Exceptions seen

     7# Exceptions seen
     8# AssertionError
     9# NameError
    10# TypeError
    
  • I change joe to a function

     1# joe = None
     2def joe():
     3    return None
     4
     5
     6def test_joe():
     7    assert joe() == 'joe, blow, M, 1996'
     8
     9
    10# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: assert None == 'joe, blow, M, 1996'
    

    because when I call joe it returns None. Using substitution since I can treat a call to a function as the object it returns

    assert joe() == 'joe, blow, M, 1996'
    assert None  == 'joe, blow, M, 1996'
    

    which raises AssertionError because None is only equal to None.

  • I change the return statement of joe

     1# joe = None
     2def joe():
     3    # return None
     4    return 'joe, blow, M, 1996'
     5
     6
     7def test_joe():
     8    assert joe() == 'joe, blow, M, 1996'
     9
    10
    11# Exceptions seen
    

    the test passes.


REFACTOR: make it better


  • I remove the commented lines

    1def joe():
    2    return 'joe, blow, M, 1996'
    3
    4
    5def test_joe():
    6    assert joe() == 'joe, blow, M, 1996'
    7
    8
    9# Exceptions seen
    
  • I add a git commit message in the other terminal

    git commit -am 'add test_joe'
    

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


test_jane


RED: make it fail


I add a test function

 5def test_joe():
 6    assert joe() == 'joe, blow, M, 1996'
 7
 8
 9def test_jane():
10    assert jane() == 'jane, doe, F, 1991'
11
12
13
14# Exceptions seen

the terminal is my friend, and shows NameError

NameError: name 'jane' is not defined

because there is no definition for jane in this file.


GREEN: make it pass


  • I add a variable for jane and point it to None

    1def joe():
    2    return 'joe, blow, M, 1996'
    3
    4
    5jane = None
    6
    7
    8def test_joe():
    

    the terminal is my friend, and shows TypeError

    TypeError: 'NoneType' object is not callable
    

    because I called jane which points to None and I cannot call None like a function. Using substitution

    jane = None # point the name to the object
    jane()      # call the name
    None()      # substitute the value for the name
    

    None() raises TypeError.

  • I change jane to a function

     1def joe():
     2    return 'joe, blow, M, 1996'
     3
     4
     5# jane = None
     6def jane():
     7    return None
     8
     9
    10def test_joe():
    

    the terminal is my friend, and shows AssertionError

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

    because when I call jane it returns None. Using substitution since I can treat a call to a function as the object it returns

    assert jane() == 'jane, doe, F, 1991'
    assert None   == 'jane, doe, F, 1991'
    

    which raises AssertionError because None is only equal to None.

  • I change the return statement of jane

     1def joe():
     2    return 'joe, blow, M, 1996'
     3
     4
     5# jane = None
     6def jane():
     7    # return None
     8    return 'jane, doe, F, 1991'
     9
    10
    11def test_joe():
    

    the test passes.


REFACTOR: make it better


  • I remove the commented lines

     1def joe():
     2    return 'joe, blow, M, 1996'
     3
     4
     5def jane():
     6    return 'jane, doe, F, 1991'
     7
     8
     9def test_joe():
    10    assert joe() == 'joe, blow, M, 1996'
    11
    12
    13def test_jane():
    14    assert jane() == 'jane, doe, F, 1991'
    15
    16
    17# Exceptions seen
    
  • I add a git commit message in the other terminal

    git commit -am 'add test_jane'
    

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


test_john


RED: make it fail


I add another test function

13def test_jane():
14    assert jane() == 'jane, doe, F, 1991'
15
16
17def test_john():
18    assert john() == 'john, smith, M, 1580'
19
20
21
22# Exceptions seen

the terminal is my friend, and shows NameError

NameError: name 'john' is not defined

because there is no definition for john in this file, yet.


GREEN: make it pass


  • I add a variable for john and point it to None

     5def jane():
     6    return 'jane, doe, F, 1991'
     7
     8
     9john = None
    10
    11
    12def test_joe():
    

    the terminal is my friend, and shows TypeError

    TypeError: 'NoneType' object is not callable
    

    because I called john which points to None and I cannot call None like a function. Using substitution

    john = None # point the name to the object
    john()      # call the name
    None()      # substitute the value for the name
    

    None() raises TypeError.

  • I change john to a function

     5def joe():
     6    return 'joe, blow, M, 1996'
     7
     8
     9# john = None
    10def john():
    11    return None
    12
    13
    14def test_joe():
    

    the terminal is my friend, and shows AssertionError

    AssertionError: assert None == 'john, smith, M, 1580'
    

    because when I call john it returns None. Using substitution since I can treat a call to a function as the object it returns

    assert john() == 'john, smith, M, 1580'
    assert None   == 'john, smith, M, 1580'
    

    which raises AssertionError because None is only equal to None.

  • I change the return statement of john

     5def jane():
     6    return 'jane, doe, F, 1991'
     7
     8
     9# john = None
    10def john():
    11    # return None
    12    return 'john, smith, M, 1580'
    13
    14
    15def test_joe():
    

    the test passes.


REFACTOR: make it better


  • I remove the commented lines

     1def joe():
     2    return 'joe, blow, M, 1996'
     3
     4
     5def jane():
     6    return 'jane, doe, F, 1991'
     7
     8
     9def john():
    10    return 'john, smith, M, 1580'
    11
    12
    13def test_joe():
    14    assert joe() == 'joe, blow, M, 1996'
    15
    16
    17def test_jane():
    18    assert jane() == 'jane, doe, F, 1991'
    19
    20
    21def test_john():
    22    assert john() == 'john, smith, M, 1580'
    23
    24
    25# Exceptions seen
    
  • I add a git commit message in the other terminal

    git commit -am 'add test_john'
    

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


test_mary


RED: make it fail


I add another test function

16def test_john():
17    assert john() == 'john, smith, M, 1580'
18
19
20def test_mary():
21    assert mary() == 'mary, public, F, 2000'
22
23
24# Exceptions seen

the terminal is my friend, and shows NameError

NameError: name 'mary' is not defined

because there is no definition for mary, it is just a name.


GREEN: make it pass


  • I add a variable for mary and point it to None

     9def john():
    10    return 'john, smith, M, 1580'
    11
    12
    13mary = None
    14
    15
    16def test_joe():
    

    the terminal is my friend, and shows TypeError

    TypeError: 'NoneType' object is not callable
    

    because I called mary which points to None and I cannot call None like a function. Using substitution

    mary = None # point the name to the object
    mary()      # call the name
    None()      # substitute the value for the name
    

    None() raises TypeError.

  • I change mary to a function

     9def john():
    10    return 'john, smith, M, 1580'
    11
    12
    13# mary = None
    14def mary():
    15    return None
    16
    17
    18def test_joe():
    

    the terminal is my friend, and shows AssertionError

    AssertionError: assert None == 'mary, public, F, 2000'
    

    because when I call mary it returns None. Using substitution since I can treat a call to a function as the object it returns

    assert mary() == 'mary, public, F, 2000'
    assert None   == 'mary, public, F, 2000'
    

    which raises AssertionError because None is only equal to None.

  • I change the return statement of mary

     9def john():
    10    return 'john, smith, M, 1580'
    11
    12
    13# mary = None
    14def mary():
    15    # return None
    16    return 'mary, public, F, 2000'
    17
    18
    19def test_joe():
    

    the test passes.


REFACTOR: make it better


  • I remove the commented lines

     1def joe():
     2    return 'joe, blow, M, 1996'
     3
     4
     5def jane():
     6    return 'jane, doe, F, 1991'
     7
     8
     9def john():
    10    return 'john, smith, M, 1580'
    11
    12
    13def mary():
    14    return 'mary, public, F, 2000'
    15
    16
    17def test_joe():
    18    assert joe() == 'joe, blow, M, 1996'
    19
    20
    21def test_jane():
    22    assert jane() == 'jane, doe, F, 1991'
    23
    24
    25def test_john():
    26    assert john() == 'john, smith, M, 1580'
    27
    28
    29def test_mary():
    30    assert mary() == 'mary, public, F, 2000'
    31
    32
    33# Exceptions seen
    34# AssertionError
    35# NameError
    36# TypeError
    
  • I add a git commit message in the other terminal

    git commit -am 'add test_mary'
    

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


close the project

  • I close test_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 functions that return strings with information for people. There are a few problems with what I have so far

  • I made a function for each person. What happens if I have to make 10 or 100 or 1000 people? I am not ready to make 1000 functions.

  • Each test is basically a repetition of the information for each person.

I want something that will take in information for a person and return a representation for the person. That way I can use one thing to make as many people as I want. I can do that with functions that take input.


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.