85 lines
2.8 KiB
Python
85 lines
2.8 KiB
Python
from didactopus.adaptive_engine import LearnerProfile
|
|
from didactopus.evidence_engine import (
|
|
EvidenceItem,
|
|
EvidenceState,
|
|
add_evidence_item,
|
|
confidence_from_weight,
|
|
evidence_weight,
|
|
ingest_evidence_bundle,
|
|
)
|
|
|
|
|
|
def test_evidence_weighting_by_type_and_recency() -> None:
|
|
item = EvidenceItem("c1", "project", 0.9, is_recent=True)
|
|
w = evidence_weight(
|
|
item,
|
|
{"explanation": 1.0, "problem": 1.5, "project": 2.5, "transfer": 2.0},
|
|
1.35,
|
|
)
|
|
assert abs(w - 3.375) < 1e-9
|
|
|
|
|
|
def test_confidence_increases_with_weight() -> None:
|
|
assert confidence_from_weight(0.0) == 0.0
|
|
assert confidence_from_weight(1.0) < confidence_from_weight(3.0)
|
|
|
|
|
|
def test_weighted_summary_promotes_mastery() -> None:
|
|
profile = LearnerProfile(learner_id="u1")
|
|
state = ingest_evidence_bundle(
|
|
profile,
|
|
[
|
|
EvidenceItem("c1", "project", 0.9, is_recent=True),
|
|
EvidenceItem("c1", "problem", 0.85, is_recent=False),
|
|
],
|
|
mastery_threshold=0.8,
|
|
resurfacing_threshold=0.55,
|
|
confidence_threshold=0.75,
|
|
type_weights={"explanation": 1.0, "problem": 1.5, "project": 2.5, "transfer": 2.0},
|
|
recent_multiplier=1.35,
|
|
)
|
|
assert "c1" in profile.mastered_concepts
|
|
assert state.summary_by_concept["c1"].weighted_mean_score >= 0.8
|
|
assert state.summary_by_concept["c1"].confidence >= 0.75
|
|
|
|
|
|
def test_recent_weak_evidence_can_resurface() -> None:
|
|
profile = LearnerProfile(learner_id="u1", mastered_concepts={"c1"})
|
|
state = ingest_evidence_bundle(
|
|
profile,
|
|
[
|
|
EvidenceItem("c1", "project", 0.3, is_recent=True),
|
|
EvidenceItem("c1", "explanation", 0.5, is_recent=True),
|
|
],
|
|
mastery_threshold=0.8,
|
|
resurfacing_threshold=0.55,
|
|
confidence_threshold=0.75,
|
|
type_weights={"explanation": 1.0, "problem": 1.5, "project": 2.5, "transfer": 2.0},
|
|
recent_multiplier=1.35,
|
|
)
|
|
assert "c1" not in profile.mastered_concepts
|
|
assert "c1" in state.resurfaced_concepts
|
|
|
|
|
|
def test_dimension_means_present() -> None:
|
|
profile = LearnerProfile(learner_id="u1")
|
|
state = ingest_evidence_bundle(
|
|
profile,
|
|
[
|
|
EvidenceItem(
|
|
"c1",
|
|
"problem",
|
|
0.8,
|
|
rubric_dimensions={"correctness": 0.9, "clarity": 0.7},
|
|
)
|
|
],
|
|
mastery_threshold=0.8,
|
|
resurfacing_threshold=0.55,
|
|
confidence_threshold=0.1,
|
|
type_weights={"explanation": 1.0, "problem": 1.5, "project": 2.5, "transfer": 2.0},
|
|
recent_multiplier=1.35,
|
|
)
|
|
summary = state.summary_by_concept["c1"]
|
|
assert abs(summary.dimension_means["correctness"] - 0.9) < 1e-9
|
|
assert abs(summary.dimension_means["clarity"] - 0.7) < 1e-9
|