Read or watch:
- 7.2. Reading and Writing Files
- 8.7. Predefined Clean-up Actions
- Dive Into Python 3: Chapter 11. Files (until “11.4 Binary Files” (included))
- JSON encoder and decoder
- Learn to Program 8 : Reading / Writing Files
- Automate the Boring Stuff with Python (ch. 8 p 180-183 and ch. 14 p 326-333)
- All about py-file I/O
- Allowed editors:
vi
,vim
,emacs
- All your files will be interpreted/compiled on Ubuntu 20.04 LTS using python3 (version 3.8.5)
- All your files should end with a new line
- The first line of all your files should be exactly
#!/usr/bin/python3
- A
README.md
file, at the root of the folder of the project, is mandatory - Your code should use the pycodestyle (version
2.8.*
) - All your files must be executable
- The length of your files will be tested using
wc
- Allowed editors:
vi
,vim
,emacs
- All your files should end with a new line
- All your test files should be inside a folder
tests
- All your test files should be text files (extension:
.txt
) - All your tests should be executed by using this command:
python3 -m doctest ./tests/*
- All your modules should have a documentation (
python3 -c 'print(__import__("my_module").__doc__)'
) - All your classes should have a documentation (
python3 -c 'print(__import__("my_module").MyClass.__doc__)'
) - All your functions (inside and outside a class) should have a documentation (
python3 -c 'print(__import__("my_module").my_function.__doc__)
' andpython3 -c 'print(__import__("my_module").MyClass.my_function.__doc__)'
) - A documentation is not a simple word, it’s a real sentence explaining what’s the purpose of the module, class or method (the length of it will be verified)
- We strongly encourage you to work together on test cases, so that you don’t miss any edge case
Write a function that reads a text file (UTF8
) and prints it to stdout:
- Prototype:
def read_file(filename=""):
- You must use the
with
statement - You don’t need to manage
file permission
orfile doesn't exist
exceptions. - You are not allowed to import any module
guillaume@ubuntu:~/0x0B$ cat 0-main.py
#!/usr/bin/python3
read_file = __import__('0-read_file').read_file
read_file("my_file_0.txt")
guillaume@ubuntu:~/0x0B$ cat my_file_0.txt
We offer a truly innovative approach to education:
focus on building reliable applications and scalable systems, take on real-world challenges, collaborate with your peers.
A school every software engineer would have dreamt of!
guillaume@ubuntu:~/0x0B$ ./0-main.py
We offer a truly innovative approach to education:
focus on building reliable applications and scalable systems, take on real-world challenges, collaborate with your peers.
A school every software engineer would have dreamt of!
guillaume@ubuntu:~/0x0B$
No test cases needed
Write a function that writes a string to a text file (UTF8
) and returns the number of characters written:
- Prototype:
def write_file(filename="", text=""):
- You must use the
with
statement - You don’t need to manage
file permission
exceptions. - Your function should create the file if doesn’t exist.
- Your function should overwrite the content of the file if it already exists.
- You are not allowed to import any module
guillaume@ubuntu:~/0x0B$ cat 1-main.py
#!/usr/bin/python3
write_file = __import__('1-write_file').write_file
nb_characters = write_file("my_first_file.txt", "This School is so cool!\n")
print(nb_characters)
guillaume@ubuntu:~/0x0B$ ./1-main.py
29
guillaume@ubuntu:~/0x0B$ cat my_first_file.txt
This School is so cool!
guillaume@ubuntu:~/0x0B$
No test cases needed
Write a function that appends a string at the end of a text file (UTF8
) and returns the number of characters added:
- Prototype:
def append_write(filename="", text=""):
- If the file doesn’t exist, it should be created
- You must use the
with
statement - You don’t need to manage
file permission
orfile doesn't exist
exceptions. - You are not allowed to import any module
guillaume@ubuntu:~/0x0B$ cat 2-main.py
#!/usr/bin/python3
append_write = __import__('2-append_write').append_write
nb_characters_added = append_write("file_append.txt", "This School is so cool!\n")
print(nb_characters_added)
guillaume@ubuntu:~/0x0B$ cat file_append.txt
cat: file_append.txt: No such file or directory
guillaume@ubuntu:~/0x0B$ ./2-main.py
29
guillaume@ubuntu:~/0x0B$ cat file_append.txt
This School is so cool!
guillaume@ubuntu:~/0x0B$ ./2-main.py
29
guillaume@ubuntu:~/0x0B$ cat file_append.txt
This School is so cool!
This School is so cool!
guillaume@ubuntu:~/0x0B$
No test cases needed
Write a function that returns the JSON
representation of an object (string):
- Prototype:
def to_json_string(my_obj):
- You don’t need to manage exceptions if the object can’t be serialized.
guillaume@ubuntu:~/0x0B$ cat 3-main.py
#!/usr/bin/python3
to_json_string = __import__('3-to_json_string').to_json_string
my_list = [1, 2, 3]
s_my_list = to_json_string(my_list)
print(s_my_list)
print(type(s_my_list))
my_dict = {
'id': 12,
'name': "John",
'places': [ "San Francisco", "Tokyo" ],
'is_active': True,
'info': {
'age': 36,
'average': 3.14
}
}
s_my_dict = to_json_string(my_dict)
print(s_my_dict)
print(type(s_my_dict))
try:
my_set = { 132, 3 }
s_my_set = to_json_string(my_set)
print(s_my_set)
print(type(s_my_set))
except Exception as e:
print("[{}] {}".format(e.__class__.__name__, e))
guillaume@ubuntu:~/0x0B$ ./3-main.py
[1, 2, 3]
<class 'str'>
{"id": 12, "is_active": true, "name": "John", "info": {"average": 3.14, "age": 36}, "places": ["San Francisco", "Tokyo"]}
<class 'str'>
[TypeError] {3, 132} is not JSON serializable
guillaume@ubuntu:~/0x0B$
No test cases needed
Write a function that returns an object (Python data structure) represented by a JSON
string:
- Prototype:
def from_json_string(my_str):
- You don’t need to manage exceptions if the
JSON
string doesn’t represent an object.
guillaume@ubuntu:~/0x0B$ cat 4-main.py
#!/usr/bin/python3
from_json_string = __import__('4-from_json_string').from_json_string
s_my_list = "[1, 2, 3]"
my_list = from_json_string(s_my_list)
print(my_list)
print(type(my_list))
s_my_dict = """
{"is_active": true, "info": {"age": 36, "average": 3.14},
"id": 12, "name": "John", "places": ["San Francisco", "Tokyo"]}
"""
my_dict = from_json_string(s_my_dict)
print(my_dict)
print(type(my_dict))
try:
s_my_dict = """
{"is_active": true, 12 }
"""
my_dict = from_json_string(s_my_dict)
print(my_dict)
print(type(my_dict))
except Exception as e:
print("[{}] {}".format(e.__class__.__name__, e))
guillaume@ubuntu:~/0x0B$ ./4-main.py
[1, 2, 3]
<class 'list'>
{'id': 12, 'is_active': True, 'name': 'John', 'info': {'age': 36, 'average': 3.14}, 'places': ['San Francisco', 'Tokyo']}
<class 'dict'>
[ValueError] Expecting property name enclosed in double quotes: line 2 column 25 (char 25)
guillaume@ubuntu:~/0x0B$
No test cases needed
Write a function that writes an Object to a text file, using a JSON
representation:
- Prototype:
def save_to_json_file(my_obj, filename):
- You must use the
with
statement - You don’t need to manage exceptions if the object can’t be serialized.
guillaume@ubuntu:~/0x0B$ cat 5-main.py
#!/usr/bin/python3
save_to_json_file = __import__('5-save_to_json_file').save_to_json_file
filename = "my_list.json"
my_list = [1, 2, 3]
save_to_json_file(my_list, filename)
filename = "my_dict.json"
my_dict = {
'id': 12,
'name': "John",
'places': [ "San Francisco", "Tokyo" ],
'is_active': True,
'info': {
'age': 36,
'average': 3.14
}
}
save_to_json_file(my_dict, filename)
try:
filename = "my_set.json"
my_set = { 132, 3 }
save_to_json_file(my_set, filename)
except Exception as e:
print("[{}] {}".format(e.__class__.__name__, e))
guillaume@ubuntu:~/0x0B$ ./5-main.py
[TypeError] {3, 132} is not JSON serializable
guillaume@ubuntu:~/0x0B$ cat my_list.json ; echo ""
[1, 2, 3]
guillaume@ubuntu:~/0x0B$ cat my_dict.json ; echo ""
{"name": "John", "places": ["San Francisco", "Tokyo"], "id": 12, "info": {"average": 3.14, "age": 36}, "is_active": true}
guillaume@ubuntu:~/0x0B$ cat my_set.json ; echo ""
guillaume@ubuntu:~/0x0B$
No test cases needed
6. Create object from a JSON file
Write a function that creates an Object from a JSON file
:
- Prototype:
def load_from_json_file(filename):
- You must use the
with
statement - You don’t need to manage exceptions if the
JSON
string doesn’t represent an object. - You don’t need to manage file
permissions
/exceptions
.
guillaume@ubuntu:~/0x0B$ cat my_fake.json
{"is_active": true, 12 }
guillaume@ubuntu:~/0x0B$ cat 6-main.py
#!/usr/bin/python3
load_from_json_file = __import__('6-load_from_json_file').load_from_json_file
filename = "my_list.json"
my_list = load_from_json_file(filename)
print(my_list)
print(type(my_list))
filename = "my_dict.json"
my_dict = load_from_json_file(filename)
print(my_dict)
print(type(my_dict))
try:
filename = "my_set_doesnt_exist.json"
my_set = load_from_json_file(filename)
print(my_set)
print(type(my_set))
except Exception as e:
print("[{}] {}".format(e.__class__.__name__, e))
try:
filename = "my_fake.json"
my_fake = load_from_json_file(filename)
print(my_fake)
print(type(my_fake))
except Exception as e:
print("[{}] {}".format(e.__class__.__name__, e))
guillaume@ubuntu:~/0x0B$ cat my_list.json ; echo ""
[1, 2, 3]
guillaume@ubuntu:~/0x0B$ cat my_dict.json ; echo ""
{"name": "John", "places": ["San Francisco", "Tokyo"], "id": 12, "info": {"average": 3.14, "age": 36}, "is_active": true}
guillaume@ubuntu:~/0x0B$ cat my_fake.json ; echo ""
{"is_active": true, 12 }
guillaume@ubuntu:~/0x0B$ ./6-main.py
[1, 2, 3]
<class 'list'>
{'name': 'John', 'info': {'age': 36, 'average': 3.14}, 'id': 12, 'places': ['San Francisco', 'Tokyo'], 'is_active': True}
<class 'dict'>
[FileNotFoundError] [Errno 2] No such file or directory: 'my_set_doesnt_exist.json'
[ValueError] Expecting property name enclosed in double quotes: line 1 column 21 (char 20)
guillaume@ubuntu:~/0x0B$
No test cases needed
Write a script that adds all arguments to a Python list, and then save them to a file:
- You must use your function
save_to_json_file
from5-save_to_json_file.py
- You must use your function
load_from_json_file
from6-load_from_json_file.py
- The list must be saved as a
JSON
representation in a file namedadd_item.json
- If the file doesn’t exist, it should be created
- You don’t need to manage file
permissions
/exceptions
.
guillaume@ubuntu:~/0x0B$ cat add_item.json
cat: add_item.json: No such file or directory
guillaume@ubuntu:~/0x0B$ ./7-add_item.py
guillaume@ubuntu:~/0x0B$ cat add_item.json ; echo ""
[]
guillaume@ubuntu:~/0x0B$ ./7-add_item.py Best School
guillaume@ubuntu:~/0x0B$ cat add_item.json ; echo ""
["Best", "School"]
guillaume@ubuntu:~/0x0B$ ./7-add_item.py 89 Python C
guillaume@ubuntu:~/0x0B$ cat add_item.json ; echo ""
["Best", "School", "89", "Python", "C"]
guillaume@ubuntu:~/0x0B$
No test cases needed
Write a function that returns the dictionary description with simple data structure (list, dictionary, string, integer and boolean) for JSON serialization of an object:
- Prototype:
def class_to_json(obj):
obj
is an instance of aClass
- All attributes of the
obj Class
are serializable:list
,dictionary
,string
,integer
andboolean
- You are not allowed to import any module
guillaume@ubuntu:~/0x0B$ cat 8-my_class.py
#!/usr/bin/python3
""" My class module
"""
class MyClass:
""" My class
"""
def __init__(self, name):
self.name = name
self.number = 0
def __str__(self):
return "[MyClass] {} - {:d}".format(self.name, self.number)
guillaume@ubuntu:~/0x0B$ cat 8-main.py
#!/usr/bin/python3
MyClass = __import__('8-my_class').MyClass
class_to_json = __import__('8-class_to_json').class_to_json
m = MyClass("John")
m.number = 89
print(type(m))
print(m)
mj = class_to_json(m)
print(type(mj))
print(mj)
guillaume@ubuntu:~/0x0B$ ./8-main.py
<class '8-my_class.MyClass'>
[MyClass] John - 89
<class 'dict'>
{'name': 'John', 'number': 89}
guillaume@ubuntu:~/0x0B$
guillaume@ubuntu:~/0x0B$ cat 8-my_class_2.py
#!/usr/bin/python3
""" My class module
"""
class MyClass:
""" My class
"""
score = 0
def __init__(self, name, number = 4):
self.__name = name
self.number = number
self.is_team_red = (self.number % 2) == 0
def win(self):
self.score += 1
def lose(self):
self.score -= 1
def __str__(self):
return "[MyClass] {} - {:d} => {:d}".format(self.__name, self.number, self.score)
guillaume@ubuntu:~/0x0B$ cat 8-main_2.py
#!/usr/bin/python3
MyClass = __import__('8-my_class_2').MyClass
class_to_json = __import__('8-class_to_json').class_to_json
m = MyClass("John")
m.win()
print(type(m))
print(m)
mj = class_to_json(m)
print(type(mj))
print(mj)
guillaume@ubuntu:~/0x0B$ ./8-main_2.py
<class '8-my_class_2.MyClass'>
[MyClass] John - 4 => 1
<class 'dict'>
{'number': 4, '_MyClass__name': 'John', 'is_team_red': True, 'score': 1}
guillaume@ubuntu:~/0x0B$
No test cases needed
Write a class Student
that defines a student by:
- Public instance attributes:
first_name
last_name
age
- Instantiation with
first_name
,last_name
andage
:def __init__(self, first_name, last_name, age):
- Public method
def to_json(self):
that retrieves a dictionary representation of aStudent
instance (same as8-class_to_json.py
) - You are not allowed to import any module
guillaume@ubuntu:~/0x0B$ cat 9-main.py
#!/usr/bin/python3
Student = __import__('9-student').Student
students = [Student("John", "Doe", 23), Student("Bob", "Dylan", 27)]
for student in students:
j_student = student.to_json()
print(type(j_student))
print(j_student['first_name'])
print(type(j_student['first_name']))
print(j_student['age'])
print(type(j_student['age']))
guillaume@ubuntu:~/0x0B$ ./9-main.py
<class 'dict'>
John
<class 'str'>
23
<class 'int'>
<class 'dict'>
Bob
<class 'str'>
27
<class 'int'>
guillaume@ubuntu:~/0x0B$
No test cases needed