PEP-8
- Class names should be
CapWords
, so instead of rectangle
you should have Rectangle
.
- Commas should be followed by 1 space. You've mostly followed this, except in
s1 = rectangle({'p1': (1,1), 'p2': (2,2)})
Bugs
- The formula for "area" is not twice the sum of width & height.
- I don't know what "surrounding" is, but the formula for perimeter is not width times height.
- The midpoint (centre?) of a rectangle should be within the bounds of the rectangle. Consider the rectangles with corners (10, 10) and (12, 12). The centre would be (11, 11), not (1, 1) as calculated.
Awkward initialization
This code:
names = list(dct.keys())
coords = list(dct.values())
start = [names[0], coords[0]]
end = [names[1], coords[1]]
self.start = start
self.end = end
relies on the dictionary's ordering of keys. It can break in Python 3.6 and earlier (CPython 3.5 and earlier). It does not enforce the key names p1
and p2
; any two keys will work. And self.start[0]
and self.end[0]
are never used, so storing the key names in these entries is unnecessary.
The code could simply and safely read:
self.start = dct['p1']
self.end = dct['p2']
with suitable modifications of the usage of self.start
and self.end
.
Class with no methods
A class should have methods. Without any methods, you'd be better off with a namedtuple
for constant data, or a dict
for mutable data.
So let's give your class some methods:
def width(self):
return self.end[0] - self.start[0]
def height(self):
return self.end[1] - self.start[1]
As mentioned by Peilonrayz, you may wish to use abs(...)
here.
You can use these methods externally:
print('width: ', s1.width())
print('height: ', s1.height())
as well as in other members of this class:
def area(self):
return (self.width() + self.height()) * 2 # Note: Formula is still incorrect
An Over-Engineered Solution
Do not submit this as your home-work solution! You would likely fail or be expelled! This illustrates some advanced concepts like the @dataclass
and the NamedTuple
, type hints and the typing
module, as well as read-only @property
attributes, a @classmethod
, and """docstrings"""
. You may find these interesting to study in your free time.
from typing import NamedTuple
from dataclasses import dataclass
class Point(NamedTuple):
x: float
y: float
@dataclass
class Rectangle:
"""A class for calculations on a Rectangle"""
p1: Point
p2: Point
@classmethod
def from_dict(cls, dct):
"""
Constructs a Rectangle from a dictionary with "p1" and "p2" keys.
These keys must contain a tuple or list of two numeric values.
"""
return Rectangle(Point._make(dct['p1']), Point._make(dct['p2']))
@property
def width(self):
"""
Computes the width of the rectangle.
"""
return abs(self.p2.x - self.p1.x)
@property
def height(self):
"""
Computes the height of the rectangle.
"""
return abs(self.p2.y - self.p1.y)
@property
def area(self):
"""
Incorrectly computes the area of the rectangle.
"""
return (self.width + self.height) * 2 # Note: still the incorrect formula
s1 = Rectangle.from_dict({'p1': (1,1), 'p2': (2,2)})
print('point one: ', s1.p1)
print('point two: ', s1.p2)
print('width: ', s1.width)
print('height: ', s1.height)
print('area: ', s1.area)
Output:
point one: Point(x=1, y=1)
point two: Point(x=2, y=2)
width: 1
height: 1
area: 4
area
property is called 'perimeter' in mathematics, while yoursurr
property is actually called the an 'area'. \$\endgroup\$