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
  • z22024794/prog-av-exercices-fadl-zemzem
  • n23017542/progavexercices
  • l23024794/saratp-1
  • d24029849/progavexercices
  • gnaves/progavexercices
5 results
Select Git revision
  • master
1 result
Show changes
Commits on Source (6)
Showing
with 667 additions and 0 deletions
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
}
}
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;
}
}
package fr.univamu.progav.td6;
public interface Lens<T> {
void set(T t);
T get();
}
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;
}
}
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"`)
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;
}
} ;
}
}
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;
}
}
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);
}
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```.
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();
}
}
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
package fr.univamu.progav.td9;
public record Book(String isbn, String title) {
@Override
public String toString() {
return title + " (" + isbn + ")";
}
}
package fr.univamu.progav.td9;
public class BookException extends Exception {
}
package fr.univamu.progav.td9;
public class BookNotFoundException extends BookException {
//TODO
}
package fr.univamu.progav.td9;
public enum BookStatus { AVAILABLE, BORROWED; }
package fr.univamu.progav.td9;
public class BookUnavailableException extends BookException {
// TODO
}
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;
}
}
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;
}
}
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
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]);
}
}