feat: add configurable max_first_operand for multiplication exercises with randomized operand order
This commit is contained in:
+39
-26
@@ -70,6 +70,7 @@ class ExerciseRequest(BaseModel):
|
|||||||
max_table: int
|
max_table: int
|
||||||
num_exercises: int = 15
|
num_exercises: int = 15
|
||||||
multiplication_only: bool = False
|
multiplication_only: bool = False
|
||||||
|
max_first_operand: int = 12 # New parameter for the maximum value of the first operand
|
||||||
|
|
||||||
|
|
||||||
class OperationExerciseRequest(BaseModel):
|
class OperationExerciseRequest(BaseModel):
|
||||||
@@ -81,6 +82,7 @@ def generate_exercises(
|
|||||||
max_table: int,
|
max_table: int,
|
||||||
num_exercises: int = 15,
|
num_exercises: int = 15,
|
||||||
multiplication_only: bool = False,
|
multiplication_only: bool = False,
|
||||||
|
max_first_operand: int = 12, # New parameter for the maximum value of the first operand
|
||||||
) -> List[str]:
|
) -> List[str]:
|
||||||
"""Génère des exercices de multiplication et division aléatoires mélangés sans doublons"""
|
"""Génère des exercices de multiplication et division aléatoires mélangés sans doublons"""
|
||||||
exercises: List[str] = []
|
exercises: List[str] = []
|
||||||
@@ -93,27 +95,28 @@ def generate_exercises(
|
|||||||
while len(exercises) < num_exercises and attempts < max_attempts:
|
while len(exercises) < num_exercises and attempts < max_attempts:
|
||||||
attempts += 1
|
attempts += 1
|
||||||
|
|
||||||
# Choisir deux nombres aléatoires entre min_table et max_table
|
# Pour les multiplications, un des opérandes est entre 1 et max_first_operand
|
||||||
a = random.randint(min_table, max_table)
|
# et l'autre est entre min_table et max_table
|
||||||
b = random.randint(min_table, max_table)
|
if multiplication_only or random.choice([True, False]):
|
||||||
result = a * b
|
|
||||||
|
|
||||||
# Déterminer le type d'exercice
|
|
||||||
if multiplication_only:
|
|
||||||
exercise_type = "multiplication"
|
|
||||||
else:
|
|
||||||
# Choisir aléatoirement le type d'exercice (seulement multiplication ou division)
|
|
||||||
exercise_type = random.choice(["multiplication", "division"])
|
|
||||||
|
|
||||||
if exercise_type == "multiplication":
|
|
||||||
# Exercice de multiplication
|
# Exercice de multiplication
|
||||||
operation_key = f"mult_{a}_{b}" # Clé unique pour cette opération
|
a = random.randint(1, max_first_operand) # Premier opérande entre 1 et max_first_operand
|
||||||
|
b = random.randint(min_table, max_table) # Second opérande entre min_table et max_table
|
||||||
|
|
||||||
|
# Randomize the order of operands
|
||||||
|
if random.choice([True, False]):
|
||||||
|
a, b = b, a
|
||||||
|
|
||||||
|
result = a * b
|
||||||
|
operation_key = f"mult_{min(a,b)}_{max(a,b)}" # Clé unique pour cette opération (order-independent)
|
||||||
if operation_key not in used_operations:
|
if operation_key not in used_operations:
|
||||||
exercise = f"{a} · {b} = ____"
|
exercise = f"{a} · {b} = ____"
|
||||||
exercises.append(exercise)
|
exercises.append(exercise)
|
||||||
used_operations.add(operation_key)
|
used_operations.add(operation_key)
|
||||||
elif not multiplication_only: # division
|
elif not multiplication_only: # division
|
||||||
# Exercice de division
|
# Exercice de division
|
||||||
|
a = random.randint(min_table, max_table)
|
||||||
|
b = random.randint(min_table, max_table)
|
||||||
|
result = a * b
|
||||||
divisor = random.choice([a, b])
|
divisor = random.choice([a, b])
|
||||||
operation_key = f"div_{result}_{divisor}" # Clé unique pour cette opération
|
operation_key = f"div_{result}_{divisor}" # Clé unique pour cette opération
|
||||||
if operation_key not in used_operations:
|
if operation_key not in used_operations:
|
||||||
@@ -127,24 +130,32 @@ def generate_exercises(
|
|||||||
remaining = num_exercises - len(exercises)
|
remaining = num_exercises - len(exercises)
|
||||||
for _ in range(remaining):
|
for _ in range(remaining):
|
||||||
# Générer des variations avec des nombres légèrement différents
|
# Générer des variations avec des nombres légèrement différents
|
||||||
|
# Pour les multiplications, un des opérandes est entre 1 et max_first_operand
|
||||||
|
# et l'autre est entre min_table et max_table
|
||||||
|
if multiplication_only or random.choice([True, False]):
|
||||||
|
# Exercice de multiplication
|
||||||
|
a = random.randint(1, max_first_operand) # Premier opérande entre 1 et max_first_operand
|
||||||
|
b = random.randint(min_table, max_table) # Second opérande entre min_table et max_table
|
||||||
|
|
||||||
|
# Randomize the order of operands
|
||||||
|
if random.choice([True, False]):
|
||||||
|
a, b = b, a
|
||||||
|
|
||||||
|
result = a * b
|
||||||
|
exercise = f"{a} · {b} = ____"
|
||||||
|
elif not multiplication_only: # division
|
||||||
a = random.randint(min_table, max_table)
|
a = random.randint(min_table, max_table)
|
||||||
b = random.randint(min_table, max_table)
|
b = random.randint(min_table, max_table)
|
||||||
result = a * b
|
result = a * b
|
||||||
|
|
||||||
# Déterminer le type d'exercice
|
|
||||||
if multiplication_only:
|
|
||||||
exercise_type = "multiplication"
|
|
||||||
else:
|
|
||||||
# Choisir aléatoirement le type d'exercice
|
|
||||||
exercise_type = random.choice(["multiplication", "division"])
|
|
||||||
|
|
||||||
if exercise_type == "multiplication":
|
|
||||||
exercise = f"{a} · {b} = ____"
|
|
||||||
elif not multiplication_only: # division
|
|
||||||
divisor = random.choice([a, b])
|
divisor = random.choice([a, b])
|
||||||
exercise = f"{result} : {divisor} = ____"
|
exercise = f"{result} : {divisor} = ____"
|
||||||
else:
|
else:
|
||||||
# Fallback to multiplication if multiplication_only is True
|
# Fallback to multiplication if multiplication_only is True
|
||||||
|
a = random.randint(1, max_first_operand)
|
||||||
|
b = random.randint(min_table, max_table)
|
||||||
|
# Randomize the order of operands
|
||||||
|
if random.choice([True, False]):
|
||||||
|
a, b = b, a
|
||||||
exercise = f"{a} · {b} = ____"
|
exercise = f"{a} · {b} = ____"
|
||||||
|
|
||||||
exercises.append(exercise)
|
exercises.append(exercise)
|
||||||
@@ -157,6 +168,7 @@ def create_math_exercises_pdf(
|
|||||||
max_table: int,
|
max_table: int,
|
||||||
num_exercises: int = 15,
|
num_exercises: int = 15,
|
||||||
multiplication_only: bool = False,
|
multiplication_only: bool = False,
|
||||||
|
max_first_operand: int = 12, # New parameter for the maximum value of the first operand
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Crée un fichier PDF avec des exercices de mathématiques mélangés en 3 colonnes et l'upload sur S3"""
|
"""Crée un fichier PDF avec des exercices de mathématiques mélangés en 3 colonnes et l'upload sur S3"""
|
||||||
import datetime
|
import datetime
|
||||||
@@ -193,7 +205,7 @@ def create_math_exercises_pdf(
|
|||||||
|
|
||||||
# Générer les exercices
|
# Générer les exercices
|
||||||
exercises = generate_exercises(
|
exercises = generate_exercises(
|
||||||
min_table, max_table, num_exercises, multiplication_only
|
min_table, max_table, num_exercises, multiplication_only, max_first_operand
|
||||||
)
|
)
|
||||||
|
|
||||||
# Pas d'en-têtes de colonnes
|
# Pas d'en-têtes de colonnes
|
||||||
@@ -290,6 +302,7 @@ async def generate_exercises_endpoint(request: ExerciseRequest):
|
|||||||
request.max_table,
|
request.max_table,
|
||||||
request.num_exercises,
|
request.num_exercises,
|
||||||
request.multiplication_only,
|
request.multiplication_only,
|
||||||
|
request.max_first_operand, # Pass the new parameter
|
||||||
)
|
)
|
||||||
|
|
||||||
# Return redirect to automatically download the file
|
# Return redirect to automatically download the file
|
||||||
|
|||||||
@@ -66,6 +66,16 @@
|
|||||||
<label class="form-check-label" for="multiplicationOnly">Générer uniquement des multiplications</label>
|
<label class="form-check-label" for="multiplicationOnly">Générer uniquement des multiplications</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="maxFirstOperand" class="form-label">Maximum du premier opérande</label>
|
||||||
|
<select class="form-select" id="maxFirstOperand">
|
||||||
|
<option value="9">9 (Tables jusqu'à 9)</option>
|
||||||
|
<option value="10" selected>10 (Tables jusqu'à 10)</option>
|
||||||
|
<option value="12">12 (Tables jusqu'à 12)</option>
|
||||||
|
</select>
|
||||||
|
<div class="form-text">La valeur maximale pour le premier opérande dans les multiplications</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="d-grid">
|
<div class="d-grid">
|
||||||
<button type="submit" class="btn btn-primary btn-lg" id="generateBtn">
|
<button type="submit" class="btn btn-primary btn-lg" id="generateBtn">
|
||||||
<span id="buttonText">Générer le PDF (Mult/Div)</span>
|
<span id="buttonText">Générer le PDF (Mult/Div)</span>
|
||||||
@@ -517,6 +527,7 @@
|
|||||||
const maxTable = parseInt(document.getElementById('maxTable').value);
|
const maxTable = parseInt(document.getElementById('maxTable').value);
|
||||||
const numExercises = parseInt(document.getElementById('numExercises').value);
|
const numExercises = parseInt(document.getElementById('numExercises').value);
|
||||||
const multiplicationOnly = document.getElementById('multiplicationOnly').checked;
|
const multiplicationOnly = document.getElementById('multiplicationOnly').checked;
|
||||||
|
const maxFirstOperand = parseInt(document.getElementById('maxFirstOperand').value);
|
||||||
|
|
||||||
const generateBtn = document.getElementById('generateBtn');
|
const generateBtn = document.getElementById('generateBtn');
|
||||||
const buttonText = document.getElementById('buttonText');
|
const buttonText = document.getElementById('buttonText');
|
||||||
@@ -537,7 +548,8 @@
|
|||||||
min_table: minTable,
|
min_table: minTable,
|
||||||
max_table: maxTable,
|
max_table: maxTable,
|
||||||
num_exercises: numExercises,
|
num_exercises: numExercises,
|
||||||
multiplication_only: multiplicationOnly
|
multiplication_only: multiplicationOnly,
|
||||||
|
max_first_operand: maxFirstOperand
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user