3.1. Serialization CSV¶
3.1.1. Rationale¶
CSV - Comma Separated Values
CSV - Character Separated Values
CSV file with numeric values.:
5.4,3.9,1.3,0.4,0
5.9,3.0,5.1,1.8,1
6.0,3.4,4.5,1.6,2
CSV file with text values. First line is a header.:
"First Name", "Last Name"
"Mark", "Watney"
"Jan", "Twardowski"
"Melissa", "Lewis"
"Alex", "Vogel"
CSV file with mixed values (numeric and strings). First line is a header.:
sepal_length,sepal_width,petal_length,petal_width,species
5.4,3.9,1.3,0.4,setosa
5.9,3.0,5.1,1.8,virginica
6.0,3.4,4.5,1.6,versicolor
7.3,2.9,6.3,1.8,virginica
5.6,2.5,3.9,1.1,versicolor
5.4,3.9,1.3,0.4,setosa
3.1.2. Encoding¶
utf-8
- international standard (should be always used!)iso-8859-1
- ISO standard for Western Europe and USAiso-8859-2
- ISO standard for Central Europe (including Poland)cp1250
orwindows-1250
- Polish encoding on Windowscp1251
orwindows-1251
- Russian encoding on Windowscp1252
orwindows-1252
- Western European encoding on WindowsASCII
- ASCII characters only
with open(FILE, encoding='utf-8') as file:
...
3.1.3. Quoting¶
csv.QUOTE_ALL
(safest)csv.QUOTE_MINIMAL
csv.QUOTE_NONE
csv.QUOTE_NONNUMERIC
quoting=csv.QUOTE_ALL
:
"Sepal length","Sepal width","Petal length","Petal width","Species"
"5.8","2.7","5.1","1.9","virginica"
"5.1","3.5","1.4","0.2","setosa"
"5.7","2.8","4.1","1.3","versicolor"
quoting=csv.QUOTE_MINIMAL
:
Sepal length,Sepal width,Petal length,Petal width,Species
5.8,2.7,5.1,1.9,virginica
5.1,3.5,1.4,0.2,setosa
5.7,2.8,4.1,1.3,versicolor
quoting=csv.QUOTE_NONE
:
Sepal length,Sepal width,Petal length,Petal width,Species
5.8,2.7,5.1,1.9,virginica
5.1,3.5,1.4,0.2,setosa
5.7,2.8,4.1,1.3,versicolor
quoting=csv.QUOTE_NONNUMERIC
:
"Sepal length","Sepal width","Petal length","Petal width","Species"
5.8,2.7,5.1,1.9,"virginica"
5.1,3.5,1.4,0.2,"setosa"
5.7,2.8,4.1,1.3,"versicolor"
3.1.4. Quotechar¶
"
- quote char (best)'
- apostrophe
quotechar='"'
:
"Sepal length","Sepal width","Petal length","Petal width","Species"
"5.8","2.7","5.1","1.9","virginica"
"5.1","3.5","1.4","0.2","setosa"
"5.7","2.8","4.1","1.3","versicolor"
quotechar="'"
:
'Sepal length','Sepal width','Petal length','Petal width','Species'
'5.8','2.7','5.1','1.9','virginica'
'5.1','3.5','1.4','0.2','setosa'
'5.7','2.8','4.1','1.3','versicolor'
quotechar='|'
:
|Sepal length|,|Sepal width|,|Petal length|,|Petal width|,|Species|
|5.8|,|2.7|,|5.1|,|1.9|,|virginica|
|5.1|,|3.5|,|1.4|,|0.2|,|setosa|
|5.7|,|2.8|,|4.1|,|1.3|,|versicolor|
quotechar='/'
:
/Sepal length/,/Sepal width/,/Petal length/,/Petal width/,/Species/
/5.8/,/2.7/,/5.1/,/1.9/,/virginica/
/5.1/,/3.5/,/1.4/,/0.2/,/setosa/
/5.7/,/2.8/,/4.1/,/1.3/,/versicolor/
3.1.5. Delimiter¶
delimiter=','
:
Sepal length,Sepal width,Petal length,Petal width,Species
5.8,2.7,5.1,1.9,virginica
5.1,3.5,1.4,0.2,setosa
5.7,2.8,4.1,1.3,versicolor
delimiter=';'
:
Sepal length;Sepal width;Petal length;Petal width;Species
5.8;2.7;5.1;1.9;virginica
5.1;3.5;1.4;0.2;setosa
5.7;2.8;4.1;1.3;versicolor
delimiter='|'
:
Sepal length|Sepal width|Petal length|Petal width|Species
5.8|2.7|5.1|1.9|virginica
5.1|3.5|1.4|0.2|setosa
5.7|2.8|4.1|1.3|versicolor
delimiter='\t'
:
Sepal length Sepal width Petal length Petal width Species
5.8 2.7 5.1 1.9 virginica
5.1 3.5 1.4 0.2 setosa
5.7 2.8 4.1 1.3 versicolor
3.1.6. Lineterminator¶
\r\n
- New line on Windows\n
- New line on*nix
*nix
operating systems: Linux, macOS, BSD and other POSIX compliant OSes (excluding Windows)
3.1.7. Dialects¶
1,2 and 2,5 -> 1,2;2,5 # delimiter=';'
1.2 and 2.5 -> 1.2,2.5 # delimiter=','
1,2;2,5 -> 1 and 2; and 2 and 5 # delimiter=','
1,2 -> 1,2;2,5 # delimiter=';'
1.2,2.5 -> 1.2 and 2.5 # delimiter=','
import csv
csv.list_dialects()
# ['excel', 'excel-tab', 'unix']
Microsoft Excel 2016 uses:
quotechar='"'
delimiter=','
lineterminator='\n'
encoding='...'
- depends on Windows version and settings typicallywindows-*
3.1.8. Reader Object¶
Read data from CSV file using csv.reader()
:
import csv
FILE = r'_temporary.csv'
# sepal_length,sepal_width,petal_length,petal_width,species
# 5.4,3.9,1.3,0.4,setosa
# 5.9,3.0,5.1,1.8,virginica
# 6.0,3.4,4.5,1.6,versicolor
with open(FILE) as file:
result = csv.reader(file)
for line in result:
print(line)
# ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species']
# ['5.4', '3.9', '1.3', '0.4', 'setosa']
# ['5.9', '3.0', '5.1', '1.8', 'virginica']
# ['6.0', '3.4', '4.5', '1.6', 'versicolor']
3.1.9. Writer Object¶
Writing data to CSV file using csv.writer()
:
import csv
FILE = r'_temporary.csv'
DATA = [('Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species'),
(5.8, 2.7, 5.1, 1.9, 'virginica'),
(5.1, 3.5, 1.4, 0.2, 'setosa'),
(5.7, 2.8, 4.1, 1.3, 'versicolor')]
with open(FILE, mode='w') as file:
result = csv.writer(file)
result.writerows(DATA)
# Sepal length,Sepal width,Petal length,Petal width,Species
# 5.8,2.7,5.1,1.9,virginica
# 5.1,3.5,1.4,0.2,setosa
# 5.7,2.8,4.1,1.3,versicolor
3.1.10. DictReader¶
Read data from CSV file using csv.DictReader()
:
import csv
FILE = r'_temporary.csv'
# sepal_length,sepal_width,petal_length,petal_width,species
# 5.4,3.9,1.3,0.4,setosa
# 5.9,3.0,5.1,1.8,virginica
# 6.0,3.4,4.5,1.6,versicolor
with open(FILE) as file:
result = csv.DictReader(file)
for line in result:
print(line)
# {'sepal_length': '5.4', 'sepal_width': '3.9', 'petal_length': '1.3', 'petal_width': '0.4', 'species': 'setosa'}
# {'sepal_length': '5.9', 'sepal_width': '3.0', 'petal_length': '5.1', 'petal_width': '1.8', 'species': 'virginica'}
# {'sepal_length': '6.0', 'sepal_width': '3.4', 'petal_length': '4.5', 'petal_width': '1.6', 'species': 'versicolor'}
Read data from CSV file using csv.DictReader()
:
import csv
FILE = r'_temporary.csv'
# 'sepal_length';'sepal_width';'petal_length';'petal_width';'species'
# '5,4';'3,9';'1,3';'0,4';'setosa'
# '5,9';'3,0';'5,1';'1,8';'virginica'
# '6,0';'3,4';'4,5';'1,6';'versicolor'
def isnumeric(value):
try:
float(value)
return True
except ValueError:
return False
def clean(line):
return {key: float(v) if isnumeric(v) else v
for key, value in line.items()
if (v := value.replace(',', '.'))}
with open(FILE) as file:
result = csv.DictReader(file, delimiter=';', quotechar="'")
for line in result:
print(clean(line))
# {'sepal_length': 5.4, 'sepal_width': 3.9, 'petal_length': 1.3, 'petal_width': 0.4, 'species': 'setosa'}
# {'sepal_length': 5.9, 'sepal_width': 3.0, 'petal_length': 5.1, 'petal_width': 1.8, 'species': 'virginica'}
# {'sepal_length': 6.0, 'sepal_width': 3.4, 'petal_length': 4.5, 'petal_width': 1.6, 'species': 'versicolor'}
Read data from CSV file using csv.DictReader()
. While giving custom names note, that first line (typically a header) will be treated like normal data. Therefore we skip it using header = file.readline()
:
import csv
FILE = r'_temporary.csv'
# sepal_length,sepal_width,petal_length,petal_width,species
# 5.4,3.9,1.3,0.4,setosa
# 5.9,3.0,5.1,1.8,virginica
# 6.0,3.4,4.5,1.6,versicolor
FIELDNAMES = [
'Sepal Length',
'Sepal Width',
'Petal Length',
'Petal Width',
'Species',
]
with open(FILE) as file:
result = csv.DictReader(file, fieldnames=FIELDNAMES, delimiter=',')
file.readline() # skip first line
for line in result:
print(line)
# {'Sepal Length': '5.4', 'Sepal Width': '3.9', 'Petal Length': '1.3', 'Petal Width': '0.4', 'Species': 'setosa'}
# {'Sepal Length': '5.9', 'Sepal Width': '3.0', 'Petal Length': '5.1', 'Petal Width': '1.8', 'Species': 'virginica'}
# {'Sepal Length': '6.0', 'Sepal Width': '3.4', 'Petal Length': '4.5', 'Petal Width': '1.6', 'Species': 'versicolor'}
3.1.11. DictWriter¶
Remember to add
mode='w'
toopen()
functionDefault encoding is
encoding='utf-8'
import csv
FILE = r'_temporary.csv'
DATA = [{'Sepal Length': 5.4, 'Sepal Width': 3.9, 'Petal Length': 1.3, 'Petal Width': 0.4, 'Species': 'setosa'},
{'Sepal Length': 5.9, 'Sepal Width': 3.0, 'Petal Length': 5.1, 'Petal Width': 1.8, 'Species': 'virginica'},
{'Sepal Length': 6.0, 'Sepal Width': 3.4, 'Petal Length': 4.5, 'Petal Width': 1.6, 'Species': 'versicolor'}]
header = DATA[0].keys()
with open(FILE, mode='w') as file:
result = csv.DictWriter(file, fieldnames=header)
result.writeheader()
result.writerows(DATA)
# Sepal Length,Sepal Width,Petal Length,Petal Width,Species
# 5.4,3.9,1.3,0.4,setosa
# 5.9,3.0,5.1,1.8,virginica
# 6.0,3.4,4.5,1.6,versicolor
Write data to CSV file using csv.DictWriter()
:
import csv
FILE = r'_temporary.csv'
DATA = [{'sepal_length': 5.4, 'sepal_width': 3.9, 'petal_length': 1.3, 'petal_width': 0.4, 'species': 'setosa'},
{'sepal_length': 5.9, 'sepal_width': 3.0, 'petal_length': 5.1, 'petal_width': 1.8, 'species': 'virginica'},
{'sepal_length': 6.0, 'sepal_width': 3.4, 'petal_length': 4.5, 'petal_width': 1.6, 'species': 'versicolor'}]
FIELDNAMES = ['sepal_length', 'sepal_width', 'petal_length',
'petal_width', 'species']
with open(FILE, mode='w', encoding='utf-8') as file:
result = csv.DictWriter(
f=file,
fieldnames=FIELDNAMES,
delimiter=',',
quotechar='"',
quoting=csv.QUOTE_ALL,
lineterminator='\n')
result.writeheader()
result.writerows(DATA)
# "sepal_length","sepal_width","petal_length","petal_width","species"
# "5.4","3.9","1.3","0.4","setosa"
# "5.9","3.0","5.1","1.8","virginica"
# "6.0","3.4","4.5","1.6","versicolor"
3.1.12. Parsing Non-CSV Files¶
Parsing /etc/passwd
file with csv.DictReader()
:
import csv
FILE = r'_temporary.txt'
# root:x:0:0:root:/root:/bin/bash
# watney:x:1000:1000:Mark Watney:/home/watney:/bin/bash
# lewis:x:1001:1001:José Jiménez:/home/lewis:/bin/bash
# twardowski:x:1002:1002:Jan Twardowski:/home/twardowski:/bin/bash
with open(FILE) as file:
result = csv.DictReader(
file,
fieldnames=['username', 'password', 'uid', 'gid', 'fullname', 'home', 'shell'],
delimiter=':',
lineterminator='\n',
quoting=csv.QUOTE_NONE)
for line in result:
print(line)
# {'username': 'root', 'password': 'x', 'uid': '0',...}
# {'username': 'watney', 'password': 'x', 'uid': '1000',...}
# {'username': 'lewis', 'password': 'x', 'uid': '1001',...}
# {'username': 'twardowski', 'password': 'x', 'uid': '1002',...}
Parsing Java properties file with csv.DictReader()
:
import csv
FILE = r'_temporary.properties'
# sonar.projectKey=habitatOS
# sonar.projectName=habitatOS
# sonar.language=py
# sonar.sourceEncoding=UTF-8
# sonar.verbose=true
with open(FILE) as file:
result = csv.DictReader(
file,
fieldnames=['property', 'value'],
delimiter='=',
lineterminator='\n',
quoting=csv.QUOTE_NONE)
for line in result:
print(line)
# {'property': 'sonar.projectKey', 'value': 'habitatOS'}
# {'property': 'sonar.projectName', 'value': 'habitatOS'}
# {'property': 'sonar.language', 'value': 'py'}
# {'property': 'sonar.sourceEncoding', 'value': 'UTF-8'}
# {'property': 'sonar.verbose', 'value': 'true'}
3.1.13. Use Cases¶
import csv
FILE = r'_temporary.csv'
total = 0
count = 0
with open(FILE) as file:
data = csv.reader(file)
next(data)
for line in data:
total += float(line[1])
count += 1
mean = total / count
print(mean)
3.1.14. Serialization¶

Figure 3.1. Relational files or database dump¶

Figure 3.2. Ffill - Forward fill¶

Figure 3.3. Fill in specified columns¶

Figure 3.4. Data duplication with unique ID¶

Figure 3.5. Each relations attribute adds one column¶

Figure 3.6. Each relations instance adds one column¶

Figure 3.7. Each relations class adds one column¶

Figure 3.8. Relations attributes split into columns¶

Figure 3.9. Hybrid compact and separate columns¶
3.1.15. Good Practices¶
Always specify:
delimiter=','
tocsv.DictReader()
objectquotechar='"'
tocsv.DictReader()
objectquoting=csv.QUOTE_ALL
tocsv.DictReader()
objectlineterminator='\n'
tocsv.DictReader()
objectencoding='utf-8'
toopen()
function (especially when working with Microsoft Excel)
3.1.16. Assignments¶
"""
* Assignment: Serialization CSV DictReader
* Complexity: easy
* Lines of code: 9 lines
* Time: 8 min
English:
1. Use data from "Given" section (see below)
2. Using `csv.DictReader` read the `FILE` content
3. Use explicit `encoding`, `delimiter` and `quotechar`
4. Replace column names to `FIELDNAMES`
5. Skip the first line (header)
6. Print rows with data
7. Compare result with "Tests" section (see below)
Polish:
1. Użyj danych z sekcji "Given" (patrz poniżej)
2. Korzystając z `csv.DictReader` wczytaj zawartość pliku `FILE`
3. Podaj jawnie `encoding`, `delimiter` oraz `quotechar`
4. Podmień nazwy kolumn na `FIELDNAMES`
5. Pomiń pierwszą linię (nagłówek)
6. Wypisz wiersze z danymi
7. Porównaj wyniki z sekcją "Tests" (patrz poniżej)
Tests:
>>> type(result)
<class 'list'>
>>> result # doctest: +NORMALIZE_WHITESPACE
[{'Sepal Length': '5.8', 'Sepal Width': '2.7', 'Petal Length': '5.1', 'Petal Width': '1.9', 'Species': 'virginica'},
{'Sepal Length': '5.1', 'Sepal Width': '3.5', 'Petal Length': '1.4', 'Petal Width': '0.2', 'Species': 'setosa'},
{'Sepal Length': '5.7', 'Sepal Width': '2.8', 'Petal Length': '4.1', 'Petal Width': '1.3', 'Species': 'versicolor'}]
>>> from os import remove
>>> remove(FILE)
"""
# Given
from csv import DictReader, QUOTE_NONE
FILE = r'_temporary.csv'
FIELDNAMES = ['Sepal Length', 'Sepal Width',
'Petal Length', 'Petal Width', 'Species']
DATA = """sepal_length,sepal_width,petal_length,petal_width,species
5.8,2.7,5.1,1.9,virginica
5.1,3.5,1.4,0.2,setosa
5.7,2.8,4.1,1.3,versicolor"""
with open(FILE, mode='w') as file:
file.write(DATA)
result: list
"""
* Assignment: Serialization CSV DictWriter
* Complexity: easy
* Lines of code: 10 lines
* Time: 8 min
English:
1. Use data from "Given" section (see below)
2. Using `csv.DictWriter()` save `DATA` to file
3. Open file in your spreadsheet program like Microsoft Excel / Libre Office / Numbers etc.
4. Open file in simple in your IDE and simple text editor (like Notepad, vim, gedit)
5. Non functional requirements:
a. All fields must be enclosed by double quote `"` character
b. Use `,` to separate columns
c. Use `utf-8` encoding
d. Use Unix `\n` newline
6. Compare result with "Tests" section (see below)
Polish:
1. Użyj danych z sekcji "Given" (patrz poniżej)
2. Za pomocą `csv.DictWriter()` zapisz `DATA` do pliku
3. Spróbuj otworzyć plik w arkuszu kalkulacyjnym tj. Microsoft Excel / Libre Office / Numbers itp
4. Spróbuj otworzyć plik w IDE i prostym edytorze tekstu tj. Notepad, vim lub gedit
5. Wymagania niefunkcjonalne:
a. Wszystkie pola muszą być otoczone znakiem cudzysłowu `"`
b. Użyj `,` do oddzielenia kolumn
c. Użyj kodowania `utf-8`
d. Użyj zakończenia linii Unix `\n`
6. Porównaj wyniki z sekcją "Tests" (patrz poniżej)
Tests:
>>> result = open(FILE).read()
>>> print(result) # doctest: +NORMALIZE_WHITESPACE
"firstname","lastname"
"Jan","Twardowski"
"José","Jiménez"
"Mark","Watney"
"Ivan","Ivanovic"
"Melissa","Lewis"
>>> from os import remove
>>> remove(FILE)
"""
# Given
from csv import DictWriter, QUOTE_ALL
FILE = r'_temporary.csv'
DATA = [{'firstname': 'Jan', 'lastname': 'Twardowski'},
{'firstname': 'José', 'lastname': 'Jiménez'},
{'firstname': 'Mark', 'lastname': 'Watney'},
{'firstname': 'Ivan', 'lastname': 'Ivanovic'},
{'firstname': 'Melissa', 'lastname': 'Lewis'}]
"""
* Assignment: Serialization CSV List of Tuples
* Complexity: easy
* Lines of code: 6 lines
* Time: 8 min
English:
1. Use data from "Given" section (see below)
2. Convert `DATA` to `list[dict]`
3. Using `csv.DictWriter()` save `DATA` to file
4. Non functional requirements:
a. Do not use quotes in output CSV file
b. Use `,` to separate columns
c. Use `utf-8` encoding
d. Use Unix `\n` newline
5. Compare result with "Tests" section (see below)
Polish:
1. Użyj danych z sekcji "Given" (patrz poniżej)
2. Przekonwertuj `DATA` do `list[dict]`
3. Za pomocą `csv.DictWriter()` zapisz `DATA` do pliku
4. Wymagania niefunkcjonalne:
a. Nie używaj cudzysłowów w wynikowym pliku CSV
b. Użyj `,` do oddzielenia kolumn
c. Użyj kodowania `utf-8`
d. Użyj zakończenia linii Unix `\n`
5. Porównaj wyniki z sekcją "Tests" (patrz poniżej)
Tests:
>>> result = open(FILE).read()
>>> print(result)
Sepal length,Sepal width,Petal length,Petal width,Species
5.8,2.7,5.1,1.9,virginica
5.1,3.5,1.4,0.2,setosa
5.7,2.8,4.1,1.3,versicolor
6.3,2.9,5.6,1.8,virginica
6.4,3.2,4.5,1.5,versicolor
4.7,3.2,1.3,0.2,setosa
7.0,3.2,4.7,1.4,versicolor
7.6,3.0,6.6,2.1,virginica
4.9,3.0,1.4,0.2,setosa
<BLANKLINE>
>>> from os import remove
>>> remove(FILE)
"""
# Given
import csv
FILE = r'_temporary.csv'
DATA = [('Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species'),
(5.8, 2.7, 5.1, 1.9, 'virginica'),
(5.1, 3.5, 1.4, 0.2, 'setosa'),
(5.7, 2.8, 4.1, 1.3, 'versicolor'),
(6.3, 2.9, 5.6, 1.8, 'virginica'),
(6.4, 3.2, 4.5, 1.5, 'versicolor'),
(4.7, 3.2, 1.3, 0.2, 'setosa'),
(7.0, 3.2, 4.7, 1.4, 'versicolor'),
(7.6, 3.0, 6.6, 2.1, 'virginica'),
(4.9, 3.0, 1.4, 0.2, 'setosa'),]
"""
* Assignment: Serialization CSV Schemaless
* Complexity: medium
* Lines of code: 7 lines
* Time: 8 min
English:
1. Use data from "Given" section (see below)
2. Using `csv.DictWriter()` write variable schema data to CSV file
3. `fieldnames` must be automatically generated from `DATA`
4. `fieldnames` must always be in the same order
5. Non functional requirements:
a. All fields must be enclosed by double quote `"` character
b. Use `;` to separate columns
c. Use `utf-8` encoding
d. Use Unix `\n` newline
6. Compare result with "Tests" section (see below)
Polish:
1. Użyj danych z sekcji "Given" (patrz poniżej)
2. Za pomocą `csv.DictWriter()` zapisz do pliku CSV dane o zmiennej strukturze
3. `fieldnames` musi być generowane automatycznie na podstawie `DATA`
4. `fieldnames` ma być zawsze w takiej samej kolejności
5. Wymagania niefunkcjonalne:
a. Wszystkie pola muszą być otoczone znakiem cudzysłowu `"`
b. Użyj `,` do oddzielenia kolumn
c. Użyj kodowania `utf-8`
d. Użyj zakończenia linii Unix `\n`
6. Porównaj wyniki z sekcją "Tests" (patrz poniżej)
Tests:
>>> result = open(FILE).read()
>>> print(result)
"Petal length","Petal width","Sepal length","Sepal width","Species"
"","","5.1","3.5","setosa"
"4.1","1.3","","","versicolor"
"","1.8","6.3","","virginica"
"","0.2","5.0","","setosa"
"4.1","","","2.8","versicolor"
"","1.8","","2.9","virginica"
<BLANKLINE>
>>> from os import remove
>>> remove(FILE)
"""
# Given
from csv import DictWriter, QUOTE_ALL
FILE = r'_temporary.csv'
DATA = [{'Sepal length': 5.1, 'Sepal width': 3.5, 'Species': 'setosa'},
{'Petal length': 4.1, 'Petal width': 1.3, 'Species': 'versicolor'},
{'Sepal length': 6.3, 'Petal width': 1.8, 'Species': 'virginica'},
{'Sepal length': 5.0, 'Petal width': 0.2, 'Species': 'setosa'},
{'Sepal width': 2.8, 'Petal length': 4.1, 'Species': 'versicolor'},
{'Sepal width': 2.9, 'Petal width': 1.8, 'Species': 'virginica'}]
"""
* Assignment: Serialization CSV Objects
* Complexity: medium
* Lines of code: 6 lines
* Time: 8 min
English:
1. Use data from "Given" section (see below)
2. Using `csv.DictWriter()` save data to CSV file
3. Non functional requirements:
a. All fields must be enclosed by double quote `"` character
b. Use `,` to separate columns
c. Use `utf-8` encoding
d. Use Unix `\n` newline
4. Compare result with "Tests" section (see below)
Polish:
1. Użyj danych z sekcji "Given" (patrz poniżej)
2. Za pomocą `csv.DictWriter()` zapisz dane do pliku CSV
3. Wymagania niefunkcjonalne:
a. Wszystkie pola muszą być otoczone znakiem cudzysłowu `"`
b. Użyj `,` do oddzielenia kolumn
c. Użyj kodowania `utf-8`
d. Użyj zakończenia linii Unix `\n`
4. Porównaj wyniki z sekcją "Tests" (patrz poniżej)
Hints:
* `obj.__dict__`
Tests:
>>> result = open(FILE).read()
>>> print(result)
sepal_length,sepal_width,petal_length,petal_width,species
5.1,3.5,1.4,0.2,setosa
5.8,2.7,5.1,1.9,virginica
5.1,3.5,1.4,0.2,setosa
5.7,2.8,4.1,1.3,versicolor
6.3,2.9,5.6,1.8,virginica
6.4,3.2,4.5,1.5,versicolor
<BLANKLINE>
>>> from os import remove
>>> remove(FILE)
"""
# Given
import csv
class Iris:
def __init__(self, sepal_length, sepal_width,
petal_length, petal_width, species):
self.sepal_length = sepal_length
self.sepal_width = sepal_width
self.petal_length = petal_length
self.petal_width = petal_width
self.species = species
FILE = r'_temporary.txt'
DATA = [Iris(5.1, 3.5, 1.4, 0.2, 'setosa'),
Iris(5.8, 2.7, 5.1, 1.9, 'virginica'),
Iris(5.1, 3.5, 1.4, 0.2, 'setosa'),
Iris(5.7, 2.8, 4.1, 1.3, 'versicolor'),
Iris(6.3, 2.9, 5.6, 1.8, 'virginica'),
Iris(6.4, 3.2, 4.5, 1.5, 'versicolor')]
"""
* Assignment: Serialization CSV Relations
* Complexity: hard
* Lines of code: 13 lines
* Time: 21 min
English:
1. Use data from "Given" section (see below)
2. Using `csv.DictWriter()` save contacts from addressbook to CSV file
3. How to write relations to CSV file (contact has many addresses)?
4. Recreate object structure from CSV file
5. Non functional requirements:
a. All fields must be enclosed by double quote `"` character
b. Use `,` to separate mission fields
c. Use `;` to separate missions
d. Use Unix `\n` newline
e. Sort fieldnames
6. Compare result with "Tests" section (see below)
Polish:
1. Użyj danych z sekcji "Given" (patrz poniżej)
2. Za pomocą `csv.DictWriter()` zapisz kontakty z książki adresowej w pliku
3. Jak zapisać w CSV dane relacyjne (kontakt ma wiele adresów)?
4. Odtwórz strukturę obiektów na podstawie danych odczytanych z pliku
5. Wymagania niefunkcjonalne:
a. Wszystkie pola muszą być otoczone znakiem cudzysłowu `"`
b. Użyj `,` do oddzielania pól mission
c. Użyj `;` do oddzielenia missions
d. Użyj zakończenia linii Unix `\n`
e. Posortuj fieldnames
6. Porównaj wyniki z sekcją "Tests" (patrz poniżej)
Tests:
>>> result = open(FILE).read()
>>> print(result)
"lastname","missions","name"
"Twardowski","1969,Apollo 11; 2024,Artemis 3","Jan"
"Watney","2035,Ares 3","Mark"
"Lewis","","Melissa"
<BLANKLINE>
>>> from os import remove
>>> remove(FILE)
"""
# Given
import csv
FILE = r'_temporary.csv'
class Astronaut:
def __init__(self, firstname, lastname, missions=None):
self.name = firstname
self.lastname = lastname
self.missions = list(missions) if missions else []
class Mission:
def __init__(self, year, name):
self.year = year
self.name = name
CREW = [
Astronaut('Jan', 'Twardowski', missions=[
Mission(1969, 'Apollo 11'),
Mission(2024, 'Artemis 3')]),
Astronaut('Mark', 'Watney', missions=[
Mission(2035, 'Ares 3')]),
Astronaut('Melissa', 'Lewis'),
]
result: list