histlearn commited on
Commit
c38caaf
·
verified ·
1 Parent(s): b5b691a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -25
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 = dados_disciplina[colunas_notas].values[0]
119
- # Converter para Series do pandas
120
- notas_series = pd.Series(notas)
121
- notas_validas = pd.to_numeric(notas_series, errors='coerce').replace([np.nan, 0], 0) > 0
122
 
123
- if any(notas_validas):
124
  bimestres = np.arange(1, len(colunas_notas) + 1)[notas_validas]
125
- notas_filtradas = pd.to_numeric(notas_series[notas_validas], errors='coerce').fillna(0)
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 com tratamento de erros melhorado
181
  colunas_freq = ['%Freq B1', '%Freq B2', '%Freq B3', '%Freq B4']
182
- freq_data = df_filtrado[colunas_freq].replace('%', '', regex=True)
183
- freq_data = freq_data.apply(pd.to_numeric, errors='coerce').fillna(0)
184
- medias_frequencia = freq_data.mean(axis=1)
185
 
186
- # Processar notas com tratamento de erros melhorado
187
  colunas_notas = ['Nota B1', 'Nota B2', 'Nota B3', 'Nota B4']
188
- notas_data = df_filtrado[colunas_notas].apply(pd.to_numeric, errors='coerce').fillna(0)
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].apply(pd.to_numeric, errors='coerce').fillna(0)
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
- freq_data = freq_data.apply(pd.to_numeric, errors='coerce').fillna(0)
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()