histlearn commited on
Commit
c609459
·
verified ·
1 Parent(s): 3a3ebd5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +92 -0
app.py CHANGED
@@ -168,6 +168,7 @@ def extrair_tabelas_pdf(pdf_path):
168
  except Exception as e:
169
  print(f"Erro na extração das tabelas: {str(e)}")
170
  raise
 
171
  def obter_disciplinas_validas(df):
172
  """Identifica disciplinas válidas no boletim com seus dados."""
173
  colunas_notas = ['Nota B1', 'Nota B2', 'Nota B3', 'Nota B4']
@@ -351,6 +352,97 @@ def plotar_evolucao_bimestres(disciplinas_dados, temp_dir, titulo=None, nome_arq
351
  plt.close()
352
  return plot_path
353
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
354
  def gerar_relatorio_pdf(df, disciplinas_dados, grafico_basica, grafico_diversificada, grafico_medias):
355
  """Gera relatório PDF com os gráficos e análises."""
356
  pdf = FPDF()
 
168
  except Exception as e:
169
  print(f"Erro na extração das tabelas: {str(e)}")
170
  raise
171
+
172
  def obter_disciplinas_validas(df):
173
  """Identifica disciplinas válidas no boletim com seus dados."""
174
  colunas_notas = ['Nota B1', 'Nota B2', 'Nota B3', 'Nota B4']
 
352
  plt.close()
353
  return plot_path
354
 
355
+ def plotar_graficos_destacados(disciplinas_dados, temp_dir):
356
+ """Plota gráficos de médias e frequências com destaques."""
357
+ n_disciplinas = len(disciplinas_dados)
358
+
359
+ if not n_disciplinas:
360
+ raise ValueError("Nenhuma disciplina válida encontrada no boletim.")
361
+
362
+ # Criar figura
363
+ plt.figure(figsize=(12, 10))
364
+
365
+ disciplinas = [d['disciplina'] for d in disciplinas_dados]
366
+ medias_notas = [d['media_notas'] for d in disciplinas_dados]
367
+ medias_freq = [d['media_freq'] for d in disciplinas_dados]
368
+
369
+ # Criar subplot com mais espaço entre os gráficos
370
+ fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 10), height_ratios=[1, 1])
371
+ plt.subplots_adjust(hspace=0.5) # Aumentar espaço entre os gráficos
372
+
373
+ # Definir cores baseadas nos limites de aprovação
374
+ cores_notas = ['red' if media < LIMITE_APROVACAO_NOTA else '#2ecc71' for media in medias_notas]
375
+ cores_freq = ['red' if media < LIMITE_APROVACAO_FREQ else '#2ecc71' for media in medias_freq]
376
+
377
+ # Calcular médias globais
378
+ media_global = np.mean(medias_notas)
379
+ freq_global = np.mean(medias_freq)
380
+
381
+ # Gráfico de notas
382
+ barras_notas = ax1.bar(disciplinas, medias_notas, color=cores_notas)
383
+ ax1.set_title('Média de Notas por Disciplina', pad=20, fontsize=12, fontweight='bold')
384
+ ax1.set_ylim(0, ESCALA_MAXIMA_NOTAS)
385
+ ax1.grid(True, axis='y', alpha=0.3, linestyle='--')
386
+
387
+ # Melhorar a apresentação dos rótulos
388
+ ax1.set_xticklabels(disciplinas, rotation=45, ha='right', va='top')
389
+ ax1.set_ylabel('Notas', fontsize=10, labelpad=10)
390
+
391
+ # Adicionar linha de média mínima
392
+ ax1.axhline(y=LIMITE_APROVACAO_NOTA, color='r', linestyle='--', alpha=0.3)
393
+ ax1.text(0.02, LIMITE_APROVACAO_NOTA + 0.1, 'Média mínima (5,0)',
394
+ transform=ax1.get_yaxis_transform(), color='r', alpha=0.7)
395
+
396
+ # Valores nas barras de notas
397
+ for barra in barras_notas:
398
+ altura = barra.get_height()
399
+ ax1.text(barra.get_x() + barra.get_width()/2., altura,
400
+ f'{altura:.1f}',
401
+ ha='center', va='bottom', fontsize=8)
402
+
403
+ # Gráfico de frequências
404
+ barras_freq = ax2.bar(disciplinas, medias_freq, color=cores_freq)
405
+ ax2.set_title('Frequência Média por Disciplina', pad=20, fontsize=12, fontweight='bold')
406
+ ax2.set_ylim(0, 110)
407
+ ax2.grid(True, axis='y', alpha=0.3, linestyle='--')
408
+
409
+ # Melhorar a apresentação dos rótulos
410
+ ax2.set_xticklabels(disciplinas, rotation=45, ha='right', va='top')
411
+ ax2.set_ylabel('Frequência (%)', fontsize=10, labelpad=10)
412
+
413
+ # Adicionar linha de frequência mínima
414
+ ax2.axhline(y=LIMITE_APROVACAO_FREQ, color='r', linestyle='--', alpha=0.3)
415
+ ax2.text(0.02, LIMITE_APROVACAO_FREQ + 1, 'Frequência mínima (75%)',
416
+ transform=ax2.get_yaxis_transform(), color='r', alpha=0.7)
417
+
418
+ # Valores nas barras de frequência
419
+ for barra in barras_freq:
420
+ altura = barra.get_height()
421
+ ax2.text(barra.get_x() + barra.get_width()/2., altura,
422
+ f'{altura:.1f}%',
423
+ ha='center', va='bottom', fontsize=8)
424
+
425
+ # Título global com informações de média
426
+ plt.suptitle(
427
+ f'Desempenho Geral\nMédia Global: {media_global:.1f} | Frequência Global: {freq_global:.1f}%',
428
+ y=0.98, fontsize=14, fontweight='bold'
429
+ )
430
+
431
+ # Aviso de risco de reprovação se necessário
432
+ if freq_global < LIMITE_APROVACAO_FREQ:
433
+ plt.figtext(0.5, 0.02,
434
+ "Atenção: Risco de Reprovação por Baixa Frequência",
435
+ ha="center", fontsize=11, color="red", weight='bold')
436
+
437
+ plt.tight_layout()
438
+
439
+ # Salvar o gráfico
440
+ plot_path = os.path.join(temp_dir, 'medias_frequencias.png')
441
+ plt.savefig(plot_path, bbox_inches='tight', dpi=300)
442
+ plt.close()
443
+
444
+ return plot_path
445
+
446
  def gerar_relatorio_pdf(df, disciplinas_dados, grafico_basica, grafico_diversificada, grafico_medias):
447
  """Gera relatório PDF com os gráficos e análises."""
448
  pdf = FPDF()