feat: add where are more items problem

This commit is contained in:
AlanSilvaaa
2026-05-26 09:58:49 -04:00
parent 494ff27c06
commit 801cdee331
8 changed files with 244 additions and 4 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 KiB

View File

@@ -0,0 +1,55 @@
import random
from app.schemas.grade_1.where_are_more_items import (
ItemGroup,
MoreItemsComparison,
PictureAsset,
WhereAreMoreItemsProblem,
)
def where_are_more_items(
available_pictures: list[dict],
comparison_count: int = 3,
min_quantity: int = 1,
max_quantity: int = 10,
seed: int | None = None,
) -> dict:
"""Generate comparison cards where students choose the group with more items."""
pictures = [PictureAsset.model_validate(picture) for picture in available_pictures]
if len(pictures) < 2:
raise ValueError("available_pictures must contain at least 2 pictures")
if min_quantity >= max_quantity:
raise ValueError("max_quantity must be greater than min_quantity")
rng = random.Random(seed)
quantity_values = list(range(min_quantity, max_quantity + 1))
comparisons: list[MoreItemsComparison] = []
for index in range(comparison_count):
left_picture, right_picture = rng.sample(pictures, 2)
left_quantity, right_quantity = rng.sample(quantity_values, 2)
answer_side = "left" if left_quantity > right_quantity else "right"
comparisons.append(
MoreItemsComparison(
position=index + 1,
left_group=ItemGroup(
side="left",
picture=left_picture,
quantity=left_quantity,
),
right_group=ItemGroup(
side="right",
picture=right_picture,
quantity=right_quantity,
),
answer_side=answer_side,
)
)
problem = WhereAreMoreItemsProblem(comparisons=comparisons)
return problem.model_dump()

View File

@@ -3,10 +3,15 @@ from fastapi import APIRouter, HTTPException
from app.problems.grade_1.join_pictures_with_quantity import (
join_pictures_with_quantity,
)
from app.problems.grade_1.where_are_more_items import where_are_more_items
from app.schemas.grade_1.join_pictures_with_quantity import (
JoinPicturesWithQuantityProblem,
JoinPicturesWithQuantityRequest,
)
from app.schemas.grade_1.where_are_more_items import (
WhereAreMoreItemsProblem,
WhereAreMoreItemsRequest,
)
router = APIRouter(prefix="/grade_1", tags=["Grade 1"])
@@ -30,3 +35,24 @@ def create_join_pictures_with_quantity_problem(
)
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
@router.post(
"/where_are_more_items",
response_model=WhereAreMoreItemsProblem,
)
def create_where_are_more_items_problem(
request: WhereAreMoreItemsRequest,
) -> dict:
try:
return where_are_more_items(
available_pictures=[
picture.model_dump() for picture in request.available_pictures
],
comparison_count=request.comparison_count,
min_quantity=request.min_quantity,
max_quantity=request.max_quantity,
seed=request.seed,
)
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc

View File

@@ -0,0 +1,36 @@
from typing import Literal
from pydantic import BaseModel, Field, PositiveInt
class PictureAsset(BaseModel):
id: str = Field(min_length=1)
name: str = Field(min_length=1)
image_path: str = Field(min_length=1)
class ItemGroup(BaseModel):
side: Literal["left", "right"]
picture: PictureAsset
quantity: PositiveInt
class MoreItemsComparison(BaseModel):
position: PositiveInt
left_group: ItemGroup
right_group: ItemGroup
answer_side: Literal["left", "right"]
has_answer_box: bool = True
class WhereAreMoreItemsProblem(BaseModel):
instructions: str = "Marca dónde hay más."
comparisons: list[MoreItemsComparison]
class WhereAreMoreItemsRequest(BaseModel):
available_pictures: list[PictureAsset] = Field(min_length=1)
comparison_count: PositiveInt = 3
min_quantity: PositiveInt = 1
max_quantity: PositiveInt = 10
seed: int | None = None