Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -9,6 +9,7 @@ import tempfile
|
|
9 |
import os
|
10 |
import matplotlib
|
11 |
import shutil
|
|
|
12 |
matplotlib.use('Agg')
|
13 |
|
14 |
def extrair_tabelas_pdf(pdf_path):
|
@@ -90,6 +91,22 @@ def obter_disciplinas_validas(df):
|
|
90 |
|
91 |
return disciplinas_validas
|
92 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
def plotar_evolucao_bimestres(df_filtrado, temp_dir):
|
94 |
"""Plota gráfico de evolução das notas por bimestre."""
|
95 |
# Obter disciplinas válidas
|
@@ -103,7 +120,6 @@ def plotar_evolucao_bimestres(df_filtrado, temp_dir):
|
|
103 |
altura_figura = max(6, n_disciplinas * 0.4)
|
104 |
plt.figure(figsize=(14, altura_figura))
|
105 |
|
106 |
-
# Gerar cores para as disciplinas
|
107 |
cores = gerar_paleta_cores(n_disciplinas)
|
108 |
marcadores = ['o', 's', '^', 'D', 'v', '<', '>', 'p', 'h', '8', '*', 'H', '+', 'x', 'd']
|
109 |
estilos_linha = ['-', '--', '-.', ':', '-', '--', '-.', ':', '-', '--', '-.', ':', '-', '--', '-.']
|
@@ -115,14 +131,13 @@ def plotar_evolucao_bimestres(df_filtrado, temp_dir):
|
|
115 |
for idx, disciplina in enumerate(disciplinas_validas):
|
116 |
dados_disciplina = df_filtrado[df_filtrado['Disciplina'] == disciplina]
|
117 |
if not dados_disciplina.empty:
|
118 |
-
notas
|
119 |
-
|
120 |
-
|
121 |
-
notas_validas = pd.to_numeric(notas_series, errors='coerce').replace([np.nan, 0], 0) > 0
|
122 |
|
123 |
-
if any(
|
124 |
bimestres = np.arange(1, len(colunas_notas) + 1)[notas_validas]
|
125 |
-
notas_filtradas = pd.to_numeric(
|
126 |
|
127 |
plt.plot(bimestres, notas_filtradas,
|
128 |
color=cores[idx % len(cores)],
|
@@ -139,7 +154,6 @@ def plotar_evolucao_bimestres(df_filtrado, temp_dir):
|
|
139 |
xytext=(0, 5),
|
140 |
ha='center',
|
141 |
fontsize=8)
|
142 |
-
|
143 |
|
144 |
plt.title('Evolução das Médias por Disciplina ao Longo dos Bimestres')
|
145 |
plt.xlabel('Bimestres')
|
@@ -147,7 +161,6 @@ def plotar_evolucao_bimestres(df_filtrado, temp_dir):
|
|
147 |
plt.xticks([1, 2, 3, 4], ['B1', 'B2', 'B3', 'B4'])
|
148 |
plt.ylim(0, 10)
|
149 |
|
150 |
-
# Ajustar legenda baseado no número de disciplinas
|
151 |
if n_disciplinas > 10:
|
152 |
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', fontsize=8)
|
153 |
else:
|
@@ -177,16 +190,15 @@ def plotar_graficos_destacados(df_boletim_clean, temp_dir):
|
|
177 |
df_filtrado = df_boletim_clean[df_boletim_clean['Disciplina'].isin(disciplinas_validas)]
|
178 |
disciplinas = df_filtrado['Disciplina'].astype(str)
|
179 |
|
180 |
-
# Processar frequências
|
181 |
colunas_freq = ['%Freq B1', '%Freq B2', '%Freq B3', '%Freq B4']
|
182 |
-
freq_data = df_filtrado[colunas_freq].replace('%', '', regex=True)
|
183 |
-
|
184 |
-
medias_frequencia = freq_data.mean(axis=1)
|
185 |
|
186 |
-
# Processar notas
|
187 |
colunas_notas = ['Nota B1', 'Nota B2', 'Nota B3', 'Nota B4']
|
188 |
-
notas_data = df_filtrado[colunas_notas].
|
189 |
-
medias_notas = notas_data.mean(axis=1)
|
190 |
|
191 |
cores_notas = ['red' if media < 5 else 'blue' for media in medias_notas]
|
192 |
cores_frequencias = ['red' if media < 75 else 'green' for media in medias_frequencia]
|
@@ -199,7 +211,6 @@ def plotar_graficos_destacados(df_boletim_clean, temp_dir):
|
|
199 |
plt.xticks(rotation=45, ha='right')
|
200 |
plt.ylim(0, 10)
|
201 |
|
202 |
-
# Adicionar valores nas barras
|
203 |
for barra in barras_notas:
|
204 |
altura = barra.get_height()
|
205 |
plt.text(barra.get_x() + barra.get_width()/2., altura,
|
@@ -212,7 +223,6 @@ def plotar_graficos_destacados(df_boletim_clean, temp_dir):
|
|
212 |
plt.xticks(rotation=45, ha='right')
|
213 |
plt.ylim(0, 100)
|
214 |
|
215 |
-
# Adicionar valores nas barras
|
216 |
for barra in barras_freq:
|
217 |
altura = barra.get_height()
|
218 |
plt.text(barra.get_x() + barra.get_width()/2., altura,
|
@@ -241,7 +251,6 @@ def gerar_relatorio_pdf(df, grafico1_path, grafico2_path):
|
|
241 |
pdf.cell(0, 10, 'Relatório de Desempenho Escolar', 0, new_x=XPos.LMARGIN, new_y=YPos.NEXT, align='C')
|
242 |
pdf.ln(10)
|
243 |
|
244 |
-
# Informações do aluno se disponíveis
|
245 |
if 'Nome do Aluno' in df.columns:
|
246 |
pdf.set_font('Helvetica', '', 12)
|
247 |
pdf.cell(0, 10, f'Aluno: {df["Nome do Aluno"].iloc[0]}', 0, new_x=XPos.LMARGIN, new_y=YPos.NEXT, align='L')
|
@@ -255,20 +264,18 @@ def gerar_relatorio_pdf(df, grafico1_path, grafico2_path):
|
|
255 |
pdf.cell(0, 10, 'Avisos Importantes:', 0, new_x=XPos.LMARGIN, new_y=YPos.NEXT, align='L')
|
256 |
pdf.set_font('Helvetica', '', 10)
|
257 |
|
258 |
-
# Obter disciplinas válidas
|
259 |
disciplinas_validas = obter_disciplinas_validas(df)
|
260 |
df_filtrado = df[df['Disciplina'].isin(disciplinas_validas)]
|
261 |
|
262 |
# Calcular médias
|
263 |
colunas_notas = ['Nota B1', 'Nota B2', 'Nota B3', 'Nota B4']
|
264 |
-
notas_data = df_filtrado[colunas_notas].
|
265 |
-
medias_notas = notas_data.mean(axis=1)
|
266 |
|
267 |
# Processar frequências
|
268 |
colunas_freq = ['%Freq B1', '%Freq B2', '%Freq B3', '%Freq B4']
|
269 |
-
freq_data = df_filtrado[colunas_freq].replace('%', '', regex=True)
|
270 |
-
|
271 |
-
medias_freq = freq_data.mean(axis=1)
|
272 |
|
273 |
# Adicionar média global
|
274 |
media_global = medias_notas.mean()
|
|
|
9 |
import os
|
10 |
import matplotlib
|
11 |
import shutil
|
12 |
+
import colorsys
|
13 |
matplotlib.use('Agg')
|
14 |
|
15 |
def extrair_tabelas_pdf(pdf_path):
|
|
|
91 |
|
92 |
return disciplinas_validas
|
93 |
|
94 |
+
def gerar_paleta_cores(n_cores):
|
95 |
+
"""Gera uma paleta de cores distintas para o número de disciplinas."""
|
96 |
+
cores_base = [
|
97 |
+
'#DC143C', '#4169E1', '#9370DB', '#32CD32', '#FF8C00',
|
98 |
+
'#00CED1', '#FF69B4', '#8B4513', '#4B0082', '#556B2F',
|
99 |
+
'#B8860B', '#483D8B', '#008B8B', '#8B008B', '#8B0000'
|
100 |
+
]
|
101 |
+
|
102 |
+
if n_cores > len(cores_base):
|
103 |
+
HSV_tuples = [(x/n_cores, 0.8, 0.9) for x in range(n_cores)]
|
104 |
+
cores_extras = ['#%02x%02x%02x' % tuple(int(x*255) for x in colorsys.hsv_to_rgb(*hsv))
|
105 |
+
for hsv in HSV_tuples]
|
106 |
+
return cores_extras
|
107 |
+
|
108 |
+
return cores_base[:n_cores]
|
109 |
+
|
110 |
def plotar_evolucao_bimestres(df_filtrado, temp_dir):
|
111 |
"""Plota gráfico de evolução das notas por bimestre."""
|
112 |
# Obter disciplinas válidas
|
|
|
120 |
altura_figura = max(6, n_disciplinas * 0.4)
|
121 |
plt.figure(figsize=(14, altura_figura))
|
122 |
|
|
|
123 |
cores = gerar_paleta_cores(n_disciplinas)
|
124 |
marcadores = ['o', 's', '^', 'D', 'v', '<', '>', 'p', 'h', '8', '*', 'H', '+', 'x', 'd']
|
125 |
estilos_linha = ['-', '--', '-.', ':', '-', '--', '-.', ':', '-', '--', '-.', ':', '-', '--', '-.']
|
|
|
131 |
for idx, disciplina in enumerate(disciplinas_validas):
|
132 |
dados_disciplina = df_filtrado[df_filtrado['Disciplina'] == disciplina]
|
133 |
if not dados_disciplina.empty:
|
134 |
+
# Converter notas para Series do pandas
|
135 |
+
notas = pd.Series(dados_disciplina[colunas_notas].values[0])
|
136 |
+
notas_validas = pd.to_numeric(notas, errors='coerce').replace([np.nan, 0], 0) > 0
|
|
|
137 |
|
138 |
+
if notas_validas.any():
|
139 |
bimestres = np.arange(1, len(colunas_notas) + 1)[notas_validas]
|
140 |
+
notas_filtradas = pd.to_numeric(notas[notas_validas], errors='coerce').replace(np.nan, 0)
|
141 |
|
142 |
plt.plot(bimestres, notas_filtradas,
|
143 |
color=cores[idx % len(cores)],
|
|
|
154 |
xytext=(0, 5),
|
155 |
ha='center',
|
156 |
fontsize=8)
|
|
|
157 |
|
158 |
plt.title('Evolução das Médias por Disciplina ao Longo dos Bimestres')
|
159 |
plt.xlabel('Bimestres')
|
|
|
161 |
plt.xticks([1, 2, 3, 4], ['B1', 'B2', 'B3', 'B4'])
|
162 |
plt.ylim(0, 10)
|
163 |
|
|
|
164 |
if n_disciplinas > 10:
|
165 |
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', fontsize=8)
|
166 |
else:
|
|
|
190 |
df_filtrado = df_boletim_clean[df_boletim_clean['Disciplina'].isin(disciplinas_validas)]
|
191 |
disciplinas = df_filtrado['Disciplina'].astype(str)
|
192 |
|
193 |
+
# Processar frequências
|
194 |
colunas_freq = ['%Freq B1', '%Freq B2', '%Freq B3', '%Freq B4']
|
195 |
+
freq_data = df_filtrado[colunas_freq].replace('%', '', regex=True).astype(float)
|
196 |
+
medias_frequencia = freq_data.replace([np.nan, 0], 0).mean(axis=1)
|
|
|
197 |
|
198 |
+
# Processar notas
|
199 |
colunas_notas = ['Nota B1', 'Nota B2', 'Nota B3', 'Nota B4']
|
200 |
+
notas_data = df_filtrado[colunas_notas].astype(float)
|
201 |
+
medias_notas = notas_data.replace([np.nan, 0], 0).mean(axis=1)
|
202 |
|
203 |
cores_notas = ['red' if media < 5 else 'blue' for media in medias_notas]
|
204 |
cores_frequencias = ['red' if media < 75 else 'green' for media in medias_frequencia]
|
|
|
211 |
plt.xticks(rotation=45, ha='right')
|
212 |
plt.ylim(0, 10)
|
213 |
|
|
|
214 |
for barra in barras_notas:
|
215 |
altura = barra.get_height()
|
216 |
plt.text(barra.get_x() + barra.get_width()/2., altura,
|
|
|
223 |
plt.xticks(rotation=45, ha='right')
|
224 |
plt.ylim(0, 100)
|
225 |
|
|
|
226 |
for barra in barras_freq:
|
227 |
altura = barra.get_height()
|
228 |
plt.text(barra.get_x() + barra.get_width()/2., altura,
|
|
|
251 |
pdf.cell(0, 10, 'Relatório de Desempenho Escolar', 0, new_x=XPos.LMARGIN, new_y=YPos.NEXT, align='C')
|
252 |
pdf.ln(10)
|
253 |
|
|
|
254 |
if 'Nome do Aluno' in df.columns:
|
255 |
pdf.set_font('Helvetica', '', 12)
|
256 |
pdf.cell(0, 10, f'Aluno: {df["Nome do Aluno"].iloc[0]}', 0, new_x=XPos.LMARGIN, new_y=YPos.NEXT, align='L')
|
|
|
264 |
pdf.cell(0, 10, 'Avisos Importantes:', 0, new_x=XPos.LMARGIN, new_y=YPos.NEXT, align='L')
|
265 |
pdf.set_font('Helvetica', '', 10)
|
266 |
|
|
|
267 |
disciplinas_validas = obter_disciplinas_validas(df)
|
268 |
df_filtrado = df[df['Disciplina'].isin(disciplinas_validas)]
|
269 |
|
270 |
# Calcular médias
|
271 |
colunas_notas = ['Nota B1', 'Nota B2', 'Nota B3', 'Nota B4']
|
272 |
+
notas_data = df_filtrado[colunas_notas].astype(float)
|
273 |
+
medias_notas = notas_data.replace([np.nan, 0], 0).mean(axis=1)
|
274 |
|
275 |
# Processar frequências
|
276 |
colunas_freq = ['%Freq B1', '%Freq B2', '%Freq B3', '%Freq B4']
|
277 |
+
freq_data = df_filtrado[colunas_freq].replace('%', '', regex=True).astype(float)
|
278 |
+
medias_freq = freq_data.replace([np.nan, 0], 0).mean(axis=1)
|
|
|
279 |
|
280 |
# Adicionar média global
|
281 |
media_global = medias_notas.mean()
|