Compare commits

..

54 commits
anri ... main

Author SHA1 Message Date
efa28a3c30
typo.. 2023-10-29 19:19:43 +01:00
669dd4bec3
uml....... 2023-10-29 19:15:50 +01:00
07ae3f42f1
mouais 2023-10-29 19:09:26 +01:00
538fc053eb
i hate uml 2023-10-29 18:53:51 +01:00
5349d5e89a
arghh 2023-10-29 17:26:34 +01:00
99c8809d6a
diagram v0 2023-10-29 17:21:15 +01:00
1182b1307a
fmt 2023-10-29 17:17:31 +01:00
3373084c62
youhou 2023-10-29 16:54:00 +01:00
ebd74a8088
not by default 2023-10-28 13:09:01 +02:00
fc0c8e3a71
tests 2023-10-28 13:08:48 +02:00
074b5adb19
space! 2023-10-28 12:56:42 +02:00
5bc9979c90
,,,,,, 2023-10-28 12:47:07 +02:00
470aa9a45c
-Wreorder 2023-10-28 12:36:10 +02:00
7ad0f154d2
reverse init! 2023-10-28 12:09:52 +02:00
b4495026cb
prettier printer! 2023-10-28 12:08:13 +02:00
c22771f587
ignore error 1 2023-10-28 12:02:41 +02:00
7d8750f128
const uwu 2023-10-28 12:00:50 +02:00
4c37ab4ef4
non car friend non hériditaire 2023-10-28 11:53:41 +02:00
8a334d46be
happy 2023-10-28 11:53:25 +02:00
e8ff85b383
paye! 2023-10-28 11:51:31 +02:00
1ee2bc5603
better clean ig 2023-10-28 11:22:50 +02:00
af2646e46e
ordonnancement 2023-10-28 11:17:43 +02:00
95765193a8
yay 2023-10-28 04:26:01 +02:00
c55907adce
salaire 2023-10-28 04:24:35 +02:00
d107592ae3
TODO! 2023-10-28 04:16:35 +02:00
74ad46d137
add getters 2023-10-28 04:14:51 +02:00
f4782634ce
total duration done!! 2023-10-28 04:06:37 +02:00
929187436b
preparation for avis 2023-10-28 03:56:31 +02:00
47ee545c0a
yay 2023-10-28 03:45:22 +02:00
5631318c73
oops 2023-10-28 03:43:55 +02:00
095419a1f8
fix all memory management issues by copying references BUT still deleting object when RunProject die 2023-10-28 03:43:33 +02:00
9ebf1af816
run! 2023-10-28 03:07:28 +02:00
8bb2629fa8
<< 2023-10-28 03:00:22 +02:00
62091bf314
prettyprinter 2023-10-28 02:59:00 +02:00
510b8680e8
const! 2023-10-28 02:35:22 +02:00
7b2726c5d2
runproject uwu 2023-10-28 02:09:10 +02:00
8d3b9973a6
fix issues 2023-10-28 01:34:58 +02:00
616d08822e
trucs 2023-10-28 00:10:54 +02:00
c4927de1eb
ajout des taches 2023-10-27 23:27:41 +02:00
dd0c3d6bd5
let me cook 2023-10-27 21:51:27 +02:00
9173dfc39a
contains isok 2023-10-27 21:41:03 +02:00
428d594e7b
topologicalSort 2023-10-27 21:40:27 +02:00
3232e8ea7f
projet stuff 2023-10-27 20:29:48 +02:00
f098d1977e
const madness 2023-10-27 20:27:49 +02:00
dee0cde24b
remove redundant includes 2023-10-27 19:35:30 +02:00
8d887ab28e
... 2023-10-27 19:33:52 +02:00
0b06f924f3
task's name 2023-10-27 19:31:44 +02:00
7cf3097046
Warnings 2023-10-27 19:27:53 +02:00
9f66c43e1e
j'ai compris la dépendance ! 2023-10-27 19:18:34 +02:00
1ac596769a
add explications 2023-10-27 19:03:15 +02:00
4564e76aa3
a lu le pdf! 2023-10-27 18:52:27 +02:00
7f55fb9a5e
make it compile 2023-10-27 18:01:17 +02:00
Emma
3b21fdbe9b avancement Projet et ProtoProjet 2023-10-26 19:08:00 +02:00
Emma
368c88423d Classe Projet 2023-10-24 16:47:59 +02:00
22 changed files with 862 additions and 57 deletions

View file

@ -9,6 +9,11 @@ OBJETS = $(patsubst %.cpp,%.cpp.o,$(notdir $(SOURCES)))
EXE = tp5 EXE = tp5
EXE_EXT = out EXE_EXT = out
PDF_LOCATION = report
PDF_FILE = explications.pdf
ARCHIVE = $(EXE).tar
%.cpp.o: src/%.cpp %.cpp.o: src/%.cpp
$(CXX) -c -o $@ $< $(CXXFLAGS) $(DEVFLAGS) $(CXX) -c -o $@ $< $(CXXFLAGS) $(DEVFLAGS)
@ -25,10 +30,19 @@ compilation: $(OBJETS)
all: all:
main main
clean: pdf-make:
$(RM) $(OBJETS) $(EXE).$(EXE_EXT) cd report && \
$(MAKE)
archive: pdf-clean:
$(TAR) "$(EXE).tar" $(SOURCES) $(wildcard includes/*.hpp) Makefile \ cd report && \
binome.txt $(MAKE) clean
# diagramme_uml.* explications.pdf
clean: pdf-clean
-$(RM) $(OBJETS) "$(EXE).$(EXE_EXT)" "$(ARCHIVE)"
archive: pdf-make
cp "$(PDF_LOCATION)/$(PDF_FILE)" .
$(TAR) "$(ARCHIVE)" $(SOURCES) $(wildcard includes/*.hpp) Makefile \
binome.txt "$(PDF_FILE)" diagramme_uml.png
$(RM) "$(PDF_FILE)"

108
TODO.md
View file

@ -2,7 +2,107 @@
TODO avant rendu : TODO avant rendu :
- [ ] "Vous remettrez en plus de votre code une page rédigée montrant que vous - [x] Page rédigée montrant que l'on a tenu compte des problématiques de copies et sécurité (private/public) en expliquant en français non technique comment vous les avez traitées (`x` à pas accès à `y`)
avez tenu compte de certaines problématiques de copies/sécurité etc en - [x] Écrire des tests pour montrer que ça fonctionne
expliquant en français non technique comment vous les avez traitées"
- [ ] Écrire un "écrirez un petit jeu de test, clair" ## Notes
- [x] Toute classe doit être surchargée avec `<<`
- [x] Gestion satisfaisante des copies, affectation, destruction
### Projet
- [x] Ne dois **pas** être instanciée directement
- [x] Se décompose en tâches (vecteur de tâches)
- [x] Durée totale dépend du degré de parallélisme que le gestionnaire décide
- [x] Deux natures de projets dépendantent de `Projet`
- En cours d'élaboration (`ProtoProjet`)
- En cours d'exécution (`RunProjet`)
- [x] Peut être vu comme un graphe acyclique (utilisation de `vector`) des tâches
- Les sommets sont des tâches
- Une tâche `fin` servira de source au graphe
- Garder un ordre topologique (triée par dépendances)
- [x] Mère des deux classes `ProtoProjet` et `RunProjet`
- [x] Méthodes utiles qu'à ses sous-classes
- Méthodes (cf. le PDF du prof)
- [x] `pick_two_random_tasks()`
- [x] `contains()`
- [x] Surcharge de `<<` : afficher toutes les tâches
- [x] `consult_tasks()`
- [x] `topologicalSort()`
#### ProtoProjet
- Permet de pouvoir ajouter de nouvelles tâches
- Ne peut pas progresser (a.k.a ne peut pas lancer les tâches)
- Champs
- [x] Tâche `début`
- [x] Tâche `fin`
- Méthodes (cf. le PDF du prof) **⇒ Tout ça avec l'ordre topologique**
- Pas de méthode d'ajout d'un objet `Tache`
- [x] `bool ajoute(nom, durée)` : sélectionne au hasard 2 tâches déjà
enregistrer et **ajoute** la nouvelle tâche entres-elles
- [x] `bool ajoute(nom, durée, id)` : **ajoute** une tâche qui doit se réaliser
**après** la tâche qui à l'`id` correspondant (et avant la tâche finale)
- [x] `bool ajoute(nom, durée, id1, id2)` : **ajoute** une tâche entre les 2 tâches
qui ont l'identifiant `id1` et `id2`
- [x] Surcharge de `<<`
#### RunProjet
- [x] Construit uniquement via un `ProtoProjet`
- [x] Avance vers sa conclusion en prenant en compte des tâches ponctuelles
- [x] Vide le contenu d'un `ProtoProjet` pour se construire, rendre les tâches "read-only"
- Méthodes (cf. le PDF du prof)
- [x] `run(id)` : Lance une tâche
- [x] `run(sequence_taches)` : Exécute une liste de tâches dans l'ordre donnée
- [x] Surcharge de `<<`
### Concepteur
L'utilisateur final en somme
- [x] Interagis avec un `ProtoProjet` pour y mettre des tâches
### Gestionnaire
- [x] Étudie/Analyse des `RunProjet`
- [x] Recommande des ordonnancements pour la suite des exécutions à venir
(ordre d'exécutions des tâches)
- [x] Calcule la durée totale restante d'un projet
- [x] Demande un salaire pour travailler
- Méthodes
- [x] Surcharge de `<<` : Affiche une facturation
- [x] `pair<vector<int>, int> avis(const RunProjet &)` : renvoie l'ordonnancement
et la durée totale restante
#### Consultant
- [x] Calcule **sans** parallélisation des tâches
#### Expert
- [x] Calcule **avec** parallélisation des tâches
### Tâches
- [x] Dépendantes, entre-elles
- [x] Durée exacte, fixe, propre à elle-même
- [x] Ne peut être lancé que si toutes les dépendances sont réalisées
- [x] Dépendances = autres tâches
- [x] Élément atomique (final)
- Champs
- [x] Nom
- [x] Numéro unique
- [x] État (réalisée/en attente)
- Réalisée → En attente : **interdit**
- En attente → Réalisée : **autorisé**
- [x] Vision locale des dépendances (`vector`)
- Méthodes (cf. le PDF du prof)
- [x] `bool realise()`
- [x] `bool depends_from(Tache & x)`
- [x] `bool ajouteDependance(Tache & x)`
- [x] `int dureeParal()`
- [x] Surcharge de `<<`

70
diagramme_uml.md Normal file
View file

@ -0,0 +1,70 @@
<!-- https://mermaid.live -->
```mermaid
%%{init: {'theme': 'neutral'}}%%
classDiagram
%% Classes
class Tache {
-static_counter_id
-nom
-duree_total
-etat
-dependances
+unique_id
+visite
+realise()
+depends_from(tache)
+ajouteDependance(tache)
+dureeParal()
+PP_postfixe(liste_tache)
}
class Projet {
#tache_fin
#tache_debut
#taches
-cleanMarks()*
#pick_two_random_tasks()
#contains(id ou name)
#topologicalSort()
+consult_tasks()
}
class ProtoProjet {
-cleanMarks()
+ajoute(nom, duree)
+ajoute(nom, duree, id)
+ajoute(nom, duree, id1, id2)
}
class RunProjet {
+run(id ou liste_tache)
}
class Gestionnaire {
-salaire
+payer(argent)
+avis(RunProjet)*
}
class Consultant {
+avis(RunProjet)
}
class Expert {
+avis(RunProjet)
}
%% Héritage
Projet <|-- ProtoProjet
ProtoProjet <|-- RunProjet
Gestionnaire <|-- Consultant
Gestionnaire <|-- Expert
%% Friends (Dependency)
%% pour : consult_tasks()
Projet ..> Consultant
Projet ..> Expert
%% Composition
Tache --* Projet
```

BIN
diagramme_uml.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -1,9 +1,9 @@
#ifndef TP5_CONSULTANT_HPP #ifndef TP5_CONSULTANT_HPP
#define TP5_CONSULTANT_HPP 1 #define TP5_CONSULTANT_HPP 1
#include <iostream> #include "Gestionnaire.hpp"
class Consultant { class Consultant final : public Gestionnaire {
friend std::ostream &operator<<(std::ostream &, const Consultant &); friend std::ostream &operator<<(std::ostream &, const Consultant &);
public: public:
@ -12,6 +12,8 @@ public:
Consultant(const Consultant &); // copy constructor Consultant(const Consultant &); // copy constructor
const Consultant &operator=(const Consultant &); // copy assignement const Consultant &operator=(const Consultant &); // copy assignement
std::pair<std::vector<int>, int> avis(const RunProjet &projet) const;
}; };
#endif #endif

View file

@ -1,9 +1,9 @@
#ifndef TP5_EXPERT_HPP #ifndef TP5_EXPERT_HPP
#define TP5_EXPERT_HPP 1 #define TP5_EXPERT_HPP 1
#include <iostream> #include "Gestionnaire.hpp"
class Expert { class Expert final : public Gestionnaire {
friend std::ostream &operator<<(std::ostream &, const Expert &); friend std::ostream &operator<<(std::ostream &, const Expert &);
public: public:
@ -12,6 +12,8 @@ public:
Expert(const Expert &); // copy constructor Expert(const Expert &); // copy constructor
const Expert &operator=(const Expert &); // copy assignement const Expert &operator=(const Expert &); // copy assignement
std::pair<std::vector<int>, int> avis(const RunProjet &projet) const;
}; };
#endif #endif

View file

@ -1,17 +1,37 @@
#ifndef TP5_GESTIONNAIRE_HPP #ifndef TP5_GESTIONNAIRE_HPP
#define TP5_GESTIONNAIRE_HPP 1 #define TP5_GESTIONNAIRE_HPP 1
#include <iostream> #include "RunProjet.hpp"
class Gestionnaire { class Gestionnaire {
int salaire_attendu;
int salaire_recu;
// Renvoie le reste à payer pour donner une expertise
int reste_a_payer() const;
friend std::ostream &operator<<(std::ostream &, const Gestionnaire &); friend std::ostream &operator<<(std::ostream &, const Gestionnaire &);
protected:
// Auxiliaire pour simplifier l'affichage d'un projet
std::ostream &print(std::ostream &) const;
// Vrai si Gestionnaire à été payé.e
bool payer() const;
public: public:
Gestionnaire(); // constructor Gestionnaire(); // constructor
virtual ~Gestionnaire(); // destructor virtual ~Gestionnaire(); // destructor
Gestionnaire(const Gestionnaire &); // copy constructor Gestionnaire(const Gestionnaire &); // copy constructor
const Gestionnaire &operator=(const Gestionnaire &); // copy assignement const Gestionnaire &operator=(const Gestionnaire &); // copy assignement
// Paye Gestionnaire, renvoie le montant restant à payer
int payer(const int argent);
// Renvoie l'ordonnancement et la durée totale restante
// Renvoie une liste vide et une durée totale -1 si pas payé.e
virtual std::pair<std::vector<int>, int> avis(const RunProjet &) const = 0;
}; };
#endif #endif

View file

@ -1,17 +1,58 @@
#ifndef TP5_PROJET_HPP #ifndef TP5_PROJET_HPP
#define TP5_PROJET_HPP 1 #define TP5_PROJET_HPP 1
#include <iostream> #include "Tache.hpp"
#include <algorithm>
struct RunProjet;
class Projet { class Projet {
friend std::ostream &operator<<(std::ostream &, const Projet &); // Auxilliaire pour simplifier les copies
void _copy(const Projet &);
// Auxiliiaire pour simplifier la libération de mémoire des tâches
void free_taches();
// Remet tous les marquages à leur valeur initiale
virtual void cleanMarks() const = 0;
friend std::ostream &operator<<(std::ostream &, const Projet &);
friend RunProjet;
protected:
Tache
// Source du graphe aka la dernière à être exécutée
*fin,
// Première tâche qui sera exécutée
*debut;
public:
Projet(); // constructor Projet(); // constructor
virtual ~Projet(); // destructor virtual ~Projet(); // destructor
Projet(const Projet &); // copy constructor Projet(const Projet &); // copy constructor
const Projet &operator=(const Projet &); // copy assignement const Projet &operator=(const Projet &); // copy assignement
// Graphe acyclique
std::vector<Tache *> taches;
// Auxiliaire pour simplifier l'affichage d'un projet
std::ostream &print(std::ostream &) const;
// Retourne une paire d'indentifiants de tâches au hasard
const std::pair<const int, const int> pick_two_random_tasks() const;
// Indique pour une tâche si elle fait partie du projet
Tache *contains(const int id) const;
Tache *contains(const std::string name) const;
// Corrige les éventuelles anomalies du vector de tâches
void topologicalSort();
public:
// Donne une version du vecteur de tâches non modifiable
const std::vector<const Tache *> consult_tasks() const;
}; };
#endif #endif

View file

@ -4,6 +4,8 @@
#include "Projet.hpp" #include "Projet.hpp"
class ProtoProjet : public Projet { class ProtoProjet : public Projet {
void cleanMarks() const;
friend std::ostream &operator<<(std::ostream &, const ProtoProjet &); friend std::ostream &operator<<(std::ostream &, const ProtoProjet &);
public: public:
@ -12,6 +14,18 @@ public:
ProtoProjet(const ProtoProjet &); // copy constructor ProtoProjet(const ProtoProjet &); // copy constructor
const ProtoProjet &operator=(const ProtoProjet &); // copy assignement const ProtoProjet &operator=(const ProtoProjet &); // copy assignement
// Insère une nouvelle tâche en la plaçant entre deux tâches au hasard
bool ajoute(const std::string nom, const int duree);
// Insère une nouvelle tâche en la plaçant après la tâche avec l'ID
// renseignée et avant la tâche finale, en créant une dépendance
bool ajoute(const std::string nom, const int duree, const int id);
// Insère une nouvelle tâche en la plaçant entre les deux tâches renseignée
// via ID
bool ajoute(const std::string nom, const int duree, const int id1,
const int id2);
}; };
#endif #endif

View file

@ -3,15 +3,29 @@
#include "ProtoProjet.hpp" #include "ProtoProjet.hpp"
class RunProjet : public ProtoProjet { struct Consultant;
struct Expert;
class RunProjet final : protected ProtoProjet {
friend std::ostream &operator<<(std::ostream &, const RunProjet &); friend std::ostream &operator<<(std::ostream &, const RunProjet &);
// Ami pour pouvoir consulter les tâches
friend Consultant;
friend Expert;
public: public:
RunProjet(); // constructor RunProjet() = delete; // remove default constructor
RunProjet(ProtoProjet &); // constructor
virtual ~RunProjet(); // destructor virtual ~RunProjet(); // destructor
RunProjet(const RunProjet &); // copy constructor RunProjet(const RunProjet &); // copy constructor
const RunProjet &operator=(const RunProjet &); // copy assignement const RunProjet &operator=(const RunProjet &); // copy assignement
// Lance une tâche
bool run(const int id) const;
// Exécute une liste de tâches dans l'ordre donnée
void run(const std::vector<const Tache *> sequence_taches) const;
}; };
#endif #endif

View file

@ -4,7 +4,7 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
class Tache { class Tache final {
// Compteur global pour les IDs // Compteur global pour les IDs
static int counter_id; static int counter_id;
@ -12,9 +12,8 @@ class Tache {
enum Etat { EnAttente, Realisee }; enum Etat { EnAttente, Realisee };
friend std::ostream &operator<<(std::ostream &, const Etat &); friend std::ostream &operator<<(std::ostream &, const Etat &);
// ID unique de la tâche // Nom de la tâche
const int unique_id; std::string name;
// Durée totale pour faire la tâche // Durée totale pour faire la tâche
int duree_total; int duree_total;
// Etat actuelle de la tâche // Etat actuelle de la tâche
@ -28,7 +27,12 @@ class Tache {
void _copy(const Tache &); void _copy(const Tache &);
public: public:
Tache(const int); // constructor // ID unique de la tâche
const int unique_id;
// Vrai si la tâche à été visitée par le parcours en profondeur
bool visite;
Tache(const std::string, const int); // constructor
virtual ~Tache(); // destructor virtual ~Tache(); // destructor
Tache(const Tache &); // copy constructor Tache(const Tache &); // copy constructor
@ -45,6 +49,15 @@ public:
// Calcule la durée totale max de réalisation d'une tâche et des dépendances // Calcule la durée totale max de réalisation d'une tâche et des dépendances
int dureeParal() const; int dureeParal() const;
// Parcours en profondeur
void PP_postfixe(std::vector<Tache *> &);
// Récupère la durée totale
int get_duree_totale() const;
// Récupère le nom
std::string get_name() const;
}; };
#endif #endif

5
report/.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
*
!.gitignore
!Makefile
!*.tex

16
report/Makefile Normal file
View file

@ -0,0 +1,16 @@
NAME = explications
TEX = $(NAME).tex
SRC = $(TEX)
PDF = $(TEX:.tex=.pdf)
TEXMK = latexmk -shell-escape -lualatex
all: $(PDF)
$(PDF): %.pdf: %.tex
$(TEXMK) $<
EXTS = aux fdb_latexmk fls log nav out snm synctex.gz toc
clean:
rm -rf $(PDF) _minted-$(NAME)/ $(foreach ext,$(EXTS),$(NAME).$(ext))

49
report/explications.tex Normal file
View file

@ -0,0 +1,49 @@
\documentclass{article}
\usepackage[T1]{fontenc} % encoding
\renewcommand{\familydefault}{\sfdefault} % sans-serif font
\usepackage[french]{babel} % langages
\frenchsetup{SmallCapsFigTabCaptions=false}
\usepackage[hidelinks]{hyperref} % clickable links in table of contents
\usepackage{graphicx} % images
\newcommand{\emma}{Emma Botti}
\newcommand{\anri}{Anri Kennel}
\newcommand{\pp}{\texttt{ProtoProjet}}
\newcommand{\rp}{\texttt{RunProjet}}
\title{Explications TP5}
\author{\emma\thanks{\emma : 00000000} et \anri\thanks{\anri : 22302653} \\
Langages à objet avancés $\cdot$ Université Paris Cité}
\date{Année universitaire 2023-2024}
\begin{document}
\maketitle
\tableofcontents
\clearpage
\section{Explications}
\subsection{Problématique de copies}
La liste des tâches est créée lors du \pp, et vider de la mémoire
lorsque \rp~disparaît. Lors du passage des tâches entre \pp~et \rp, il n'y a pas de copie.
\subsection{Problématique de sécurité}
Les variables sont toutes encapsulées dans des classes qui leur correspondent.
Les variables, quand elles n'ont pas à être exposé, sont soit cachés,
soit immuable.
\section{Diagramme UML}
\begin{figure}[h]
\centering
\includegraphics[width=1.3\textwidth]{../diagramme_uml.png}
\caption{Diagramme UML}
\end{figure}
\end{document}

View file

@ -1,10 +1,10 @@
#include "../includes/Consultant.hpp" #include "../includes/Consultant.hpp"
Consultant::Consultant() { std::cout << "Hello, Consultant!\n"; } Consultant::Consultant() {}
Consultant::~Consultant() {} Consultant::~Consultant() {}
Consultant::Consultant(const Consultant &) {} Consultant::Consultant(const Consultant &) : Gestionnaire() {}
const Consultant &Consultant::operator=(const Consultant &src) { const Consultant &Consultant::operator=(const Consultant &src) {
if (this == &src) { if (this == &src) {
@ -13,3 +13,27 @@ const Consultant &Consultant::operator=(const Consultant &src) {
return *this; return *this;
} }
std::ostream &operator<<(std::ostream &out, const Consultant &data) {
return data.print(out);
}
std::pair<std::vector<int>, int>
Consultant::avis(const RunProjet &projet) const {
std::vector<int> ordonnancement;
if (!payer()) {
return std::make_pair(ordonnancement, -1);
}
const std::vector<const Tache *> taches = projet.consult_tasks();
int duree_totale = 0;
for (const Tache *it : taches) {
duree_totale += it->get_duree_totale();
}
for (const Tache *it : taches) {
ordonnancement.push_back(it->unique_id);
}
return std::make_pair(ordonnancement, duree_totale);
}

View file

@ -1,10 +1,10 @@
#include "../includes/Expert.hpp" #include "../includes/Expert.hpp"
Expert::Expert() { std::cout << "Hello, Expert!\n"; } Expert::Expert() {}
Expert::~Expert() {} Expert::~Expert() {}
Expert::Expert(const Expert &) {} Expert::Expert(const Expert &) : Gestionnaire() {}
const Expert &Expert::operator=(const Expert &src) { const Expert &Expert::operator=(const Expert &src) {
if (this == &src) { if (this == &src) {
@ -13,3 +13,23 @@ const Expert &Expert::operator=(const Expert &src) {
return *this; return *this;
} }
std::ostream &operator<<(std::ostream &out, const Expert &data) {
return data.print(out);
}
std::pair<std::vector<int>, int> Expert::avis(const RunProjet &projet) const {
std::vector<int> ordonnancement;
if (!payer()) {
return std::make_pair(ordonnancement, -1);
}
const std::vector<const Tache *> taches = projet.consult_tasks();
const int duree_totale = taches.front()->dureeParal();
for (const Tache *it : taches) {
ordonnancement.push_back(it->unique_id);
}
return std::make_pair(ordonnancement, duree_totale);
}

View file

@ -1,15 +1,59 @@
#include "../includes/Gestionnaire.hpp" #include "../includes/Gestionnaire.hpp"
Gestionnaire::Gestionnaire() { std::cout << "Hello, Gestionnaire!\n"; } Gestionnaire::Gestionnaire() {
salaire_attendu = rand() % 500 + 400; // Entre 400 et 899
salaire_recu = 0;
}
Gestionnaire::~Gestionnaire() {} Gestionnaire::~Gestionnaire() {}
Gestionnaire::Gestionnaire(const Gestionnaire &) {} Gestionnaire::Gestionnaire(const Gestionnaire &src)
: salaire_attendu(src.salaire_attendu), salaire_recu(0) {}
const Gestionnaire &Gestionnaire::operator=(const Gestionnaire &src) { const Gestionnaire &Gestionnaire::operator=(const Gestionnaire &src) {
if (this == &src) { if (this == &src) {
return *this; return *this;
} }
salaire_attendu = src.salaire_attendu;
salaire_recu = src.salaire_recu;
return *this; return *this;
} }
std::ostream &Gestionnaire::print(std::ostream &out) const {
out << "La facture s'élève à " << salaire_attendu << "€, il reste "
<< reste_a_payer() << "€ à payer";
return out;
}
std::ostream &operator<<(std::ostream &out, const Gestionnaire &data) {
return data.print(out);
}
int Gestionnaire::reste_a_payer() const {
return salaire_attendu - salaire_recu;
}
bool Gestionnaire::payer() const {
bool return_val = salaire_recu >= salaire_attendu;
if (!return_val) {
std::cerr << "Je n'ai pas été payé. " << *this << ".\n";
}
return return_val;
}
int Gestionnaire::payer(const int argent) {
if (reste_a_payer() <= 0) {
return 0;
}
salaire_recu += argent;
if (reste_a_payer() <= 0) {
return 0;
}
return reste_a_payer();
}

View file

@ -1,15 +1,117 @@
#include "../includes/Projet.hpp" #include "../includes/Projet.hpp"
Projet::Projet() { std::cout << "Hello, project!\n"; } Projet::Projet() : fin(new Tache("Fin", 0)), debut(new Tache("Début", 0)) {
fin->ajouteDependance(*debut);
Projet::~Projet() {} taches.push_back(fin);
taches.push_back(debut);
}
Projet::Projet(const Projet &) {} Projet::~Projet() { free_taches(); }
void Projet::_copy(const Projet &src) {
// Copie des tâches
taches.reserve(src.taches.size());
for (Tache *t : src.taches) {
taches.push_back(t);
}
}
void Projet::free_taches() { taches.clear(); }
Projet::Projet(const Projet &src) : fin(src.fin), debut(src.debut) {
_copy(src);
}
const Projet &Projet::operator=(const Projet &src) { const Projet &Projet::operator=(const Projet &src) {
if (this == &src) { if (this == &src) {
return *this; return *this;
} }
fin = src.fin;
debut = src.debut;
free_taches();
_copy(src);
return *this; return *this;
} }
std::ostream &Projet::print(std::ostream &out) const {
// Liste vide
if (taches.empty()) {
out << "[]";
return out;
}
out << "[\n";
for (Tache *t : taches) {
out << " " << *t << ",\n";
}
out << ']';
return out;
}
std::ostream &operator<<(std::ostream &out, const Projet &data) {
return data.print(out);
}
const std::pair<const int, const int> Projet::pick_two_random_tasks() const {
// Choix aléatoire d'une tâche
size_t size = this->taches.size();
size_t rand1 = static_cast<size_t>(rand()) % size;
size_t rand2 = static_cast<size_t>(rand()) % size;
Tache *tache1 = this->taches[rand1];
Tache *tache2 = this->taches[rand2];
// tache2 ne doit pas dépendre transitivement de tache1
if (tache2->depends_from(*tache1)) {
return pick_two_random_tasks();
}
int id1 = tache1->unique_id;
int id2 = tache2->unique_id;
return std::make_pair(id1, id2);
}
Tache *Projet::contains(const int id) const {
for (Tache *t : this->taches) {
if (id == t->unique_id) {
return t;
}
}
return nullptr;
}
Tache *Projet::contains(const std::string name) const {
for (Tache *t : this->taches) {
if (name == t->get_name()) {
return t;
}
}
return nullptr;
}
const std::vector<const Tache *> Projet::consult_tasks() const {
return std::vector<const Tache *>(taches.begin(), taches.end());
}
void Projet::topologicalSort() {
// Construction de la pile
std::vector<Tache *> pile;
for (Tache *it : taches) {
if (!it->visite) {
it->PP_postfixe(pile);
}
}
// Nettoyage des marques
cleanMarks();
// Reverse de la pile
std::reverse(pile.begin(), pile.end());
// Modifie la liste des tâches topologiquement triée
taches = pile;
}

View file

@ -1,10 +1,10 @@
#include "../includes/ProtoProjet.hpp" #include "../includes/ProtoProjet.hpp"
ProtoProjet::ProtoProjet() { std::cout << "Hello, protoProject!\n"; } ProtoProjet::ProtoProjet() {}
ProtoProjet::~ProtoProjet() {} ProtoProjet::~ProtoProjet() {}
ProtoProjet::ProtoProjet(const ProtoProjet &) : Projet() {} ProtoProjet::ProtoProjet(const ProtoProjet &src) : Projet(src) {}
const ProtoProjet &ProtoProjet::operator=(const ProtoProjet &src) { const ProtoProjet &ProtoProjet::operator=(const ProtoProjet &src) {
if (this == &src) { if (this == &src) {
@ -13,3 +13,50 @@ const ProtoProjet &ProtoProjet::operator=(const ProtoProjet &src) {
return *this; return *this;
} }
std::ostream &operator<<(std::ostream &out, const ProtoProjet &data) {
return data.print(out);
}
void ProtoProjet::cleanMarks() const {
for (auto t : taches) {
t->visite = false;
}
};
bool ProtoProjet::ajoute(const std::string nom, const int duree) {
// Sélection de 2 tâches au hasard
auto tasks = pick_two_random_tasks();
// Ajout des tâches
return ajoute(nom, duree, tasks.first, tasks.second);
}
bool ProtoProjet::ajoute(const std::string nom, const int duree, const int id) {
// Ajout de la tâche entre l'ID voulu et la tâche finale
return ajoute(nom, duree, id, fin->unique_id);
}
bool ProtoProjet::ajoute(const std::string nom, const int duree, const int id1,
const int id2) {
Tache *tache1 = contains(id1);
Tache *tache2 = contains(id2);
// Vérifie que les tâches avec les id1 et id2 existent bien dans la liste
if (!tache1 || !tache2) {
return false;
}
// Création des dépendances
Tache *tache = new Tache(nom, duree);
if (!tache1->ajouteDependance(*tache) && !tache->ajouteDependance(*tache2)) {
// Problème de dépendance
delete tache;
return false;
}
// Mise à jour du vecteur avec tri topologique
taches.push_back(tache);
topologicalSort();
return true;
}

View file

@ -1,10 +1,15 @@
#include "../includes/RunProjet.hpp" #include "../includes/RunProjet.hpp"
RunProjet::RunProjet() { std::cout << "Hello, runProject!\n"; } RunProjet::RunProjet(ProtoProjet &src) : ProtoProjet(src) { src.free_taches(); }
RunProjet::~RunProjet() {} RunProjet::~RunProjet() {
// Ici on veut supprimes les tâches
for (Tache *it : taches) {
delete it;
}
}
RunProjet::RunProjet(const RunProjet &) : ProtoProjet() {} RunProjet::RunProjet(const RunProjet &src) : ProtoProjet(src) {}
const RunProjet &RunProjet::operator=(const RunProjet &src) { const RunProjet &RunProjet::operator=(const RunProjet &src) {
if (this == &src) { if (this == &src) {
@ -13,3 +18,24 @@ const RunProjet &RunProjet::operator=(const RunProjet &src) {
return *this; return *this;
} }
std::ostream &operator<<(std::ostream &out, const RunProjet &data) {
return data.print(out);
}
bool RunProjet::run(const int id) const {
Tache *tache = contains(id);
// La tâche n'existe pas
if (!tache) {
return false;
}
// Renvoie si la tâche s'est réalisée
return tache->realise();
}
void RunProjet::run(const std::vector<const Tache *> sequence_taches) const {
for (const Tache *it : sequence_taches) {
run(it->unique_id);
}
}

View file

@ -2,9 +2,10 @@
int Tache::counter_id = 0; int Tache::counter_id = 0;
Tache::Tache(const int duree) Tache::Tache(const std::string n, const int duree)
: unique_id(++counter_id), duree_total(duree), etat(EnAttente), : name(n), duree_total(duree), etat(EnAttente),
dependances(std::vector<Tache *>()) {} dependances(std::vector<Tache *>()), unique_id(counter_id++),
visite(false) {}
Tache::~Tache() {} Tache::~Tache() {}
@ -17,7 +18,8 @@ void Tache::_copy(const Tache &src) {
} }
Tache::Tache(const Tache &src) Tache::Tache(const Tache &src)
: unique_id(++counter_id), duree_total(src.duree_total), etat(src.etat) { : name(src.name), duree_total(src.duree_total), etat(src.etat),
unique_id(counter_id++), visite(src.visite) {
_copy(src); _copy(src);
} }
@ -25,8 +27,10 @@ const Tache &Tache::operator=(const Tache &src) {
if (this == &src) { if (this == &src) {
return *this; return *this;
} }
name = src.name;
duree_total = src.duree_total; duree_total = src.duree_total;
etat = src.etat; etat = src.etat;
visite = src.visite;
_copy(src); _copy(src);
return *this; return *this;
} }
@ -34,7 +38,7 @@ const Tache &Tache::operator=(const Tache &src) {
std::ostream &operator<<(std::ostream &out, const Tache::Etat &data) { std::ostream &operator<<(std::ostream &out, const Tache::Etat &data) {
switch (data) { switch (data) {
case Tache::EnAttente: case Tache::EnAttente:
out << "En Attente"; out << "Attend";
break; break;
case Tache::Realisee: case Tache::Realisee:
@ -45,8 +49,8 @@ std::ostream &operator<<(std::ostream &out, const Tache::Etat &data) {
} }
std::ostream &operator<<(std::ostream &out, const Tache &data) { std::ostream &operator<<(std::ostream &out, const Tache &data) {
out << "Tâche #" << data.unique_id << " " << data.etat << " avec " out << "Tâche(#" << data.unique_id << ", \"" << data.name << "\", "
<< data.dependances.size() << " dépendances"; << data.etat << ")\t=> " << data.dependances.size() << " dépendances";
return out; return out;
} }
@ -59,9 +63,11 @@ bool Tache::realise() {
} }
} }
// TODO: Ca veux dire quoi déclencher une tâche ? // TODO: Faire une vérification si le temps est écoulée ?
// Dans ce cas là faut stocker le temps d'exécution actuelle de la tâche ?
etat = Realisee; etat = Realisee;
return false; return true;
} }
bool Tache::depends_from(const Tache &x) const { bool Tache::depends_from(const Tache &x) const {
@ -82,7 +88,7 @@ bool Tache::depends_from(const Tache &x) const {
bool Tache::ajouteDependance(Tache &x) { bool Tache::ajouteDependance(Tache &x) {
// On ne créer pas de dépendances cyclique aka 2 tâches // On ne créer pas de dépendances cyclique aka 2 tâches
// qui dépendent l'une de l'autre // qui dépendent l'une de l'autre
if (depends_from(x)) { if (x.depends_from(*this)) {
return false; return false;
} }
@ -109,3 +115,19 @@ int Tache::dureeParal() const {
// On ajoute la valeur max à notre durée totale // On ajoute la valeur max à notre durée totale
return ret_value + max_duree; return ret_value + max_duree;
} }
void Tache::PP_postfixe(std::vector<Tache *> &pile) {
visite = true;
for (Tache *it : dependances) {
if (!it->visite) {
it->PP_postfixe(pile);
}
}
// Moment post-fix du parcours
pile.push_back(this);
}
int Tache::get_duree_totale() const { return duree_total; }
std::string Tache::get_name() const { return name; }

View file

@ -1 +1,161 @@
int main(int argc, char const *argv[]) { return 0; } #include "../includes/Consultant.hpp"
#include "../includes/Expert.hpp"
using namespace std;
// Fait des tests pour vérifier/montrer que ça fonctionne
void test();
// Transforme un vecteur<int> en string
std::string vecint_tostring(std::vector<int> list);
int main() {
/* test();
return EXIT_SUCCESS; */
ProtoProjet pp;
pp.ajoute("a", 10); // probablement numero 2
cout << pp; // avec ses 3 taches
cout << "\n----------" << endl;
pp.ajoute("b", 15, 0, 1); // en supposant que 0: fin et 1: début
cout << pp;
cout << "\n----------" << endl;
RunProjet rp{pp};
cout << "----- verification : ProtoProjet vide " << endl;
cout << pp << endl;
Consultant c;
c.payer(1000);
cout << c.avis(rp).second << endl; // dira 25
Expert e;
e.payer(1000);
cout << e.avis(rp).second << endl; // dira 15
return EXIT_SUCCESS;
}
void test() {
/********************************** Projet **********************************/
// Projet p; // impossible car classe abstraite
/******************************* ProtoProjet *******************************/
ProtoProjet pp;
cout << "pp: " << pp << "\n";
/* pp: [
* Tâche(#0, "Fin", Attend) => 1 dépendances,
* Tâche(#1, "Début", Attend) => 0 dépendances,
* ] */
pp.ajoute("a", 10); // ajoute une dépendance à #1 le "début"
pp.ajoute("b", 15, 0, 1); // ajoute une dépendance à #0 (id1)
cout << "pp: " << pp << "\n";
/* pp: [
* Tâche(#0, "Fin", Attend) => 2 dépendances,
* Tâche(#3, "b", Attend) => 0 dépendances,
* Tâche(#1, "Début", Attend) => 1 dépendances,
* Tâche(#2, "a", Attend) => 0 dépendances,
* ]
*
* => L'ordre pour les dépendances est respecté */
/******************************** RunProjet ********************************/
// RunProjet rp; // impossible car le constructeur vide n'existe pas
RunProjet rp(pp);
cout << "pp: " << pp << "\n";
/* pp: []
*
* => La liste est bien vidée*/
cout << "rp: " << rp << "\n";
/* rp: [
* Tâche(#0, "Fin", Attend) => 2 dépendances,
* Tâche(#3, "b", Attend) => 0 dépendances,
* Tâche(#1, "Début", Attend) => 1 dépendances,
* Tâche(#2, "a", Attend) => 0 dépendances,
* ]
*
* => Les mêmes tâches ont étés transférés à RunProjet (pas de copie vérifiés
* par les ID identiques) */
/******************************** Consultant *******************************/
Consultant c;
cout << "c: " << c << "\n";
/* c: La facture s'élève à 693€, il reste 693€ à payer
*
* => Affiche la facture */
auto avis = c.avis(rp);
cout << "c(avis): (" << vecint_tostring(avis.first) << ", " << avis.second
<< ")\n";
/* Je n'ai pas été payé. La facture s'élève à 693€, il reste 693€ à payer.
* c(avis): ([], -1)
*
* => Iel ne donne pas d'avis car pas payé. */
cout << "c(payer 1000): " << c.payer(1000) << "\n";
/* c(payer 1000): 0
*
* On donne 1000 pour être sûr qu'iel soit content
* Il renvoie 0 car iel a plus besoin d'être payé */
auto avis2 = c.avis(rp);
cout << "c(avis): (" << vecint_tostring(avis2.first) << ", " << avis2.second
<< ")\n";
/* c(avis): ([0, 3, 1, 2], 25)
*
* => Iel donne la liste d'exécution
* et le temps d'exécution sans parallélisation */
/********************************** Expert *********************************/
Expert e;
cout << "e: " << e << "\n";
/* e: La facture s'élève à x€, il reste x€ à payer
*
* => Affiche la facture */
auto avis3 = e.avis(rp);
cout << "e(avis): (" << vecint_tostring(avis3.first) << ", " << avis3.second
<< ")\n";
/* Je n'ai pas été payé. La facture s'élève à y€, il reste y€ à payer.
* e(avis): ([], -1)
*
* => Iel ne donne pas d'avis car pas payé. */
cout << "e(payer 1000): " << e.payer(1000) << "\n";
/* e(payer 1000): 0
*
* On donne 1000 pour être sûr qu'iel soit content
* Il renvoie 0 car iel a plus besoin d'être payé */
auto avis4 = e.avis(rp);
cout << "e(avis): (" << vecint_tostring(avis4.first) << ", " << avis4.second
<< ")\n";
/* e(avis): ([0, 3, 1, 2], 15)
*
* => Iel donne la liste d'exécution
* et le temps d'exécution avec parallélisation */
/* A la fin, la mémoire est correctement libérée, testé via Valgrind-3.21.0 :
* HEAP SUMMARY:
* in use at exit: 0 bytes in 0 blocks
* total heap usage: 33 allocs, 33 frees, 75,550 bytes allocated
* All heap blocks were freed -- no leaks are possible
* ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) */
}
std::string vecint_tostring(std::vector<int> list) {
std::string return_value = "[";
if (list.empty()) {
return return_value + "]";
}
for (auto it : list) {
return_value += std::to_string(it) + ", ";
}
// \b\b pour retirer la dernière virgule
return return_value + "\b\b]";
}