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