<s> """<STR_LIT>""" <EOL> import api <EOL> import random <EOL> import imp <EOL> import shutil <EOL> import os <EOL> from os import path <EOL> from functools import partial <EOL> from bson import json_util <EOL> from api . common import InternalException , SevereInternalException <EOL> log = api . logger . use ( __name__ ) <EOL> modifiable_problem_fields = [ "<STR_LIT:description>" ] <EOL> seed = "<STR_LIT>" <EOL> def is_autogen_problem ( pid ) : <EOL> """<STR_LIT>""" <EOL> return api . problem . get_problem ( pid = pid ) . get ( "<STR_LIT>" , False ) <EOL> def get_metadata_path ( pid , n ) : <EOL> """<STR_LIT>""" <EOL> return path . join ( get_instance_path ( pid , n = n , public = False ) , "<STR_LIT>" ) <EOL> def write_metadata ( pid , n , data ) : <EOL> """<STR_LIT>""" <EOL> metadata_path = get_metadata_path ( pid , n ) <EOL> with open ( metadata_path , "<STR_LIT:w>" ) as f : <EOL> f . write ( json_util . dumps ( data ) ) <EOL> @ api . cache . memoize ( timeout = <NUM_LIT> , fast = True ) <EOL> def read_metadata ( pid , n ) : <EOL> """<STR_LIT>""" <EOL> metadata_path = get_metadata_path ( pid , n ) <EOL> with open ( metadata_path , "<STR_LIT:r>" ) as f : <EOL> return json_util . loads ( f . read ( ) ) <EOL> def build_problem_instances ( pid , instances ) : <EOL> """<STR_LIT>""" <EOL> problem = api . problem . get_problem ( pid = pid ) <EOL> if not is_autogen_problem ( pid ) : <EOL> raise InternalException ( "<STR_LIT>" . format ( problem [ "<STR_LIT:name>" ] ) ) <EOL> previous_state = seed_generator ( "<STR_LIT>" , pid ) <EOL> instance_path , static_instance_path = get_instance_path ( pid ) , get_static_instance_path ( pid ) <EOL> for autogen_path in [ instance_path , static_instance_path ] : <EOL> log . debug ( "<STR_LIT>" , autogen_path ) <EOL> if not path . isdir ( autogen_path ) : <EOL> log . debug ( "<STR_LIT>" ) <EOL> os . makedirs ( autogen_path ) <EOL> for n in range ( instances ) : <EOL> log . debug ( "<STR_LIT>" , problem [ "<STR_LIT:name>" ] , str ( n ) ) <EOL> build = get_generator ( pid ) . generate ( random , pid , api . autogen_tools , n ) <EOL> autogen_instance_path = get_instance_path ( pid , n = n ) <EOL> file_type_paths = { <EOL> "<STR_LIT>" : { <EOL> "<STR_LIT>" : get_instance_path ( pid , n = n , public = True ) , <EOL> "<STR_LIT>" : get_instance_path ( pid , n = n , public = False ) <EOL> } , <EOL> "<STR_LIT>" : { <EOL> "<STR_LIT>" : get_static_instance_path ( pid , public = True ) , <EOL> "<STR_LIT>" : get_static_instance_path ( pid , public = False ) <EOL> } <EOL> } <EOL> for _ , file_types in file_type_paths . items ( ) : <EOL> for _ , autogen_path in file_types . items ( ) : <EOL> if not path . isdir ( autogen_path ) : <EOL> os . makedirs ( autogen_path ) <EOL> problem_updates = build . get ( "<STR_LIT>" , None ) <EOL> if problem_updates is None : <EOL> raise InternalException ( "<STR_LIT>" . format ( problem [ "<STR_LIT>" ] ) ) <EOL> write_metadata ( pid , n , problem_updates ) <EOL> for file_type , listings in build . items ( ) : <EOL> destination_type = file_type_paths . get ( file_type , None ) <EOL> if destination_type is not None : <EOL> for listing in listings : <EOL> destination = destination_type . get ( listing , None ) <EOL> if destination is not None : <EOL> files = listings [ listing ] <EOL> for f , name in files : <EOL> if path . isfile ( f ) : <EOL> shutil . copyfile ( f , path . join ( destination , name ) ) <EOL> elif path . isdir ( f ) : <EOL> shutil . copytree ( f , autogen_instance_path ) <EOL> api . autogen_tools . clear_build_directories ( ) <EOL> log . debug ( "<STR_LIT>" ) <EOL> random . setstate ( previous_state ) <EOL> def get_generator_path ( pid ) : <EOL> """<STR_LIT>""" <EOL> problem = api . problem . get_problem ( pid = pid ) <EOL> if not is_autogen_problem ( pid ) : <EOL> raise InternalException ( "<STR_LIT>" ) <EOL> if not problem . get ( "<STR_LIT>" , False ) : <EOL> raise InternalException ( "<STR_LIT>" . format ( problem [ "<STR_LIT:name>" ] ) ) <EOL> return path . join ( api . problem . grader_base_path , problem [ "<STR_LIT>" ] ) <EOL> def get_generator ( pid ) : <EOL> """<STR_LIT>""" <EOL> generator_path = get_generator_path ( pid ) <EOL> if not path . isfile ( generator_path ) : <EOL> raise InternalException ( "<STR_LIT>" . format ( generator_path ) ) <EOL> return imp . load_source ( generator_path [ : - <NUM_LIT:3> ] , generator_path ) <EOL> def get_seed ( pid , tid ) : <EOL> """<STR_LIT>""" <EOL> return seed + tid + pid <EOL> def seed_generator ( pid , tid ) : <EOL> """<STR_LIT>""" <EOL> previous_state = random . getstate ( ) <EOL> random . seed ( get_seed ( pid , tid ) ) <EOL> return previous_state <EOL> @ api . cache . memoize ( timeout = <NUM_LIT> , fast = True ) <EOL> def get_instance_number ( pid , tid ) : <EOL> """<STR_LIT>""" <EOL> previous_state = seed_generator ( tid , pid ) <EOL> total_instances = get_number_of_instances ( pid ) <EOL> if total_instances == <NUM_LIT:0> : <EOL> raise InternalException ( "<STR_LIT>" . format ( pid ) ) <EOL> instance_number = random . randint ( <NUM_LIT:0> , total_instances - <NUM_LIT:1> ) <EOL> random . setstate ( previous_state ) <EOL> return instance_number <EOL> @ api . cache . memoize ( timeout = <NUM_LIT> , fast = True ) <EOL> def get_number_of_instances ( pid ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> return [ dirname . isdigit ( ) for dirname in os . listdir ( get_instance_path ( pid , public = False ) ) ] . count ( True ) <EOL> except FileNotFoundError : <EOL> raise InternalException ( "<STR_LIT>" ) <EOL> def get_static_instance_path ( pid , public = True ) : <EOL> """<STR_LIT>""" <EOL> return path . abspath ( path . join ( get_instance_path ( pid , public = public ) , "<STR_LIT>" ) ) <EOL> def get_instance_path ( pid , n = "<STR_LIT>" , public = True ) : <EOL> """<STR_LIT>""" <EOL> generator_path = get_generator_path ( pid ) <EOL> name = api . problem . get_problem ( pid ) [ "<STR_LIT:name>" ] <EOL> instance_path = path . join ( path . dirname ( generator_path ) , "<STR_LIT>" , name , str ( n ) ) <EOL> if public : <EOL> instance_path = path . join ( instance_path , "<STR_LIT>" ) <EOL> return path . abspath ( instance_path ) <EOL> @ api . cache . memoize ( timeout = <NUM_LIT> , fast = True ) <EOL> def get_problem_instance ( pid , tid ) : <EOL> """<STR_LIT>""" <EOL> problem = api . problem . get_problem ( pid = pid ) <EOL> n = get_instance_number ( pid , tid ) <EOL> metadata = read_metadata ( pid , n ) <EOL> if not set ( metadata ) . issubset ( modifiable_problem_fields ) : <EOL> invalid_keys = set ( metadata ) . difference ( modifiable_problem_fields ) <EOL> raise InternalException ( "<STR_LIT>" . format ( pid , invalid_keys ) ) <EOL> problem . update ( metadata ) <EOL> return problem <EOL> def grade_problem_instance ( pid , tid , key ) : <EOL> """<STR_LIT>""" <EOL> if not is_autogen_problem ( pid ) : <EOL> raise InternalException ( "<STR_LIT>" . format ( pid ) ) <EOL> problem = api . problem . get_problem ( pid ) <EOL> n = get_instance_number ( pid , tid ) <EOL> grader_problem_instance = GraderProblemInstance ( pid , tid , n ) <EOL> grader = api . problem . get_grader ( pid ) <EOL> try : <EOL> correct , message = grader . grade ( grader_problem_instance , key ) <EOL> except Exception as e : <EOL> raise SevereInternalException ( "<STR_LIT>" . format ( pid , str ( e ) ) ) <EOL> return { <EOL> "<STR_LIT>" : correct , <EOL> "<STR_LIT>" : problem [ "<STR_LIT>" ] , <EOL> "<STR_LIT:message>" : message <EOL> } <EOL> class GraderProblemInstance ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , pid , tid , n ) : <EOL> self . instance = n <EOL> self . get_instance_path = partial ( get_instance_path , pid , n = n ) <EOL> self . seed_generator = partial ( seed_generator , pid , tid ) <EOL> self . write_metadata = partial ( write_metadata , pid , n ) <EOL> self . read_metadata = partial ( read_metadata , pid ) </s>
