histlearn commited on
Commit
dd811fe
·
verified ·
1 Parent(s): a044811

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +90 -30
app.py CHANGED
@@ -7,17 +7,48 @@ from fpdf import FPDF
7
  import tempfile
8
  import os
9
  import matplotlib
10
- matplotlib.use('Agg') # Usar backend não-interativo
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  def converter_nota(valor):
 
13
  if pd.isna(valor) or valor == '-' or valor == 'N':
14
  return 0
15
  try:
16
- return float(valor)
17
  except:
18
  return 0
19
 
20
  def plotar_evolucao_bimestres(df_filtrado, temp_dir):
 
21
  plt.figure(figsize=(12, 6))
22
 
23
  disciplinas_basicas = ['LINGUA PORTUGUESA', 'ARTE', 'LINGUA ESTRANGEIRA INGLES',
@@ -61,7 +92,7 @@ def plotar_evolucao_bimestres(df_filtrado, temp_dir):
61
  alpha=0.8)
62
 
63
  for x, y in zip(bimestres, notas_filtradas):
64
- plt.annotate(str(y), (x, y), textcoords="offset points", xytext=(0, 10), ha='center')
65
 
66
  plt.title('Evolução das Médias por Disciplina ao Longo dos Bimestres')
67
  plt.xlabel('Bimestres')
@@ -77,11 +108,16 @@ def plotar_evolucao_bimestres(df_filtrado, temp_dir):
77
  return plot_path
78
 
79
  def plotar_graficos_destacados(df_boletim_clean, temp_dir):
 
80
  plt.figure(figsize=(12, 6))
81
 
82
  disciplinas = df_boletim_clean['Disciplina'].astype(str)
83
 
84
- medias_frequencia = df_boletim_clean[['Freq B1', 'Freq B2', 'Freq B3', 'Freq B4']].apply(pd.to_numeric, errors='coerce').mean(axis=1)
 
 
 
 
85
  medias_notas = df_boletim_clean[['Nota B1', 'Nota B2', 'Nota B3', 'Nota B4']].apply(pd.to_numeric, errors='coerce').mean(axis=1)
86
 
87
  cores_notas = ['red' if media < 5 else 'blue' for media in medias_notas]
@@ -114,6 +150,7 @@ def plotar_graficos_destacados(df_boletim_clean, temp_dir):
114
  return plot_path
115
 
116
  def gerar_relatorio_pdf(df, grafico1_path, grafico2_path):
 
117
  pdf = FPDF()
118
  pdf.add_page()
119
 
@@ -130,8 +167,13 @@ def gerar_relatorio_pdf(df, grafico1_path, grafico2_path):
130
  pdf.cell(0, 10, 'Avisos Importantes:', 0, 1, 'L')
131
  pdf.set_font('Arial', '', 10)
132
 
 
133
  medias_notas = df[['Nota B1', 'Nota B2', 'Nota B3', 'Nota B4']].apply(pd.to_numeric, errors='coerce').mean(axis=1)
134
- medias_freq = df[['Freq B1', 'Freq B2', 'Freq B3', 'Freq B4']].apply(pd.to_numeric, errors='coerce').mean(axis=1)
 
 
 
 
135
 
136
  for idx, (disciplina, media_nota, media_freq) in enumerate(zip(df['Disciplina'], medias_notas, medias_freq)):
137
  if media_nota < 5:
@@ -144,55 +186,73 @@ def gerar_relatorio_pdf(df, grafico1_path, grafico2_path):
144
  pdf.output(pdf_path)
145
  return pdf_path
146
 
147
- def processar_boletim(pdf_file):
 
 
148
  try:
 
 
 
 
 
149
  temp_dir = tempfile.mkdtemp()
 
150
 
151
- # Ler o arquivo temporário e salvar seu conteúdo
152
  temp_pdf = os.path.join(temp_dir, 'boletim.pdf')
153
  with open(temp_pdf, 'wb') as f:
154
- f.write(pdf_file.read()) # Usar .read() para obter o conteúdo do arquivo
155
-
156
- tables = camelot.read_pdf(temp_pdf, pages='all', flavor='lattice')
157
-
158
- if len(tables) == 0:
159
- return None, "Nenhuma tabela encontrada no PDF."
160
 
161
- df = tables[0].df
 
 
 
162
 
163
- df.columns = ['Disciplina', 'Nota B1', 'Freq B1', '%Freq B1', 'AC B1',
164
- 'Nota B2', 'Freq B2', '%Freq B2', 'AC B2',
165
- 'Nota B3', 'Freq B3', '%Freq B3', 'AC B3',
166
- 'Nota B4', 'Freq B4', '%Freq B4', 'AC B4',
167
- 'CF', 'Nota Final', 'Freq Final', 'AC Final']
168
 
 
169
  colunas_notas = ['Nota B1', 'Nota B2', 'Nota B3', 'Nota B4']
170
  for col in colunas_notas:
171
- df[col] = df[col].apply(converter_nota)
 
 
172
 
 
 
173
  grafico1_path = plotar_evolucao_bimestres(df, temp_dir)
174
  grafico2_path = plotar_graficos_destacados(df, temp_dir)
 
175
 
 
 
176
  pdf_path = gerar_relatorio_pdf(df, grafico1_path, grafico2_path)
 
177
 
 
178
  with open(pdf_path, 'rb') as f:
179
  pdf_content = f.read()
180
 
181
- # Limpar arquivos temporários
182
- os.remove(pdf_path)
183
- for file in os.listdir(temp_dir):
184
- os.remove(os.path.join(temp_dir, file))
185
- os.rmdir(temp_dir)
186
-
187
  return pdf_content, "Relatório gerado com sucesso!"
188
 
189
  except Exception as e:
190
- if 'temp_dir' in locals():
191
- for file in os.listdir(temp_dir):
192
- os.remove(os.path.join(temp_dir, file))
193
- os.rmdir(temp_dir)
194
  return None, f"Erro ao processar o boletim: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
195
 
 
196
  iface = gr.Interface(
197
  fn=processar_boletim,
198
  inputs=gr.File(label="Upload do Boletim (PDF)"),
 
7
  import tempfile
8
  import os
9
  import matplotlib
10
+ matplotlib.use('Agg')
11
+
12
+ def extrair_tabelas_pdf(pdf_path):
13
+ """Extrai tabelas do PDF e retorna um DataFrame processado."""
14
+ try:
15
+ # Extrair tabelas do PDF usando o método 'lattice'
16
+ tables = camelot.read_pdf(pdf_path, pages='all', flavor='lattice')
17
+ print(f"Tabelas extraídas: {len(tables)}")
18
+
19
+ if len(tables) == 0:
20
+ raise ValueError("Nenhuma tabela foi extraída do PDF.")
21
+
22
+ # Processar a primeira tabela
23
+ df = tables[0].df
24
+
25
+ # Verificar se a tabela tem conteúdo
26
+ if df.empty:
27
+ raise ValueError("A tabela extraída está vazia.")
28
+
29
+ # Salvar todas as tabelas extraídas em CSV (para debug)
30
+ temp_dir = os.path.dirname(pdf_path)
31
+ for i, table in enumerate(tables):
32
+ csv_path = os.path.join(temp_dir, f'boletim_extraido_{i+1}.csv')
33
+ table.to_csv(csv_path)
34
+ print(f"Tabela {i+1} salva como CSV em {csv_path}")
35
+
36
+ return df
37
+ except Exception as e:
38
+ print(f"Erro na extração das tabelas: {str(e)}")
39
+ raise
40
 
41
  def converter_nota(valor):
42
+ """Converte valor de nota para float, tratando casos especiais."""
43
  if pd.isna(valor) or valor == '-' or valor == 'N':
44
  return 0
45
  try:
46
+ return float(valor.replace(',', '.')) # Tratar decimal com vírgula
47
  except:
48
  return 0
49
 
50
  def plotar_evolucao_bimestres(df_filtrado, temp_dir):
51
+ """Plota gráfico de evolução das notas por bimestre."""
52
  plt.figure(figsize=(12, 6))
53
 
54
  disciplinas_basicas = ['LINGUA PORTUGUESA', 'ARTE', 'LINGUA ESTRANGEIRA INGLES',
 
92
  alpha=0.8)
93
 
94
  for x, y in zip(bimestres, notas_filtradas):
95
+ plt.annotate(f"{y:.1f}", (x, y), textcoords="offset points", xytext=(0, 10), ha='center')
96
 
97
  plt.title('Evolução das Médias por Disciplina ao Longo dos Bimestres')
98
  plt.xlabel('Bimestres')
 
108
  return plot_path
109
 
110
  def plotar_graficos_destacados(df_boletim_clean, temp_dir):
111
+ """Plota gráficos de médias e frequências com destaques."""
112
  plt.figure(figsize=(12, 6))
113
 
114
  disciplinas = df_boletim_clean['Disciplina'].astype(str)
115
 
116
+ # Processar frequências (remover % e converter para número)
117
+ colunas_freq = ['%Freq B1', '%Freq B2', '%Freq B3', '%Freq B4']
118
+ freq_data = df_boletim_clean[colunas_freq].replace('%', '', regex=True)
119
+ medias_frequencia = freq_data.apply(pd.to_numeric, errors='coerce').mean(axis=1)
120
+
121
  medias_notas = df_boletim_clean[['Nota B1', 'Nota B2', 'Nota B3', 'Nota B4']].apply(pd.to_numeric, errors='coerce').mean(axis=1)
122
 
123
  cores_notas = ['red' if media < 5 else 'blue' for media in medias_notas]
 
150
  return plot_path
151
 
152
  def gerar_relatorio_pdf(df, grafico1_path, grafico2_path):
153
+ """Gera relatório PDF com os gráficos e análises."""
154
  pdf = FPDF()
155
  pdf.add_page()
156
 
 
167
  pdf.cell(0, 10, 'Avisos Importantes:', 0, 1, 'L')
168
  pdf.set_font('Arial', '', 10)
169
 
170
+ # Calcular médias
171
  medias_notas = df[['Nota B1', 'Nota B2', 'Nota B3', 'Nota B4']].apply(pd.to_numeric, errors='coerce').mean(axis=1)
172
+
173
+ # Processar frequências
174
+ colunas_freq = ['%Freq B1', '%Freq B2', '%Freq B3', '%Freq B4']
175
+ freq_data = df[colunas_freq].replace('%', '', regex=True)
176
+ medias_freq = freq_data.apply(pd.to_numeric, errors='coerce').mean(axis=1)
177
 
178
  for idx, (disciplina, media_nota, media_freq) in enumerate(zip(df['Disciplina'], medias_notas, medias_freq)):
179
  if media_nota < 5:
 
186
  pdf.output(pdf_path)
187
  return pdf_path
188
 
189
+ def processar_boletim(file):
190
+ """Função principal que processa o boletim e gera o relatório."""
191
+ temp_dir = None
192
  try:
193
+ # Verificar se o arquivo é válido
194
+ if file is None:
195
+ return None, "Nenhum arquivo foi fornecido."
196
+
197
+ # Criar diretório temporário
198
  temp_dir = tempfile.mkdtemp()
199
+ print(f"Diretório temporário criado: {temp_dir}")
200
 
201
+ # Salvar o PDF enviado
202
  temp_pdf = os.path.join(temp_dir, 'boletim.pdf')
203
  with open(temp_pdf, 'wb') as f:
204
+ f.write(file.read())
205
+ print(f"PDF salvo em: {temp_pdf}")
 
 
 
 
206
 
207
+ # Extrair tabelas do PDF
208
+ print("Iniciando extração das tabelas...")
209
+ df = extrair_tabelas_pdf(temp_pdf)
210
+ print("Tabelas extraídas com sucesso")
211
 
212
+ # Verificar se o DataFrame foi criado corretamente
213
+ if df is None or df.empty:
214
+ raise ValueError("Não foi possível extrair dados do PDF.")
 
 
215
 
216
+ # Processar notas
217
  colunas_notas = ['Nota B1', 'Nota B2', 'Nota B3', 'Nota B4']
218
  for col in colunas_notas:
219
+ if col in df.columns:
220
+ df[col] = df[col].apply(converter_nota)
221
+ print("Notas processadas")
222
 
223
+ # Gerar gráficos
224
+ print("Gerando gráficos...")
225
  grafico1_path = plotar_evolucao_bimestres(df, temp_dir)
226
  grafico2_path = plotar_graficos_destacados(df, temp_dir)
227
+ print("Gráficos gerados")
228
 
229
+ # Gerar PDF
230
+ print("Gerando relatório PDF...")
231
  pdf_path = gerar_relatorio_pdf(df, grafico1_path, grafico2_path)
232
+ print("Relatório PDF gerado")
233
 
234
+ # Ler PDF gerado
235
  with open(pdf_path, 'rb') as f:
236
  pdf_content = f.read()
237
 
 
 
 
 
 
 
238
  return pdf_content, "Relatório gerado com sucesso!"
239
 
240
  except Exception as e:
241
+ print(f"Erro durante o processamento: {str(e)}")
 
 
 
242
  return None, f"Erro ao processar o boletim: {str(e)}"
243
+
244
+ finally:
245
+ # Limpar arquivos temporários
246
+ if temp_dir and os.path.exists(temp_dir):
247
+ try:
248
+ for file in os.listdir(temp_dir):
249
+ os.remove(os.path.join(temp_dir, file))
250
+ os.rmdir(temp_dir)
251
+ print("Arquivos temporários limpos")
252
+ except Exception as e:
253
+ print(f"Erro ao limpar arquivos temporários: {str(e)}")
254
 
255
+ # Interface Gradio
256
  iface = gr.Interface(
257
  fn=processar_boletim,
258
  inputs=gr.File(label="Upload do Boletim (PDF)"),