From 38cf594f02c2bb955fb6a4d5aa75e1b280f27cd9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Denis=20Rodrigues?= <joao.denisr@gmail.com>
Date: Thu, 27 Jul 2017 12:04:18 -0300
Subject: [PATCH] Coisas do antigo

---
 README.md                                    |  91 +++++
 load_csv/__init__.py                         |   0
 load_csv/fix_ementa_relatorio_disciplinas.sh |  21 ++
 load_csv/fix_evasao_aluno.py                 |  29 ++
 load_csv/fix_historico_aluno.py              |  33 ++
 load_csv/read_csv.py                         | 335 +++++++++++++++++++
 load_excel/load.py                           | 173 ++++++++++
 load_excel/load2.py                          |  73 ++++
 load_excel/load3.py                          |  54 +++
 makefile                                     |  43 +++
 requirements-dev.txt                         |   5 +
 requirements.txt                             |   4 +
 12 files changed, 861 insertions(+)
 create mode 100644 README.md
 create mode 100644 load_csv/__init__.py
 create mode 100644 load_csv/fix_ementa_relatorio_disciplinas.sh
 create mode 100644 load_csv/fix_evasao_aluno.py
 create mode 100644 load_csv/fix_historico_aluno.py
 create mode 100644 load_csv/read_csv.py
 create mode 100644 load_excel/load.py
 create mode 100644 load_excel/load2.py
 create mode 100644 load_excel/load3.py
 create mode 100644 makefile
 create mode 100644 requirements-dev.txt
 create mode 100644 requirements.txt

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..d42d595
--- /dev/null
+++ b/README.md
@@ -0,0 +1,91 @@
+# ADEGA
+
+Este software faz parte de um projeto do PET Computação UFPR para 
+análise de dados dos cursos de graduação da UFPR. Veja a [wiki](http://gitlab.c3sl.ufpr.br/pet/adega/wikis/home).
+
+
+## Versão
+0.0.0
+
+
+
+## Obtendo os códigos
+
+
+Os códigos fonte do projeto estão disponíveis publicamente no [gitlab]
+(gitlab.c3sl.ufpr.br/pet/adega).
+
+E podem ser clonado com o comando
+
+```bash
+$ git clone git@gitlab.c3sl.ufpr.br:pet/adega.git
+```
+
+
+## Instalação e dependências
+
+
+```bash
+sudo make install-dev
+```
+
+se você possui o arquivo do banco de dados compartilhado internamente pelos 
+desenvolvedores do projeto coloque-o na home do projeto, ele vem com um usuário 
+`pet` com senha `pet` pré-configurado para testes.
+
+
+se você não possui o arquivo rode
+
+```bash
+python manage.py migrate
+python manage.py createsuperuser
+```
+
+
+## Executando o projeto
+
+Por padrão ele irá rodar no 127.0.0.1:8000
+```bash
+python manage.py runserver
+```
+
+Se estiver usando o cloud9 use o ip e a porta que ele libera, assim:
+```bash
+python manage.py runserver $IP:$PORT
+```
+Então acesse pela url fornecida
+
+## Transformando o seu usuário em um professor
+
+Após você logar no sistema com o seu super usuário você terá acesso ao `URL_DO_SITE/admin`, graças ao [Django admin](https://docs.djangoproject.com/en/1.10/ref/contrib/admin/) nesta tela você é capaz de gerenciar os dados salvos nas models do projeto.   
+Para transformar o seu usuário em professor basta clicar em `professor`e então selecionar o seu usuário e o curso. Agora se você voltar para a página inicial do sistema você deve ver uma listagem dos seus cursos. 
+
+
+## Gerar diagrama do projeto
+
+Basta executar:
+```bash
+python manage.py graph_models -a -o diagrama.png
+```
+
+### Entendendo as dependências do projeto:
+
+* [Django](https://www.djangoproject.com/) - Framework base. Trata a requisição dos clientes e chama as devidas rotinas.
+* [Bootstrap](http://getbootstrap.com/) - Framework css. Usamos os seus componentes para deixar as telas bonitas
+* [Charts.js](http://www.chartjs.org/) - Biblioteca javascript para desenhar gráficos.
+* [Pandas](http://pandas.pydata.org/) - usada para importação dos dados
+* [django-extensions](https://django-extensions.readthedocs.io/en/latest/) - Várias extensões para o django. Estamos usando para gerar o diagrama do projeto.
+
+Dependências antigas 
+* [Pyyaml](http://pyyaml.org/)
+* [Scipy](https://www.scipy.org/)
+* [Matplotlib](http://matplotlib.org/)
+* [IPython](https://ipython.org/)
+
+
+## Contato
+
+
+Email - pet@inf.ufpr.br
+
+Facebook - pt-br.facebook.com/petcompufpr
diff --git a/load_csv/__init__.py b/load_csv/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/load_csv/fix_ementa_relatorio_disciplinas.sh b/load_csv/fix_ementa_relatorio_disciplinas.sh
new file mode 100644
index 0000000..faed589
--- /dev/null
+++ b/load_csv/fix_ementa_relatorio_disciplinas.sh
@@ -0,0 +1,21 @@
+#! /bin/bash
+
+FILE=$(tail -n +2 "$1") #sem cabeçalho
+
+head -1 $1 #cabeçalho
+
+while read line
+do
+    ementa=$(echo "$line" | cut -d',' -f15)
+   re='^[0-9]+$'
+    if  [[ $ementa =~ $re ]] ; then
+        echo "$line" | cut -d',' -f1-14 --output-delimiter="," | xargs echo -n
+        echo -n ",,"
+        echo  "$line" | cut -d',' -f15- --output-delimiter=","
+    else
+        echo "$line"
+    fi
+    
+done <<< "$FILE"
+
+
diff --git a/load_csv/fix_evasao_aluno.py b/load_csv/fix_evasao_aluno.py
new file mode 100644
index 0000000..7503ce9
--- /dev/null
+++ b/load_csv/fix_evasao_aluno.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+# *-* coding:utf-8
+
+from __future__ import print_function
+import pandas as pd
+import sys
+
+
+def shift_evasao(row):
+    if row['ANO_EVASAO'] in ("1o. Semestre", "2o. Semestre"):
+        row['PERIODO_EVASAO'] = row['ANO_EVASAO']
+        row['ANO_EVASAO'] = row['DT_SAIDA']
+        row['DT_SAIDA'] = None
+    return row
+
+
+def eprint(*args, **kwargs):
+    print(*args, file=sys.stderr, **kwargs)
+
+
+PATH = sys.argv[1]
+if not PATH:
+    eprint('Erro: Passe o caminho do relatório de matricula  dos alunos como parametro')
+
+df = pd.read_csv(PATH)
+
+df = df.apply(shift_evasao, axis=1)
+
+df.to_csv(sys.stdout, sep=',', encoding='utf-8')
diff --git a/load_csv/fix_historico_aluno.py b/load_csv/fix_historico_aluno.py
new file mode 100644
index 0000000..85fe5de
--- /dev/null
+++ b/load_csv/fix_historico_aluno.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# *-* coding:utf-8
+
+from __future__ import print_function
+import pandas as pd
+import sys
+
+
+def preenhce_situacao_limpa_media_credito(row):
+    if row['MEDIA_CREDITO'] != 'A':
+        row['SITUACAO_CURRICULO'] = row['MEDIA_CREDITO']
+        row['MEDIA_CREDITO'] = ''
+    return row
+
+
+def eprint(*args, **kwargs):
+    print(*args, file=sys.stderr, **kwargs)
+
+
+PATH = sys.argv[1]
+if not PATH:
+    eprint('Erro: Passe o caminho do relatório do historico dos alunos como parametro')
+
+df = pd.read_csv(PATH)
+# shifta DESCR_ESTRUTURA e ID_ESTRUTURA_CUR uma coluna para direita
+df = df.rename(columns={'DESCR_ESTRUTURA': 'OLD_DESCR_ESTRUTURA'})
+df = df.rename(columns={'ID_ESTRUTURA_CUR': 'DESCR_ESTRUTURA'})
+df = df.rename(columns={'ID_NOTA': 'ID_ESTRUTURA_CUR'})
+df['ID_NOTA'] = pd.Series()
+
+df = df.apply(preenhce_situacao_limpa_media_credito, axis=1)
+
+df.to_csv(sys.stdout, sep=',', encoding='utf-8')
diff --git a/load_csv/read_csv.py b/load_csv/read_csv.py
new file mode 100644
index 0000000..c965373
--- /dev/null
+++ b/load_csv/read_csv.py
@@ -0,0 +1,335 @@
+#!/usr/bin/env python
+# coding: utf-8
+from __future__ import print_function
+import sys
+import os
+import django
+import pandas as pd
+
+sys.path.append("..")
+os.environ["DJANGO_SETTINGS_MODULE"] = "adega.settings"
+django.setup()
+
+from django.db import models
+from student.models import *
+from curso.models import *
+from turmaIngresso.models import *
+from disciplina.models import *
+from turma.models import *
+from student.analysis import calcular_ira
+from django.db import models
+from django.core.exceptions import ObjectDoesNotExist
+
+DIR_RELATORIOS = "../relatorios/"
+CAMINHO_RELATORIO_DISCIPLINAS = DIR_RELATORIOS + "11.02.01.99.06-MUDA.csv"
+CAMINHO_RELATORIO_MATRICULA = DIR_RELATORIOS + "11.02.04.99.43-MUDA.csv"
+CAMINHO_RELATORIO_HISTORICOS = DIR_RELATORIOS + "11.02.05.99.33-historico-ira-curso-MUDA.csv"
+
+"""
+--------------------------------EXCEPTIONS--------------------------------
+
+"""
+
+
+class AlunoNaoExiste(Exception):
+    pass
+
+
+class DisciplinaNaoExiste(Exception):
+    pass
+
+
+class NenhumCursoEncontrado(Exception):
+    pass
+
+
+class NenhumaGradeEncontrada(Exception):
+    pass
+
+
+class GradeNaoEncontrada(Exception):
+    pass
+
+
+class NenhumaDisciplinaEncontrada(Exception):
+    pass
+
+
+_students = set()
+
+m_students = dict()
+
+
+"""
+---------------------------------------------------------------------------
+"""
+
+
+# printa na saída de erros
+def eprint(*args, **kwargs):
+    print(*args, file=sys.stderr, **kwargs)
+
+
+"""
+-------------------------FUNÇÕES LEITURA DOS RELATORIOS--------------------
+"""
+
+
+# todo: tratar exceptions
+def ler_relatorio_disciplinas(listaDisciplinas):
+    # TODO: validar se existe codigo do curso
+    cursos_df = listaDisciplinas.drop_duplicates(subset=['COD_CURSO'])
+
+    if cursos_df.empty:
+        raise NenhumCursoEncontrado()
+
+    # Pega o curso do banco de dados, caso ele não exista cria
+    curso, curso_created = Curso.objects.get_or_create(codigo=cursos_df['COD_CURSO'][0],
+                                                       nome=cursos_df['NOME_UNIDADE'][0])
+    if curso_created:
+        # grade criada, pois não temos todas as grades e queremos manter uma relação entre as disciplinas e o curso
+        grade_fake = Grade(ano_inicio=1000,
+                           curso=curso)
+        grade_fake.save()
+
+    # Agrupa os relatório pela versões da grade
+    grades_df = listaDisciplinas[listaDisciplinas.COD_CURSO == curso.codigo].drop_duplicates(subset=['NUM_VERSAO'])
+
+    if grades_df.empty:
+        raise NenhumaGradeEncontrada()
+
+    # Percorre as grades do curso
+    for index, row in grades_df.iterrows():
+        # Pega a grade do banco de dados, caso ela ainda não exista cria
+        grade, grade_created = Grade.objects.get_or_create(curso=curso,
+                                                           ano_inicio=row['NUM_VERSAO'])
+        ler_disciplinas_grade(listaDisciplinas, grade)
+    return curso
+
+
+def ler_disciplinas_grade(listaDisciplinas, grade):
+    # Seleciona as linahs que são do curso da grade e da versão da grade
+    disciplinas_df = listaDisciplinas[(listaDisciplinas.COD_CURSO == grade.curso.codigo)
+                                      & (listaDisciplinas.NUM_VERSAO == grade.ano_inicio)].drop_duplicates(
+        subset=['COD_DISCIPLINA'])
+
+    if disciplinas_df.empty:
+        raise NenhumaDisciplinaEncontrada()
+    for index, row in disciplinas_df.iterrows():
+        # Pega a disciplina no banco de dados, caso ela não exista, cria
+        disciplina, disciplina_created = Disciplina.objects.get_or_create(
+            codigo=row['COD_DISCIPLINA'], defaults={
+                'nome': row['NOME_DISCIPLINA'],
+                'carga_horaria': row['CH_TOTAL'],
+            })
+        # Caso a disciplina não exista ainda no banco de dados também cria a relação com a grade
+        if disciplina_created:
+            dg = DisciplinaGrade(grade=grade,
+                                 disciplina=disciplina,
+                                 periodo=row['PERIODO_IDEAL'],
+                                 tipo_disciplina=row['TIPO_DISCIPLINA'])
+            dg.save()
+
+
+def ler_relatorio_matriculas(matricula_aluno_df, curso):
+    # Muda valores que estão com NaN para None
+    matricula_aluno_df = matricula_aluno_df.where((pd.notnull(matricula_aluno_df)), None)
+    students = []
+
+    # Seleciona os alunos que são do curso
+    curso_df = matricula_aluno_df[matricula_aluno_df.COD_CURSO == curso.codigo]
+
+    # Agrupa os alunos pela versão da grade que está
+    grouped_grade_df = curso_df.groupby('VERSAO')
+
+    # Percorre as grades
+    for ano_grade, grade_df in grouped_grade_df:
+
+        try:
+            grade = curso.grade_set.get(ano_inicio=ano_grade)
+        except ObjectDoesNotExist as ex:
+            # raise GradeNaoEncontrada()
+            eprint("GradeNaoEncontrada: versao:{0}".format(ano_grade))
+            continue;
+        # TODO: Remover o filtro da data de ingresso no formato certo e adicionar validação
+        ti_df = curso_df[
+            matricula_aluno_df.DT_INGRESSO.str.contains("^(0[1-9]|[12][0-9]|3[01])[/](0[1-9]|1[012])[/](\d){4}$",
+                                                        na=False)]
+
+        ti_df['DT_INGRESSO'] = pd.to_datetime(ti_df['DT_INGRESSO'], format="%d/%m/%Y")
+        ti_df['ANO'] = ti_df['DT_INGRESSO'].dt.year
+        ti_df['SEMESTRE'] = ti_df['DT_INGRESSO'].apply(lambda d: 1 if d.month <= 6 else 2)
+
+        grouped_ti_df = ti_df.groupby(['ANO', 'SEMESTRE'])
+
+        for names, group in grouped_ti_df:
+            ti, created_ti = TurmaIngresso.objects.get_or_create(ano=names[0], semestre=names[1], curso=curso)
+            for index, student_row in group.iterrows():
+                # TODO: Descobrir o que fazer com evasao anual
+                # anual e dado invalido é tratada como primeiro semestre por enquanto
+                semestre_evasao = None
+                if student_row['PERIODO_EVASAO'] in SEMESTRE:
+                    semestre_evasao = SEMESTRE[student_row['PERIODO_EVASAO']]
+                elif student_row['PERIODO_EVASAO'] == "Anual":
+                    semestre_evasao = 1
+                    
+                if student_row['MATRICULA'][3:] not in _students:
+                    _students.add(student_row['MATRICULA'][3:])
+
+                    
+                    student, created_student = Student.objects.get_or_create(grr=student_row['MATRICULA'][3:],
+                                                                             defaults={'name': student_row['ALUNO'],
+                                                                                       'ira': 0,
+                                                                                       'forma_evasao': student_row[
+                                                                                           'FORMA_EVASAO'],
+                                                                                       'ano_evasao': student_row[
+                                                                                           'ANO_EVASAO'],
+                                                                                       'semestre_evasao': semestre_evasao,
+                                                                                       'turma_ingresso': ti,
+                                                                                       'grade_atual': grade
+                                                                                       })
+                                                                                       
+                    m_students[student_row['MATRICULA'][3:]] = student
+                    
+                    students.append(student)
+    return students
+
+
+
+def ler_historico_aluno(historico_df, curso):
+    disciplinas_gdf = historico_df.groupby('COD_ATIV_CURRIC')
+    grade_fake = curso.grade_set.get(ano_inicio=1000)
+
+    # inicializa data relatorio com nulo, para ser preenchida durante a leitura
+    curso.ano_relatorio = 0
+    curso.semestre_relatorio = 0
+
+    for codigo_disciplina, disciplina_df in disciplinas_gdf:
+        try:
+            disciplina = Disciplina.objects.get(codigo=codigo_disciplina)
+        except ObjectDoesNotExist:
+            primeira_linha = disciplina_df.iloc[0]
+            descr_estrutura = primeira_linha['DESCR_ESTRUTURA']
+            carga_horaria = primeira_linha['CH_TOTAL']
+            nome_disciplina = primeira_linha['NOME_ATIV_CURRIC']
+
+            if descr_estrutura == "Disciplinas de outros cursos":
+                disciplina = Disciplina(codigo=codigo_disciplina,
+                                        nome=nome_disciplina,
+                                        carga_horaria=carga_horaria)
+                disciplina.save()
+
+            # FIXME: REMOVER GRADE FAKE DEPOIS DE OBTER DE TER CERTEZA QUE TEMOS TODOS OS CURRICULOS
+            elif descr_estrutura == "Discipl. de outros currículos do curso":
+                disciplina = Disciplina(codigo=codigo_disciplina,
+                                        nome=nome_disciplina,
+                                        carga_horaria=carga_horaria)
+                disciplina.save()
+
+                dg = DisciplinaGrade(grade=grade_fake,
+                                     disciplina=disciplina,
+                                     periodo=1,
+                                     tipo_disciplina=descr_estrutura)
+                dg.save()
+
+            # TODO:O que fazer com as atividades formativas? Elas não são disciplinas, porém o que fazer com elas? obs: existem poucos registros delas no relatório, talvez elas não devam contar nele mesmo
+            elif descr_estrutura == "Atividades Formativas Complementares":
+                eprint("Atividade Formativa Encontrada: codigo={0}".format(codigo_disciplina))
+                continue
+            else:
+                try:
+                    raise DisciplinaNaoExiste("DisciplinaNaoExiste: codigo={0}".format(codigo_disciplina))
+                except DisciplinaNaoExiste as ex:
+                    eprint(ex)
+                    continue
+
+        # FIXME: Adicionar mais uma chave no group by para separar as turmas do mesmo ano e semestre(talvez sigla?)
+        turmas_gdf = disciplina_df.groupby(['ANO', 'PERIODO'])
+        # periodo do relatório na verdade é o semestre(1 ou 2)
+        for ano_periodo, turma_df in turmas_gdf:
+            if ano_periodo[1] not in SEMESTRE:
+                eprint(
+                    "PERIODO INVALIDO: cod_disciplina={0} ano={1} periodo:{2}".format(codigo_disciplina, ano_periodo[0],
+                                                                                      ano_periodo[1]))
+                continue
+            ano = ano_periodo[0]
+            semestre = SEMESTRE[ano_periodo[1]]
+            """"
+            Pega a maior data do historico para ser a data que as informações do relatório são válidas
+            """
+            if ano > curso.ano_relatorio:
+                curso.ano_relatorio = ano
+                curso.semestre_relatorio = semestre
+            elif ano == curso.semestre_relatorio:
+                if semestre > curso.semestre_relatorio:
+                    curso.semestre_relatorio = semestre
+
+            turma, created_turma = Turma.objects.get_or_create(disciplina=disciplina,
+                                                               ano=ano,
+                                                               semestre=semestre
+                                                               )
+            # TODO: validar se existe estudantes iguais na turma
+            for index, student_row in turma_df.iterrows():
+                grr = student_row['MATR_ALUNO'][3:]
+                
+                if grr not in _students:
+                    try:
+                        raise AlunoNaoExiste("AlunoNaoExiste: GRR={0}".format(grr))
+                    except AlunoNaoExiste as ex:
+                        eprint(ex)
+                        continue
+                        
+                student = m_students[grr]
+
+                # TODO: Verficar se o valor 9999 é o valor real do relatório, ou foi atribuido na criptografia do relatório
+                nota = 0 if student_row['MEDIA_FINAL'] == 9999 else student_row['MEDIA_FINAL']
+
+                # Não adianta só checar o created_turma p/ saber se precisa ou não criar o aluno_turma, pois o relatório anteriormente enviado pode não conter o aluno ainda, por exemplo antes do reajuste de matricula
+                aluno_turma, create_aluno_turma = AlunoTurma.objects.get_or_create(
+                    turma=turma, student=student, defaults={
+                        'nota': nota,
+                        'situacao': student_row['SITUACAO']
+                    })
+    # salva ano, semestre do relatório
+    curso.save()
+
+
+"""
+--------------------------------------------------------------------------------
+"""
+
+
+def gerar():
+    # ofertaDisciplina = pd.read_csv(DIR_RELATORIOS + "11.02.03.99.05-MUDA.csv")
+
+
+    relatorio_disciplinas_df = pd.read_csv(CAMINHO_RELATORIO_DISCIPLINAS)
+    print("ANALISANDO O RELATÓRIO DE DISCIPLINAS")
+    curso = ler_relatorio_disciplinas(relatorio_disciplinas_df)
+
+    print("ANALISANDO O RELATÓRIO DE MATRICULAS")
+    relatorio_matriculas_df = pd.read_csv(CAMINHO_RELATORIO_MATRICULA)
+    students = ler_relatorio_matriculas(relatorio_matriculas_df, curso)
+
+    print("ANALISANDO O RELATÓRIO DOS HISTÓRICOS")
+    relatorio_historicos_df = pd.read_csv(CAMINHO_RELATORIO_HISTORICOS)
+    ler_historico_aluno(relatorio_historicos_df, curso)
+
+    print("CALCULANDO IRAs")
+    # Atribui ira para os alunos dos relatórios
+    for student in students:
+        student.ira = calcular_ira(student.alunoturma_set.all())
+        student.save()
+
+
+def apagar():
+    AlunoTurma.objects.all().delete()
+    Student.objects.all().delete()
+    Turma.objects.all().delete()
+    Disciplina.objects.all().delete()
+    TurmaIngresso.objects.all().delete()
+    Curso.objects.all().delete()
+
+
+gerar()
+# apagar()
diff --git a/load_excel/load.py b/load_excel/load.py
new file mode 100644
index 0000000..e9cd14d
--- /dev/null
+++ b/load_excel/load.py
@@ -0,0 +1,173 @@
+#!/usr/bin/python3
+
+
+'''
+rodar do diretório adega, não do load_excel
+
+
+'''
+
+import re
+import os
+import sys
+import pandas as pd
+
+from glob import glob
+from json import load as json_load
+
+import django
+
+sys.path.append(os.getcwd())
+
+print(os.getcwd())
+
+os.environ["DJANGO_SETTINGS_MODULE"] = "adega.settings"
+django.setup()
+
+
+from curso.models import *
+from student.models import *
+from disciplina.models import *
+from turmaIngresso.models import *
+from turma.models import *
+
+
+hist = pd.read_excel('load_excel/relatorios/historico.xls', 'Planilha1')
+matr = pd.read_excel('load_excel/relatorios/matricula.xls', 'Planilha1')
+
+validos = set(hist.MATR_ALUNO.values)
+
+bcc = Curso.objects.create(codigo='21A', ano_relatorio=2016,
+                           semestre_relatorio=2, nome="Ciência da Computação")
+
+
+g2007 = Grade.objects.create(curso=bcc, ano_inicio=2007)
+g2011 = Grade.objects.create(curso=bcc, ano_inicio=2011)
+
+with open('load_excel/data/bcc/grade2007.json') as f:
+    g2007_data = json_load(f)
+
+with open('load_excel/data/bcc/grade2011.json') as f:
+    g2011_data = json_load(f)
+
+
+for obr in g2007_data:
+    d = Disciplina()
+
+    d.codigo = obr['codigo']
+    d.nome = obr['nome']
+    d.carga_horaria = obr['carga_horaria']
+    d.creditos = obr['creditos']
+
+    d.save()
+
+    dg = DisciplinaGrade()
+    dg.grade = g2007
+    dg.disciplina = d
+
+    if 'periodo' in obr:
+        dg.periodo = obr['periodo']
+        
+    dg.tipo_disciplina = obr['tipo']
+
+    dg.save()
+
+
+
+
+for obr in g2011_data:
+
+    try:
+        d = Disciplina.objects.get(codigo=obr['codigo'])
+    except Disciplina.DoesNotExist:
+        d = Disciplina()
+
+        d.codigo = obr['codigo']
+        d.nome = obr['nome']
+        d.carga_horaria = obr['carga_horaria']
+        d.creditos = obr['creditos']
+
+        d.save()
+
+    dg = DisciplinaGrade()
+    dg.grade = g2011
+    dg.disciplina = d
+    
+    if 'periodo' in obr:
+        dg.periodo = obr['periodo']
+        
+    dg.tipo_disciplina = obr['tipo']
+
+    dg.save()
+    
+
+
+for _, student in matr.iterrows():
+    if student['MATR_ALUNO'] not in validos:
+        continue
+
+    s = Student()
+    
+    s.grr = student['MATR_ALUNO']
+    s.name = student['NOME_PESSOA']
+    
+    s.forma_evasao = student['FORMA_EVASAO']
+    
+    grade = g2011
+    
+    if type(student['PERIODO_EVASAO']) == str:
+        r = re.search('(?P<ano>\d*)/(?P<semestre>\d)', student['PERIODO_EVASAO'])
+        
+        if r is None:
+            continue
+        
+        ano, semestre = int(r.group('ano')), int(r.group('semestre'))
+        
+        s.ano_evasao = ano
+        s.semestre_evasao = semestre
+        
+        if ano < 2011:
+            grade = g2007
+        
+    r = re.search('(?P<ano>\d*)/(?P<semestre>\d)', student['PERIODO_INGRESSO'])
+    ano, semestre = int(r.group('ano')), int(r.group('semestre'))
+    
+    t, _ = TurmaIngresso.objects.get_or_create(ano=ano, semestre=semestre, curso=bcc)
+    
+    s.turma_ingresso = t
+    
+    s.grade_atual = grade
+    
+    s.save()
+
+
+sys.exit(0)
+
+for _, data in hist.iterrows():
+    
+    student = Student.objects.get(grr=data['MATR_ALUNO'])
+    disciplina = Disciplina.objects.get(codigo=data['COD_ATIV_CURRIC'])
+    
+    ano = data['ANO']
+    
+    try:
+        semestre = int(data['PERIODO'][0])
+    except:
+        semestre = 1
+    
+    turma = Turma.objects.get_or_create(disciplina=disciplina, ano=ano, semestre=semestre)
+    
+    t = AlunoTurma()
+    
+    t.turma = turma
+    t.student = student
+    
+    t.nota = data['MEDIA_FINAL']
+    
+    t.situacao = data['SITUACAO']
+    
+    t.save()
+    
+
+    
+
diff --git a/load_excel/load2.py b/load_excel/load2.py
new file mode 100644
index 0000000..872cbf4
--- /dev/null
+++ b/load_excel/load2.py
@@ -0,0 +1,73 @@
+#!/usr/bin/python3
+
+import re
+import os
+import sys
+import pandas as pd
+
+from glob import glob
+from json import load as json_load
+
+import django
+
+sys.path.append(os.getcwd())
+
+os.environ["DJANGO_SETTINGS_MODULE"] = "adega.settings"
+django.setup()
+
+
+from curso.models import *
+from student.models import *
+from disciplina.models import *
+from turmaIngresso.models import *
+from turma.models import *
+
+
+hist = pd.read_excel('load_excel/relatorios/historico.xls', 'Planilha1')
+
+total = hist.shape[1]
+
+  
+     
+
+def proccess(d):
+
+    data = d[1]
+
+    try:
+        student = Student.objects.get(grr=data['MATR_ALUNO'])
+        disciplina = Disciplina.objects.get(codigo=data['COD_ATIV_CURRIC'])
+    except:
+        return
+    
+    ano = data['ANO']
+    
+    try:
+        semestre = int(data['PERIODO'][0])
+    except:
+        semestre = 1
+    
+    turma, _ = Turma.objects.get_or_create(disciplina=disciplina, ano=ano, semestre=semestre)
+    
+    t = AlunoTurma()
+    
+    t.turma = turma
+    t.student = student
+    
+    t.nota = data['MEDIA_FINAL']
+    
+    t.situacao = data['DESCR_SITUACAO']
+    
+    t.save()
+    
+    
+count = 0
+total = hist.shape[0]
+
+for i in hist.iterrows():
+    proccess(i)
+    
+    if count % 100 == 0:
+        print('{:>6} / {}'.format(count, total))
+        
+    count += 1
diff --git a/load_excel/load3.py b/load_excel/load3.py
new file mode 100644
index 0000000..2aabd60
--- /dev/null
+++ b/load_excel/load3.py
@@ -0,0 +1,54 @@
+#!/usr/bin/python3
+
+import re
+import os
+import sys
+import pandas as pd
+
+from glob import glob
+from json import load as json_load
+
+import django
+
+sys.path.append(os.getcwd())
+
+os.environ["DJANGO_SETTINGS_MODULE"] = "adega.settings"
+django.setup()
+
+
+from curso.models import *
+from student.models import *
+from disciplina.models import *
+from turmaIngresso.models import *
+from turma.models import *
+
+from student.analysis import SITUACOES_CONTRIBUEM_IRA
+
+
+hist = pd.read_excel('load_excel/relatorios/historico.xls', 'Planilha1')
+
+
+
+group = hist.groupby('MATR_ALUNO')
+
+total = len(group)
+
+for i, data in enumerate(group):
+
+    index, data = data[0], data[1]
+    
+    try:
+        aluno = Student.objects.get(grr=index)
+    except:
+        continue
+    
+    print("{:>5}/{}\t\t{}".format(i, total, index))
+    
+    ira = data[data.DESCR_SITUACAO.isin(SITUACOES_CONTRIBUEM_IRA)].MEDIA_FINAL.mean()
+    
+    aluno.ira = ira if pd.notnull(ira) else None 
+    
+    aluno.save()
+    
+    
+    
diff --git a/makefile b/makefile
new file mode 100644
index 0000000..4196726
--- /dev/null
+++ b/makefile
@@ -0,0 +1,43 @@
+SITE-OWNER = www-data
+SITE-OWNER-GROUP = www-data
+
+all:
+
+
+clean:
+	@rm -rf *~ *.pyc *.backup
+
+clean-deploy: clean
+	@rm -rf static db.sqlite3
+
+coverage:
+	coverage run --source='.' manage.py test
+	coverage html
+	xdg-open htmlcov/index.html
+
+
+docs:
+	@echo 'ainda não implementado'
+
+
+deploy:
+	python manage.py migrate
+	python manage.py collectstatic -v0 --noinput
+	chown $(SITE-OWNER):$(SITE-OWNER-GROUP) -R .
+
+clean-docs:
+	@rm -rf docs
+
+install:
+	apt-get install -y python3-dev
+	apt-get install -y python3-pip
+	pip3 install -U pip setuptools
+	pip3 install -r requirements.txt
+
+install-dev: install
+	pip3 install -r requirements-dev.txt
+
+create-db:
+	mysql -u root < configure-db.sql
+	python3 manage.py migrate
+	
diff --git a/requirements-dev.txt b/requirements-dev.txt
new file mode 100644
index 0000000..1be476d
--- /dev/null
+++ b/requirements-dev.txt
@@ -0,0 +1,5 @@
+coverage
+ipython
+pydotplus
+jupyter
+django-silk
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..5910c09
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,4 @@
+django==1.8
+django-widget-tweaks
+pandas==0.18.1
+django-extensions
-- 
GitLab