Skip to content

Instantly share code, notes, and snippets.

@pedrogk
Last active June 4, 2019 22:47
Show Gist options
  • Save pedrogk/0dd79642cf51ade4a0daf49a8e3433e5 to your computer and use it in GitHub Desktop.
Save pedrogk/0dd79642cf51ade4a0daf49a8e3433e5 to your computer and use it in GitHub Desktop.
View in the BP2C Reviews app (Django) to display descriptive statistics for the different answers in the survey for a company
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.contrib.auth import get_user
from django.db.models import Max, Avg, Count
from .models import ReviewInstance, Criteria,Contact
from .choices import CATEGORIES
import numpy as np
import pandas as pd
from bokeh.plotting import figure, output_file, show
from bokeh.embed import components
def get_plot(series):
p = figure(plot_height = 300, plot_width = 400, title = "", x_axis_label = 'Calificación', y_axis_label = '# de respuestas')
p.xaxis.ticker = list(range(1,11))
hist, edges = np.histogram(series, range=(0.5,10.5))
p.quad(bottom=0, top=hist, left=edges[:-1], right=edges[1:], line_color='#c0c0c0')
return p
def make_category_tree():
tree = []
for cat_key, cat_name in CATEGORIES:
criterias = Criteria.objects.filter(category=cat_key)
criteria_list = []
for c in criterias:
crit_obj = {
'machineName' : c.machineName,
'description' : c.description,
}
criteria_list.append(crit_obj)
cat_obj = {
'title' : cat_name,
'criteria_list' : criteria_list,
}
tree.append(cat_obj)
return tree
def fill_criteria_stats():
return
@login_required
def results_report(request, revId):
try:
user_company = Contact.objects.get(user=get_user(request)).company
except Contact.DoesNotExist:
user_company = False
revInstance = ReviewInstance.objects.get(id=revId)
if(revInstance.company != user_company and not request.user.is_staff):
messages.warning(request, 'No tienes permiso para ver evaluaciones de esta empresa.')
return HttpResponseRedirect(reverse('reviews:error', args=()))
from django.db import connection
import pandas as pd
query_text = "SELECT * from reviews_view_answers where verified is not False and review_id = {}".format(revId)
df = pd.read_sql(query_text, connection.connection)
score_sum = 0
tree = make_category_tree()
plots = {}
# Because of how components() works, we need to go through the tree twice.
# First time to set fields and generate the plots,
for cat in tree:
for c in cat['criteria_list']:
name = c['machineName']
c['count'] = df[name].count()
c['median'] = df[name].median()
try:
c['mode'] = int(df[name].mode()[0])
except IndexError:
c['mode'] = 0
c['mean'] = df[name].mean()
plots[name] = get_plot(df[name])
# Once we have all the plots we call components()
script, divs = components(plots)
# Once we have the divs, we go through the list again to set them for each criteria.
# Since we have all the medians, we can also do the average.
for cat in tree:
median_sum = 0
for c in cat['criteria_list']:
name = c['machineName']
c['div'] = divs[name]
median_sum += c['median']
cat['score'] = round(median_sum * 10 / len(cat['criteria_list']),0)
score_sum += cat['score']
context = {
'rev_instance' : revInstance,
'count' : df['id'].count(),
'score' : round(score_sum / len(tree),0),
'script' : script,
'results_tree' : tree
}
return render(request, 'results_report.html', context)
# This view should only be accesible to logged in users.
@login_required
def results_xls(request, revId):
try:
user_company = Contact.objects.get(user=get_user(request)).company
except Contact.DoesNotExist:
user_company = False
revInstance = ReviewInstance.objects.get(id=revId)
if(revInstance.company != user_company and not request.user.is_staff):
messages.warning(request, 'No tienes permiso para ver evaluaciones de esta empresa.')
return HttpResponseRedirect(reverse('reviews:error', args=()))
from django.db import connection
import pandas as pd
query_text = "SELECT * from reviews_view_answers where verified is not False and review_id = {}".format(revId)
df = pd.read_sql(query_text, connection.connection)
score_sum = 0
tree = make_category_tree()
plots = {}
for cat in tree:
median_sum = 0
for c in cat['criteria_list']:
name = c['machineName']
c['count'] = int(df[name].count())
try:
c['median'] = int(df[name].median())
except ValueError:
c['median'] = 0
try:
c['mode'] = int(df[name].mode()[0])
except IndexError:
c['mode'] = 0
c['mean'] = round(df[name].mean(),1)
c['std'] = round(df[name].std(),1)
median_sum += c['median']
cat['score'] = int(round(median_sum * 10 / len(cat['criteria_list']),0))
score_sum += cat['score']
# Create the HttpResponse object with the appropriate CSV header.
response = HttpResponse(content_type='application/ms-excel')
response['Content-Disposition'] = 'attachment; filename="bestplacetocode-resultados.xls"'
import xlwt
wb = xlwt.Workbook(encoding='utf-8')
ws = wb.add_sheet('Resumen')
normal = xlwt.easyxf()
bold = xlwt.easyxf("font: bold on")
big = xlwt.easyxf("font: height 320")
row_num = 0
ws.write(row_num, 0, str(revInstance), big)
row_num += 1
ws.write(row_num,0,'Respuestas', normal)
ws.write(row_num,1,int(round(df['id'].count(),0)), normal)
row_num += 1
ws.write(row_num,0,'Calificación global', normal)
ws.write(row_num,1, int(round(score_sum / len(tree),0)), normal)
for cat in tree:
row_num += 1
ws.write(row_num, 0, cat['title'], normal)
ws.write(row_num, 1, cat['score'], normal)
ws = wb.add_sheet('Detalles')
columns = ['Criterio', 'Categoria', 'Respuestas', 'Mediana', 'Moda', 'Promedio', 'Desviación estándar']
row_num = 0
for col_num in range(len(columns)):
ws.write(row_num, col_num, columns[col_num], bold)
for cat in tree:
for c in cat['criteria_list']:
row_num += 1
ws.write(row_num,0,c['description'], normal)
ws.write(row_num,1,cat['title'], normal)
ws.write(row_num,2,c['count'], normal)
ws.write(row_num,3,c['median'], normal)
ws.write(row_num,4,c['mode'], normal)
ws.write(row_num,5,c['mean'], normal)
ws.write(row_num,6,c['std'], normal)
wb.save(response)
return response
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment