def detail_teacher_bamboo(request, uid): ''' Report Card View leveraging bamboo aggregation ''' context = {'category': 'teachers', 'schoolcat': '%s|%s' % (request.user.project.slug, 'school_names')} # retrieve short ID sid = request.GET.get('short', None) if not sid: sid = short_id_from(uid) # build barcode (identifier on submissions) from UID param. barcode = build_urlid_with(uid, sid) connection = Connection(get_bamboo_url(request.user.project)) teacher_dataset = CachedDataset(get_bamboo_dataset_id(request.user.project, is_registration=True), connection=connection) # Retrieve teacher data from bamboo (1req) teacher = teacher_dataset.get_data(query={'barcode': barcode}, cache=True, cache_expiry=VLONG)[0] context.update({'teacher': teacher}) teacher.update(detailed_id_dict(teacher)) return render(request, 'detail_teacher_bamboo.html', context)
def detail_teacher_django(request, uid): ''' Report Card View processing data from submissions list/data only 2 bamboo requests: - teacher data from uuid - list of submissions for that teacher All processing/grouping done in python. ''' context = {'category': 'teachers', 'schoolcat': '%s|%s' % (request.user.project.slug, 'school_names')} connection = Connection(get_bamboo_url(request.user.project)) main_dataset = CachedDataset(get_bamboo_dataset_id(request.user.project), connection=connection) teacher_dataset = CachedDataset(get_bamboo_dataset_id(request.user.project, is_registration=True), connection=connection) def get_age_group(sub): ''' return age group (key str) of a given submission based on age''' for key, age_range in REPORTS_AGE_GROUPS.items(): if (sub.get(u'general_information_age', 0) in range(age_range[0], age_range[1] + 1)): return key return u"all" def init_reports(): ''' A reports container with initial values ''' reports = {} for age_group in REPORTS_AGE_GROUPS.keys(): reports[age_group] = {} for sex in ('male', 'female', 'total'): reports[age_group][sex] = {} for level in REPORTS_READING_LEVELS.keys() \ + REPORTS_NUMERACY_LEVELS.keys() + ['total']: reports[age_group][sex][level] = {'nb': 0, 'percent': None} return reports def compute_report_for(reports, submission, is_numeracy=False): ''' increment counters on all categories for a submission ''' age_group = get_age_group(submission) sex = submission.get('general_information_sex') level = submission.get('learning_levels_numeracy_nothing' if is_numeracy else 'learning_levels_reading_nothing') # AGE GRP SEX LEVEL reports['all']['total']['total']['nb'] += 1 reports['all']['total'][level]['nb'] += 1 reports['all'][sex]['total']['nb'] += 1 reports['all'][sex][level]['nb'] += 1 reports[age_group][sex][level]['nb'] += 1 reports[age_group]['total'][level]['nb'] += 1 reports[age_group][sex]['total']['nb'] += 1 reports[age_group]['total']['total']['nb'] += 1 def compute_percentages(reports): ''' calculates the percentages fields for the reports dict ''' def pc(num, denum): try: return float(num['nb']) / float(denum['nb']) except ZeroDivisionError: return 0 for age_group, ago in reports.items(): for sex, so in ago.items(): for level, lo in so.items(): reports[age_group][sex][level]['percent'] = \ pc(reports[age_group][sex][level], reports[age_group][sex]['total']) def sort_reports(reports_dict): ''' sort report by Age (asc) then gender keeping total/All at last ''' def cmp_rep(x, y): if x == y: return 0 # 'all' age group is last if x == 'all' or y == 'all': return 1 if x == 'all' else -1 # compare minimum age for group to sort xa_min = REPORTS_AGE_GROUPS.get(x, (100, 0))[0] ya_min = REPORTS_AGE_GROUPS.get(y, (100, 0))[0] return 1 if xa_min > ya_min else -1 reports = [] # loop on dict and transform to: # - dicts composed of {'name': x, 'data': y} # - data is an ordered array of dicts for age_group in sorted(reports_dict.keys(), cmp=cmp_rep): age_group_data = reports_dict.get(age_group) age_group_data.update({'name': age_group}) age_group_sex = [] for sex in sorted(age_group_data.keys()): if sex == 'name': continue sex_data = age_group_data.get(sex) sex_data.update({'name': sex}) age_group_sex.append(sex_data) reports.append({'name': age_group, 'data': age_group_sex}) return reports # retrieve short ID sid = request.GET.get('short', None) if not sid: sid = short_id_from(uid) # if we don't have an UID, find out teacher from SID. if uid == sid: barcodes = {} for bc in teacher_dataset.get_data(select=['barcode'], cache=True, cache_expiry=VSHORT): barcodes[short_id_from(bc)] = bc barcode = barcodes.get(sid, '') else: barcode = uid # Retrieve teacher data from bamboo (1req) teacher = teacher_dataset.get_data(query={'barcode': barcode}, cache=True, cache_expiry=VLONG)[0] teacher.update(detailed_id_dict(teacher)) # retrieve list of submissions from bamboo (1req) submissions = main_dataset.get_data( query={'$or': [{'teacher_barcode': barcode}, {'teacher_fallback_id': {'$regex':sid, '$options':'i'}}]}, select=['general_information_age', 'general_information_sex', 'learning_levels_numeracy_nothing', 'learning_levels_reading_nothing', 'school_junior_secondary', 'school_primary', 'school_senior_secondary', 'schooling_status_grades']) # initialize containers for reading report and numeracy report. reading_dict = init_reports() numeracy_dict = init_reports() # loop on submissions to fill reading/num reports for submission in submissions: compute_report_for(reading_dict, submission) compute_report_for(numeracy_dict, submission, is_numeracy=True) # compute percentages for reading/num reports compute_percentages(reading_dict) compute_percentages(numeracy_dict) # sort/transform reports for template reading_reports = sort_reports(reading_dict) numeracy_reports = sort_reports(numeracy_dict) context.update({'teacher': teacher, 'reading_reports': reading_reports, 'numeracy_reports': numeracy_reports}) return render(request, 'detail_teacher.html', context)