Пример #1
0
def main(rulepath,
         datapath,
         detailed=False,
         name_filter=None,
         is_student=False):
    ruleset = rules.parse_file(rulepath)
    exported = aaps.read_exported_kattis_file(datapath)

    def handle_student(student):
        kattis = aaps.KattisResult()
        if is_student:
            kattis.resolve_sessions_with_input()
        add_sub = lambda sub: kattis.add_submission(sub)
        util.map_now(add_sub, student.submissions)
        context = resolver.make_context()
        plugins = kattis.get_plugins()
        add_plugin = lambda c, r: resolver.context_add_plugin(context, c, r)
        util.starmap_now(add_plugin, plugins)
        result = resolver.resolve(ruleset, context)
        return make_student_result(student, ruleset, kattis, context, result)

    def name_match(student):
        return name_filter.lower() in student.name or \
            name_filter.lower() in student.username

    students = util.filter_now(name_match, exported.students)
    student_results = util.map_now(handle_student, students)

    print_result = lambda result: print_student_result(result, detailed)
    util.map_now(print_result, student_results)
Пример #2
0
def resolve(ruleset, context):
    rules = ruleset.rules
    result = Result()
    context_set_result(context, result)

    def on_rule_fail(rule):
        result_update_failed_goal(result, rule)

    def on_rule_success(rule):
        points = 0
        try:
            points = context.value_expression(rule.points)
        except TypeError as e:
            print('Got a TypeError saying "{}"'.format(e))
            print('while trying to resolve points for: \n\n{}\n'.format(rule))
        result_update_resolved_goal(result, rule, points)

    def process_rule(rule):
        needs = context.bool_expression(rule.needs)
        success = lambda: on_rule_success(rule)
        fail = lambda: on_rule_fail(rule)
        util.crossroad(lambda: needs, success, fail)

    def process_by_index(index):
        process_rule(rules[index])

    order = topological_order(rules)
    util.map_now(process_by_index, order)
    return result
Пример #3
0
def main():
    check_config_path_or_write_help_message()
    config = get_config()
    reply = login(config)

    def get_profile_page(idx):
        hostname = urlparse(config.get('kattis', 'loginurl')).netloc
        username = config.get('user', 'username')
        return 'https://{}/users/{}?page={}'.format(hostname, username, idx)

    # If someone has over 1000 pages then they surely will have no problem
    # finding out how this looks and rewriting this to work for them.
    one_thousand_pages = [get_profile_page(idx) for idx in range(1000)]
    allpages = collections.deque(one_thousand_pages)
    collected = collections.deque()
    page1 = allpages[0]

    def collector(info):
        collected.append(info)
        if len(collected) % 100 == 0:
            print('Collected at least {} entries'.format(
                100 * (len(collected) // 100)),
                  file=sys.stderr)

    def destructor():
        return 'IShouldStopNow'

    def thread_main():
        for idx in range(100):
            try:
                page = allpages.popleft()
            except IndexError:
                return
            result = scrape_site(page, reply.cookies, collector, destructor)
            if result == 'IShouldStopNow':
                return

    threads = [threading.Thread(target=thread_main) for _ in range(10)]
    start_thread = lambda t: t.start()
    util.map_now(start_thread, threads)
    for thread in threads:
        thread.join()
    student = {'username': '******', 'name': 'Me', 'email': '', 'submissions': []}

    for submission in collected:
        judgement = 'Accepted' if 'accepted' in submission[
            'status'] else 'Wrong Answer'
        item = {
            'time': submission['time'],
            'judgement': judgement,
            'problem': submission['problem_id']
        }
        student['submissions'].append(item)

    data = {"students": [student], "sessions": []}
    print(json.dumps(data))
Пример #4
0
 def add_student_session_problems(starttime, student, problems):
     is_student = lambda s: s.username == student
     student_data = util.find(is_student, result.students)
     student_not_exist = util.constant(not bool(student_data))
     is_solved = lambda problem: 'solve_time' in problem
     add_problem = lambda problem: add_session_problem(
         student_data, problem, starttime)
     handle_single_problem = util.cond([(student_not_exist, util.noop),
                                        (is_solved, add_problem)])
     util.map_now(handle_single_problem, problems)
Пример #5
0
 def json_to_student(root):
     username = root.get('username', '[No Username]')
     name = root.get('name', '[No Name]')
     email = root.get('email', '')
     json_submissions = root.get('submissions', [])
     submissions = util.map_now(json_to_submission, json_submissions)
     student = make_student(username, name, email)
     add_sub = lambda sub: student_add_submission(student, sub)
     util.map_now(add_sub, submissions)
     return student
Пример #6
0
 def handle_student(student):
     kattis = aaps.KattisResult()
     if is_student:
         kattis.resolve_sessions_with_input()
     add_sub = lambda sub: kattis.add_submission(sub)
     util.map_now(add_sub, student.submissions)
     context = resolver.make_context()
     plugins = kattis.get_plugins()
     add_plugin = lambda c, r: resolver.context_add_plugin(context, c, r)
     util.starmap_now(add_plugin, plugins)
     result = resolver.resolve(ruleset, context)
     return make_student_result(student, ruleset, kattis, context, result)
Пример #7
0
 def resolver(context, tree):
     # If a problem does not have a deadline, then assume it is a lab
     # and move the deadline to something like 100 years from now.
     problems = util.map_now(make_problem, tree['uppgift']['problems'])
     deadline = tree['uppgift'].get('deadline', '01-01-2117 08:00')
     points = lambda problem: count_for_single_problem(problem, deadline)
     return sum(map(points, problems))
Пример #8
0
def parse_json(json, _from_file=''):
    # Create ruleset and add rules from json
    ruleset = make_ruleset()
    add_rule = lambda rule: ruleset_add_rule(ruleset, make_rule_from_json(rule)
                                             )
    rules = json.get('rules', [])
    util.map_now(add_rule, rules)

    # Find all includes and include their rules as well
    include_group = get_include_group(json.get('includes', []))

    def is_not_origin(fpath):
        return os.path.abspath(fpath) != os.path.abspath(_from_file)

    def add_rules_from_file(fpath):
        util.map_now(add_rule, get_rules_from_file(fpath))

    include_group_except_self = filter(is_not_origin, include_group)
    util.map_now(add_rules_from_file, include_group_except_self)

    return ruleset
Пример #9
0
 def add_session(session):
     # starttime in seconds since epoch
     starttime = int(session['starttime'])
     results = session['results']
     add_team = lambda result: add_team_result(starttime, result)
     util.map_now(add_team, results)
Пример #10
0
 def add_team_result(starttime, result):
     members = result['members']
     problems = result['problems']
     add_for_student = lambda student: add_student_session_problems(
         starttime, student, problems)
     util.map_now(add_for_student, members)
Пример #11
0
def read_exported_kattis_file(fpath):
    with open(fpath, 'r') as fp:
        content = json.load(fp)
    json_students = content['students']

    def normalize_time(timestr):
        # Time is given in two different ways. Eiter '%Y-%m-%d %H:%M:%S'
        # or '%H:%M:%S' and in the latter it is supposed to be today.
        items = timestr.split('-')
        if len(items) <= 1:
            # Add date in front, it is the date for today
            today = time.localtime()
            return '{}-{}-{} {}'.format(today.tm_year, today.tm_mon,
                                        today.tm_mday, timestr)
        return timestr

    def json_to_submission(submission):
        problem_id = submission['problem']
        judgement = submission['judgement']
        subtime = normalize_time(submission['time'])
        judgement_translation_map = {
            'Wrong Answer': 'WA',
            'Time Limit Exceeded': 'TLE',
            'Accepted': 'AC',
            'Run Time Error': 'RTE',
            'Memory Limit Exceeded': 'MLE',
        }
        inputtimeformat = '%Y-%m-%d %H:%M:%S'
        time_struct = time.strptime(subtime, inputtimeformat)
        year, month, day, hour, minute = time_struct[:5]
        output_time = '{}-{}-{} {}:{}'.format(day, month, year, hour, minute)
        result = judgement_translation_map.get(judgement, '')
        return make_submission(problem_id, output_time, result)

    def json_to_student(root):
        username = root.get('username', '[No Username]')
        name = root.get('name', '[No Name]')
        email = root.get('email', '')
        json_submissions = root.get('submissions', [])
        submissions = util.map_now(json_to_submission, json_submissions)
        student = make_student(username, name, email)
        add_sub = lambda sub: student_add_submission(student, sub)
        util.map_now(add_sub, submissions)
        return student

    result = make_exported_kattis()
    students = util.map_now(json_to_student, json_students)
    add_student = lambda student: exported_kattis_add_student(result, student)
    util.map_now(add_student, students)

    def solve_time(starttime, solvetime):
        solvetime_in_s = solvetime * 60
        t = time.ctime(starttime + solvetime_in_s)
        year, month, day, hour, minute = t[:5]
        return '{}-{}-{} {}:{}'.format(day, month, year, hour, minute)

    def add_session_problem(student, problem, starttime):
        timestr = solve_time(starttime, problem['solve_time'])
        problem_id = problem['problem_name']
        submission = make_submission(problem_id, timestr, 'AC')
        student_add_submission(student, submission)

    def add_student_session_problems(starttime, student, problems):
        is_student = lambda s: s.username == student
        student_data = util.find(is_student, result.students)
        student_not_exist = util.constant(not bool(student_data))
        is_solved = lambda problem: 'solve_time' in problem
        add_problem = lambda problem: add_session_problem(
            student_data, problem, starttime)
        handle_single_problem = util.cond([(student_not_exist, util.noop),
                                           (is_solved, add_problem)])
        util.map_now(handle_single_problem, problems)

    def add_team_result(starttime, result):
        members = result['members']
        problems = result['problems']
        add_for_student = lambda student: add_student_session_problems(
            starttime, student, problems)
        util.map_now(add_for_student, members)

    def add_session(session):
        # starttime in seconds since epoch
        starttime = int(session['starttime'])
        results = session['results']
        add_team = lambda result: add_team_result(starttime, result)
        util.map_now(add_team, results)

    util.map_now(add_session, content['sessions'])

    return result
Пример #12
0
 def add_rev_dependency(key, values):
     util.map_now(lambda val: rule_rev_dependency[val].append(key), values)
Пример #13
0
 def find_and_add_goals(index, rule):
     get_need = find_expressions('get', rule.needs)
     get_point = find_expressions('get', rule.points)
     all_goals = get_need + get_point
     add_goal = lambda expr: goal_dependencies[index].add(expr['get'])
     util.map_now(add_goal, all_goals)
Пример #14
0
def topological_order(rules):
    # 1. Find each rule and the goals that it depends on
    # 2. Create a dependency tree where each rule depends
    #    on all rules that go towards what they depend on
    # 3. Solve dependency with toposort

    goal_dependencies = collections.defaultdict(set)

    def find_and_add_goals(index, rule):
        get_need = find_expressions('get', rule.needs)
        get_point = find_expressions('get', rule.points)
        all_goals = get_need + get_point
        add_goal = lambda expr: goal_dependencies[index].add(expr['get'])
        util.map_now(add_goal, all_goals)

    util.starmap_now(find_and_add_goals, enumerate(rules))

    def is_dependency_rule(index, original_idx):
        return rules[index].towards in goal_dependencies[original_idx]

    def find_rule_dependency(index):
        indices = range(len(rules))
        # Note: also include self, because we can have the case that a user writes
        # a rule that depends on itself being completed...
        indexes_to_add = filter(lambda idx: is_dependency_rule(idx, index),
                                indices)
        return list(indexes_to_add)

    rule_dependency = util.map_now(find_rule_dependency, range(len(rules)))
    rule_rev_dependency = [[] for _ in range(len(rules))]

    def add_rev_dependency(key, values):
        util.map_now(lambda val: rule_rev_dependency[val].append(key), values)

    util.starmap_now(add_rev_dependency, enumerate(rule_dependency))
    connection_count = [len(x) for x in rule_dependency]

    # rule_rev_dependency is our dependency mapping and connection_count count
    # how many unsolved we depend on

    def should_add_to_queue(index):
        return connection_count[index] == 0

    def add_to_queue(index):
        queue.append(index)

    def process_item(index):
        connection_count[index] -= 1
        util.cond([(should_add_to_queue, add_to_queue)])(index)

    queue = list(filter(should_add_to_queue, range(len(rules))))

    idx = 0
    # We need to continuously evaluate the length of the queue so we
    # need to run with a while loop -.-
    while idx < len(queue):
        item = queue[idx]
        util.map_now(process_item, rule_rev_dependency[item])
        idx += 1

    return queue
Пример #15
0
 def search_in_list(seq):
     return util.map_now(find_expression_rec, seq)
Пример #16
0
 def process_all_rows():
     data = util.map_now(process_row, rows)
     util.map_now(collector, data)
Пример #17
0
 def resolver(context, tree):
     expression = tree[string]
     values = util.map_now(lambda expr: handle_expr(context, expr),
                           get_values(expression))
     return oper(values)
Пример #18
0
 def add_rules_from_file(fpath):
     util.map_now(add_rule, get_rules_from_file(fpath))