Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • master
1 result

Target

Select target project
No results found
Select Git revision
  • master
1 result
Show changes
35 files
+ 1511
0
Compare changes
  • Side-by-side
  • Inline

Files

Original line number Original line Diff line number Diff line
Cette semaine, les exercices consistent en créer des énumérations, 
enregistrements et interfaces scellés. Nous n'écrirons pas de méthode, donc 
il n'y a pas de test associé, ni de classes fournies. Un fois l'exercice 
fini, demandez à votre enseignant d'évaluer votre solution.

Introduction
============

Un atelier de céramistes d'Aubagne produit différents objets en terre cuite, et 
nous demande de réaliser une application pour gérer ses commandes. Pour cela nous 
devons représenter chaque objet pouvant être fabriqué. Il s'agit
1. d'escudelles, caractérisées par un diamètre (en centimètres);
2. de mazettes, existants en trois tailles (taille café, taille thé ou 
   taille chocolat);
3. de toupins, définis par une contenance en litres;
4. de poumié, avec un nombre arbitraire de pommes (généralement 3 ou 6).

De plus, chaque objet peut être fabriqué avec une couleur au choix, parmi :
1. Corail
2. Olive
3. Jaune de cobalt
4. Indigo
5. Chartreuse
6. Blanc lunaire
7. Céruléen


Exercice 1
==========

Créer un fichier `Color.java` et y définir une énumération pour représenter 
toutes les couleurs disponibles.

Exercice 2
==========

Définir une énumération pour les tailles des mazettes, dans un fichier 
`Mazette.java`.

Exercice 3
==========

Définir dans un fichier `Mazette.java`, un enregistrement pour représenter 
les mazettes.

Exercice 4
==========

Procéder de même pour définir des enregistrements pour représenter les 
escudelles, les toupins et les poumiés.

Exercice 5
==========

Créer une interface scellée `Product`, dans un fichier du même nom. Un 
produit peut-être l'un des quatre proposés. Assurez-vous que chaque produit 
possède bien une couleur.


Original line number Original line Diff line number Diff line
package fr.univamu.progav.td5;

public record Blow(int physicalDamage, int magicalDamage) {
}
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td5;

public abstract class Character {

  // TODO add health points

  public boolean isAlive() {
    // TODO
    return false;
  }

  protected int getHealth() {
    // TODO
    return 0;
  }
  protected void reduceHealth(int amount) {
    // TODO
  }
  protected void setHealth(int health) {
    // TODO
  }

  public abstract Blow attack();

  public abstract void defend(Blow blow);

  public abstract void specialAction();

}
Original line number Original line Diff line number Diff line
Dans cet exercice, nous implémentons le comportement de trois personnages, le 
guerrier, le mage et le prêtre, dans un jeu de rôle. Chacun peut donner et 
recevoir des coups, a des points de vie et meurt lorsque ses points de vie 
deviennent négatifs. Par contre, ils réagissent différemment aux coups, ont des 
attaques différentes et ont chacun une action spéciale spécifique.

Les coups sont décrits par la classe `Blow`, chaque coup ayant une 
composante *dommage physique* et une composante *dommage magique*.
Chaque point de dommage, physique ou magique, fait baisser d'un point la vie 
du personnage recevant le coup.

Le guerrier
-----------

- Ses attaques sont physiques : 3 dommages physiques et 0 dommage magique.
- Il est costaud : il ne subit que la moitié des dommages physiques des 
  coups qu'il reçoit.
- Il peut entrer en rage avec son action spéciale. Sa rage lui permet de 
  frapper deux fois plus fort pendant 3 attaques (6 dommages physiques).
- Après 3 attaques, il perd sa rage.
- S'il reçoit un coup provoquant une perte d'au moins 5 points de vie 
  pendant sa rage, sa rage dure une attaque supplémentaire.

Le mage
-------

- Ses attaques sont magiques : 4 dommages magiques et 0 dommage physique.
- Il absorbe la magie : s'il reçoit un coup, il ne perd pas de vie à cause 
  des dommages magiques, au contraire, la moitié des dommages magiques du 
  coup s'annule avec les dommages physiques (par exemple, pour 5 dommages 
  physiques et 3 magiques, il ne perd que 5 - (3/2) = 4 points de vie).
- L'absorption de magie ne lui permet pas de gagner des points de vie 
  (seulement de réduire les dommages physiques).
- Son action spéciale consiste à invoquer un bouclier magique, qui absorbe 
  les dommages physiques, jusqu'à 8 points. Le bouclier disparait une fois 
  qu'il a absorbé 8 points au total (par exemple après deux attaques faisant 
  5 dommages physiques chacune, il laissera passer 2 dommages physiques lors 
  de la deuxième attaque).
- Le bouclier est appliqué avant la règle de l'absorption des dommages magiques.


Le prêtre
---------

- Ses attaques combinent force (2 dommages physiques) et esprit (1 dommage 
  magique).
- Son action spéciale est de prier.
- Toutes les 3 prières, il est exaucé : il récupère 10 points de vie, et sa 
  prochaine attaque provoque 5 dommages magiques supplémentaires. 


Travail à faire
---------------

1. Compléter l'implémentation du guerrier et de la classe abstraite `Character`.
2. Vérifier votre travail avec les tests du guerrier.
3. Compléter l'implémentation du mage, jusqu'à passage réussi des tests.
4. Créer la classe du prêtre tel que décrit.
 No newline at end of file
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td5;

public class Warrior extends Character {

  private static final int BASE_DAMAGE = 3;
  private static final int BASE_HEALTH = 30;
  public static final int RAGE_DAMAGE_THRESHOLD = 5;

  // TODO add rage

  public Warrior() {
    // TODO
  }

  @Override
  public Blow attack() {
    // TODO
    return null;
  }

  @Override
  public void defend(Blow blow) {
    // TODO
  }

  @Override
  public void specialAction() {
    // TODO
  }

  public int getRage() {
    // TODO
    return 0;
  }
}
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td5;

public class Wizard extends Character {

  private static final int BASE_HEALTH = 20;
  private static final int BASE_DAMAGE = 4;
  private static final int BASE_SHIELD_VALUE = 8;

  // TODO add shield


  public Wizard() {
    // TODO
  }

  @Override
  public Blow attack() {
    //TODO
    return null;
  }

  @Override
  public void defend(Blow blow) {
    // TODO
  }

  @Override
  public void specialAction() {
    // TODO
  }

  public int getShield() {
    // TODO
    return 0;
  }
}
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td6;

public class ArrayCellLens<T> implements Lens<T> {

  // TODO ajouter les propriétés

  public ArrayCellLens(T[] array, int index) {
    // TODO
  }

  @Override
  public T get() {
    // TODO
    return null;
  }

  @Override
  public void set(T t) {
    // TODO
  }
}
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td6;

public class Box implements Lens<Integer> {

  private int content;

  public Box(int content) {
    this.content = content;
  }

  @Override
  public void set(Integer newContent) {
    this.content = newContent;
  }

  @Override
  public Integer get() {
    return this.content;
  }
}
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td6;

import java.util.List;

public class ListCellLens<T> implements Lens<T> {

  // TODO ajouter les propriétés

  public ListCellLens(List<T> list, int index) {
    // TODO
  }

  @Override
  public void set(T t) {
    // TODO
  }

  @Override
  public T get() {
    // TODO
    return null;
  }
}
Original line number Original line Diff line number Diff line
Ces exercices ont pour sujet une interface `Lens` générique, permettant 
de représenter un emplacement mémoire autorisant la lecture et l'écriture.

Prendre connaissance de cette interface, qui propose deux méthodes `set`
et `get`.


Exercice 1
==========

Rendre la classe `Box` générique. Pour l'instant elle implémente un 
`Lens<Integer>`, mais nous voulons l'utiliser avec d'autres types.

Modifier la méthode de test `genericTest` de la classe `BoxTest` pour qu'elle 
fonctionne.

Exercice 2
==========

Étant donné une liste, chaque case de la liste est accessible en lecture et 
en écriture. Il est donc possible de décrire chaque case avec l'interface 
`Lens`. Compléter la classe générique `ListCellLens`, prenant une liste et 
l'indice d'une case en paramètre du constructeur, et représentant la case ainsi 
désignée.

Vérifiez votre travail à l'aide des tests `ListCellLensTest` associés à la 
classe.

Exercice 3
==========

Nous pouvons faire la même chose avec les tableaux. Compléter la classe 
générique `ArrayCellLens`, prenant un tableau et
l'indice d'une case en paramètre du constructeur, et représentant la case ainsi
désignée.

Vérifiez votre travail à l'aide des tests `ArrayCellLensTest` associés à la 
classe.

Exercice 4
==========

Si vous essayez d'utiliser `ArrayCellLens` avec un tableau de type `int[]`, 
cela produit une erreur à la compilation. Pourquoi ?

Ajouter une classe `IntArrayCellLens` pour pouvoir faire un `Lens` sur une 
case d'un tableau de type `int[]`.

Ajouter un test dans la classe `ArrayCellLensTest`, s'assurant du bon 
fonctionnement des méthodes `set` et `get` pour une case d'un tableau de 
type `int[]`

Exercice 5 (Optionnel)
======================

Nous pouvons utiliser un objet de type `Lens` pour stocker une valeur sous 
un format compressé. Pour un type `S` (dont les valeurs prennent beaucoup de 
place), si nous disposons d'une fonction de compression `f` vers un type `T` 
(nécessitant moins de place), et de son inverse `g`, nous pouvons 
représenter une valeur `s` de type `S` en stockant uniquement `f(s)`. La 
méthode `get` applique automatiquement `g` pour retrouver la valeur initiale 
(de type `S`). La méthode `set` applique automatiquement `f` pour ne stocker 
qu'une image (de type `T`). Ainsi, nous réduisons l'espace utilisé, en 
échange d'un coût de calcul des fonctions `f` et `g` `chaque opération.

Ajouter une interface `Bijection` permettant de représenter par deux 
méthodes les fonctions `f` et `g`.

Ensuite créer une classe `ConvertingLens`, de type `Lens<S>`, et ayant une 
propriété de type `T`. Le constructeur sera paramétré par la bijection à 
utiliser.

Tester avec `S = String`, `T = Integer`, en se restreignant aux chaînes de 
caractères correspondant à des nombres décimaux (comme `"129873"`)
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td7;

import java.util.Iterator;
import java.util.NoSuchElementException;

/** A class to represent sets of consecutive integers.
 * @param mini the smallest integer in the set.
 * @param maxi the largest integer in the set. If maxi < mini, the set is empty.
 */
public record Interval(int mini, int maxi) implements Iterable<Integer> {

  /**
   * @param i an arbitrary integer
   * @return true if i is in the set
   */
  public boolean contains(int i) {
    // TODO
    return false;
  }

  /**
   * @return the number of integers in the set.
   */
  public int size() {
    // TODO
    return -1;
  }

  /**
   * @return true if this is empty.
   */
  public boolean isEmpty() {
    // TODO
    return false;
  }

  /** Decide whether two intervals intersect each other.
   * @param range the second interval
   * @return true if this and range intersect
   */
  public boolean intersects(Interval range) {
    // TODO
    return false;
  }

  /**
   * @return an iterator over the integers in the set
   */
  @Override
  public Iterator<Integer> iterator() {
    return new Iterator<Integer>() {
      // TODO ajouter une propriété pour le prochain élément

      @Override
      public boolean hasNext() {
        // TODO
        return false;
      }

      @Override
      public Integer next() {
        if (!hasNext()) {
          throw new NoSuchElementException();
        }
        // TODO
        return null;
      }
    } ;
  }
}
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td7;

public class IntervalSequences {

  public static boolean containsEmptyInterval(Sequence<Interval> intervals) {
    // TODO
    return false;
  }

  public static int sumOfSizes(Sequence<Interval> intervals) {
    // TODO
    return -1;
  }


  public static Interval longestInterval(Sequence<Interval> intervals) {
    // TODO
    return null;
  }


}
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td7;

import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.Predicate;

public interface Sequence<T> {

  void forEach(Consumer<T> action);

  boolean anyMatch(Predicate<T> predicate);

  T maximum(Comparator<T> compare);
}
Original line number Original line Diff line number Diff line
Cette semaine les exercices portent sur les classes anonymes, les lambdas et 
les références de méthodes.


Exercice 1
==========

Compléter la classe ```Interval``` qui représente des ensembles d'entiers 
consécutifs, comme $\{3,4,5,6,7\}$.

Pour la méthode ```iterator```, compléter la classe anonyme. Il faudra 
ajouter une propriété pour retenir le prochain entier de l'itération. 

Vérifier votre travail avec les tests de la classe ```IntervalTest```.

Exercice 2
==========

Une ```Sequence<T>``` ressemble à une ```List<T>```, mais on ne nous donne 
que des méthodes nécessitant un argument fonctionnel.

- ```forEach``` demande un ```Consumer<T>```, une action qui sera appliquée 
  à chaque élément de la séquence. L'interface ```Consumer<T>``` est définie 
  par 
```java
interface Consumer<T> {
  void accept(T value);
}
```
- ```anyMatch``` demande un ```Predicate<T>```, un prédicat pouvant être 
  appliqué aux éléments de la séquence. ```anyMatch``` renvoie ```true``` si au 
  moins un des éléments de la séquence satisfait le prédicat. L'interface 
  ```Predicate<T>``` est définie par
```java
interface Predicate<T> {
  boolean test(T value);
}
```
- ```maximum``` demande un ```Comparator<T>```, un objet capable de décider 
  quel est la plus grande de 2 valeurs de type ```T```. L'interface 
  ```Comparator<T>``` est définie par 
```java
interface Comparator<T> {
  int compare(T t1, T t2);
}
```

Compléter les méthodes statiques de la classe ```IntervalSequence```. Pour 
cela :

- pour ```containsEmptyInterval```, utiliser une référence de méthode pour 
  définir le prédicat "est vide" des intervalles.
- Pour ```sumOfSizes```, essayer d'utiliser une lambda avec un compteur 
  de type ```int```. Cela ne va pas fonctionner, pourquoi ? 
- Introduire une interface correspondant à un compteur entier :
```java
  interface IntCounter {
    void add(int value);
    int get();
  }
```
- Dans ```sumOfSizes```, créer un compteur à l'aide d'une classe anonyme, 
  puis utiliser ```forEach``` sur la séquence avec une lambda pour augmenter 
  le compteur.
- Dans ```longestInterval```, utiliser une lambdas.
- Vérifier votre travail avec les tests de la classe 
  ```IntervalSequencesTest```.

Original line number Original line Diff line number Diff line
package fr.univamu.progav.td8;

import fr.univamu.progav.td1.ExercicesBoucles;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class ExercicesStream {

  public interface Person {
    int age();
    String name();
    boolean isFemale();
    Person mother();
    Person father();
    List<Person> children();
  }

  // Exercice : compléter toutes les méthodes suivantes


  // retourne vrai si la stream contient une femme
  public static boolean hasFemale(Stream<Person> persons) {
    // TODO
    return false;
  }


  // retourne vrai si la stream contient un individu homme et mineur (moins de 18 ans)
  public static boolean containsMinorMale(Stream<Person> persons) {
    // TODO
    return false;
  }


  // retourne un individu de la stream, femme et ayant au moins un enfant,
  // null si aucun individu ne convient
  public static Optional<Person> findMother(Stream<Person> persons) {
    // TODO
    return Optional.empty();
  }


  // retourne vrai si tous les individus de la stream sont majeurs (âge >= 18)
  public static boolean areAllMajor(Stream<Person> persons) {
    // TODO
    return false;
  }


  // retourne la liste de tous les hommes de la stream.
  public static List<Person> males(Stream<Person> persons) {
    // TODO
    return List.of();
  }


  // retourne le nombre de femmes de la stream
  public static long nbFemales(Stream<Person> persons) {
    // TODO
    return 0L;
  }

  // trouve un individu de la stream ayant un enfant, et retourne l'âge
  // de cet enfant.
  public static Optional<Integer> ageOfSomeChild(Stream<Person> persons) {
    // TODO
    return Optional.empty();
  }


  // retourne la personne la plus agée de la stream,
  public static Optional<Person> eldest(Stream<Person> persons) {
    // TODO
    return Optional.empty();
  }


  // retourne une chaîne de caractères, comprenant les noms de toutes les
  // personnes de la stream, dans l'ordre, séparés par une espace.
  public static String names(Stream<Person> persons) {
    // TODO
    return "";
  }


  // retourne l'âge moyen des individus de la stream
  public static OptionalDouble averageAge(Stream<Person> persons) {
    // TODO
    return OptionalDouble.empty();
  }


  private static class SexCount {
    // TODO ajouter des propriétés pour compter le nombre d'hommes et de femmes
    SexCount() {}

    void add(Person p) {
      // TODO dénombrer p dans les statistiques
    }

    void merge(SexCount count) {
      // TODO fusionner les statistiques
    }

    boolean areEquals() {
      // TODO renvoyer vrai si les nombres de femmes et d'hommes sont égaux
      return false;
    }
  }
  // retourne vrai si les nombres d'hommes et de femmes sont égaux.
  public static boolean hasAsManyMalesAsFemales(Stream<Person> persons) {
    Supplier<SexCount> supplier = null; // TODO initialiser les 3 variables.
    BiConsumer<SexCount, Person> accumulator = null;
    BiConsumer<SexCount,SexCount> combiner = null;
    return persons
      .collect(supplier,accumulator,combiner)
      .areEquals();
  }
}
Original line number Original line Diff line number Diff line
Exercice
========

Compléter les méthodes de la classe `ExercicesStream`.

Vous devez utiliser des Stream. Il est interdit d'utiliser des boucles ou 
des récursions. Il est interdit de convertir les streams en listes (sauf 
pour calculer la liste à retourner dans la méthode ```males```). Toutes 
les méthodes doivent avoir une seule instruction, l'instruction ```return```.

La dernière méthode est la plus difficile, elle demande de construire un 
collecteur à partir de trois éléments :
- un ```Supplier<R>```, ```R``` étant le type des objets effectuant la 
  collection, disons un collecteur. Ce ```Supplier``` permet de créer un 
  nouveau collecteur; 
- un ```BiConsumer<R,People>```, qui est une fonction prenant un collecteur 
  et une personne collectée. C'est en général la méthode du collecteur 
  chargé d'accepter les personnes collectées l'une après l'autre. Le 
  collecteur met à jour son état interne pour tenir compte de la personne 
  collectée.
- un ```BiConsumer<R,R>```, qui est une fonction permettant de fusionner le 
  travail de deux collecteurs. Le premier collecteur agrège les données 
  récoltées par le deuxième collecteur dans son état interne.

Pour nous, le collecteur est un objet calculant le nombre de personnes de 
chaque sexe. Le premier argument sera donc son constructeur, le deuxième 
sera sa méthode ```add```, et le troisième sa méthode ```merge```, chacun 
pouvant être donné par une référence de méthode. Une fois le collecteur 
effectué, il reste à utiliser la méthode ```areEquals()``` pour déterminer 
si le nombre de femmes est égal au nombre d'hommes.

Tous les tests de ```ExercicesStreamTest``` doivent passer à la fin de 
l'exercice.
 No newline at end of file
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td9;

public record Book(String isbn, String title) {

  @Override
  public String toString() {
    return title + " (" + isbn + ")";
  }
}
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td9;

import java.util.ArrayList;
import java.util.List;

public record BulkCheckoutResult(
  List<Book> successfulCheckouts,
  List<BookException> failedCheckouts
) {

  public BulkCheckoutResult() {
    this(new ArrayList<>(), new ArrayList<>());
  }

  public boolean isCompletelySuccessful() {
    // TODO
    return false;
  }

}
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td9;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Library {

  private final Map<String, Book> collection = new HashMap<>();
  private final Map<Book, BookStatus> bookStatuses = new HashMap<>();

  public void addBook(Book book) {
    collection.put(book.isbn(), book);
    bookStatuses.put(book, BookStatus.AVAILABLE);
  }

  public Book findBook(String isbn) {
    // TODO
    return null;
  }


  public BookStatus getBookStatus(String isbn) {
    // TODO
    return null;
  }

  public Book checkoutBook(String isbn) {
    // TODO
    return null;
  }

  public BulkCheckoutResult checkoutBooks(List<String> isbns) {
    // TODO
    return null;
  }

}
Original line number Original line Diff line number Diff line
Ces exercices portent sur la gestion des exceptions. Le contexte est la 
gestion des livres d'une bibliothèque, qui n'est pas un exemple très 
pertinent pour l'utilisation d'exceptions, mais qui a l'avantage d'être 
relativement simple pour apprendre les bases de la manipulation des exceptions.

La bibliothèque ```Library``` possède une collection de livres ```Book```, et 
les clients peuvent venir emprunter un ou plusieurs livres (méthodes 
```checkoutBook``` et ```checkoutBooks```). Un livre peut donc être 
disponible ou indisponible (classe ```BookStatus```), ou bien ne pas faire 
partie de la bibliothèque.

Si un client veut emprunter un livre déjà prêté, l'exception 
```BookUnavailableException``` sera levée. Si le livre n'est pas possédé par la 
bibliothèque, l'exception ```BookNotFoundException``` sera levée.

Exercice 1
==========

Compléter les 2 extensions ```BookNotFoundException``` (possédant un code 
ISBN) et ```BookUnavailable``` (possédant un livre) de la 
classe```BookException```. Assurez-vous que la méthode ```getMessage``` de 
chacune délivre un message adapté et mentionnant soit le code ISBN, soit le 
livre concerné.

Exercice 2
==========

Compléter la méthode ```findBook``` de la classe ```Library```. Elle doit 
retourner le livre dont le code ISBN est fourni. S'il n'existe pas un tel 
livre, il faut émettre l'exception ```BookNotFoundException```. Ajouter la 
déclaration d'exception à la méthode.

Exercice 3
==========

Compléter la méthode ```checkBookStatus``` de la classe ```Library```, 
retournant le status d'un livre précisé par son code ISBN. Si le livre 
n'existe pas, l'exception ```BookNotFound``` sera émise. Ajouter la
déclaration d'exception à la méthode.

Exercice 4
==========

Compléter la méthode ```checkoutBook``` de la classe ```Library```.
La méthode vérifie l'existence et la disponibilité du livre (donné par son 
code ISBN), et modifie alors son status à ```BORROWED```. Si les conditions 
ne sont pas respectées, la méthode émet l'exception appropriée. Ajouter la
déclaration d'exception à la méthode.

Exercice 5
==========

Compléter la méthode ```isCompletelySuccessful``` de la classe 
```BulkCheckoutResult```. Cette classe contiendra les résultats de la 
réservation d'une liste de livres, comprenant :
- la liste des livres empruntés;
- la liste des échecs des tentatives d'emprunt.

Exercice 6
==========

Compléter la méthode ```checkoutBooks``` de la classe ```Library```.


Vérifier votre travail à l'aide des tests fournis.
 No newline at end of file
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td5;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;
class WarriorTest {

  @Test
  void newWarrior() {
    Warrior warrior = new Warrior();
    assertEquals(30,warrior.getHealth());
    warrior.reduceHealth(8);
    assertEquals(22,warrior.getHealth());
    warrior.setHealth(25);
    assertEquals(25,warrior.getHealth());
  }

  @Test
  void attack() {
    Warrior warrior = new Warrior();
    Blow b = warrior.attack();
    assertEquals(3,b.physicalDamage());
    assertEquals(0,b.magicalDamage());
  }

  @Test
  void defend() {
    Warrior warrior = new Warrior();
    warrior.defend(new Blow(10,2));
    assertEquals(23,warrior.getHealth());
    warrior.defend(new Blow(1,5));
    assertEquals(18,warrior.getHealth());
  }

  @Test
  void specialAction() {
    Warrior warrior = new Warrior();
    warrior.specialAction();
    Blow b  = warrior.attack();
    assertEquals(6,b.physicalDamage());
    assertEquals(0,b.magicalDamage());
    b  = warrior.attack();
    b  = warrior.attack();
    assertEquals(6,b.physicalDamage());
    assertEquals(0,b.magicalDamage());
    b  = warrior.attack();
    assertEquals(3,b.physicalDamage());
    assertEquals(0,b.magicalDamage());
  }

  @Test
  void getRage() {
    Warrior warrior = new Warrior();
    assertEquals(0,warrior.getRage());
    warrior.specialAction();
    assertEquals(3,warrior.getRage());
    warrior.attack();
    assertEquals(2,warrior.getRage());
    warrior.specialAction();
    assertEquals(3,warrior.getRage());
  }

  @Test
  void defendIncreaseRage() {
    Warrior warrior = new Warrior();
    warrior.defend(new Blow(4,4));
    assertEquals(0,warrior.getRage(), "Warrior does not enter rage by receiving a blow");
    warrior.specialAction();
    warrior.defend(new Blow(0,5));
    assertEquals(4,warrior.getRage(), "Increase rage when 5 health lost");
    warrior.defend(new Blow(0,4));
    assertEquals(4,warrior.getRage(), "Do not increase rage when <5 health lost");
    warrior.defend(new Blow(6,0));
    assertEquals(4,warrior.getRage(),"Do not increase rage when <5 health lost");
  }
}
 No newline at end of file
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td5;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;
class WizardTest {


  @Test
  void newWizard() {
    Wizard wizard = new Wizard();
    assertEquals(20,wizard.getHealth());
    assertEquals(0,wizard.getShield());
    assertTrue(wizard.isAlive());
  }

  @Test
  void attack() {
    Wizard wizard = new Wizard();
    Blow b = wizard.attack();
    assertEquals(4, b.magicalDamage());
    assertEquals(0, b.physicalDamage());
    wizard.specialAction();
    b = wizard.attack();
    assertEquals(4, b.magicalDamage());
    assertEquals(0,b.physicalDamage());
  }

  @Test
  void defend() {
    Wizard wizard = new Wizard();
    assertEquals(20,wizard.getHealth());
    wizard.defend(new Blow(6,2));
    assertEquals(15,wizard.getHealth(), "Wizard loses life on physical attack, but physical damage is reduced by half of magical damage");
    wizard.defend(new Blow(0,10));
    assertEquals(15,wizard.getHealth(), "Wizard does not gain life on magical attack.");
  }

  @Test
  void specialAction() {
    Wizard wizard = new Wizard();
    wizard.specialAction();
    assertEquals(20, wizard.getHealth());
    wizard.defend(new Blow(6, 2));
    assertEquals(20, wizard.getHealth(), "Wizard's shield absorbs physical damage");
    assertEquals(2, wizard.getShield());
    wizard.defend(new Blow(6, 2));
    assertEquals(
      17,
      wizard.getHealth(),
      "Wizard's shield absorbs physical damage until depleted, then normal rules apply"
    );
    assertEquals(0, wizard.getShield());
  }

  @Test
  void maxShieldValue() {
    Wizard wizard = new Wizard();
    wizard.specialAction();
    wizard.defend(new Blow(5,0));
    wizard.specialAction();
    wizard.defend(new Blow(5,0));
    assertEquals(3, wizard.getShield(),"Wizard's special action sets shield to 8 (not an addition)");
  }
}
 No newline at end of file
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td6;

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

class ArrayCellLensTest {

  @Test
  void testGet() {
    Integer[] array = {4, 3, 2, 1};
    Lens<Integer> lens1 = new ArrayCellLens<>(array, 1);
    assertEquals(3, lens1.get());
    array[1] = 5;
    assertEquals(5, lens1.get());
  }

  @Test
  void testSet() {
    Integer[] array = {4, 3, 2, 1};
    Lens<Integer> lens1 = new ArrayCellLens<>(array, 1);
    lens1.set(8);
    assertEquals(8, lens1.get());
  }


  @Test
  void testSetModifyArray() {
    Integer[] array = {4, 3, 2, 1};
    Lens<Integer> lens1 = new ArrayCellLens<>(array, 1);
    lens1.set(5);
    assertEquals(5, lens1.get());
    assertEquals(5, array[1]);
    assertEquals(4, array[0]);
    assertEquals(2, array[2]);
  }

}
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td6;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class BoxTest {

  @Test
  void testGet() {
    Lens<Integer> box = new Box(0);
    assertEquals(0,box.get());
    box = new Box(42);
    assertEquals(42,box.get());
  }

  @Test
  void testSet() {
    Lens<Integer> box = new Box(0);
    box.set(3);
    assertEquals(3,box.get());
    box.set(5);
    assertEquals(5,box.get());
    box.set(-3);
    assertEquals(-3,box.get());
  }


  @Test
  void genericBox() {
    Lens<String> box = null; // TODO créer une boîte contenant "foo"
    assertEquals("foo", box.get());
    box.set("bar");
    assertEquals("bar", box.get());
    Lens<Lens<Integer>> boxbox = null; // TODO créer une boîte contenant une boîte contenant 0
    boxbox.get().set(2);
    assertEquals(2,boxbox.get().get());
  }

}
 No newline at end of file
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td6;

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

class ListCellLensTest {

  @Test
  void testGet() {
    List<Integer> list = new ArrayList<>(List.of(4,3,2,1));
    Lens<Integer> lens1 = new ListCellLens<>(list, 1);
    assertEquals(3, lens1.get());
    list.set(1,5);
    assertEquals(5, lens1.get());
  }

  @Test
  void testSet() {
    List<Integer> list = new ArrayList<>(List.of(4,3,2,1));
    Lens<Integer> lens1 = new ListCellLens<>(list, 1);
    lens1.set(8);
    assertEquals(8, lens1.get());
  }


  @Test
  void testSetModifyList() {
    List<Integer> list = new ArrayList<>(List.of(4,3,2,1));
    Lens<Integer> lens1 = new ListCellLens<>(list, 1);
    lens1.set(5);
    assertEquals(5, lens1.get());
    assertEquals(5, list.get(1));
    assertEquals(4, list.get(0));
    assertEquals(2, list.get(2));
  }

}
 No newline at end of file
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td7;

import org.junit.jupiter.api.Test;

import static fr.univamu.progav.td7.IntervalSequences.*;
import static org.junit.jupiter.api.Assertions.*;

class IntervalSequencesTest {

  private final Sequence<Interval> seq1 = new ListSequence<>(
    new Interval(2,8),
    new Interval(-4,5),
    new Interval(3,-2),
    new Interval(-9,-3)
  );
  private final Sequence<Interval> seq2 = new ListSequence<>(
    new Interval(0,0),
    new Interval(0,10),
    new Interval(-10,5),
    new Interval(-3,-3)
  );
  private final Sequence<Interval> seqEmpty = new ListSequence<>();

  @Test
  void testContainsEmptyInterval() {
    assertTrue(containsEmptyInterval(seq1));
    assertFalse(containsEmptyInterval(seq2));
    assertFalse(containsEmptyInterval(seqEmpty));
  }

  @Test
  void testSumOfSizes() {
    assertEquals(24, sumOfSizes(seq1));
    assertEquals(29, sumOfSizes(seq2));
    assertEquals(0, sumOfSizes(seqEmpty));
  }

  @Test
  void testLongestInterval() {
    assertEquals(10,longestInterval(seq1).size());
    assertEquals(16,longestInterval(seq2).size());
    assertNull(longestInterval(seqEmpty));
  }
}
 No newline at end of file
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td7;

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

import static org.junit.jupiter.api.Assertions.*;

class IntervalTest {

  @Test
  void contains() {
    Interval range = new Interval(-2, 5);
    assertTrue(range.contains(-2));
    assertTrue(range.contains(0));
    assertTrue(range.contains(1));
    assertTrue(range.contains(4));
    assertTrue(range.contains(5));
    assertFalse(range.contains(-3));
    assertFalse(range.contains(-30));
    assertFalse(range.contains(6));
    assertFalse(range.contains(42));
    assertFalse(range.contains(2904429));
  }

  @Test
  void size() {
    assertEquals(5, new Interval(0,4).size());
    assertEquals(0, new Interval(4,0).size());
    assertEquals(6, new Interval(4,9).size());
    assertEquals(7, new Interval(-7,-1).size());
    assertEquals(8, new Interval(-3,4).size());
    assertEquals(1, new Interval(3,3).size());
  }

  @Test
  void isEmpty() {
    assertTrue(new Interval(5,3).isEmpty());
    assertTrue(new Interval(2,-5).isEmpty());
    assertTrue(new Interval(0,-1).isEmpty());
    assertTrue(new Interval(1,0).isEmpty());
    assertFalse(new Interval(1,1).isEmpty());
    assertFalse(new Interval(0,0).isEmpty());
    assertFalse(new Interval(-3,3).isEmpty());
  }

  @Test
  void intersects() {
    assertTrue(new Interval(1,5).intersects(new Interval(2,3)));
    assertTrue(new Interval(-5,5).intersects(new Interval(-3,-2)));
    assertTrue(new Interval(-5,5).intersects(new Interval(-2,3)));
    assertTrue(new Interval(-5,5).intersects(new Interval(-6,-5)));
    assertTrue(new Interval(-5,5).intersects(new Interval(5,7)));
    assertTrue(new Interval(-3,4).intersects(new Interval(-4,8)));
    assertFalse(new Interval(-3,4).intersects(new Interval(2,-2)));
    assertFalse(new Interval(-3,4).intersects(new Interval(5,8)));
    assertFalse(new Interval(-3,4).intersects(new Interval(-7,-4)));
    assertFalse(new Interval(-3,4).intersects(new Interval(12,35)));
    assertFalse(new Interval(-3,4).intersects(new Interval(67,-21)));
  }

  @Test
  void iterator() {
    Iterator<Integer> iterator = new Interval(-2,8).iterator();
    List<Integer> elements = new ArrayList<>();
    while (iterator.hasNext()) {
      elements.add(iterator.next());
    }
    assertEquals(List.of(-2,-1,0,1,2,3,4,5,6,7,8), elements);
    assertThrows(NoSuchElementException.class, iterator::next, "Iterator.next() must throw NoSuchElementException when iteration is over");
    iterator = new Interval(0,-1).iterator();
    assertFalse(iterator.hasNext());
    assertThrows(NoSuchElementException.class, iterator::next, "Iterator.next() must throw NoSuchElementException when iteration is over");
  }

}
 No newline at end of file
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td7;



import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;

public class ListSequence<T> implements Sequence<T> {
// Ne pas modifier cette classe !
  private final List<T> elements;


  public ListSequence(List<T> elements) {
    this.elements = elements;
  }

  @SafeVarargs
  public ListSequence(T... elements) {
    this.elements = Arrays.asList(elements);
  }

  public void forEach(Consumer<T> action) {
    elements.forEach(action);
  }

  public boolean anyMatch(Predicate<T> predicate) {
    return elements.stream().anyMatch(predicate);
  }

  public T maximum(Comparator<T> compare) {
    return elements.stream().max(compare).orElse(null);
  }
}
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td8;

import fr.univamu.progav.td8.ExercicesStream;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static fr.univamu.progav.td8.ExercicesStream.Person;
import static org.junit.jupiter.api.Assertions.*;

class ExercicesStreamTest {

  private record MockPerson(
    int age,
    String name,
    boolean isFemale,
    Person mother,
    Person father,
    List<Person> children
  ) implements Person {
    @Override
    public String toString() {
      return this.name;
    }
  }

  private static final Person alfa =
    new MockPerson(78,"Alfa",true,null,null, new ArrayList<>());
  private static final Person bravo =
    new MockPerson(82,"Bravo",false,null,null, new ArrayList<>());
  private static final Person charlie =
    new MockPerson(42,"Charlie",false, alfa,bravo,List.of());
  private static final Person delta =
    new MockPerson(38,"Delta",false, alfa,bravo, new ArrayList<>());
  private static final Person echo =
    new MockPerson(41,"Echo",true,null,null, new ArrayList<>());
  private static final Person foxtrot =
    new MockPerson(7,"Foxtrot",true,echo,delta, List.of());
  private static final Person golf =
    new MockPerson(25,"Golf",true,null,null, new ArrayList<>());
  private static final Person hotel =
    new MockPerson(2,"Hotel",false,golf,null, List.of());
  private static final Person india =
    new MockPerson(8,"India",true,null,null, List.of());
  private static final Person juliett =
    new MockPerson(18,"Juliett",false,null,null,List.of());

  static {
    alfa.children().addAll(List.of(charlie, delta));
    bravo.children().addAll(List.of(charlie, delta));
    delta.children().add(foxtrot);
    echo.children().add(foxtrot);
    golf.children().add(hotel);
  }

  private static final List<Person> ALL =
    List.of(alfa,bravo,charlie,delta,echo,foxtrot,golf,hotel,india,juliett);
  private static Stream<Person> femaleStream() {
    return Stream.of(alfa, echo, foxtrot, golf, india);
  }
  private static Stream<Person> maleStream() {
    return Stream.of(bravo,charlie,delta,hotel,juliett);
  }
  @Test
  void hasFemale() {
    assertTrue(ExercicesStream.hasFemale(ALL.stream()));
    assertFalse(ExercicesStream.hasFemale(Stream.of(bravo,charlie,delta)));
    assertTrue(ExercicesStream.hasFemale(Stream.of(alfa)));
    assertFalse(ExercicesStream.hasFemale(Stream.of()), "Cas de la stream vide");
  }

  @Test
  void containsMinorMale() {
    assertTrue(ExercicesStream.containsMinorMale(ALL.stream()));
    assertFalse(ExercicesStream.containsMinorMale(Stream.of(bravo,charlie,delta)), "Pas de mineurs");
    assertFalse(ExercicesStream.containsMinorMale(Stream.of(foxtrot,india)), "Pas d'hommes");
    assertFalse(ExercicesStream.containsMinorMale(Stream.of()), "Cas de la stream vide");
  }

  @Test
  void findMother() {
    Optional<Person> found = ExercicesStream.findMother(ALL.stream());
    assertTrue(found.isPresent());
    assertTrue(found.get().isFemale() && !found.get().children().isEmpty());
    assertEquals(Optional.of(golf),ExercicesStream.findMother(Stream.of(bravo,charlie,delta,golf,hotel,india)));
    assertEquals(Optional.empty(), ExercicesStream.findMother(Stream.of(bravo,charlie,delta,foxtrot,hotel,india)));
    assertEquals(Optional.empty(), ExercicesStream.findMother(Stream.of()), "Cas de la stream vide");
  }

  @Test
  void areAllMajor() {
    assertFalse(ExercicesStream.areAllMajor(ALL.stream()));
    assertTrue(ExercicesStream.areAllMajor(Stream.of(alfa,bravo,charlie,delta,echo,golf)));
    assertTrue(ExercicesStream.areAllMajor(Stream.of(alfa,bravo,charlie,delta,echo,golf,juliett)), "Cas d'un individu ayant 18 ans");
    assertFalse(ExercicesStream.areAllMajor(Stream.of(foxtrot,hotel,india)));
    assertTrue(ExercicesStream.areAllMajor(Stream.of()), "Cas de la stream vide");
  }

  @Test
  void ageOfSomeChild() {
    Optional<Integer> maybeAge =
      ExercicesStream.ageOfSomeChild(Stream.of(hotel, india, juliett, alfa, foxtrot, charlie));
    assertTrue(maybeAge.isPresent());
    assertTrue(List.of(charlie.age(),delta.age()).contains(maybeAge.get()));
    assertTrue(ExercicesStream.ageOfSomeChild(Stream.of(charlie,foxtrot,hotel,india,juliett)).isEmpty());
    assertTrue(ExercicesStream.ageOfSomeChild(Stream.of()).isEmpty(),"Cas de la stream vide");
  }

  @Test
  void males() {
    List<Person> allMales = ExercicesStream.males(ALL.stream());
    List<Person> expected = ALL.stream().filter(p -> !p.isFemale()).toList();
    assertNotNull(allMales);
    assertEquals(expected.size(), allMales.size(), "Nombre d'hommes incorrect");
    for (Person p : expected ) {
      assertTrue(allMales.contains(p), p.name() + " est un homme qui n'est pas dans la stream");
    }
    List<Person> neitherMaleNorFemale = ExercicesStream.males(femaleStream());
    assertNotNull(neitherMaleNorFemale);
    assertTrue(neitherMaleNorFemale.isEmpty());
    List<Person> empty = ExercicesStream.males(Stream.of());
    assertNotNull(empty, "Cas de la stream vide");
    assertTrue(empty.isEmpty(), "Cas de la stream vide");
  }

  @Test
  void nbFemales() {
    assertEquals(0,ExercicesStream.nbFemales(Stream.of()), "Cas de la stream vide");
    assertEquals(5,ExercicesStream.nbFemales(ALL.stream()));
    assertEquals(0,ExercicesStream.nbFemales(maleStream()));
  }

  @Test
  void eldest() {
    assertTrue(ExercicesStream.eldest(Stream.of()).isEmpty(), "Cas de la stream vide");
    assertEquals(Optional.of(bravo),ExercicesStream.eldest(ALL.stream()));
  }

  @Test
  void names() {
    String allNames = ExercicesStream.names(ALL.stream()).trim();
    assertEquals("Alfa Bravo Charlie Delta Echo Foxtrot Golf Hotel India Juliett",allNames);
    assertEquals("",ExercicesStream.names(Stream.of()), "Cas de la liste vide");
  }

  @Test
  void hasAsManyMalesAsFemales() {
    assertTrue(ExercicesStream.hasAsManyMalesAsFemales(Stream.of()), "Cas de la liste vide");
    assertFalse(ExercicesStream.hasAsManyMalesAsFemales(Stream.of(alfa)));
    assertFalse(ExercicesStream.hasAsManyMalesAsFemales(Stream.of(bravo)));
    assertFalse(ExercicesStream.hasAsManyMalesAsFemales(femaleStream()));
    assertFalse(ExercicesStream.hasAsManyMalesAsFemales(maleStream()));
    assertTrue(ExercicesStream.hasAsManyMalesAsFemales(ALL.stream()));
  }

  @Test
  void averageAge() {
    assertTrue(ExercicesStream.averageAge(Stream.of()).isEmpty(), "Cas de la liste vide");
    OptionalDouble average = ExercicesStream.averageAge(ALL.stream());
    assertTrue(average.isPresent());
    double expected = 34.1;
    assertTrue(Math.abs(average.getAsDouble() - expected) < 0.1, "La moyenne correcte est " + expected);
  }
}
 No newline at end of file
Original line number Original line Diff line number Diff line
package fr.univamu.progav.td9;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

public class LibraryTest {

  private Library library;
  private Book book1;
  private Book book2;
  private Book book3;

  @BeforeEach
  void setUp() {
    library = new Library();
    book1 = new Book("123", "Livre 1");
    book2 = new Book("456", "Livre 2");
    book3 = new Book("789", "Livre 3");
    library.addBook(book1);
    library.addBook(book2);
    library.addBook(book3);
  }

  @Test
  void testFindBookThrowsException() {
    assertThrows(BookNotFoundException.class, () -> {
      library.findBook("999");
    });
  }

  @Test
  void testSingleCheckoutSuccess() throws BookException {
    library.checkoutBook("123");
    assertEquals(BookStatus.BORROWED, library.getBookStatus("123"));
  }

  @Test
  void testBulkCheckoutPartialSuccess() throws BookException {
    library.checkoutBook("123");
    Book nonExistentBook = new Book("999", "Nonexistent");
    List<String> booksToCheckout = List.of("123", "456", "999");
    BulkCheckoutResult result = library.checkoutBooks(booksToCheckout);
    assertFalse(result.isCompletelySuccessful());
    assertEquals(1, result.successfulCheckouts().size());
    assertEquals(2, result.failedCheckouts().size());
    assertInstanceOf(BookUnavailableException.class, result.failedCheckouts().get(0));
    assertInstanceOf(BookNotFoundException.class, result.failedCheckouts().get(1));
    assertEquals(
      "Livre 1 (123): book unavailable",
      result.failedCheckouts().get(0).getMessage()
    );
    assertEquals(
      "Nonexistent (999): book not found",
      result.failedCheckouts().get(1).getMessage()
    );
  }

  @Test
  void testBulkCheckoutAllSuccess() {
    List<String> booksToCheckout = List.of("123", "456");
    BulkCheckoutResult result = library.checkoutBooks(booksToCheckout);

    assertTrue(result.isCompletelySuccessful());
    assertEquals(2, result.successfulCheckouts().size());
    assertTrue(result.failedCheckouts().isEmpty());
  }
}