Commit d9aac66f authored by Alexis Lebis's avatar Alexis Lebis

course op== + CSVP implem and test

parent 12aad2df
...@@ -136,5 +136,12 @@ int main(int argc, char* argv[]) ...@@ -136,5 +136,12 @@ int main(int argc, char* argv[])
assert(c.teachedCompetenciesWeighted().size() == 2); assert(c.teachedCompetenciesWeighted().size() == 2);
std::cout << "RM teached comp ok" << std::endl; std::cout << "RM teached comp ok" << std::endl;
assert(c == c);
std::cout << "Equality ok" << std::endl;
Course c2;
assert( !(c == c2) );
std::cout << "Not equal ok" << std::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
\ No newline at end of file
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include "model/course.h" #include "model/course.h"
#include "model/competency.h" #include "model/competency.h"
#include "model/exception/csdvpOverlapingBoundaryException.h"
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
CSDVP pb; CSDVP pb;
...@@ -19,7 +21,74 @@ int main(int argc, char* argv[]) ...@@ -19,7 +21,74 @@ int main(int argc, char* argv[])
std::cout << "CSDVP constructor OK" << std::endl; std::cout << "CSDVP constructor OK" << std::endl;
assert(pb.checkConfig() == false); assert(pb.checkConfig() == false);
std::cout << "OK! CSDVP is not cofig yet here" << std::endl; std::cout << "OK! CSDVP shoukd not be config yet here" << std::endl;
CSDVP::generateProblem(pb, 7777);
assert(pb.seed() == 7777);
assert(pb.checkConfig() == false);
CSDVP::generateProblem(pb, -1);
assert(pb.seed() == -1);
assert(pb.checkConfig() == false);
std::cout << "generateProblem does not trigger generation if pb is not config" << std::endl;
pb.set_cfg_quantityCompetencies(50);
assert(pb.cfg_quantityCompetencies() == 50);
assert(pb.checkConfig() == false);
pb.set_cfg_quantityCourses(25);
assert(pb.cfg_quantityCourses() == 25);
assert(pb.checkConfig() == false);
pb.set_cfg_quantityTimeFrames(10);
assert(pb.cfg_quantityTimeFrames() == 10);
assert(pb.checkConfig() == false);
pb.set_cfg_ectsMin(3);
assert(pb.cfg_ectsMin() == 3);
assert(pb.checkConfig() == false);
pb.set_cfg_ectsMax(5);
assert(pb.cfg_ectsMax() == 5);
assert(pb.checkConfig() == false);
pb.set_cfg_courseByTFMin(5);
assert(pb.cfg_courseByTFMin() == 5);
assert(pb.checkConfig() == false);
pb.set_cfg_courseByTFMax(8);
assert(pb.cfg_courseByTFMax() == 8);
assert(pb.checkConfig() == false);
std::cout << "Config ok -- excepting seed" << std::endl;
pb.set_cfg_courseByTFMin(9);
try
{
CSDVP::generateProblem(pb, 7777);
}
catch(CSDVPOverlapingBoundariesException & e)
{
std::cout << "Overlaping protection 1/2 OK" << std::endl;
}
pb.set_cfg_courseByTFMin(4);
pb.set_cfg_ectsMax(2);
try
{
CSDVP::generateProblem(pb, 7777);
}
catch(CSDVPOverlapingBoundariesException & e)
{
std::cout << "Overlaping protection 2/2 OK" << std::endl;
}
pb.set_cfg_ectsMax(5);
CSDVP::generateProblem(pb, 7777);
assert(pb.checkConfig());
std::cout << "CSDVP has been correctly configurated" << std::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
\ No newline at end of file
...@@ -6,9 +6,11 @@ ...@@ -6,9 +6,11 @@
#include "course.h" #include "course.h"
#include "competency.h" #include "competency.h"
#include "tools.h"
#include "exception/courseECTSException.h" #include "exception/courseECTSException.h"
#include "exception/courseTemporalFrameException.h" #include "exception/courseTemporalFrameException.h"
#include "exception/notImplementedException.h"
int Course::COURSE_COUNTER = 0; int Course::COURSE_COUNTER = 0;
...@@ -70,7 +72,7 @@ Course::Course(int id, int ects, std::string name) ...@@ -70,7 +72,7 @@ Course::Course(int id, int ects, std::string name)
} }
void Course::addPrerequisite(Competency & prereq) void Course::addPrerequisite(Competency & prereq)
{ {
if( _duplicataProtection(&(this->_prerequisites), prereq) ) if( duplicataFlag((this->_prerequisites), prereq) )
return; return;
this->_prerequisites.push_back(prereq); this->_prerequisites.push_back(prereq);
} }
...@@ -78,7 +80,7 @@ Course::Course(int id, int ects, std::string name) ...@@ -78,7 +80,7 @@ Course::Course(int id, int ects, std::string name)
{ {
if(time < 0) if(time < 0)
throw CourseTemporalFrameException(this, time); throw CourseTemporalFrameException(this, time);
if( _duplicataProtection(&(this->_temporalAvailability), time) ) if( duplicataFlag((this->_temporalAvailability), time) )
return; return;
this->_temporalAvailability.push_back(time); this->_temporalAvailability.push_back(time);
} }
...@@ -155,18 +157,20 @@ Course::Course(int id, int ects, std::string name) ...@@ -155,18 +157,20 @@ Course::Course(int id, int ects, std::string name)
// === FUNC // === FUNC
bool Course::_duplicataProtection(std::vector<int> * timeFrame, int time) /// @deprecated
{ // bool Course::_duplicataProtection(std::vector<int> * timeFrame, int time)
std::vector<int>::iterator it = std::find( timeFrame->begin(), timeFrame->end(), time); // {
// std::vector<int>::iterator it = std::find( timeFrame->begin(), timeFrame->end(), time);
return it != timeFrame->end(); // return it != timeFrame->end();
} // }
bool Course::_duplicataProtection(std::vector<Competency> * prereq, Competency c) /// @deprecated
{ // bool Course::_duplicataProtection(std::vector<Competency> * prereq, Competency c)
std::vector<Competency>::iterator it = std::find( prereq->begin(), prereq->end(), c); // {
return it != prereq->end(); // std::vector<Competency>::iterator it = std::find( prereq->begin(), prereq->end(), c);
} // return it != prereq->end();
// }
bool Course::_duplicataProtection(std::vector<std::pair<Competency,double>> *teached, Competency c) bool Course::_duplicataProtection(std::vector<std::pair<Competency,double>> *teached, Competency c)
{ {
...@@ -208,6 +212,20 @@ bool Course::_duplicataProtection(std::vector<std::pair<Competency,double>> *tea ...@@ -208,6 +212,20 @@ bool Course::_duplicataProtection(std::vector<std::pair<Competency,double>> *tea
// } // }
bool Course::_lazyEquality(const Course & c) const
{
return (this->_id == c.id() &&
this->_name.compare(c.name()) == 0 &&
this->_ects == c.ects()
);
}
///@todo
bool Course::_fullEquality(const Course & c) const
{
throw NotImplementedException("Course::_fullEquality");
}
// === OPERATOR // === OPERATOR
std::ostream& operator<<(std::ostream& Stream, const Course & c) std::ostream& operator<<(std::ostream& Stream, const Course & c)
{ {
...@@ -215,6 +233,11 @@ std::ostream& operator<<(std::ostream& Stream, const Course & c) ...@@ -215,6 +233,11 @@ std::ostream& operator<<(std::ostream& Stream, const Course & c)
Stream << s; Stream << s;
return Stream; return Stream;
} }
bool Course::operator==(const Course & c) const
{
return _lazyEquality(c);
}
// === END OPERATOR // === END OPERATOR
......
...@@ -41,10 +41,17 @@ class Course ...@@ -41,10 +41,17 @@ class Course
// === FUNC // === FUNC
/// _duplicataProtection returns true if the value (2nd param) searched into (1st param) is found /// _duplicataProtection returns true if the value (2nd param) searched into (1st param) is found
/// @deprecated
bool _duplicataProtection(std::vector<int> *, int); bool _duplicataProtection(std::vector<int> *, int);
/// @deprecated
bool _duplicataProtection(std::vector<Competency> *, Competency); bool _duplicataProtection(std::vector<Competency> *, Competency);
bool _duplicataProtection(std::vector<std::pair<Competency,double>> *, Competency); bool _duplicataProtection(std::vector<std::pair<Competency,double>> *, Competency);
/** Only check equality on id, etcs and name. It should be sufficient in the majority of case */
bool _lazyEquality (const Course & c) const;
/** Full check equality on id, ects, name, timeframes, prerequisites, compentencies*/
bool _fullEquality(const Course & c) const;
// Static // Static
static int COURSE_COUNTER; static int COURSE_COUNTER;
static int assignID(); static int assignID();
...@@ -54,6 +61,9 @@ class Course ...@@ -54,6 +61,9 @@ class Course
Course(int id, int ects, std::string name); Course(int id, int ects, std::string name);
public: public:
static Course build(int ects = 0, std::string name = ""); static Course build(int ects = 0, std::string name = "");
/// Default constructor. Use Course::build instead !
Course() = default;
// === GETTER // === GETTER
const int id() const{return this->_id;}; const int id() const{return this->_id;};
...@@ -92,6 +102,9 @@ class Course ...@@ -92,6 +102,9 @@ class Course
// template<typename T> // template<typename T>
// static std::pair<int, T> findInVector(const std::vector<T> &, const T &); // static std::pair<int, T> findInVector(const std::vector<T> &, const T &);
// === OPERATOR
/// A course is equal to another iff {(lazy_equality) || (full_equality)
bool operator==(const Course & c) const;
}; };
// === OPERATOR // === OPERATOR
......
#ifndef SRC_MODEL_EXCEPTION_CSDVP_OVERLAPING_BOUNDARIES_EXCEPTION_H_
#define SRC_MODEL_EXCEPTION_CSDVP_OVERLAPING_BOUNDARIES_EXCEPTION_H_
#include <exception>
#include <iostream>
#include <string>
#include "../problem.h"
class CSDVPOverlapingBoundariesException : public std::exception
{
private:
CSDVP * _csdvp;
std::string _msg;
public:
CSDVPOverlapingBoundariesException(CSDVP * pb) throw()
: _csdvp(pb)
{
this->_msg = "Boundaries of the CSDVP (id:"+std::to_string(pb->id())+") are overlaping.";
}
virtual const char* what() const throw()
{return this->_msg.c_str();}
CSDVP & getCSDVP() {return *(this->_csdvp);}
};
#endif // SRC_MODEL_EXCEPTION_CSDVP_OVERLAPING_BOUNDARIES_EXCEPTION_H_
\ No newline at end of file
#ifndef SRC_MODEL_EXCEPTION_NOT_IMPLEMENTED_EXCEPTION_H_
#define SRC_MODEL_EXCEPTION_NOT_IMPLEMENTED_EXCEPTION_H_
#include <exception>
#include <string>
class NotImplementedException : public std::exception
{
private:
std::string _msg;
public:
NotImplementedException(std::string funcName)
{
this->_msg = "Function "+funcName+" not yet implemented.";
}
virtual const char* what() const throw()
{
return this->_msg.c_str();
}
};
#endif // SRC_MODEL_EXCEPTION_NOT_IMPLEMENTED_EXCEPTION_H_
\ No newline at end of file
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
#include <algorithm> #include <algorithm>
#include "problem.h" #include "problem.h"
#include "tools.h"
#include "exception/csdvpOverlapingBoundaryException.h"
int CSDVP::CSDVP_COUNTER = 0; int CSDVP::CSDVP_COUNTER = 0;
...@@ -30,9 +33,52 @@ int CSDVP::CSDVP_COUNTER = 0; ...@@ -30,9 +33,52 @@ int CSDVP::CSDVP_COUNTER = 0;
// === END CONSTRUCTOR // === END CONSTRUCTOR
// === MUTATOR // === MUTATOR
// SETTER // SETTER
void CSDVP::set_cfg_quantityCompetencies(int nb)
{this->_quantityAvailableCompetencies = nb;}
void CSDVP::set_cfg_quantityCourses(int nb)
{this->_quantityAvailableCourses = nb;}
void CSDVP::set_cfg_quantityTimeFrames(int nb)
{this->_quantityOfTimeFrame = nb;}
void CSDVP::set_cfg_ectsMin(int nb)
{
this->_minimalECTSValue = nb;}
void CSDVP::set_cfg_ectsMax(int nb)
{this->_maximalECTSValue = nb;}
void CSDVP::set_cfg_courseByTFMin(int nb)
{this->_minimalCoursesByTimeFrame = nb;}
void CSDVP::set_cfg_courseByTFMax(int nb)
{this->_maximalCoursesByTimeFrame = nb;}
void CSDVP::setTimeFrames(std::vector<int> & v)
{this->_timeFrames = v;}
void CSDVP::setCoursesCatalogue(std::vector<Course> & c)
{this->_availableCourses;}
void CSDVP::setCompetenciesCatalogue(std::vector<Competency> & c)
{this->_availableCompentecies;}
// ADDER
void CSDVP::addTimeFrame(int tF)
{
if(duplicataFlag(this->_timeFrames, tF))
return; // NTD
this->_timeFrames.push_back(tF);
}
void CSDVP::addCourseToCatalogue(Course & c)
{
if(duplicataFlag(this->_availableCourses, c))
return;
this->_availableCourses.push_back(c);
}
void CSDVP::addCompetencyToCatalogue(Competency & c)
{
if(duplicataFlag(this->_availableCompentecies, c))
return;
this->_availableCompentecies.push_back(c);
}
// ADDER
// === END MUTATOR // === END MUTATOR
...@@ -53,6 +99,13 @@ int CSDVP::CSDVP_COUNTER = 0; ...@@ -53,6 +99,13 @@ int CSDVP::CSDVP_COUNTER = 0;
return this->_isConfig; return this->_isConfig;
} }
// verify overlaping range
if( this->_minimalECTSValue > this->_maximalECTSValue ||
this->_minimalCoursesByTimeFrame > this->_maximalCoursesByTimeFrame)
{
throw CSDVPOverlapingBoundariesException(this);
}
this->_isConfig = true; this->_isConfig = true;
return this->_isConfig; return this->_isConfig;
} }
...@@ -64,7 +117,7 @@ int CSDVP::CSDVP_COUNTER = 0; ...@@ -64,7 +117,7 @@ int CSDVP::CSDVP_COUNTER = 0;
csdvp._seed = seed; csdvp._seed = seed;
if(! csdvp.checkConfig() ) //if csdvp is not configurated, aborting generation if(! csdvp.checkConfig() ) //if csdvp is not configurated, aborting generation
return; return; //aborting pb generation
std::cout << "generateProblem TODO" << std::endl; std::cout << "generateProblem TODO" << std::endl;
} }
......
...@@ -55,7 +55,7 @@ class CSDVP ...@@ -55,7 +55,7 @@ class CSDVP
// === CONSTRUCTOR // === CONSTRUCTOR
CSDVP(); CSDVP();
/// Generate an instance of the CSDVP iff isConfig is true. Thus, seed != -1; /// Generate an instance of the CSDVP iff isConfig is true. Thus, seed != -1;
void generateProblem(CSDVP & csdvp, int seed= -1 ); void static generateProblem(CSDVP & csdvp, int seed= -1 );
// === GETTER // === GETTER
const int id() const{return this->_id;} const int id() const{return this->_id;}
...@@ -66,21 +66,36 @@ class CSDVP ...@@ -66,21 +66,36 @@ class CSDVP
const int cfg_ectsMax() const{return this->_maximalECTSValue;} const int cfg_ectsMax() const{return this->_maximalECTSValue;}
const int cfg_ectsMin() const{return this->_minimalECTSValue;} const int cfg_ectsMin() const{return this->_minimalECTSValue;}
const int cfg_courseByTFMax() const{return this->_maximalCoursesByTimeFrame;} const int cfg_courseByTFMax() const{return this->_maximalCoursesByTimeFrame;}
const int cfg_courseByTFMin() const{return this->_minimalECTSValue;} const int cfg_courseByTFMin() const{return this->_minimalCoursesByTimeFrame;}
const std::vector<int> timeFrames() const{return this->_timeFrames;} const std::vector<int> timeFrames() const{return this->_timeFrames;}
const std::vector<Course> coursesCatalogue() const{return this->_availableCourses;} const std::vector<Course> coursesCatalogue() const{return this->_availableCourses;}
const std::vector<Competency> competencyCatalogue() const{return this->_availableCompentecies;} const std::vector<Competency> competencyCatalogue() const{return this->_availableCompentecies;}
std::vector<int> unlocked_timeFrames(){return this->_timeFrames;} std::vector<int> unlocked_timeFrames(){return this->_timeFrames;}
std::vector<Course> unlocked_coursesCatalogue(){return this->_availableCourses;} std::vector<Course> unlocked_coursesCatalogue(){return this->_availableCourses;}
std::vector<Competency> unlocked_competencyCatalogue(){return this->_availableCompentecies;} std::vector<Competency> unlocked_competenciesCatalogue(){return this->_availableCompentecies;}
///@todo getDecayPolitic ///@todo getDecayPolitic
// === MUTATOR // === MUTATOR
// SETTER // SETTER
/*setSeed is deactivated. The only way to attribute a seed to CSDVP is by generateProblem.*/
//void setSeed(int s);
void set_cfg_quantityCompetencies(int nb);
void set_cfg_quantityCourses(int nb);
void set_cfg_quantityTimeFrames(int nb);
void set_cfg_ectsMin(int nb);
void set_cfg_ectsMax(int nb);
void set_cfg_courseByTFMax(int nb);
void set_cfg_courseByTFMin(int nb);
void setTimeFrames(std::vector<int> & v);
void setCoursesCatalogue(std::vector<Course> &);
void setCompetenciesCatalogue(std::vector<Competency> &);
// ADDER // ADDER
//Any adder has a duplicata protection. Tend to favor addX instead of setX to prevent duplicata
void addTimeFrame(int t);
void addCourseToCatalogue(Course & c);
void addCompetencyToCatalogue(Competency & c);
// === FUNC // === FUNC
/// Checks all configuration attributes. If they have been all set, then isConfig is set to true /// Checks all configuration attributes. If they have been all set, then isConfig is set to true
......
#ifndef SRC_MODEL_TOOLS_H_
#define SRC_MODEL_TOOLS_H
#include <vector>
#include <utility>
#include <algorithm>
template<typename T>
/** Searches into vec the element findMe. The class T must have T() defined ( T()=default; is OK) */
static std::pair<int, T> findInVector(std::vector<T> & vec, const T & findMe)
{
std::pair<int, T> res;
typename std::vector<T>::iterator it = std::find( vec.begin(), vec.end(), findMe);
if(it == vec.end())
{
res.first = -1;
res.second; //NTD, -1 SHOULD BE USED TO DETECT THAT NOTHING HAS BEEN FOUND
}
else
{
res.first = std::distance(vec.begin(), it);
res.second = vec.at(res.first);
}
return res;
}
template<typename T>
/** duplicataFlag returns true if the value (2nd param) searched into (1st param) is found */
static bool duplicataFlag(std::vector<T> & toProtect, const T & toAdd)
{
std::pair<int, T> res = findInVector(toProtect, toAdd);
if(res.first < 0)
return false;
else
return true;
}
#endif // SRC_MODEL_TOOLS_H_
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment