1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
| import tkinter as tk
from tkinter import ttk
import pymysql
from tkinter import messagebox
import fpdf
# Database connection
maBase = pymysql.connect(host="localhost", user="root", password="", database="ecoledb")
cursor = maBase.cursor()
subject_info = None
average= None
appreciation = None
# Function to retrieve student information
def get_student_info(student_id):
cursor.execute('SELECT nom, classe FROM eleve WHERE matricule = %s', (student_id,))
student_info = cursor.fetchone()
if student_info:
return student_info[0], student_info[1]
else:
return None, None
# Function to retrieve school information
def get_school_info():
cursor.execute('SELECT nom,tutelle FROM etablissement')
school_info = cursor.fetchone()
if school_info:
return school_info[0], school_info[1]
else:
return None, None
# Function to retrieve subject information for a specific student
def get_subject_info(student_id, year, trimester):
cursor.execute("""
SELECT matiere.nom, enseignant.nom AS nom_enseignant, note.note, matiere.coef
FROM note
JOIN matiere ON note.matiere = matiere.mid
JOIN enseignant ON note.professeur = enseignant.enid
WHERE note.matricule = %s AND note.annee = %s AND note.periode = %s
""", (student_id, year, trimester))
subject_info = cursor.fetchall()
return subject_info
# Function to calculate final grade and average
def calculate_grades(subject_info):
total_marks = 0
total_coefficients = 0
for subject in subject_info:
total_marks += subject[2] * subject[3]
total_coefficients += subject[3]
if total_coefficients != 0:
average = total_marks / total_coefficients
else:
average = 0
return average
# Function to generate appreciation based on average score
def generate_appreciation(average):
if average >= 90:
appreciation = "Excellent"
elif average >= 80:
appreciation = "Très Bien"
elif average >= 70:
appreciation = "Bien"
elif average >= 60:
appreciation = "Assez Bien"
else:
appreciation = "Passable"
return appreciation
# Function to generate bulletin PDF report
def generate_bulletin_pdf(school_info,student_info,subject_info,average,appreciation):
# Create PDF object
pdf = fpdf.FPDF()
# Set PDF properties
pdf.add_page()
pdf.set_font('Arial', 'B', 16) # Set font to Arial Bold 16
# Add school logo (if available)
if school_info[1]:
with open(school_info[1], 'rb') as logo_file:
logo_data = logo_file.read()
pdf.image(logo_data, x=10, y=10, w=30, h=30)
# Add school name and student information
pdf.set_y(40) # Set y-position for school name
pdf.cell(0, 10, school_info[0], align='C') # Print school name centered
pdf.set_y(50) # Set y-position for student information
pdf.set_font('Arial', '', 12) # Change font to Arial Regular 12
pdf.cell(40, 10, "Nom:", align='L')
pdf.cell(60, 10, student_info[0], align='L')
pdf.cell(40, 10, "Classe:", align='L')
pdf.cell(0, 10, student_info[1], align='L')
# Add table header for subject information
pdf.set_y(70) # Set y-position for table header
pdf.set_font('Arial', 'B', 10) # Set font to Arial Bold 10
pdf.cell(60, 10, "Matière", align='C')
pdf.cell(40, 10, "Enseignant", align='C')
pdf.cell(20, 10, "Note", align='C')
pdf.cell(20, 10, "Coeff.", align='C')
pdf.cell(40, 10, "Note Finale", align='C')
pdf.ln(10) # Add line break after header
# Add subject information with lines
pdf.set_font('Arial', '', 10) # Set font to Arial Regular 10
for subject in subject_info:
pdf.cell(60, 10, subject[0], align='L')
pdf.cell(40, 10, subject[1], align='L')
pdf.cell(20, 10, str(subject[2]), align='C')
pdf.cell(20, 10, str(subject[3]), align='C')
# Calculate and display final grade (Note * Coeff)
final_grade = subject[2] * subject[3]
pdf.cell(40, 10, str(final_grade), align='C')
pdf.ln(10) # Add line break after each subject
# Add average and appreciation
pdf.set_font('Arial', 'B', 12) # Set font to Arial Bold 12
pdf.cell(80, 10, "Moyenne :", align='L')
pdf.cell(0, 10, str(average), align='L')
pdf.set_y(pdf.get_y() + 10) # Move down a bit
pdf.cell(80, 10, "Appréciation :", align='L')
pdf.cell(0, 10, appreciation, align='L')
# Add signature lines (optional)
# You can uncomment and modify these lines to add signature areas
# pdf.set_y(pdf.get_y() + 50)
# pdf.cell(0, 10, "Signature du Chef d'Établissement
# Main application window
window = tk.Tk()
window.title("Gestion des Bulletins Scolaires")
# Frame for student selection
student_frame = tk.Frame(window)
student_frame.pack(pady=10)
student_id_label = tk.Label(student_frame, text="ID Élève:")
student_id_label.pack(side=tk.LEFT, padx=5)
student_id_entry = tk.Entry(student_frame)
student_id_entry.pack(side=tk.LEFT, padx=5)
select_student_button = tk.Button(student_frame, text="Sélectionner Élève", command=lambda: get_student_data())
select_student_button.pack(side=tk.LEFT, padx=5)
# Frame for student information display
student_info_frame = tk.Frame(window)
student_info_frame.pack(pady=10)
student_name_label = tk.Label(student_info_frame, text="Nom:")
student_name_label.pack(side=tk.LEFT, padx=5)
student_name_value = tk.Label(student_info_frame, text="")
student_name_value.pack(side=tk.LEFT, padx=5)
student_class_label = tk.Label(student_info_frame, text="Classe:")
student_class_label.pack(side=tk.LEFT, padx=5)
student_class_value = tk.Label(student_info_frame, text="")
student_class_value.pack(side=tk.LEFT, padx=5)
# Frame for school information display
school_info_frame = tk.Frame(window)
school_info_frame.pack(pady=10)
school_name_label = tk.Label(school_info_frame, text="Établissement:")
school_name_label.pack(side=tk.LEFT, padx=5)
school_name_value = tk.Label(school_info_frame, text="")
school_name_value.pack(side=tk.LEFT, padx=5)
# Frame for subject information display
subject_info_frame = tk.Frame(window, bd=1, relief=tk.SUNKEN)
subject_info_frame.pack(pady=10)
subject_tree = ttk.Treeview(subject_info_frame, columns=("Matière", "Enseignant", "Note", "Coefficient", "Note Finale"))
subject_tree.heading("Matière", text="Matière")
subject_tree.heading("Enseignant", text="Enseignant")
subject_tree.heading("Note", text="Note")
subject_tree.heading("Coefficient", text="Coefficient")
subject_tree.heading("Note Finale", text="Note Finale")
subject_tree.pack()
# Frame for average and appreciation display
average_frame = tk.Frame(window)
average_frame.pack(pady=10)
average_label = tk.Label(average_frame, text="Moyenne:")
average_label.pack(side=tk.LEFT, padx=5)
average_value = tk.Label(average_frame, text="")
average_value.pack(side=tk.LEFT, padx=5)
appreciation_label = tk.Label(average_frame, text="Appréciation:")
appreciation_label.pack(side=tk.LEFT, padx=5)
appreciation_value = tk.Label(average_frame, text="")
appreciation_value.pack(side=tk.LEFT, padx=5)
# Frame for signature and generation buttons
signature_frame = tk.Frame(window)
signature_frame.pack(pady=10)
principal_signature_label = tk.Label(signature_frame, text="Signature du Chef d'Établissement:")
principal_signature_label.pack(side=tk.LEFT, padx=5)
principal_signature_entry = tk.Entry(signature_frame)
principal_signature_entry.pack(side=tk.LEFT, padx=5)
guardian_signature_label = tk.Label(signature_frame, text="Signature du Tuteur:")
guardian_signature_label.pack(side=tk.LEFT, padx=5)
guardian_signature_entry = tk.Entry(signature_frame)
guardian_signature_entry.pack(side=tk.LEFT, padx=5)
generate_button = tk.Button(signature_frame, text="Générer Bulletin", command=lambda: generate_bulletin())
generate_button.pack(pady=5)
# Function to retrieve and display student data
def get_student_data():
student_id = student_id_entry.get()
if student_id:
try:
student_id = int(student_id)
except ValueError:
messagebox.showerror("Erreur", "ID Élève invalide.")
return
student_name, student_class = get_student_info(student_id)
if student_name and student_class:
student_name_value.config(text=student_name)
student_class_value.config(text=student_class)
school_name, school_logo = get_school_info()
if school_name and school_logo:
school_name_value.config(text=school_name)
subject_info = get_subject_info(student_id, 2024, 1) # Replace with actual year and trimester
if subject_info:
subject_tree.delete(*subject_tree.get_children())
for subject in subject_info:
subject_tree.insert("", tk.END, values=subject)
average = calculate_grades(subject_info)
appreciation = generate_appreciation(average)
average_value.config(text=f"{average:.2f}")
appreciation_value.config(text=appreciation)
def generate_bulletin(subject_info, average, appreciation):
# Retrieve data from labels and entries
student_name = student_name_value.cget("text")
student_class = student_class_value.cget("text")
school_name = school_name_value.cget("text")
principal_signature = principal_signature_entry.get()
guardian_signature = guardian_signature_entry.get()
# Generate PDF report using the retrieved data
generate_bulletin_pdf(
student_name, student_class, school_name,subject_info, average, appreciation,
principal_signature, guardian_signature
)
# Main event loop
window.mainloop() |
Partager