22from collections import defaultdict , Counter
33from datetime import datetime
44import csv
5- import math
65import argparse
76import subprocess
87import yaml
3332try :
3433 from assign_variant import assign_variant
3534except Exception :
36- def assign_variant (surname : str , name : str , group : str , repo : str , patronymic : str = "" , num_variants : int = 1 ) -> int :
35+
36+ def assign_variant (
37+ surname : str ,
38+ name : str ,
39+ group : str ,
40+ repo : str ,
41+ patronymic : str = "" ,
42+ num_variants : int = 1 ,
43+ ) -> int :
3744 return 0
3845
3946
@@ -225,6 +232,7 @@ def _find_process_report_max(points_info, task_number: int) -> int:
225232 return 0
226233 return 0
227234
235+
228236def _find_process_points (points_info , task_number : int ) -> tuple [int , int , int , int ]:
229237 """Return (S_mpi, S_seq, A_mpi, R) maxima for a given process task ordinal (1..3).
230238 Supports both mapping and list-of-maps (per user's YAML example).
@@ -233,6 +241,7 @@ def _find_process_points(points_info, task_number: int) -> tuple[int, int, int,
233241 key = f"mpi_task_{ task_number } "
234242 for t in proc_tasks :
235243 if str (t .get ("name" )) == key :
244+
236245 def _extract (obj , k ):
237246 if isinstance (obj , dict ):
238247 return int (obj .get (k , 0 ))
@@ -269,6 +278,7 @@ def _find_process_variants_max(points_info, task_number: int) -> int:
269278 return 1
270279 return 1
271280
281+
272282def get_solution_points_and_style (task_type , status , cfg ):
273283 """Get solution points and CSS style based on task type and status."""
274284 max_sol_points = _find_max_solution (cfg , task_type )
@@ -309,7 +319,9 @@ def check_plagiarism_and_calculate_penalty(
309319 and isinstance (plagiarism_cfg [semester ], dict )
310320 ):
311321 inner = plagiarism_cfg [semester ]
312- plag_map = (inner .get ("copying" ) if "copying" in inner else inner .get ("plagiarism" , {})) or {}
322+ plag_map = (
323+ inner .get ("copying" ) if "copying" in inner else inner .get ("plagiarism" , {})
324+ ) or {}
313325
314326 flagged_list = set (plag_map .get (task_type , []) or [])
315327 is_cheated = dir in flagged_list or clean_dir in flagged_list
@@ -459,11 +471,11 @@ def _load_student_fields(dir_name: str):
459471 # Performance points P for non-seq types, based on efficiency
460472 perf_max = _find_performance_max (cfg , task_type )
461473 if task_type != "seq" :
462- perf_points = _calc_perf_points_from_efficiency (
463- efficiency , perf_max
464- )
474+ perf_points = _calc_perf_points_from_efficiency (efficiency , perf_max )
465475 perf_points_display = (
466- f"{ perf_points :.2f} " if isinstance (efficiency , str ) and efficiency .endswith ("%" ) else "—"
476+ f"{ perf_points :.2f} "
477+ if isinstance (efficiency , str ) and efficiency .endswith ("%" )
478+ else "—"
467479 )
468480 else :
469481 perf_points = 0.0
@@ -494,7 +506,14 @@ def _load_student_fields(dir_name: str):
494506 if fields :
495507 last , first , middle , group = fields
496508 try :
497- v_idx = assign_variant (last , first , group , REPO_SALT , patronymic = middle , num_variants = threads_vmax )
509+ v_idx = assign_variant (
510+ last ,
511+ first ,
512+ group ,
513+ REPO_SALT ,
514+ patronymic = middle ,
515+ num_variants = threads_vmax ,
516+ )
498517 variant = str (v_idx + 1 )
499518 except Exception :
500519 variant = "?"
@@ -535,8 +554,8 @@ def main():
535554 if dl_file .exists ():
536555 with open (dl_file , "r" ) as f :
537556 dl_cfg = yaml .safe_load (f ) or {}
538- deadlines_display_threads = ( dl_cfg .get ("threads" ) or {})
539- deadlines_display_processes = ( dl_cfg .get ("processes" ) or {})
557+ deadlines_display_threads = dl_cfg .get ("threads" ) or {}
558+ deadlines_display_processes = dl_cfg .get ("processes" ) or {}
540559 except Exception :
541560 pass
542561
@@ -778,10 +797,14 @@ def _build_cell(dir_name: str, ttype: str):
778797 except Exception :
779798 plag_coeff = 0.0
780799 p_mpi = (
781- - plag_coeff * s_mpi if (has_mpi and group_cells [0 ].get ("plagiarised" )) else 0
800+ - plag_coeff * s_mpi
801+ if (has_mpi and group_cells [0 ].get ("plagiarised" ))
802+ else 0
782803 )
783804 p_seq = (
784- - plag_coeff * s_seq if (has_seq and group_cells [1 ].get ("plagiarised" )) else 0
805+ - plag_coeff * s_seq
806+ if (has_seq and group_cells [1 ].get ("plagiarised" ))
807+ else 0
785808 )
786809 group_cells [0 ]["plagiarism_points" ] = p_mpi
787810 group_cells [1 ]["plagiarism_points" ] = p_seq
@@ -866,7 +889,9 @@ def _build_cell(dir_name: str, ttype: str):
866889 output_path .mkdir (parents = True , exist_ok = True )
867890
868891 # Render tables
869- generated_msk = datetime .now (ZoneInfo ("Europe/Moscow" )).strftime ("%Y-%m-%d %H:%M:%S" )
892+ generated_msk = datetime .now (ZoneInfo ("Europe/Moscow" )).strftime (
893+ "%Y-%m-%d %H:%M:%S"
894+ )
870895 table_template = env .get_template ("index.html.j2" )
871896 threads_vmax = int ((cfg .get ("threads" , {}) or {}).get ("variants_max" , 1 ))
872897 # Build display deadlines (use file values if present, fill missing with auto)
@@ -914,7 +939,9 @@ def _build_cell(dir_name: str, ttype: str):
914939 label = None
915940 if deadlines_display_processes :
916941 key = f"task_{ n } "
917- val = deadlines_display_processes .get (key ) or deadlines_display_processes .get (f"mpi_task_{ n } " )
942+ val = deadlines_display_processes .get (
943+ key
944+ ) or deadlines_display_processes .get (f"mpi_task_{ n } " )
918945 if val is not None :
919946 if isinstance (val , int ):
920947 shift_days = val
@@ -1148,7 +1175,9 @@ def _id_key(stud: dict) -> str:
11481175 else :
11491176 perf_points_mpi_display_g = "—"
11501177 proc_groups_g [base_idx ]["perf_points" ] = perf_points_mpi_g
1151- proc_groups_g [base_idx ]["perf_points_display" ] = perf_points_mpi_display_g
1178+ proc_groups_g [base_idx ]["perf_points_display" ] = (
1179+ perf_points_mpi_display_g
1180+ )
11521181 proc_groups_g [base_idx + 1 ]["perf_points" ] = 0
11531182 try :
11541183 plag_coeff_g = float (
@@ -1165,7 +1194,9 @@ def _id_key(stud: dict) -> str:
11651194 )
11661195 p_seq_g = (
11671196 - plag_coeff_g * s_seq_g
1168- if (has_seq_g and proc_groups_g [base_idx + 1 ].get ("plagiarised" ))
1197+ if (
1198+ has_seq_g and proc_groups_g [base_idx + 1 ].get ("plagiarised" )
1199+ )
11691200 else 0
11701201 )
11711202 proc_groups_g [base_idx ]["plagiarism_points" ] = p_mpi_g
@@ -1174,7 +1205,9 @@ def _id_key(stud: dict) -> str:
11741205 # Sum points by processes S + P + R (and C penalties)
11751206 s_inc_g = (s_mpi_g if has_mpi_g else 0 ) + (s_seq_g if has_seq_g else 0 )
11761207 r_inc_g = r_max_g if report_present_g else 0
1177- total_points_sum_g += s_inc_g + perf_points_mpi_g + r_inc_g + p_mpi_g + p_seq_g
1208+ total_points_sum_g += (
1209+ s_inc_g + perf_points_mpi_g + r_inc_g + p_mpi_g + p_seq_g
1210+ )
11781211 proc_r_values_g .append (r_inc_g )
11791212 else :
11801213 proc_top_headers_g .append (f"task-{ n } " )
@@ -1249,7 +1282,9 @@ def _id_key(stud: dict) -> str:
12491282 label = None
12501283 if deadlines_display_processes :
12511284 key = f"task_{ n } "
1252- val = deadlines_display_processes .get (key ) or deadlines_display_processes .get (f"mpi_task_{ n } " )
1285+ val = deadlines_display_processes .get (
1286+ key
1287+ ) or deadlines_display_processes .get (f"mpi_task_{ n } " )
12531288 if val is not None :
12541289 if isinstance (val , int ):
12551290 shift_days = val
0 commit comments