adaptivetesting 1.1.5__tar.gz → 1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. adaptivetesting-1.2/PKG-INFO +100 -0
  2. adaptivetesting-1.2/README.md +79 -0
  3. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/__init__.py +16 -3
  4. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/data/__csv_context.py +23 -10
  5. adaptivetesting-1.2/adaptivetesting/data/__read_prev_items_exp_cont.py +56 -0
  6. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/implementations/__pre_test.py +10 -3
  7. adaptivetesting-1.2/adaptivetesting/implementations/__test_assembler.py +427 -0
  8. adaptivetesting-1.2/adaptivetesting/math/__gen_response_pattern.py +141 -0
  9. adaptivetesting-1.2/adaptivetesting/math/content_balancing/__constraint.py +23 -0
  10. adaptivetesting-1.2/adaptivetesting/math/content_balancing/__content_balancing.py +35 -0
  11. adaptivetesting-1.2/adaptivetesting/math/content_balancing/__functions.py +266 -0
  12. adaptivetesting-1.2/adaptivetesting/math/content_balancing/__init__.py +1 -0
  13. adaptivetesting-1.2/adaptivetesting/math/content_balancing/__maximum_priority_index.py +82 -0
  14. adaptivetesting-1.2/adaptivetesting/math/content_balancing/__weighted_penalty_model.py +337 -0
  15. adaptivetesting-1.2/adaptivetesting/math/estimators/__bayes_modal_estimation.py +124 -0
  16. adaptivetesting-1.2/adaptivetesting/math/estimators/__expect_a_posteriori.py +166 -0
  17. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/math/estimators/__functions/__bayes.py +35 -17
  18. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/math/estimators/__functions/__estimators.py +34 -19
  19. adaptivetesting-1.2/adaptivetesting/math/estimators/__functions/__poly/__gpcm.py +70 -0
  20. adaptivetesting-1.2/adaptivetesting/math/estimators/__functions/__poly/__grm.py +77 -0
  21. adaptivetesting-1.2/adaptivetesting/math/estimators/__functions/__poly/__init__.py +4 -0
  22. adaptivetesting-1.2/adaptivetesting/math/estimators/__functions/__poly/__poly_math.py +193 -0
  23. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/math/estimators/__init__.py +1 -1
  24. adaptivetesting-1.2/adaptivetesting/math/estimators/__ml_estimation.py +113 -0
  25. adaptivetesting-1.2/adaptivetesting/math/estimators/__prior.py +183 -0
  26. adaptivetesting-1.2/adaptivetesting/math/estimators/__test_information.py +217 -0
  27. adaptivetesting-1.2/adaptivetesting/math/exposure_control/__exposure_control.py +32 -0
  28. adaptivetesting-1.2/adaptivetesting/math/exposure_control/__init__.py +2 -0
  29. adaptivetesting-1.2/adaptivetesting/math/exposure_control/__mpi_exposure_control.py +81 -0
  30. adaptivetesting-1.2/adaptivetesting/math/exposure_control/__randomesque.py +114 -0
  31. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/math/item_selection/__maximum_information_criterion.py +8 -13
  32. adaptivetesting-1.2/adaptivetesting/math/item_selection/__urrys_rule.py +38 -0
  33. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/models/__adaptive_test.py +2 -33
  34. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/models/__item_pool.py +87 -69
  35. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/models/__item_selection_exception.py +1 -0
  36. adaptivetesting-1.2/adaptivetesting/models/__test_item.py +81 -0
  37. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/services/__estimator_interface.py +17 -10
  38. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/services/__item_selection_protocol.py +0 -2
  39. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/services/__test_results_interface.py +0 -2
  40. adaptivetesting-1.2/adaptivetesting/simulation/__init__.py +5 -0
  41. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/simulation/__simulation.py +39 -28
  42. adaptivetesting-1.2/adaptivetesting/tests/__init__.py +0 -0
  43. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/tests/test_adaptive_test.py +0 -4
  44. adaptivetesting-1.2/adaptivetesting/tests/test_bayes_modal.py +194 -0
  45. adaptivetesting-1.2/adaptivetesting/tests/test_content_balacing.py +131 -0
  46. adaptivetesting-1.2/adaptivetesting/tests/test_eap.py +159 -0
  47. adaptivetesting-1.2/adaptivetesting/tests/test_exposure_control_mpi.py +87 -0
  48. adaptivetesting-1.2/adaptivetesting/tests/test_full_tests.py +224 -0
  49. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/tests/test_generate_response_pattern.py +33 -2
  50. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/tests/test_item_selection.py +12 -2
  51. adaptivetesting-1.2/adaptivetesting/tests/test_load_test_items.py +325 -0
  52. adaptivetesting-1.2/adaptivetesting/tests/test_poly_models.py +103 -0
  53. adaptivetesting-1.2/adaptivetesting/tests/test_priors.py +56 -0
  54. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/tests/test_simulation.py +63 -1
  55. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/tests/test_test_assembler.py +8 -8
  56. adaptivetesting-1.2/adaptivetesting/tests/test_weighted_penalty_model.py +530 -0
  57. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/utils/__funcs.py +1 -1
  58. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/utils/__plots.py +34 -26
  59. adaptivetesting-1.2/adaptivetesting.egg-info/PKG-INFO +100 -0
  60. adaptivetesting-1.2/adaptivetesting.egg-info/SOURCES.txt +87 -0
  61. adaptivetesting-1.2/adaptivetesting.egg-info/dependency_links.txt +1 -0
  62. adaptivetesting-1.2/adaptivetesting.egg-info/requires.txt +6 -0
  63. adaptivetesting-1.2/adaptivetesting.egg-info/top_level.txt +1 -0
  64. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/pyproject.toml +22 -12
  65. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/setup.cfg +7 -2
  66. adaptivetesting-1.2/setup.py +21 -0
  67. adaptivetesting-1.1.5/.github/CONTRIBUTING.md +0 -11
  68. adaptivetesting-1.1.5/.github/workflows/publish.yml +0 -39
  69. adaptivetesting-1.1.5/.github/workflows/python-test.yml +0 -60
  70. adaptivetesting-1.1.5/.gitignore +0 -170
  71. adaptivetesting-1.1.5/.gitlab-ci.yml +0 -13
  72. adaptivetesting-1.1.5/.python-version +0 -1
  73. adaptivetesting-1.1.5/.readthedocs.yml +0 -22
  74. adaptivetesting-1.1.5/.vscode/extensions.json +0 -8
  75. adaptivetesting-1.1.5/.vscode/settings.json +0 -14
  76. adaptivetesting-1.1.5/CHANGELOG.md +0 -13
  77. adaptivetesting-1.1.5/PKG-INFO +0 -375
  78. adaptivetesting-1.1.5/README.md +0 -356
  79. adaptivetesting-1.1.5/adaptivetesting/implementations/__test_assembler.py +0 -231
  80. adaptivetesting-1.1.5/adaptivetesting/math/__gen_response_pattern.py +0 -50
  81. adaptivetesting-1.1.5/adaptivetesting/math/estimators/__bayes_modal_estimation.py +0 -121
  82. adaptivetesting-1.1.5/adaptivetesting/math/estimators/__expect_a_posteriori.py +0 -90
  83. adaptivetesting-1.1.5/adaptivetesting/math/estimators/__ml_estimation.py +0 -65
  84. adaptivetesting-1.1.5/adaptivetesting/math/estimators/__prior.py +0 -94
  85. adaptivetesting-1.1.5/adaptivetesting/math/estimators/__test_information.py +0 -91
  86. adaptivetesting-1.1.5/adaptivetesting/math/item_selection/__urrys_rule.py +0 -33
  87. adaptivetesting-1.1.5/adaptivetesting/models/__test_item.py +0 -33
  88. adaptivetesting-1.1.5/adaptivetesting/simulation/__init__.py +0 -1
  89. adaptivetesting-1.1.5/adaptivetesting/tests/test_bayes_modal.py +0 -89
  90. adaptivetesting-1.1.5/adaptivetesting/tests/test_eap.py +0 -27
  91. adaptivetesting-1.1.5/adaptivetesting/tests/test_load_test_items.py +0 -176
  92. adaptivetesting-1.1.5/docs/Makefile +0 -20
  93. adaptivetesting-1.1.5/docs/data.md +0 -69
  94. adaptivetesting-1.1.5/docs/implementations.md +0 -117
  95. adaptivetesting-1.1.5/docs/index.md +0 -32
  96. adaptivetesting-1.1.5/docs/make.bat +0 -35
  97. adaptivetesting-1.1.5/docs/math.md +0 -254
  98. adaptivetesting-1.1.5/docs/models.md +0 -248
  99. adaptivetesting-1.1.5/docs/readme.md +0 -32
  100. adaptivetesting-1.1.5/docs/requirements.txt +0 -0
  101. adaptivetesting-1.1.5/docs/services.md +0 -42
  102. adaptivetesting-1.1.5/docs/simulation.md +0 -53
  103. adaptivetesting-1.1.5/docs/source/_static/SPEC-0.svg +0 -1
  104. adaptivetesting-1.1.5/docs/source/_static/logo.svg +0 -67
  105. adaptivetesting-1.1.5/docs/source/_static/main.css +0 -24
  106. adaptivetesting-1.1.5/docs/source/conf.py +0 -49
  107. adaptivetesting-1.1.5/docs/source/data.rst +0 -9
  108. adaptivetesting-1.1.5/docs/source/implementations.rst +0 -8
  109. adaptivetesting-1.1.5/docs/source/index.rst +0 -37
  110. adaptivetesting-1.1.5/docs/source/math.rst +0 -21
  111. adaptivetesting-1.1.5/docs/source/models.rst +0 -9
  112. adaptivetesting-1.1.5/docs/source/services.rst +0 -8
  113. adaptivetesting-1.1.5/docs/source/simulation.rst +0 -9
  114. adaptivetesting-1.1.5/docs/source/tests.rst +0 -5
  115. adaptivetesting-1.1.5/docs/tests.md +0 -4
  116. adaptivetesting-1.1.5/examples/.gitignore +0 -3
  117. adaptivetesting-1.1.5/examples/simulation.py +0 -134
  118. adaptivetesting-1.1.5/examples/testing.py +0 -108
  119. adaptivetesting-1.1.5/images/default.svg +0 -208
  120. adaptivetesting-1.1.5/images/semi-adaptive.svg +0 -254
  121. adaptivetesting-1.1.5/mypy.ini +0 -8
  122. adaptivetesting-1.1.5/requirements.txt +0 -0
  123. adaptivetesting-1.1.5/uv.lock +0 -4274
  124. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/LICENSE +0 -0
  125. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/data/__init__.py +0 -0
  126. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/data/__pickle_context.py +0 -0
  127. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/implementations/__default_implementation.py +0 -0
  128. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/implementations/__init__.py +0 -0
  129. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/implementations/__semi_implementation.py +0 -0
  130. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/math/__init__.py +0 -0
  131. {adaptivetesting-1.1.5/adaptivetesting/tests → adaptivetesting-1.2/adaptivetesting/math/estimators/__functions}/__init__.py +0 -0
  132. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/math/item_selection/__init__.py +0 -0
  133. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/models/__algorithm_exception.py +0 -0
  134. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/models/__init__.py +0 -0
  135. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/models/__misc.py +0 -0
  136. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/models/__test_result.py +0 -0
  137. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/services/__init__.py +0 -0
  138. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/tests/test_descriptives.py +0 -0
  139. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/tests/test_information_test.py +0 -0
  140. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/tests/test_mle.py +0 -0
  141. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/tests/test_plots.py +0 -0
  142. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/tests/test_pretest.py +0 -0
  143. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/tests/test_standard_error.py +0 -0
  144. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/utils/__descriptives.py +0 -0
  145. {adaptivetesting-1.1.5 → adaptivetesting-1.2}/adaptivetesting/utils/__init__.py +0 -0
@@ -0,0 +1,100 @@
1
+ Metadata-Version: 2.4
2
+ Name: adaptivetesting
3
+ Version: 1.2
4
+ Summary: adaptivetesting is a Python package that can be used to simulate and evaluate custom CAT scenarios as well as implement them in real-world testing scenarios from a single codebase
5
+ Author-email: Jonas Engicht <dev@condecon.de>
6
+ Project-URL: Homepage, https://github.com/condecon/adaptivetesting
7
+ Project-URL: Documentation, https://github.com/condecon/adaptivetesting/wiki
8
+ Project-URL: Repository, https://github.com/condecon/adaptivetesting.git
9
+ Project-URL: Issues, https://github.com/condecon/adaptivetesting/issues
10
+ Keywords: statistics,psychology,item-response-theory,computerized-adaptive-testing
11
+ Requires-Python: >=3.12
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: numpy>=2.1.0
15
+ Requires-Dist: pandas>=2.3.0
16
+ Requires-Dist: scipy>=1.15.0
17
+ Requires-Dist: tqdm>=4.66.0
18
+ Requires-Dist: matplotlib>=3.10.0
19
+ Requires-Dist: numdifftools>=0.9.42
20
+ Dynamic: license-file
21
+
22
+ # adaptivetesting
23
+
24
+ <img src="/docs/_static/logo.svg" style="width: 100%">
25
+ </img>
26
+
27
+ **An open-source Python package for simplified, customizable Computerized Adaptive Testing (CAT) using Bayesian methods.**
28
+
29
+
30
+ ## Key Features
31
+
32
+ - **Bayesian Methods**: Built-in support for Bayesian ability estimation with customizable priors
33
+ - **Flexible Architecture**: Object-oriented design with abstract classes for easy extension
34
+ - **Item Response Theory**: Full support for 1PL, 2PL, 3PL, and 4PL models, GRM, GPCM
35
+ - **Multiple Estimators**:
36
+ - Maximum Likelihood Estimation (MLE)
37
+ - Bayesian Modal Estimation (BM)
38
+ - Expected A Posteriori (EAP)
39
+ - **Item Selection Strategies**: Maximum information criterion
40
+ - **Content Balancing**: Maximum Priority Index, Weighted Penalty Model
41
+ - **Exposure Control**: Randomesque Item Selection, Maximum Priority Index
42
+ - **Simulation Framework**: Comprehensive tools for CAT simulation and evaluation
43
+ - **Real-world Application**: Direct transition from simulation to production testing
44
+ - **Stopping Criteria**: Support for standard error and test length criteria
45
+ - **Data Management**: Built-in support for CSV and pickle data formats
46
+
47
+ ## Installation
48
+
49
+ Install from PyPI using pip:
50
+
51
+ ```bash
52
+ pip install adaptivetesting
53
+ ```
54
+
55
+ For the latest development version:
56
+
57
+ ```bash
58
+ pip install git+https://github.com/condecon/adaptivetesting
59
+ ```
60
+
61
+ ## Contributing
62
+
63
+ We welcome contributions! Please see our [GitHub repository](https://github.com/condecon/adaptivetesting) for:
64
+
65
+ - Issue tracking
66
+ - Feature requests
67
+ - Pull request guidelines
68
+ - Development setup
69
+
70
+ ## Research and Applications
71
+
72
+ This package is designed for researchers and practitioners in:
73
+
74
+ - Educational assessment
75
+ - Psychological testing
76
+ - Cognitive ability measurement
77
+ - Adaptive learning systems
78
+ - Psychometric research
79
+
80
+ The package facilitates the transition from research simulation to real-world testing applications without requiring major code modifications.
81
+
82
+ ## Citation
83
+ If you use this package for your academic work, please provide the following reference:
84
+ Engicht, J., Bee, R. M., & Koch, T. (2025). Customizable Bayesian Adaptive Testing with Python – The adaptivetesting Package. Open Science Framework. https://doi.org/10.31219/osf.io/d2xge_v1
85
+
86
+ ```
87
+ @online{engichtCustomizableBayesianAdaptive2025,
88
+ title = {Customizable {{Bayesian Adaptive Testing}} with {{Python}} – {{The}} Adaptivetesting {{Package}}},
89
+ author = {Engicht, Jonas and Bee, R. Maximilian and Koch, Tobias},
90
+ date = {2025-08-06},
91
+ eprinttype = {Open Science Framework},
92
+ doi = {10.31219/osf.io/d2xge_v1},
93
+ url = {https://osf.io/d2xge_v1},
94
+ pubstate = {prepublished}
95
+ }
96
+ ```
97
+
98
+ ## License
99
+
100
+ This project is licensed under the terms specified in the [LICENSE](LICENSE) file.
@@ -0,0 +1,79 @@
1
+ # adaptivetesting
2
+
3
+ <img src="/docs/_static/logo.svg" style="width: 100%">
4
+ </img>
5
+
6
+ **An open-source Python package for simplified, customizable Computerized Adaptive Testing (CAT) using Bayesian methods.**
7
+
8
+
9
+ ## Key Features
10
+
11
+ - **Bayesian Methods**: Built-in support for Bayesian ability estimation with customizable priors
12
+ - **Flexible Architecture**: Object-oriented design with abstract classes for easy extension
13
+ - **Item Response Theory**: Full support for 1PL, 2PL, 3PL, and 4PL models, GRM, GPCM
14
+ - **Multiple Estimators**:
15
+ - Maximum Likelihood Estimation (MLE)
16
+ - Bayesian Modal Estimation (BM)
17
+ - Expected A Posteriori (EAP)
18
+ - **Item Selection Strategies**: Maximum information criterion
19
+ - **Content Balancing**: Maximum Priority Index, Weighted Penalty Model
20
+ - **Exposure Control**: Randomesque Item Selection, Maximum Priority Index
21
+ - **Simulation Framework**: Comprehensive tools for CAT simulation and evaluation
22
+ - **Real-world Application**: Direct transition from simulation to production testing
23
+ - **Stopping Criteria**: Support for standard error and test length criteria
24
+ - **Data Management**: Built-in support for CSV and pickle data formats
25
+
26
+ ## Installation
27
+
28
+ Install from PyPI using pip:
29
+
30
+ ```bash
31
+ pip install adaptivetesting
32
+ ```
33
+
34
+ For the latest development version:
35
+
36
+ ```bash
37
+ pip install git+https://github.com/condecon/adaptivetesting
38
+ ```
39
+
40
+ ## Contributing
41
+
42
+ We welcome contributions! Please see our [GitHub repository](https://github.com/condecon/adaptivetesting) for:
43
+
44
+ - Issue tracking
45
+ - Feature requests
46
+ - Pull request guidelines
47
+ - Development setup
48
+
49
+ ## Research and Applications
50
+
51
+ This package is designed for researchers and practitioners in:
52
+
53
+ - Educational assessment
54
+ - Psychological testing
55
+ - Cognitive ability measurement
56
+ - Adaptive learning systems
57
+ - Psychometric research
58
+
59
+ The package facilitates the transition from research simulation to real-world testing applications without requiring major code modifications.
60
+
61
+ ## Citation
62
+ If you use this package for your academic work, please provide the following reference:
63
+ Engicht, J., Bee, R. M., & Koch, T. (2025). Customizable Bayesian Adaptive Testing with Python – The adaptivetesting Package. Open Science Framework. https://doi.org/10.31219/osf.io/d2xge_v1
64
+
65
+ ```
66
+ @online{engichtCustomizableBayesianAdaptive2025,
67
+ title = {Customizable {{Bayesian Adaptive Testing}} with {{Python}} – {{The}} Adaptivetesting {{Package}}},
68
+ author = {Engicht, Jonas and Bee, R. Maximilian and Koch, Tobias},
69
+ date = {2025-08-06},
70
+ eprinttype = {Open Science Framework},
71
+ doi = {10.31219/osf.io/d2xge_v1},
72
+ url = {https://osf.io/d2xge_v1},
73
+ pubstate = {prepublished}
74
+ }
75
+ ```
76
+
77
+ ## License
78
+
79
+ This project is licensed under the terms specified in the [LICENSE](LICENSE) file.
@@ -12,18 +12,21 @@ from .data.__pickle_context import PickleContext
12
12
  from .implementations.__default_implementation import DefaultImplementation
13
13
  from .implementations.__pre_test import PreTest
14
14
  from .implementations.__semi_implementation import SemiAdaptiveImplementation
15
- from .implementations.__test_assembler import TestAssembler
15
+ from .implementations.__test_assembler import TestAssembler, ContentBalancingArgs, ExposureControlArgs
16
16
 
17
17
  from .math.__gen_response_pattern import generate_response_pattern
18
18
  from .math.estimators.__ml_estimation import MLEstimator
19
19
  from .math.estimators.__bayes_modal_estimation import BayesModal
20
20
  from .math.estimators.__expect_a_posteriori import ExpectedAPosteriori
21
- from .math.estimators.__prior import Prior, NormalPrior, CustomPrior, CustomPriorException
21
+ from .math.estimators.__prior import Prior, NormalPrior, CustomPrior, CustomPriorException, SkewNormalPrior, EmpiricalPrior
22
22
  from .math.estimators.__functions.__estimators import probability_y0, probability_y1, maximize_likelihood_function, likelihood
23
23
  from .math.estimators.__functions.__bayes import maximize_posterior
24
24
  from .math.estimators.__test_information import test_information_function, item_information_function, prior_information_function
25
25
  from .math.item_selection.__maximum_information_criterion import maximum_information_criterion
26
26
  from .math.item_selection.__urrys_rule import urrys_rule
27
+ from .math.content_balancing.__weighted_penalty_model import WeightedPenaltyModel
28
+ from .math.content_balancing.__constraint import *
29
+ from .math.content_balancing.__functions import *
27
30
 
28
31
  from .models.__adaptive_test import AdaptiveTest
29
32
  from .models.__algorithm_exception import AlgorithmException
@@ -39,4 +42,14 @@ from .services.__item_selection_protocol import ItemSelectionStrategy
39
42
 
40
43
  from .simulation.__simulation import Simulation, SimulationPool, setup_simulation_and_start
41
44
 
42
- from .utils.__descriptives import bias, average_absolute_deviation, rmse
45
+ from .utils.__descriptives import bias, average_absolute_deviation, rmse
46
+ from .utils.__funcs import load_final_test_results, load_test_results_single_participant
47
+ from .utils.__plots import (
48
+ plot_exposure_rate,
49
+ plot_final_ability_estimates,
50
+ plot_icc,
51
+ plot_iif,
52
+ plot_exposure_rate,
53
+ plot_test_information,
54
+ plot_theta_estimation_trace
55
+ )
@@ -3,7 +3,8 @@ import csv
3
3
  import pathlib
4
4
  from ..models.__test_result import TestResult
5
5
  from ..services.__test_results_interface import ITestResults
6
- from dataclasses import fields
6
+ import json
7
+ import ast
7
8
 
8
9
 
9
10
  class CSVContext(ITestResults):
@@ -47,22 +48,34 @@ class CSVContext(ITestResults):
47
48
  file.close()
48
49
 
49
50
  def load(self) -> List[TestResult]:
50
- """Loads test results from a CSV file for a specific participant and simulation.
51
- Reads the CSV file located at `data/{simulation_id}/{participant_id}.csv`,
52
- parses each row into a `TestResult` object,
53
- and returns a list of these objects.
54
-
55
- Returns:
56
- List[TestResult]: A list of `TestResult` objects loaded from the CSV file.
51
+ """Loads results from the database.
52
+ The implementation of this method is required
53
+ by the interface. However, it does not have
54
+ any implemented functionality and will throw an error
55
+ if used.
56
+
57
+ Returns: List[TestResult]
57
58
  """
58
59
  foldername = f"data/{self.simulation_id}"
59
60
 
60
- fieldnames = list(fields(TestResult))
61
61
  test_results: list[TestResult] = []
62
62
  with open(f"{foldername}/{self.participant_id}.csv", "r", encoding="utf-8") as file:
63
- reader = csv.DictReader(file, fieldnames=fieldnames)
63
+ reader = csv.DictReader(file)
64
+ next(reader, None) # skip header row
64
65
  for row in reader:
65
66
  test_result = TestResult.from_dict(row)
67
+ # showed_item is read as a string representation of a Python
68
+ # literal (e.g. a dict). Use ast.literal_eval to safely parse
69
+ # it back into a dict. Fallback to a JSON-style conversion
70
+ # if literal_eval fails.
71
+ try:
72
+ test_result.showed_item = ast.literal_eval(str(test_result.showed_item))
73
+ except Exception:
74
+ json_string = str(test_result.showed_item).replace("'", '"').replace("None", "null")
75
+ try:
76
+ test_result.showed_item = json.loads(json_string)
77
+ except Exception:
78
+ test_result.showed_item = {}
66
79
  test_results.append(test_result)
67
80
  file.close()
68
81
  return test_results
@@ -0,0 +1,56 @@
1
+ from typing import Literal
2
+ from warnings import deprecated
3
+ from ..models.__test_item import TestItem
4
+ from ..models.__test_result import TestResult
5
+ from .__csv_context import CSVContext
6
+ from .__pickle_context import PickleContext
7
+
8
+
9
+ def read_prev_items(format: Literal["CSV", "PICKLE"],
10
+ test_id: str,
11
+ participant_ids: list[str]) -> list[TestItem]:
12
+ """Read previously administered items.
13
+ This function is internally used to perform exposure control.
14
+
15
+ Args:
16
+ format (Literal["CSV", "PICKLE"]): The format of the results: CSV or PICKLE.
17
+ test_id (str): The test ID / simulation ID.
18
+ participant_ids (list[str]): The participant IDs.
19
+
20
+ Returns:
21
+ list[TestItem]: A list of TestItem objects.
22
+ """
23
+ all_shown_test_items = []
24
+
25
+ for part_id in participant_ids:
26
+ test_results = read_single_participant(test_id, part_id, format)
27
+ items = [TestItem.from_dict(res.showed_item) for res in test_results]
28
+
29
+ all_shown_test_items += items
30
+
31
+ return all_shown_test_items
32
+
33
+
34
+ @deprecated("This function will be removed in future releases.")
35
+ def read_single_participant(test_id: str, participant_id: str, format: Literal["CSV", "PICKLE"]) -> list[TestResult]:
36
+ """
37
+ Reads the test results of a particular participant.
38
+ Args:
39
+ test_id (str): The test ID / simulation ID.
40
+ participant_id (str): The participant ID.
41
+ format (Literal["CSV", "PICKLE"]): The format of the results: CSV or PICKLE.
42
+
43
+ Returns:
44
+ list[TestResult]: A list of TestResult objects.
45
+
46
+ Raises:
47
+ ValueError: If the format is not supported.
48
+ """
49
+ context: CSVContext | PickleContext
50
+ if format == "CSV":
51
+ context = CSVContext(test_id, participant_id)
52
+ return context.load()
53
+ if format == "PICKLE":
54
+ context = PickleContext(test_id, participant_id)
55
+ return context.load()
56
+ raise ValueError(f"Unknown format: {format}")
@@ -1,4 +1,4 @@
1
- from typing import List
1
+ from typing import List, cast
2
2
  import numpy as np
3
3
  from ..models.__test_item import TestItem
4
4
  import random
@@ -10,6 +10,7 @@ class PreTest:
10
10
  The pretest class can be used to draw items randomly from
11
11
  difficulty quantiles
12
12
  of the item pool.
13
+ This pretest can only be used with dichotomous IRT models and items.
13
14
 
14
15
  Args:
15
16
  items: Item pool
@@ -18,15 +19,21 @@ class PreTest:
18
19
  If not, the item selection will be drawn randomly, and you will not be able
19
20
  to reproduce the results.
20
21
 
22
+ Raises:
23
+ ValueError: Raised if the items are specified for polytomous IRT models.
24
+
21
25
  """
22
26
  self.items = items
23
27
  self.seed = seed
24
28
 
29
+ if any([isinstance(item.b, list) for item in items]):
30
+ raise ValueError("The pretest can only be used with dichotomous IRT models and items.")
31
+
25
32
  def calculate_quantiles(self) -> np.ndarray:
26
33
  """Calculates quantiles 0.25, 0.5, 0.75
27
34
  """
28
35
  # get difficulties
29
- difficulties: List[float] = [item.b for item in self.items]
36
+ difficulties: List[float] = [cast(float, item.b) for item in self.items]
30
37
 
31
38
  quantiles = np.array([])
32
39
  # calculate quantiles
@@ -50,7 +57,7 @@ class PreTest:
50
57
  """
51
58
  # select only items with difficulty in interval
52
59
  items_in_interval: List[TestItem] = [item for item in list(self.items)
53
- if lower < item.b <= upper]
60
+ if lower < cast(float, item.b) <= upper]
54
61
  # draw one item randomly
55
62
  if self.seed is not None:
56
63
  random.seed(self.seed)