Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 28285x 28285x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 28285x 28285x 28285x 28285x 28285x 28285x 28285x 28285x 28285x 28285x 28285x 28285x 28285x 28285x 13837x 13837x 13837x 28285x 14448x 14448x 14448x 14448x 28285x 2x 2x 2x 2x 2x | /**
* Evidence Quality Modifiers
*
* Not all observations are equally informative. We adjust the weight
* of evidence based on:
* - Help usage: Using help = less confident the student really knows it
* - Response time: Fast correct = strong mastery, slow correct = struggled
*/
/**
* Adjust observation weight based on whether help was used.
* Using help = less confident the student really knows it.
*
* @param hadHelp - true if help was used, false otherwise
* @returns Weight multiplier [0.5, 1.0]
*/
export function helpWeight(hadHelp: boolean): number {
return hadHelp ? 0.5 : 1.0
}
/**
* Adjust observation weight based on response time.
*
* The intuition:
* - Fast correct → strong evidence of mastery (automatic recall)
* - Slow correct → might have struggled (mastery less certain)
* - Fast incorrect → careless slip (don't penalize too much)
* - Slow incorrect → genuine confusion (stronger negative evidence)
*
* @param responseTimeMs - Time to answer in milliseconds
* @param isCorrect - Whether the answer was correct
* @param expectedTimeMs - Expected response time (default 5000ms)
* @returns Weight multiplier for the observation
*/
export function responseTimeWeight(
responseTimeMs: number,
isCorrect: boolean,
expectedTimeMs: number = 5000
): number {
// Guard against invalid values that would produce NaN
if (
typeof responseTimeMs !== 'number' ||
!Number.isFinite(responseTimeMs) ||
responseTimeMs <= 0
) {
return 1.0 // Neutral weight for invalid data
}
const ratio = responseTimeMs / expectedTimeMs
if (isCorrect) {
if (ratio < 0.5) return 1.2 // Very fast - strong mastery
if (ratio > 2.0) return 0.8 // Very slow - struggled
return 1.0
} else {
if (ratio < 0.3) return 0.5 // Very fast error - careless slip
if (ratio > 2.0) return 1.2 // Very slow error - genuine confusion
return 1.0
}
}
/**
* Combined evidence weight from help usage and response time.
*/
export function combinedEvidenceWeight(
hadHelp: boolean,
responseTimeMs: number,
isCorrect: boolean,
expectedTimeMs: number = 5000
): number {
return helpWeight(hadHelp) * responseTimeWeight(responseTimeMs, isCorrect, expectedTimeMs)
}
|