Hey, how about returning the boolean if there is no text, and the text otherwise. I think this is sane as any non-empty string evaluates to a True logical value. So anyone using the variable in a logical expression should be fine, while anyone who needs access to the text can get it at the same time.
The reason that this is not supported, is that the string replacement
feature was only added at a later point ...
Benjamin
On Do, 2015-02-12 at 11:05 -0500, Matthew Roy wrote:
> Hi all,
>
> I'm working on some reports that use text boxes with their image
> content input as strings and would like to be able to use the CLI
> filters based on the string content. However, it looks like the
> Locals.__getitem___(self, key) method in sdaps.clifilter boxes (haha)
> the filter expressions into using the return value of
> qobjects[key].get_answer() which, for a Text Question, is always a
> bool (see class Text in sdaps.model.questionnaire ). Unless I'm
> missing something this looks like there's no existing capability to
> filter on the string of the response. Two questions:
>
> 1) Is there something I'm missing that already does this?
> 2) If not, is there any suggestion on the most elegant way to
> incorporate this into filters?
>
> My initial hack is to add an additional check to
> Locals.__getitem__(self, key) that use a regex to search for
> "csvtext(_[0-9_]+)" and and then take the group from the match
> (_[0-9_]+), look for a matching key in self.qobjects, and returns the
> text or array of text. I do not think that will break anyone else's
> filters, but also do not understand this codebase as well as some of
> you might. I assume there may also be a more elegant solution.
>
> If there's any feedback on this I will revise and pull-request the
> patches.
>
> Thanks for your thoughts,
> Matthew Roy
>
>
> The relevant existing code for filtering:
> ========== sdaps.clifilter
> class Locals(object):
> def __init__(self, survey):
> self.survey = survey
> self.qobjects = dict([
> (qobject.id_filter(), qobject)
> for qobject in self.survey.questionnaire.qobjects
> ])
>
> def __getitem__(self, key):
> if key in self.qobjects:
> return self.qobjects[key].get_answer()
> elif key in ['survey_id', 'questionnaire_id', 'global_id',
> 'valid', 'quality', 'recognized', 'verified', 'complete']:
> return getattr(self.survey.sheet, key)
> else:
> raise KeyError
>
>
> def clifilter(survey, expression):
> if expression is None or expression.strip() == '':
> return lambda: True
>
> exp = compile(expression, '<string>', 'eval')
> globals = __builtins__
> locals = Locals(survey)
> return lambda: eval(exp, globals, locals)
>
>
> ========== sdaps.model.questionnaire
> class Text(Question):
>
> def __unicode__(self):
> return unicode().join(
> [Question.__unicode__(self)] +
> [unicode(box) for box in self.boxes]
> )
>
> def get_answer(self):
> '''it's a bool, wether there is content in the textbox
> '''
> assert len(self.boxes) == 1
> return self.boxes[0].data.state
>
>
> === proposed sdaps.clifilter.Locals.__getitem__(self, key)
> def __getitem__(self, key):
> if key in self.qobjects:
> return self.qobjects[key].get_answer()
> elif key in ['survey_id', 'questionnaire_id', 'global_id',
> 'valid', 'quality', 'recognized', 'verified', 'complete']:
> return getattr(self.survey.sheet, key)
> else:
> #try to match the "reporttext" "csvtext" filter parameters
> match = re.match('reporttext(_[0-9_]+)', key)
> if match and match.group(1) in self.qobjects:
> text = ""
> for box in self.qobjects[match.group(1)].boxes:
> text = text + box.data.text
> return text
> match = re.match('csvtext(_[0-9_]+)', key)
> if match and match.group(1) in self.qobjects:
> return
> self.qobjects[match.group(1)].csvdata.export_data()
> #If nothing worked, raise a KeyError
> raise KeyError
>
> === proposed usage
> #csvexport will return a dictionary of text by sub-box
> sdaps PROJECT csv export --filter "'TERM' in csvtext_1_7['1_7_0']"
> #reporttext will just append them all together
> sdaps PROJECT report --filter "'TERM' in reporttext_1_7"
>
>
> --
> Matthew Roy
>
> TurnAround Factor
> Richmond, Virginia
signature.asc
Description: This is a digitally signed message part
