Commit 6606a415 authored by Bruno Meyer's avatar Bruno Meyer
Browse files

#121 Cleaning up & docker container integrating postgres+django

parent f37028cd
Pipeline #15861 failed with stage
in 2 minutes and 2 seconds
FROM python:3.5
Run apt-get update -qq
Run apt-get install -y \
RUN apt-get update -qq
RUN apt-get install -y \
python3-pip libpq-dev \
postgresql-client
Run mkdir /adega
RUN mkdir /adega
WORKDIR /adega
ADD . /adega
Run pip3 install -r requirements.txt
run ./install.sh --configure
# Not necessary (only do the build slow)
# ADD . /adega
ADD requirements.txt /adega/requirements.txt
RUN pip3 install -r requirements.txt
# Not necessary. The migrate can be done by makefile or in docker-compose.yml
# Besides that, there is no database to migrate yet (while docker build)
# RUN ./install.sh --configure
The MIT License (MIT)
Copyright (c) 2016 Simple is Better Than Complex
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
......@@ -8,11 +8,7 @@ services:
- POSTGRES_DB=adega
web:
build: .
command: python3 ./src/manage.py makemigrations degree
command: python3 ./src/manage.py makemigrations uploads
command: python3 ./src/manage.py makemigrations educator
command: python3 ./src/manage.py migrate
command: python3 ./src/manage.py runserver 0.0.0.0:8000
command: bash "./docker_scripts/on_docker_init.sh"
volumes:
- .:/adega
ports:
......@@ -21,3 +17,8 @@ services:
- db
depends_on:
- db
environment:
Please register or sign in to reply
- POSTGRES_USER=adega
- POSTGRES_PASSWORD=adega
- POSTGRES_DB=adega
- POSTGRES_HOST=adega_db_1
bash ./docker_scripts/wait-for-postgres.sh
python ./src/manage.py migrate
python ./src/manage.py runserver 0.0.0.0:8000
  • @omdj17 @jcrodrigues Coloquem aqui o que quiserem que aconteça quando o container é iniciado.

    Recomendo NÃO colocar os makemigrations aqui, porque se não eventualmente pode acabar acontecendo de alterar um model sem vocês perceberem. Mas dai teria que ser pensado em uma maneira de fazer os makemigrations na primeira que rodar o docker pelo menos (não tem como fazer no build pois o DB não existe nesse momento).

Please register or sign in to reply
#!/bin/bash
# wait-for-postgres.sh
set -e
host="$1"
cmd="$@"
until PGPASSWORD=$POSTGRES_PASSWORD psql -h "$POSTGRES_HOST" -U "$POSTGRES_USER" -c '\q'; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 1
done
>&2 echo "Postgres is up"
#~ >&2 echo "Postgres is up - executing command"
#~ exec $cmd
......@@ -4,8 +4,8 @@ verbose=0
# ---------- functions ------------------
configure() {
postgres psql < postgres/create.sql
#~ postgres psql < postgres/create.sql
PGPASSWORD=adega psql -h adega_db_1 -U adega < postgres/create.sql
python3 src/manage.py makemigrations degree
python3 src/manage.py makemigrations uploads
python3 src/manage.py makemigrations educator
......
......@@ -36,3 +36,13 @@ install-user:
pipenv install
%:
@:
args = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}`
manage:
@echo $(call args,"")
sudo docker exec -it adega_web_1 python3 ./src/manage.py $(call args,"")
CREATE DATABASE adega;
CREATE USER adega WITH PASSWORD 'adega';
-- ~ CREATE USER adega WITH PASSWORD 'adega';
ALTER ROLE adega SET client_encoding TO 'utf8';
ALTER ROLE adega SET default_transaction_isolation TO 'read committed';
ALTER ROLE adega SET timezone TO 'UTC-3';
GRANT ALL PRIVILEGES ON DATABASE adega TO adega;
Please register or sign in to reply
-- ~ ALTER ROLE adega SET client_encoding TO 'utf8';
-- ~ ALTER ROLE adega SET default_transaction_isolation TO 'read committed';
-- ~ ALTER ROLE adega SET timezone TO 'UTC-3';
-- ~ GRANT ALL PRIVILEGES ON DATABASE adega TO adega;
import numpy as np
from utils.situations import *
ANO_ATUAL = 2017
SEMESTRE_ATUAL = 2
def listagem_turma_ingresso(df):
#~ print(df.groupby(["ANO_INGRESSO", "SEMESTRE_INGRESSO"]).groups)
grupos = df.groupby(["ANO_INGRESSO", "SEMESTRE_INGRESSO"]).groups
for t in grupos:
print(t)
print("\n\n")
print(df["FORMA_INGRESSO"][grupos[t]].drop_duplicates())
# -*- coding: utf-8 -*-
from datetime import datetime
import ujson as 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)
import pandas as pd
import math
import ujson as json
from utils.situations import Situation, EvasionForm
def average_graduation(df):
total_student = df['MATR_ALUNO'].drop_duplicates().shape[0]
total_graduate = df[df.FORMA_EVASAO == EvasionForm.EF_FORMATURA].shape[0]
return total_graduate / total_student
def general_failure(df):
affect_ira = df[df.SITUACAO.isin(Situation.SITUATION_AFFECT_IRA)]
failures = affect_ira[affect_ira.SITUACAO.isin(Situation.SITUATION_FAIL)]
average = failures.shape[0] / affect_ira.shape[0]
student_courses = affect_ira.groupby(['MATR_ALUNO'], as_index=False)\
.aggregate({'SITUACAO': 'count'})
student_failures = failures.groupby(['MATR_ALUNO'], as_index=False)\
.aggregate({'SITUACAO': 'count'})
merged = pd.merge(student_courses, student_failures, on=['MATR_ALUNO'])
merged.columns = ['MART_ALUNO', 'FEITAS', 'REPROVADO']
variance = merged['REPROVADO'].div(merged['FEITAS']).sub(average)\
.pow(2).sum() / merged.shape[0]
standard_deviation = math.sqrt(variance)
return (average, standard_deviation)
def current_students_failure(df):
fixed = df.loc[(df.FORMA_EVASAO == EvasionForm.EF_ATIVO)]
affect_ira = fixed[fixed.SITUACAO.isin(Situation.SITUATION_AFFECT_IRA)]
failures = affect_ira[affect_ira.SITUACAO.isin(Situation.SITUATION_FAIL)]
average = failures.shape[0] / affect_ira.shape[0]
student_courses = affect_ira.groupby(['MATR_ALUNO'], as_index=False)\
.aggregate({'SITUACAO': 'count'})
student_failures = failures.groupby(['MATR_ALUNO'], as_index=False)\
.aggregate({'SITUACAO': 'count'})
merged = pd.merge(student_courses, student_failures, on=['MATR_ALUNO'])
merged.columns = ['MART_ALUNO', 'FEITAS', 'REPROVADO']
variance = merged['REPROVADO'].div(merged['FEITAS']).sub(average)\
.pow(2).sum() / merged.shape[0]
standard_deviation = math.sqrt(variance)
return (average, standard_deviation)
def general_ira(df):
fixed = df[df.SITUACAO.isin(Situation.SITUATION_AFFECT_IRA)]
fixed = fixed[fixed.MEDIA_FINAL <= 100]
return (fixed.MEDIA_FINAL.mean(), fixed.MEDIA_FINAL.std())
def current_ira(df):
ano_grade = int(df.loc[df['NUM_VERSAO'].idxmax()]['NUM_VERSAO'])
fixed = df.loc[(df['NUM_VERSAO'] == ano_grade)]
fixed = fixed[fixed.SITUACAO.isin(Situation.SITUATION_AFFECT_IRA)]
fixed = fixed[fixed.MEDIA_FINAL <= 100]
return (fixed.MEDIA_FINAL.mean(), fixed.MEDIA_FINAL.std())
def current_students_ira(df):
fixed = df.loc[(df.FORMA_EVASAO == EvasionForm.EF_ATIVO)]
fixed = fixed[fixed.SITUACAO.isin(Situation.SITUATION_AFFECT_IRA)]
fixed = fixed[fixed.MEDIA_FINAL <= 100]
return (fixed.MEDIA_FINAL.mean(), fixed.MEDIA_FINAL.std())
def general_evasion_rate(df):
students = df['MATR_ALUNO'].drop_duplicates()
total_student = students.shape[0]
total_evasion = students.loc[(df.FORMA_EVASAO != EvasionForm.EF_ATIVO) & (df.FORMA_EVASAO != EvasionForm.EF_FORMATURA) & (df.FORMA_EVASAO != EvasionForm.EF_REINTEGRACAO)].shape[0]
return total_evasion / total_student
def current_evasion_rate(df):
ano_grade = int(df.loc[df['NUM_VERSAO'].idxmax()]['NUM_VERSAO'])
students = df.loc[(df['NUM_VERSAO'] == ano_grade)]
students = students['MATR_ALUNO'].drop_duplicates()
total_student = students.shape[0]
total_evasion = students.loc[(df.FORMA_EVASAO != EvasionForm.EF_ATIVO) & (df.FORMA_EVASAO != EvasionForm.EF_FORMATURA) & (df.FORMA_EVASAO != EvasionForm.EF_REINTEGRACAO)].shape[0]
return total_evasion / total_student
def average_graduation_time(df):
graduates = df.loc[(df.FORMA_EVASAO == EvasionForm.EF_FORMATURA)]
total_graduate = graduates.shape[0]
average_time = 0
year_end = int(df['ANO'].max())
semester_end = graduates['PERIODO'].max()
for index, row in graduates.iterrows():
if pd.notnull(row['ANO_EVASAO']):
year_end = int(row['ANO_EVASAO'])
try:
semester_end = int(row['SEMESTRE_EVASAO'])
except ValueError:
semester_end = graduates['PERIODO'].max()
year = int(row['ANO_INGRESSO'])
semester = int(row['SEMESTRE_INGRESSO'])
difference = 2 * (year_end - year) + (semester_end - semester) + 1
average_time += difference
average_time /= total_graduate
average_time /= 2
return average_time
def total_students(df):
return df.drop_duplicates('MATR_ALUNO').shape[0]
def current_total_students(df):
return df.loc[(df.FORMA_EVASAO == EvasionForm.EF_ATIVO)].drop_duplicates('MATR_ALUNO').shape[0]
def taxa_abandono(df):
students = df['MATR_ALUNO'].drop_duplicates()
total_student = students.shape[0]
total_abandono = students.loc[(df.FORMA_EVASAO == EvasionForm.EF_ABANDONO)].shape[0]
return total_abandono / total_student
def average_ira_graph(df):
alunos = df.drop_duplicates('MATR_ALUNO')