Do you love geometry? Our young friend Zigy (Zygfryd) loves it too. Unfortunately it's one-sided love. He's studying hard for his high-school exam, but with minor success. You've got to help him!
But how?
You'll write a Object Oriented Python Application to teach him geometry. Don't worry! Our Finnish software architect Linus Coolvalds has already created a boilerplate for you. However he forgot to create a UML class diagram. You have to do it for him.
In order to help Zigy you have to:
- Implement 6 classes in
geometry.py
module - Implement
main.py
module. - You are allowed to implement your own modules. Remember about clean code.
- Explain why Linus designed some methods to be class methods instead of instance methods.
- Remember about comments and docstrings.
- Add UML.png file containing UML class diagram of a geometry.py module
- All tests must pass.
- Focus most on the OOP not the ui.
Hint: you can reuse code from the previous assignments.
Here you can find information what you have to implement.
This is the main entrance of the program.
The program allows user to create and add shapes to a list and do some things with it.
Running python main.py
should show such menu:
Learn Geometry.
What do you want to do?
(1) Add new shape
(2) Show all shapes
(3) Show shape with the largest perimeter
(4) Show shape with the largest area
(5) Show formulas
(0) Exit program
As you can see the program has 5 features.
This feature allows user to add new shape to shapes list. User should be able to choose what kind of shapes he/she wants to add. Then he/she should specify attributes that a given shape requires.
This feature should print table containing all shapes added to the list. Take a look at ShapeList.get_shapes_table()
This feature prints shape with the largest perimeter from a list.
This feature prints shape with the largest area from a list.
This feature should allow user to choose shape type and print it's formulas (perimeter, area).
This is the most important part of this assignment. You've got to implement all of them in geometry.py
module.
This is a so called abstract class. It means that we don't create instances of it. We only use it as a parent class for other concrete classes. This parent is a boilerplate for it's children. It contains attributes and methods that should be implemented in child classes.
Constructs shape object. Should raise ValueError
if any of the parameters is below 0 (e.g. circle with negative radius doesn't exist).
Returns the area of the shape.
Returns the perimeter of the shape.
Returns information about given shape as string.
Returns formula for the area of the shape as a string.
Returns formula for the perimeter of the shape.
Why this methods should be class methods? Edit this readme and give answer below:
Because this method not use instance attributes so you don't need to create new object to calling the above methods.
This class represents circle shape.
Shape
r
- data: float
- description: circle radius length
__init__(self, r)
- constructor of the Cricle
Override (implement) other methods inherited from the parent class.
Required formulas:
Perimeter = 2×π×r
Area = π×r2
This class represents triangle shape.
Shape
a
- data: float
- description: one side's length of a triangle
b
- data: float
- description: second side's length of a triangle
c
- data: float
- description: third side's length of a triangle
__init__(self, a, b, c)
- constructor of the Triangle
Override (implement) methods inherited from the parent class.
Required formulas:
Perimeter = a + b + c
Area = sqrt(s(s-a)(s-b)(s-c)),
where s = (a+b+c)/2
Heron's Formula
This is a triangle that has all sides equal.
Triangle
Hint: check if you can reuse attributes from the parent class
a
- data: float
- description: side's length of a triangle
__init__(self, a)
- constructor of the Equilateral Triangle
Decide on your own if you have to override inherited methods.
This class represents rectangle shape.
Shape
a
- data: float
- description: one side length
b
- data: float
- description: second side length
__init__(self, a, b)
- constructor of the Rectangle
Override (implement) other methods inherited from the parent class.
Required formulas:
Perimeter = 2a + 2b
Area = a×b
This is a rectangle that has all sides equal.
Rectangle
Hint: check if you can reuse attributes from the parent class
a
- data: float
- description: side's length of the square
__init__(self, a)
- constructor of the Square
Decide on your own if you have to override inherited methods.
This is a shape with 5 sides. All sides are of the same length.
Shape
a
- data: float
- description: side's length of the pentagon
__init__(self, a)
- constructor of the RegularPentagon
Override (implement) other methods inherited from the parent class.
Required formulas:
Perimeter = 5a
Area = (a2 sqrt(5(5+2sqrt(5))))/4 (see image above)
This class is meant to hold geometrical shapes (objects that inherit from Shape class).
shapes
- data: list
- description: list of Shape objects
Constructs ShapeList object
Adds shape to shapes list. This method should check if shape's has Shape class as it's ancestor. If not it should raise TypeError
. Hint: check isinstance
function. (This is a good example of so called polymorphism)
shape
- data_type: Shape
- description: object to be added to the shapes list
This method returns shapes list as string formatted into table. This is sample output:
/------------------------------------------------------------------------------------------------------\
| idx | Class | __str__ | Perimeter | Formula | Area | Formula |
|--------|----------------|----------------------|--------------|-------------|-----------|------------|
| 0 | Circle | Circle, r = 3 | 18.85 | 2×π×r | 28.27 | π×r^2 |
|--------|----------------|----------------------|--------------|-------------|-----------|------------|
| 1 | Square | Square, a = 2 | 8.00 | 4×a | 4.00 | a^2 |
\------------------------------------------------------------------------------------------------------/
string
object
Returns shape with largest perimeter. Hint: have a look at comparison methods
Shape
object
Returns shape with largest area. Hint: have a look at comparison methods
Shape
object
Take radius from user, check correct format (int) and create new object of Circle class.
#####Returns value
Circle
object
Take side a, b, c from user, check correct format (int) and create new object of Triangle class.
#####Returns value
Triangle
object
Take side a, b from user, check correct format (int) and create new object of Rectangle class.
#####Returns value
Rectangle
object
Take side a from user, check correct format (int) and create new object of Square class.
#####Returns value
Square
object
Take side a from user, check correct format (int) and create new object of RegularPentagon class.
#####Returns value
RegularPentagon
object
Raise Value Error if some argument is not digit.
Show options. User choose shape.
#####Returns value
user_choice
- str
Depending on the user_choice, create proper geometrical figure.
Shape
object
Create table row: insert data to list in proper order (according to the tittle). Add row list to bigger list with all rows.
rows_list - list of lists
Find max length of data in column.
length longest string - int
Draw row with data (with proper width and format).
row_data - string
Draw out row (with proper width and format).
out_row - string
If you've fulfilled all the basic requirements and you're ambitious enough to continue, here's idea what you can do.
Help Zigy even more and implement quiz feature. This feature should generate random shape. Tell the user the type of shape and it's attributes. The user should calculate the perimeter and area. The program should check users answer.
Visualize shapes using turtle module.
You can also add more shapes to the geometry class.