@@ -45,6 +45,11 @@ def _get_statement_path():
4545 return None
4646
4747
48+ def _get_statement_tex ():
49+ return list_files (
50+ ["statement/*.tex" , "testo/*.tex" ], valid_extensions = [".tex" ])
51+
52+
4853def _check_git_has_file (path : str ) -> Optional [bool ]:
4954 # git is not installed
5055 if not find_executable ("git" ):
@@ -61,6 +66,55 @@ def _check_git_has_file(path: str) -> Optional[bool]:
6166 return False
6267
6368
69+ def _check_pdf_statement (interface : IOIUIInterface ):
70+ path = _get_statement_path ()
71+ if not path :
72+ interface .add_warning ("The statement file is missing" )
73+ return
74+ if _check_git_has_file (path ) is False :
75+ interface .add_warning (
76+ "The statement file {} is not known to git" .format (path ))
77+ if os .path .islink (path ):
78+ realpath = os .path .relpath (path )
79+ if not os .path .exists (realpath ):
80+ interface .add_warning ("The statement is a broken link" )
81+
82+
83+ def _check_tex_statement (task : Task , interface : IOIUIInterface ):
84+ statements = _get_statement_tex ()
85+ if not statements :
86+ return
87+ regex = r".*\{Subtask ([0-9]+)\} *\[(?:\\phantom\{.\})?([0-9]+).*\].*"
88+ for statement in statements :
89+ is_non_sequential = False
90+ is_wrong = False
91+ with open (statement , "r" ) as f :
92+ matches = re .findall (regex , f .read ())
93+ if not matches :
94+ continue
95+ one_based = int (matches [0 ][0 ] == '1' )
96+ last = - 1
97+ for subtask , score in matches :
98+ subtask = int (subtask ) - one_based
99+ score = int (score )
100+ if subtask != last + 1 :
101+ is_non_sequential = True
102+ # if the numbers are screwed up the scores have no sense
103+ break
104+ last = subtask
105+ from_task = task .subtasks .get (subtask )
106+ if not from_task or from_task .max_score != score :
107+ is_wrong = True
108+ if is_non_sequential :
109+ interface .add_warning (
110+ "The subtasks in the statement {} are "
111+ "non-sequentially numbered" .format (statement ))
112+ elif is_wrong :
113+ interface .add_warning (
114+ "The subtasks in the statement {} don't match "
115+ "the task's ones" .format (statement ))
116+
117+
64118def _setup_execution_callback (interface : IOIUIInterface , execution : Execution ,
65119 description : str ):
66120 log_prefix = "{} " .format (description ).ljust (50 )
@@ -181,26 +235,16 @@ def check_sol_folder(solutions: List[Solution], interface: IOIUIInterface):
181235 "Official solution {} is not a symlink" .format (sol ))
182236
183237
184- def check_statement (interface : IOIUIInterface ):
238+ def check_statement (task : Task , interface : IOIUIInterface ):
185239 """
186240 Check if the statement is present and, if git is used, that is known.
187241 Check that the latex statements, if present contain the same subtasks, with
188242 the same score, as the task
189243 Check if the template functions in the statement and in the graders have the
190244 same signature
191245 """
192- path = _get_statement_path ()
193- if not path :
194- interface .add_warning ("The statement file is missing" )
195- return
196- if _check_git_has_file (path ) is False :
197- interface .add_warning (
198- "The statement file {} is not known to git" .format (path ))
199- if os .path .islink (path ):
200- realpath = os .path .relpath (path )
201- if not os .path .exists (realpath ):
202- interface .add_warning ("The statement is a broken link" )
203- # TODO check if the subtasks match the one in the statement
246+ _check_pdf_statement (interface )
247+ _check_tex_statement (task , interface )
204248 # TODO check if the template signatures match the one in the statement
205249
206250
@@ -333,7 +377,7 @@ def sanity_pre_checks(task: Task, solutions: List[Solution],
333377 check_subtask_score_sum (task , interface )
334378 check_att_folder (task , solutions , interface )
335379 check_sol_folder (solutions , interface )
336- check_statement (interface )
380+ check_statement (task , interface )
337381 check_sample_cases (task , frontend , config , interface )
338382
339383
0 commit comments