Commit d15afbdd authored by Bruno Meyer's avatar Bruno Meyer 😢

Merge branch '114-integrar-analises-relacionada-ao-curso-com-o-sistema-web' into 'development'

# Conflicts:
#   src/adega/settings.py
#   src/adega/static/adega/js/adega-chart.js
#   src/adega/templates/adega/navbar.html
#   src/adega/templates/base.html
#   src/adega/urls.py
#   src/admission/templates/admission/index.html
#   src/course/templates/course/index.html
#   src/course/views.py
#   src/report_api/views.py
#   src/script/analysis/course_analysis.py
#   src/script/build_cache.py
parents f3e38e49 d2bda136
......@@ -47,6 +47,7 @@ INSTALLED_APPS = [
'educator',
'admission',
'course',
'student',
'report_api',
'uploads'
]
......
html {
height: 100%;
font-size: 100%; /* Fix bootstrap resizing problem */
}
body {
min-height: 100%;
display: flex;
......@@ -166,4 +166,11 @@ footer h3 {
.content {
padding: 2em;
}
.paginate_button{
margin-left:10px;
margin-right:10px;
cursor: pointer;
}
\ No newline at end of file
......@@ -4,6 +4,11 @@ class AdegaChart{
//Object with two arrays (two charts), and the key is the x-axis
this.data = config.data || null;
this.hide_charts = config.hide_charts || null;
this.legend = config.legend || null;
if(config.data == null){
this.data_x = config.data_x;
......@@ -12,15 +17,34 @@ class AdegaChart{
}
else{
this.data_x = [];
this.data_y = [[],[]];
this.data_y = [];
var first_element;
for (first_element in this.data) break;
first_element = this.data[first_element];
var multiplePlots = Array.isArray(first_element);
if(multiplePlots){
for(var i in first_element){
this.data_y.push([]);
}
}
for(var obj in this.data){
this.data_x.push(obj);
}
this.data_x.sort();
for(var i in this.data_x){
var key = this.data_x[i];
this.data_y[0].push(this.data[key][0]);
this.data_y[1].push(this.data[key][1]);
if(multiplePlots){
for(var i in first_element){
this.data_y[i].push(this.data[key][i]);
}
}
else{
this.data_y.push(this.data[key]);
}
}
}
......@@ -28,7 +52,7 @@ class AdegaChart{
this.div_target = config.div_target;
this.type = config.type || "scatter";
this.title = config.title || "";
this.legend = config.legend || null;
if(typeof(this.data_y[0]) == "number"){
this.data_y = [this.data_y];
......@@ -42,35 +66,51 @@ class AdegaChart{
this.reloadGraph();
}
transformToAcumulation(){
var number_lines = this.data_y.length;
for(var i in this.data_y){
var acumulation = 0;
for(var j in this.data_y[i]){
acumulation += this.data_y[i][j];
this.data_y[i][j] = acumulation;
}
};
this.reloadGraph();
}
reloadGraph(){
var data = [];
for(var i in this.data_y){
data.push(
{
x: this.data_x,
y: this.data_y[i],
type: this.type[i],
fill: this.fill
if(this.hide_charts && this.hide_charts[i])
continue;
data.push(
{
x: this.data_x,
y: this.data_y[i],
type: this.type[i],
fill: this.fill
}
);
if(this.legend && this.legend[i] != null){
data[i].name = this.legend[i];
}
);
if(this.legend && this.legend[i] != null){
data[i].name = this.legend[i];
}
if(this.error_y && this.error_y[i] != null){
data[i].error_y = {
type: 'data',
array: this.error_y[i],
visible: true,
if(this.error_y && this.error_y[i] != null){
data[i].error_y = {
type: 'data',
array: this.error_y[i],
visible: true,
}
}
}
}
var layout = {
title: this.title
title: this.title,
showlegend: true
};
Plotly.newPlot(this.div_target, data, layout);
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
table.dataTable{clear:both;margin-top:6px !important;margin-bottom:6px !important;max-width:none !important;border-collapse:separate !important}table.dataTable td,table.dataTable th{-webkit-box-sizing:content-box;box-sizing:content-box}table.dataTable td.dataTables_empty,table.dataTable th.dataTables_empty{text-align:center}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}div.dataTables_wrapper div.dataTables_length label{font-weight:normal;text-align:left;white-space:nowrap}div.dataTables_wrapper div.dataTables_length select{width:75px;display:inline-block}div.dataTables_wrapper div.dataTables_filter{text-align:right}div.dataTables_wrapper div.dataTables_filter label{font-weight:normal;white-space:nowrap;text-align:left}div.dataTables_wrapper div.dataTables_filter input{margin-left:0.5em;display:inline-block;width:auto}div.dataTables_wrapper div.dataTables_info{padding-top:8px;white-space:nowrap}div.dataTables_wrapper div.dataTables_paginate{margin:0;white-space:nowrap;text-align:right}div.dataTables_wrapper div.dataTables_paginate ul.pagination{margin:2px 0;white-space:nowrap}div.dataTables_wrapper div.dataTables_processing{position:absolute;top:50%;left:50%;width:200px;margin-left:-100px;margin-top:-26px;text-align:center;padding:1em 0}table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc,table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>td.sorting{padding-right:30px}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{cursor:pointer;position:relative}table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:after,table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{position:absolute;bottom:8px;right:8px;display:block;font-family:'Glyphicons Halflings';opacity:0.5}table.dataTable thead .sorting:after{opacity:0.2;content:"\e150"}table.dataTable thead .sorting_asc:after{content:"\e155"}table.dataTable thead .sorting_desc:after{content:"\e156"}table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{color:#eee}div.dataTables_scrollHead table.dataTable{margin-bottom:0 !important}div.dataTables_scrollBody>table{border-top:none;margin-top:0 !important;margin-bottom:0 !important}div.dataTables_scrollBody>table>thead .sorting:after,div.dataTables_scrollBody>table>thead .sorting_asc:after,div.dataTables_scrollBody>table>thead .sorting_desc:after{display:none}div.dataTables_scrollBody>table>tbody>tr:first-child>th,div.dataTables_scrollBody>table>tbody>tr:first-child>td{border-top:none}div.dataTables_scrollFoot>.dataTables_scrollFootInner{box-sizing:content-box}div.dataTables_scrollFoot>.dataTables_scrollFootInner>table{margin-top:0 !important;border-top:none}@media screen and (max-width: 767px){div.dataTables_wrapper div.dataTables_length,div.dataTables_wrapper div.dataTables_filter,div.dataTables_wrapper div.dataTables_info,div.dataTables_wrapper div.dataTables_paginate{text-align:center}}table.dataTable.table-condensed>thead>tr>th{padding-right:20px}table.dataTable.table-condensed .sorting:after,table.dataTable.table-condensed .sorting_asc:after,table.dataTable.table-condensed .sorting_desc:after{top:6px;right:6px}table.table-bordered.dataTable th,table.table-bordered.dataTable td{border-left-width:0}table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable td:last-child,table.table-bordered.dataTable td:last-child{border-right-width:0}table.table-bordered.dataTable tbody th,table.table-bordered.dataTable tbody td{border-bottom-width:0}div.dataTables_scrollHead table.table-bordered{border-bottom-width:0}div.table-responsive>div.dataTables_wrapper>div.row{margin:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:first-child{padding-left:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:last-child{padding-right:0}
/*!
DataTables Bootstrap 3 integration
©2011-2015 SpryMedia Ltd - datatables.net/license
*/
(function(b){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(a){return b(a,window,document)}):"object"===typeof exports?module.exports=function(a,d){a||(a=window);if(!d||!d.fn.dataTable)d=require("datatables.net")(a,d).$;return b(d,a,a.document)}:b(jQuery,window,document)})(function(b,a,d,m){var f=b.fn.dataTable;b.extend(!0,f.defaults,{dom:"<'row'<'col-sm-6'l><'col-sm-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-5'i><'col-sm-7'p>>",renderer:"bootstrap"});b.extend(f.ext.classes,
{sWrapper:"dataTables_wrapper form-inline dt-bootstrap",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm",sProcessing:"dataTables_processing panel panel-default"});f.ext.renderer.pageButton.bootstrap=function(a,h,r,s,j,n){var o=new f.Api(a),t=a.oClasses,k=a.oLanguage.oPaginate,u=a.oLanguage.oAria.paginate||{},e,g,p=0,q=function(d,f){var l,h,i,c,m=function(a){a.preventDefault();!b(a.currentTarget).hasClass("disabled")&&o.page()!=a.data.action&&o.page(a.data.action).draw("page")};
l=0;for(h=f.length;l<h;l++)if(c=f[l],b.isArray(c))q(d,c);else{g=e="";switch(c){case "ellipsis":e="&#x2026;";g="disabled";break;case "first":e=k.sFirst;g=c+(0<j?"":" disabled");break;case "previous":e=k.sPrevious;g=c+(0<j?"":" disabled");break;case "next":e=k.sNext;g=c+(j<n-1?"":" disabled");break;case "last":e=k.sLast;g=c+(j<n-1?"":" disabled");break;default:e=c+1,g=j===c?"active":""}e&&(i=b("<li>",{"class":t.sPageButton+" "+g,id:0===r&&"string"===typeof c?a.sTableId+"_"+c:null}).append(b("<a>",{href:"#",
"aria-controls":a.sTableId,"aria-label":u[c],"data-dt-idx":p,tabindex:a.iTabIndex}).html(e)).appendTo(d),a.oApi._fnBindAction(i,{action:c},m),p++)}},i;try{i=b(h).find(d.activeElement).data("dt-idx")}catch(v){}q(b(h).empty().html('<ul class="pagination"/>').children("ul"),s);i!==m&&b(h).find("[data-dt-idx="+i+"]").focus()};return f});
This diff is collapsed.
This diff is collapsed.
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="col-md-2">
<nav class="navbar-expand-lg navbar-dark bg-primary">
<div class="col-md-2">
<a class="navbar-brand" href="{% url 'dashboard' %}">ADEGA</a>
</div>
<div class="collapse navbar-collapse" id="navbartoggle">
......@@ -63,7 +63,7 @@
<ul class="nav navbar-nav hidden-md hidden-lg">
<li><a href="#">Alunos</a></li>
<li><a href="{% url 'student:index' degree_id=degree.code%}">Alunos</a></li>
<li><a href="{% url 'course:index' degree_id=degree.code%}">Turmas de Ingresso</a></li>
<li class="dropdown">
<a href="{% url 'course:index' degree_id=degree.code%}" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
......
<div class="sidebar left hidden-sm hidden-xs">
<ul class="list-sidebar">
<li><a href="#">Alunos</a></li>
<li><a href="{% url 'student:index' degree_id=degree.code%}">Alunos</a></li>
<li style="display: block;">
<div>
<a href="{% url 'course:index' degree_id=degree.code%}">Disciplinas</a>
......@@ -26,4 +26,4 @@
</ul>
</li>
</ul>
</div>
\ No newline at end of file
</div>
......@@ -6,17 +6,22 @@
<link rel="icon" href="{% static 'favicon.ico' %}" type="image/x-icon" />
<title>{% if title %}{{ title}} | {% endif %}A.D.E.G.A.</title>
<link rel="stylesheet" href="{% static 'flatly/bootstrap.min.css' %}"/>
<link href="https://use.fontawesome.com/releases/v5.0.8/css/all.css" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
<link rel="stylesheet" href="{% static 'flatly/bootstrap.css' %}"/>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/all.css">
<link rel="stylesheet" href="{% static 'fontawesome5/css/fa-regular.min.css' %}"/>
<link rel="stylesheet" href="{% static 'adega/css/styles.css' %}"/>
<script defer src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script defer src="{% static 'bootstrap4/js/bootstrap.bundle.min.js' %}"></script>
<script defer src="{% static 'adega/js/scripts.js' %}"></script>
<link rel="preload" href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic" as="style"/>
</head>
<body>
<section id="header">
......@@ -66,8 +71,20 @@
</div>
</footer>
</body>
<script src="{% static 'adega/js/plotly-latest.min.js' %}"></script>
<script src="{% static 'jquery/jquery-3.3.1.js' %}"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap.min.js"></script>
<script src="{% static 'adega/js/adega-chart.js' %}"></script>
<link rel="stylesheet" href="{% static 'datatables/dataTables.bootstrap.min.css' %}"/>
<script src="{% static 'datatables/jquery.dataTables.min.js' %}"></script>
{% block js-foot %}
{% endblock js-foot %}
......
......@@ -13,6 +13,8 @@ urlpatterns = [
url(r'^course/(?P<degree_id>\w*)/', include('course.urls', namespace='course')),
url(r'^student/(?P<degree_id>\w*)/', include('student.urls', namespace='student')),
url(r'^degree/(?P<degree_id>\w*)/', include('degree.urls', namespace='degree')),
url(r'^public/', include('public.urls', namespace='public')),
......
......@@ -9,7 +9,7 @@
<div class="row">
<div class="col-md-12">
<h2>Turmas de Ingresso</h2>
<table class="table datatable">
<table class="table table-striped table-bordered" id="admission_table">
<thead>
<tr>
<th>Ano/Semestre</th>
......@@ -41,3 +41,14 @@
</div>
</div>
{% endblock content %}
{% block js-foot %}
<script>
$('#admission_table').dataTable({
"bPaginate": true,
"bInfo": false,
"aaSorting": [[ 1, "desc" ]],
"responsive": true
});
</script>
{% endblock js-foot %}
......@@ -9,7 +9,7 @@
<div class="row">
<div class="col-md-12">
<h2>Disciplinas</h2>
<table id="lista_disciplinas" class="table">
<table id="course_table" class="table table-striped table-bordered">
<thead>
<tr>
<th>Código</th>
......@@ -23,7 +23,7 @@
<td>
<a href="{% url 'course:detail' degree_id=degree.code codigo_disciplina=key %}">{{key}}</a>
</td>
<td> {{key}} </td>
<td> {{value.name}} </td>
<td> {{value.nota.0 | floatformat:2}} &plusmn {{value.nota.1 | floatformat:2}} </td>
</tr>
{% endfor %}
......@@ -31,5 +31,16 @@
</table>
</div>
</div>
{% endblock content %}
{% block js-foot %}
<script>
$('#course_table').dataTable({
"bPaginate": true,
"bInfo": false,
"aaSorting": [[ 1, "desc" ]],
"responsive": true
});
</script>
{% endblock js-foot %}
......@@ -28,7 +28,10 @@ def index(request, degree_id):
if not (degree in request.user.educator.degree.all()):
return redirect("adega:dashboard")
analysis_result = get_list_courses(request.session, degree)
courses_list = analysis_result["cache"]
return render(request, 'course/index.html', {
"courses": get_list_courses(request.session, degree)["cache"],
"courses": courses_list,
"degree": degree
})
......@@ -48,7 +48,7 @@
{% endcomment %}
</table>
{% comment %}
{% comment %}
<div>
<div class="panel-container">
<div class="data-panel">
......@@ -71,17 +71,16 @@
</div>
</div>
</div>
{% endcomment %}
{% comment %}
{% endcomment %}
<div id="graficos">
<div class="row">
<div class="col-md-6">
<h3>Quantidade alunos/IRA</h3>
<canvas id="ira_semestral" data-data='{{ degree_data.ira_medio_grafico|safe }}'></canvas>
<!-- <h3>Quantidade alunos/IRA</h3> -->
<div id="ira_semestral"></div>
</div>
<div class="col-md-6">
<h3>Quantidade evasão/período</h3>
<canvas id="evasao_semestre" data-data='{{ degree_data.evasao_grafico|safe }}'></canvas>
<!-- <h3>Quantidade evasão/período</h3> -->
<div id="evasao_semestre"></div>
</div>
<!--
<div class="col-md-6">
......@@ -91,6 +90,7 @@
</div> essa analise foi feita de uma maneira ruim no adega
antigo -->
<!-- analises sa02 -->
{% comment %}
<div class="col-md-6">
<h3>Alunos/Periodo</h3>
<canvas id="aluno_periodo"
......@@ -109,10 +109,68 @@
<canvas id="taxa_aprovacao_periodo"
data-data='{{ degree_data.taxa_aprovacao_periodo|safe }}'></canvas>
</div>
{% endcomment %}
<!-- fim analise sa02 -->
</div>
</div>
{% endcomment %}
</div>
</div>
{% endblock content %}
{% block js-foot %}
<script>
// TODO: Refactor the analyzes to avoid this pretreatment
// Assure that the keys is in order and convert the data
// to a format that AdegaChart will accept
function convert_degree_chart_data(data){
var new_data = {};
var dict_order_keys = Object.keys(data[0][1]);
data.map(function(x){
var elements_tick = [];
for(var i in dict_order_keys) elements_tick.push(0);
for(var y in x[1]){
var index = dict_order_keys.indexOf(y);
elements_tick[index] = x[1][y];
}
var index = x[0];
new_data[index] = elements_tick;
});
return new_data;
}
var ira_semestral = {{degree_data.ira_medio_grafico|safe}};
var ira_semestral_data = convert_degree_chart_data(ira_semestral);
var evasao_semestre = {{degree_data.evasao_grafico|safe}};
var evasao_semestre_data = convert_degree_chart_data(evasao_semestre);
// ira_semestral_data will be in format of:
// {"00-4.9": [10,20,30], "05-9.9": [11,21,31], ...}
console.log(evasao_semestre_data);
var chart1 = new AdegaChart({
data: ira_semestral_data,
div_target: "ira_semestral",
title: "Quantidade alunos/IRA",
fill: "none",
legend: ["Ira médio", "Alunos sem evasão", "Formados"]
});
var chart2 = new AdegaChart({
data: evasao_semestre_data,
div_target: "evasao_semestre",
title: "Quantidade evasão/período",
fill: "none",
legend: ["Taxa", "Quantidade"]
});
</script>
{% endblock js-foot %}
\ No newline at end of file
......@@ -13,14 +13,20 @@ def get_data(session,degree,data_name):
data = json.load(data_f)
return data
def get_degree_information(session,degree):
def get_degree_information(session, degree):
return get_data(session,degree,"degree.json")
def get_list_admission(session,degree):
def get_list_admission(session, degree):
return get_data(session,degree,"admission/lista_turma_ingresso.json")
def get_list_courses(session,degree):
def get_list_courses(session, degree):
return get_data(session,degree,"disciplina/disciplinas.json")
def get_course_detail(session,degree, course_id):
return get_data(session,degree,"disciplina/"+course_id+".json")
\ No newline at end of file
def get_course_detail(session, degree, course_id):
return get_data(session,degree,"disciplina/"+course_id+".json")
def get_list_students(session, degree, list_name):
return get_data(session,degree,"students/list/"+list_name+".json")
def get_student_detail(session, degree, student_id):
return get_data(session,degree,"students/"+student_id+".json")
\ No newline at end of file
import numpy as np
from script.utils.situations import *
from script.analysis.student_analysis import ira_alunos
from script.analysis.student_analysis import StudentAnalysis
from collections import defaultdict
import numpy as np
......@@ -63,8 +63,9 @@ def admission_class_ira_per_semester(df):
return dict_admission
def iras_alunos_turmas_ingressos(df):
iras = ira_alunos(df)
student_analysis = StudentAnalysis(df)
iras = student_analysis.ira_alunos()
turmas_ingresso_grr = df.groupby([
"ANO_INGRESSO",
"SEMESTRE_INGRESSO",
......
This diff is collapsed.
......@@ -9,14 +9,19 @@ from script.analysis.cepe9615_analysis import *
from collections import defaultdict
try:
to_unicode = unicode
to_unicode = unicode
except NameError:
to_unicode = str
to_unicode = str
student_analysis = None
def build_cache(dataframe,path):
# os.chdir("../src")
ensure_path_exists(path)
# os.chdir("../src")
ensure_path_exists(path)
student_analysis = StudentAnalysis(dataframe)
for cod, df in dataframe.groupby('COD_CURSO'):
path = path + '/'
......@@ -34,99 +39,105 @@ def generate_cepe_data(path,df):
save_json(path+"cepe9615.json", cepe_dict)
def generate_degree_data(path, dataframe):
ensure_path_exists(path)
ensure_path_exists(path+'students')
ensure_path_exists(path)
ensure_path_exists(path+'students')
students = dataframe[['MATR_ALUNO', 'FORMA_EVASAO']].drop_duplicates()
build_degree_json(path,dataframe)
students = dataframe[['MATR_ALUNO', 'FORMA_EVASAO']].drop_duplicates()
build_degree_json(path,dataframe)
def historico(dataframe):
res = []
res = []
for _, row in dataframe.iterrows():
res.append(dict(row[['ANO', 'MEDIA_FINAL', 'PERIODO', 'SITUACAO', 'COD_ATIV_CURRIC', 'NOME_ATIV_CURRIC',
'CREDITOS', 'CH_TOTAL', 'DESCR_ESTRUTURA', 'FREQUENCIA']]))
for _, row in dataframe.iterrows():
res.append(dict(row[['ANO', 'MEDIA_FINAL', 'PERIODO', 'SITUACAO', 'COD_ATIV_CURRIC', 'NOME_ATIV_CURRIC',
'CREDITOS', 'CH_TOTAL', 'DESCR_ESTRUTURA', 'FREQUENCIA']]))
return res
return res
def process_semestre(per, df):
ira = df[df.SITUACAO.isin(Situation.SITUATION_AFFECT_IRA)].MEDIA_FINAL.mean()
completas = df[df.SITUACAO.isin(Situation.SITUATION_PASS)].shape[0]
tentativas = df[df.SITUACAO.isin(Situation.SITUATION_COURSED)].shape[0]
return {
'semestre': per,
'ira': ira,
'completas': completas,
'tentativas': tentativas,
'aprovacao': completas/tentativas if tentativas else 0,
'ira_por_quantidade_disciplinas': ira/tentativas if tentativas else 0
}
ira = df[df.SITUACAO.isin(Situation.SITUATION_AFFECT_IRA)].MEDIA_FINAL.mean()
completas = df[df.SITUACAO.isin(Situation.SITUATION_PASS)].shape[0]
tentativas = df[df.SITUACAO.isin(Situation.SITUATION_COURSED)].shape[0]
return {
'semestre': per,
'ira': ira,
'completas': completas,
'tentativas': tentativas,
'aprovacao': completas/tentativas if tentativas else 0,
'ira_por_quantidade_disciplinas': ira/tentativas if tentativas else 0
}
def generate_student_data(path, dataframe):
student_data = dict()
all_grrs = list(dataframe["MATR_ALUNO"].drop_duplicates())
for x in all_grrs:
student_data[x] = dict()
analises = [
# tupla que contem no primeiro elemento a funcao que retorna um dicionario com {"GRR": valor}
# e na segunda posicao o nome que esta analise tera no json
def generate_student_data(path, dataframe, student_analysis):
student_data = defaultdict(dict)
all_grrs = list(dataframe["MATR_ALUNO"].drop_duplicates())
for x in all_grrs:
student_data[x] = dict()
analysis = [
# tuple that contains in the first element the function that returns a dictionary with {"GRR": value}
# and in the second position the name that this analysis will have in json
(posicao_turmaIngresso_semestral(dataframe),
"posicao_turmaIngresso_semestral"),
# (student_analysis.posicao_turmaIngresso_semestral(),
# "posicao_turmaIngresso_semestral"),
(periodo_real(dataframe),
"periodo_real"),