Skip to content

Commit 09c600f

Browse files
authored
Merge pull request #186 from kobotoolbox/185-autoreport-crashes-with-non-numeric-in-numeric-field
autoreport ignores non-numeric values in numeric field
2 parents dc06fd7 + ff19064 commit 09c600f

File tree

3 files changed

+61
-4
lines changed

3 files changed

+61
-4
lines changed

src/formpack/pack.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,6 @@ def get_fields_for_versions(self, versions=-1, data_types=None):
233233
if isinstance(data_types, str_types):
234234
data_types = [data_types]
235235

236-
237236
# tmp2 is a 2 dimensions list of `field`.
238237
# First dimension is the position of fields where they should be in the latest version
239238
# Second dimension is their position in the stack at the same position.

src/formpack/reporting/autoreport.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import (division, print_function, unicode_literals)
44

5+
import logging
56
from collections import Counter, defaultdict
67

78
from ..constants import UNSPECIFIED_TRANSLATION
@@ -70,9 +71,18 @@ def _calculate_stats(self, submissions, fields, versions, lang):
7071
counter = metrics[field.name]
7172
raw_value = entry.get(field.path)
7273
if raw_value is not None:
73-
values = list(field.parse_values(raw_value))
74-
counter.update(values)
75-
counter['__submissions__'] += 1
74+
try:
75+
values = list(field.parse_values(raw_value))
76+
except ValueError as e:
77+
# TODO: Remove try/except when
78+
# https://github.com/kobotoolbox/formpack/issues/151
79+
# is fixed?
80+
logging.warning(str(e), exc_info=True)
81+
# Treat the bad value as a blank response
82+
counter[None] += 1
83+
else:
84+
counter.update(values)
85+
counter['__submissions__'] += 1
7686
else:
7787
counter[None] += 1
7888

tests/test_autoreport.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,3 +381,51 @@ def test_disaggregate_extended_fields(self):
381381
frequency_responses = [x[0] for x in value_list.get("frequency")]
382382
assert percentage_responses == frequency_responses
383383
assert percentage_responses[-1] == "..."
384+
385+
def test_stats_with_non_numeric_value_for_numeric_field(self):
386+
'''
387+
A string response to an integer question, for example, should not cause
388+
a crash; it should be treated as if no response was provided
389+
'''
390+
391+
title = 'Just one number'
392+
schemas = [{
393+
'content': {
394+
'survey': [
395+
{
396+
'type': 'integer',
397+
'name': 'the_number',
398+
'label': 'Enter the number!'
399+
}
400+
]
401+
}
402+
}]
403+
submissions = [
404+
{'the_number': 10},
405+
{'the_number': 20},
406+
{'the_number': 30},
407+
{'the_number': 'oops!'},
408+
]
409+
fp = FormPack(schemas, title)
410+
411+
report = fp.autoreport()
412+
stats = report.get_stats(submissions)
413+
414+
assert stats.submissions_count == len(submissions)
415+
416+
stats = [(unicode(repr(f)), n, d) for f, n, d in stats]
417+
expected = [(
418+
"<NumField name='the_number' type='integer'>", 'the_number',
419+
{
420+
'mean': 20.0,
421+
'median': 20,
422+
'mode': u'*',
423+
'not_provided': 1,
424+
'provided': 3,
425+
'show_graph': False,
426+
'stdev': 10.0,
427+
'total_count': 4
428+
}
429+
)]
430+
for (i, stat) in enumerate(stats):
431+
assert stat == expected[i]

0 commit comments

Comments
 (0)