adaptivetesting 1.0.1__tar.gz → 1.1.1__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 (123) hide show
  1. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/.github/workflows/python-test.yml +0 -3
  2. adaptivetesting-1.1.1/BREAKING_CHANGES.md +65 -0
  3. adaptivetesting-1.1.1/PKG-INFO +348 -0
  4. adaptivetesting-1.1.1/README.md +330 -0
  5. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/__init__.py +1 -1
  6. adaptivetesting-1.1.1/adaptivetesting/data/__csv_context.py +57 -0
  7. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/data/__init__.py +1 -1
  8. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/data/__pickle_context.py +4 -4
  9. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/implementations/__default_implementation.py +17 -6
  10. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/implementations/__init__.py +1 -0
  11. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/implementations/__pre_test.py +1 -1
  12. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/implementations/__semi_implementation.py +32 -14
  13. adaptivetesting-1.1.1/adaptivetesting/implementations/__test_assembler.py +231 -0
  14. adaptivetesting-1.1.1/adaptivetesting/math/__gen_response_pattern.py +50 -0
  15. adaptivetesting-1.1.1/adaptivetesting/math/__init__.py +1 -0
  16. adaptivetesting-1.1.1/adaptivetesting/math/estimators/__bayes_modal_estimation.py +121 -0
  17. adaptivetesting-1.1.1/adaptivetesting/math/estimators/__expect_a_posteriori.py +90 -0
  18. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/math/estimators/__functions/__bayes.py +1 -1
  19. adaptivetesting-1.1.1/adaptivetesting/math/estimators/__functions/__estimators.py +139 -0
  20. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/math/estimators/__init__.py +3 -1
  21. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/math/estimators/__ml_estimation.py +28 -2
  22. adaptivetesting-1.1.1/adaptivetesting/math/estimators/__prior.py +94 -0
  23. adaptivetesting-1.1.1/adaptivetesting/math/estimators/__test_information.py +101 -0
  24. adaptivetesting-1.1.1/adaptivetesting/math/item_selection/__init__.py +2 -0
  25. adaptivetesting-1.1.1/adaptivetesting/math/item_selection/__maximum_information_criterion.py +55 -0
  26. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/models/__adaptive_test.py +56 -31
  27. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/models/__init__.py +1 -1
  28. adaptivetesting-1.1.1/adaptivetesting/models/__misc.py +17 -0
  29. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/models/__test_result.py +1 -1
  30. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/services/__estimator_interface.py +13 -1
  31. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/services/__init__.py +1 -0
  32. adaptivetesting-1.1.1/adaptivetesting/services/__item_selection_protocol.py +25 -0
  33. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/services/__test_results_interface.py +3 -3
  34. adaptivetesting-1.1.1/adaptivetesting/simulation/__init__.py +1 -0
  35. adaptivetesting-1.1.1/adaptivetesting/simulation/__simulation.py +152 -0
  36. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/tests/test_adaptive_test.py +14 -7
  37. adaptivetesting-1.1.1/adaptivetesting/tests/test_bayes_modal.py +89 -0
  38. adaptivetesting-1.0.1/adaptivetesting/tests/test_bayes_modal.py → adaptivetesting-1.1.1/adaptivetesting/tests/test_eap.py +6 -9
  39. adaptivetesting-1.1.1/adaptivetesting/tests/test_generate_response_pattern.py +106 -0
  40. adaptivetesting-1.1.1/adaptivetesting/tests/test_information_test.py +55 -0
  41. adaptivetesting-1.1.1/adaptivetesting/tests/test_item_selection.py +60 -0
  42. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/tests/test_pretest.py +1 -1
  43. adaptivetesting-1.1.1/adaptivetesting/tests/test_simulation.py +99 -0
  44. adaptivetesting-1.1.1/adaptivetesting/tests/test_standard_error.py +160 -0
  45. adaptivetesting-1.1.1/adaptivetesting/tests/test_test_assembler.py +204 -0
  46. adaptivetesting-1.1.1/docs/readme.md +32 -0
  47. {adaptivetesting-1.0.1/docs_generation → adaptivetesting-1.1.1/docs}/source/conf.py +5 -4
  48. adaptivetesting-1.1.1/docs/source/data.rst +9 -0
  49. adaptivetesting-1.1.1/docs/source/implementations.rst +8 -0
  50. adaptivetesting-1.1.1/docs/source/math.rst +21 -0
  51. adaptivetesting-1.1.1/docs/source/models.rst +9 -0
  52. adaptivetesting-1.1.1/docs/source/services.rst +8 -0
  53. adaptivetesting-1.1.1/docs/source/simulation.rst +9 -0
  54. adaptivetesting-1.1.1/examples/.gitignore +3 -0
  55. adaptivetesting-1.1.1/examples/simulation.py +134 -0
  56. adaptivetesting-1.1.1/examples/testing.py +105 -0
  57. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/pyproject.toml +23 -5
  58. adaptivetesting-1.1.1/requirements.txt +612 -0
  59. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/setup.cfg +1 -1
  60. adaptivetesting-1.1.1/uv.lock +5341 -0
  61. adaptivetesting-1.0.1/PKG-INFO +0 -90
  62. adaptivetesting-1.0.1/README.md +0 -76
  63. adaptivetesting-1.0.1/adaptivetesting/data/__sqlite_context.py +0 -73
  64. adaptivetesting-1.0.1/adaptivetesting/math/__gen_response_pattern.py +0 -35
  65. adaptivetesting-1.0.1/adaptivetesting/math/__init__.py +0 -3
  66. adaptivetesting-1.0.1/adaptivetesting/math/__standard_error.py +0 -60
  67. adaptivetesting-1.0.1/adaptivetesting/math/__test_information.py +0 -37
  68. adaptivetesting-1.0.1/adaptivetesting/math/estimators/__bayes_modal_estimation.py +0 -45
  69. adaptivetesting-1.0.1/adaptivetesting/math/estimators/__functions/__estimators.py +0 -133
  70. adaptivetesting-1.0.1/adaptivetesting/math/estimators/__prior.py +0 -47
  71. adaptivetesting-1.0.1/adaptivetesting/math/item_selection/__init__.py +0 -1
  72. adaptivetesting-1.0.1/adaptivetesting/simulation/__init__.py +0 -1
  73. adaptivetesting-1.0.1/adaptivetesting/simulation/__simulation.py +0 -75
  74. adaptivetesting-1.0.1/adaptivetesting/tests/test_code_examples.py +0 -22
  75. adaptivetesting-1.0.1/adaptivetesting/tests/test_generate_response_pattern.py +0 -59
  76. adaptivetesting-1.0.1/adaptivetesting/tests/test_information_test.py +0 -39
  77. adaptivetesting-1.0.1/adaptivetesting/tests/test_standard_error.py +0 -58
  78. adaptivetesting-1.0.1/adaptivetesting/tests/test_urrys_rule.py +0 -28
  79. adaptivetesting-1.0.1/code_examples/example_default.py +0 -76
  80. adaptivetesting-1.0.1/code_examples/example_psychopy.py +0 -116
  81. adaptivetesting-1.0.1/code_examples/example_semi.py +0 -77
  82. adaptivetesting-1.0.1/data/default/0.pickle +0 -0
  83. adaptivetesting-1.0.1/data/semi/0.pickle +0 -0
  84. adaptivetesting-1.0.1/docs_generation/source/data.rst +0 -19
  85. adaptivetesting-1.0.1/docs_generation/source/implementations.rst +0 -31
  86. adaptivetesting-1.0.1/docs_generation/source/math.rst +0 -77
  87. adaptivetesting-1.0.1/docs_generation/source/models.rst +0 -46
  88. adaptivetesting-1.0.1/docs_generation/source/services.rst +0 -18
  89. adaptivetesting-1.0.1/docs_generation/source/simulation.rst +0 -29
  90. adaptivetesting-1.0.1/requirements.txt +0 -552
  91. adaptivetesting-1.0.1/uv.lock +0 -1016
  92. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/.github/workflows/publish.yml +0 -0
  93. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/.gitignore +0 -0
  94. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/.gitlab-ci.yml +0 -0
  95. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/.python-version +0 -0
  96. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/.vscode/extensions.json +0 -0
  97. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/.vscode/settings.json +0 -0
  98. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/LICENSE +0 -0
  99. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/math/item_selection/__urrys_rule.py +0 -0
  100. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/models/__algorithm_exception.py +0 -0
  101. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/models/__item_pool.py +0 -0
  102. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/models/__item_selection_exception.py +0 -0
  103. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/models/__test_item.py +0 -0
  104. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/tests/__init__.py +0 -0
  105. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/tests/test_load_test_items.py +0 -0
  106. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/adaptivetesting/tests/test_mle.py +0 -0
  107. {adaptivetesting-1.0.1/docs_generation → adaptivetesting-1.1.1/docs}/Makefile +0 -0
  108. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/docs/data.md +0 -0
  109. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/docs/implementations.md +0 -0
  110. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/docs/index.md +0 -0
  111. {adaptivetesting-1.0.1/docs_generation → adaptivetesting-1.1.1/docs}/make.bat +0 -0
  112. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/docs/math.md +0 -0
  113. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/docs/models.md +0 -0
  114. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/docs/services.md +0 -0
  115. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/docs/simulation.md +0 -0
  116. {adaptivetesting-1.0.1/docs_generation → adaptivetesting-1.1.1/docs}/source/_static/logo.svg +0 -0
  117. {adaptivetesting-1.0.1/docs_generation → adaptivetesting-1.1.1/docs}/source/_static/main.css +0 -0
  118. {adaptivetesting-1.0.1/docs_generation → adaptivetesting-1.1.1/docs}/source/index.rst +0 -0
  119. {adaptivetesting-1.0.1/docs_generation → adaptivetesting-1.1.1/docs}/source/tests.rst +0 -0
  120. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/docs/tests.md +0 -0
  121. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/images/default.svg +0 -0
  122. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/images/semi-adaptive.svg +0 -0
  123. {adaptivetesting-1.0.1 → adaptivetesting-1.1.1}/mypy.ini +0 -0
@@ -34,9 +34,6 @@ jobs:
34
34
  - name: Type checking
35
35
  run: |
36
36
  uv run mypy
37
- - name: Type checking code examples
38
- run: |
39
- uv run mypy code_examples
40
37
  - name: Test with unittest
41
38
  run: |
42
39
  uv run python -m unittest
@@ -0,0 +1,65 @@
1
+ # Breaking Changes in `adaptivetesting`
2
+
3
+ This document highlights breaking changes and updates in the `adaptivetesting` package, considering its structure, features, and potential impacts on users transitioning between versions.
4
+
5
+ ## 1. Python Version Requirement
6
+ - **Updated Requirement**: Python version `>= 3.11` is now required. Users on Python 3.10 or earlier may experience compatibility issues.
7
+
8
+ ## 2. Package Structure
9
+ - The package is organized into several key modules:
10
+ - **`adaptivetesting.models`**: Core classes including `AdaptiveTest`, `ItemPool`, and `TestItem`.
11
+ - **`adaptivetesting.implementations`**: Ready-to-use test implementations like `TestAssembler`.
12
+ - **`adaptivetesting.math`**: Mathematical functions for IRT, ability estimation, and item selection.
13
+ - **`adaptivetesting.simulation`**: Simulation framework and result management.
14
+ - **`adaptivetesting.data`**: Data management utilities for CSV and pickle formats.
15
+ - **`adaptivetesting.services`**: Abstract interfaces and protocols.
16
+
17
+ ## 3. Key Features
18
+ - **Bayesian Methods**: Built-in support for Bayesian ability estimation with customizable priors.
19
+ - **Flexible Architecture**: Object-oriented design with abstract classes for easy extension.
20
+ - **Item Response Theory**: Full support for 1PL, 2PL, 3PL, and 4PL models.
21
+ - **Multiple Estimators**:
22
+ - Maximum Likelihood Estimation (MLE)
23
+ - Bayesian Modal Estimation (BM)
24
+ - Expected A Posteriori (EAP)
25
+ - **Item Selection Strategies**: Maximum information criterion and Urry's rule.
26
+ - **Simulation Framework**: Comprehensive tools for CAT simulation and evaluation.
27
+ - **Real-world Application**: Direct transition from simulation to production testing.
28
+ - **Stopping Criteria**: Support for standard error and test length criteria.
29
+ - **Data Management**: Built-in support for CSV and pickle data formats.
30
+
31
+ ## 4. Installation Instructions
32
+ - Install from PyPI using pip:
33
+ ```bash
34
+ pip install adaptivetesting
35
+ ```
36
+ - For the latest development version:
37
+ ```bash
38
+ pip install git+https://github.com/condecon/adaptivetesting
39
+ ```
40
+
41
+ ## 5. Requirements
42
+ - The following dependencies are required:
43
+ - Python >= 3.11
44
+ - NumPy >= 2.0.0
45
+ - Pandas >= 2.2.0
46
+ - SciPy >= 1.15.0
47
+ - tqdm >= 4.67.1
48
+
49
+ ## 6. Documentation Updates
50
+ - Full documentation is available in the `docs/` directory:
51
+ - [API Reference](docs/readme.md)
52
+ - [Models Module](docs/adaptivetesting.models.md)
53
+ - [Math Module](docs/adaptivetesting.math.md)
54
+ - [Implementation Examples](docs/adaptivetesting.implementations.md)
55
+ - [Simulation Guide](docs/adaptivetesting.simulation.md)
56
+
57
+ ## 7. Testing
58
+ - Comprehensive tests are included. Run them using:
59
+ ```bash
60
+ python -m pytest adaptivetesting/tests/
61
+ ```
62
+
63
+ ---
64
+
65
+ **Action Required**: Users should review these changes and update their environments and workflows accordingly.
@@ -0,0 +1,348 @@
1
+ Metadata-Version: 2.4
2
+ Name: adaptivetesting
3
+ Version: 1.1.1
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
+ Project-URL: Homepage, https://github.com/condecon/adaptivetesting
6
+ Project-URL: Documentation, https://github.com/condecon/adaptivetesting/tree/main/docs
7
+ Project-URL: Repository, https://github.com/condecon/adaptivetesting.git
8
+ Project-URL: Issues, https://github.com/condecon/adaptivetesting/issues
9
+ Author-email: Jonas Engicht <dev@condecon.de>
10
+ License-File: LICENSE
11
+ Keywords: computerized-adaptive-testing,item-response-theory,psychology,statistics
12
+ Requires-Python: >=3.10
13
+ Requires-Dist: numpy>=2.0.0
14
+ Requires-Dist: pandas>=2.2.0
15
+ Requires-Dist: scipy>=1.15.0
16
+ Requires-Dist: tqdm>=4.67.1
17
+ Description-Content-Type: text/markdown
18
+
19
+ # adaptivetesting
20
+
21
+ <img src="/docs/source/_static/logo.svg" style="width: 100%">
22
+ </img>
23
+
24
+ **An open-source Python package for simplified, customizable Computerized Adaptive Testing (CAT) using Bayesian methods.**
25
+
26
+
27
+ ## Key Features
28
+
29
+ - **Bayesian Methods**: Built-in support for Bayesian ability estimation with customizable priors
30
+ - **Flexible Architecture**: Object-oriented design with abstract classes for easy extension
31
+ - **Item Response Theory**: Full support for 1PL, 2PL, 3PL, and 4PL models
32
+ - **Multiple Estimators**:
33
+ - Maximum Likelihood Estimation (MLE)
34
+ - Bayesian Modal Estimation (BM)
35
+ - Expected A Posteriori (EAP)
36
+ - **Item Selection Strategies**: Kaximum information criterion and Urry's rule
37
+ - **Simulation Framework**: Comprehensive tools for CAT simulation and evaluation
38
+ - **Real-world Application**: Direct transition from simulation to production testing
39
+ - **Stopping Criteria**: Support for standard error and test length criteria
40
+ - **Data Management**: Built-in support for CSV and pickle data formats
41
+
42
+ ## Installation
43
+
44
+ Install from PyPI using pip:
45
+
46
+ ```bash
47
+ pip install adaptivetesting
48
+ ```
49
+
50
+ For the latest development version:
51
+
52
+ ```bash
53
+ pip install git+https://github.com/condecon/adaptivetesting
54
+ ```
55
+
56
+ ## Requirements
57
+
58
+ - Python >= 3.10
59
+ - NumPy >= 2.0.0
60
+ - Pandas >= 2.2.0
61
+ - SciPy >= 1.15.0
62
+ - tqdm >= 4.67.1
63
+
64
+ ## Quick Start
65
+
66
+ ### Basic Example: Setting Up an Adaptive Test
67
+
68
+ ```python
69
+ from adaptivetesting.models import ItemPool, TestItem
70
+ from adaptivetesting.implementations import TestAssembler
71
+ from adaptivetesting.math.estimators import BayesModal, NormalPrior
72
+ from adaptivetesting.simulation import Simulation, StoppingCriterion, ResultOutputFormat
73
+ import pandas as pd
74
+
75
+ # Create item pool from DataFrame
76
+ items_data = pd.DataFrame({
77
+ "a": [1.32, 1.07, 0.84, 1.19, 0.95], # discrimination
78
+ "b": [-0.63, 0.18, -0.84, 0.41, -0.25], # difficulty
79
+ "c": [0.17, 0.10, 0.19, 0.15, 0.12], # guessing
80
+ "d": [0.87, 0.93, 1.0, 0.89, 0.94] # upper asymptote
81
+ })
82
+ item_pool = ItemPool.load_from_dataframe(items_data)
83
+
84
+ # Set up adaptive test
85
+ adaptive_test = TestAssembler(
86
+ item_pool=item_pool,
87
+ simulation_id="sim_001",
88
+ participant_id="participant_001",
89
+ ability_estimator=BayesModal,
90
+ estimator_args={"prior": NormalPrior(mean=0, sd=1)},
91
+ true_ability_level=0.5, # For simulation
92
+ simulation=True
93
+ )
94
+
95
+ # Run simulation
96
+ simulation = Simulation(
97
+ test=adaptive_test,
98
+ test_result_output=ResultOutputFormat.CSV
99
+ )
100
+
101
+ simulation.simulate(
102
+ criterion=StoppingCriterion.SE,
103
+ value=0.3 # Stop when standard error <= 0.3
104
+ )
105
+
106
+ # Save results
107
+ simulation.save_test_results()
108
+ ```
109
+
110
+ ### Custom Prior Example
111
+
112
+ ```python
113
+ from adaptivetesting.math.estimators import CustomPrior
114
+ from scipy.stats import t
115
+
116
+ # Create custom t prior
117
+ custom_prior = CustomPrior(t, 100)
118
+
119
+ # Use in estimator
120
+ adaptive_test = TestAssembler(
121
+ item_pool=item_pool,
122
+ simulation_id="custom_prior_sim",
123
+ participant_id="participant_002",
124
+ ability_estimator=BayesModal,
125
+ estimator_args={"prior": custom_prior},
126
+ true_ability_level=0.0,
127
+ simulation=True
128
+ )
129
+ ```
130
+
131
+ ### Real-world Testing (Non-simulation) with PsychoPy
132
+
133
+ ```python
134
+ from psychopy import visual, event
135
+ from psychopy.hardware import keyboard
136
+ from adaptivetesting.implementations import TestAssembler
137
+ from adaptivetesting.models import AdaptiveTest, ItemPool, TestItem
138
+ from adaptivetesting.data import CSVContext
139
+ from adaptivetesting.math.estimators import BayesModal, CustomPrior
140
+ from adaptivetesting.math.item_selection import maximum_information_criterion
141
+ from scipy.stats import t
142
+ import pandas as pd
143
+
144
+
145
+ # Create item pool from DataFrame
146
+ items_data = pd.DataFrame({
147
+ "a": [1.32, 1.07, 0.84, 1.19, 0.95], # discrimination
148
+ "b": [-0.63, 0.18, -0.84, 0.41, -0.25], # difficulty
149
+ "c": [0.17, 0.10, 0.19, 0.15, 0.12], # guessing
150
+ "d": [0.87, 0.93, 1.0, 0.89, 0.94] # upper asymptote
151
+ })
152
+ item_pool = ItemPool.load_from_dataframe(items_data)
153
+
154
+ # Create adaptive test
155
+ adaptive_test: AdaptiveTest = TestAssembler(
156
+ item_pool=item_pool,
157
+ simulation_id="example",
158
+ participant_id="dummy",
159
+ ability_estimator=BayesModal,
160
+ estimator_args={
161
+ "prior": CustomPrior(t, 100),
162
+ "optimization_interval":(-10, 10)
163
+ },
164
+ item_selector=maximum_information_criterion,
165
+ simulation=False,
166
+ debug=False
167
+ )
168
+
169
+ # ====================
170
+ # Setup PsychoPy
171
+ # ====================
172
+
173
+ # general setup
174
+ win = visual.Window([800, 600],
175
+ monitor="testMonitor",
176
+ units="deg",
177
+ fullscr=False)
178
+
179
+ # init keyboard
180
+ keyboard.Keyboard()
181
+
182
+
183
+ # define function to get user input
184
+ def get_response(item: TestItem) -> int:
185
+ # get index
186
+ item_difficulty: float = item.b
187
+ stimuli: str = [item for item in item_pool.test_items if item["Difficulty"] == item_difficulty][0]["word"]
188
+
189
+ # create text box and display stimulus
190
+ text_box = visual.TextBox2(win=win,
191
+ text=stimuli,
192
+ alignment="center",
193
+ size=24)
194
+ # draw text
195
+ text_box.draw()
196
+ # update window
197
+ win.flip()
198
+
199
+ # wait for pressed keys
200
+ while True:
201
+ keys = event.getKeys()
202
+ # if keys are not None
203
+ if keys:
204
+ # if the right arrow keys is pressed
205
+ # return 1
206
+ if keys[0] == "right":
207
+ return 1
208
+ # if the left arrow keys is pressed
209
+ # return 0
210
+ if keys[0] == "left":
211
+ return 0
212
+
213
+
214
+ # override adaptive test default function
215
+ adaptive_test.get_response = get_response
216
+
217
+ # start adaptive test
218
+ while True:
219
+ adaptive_test.run_test_once()
220
+
221
+ # check stopping criterion
222
+ if adaptive_test.standard_error <= 0.4:
223
+ break
224
+
225
+ # end test if all items have been shown
226
+ if len(adaptive_test.item_pool.test_items) == 0:
227
+ break
228
+
229
+ # save test results
230
+ data_context = CSVContext(
231
+ adaptive_test.simulation_id,
232
+ adaptive_test.participant_id
233
+ )
234
+
235
+ data_context.save(adaptive_test.test_results)
236
+ ```
237
+
238
+ ## Package Structure
239
+
240
+ The package is organized into several key modules:
241
+
242
+ - **`adaptivetesting.models`**: Core classes including `AdaptiveTest`, `ItemPool`, and `TestItem`
243
+ - **`adaptivetesting.implementations`**: Ready-to-use test implementations like `TestAssembler`
244
+ - **`adaptivetesting.math`**: Mathematical functions for IRT, ability estimation, and item selection
245
+ - **`adaptivetesting.simulation`**: Simulation framework and result management
246
+ - **`adaptivetesting.data`**: Data management utilities for CSV and pickle formats
247
+ - **`adaptivetesting.services`**: Abstract interfaces and protocols
248
+
249
+ ## Advanced Features
250
+
251
+ ### Multiple Stopping Criteria
252
+
253
+ ```python
254
+ simulation.simulate(
255
+ criterion=[StoppingCriterion.SE, StoppingCriterion.LENGTH],
256
+ value=[0.3, 20] # Stop at SE ≤ 0.3 OR length ≥ 20 items
257
+ )
258
+ ```
259
+
260
+ ### Pretest Phase
261
+
262
+ ```python
263
+ adaptive_test = TestAssembler(
264
+ item_pool=item_pool,
265
+ simulation_id="pretest_sim",
266
+ participant_id="participant_003",
267
+ ability_estimator=BayesModal,
268
+ estimator_args={"prior": NormalPrior(0, 1)},
269
+ pretest=True,
270
+ pretest_seed=42,
271
+ simulation=True
272
+ )
273
+ ```
274
+
275
+ ### Custom Item Selection
276
+
277
+ ```python
278
+ from adaptivetesting.math.item_selection import maximum_information_criterion
279
+
280
+ adaptive_test = TestAssembler(
281
+ item_pool=item_pool,
282
+ simulation_id="custom_selection",
283
+ participant_id="participant_004",
284
+ ability_estimator=BayesModal,
285
+ estimator_args={"prior": NormalPrior(0, 1)},
286
+ item_selector=maximum_information_criterion,
287
+ item_selector_args={"additional_param": "value"},
288
+ simulation=True
289
+ )
290
+ ```
291
+
292
+ ### Custom Optimization Interval
293
+ ```python
294
+ adaptive_test = TestAssembler(
295
+ item_pool=item_pool,
296
+ simulation_id="pretest_sim",
297
+ participant_id="participant_003",
298
+ ability_estimator=BayesModal,
299
+ estimator_args={
300
+ "prior": NormalPrior(0, 1),
301
+ "optimization_interval": (-5, 5)},
302
+ pretest_seed=42,
303
+ simulation=True
304
+ )
305
+ ```
306
+
307
+ ## Documentation
308
+
309
+ Full documentation is available in the `docs/` directory:
310
+
311
+ - [API Reference](docs/readme.md)
312
+ - [Models Module](docs/adaptivetesting.models.md)
313
+ - [Math Module](docs/adaptivetesting.math.md)
314
+ - [Implementation Examples](docs/adaptivetesting.implementations.md)
315
+ - [Simulation Guide](docs/adaptivetesting.simulation.md)
316
+
317
+ ## Testing
318
+
319
+ The package includes comprehensive tests. Run them using:
320
+
321
+ ```bash
322
+ python -m pytest adaptivetesting/tests/
323
+ ```
324
+
325
+ ## Contributing
326
+
327
+ We welcome contributions! Please see our [GitHub repository](https://github.com/condecon/adaptivetesting) for:
328
+
329
+ - Issue tracking
330
+ - Feature requests
331
+ - Pull request guidelines
332
+ - Development setup
333
+
334
+ ## Research and Applications
335
+
336
+ This package is designed for researchers and practitioners in:
337
+
338
+ - Educational assessment
339
+ - Psychological testing
340
+ - Cognitive ability measurement
341
+ - Adaptive learning systems
342
+ - Psychometric research
343
+
344
+ The package facilitates the transition from research simulation to real-world testing applications without requiring major code modifications.
345
+
346
+ ## License
347
+
348
+ This project is licensed under the terms specified in the [LICENSE](LICENSE) file.