Source code for vulyk.cli.stats
# -*- coding: utf-8 -*-
from collections import OrderedDict
from mongoengine import Q
from vulyk.app import TASKS_TYPES
from vulyk.models.tasks import Batch, AbstractTask
[docs]def batch_completeness(batch_name: str, task_type: str) -> OrderedDict:
"""
Gathers completeness stats on every batch using 2 metrics:
- actually completed tasks
- actual reports to total planned amount ratio (tasks * redundancy)
:param batch_name: Optional name of batch to filter by
:type batch_name: str
:param task_type: Optional name of task type to filter by
:type task_type: str
:rtype: OrderedDict
"""
batches = OrderedDict()
rs = lambda batch: AbstractTask.objects(batch=batch)
percent = lambda done, total: (float(done) / (total or done or 1)) * 100
query = Q(id=batch_name) if batch_name else Q()
query &= Q(task_type=task_type) if task_type else Q()
for b in Batch.objects(query).order_by('id'):
batches[b.id] = {
'total': 0,
'flag': 0,
'flag_percent': 0,
'answers': 0,
'answers_percent': 0,
'breakdown': ''}
if len(rs(b.id)) > 0:
rs_task = TASKS_TYPES[rs(b.id).first().task_type]
answers = rs(b.id).filter(closed=False).sum('users_count')
answers_all = rs(b.id).sum('users_count')
answers_mix = answers + (rs_task.redundancy * b.tasks_processed)
answers_needed = b.tasks_count * rs_task.redundancy
batches[b.id] = {
'total': b.tasks_count,
'flag': b.tasks_processed,
'flag_percent': percent(b.tasks_processed, b.tasks_count),
'answers': answers_all,
'answers_percent': percent(answers_mix, answers_needed),
'breakdown': _breakdown_by_processed(b.id)
}
return batches
def _breakdown_by_processed(batch: str) -> str:
"""
Combines stats on responses count ratio for certain batch
:param batch: Batch ID
:type batch: str
:returns: string ready to be displayed in CLI
:rtype: str
"""
result = []
rs = AbstractTask.objects(batch=batch)
for i in rs.item_frequencies('users_count').items():
result.append('{:>12}: {}'.format(*i))
return '\n'.join(result)