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'