diff --git a/script/analysis/course_analysis.py b/script/analysis/course_analysis.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..63c27a7cce58ffa89de30ee373e86a1de363890d 100644 --- a/script/analysis/course_analysis.py +++ b/script/analysis/course_analysis.py @@ -0,0 +1,310 @@ +# -*- coding: utf-8 -*- +from datetime import datetime +import pprint +import pandas as pd +import json +import numpy as np +from utils.situations import Situation as sit +def grafico(df,lista_disciplinas): + for disciplina in lista_disciplinas.keys() : + qtd_aluno = lista_disciplinas[disciplina]["qtd_alunos"] + dic = {"00-4.9":0.0 , "05-9.9":0.0 , "10-14.9":0.0 , "15-19.9":0.0 , "20-24.9":0.0 , "25-29.9":0.0 , "30-34.9":0.0 , + "35-39.9":0.0 , "40-44.9":0.0 , "45-49.9":0.0 , "50-54.9":0.0 , "55-59.9":0.0 , "60-64.9":0.0 , "65-69.9":0.0 , + "70-74.9":0.0 , "75-79.9":0.0 , "80-84.9":0.0 , "85-89.9":0.0 , "90-94.9":0.0 ,"95-100": 0.0} + disciplina_df = df.loc[df.COD_ATIV_CURRIC == disciplina] + disci_lista = [] + for i in disciplina_df.iterrows(): + nota = 0.0 if i[1].MEDIA_FINAL > 100 else i[1].MEDIA_FINAL + for key in dic.keys(): + a = key.split('-') + value_min = float(a[0]) + value_max = float(a[1]) + if((nota >= value_min) and (nota <= value_max)): + dic[key] += float(nota) + break; + for j in dic.keys(): + disci_lista.append([j, 0.0 if qtd_aluno == 0 else dic[j] / qtd_aluno]) + + lista_disciplinas[disciplina]["compara_nota"] = disci_lista + + + + +def informacoes_gerais(df,lista_disciplinas): + #quantidade de matriculas + disciplinas = df.groupby(["COD_ATIV_CURRIC"]).size() + for disciplina in disciplinas.index: + disciplina_dict = {} + disciplina_df = df.loc[df.COD_ATIV_CURRIC == disciplina] + disciplina_dict["qtd_alunos"] = int(disciplinas[disciplina]) + disciplina_dict["disciplina_codigo"] = disciplina + disciplina_dict["disciplina_nome"] = \ + disciplina_df.NOME_ATIV_CURRIC.values[0] + lista_disciplinas[disciplina] = disciplina_dict +def conhecimento(qtd,disciplina_dict): + conheci_df = qtd.loc[(qtd.SITUACAO == sit.SIT_CONHECIMENTO_APROVADO) | + (qtd.SITUACAO == sit.SIT_CONHECIMENTO_REPROVADO)] + total_conheci = conheci_df.qtd.sum() + if np.isnan(total_conheci): + total_conheci = 0 + conheci_aprov = conheci_df.loc[conheci_df.SITUACAO == \ + sit.SIT_CONHECIMENTO_APROVADO].set_index("COD_ATIV_CURRIC" ) + disciplina_dict["qtd_conhecimento"] = int(total_conheci) + + if (total_conheci !=0) and (not conheci_aprov.empty): + disciplina_dict["taxa_conhecimento"] = float(conheci_aprov.qtd.values[0] / + total_conheci) + else: + disciplina_dict["taxa_conhecimento"] = 0.0 + +def trancamento(qtd,disciplina_dict,qtd_matr): + trancamento_df = qtd.loc[(qtd.SITUACAO == sit.SIT_TRANCAMENTO_ADMINISTRATIVO) | + (qtd.SITUACAO == sit.SIT_TRANCAMENTO_TOTAL) | + (qtd.SITUACAO == sit.SIT_CANCELADO)] + qtd_tranc = trancamento_df.qtd.sum() + if np.isnan(qtd_tranc): + qtd_tranc = 0 + disciplina_dict["qtd_trancamento"] = int(qtd_tranc) + disciplina_dict["taxa_trancamento"] = float(qtd_tranc / qtd_matr) if qtd_matr else 0.0 + + +def reprovacao(qtd,disciplina,qtd_matr,taxa_reprov_absoluta,taxa_reprov_freq): + """existem as analises reprovacao absoluta, reprovacao por frequencia, + reprovacao absoluta, reprovacao por frequencia da ultima vez que a + disciplina foi ofertada, a logica das analise sao a mesma so muda os valores + do dataframe qtd e o nomes das chaves do dicionario,logo é possÃvel reaproveitar + o mesmo codigo para fazer analise geral e da ultima vez que foi ofertado.""" + sit_reprov = sit.SITUATION_FAIL + (sit.SIT_REPROVADO_SEM_NOTA,) + reprov_df = qtd.loc[(qtd.SITUACAO == sit_reprov[0]) | + (qtd.SITUACAO == sit_reprov[1]) | + (qtd.SITUACAO == sit_reprov[2]) | + (qtd.SITUACAO == sit_reprov[3]) ] + qtd_reprov_abso = reprov_df.qtd.sum() #quantidade de reprovacao absoluta + qtd_reprov_freq = reprov_df.loc[reprov_df.SITUACAO == sit_reprov[1]] + if qtd_matr != 0: + if np.isnan(qtd_reprov_abso): + disciplina[taxa_reprov_absoluta] = 0.0 + else: + disciplina[taxa_reprov_absoluta] = float(qtd_reprov_abso / qtd_matr) + + if qtd_reprov_freq.empty: + disciplina[taxa_reprov_freq] = 0.0 + else: + disciplina[taxa_reprov_freq] = float(qtd_reprov_freq.qtd.values[0] / qtd_matr) + + else: + disciplina[taxa_reprov_absoluta] = 0.0 + disciplina[taxa_reprov_freq] = 0.0 + +def nota(notas_df,disciplina,index): + notas = [] + for i in notas_df.iterrows(): + if i[1].SITUACAO in sit.SITUATION_AFFECT_IRA: + nota = 0 if np.isnan(i[1].MEDIA_FINAL) else i[1].MEDIA_FINAL + #alguns valores de media_final não são confiaveis na tabela .33 + nota = 0 if nota > 100 else nota + notas.append(nota) + + if len(notas) != 0: + notas_np = np.array(notas) + media_np = np.mean(notas_np) + desvio_np = np.std(notas_np) + media = 0.0 if np.isnan(media_np) else media_np + desvio = 0.0 if np.isnan(desvio_np) else desvio_np + disciplina[index] = [media,desvio] + else: + disciplina[index] = [0.0,0.0] + + +def analises_gerais(df,lista_disciplinas): + qtd_geral= df.groupby(["COD_ATIV_CURRIC","SITUACAO"]).size().reset_index(name="qtd" ) + qtd_ultimo_geral = \ + df.groupby(["COD_ATIV_CURRIC","SITUACAO","ANO"]).size().reset_index(name="qtd") + matr_por_semestre = \ + df.groupby(["COD_ATIV_CURRIC","ANO"]).size().reset_index(name="matr") + """ dataframe com a quantidade de matriculas por periodo e ano, por exemplo + disciplina ci055 2010/1 teve x matriculas""" + """Dataframes relacionado a notas.O campo qtd é inutil, o groupby pede se + que se use um apply sobre o groupby, pois se não o grouby é tratado como + objeto e não como um dataframe """ + nota_geral_df = df.groupby(["COD_ATIV_CURRIC","MEDIA_FINAL", "SITUACAO", + ]).size().reset_index(name = "qtd" ) + nota_semestral_df = df.groupby(["COD_ATIV_CURRIC","ANO", "MEDIA_FINAL", "SITUACAO", + ]).size().reset_index(name = "qtd" ) + for disciplina in lista_disciplinas.keys(): + disciplina_dict = {} #facilitar os calculos + + qtd = qtd_geral.loc[qtd_geral.COD_ATIV_CURRIC == disciplina] + + disciplina_semestral = qtd_ultimo_geral.loc[qtd_ultimo_geral.COD_ATIV_CURRIC == \ + disciplina] + + ano = datetime.now().year - 1 + + qtd_ultimo = disciplina_semestral.loc[disciplina_semestral.ANO == ano] + + + #quantidade de alunos + qtd_matriculas = lista_disciplinas[disciplina]["qtd_alunos"] + + + #qtd é um dataframe que contem a ocorrencia de cada situacao + qtd = qtd_geral.loc[qtd_geral.COD_ATIV_CURRIC == disciplina] + + #faz analises relacionada ao conhecimento + conhecimento(qtd,disciplina_dict) + + # faz analises relacionada ao trancamento + trancamento(qtd,disciplina_dict,qtd_matriculas) + + # faz analises relacionada a reprovacoes + reprovacao(qtd,disciplina_dict,qtd_matriculas,"taxa_reprovacao_absoluta","taxa_reprovacao_frequencia") + qtd_matr_ultimo = matr_por_semestre.loc[(matr_por_semestre.COD_ATIV_CURRIC \ + == disciplina) & matr_por_semestre.ANO == ano] + + if qtd_matr_ultimo.empty: #caso a disciplina nao foi ofertada no ultimo ano + disciplina_dict["taxa_reprovacao_ultimo_absoluta"] = -1 + disciplina_dict["taxa_reprovacao_ultimo_frequencia"] = -1 + else: + reprovacao(qtd_ultimo,disciplina_dict,qtd_matriculas,"taxa_reprovacao_ultimo_absoluta", + "taxa_reprovacao_ultimo_frequencia") + + #faz as analises relacionada a nota + nota_df = nota_geral_df.loc[nota_geral_df.COD_ATIV_CURRIC == disciplina] + nota_por_semestre_df = nota_semestral_df.loc[nota_semestral_df.COD_ATIV_CURRIC == disciplina] + nota_ultimo = nota_por_semestre_df.loc[nota_por_semestre_df.ANO == + ano] + + nota(nota_df,disciplina_dict,"nota") + if nota_ultimo.empty: + disciplina_dict["nota_ultimo_ano"] = -1 + nota(nota_ultimo,disciplina_dict,"nota_ultimo_ano") + + + lista_disciplinas[disciplina].update(disciplina_dict) +# *cursada ate a aprovacao +def analises_semestrais(df,lista_disciplinas): + # [ ] -> nota media de aprovaçao + geral_df = \ + df.groupby(["COD_ATIV_CURRIC","ANO","PERIODO"]).size().reset_index(name + = "matr" ) + df_semestral = df.groupby(["COD_ATIV_CURRIC", "ANO", "PERIODO" , + "SITUACAO"]).size().reset_index(name = "qtds" ) + disciplinas = {} + for i in df_semestral.iterrows(): # percorre o dataframe + disciplina = i[1].COD_ATIV_CURRIC #nome da disciplina + if not(disciplina in disciplinas): + disciplinas[disciplina] = {} + + # para chave do dicionario ser do formato ano/periodo + ano = str(int(i[1].ANO)) + periodo = str(i[1].PERIODO) + periodo_curso = ano+"/"+periodo # chave do dicionario + + situacao = i[1].SITUACAO + #verifica se a chave ano/periodo exitste no dicionario + if not(periodo_curso in disciplinas[disciplina] ): + disciplinas[disciplina][periodo_curso] = [0,0] #qtd aprovado,total + + # se a situacao for igual a aprovado entao qtd de aprovados em + # ano/periodo +1 + if situacao in sit.SITUATION_PASS: + disciplinas[disciplina][periodo_curso][0] += 1 # qtd de aprovados + + #quantidade total de matriculas no periodo ano/periodo + disciplinas[disciplina][periodo_curso][1] += 1 + + for disciplina in disciplinas.keys(): + for ano_periodo in disciplinas[disciplina].keys(): + qtd_total = disciplinas[disciplina][ano_periodo][1] + qtd_aprovados = disciplinas[disciplina][ano_periodo][0] + #calcula a taxa de aprovacao por semestre, qtd_aprov/qtd_total + if qtd_total != 0: + disciplinas[disciplina][ano_periodo][0] = qtd_aprovados / qtd_total + else: + disciplinas[disciplina][ano_periodo][0] = 0.0 + + aprovacao_semestral = disciplinas[disciplina] + lista_disciplinas[disciplina]["aprovacao_semestral"] = aprovacao_semestral +def transforma_json(lista_disciplinas): + for disciplina in lista_disciplinas.keys(): + disciplina_dict =lista_disciplinas[disciplina] + with open('cache/'+disciplina+'.json','w') as f: + f.write(json.dumps(lista_disciplinas[disciplina],indent=4)) +def listagem_disciplina(df,lista_disciplinas): + listagem = {} + compara_aprov = {} + compara_nota = {} + cache = {} + disciplinas = {} + # nota media de todas as disciplinas + trancamento = [] + reprovacao = [] + conhecimento = [] + nota= [] # lista que contem todas as notas medias de todas as disciplinas + nota_desvio = [] # lista que contem todos os desvio padrao de todas as disciplinas + grafico(df,lista_disciplinas) + + for disciplina in lista_disciplinas.keys(): + disciplina_dict = lista_disciplinas[disciplina] + cache[disciplina] = {"nota":disciplina_dict["nota"], + "taxa_reprovacao_absoluta":disciplina_dict["taxa_reprovacao_absoluta"], + "taxa_reprovacao_frequencia":disciplina_dict["taxa_reprovacao_frequencia"], + "taxa_trancamento":disciplina_dict["taxa_trancamento"] } + compara_disciplina = [] + compara_nota[disciplina]= lista_disciplinas[disciplina]["compara_nota"] + #calcula aprovacao semestral + for ano in disciplina_dict["aprovacao_semestral"].keys(): + aprov_por_ano = [ano,disciplina_dict["aprovacao_semestral"][ano][0]] + compara_disciplina.append(aprov_por_ano) + + compara_aprov[disciplina] = compara_disciplina + disciplinas[disciplina] = disciplina_dict["disciplina_nome"] + + # pega todas as taxas adiciona em uma lista, que depois será tranformada + # em numpy array para poder uutilizar os metodos np.mean e np.std + conhecimento.append(disciplina_dict["taxa_conhecimento"]) + trancamento.append(disciplina_dict["taxa_trancamento" ]) + reprovacao.append(disciplina_dict["taxa_reprovacao_absoluta" ]) + nota.append(disciplina_dict["nota"][0]) + + #nota + nota_np = np.array(nota) + nota_media= np.mean(nota_np) + nota_desvio= np.std(nota_np) + #trancamento + trancamento_np = np.array(trancamento) + trancamento_media = np.mean(trancamento_np) + trancamento_desvio = np.std(trancamento_np) + #conhecimento + conhecimento_np = np.array(trancamento) + conhecimento_media = np.mean(trancamento_np) + conhecimento_desvio = np.std(trancamento_np) + #reprovacao + reprovacao_np = np.array(trancamento) + reprovacao_media = np.mean(trancamento_np) + reprovacao_desvio = np.std(trancamento_np) + + #verifica se o resultado final não é nan + + listagem = { "cache" : cache, + "compara_aprov": compara_aprov, + "compara_nota": compara_nota, + "disciplinas": disciplinas, + "taxa_conhecimento":[float(conhecimento_media),float(conhecimento_desvio)] , + "taxa_trancamento":[float(trancamento_media),float(trancamento_desvio)] , + "taxa_reprovacao":[float(reprovacao_media),float(reprovacao_desvio)] , + "nota": [float(nota_media),float(nota_desvio)] + } + with open("cache/disciplinas.json",'w') as f: + f.write(json.dumps(listagem,indent=4)) + # [ ] ->media_disc + # [ ] compara_aprov + +def analises_disciplinas(df): + lista_disciplinas = {} + informacoes_gerais(df,lista_disciplinas) + analises_gerais(df,lista_disciplinas) + analises_semestrais(df,lista_disciplinas) + transforma_json(lista_disciplinas) + listagem_disciplina(df,lista_disciplinas) diff --git a/script/main.py b/script/main.py index 9cec7b09a78b458494d823b843b30664a92b2c40..4000d54e67cdf2ec3be08a4f8a9150a5c0539ea0 100644 --- a/script/main.py +++ b/script/main.py @@ -3,18 +3,23 @@ import time from base.dataframe_base import load_dataframes from build_cache import build_cache from datetime import timedelta +<<<<<<< HEAD from analysis.degree_analysis import * +======= +from utils.situations import * +from analysis.course_analysis import * +>>>>>>> origin/course def main(): start_time = time.clock() start_time_exec = time.time() dataframe = load_dataframes(os.getcwd() + '/' + 'base') build_cache(dataframe) - cpu_time = timedelta(seconds=round(time.clock() - start_time)) + Main(dataframe) run_time = timedelta(seconds=round(time.time() - start_time_exec)) print("--- Tempo de CPU: {} ---".format(cpu_time)) print("--- Tempo total: {} ---".format(run_time)) diff --git a/script/utils/situations.py b/script/utils/situations.py index 96ab5a0f9a2920f058b4c75b720ac2be034e78dd..d44993528dbff0fc440702eacae7b1cfc44efaf1 100644 --- a/script/utils/situations.py +++ b/script/utils/situations.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # == Admission Form == # class AdmissionType: AT_DESCONHECIDO = 0 @@ -65,6 +66,14 @@ class EvasionForm: ) # == Situation Courses == # +#note: os valores da coluna media_final não são confiavel, situation como +# reprovacao,reprovacao_freq,dispensa_com_nota aparecem em algumas linha como +# 9999, o valor 9999 é o valor definido pelo sie para ser o 'null' na tabela +# .33, na tabela .18 o 'null' é o zero e não ocorre problema de calculo de +# nota/ira +# orientaçao: verificar se media_final é maior que 100 se sim atribua 0 se nao +# atribua media_final + class Situation: SIT_DESCONHECIDA = 0