course_analysis.py 13.8 KB
Newer Older
Odair M.'s avatar
Odair M. committed
1
# -*- coding: utf-8 -*-
2
from datetime import datetime
3 4

import ujson as json
Odair M.'s avatar
Odair M. committed
5
import numpy as np
Odair M.'s avatar
Odair M. committed
6
from utils.situations import Situation as sit
7

Odair M.'s avatar
Odair M. committed
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
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




Odair M.'s avatar
Odair M. committed
33 34
def informacoes_gerais(df,lista_disciplinas):
    #quantidade de matriculas
35
    disciplinas = df.groupby(["COD_ATIV_CURRIC"]).size()  
Odair M.'s avatar
Odair M. committed
36
    for disciplina in disciplinas.index:
Odair M.'s avatar
Odair M. committed
37 38
        disciplina_dict = {} 
        disciplina_df = df.loc[df.COD_ATIV_CURRIC == disciplina] 
39 40 41
        disciplina_dict["qtd_alunos"] = int(disciplinas[disciplina])   
        disciplina_dict["disciplina_codigo"] = disciplina 
        disciplina_dict["disciplina_nome"] = \
Odair M.'s avatar
Odair M. committed
42
        disciplina_df.NOME_ATIV_CURRIC.values[0]    
43 44
        lista_disciplinas[disciplina] = disciplina_dict

Odair M.'s avatar
Odair M. committed
45 46
def conhecimento(qtd,disciplina_dict):
    conheci_df = qtd.loc[(qtd.SITUACAO == sit.SIT_CONHECIMENTO_APROVADO) |
Odair M.'s avatar
Odair M. committed
47 48
            (qtd.SITUACAO == sit.SIT_CONHECIMENTO_REPROVADO)] 
    total_conheci = conheci_df.qtd.sum() 
Odair M.'s avatar
Odair M. committed
49 50 51
    if np.isnan(total_conheci):
        total_conheci = 0
    conheci_aprov = conheci_df.loc[conheci_df.SITUACAO == \
52 53
            sit.SIT_CONHECIMENTO_APROVADO].set_index("COD_ATIV_CURRIC" ) 
    disciplina_dict["qtd_conhecimento"] = int(total_conheci)
Odair M.'s avatar
Odair M. committed
54 55

    if (total_conheci !=0) and (not conheci_aprov.empty):
56 57
        disciplina_dict["taxa_conhecimento"] = float(conheci_aprov.qtd.values[0] /
                total_conheci)
Odair M.'s avatar
Odair M. committed
58
    else:
59
        disciplina_dict["taxa_conhecimento"] = 0.0
Odair M.'s avatar
Odair M. committed
60 61

def trancamento(qtd,disciplina_dict,qtd_matr):
Odair M.'s avatar
Odair M. committed
62 63 64 65
    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() 
Odair M.'s avatar
Odair M. committed
66 67
    if np.isnan(qtd_tranc):
        qtd_tranc = 0
68 69
    disciplina_dict["qtd_trancamento"] = int(qtd_tranc) 
    disciplina_dict["taxa_trancamento"] = float(qtd_tranc / qtd_matr) if qtd_matr else 0.0
Odair M.'s avatar
Odair M. committed
70

Odair M.'s avatar
Odair M. committed
71 72
 
def reprovacao(qtd,disciplina,qtd_matr,taxa_reprov_absoluta,taxa_reprov_freq): 
73
    """existem as analises reprovacao absoluta, reprovacao por frequencia,  
Odair M.'s avatar
Odair M. committed
74
    reprovacao absoluta, reprovacao por frequencia da ultima vez que a
75 76
    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
77
    o mesmo codigo para fazer analise geral e da ultima vez que foi ofertado.""" 
Odair M.'s avatar
Odair M. committed
78 79 80 81 82 83
    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
Odair M.'s avatar
Odair M. committed
84
    qtd_reprov_freq = reprov_df.loc[reprov_df.SITUACAO == sit_reprov[1]] 
Odair M.'s avatar
Odair M. committed
85
    if qtd_matr != 0:
86 87 88 89 90 91 92 93 94 95
        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)

Odair M.'s avatar
Odair M. committed
96 97
    else:
        disciplina[taxa_reprov_absoluta] = 0.0
Odair M.'s avatar
Odair M. committed
98
        disciplina[taxa_reprov_freq] = 0.0 
Odair M.'s avatar
Odair M. committed
99

Odair M.'s avatar
Odair M. committed
100
def nota(notas_df,disciplina,index):
101 102
    notas = [] 
    for i in notas_df.iterrows():
103
        if i[1].SITUACAO in sit.SITUATION_AFFECT_IRA:
104 105 106
            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 
107
            notas.append(nota) 
108

109 110 111 112 113 114 115 116 117
    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]  
118 119


Odair M.'s avatar
Odair M. committed
120
def analises_gerais(df,lista_disciplinas):
121
    qtd_geral= df.groupby(["COD_ATIV_CURRIC","SITUACAO"]).size().reset_index(name="qtd" ) 
Odair M.'s avatar
Odair M. committed
122
    qtd_ultimo_geral = \
123
    df.groupby(["COD_ATIV_CURRIC","SITUACAO","ANO"]).size().reset_index(name="qtd")  
Odair M.'s avatar
Odair M. committed
124
    matr_por_semestre = \
125 126 127 128
    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
129
    que se use um apply sobre o groupby, pois se não o grouby é tratado como
130 131 132 133 134
    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" )  
Odair M.'s avatar
Odair M. committed
135
    for disciplina in lista_disciplinas.keys():
136 137
        disciplina_dict = {} #facilitar os calculos 

Odair M.'s avatar
Odair M. committed
138
        qtd  = qtd_geral.loc[qtd_geral.COD_ATIV_CURRIC == disciplina] 
139

Odair M.'s avatar
Odair M. committed
140 141
        disciplina_semestral = qtd_ultimo_geral.loc[qtd_ultimo_geral.COD_ATIV_CURRIC == \
                disciplina] 
142

143
        ano = datetime.now().year - 1
144

145
        qtd_ultimo = disciplina_semestral.loc[disciplina_semestral.ANO == ano] 
146 147


Odair M.'s avatar
Odair M. committed
148
        #quantidade de alunos
149
        qtd_matriculas = lista_disciplinas[disciplina]["qtd_alunos"]  
150 151 152


        #qtd é um dataframe que contem a ocorrencia de cada situacao
Odair M.'s avatar
Odair M. committed
153
        qtd  = qtd_geral.loc[qtd_geral.COD_ATIV_CURRIC == disciplina] 
154

Odair M.'s avatar
Odair M. committed
155
        #faz analises relacionada ao conhecimento
Odair M.'s avatar
Odair M. committed
156
        conhecimento(qtd,disciplina_dict) 
157

Odair M.'s avatar
Odair M. committed
158
        # faz analises relacionada ao trancamento
Odair M.'s avatar
Odair M. committed
159
        trancamento(qtd,disciplina_dict,qtd_matriculas) 
160

Odair M.'s avatar
Odair M. committed
161
        # faz analises relacionada a reprovacoes
162 163 164 165 166 167 168
        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  
169
        else:
170 171
            reprovacao(qtd_ultimo,disciplina_dict,qtd_matriculas,"taxa_reprovacao_ultimo_absoluta",
                    "taxa_reprovacao_ultimo_frequencia") 
Odair M.'s avatar
Odair M. committed
172

173 174 175
        #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] 
176
        nota_ultimo = nota_por_semestre_df.loc[nota_por_semestre_df.ANO ==
177 178
                ano] 

179
        nota(nota_df,disciplina_dict,"nota") 
180
        if nota_ultimo.empty:
181 182
            disciplina_dict["nota_ultimo_ano"] = -1 
        nota(nota_ultimo,disciplina_dict,"nota_ultimo_ano") 
183 184 185


        lista_disciplinas[disciplina].update(disciplina_dict)
186
#   *cursada ate a aprovacao
Odair M.'s avatar
Odair M. committed
187
def analises_semestrais(df,lista_disciplinas):
188
    # [ ] -> nota media de aprovaçao 
Odair M.'s avatar
Odair M. committed
189
    geral_df = \
190 191 192
    df.groupby(["COD_ATIV_CURRIC","ANO","PERIODO"]).size().reset_index(name
            = "matr" ) 
    df_semestral = df.groupby(["COD_ATIV_CURRIC", "ANO", "PERIODO" ,
193
       "SITUACAO"]).size().reset_index(name = "qtds" ) 
194
    disciplinas = {} 
195 196
    for i in df_semestral.iterrows(): # percorre o dataframe
        disciplina = i[1].COD_ATIV_CURRIC #nome da disciplina
197 198
        if not(disciplina in disciplinas):
            disciplinas[disciplina] = {} 
199 200

        # para chave do dicionario ser do formato ano/periodo
201 202
        ano = str(int(i[1].ANO)) 
        periodo = str(i[1].PERIODO)   
203 204
        periodo_curso = ano+"/"+periodo # chave do dicionario

205
        situacao = i[1].SITUACAO 
206
        #verifica se a chave ano/periodo exitste no dicionario
207
        if not(periodo_curso in disciplinas[disciplina] ): 
208 209 210 211 212 213 214 215 216 217
            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

218 219
    for disciplina in disciplinas.keys(): 
        for ano_periodo in disciplinas[disciplina].keys():  
220 221 222 223 224
            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
225 226
            else:
                disciplinas[disciplina][ano_periodo][0] = 0.0
227
                
228
        aprovacao_semestral = disciplinas[disciplina]   
229 230 231 232 233 234
        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))
Odair M.'s avatar
Odair M. committed
235
def listagem_disciplina(df,lista_disciplinas):
236 237
    listagem = {} 
    compara_aprov = {} 
Odair M.'s avatar
Odair M. committed
238 239
    compara_nota = {} 
    cache = {} 
240 241
    disciplinas = {} 
    # nota media de todas as disciplinas
Odair M.'s avatar
Odair M. committed
242 243 244 245
    trancamento = []
    reprovacao = []
    conhecimento = []
    nota= [] # lista que contem todas as notas medias de todas as disciplinas
246
    nota_desvio = [] # lista que contem todos os desvio padrao de todas as disciplinas 
Odair M.'s avatar
Odair M. committed
247
    grafico(df,lista_disciplinas) 
248

249 250 251 252
    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"],
Odair M.'s avatar
Odair M. committed
253 254
                "taxa_reprovacao_frequencia":disciplina_dict["taxa_reprovacao_frequencia"],
                "taxa_trancamento":disciplina_dict["taxa_trancamento"] }  
255
        compara_disciplina = [] 
Odair M.'s avatar
Odair M. committed
256
        compara_nota[disciplina]= lista_disciplinas[disciplina]["compara_nota"]  
257
        #calcula aprovacao semestral
258 259 260
        for ano in disciplina_dict["aprovacao_semestral"].keys():  
            aprov_por_ano = [ano,disciplina_dict["aprovacao_semestral"][ano][0]] 
            compara_disciplina.append(aprov_por_ano) 
261

262 263
        compara_aprov[disciplina] = compara_disciplina 
        disciplinas[disciplina] = disciplina_dict["disciplina_nome"]  
264

Odair M.'s avatar
Odair M. committed
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
        # 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) 

289 290
    #verifica se o resultado final não é nan

291 292
    listagem = { "cache" : cache,
            "compara_aprov":  compara_aprov,
Odair M.'s avatar
Odair M. committed
293
            "compara_nota": compara_nota, 
294
            "disciplinas": disciplinas,
Odair M.'s avatar
Odair M. committed
295 296 297 298
            "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)] 
299
            } 
300 301
    with open("cache/disciplinas.json",'w') as f:
        f.write(json.dumps(listagem,indent=4)) 
302 303
 # [ ] ->media_disc
 # [ ] compara_aprov 
304

Odair M.'s avatar
Odair M. committed
305
def analises_disciplinas(df):
Odair M.'s avatar
Odair M. committed
306
    lista_disciplinas = {}
Odair M.'s avatar
Odair M. committed
307 308 309
    informacoes_gerais(df,lista_disciplinas) 
    analises_gerais(df,lista_disciplinas) 
    analises_semestrais(df,lista_disciplinas) 
310
    transforma_json(lista_disciplinas) 
Odair M.'s avatar
Odair M. committed
311
    listagem_disciplina(df,lista_disciplinas)