From 695d1b56706c9f562b01e99b376eb98c7896f779 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Denis=20Rodrigues?= <joao.denisr@gmail.com>
Date: Fri, 28 Jul 2017 11:14:38 -0300
Subject: [PATCH] Terminada a traducao do analysis do student

---
 src/admission/analysis.py |   0
 src/course/analysis.py    |   0
 src/degree/analysis.py    |  52 +++++-------
 src/script.py             |  75 +++++++++++++++++
 src/student/analysis.py   | 165 ++++++++++++++++++++++++++++++++++++++
 src/student/models.py     |  16 ++++
 src/utils/data.py         |  69 ++++++++++++++++
 7 files changed, 345 insertions(+), 32 deletions(-)
 create mode 100644 src/admission/analysis.py
 create mode 100644 src/course/analysis.py
 create mode 100644 src/script.py
 create mode 100644 src/student/analysis.py
 create mode 100644 src/utils/data.py

diff --git a/src/admission/analysis.py b/src/admission/analysis.py
new file mode 100644
index 0000000..e69de29
diff --git a/src/course/analysis.py b/src/course/analysis.py
new file mode 100644
index 0000000..e69de29
diff --git a/src/degree/analysis.py b/src/degree/analysis.py
index c29419b..4a3aadc 100644
--- a/src/degree/analysis.py
+++ b/src/degree/analysis.py
@@ -5,46 +5,34 @@ from klass.models import Klass, StudentKlass
 import numpy as np
 import math
 
-SITUATIONS_COURSE_COMPLETED = ( # Situacoes cursadas ate o fim
-    u'Reprovado por nota',
-    u'Aprovado',
-    u'Aprovado Adiantamento',
-    u'Reprovado por Frequência',
-    u'Reprovado sem note',
-)
 
-SITUATIONS_DISAPPROVALS = ( # Situacoes reprovacao
-    u'Reprovado por nota',
-    u'Reprovado por Frequência',
-    u'Reprovado sem nota',
-)
+def graph_period(degree):
+    admissions = Admission.objects.filter(degree = degree)
+    dict_amount = {}
+    dic = {}
+    evasion = 0
 
-SITUATION_COMPLETED = (
-    u'Aprovado',
-    u'Aprovado Adiantamento',
-    u'Aprov Conhecimento',
-    u'Dispensa de Disciplinas (com nota)',
-    u'Dispensa de Disciplinas (sem nota)',
-#    u'Equivalência de Disciplina'
-)
+    for admission in admissions:
+        year = admission.year
+        semester = admission.semester
+        index_semester_evasion = 0
 
+def student_retirement(degree):
+    year = degree.report_year
+    semester = degree.report_semester
+    curriculum = Curriculum.objects.filter(degree = degree)
+    retirement = ((Curriculum.get_amount_of_semesters(curriculum) + 1) / 2) * 1.5
+    year = int(year - retirement)
+    students = Student.objects.filter(admission__degree = degree,
+                   admission__year = year, admission__semester = semester,
+                   evasion_form = "Sem evasão").count()
 
-SITUATION_NO_EVASION = (
-    u'Sem evasão',
-    u'Formatura',
-    u'Reintegração',
-)
-
-SITUATION_LOCKING = (
-    u'Trancamento Total',
-    u'Trancamento Administrativo'
-)
-
+    return students
 
 def student_lock(degree):
     students = Student.objects.filter(admission__degree = degree, 
                    evasion_form = "Sem evasão")
-    lockings = StudeintKlass.objects.filter(student__in = students,
+    lockings = StudentKlass.objects.filter(student__in = students,
                    situation__in = SITUATION_LOCKING)
 
     previous_student = None
diff --git a/src/script.py b/src/script.py
new file mode 100644
index 0000000..c464b2b
--- /dev/null
+++ b/src/script.py
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+import sys
+import os
+import django
+import time
+import json
+import io
+import math
+
+from datetime import timedelta
+from pathlib import Path
+
+sys.path.append(os.getcwd())
+os.environ["DJANGO_SETTINGS_MODULE"] = "adega.settings"
+django.setup()
+
+from django.db import models
+from student.models import *
+from course.models import *
+from degree.models import *
+from admission.models import *
+
+from student.analysis import *
+from course.analysis import *
+from degree.analysis import *
+from admission.analysis import *
+from utils.data import *
+try:
+    to_unicode = unicode
+except NameError:
+    to_unicode = str
+
+def main():
+    start_time = time.clock()
+    start_time_exec = time.time()
+
+    generate_data()
+
+    print("--- Tempo de cpu: {} ---".format(timedelta(seconds=round(time.clock() - start_time))))
+    print("--- Duração real: {} ---".format(timedelta(seconds=round(time.time() - start_time_exec))))
+
+
+def generate_data():
+    path = 'cache'
+    if not os.path.exists(path):
+        os.mkdir(path)
+
+    path = 'cache/curso'
+    if not os.path.ecists(path):
+        os.mkdir(path)
+
+    degrees = Degree.objects.all()
+
+    for degree in degrees:
+        path = 'cache/curso/' + degree.code
+        if not os.path.exists(path):
+            os.mkdir(path)
+            generate_degree_data(degree)
+
+
+def generate_degree_data(degree, path):
+    average_graduation = average_graduation(degree) # media_formandos
+    dic = merge_dicts(graph_average_ira(degree), graph_average_ira_evasion_semester(degree), graph_average_ira_graduation(degree), ['average_ira', 'semester_evasion', 'graduation'])
+'''
+    degree_data = {
+        'time_graduation': average_time_to_graduation_degree(degree),
+        'graduation_rate': average_graduation[0],
+        'student_amount': average_graduation[1],
+        'failure_rate': averag
+        'ira_average':
+
+    }
+'''
+if __name__ == '__main__':
+    main()
diff --git a/src/student/analysis.py b/src/student/analysis.py
new file mode 100644
index 0000000..03afa81
--- /dev/null
+++ b/src/student/analysis.py
@@ -0,0 +1,165 @@
+# -*- coding:utf-8 -*-
+from student.models import Student
+from klass.models import *
+from admission.models import Admission
+from degree.models import *
+from datetime import datetime
+from django.db.models import Max
+from adega.utils.data import *
+
+def pass_amount(student_klasses): # calcular_indice_aprovacao
+    amount_pass = 0
+    amount_courses = 0
+    for student_klass in student_klasses:
+        if student_klass.situation in SITUATION_COURSE_COMPLETED:
+            amount_courses += 1
+            if student_klass.situation in SITUATION_PASS:
+                amount_pass += 1
+
+
+    return -1 if amount_courses == 0 else amount_pass
+
+def pass_rate(student_klasses): # indice_aprovacao
+    amount_pass = 0
+    pass
+
+def semester_pass_rate(student): # calcular_indice_aprovacao_semestral
+    index = {}
+    amount_semesters = student.get_time_in_degree()
+    year = student.admission.year
+    semester = student.admission.semester 
+
+    for i in range(0, amoun_semesters):
+        #semester_student_klass = student.studentklass_set.filter(klass__year = year, klass__semester = semester
+        #semester_index = pass_amount
+        semester_index = student.studentklass_set.filter(klass__year = year, klass__semester = semester, situation__in = SITUATION_PASS).count()
+
+        if semester_index > 0:
+            key = "{}/{}".format(year, semester)
+            index[key] = semester_index
+
+        semester = (semester % 2) + 1
+        semester += semester % 2
+
+    return index
+
+def get_student_courses_completed(student_klasses):
+    student_courses_completed = []
+
+    for student_klass in student_klasses:
+        if student_klass.situation in SITUATION_COURSE_COMPLETED:
+            student_courses_completed.append(student_klass)
+
+    return student_courses_completed
+
+def get_amount_courses_completed(student):
+    amount = {}
+
+    amount_semesters = student.get_time_in_degree()
+    year = student.admission.year
+    semester = student.admission.semester
+
+    for i in range(0, amount_semesters):
+        student_klass_semester = student.studentklass_set.filter(klass__year = year, klass__semester = semester)
+        key = "{}/{}".format(year, semester)
+        amount[key] = len(get_student_courses_completed(student_klass_semester))
+        semester = (semester % 2) + 1
+        year += semester % 2
+
+    return amount
+
+def calculate_ira(student_klasses):
+    ira = 0
+    total_workload = 0
+
+    for student_klass in student_klasses:
+        if student_klass.situation in SITUATION_AFFECT_IRA:
+            workload = student_klass.klass.course.workload
+            total_workload += workload
+            ira += student_klass.grade * workload
+
+    if total_workload == 0:
+        return -1
+    else:
+       ira /= total_workload
+
+    return ira / 100
+
+def get_ira_semester(student)
+    iras = {}
+
+    amount_semesters = student.get_time_in_degree()
+    year = student.admission.year
+    semester = student.admission.semester
+    
+    for i in range(0, amount_semesters):
+        student_klass_semester = student.studentklass_set.filter(klass__year = year, klass__semester = semester)
+        semester_ira = calculate_ira(student_klass_semester)
+
+        if semester_ira >= 0
+            key = "{}/{}".format(year, semester)
+            iras[key] = semester_ira
+
+        semester = (semester % 2) + 1
+        year += semester % 2
+
+    return iras
+
+def get_student_position(student):
+    student_iras = get_ira_semester(student)
+    positions = {}
+    positions = positions.fromkeys(student_iras.keys())
+    positions = {semester: {'position': 1, 'amount_student': 1} for semester, value in student_iras.items())}
+
+    admission_students = Student.objects.filter(admission = student.admission).exclude(grr = student.grr)
+
+    for admission_student in admission_students:
+        iras = get_ira_semester(admission_student)
+        for key in positions:
+            if key in iras and iras[key] >= 0:
+                positions[key]['position'] += 1
+            positions[key]['amount_student'] += 1
+
+    positions = {semester: value['position'] / value['amount_student'] for semester, value in positions.items()}
+
+    return position
+
+def ira_amount_courses(student):
+    ira_semesters = get_ira_semester(student)
+    amount_courses = get_student_courses_completed(student)
+
+    ira_amount_course = {}
+    ira_amount_course = ira_amount_course.fromkeys(ira_semesters.keys())
+
+    for ira_semester in ira_semesters:
+        ira_amount_course[ira_semester] = [ira_semesters[ira_semester], amount_course[ira_semester]]
+
+    return ira_amount_course
+
+def get_real_period(student, last_period = None):
+    if last_period is None:
+        last_period = student.curriculum.get_amount_of_semesters()
+
+    real_period = 0
+    period_completed = True
+    while period_completed and real_period <= last_period:
+        real_period += 1
+
+        courses_period = student.current_grade.courses.filter(coursecurriculum__period = real_period)
+        courses_passed_period = courses_period.filter(klass__studentklass__student = student, klass__studentkass__situation__in = SITUATION_CONCLUDED)
+        period_completed = len(courses_passed_period) == len(courses_period)
+
+    if real_period > last_period:
+        return -1
+
+    return real_period
+
+def get_intended_period(student):
+    amount_semester_student = student.get_time_in_degree()
+    last_period_curriculum = student.current_curriculum.get_amount_of_semesters()
+
+    if amount_semester_student > last_period_curriculum:
+        return -1
+    return amount_semester_student
+
+
diff --git a/src/student/models.py b/src/student/models.py
index cc56339..16ee1f2 100644
--- a/src/student/models.py
+++ b/src/student/models.py
@@ -1,6 +1,8 @@
 from django.db import models
 from django.core.validators import MinValueValidator
 from degree.models import Curriculum
+from admission.models import Admission
+from utils.data import difference_semesters
 
 # Create your models here.
 class Student(models.Model):
@@ -11,4 +13,18 @@ class Student(models.Model):
     evasion_year = models.PositiveIntegerField(null = True, blank = True)
     evasion_semester = models.PositiveIntegerField(null = True, blank = True)
     current_curriculum = models.ForeignKey(Curriculum)
+    admission = models.ForeignKey(Admission)
     klasses = models.ManyToManyField('klass.Klass', through = 'klass.StudentKlass')
+
+    def get_time_in_degree(self):
+        if self.evasion_year is not None:
+            year_end = self.evasion_year
+            if self.evasion_semester is None:
+                semester_end = 2
+            else:
+                semester_end = self.evasion_semester
+
+        year_start = self.admission.year
+        semester_start = self.admission.semester
+        difference = difference_semester(year_start, semester_start, year_end, semester_end)
+        return difference 
diff --git a/src/utils/data.py b/src/utils/data.py
new file mode 100644
index 0000000..d992ee2
--- /dev/null
+++ b/src/utils/data.py
@@ -0,0 +1,69 @@
+SITUATIONS_COURSE_COMPLETED = ( # Situacoes cursadas ate o fim
+    u'Reprovado por nota',
+    u'Aprovado',
+    u'Aprovado Adiantamento',
+    u'Reprovado por Frequência',
+    u'Reprovado sem note',
+)
+
+SITUATIONS_FAILURE = ( # Situacoes reprovacao
+    u'Reprovado por nota',
+    u'Reprovado por Frequência',
+    u'Reprovado sem nota',
+)
+
+SITUATION_CONCLUDED = ( # Situacoes concluidas
+    u'Aprovado',
+    u'Aprovado Adiantamento',
+    u'Aprov Conhecimento',
+    u'Aprovado Conhecimento',
+    u'Dispensa de Disciplinas (com nota)',
+    u'Dispensa de Disciplinas (sem nota)',
+    u'Equivalência de Disciplina'
+)
+
+SITUATION_PASS = ( # Situacoes aprovacao
+    u'Aprovado'
+    u'Aprovado Adiantamento',
+    u'Equivalência de Disciplinas',
+    u'Aprovado Conhecimento',
+)
+
+
+SITUATION_NO_EVASION = ( # Situacoes nao evasao
+    u'Sem evasão',
+    u'Formatura',
+    u'Reintegração',
+)
+
+SITUATION_LOCKING = ( # Situacoes trancamento
+    u'Trancamento Total',
+    u'Trancamento Administrativo'
+)
+
+
+SITUATION_AFFECT_IRA = ( # Situacoes contribuem para o ira
+    u'Reprovado por nota',
+    u'Aprovado',
+    u'Reprovado por Frequência',
+    u'Reprovado sem nota',
+    u'Aprovado Adiantamento', # TODO: Descobrir se realmente contribui
+)
+
+SITUATION_FAILURE_COMPLETED = ( # Situacoes reprovacao cursada ate o fim
+    u'Reprovado por nota',
+    u'Reprovado por Frequência',
+    u'Reprovado sem nota',
+)
+
+def difference_between_semesters(year_start, semester_start, year_end, semester_end):
+    return 2 * (year_end - year_start) + (semester_end - year_end) + 1
+
+def merge_dicts(dict1, dict2, dict3, keys):
+    dict_out = {}
+    for key, value in dict1.items():
+        v2 = dict2[key] if key in dict2 else None
+        v3 = dict3[key] if key in dict3 else None
+        dict_out[key] = {keys[0]: value, keys[1]: v2, keys[2]: v3}
+
+    return dict_out
-- 
GitLab