Skip to content

Commit

Permalink
[TECH] Suppression de paramètres dans le simulateur de déroulé (PIX-1…
Browse files Browse the repository at this point in the history
  • Loading branch information
pix-service-auto-merge authored Nov 18, 2024
2 parents 472da35 + 6dd8679 commit 525d19a
Show file tree
Hide file tree
Showing 18 changed files with 75 additions and 1,171 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,17 @@ async function simulateFlashAssessmentScenario(
stopAtChallenge,
initialCapacity,
numberOfIterations = 1,
warmUpLength,
forcedCompetences,
useObsoleteChallenges,
challengePickProbability,
challengesBetweenSameCompetence,
limitToOneQuestionPerTube,
minimumEstimatedSuccessRateRanges: minimumEstimatedSuccessRateRangesDto,
enablePassageByAllCompetences,
doubleMeasuresUntil,
variationPercent,
variationPercentUntil,
capacity,
} = request.payload;

const pickAnswerStatus = _getPickAnswerStatusMethod(dependencies.pickAnswerStatusService, request.payload);
const pickAnswerStatus = dependencies.pickAnswerStatusService.pickAnswerStatusForCapacity(capacity);

const locale = dependencies.extractLocaleFromRequest(request);

Expand All @@ -59,21 +56,17 @@ async function simulateFlashAssessmentScenario(
locale,
stopAtChallenge,
initialCapacity,
warmUpLength,
forcedCompetences,
useObsoleteChallenges,
challengesBetweenSameCompetence,
limitToOneQuestionPerTube,
minimumEstimatedSuccessRateRanges,
enablePassageByAllCompetences,
doubleMeasuresUntil,
variationPercent,
variationPercentUntil,
},
_.isUndefined,
);

const simulationReport = await usecases.simulateFlashDeterministicAssessmentScenario(usecaseParams);
const simulationReport = await usecases.simulateFlashAssessmentScenario(usecaseParams);

yield JSON.stringify({
index,
Expand All @@ -95,25 +88,6 @@ async function simulateFlashAssessmentScenario(
return h.response(generatedResponse).type('text/event-stream; charset=utf-8');
}

function _getPickAnswerStatusMethod(pickAnswerStatusService, payload) {
const { type, probabilities, length, capacity, answerStatusArray } = payload;

switch (type) {
case 'deterministic':
return pickAnswerStatusService.pickAnswerStatusFromArray(answerStatusArray);
case 'random': {
const answer = _generateAnswerStatusArray(random, probabilities, length);
return pickAnswerStatusService.pickAnswerStatusFromArray(answer);
}
case 'capacity':
return pickAnswerStatusService.pickAnswerStatusForCapacity(capacity);
}
}

function _generateAnswerStatusArray(random, probabilities, length) {
return random.weightedRandoms(probabilities, length);
}

function _minimumEstimatedSuccessRateRangesToDomain(successRateRanges) {
if (!successRateRanges) {
return undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,20 @@ import Joi from 'joi';
import { securityPreHandlers } from '../../../shared/application/security-pre-handlers.js';
import { scenarioSimulatorController } from './scenario-simulator-controller.js';

const _successRatesConfigurationValidator = Joi.alternatives(
Joi.object({
type: Joi.string().valid('fixed').required(),
startingChallengeIndex: Joi.number().integer().min(0).required(),
endingChallengeIndex: Joi.number().integer().min(Joi.ref('startingChallengeIndex')).required(),
value: Joi.number().min(0).max(1).required(),
}),
Joi.object({
type: Joi.string().valid('linear').required(),
startingChallengeIndex: Joi.number().integer().min(0).required(),
endingChallengeIndex: Joi.number().integer().min(Joi.ref('startingChallengeIndex')).required(),
startingValue: Joi.number().min(0).max(1).required(),
endingValue: Joi.number().min(0).max(1).required(),
}),
);
const _successRatesConfigurationValidator = Joi.object({
startingChallengeIndex: Joi.number().integer().min(0).required(),
endingChallengeIndex: Joi.number().integer().min(Joi.ref('startingChallengeIndex')).required(),
value: Joi.number().min(0).max(1).required(),
});

const _baseScenarioParametersValidator = Joi.object().keys({
initialCapacity: Joi.number().integer().min(-8).max(8),
stopAtChallenge: Joi.number().integer().min(0),
numberOfIterations: Joi.number().integer().min(0),
warmpUpLength: Joi.number().integer().min(0),
forcedCompetencies: Joi.array().items(Joi.string()),
useObsoleteChallenges: Joi.boolean(),
challengePickProbability: Joi.number().min(0).max(100),
challengesBetweenSameCompetence: Joi.number().min(0),
limitToOneQuestionPerTube: Joi.boolean(),
minimumEstimatedSuccessRateRanges: Joi.array().items(_successRatesConfigurationValidator),
enablePassageByAllCompetences: Joi.boolean(),
doubleMeasuresUntil: Joi.number().min(0),
variationPercent: Joi.number().min(0).max(1),
variationPercentUntil: Joi.number().min(0),
Expand All @@ -52,27 +38,11 @@ const register = async (server) => {
options: {
allowUnknown: true,
},
payload: Joi.alternatives([
_baseScenarioParametersValidator.keys({
type: Joi.string().valid('deterministic').required(),
answerStatusArray: Joi.array()
.items(Joi.string().allow('ok', 'ko', 'aband'))
.required(),
}),
_baseScenarioParametersValidator.keys({
type: Joi.string().valid('random').required(),
probabilities: Joi.object({
ok: Joi.number(),
ko: Joi.number(),
aband: Joi.number(),
}),
length: Joi.number().integer().min(0).required(),
}),
_baseScenarioParametersValidator.keys({
type: Joi.string().valid('capacity').required(),
payload: _baseScenarioParametersValidator
.keys({
capacity: Joi.number().min(-8).max(8).required(),
}),
]).required(),
})
.required(),
},
handler: scenarioSimulatorController.simulateFlashAssessmentScenario,
tags: ['api'],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { FlashAssessmentSuccessRateHandlerFixedStrategy } from './FlashAssessmentSuccessRateHandlerFixedStrategy.js';
import { FlashAssessmentSuccessRateHandlerLinearStrategy } from './FlashAssessmentSuccessRateHandlerLinearStrategy.js';

class FlashAssessmentSuccessRateHandler {
constructor({ startingChallengeIndex, endingChallengeIndex, strategy }) {
this.startingChallengeIndex = startingChallengeIndex;
this.endingChallengeIndex = endingChallengeIndex;

this._strategy = strategy;
}

Expand All @@ -18,15 +16,7 @@ class FlashAssessmentSuccessRateHandler {
}

static create(successRateRange) {
if (successRateRange.type === 'linear') {
return FlashAssessmentSuccessRateHandler.createLinear(successRateRange);
}
if (successRateRange.type === 'fixed') {
return FlashAssessmentSuccessRateHandler.createFixed(successRateRange);
}
}

static createFixed({ startingChallengeIndex, endingChallengeIndex, value }) {
const { startingChallengeIndex, endingChallengeIndex, value } = successRateRange;
return new FlashAssessmentSuccessRateHandler({
startingChallengeIndex,
endingChallengeIndex,
Expand All @@ -36,17 +26,6 @@ class FlashAssessmentSuccessRateHandler {
});
}

static createLinear({ startingChallengeIndex, endingChallengeIndex, startingValue, endingValue }) {
return new FlashAssessmentSuccessRateHandler({
startingChallengeIndex,
endingChallengeIndex,
strategy: new FlashAssessmentSuccessRateHandlerLinearStrategy({
startingValue,
endingValue,
}),
});
}

toDTO() {
return {
startingChallengeIndex: this.startingChallengeIndex,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,31 @@ import { AssessmentSimulatorDoubleMeasureStrategy } from '../models/AssessmentSi
import { AssessmentSimulatorSingleMeasureStrategy } from '../models/AssessmentSimulatorSingleMeasureStrategy.js';
import { FlashAssessmentAlgorithm } from '../models/FlashAssessmentAlgorithm.js';

export async function simulateFlashDeterministicAssessmentScenario({
export async function simulateFlashAssessmentScenario({
locale,
pickChallenge,
pickAnswerStatus,
stopAtChallenge,
initialCapacity,
useObsoleteChallenges,
warmUpLength = 0,
forcedCompetences = [],
challengesBetweenSameCompetence = 0,
limitToOneQuestionPerTube = true,
minimumEstimatedSuccessRateRanges = [],
enablePassageByAllCompetences = false,
doubleMeasuresUntil = 0,
variationPercent,
variationPercentUntil,
challengeRepository,
flashAlgorithmService,
}) {
const challenges = await challengeRepository.findFlashCompatible({ locale, useObsoleteChallenges });
const challenges = await challengeRepository.findActiveFlashCompatible({ locale });

const enablePassageByAllCompetencesValueInProduction = true;

const flashAssessmentAlgorithm = new FlashAssessmentAlgorithm({
flashAlgorithmImplementation: flashAlgorithmService,
configuration: new FlashAssessmentAlgorithmConfiguration({
warmUpLength,
forcedCompetences,
limitToOneQuestionPerTube,
minimumEstimatedSuccessRateRanges,
enablePassageByAllCompetences,
enablePassageByAllCompetences: enablePassageByAllCompetencesValueInProduction,
variationPercent,
variationPercentUntil,
doubleMeasuresUntil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,6 @@ const challengeDatasource = datasource.extend({
return flashChallenges.filter((challengeData) => _challengeHasStatus(challengeData, [VALIDATED_CHALLENGE]));
},

async findOperativeFlashCompatible(locale) {
const flashChallenges = await this.findFlashCompatible({ locale });
return flashChallenges.filter((challengeData) => _challengeHasStatus(challengeData, OPERATIVE_CHALLENGES));
},

async findFlashCompatible({ locale, useObsoleteChallenges }) {
const challenges = await this.listByLocale(locale);

Expand Down
19 changes: 0 additions & 19 deletions api/src/shared/infrastructure/repositories/challenge-repository.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,23 +95,6 @@ const findActiveFlashCompatible = async function ({
return _toDomainCollection({ challengeDataObjects, skills: activeSkills, successProbabilityThreshold });
};

const findOperativeFlashCompatible = async function ({
locale,
successProbabilityThreshold = config.features.successProbabilityThreshold,
} = {}) {
_assertLocaleIsDefined(locale);
const challengeDataObjects = await challengeDatasource.findOperativeFlashCompatible(locale);
const skills = await skillDatasource.list();
return _toDomainCollection({ challengeDataObjects, skills, successProbabilityThreshold });
};

const findFlashCompatible = async function ({ locale, useObsoleteChallenges } = {}) {
_assertLocaleIsDefined(locale);
const challengeDataObjects = await challengeDatasource.findFlashCompatible({ locale, useObsoleteChallenges });
const skills = await skillDatasource.list();
return _toDomainCollection({ challengeDataObjects, skills });
};

const findFlashCompatibleWithoutLocale = async function ({ useObsoleteChallenges } = {}) {
const challengeDataObjects = await challengeDatasource.findFlashCompatibleWithoutLocale({ useObsoleteChallenges });
const skills = await skillDatasource.list();
Expand All @@ -132,11 +115,9 @@ export async function getManyTypes(ids) {

export {
findActiveFlashCompatible,
findFlashCompatible,
findFlashCompatibleWithoutLocale,
findOperative,
findOperativeBySkills,
findOperativeFlashCompatible,
findValidated,
findValidatedByCompetenceId,
findValidatedBySkillId,
Expand Down
16 changes: 1 addition & 15 deletions api/src/shared/infrastructure/utils/random.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,3 @@
const weightedRandom = (values) => {
let probabilitiesSum = 0;
const randomFloat = Math.random();
for (const key in values) {
probabilitiesSum += values[key];
const shouldSelectCurrentKey = probabilitiesSum > randomFloat;
if (shouldSelectCurrentKey) {
return key;
}
}
};

const weightedRandoms = (values, length) => [...new Array(length)].map(() => weightedRandom(values));

const binaryTreeRandom = (probability, length) => {
if (length === 1) {
return 0;
Expand All @@ -26,4 +12,4 @@ const binaryTreeRandom = (probability, length) => {
return 1 + binaryTreeRandom(probability, length - 1);
};

export const random = { weightedRandoms, binaryTreeRandom };
export const random = { binaryTreeRandom };
Loading

0 comments on commit 525d19a

Please sign in to comment.