====== De la modélisation au code : FINALE ======
[[2019_2020:s2:td:coorectionexamintermediaire|Corrections de l'examen intermédiaire]]
{{:2019_2020:s2:td:exams2-mars2019.pdf|L'examen de l'an passé}}
===== La classe "Journey" (30mn) =====
* On définit un ''Trajet/Journey'' comme une suite ordonnée de points.(( Pour dire qu'une association est ordonnée, il faut le sélectionner dans la partie {{:2019_2020:s2:td:capture_d_e_cran_2020-03-04_a_14.50.04.png|}} properties))
* Un point a un intitulé (par exemple, "IUT, Fabron").
* Un point peut appartenir à plusieurs Trajets.
* Un point ne sait pas à quel(s) trajet(s) il est associé.
* On veut connaitre la distance que représente un Trajet, c'est la somme des distances entre les points (cf. si besoin [[http://fr.wikipedia.org/wiki/Distance_entre_deux_points_sur_le_plan_cart%C3%A9sien|Calcul de distance]])
- Modéliser le concept de Trajet, y compris les autres concepts dont vous pouvez avoir besoin.
- Codez-les.
Je sais représenter des associations entre classes et je comprends leur correspondance en java.
/*
===== La classe ''Polygone'' (15mn) =====
Un polygone est composé d'une suite de points.
- Modéliser la classe ''Polygone'' en UML.
- Il est possible de créer un Polygone comme un ensemble vide de Points ou en passant un tableau de Points. Dans VP, vous pouvez ajouter des constructeurs.
- Générer le code. Quelle structure de données utilisez-vous pour représenter la suite de points? Regardez le code généré ... Evidemment il n'est pas possible de modifier la classe Point fournie par java. Vous ne devez donc pas la générer.
- Tester votre classe, par exemple en ajoutant une méthode ''ToString''.
Même acquis que précédemment et prise en compte des structures (Tableau, ArrayList pour représenter des "suites").
==== La classe ''Polygone'': V2 (10mn) ====
* Pour remplir le tableau de points, on a besoin d'une première méthode ''addPoint'' qui ajoutera un point à ceux déjà présents.
- Etendez votre modélisation de la classe ''Polygone'' en UML.
- Générer le code.
- Tester votre classe.
- Que retenez-vous de cet exercice? Quand se fait le choix de la structure?
Le choix de l'implémentation dépend de ce que l'on fait des objets.
*/
===== Votre application : SpyMe (2H20) =====
Attention cette fois-ci, la description de l'étude de cas n'est pas complètement structurée; la structure des classes en particulier exige une analyse "globale" de l'étude de cas.
On décide de produire une nouvelle application telle que :
* Un internaute peut s'inscrire à l'application en utilisant son compte facebook ou twitter ou un formulaire dédié.
* Un membre peut enregistrer son parcours :
- il déclare sur son téléphone qu'il commence à enregistrer un parcours;
- toutes les 10 secondes, le système crée un nouveau point automatiquement en demandant au GPS du téléphone sa position et l'heure actuelle; le point est ajouté au parcours en cours; Les coordonnées GPS sont des coordonnées sur une sphère et pas des coordonnées cartésiennes, cependant dans le cadre de ce TD, travaillez "simplement" avec des coordonnées cartésiennes;
- le membre signale la fin du parcours qui est automatiquement enregistré dans sa base de parcours.
* Un membre peut visualiser les parcours passés : par la distance parcourue, la durée, la vitesse moyenne, la date (jour et heure), le type d'entrainement, ...
* Un membre peut demander à visualiser un parcours en utilisant googleMAP.
* Un membre peut savoir quand il était le plus proche d'un point donné lors d'un parcours.
* Un membre peut savoir où il était à une date particulière : le système renvoie la position enregistrée à la date la plus proche.
* Un membre peut préciser qu'il veut enregistrer un parcours d'entrainement; dans ce cas, avant le départ, il précise le mode d'entrainement. Pour chaque mode, un temps de relevé des points différent est prévu : marche rapide (2mn), course à pied (10s), vélos (5s), foot (10s), ...
* Un membre peut créer son propre mode d'entrainement en précisant les temps de consultation etc.
* Un membre qui a précisé son compte twitter, peut demander en début de parcours, que chaque relevé de point soit automatiquement "tweetté" avec le message "Je suis en position ...".
==== Questions ====
Evidemment vous commencez par identifier les cas d'utilisation de haut niveau. Mais ensuite vous pouvez travailler comme bon vous semble.
* Définir le diagramme de cas d'utilisation
* Définir le diagramme de classes
* Définir le diagramme de séquence correspondant à l'enregistrement d'un parcours par un membre, vous pouvez vous aider du diagramme ci-après.
* Implémenter les scénario de la partie 1 ci-après en vous aidant des codes donnés. En particulier, comme nous ne disposons pas du GPS dans l'exemple donné ci-après c'est l'utilisateur qui saisit sa position. De même comme vous ne connaissez pas encore la parallèlisation des tâches on demande à chaque relevé de position, s'il faut ou non continuer à enregistrer le parcours.
* Pouvez-vous étendre votre application pour donner la vitesse moyenne entre deux points donnés d'un parcours?
* **Partie 1** : Voici des exemples très simples de tests de "validation", c'est à dire des tests qui mettent en exergue certaines des exigences client décrites ci-dessus.
- "Bipbip" s'inscrit en utilisant son compte "Facebook";
- "Xavier-Bertrand" s'inscrit en saisissant son nom et déclare son compte twitter;
- "Bipbip" demande l'enregistrement de son parcours "lundi": par exemple : Journey [points=[ [date=Thu Feb 28 21:39:15 CET 2019, Point [x=5, y=5, label=domicile]], [date=Thu Feb 28 21:39:16 CET 2019, Point [x=7, y=7, label=p1]], [date=Thu Feb 28 21:39:17 CET 2019, Point [x=10, y=10, label=p2]],..
- "Bipbip" demande //quand// il était près d'un point d'un parcours donné :
- (1) si le point a été enregistré pendant le parcours e.g. ( (7,7) -> ''date=Thu Feb 28 21:39:16 CET 2019'') ;
- (2) si le point n'a pas été enregistré, il cherche le point le plus proche lors d'un parcours (e.g. (12,12) -> ''date=Thu Feb 28 21:39:17 CET 2019'')
-"Bipbip" demande où il était à ''Thu Feb 28 21:39:17 CET 2019'' : le système renvoie (12,12) etc.
* **Partie 2** : "Prévoyez" les tests correspondant aux scénarii suivants, mais, à moins d'être très avancés n'allez pas au code.
- "Bipbip" demande également l'enregistrement de son parcours et précise qu'il s'agit d'un entrainement à la course.
- "Bipbip" demande à voir ses parcours triés par la durée : il a couru lundi pendant 20mn et mercredi 30mn.
- "Bipbip" demande à voir ses parcours triés par la vitesse moyenne: il a couru lundi à 11km/h et mercredi 10km/h.
- "Xavier-Bertrand" déclare un nouveau mode d'entrainement : le Marathon, les relevés ne se font que toutes les minutes.
==== Pour vous aider ====
=== Si vous avez du mal à identifier les "objets" de l'application ... ===
{{ :2015_2016:s2:td:courseapiedpk.scenariopointdevuepartiel.jpg?direct&200 |}}
* Avez-vous besoin d'information supplémentaires sur la notion de Point? Comment faire?
* De quelles informations avez-vous besoin pour construire un Parcours?
== Obtenir le moment présent ==
import java.util.Date;
................
//obtenir la date courante
Date date = new Date();
=== Gestion du temps ===
Si vous voulez représenter la gestion du temps (mais vous pouvez vous en passer), voici une approche très simple :
try {
Thread.sleep(10000);//1000 milliseconds is one second.
} catch (InterruptedException e) {
e.printStackTrace();
}
=== Saisir des entiers ou des boolean au clavier ===
import java.util.Scanner;
.....................
Scanner sc = new Scanner(System.in);
int y = sc.nextInt();
boolean encore = sc.nextBoolean();
=== Vision Globale ===
Attention, votre code ne correspond probablement pas à cela !!
Scanner sc = new Scanner(System.in);
int interval = 1000;
public Journey createJourney(Member m) throws InterruptedException{
System.out.println("Creating a journey ");
DatedPoint currentPoint = enterDatedPoint(); ;
Journey path = new Journey(currentPoint);
boolean again = true;
while (again){
currentPoint = enterDatedPoint();
path.addPoint(currentPoint);
System.out.println("Distance : " + path.distance());
System.out.println("Duration since departure : " + path.duration() + " soit :" + path.duration()/1000 + " secondes" );
System.out.println("We continue ? (true or false)");
again = sc.nextBoolean();
Thread.sleep(interval); //1000 milliseconds is one second.
}
return path;
}
private DatedPoint enterDatedPoint() {
DatedPoint currentPoint;
int x;
int y;
System.out.println(" X ");
x = sc.nextInt();
System.out.println(" Y ");
y = sc.nextInt();
//obtenir la date courante
Date date = new Date();
currentPoint = new DatedPoint(x,y,date);
return currentPoint;
}
Autres exemples
//To improve taking into account the displacement
public Date whenWasYouHere(Point point) {
DatedPoint closestPoint = points[0];
double distanceMin = point.distance(closestPoint);
for (int i =1; i
Et des exemples de tests ...
void testClosestPoint() throws InterruptedException {
Date currentDate1 = new Date();
DatedPoint currentPoint1 = new DatedPoint(5,5,currentDate1,"domicile") ;
Thread.sleep(1000);
Date currentDate2 = new Date();
DatedPoint currentPoint2 = new DatedPoint(7,7,currentDate2,"p1") ;
Thread.sleep(1000);
DatedPoint currentPoint3 = new DatedPoint(10,10,new Date(),"p2") ;
Thread.sleep(1000);
Journey path = new Journey(currentPoint1);
path.addPoint(currentPoint2);
path.addPoint(currentPoint3);
System.out.println(path);
assertEquals(currentPoint1.getDate(), path.whenWasYouHere(currentPoint1));
assertEquals(currentPoint2.getDate(), path.whenWasYouHere(currentPoint2));
assertEquals(currentPoint3.getDate(), path.whenWasYouHere(currentPoint3));
assertEquals(currentPoint3.getDate(), path.whenWasYouHere(new Point(12,12)));
assertEquals(currentPoint1.getDate(), path.whenWasYouHere(new Point(4,4)));
assertEquals(currentPoint2.getDate(), path.whenWasYouHere(new Point(8,8)));
}
@Test
void testWhereWereYou() throws InterruptedException {
Date currentDate1 = new Date();
DatedPoint currentPoint1 = new DatedPoint(5,5,currentDate1) ;
Thread.sleep(1000);
Date currentDate2 = new Date();
DatedPoint currentPoint2 = new DatedPoint(7,7,currentDate2) ;
Thread.sleep(1000);
DatedPoint currentPoint3 = new DatedPoint(10,10,new Date()) ;
Thread.sleep(1000);
Date currentDate3 = new Date();
Journey path = new Journey(currentPoint1);
path.addPoint(currentPoint2);
path.addPoint(currentPoint3);
assertEquals(currentPoint1, path.whereWereYou(currentDate1));
assertEquals(currentPoint2, path.whereWereYou(currentDate2));
assertEquals(currentPoint3, path.whereWereYou(currentDate3));
assertEquals(currentPoint3, path.whereWereYou(new Date()));
assertEquals(currentPoint1, path.whereWereYou(new Date(currentDate1.getTime()-1000)) );
}
{{:2019_2020:s2:td:journey.jpg|}}