Exercise: Away From Raw Dictionaries#
Requirement#
Up to the past two iterations (Exercise: Refactoring - Extract Both CSV Formats Into Module and Exercise: Convert User Record To JSON And Back), we have represented the Persons as raw dictionaries of the following form:
{
'id': 2, # int
'firstname': 'Jörg',
'lastname': 'Faschingbauer',
'birth': '19.6.1966',
}
Now that we know what classes are, and which benefits they bring (Classes And Dictionaries), lets
design a
class Person
re-implement all of the CSV stuff, by creating a parallel set of function that return
Person
objects instead of those dictionaries
Note
The lovely collections.namedtuple can be used to solve that problem.
Test Code#
The following tests cover the required class Person
changes.
import userdb_csv
def test_noheader_person(tmpdir):
with open(tmpdir/'noheader.csv', 'w', encoding='cp1252') as f:
f.writelines([
'1;"Jörg;DI";Faschingbauer;19.6.1966\n',
'2;Caro;Faschingbauer;25.4.1997\n',
'3;Johanna;Faschingbauer;11.6.1995\n',
'4;Philipp;Lichtenberger;6.4.1986\n',
'5;Elizabeth II;Queen;1.1.1900\n',
])
users = list(userdb_csv.read_noheader_person(tmpdir/'noheader.csv'))
assert type(users[0]) is userdb_csv.Person
assert users[0].id == 1
assert users[0].firstname == 'Jörg;DI'
assert users[0].lastname == 'Faschingbauer'
assert users[0].birth == '19.6.1966'
assert type(users[1]) is userdb_csv.Person
assert users[1].id == 2
assert users[1].firstname == 'Caro'
assert users[1].lastname == 'Faschingbauer'
assert users[1].birth == '25.4.1997'
assert type(users[2]) is userdb_csv.Person
assert users[2].id == 3
assert users[2].firstname == 'Johanna'
assert users[2].lastname == 'Faschingbauer'
assert users[2].birth == '11.6.1995'
assert type(users[3]) is userdb_csv.Person
assert users[3].id == 4
assert users[3].firstname == 'Philipp'
assert users[3].lastname == 'Lichtenberger'
assert users[3].birth == '6.4.1986'
assert type(users[4]) is userdb_csv.Person
assert users[4].id == 5
assert users[4].firstname == 'Elizabeth II'
assert users[4].lastname == 'Queen'
assert users[4].birth == '1.1.1900'
def test_must_not_use_global_variables_as_return_object(tmpdir):
filename1 = tmpdir/'noheader1.csv'
with open(filename1, 'w', encoding='cp1252') as f:
f.writelines([
'1;"Jörg;DI";Faschingbauer;19.6.1966\n',
'2;Caro;Faschingbauer;25.4.1997\n',
'3;Johanna;Faschingbauer;11.6.1995\n',
'4;Philipp;Lichtenberger;6.4.1986\n',
'5;Elizabeth II;Queen;1.1.1900\n',
])
filename2 = tmpdir/'noheader2.csv'
with open(filename2, 'w', encoding='cp1252') as f:
f.writelines([
'3;Johanna;Faschingbauer;11.6.1995\n',
'4;Philipp;Lichtenberger;6.4.1986\n',
'5;Elizabeth II;Queen;1.1.1900\n',
])
users1 = list(userdb_csv.read_noheader_person(filename1))
users2 = list(userdb_csv.read_noheader_person(filename2))
assert len(users1) == 5
assert len(users2) == 3
import userdb_csv
def test_header_person(tmpdir):
with open(tmpdir/'header.csv', 'w', encoding='cp1252') as f:
f.writelines([
'ID;First name;Last name;Date of Birth\n',
'1;"Jörg;DI";Faschingbauer;19.6.1966\n',
'2;Caro;Faschingbauer;25.4.1997\n',
'3;Johanna;Faschingbauer;11.6.1995\n',
'4;Philipp;Lichtenberger;6.4.1986\n',
'5;Elizabeth II;Queen;1.1.1900\n',
])
users = list(userdb_csv.read_header_person(tmpdir/'header.csv'))
assert type(users[0]) is userdb_csv.Person
assert users[0].id == 1
assert users[0].firstname == 'Jörg;DI'
assert users[0].lastname == 'Faschingbauer'
assert users[0].birth == '19.6.1966'
assert type(users[1]) is userdb_csv.Person
assert users[1].id == 2
assert users[1].firstname == 'Caro'
assert users[1].lastname == 'Faschingbauer'
assert users[1].birth == '25.4.1997'
assert type(users[2]) is userdb_csv.Person
assert users[2].id == 3
assert users[2].firstname == 'Johanna'
assert users[2].lastname == 'Faschingbauer'
assert users[2].birth == '11.6.1995'
assert type(users[3]) is userdb_csv.Person
assert users[3].id == 4
assert users[3].firstname == 'Philipp'
assert users[3].lastname == 'Lichtenberger'
assert users[3].birth == '6.4.1986'
assert type(users[4]) is userdb_csv.Person
assert users[4].id == 5
assert users[4].firstname == 'Elizabeth II'
assert users[4].lastname == 'Queen'
assert users[4].birth == '1.1.1900'
def test_must_not_use_global_variables_as_return_object(tmpdir):
filename1 = tmpdir/'noheader1.csv'
with open(filename1, 'w', encoding='cp1252') as f:
f.writelines([
'1;"Jörg;DI";Faschingbauer;19.6.1966\n',
'2;Caro;Faschingbauer;25.4.1997\n',
'3;Johanna;Faschingbauer;11.6.1995\n',
'4;Philipp;Lichtenberger;6.4.1986\n',
'5;Elizabeth II;Queen;1.1.1900\n',
])
filename2 = tmpdir/'noheader2.csv'
with open(filename2, 'w', encoding='cp1252') as f:
f.writelines([
'3;Johanna;Faschingbauer;11.6.1995\n',
'4;Philipp;Lichtenberger;6.4.1986\n',
'5;Elizabeth II;Queen;1.1.1900\n',
])
users1 = list(userdb_csv.read_noheader_person(filename1))
users2 = list(userdb_csv.read_noheader_person(filename2))
assert len(users1) == 5
assert len(users2) == 3
from userdb_csv import Person
import userdb_json
def test_person_to_json():
joerg = Person(
id=1,
firstname='Jörg',
lastname='Faschingbauer',
birth='19.6.1966',
)
joerg_sent = userdb_json.to_json_person(joerg)
joerg_received = userdb_json.from_json_person(joerg_sent)
assert joerg_received.id == 1
assert joerg_received.firstname == 'Jörg'
assert joerg_received.lastname == 'Faschingbauer'
assert joerg_received.birth == '19.6.1966'