74 lines
2.5 KiB
Python
74 lines
2.5 KiB
Python
import random
|
|
|
|
from app.schemas.grade_1.join_pictures_with_quantity import (
|
|
JoinPicturesWithQuantityProblem,
|
|
NumberCard,
|
|
PictureAsset,
|
|
PictureContainer,
|
|
)
|
|
|
|
|
|
def join_pictures_with_quantity(
|
|
available_pictures: list[dict],
|
|
container_count_per_side: int = 5,
|
|
min_quantity: int = 1,
|
|
max_quantity: int = 10,
|
|
seed: int | None = None,
|
|
) -> dict:
|
|
"""Generate a count-and-match picture problem.
|
|
|
|
The caller only provides the picture assets that exist in the project. The
|
|
function chooses unique quantities, assigns pictures to the left and right
|
|
containers, and returns a JSON-ready validated problem structure.
|
|
|
|
Each picture must have: id, name, image_path.
|
|
"""
|
|
if seed is not None:
|
|
random.seed(seed)
|
|
|
|
pictures = [PictureAsset.model_validate(picture) for picture in available_pictures]
|
|
available_quantities = list(range(min_quantity, max_quantity + 1))
|
|
|
|
if container_count_per_side < 1:
|
|
raise ValueError("container_count_per_side must be at least 1")
|
|
|
|
if len(available_quantities) < container_count_per_side:
|
|
raise ValueError(
|
|
"quantity range must contain at least container_count_per_side values"
|
|
)
|
|
|
|
required_picture_count = container_count_per_side * 2
|
|
if len(pictures) < required_picture_count:
|
|
raise ValueError(
|
|
f"available_pictures must contain at least {required_picture_count} pictures"
|
|
)
|
|
|
|
number_card_values = random.sample(available_quantities, container_count_per_side)
|
|
left_quantities = random.sample(number_card_values, len(number_card_values))
|
|
right_quantities = random.sample(number_card_values, len(number_card_values))
|
|
selected_pictures = random.sample(pictures, required_picture_count)
|
|
|
|
left_pictures = selected_pictures[:container_count_per_side]
|
|
right_pictures = selected_pictures[container_count_per_side:]
|
|
|
|
problem = JoinPicturesWithQuantityProblem(
|
|
left_containers=[
|
|
PictureContainer(
|
|
position=index + 1, quantity=quantity, picture=left_pictures[index]
|
|
)
|
|
for index, quantity in enumerate(left_quantities)
|
|
],
|
|
number_cards=[
|
|
NumberCard(position=index + 1, value=value)
|
|
for index, value in enumerate(number_card_values)
|
|
],
|
|
right_containers=[
|
|
PictureContainer(
|
|
position=index + 1, quantity=quantity, picture=right_pictures[index]
|
|
)
|
|
for index, quantity in enumerate(right_quantities)
|
|
],
|
|
)
|
|
|
|
return problem.model_dump()
|