Example #1
0
def parse_and_eval(string, values=[]):
    expr, variables = parse_webwork(string)
    try:
        if expr:
            if len(variables) == 0:
                etree = eval_parsed(expr)
                return etree, {}
            if len(variables) != len(values):
                return expr, variables  # if the number of values does
                # not match number of variables,
                # return the description of the
                # variables.
            else:
                # if number of values matches
                # number of variables then
                # substitute values for
                # variables and call parser
                # again on numerical expression.
                subs_string = substitute(string, variables, values)
                subs_expr, variables = parse_webwork(subs_string)
                assert len(variables) == 0
                if subs_expr:
                    etree = eval_parsed(subs_expr)
                    return etree, {}

        else:
            raise Exception
    except:
        log.error('Exception in parse_and_eval, string=%s, parsed=%s' %
                  (string, str(expr)))
        traceback.print_exc(file=sys.stdout)
        return None
Example #2
0
def find_matches(answer, attempt):

    logger.debug('find_matches recieved answer=' + str(answer) + ' attempt=' +
                 str(attempt))
    attempt_parsed = parse_webwork(attempt)
    logger.debug('calling eval_parsed on on' + str(attempt_parsed))
    attempt_tree = eval_parsed(attempt_parsed)
    logger.debug('calling flatten on' + str(attempt_tree))
    attempt_list = flatten(attempt_tree, 't')
    logger.debug('attempt list:\n' + str(attempt_list))

    answer_parsed = parse_webwork(answer)
    logger.debug('calling eval_parsed on on' + str(answer_parsed))
    answer_tree = eval_parsed(answer_parsed)
    logger.debug('calling flatten on' + str(answer_tree))
    answer_list = flatten(answer_tree, 'c')
    logger.debug('answer list\n' + str(answer_list))

    combined_list = sorted(answer_list + attempt_list, key=lambda x: x[0])
    logger.debug('combined list\n' + str(combined_list))

    Hits = find_Hits(combined_list)
    logger.debug('Hits:\n' + str(Hits))

    final_matches = find_dominating_hits(Hits, answer, attempt)

    return final_matches
def parse_and_eval(string,values=[]):
    expr,variables = parse_webwork(string)
    try:
        if expr:
            if len(variables)==0:
                etree = eval_parsed(expr)
                return etree,{}
            if len(variables)!=len(values):
                return expr,variables # if the number of values does
                                      # not match number of variables,
                                      # return the description of the
                                      # variables.
            else:
                                      # if number of values matches
                                      # number of variables then
                                      # substitute values for
                                      # variables and call parser
                                      # again on numerical expression.
                subs_string=substitute(string,variables,values)
                subs_expr,variables=parse_webwork(subs_string)
                assert len(variables)==0;
                if subs_expr:
                    etree=eval_parsed(subs_expr)
                    return etree,{}
                        
        else:
            raise Exception
    except:
        log.error('Exception in parse_and_eval, string=%s, parsed=%s'%(string,str(expr)))
        traceback.print_exc(file=sys.stdout)
        return None
    def from_string(cls, string):
        """
        Creates expression tree from a string.

        Throws webwork_parser.WebworkParseException on failure
        """
        data = webwork_parser.parse_webwork(string)
        return cls(data)
Example #5
0
def parse_and_collect_numbers(string):
    try:
        parse_tree = parse_webwork(string)
        eval_tree = eval_parsed(parse_tree)
        eval_numbers = Collect_numbers(eval_tree)
        return set(eval_numbers.keys())
    except:
        return set()
def parse_and_collect_numbers(string):
    try:
        parse_tree = parse_webwork(string)
        eval_tree = eval_parsed(parse_tree)
        eval_numbers = Collect_numbers(eval_tree)
        return set(eval_numbers.keys())
    except:
        return set()
    def from_string(cls, string):
        """
        Creates expression tree from a string.

        Throws webwork_parser.WebworkParseException on failure
        """
        data = webwork_parser.parse_webwork(string)
        return cls(data)
Example #8
0
def parse_and_eval(string, variables=None):
    expr = parse_webwork(string)
    if expr:
        try:
            etree = eval_parsed(expr, variables)
            return expr, etree
        except:
            return (None, None)
    else:
        return (None, None)
def parse_and_eval(string, variables=None):
    expr = parse_webwork(string)
    if expr:
        try:
            etree = eval_parsed(expr, variables)
            return expr, etree
        except:
            return (None, None)
    else:
        return (None, None)
def parse_and_collect_numbers(string):
    try:
        parse_tree, variables = parse_webwork(string)
        if len(variables)==0:
            eval_tree = eval_parsed(parse_tree)
            eval_numbers = Collect_numbers(eval_tree)
            return set(eval_numbers.keys())
        else: 
            return Eval_with_Variables(string,variables)
    except:
        return set()
Example #11
0
def parsed(string):
    expr = parse_webwork(string)
    if expr:
        try:
            etree = eval_parsed(expr)
            nums = Collect_numbers(etree)
            return etree, nums
        except:
            return (None, None)
    else:
        return (None, None)
def parsed(string):
    expr = parse_webwork(string)
    if expr:
        try:
            etree = eval_parsed(expr)
            nums = Collect_numbers(etree)
            return etree, nums
        except:
            return (None, None)
    else:
        return (None, None)
Example #13
0
def parse_and_collect_numbers(string):
    try:
        parse_tree, variables = parse_webwork(string)
        if len(variables) == 0:
            eval_tree = eval_parsed(parse_tree)
            eval_numbers = Collect_numbers(eval_tree)
            return set(eval_numbers.keys())
        else:
            return Eval_with_Variables(string, variables)
    except:
        return set()
Example #14
0
def parse_eval(string):
    """ Given an expression, return it's parse tree and it's evaluation tree """
    expr = parse_webwork(string)
    if expr:
        try:
            etree = eval_parsed(expr)
            return expr, etree
        except:
            return (None, None)
    else:
        return (None, None)
def parse_eval(string):
    """ Given an expression, return it's parse tree and it's evaluation tree """
    expr = parse_webwork(string)
    if expr:
        try:
            etree = eval_parsed(expr)
            return expr, etree
        except:
            return (None, None)
    else:
        return (None, None)
def parse_pg_file(pg_file):
    answer_re = re.compile(".*\[_+\]{(.*)}")
    compute_re = re.compile("Compute\(\"(.*)\"\)")
    with open(os.path.expanduser(pg_file), 'r') as f:
        for line in f:
            m = answer_re.match(line)
            if m:
                print line
                print m.group(1)
                mc = compute_re.match(m.group(1))
                if mc:
                    print mc.group(1)
                    parsed = parse_webwork(mc.group(1))
                    print parsed
Example #17
0
def parse_pg_file(pg_file):
    answer_re = re.compile(".*\[_+\]{(.*)}")
    compute_re = re.compile("Compute\(\"(.*)\"\)")
    with open(os.path.expanduser(pg_file), 'r') as f:
        for line in f:
            m = answer_re.match(line)
            if m:
                print line
                print m.group(1)
                mc = compute_re.match(m.group(1))
                if mc:
                    print mc.group(1)
                    parsed = parse_webwork(mc.group(1))
                    print parsed
    def post(self):
        '''
            Parses an expression and returns the parsed data structure.

            Sample arguments:
            expression="1+1"

            Response:
                [['+', [0,2]], 1, 1]
            '''
        expression = self.get_argument('expression')
        etree = parse_webwork(expression)
        if etree:
            self.write(json.dumps(etree))
        else:
            logger.error("Failed to parse expression '%s'", expression)
            self.set_status(400)
            self.write(json.dumps({'error': 'Error parsing expression %s' % expression}))
Example #19
0
    def post(self):
        '''
            Parses an expression and returns the parsed data structure.

            Sample arguments:
            expression="1+1"

            Response:
                [['+', [0,2]], 1, 1]
            '''
        expression = self.get_argument('expression')
        etree = parse_webwork(expression)
        if etree:
            self.write(json.dumps(etree))
        else:
            logger.error("Failed to parse expression '%s'", expression)
            self.set_status(400)
            self.write(
                json.dumps(
                    {'error': 'Error parsing expression %s' % expression}))
# e3=webwork_parser.parse_webwork('C(6*7*5,5^3)+9/(31+18)')
# print e3

# We want to cluster all incorrect attempts
# For each incorrect attempt:
#  Parse answer expression into tree
#  (Discard unparseable expressions or something)
#  Stick parse tree into a list

trees = []
part = 0
for i, a in answers.iteritems():
    if df.scores[i][part] == '0':
        # Only consider incorrect answers
        try:
            expr = webwork_parser.parse_webwork(a[part])
            n = ExpressionNode(expr)
            trees.append(n)
        except webwork_parser.WebworkParseException:
            pass

print len(trees), 'incorrect expressions parsed'

"""
K Medoids Algorithm

1. Initialize: randomly select k of the n data points as the medoids
2. Associate each data point to the closest medoid.
3. For each medoid m

    1. For each non-medoid data point o
    def get(self):
        '''
            Parses all expressions for a given question

            Sample arguments:
            course='CSE103_Fall14',
            set_id='Week1',
            problem_id=1,
            part_id=1
            include_finished=0
            Response:
                ...
            '''
        # Get correct answers
        logger.debug('Starting get')
        self.answer_exps = {}
        course = self.get_argument('course')
        set_id = self.get_argument('set_id')
        problem_id = self.get_argument('problem_id')
        part_id = int(self.get_argument('part_id'))
        include_finished = (int(self.get_argument('include_finished', 1)) == 1)

        source_file = conn.query('''
            select source_file from {course}_problem
            where
                problem_id={problem_id} and
                set_id="{set_id}";
        '''.format(course=course, set_id=set_id, problem_id=problem_id))[0]['source_file']
        
        pg_path = os.path.join(webwork_dir, 'courses', course, 'templates', source_file)
        with open(pg_path, 'r') as fin:
            pg_file = fin.read()
        # name  problem_id set_id   user_id  value
        user_variables = conn.query('''SELECT * from {course}_user_variables
        WHERE set_id="{set_id}" AND problem_id = {problem_id};
        '''.format(course=course, set_id=set_id, problem_id=problem_id))
        self.variables_df = pd.DataFrame(user_variables)
        if len(self.variables_df) == 0:
            logger.warn("No user variables saved for assignment %s, please run the save_answers script", set_id)
            # raise tornado.web.HTTPError(500)
        answer_re = re.compile('\[__+\]{(?:Compute\(")?(.+?)(?:"\))?}')
        answer_boxes = answer_re.findall(pg_file)
        self.part_answer = answer_boxes[part_id-1]
        self.answer_ptree = parse_webwork(self.part_answer)

        # Get attempts by part
        if include_finished:
            query = '''SELECT * from {course}_answers_by_part
            WHERE set_id="{set_id}" AND problem_id = {problem_id}
            AND part_id={part_id};
            '''.format(course=course, set_id=set_id, problem_id=problem_id,
                       part_id=part_id)
        else:
            # This self join query idea comes from http://stackoverflow.com/a/4519302/90551
            # You can do this more clearly with subqueries but it's super slow
            query = '''SELECT abp.* FROM {course}_answers_by_part as abp
            LEFT JOIN {course}_answers_by_part AS abp2
            ON abp.problem_id = abp2.problem_id AND abp.set_id = abp2.set_id
            AND abp.part_id = abp2.part_id AND abp.user_id = abp2.user_id AND abp2.score = '1'
            WHERE abp.set_id='{set_id}' AND abp.problem_id={problem_id}
            AND abp.part_id={part_id} AND abp2.user_id IS NULL;
            '''.format(course=course, set_id=set_id, problem_id=problem_id,
                       part_id=part_id)

        logger.debug('Before sending SQL')
        answers = conn.query(query)
        logger.debug('After sending SQL')

        all_correct_terms = set()
        correct_terms_map = defaultdict(lambda: defaultdict(list))
        incorrect_terms_map = defaultdict(lambda: defaultdict(list))
        # Parse and evaluate all answers
        for a in answers:
            # {'user_id': u'acpatel', 'timestamp': datetime.datetime(2014, 10, 12, 2, 10, 19), 'id': 284488L, 'score': u'1', 'answer_string': u'C(55,6)', 'part_id': 2L, 'problem_id': 10L, 'set_id': u'Week2', 'answer_id': 199326L}
            user_id = a['user_id']
            ans = self.answer_for_student(user_id)

            if a['score'] != '1':
                etree, nums = parsed(a['answer_string'])
                if etree and nums:
                    correct_terms = self.correct_terms(nums, ans)
                    all_correct_terms |= set(correct_terms)
                    # logger.debug(set(correct_terms))
                    if a['user_id'] not in correct_terms_map[str(sorted(correct_terms))][a['answer_string']]:
                        correct_terms_map[str(sorted(correct_terms))][a['answer_string']].append(a['user_id'])

        out = {}
        out['correct'] = correct_terms_map
        out['correct_terms'] = sorted(all_correct_terms)
        out['incorrect'] = incorrect_terms_map
        out['answer_ptree'] = str(self.answer_ptree)
        self.write(json.dumps(out, default=serialize_datetime))
        logger.debug('Finished')
Example #22
0
                # variables.
            else:
                # if number of values matches
                # number of variables then
                # substitute values for
                # variables and call parser
                # again on numerical expression.
                subs_string = substitute(string, variables, values)
                subs_expr, variables = parse_webwork(subs_string)
                assert len(variables) == 0
                if subs_expr:
                    etree = eval_parsed(subs_expr)
                    return etree, {}

        else:
            raise Exception
    except:
        log.error('Exception in parse_and_eval, string=%s, parsed=%s' %
                  (string, str(expr)))
        traceback.print_exc(file=sys.stdout)
        return None


if __name__ == "__main__":
    string = sys.argv[1]
    print 'input:::', string
    tree, variables = parse_webwork(string)
    print 'output:::', tree, variables
    eval_tree = eval_parsed(tree)
    print 'Eval_tree:::', eval_tree
Example #23
0
def parse_and_collect_numbers(string):
    try:
        parse_tree = parse_webwork(string)
        eval_tree = eval_parsed(parse_tree)
        eval_numbers = Collect_numbers(eval_tree)
        return set(eval_numbers.keys())
    except:
        return set()


def parse_and_eval(string, variables=None):
    expr = parse_webwork(string)
    if expr:
        try:
            etree = eval_parsed(expr, variables)
            return expr, etree
        except:
            return (None, None)
    else:
        return (None, None)


if __name__ == "__main__":
    string = sys.argv[1]
    print 'input:::', string
    tree = parse_webwork(string)
    print 'output:::', tree
    eval_tree = eval_parsed(tree)
    print 'Eval_tree:::', eval_tree
                                      # not match number of variables,
                                      # return the description of the
                                      # variables.
            else:
                                      # if number of values matches
                                      # number of variables then
                                      # substitute values for
                                      # variables and call parser
                                      # again on numerical expression.
                subs_string=substitute(string,variables,values)
                subs_expr,variables=parse_webwork(subs_string)
                assert len(variables)==0;
                if subs_expr:
                    etree=eval_parsed(subs_expr)
                    return etree,{}
                        
        else:
            raise Exception
    except:
        log.error('Exception in parse_and_eval, string=%s, parsed=%s'%(string,str(expr)))
        traceback.print_exc(file=sys.stdout)
        return None

if __name__=="__main__":
    string=sys.argv[1]
    print 'input:::',string
    tree,variables=parse_webwork(string)
    print 'output:::',tree, variables
    eval_tree=eval_parsed(tree)
    print 'Eval_tree:::',eval_tree
Example #25
0
    def get(self):
        '''
            Parses all expressions for a given question

            Sample arguments:
            course='CSE103_Fall14',
            set_id='Week1',
            problem_id=1,
            part_id=1
            include_finished=0
            Response:
                ...
            '''
        # Get correct answers
        logger.debug('Starting get')
        self.answer_exps = {}
        course = self.get_argument('course')
        set_id = self.get_argument('set_id')
        problem_id = self.get_argument('problem_id')
        part_id = int(self.get_argument('part_id'))
        include_finished = (int(self.get_argument('include_finished', 1)) == 1)

        source_file = conn.query('''
            select source_file from {course}_problem
            where
                problem_id={problem_id} and
                set_id="{set_id}";
        '''.format(course=course, set_id=set_id,
                   problem_id=problem_id))[0]['source_file']

        pg_path = os.path.join(webwork_dir, 'courses', course, 'templates',
                               source_file)
        with open(pg_path, 'r') as fin:
            pg_file = fin.read()
        # name  problem_id set_id   user_id  value
        user_variables = conn.query('''SELECT * from {course}_user_variables
        WHERE set_id="{set_id}" AND problem_id = {problem_id};
        '''.format(course=course, set_id=set_id, problem_id=problem_id))
        self.variables_df = pd.DataFrame(user_variables)
        if len(self.variables_df) == 0:
            logger.warn(
                "No user variables saved for assignment %s, please run the save_answers script",
                set_id)
            # raise tornado.web.HTTPError(500)
        answer_re = re.compile('\[__+\]{(?:Compute\(")?(.+?)(?:"\))?}')
        answer_boxes = answer_re.findall(pg_file)
        self.part_answer = answer_boxes[part_id - 1]
        self.answer_ptree = parse_webwork(self.part_answer)

        # Get attempts by part
        if include_finished:
            query = '''SELECT * from {course}_answers_by_part
            WHERE set_id="{set_id}" AND problem_id = {problem_id}
            AND part_id={part_id};
            '''.format(course=course,
                       set_id=set_id,
                       problem_id=problem_id,
                       part_id=part_id)
        else:
            # This self join query idea comes from http://stackoverflow.com/a/4519302/90551
            # You can do this more clearly with subqueries but it's super slow
            query = '''SELECT abp.* FROM {course}_answers_by_part as abp
            LEFT JOIN {course}_answers_by_part AS abp2
            ON abp.problem_id = abp2.problem_id AND abp.set_id = abp2.set_id
            AND abp.part_id = abp2.part_id AND abp.user_id = abp2.user_id AND abp2.score = '1'
            WHERE abp.set_id='{set_id}' AND abp.problem_id={problem_id}
            AND abp.part_id={part_id} AND abp2.user_id IS NULL;
            '''.format(course=course,
                       set_id=set_id,
                       problem_id=problem_id,
                       part_id=part_id)

        logger.debug('Before sending SQL')
        answers = conn.query(query)
        logger.debug('After sending SQL')

        all_correct_terms = set()
        correct_terms_map = defaultdict(lambda: defaultdict(list))
        incorrect_terms_map = defaultdict(lambda: defaultdict(list))
        # Parse and evaluate all answers
        for a in answers:
            # {'user_id': u'acpatel', 'timestamp': datetime.datetime(2014, 10, 12, 2, 10, 19), 'id': 284488L, 'score': u'1', 'answer_string': u'C(55,6)', 'part_id': 2L, 'problem_id': 10L, 'set_id': u'Week2', 'answer_id': 199326L}
            user_id = a['user_id']
            ans = self.answer_for_student(user_id)

            if a['score'] != '1':
                etree, nums = parsed(a['answer_string'])
                if etree and nums:
                    correct_terms = self.correct_terms(nums, ans)
                    all_correct_terms |= set(correct_terms)
                    # logger.debug(set(correct_terms))
                    if a['user_id'] not in correct_terms_map[str(
                            sorted(correct_terms))][a['answer_string']]:
                        correct_terms_map[str(
                            sorted(correct_terms))][a['answer_string']].append(
                                a['user_id'])

        out = {}
        out['correct'] = correct_terms_map
        out['correct_terms'] = sorted(all_correct_terms)
        out['incorrect'] = incorrect_terms_map
        out['answer_ptree'] = str(self.answer_ptree)
        self.write(json.dumps(out, default=serialize_datetime))
        logger.debug('Finished')