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()