Skip to content

Commit 06f8479

Browse files
committed
0x0C-python-almost_a_circle
1 parent 09e1ffc commit 06f8479

File tree

9 files changed

+1526
-0
lines changed

9 files changed

+1526
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Python - Almost a circle
2+
![python](https://contentstatic.techgig.com/thumb/msid-90765233,width-460,resizemode-4/3-Reasons-why-Python-is-not-suitable-for-big-projects.jpg?27034)
3+
4+
## Learning Objectives
5+
* What is `Unit testing` and how to implement it in a large project
6+
* How to `serialize` and `deserialize` a Class
7+
* How to write and read a `JSON` file
8+
* What is `*args` and how to use it
9+
* What is `**kwargs` and how to use it
10+
* How to handle named arguments in a function
11+
12+
## Python Unit test
13+
![python_unit_test](https://res.cloudinary.com/dyd911kmh/image/upload/f_auto,q_auto:best/v1588353328/unit9_ys353w.png)
14+
* Allowed editors: `vi`, `vim`, `emacs`
15+
* All your files should end with a new line
16+
* All your test files should be inside a folder `tests`
17+
* You have to use the unittest module
18+
* All your test files should be python files `(extension: .py)`
19+
* All your test files and folders should start with `test_`
20+
* Your file organization in the tests folder should be the same as your project: ex: for `models/base.py`, unit tests must be in: `tests/test_models/test_base.py`
21+
* All your tests should be executed by using this command: `python3 -m unittest` discover tests
22+
* You can also test file by file by using this command: `python3 -m unittest tests/test_models/test_base.py`
23+
* We strongly encourage you to work together on test cases so that you don’t miss any edge case

0x0C-python-almost_a_circle/models/__init__.py

Whitespace-only changes.
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
#!/usr/bin/python3
2+
"""Module base"""
3+
import json
4+
import csv
5+
from collections import OrderedDict
6+
import turtle
7+
8+
9+
class Base:
10+
"""Defines a base class"""
11+
__nb_objects = 0
12+
13+
def __init__(self, id=None):
14+
"""Method that assign the public instance attribute id
15+
16+
Args:
17+
id(int): integer value to manage id in this project
18+
19+
Return:
20+
Always nothing.
21+
22+
"""
23+
if id is not None:
24+
self.id = id
25+
else:
26+
Base.__nb_objects += 1
27+
self.id = Base.__nb_objects
28+
29+
@staticmethod
30+
def to_json_string(list_dictionaries):
31+
"""Method that returns the JSON
32+
string representation
33+
34+
Args:
35+
list_dictionaries(dict): List of dictionaries
36+
37+
Return:
38+
JSON string
39+
"""
40+
if list_dictionaries is None or bool(list_dictionaries) is False:
41+
return "[]"
42+
else:
43+
json_string = json.dumps(list_dictionaries)
44+
return json_string
45+
46+
@classmethod
47+
def save_to_file(cls, list_objs):
48+
""" Method that writes the JSON string representation
49+
of list_objs to a file
50+
51+
Args:
52+
list_objs(list): List of objects
53+
54+
Return:
55+
Always nothing
56+
"""
57+
filename = "{}.json".format(cls.__name__)
58+
list_dictionaries = []
59+
if list_objs is not None:
60+
for obj in list_objs:
61+
dictionary = obj.to_dictionary()
62+
list_dictionaries.append(dictionary)
63+
json_string = Base.to_json_string(list_dictionaries)
64+
with open(filename, 'w') as f:
65+
if list_objs is None:
66+
f.write("[]")
67+
else:
68+
f.write(json_string)
69+
70+
@staticmethod
71+
def from_json_string(json_string):
72+
"""Method that returns the list of the
73+
JSON string representation
74+
75+
Args:
76+
json_string: JSON string
77+
78+
Return:
79+
Python object
80+
81+
"""
82+
if json_string is None or bool(json_string) is False:
83+
json_string = "[]"
84+
return json.loads(json_string)
85+
86+
@classmethod
87+
def create(cls, **dictionary):
88+
"""Update the class Base and returns a instance with all
89+
attributes already set
90+
91+
Args:
92+
dictionary: Dictionary with all attributes of the object
93+
94+
Return:
95+
A instance with all attributes already set
96+
97+
"""
98+
if cls.__name__ == "Rectangle":
99+
dummy = cls(1, 1)
100+
elif cls.__name__ == "Square":
101+
dummy = cls(1)
102+
dummy.update(**dictionary)
103+
return dummy
104+
105+
@classmethod
106+
def load_from_file(cls):
107+
"""Method that returns a list of instances
108+
- the type of these instances depends on cls
109+
"""
110+
filename = "{}.json".format(cls.__name__)
111+
instance_list = []
112+
try:
113+
with open(filename, 'r') as f:
114+
json_string = f.read()
115+
dictionary_list = cls.from_json_string(json_string)
116+
for item in dictionary_list:
117+
instance = cls.create(**item)
118+
instance_list.append(instance)
119+
except FileNotFoundError:
120+
return instance_list
121+
return instance_list
122+
123+
@classmethod
124+
def save_to_file_csv(cls, list_objs):
125+
"""Method that serializes in CSV
126+
127+
Args:
128+
list_objs(list): List of objects
129+
130+
Return:
131+
Always nothing
132+
"""
133+
filename = "{}.csv".format(cls.__name__)
134+
data = []
135+
if list_objs is not None:
136+
for obj in list_objs:
137+
dictionary = obj.to_dictionary()
138+
data.append(dictionary)
139+
rectangle_header = ['id', 'width', 'height', 'x', 'y']
140+
square_header = ['id', 'size', 'x', 'y']
141+
with open(filename, mode='w') as f:
142+
if list_objs is None:
143+
f.write("[]")
144+
else:
145+
if cls.__name__ == 'Rectangle':
146+
result = csv.DictWriter(f, fieldnames=rectangle_header)
147+
elif cls.__name__ == 'Square':
148+
result = csv.DictWriter(f, fieldnames=square_header)
149+
result.writeheader()
150+
result.writerows(data)
151+
152+
@classmethod
153+
def load_from_file_csv(cls):
154+
"""Method that deserializes in CSV
155+
"""
156+
filename = "{}.csv".format(cls.__name__)
157+
instance_list = []
158+
try:
159+
with open(filename) as f:
160+
result = csv.DictReader(f)
161+
for row in result:
162+
row = dict(row)
163+
for key in row:
164+
row[key] = int(row[key])
165+
instance = cls.create(**row)
166+
instance_list.append(instance)
167+
except FileNotFoundError:
168+
return instance_list
169+
return instance_list
170+
171+
@staticmethod
172+
def draw(list_rectangles, list_squares):
173+
"""Method that draws the shape with turtle module
174+
175+
Args:
176+
list_squares(list): List of square objects
177+
list_rectangles(list): List of rectangle objects
178+
179+
Return:
180+
Always nothing
181+
"""
182+
# Open screen and set the turtle in the center
183+
s = turtle.getscreen()
184+
t = turtle.Turtle()
185+
186+
# Add a title to my screen
187+
turtle.title("My first draw with python and tutle module")
188+
189+
# Customize turtle and screen background
190+
t.shape("turtle")
191+
turtle.bgcolor("black")
192+
193+
# Customize pen for rectangle
194+
t.pen(pencolor="blue", fillcolor="white", pensize=5, speed=1)
195+
# Extract the data from the instance rectangle list
196+
for instance in list_rectangles:
197+
# Customize pen for rectangle
198+
t.pen(pencolor="blue", fillcolor="white", pensize=5, speed=1)
199+
data = instance.to_dictionary()
200+
# Set the position acording the rectangle object
201+
t.home()
202+
t.setpos(data['x'], data['y'])
203+
# Draw process
204+
t.pd()
205+
for i in range(2):
206+
t.forward(data['width'])
207+
t.left(90)
208+
t.forward(data['height'])
209+
t.left(90)
210+
t.pu()
211+
212+
# Customize pen for square
213+
t.pen(pencolor="red", fillcolor="white", pensize=5, speed=0.5)
214+
# Extract the data from the instance square list
215+
for instance in list_squares:
216+
data = instance.to_dictionary()
217+
# Set the position acording the square object
218+
t.home()
219+
t.setpos(data['x'], data['y'])
220+
# Draw process
221+
t.pd()
222+
for i in range(4):
223+
t.forward(data['size'])
224+
t.left(90)
225+
t.pu()
226+
227+
# Keeps window open
228+
turtle.getscreen()._root.mainloop()

0 commit comments

Comments
 (0)