diff --git a/.DS_Store b/.DS_Store
index f9eff7d8caa48695afec3a1f76904ad3a16c43f0..c66136cf486383b3afb2e9e018a604d3a5ae1499 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/Data_Base.xlsx b/Data_Base.xlsx
index d9513acf2c25892a5e2e901484c9020144c85240..120e1ff2f3611fc448aae7f91eb8f85f9ec407ad 100644
Binary files a/Data_Base.xlsx and b/Data_Base.xlsx differ
diff --git a/projet_personnel/algorithme_gestion_etudiants.py b/projet_personnel/algorithme_gestion_etudiants.py
index 1de243ae9225b461f10dfb871a12a74bbc3986b4..f9d71dc86ad65afb85240caae65a2ec8662a9192 100644
--- a/projet_personnel/algorithme_gestion_etudiants.py
+++ b/projet_personnel/algorithme_gestion_etudiants.py
@@ -190,15 +190,15 @@ def register(data, firstname, lastname, date_of_birth, place_of_birth, address,
     return
 
 def generate_matricule(firstname, lastname, date_of_birth):
-    consonants_name = ''.join([c for c in firstname if c.lower() not in 'aeiouy'])[:3]
-    consonants_surname = ''.join([c for c in lastname if c.lower() not in 'aeiouy'])[:2]
-    last_consonant_surname = ''.join([c for c in lastname if c.lower() not in 'aeiouy']).lower()[-1]  # not sure if it's the consonant of the first name or the last name
-    birth_year_last_two_digits = str(date_of_birth)[-2:]
+    consonant_of_firstname = ''.join([c for c in firstname if c.lower() not in 'aeiou'])[:3]
+    consonant_of_lastname = ''.join([c for c in lastname if c.lower() not in 'aeiou'])[:2]
+    last_consonant_of_lastname = ''.join([c for c in lastname if c.lower() not in 'aeiou']).lower()[-1] # ne sait pas si c'est la consonne du prénom ou du nom
+    year_of_birth_string = str(date_of_birth)[-4:]
     random_integer = random.randint(0, 10)
-    matricule_e = f"{consonants_name}{consonants_surname}{last_consonant_surname}{birth_year_last_two_digits}{random_integer}"
-    matricule_e = matricule_e.lower()
+    matricule = f"{consonant_of_lastname }{consonant_of_firstname}{last_consonant_of_lastname}{year_of_birth_string}{random_integer}"
+    matricule = matricule.lower()
 
-    return matricule_e
+    return matricule
 
 # MODIFYING THE DATA OF A STUDENT
 def modify(data):
@@ -364,7 +364,7 @@ def modify(data):
 
         data.at[student_index, 'Matricule'] = matricule # Update the Matricule column with the new matricule
         
-        print("be careful because of a modification the registration number has changed :")
+        print("Be careful because of a modification the registration number has changed :")
 
         print(f"the new matricule is : {matricule}")
 
@@ -374,15 +374,15 @@ def modify(data):
 
 # Mapping for field names to DataFrame column names
 field_mapping = {
-    1: 'Name',
-    2: 'Surname',
-    3: 'Date of Birth',
-    4: 'Place of Birth',
-    5: 'Address',
-    6: 'Telephone',
-    7: 'Email',
-    8: 'Gender',
-    9: 'Academic Year',
+    1:  'Name',
+    2:  'Surname',
+    3:  'Date of Birth',
+    4:  'Place of Birth',
+    5:  'Address',
+    6:  'Telephone',
+    7:  'Email',
+    8:  'Gender',
+    9:  'Academic Year',
     10: 'Curriculum',
     12: 'Campus'
 }
@@ -460,11 +460,11 @@ def filter_students(data):
         headers = ["Firstname", "Lastname", "Matricule"]
         print(tabulate(table_data, headers=headers, tablefmt="pretty"))
     
-    export_choice = input("Do you want to export the list to an Excel file? (yes/no): ").lower()
-    if export_choice == "yes":
+    export_choice = input("Do you want to export the list to an Excel file? (YES/NO): ").upper()
+    if export_choice == "YES":
         export_to_excel(data)
-    read_choice = input("Do you want to read the exported list from an Excel file? (yes/no): ").lower()
-    if read_choice == "yes":
+    read_choice = input("Do you want to read the exported list from an Excel file? (YES/NO): ").upper()
+    if read_choice == "YES":
         read_exported_list()
 
 
@@ -565,7 +565,6 @@ def sort_by_academic_year(data):
     export_option(sorted_data)
 
 
-# attention il faut pouvoir matcher ceci avec les résultats obtenus
 def sort_passed(data):
     course_columns = data.columns[11:]
     print("Available Courses:")
@@ -604,7 +603,6 @@ def sort_failed(data):
 
     failed_data = data[data[selected_course] < 10]
     
-    # Notez que 'selected_course' doit être passé comme une liste pour inclure la note du cours dans 'columns_to_show'
     see_the_data( failed_data, columns_to_show=['Firstname', 'Lastname', selected_course])
     export_option( failed_data)
 
@@ -646,127 +644,180 @@ def see_the_data(data, columns_to_show=None):
 # STATS
 
 def statistics_analysis(data):
-    print('1. Get basic statistics')
-    print('2. Get all student grades')
-    print('3. Get all grades for a course')
-    print('4. Export all statistics')
+    print_menu([
+        "Get basic statistics",
+        "Get all student grades",
+        "Get all grades for a course",
+    ])
+    
+    stats_choice = get_valid_input("Enter the number of what you want to do: ", 1, 3)
+
+    if stats_choice == 1 :
+        results = search_and_display_stats(data, "Statistics")
+    elif stats_choice == 2:
+        results = search_and_display_stats(data, "Grades")
+    elif stats_choice == 3:
+        results = course_grades(data)
 
+def print_menu(options):
+    for index, option in enumerate(options, start=1):
+        print(f"{index}. {option}")
+
+def get_valid_input(prompt, lower_limit, upper_limit):
     while True:
-        stats_choice = input("Enter the number of what you want to do: ")
-        if stats_choice.isdigit():
-            stats_int = int(stats_choice)
-            if 1 <= stats_int <= 4:
-                print("The choice is valid.")
-                break
+        user_input = input(prompt)
+        if user_input.isdigit():
+            user_choice = int(user_input)
+            if lower_limit <= user_choice <= upper_limit:
+                return user_choice
             else:
-                print("The choice must be one of those proposed.")
-
-    if stats_choice == "1":
-        basic_stats(data)
-    elif stats_choice == "2":
-        all_grades(data)
-    elif stats_choice == "3":
-        course_grades(data)
-    elif stats_choice == "4":
-        export_stats(data)
-
-def basic_stats(data):
-    search_criteria = input("Enter the search criteria for student statistics (Name/Surname/Matricule): ").capitalize()
-
-    if search_criteria == "Name":
-        name_search = input("Enter the name of the student: ")
-        results = data[data['Name'].str.contains(name_search, case=False, na=False)]
-    elif search_criteria == "Surname":
-        surname_search = input("Enter the surname of the student: ")
-        results = data[data['Surname'].str.contains(surname_search, case=False, na=False)]
-    elif search_criteria == "Matricule":
-        matricule_search = input("Enter the matricule of the student: ")
-        results = data[data['Matricule'].str.contains(matricule_search, case=False, na=False)]
+                print(f"The choice must be between {lower_limit} and {upper_limit}.")
+        else:
+            print("Invalid input. Please enter a valid number.")
+
+def search_and_display_stats(data, stats_type):
+    print_menu(["Search by Firstname", "Search by Lastname", "Search by Matricule"])
+    search_criteria = get_valid_input(f"Enter the number of the search criteria for student {stats_type}: ", 1, 3)
+
+    if search_criteria == 1:
+        field_name = "Firstname"
+    elif search_criteria == 2:
+        field_name = "Lastname"
+    elif search_criteria == 3:
+        field_name = "Matricule"
     else:
         print("Invalid search criteria.")
         return
 
+    search_term = input(f"Enter the {field_name.lower()} of the student: ")
+    results = data[data[field_name].str.contains(search_term, case=False, na=False)]
+
+    if not results.empty:
+        if stats_type == "Statistics":
+            display_statistics(results)
+        elif stats_type == "Grades":
+            display_student_grades(results)
+    else:
+        print(f"No students found with the specified {field_name}.")
+
+def display_statistics(results):
     numeric_columns = results.select_dtypes(include=['number']).columns
 
     for index, row in results.iterrows():
-        student_name = f"{row['Name']} {row['Surname']}"
+        student_name = f"{row['Firstname']} {row['Lastname']}"
         student_grades = [row[column] for column in numeric_columns if not pd.isnull(row[column])]
 
         if student_grades:
-            lowest_grade = min(student_grades)
-            highest_grade = max(student_grades)
-            average_grade = statistics.mean(student_grades)
-            median_grade = statistics.median(student_grades)
-            std_deviation = statistics.stdev(student_grades)
-
-            print(f"\nStatistics for student {student_name}:")
-            print(f"Lowest grade: {lowest_grade}")
-            print(f"Highest grade: {highest_grade}")
-            print(f"Average grade: {average_grade}")
-            print(f"Median grade: {median_grade}")
-            print(f"Standard deviation of grades: {std_deviation}")
+            print_student_statistics(student_name, student_grades)
         else:
             print(f"\nNo grades found for student {student_name}.")
+    export_choice = input("Do you want to export these statistics? (YES/NO): ").upper()
+    if export_choice == 'YES':
+        export_stats(results)
+
+def print_student_statistics(student_name, student_grades):
+    lowest_grade = min(student_grades)
+    highest_grade = max(student_grades)
+    average_grade = statistics.mean(student_grades)
+    median_grade = statistics.median(student_grades)
+    std_deviation = statistics.stdev(student_grades)
+
+    table = [
+        ["Lowest grade", lowest_grade],
+        ["Highest grade", highest_grade],
+        ["Average grade", average_grade],
+        ["Median grade", median_grade],
+        ["Standard deviation of grades", std_deviation]
+    ]
+
+    print(f"\nStatistics for student {student_name}:")
+    print(tabulate(table, headers=["Metric", "Value"], tablefmt="pretty"))
+
+def display_student_grades(results):
+    for index, row in results.iterrows():
+        student_name = f"{row['Firstname']} {row['Lastname']}"
+        print(f"\nGrades for student {student_name}:")
+        table = [[column, grade] for column, grade in row.iteritems() if pd.notnull(grade)]
+        print(tabulate(table, headers=["Course", "Grade"], tablefmt="pretty"))
+    export_choice = input("Do you want to export these statistics? (YES/NO): ").upper()
+    if export_choice == 'YES':
+        export_stats(results)
 
-def all_grades(data):
-    search_criteria = input("Enter the search criteria for student grades (Name/Surname/Matricule): ").capitalize()
-
-    if search_criteria == "Name":
-        name_search = input("Enter the name of the student: ")
-        results = data[data['Name'].str.contains(name_search, case=False, na=False)]
-    elif search_criteria == "Surname":
-        surname_search = input("Enter the surname of the student: ")
-        results = data[data['Surname'].str.contains(surname_search, case=False, na=False)]
-    elif search_criteria == "Matricule":
-        matricule_search = input("Enter the matricule of the student: ")
-        results = data[data['Matricule'].str.contains(matricule_search, case=False, na=False)]
-    else:
-        print("Invalid search criteria.")
-        return
+def course_grades(data):
+    print("Here is the list of courses:")
+    print(data.select_dtypes(include=['number']).columns)
 
-    student = data[data['Matricule'].str.contains(matricule_search, case=False, na=False)]
+    course_name = input("For which course do you want to display grades? ")
 
-    if student.empty:
-        print(f"No student found with matricule {matricule_search}.")
-        return
+    if course_name in data.columns:
+        students_in_course = data[data[course_name].notnull()]
+
+        if not students_in_course.empty:
+            display_course_grades(students_in_course, course_name)
+        else:
+            print(f"No students participated in the course {course_name}.")
+    else:
+        print(f"The specified course ({course_name}) was not found.")
+    
+    export_choice = input("Do you want to export these statistics? (YES/NO): ").upper()
+    if export_choice == 'YES':
+        export_stats(students_in_course)
 
-    # Select columns containing grades
-    grade_columns = student.select_dtypes(include=['number']).columns
+    return students_in_course
 
-    # Display student's grades
-    print(f"Grades for student with matricule {matricule_search}:")
-    for column in grade_columns:
-        if not pd.isnull(student[column].values[0]):
-            print(f"{column}: {student[column].values[0]}")
+def display_course_grades(students_in_course, course_name):
+    print(f"\nGrades of students for the course {course_name}:")
+    table = [
+        ["Matricule", "Grade"],
+        *[[row['Matricule'], row[course_name]] for _, row in students_in_course.iterrows() if not pd.isnull(row[course_name])]
+    ]
+    print(tabulate(table, headers="firstrow", tablefmt="pretty"))
 
-def course_grades(data):
 
-    numeric_columns = data.select_dtypes(include=['number']).columns.tolist()
-    print("Here is the list of courses:")
-    for column in numeric_columns:
-        print(column)
+def export_stats(data):
+    # Ensure numeric columns only
+    numeric_columns = data.select_dtypes(include=['number']).columns
+    
+    # Calculate overall statistics
+    overall_stats = calculate_overall_stats(data, numeric_columns)
+    
+    # Save overall statistics to Excel
+    overall_stats.to_excel("overall_statistics.xlsx", index=False)
 
-    course_name = input(print("For which course do you want to display grades?"))
+    # Calculate and save statistics for each student
+    for index, row in data.iterrows():
+        student_name = f"{row['Firstname']} {row['Lastname']}"
+        student_stats = calculate_student_stats(row, numeric_columns)
+        student_stats.to_excel(f"{student_name}_statistics.xlsx", index=False)
 
-    if course_name not in data.columns:
-        print(f"The specified course ({course_name}) was not found.")
-        return
+    print("Statistics exported successfully.")
 
-    # Filter students who participated in this course (non-null grade)
-    students_in_course = data[data[course_name].notnull()]
+def calculate_overall_stats(data, numeric_columns):
+    all_grades = [row[column] for column in numeric_columns for _, row in data.iterrows() if not pd.isnull(row[column])]
+    
+    overall_stats = {
+        "Lowest grade": min(all_grades),
+        "Highest grade": max(all_grades),
+        "Average grade": statistics.mean(all_grades),
+        "Median grade": statistics.median(all_grades),
+        "Standard deviation of grades": statistics.stdev(all_grades)
+    }
 
-    if students_in_course.empty:
-        print(f"No student participated in the course {course_name}.")
-        return
+    return pd.DataFrame(list(overall_stats.items()), columns=["Metric", "Value"])
 
-    # Display grades of students for the specified course
-    print(f"Grades of students for the course {course_name}:")
-    for index, row in students_in_course.iterrows():
-        print(f"Matricule: {row['Matricule']}, Grade: {row[course_name]}")
+def calculate_student_stats(row, numeric_columns):
+    student_grades = [row[column] for column in numeric_columns if not pd.isnull(row[column])]
 
-def export_stats(data):
+    student_stats = {
+        "Lowest grade": min(student_grades),
+        "Highest grade": max(student_grades),
+        "Average grade": statistics.mean(student_grades),
+        "Median grade": statistics.median(student_grades),
+        "Standard deviation of grades": statistics.stdev(student_grades)
+    }
+
+    return pd.DataFrame(list(student_stats.items()), columns=["Metric", "Value"])
 
-    return
 
 # Example of usage
 # Make sure you have defined and loaded your DataFrame 'data' before calling this function
@@ -776,7 +827,7 @@ def export_stats(data):
 # Action
 
 def action():
-    print("What do you want to do?\nBelow, you will find what is possible followed by the commands to type.\n")
+    print("What do you want to do?\nBelow, you will find what is possible followed by the commands to type.")
     print("1. Register a student")
     print("2. Modify one or more fields")
     print("3. Delete a student")
diff --git a/projet_personnel/algorithme_student_generate.py b/projet_personnel/algorithme_student_generate.py
index b37fb2c5cfdf28ee0d0cba8ee88ee18d4cdcaa04..9206e0c9f049c7115597eadd6fc073c79d619c53 100644
--- a/projet_personnel/algorithme_student_generate.py
+++ b/projet_personnel/algorithme_student_generate.py
@@ -148,12 +148,12 @@ for each in range(number_of_students): # générer des données
 
 
     # attribution du matricule
-    consonant_of_lastname = ''.join([c for c in last_name if c.lower() not in 'aeiou'])[:3]
-    consonant_of_firstname = ''.join([c for c in first_name if c.lower() not in 'aeiou'])[:2]
-    last_consonant_of_firstname = ''.join([c for c in first_name if c.lower() not in 'aeiou']).lower()[-1] # ne sait pas si c'est la consonne du prénom ou du nom
-    year_of_birth_string = str(year_of_birth)[-2:]
+    consonant_of_firstname = ''.join([c for c in first_name if c.lower() not in 'aeiou'])[:3]
+    consonant_of_lastname = ''.join([c for c in last_name if c.lower() not in 'aeiou'])[:2]
+    last_consonant_of_lastname = ''.join([c for c in last_name if c.lower() not in 'aeiou']).lower()[-1] # ne sait pas si c'est la consonne du prénom ou du nom
+    year_of_birth_string = str(year_of_birth)[-4:]
     random_integer = random.randint(0, 10)
-    matricule = f"{consonant_of_lastname }{consonant_of_firstname}{last_consonant_of_firstname}{year_of_birth_string}{random_integer}"
+    matricule = f"{consonant_of_lastname }{consonant_of_firstname}{last_consonant_of_lastname}{year_of_birth_string}{random_integer}"
     matricule = matricule.lower()