import pandas as pd
import numpy as np # Importação direta do NumPy
import matplotlib.pyplot as plt
import seaborn as sns
from urllib.request import urlopen
from urllib.parse import urlparse
import io
import csv
import logging
import os
from datetime import datetime
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
def carregar_dados(url):
ext = urlparse(url).path.split('.')[-1].lower()
conteudo = urlopen(url).read()
buffer = io.BytesIO(conteudo)
if ext == 'csv':
try:
sep = csv.Sniffer().sniff(conteudo[:1024].decode('utf-8', errors='ignore')).delimiter
except Exception:
sep = ','
try:
return pd.read_csv(buffer, sep=sep, encoding='utf-8')
except UnicodeDecodeError:
buffer.seek(0)
return pd.read_csv(buffer, sep=sep, encoding='latin1')
elif ext in ('xls', 'xlsx'):
return pd.read_excel(buffer)
elif ext == 'json':
return pd.read_json(buffer)
else:
raise ValueError(f'Extensão não suportada: .{ext}')
def criar_pasta_saida(base='output'):
path = os.path.join(base, datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
os.makedirs(path, exist_ok=True)
return path
# Carrega dados
url = 'https://raw.githubusercontent.com/alura-cursos/pandas-conhecendo-a-biblioteca/main/desafios/alunos.csv'
dados = carregar_dados(url)
if 'Notas' not in dados.columns:
raise ValueError("Coluna 'Notas' não encontrada nos dados.")
dados['Notas'] = pd.to_numeric(dados['Notas'], errors='coerce')
# Calcula atividade extra, nota final e classifica
dados['Atv_Extra'] = dados['Notas'].apply(lambda x: x*0.4 if pd.notna(x) and x < 6 else 0)
dados['Nota_Final'] = dados['Notas'] + dados['Atv_Extra']
conds = [
dados['Notas'].isna(),
(dados['Nota_Final'] >= 6) & (dados['Atv_Extra'] == 0),
(dados['Nota_Final'] >= 6) & (dados['Atv_Extra'] > 0),
(dados['Nota_Final'] < 6) & (dados['Atv_Extra'] == 0),
(dados['Nota_Final'] < 6) & (dados['Atv_Extra'] > 0),
]
valores = [
'Dados Invalidos',
'Aprovados Sem Atv_Extra',
'Aprovados Com Atv_Extra',
'Reprovados Sem Atv_Extra',
'Reprovados Com Atv_Extra',
]
dados['Classificacao'] = pd.Series(
pd.Categorical(
np.select(conds, valores, default='Dados Invalidos'),
categories=valores,
ordered=True
)
)
# Garante que Classificacao é última coluna
dados = dados[[c for c in dados.columns if c != 'Classificacao'] + ['Classificacao']]
# Resumo para gráfico
contagem = dados['Classificacao'].value_counts().reindex(valores).reset_index()
contagem.columns = ['Classificacao', 'Quantidade']
contagem['Porcentagem'] = 100 * contagem['Quantidade'] / contagem['Quantidade'].sum()
# Plot
plt.figure(figsize=(10,6))
cores = sns.color_palette('Set2', len(contagem))
bars = plt.bar(contagem['Classificacao'], contagem['Porcentagem'], color=cores)
for bar, pct, qtd in zip(bars, contagem['Porcentagem'], contagem['Quantidade']):
plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.5,
f'{pct:.1f}%\n({qtd})', ha='center', va='bottom', fontsize=10, fontweight='bold')
plt.xlabel('Classificação')
plt.ylabel('Porcentagem')
plt.title('Distribuição de alunos por classificação')
plt.xticks(rotation=45)
plt.ylim(0, contagem['Porcentagem'].max() + 10)
plt.tight_layout()
plt.show()
# Salvar arquivos
pasta_saida = criar_pasta_saida()
plt.savefig(os.path.join(pasta_saida, 'grafico.png'))
plt.close()
dados.to_csv(os.path.join(pasta_saida, 'alunos_processados.csv'), index=False)
contagem.to_csv(os.path.join(pasta_saida, 'resumo_classificacao.csv'), index=False)
# Salvar grupos
grupos = {
'aprovados_sem_atividade_extra.csv': dados[dados['Classificacao'] == 'Aprovados Sem Atv_Extra'],
'aprovados_com_atividade_extra.csv': dados[dados['Classificacao'] == 'Aprovados Com Atv_Extra'],
'reprovados_sem_atividade_extra.csv': dados[dados['Classificacao'] == 'Reprovados Sem Atv_Extra'],
'reprovados_com_atividade_extra.csv': dados[dados['Classificacao'] == 'Reprovados Com Atv_Extra'],
'dados_invalidos.csv': dados[dados['Classificacao'] == 'Dados Invalidos'],
}
for nome, df in grupos.items():
df.to_csv(os.path.join(pasta_saida, nome), index=False)
# Impressão final no console
print("\n=== Dados Processados (preview) ===")
print(dados.head(10))
print("\n=== Resumo de Classificação ===")
print(contagem)
print("\n=== Quantidade por Grupo ===")
for nome, df in grupos.items():
print(f"{nome}: {len(df)} registros")
logging.info(f'Dados processados e salvos em: {pasta_saida}')