Example #1
0
def get_answer_value(valid_answers, cur=None):
    print('Valid Answers:')
    if all([isinstance(k, int) for k in valid_answers]):
        for k, v in enumerate(valid_answers):
            if k == cur:
                print('[%d]' % v)
            else:
                print(' %d ' % v)
        if cur is None:
            choice = int(input('Enter a value: '))
        else:
            choice = int(ifinput('Enter a value: ', valid_answers[cur]))
        try:
            choice = [k for k, v in enumerate(valid_answers) if v == choice][0]
        except IndexError:
            return -1
    else:
        for k, v in enumerate(valid_answers):
            if k == cur:
                print('[%d: %s]' % (k+1, v))
            else:
                print(' %d: %s ' % (k+1, v))
        if cur is None:
            choice = int(input('Select an answer 1-%d:' % len(valid_answers)))
        else:
            choice = int(ifinput('Select an answer 1-%d:' % len(valid_answers), cur+1))
        choice -= 1
    return choice
Example #2
0
    def merge_answers(self, question, answers, merge_to=None):
        """
        Merge one or more answer values together, keeping the sequence of answers the same.  References to the
        merged answers in criteria or caveats will be replaced with a reference to the 'merge_to' answer.

        examples:
        self.merge_answers(53, ['low-medium', 'medium'], merge_to='medium')
        will change all entries with 'low-medium' answer values to 'medium'.

        self.merge_answers(53, ['low-medium', 'medium'], merge_to='high')
        will change all entries with 'low-medium' or 'medium' answer values to 'high'.

        If merge_to is omitted, defaults to the first answer listed in the answers argument.

        self.merge_answers(53, ['low-medium', 'medium'])
        will change all entries with 'medium' answer values to 'low-medium'.

        In all cases the merged answers are subsequently deleted.

        pandas was a really terrible choice, internally.

        :param question:
        :param answers:
        :param merge_to:
        :return:
        """
        if isinstance(answers, str):
            answers = [answers]
        cur = self._questions[question].valid_answers
        ans_ind = [indices(cur, lambda x: x == ans)[0] for ans in answers]
        if merge_to is None:
            merge_ind = ans_ind[0]
        else:
            merge_ind = indices(cur, lambda x: x == merge_to)[0]

        mapping = range(len(cur))
        for i in mapping:
            if i in ans_ind:
                mapping[i] = merge_ind

        print ("Merging answers into %s:" % cur[merge_ind])
        for i in ans_ind:
            print (" %s" % cur[i])

        if ifinput("Really continue?", "y") != "y":
            print ("NOT merged.")
            return

        new_cri, new_cav = self._remap_answers(question, mapping)
        self._criteria = new_cri
        self._caveats = new_cav
        for i in ans_ind:
            if i != merge_ind:
                self.delete_answer(question, cur[i])
Example #3
0
    def delete_answer(self, question, answer):
        """
        Deletes all references to the supplied answer.  If any references are found, the user will be prompted for
        confirmation prior to deleting them.

        This method has to do three things: delete criteria / caveat entries with the matching question+answer,
        re-map all the answers for that question to their new indices,
        and delete the designated answer from the question's answer list

        :param question:
        :param answer:
        :return:
        """
        cur = self._questions[question].valid_answers
        ind = [k for k, v in enumerate(cur) if v == answer]
        assert len(ind) == 1, "Not enough / too many answers found"
        ind = ind[0]

        cri_index = (self._criteria['QuestionID']
                     == question) & (self._criteria['Threshold'] == ind)
        cav_index = (self._caveats['QuestionID']
                     == question) & (self._caveats['Answer'] == ind)

        check = False
        if len(cri_index.loc[cri_index]) > 0:
            print('Matching Criteria:')
            print(self._criteria.loc[cri_index])
            check = True

        if len(cav_index.loc[cav_index]) > 0:
            print('Matching Caveats:')
            print(self._caveats.loc[cav_index])
            check = True

        if check:
            if ifinput('Really delete this answer?', 'y') != 'y':
                print('NOT deleted.')
                return

        a = range(len(cur))
        mapping = a[:ind] + [None] + a[ind:-1]

        new_cri, new_cav = self._remap_answers(question, mapping)

        new_cri = new_cri.loc[~cri_index]
        new_cav = new_cav[~cav_index]

        # 'atomic' update
        del cur[ind]
        self._criteria = new_cri
        self._caveats = new_cav
Example #4
0
    def delete_answer(self, question, answer):
        """
        Deletes all references to the supplied answer.  If any references are found, the user will be prompted for
        confirmation prior to deleting them.

        This method has to do three things: delete criteria / caveat entries with the matching question+answer,
        re-map all the answers for that question to their new indices,
        and delete the designated answer from the question's answer list

        :param question:
        :param answer:
        :return:
        """
        cur = self._questions[question].valid_answers
        ind = [k for k, v in enumerate(cur) if v == answer]
        assert len(ind) == 1, "Not enough / too many answers found"
        ind = ind[0]

        cri_index = (self._criteria["QuestionID"] == question) & (self._criteria["Threshold"] == ind)
        cav_index = (self._caveats["QuestionID"] == question) & (self._caveats["Answer"] == ind)

        check = False
        if len(cri_index.loc[cri_index]) > 0:
            print ("Matching Criteria:")
            print (self._criteria.loc[cri_index])
            check = True

        if len(cav_index.loc[cav_index]) > 0:
            print ("Matching Caveats:")
            print (self._caveats.loc[cav_index])
            check = True

        if check:
            if ifinput("Really delete this answer?", "y") != "y":
                print ("NOT deleted.")
                return

        a = range(len(cur))
        mapping = a[:ind] + [-1] + a[ind:-1]  # -1 gets deleted below

        new_cri, new_cav = self._remap_answers(question, mapping)

        new_cri = new_cri.loc[~cri_index]
        new_cav = new_cav[~cav_index]

        # 'atomic' update
        del cur[ind]  # aha! delete by reference!
        self._criteria = new_cri
        self._caveats = new_cav