From 8f5f7afa7a5e0bfaa14881f4fef06fd07de8f97d Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 16 Apr 2024 17:00:50 -0400 Subject: [PATCH] remove 14 --- labs/14_exceptions_inheritance/README.md | 93 -------- labs/14_exceptions_inheritance/cp1/input.txt | 31 --- .../cp2/output_simple.txt | 8 - labs/14_exceptions_inheritance/cp2/simple.txt | 7 - .../cp2/simple_main.cpp | 168 ------------- .../14_exceptions_inheritance/cp2/utilities.h | 120 ---------- labs/14_exceptions_inheritance/cp3/main.cpp | 223 ------------------ labs/14_exceptions_inheritance/cp3/quads.txt | 9 - .../cp3/triangles.txt | 9 - .../images/multiple_inheritance.png | Bin 25098 -> 0 bytes .../images/single_inheritance.png | Bin 14139 -> 0 bytes 11 files changed, 668 deletions(-) delete mode 100644 labs/14_exceptions_inheritance/README.md delete mode 100644 labs/14_exceptions_inheritance/cp1/input.txt delete mode 100644 labs/14_exceptions_inheritance/cp2/output_simple.txt delete mode 100644 labs/14_exceptions_inheritance/cp2/simple.txt delete mode 100644 labs/14_exceptions_inheritance/cp2/simple_main.cpp delete mode 100644 labs/14_exceptions_inheritance/cp2/utilities.h delete mode 100644 labs/14_exceptions_inheritance/cp3/main.cpp delete mode 100644 labs/14_exceptions_inheritance/cp3/quads.txt delete mode 100644 labs/14_exceptions_inheritance/cp3/triangles.txt delete mode 100644 labs/14_exceptions_inheritance/images/multiple_inheritance.png delete mode 100644 labs/14_exceptions_inheritance/images/single_inheritance.png diff --git a/labs/14_exceptions_inheritance/README.md b/labs/14_exceptions_inheritance/README.md deleted file mode 100644 index 21800a1..0000000 --- a/labs/14_exceptions_inheritance/README.md +++ /dev/null @@ -1,93 +0,0 @@ -# Lab 14 — Multiple Inheritance & Exceptions - -For this lab you will build a class inheritance structure to match the hierarchy of classic geometric shapes. -The finished program will read lists of 2D point coordinates from a file and determine the shape described -by each list of points. We will use a somewhat quirky method to determine the type of each shape. We will -pass the list of points to each specialized shape constructor in turn, and if the constructor doesn’t fail, then -we know that that list of points is in fact that type of shape. Remember, the only way for a constructor to -fail is to throw an exception. - -## Checkpoint 0 - -If you haven’t done so already, please complete your course evaluation for Data Structures (your honest & anonymous feedback is very important!). Have the webpage receipt saying “completed” open in your browser to receive credit for Checkpoint 0. - -## Checkpoint 1: Shape Hierarchy - -*estimate: 20-40 minutes* - -Consider the “is-a” relationships between these 13 different shapes: Polygon, Triangle, Quadrilateral, Isosceles Triangle, Right Triangle, Isosceles Right Triangle, Equilateral Triangle, Trapezoid, Kite, Parallelogram, Rectangle, Rhombus, and Square. Note that a particular shape may be correctly labeled by more than one of these names; e.g., a Square is also a Quadrilateral. - -Draw the class hierarchy with arrows indicating all of the inheritance relationships (you do not need to include the member variables or member functions). Be neat, have a consistent (up or down) orientation to your arrows, and avoid messy scribbles or cross outs and arrow crossings. Sketch the shapes in the [input.txt](cp1/input.txt) file - each line of the input file begins with a string name followed by 3 or more 2D coordinate vertices. Write the name of each shape next to the most specific type of shape it represents. Hint: you may want to grab or print yourself some graph paper. - -The inheritance diagram of these shapes includes multiple inheritance, specifically in the form of the Diamond Problem. That is, Class D multiply inherits from Class B and Class C, and Class B and Class C each inherit from Class A. Thus when an object of type D is created, in turn instances of B and C are created, and unfortunately both will try to make their own instance of A. If two instances of A were allowed, attempts to refer to member variables or member functions of A would be ambiguous. To solve the problem, we should specify that B virtually inherits from A and C virtually inherits from A. Furthermore, when we construct an instance of D, in addition to specifying how to call constructors for B and C, we also explicitly specify the constructor for A. - -![alt text](images/multiple_inheritance.png "Multiple Inheritance") - - - -Note how in the single inheritance example below, G only explicitly calls a constructor for F. - -![alt text](images/single_inheritance.png "Single Inheritance") - - - -Label the virtual inheritance paths in your diagram. Hint: 6 of the inheritance arrows will be labeled virtual. - -**To complete this checkpoint**: Present your class inheritance diagram and your shape sketches to one of the TAs. - -## Checkpoint 2: - -*estimate: 20-40 minutes* - -To start the implementation, we’ll focus on just 7 of those shapes: Polygon, Triangle, Quadrilateral, Isosceles Triangle, Equilateral Triangle, Rectangle, and Square. This subset will allow us to initially ignore the multiple inheritance diamond property and the need for virtual inheritance it causes. - -Download the code and initial example: [simple_main.cpp](cp2/simple_main.cpp), [utilities.h](cp2/utilities.h), [simple.txt](cp2/simple.txt), [output_simple.txt](cp2/output_simple.txt). -The program expects 2 command line arguments, the names of the input and output files. Each line of the input file begins with a string name followed by 3 or more 2D coordinate vertices. The output categorizes each shape into one or more classes, and into groups with equal angles, equal edges, and/or a right angle. The provided code includes code to call the constructors of the different classes, generally ordered from most specific/constrained to least specific. For example, the program will try to create a Square with the data first, and only if that constructor fails (throws an exception) then it will try to create a Rectangle. We also include a utilities.h file with a number of simple geometric operations: e.g., calculate the distance between two points, calculate the angle between two edges, and compare two distances or two angles and judge if they are sufficiently close to be called “equal”. Remember that you usually don’t want to check if two floating point numbers are equal; instead, check if the difference is below an appropriate tolerance. - -Create a polygons.h file (and optionally a polygons.cpp file). Create the 7 classes for these shapes deriving classes from the other classes as appropriate. In each constructor write code to check whether the vertices passed in meet the requirements for that shape. Throw an exception if you find a problem. Note: Just throw a value of type integer. The value thrown is unimportant in this program – it will be ignored. - -**To complete this checkpoint**: Compile, run, and debug your program. Study the output and confirm that your program is correctly labeling the shapes in simple.txt. - -## Checkpoint 3: - -*estimate: 20-30 minutes* - -Now tackle the problem of multiple inheritance and the diamond property. Focus on either the [triangles](cp3/triangles.txt) or the [quadrilaterals](cp3/quads.txt) (more challenging). Here is a revised [main.cpp](cp3/main.cpp) for all shapes (comment out the portions you are not implementing). - -In organizing your code for this lab, try to avoid unnecessarily duplicating code. For example, don’t implement the HasARightAngle function in every class. Also, you don’t need to check if the Rectangle has 4 vertices (the constructor for its base class will do that). Instead, allow the derived class to rely on the implementation of that function in its parent class. Similarly, don’t recalculate measurement data if you can deduce information from properties of that shape. For example, when a Rectangle is asked if it HasARightAngle, no calculation is necessary — the answer is guaranteed to be true. - -**To complete this checkpoint**: Be sure to ask your TAs for help if you get stuck. Near the end of lab period show a TA your progress. diff --git a/labs/14_exceptions_inheritance/cp1/input.txt b/labs/14_exceptions_inheritance/cp1/input.txt deleted file mode 100644 index a5164a6..0000000 --- a/labs/14_exceptions_inheritance/cp1/input.txt +++ /dev/null @@ -1,31 +0,0 @@ -black (1,0) (0.5,0.866) (1,1.732) (3,1.732) (3.5,0.866) (3,0) -blue (0,0) (0,1) (1,1) (1,0) -brown (2,0) (0,1) (3,3) -cyan (0,0) (0,2) (1,0) -green (0,0) (0,1) (1,0) -grey (1,0) (1.5,0.866) (1,1.732) (2,1.732) (2.5,0.866) (2,0) -magenta (0,0) (1,1) (4,1) (3,0) -olive (0,0) (1,2) (6,3) (4,0) -orange (0,0) (0,3) (2,3) (2,0) -pink (1,0) (0,2) (4,2) (3,0) -purple (0,0) (0,2) (3,1) -red (0,0) (0.5,0.866) (1,0) -teal (1,0) (0,3) (1,4) (2,3) -white (2,0) (0,1) (3,4) (6,1) (4,0) -yellow (0,1) (2,2) (4,1) (2,0) - - - - - - - - - - - - - - - - diff --git a/labs/14_exceptions_inheritance/cp2/output_simple.txt b/labs/14_exceptions_inheritance/cp2/output_simple.txt deleted file mode 100644 index c4eda00..0000000 --- a/labs/14_exceptions_inheritance/cp2/output_simple.txt +++ /dev/null @@ -1,8 +0,0 @@ -7 Polygon(s): blue brown grey olive orange purple red -3 Triangle(s): brown purple red -2 IsoscelesTriangle(s): purple red -1 EquilateralTriangle(s): red -3 Quadrilateral(s): blue olive orange -2 Rectangle(s): blue orange -1 Square(s): blue -3 Shape(s) with all equal sides: blue grey red diff --git a/labs/14_exceptions_inheritance/cp2/simple.txt b/labs/14_exceptions_inheritance/cp2/simple.txt deleted file mode 100644 index 353859c..0000000 --- a/labs/14_exceptions_inheritance/cp2/simple.txt +++ /dev/null @@ -1,7 +0,0 @@ -blue (0,0) (0,1) (1,1) (1,0) -brown (2,0) (0,1) (3,3) -grey (1,0) (1.5,0.866) (1,1.732) (2,1.732) (2.5,0.866) (2,0) -olive (0,0) (1,2) (6,3) (4,0) -orange (0,0) (0,3) (2,3) (2,0) -purple (0,0) (0,2) (3,1) -red (0,0) (0.5,0.866) (1,0) diff --git a/labs/14_exceptions_inheritance/cp2/simple_main.cpp b/labs/14_exceptions_inheritance/cp2/simple_main.cpp deleted file mode 100644 index d3ebe2d..0000000 --- a/labs/14_exceptions_inheritance/cp2/simple_main.cpp +++ /dev/null @@ -1,168 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "polygons.h" - -// helper function prototypes -Polygon* CreatePolygon(const std::string &name, const std::vector &points); -void OutputStats(const std::vector &polygons, std::ofstream &ostr); - -// ------------------------------------------------------------------------------ - -int main(int argc, char* argv[]) { - - // command line arguments & opening files - if (argc != 3) { - std::cerr << "Usage: " << argv[0] << " input.txt output.txt" << std::endl; - exit(1); - } - std::ifstream istr(argv[1]); - if (!istr) { - std::cerr << "ERROR: could not open " << argv[1] << std::endl; - exit(1); - } - std::ofstream ostr(argv[2]); - if (!ostr) { - std::cerr << "ERROR: could not open " << argv[2] << std::endl; - exit(1); - } - - // the master container of polygons - std::vector polygons; - - // read the input file one line at a time - std::string line; - while (getline(istr,line)) { - std::stringstream ss(line); - std::string name, token; - if (!(ss >> name)) continue; - std::vector points; - while (ss >> token) { - std::stringstream ss2(token); - char c; - double x,y; - ss2 >> c; - assert (c == '('); - ss2 >> x; - ss2 >> c; - assert (c == ','); - ss2 >> y; - ss2 >> c; - assert (c == ')'); - points.push_back(Point(x,y)); - } - assert (points.size() >= 3); - Polygon* p = CreatePolygon(name,points); - // add the new polygon to the master container - polygons.push_back(p); - } - - // write out the statistics - OutputStats(polygons,ostr); - - // delete the dynamically allocated polygons - for (int i = 0; i < polygons.size(); i++) { - delete polygons[i]; - } -} - -// ------------------------------------------------------------------------------ - -// This function determines the most specific type of shape that can -// be created from the sequence of points. It does this by process of -// elimination. Note that the order in which it attempts to create -// the shapes is important. - -Polygon* CreatePolygon(const std::string &name, const std::vector &points) { - Polygon *answer = NULL; - try{ - answer = new EquilateralTriangle(name,points); - } - catch (int) { - try { - answer= new IsoscelesTriangle(name,points); - } - catch (int) { - try { - answer= new Triangle(name,points); - } - catch (int) { - try { - answer= new Square(name,points); - } - catch (int) { - try { - answer= new Rectangle(name,points); - } - catch (int) { - try { - answer= new Quadrilateral(name,points); - } - catch (int) { - answer= new Polygon(name,points); - } - } - } - } - } - } - assert (answer != NULL); - return answer; -} - -// ------------------------------------------------------------------------------ - -// This function prints the output. C++ macros are used to abbreviate -// some repetitive code. The function call-like macros are actually -// replaced using substitution by the preprocessor before the code is -// given to the compiler. (You are not required to understand the -// details of the macros. You do not need to edit this code.) - -void OutputStats(const std::vector &polygons, std::ofstream &ostr) { - - // define and initialize variables -# define InitializeCount(type) std::vector all_##type - InitializeCount(Polygon); - InitializeCount(Triangle); - InitializeCount(IsoscelesTriangle); - InitializeCount(EquilateralTriangle); - InitializeCount(Quadrilateral); - InitializeCount(Rectangle); - InitializeCount(Square); - std::vector equal_sides; - - // count & record the names of shapes in each category - for (std::vector::const_iterator i = polygons.begin(); i!=polygons.end(); ++i) { -# define IncrementCount(type) if (dynamic_cast (*i)) all_##type.push_back((*i)->getName()) - IncrementCount(Polygon); - IncrementCount(Triangle); - IncrementCount(IsoscelesTriangle); - IncrementCount(EquilateralTriangle); - IncrementCount(Quadrilateral); - IncrementCount(Rectangle); - IncrementCount(Square); - if ((*i)->HasAllEqualSides()) equal_sides.push_back((*i)->getName()); - } - - - // output data for each category, sorted alphabetically by the shape's name -# define PrintVector(vecname) std::sort((vecname).begin(),(vecname).end()); \ - for (unsigned int j = 0; j < (vecname).size(); j++) { ostr << " " << (vecname)[j]; } ostr << std::endl -# define PrintCount(type) do { ostr << all_##type.size() << " " #type"(s): "; PrintVector(all_##type); } while (0) - PrintCount(Polygon); - PrintCount(Triangle); - PrintCount(IsoscelesTriangle); - PrintCount(EquilateralTriangle); - PrintCount(Quadrilateral); - PrintCount(Rectangle); - PrintCount(Square); - ostr << equal_sides.size() << " Shape(s) with all equal sides: "; - PrintVector(equal_sides); -} - -// ------------------------------------------------------------------------------ diff --git a/labs/14_exceptions_inheritance/cp2/utilities.h b/labs/14_exceptions_inheritance/cp2/utilities.h deleted file mode 100644 index e0d1ec6..0000000 --- a/labs/14_exceptions_inheritance/cp2/utilities.h +++ /dev/null @@ -1,120 +0,0 @@ -// ========================================= -// -// IMPORTANT NOTE: DO NOT EDIT THIS FILE -// -// ========================================= - -#ifndef _UTILITIES_H_ -#define _UTILITIES_H_ - -#include -#include -#include - -// epsilon values used in comparing the edge lengths & angles between -// edges note that these values are dependent on the precision of -// the coordinates and the overall scale of the objects -#define DISTANCE_EPSILON 0.0001 -#define ANGLE_EPSILON 0.1 - -// ----------------------------------------------------------------- - -// Stores a 2D coordinate -class Point { -public: - Point(double _x, double _y) : x(_x),y(_y) {} - double x; - double y; -}; - -// Stores a 2D vector, constructed from 2 Points -class Vector { -public: - Vector(const Point &a, const Point &b) { dx = b.x-a.x; dy = b.y-a.y; } - double Length() const { return sqrt(dx*dx+dy*dy); } - void Normalize() { - // make this a unit vector (length = 1) - double length = Length(); - if (length < DISTANCE_EPSILON) throw std::string("LENGTH = 0"); - assert (length > DISTANCE_EPSILON); - dx /= length; - dy /= length; - } - // representation - double dx; - double dy; -}; - - -inline std::ostream& operator<< (std::ostream &ostr, const Vector &v) { - ostr << "<" << v.dx << "," << v.dy << ">"; - return ostr; -} - - -// ----------------------------------------------------------------- - -// calculate the length of an edge, the distance between 2 points -inline double DistanceBetween(const Point &a, const Point &b) { - Vector v(a,b); - return v.Length(); -} - -// Calculate the angle at vertex b in degrees, that is, the angle -// between edges ab and bc. This will return a positive number -// measured as the clockwise rotation in the xy plane from point c to -// point a (rotating around point b). -inline double Angle(const Point &a, const Point &b, const Point &c) { - // make unit vector along each of the edges - Vector ba(b,a); ba.Normalize(); - Vector bc(b,c); bc.Normalize(); - // calculate the angle in radians - double dot_product = ba.dx * bc.dx + ba.dy * bc.dy; - - if (dot_product < -1 || dot_product > 1) throw std::string("DOT PRODUCT RANGE"); - - assert (dot_product >= -1 && dot_product <= 1); - float perpDot = ba.dx * bc.dy - ba.dy * bc.dx; - // using atan2 to ensure than we get a signed answer. - double angle_in_radians = atan2(perpDot, dot_product); - // convert to degrees - double answer = angle_in_radians * 180.0 / M_PI; - if (answer < 0) { - answer += 360; - } - assert (answer >= 0 && answer <= 360); - return answer; -} - -// returns true if these two vectors are parallel -inline bool Parallel(const Vector &a, const Vector &b) { - Vector a2 = a; a2.Normalize(); - Vector b2 = b; b2.Normalize(); - double dot_product = a2.dx * b2.dx + a2.dy * b2.dy; - // parallel vectors have dot product == 1 - if (fabs(dot_product) > 1-DISTANCE_EPSILON) return true; - return false; -} - - -// ----------------------------------------------------------------- -// simple functions for angles & sides - -inline bool EqualSides(double a, double b) { - return (fabs(a-b) < DISTANCE_EPSILON); -} - -inline bool EqualAngles(double a, double b) { - assert (a >= 0.0 && a < 360.0); - assert (b >= 0.0 && b < 360.0); - return (fabs(a-b) < ANGLE_EPSILON); -} - -inline bool RightAngle(double a) { - assert (a >= 0.0 && a < 360.0); - return (fabs(a-90.0) < ANGLE_EPSILON); -} - -// ----------------------------------------------------------------- - -#endif diff --git a/labs/14_exceptions_inheritance/cp3/main.cpp b/labs/14_exceptions_inheritance/cp3/main.cpp deleted file mode 100644 index 9c7028e..0000000 --- a/labs/14_exceptions_inheritance/cp3/main.cpp +++ /dev/null @@ -1,223 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "polygons.h" - -// helper function prototypes -Polygon* CreatePolygon(const std::string &name, const std::vector &points); -void OutputStats(const std::vector &polygons, std::ofstream &ostr); - -// ------------------------------------------------------------------------------ - -int main(int argc, char* argv[]) { - - // command line arguments & opening files - if (argc != 3) { - std::cerr << "Usage: " << argv[0] << " input.txt output.txt" << std::endl; - exit(1); - } - std::ifstream istr(argv[1]); - if (!istr) { - std::cerr << "ERROR: could not open " << argv[1] << std::endl; - exit(1); - } - std::ofstream ostr(argv[2]); - if (!ostr) { - std::cerr << "ERROR: could not open " << argv[2] << std::endl; - exit(1); - } - - // the master container of polygons - std::vector polygons; - - // read the input file one line at a time - std::string line; - while (getline(istr,line)) { - std::stringstream ss(line); - std::string name, token; - if (!(ss >> name)) continue; - std::vector points; - while (ss >> token) { - std::stringstream ss2(token); - char c; - double x,y; - ss2 >> c; - assert (c == '('); - ss2 >> x; - ss2 >> c; - assert (c == ','); - ss2 >> y; - ss2 >> c; - assert (c == ')'); - points.push_back(Point(x,y)); - } - assert (points.size() >= 3); - Polygon* p = CreatePolygon(name,points); - // add the new polygon to the master container - polygons.push_back(p); - } - - // write out the statistics - OutputStats(polygons,ostr); - - // delete the dynamically allocated polygons - for (int i = 0; i < polygons.size(); i++) { - delete polygons[i]; - } -} - -// ------------------------------------------------------------------------------ - -// This function determines the most specific type of shape that can -// be created from the sequence of points. It does this by process of -// elimination. Note that the order in which it attempts to create -// the shapes is important. - -Polygon* CreatePolygon(const std::string &name, const std::vector &points) { - Polygon *answer = NULL; - try{ - answer = new EquilateralTriangle(name,points); - } - catch (int) { - try { - answer= new IsoscelesRightTriangle(name,points); - } - catch (int) { - try { - answer= new RightTriangle(name,points); - } - catch (int) { - try { - answer= new IsoscelesTriangle(name,points); - } - catch (int) { - try { - answer= new Triangle(name,points); - } - catch (int) { - try { - answer= new Square(name,points); - } - catch (int) { - try { - answer= new Rectangle(name,points); - } - catch (int) { - try { - answer= new Rhombus(name,points); - } - catch (int) { - try { - answer= new Parallelogram(name,points); - } - catch (int) { - try { - answer= new Kite(name,points); - } - catch (int) { - try { - answer= new Trapezoid(name,points); - } - catch (int) { - try { - answer= new Quadrilateral(name,points); - } - catch (int) { - answer= new Polygon(name,points); - } - } - } - } - } - } - } - } - } - } - } - } - assert (answer != NULL); - return answer; -} - -// ------------------------------------------------------------------------------ - -// This function prints the output. C++ macros are used to abbreviate -// some repetitive code. The function call-like macros are actually -// replaced using substitution by the preprocessor before the code is -// given to the compiler. (You are not required to understand the -// details of the macros. You do not need to edit this code.) - -void OutputStats(const std::vector &polygons, std::ofstream &ostr) { - - // define and initialize variables -# define InitializeCount(type) std::vector all_##type - InitializeCount(Polygon); - InitializeCount(Triangle); - InitializeCount(IsoscelesTriangle); - InitializeCount(RightTriangle); - InitializeCount(IsoscelesRightTriangle); - InitializeCount(EquilateralTriangle); - InitializeCount(Quadrilateral); - InitializeCount(Trapezoid); - InitializeCount(Kite); - InitializeCount(Parallelogram); - InitializeCount(Rhombus); - InitializeCount(Rectangle); - InitializeCount(Square); - std::vector equal_sides; - std::vector equal_angles; - std::vector right_angle; - - // count & record the names of shapes in each category - for (std::vector::const_iterator i = polygons.begin(); i!=polygons.end(); ++i) { -# define IncrementCount(type) if (dynamic_cast (*i)) all_##type.push_back((*i)->getName()) - IncrementCount(Polygon); - IncrementCount(Triangle); - IncrementCount(IsoscelesTriangle); - IncrementCount(RightTriangle); - IncrementCount(IsoscelesRightTriangle); - IncrementCount(EquilateralTriangle); - IncrementCount(Quadrilateral); - IncrementCount(Trapezoid); - IncrementCount(Kite); - IncrementCount(Parallelogram); - IncrementCount(Rhombus); - IncrementCount(Rectangle); - IncrementCount(Square); - if ((*i)->HasAllEqualSides()) equal_sides.push_back((*i)->getName()); - if ((*i)->HasAllEqualAngles()) equal_angles.push_back((*i)->getName()); - if ((*i)->HasARightAngle()) right_angle.push_back((*i)->getName()); - } - - // output data for each category, sorted alphabetically by the shape's name -# define PrintVector(vecname) std::sort((vecname).begin(),(vecname).end()); \ - for (unsigned int j = 0; j < (vecname).size(); j++) { ostr << " " << (vecname)[j]; } ostr << std::endl -# define PrintCount(type) do { ostr << all_##type.size() << " " #type"(s): "; PrintVector(all_##type); } while (0) - PrintCount(Polygon); - PrintCount(Triangle); - PrintCount(IsoscelesTriangle); - PrintCount(RightTriangle); - PrintCount(IsoscelesRightTriangle); - PrintCount(EquilateralTriangle); - PrintCount(Quadrilateral); - PrintCount(Trapezoid); - PrintCount(Kite); - PrintCount(Parallelogram); - PrintCount(Rhombus); - PrintCount(Rectangle); - PrintCount(Square); - ostr << equal_sides.size() << " Shape(s) with all equal sides: "; - PrintVector(equal_sides); - ostr << equal_angles.size() << " Shape(s) with all equal angles: "; - PrintVector(equal_angles); - ostr << right_angle.size() << " Shape(s) with a right angle: "; - PrintVector(right_angle); -} - -// ------------------------------------------------------------------------------ diff --git a/labs/14_exceptions_inheritance/cp3/quads.txt b/labs/14_exceptions_inheritance/cp3/quads.txt deleted file mode 100644 index 2bdf20c..0000000 --- a/labs/14_exceptions_inheritance/cp3/quads.txt +++ /dev/null @@ -1,9 +0,0 @@ -blue (0,0) (0,1) (1,1) (1,0) -orange (0,0) (0,3) (2,3) (2,0) -yellow (0,1) (2,2) (4,1) (2,0) -magenta (0,0) (1,1) (4,1) (3,0) -pink (1,0) (0,2) (4,2) (3,0) -teal (1,0) (0,3) (1,4) (2,3) -olive (0,0) (1,2) (6,3) (4,0) - - diff --git a/labs/14_exceptions_inheritance/cp3/triangles.txt b/labs/14_exceptions_inheritance/cp3/triangles.txt deleted file mode 100644 index b623368..0000000 --- a/labs/14_exceptions_inheritance/cp3/triangles.txt +++ /dev/null @@ -1,9 +0,0 @@ -red (0,0) (0.5,0.866) (1,0) -green (0,0) (0,1) (1,0) -cyan (0,0) (0,2) (1,0) -purple (0,0) (0,2) (3,1) -brown (2,0) (0,1) (3,3) - - - - diff --git a/labs/14_exceptions_inheritance/images/multiple_inheritance.png b/labs/14_exceptions_inheritance/images/multiple_inheritance.png deleted file mode 100644 index 3212bbb5f6db6c7eb5823af027e3e1eccadd1a53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25098 zcma%iWmsHGv?Z>=-DxzqySqbz1b26*ad&qK?(PJ4Cs+vXG#;GbK7H@Zdoyp|{Fop8 zb)Pz2-F0g3s@i+6wW7W#%b*|;B0)evpvcKeszN|OmVjSS2yoz*M#SP#@EfG7s*E^9 z-3;*`@CA&en35RyRs!;?F)a8R(MeX@6#@cv=${wlm}7+*1cY(EoTQk#r@{Fqyq?R1!fV#?I5d>4Xr^L~h5d&{1CDATN0+x;T9n{YM76I6|d5b|L~G z^fN4yEVwll3YJP70U#d)g$W2nFBOH1LKlxzEwI_9c6+=s7W92g%&+3-cRvZe?EA>e zrwBzqkbtZVt*NaAU?Z_vOyLVlJ#F^*;9+23v;!|m^TlOXQ_8{z)~C@Nb?=7?>ekd> z#pPq6R1uYOcro$=-aB3$HJneEm|mYx>;LvicE}YAIUiiOnmJ|MNN%2&-BwJN<46!+(Ml@`Mo3G*510-6G7@a!Liv*dqKmTe#Zx0W>7W1u0|@Oc zh&R9vvGH=vl6@k9t34KmhGo7K6}r6fZ4~3TrJct-CN1fK$W%=5NQ-=7MtcInQnFIPnF!}*2YpEp zXg}DE+380g?#}*-kKwzKUvMNU^w<^A`#~yIQE|nBKt}?eS@qywDTYN4J7FuPrZL+z zM0=C-QLj0JC7|CM1`S(AG05v<=~?@rMWJz`&pIZ5n8KKx&Uon zYtEe3+0k}7k-cH204jEOg!%b__I#&mzKDi(dK_Rv{Sf1+6fX!TN|KqfWX%Q@^}JR5 zWOGl8XOb{R*%P43U5p^kta*F&1KB^{3mt8*dxuoZtuWVnTciD%9Nm9iU=Y;pQ!02v zu?YWl z?na&|k3h#Z5sfOSgNKzc$py8U?N=Djbt1tx@pTPEFEH@-(K_)kvm1VMW=jslYe4Mv zGFi|adHiGuj!Lt?{>7g5D>k51;$I8A_j|%HUqJ6|l^ypD!}90q{Io4YysR5?;!yjf zbsl;ZkWo-??HIcaLUG;%X|W2yojz+71Z<0Gy;Y!^pehZf3cc$w%LOiEix>rZ1>ABF zA!jc&vsFSr*vBIKRq|X9LAc&tT81}r*RuJjMu^+?M_o9McKe}Wc+8SCq8RjV3L(|? z`NawOBdOb?Bank!>?r(`6Mq+Y$Wlw5C(5oSiKj9L7u1FCE|!c~%i=7H3B~C>BxAA- zLvhK@Cj+W9$nF+g59P>lkqc;)B$_I4PnOkK+62B>2XpvmcVT+43|qY{ZZ|yj(k?uD zg?^590ed{5Mnwh{{zQefKYpxPyAf5_W3?^!6wW`NQ-z>WCfUIEPP9zYHvK$BZUaeR zDOKhFKX#(P66_LBcQ3LTxQq%01yxhoBy1W|)d@KanNW2j^zZ$`e{#aEtPkEHLytGBq}M^sim)C<>3B?z)`aXu@XE#V zTrgtw=Ub}Nk8;knneegnWWi!9gp_61iyvZuFA~oGUR(fTX^Kk9$y9aIlnzaWMv_fa zB7}dD0M3m!pr~Ux?({dJccQDiCTGO2Jj|PA-W|sW%`cfuCWBbX0wCTASU~NUw2BuW zC}*n4JI*#F7P?A<7X>**8;l!v2%Bz>+<{1iMLPVQkig>gF#SXTnW0u4_42oZ;FdYgJWIo1xP(vG9XV7 zaot-R;oW`RNLG={!b#cV;V%*1A0V}sWOvG8TFTX4@E~k-UjtL_1B}IZP8@^O8Nst4 z4|7RrIUt-5?OL3b$kG@00NMi7Qs5LQ>` zI|XjT!sqgdN^D3zGNDQmlR^vls*C1Vqc|75i&1F=emb>iN>u&%p{YOTbhngH5ifCgY}ND^!YN%EZtZK60u7v;n!8A-bfEU`}kc$QC} z>ju$%ct;5a#QXLob`gdD=MsP3^;*v7-Qv7%k%?5G?QerN-IQmorVuhxj}pr2;1AH_A_4d5%lnMV^Sd`{kR^>+ME(t%)g$5orHjF*A(7Y}3mz2r0@OP} zeSZb^`9uu`EJ9c}SZ184{)I(_B?ZqQdA3(rz(J&oY#P>)#R)%efk z8qqL%e4Z%hnrnkg+_QZ*M~x1txaz<4uO9#^gh9=O$%4&e%3W>8Tm2-u%APm&;4lYl z<{+wD-utdBljq07C$vBtSH&Cw$XfMgbQc?ux?V?8@hZfi_fKa{KZc|P1ae*r(QI!1 zgf6&&JL*w5y!PVtj+z>kj?f-_b-aR!wPFsW8buXAgY9(`0Y^=X_^>6>sedBow^jOs zQ&^IA?|J-JotX^p9OT-uP#yT9;3rfAONZ=l)O|ai_(d`jO=Pjqk4c^{+|eI81K+>J z&?-q~9x3TLBZ(HNNAr@wU;N;qP^}CjrV|1Gf3h^1;<`I>5(QloMQ(%bs+HULjih#g z01Wa{evo4{b`w%!vYBCyHdl1Mf=zb`Ja5N5u0NTFaE1~l>UsxdWBJ*R?LKiG&C ze^62@VkDg*-ieK)=>%BzdS?}=IOs6*yoL@2X<|9@gZGTpSHn}${)t=w6FeR}V}{?1 z>Rq?qOGB^L1WDFU>;m6#tIw!{NNFzGhJNoaX5K7wjJ(KVKMgU}kS!5!hcIm@sp$q0 z@~b=&^pQQni+J1(y#f7BF;rVWlVhlwNAB#s!wA8j3~USC4q3)bXg0psDKM@Z!RBuC z*(~DXxA}8Z!2^eWNG?99w}1RqOQKetlu}jxr?1BU8THUyihqt6KVt5_Wn`-ejApN5 zs%6zWf^>+$&2Ppi9VQ=Mg`VYVDad7^KrARN4gLb;5sXnN{>fc3^;MLjq{{OYbvE>( zp@ChZ+>-QaT*HP|NnSero9P0}F&@*eAdfd}Dr(#tayd7&^>Tl>(^Z*7b|;w5gHxJ% z+}PTwYm;R+E!}{)5P$4s+0~*zNm(4gzKax^Vb{(>7W_5q4Dv#zUlh~iuRo!A3Kp=JVifBI<bXF)y;{kYH~ND^Cgu+ZQ#Oh{db^MtnG!cNUEU?KsIQ$!9+)NC zWbPdY=GQ5gasb?Fakb`sp;)XUgnvv4S@e?4=C~~py6Gxo7lP*mOb9-8G&EIFZp_kQ zVbpevtX6327t$P}w9cXY_P!sVM1)t+Jea$LNS;_iDP-8EVJ$0nbhxxji%4e*KC3IC z7G7$?ZQW>0F6#odhs0KHSxK!imapHsOgJ<+2|J+2ECt6@49TXHF<*>MHFf*_1>@Y` zPAtpm#7z+nXJ`83gL;g(jq!X(DB2xbf-A3ObLMnH`EVCjG3dxRUnLRKR^=;`JNbaL{uJn<)W z*ihQKm5CK^mS(kk`%O z!16NQ(M;}8DxKORAI{Oo`{jp`xj8H}G_==FV?)Ev5xRMrzXyA)!)*9=AqHnGAAp#i z=@9`00{x}v4uXdN8Ilwp4#)3tHa=UcWxw8<#v=0hGlE0}>IitFJUEp})%t467nzcj zDGm)v`W^G|z;Uga-^K#?y@)9&IIV7pL^#2P$_C9<<+7MqTaLm--ag^~?AeG@~NW8WL@ z%fsbS`PTfxLd`-z+;$b#;g*puPVp)MB-v6o&>*bu+uibC2=X+GhmM;1`h>(p^rzFGzbe&eL&L*= z8cx!4kJIxKi}>pq_{yZJ9EMpR`%e&}si;UIdVdGU|3wsCs>yfeZMMtI3zcf{?x#y> zMCnU; z9Jh=Pex|j1-O$YB@KLH%*Br_4>9jd8eK6R%?(gmfD`j&7C@949q*GON3c)jt;o=4F zZ_r9K^8`0RS@QfpNAb8>rbJ}7-l`;=o0%CoJ}&Eaxuq|xPe3ZT2&%dK{UC9 zno_A2l5pX@A;_ZCq%zX$8S|^-?)9@0|MyJoLe1vi=IAU2-H{sA-v-9UWDFK{v?pxd z?k+ZoZjNR%L@wzSMbsTe zh4Wf5DqnDID%1=EYd#^uOs^Lx(PfWL2G6xv&sQm`An12_j3iSl{N#=(X&K8D`00Kk zk(dSnygAiLk_sYj{aCyi zn_8)#H94|Tw<>u zoTb2pNkW;GPCS|u2PFkMgMA=(CqMPpRh7DWhGqxOW}2uJiRlG7CB?UBxDBNU#*`{2EC2qFKr4woXLh?N+O-x!lrY1 zIqkM_`Gcth1NP%0deJ~n5^-@p88UCqZ<6%N@gHwcAP=;$?EO9eQqf`! zo%G?pV%Qat2*b9Z9vT^gAzobyQQv;)b$lKLKk&z@ZaaB)P8R*Z8FrbBs=#=Rd;ASw z_Lc?)O|R#giXJzKr8p7)2A#)2s>pcR<5zkg3$n2R5IwO7*>!T}mHV^9{n_gAa(zCy z__EMqt>(2X?sI=O5KF-EsJ-!Kk|?84Qe+M5(*azR+1RuZU;pvh*Yk;bVJGawt6Q!(Okv ziktnnFDW5Vk)0B*+2^F9 z9R?|N!rgi&jNtFle9^Ft@yDXwX~vMYGH9dYcefARPdt)UU-kkvihbjK?U6uFs*H!b z^ru#(f*07m4U72lhaWxU#Y%0`g*8_F;xc6c{e>UGbV%u4K&?Y#=w2NzJGM zO3|XSPOMPO_Jgnb4i)1Tvf9_PPWI~*um05NVvr8JJy!Umb`N2Z`G$a!uTCqipI-EE z>@XP-LpIAot{zv?QfUAbRQLms84cF&%e&`#F# zzGpw%oal;(Ta8zRmlGU6=lVhm_`kw3-1AeWsL-d6lQ|f_H5@*Y+G%qW+D~4imOchj zl}Cr$-~B?E@Vucp8h6F3MwQl!FQ?YwIq+G>9NAN1mpEUtpQG1=*W2AUE2-j?euHrw zK0z5dzUE*J04aW&+uIu6%$1SshWy?V=K-&g}Y*;l_M$ey-E0Kl<)py=KV`px1aG1AY*I&2yQS0oW}r zbg`2j!x9WFfvzTLS^Hf&g|#&swNqIu%>A@&_mXlR(CLH-h<3ZGa=P6A6N!2q(HDSF zG+!bcg|KfRGOD%;XFf{KNsbskiDr7x|By>(J}Nw78W0dV?BpYt9LpL&CaAQNo<4~$S5O`&F(Uix;u|`&>+~y?m`NFSX zlcWFfz_!ujfY)u89d)EN43u%r$xKrD74izjYdRnUACU#>ikDN`Us25vc0h!jctTa9 zg_s>}K995+-Psr|ip zS|NDx*=>?S>XUX&srwWLAQBwaMVt=5RmEsxPU`q(ghfiXe|SlH_^}qP5C5qKevzb& zRp~N~Ch)U~q>LnGbv%OHZ&X%WO?Z0xlV3IENj*-+FoUM}Eo;YzKjB<}!x%}jlJgH- zr6m&xw_ee1X>eAx>yaO4uDk-ml2v)I&p&%L-=!Udii)njbBPme!o9+=m$>5XEN>j# z`+Ya5(y8s-#nw2jyZz@(n!|{kse=BRj7>7N<}4--d-DCR0It5_f&@N77%}__vd_1B;ep!$?@jwyETY7w-rC3ud;9 zEo`_J)2IQF0I{JkuAe2bbj2A&*~VZr;G0(WGMvX)hN;~)0WV|zS8PPge4l~03k~Au zb3zzOnF7BHq6Db40^naovYeL#1}*J?1darQfx9d5SW+&$zBi)b%}B%H``YYAmuI6X zL5yj5bPQ6%jqqs^WwE}wd{gm{!bk6sWqfuovOK}2k=AXMq0?!#jmJHn*ZXzuoO{La z{Zh*NH%@}LzD5c8WO(J;Y?NxbE(|K&wiboV^+`e^JC>cD2g+XoTV7XPjgl_u#!JNl zaLT$dObX#czORsvmffLyz4@#iA3O~Ta=~Mj?wR&nh+PNB854tVcc!d<=eUdn4)NFU zuQ4-0E*&W`>un}CKmXth-oO-X*H*VJ071X_LVMq=-ivtFGzXfUQ`4X|hQVa#~H3D(BLF(n_1{x)q9Q-DowVA;(KOZXUNpQ>gjEcgn=iWN zK{^BH3k&PXmlh<(xGx`4Z{yGeCFaR}zAdmHF^tS@JRlZs$>T9af4EO*loxe&BQbR{ z9I&P1r1gAKfT><575YSYh@{Sr;}(0scl{Y*vBRkBSgei{Q_#^adTYA*p-?(TWgjOn znkp`Q{(cpo=fEi@<|Mh*l!ViRqu`FLB_kt%@+rkjkmjQpT5 z+0|GI>p?q^7_pEC;XU3F<=wIdZ+`zQy|{gkaD%E_#izJ;{PjN=%s$k+O9!l(ap#r4 zj%>1&2QxO!`lPrP>h$%Dm@+xn5Z5gehEnrYcG5+FGgZh*c?Ncn`h_qXd=(4=TpB-& zO%^_}NDMYvV#^2Oc6R>#4f~&kSD>-9aq@UUa=ygBxDA({e|}U5+TP9q>7#Hzj^ux> zhj>LtO-j^N%d@GU7RA>r#eBwcr0m|wUL@$z>2vfP|2>Ft9bQ=Ipvx)FuR3q`HNR`! zpCEj>hIEanWm-g$12}+~AR8*rq2Ka#R?@|#tounLSnDR)t_LC;yPjEoE_;~ z#6>3%jFMeQjs#N<)Z~C4{c9X59jqFmQ(e4%QfRisEW5uht68@KStJgGaa!CdaD`7| z?qp_$<`z*+^NB;J)exz~blIFil(+f;Fh?Z%#yt0ksB75GIeH~@h_bsLMe>cBh|IL7 zPiXgR&ti>p{U=2qT7H5}o5(M$9I;&LXK>=B1|euR`WEwn()Iv$_7e0hL)ghxk5#mH zSQ~U%>W%NtUCe?|jjz&{TS9RR-nKiQ*XaI+T%?yCrgTwn`a6sa&zRx;TWqM(xJ{%V zuwSrb0TTwi6fU^TwBda*98Dr7Xk)yTTE~5TtE#CxDZSLf5md7qpmj4`53;q0;`K7o zlRF6KRS{5;_0my%Cd}$kKsw6^G$v59=&LRYBOk(p!Et}PWeVDb4Hetm#^|Dytq_ys zi?DQy@2nX)BO{#Zw8yWEZE4@g(l7ucs?|a#b?89TY=tXu`IB{{vuAZtoW(R%q&4r_&ZLU&4}CX0xx0XWsPRfxZ}yFyOLrdlnsBjfePSpTe)@7M{_|tMK*eZ{R<%UMBckm>SP}bJMu*^v1=!1}|hk8VB+{ zKkPBT{tNWMKe-?!d%EK+8KOlDeLN2g4bOzMd@u}bu4i}tSpIs2a@BjFm z-|&EEaOaT8Di!S~F>S=Xje?s3FN$lr(4{>t#U*`*`lT3|JLclUp5qeKrbsHSC0?@wW)2 z@p7;kR;l0H8G)#1J%hUu3o+V=p44##qG-N9;~A5Tnr>B~J~5*wYqmMxw!o{l2oya0 z!f1GuRP%3?zZV7@MoRRDn5|ngagdmPOX99Gu8iYYQJw+ICqgcWXO!Vcw;uyxFLOqB zZUwcANZ}F@MYg*rXU%A0wcIrL+@r}pWayXvaAOxPfJzCx+YdOt11%A2E;#i35#dJA;4oRbb?4lZ1oD^r8etpr*Nk?)f z>HV!l7nOrIbcIIQzN)krT)@9@!zh`YHM*&8EnXZL!tgILgd=hhMnA%*uKF8>_k$ac z;oLxUrxGp5uifck*5c+wg^r%2Xp(n13hHX(IxjuKVF=_L6RCa&dhCU-(q^1BJO2LK z^_6mAT3h7;o`5U^)jgM{!f;B1{;~m+Yv9G0p1A6Q?a)8d`r27mb6G597nL1ArjQ)m zfE>ei>x8E#+=dSq_g5&9yi{}#aGSsXZAZ7t>Q<)`Jg9Iiqgnivfx1!!V{v(6$63q(NLA4<|c8f09h-}Ie-`eq`D zBhUpA=1Wxl0eAU2M*=8mT6heUlyZOi3NE}Qq3G{~Wq=3IfP>;+3%|wq0kgt`_&sSI1WTo#^6P9Olg9IGZj2=ZJ zjvum-Edm4WmJACA^BsJ$%2T33=g$YrE6Isa3oFE`?w8dUrZ`-Ruur@{h24U#X4vuD zT86_-#*)cPVkcZ=xll3~Omg|%O$Z1Ge39rPwHPgEXlTyB6r@8nS#69h?crOcB~~&3 z55Q}PdFptuCShdUqCpBSzp+@Z=@!p!jGUu&lvd#$(Ze!Hm_vJSs3+NPA1ZrpIhq&~DD{dBjKo-*tb=T3( zK#^GtbqUmBJ9y}%-->E*ga#R(wB!Zc#O#G`8`(8HD{#es%Euwgf~TDwJjwp4?#EEp zMYQj$w#XtQqu{4HyW%S)42nLHkBGkbnO8GjS8M=WS|88Mx@9$^{3g&~<%Ot2;i_dZ z!%uW?j!RQkqibuwwC2eyK$17G@oqWTnR#z6JxWs(0YYe91ALd$qH#44h|T(r-;5f^ zsio$3@iJAr>QT=)x_iEgseom%@dIbxu42sl`>p8>I3CJRY6$faSdpA(uF2>?Jhd>J ze!rDZsn3Z0<%hyCPc-NO_a%#@Qj4oBon*1V?V!k)M+YF%l~v?N$rmn$0EtPLT?nZx#7K z1MT=gwZjs%SgMUxen})ai)l>sos^-e88&2z74@A>GJcyF;y)#RFgFz!b^aBT0){63 z{bCP|$rZ>XvS9QrO71@)Q~s_WUk{RLUhz{QdP|w995NuW^cuk{s?B+_Lx+*D=+YZ*v{@8v`?1ZMUHtd8o$avm$;xOT`;78MBwya15uO_Yr7NB+LQjM9iumyRS>)z7{>zKN z(mA~AyK)(0n;RC~R!zIw-?K_VN%NXlFFx2V53cdI&6##?M9pug#>4O&vKlvEAtyFB zNlZs$gL-;|@>RKFNrec37aKuINf`O!NLaYI;jQ-TgCiqhDwTx2uYVQJHoG)Q6{{l@ zUj>?JnPcxpDz6C>1z$)c%1TWWPWjz3?)Wn7B3PJaOjA$!eCtx)qKJP-zTpeezuTT^Fi|@x?P6v#ngjcd|o(JCvZ2^Nb>>j8YXTYFl$Lux8Mh>GffO9nT6|J|6 z@u{U~0{VAt)|CJ!yNW1(1f6snYYMXLrSulLMhYW&T6%Ui5eE;?QF#@rgoMQX6-dHA z8vEd2GDA^QGXqR{l#VB!sMGHnRndSan0l|ix4Y%WJ3RCaJOA*8AnKlpJ8*lX>~78^ zh+Uc8a(~awex!TxE8x>TE!WZ%&1%DIz9*Eno2DGuVnJOUg!{BIKErrAB25-+e5olm ze!<9XM0tOt?4$B}3*`Rg%Os+K4e%i%nW|&qG8Xc8NqO*i51JyfGoV#yJ-k=L&6eLJ z(J)`UC%^eVTa{3tXQqu^hnZhLq|@mfzQ0@4n8fip-J ziNl4Ojg~I}-Y`7Pd+Ncr>6?a2WBiMbv7!NFV7pAmZd?6BHv_lY=?|DwlzNjtxDR^g zg(Z=$dQtfsGA4V$Grr%UV4!4w&);YQRTMyj*$_V-??jDE_A0`p)R~Fr#F9K_K!iP^ zZi;ABeiy^@f&0SeWsrrJ@Hfr*uhjzN&U;R&dfY-@ z|F3~h$Z)>5Z1qSerls{PCg~G)yj*9|?>DGB3qYZ*yDg?qT?qot`9_h}F+l53bzs_e z3Cx!BkhydcbRP%4!`a-JFx@&z3L%n8M}ytDJE2SwQM74(9Z>m=%FV--LKQw@k)!=+ z=mm)pyD8oV`?|^1LOp9^KIzphls|C|{JBL)&1d{1!ZMebGZ^=|k|791vQ7Q>AuKnN7&1JT!3UAL(WRl~>+u_wPZLgq@qbLO zn-#>0?^3G7f}Pg+@L65B9F}t9Vzy>@|4tIe68$EFmQfi361{_56!97w%4rg_;%^C6 z@pR~MB{bAHJ|2Y=DL?~qXHC}M&? z>i(*juh0i}US*ca$Q%>?9OH+zX4g6I8SfR!CrN8r26uqVVsiT6rWqm<|HBAEM>n(x z%Q}iB{~tM&qWv^N^#jv_@e>O3C?tINFm=c*r*~6$2Wm)^2$tauhcGmqVqqC%LU-&ieLQaV1K8pCM!41sU&^l)sJaM|c4PQQ2dz_I>QJIu_Myh)_ zF`nqX{3SQQ7K>1cno3VDH10ci%8+Gk?#s7?BFj7v=!Gt)+ zLYX9c&Q?Vwr;4dc)x^%rwNL~QLIg;CsR}H4o?!LuGok+GxDwq{?y&Rq*N3t8=@@UL zFBM~1zBDhFUcC#<8o$-&FOXVDn3%_W#Qs{HZ1sA{4DOCE28uXh#2%WWd2stk}+ z0GWpS`u;&zx!;}}BL28}S+8y=RB`viecarTgF_u2 zAXEP+kyl$B@;3|s0xD{MsnSg&!}eflq{~XU`HP-N?@|0d(aQB6i&o<@0n+wE)GG*g z3C%YCav(={-SB>a7*4>lAC^_hSpO zwIwabTgS3CjR;c)#>lJQyQ%U6l=c}s2R@d|_MPavz8E7p?|1X-KO3KL|L$+J@Afu>QNkNaXMcZ>mU@ z`pn)F;$bacD9QedG$-=)jcKoc5F>k7fB-G!A>z%^?~vk-9x7!MmN(Ky+Ut#`-$mM2 zLs)jw5n^_Ge%lZElhKy5WG~I=t1sF}F`sTt6NZwva&-y5`cEB*(0Z`2-VePoqB_bk0$RU<24Dyd|I)T zDbm_ECBr4o00RD3<{1)Z*>H^R5b*Te*uNnVrn$hUjtY&BY-rUe*8Sgg^35Eva#zwPXll|{;qJ9s9V+owZx7E`8@!NLV~wS!-0GP2fTrBAEWLb_ zzZ{n0yBfdum&LN03DrJu^xe{)O*JJ=6;yHwJaH%S*=J2D>SQ&d{0*CgQiWfVY{Mhs zHAW&bUP;lueArWU#YRsICAHh$us*x_Dx`H&=%c;R6R_0 z0Dg+k5HgMLB<$O%LY7=Ye&+fM4igV{qHNMnYH|$-b2Qm`{y0;aCkEqx$_W#e@-En^ z67oKGsXYj2W_3I>%_zld4aR?CT0^BsiHBnQRz{dN{iX~?HY~>y+F4giJ-Gh*F(ygETur7Se z@oXlDJdCCBEc_UyxkH%PA7e?T4S3ht#$#)fSoClcZ?h%{$-K~$yF2dH3Z3;I{)Sw)b z+um*Qr1q@i5vnfoA5d9X z))pZa{6D2d=vAHebAs&nVwZViB?BKnaUL12c8Vm2%&l(6R+JN*Rv9qbm?H-4>{P;p zH7DILd(UWm`YXcMekeSUOAwxio;Qyf|D2_DniRoM)Q`Nq{Vh_8_m4QCMgrwO#0k5j zC|Lh!6S^aS{|S*LFO#NA!lk_uV|ovrgKXPhg|XntMh7N^8je9Xi!UaNi|`1y>+$iZ zM<4@8G)_7&9U26~D%TP3nzy=GnSAjc^usdG#kdL~3+VhDO}fNuFkHB;Y1}PF;vWtp zrb}xAD(=+^*cT+$KWDw45L*#U6UA)7!NL<3-@cP^+M2`hFwNg7Py$VUwP(jw6WAWU zj0o9Jqbs>aU1{CLC&d*Yjl_=1`!K4nB~yJ$En1ZNXngiG>%zM?w!p78Itrt|BP=lP zWk`qPv_Vcv0)$W1!(nvxmM9n?$pJO}#VPlFuRHz2sCT?~dkDpT6eO^Eu%V1;xG*M2QCXm$8lxc0&t~`b`Mu~qZaYB`Owc< zzxxf-!rEl2v-P(b%AGfRivP`O*7zq6$30n#wGO`O;?2A}_CJ${Io=anj#7j-kM{T+ z$Ak8UZ9#S;aqVYCy^`>)Q{5aKXSM^1id~IMYqeR|8}l3SebY-Qr!$>*7h}&_pUgrO z@3i5I5$)PCuyh5cQnT=ZMsb|q+5JqhEF5}ry>J?Znkc&By*ITTDNQYY4<*KFo%a_t zK^01wV$!!IiL0SNgQ^l zWjEn>*KJM;c>e47S^PUw_L@Io*HwBxv&=u6>SyvaT12ce^Zm|tdUA%eQnP(Q*`287 zeLQz#8%za^!#r9G?Ntsf)o9ii@!EpeN3C@A;gNPmS$2*U`05u7q<3bvNm(Y(4~x>W zhVHJ$k}aWfOysPFz_3UTRc&biye0*9`dK?(7532=Il0}{T&2A%DHci#{&$skZM~-g zaGpyaN561tQy{4#vB3FNg>rWGTLDb~TyfnhI#?|?izUkB14p=|#`5*4J6u_fQ@w_& zc0t|Nb|+-<4FNVF1A_27?4=>swD))yk%DA$@Np)#S!s`$I%bGBBr=ATm3VPtNOe`6 zLDQZ=g=&rjb!ip!q=rZP@>j3A|cnqajqvwpf%^JY_4V! z0h}%)&;kCdkOhTQNBY09=RXUX|DpSy`1fC-fhe7KG)+m)Kgx)rD6A`r9k#sDQc5m* zh+aVbla9`RDBH%RtL6M~U_Jt!s1!8jT*d_zIUL4EGSs_~uB66KbNY+nLarwpJk6U$GSUM3&F zuARR>$$*kKSHG@xTN1Z}qcOZ)xO-Qwk#b+$BzKv77PPTKk>^_u$gsAaNcCkpjlO5Y zFEOmtq5;f7#ZbTJ%T=x?S^7jZG@jVO-1ANG`M+_A6Vu33)cx4cUAU znw#+9U3S%pofU{1;kBdhUb@aUCPFpp{LpYLPQn z6r_&3Jj3o1?VseR;fKEfcdsVU z)mjQXCFzqH$u(q}lv3V^guGk2Ux-va28V`LAFube&rMZb{yJC+3o(+>h%dcOPUePW z&V7)A_e3_gAjp?nRuTWued=|-@yNGJF=Z9kXf%Ct|L!2|+s$F9$sc_L;_}K*P2A>^ z9?Q&oJ3A0y1;r~^xge{gQNv=Q%DVcl+w05sj}SfJ<4rTq!oq^)LqT3y+b24m#(Ouv zr}e5hAGy-X*Qm;)_w9Zi2)t?v0GHj3Q3yGWz+`7*OgVzPV=alu5tCNaG1RB`l=HET z7x$$a?bj|@xzDaDbK(zNQ;LoV>y=K+o1v+33Etr)Qy%AQVK@xmL_hl)qI~-{Q3&?B ztE(%~>Tk7=>Z-)rBXHWViTnFzPt94xCnqN>P3Fk{k05yAu+Q@MpCl~FUf0us8qL>!hgj4kxM zbl+=mH+M&3=DNLHeg96-{(Ylg@54@%kN;<-8!fhuGXnsSafDoh?{6=SMgve@U8yZC zoWueiu>tUOblP)zc6K%0ehD?Q>fB80kJqW^8I0z=M|tE&XyRght* z{-dP@Ja;*=j``Gu+3_~6U4~ImZSoJl~Yl%1Oq{4_xJa{ zNR^6F;0UFFG-S0+*P~%^DL1PuoM8R7?jv9Eu%l3f<7p{qcjT$;|h@?(6!D1T5s9Y0o&+ z`+UU?R%O_m3%f6bROrpY`qdwH?H3Y%#d?NlOk@o@tse@2b$JE2LK)-~ydYn4L>cMM zJF=uqLXPhTp*L;Rl`C0NM+#~JMeDag@fDUAutbBp4h+%8fawxW9;Z78Wt@YM($2F% zHQ`%OAL@aYk7ahI)Ph_O(6Vm5wAr<8gU_LI;woEMv9?FJEQ_Z!_1rH)`! zd|4#??}eYGYHeM+0~k(abng1B)03vll^7F7xX<+VeiGT~LVmwP-VpttegN7K=M4Ri-{NCh@;C8Z~P)>`Uv zCPQ;u=LPEeaB(YP9F}h3)kckjdbP3yI~)t{bt$Q~bN_Sha39Z|_TLH!66<#@h;?6u zLqfMYxeWg-qpwPfRXfmt!Z_& zBrY2>;4v~hLZ_z)Eu&#VY= z#XoBSB<6+`4Y({xy431k$6bm!OnPI^4E7~NK1_z%pqoHLR+!3?j->_tqM6k;mX%7% z$)`PDzOwT%^Flt;Q$nL9D()qLZ4~t@cMWtUVW}_O;U<933K*g6_2b=R&lMea z#!YBx#jiODbDD&b^HC~4t6(@MVM1SwJlBZ|WnBWZ(oR3$h=IH`QA*CoGyg1i4eRG= zlA!PpRm>L5QdHJZ6v?C0ooziRst{$QrB?kCb0g!*hp)qOC~pUsyLyV89tT_~j`XJ7 zm~o2IX>|2yr3hVi!4MFUm`IWR6YUvD7gN`|@Z*m5lS2-Y%8rkI%TH}iq80ZS^=ZoJ zecy_L>?B0%a)gu=0Pde|(kOHW$3tz_Q2iU|W$lnKlrc&MumQzS%iL7eR8WzSu~TUj z`!*;qKfs)XHz^{cVs^ses2knsKi>g+OaVs3+J38i8>R46uXTFNVvC2=V?XHp_Y?3G z&2Ow?P>GS5*Oa~q5kq8q{;(3w9gv90J=@}?%COASV!{&DuVN+eb6BhjFMPE1iaeBR zchG3{(2?`Bwa;_J*h=U@x&rVXU_wIU4BWK=f5pYB-6igN3L!wi&j%VEvxNSRO{jX@ zr4p`p-wQaghgTpbu=QX9znzm2W90!}_M`b;ya)7G3JJ z^2}9Vg-8$kg6PeB5s>=XzW?M>_@J9Gd>ne92h(^ziAUf@&`j*m9obUaX;Miq8-(}V1wHN8VUY1s z24iGUSDg)X)9Bi<4-yb!KTo`J!5)Z);nKCO(8U92=9a&`J<+?YBk{^q&V63#2$KYM z7Ys5knuPLZ-3QG(PaLhcGyJ}Drz{U4ncc2HyLYnKs{bW??qFEp!V?$25!3gh@%<)_ z{bG}Vn!5VB4x5sXkLWJ6ioT}4ep4rmZ_tOJbHQ1xs#!9YBT{QH*3*-3GRrr^=48^1 z?A6fdhSV>2?wB5bo?u?u3lrS+Wuk6`pj<=ZtdU`JT3jdo!e&Vh7Mf&*wzOAIRIuiy za+q)WHCWQjUC(O_>+x=&YAWY@bT*IrxTSv%n&I)@l~uqwgJ5KSi_Z`+XsxH+g}v+bH~PqGu%6F|;Wb~`CzI`(@J-@OM=PeFdAezc!~%SZ^Y zyN<*?(^@{1M@q`<7YS*Y^V8T3+y!|!h7v?tk!w$@?;s|@@sGy4+g!OV-K)MzFlOiJw&OjYgRWejRBef^@yOZ;Rk7ArT80r3AJzsg z9&eD&d!gVA+Oo(JX(*}(Zw%VIc$+NnKk4yhPHJ)QZp~uqDpT^pO0Od}PQ(hmx%2}@c=Tz zdT%(NC0Q=3#au369(Yx(jyccLkc#9GVka_sZ#UpdX$ZolM z^t@*eM`7Jtp7l-n2pQF=Kz2SSg=s$MvRz(M+s=*+J`JX9_BmtA(yn@AVq!R$$Y}@! zif73tz`kj&LC5>{%9Q?y)ytq?EL$T&`_nq-bmB3MOTwdq5q4c6`;n^$IgA`9KS=?% zJzSpK2Uh27za+){yFW3y945(ASzAT4nKyGS+C-c6RNnlE<{^PabOK}KR;?uf6dc!8 z8ZtebKt8i2D;%mv*EmTz*?z@?=WwHmZXC?imMmJ!y?$?nd$0zomSV~dg+BA1AJBrkA zPZ|`uDjA*^*j5&8#+DUnjGh?uM<^Wxv}J`eT9>CO^79A(Dw8Sf87lsm{>~MChm?KP zDj*OHI8xxULyC)(hKUJQGx+FYpM*-AOPh;A%1J|-Nn@9!bmS?PK zUy34Liu+AsH4TRcpuBvv3aIkvhGc)@a<>sc)csplLvakD2}b>~4vd%j9ZSZ5wHFcx zm!W~nas&WO+|{kB$;vii>f*NY&MPGU*I@K9S$%y|R$0AyB*kGtya^2WGMYa%?lr9^j`q9jJPJqn(DZ~k z8(xkozs@~4TIoW=#T~uiW@A&OO2A0fUwW_}jEsuna#`vLCy5;~X$h--*3PgYI`V;O zu<$RfJ1K(BdZ}ld-N#_f8!yz~?9(xd$0Zp)l4C~Lr|4_TyVz3~_u4KfGpfa@E`rL~ zYxOsmXnwQQ9UqkRp^<(;!Gb*;n;C@SmutA*=V^hwJ)Vkm3OSonQ2X6bUCDgmKdQ9a zQwy{`$~ANAFQfa!0%&>oAC8Rx-bj}3D~h1hTqDN|;05ID7bK{TcB6G40XQ*>#5y}l>pL0m zauHoC+?B!n=|2Q`roROEf=xCQju@t$*^QAQ4*zO~%XIu#V<2<_C>(ZiRb0~1-w%c> z9AQ~>12ij3ID+HfFn4X7I-AH0YoxwcQ}fu0R@ii@Yb3jdDyrueOY#fy+Rn^>Hy~Cs zub;)XT5LW8++7<~1_rCA_@mMbT3pZ*AK3@Yl-qLy-p)jy2^@6zjEZ+;hLOQTY6I8x zy8}LCsa5`dk%rMr{4jJ_1cHjew|#Lyc7DH+Coez(`*+HCgIUTcg~EV6Xvi;;Y?7in z9+~AOfSEmWr)W0gOpp)2B!LABo5tZVs!RT7;Tm-T`k>y#Guf)RaKF`orBnvMsm8Sy zt*Px&PXW84&M4=yP6`QH{F<3hA*shXK37Z52lMXEsm2RT?e?o*58K+V+vvr~Uiiu2 zmvh)CYP>L5i|QSMLSsC5d2IP{ZrZr%)@B?dT@ee$ohh6|p7vf)?sr{F` zRUrKm8Qe6vK&CX4`N7uVZk4bJP=M1p4jV9SZ6!Q)v{4Yqyz^ive3j<(_3_Y!zz$o z{B}{TZKxV@i+`RetaiVrn4H?J4Qkv38@@irN=%>|YCU2N^cq#`mSq~MKekMaHG)d6 zoa^7?CTO#s`^hkXhc??80KA)gk2@jFXP!l=VQKlL@}rIZSe+V(gEQB9`7<8%U>sos ztdGg!*h{eLnD~2g?6&uL;jKloWl>*LjA|~%Sra*n3_G^82Eo~jlUoO5yAxZXomA{s zS`ruHPp7JFvn?b%HdwNf@@PbvkPY8CKl|LBo$0)WJT}JRkmYj2{(!1lOnB4!WJ15* z;=z*C(~-UPhDSy9g{5|N%sCT=iu(6I11c@aEm!PsRg)`ZC1-n6^O8t3vDDmanF3d0 z@5oQ9r<6fknhvB(+RyL1_suu_0DGZo1LW0;lA#xAM`2&KC`wW=*JGl}=nZHi@N{m@ z4ZI;vKPulbHkB;e&Bl+L&bfh0MH>O75aW8Mm07cZ&ku~CXEq8V|Ae;uC?7TvPsjR` zX=L6s(92;-5e$b7++$Lty{{ArAb1Mfmyn_Xp9cHBjB6QZq#cNO^gBxXsG~U@7=4Vq z`e81u{kKHC6bj;IS%_mp}nWmsPQ?UOjHq_v}gz@pK@U(bGou6AS?yBzy5nl1TSGB6jgEM(x& z+I)f!lc=ncmh_h2w9|E2D|z980-Ddzu{I?-RF?``Jp4i1{+Ps-m>ok_!0Dtp`O&j) zT=ikY9V_z#!l4o!iw_#gUvf%MB%_QnSuWhehfLs}3>jt*$x%t$7GCv!x>F- z`BlSDeX#{WjzWbt(az%N7nXDT*P7r6D zyI>s(NdqoE{NZUrF_iXqAU zvD+(PLX`4?9-9_%gu+OOB<@p4+RD~sSwk-JKw%u24mpy9m#%U=$^;U}qo&4}tfGlX zv^Jn79JVjfJEF?BghE=2GEh{laJ}rD*A!>9?qd!4l33Vc(uM1@$#kz~Wd@YiTSymM zn}QV=I*8R6-rmBTh3iHzhV|lqUap~WxM~O2rJ}L&YQ;`D(AAmFMS9-cSVieLP9U7x zEaw*E)y_e1@fhB`+ede<=NHjUFBY_AWAN_ggiRl$oJ?7ts1-zNOxUBX%mG!yj zB!klsm55`o9(aP%7GF#S`m~x>Fs8igE6E23iP|JW;XON@;*=mQJohM9^T>| zqRZcd)A8hQ;eY`E8j9=y26CQiwze9!-5cpRlG%P8H?*;`(F@^CcT$2h#V(68>mkYO zh`C^0{%Oa5t} zjK-W|?m(>k8E(q(I1Cb!PiU*}W2PV*@d$%i0}bT$))Q9qf;P<8B+y>3_(mQAl6JOs z7QGOKFB$lx_P=rmQKx}jM9khwd2Y)_elOvhp78Ew=95XIDDht{ z{Ck=)(ci+GREz&{dgq@1bYPX>G^U%%#)_hZ=d%%DZ&sQ&%ScpHQ`2EATjrLq7=pie zUUPiS3H|t?6gJ@8%iE>d1rr?A^)FXvI$apcN&)V+uQCGTA{ZdBVLm|ag_I4o7cmhd zI3r~WH2qF2$z=3ryqmR8HTInb6n=x>>zb~%s)dtHpHRSoNnOc^IBh0O^J z!Z-#G9H4^KOzWFTHwBYUQDeb(1 zNj{3`FZ-#Tz!`36%P7u6eXW3InPgyPI>r8aDb%lyG10LyNb|s~)($hmSc)PpxOt_- zG$E~|x7__#agwDe7RMy{{k`>tnlVY2&|>>IjB;J4n#ONd4L1>)`}yl&kE5T04{u79 zs}FKzf9@SWCpVh=Fvp32z{yzzYU_~*pV4`z$<9=`nuj()Vn2I zUTp=UZ}rL_@K9GKoTXMvv4vuWOq9B{a4jM4oDGuGI=YM4n=UfI5~fC%x7=PJ$y?Or zWV`XFbjX8fJ(EJi+4JHz2u1%z`)|0Yd&N^~lC#1LdQ-kdYubDpm4Zr5H!?^Wcvuek zC)wX9mB-lonNoB{$X(Bs@|_3K2($Gl>!e>?QVG|bV6?o;*o__GyL)|?o`Bn=#|_J{Zo$4W(ktvPAk_`HyDvH+th| z<#fel?biYGuDm?R+P&=z#bHMq)$_RGKhId6&~}(MysJTdNV5zAB=FLGQtb$qy8md~ zMn>9|gjVc95spWuZ$Xj%fRKD(f%)T_o>x`BD%=?yk`*H!-0Vy+H0OtQ6Xn!JSWH6I zy|FGjHRia7X8opC;eJ{*H1sR|PW1C0tFUxQ297yTD*mwvYtClU znoN}Ip|=YaLs!G0we?GH9-<7f=KB`nE*YX2W&$}6CbRBVPZHq-^M7ab2(^)aQ_?oq zf8n+_ZD!qlm`6->w}J5zKy^71=KwWF?kpX!k*viU8+a~^@wr+{H`B5PrfFO zMSkUVYJYLXO2o4@DU#Gvcx z53{XOK}L19=u;6aU6%KhHvJ(ME-@z_WXRRjhcWj%M|t(IQe%zNfSX=N@Lr2L@mF;q zw$OG@1gfU3uVm4^S?##DGUIR8HCjC!a$K-3(L|UUwBZ6<@y;1Xy_WqN97KqhBxre< z_Udx^xsLATD!K%mN6CUaEjVM)?BT?SL{Fyot;#g~>w8vGJ>t3j|ANvd(lp}qwPRYh zdYqn&$M4ZQcevaJH>|S5#59XVvn3h zc%CuuC^Pj_L(LE=C#R5f2TnbDG4bPyDj0{wje;Eh!ss_`#D8B7-#}xXDYZdLUD3&R zAp&juDUX-vhVQ*{yxuY-F%M`! zK&THtr_|(t68Wf7PoC3GQ^T>D)%EpCE-pM$dLCQb+ZH=h#kYj7P%0ko3Gb-m=Xpvgj diff --git a/labs/14_exceptions_inheritance/images/single_inheritance.png b/labs/14_exceptions_inheritance/images/single_inheritance.png deleted file mode 100644 index 9ab52617982bdb67d6796ab3bcabc72d6eec630e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14139 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 IW*qdt0G*sXU;qFB