Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -6,6 +6,8 @@ import numpy as np
|
|
6 |
from fpdf import FPDF
|
7 |
import tempfile
|
8 |
import os
|
|
|
|
|
9 |
|
10 |
def converter_nota(valor):
|
11 |
if pd.isna(valor) or valor == '-' or valor == 'N':
|
@@ -69,13 +71,14 @@ def plotar_evolucao_bimestres(df_filtrado, temp_dir):
|
|
69 |
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
|
70 |
plt.tight_layout()
|
71 |
|
72 |
-
# Salvar o gráfico
|
73 |
plot_path = os.path.join(temp_dir, 'evolucao_notas.png')
|
74 |
plt.savefig(plot_path, bbox_inches='tight', dpi=300)
|
75 |
plt.close()
|
76 |
return plot_path
|
77 |
|
78 |
def plotar_graficos_destacados(df_boletim_clean, temp_dir):
|
|
|
|
|
79 |
disciplinas = df_boletim_clean['Disciplina'].astype(str)
|
80 |
|
81 |
medias_frequencia = df_boletim_clean[['Freq B1', 'Freq B2', 'Freq B3', 'Freq B4']].apply(pd.to_numeric, errors='coerce').mean(axis=1)
|
@@ -86,8 +89,6 @@ def plotar_graficos_destacados(df_boletim_clean, temp_dir):
|
|
86 |
|
87 |
frequencia_global_media = medias_frequencia.mean()
|
88 |
|
89 |
-
plt.figure(figsize=(12, 6))
|
90 |
-
|
91 |
plt.subplot(1, 2, 1)
|
92 |
plt.bar(disciplinas, medias_notas, color=cores_notas)
|
93 |
plt.title('Média de Notas por Disciplina (Vermelho: < 5)')
|
@@ -107,7 +108,6 @@ def plotar_graficos_destacados(df_boletim_clean, temp_dir):
|
|
107 |
|
108 |
plt.tight_layout()
|
109 |
|
110 |
-
# Salvar o gráfico
|
111 |
plot_path = os.path.join(temp_dir, 'medias_frequencias.png')
|
112 |
plt.savefig(plot_path, bbox_inches='tight', dpi=300)
|
113 |
plt.close()
|
@@ -117,18 +117,15 @@ def gerar_relatorio_pdf(df, grafico1_path, grafico2_path):
|
|
117 |
pdf = FPDF()
|
118 |
pdf.add_page()
|
119 |
|
120 |
-
# Título
|
121 |
pdf.set_font('Arial', 'B', 16)
|
122 |
pdf.cell(0, 10, 'Relatório de Desempenho Escolar', 0, 1, 'C')
|
123 |
pdf.ln(10)
|
124 |
|
125 |
-
# Adicionar gráficos
|
126 |
pdf.image(grafico1_path, x=10, w=190)
|
127 |
pdf.ln(10)
|
128 |
pdf.image(grafico2_path, x=10, w=190)
|
129 |
pdf.ln(10)
|
130 |
|
131 |
-
# Adicionar avisos
|
132 |
pdf.set_font('Arial', 'B', 12)
|
133 |
pdf.cell(0, 10, 'Avisos Importantes:', 0, 1, 'L')
|
134 |
pdf.set_font('Arial', '', 10)
|
@@ -142,7 +139,6 @@ def gerar_relatorio_pdf(df, grafico1_path, grafico2_path):
|
|
142 |
if media_freq < 75:
|
143 |
pdf.cell(0, 10, f'- {disciplina}: Frequência abaixo de 75% ({media_freq:.1f}%)', 0, 1, 'L')
|
144 |
|
145 |
-
# Salvar PDF em um arquivo temporário
|
146 |
temp_pdf = tempfile.NamedTemporaryFile(delete=False, suffix='.pdf')
|
147 |
pdf_path = temp_pdf.name
|
148 |
pdf.output(pdf_path)
|
@@ -150,54 +146,53 @@ def gerar_relatorio_pdf(df, grafico1_path, grafico2_path):
|
|
150 |
|
151 |
def processar_boletim(pdf_file):
|
152 |
try:
|
153 |
-
# Criar diretório temporário
|
154 |
temp_dir = tempfile.mkdtemp()
|
155 |
|
156 |
-
#
|
157 |
temp_pdf = os.path.join(temp_dir, 'boletim.pdf')
|
158 |
with open(temp_pdf, 'wb') as f:
|
159 |
-
f.write(pdf_file)
|
160 |
|
161 |
-
# Extrair tabelas do PDF
|
162 |
tables = camelot.read_pdf(temp_pdf, pages='all', flavor='lattice')
|
163 |
|
164 |
if len(tables) == 0:
|
165 |
return None, "Nenhuma tabela encontrada no PDF."
|
166 |
|
167 |
-
# Processar primeira tabela
|
168 |
df = tables[0].df
|
169 |
|
170 |
-
# Renomear colunas
|
171 |
df.columns = ['Disciplina', 'Nota B1', 'Freq B1', '%Freq B1', 'AC B1',
|
172 |
'Nota B2', 'Freq B2', '%Freq B2', 'AC B2',
|
173 |
'Nota B3', 'Freq B3', '%Freq B3', 'AC B3',
|
174 |
'Nota B4', 'Freq B4', '%Freq B4', 'AC B4',
|
175 |
'CF', 'Nota Final', 'Freq Final', 'AC Final']
|
176 |
|
177 |
-
# Converter notas
|
178 |
colunas_notas = ['Nota B1', 'Nota B2', 'Nota B3', 'Nota B4']
|
179 |
for col in colunas_notas:
|
180 |
df[col] = df[col].apply(converter_nota)
|
181 |
|
182 |
-
# Gerar gráficos
|
183 |
grafico1_path = plotar_evolucao_bimestres(df, temp_dir)
|
184 |
grafico2_path = plotar_graficos_destacados(df, temp_dir)
|
185 |
|
186 |
-
# Gerar PDF com o relatório
|
187 |
pdf_path = gerar_relatorio_pdf(df, grafico1_path, grafico2_path)
|
188 |
|
189 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
190 |
|
191 |
except Exception as e:
|
192 |
-
return None, f"Erro ao processar o boletim: {str(e)}"
|
193 |
-
finally:
|
194 |
-
# Limpar arquivos temporários
|
195 |
if 'temp_dir' in locals():
|
196 |
for file in os.listdir(temp_dir):
|
197 |
os.remove(os.path.join(temp_dir, file))
|
198 |
os.rmdir(temp_dir)
|
|
|
199 |
|
200 |
-
# Interface Gradio
|
201 |
iface = gr.Interface(
|
202 |
fn=processar_boletim,
|
203 |
inputs=gr.File(label="Upload do Boletim (PDF)"),
|
|
|
6 |
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':
|
|
|
71 |
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
|
72 |
plt.tight_layout()
|
73 |
|
|
|
74 |
plot_path = os.path.join(temp_dir, 'evolucao_notas.png')
|
75 |
plt.savefig(plot_path, bbox_inches='tight', dpi=300)
|
76 |
plt.close()
|
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)
|
|
|
89 |
|
90 |
frequencia_global_media = medias_frequencia.mean()
|
91 |
|
|
|
|
|
92 |
plt.subplot(1, 2, 1)
|
93 |
plt.bar(disciplinas, medias_notas, color=cores_notas)
|
94 |
plt.title('Média de Notas por Disciplina (Vermelho: < 5)')
|
|
|
108 |
|
109 |
plt.tight_layout()
|
110 |
|
|
|
111 |
plot_path = os.path.join(temp_dir, 'medias_frequencias.png')
|
112 |
plt.savefig(plot_path, bbox_inches='tight', dpi=300)
|
113 |
plt.close()
|
|
|
117 |
pdf = FPDF()
|
118 |
pdf.add_page()
|
119 |
|
|
|
120 |
pdf.set_font('Arial', 'B', 16)
|
121 |
pdf.cell(0, 10, 'Relatório de Desempenho Escolar', 0, 1, 'C')
|
122 |
pdf.ln(10)
|
123 |
|
|
|
124 |
pdf.image(grafico1_path, x=10, w=190)
|
125 |
pdf.ln(10)
|
126 |
pdf.image(grafico2_path, x=10, w=190)
|
127 |
pdf.ln(10)
|
128 |
|
|
|
129 |
pdf.set_font('Arial', 'B', 12)
|
130 |
pdf.cell(0, 10, 'Avisos Importantes:', 0, 1, 'L')
|
131 |
pdf.set_font('Arial', '', 10)
|
|
|
139 |
if media_freq < 75:
|
140 |
pdf.cell(0, 10, f'- {disciplina}: Frequência abaixo de 75% ({media_freq:.1f}%)', 0, 1, 'L')
|
141 |
|
|
|
142 |
temp_pdf = tempfile.NamedTemporaryFile(delete=False, suffix='.pdf')
|
143 |
pdf_path = temp_pdf.name
|
144 |
pdf.output(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)"),
|