diff --git a/42/Piscine Object/Module 03 - SMART/README.md b/42/Piscine Object/Module 03 - SMART/README.md new file mode 100644 index 00000000..375ec0d5 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/README.md @@ -0,0 +1,93 @@ +# SOLID - SMART + +*** + +## Single Responsability [S] + +This Principle says that each class should have only responsability + +In the context of the exercise we are told that a car can do the following actions: + +* start(): starts the engine +* stop(): stops the engine and applies the brakes +* accelerate(speed): increases the speed of the car by a specified value +* shift_gears_up(): shifts up to the next gear +* shift_gears_down(): shifts down to the previous gear +* reverse(): puts the transmission in reverse gear +* turn_wheel(angle): turns the wheels by a specified angle +* straighten_wheels(): returns the wheels to a straight-ahead position +* apply_force_on_brakes(force): applies a specified force to the brakes +* apply_emergency_brakes(): applies the brakes with maximum force for an emergency stop + +Given this example, I imediately identify that the only responsability of the car was to enforce the car actions.
+Nothing more, tha car is only the concept, the car is the enforcer, but he will do nothing more.
+The respponsability of the car is only to serve as a concept to execute the actions (link the car components)
+ +*** + +So I also identify which actions are compatible: + +start & stop (both affect the Motor) +accelerate, apply_force_on_brakes & apply_emergency_brakes (both have to do with the speed of the car, although also with the brakes) +shift_gears_up, shift_gears_down, reverse (affect the transmission gear) +turn_wheel & straighten_wheels (affect the wheels) + +The only "tricky" case in this example is the accelerate, apply_force_on_brakes & apply_emergency_brakes, because they have two responsabilities
+Change the car speed and actionate the brakes (if you concider that applying force on the brakes is an action)
+For this you can divide in a third object to handle the speed, and other objects which will use this object to modify the speed
+Accelerator will simply increase the speed
+While the brakes will decrease the speed according to the force
+ +*** + +## Open/Closed [O] + +This principle basically says that the code should be open for extension and closed for modification. + +In other words, if you want to add functionalities you should be able to do it without changing the current code. + +In the case of the example, the Command class should be designed so that you can add Command derivates without having to change the original Command. + +This is possible by using for example the protected properly and virtual, so that new Classes will automatically have access to the Base class and can implement method calls over the Base. + +*** + +## Liskov substitution [L] + +The Liskov Substitution Principle (LSP) is a fundamental concept in object-oriented programming (OOP) that states that objects of a superclass should be replaceable with objects of its subclasses without affecting the correctness of the program. In simpler terms, if S is a subtype of T, then objects of type T may be replaced with objects of type S without altering any of the desirable properties of the program. + +Let's consider the example from the subject: a superclass called Shape and subclasses Rectangle, Circle, and Triangle. + + +Now, let's examine how these classes adhere to the Liskov Substitution Principle: + + Substitutability: Any method that expects a Shape should be able to work with any subclass of Shape without knowing the difference. + + Preservation of behavior: If we replace an instance of Shape with an instance of its subclass (Rectangle, Circle, or Triangle), the behavior should remain consistent. + +*** + +## Interface segregation [I] + +The Interface Segregation Principle (ISP) in object-oriented design states that a class should not be forced to implement interfaces it doesn't use.
+Instead of one large interface, clients should be able to depend only on the methods they use.
+Essentially, it promotes the idea of smaller, more focused interfaces. + +In this case, the interface of Employee is making sure only the essential methods are implemented by the implementing classes. + +For example, calculateSalary must be implemented by EVERYONE because it is essencial and each employee has a different salary. +Now executeWorkday might be similar for some users, which I identified. +There is a generic executeWorkday which just counts the day as worked. But if an employee should register the total amount of hours and not the whole day he can implement this method (because it's virtual) and change it's functionality, but only if needed, respecting the Interface segregation. +Others might just count a day as worked not counting hours, like contractEmployees. + +*** + +## Dependency Inversion [D] + +Dependency Inversion Principle (DIP) is one of the five SOLID principles of object-oriented programming. It states that high-level modules should not depend on low-level modules; both should depend on abstractions. Additionally, abstractions should not depend on details; rather, details should depend on abstractions. + +In simpler terms, DIP encourages decoupling between modules by introducing an abstraction layer. This allows for more flexibility and easier maintenance of the codebase because changes in one module do not necessarily affect other modules directly. + +Instead of implementing the date method inside the classes, I decided to implement another interface an IHeader so that the Loggers can choose to have a header, but they don't need to know how to use the header, or what the header should do, they just use the interface, and the .header() to get the header! + +*** \ No newline at end of file diff --git a/42/Piscine Object/Module 03 - SMART/ex02/Makefile b/42/Piscine Object/Module 03 - SMART/ex02/Makefile index 529b2573..dac70e29 100644 --- a/42/Piscine Object/Module 03 - SMART/ex02/Makefile +++ b/42/Piscine Object/Module 03 - SMART/ex02/Makefile @@ -9,7 +9,12 @@ INC_PATH = . SRC_PATH = . -SRC = ./main.cpp +SRC = ./main.cpp \ + ./triangle.cpp \ + ./circle.cpp \ + ./rectangle.cpp \ + ./point.cpp \ + ./shape.cpp \ CFLAGS = -Wall -Wextra -Werror -std=c++98 -pedantic -fsanitize=address #-O3 -g -fsanitize=leak diff --git a/42/Piscine Object/Module 03 - SMART/ex02/circle.cpp b/42/Piscine Object/Module 03 - SMART/ex02/circle.cpp new file mode 100644 index 00000000..197b7598 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex02/circle.cpp @@ -0,0 +1,40 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#include + +#include "circle.hpp" +#define PI 3.1416 + +Circle::Circle(Point xx, float rad): + Shape("circle"), xx_(xx), rad_(rad) { + ; +} + +Circle::~Circle() { + std::cout << "Circle destroyed" << std::endl; +} + +float Circle::area() const { + return PI * (pow(rad_, 2)); +} + + +float Circle::perimeter() const { + return 2 * PI * rad_; +} + +Point Circle::getCenter() const { + return xx_; +} + +float Circle::getRad() const { + return rad_; +} + +std::ostream& operator<<(std::ostream& s, const Circle& c) { + s << "Xo: "<< c.getCenter() << " Rad: " << c.getRad(); + return (s); +} + diff --git a/42/Piscine Object/Module 03 - SMART/ex02/circle.hpp b/42/Piscine Object/Module 03 - SMART/ex02/circle.hpp new file mode 100644 index 00000000..ddd294a2 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex02/circle.hpp @@ -0,0 +1,26 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#ifndef __CIRCLE_HPP__ +# define __CIRCLE_HPP__ + +#include + +#include "shape.hpp" +#include "point.hpp" + +class Circle: public Shape { + public: + Circle(Point xx, float rad); + ~Circle(); + float area() const; + float perimeter() const; + Point getCenter() const; + float getRad() const; + private: + Point xx_; + float rad_; +}; +std::ostream& operator<<(std::ostream&, const Circle&); +#endif diff --git a/42/Piscine Object/Module 03 - SMART/ex02/main.cpp b/42/Piscine Object/Module 03 - SMART/ex02/main.cpp index df628168..9f116a43 100644 --- a/42/Piscine Object/Module 03 - SMART/ex02/main.cpp +++ b/42/Piscine Object/Module 03 - SMART/ex02/main.cpp @@ -3,11 +3,54 @@ //***************************// #include "ex02.inc" +#include "shape.hpp" +#include "rectangle.hpp" +#include "circle.hpp" +#include "triangle.hpp" + +void printShapeByRef(const Shape & fig) { + std::cout << fig << std::endl; +} + +void printShapeByPointer(const Shape* fig_ptr) { + std::cout << *fig_ptr << std::endl; +} + int main(void) { if (DEBUG) std::cout << "Debug ON!" << std::endl; - std::cout << "Hello Friend\nPulgamecanica greets you :D\n"; + std::cout << BLUE << "- - - Normal Rectangle - - -" << ENDC << std::endl; + Rectangle rect(Point(42, 42.42), Point(4.2, 0.42)); + std::cout << rect << std::endl; + printShapeByRef(rect); + std::cout << BLUE << "- - - Polymorphic Rectangle - - -" << ENDC << std::endl; + { + Shape * fig = ▭ + printShapeByPointer(fig); + } + std::cout << BLUE << "- - - Normal Circle - - -" << ENDC << std::endl; + Circle circ(Point(2.4, 4.2), 42); + std::cout << circ << std::endl; + printShapeByRef(circ); + std::cout << BLUE << "- - - Polymorphic Circle - - -" << ENDC << std::endl; + { + Shape * fig = ˆ + printShapeByPointer(fig); + } + std::cout << BLUE << "- - - Normal Triangle - - -" << ENDC << std::endl; + // https://www.triangle-calculator.com/ + Triangle tri(Point(2.4, 4.2), Point(4.5, 8.2), Point(3.0, 0)); + std::cout << tri << std::endl; + printShapeByRef(tri); + std::cout << BLUE << "- - - Polymorphic Triangle - - -" << ENDC << std::endl; + { + Shape * fig = &tri; + printShapeByPointer(fig); + } + std::cout << BLUE << "- - - - - - - - - - - - - - - - -" << ENDC << std::endl; + + return (0); } diff --git a/42/Piscine Object/Module 03 - SMART/ex02/point.cpp b/42/Piscine Object/Module 03 - SMART/ex02/point.cpp new file mode 100644 index 00000000..0f2c5a43 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex02/point.cpp @@ -0,0 +1,18 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#include "point.hpp" + +Point::Point(float x, float y): x(x), y(y) { + ; +} + +Point::~Point() { + ; +} + +std::ostream& operator<<(std::ostream& s, const Point& p) { + s << "(" << p.x << ", " << p.y << ")"; + return s; +} diff --git a/42/Piscine Object/Module 03 - SMART/ex02/point.hpp b/42/Piscine Object/Module 03 - SMART/ex02/point.hpp new file mode 100644 index 00000000..cd19ccac --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex02/point.hpp @@ -0,0 +1,18 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#ifndef __POINT_HPP__ +# define __POINT_HPP__ + +#include + +struct Point { + Point(float x, float y); + ~Point(); + float x; + float y; +}; +std::ostream& operator<<(std::ostream&, const Point&); + +#endif diff --git a/42/Piscine Object/Module 03 - SMART/ex02/rectangle.cpp b/42/Piscine Object/Module 03 - SMART/ex02/rectangle.cpp new file mode 100644 index 00000000..9229d2ec --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex02/rectangle.cpp @@ -0,0 +1,36 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#include "rectangle.hpp" + +Rectangle::Rectangle(Point trc, Point size): + Shape("rectangle"), trc_(trc), size_(size) { + ; +} + +Rectangle::~Rectangle() { + std::cout << "Rectangle destroyed" << std::endl; +} + +float Rectangle::area() const { + return size_.x * size_.y; +} + +float Rectangle::perimeter() const { + return (size_.x * 2) + (size_.y * 2); +} + +Point Rectangle::getTopRight() const { + return trc_; +} + +Point Rectangle::getSize() const { + return size_; +} + +std::ostream& operator<<(std::ostream& s, const Rectangle& rect) { + s << "TRC: " << rect.getTopRight() << " Size: " << rect.getSize(); + return (s); +} + diff --git a/42/Piscine Object/Module 03 - SMART/ex02/rectangle.hpp b/42/Piscine Object/Module 03 - SMART/ex02/rectangle.hpp new file mode 100644 index 00000000..7630f497 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex02/rectangle.hpp @@ -0,0 +1,26 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#ifndef __RECTANGLE_HPP__ +# define __RECTANGLE_HPP__ + +#include + +#include "shape.hpp" +#include "point.hpp" + +class Rectangle: public Shape { + public: + Rectangle(Point trc, Point size); + ~Rectangle(); + Point getTopRight() const; + Point getSize() const; + float perimeter() const; + float area() const; + private: + Point trc_; + Point size_; +}; +std::ostream& operator<<(std::ostream&, const Rectangle&); +#endif diff --git a/42/Piscine Object/Module 03 - SMART/ex02/shape.cpp b/42/Piscine Object/Module 03 - SMART/ex02/shape.cpp new file mode 100644 index 00000000..d5d69978 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex02/shape.cpp @@ -0,0 +1,23 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#include "shape.hpp" + +Shape::Shape(const std::string& type): type_(type) { + ; +} + +Shape::~Shape() { + std::cout << "Shape " << type_ << " destroyed" << std::endl; +} + +const std::string Shape::getType() const { + return type_; +} + +std::ostream& operator<<(std::ostream& s, const Shape& fig) { + s << fig.getType() << " area: " << fig.area() << " perimeter: " << fig.perimeter(); + return (s); +} + diff --git a/42/Piscine Object/Module 03 - SMART/ex02/shape.hpp b/42/Piscine Object/Module 03 - SMART/ex02/shape.hpp new file mode 100644 index 00000000..640faaa0 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex02/shape.hpp @@ -0,0 +1,21 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#ifndef __FIGURE_HPP__ +# define __FIGURE_HPP__ + +#include + +class Shape { + public: + Shape(const std::string & type); + ~Shape(); + const std::string getType() const; + virtual float perimeter() const = 0; + virtual float area() const = 0; + private: + const std::string type_; +}; +std::ostream& operator<<(std::ostream&, const Shape&); +#endif diff --git a/42/Piscine Object/Module 03 - SMART/ex02/triangle.cpp b/42/Piscine Object/Module 03 - SMART/ex02/triangle.cpp new file mode 100644 index 00000000..456a5ef5 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex02/triangle.cpp @@ -0,0 +1,46 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#include "math.h" + +#include "triangle.hpp" + +Triangle::Triangle(Point a, Point b, Point c): + Shape("triangle"), a_(a), b_(b), c_(c) { +} + +Triangle::~Triangle() { + std::cout << "Triangle destroyed" << std::endl; +} + +// https://xoax.net/sub_cpp/ref_examples/ex_tri_area/ +float Triangle::area() const { + float area = ((b_.x - a_.x)*(c_.y - a_.y) - (c_.x - a_.x)*(b_.y - a_.y)) / 2.0; + return (area > 0.0) ? area : -area; +} + +float Triangle::perimeter() const { + float ab = sqrt((double)(b_.x-a_.x) * (b_.x-a_.x) + (b_.y-a_.y) * (b_.y-a_.y)); + float bc = sqrt((double)(b_.x-c_.x) * (b_.x-c_.x) + (b_.y-c_.y) * (b_.y-c_.y)); + float ca = sqrt((double)(a_.x-c_.x) * (a_.x-c_.x) + (a_.y-c_.y) * (a_.y-c_.y)); + return ab + bc + ca; +} + +Point Triangle::getA() const { + return a_; +} + +Point Triangle::getB() const { + return b_; +} + +Point Triangle::getC() const { + return c_; +} + +std::ostream& operator<<(std::ostream& s, const Triangle& tri) { + s << "A: " << tri.getA() << " B: " << tri.getB() << " C: " << tri.getC(); + return (s); +} + diff --git a/42/Piscine Object/Module 03 - SMART/ex02/triangle.hpp b/42/Piscine Object/Module 03 - SMART/ex02/triangle.hpp new file mode 100644 index 00000000..97031b39 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex02/triangle.hpp @@ -0,0 +1,28 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#ifndef __TRIANGLE_HPP__ +# define __TRIANGLE_HPP__ + +#include + +#include "shape.hpp" +#include "point.hpp" + +class Triangle: public Shape { + public: + Triangle(Point a, Point b, Point c); + ~Triangle(); + float area() const; + float perimeter() const; + Point getA() const; + Point getB() const; + Point getC() const; + private: + Point a_; + Point b_; + Point c_; +}; +std::ostream& operator<<(std::ostream&, const Triangle&); +#endif diff --git a/42/Piscine Object/Module 03 - SMART/ex03/Makefile b/42/Piscine Object/Module 03 - SMART/ex03/Makefile index b0338fd9..d98200cf 100644 --- a/42/Piscine Object/Module 03 - SMART/ex03/Makefile +++ b/42/Piscine Object/Module 03 - SMART/ex03/Makefile @@ -9,7 +9,12 @@ INC_PATH = . SRC_PATH = . -SRC = ./main.cpp +SRC = ./main.cpp \ + ./apprentice.cpp \ + ./contractEmployee.cpp \ + ./tempWorker.cpp \ + ./employeeManagement.cpp \ + ./employee.cpp \ CFLAGS = -Wall -Wextra -Werror -std=c++98 -pedantic -fsanitize=address #-O3 -g -fsanitize=leak diff --git a/42/Piscine Object/Module 03 - SMART/ex03/apprentice.cpp b/42/Piscine Object/Module 03 - SMART/ex03/apprentice.cpp new file mode 100644 index 00000000..071d386d --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex03/apprentice.cpp @@ -0,0 +1,38 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#include // for std::find + +#include "ex03.inc" + +#include "apprentice.hpp" + +Apprentice::Apprentice(): ContractEmployee(22), school_hours_(3) { + // For the contract of one year the following days are vacations + // 4, 2, 42, 142, 242, 342 + no_work_days_.push_back(4); + no_work_days_.push_back(2); + no_work_days_.push_back(42); + no_work_days_.push_back(142); + no_work_days_.push_back(242); + no_work_days_.push_back(342); + // Students always get sick the 22th, 55th, 164th & 299th day, everyone knows this + no_work_days_.push_back(22); + no_work_days_.push_back(55); + no_work_days_.push_back(164); + no_work_days_.push_back(299); + // Student birthday is the 118th day of the year, you can take the day off + no_work_days_.push_back(118); +} + +Apprentice::~Apprentice() { + if (DEBUG) + std::cout << RED << "Apprentice destroyed" << ENDC << std::endl; +} + +double Apprentice::calculateSalary(int day) { + if (std::find(no_work_days_.begin(), no_work_days_.end(), day) == no_work_days_.end()) + return ((7 - school_hours_) * hourlyValue) + (school_hours_ * (hourlyValue / 2)); + return 0; +} diff --git a/42/Piscine Object/Module 03 - SMART/ex03/apprentice.hpp b/42/Piscine Object/Module 03 - SMART/ex03/apprentice.hpp new file mode 100644 index 00000000..b0dd7307 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex03/apprentice.hpp @@ -0,0 +1,19 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#ifndef __APPRENTICE_HPP__ +# define __APPRENTICE_HPP__ + +#include + +#include "contractEmployee.hpp" + +class Apprentice: public ContractEmployee { + public: + Apprentice(); + ~Apprentice(); + double calculateSalary(int day); + const int school_hours_; +}; +#endif diff --git a/42/Piscine Object/Module 03 - SMART/ex03/contractEmployee.cpp b/42/Piscine Object/Module 03 - SMART/ex03/contractEmployee.cpp new file mode 100644 index 00000000..08a74028 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex03/contractEmployee.cpp @@ -0,0 +1,35 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#include // for std::find + +#include "ex03.inc" + +#include "contractEmployee.hpp" + +ContractEmployee::ContractEmployee(int rate): Employee("contract employee", rate) { + // For the contract of one year the following days are vacations + // 4, 2, 42, 142, 242, 342 + no_work_days_.push_back(4); + no_work_days_.push_back(2); + no_work_days_.push_back(42); + no_work_days_.push_back(142); + no_work_days_.push_back(242); + no_work_days_.push_back(342); + // Workers always get sick the 66th day, everyone knows this + no_work_days_.push_back(66); + // Workers birthday is the 122th day of the year, you can take the day off + no_work_days_.push_back(122); +} + +ContractEmployee::~ContractEmployee() { + if (DEBUG) + std::cout << RED << "ContractEmployee destroyed" << ENDC << std::endl; +} + +double ContractEmployee::calculateSalary(int day) { + if (std::find(no_work_days_.begin(), no_work_days_.end(), day) == no_work_days_.end()) + return hourlyValue * 7; + return 0; +} diff --git a/42/Piscine Object/Module 03 - SMART/ex03/contractEmployee.hpp b/42/Piscine Object/Module 03 - SMART/ex03/contractEmployee.hpp new file mode 100644 index 00000000..20e69c1a --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex03/contractEmployee.hpp @@ -0,0 +1,21 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#ifndef __CONTRACTEMPLOYEE_HPP__ +# define __CONTRACTEMPLOYEE_HPP__ + +#include +#include + +#include "employee.hpp" + +class ContractEmployee: public Employee { + public: + ContractEmployee(int rate = 42); + virtual ~ContractEmployee(); + virtual double calculateSalary(int day); + protected: + std::vector no_work_days_; +}; +#endif diff --git a/42/Piscine Object/Module 03 - SMART/ex03/employee.cpp b/42/Piscine Object/Module 03 - SMART/ex03/employee.cpp new file mode 100644 index 00000000..ef6d50c9 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex03/employee.cpp @@ -0,0 +1,36 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#include "ex03.inc" + +#include "employee.hpp" + +Employee::Employee(const std::string& type, int hourlyValue): + type_(type), hourlyValue(hourlyValue), last_day_worked_(0) { + ; +} + +Employee::~Employee() { + if (DEBUG) + std::cout << RED << "Employee " << ENDC << type_ << RED << " destroyed" << ENDC << std::endl; +} + +double Employee::calculateSalaryBetween(int start, int end) { + double total = 0; + for (int i = start; i < end; ++i) { + total += calculateSalary(i); + if (DEBUG) + std::cout << BLUE << *this << ENDC << " day " << i << GREEN << " +$" << calculateSalary(i) << ENDC << std::endl; + } + return total; +} + +int Employee::executeWorkday() { + return last_day_worked_++; +} +std::ostream& operator<<(std::ostream& s, const Employee& param) { + s << param.type_; + return (s); +} + diff --git a/42/Piscine Object/Module 03 - SMART/ex03/employee.hpp b/42/Piscine Object/Module 03 - SMART/ex03/employee.hpp new file mode 100644 index 00000000..f63bfa74 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex03/employee.hpp @@ -0,0 +1,23 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#ifndef __EMPLOYEE_HPP__ +# define __EMPLOYEE_HPP__ + +#include + +class Employee { + public: + Employee(const std::string& type, int hourlyValue); + virtual ~Employee(); + double calculateSalaryBetween(int start, int end); + virtual double calculateSalary(int day) = 0; + virtual int executeWorkday(); + const std::string type_; + protected: + int hourlyValue; + int last_day_worked_; +}; +std::ostream& operator<<(std::ostream& s, const Employee& param); +#endif diff --git a/42/Piscine Object/Module 03 - SMART/ex03/employeeManagement.cpp b/42/Piscine Object/Module 03 - SMART/ex03/employeeManagement.cpp new file mode 100644 index 00000000..ff6f1545 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex03/employeeManagement.cpp @@ -0,0 +1,54 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#include // for std::find +#include "ex03.inc" +#include "employeeManagement.hpp" + +EmployeeManagement::EmployeeManagement(): current_work_day_(0) { + (void)employees_; +} + +EmployeeManagement::~EmployeeManagement() { + if (DEBUG) + std::cout << RED << "EmployeeManagement destroyed" << ENDC << std::endl; +} + +void EmployeeManagement::addEmployee(Employee *e) { + employees_.push_back(e); + if (DEBUG) + std::cout << GREEN << "ADD\t" << BLUE << *e << ENDC << std::endl; +} + +void EmployeeManagement::removeEmployee(Employee *e) { + std::vector::iterator it = std::find(employees_.begin(), employees_.end(), e); + if (it != employees_.end()) + employees_.erase(it); + if (DEBUG) + std::cout << RED << "REMOVE\t" << BLUE << *e << ENDC << std::endl; +} + +void EmployeeManagement::executeWorkday() { + for (std::vector::iterator i = employees_.begin(); i != employees_.end(); ++i) + (*i)->executeWorkday(); + current_work_day_++; +} + +void EmployeeManagement::calculatePayroll() { + if (current_work_day_ < 30) { + std::cout << RED << "Warning, cannot caluclate Payroll because there is not enough data, at least work for 1 month" << std::endl; + return ; + } + int latest_compleated_month = current_work_day_ / 30; + int first_day_of_month = (latest_compleated_month - 1) * 30; + double total = 0; + std::cout << BLUE << "Payroll for month: " << YELLOW << latest_compleated_month << ENDC << std::endl; + for (std::vector::iterator i = employees_.begin(); i != employees_.end(); ++i) { + double salary = (*i)->calculateSalaryBetween(first_day_of_month, first_day_of_month + 30); + std::cout << " Employee: " << BLUE << **i << ENDC << " Gets: $" << salary << std::endl; + total += salary; + } + std::cout << BLUE "Total Payroll " << GREEN << "$" << total << ENDC << std::endl; +} + diff --git a/42/Piscine Object/Module 03 - SMART/ex03/employeeManagement.hpp b/42/Piscine Object/Module 03 - SMART/ex03/employeeManagement.hpp new file mode 100644 index 00000000..14db5b23 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex03/employeeManagement.hpp @@ -0,0 +1,33 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#ifndef __EMPLOYEEMANAGEMENT_HPP__ +# define __EMPLOYEEMANAGEMENT_HPP__ + +#include +#include + +#include "employee.hpp" + + +class EmployeeManagement { + public: + enum WorkDays { + MONDAY, + TUESDAY, + WEDNESDAY, + THURSDAY, + FRIDAY + }; + EmployeeManagement(); + ~EmployeeManagement(); + void addEmployee(Employee *); + void removeEmployee(Employee *); + void executeWorkday(); // 7hrs of work! + void calculatePayroll(); + private: + std::vector employees_; + int current_work_day_; +}; +#endif diff --git a/42/Piscine Object/Module 03 - SMART/ex03/main.cpp b/42/Piscine Object/Module 03 - SMART/ex03/main.cpp index 7a017964..1a333f34 100644 --- a/42/Piscine Object/Module 03 - SMART/ex03/main.cpp +++ b/42/Piscine Object/Module 03 - SMART/ex03/main.cpp @@ -3,11 +3,47 @@ //***************************// #include "ex03.inc" +#include "employeeManagement.hpp" +#include "tempWorker.hpp" +#include "contractEmployee.hpp" +#include "apprentice.hpp" int main(void) { if (DEBUG) std::cout << "Debug ON!" << std::endl; - std::cout << "Hello Friend\nPulgamecanica greets you :D\n"; + EmployeeManagement em; + + std::cout << YELLOW << "- - - - TempWorker Test - - - -" << ENDC << std::endl; + TempWorker tw1; + + em.addEmployee(&tw1); + for (int i = 0; i < 80; ++i) + { + em.executeWorkday(); + } + em.calculatePayroll(); + em.removeEmployee(&tw1); + std::cout << YELLOW << "- - - - ContractEmployee Test - - - -" << ENDC << std::endl; + ContractEmployee ce1; + + em.addEmployee(&ce1); + for (int i = 0; i < 35; ++i) + { + em.executeWorkday(); + } + em.calculatePayroll(); + em.removeEmployee(&ce1); + std::cout << YELLOW << "- - - - apprentice Test - - - -" << ENDC << std::endl; + Apprentice ap1; + + em.addEmployee(&ap1); + for (int i = 0; i < 30; ++i) + { + em.executeWorkday(); + } + em.calculatePayroll(); + em.removeEmployee(&ap1); + std::cout << YELLOW << "- - - - - - - - - - - - - - - -" << std::endl; return (0); } diff --git a/42/Piscine Object/Module 03 - SMART/ex03/tempWorker.cpp b/42/Piscine Object/Module 03 - SMART/ex03/tempWorker.cpp new file mode 100644 index 00000000..646e80cc --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex03/tempWorker.cpp @@ -0,0 +1,40 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#include "ex03.inc" + +#include "tempWorker.hpp" + +TempWorker::TempWorker(): Employee("temp worker", 15) { + +} + +TempWorker::~TempWorker() { + if (DEBUG) + std::cout << RED << "TempWorker destroyed" << ENDC << std::endl; +} + +double TempWorker::calculateSalary(int day) { + int hours_worked = 0; + try { + hours_worked = hours_worked_map_[day]; + } catch (std::exception & e) { + ; + } + return hours_worked * hourlyValue; +} + +int TempWorker::executeWorkday() { + if (last_day_worked_ % 30 == 0) { + if (DEBUG) + std::cout << RED << "NO WORK\t" << ENDC << "Today I can't work" << std::endl; + last_day_worked_++; + return -1; + } + hours_worked_map_[last_day_worked_] = 4.5; + if (DEBUG) + std::cout << GREEN << "WORK\t" << YELLOW << "day: " << last_day_worked_ << BLUE << " " << *this << ENDC << " Worked for 4.5hrs" << std::endl; + last_day_worked_++; + return 1; +} diff --git a/42/Piscine Object/Module 03 - SMART/ex03/tempWorker.hpp b/42/Piscine Object/Module 03 - SMART/ex03/tempWorker.hpp new file mode 100644 index 00000000..796c2c84 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex03/tempWorker.hpp @@ -0,0 +1,24 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#ifndef __TEMPWORKER_HPP__ +# define __TEMPWORKER_HPP__ + +#include +#include + +#include "employee.hpp" + +// Temp Worker doesn't work the first day of everymonth +// It must go visit his best friend forever +class TempWorker: public Employee { + public: + TempWorker(); + ~TempWorker(); + double calculateSalary(int day) ; + int executeWorkday(); + private: + std::map hours_worked_map_; // For the day, how many hours he worked +}; +#endif diff --git a/42/Piscine Object/Module 03 - SMART/ex04/ConstHeader.cpp b/42/Piscine Object/Module 03 - SMART/ex04/ConstHeader.cpp new file mode 100644 index 00000000..860cbe6c --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex04/ConstHeader.cpp @@ -0,0 +1,17 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#include "ConstHeader.hpp" + +ConstHeader::ConstHeader(const std::string header_str): header_str_(header_str) { + ; +} + +ConstHeader::~ConstHeader() { + ; +} + +const std::string ConstHeader::header() { + return header_str_; +} \ No newline at end of file diff --git a/42/Piscine Object/Module 03 - SMART/ex04/ConstHeader.hpp b/42/Piscine Object/Module 03 - SMART/ex04/ConstHeader.hpp new file mode 100644 index 00000000..ff8d93bc --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex04/ConstHeader.hpp @@ -0,0 +1,20 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#ifndef __CONSTHEADER_HPP__ +# define __CONSTHEADER_HPP__ + +#include + +#include "IHeader.hpp" + +class ConstHeader: public IHeader { + public: + ConstHeader(const std::string header_str); + ~ConstHeader(); + virtual const std::string header(); + private: + const std::string header_str_; +}; +#endif diff --git a/42/Piscine Object/Module 03 - SMART/ex04/DateHeader.cpp b/42/Piscine Object/Module 03 - SMART/ex04/DateHeader.cpp new file mode 100644 index 00000000..9c580aea --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex04/DateHeader.cpp @@ -0,0 +1,22 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#include + +#include "DateHeader.hpp" + +DateHeader::DateHeader() { + ; +} + +DateHeader::~DateHeader() { + ; +} + +const std::string DateHeader::header() { + std::time_t now = std::time(NULL); + char buffer[80]; + std::strftime(buffer, sizeof(buffer), "[%Y-%m-%d %H:%M:%S]", std::localtime(&now)); + return std::string(buffer); +} \ No newline at end of file diff --git a/42/Piscine Object/Module 03 - SMART/ex04/DateHeader.hpp b/42/Piscine Object/Module 03 - SMART/ex04/DateHeader.hpp new file mode 100644 index 00000000..f993434e --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex04/DateHeader.hpp @@ -0,0 +1,18 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#ifndef __DATEHEADER_HPP__ +# define __DATEHEADER_HPP__ + +#include + +#include "IHeader.hpp" + +class DateHeader: public IHeader { + public: + DateHeader(); + ~DateHeader(); + const std::string header(); +}; +#endif diff --git a/42/Piscine Object/Module 03 - SMART/ex04/FileLogger.cpp b/42/Piscine Object/Module 03 - SMART/ex04/FileLogger.cpp new file mode 100644 index 00000000..0b60bbd0 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex04/FileLogger.cpp @@ -0,0 +1,20 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#include "FileLogger.hpp" + +FileLogger::FileLogger(const std::string& filename, IHeader *header) : header(header) { + file.open(filename.c_str(), std::ios::app); +} + +FileLogger::~FileLogger() { + file.close(); +} + +void FileLogger::write(const std::string& message) { + if (header) + file << header->header() << " " << message << std::endl; + else + file << message << std::endl; +} \ No newline at end of file diff --git a/42/Piscine Object/Module 03 - SMART/ex04/FileLogger.hpp b/42/Piscine Object/Module 03 - SMART/ex04/FileLogger.hpp new file mode 100644 index 00000000..0acd3031 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex04/FileLogger.hpp @@ -0,0 +1,23 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#ifndef __FILELOGGER_HPP__ +# define __FILELOGGER_HPP__ + +#include +#include + +#include "ILogger.hpp" +#include "IHeader.hpp" + +class FileLogger: public ILogger { +public: + FileLogger(const std::string& filename, IHeader *header = NULL); + ~FileLogger(); + void write(const std::string& message); +private: + IHeader *header; + std::ofstream file; +}; +#endif diff --git a/42/Piscine Object/Module 03 - SMART/ex04/IHeader.hpp b/42/Piscine Object/Module 03 - SMART/ex04/IHeader.hpp new file mode 100644 index 00000000..03bf23e7 --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex04/IHeader.hpp @@ -0,0 +1,16 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#ifndef __IHEADER_HPP__ +# define __IHEADER_HPP__ + +#include + +class IHeader { + public: + virtual ~IHeader() {} + virtual const std::string header() = 0; + private: +}; +#endif diff --git a/42/Piscine Object/Module 03 - SMART/ex04/ILogger.hpp b/42/Piscine Object/Module 03 - SMART/ex04/ILogger.hpp new file mode 100644 index 00000000..27b2669a --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex04/ILogger.hpp @@ -0,0 +1,15 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#ifndef __ILOGGER_HPP__ +# define __ILOGGER_HPP__ + +#include + +class ILogger { +public: + virtual ~ILogger() {} + virtual void write(const std::string& message) = 0; +}; +#endif diff --git a/42/Piscine Object/Module 03 - SMART/ex04/Makefile b/42/Piscine Object/Module 03 - SMART/ex04/Makefile index e615be78..75fa72c4 100644 --- a/42/Piscine Object/Module 03 - SMART/ex04/Makefile +++ b/42/Piscine Object/Module 03 - SMART/ex04/Makefile @@ -9,7 +9,11 @@ INC_PATH = . SRC_PATH = . -SRC = ./main.cpp +SRC = ./main.cpp \ + ./ConstHeader.cpp \ + ./DateHeader.cpp \ + ./StreamLogger.cpp \ + ./FileLogger.cpp \ CFLAGS = -Wall -Wextra -Werror -std=c++98 -pedantic -fsanitize=address #-O3 -g -fsanitize=leak diff --git a/42/Piscine Object/Module 03 - SMART/ex04/StreamLogger.cpp b/42/Piscine Object/Module 03 - SMART/ex04/StreamLogger.cpp new file mode 100644 index 00000000..32df765a --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex04/StreamLogger.cpp @@ -0,0 +1,16 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#include "StreamLogger.hpp" + +StreamLogger::StreamLogger(std::ostream& stream, IHeader *header): + header(header), stream(stream) { +} + +void StreamLogger::write(const std::string& message) { + if (header) + stream << header->header() << " " << message << std::endl; + else + stream << message << std::endl; +} \ No newline at end of file diff --git a/42/Piscine Object/Module 03 - SMART/ex04/StreamLogger.hpp b/42/Piscine Object/Module 03 - SMART/ex04/StreamLogger.hpp new file mode 100644 index 00000000..7ddd41ce --- /dev/null +++ b/42/Piscine Object/Module 03 - SMART/ex04/StreamLogger.hpp @@ -0,0 +1,21 @@ +//***************************// +//*Template by pulgamecanica*// +//***************************// + +#ifndef __STERAMLOGGER_HPP__ +# define __STERAMLOGGER_HPP__ + +#include + +#include "ILogger.hpp" +#include "IHeader.hpp" + +class StreamLogger : public ILogger { +public: + StreamLogger(std::ostream& stream, IHeader *header = NULL); + void write(const std::string& message); +private: + IHeader *header; + std::ostream& stream; +}; +#endif diff --git a/42/Piscine Object/Module 03 - SMART/ex04/main.cpp b/42/Piscine Object/Module 03 - SMART/ex04/main.cpp index c7e78c69..59c01442 100644 --- a/42/Piscine Object/Module 03 - SMART/ex04/main.cpp +++ b/42/Piscine Object/Module 03 - SMART/ex04/main.cpp @@ -2,12 +2,111 @@ //*Template by pulgamecanica*// //***************************// +#include + #include "ex04.inc" -int main(void) -{ - if (DEBUG) - std::cout << "Debug ON!" << std::endl; - std::cout << "Hello Friend\nPulgamecanica greets you :D\n"; - return (0); -} +#include "ILogger.hpp" +#include "FileLogger.hpp" +#include "StreamLogger.hpp" +#include "ConstHeader.hpp" +#include "DateHeader.hpp" + + +int main() { + std::cout << YELLOW << "- - - - - - Without headers - - - - -" << ENDC << std::endl; + { + // Create instances of loggers + ILogger * fileLogger = new FileLogger("log.txt"); + ILogger * streamLogger = new StreamLogger(std::cout); + ILogger * errorLogger = new StreamLogger(std::cerr); + + // Vector to hold ILogger pointers + std::vector loggers; + loggers.push_back(fileLogger); + loggers.push_back(streamLogger); + loggers.push_back(errorLogger); + + // List of strings to log + std::vector messages; + messages.push_back("Message 1"); + messages.push_back("Message 2"); + messages.push_back("Message 3"); + + // Iterate through messages and log them using all loggers + for (std::vector::iterator it = messages.begin(); it != messages.end(); ++it) { + for (std::vector::iterator it2 = loggers.begin(); it2 != loggers.end(); ++it2) { + (*it2)->write(*it); + } + } + delete fileLogger; + delete streamLogger; + delete errorLogger; + } + + std::cout << YELLOW << "- - - - - - With Const headers - - - - -" << ENDC << std::endl; + { + // Create instances of loggers + ConstHeader ch1("This is a const header!"); + ConstHeader ch2("*Pulgamecanica*"); + ConstHeader ch3("|Header.com|"); + ILogger * fileLogger = new FileLogger("log_const_header.txt", &ch1); + ILogger * streamLogger = new StreamLogger(std::cout, &ch2); + ILogger * errorLogger = new StreamLogger(std::cerr, &ch3); + + // Vector to hold ILogger pointers + std::vector loggers; + loggers.push_back(fileLogger); + loggers.push_back(streamLogger); + loggers.push_back(errorLogger); + + // List of strings to log + std::vector messages; + messages.push_back("Message 1"); + messages.push_back("Message 2"); + messages.push_back("Message 3"); + + // Iterate through messages and log them using all loggers + for (std::vector::iterator it = messages.begin(); it != messages.end(); ++it) { + for (std::vector::iterator it2 = loggers.begin(); it2 != loggers.end(); ++it2) { + (*it2)->write(*it); + } + } + delete fileLogger; + delete streamLogger; + delete errorLogger; + } + std::cout << YELLOW << "- - - - - - With Date headers - - - - -" << ENDC << std::endl; + { + // Create instances of loggers + DateHeader dh1; + DateHeader dh2; + DateHeader dh3; + ILogger * fileLogger = new FileLogger("log_date_header.txt", &dh1); + ILogger * streamLogger = new StreamLogger(std::cout, &dh2); + ILogger * errorLogger = new StreamLogger(std::cerr, &dh3); + + // Vector to hold ILogger pointers + std::vector loggers; + loggers.push_back(fileLogger); + loggers.push_back(streamLogger); + loggers.push_back(errorLogger); + + // List of strings to log + std::vector messages; + messages.push_back("Message 1"); + messages.push_back("Message 2"); + messages.push_back("Message 3"); + + // Iterate through messages and log them using all loggers + for (std::vector::iterator it = messages.begin(); it != messages.end(); ++it) { + for (std::vector::iterator it2 = loggers.begin(); it2 != loggers.end(); ++it2) { + (*it2)->write(*it); + } + } + delete fileLogger; + delete streamLogger; + delete errorLogger; + } + return 0; +} \ No newline at end of file