bugfix
This commit is contained in:
@@ -103,3 +103,65 @@ def assert_draft_matches_shape(o: dict, shape: list[dict]) -> None:
|
||||
f'Вопрос {i + 1}: hasMultipleAnswers должен быть {sh["hasMultipleAnswers"]}.',
|
||||
code='llm_shape',
|
||||
)
|
||||
min_c = int(sh.get('minCorrect', 1))
|
||||
max_c = int(sh.get('maxCorrect', sh['optionsCount']))
|
||||
correct_n = sum(1 for op in opts if bool(op.get('isCorrect')))
|
||||
if correct_n < min_c or correct_n > max_c:
|
||||
raise LlmError(
|
||||
f'Вопрос {i + 1}: правильных ответов должно быть от {min_c} до {max_c}, в ответе: {correct_n}.',
|
||||
code='llm_shape',
|
||||
)
|
||||
|
||||
|
||||
def normalize_draft_to_shape(draft: dict, shape: list[dict]) -> dict:
|
||||
"""Приводит draft к shape: число вопросов/вариантов/мульти и диапазон correct."""
|
||||
qs = list((draft or {}).get('questions') or [])
|
||||
out_qs = []
|
||||
|
||||
def _mk_option(i: int) -> dict:
|
||||
return {'text': f'Вариант {i + 1}', 'isCorrect': False}
|
||||
|
||||
for i, sh in enumerate(shape):
|
||||
src = qs[i] if i < len(qs) and isinstance(qs[i], dict) else {}
|
||||
text = str(src.get('text') or '').strip() or f'Вопрос {i + 1}'
|
||||
has_multi = bool(sh.get('hasMultipleAnswers'))
|
||||
min_c = int(sh.get('minCorrect', 1))
|
||||
max_c = int(sh.get('maxCorrect', sh['optionsCount']))
|
||||
if not has_multi:
|
||||
min_c = 1
|
||||
max_c = 1
|
||||
|
||||
raw_opts = src.get('options') if isinstance(src.get('options'), list) else []
|
||||
opts = []
|
||||
for j in range(sh['optionsCount']):
|
||||
if j < len(raw_opts) and isinstance(raw_opts[j], dict):
|
||||
t = str(raw_opts[j].get('text') or '').strip() or f'Вариант {j + 1}'
|
||||
opts.append({'text': t, 'isCorrect': bool(raw_opts[j].get('isCorrect'))})
|
||||
else:
|
||||
opts.append(_mk_option(j))
|
||||
|
||||
true_idx = [idx for idx, op in enumerate(opts) if op['isCorrect']]
|
||||
if not has_multi:
|
||||
keep = true_idx[0] if true_idx else 0
|
||||
for idx, op in enumerate(opts):
|
||||
op['isCorrect'] = (idx == keep)
|
||||
else:
|
||||
if len(true_idx) < min_c:
|
||||
for idx in range(len(opts)):
|
||||
if idx not in true_idx:
|
||||
opts[idx]['isCorrect'] = True
|
||||
true_idx.append(idx)
|
||||
if len(true_idx) >= min_c:
|
||||
break
|
||||
if len(true_idx) > max_c:
|
||||
keep = set(true_idx[:max_c])
|
||||
for idx, op in enumerate(opts):
|
||||
op['isCorrect'] = idx in keep
|
||||
|
||||
out_qs.append({'text': text, 'hasMultipleAnswers': has_multi, 'options': opts})
|
||||
|
||||
return {
|
||||
'title': str((draft or {}).get('title') or '').strip() or 'Тест',
|
||||
'description': (draft or {}).get('description'),
|
||||
'questions': out_qs,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user