diff --git a/README.md b/README.md
index 620603fa79b24938a364b4bd46f34f8168f372c0..7eb4fa57b39a8251373f527077a7de69f24cf402 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,9 @@
-# Gestion des notes des étudiants
+# Mandelbrot
 
-## Description du projet
+## Description du projet 
 
-Le but de ce TP est de créer des classes permettant de représenter des étudiants (classe `Student`), des notes (classe `Grade`), des résultats à une unité d'enseignement (classe `TeachingUnitResult`) et des promotions d'étudiants (classe `Cohort`).
+On va travailler sur ce TP sur l'affichage de l'[ensemble de Mandelbrot](https://en.wikipedia.org/wiki/Mandelbrot_set). Pour cela, on va utiliser un code pré-existant. 
+Le but du TP sera de corriger le code de la classe `Complex` en s'aidant de tests unitaires.
 
 ## Membres du projet
 
diff --git a/build.gradle b/build.gradle
index b2184c7b55f18065361b00f429f9cf48647eef62..3af223ee845607eb06a1f70bc54a4dcbf3f326eb 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,10 +1,15 @@
 plugins {
-    id "application"
+    id 'application'
+    id "org.openjfx.javafxplugin" version "0.0.10"
 }
-apply plugin : "java"
 
-group 'l2info'
-version '1.0-SNAPSHOT'
+javafx {
+    version = "17"
+    modules = [ 'javafx.controls', 'javafx.fxml' ]
+}
+
+sourceCompatibility = "16"
+targetCompatibility = "16"
 
 repositories {
     mavenCentral()
@@ -20,7 +25,7 @@ test {
 }
 
 ext {
-    javaMainClass = "Main"
+    javaMainClass = "viewer.Main"
 }
 
 application {
diff --git a/src/main/java/Cohort.java b/src/main/java/Cohort.java
deleted file mode 100644
index b997326978841098c0235774f90bd70fd6c389c1..0000000000000000000000000000000000000000
--- a/src/main/java/Cohort.java
+++ /dev/null
@@ -1,56 +0,0 @@
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A group of students.
- */
-
-public class Cohort {
-  private final String name;
-  private final List<Student> students;
-
-  /**
-   * Constructs a cohort with a name equals to the specified {@code name} and no students.
-   * @param name the name of the constructed Cohort
-   */
-
-  public Cohort(String name) {
-    this.name = name;
-    this.students = new ArrayList<>();
-  }
-
-  /**
-   * Add the specified {@code student} to the students of the cohort.
-   * @param student the student to be added to the cohort
-   */
-  public void addStudent(Student student){
-    // TODO : add code
-  }
-
-  /**
-   * Returns the list of students of the cohort.
-   * @return the list of students of the cohort.
-   */
-  public List<Student> getStudents(){
-    // TODO : change code
-    return null;
-  }
-
-  /**
-   * Print via the standard output the name of the cohort and all results associated to the students with their average
-   * grade.
-   */
-  public void printStudentsResults(){
-    // TODO : add code
-  }
-
-  /**
-   * Returns the name of the cohort.
-   * @return the name of the cohort
-   */
-  @Override
-  public String toString() {
-    // TODO : change code
-    return null;
-  }
-}
diff --git a/src/main/java/Grade.java b/src/main/java/Grade.java
deleted file mode 100644
index 12154f6b79462c66071149335b102342b1b409e0..0000000000000000000000000000000000000000
--- a/src/main/java/Grade.java
+++ /dev/null
@@ -1,83 +0,0 @@
-import java.util.List;
-
-/**
- * A grade with a float value comprised between 0 and 20.
- *
- */
-public class Grade {
-  /**
-   * The maximum value of a grade.
-   */
-  private static final int MAXIMUM_GRADE = 20;
-  private final double value;
-
-  /**
-   * Constructs a grade with a value equals to the specified {@code value}.
-   *
-   * @param value the value of the constructed grade
-   */
-
-  public Grade(double value) {
-    this.value = value;
-  }
-
-  /**
-   * Returns the value of the grade as a double.
-   *
-   * @return the value of the grade
-   */
-
-  public double getValue() {
-    // TODO : change code
-    return 0.;
-  }
-
-  /**
-   * Returns a string representation of the grade in the format X.X/20.
-   * @return a string representation of the grade
-   */
-  @Override
-  public String toString() {
-    // TODO : change code
-    return null;
-  }
-
-  /**
-   * Returns a grade with a value equals to the arithmetic mean of the values of the grade in
-   * the specified list.
-   *
-   * @param grades a list of grades
-   * @return a grade corresponding to the mean of grade in {@code grades}
-   */
-  public static Grade averageGrade(List<Grade> grades){
-    // TODO : change code
-    return null;
-  }
-
-  /**
-   * Determines whether or not two grades are equal. Two instances of Grade are equal if the values
-   * of their {@code value} member field are the same.
-   * @param o  an object to be compared with this Grade
-   * @return {@code true} if the object to be compared is an instance of Grade and has the same value; {@code false}
-   * otherwise.
-   */
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-
-    Grade grade = (Grade) o;
-
-    return Double.compare(grade.value, value) == 0;
-  }
-
-  /**
-   * Returns a hash code value for the object.
-   * @return a hash code value for this object.
-   */
-  @Override
-  public int hashCode() {
-    long temp = Double.doubleToLongBits(value);
-    return (int) (temp ^ (temp >>> 32));
-  }
-}
diff --git a/src/main/java/Main.java b/src/main/java/Main.java
deleted file mode 100644
index 43057dd29d12bbbe5656d926c6def3add7985b4b..0000000000000000000000000000000000000000
--- a/src/main/java/Main.java
+++ /dev/null
@@ -1,5 +0,0 @@
-public class Main {
-  public static void main(String[] args){
-    // TODO: add code.
-  }
-}
diff --git a/src/main/java/Student.java b/src/main/java/Student.java
deleted file mode 100644
index 3f018e120474735e1ac185c427691ae5dd11f9ba..0000000000000000000000000000000000000000
--- a/src/main/java/Student.java
+++ /dev/null
@@ -1,108 +0,0 @@
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A students with results.
- */
-
-public class Student {
-  private final String firstName;
-  private final String lastName;
-  private final List<TeachingUnitResult> results;
-
-  /**
-   * Constructs a student with the specified first name and last name and no associated results.
-   *
-   * @param firstName the first name of the constructed student
-   * @param lastName the last name of the constructed student
-   */
-
-  public Student(String firstName, String lastName) {
-    this.firstName = firstName;
-    this.lastName = lastName;
-    this.results = new ArrayList<>();
-  }
-
-  /**
-   * Add a grade associated to a teaching unit to the results of the student.
-   *
-   * @param teachingUnitName the name of the teaching unit of the added result
-   * @param grade the grade of the added result
-   */
-  public void addResult(String teachingUnitName, Grade grade){
-    // TODO : add code
-  }
-
-  /**
-   * Returns a string representation of the student in the format first name last name.
-   * @return a string representation of the student
-   */
-  @Override
-  public String toString() {
-    // TODO : change code
-    return null;
-  }
-
-
-  /**
-   * Returns the grades of the student.
-   *
-   * @return the grades of the student
-   */
-  public List<Grade> getGrades(){
-    // TODO : change code
-    return null;
-  }
-
-  /**
-   * Returns the average grade of the student.
-   *
-   * @return the average grade of the student
-   */
-  public Grade averageGrade() {
-    // TODO : change code
-    return null;
-  }
-
-  /**
-   * Print via the standard output the name of the student, all results associated to the students and
-   * the average grade of the student.
-   */
-  public void printResults(){
-    // TODO : add code
-  }
-
-
-  /**
-   * Determines whether or not two students are equal. Two instances of Student are equal if the values
-   * of their {@code firtName}  and {@code lastName} member fields are the same.
-   * @param o  an object to be compared with this Student
-   * @return {@code true} if the object to be compared is an instance of Student and has the same name; {@code false}
-   * otherwise.
-   */
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-
-    Student student = (Student) o;
-
-    if (!firstName.equals(student.firstName)) return false;
-    return lastName.equals(student.lastName);
-  }
-
-  /**
-   * Returns a hash code value for the object.
-   * @return a hash code value for this object.
-   */
-  @Override
-  public int hashCode() {
-    int result = firstName.hashCode();
-    result = 31 * result + lastName.hashCode();
-    return result;
-  }
-
-
-
-
-}
diff --git a/src/main/java/TeachingUnitResult.java b/src/main/java/TeachingUnitResult.java
deleted file mode 100644
index 38ddcb51104cc52b8674099ede96e00f0ee9218d..0000000000000000000000000000000000000000
--- a/src/main/java/TeachingUnitResult.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * A result corresponding to a grade associated with a teaching unit.
- */
-
-public class TeachingUnitResult {
-  private final String teachingUnitName;
-  private final Grade grade;
-
-
-  /**
-   * Constructs an instance of TeachingUnitResult with a grade equals to the specified {@code grade}
-   * and a teaching unit name equals to the specified {@code teachingUnitName}.
-   *
-   * @param teachingUnitName the name of the teaching unit of the constructed TeachingUnitResult
-   * @param grade the grade of the constructed TeachingUnitResult
-   */
-
-  public TeachingUnitResult(String teachingUnitName, Grade grade) {
-    this.teachingUnitName = teachingUnitName;
-    this.grade = grade;
-  }
-
-  /**
-   * Returns the grade associated to the result.
-   *
-   * @return the grade associated to the result
-   */
-  public Grade getGrade() {
-    // TODO : change code
-    return null;
-  }
-
-  /**
-   * Returns a string representation of the result in the format Name of the teaching unit : X.X.
-   * @return a string representation of the result
-   */
-  @Override
-  public String toString() {
-    // TODO : change code
-    return null;
-  }
-
-
-  /**
-   * Determines whether or not two results are equal. Two instances of TeachingUnitResult are equal if the values
-   * of their {@code teachingUnitName} and {@code grade} member fields are the same.
-   * @param o  an object to be compared with this TeachingUnitResult
-   * @return {@code true} if the object to be compared is an instance of TeachingUnitResult and has the same grad and
-   * teaching unit name; {@code false} otherwise.
-   */
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-
-    TeachingUnitResult that = (TeachingUnitResult) o;
-
-    if (!teachingUnitName.equals(that.teachingUnitName)) return false;
-    return grade.equals(that.grade);
-  }
-
-  /**
-   * Returns a hash code value for the object.
-   * @return a hash code value for this object.
-   */
-  @Override
-  public int hashCode() {
-    int result = teachingUnitName.hashCode();
-    result = 31 * result + grade.hashCode();
-    return result;
-  }
-}
diff --git a/src/main/java/mandelbrot/Complex.java b/src/main/java/mandelbrot/Complex.java
new file mode 100644
index 0000000000000000000000000000000000000000..5dd4e6b04d86e298aa9e8258c7b40e8e63eddde9
--- /dev/null
+++ b/src/main/java/mandelbrot/Complex.java
@@ -0,0 +1,246 @@
+package mandelbrot;
+
+import java.util.Objects;
+
+/**
+ *  The {@code Complex} class represents a complex number.
+ *  Complex numbers are immutable: their values cannot be changed after they
+ *  are created.
+ *  It includes methods for addition, subtraction, multiplication, division,
+ *  conjugation, and other common functions on complex numbers.
+ *
+ * @author Arnaud Labourel
+ * @author Guyslain Naves
+ */
+public class Complex {
+
+    /**
+     * The real part of a complex number.
+     */
+    private final double real;
+
+    /**
+     * The imaginary part of a complex number.
+     */
+    private final double imaginary;
+
+
+    /**
+     * Initializes a complex number with the specified real and imaginary parts.
+     *
+     * @param real      the real part
+     * @param imaginary the imaginary part
+     */
+    public Complex(double real, double imaginary) {
+        this.real = real;
+        this.imaginary = imaginary;
+    }
+
+    /**
+     * Zero as a complex number, i.e., a number representing "0.0 + 0.0i".
+     */
+    public static final Complex ZERO = new Complex(0, 0);
+
+    /**
+     * One as a complex number, i.e., a number representing "1.0 + 0.0i".
+     */
+    public static final Complex ONE = new Complex(1, 0);
+
+
+    /**
+     * The square root of -1, i.e., a number representing "0.0 + 1.0i".
+     */
+    public static final Complex I = new Complex(0, 1);
+
+    /**
+     * Returns the real part of this complex number.
+     *
+     * @return the real part of this complex number
+     */
+    public double getReal() {
+        return real;
+    }
+
+    /**
+     * Returns the imaginary part of this complex number.
+     *
+     * @return the imaginary part of this complex number
+     */
+    public double getImaginary() {
+        return imaginary;
+    }
+
+    /**
+     * Returns a complex number, whose multiplication corresponds to a rotation by the given angle in the complex plane.
+     * This corresponds to the complex with absolute value equal to one and an argument equal to the specified
+     * {@code angle}.
+     *
+     * @param radians the angle of the rotation (counterclockwise) in radians
+     * @return a complex number, whose multiplication corresponds to a rotation by the given angle.
+     */
+    public static Complex rotation(double radians) {
+        return new Complex(Math.cos(radians), Math.sin(radians));
+    }
+
+    /**
+     * Creates a complex number with the specified real part and an imaginary part equal to zero.
+     *
+     * @param real the real component
+     * @return the complex {@code real + 0i}
+     */
+    public static Complex real(double real) {
+        return new Complex(real, 0);
+    }
+
+    /**
+     * Returns a {@code Complex} whose value is {@code (this + addend)}.
+     *
+     * @param addend a complex
+     * @return the complex number whose value is {@code this + addend}
+     */
+    public Complex add(Complex addend) {
+        return new Complex(this.real + addend.real,
+                this.imaginary + addend.imaginary);
+    }
+
+    /**
+     * Returns the negation of this complex number.
+     *
+     * @return A complex <code>c</code> such that <code>this + c = 0</code>
+     */
+    public Complex negate() {
+        return new Complex(-this.real, -this.imaginary);
+    }
+
+    /**
+     * Returns the conjugate of this complex number.
+     *
+     * @return A complex <code>c</code> such that <code>this * c = ||this|| ** 2</code>
+     */
+    public Complex conjugate() {
+        return new Complex(this.real, -this.imaginary);
+    }
+
+    /**
+     * Returns a {@code Complex} whose value is {@code (this - subtrahend)}.
+     *
+     * @param subtrahend the complex to be subtracted from {@code this}
+     * @return the complex number {@code (this - subtrahend)}
+     */
+    public Complex subtract(Complex subtrahend) {
+        return new Complex(this.real - subtrahend.real, this.imaginary - subtrahend.imaginary);
+    }
+
+    /**
+     * Returns a {@code Complex} whose value is {@code this * factor}
+     *
+     * @param factor the complex number to multiply to {@code this}
+     * @return the complex number {@code this * factor}
+     */
+    public Complex multiply(Complex factor) {
+        return new Complex(
+                this.real * factor.real - this.imaginary * factor.imaginary,
+                this.real * factor.imaginary + this.imaginary * factor.real);
+    }
+
+    /**
+     * Returns the squared modulus of this complex number.
+     *
+     * @return <code>||this|| ** 2</code>
+     */
+    public double squaredModulus() {
+        return real * real + imaginary * imaginary;
+    }
+
+    /**
+     * Returns the modulus (distance to zero) of this complex number.
+     *
+     * @return <code>||this||</code>
+     */
+    public double modulus() {
+        return Math.sqrt(squaredModulus());
+    }
+
+
+    /**
+     * Returns the reciprocal of this complex number.
+     *
+     * @return a complex number <code>c</code> such that <code>this * c = 1</code>
+     */
+    public Complex reciprocal() {
+        if (this.equals(ZERO)){
+            throw new ArithmeticException("divide by zero");
+        }
+        double m = squaredModulus();
+        return this.conjugate().scale(1. / m);
+    }
+
+    /**
+     * Returns a {@code Complex} whose value is <code>this / divisor</code>.
+     *
+     * @param divisor the denominator (a complex number)
+     * @return the complex number <code>this / divisor</code>
+     */
+    public Complex divide(Complex divisor) {
+        return this.multiply(divisor.reciprocal());
+    }
+
+
+    /**
+     * Returns the integral power of this complex number.
+     *
+     * @param p a non-negative integer
+     * @return the complex number <code>this ** p</code>
+     */
+    public Complex pow(int p) {
+        if (p == 0)
+            return ONE;
+        Complex result = (this.multiply(this)).pow(p / 2);
+        if (p % 2 == 1)
+            result = result.multiply(this);
+        return result;
+    }
+
+    /**
+     * Returns the scalar multiplication of this complex number.
+     *
+     * @param lambda a scalar number
+     * @return the complex number <code>lambda * this</code>
+     */
+    public Complex scale(double lambda) {
+        return new Complex(lambda * real, lambda * imaginary);
+    }
+
+    /**
+     * Test for equality with another object. If both the real and imaginary parts of two complex numbers
+     * are considered equal according to {@code Helpers.doubleCompare} (i.e., within {@code Helpers.RANGE}), the two
+     * Complex objects are considered to be equal.
+     *
+     * @param other Object to test for equality with this instance.
+     * @return {@code true} if the objects are equal, {@code false} if object is {@code null}, not an instance of
+     * {@code Complex}, or not equal to this instance.
+     */
+    @Override
+    public boolean equals(Object other) {
+        if (this == other)
+            return true;
+        if (!(other instanceof Complex))
+            return false;
+        Complex complex = (Complex) other;
+        return Helpers.doubleCompare(complex.real, real) == 0 &&
+                Helpers.doubleCompare(complex.imaginary, imaginary) == 0;
+    }
+
+    /**
+     * Returns a string representation of this complex number.
+     *
+     * @return a string representation of this complex number of the form 42.0 - 1024.0i.
+     */
+    @Override
+    public String toString() {
+        if (Helpers.doubleCompare(imaginary, 0) == 0) return real + "";
+        if (Helpers.doubleCompare(real, 0) == 0) return imaginary + "i";
+        if (Helpers.doubleCompare(imaginary, 0) < 0) return real + " - " + (-imaginary) + "i";
+        return real + " + " + imaginary + "i";
+    }
+}
diff --git a/src/main/java/mandelbrot/Helpers.java b/src/main/java/mandelbrot/Helpers.java
new file mode 100644
index 0000000000000000000000000000000000000000..39708dc402de32073f9823293b07f685ba1ced3a
--- /dev/null
+++ b/src/main/java/mandelbrot/Helpers.java
@@ -0,0 +1,29 @@
+package mandelbrot;
+
+/**
+ * Some helpful functions and values.
+ */
+class Helpers {
+    /**
+     * A small double used to bound the precision of the comparison of doubles.
+     */
+    final static double EPSILON = 1e-9;
+
+    /**
+     * Comparison of doubles (up to <code>EPSILON</code>)
+     * <p>
+     * Please note that floating-point comparison is very tricky, this function
+     * is not suited to compare small floating-point numbers.
+     *
+     * @param d1 an arbitrary double
+     * @param d2 an arbitrary double
+     * @return the result of comparing <code>d1</code> and <code>d2</code>.
+     */
+    static int doubleCompare(double d1, double d2) {
+        double diff = d1 - d2;
+        return
+                (diff > EPSILON) ? 1 :
+                        (diff < -EPSILON) ? -1 :
+                                0;
+    }
+}
diff --git a/src/main/java/mandelbrot/Mandelbrot.java b/src/main/java/mandelbrot/Mandelbrot.java
new file mode 100644
index 0000000000000000000000000000000000000000..0721c43d78897885f4044e20e2533744e1c8c8a8
--- /dev/null
+++ b/src/main/java/mandelbrot/Mandelbrot.java
@@ -0,0 +1,115 @@
+package mandelbrot;
+
+import java.util.function.Function;
+
+/**
+ * A class to compute how fast a paramaterized polynomial sequence diverges.
+ * This is used to compute the colors of point in the Mandelbrot fractal.
+ */
+public class Mandelbrot {
+
+    /**
+     * If a complex has modulus above <code>RADIUS</code>, we know that
+     * the sequence diverges. <code>RADIUS</code> should be at least 2 for
+     * the usual Mandelbrot sequence.
+     */
+    private static double RADIUS = 10;
+
+    /**
+     * The square of <code>RADIUS</code>, used in computations.
+     */
+    private static double RADIUS2 = RADIUS * RADIUS;
+
+
+    /**
+     * How many iterations of the sequence do we compute before concluding
+     * that it probably converges. The more, the better in term of image
+     * quality, specially in details of the fractal, but also the slower
+     * the computation is.
+     */
+    private static int MAX_ITERATIONS = 1000;
+
+
+    /**
+     * The degree of the polynomial defining the sequence.
+     */
+    private static int DEGREE = 2;
+
+    /**
+     * Compute how divergent is the sequence generated by <code>z -&gt; z ** 2 + c</code>
+     *
+     * @param c A complex parameter, defining the polynomial to use.
+     * @return Some value, <code>POSITIVE_INFINITY</code> if the sequence
+     * converges (or does not seem to converge after
+     * <code>MAX_ITERATIONS</code>, or a indicative floating-point number of
+     * the number of iterations needed to goes above the <code>RADIUS</code>.
+     */
+    public double divergence(Complex c) {
+        if (isConvergent(c)) return Double.POSITIVE_INFINITY;
+        Function<Complex, Complex> f = z -> z.pow(DEGREE).add(c);
+        Sequence seq = new Sequence(c, f);
+        int countIterations = 0;
+        for (Complex z : seq) {
+            if (isDiverging(z))
+                return smoothIterationCount(countIterations, z);
+            if (countIterations >= MAX_ITERATIONS)
+                return Double.POSITIVE_INFINITY;
+            countIterations++;
+        }
+        return 0.;
+    }
+
+    /**
+     * This method is used to smooth the number of iterations until
+     * getting out of the <code>RADIUS</code>, so that we get a
+     * floating-point value and thus smooth coloring.
+     *
+     * @param countIterations the iteration on which <code>RADIUS</code> is beaten.
+     * @param z               the first complex of the sequence whose modulus is above <code>RADIUS</code>
+     * @return a double close to <code>countIterations</code>.
+     */
+    private double smoothIterationCount(int countIterations, Complex z) {
+        double x = Math.log(z.modulus()) / Math.log(RADIUS);
+        return (double) countIterations - Math.log(x) / Math.log(DEGREE);
+
+    }
+
+
+    /**
+     * Checks whether a term of the sequence is out of the given
+     * <code>RADIUS</code>, which guarantees that the sequence diverges.
+     *
+     * @param z a term of the sequence
+     * @return <code>true</code> if we are sure that the sequence diverges.
+     */
+    private boolean isDiverging(Complex z) {
+        return z.squaredModulus() > RADIUS2;
+    }
+
+
+    /**
+     * Checks whether the parameter of the sequence is in some region
+     * that guarantees that the sequence is convergent. This does not
+     * capture all convergent parameters.
+     *
+     * @param c the parameter for the polynomial
+     * @return <code>true</code> if we are sure that the sequence converges.
+     */
+    private boolean isConvergent(Complex c) {
+        return isIn2Bulb(c) || isInCardioid(c);
+    }
+
+    /* The cardioid black shape of the fractal */
+    private boolean isInCardioid(Complex z) {
+        double m = z.squaredModulus();
+        return Helpers.doubleCompare(m * (8 * m - 3), 3. / 32. - z.getReal()) <= 0;
+    }
+
+    /* The main black disc of the fractal */
+    private boolean isIn2Bulb(Complex z) {
+        Complex zMinusOne = z.subtract(new Complex(-1, 0));
+        return Helpers.doubleCompare(zMinusOne.squaredModulus(), 1. / 16.) < 0;
+    }
+
+
+}
diff --git a/src/main/java/mandelbrot/Sequence.java b/src/main/java/mandelbrot/Sequence.java
new file mode 100644
index 0000000000000000000000000000000000000000..8d84cf1f1e82d90e3cc9bb9c91523ae7759ae2fc
--- /dev/null
+++ b/src/main/java/mandelbrot/Sequence.java
@@ -0,0 +1,59 @@
+package mandelbrot;
+
+import java.util.Iterator;
+import java.util.function.Function;
+
+/**
+ * A class to compute the term of a sequence of complex numbers, generated
+ * by a function <code>f</code> and an initial term <code>u_0</code>, such
+ * that <code> u_{n+1} = f(u_n)</code>.
+ * <p>
+ * It implements <code>Iterable</code>, allowing to traverse the sequence
+ * with <code>for (Complex z : mySequence)</code>
+ */
+public class Sequence implements Iterable<Complex> {
+
+    /* The generating function */
+    private final Function<Complex, Complex> f;
+
+    /* The initial term */
+    private final Complex u0;
+
+
+    /**
+     * Creates a sequence given the initial term and the function.
+     *
+     * @param u0 the first term of the sequence,
+     * @param f  the function over complexes whose repeated application generates the sequence
+     */
+    Sequence(Complex u0, Function<Complex, Complex> f) {
+        this.f = f;
+        this.u0 = u0;
+    }
+
+
+    /**
+     * Creates an iterator iterating all terms of the sequence in order.
+     *
+     * @return an iterator
+     */
+    @Override
+    public Iterator<Complex> iterator() {
+        return new SeqIterator();
+    }
+
+    private class SeqIterator implements Iterator<Complex> {
+        private Complex current = u0;
+
+        @Override
+        public boolean hasNext() {
+            return true;
+        }
+
+        @Override
+        public Complex next() {
+            current = f.apply(current);
+            return current;
+        }
+    }
+}
diff --git a/src/main/java/viewer/Camera.java b/src/main/java/viewer/Camera.java
new file mode 100644
index 0000000000000000000000000000000000000000..7edad181d76e01e557c127d0c0fe9f934935f5d1
--- /dev/null
+++ b/src/main/java/viewer/Camera.java
@@ -0,0 +1,55 @@
+package viewer;
+
+import mandelbrot.Complex;
+
+/**
+ * A class to represent the view (a rectangle over the complex plane)
+ * to be displayed. Some interesting views are already defined.
+ */
+class Camera {
+
+    /**
+     * The high-level view of the Mandelbrot set.
+     */
+    static Camera camera0 =
+            new Camera(
+                    -0.5,
+                    0.,
+                    3,
+                    4. / 3.);
+
+
+
+
+    private Complex center; /* Center of the rectangle */
+    private Complex width; /* Vector for the width of the rectangle */
+    private Complex height; /* Vector for the height of the rectangle */
+
+
+    /**
+     * Creates a view.
+     *
+     * @param centerX     the real part of the point on which the view is centered
+     * @param centerY     the imaginary part of the point on which the view is centered
+     * @param width       the width of the rectangle to display
+     * @param aspectRatio the ratio width/height of the rectangle to display
+     */
+    private Camera(double centerX, double centerY, double width, double aspectRatio) {
+        this.width = Complex.real(width);
+        this.height = new Complex(0, width / aspectRatio);
+        this.center = new Complex(centerX, centerY);
+    }
+
+    /**
+     * Converts position relative to the rectangle defining the view
+     * into absolute complex numbers.
+     *
+     * @param tx horizontal relative position, between 0 (left) and 1 (right)
+     * @param ty vertical relative position, between 0 (bottom) and 1 (top)
+     * @return the complex at this position of the rectangle
+     */
+    Complex toComplex(double tx, double ty) {
+        return center.add(width.scale(tx - 0.5)).add(height.scale(ty - 0.5));
+    }
+
+}
diff --git a/src/main/java/viewer/Controller.java b/src/main/java/viewer/Controller.java
new file mode 100644
index 0000000000000000000000000000000000000000..df7db671bb5017fa25af48494a2ca5ac5610377c
--- /dev/null
+++ b/src/main/java/viewer/Controller.java
@@ -0,0 +1,160 @@
+package viewer;
+
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.canvas.Canvas;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+import mandelbrot.Complex;
+import mandelbrot.Mandelbrot;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ResourceBundle;
+
+/**
+ * Controls the color of the pixels of the canvas.
+ */
+public class Controller implements Initializable {
+
+    /**
+     * Dimension of the grid used to supersample each pixel.
+     * The number of subpixels for each pixel is the square of <code>SUPERSAMPLING</code>
+     */
+    private static final int SUPERSAMPLING = 3;
+
+    @FXML
+    private Canvas canvas; /* The canvas to draw on */
+
+    private Camera camera = Camera.camera0; /* The view to display */
+
+    private Mandelbrot mandelbrot = new Mandelbrot(); /* the algorithm */
+
+
+    /* positions of colors in the histogram */
+    private double[] breakpoints = {0., 0.75, 0.85, 0.95, 0.99, 1.0};
+    /* colors of the histogram */
+    private Color[] colors =
+            {Color.gray(0.2),
+                    Color.gray(0.7),
+                    Color.rgb(55, 118, 145),
+                    Color.rgb(63, 74, 132),
+                    Color.rgb(145, 121, 82),
+                    Color.rgb(250, 250, 200)
+            };
+    /* algorithm to generate the distribution of colors */
+    private Histogram histogram = new Histogram(breakpoints, colors);
+
+    /**
+     * Method called when the graphical interface is loaded
+     *
+     * @param location  location
+     * @param resources resources
+     */
+    @Override
+    public void initialize(URL location, ResourceBundle resources) {
+        render();
+    }
+
+    /**
+     * compute and display the image.
+     */
+    private void render() {
+        List<Pixel> pixels = getPixels();
+        renderPixels(pixels);
+    }
+
+    /**
+     * display each pixel
+     *
+     * @param pixels the list of all the pixels to display
+     */
+    private void renderPixels(List<Pixel> pixels) {
+        GraphicsContext context = canvas.getGraphicsContext2D();
+        for (Pixel pix : pixels) {
+            pix.render(context);
+        }
+    }
+
+    /**
+     * Attributes to each subpixel a color
+     *
+     * @param subPixels the list of all subpixels to display
+     */
+    private void setSubPixelsColors(List<SubPixel> subPixels) {
+        int nonBlackPixelsCount = countNonBlackSubPixels(subPixels);
+        if (nonBlackPixelsCount == 0) return;
+        Color[] colors = histogram.generate(nonBlackPixelsCount);
+        subPixels.sort(SubPixel::compare);
+        int pixCount = 0;
+        for (SubPixel pix : subPixels) {
+            pix.setColor(colors[pixCount]);
+            pixCount++;
+            if (pixCount >= colors.length) // remaining subpixels stay black (converge).
+                break;
+        }
+    }
+
+
+    /**
+     * Count how many subpixel diverge.
+     *
+     * @param subPixels the subpixels to display
+     * @return the number of diverging subpixels
+     */
+    private int countNonBlackSubPixels(List<SubPixel> subPixels) {
+        return (int)
+                subPixels.stream()
+                        .filter(pix -> pix.value != Double.POSITIVE_INFINITY)
+                        .count();
+    }
+
+    /**
+     * Generates the list of all the pixels in the canvas
+     *
+     * @return the list of pixels
+     */
+    private List<Pixel> getPixels() {
+        int width = (int) canvas.getWidth();
+        int height = (int) canvas.getHeight();
+        List<SubPixel> subPixels =
+                new ArrayList<>(width * height * SUPERSAMPLING * SUPERSAMPLING);
+        List<Pixel> pixels =
+                new ArrayList<>(width * height);
+        for (int x = 0; x < width; x++) {
+            for (int y = 0; y < height; y++) {
+                Pixel pix = preparePixel(x, y);
+                subPixels.addAll(pix.getSubPixels());
+                pixels.add(pix);
+            }
+        }
+        setSubPixelsColors(subPixels);
+        return pixels;
+    }
+
+    /**
+     * Create the pixel with given coordinates
+     *
+     * @param x horizontal coordinate of the pixel
+     * @param y vertical coordinate of the pixel
+     * @return the computed pixel with given coordinates
+     */
+    private Pixel preparePixel(int x, int y) {
+        double width = SUPERSAMPLING * canvas.getWidth();
+        double height = SUPERSAMPLING * canvas.getHeight();
+        List<SubPixel> sampledSubPixels = new ArrayList<>();
+        for (int i = 0; i < SUPERSAMPLING; i++) {
+            for (int j = 0; j < SUPERSAMPLING; j++) {
+                Complex z =
+                        camera.toComplex(
+                                ((double) (SUPERSAMPLING * x) + i) / width,
+                                1 - ((double) (SUPERSAMPLING * y) + j) / height // invert y-axis
+                        );
+                double divergence = mandelbrot.divergence(z);
+                sampledSubPixels.add(new SubPixel(divergence));
+            }
+        }
+        return new Pixel(x, y, sampledSubPixels);
+    }
+}
diff --git a/src/main/java/viewer/Histogram.java b/src/main/java/viewer/Histogram.java
new file mode 100644
index 0000000000000000000000000000000000000000..2292ac62f7b294613c494bae03ba5b7838397dfc
--- /dev/null
+++ b/src/main/java/viewer/Histogram.java
@@ -0,0 +1,56 @@
+package viewer;
+
+import javafx.scene.paint.Color;
+
+/**
+ * Histogram of colors, used to generate a list of colors made
+ * from several gradients combined together, so that the list looks smooth.
+ */
+class Histogram {
+
+    private double[] breakpoints;
+    private Color[] colors;
+
+    /**
+     * Creates a schema of colors.
+     * <code>breakpoints</code> and <code>colors</code> must have the same length.
+     * Two consecutive indices of <code>colors</code> define a gradient of colors.
+     * Those colors will be linearly mapped to the interval defined by the same
+     * indices taken in <code>breakpoints</code>
+     * For instance, { 0, 0.4, 1.} with { BLACK, RED, WHITE} represents a black
+     * to red to white spectrum, where 40% of the point are the black to red
+     * gradient, 60% are the red to white gradient.
+     *
+     * @param breakpoints values from 0 to 1, in increasing order, the first value must be 0 and the last one.
+     * @param colors      colors assigned to each breakpoint.
+     */
+    Histogram(double[] breakpoints, Color[] colors) {
+        assert (breakpoints[0] == 0);
+        assert (breakpoints[breakpoints.length - 1] == 1);
+        assert (colors.length == breakpoints.length);
+        this.breakpoints = breakpoints;
+        this.colors = colors;
+    }
+
+
+    /**
+     * Generates a list of colors of given length representing this spectrum.
+     *
+     * @param howManyPoints the number of colors returned
+     * @return a list of colors following the schema defined in the constructor
+     */
+    Color[] generate(int howManyPoints) {
+        Color[] result = new Color[howManyPoints];
+        double length = (double) howManyPoints;
+        int bpIndex = 0;
+        for (int ptIndex = 0; ptIndex < howManyPoints; ptIndex++) {
+            double absolute = (double) ptIndex / length;
+            while (absolute > breakpoints[bpIndex + 1] && bpIndex < breakpoints.length - 1)
+                bpIndex++;
+            double relative = (absolute - breakpoints[bpIndex]) / (breakpoints[bpIndex + 1] - breakpoints[bpIndex]);
+            result[ptIndex] = colors[bpIndex].interpolate(colors[bpIndex + 1], relative);
+        }
+        return result;
+    }
+
+}
diff --git a/src/main/java/viewer/Main.java b/src/main/java/viewer/Main.java
new file mode 100644
index 0000000000000000000000000000000000000000..f1d621c406af2fc6f009990736f78ae17544a061
--- /dev/null
+++ b/src/main/java/viewer/Main.java
@@ -0,0 +1,23 @@
+package viewer;
+
+import javafx.application.Application;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+public class Main extends Application {
+
+    @Override
+    public void start(Stage primaryStage) throws Exception {
+        Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("viewer/viewer.fxml"));
+        primaryStage.setTitle("Mandelbrot");
+        primaryStage.setScene(new Scene(root, 1200, 900));
+        primaryStage.show();
+    }
+
+
+    public static void main(String[] args) {
+        launch(args);
+    }
+}
diff --git a/src/main/java/viewer/Pixel.java b/src/main/java/viewer/Pixel.java
new file mode 100644
index 0000000000000000000000000000000000000000..7c77c2894f1ae1543ff4184c636ddfac37e3cacc
--- /dev/null
+++ b/src/main/java/viewer/Pixel.java
@@ -0,0 +1,69 @@
+package viewer;
+
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+
+import java.util.Collection;
+
+/**
+ * A Pixel. Because of antialiasing, each pixel is further decomposed into
+ * subpixels. Each subpixels has a color, the color of the pixel is the average
+ * of the subpixels' colors.
+ */
+class Pixel {
+
+    private final int x;
+    private final int y;
+    private final Collection<SubPixel> subPixels;
+
+    /**
+     * Creates a pixel with given coordinates and subpixels.
+     *
+     * @param x         the horizontal coordinate of the pixel on the screen
+     * @param y         the vertical coordinate of the pixel on the screen
+     * @param subPixels a collection of subpixels for this pixel
+     */
+    Pixel(int x, int y, Collection<SubPixel> subPixels) {
+        this.x = x;
+        this.y = y;
+        this.subPixels = subPixels;
+    }
+
+
+    /**
+     * @return the list of subpixels in this pixel
+     */
+    Collection<SubPixel> getSubPixels() {
+        return subPixels;
+    }
+
+
+    private Color getAverageColor() {
+        double red = 0;
+        double green = 0;
+        double blue = 0;
+        int count = 0;
+        for (SubPixel subPixel : subPixels) {
+            count++;
+            Color col = subPixel.getColor();
+            red += col.getRed();
+            green += col.getGreen();
+            blue += col.getBlue();
+        }
+        double c = (double) count;
+        return new Color(red / c, green / c, blue / c, 1.);
+    }
+
+
+    /**
+     * Displays the pixel.
+     *
+     * @param context the context of the canvas on which to paint.
+     */
+    void render(GraphicsContext context) {
+        context.setFill(getAverageColor());
+        context.fillRect((double) x, (double) y, 1, 1);
+    }
+
+
+}
diff --git a/src/main/java/viewer/SubPixel.java b/src/main/java/viewer/SubPixel.java
new file mode 100644
index 0000000000000000000000000000000000000000..570b70f48743cf627c85a5f37657fbaf2e11df43
--- /dev/null
+++ b/src/main/java/viewer/SubPixel.java
@@ -0,0 +1,56 @@
+package viewer;
+
+
+import javafx.scene.paint.Color;
+
+/**
+ * A subpixel contributes to the color of one pixel. Pixels are usually
+ * composed of several subpixels, whose colors are averaged.
+ */
+
+class SubPixel {
+
+    private Color color = Color.BLACK;
+
+    /**
+     * Each subpixel has a value that will be used to color them.
+     */
+    final double value;
+
+
+    /**
+     * Creates a subpixel.
+     *
+     * @param value divergence for the corresponding pixel. This will be mapped to a color.
+     */
+    SubPixel(double value) {
+        this.value = value;
+    }
+
+    /**
+     * Attributes a color to a subpixel.
+     *
+     * @param color the color to give to the subpixel
+     */
+    void setColor(Color color) {
+        this.color = color;
+    }
+
+    /**
+     * @return the color of the subpixel. Default is black.
+     */
+    Color getColor() {
+        return color;
+    }
+
+    /**
+     * Comparison of two subpixels by their values.
+     *
+     * @param pix1 first subpixel to compare
+     * @param pix2 second subpixel to compare
+     * @return an integer representing the result of the comparison, with the usual convention.
+     */
+    static int compare(SubPixel pix1, SubPixel pix2) {
+        return Double.compare(pix1.value, pix2.value);
+    }
+}
diff --git a/src/main/resources/viewer/viewer.fxml b/src/main/resources/viewer/viewer.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..93e243f8c4aa72de69ed3034b666ce3777bef6ba
--- /dev/null
+++ b/src/main/resources/viewer/viewer.fxml
@@ -0,0 +1,8 @@
+<?import javafx.scene.layout.GridPane?>
+
+<?import javafx.scene.canvas.Canvas?>
+<GridPane fx:controller="viewer.Controller"
+          xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
+
+    <Canvas fx:id="canvas" width="1200" height="900"/>
+</GridPane>
\ No newline at end of file
diff --git a/src/test/java/StandardOutputSandbox.java b/src/test/java/StandardOutputSandbox.java
deleted file mode 100644
index b8bc1dbae6823585699aaba671439a3cce1462b6..0000000000000000000000000000000000000000
--- a/src/test/java/StandardOutputSandbox.java
+++ /dev/null
@@ -1,27 +0,0 @@
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-
-
-public class StandardOutputSandbox implements Runnable {
-  static String NEW_LINE = System.getProperty("line.separator");
-  private Runnable runnable;
-  private OutputStream outputStream;
-
-  StandardOutputSandbox(Runnable runnable) {
-    this.runnable = runnable;
-  }
-
-  public void run(){
-    outputStream = new ByteArrayOutputStream();
-    PrintStream printStream = new PrintStream(outputStream);
-    System.setOut(printStream);
-    runnable.run();
-    PrintStream originalOut = System.out;
-    System.setOut(originalOut);
-  }
-
-  String getProducedOutput() {
-    return outputStream.toString();
-  }
-}
diff --git a/src/test/java/TestCohort.java b/src/test/java/TestCohort.java
deleted file mode 100644
index 0ff9b4f9974b90e7bfab2839f8bfb805ecc5e0db..0000000000000000000000000000000000000000
--- a/src/test/java/TestCohort.java
+++ /dev/null
@@ -1,43 +0,0 @@
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import java.util.List;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-class TestCohort {
-  private static Cohort cohort = new Cohort("L2 informatique");
-
-  @BeforeAll
-  static void addStudentsToCohort(){
-    Student paulCalcul = new Student("Paul", "Calcul");
-    Student pierreKiroul = new Student("Pierre", "Kiroul");
-    pierreKiroul.addResult("Programmation 2", TestGrade.ten);
-    pierreKiroul.addResult("Structures discrètes", TestGrade.zero);
-    paulCalcul.addResult("Programmation 2", TestGrade.ten);
-    paulCalcul.addResult("Structures discrètes", TestGrade.twenty);
-    cohort.addStudent(paulCalcul);
-    cohort.addStudent(pierreKiroul);
-  }
-
-  @Test
-  void testGetStudents(){
-    assertEquals(List.of(TestStudent.paulCalcul, TestStudent.pierreKiroul), cohort.getStudents());
-  }
-
-  @Test
-  void testPrintStudentsResults() {
-    StandardOutputSandbox standardOutputSandbox = new StandardOutputSandbox(() ->cohort.printStudentsResults());
-    String expectedOutput = "L2 informatique" + StandardOutputSandbox.NEW_LINE + StandardOutputSandbox.NEW_LINE
-            + "Paul Calcul" + StandardOutputSandbox.NEW_LINE
-            + "Programmation 2 : 10.0/20" + StandardOutputSandbox.NEW_LINE
-            + "Structures discrètes : 20.0/20" + StandardOutputSandbox.NEW_LINE
-            + "Note moyenne : 15.0/20" + StandardOutputSandbox.NEW_LINE + StandardOutputSandbox.NEW_LINE
-            + "Pierre Kiroul" + StandardOutputSandbox.NEW_LINE
-            + "Programmation 2 : 10.0/20" + StandardOutputSandbox.NEW_LINE
-            + "Structures discrètes : 0.0/20" + StandardOutputSandbox.NEW_LINE
-            + "Note moyenne : 5.0/20" + StandardOutputSandbox.NEW_LINE + StandardOutputSandbox.NEW_LINE;
-    standardOutputSandbox.run();
-    assertEquals(expectedOutput, standardOutputSandbox.getProducedOutput());
-  }
-}
diff --git a/src/test/java/TestGrade.java b/src/test/java/TestGrade.java
deleted file mode 100644
index 8c25076faab40a0adc21be2687a746d58765c884..0000000000000000000000000000000000000000
--- a/src/test/java/TestGrade.java
+++ /dev/null
@@ -1,32 +0,0 @@
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotEquals;
-
-import org.junit.jupiter.api.Test;
-
-import java.util.List;
-
-class TestGrade {
-  static Grade twenty = new Grade(20);
-  static Grade zero = new Grade(0);
-  static Grade ten = new Grade(10);
-  private static List<Grade> grades = List.of(zero, twenty, ten);
-  private static List<Grade> gradesZero = List.of(zero, zero);
-
-  @Test
-  void testGetValue() {
-    assertEquals(20, twenty.getValue());
-    assertEquals(0, zero.getValue());
-  }
-
-  @Test
-  void testToString() {
-    assertEquals("20.0/20", twenty.toString());
-    assertEquals("0.0/20", zero.toString());
-  }
-
-  @Test
-  void testAverageGrade(){
-    assertEquals(ten, Grade.averageGrade(grades));
-    assertEquals(zero, Grade.averageGrade(gradesZero));
-  }
-}
diff --git a/src/test/java/TestStudent.java b/src/test/java/TestStudent.java
deleted file mode 100644
index 97ece12db7d2047da0e81ba2033da091b450d9dd..0000000000000000000000000000000000000000
--- a/src/test/java/TestStudent.java
+++ /dev/null
@@ -1,54 +0,0 @@
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import java.util.List;
-
-class TestStudent {
-  private static Student arnaudLabourel = new Student("Arnaud", "Labourel");
-  static Student paulCalcul = new Student("Paul", "Calcul");
-  static Student pierreKiroul = new Student("Pierre", "Kiroul");
-
-  @BeforeAll
-  static void addResultsToStudents(){
-    arnaudLabourel.addResult("Programmation 2", TestGrade.twenty);
-    arnaudLabourel.addResult("Structures discrètes", TestGrade.twenty);
-    pierreKiroul.addResult("Programmation 2", TestGrade.ten);
-    pierreKiroul.addResult("Structures discrètes", TestGrade.zero);
-    paulCalcul.addResult("Programmation 2", TestGrade.ten);
-    paulCalcul.addResult("Structures discrètes", TestGrade.twenty);
-  }
-
-  @Test
-  void testToString() {
-    assertEquals("Paul Calcul", paulCalcul.toString());
-    assertEquals("Pierre Kiroul", pierreKiroul.toString());
-  }
-
-  @Test
-  void testGetGrades() {
-    assertEquals(List.of(TestGrade.twenty, TestGrade.twenty), arnaudLabourel.getGrades());
-    assertEquals(List.of(TestGrade.ten, TestGrade.zero), pierreKiroul.getGrades());
-    assertEquals(List.of(TestGrade.ten, TestGrade.twenty), paulCalcul.getGrades());
-  }
-
-  @Test
-  void testGetAverageGrade() {
-    assertEquals(TestGrade.twenty, arnaudLabourel.averageGrade());
-    assertEquals(new Grade(5), pierreKiroul.averageGrade());
-    assertEquals(new Grade(15), paulCalcul.averageGrade());
-  }
-
-  @Test
-  void testPrintResults() {
-    StandardOutputSandbox standardOutputSandbox = new StandardOutputSandbox(() ->arnaudLabourel.printResults());
-    String expectedOutput =
-            "Arnaud Labourel" + StandardOutputSandbox.NEW_LINE
-            + "Programmation 2 : 20.0/20" + StandardOutputSandbox.NEW_LINE
-            + "Structures discrètes : 20.0/20" + StandardOutputSandbox.NEW_LINE
-            + "Note moyenne : 20.0/20" + StandardOutputSandbox.NEW_LINE;
-    standardOutputSandbox.run();
-    assertEquals(expectedOutput, standardOutputSandbox.getProducedOutput());
-  }
-}
\ No newline at end of file
diff --git a/src/test/java/TestTeachingUnitResult.java b/src/test/java/TestTeachingUnitResult.java
deleted file mode 100644
index 10525b19b7b9759576fc8195fc39c5b96d579c59..0000000000000000000000000000000000000000
--- a/src/test/java/TestTeachingUnitResult.java
+++ /dev/null
@@ -1,21 +0,0 @@
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import org.junit.jupiter.api.Test;
-
-class TestTeachingUnitResult {
-  private static TeachingUnitResult twentyAtProg =
-          new TeachingUnitResult("Programmation 2", TestGrade.twenty);
-  private static TeachingUnitResult zeroAtStructDiscrete =
-          new TeachingUnitResult("Structures discrètes", TestGrade.zero);
-
-  @Test
-  void testGetGrade() {
-    assertEquals(TestGrade.twenty, twentyAtProg.getGrade());
-    assertEquals(TestGrade.zero, zeroAtStructDiscrete.getGrade());
-  }
-
-  @Test
-  void testToString() {
-    assertEquals("Programmation 2 : 20.0/20", twentyAtProg.toString());
-    assertEquals("Structures discrètes : 0.0/20", zeroAtStructDiscrete.toString());
-  }
-}