eduloggen 1.4.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 (208) hide show
  1. eduloggen-1.4.1/.gitignore +227 -0
  2. eduloggen-1.4.1/CHANGELOG.md +278 -0
  3. eduloggen-1.4.1/LICENSE +21 -0
  4. eduloggen-1.4.1/PKG-INFO +258 -0
  5. eduloggen-1.4.1/README.md +195 -0
  6. eduloggen-1.4.1/docs/01_VISION.md +203 -0
  7. eduloggen-1.4.1/docs/02_PRD.md +1311 -0
  8. eduloggen-1.4.1/docs/03_ARCHITECTURE.md +3254 -0
  9. eduloggen-1.4.1/docs/04_EXPERIMENTAL_GENERATOR.md +266 -0
  10. eduloggen-1.4.1/docs/api/analysis.md +3 -0
  11. eduloggen-1.4.1/docs/api/benchmark.md +3 -0
  12. eduloggen-1.4.1/docs/api/cli.md +3 -0
  13. eduloggen-1.4.1/docs/api/config.md +3 -0
  14. eduloggen-1.4.1/docs/api/core.md +3 -0
  15. eduloggen-1.4.1/docs/api/datasets.md +3 -0
  16. eduloggen-1.4.1/docs/api/eduloggen.md +3 -0
  17. eduloggen-1.4.1/docs/api/evaluation.md +3 -0
  18. eduloggen-1.4.1/docs/api/generators.md +3 -0
  19. eduloggen-1.4.1/docs/api/index.md +24 -0
  20. eduloggen-1.4.1/docs/api/io.md +3 -0
  21. eduloggen-1.4.1/docs/api/models.md +3 -0
  22. eduloggen-1.4.1/docs/api/plugins.md +3 -0
  23. eduloggen-1.4.1/docs/api/privacy.md +3 -0
  24. eduloggen-1.4.1/docs/api/scenarios.md +3 -0
  25. eduloggen-1.4.1/docs/api/validation.md +3 -0
  26. eduloggen-1.4.1/docs/api/visualization.md +3 -0
  27. eduloggen-1.4.1/docs/api/workflow.md +3 -0
  28. eduloggen-1.4.1/docs/case-study-oulad.md +57 -0
  29. eduloggen-1.4.1/docs/changelog.md +55 -0
  30. eduloggen-1.4.1/docs/contributing.md +23 -0
  31. eduloggen-1.4.1/docs/getting-started.md +307 -0
  32. eduloggen-1.4.1/docs/index.md +35 -0
  33. eduloggen-1.4.1/docs/plugins.md +85 -0
  34. eduloggen-1.4.1/docs/privacy.md +54 -0
  35. eduloggen-1.4.1/mkdocs.yml +98 -0
  36. eduloggen-1.4.1/pyproject.toml +190 -0
  37. eduloggen-1.4.1/src/eduloggen/__init__.py +84 -0
  38. eduloggen-1.4.1/src/eduloggen/__main__.py +10 -0
  39. eduloggen-1.4.1/src/eduloggen/__version__.py +9 -0
  40. eduloggen-1.4.1/src/eduloggen/analysis/__init__.py +92 -0
  41. eduloggen-1.4.1/src/eduloggen/analysis/activity.py +201 -0
  42. eduloggen-1.4.1/src/eduloggen/analysis/features.py +83 -0
  43. eduloggen-1.4.1/src/eduloggen/analysis/graphs.py +59 -0
  44. eduloggen-1.4.1/src/eduloggen/analysis/profiles.py +48 -0
  45. eduloggen-1.4.1/src/eduloggen/analysis/result.py +148 -0
  46. eduloggen-1.4.1/src/eduloggen/analysis/sequences.py +52 -0
  47. eduloggen-1.4.1/src/eduloggen/analysis/service.py +77 -0
  48. eduloggen-1.4.1/src/eduloggen/analysis/sessionize.py +138 -0
  49. eduloggen-1.4.1/src/eduloggen/analysis/stats.py +81 -0
  50. eduloggen-1.4.1/src/eduloggen/analysis/strata.py +336 -0
  51. eduloggen-1.4.1/src/eduloggen/analysis/temporal.py +319 -0
  52. eduloggen-1.4.1/src/eduloggen/analysis/timing.py +74 -0
  53. eduloggen-1.4.1/src/eduloggen/analysis/transitions.py +181 -0
  54. eduloggen-1.4.1/src/eduloggen/api.py +294 -0
  55. eduloggen-1.4.1/src/eduloggen/benchmark/__init__.py +44 -0
  56. eduloggen-1.4.1/src/eduloggen/benchmark/protocol.py +183 -0
  57. eduloggen-1.4.1/src/eduloggen/benchmark/report.py +273 -0
  58. eduloggen-1.4.1/src/eduloggen/benchmark/runner.py +193 -0
  59. eduloggen-1.4.1/src/eduloggen/cli/__init__.py +11 -0
  60. eduloggen-1.4.1/src/eduloggen/cli/commands.py +659 -0
  61. eduloggen-1.4.1/src/eduloggen/cli/logs.py +70 -0
  62. eduloggen-1.4.1/src/eduloggen/cli/main.py +374 -0
  63. eduloggen-1.4.1/src/eduloggen/config/__init__.py +60 -0
  64. eduloggen-1.4.1/src/eduloggen/config/env.py +71 -0
  65. eduloggen-1.4.1/src/eduloggen/config/fingerprint.py +35 -0
  66. eduloggen-1.4.1/src/eduloggen/config/loader.py +98 -0
  67. eduloggen-1.4.1/src/eduloggen/config/merge.py +98 -0
  68. eduloggen-1.4.1/src/eduloggen/config/schema.py +445 -0
  69. eduloggen-1.4.1/src/eduloggen/core/__init__.py +66 -0
  70. eduloggen-1.4.1/src/eduloggen/core/constants.py +68 -0
  71. eduloggen-1.4.1/src/eduloggen/core/context.py +145 -0
  72. eduloggen-1.4.1/src/eduloggen/core/exceptions.py +178 -0
  73. eduloggen-1.4.1/src/eduloggen/core/typing.py +20 -0
  74. eduloggen-1.4.1/src/eduloggen/datasets/__init__.py +10 -0
  75. eduloggen-1.4.1/src/eduloggen/datasets/demo.py +208 -0
  76. eduloggen-1.4.1/src/eduloggen/evaluation/__init__.py +33 -0
  77. eduloggen-1.4.1/src/eduloggen/evaluation/clustering.py +149 -0
  78. eduloggen-1.4.1/src/eduloggen/evaluation/detection.py +262 -0
  79. eduloggen-1.4.1/src/eduloggen/generators/__init__.py +63 -0
  80. eduloggen-1.4.1/src/eduloggen/generators/artifact.py +150 -0
  81. eduloggen-1.4.1/src/eduloggen/generators/base.py +559 -0
  82. eduloggen-1.4.1/src/eduloggen/generators/calendar.py +277 -0
  83. eduloggen-1.4.1/src/eduloggen/generators/distributions.py +263 -0
  84. eduloggen-1.4.1/src/eduloggen/generators/markov.py +205 -0
  85. eduloggen-1.4.1/src/eduloggen/generators/registry.py +110 -0
  86. eduloggen-1.4.1/src/eduloggen/generators/semi_markov.py +86 -0
  87. eduloggen-1.4.1/src/eduloggen/generators/statistical.py +68 -0
  88. eduloggen-1.4.1/src/eduloggen/generators/tokenization.py +71 -0
  89. eduloggen-1.4.1/src/eduloggen/ingestion/__init__.py +12 -0
  90. eduloggen-1.4.1/src/eduloggen/io/__init__.py +108 -0
  91. eduloggen-1.4.1/src/eduloggen/io/base.py +176 -0
  92. eduloggen-1.4.1/src/eduloggen/io/coerce.py +170 -0
  93. eduloggen-1.4.1/src/eduloggen/io/corpus.py +394 -0
  94. eduloggen-1.4.1/src/eduloggen/io/ingest.py +222 -0
  95. eduloggen-1.4.1/src/eduloggen/io/mapping.py +422 -0
  96. eduloggen-1.4.1/src/eduloggen/io/quality.py +106 -0
  97. eduloggen-1.4.1/src/eduloggen/io/readers.py +269 -0
  98. eduloggen-1.4.1/src/eduloggen/io/streaming.py +31 -0
  99. eduloggen-1.4.1/src/eduloggen/io/writers.py +176 -0
  100. eduloggen-1.4.1/src/eduloggen/models/__init__.py +62 -0
  101. eduloggen-1.4.1/src/eduloggen/models/_checks.py +129 -0
  102. eduloggen-1.4.1/src/eduloggen/models/annotations.py +292 -0
  103. eduloggen-1.4.1/src/eduloggen/models/dataset.py +325 -0
  104. eduloggen-1.4.1/src/eduloggen/models/features.py +71 -0
  105. eduloggen-1.4.1/src/eduloggen/models/generator_model.py +140 -0
  106. eduloggen-1.4.1/src/eduloggen/models/records.py +322 -0
  107. eduloggen-1.4.1/src/eduloggen/models/schema_validate.py +126 -0
  108. eduloggen-1.4.1/src/eduloggen/models/vocab.py +97 -0
  109. eduloggen-1.4.1/src/eduloggen/plugins/__init__.py +34 -0
  110. eduloggen-1.4.1/src/eduloggen/plugins/registry.py +416 -0
  111. eduloggen-1.4.1/src/eduloggen/privacy/__init__.py +27 -0
  112. eduloggen-1.4.1/src/eduloggen/privacy/policies.py +173 -0
  113. eduloggen-1.4.1/src/eduloggen/py.typed +2 -0
  114. eduloggen-1.4.1/src/eduloggen/scenarios/__init__.py +98 -0
  115. eduloggen-1.4.1/src/eduloggen/scenarios/anomalies.py +496 -0
  116. eduloggen-1.4.1/src/eduloggen/scenarios/check.py +485 -0
  117. eduloggen-1.4.1/src/eduloggen/scenarios/clustering.py +258 -0
  118. eduloggen-1.4.1/src/eduloggen/scenarios/controls.py +249 -0
  119. eduloggen-1.4.1/src/eduloggen/scenarios/experiment.py +148 -0
  120. eduloggen-1.4.1/src/eduloggen/scenarios/inject.py +303 -0
  121. eduloggen-1.4.1/src/eduloggen/scenarios/profiles.py +1004 -0
  122. eduloggen-1.4.1/src/eduloggen/utils/__init__.py +12 -0
  123. eduloggen-1.4.1/src/eduloggen/utils/fs.py +112 -0
  124. eduloggen-1.4.1/src/eduloggen/utils/hashing.py +25 -0
  125. eduloggen-1.4.1/src/eduloggen/utils/seeding.py +61 -0
  126. eduloggen-1.4.1/src/eduloggen/validation/__init__.py +68 -0
  127. eduloggen-1.4.1/src/eduloggen/validation/base.py +158 -0
  128. eduloggen-1.4.1/src/eduloggen/validation/detailed.py +378 -0
  129. eduloggen-1.4.1/src/eduloggen/validation/distances.py +121 -0
  130. eduloggen-1.4.1/src/eduloggen/validation/metrics/__init__.py +51 -0
  131. eduloggen-1.4.1/src/eduloggen/validation/metrics/marginal.py +117 -0
  132. eduloggen-1.4.1/src/eduloggen/validation/metrics/privacy.py +142 -0
  133. eduloggen-1.4.1/src/eduloggen/validation/metrics/sequential.py +119 -0
  134. eduloggen-1.4.1/src/eduloggen/validation/metrics/temporal.py +32 -0
  135. eduloggen-1.4.1/src/eduloggen/validation/registry.py +77 -0
  136. eduloggen-1.4.1/src/eduloggen/validation/report.py +140 -0
  137. eduloggen-1.4.1/src/eduloggen/validation/service.py +135 -0
  138. eduloggen-1.4.1/src/eduloggen/visualization/__init__.py +73 -0
  139. eduloggen-1.4.1/src/eduloggen/visualization/base.py +155 -0
  140. eduloggen-1.4.1/src/eduloggen/visualization/dashboard.py +120 -0
  141. eduloggen-1.4.1/src/eduloggen/visualization/distributions.py +184 -0
  142. eduloggen-1.4.1/src/eduloggen/visualization/export.py +137 -0
  143. eduloggen-1.4.1/src/eduloggen/visualization/graphs.py +188 -0
  144. eduloggen-1.4.1/src/eduloggen/visualization/heatmaps.py +97 -0
  145. eduloggen-1.4.1/src/eduloggen/visualization/sankey.py +244 -0
  146. eduloggen-1.4.1/src/eduloggen/visualization/timeline.py +61 -0
  147. eduloggen-1.4.1/tests/__init__.py +5 -0
  148. eduloggen-1.4.1/tests/analysis/__init__.py +0 -0
  149. eduloggen-1.4.1/tests/analysis/conftest.py +63 -0
  150. eduloggen-1.4.1/tests/analysis/test_analyze.py +79 -0
  151. eduloggen-1.4.1/tests/analysis/test_fine_grained.py +218 -0
  152. eduloggen-1.4.1/tests/analysis/test_sessionize.py +125 -0
  153. eduloggen-1.4.1/tests/analysis/test_statistics.py +238 -0
  154. eduloggen-1.4.1/tests/benchmark/__init__.py +0 -0
  155. eduloggen-1.4.1/tests/benchmark/test_benchmark.py +266 -0
  156. eduloggen-1.4.1/tests/cli/__init__.py +0 -0
  157. eduloggen-1.4.1/tests/cli/conftest.py +80 -0
  158. eduloggen-1.4.1/tests/cli/test_api.py +119 -0
  159. eduloggen-1.4.1/tests/cli/test_cli.py +277 -0
  160. eduloggen-1.4.1/tests/config/__init__.py +0 -0
  161. eduloggen-1.4.1/tests/config/test_loading.py +209 -0
  162. eduloggen-1.4.1/tests/config/test_schema.py +181 -0
  163. eduloggen-1.4.1/tests/conftest.py +7 -0
  164. eduloggen-1.4.1/tests/core/__init__.py +0 -0
  165. eduloggen-1.4.1/tests/core/test_constants.py +63 -0
  166. eduloggen-1.4.1/tests/core/test_context.py +96 -0
  167. eduloggen-1.4.1/tests/core/test_exceptions.py +88 -0
  168. eduloggen-1.4.1/tests/datasets/__init__.py +0 -0
  169. eduloggen-1.4.1/tests/datasets/test_demo.py +25 -0
  170. eduloggen-1.4.1/tests/evaluation/__init__.py +0 -0
  171. eduloggen-1.4.1/tests/evaluation/test_clustering.py +79 -0
  172. eduloggen-1.4.1/tests/evaluation/test_detection.py +377 -0
  173. eduloggen-1.4.1/tests/generators/__init__.py +0 -0
  174. eduloggen-1.4.1/tests/generators/conftest.py +68 -0
  175. eduloggen-1.4.1/tests/generators/test_distributions.py +162 -0
  176. eduloggen-1.4.1/tests/generators/test_generators.py +423 -0
  177. eduloggen-1.4.1/tests/generators/test_registry_artifacts.py +285 -0
  178. eduloggen-1.4.1/tests/generators/test_start_times.py +111 -0
  179. eduloggen-1.4.1/tests/io/__init__.py +0 -0
  180. eduloggen-1.4.1/tests/io/test_coerce.py +153 -0
  181. eduloggen-1.4.1/tests/io/test_corpus.py +293 -0
  182. eduloggen-1.4.1/tests/io/test_ingest.py +223 -0
  183. eduloggen-1.4.1/tests/io/test_mapping.py +286 -0
  184. eduloggen-1.4.1/tests/io/test_readers_writers.py +290 -0
  185. eduloggen-1.4.1/tests/models/__init__.py +0 -0
  186. eduloggen-1.4.1/tests/models/conftest.py +33 -0
  187. eduloggen-1.4.1/tests/models/test_dataset.py +325 -0
  188. eduloggen-1.4.1/tests/models/test_records.py +267 -0
  189. eduloggen-1.4.1/tests/models/test_vocab_features.py +110 -0
  190. eduloggen-1.4.1/tests/plugins/__init__.py +0 -0
  191. eduloggen-1.4.1/tests/plugins/sample_plugin.py +83 -0
  192. eduloggen-1.4.1/tests/plugins/test_plugins.py +339 -0
  193. eduloggen-1.4.1/tests/privacy/__init__.py +0 -0
  194. eduloggen-1.4.1/tests/privacy/test_policies.py +131 -0
  195. eduloggen-1.4.1/tests/scenarios/__init__.py +0 -0
  196. eduloggen-1.4.1/tests/scenarios/test_anomalies.py +411 -0
  197. eduloggen-1.4.1/tests/scenarios/test_controls.py +499 -0
  198. eduloggen-1.4.1/tests/scenarios/test_profiles.py +552 -0
  199. eduloggen-1.4.1/tests/test_architecture.py +131 -0
  200. eduloggen-1.4.1/tests/test_package.py +64 -0
  201. eduloggen-1.4.1/tests/utils/__init__.py +0 -0
  202. eduloggen-1.4.1/tests/utils/test_utils.py +61 -0
  203. eduloggen-1.4.1/tests/validation/__init__.py +0 -0
  204. eduloggen-1.4.1/tests/validation/test_detailed.py +197 -0
  205. eduloggen-1.4.1/tests/validation/test_distances.py +71 -0
  206. eduloggen-1.4.1/tests/validation/test_validate.py +363 -0
  207. eduloggen-1.4.1/tests/visualization/__init__.py +0 -0
  208. eduloggen-1.4.1/tests/visualization/test_visualization.py +343 -0
@@ -0,0 +1,227 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ # Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ # poetry.lock
109
+ # poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ # pdm.lock
116
+ # pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ # pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # Redis
135
+ *.rdb
136
+ *.aof
137
+ *.pid
138
+
139
+ # RabbitMQ
140
+ mnesia/
141
+ rabbitmq/
142
+ rabbitmq-data/
143
+
144
+ # ActiveMQ
145
+ activemq-data/
146
+
147
+ # SageMath parsed files
148
+ *.sage.py
149
+
150
+ # Environments
151
+ .env
152
+ .envrc
153
+ .venv
154
+ env/
155
+ venv/
156
+ ENV/
157
+ env.bak/
158
+ venv.bak/
159
+
160
+ # Spyder project settings
161
+ .spyderproject
162
+ .spyproject
163
+
164
+ # Rope project settings
165
+ .ropeproject
166
+
167
+ # mkdocs documentation
168
+ /site
169
+
170
+ # mypy
171
+ .mypy_cache/
172
+ .dmypy.json
173
+ dmypy.json
174
+
175
+ # Pyre type checker
176
+ .pyre/
177
+
178
+ # pytype static type analyzer
179
+ .pytype/
180
+
181
+ # Cython debug symbols
182
+ cython_debug/
183
+
184
+ # PyCharm
185
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
186
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
187
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
188
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
189
+ # .idea/
190
+
191
+ # Abstra
192
+ # Abstra is an AI-powered process automation framework.
193
+ # Ignore directories containing user credentials, local state, and settings.
194
+ # Learn more at https://abstra.io/docs
195
+ .abstra/
196
+
197
+ # Visual Studio Code
198
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
199
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
200
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
201
+ # you could uncomment the following to ignore the entire vscode folder
202
+ # .vscode/
203
+ # Temporary file for partial code execution
204
+ tempCodeRunnerFile.py
205
+
206
+ # Ruff stuff:
207
+ .ruff_cache/
208
+
209
+ # PyPI configuration file
210
+ .pypirc
211
+
212
+ # Marimo
213
+ marimo/_static/
214
+ marimo/_lsp/
215
+ __marimo__/
216
+
217
+ # Streamlit
218
+ .streamlit/secrets.toml
219
+
220
+ # macOS Finder metadata
221
+ .DS_Store
222
+
223
+ # Real datasets (download separately; never commit)
224
+ /OULAD/
225
+ studies/**/data/
226
+ studies/**/out/
227
+ studies/**/run.log
@@ -0,0 +1,278 @@
1
+ # Changelog
2
+
3
+ All notable changes to EduLogGen are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [1.4.1] - 2026-10-09
11
+
12
+ Ready for public release: PyPI publishing, citation metadata, an OULAD case
13
+ study, and more robust automatic profiles on real data.
14
+
15
+ ### Added
16
+
17
+ - Publishing: PyPI release workflow (trusted publishing, triggered by a
18
+ version tag, with a GitHub release from the changelog), documentation
19
+ deployment to GitHub Pages, `CITATION.cff`, `SECURITY.md`, and
20
+ `CODE_OF_CONDUCT.md`
21
+ - Case study on the Open University Learning Analytics Dataset
22
+ (`studies/oulad/`, docs page "Case study: OULAD") and a SoftwareX
23
+ manuscript draft (`paper/softwarex/`)
24
+
25
+ ### Changed
26
+
27
+ - README: `pip install eduloggen`, a citation section, and absolute links so
28
+ they work on PyPI
29
+
30
+ ### Fixed
31
+
32
+ - Markov back-off now says when every session has a single event, instead
33
+ of "reducing Markov order from 1 to 1"
34
+ - Automatic profiles on real data: event types below 1% of events are now
35
+ pooled into one `share:(other)` feature, and standardised features are
36
+ capped at ±3, so a handful of learners who used a rare activity no longer
37
+ form clusters of their own (found on OULAD, where k=4 produced clusters of
38
+ 3 and 4 learners; now 42–80). `Standardizer` gains `clip` (default 3);
39
+ profile sets saved by 1.4.0 keep assigning without a cap.
40
+ - `fit_profiles` no longer fails when a profile only has very short sessions
41
+ (e.g. learners active one day a week): per-profile models now lower the
42
+ Markov order instead (`on_insufficient_data: backoff`) unless you set
43
+ `on_insufficient_data` yourself.
44
+
45
+ ## [1.4.0] - 2026-10-09
46
+
47
+ Level 2, milestone M3: behavioural profiles and profile mixtures, and
48
+ generators that learn when sessions start.
49
+
50
+ ### Changed
51
+
52
+ - Generators now learn **when** sessions start (generator version 1.1):
53
+ models record session starts per hour of day (UTC) and per day of the
54
+ training period, and generation draws starts from that learned calendar.
55
+ Synthetic sessions no longer start in hours or on days without real
56
+ activity (on the demo course, 45% of sessions previously started in hours
57
+ with no real sessions; now none do). Models fitted with earlier versions
58
+ lack these counts and generate exactly as before. An explicit `calendar`
59
+ still takes precedence; `start_time` moves the learned pattern and remains
60
+ the earliest possible start.
61
+
62
+ ### Added
63
+
64
+ - Level 2, M3 — behavioural profiles (`eduloggen.scenarios`):
65
+ - `fit_profiles(mode="auto")`: seeded k-means++ (with restarts) on
66
+ standardised per-learner features (sessions, session length, duration,
67
+ success rate, event-type shares); profiles `profile_1..k` ordered by
68
+ size, with a table of distinguishing features; `ProfileSet.assign` maps
69
+ new (e.g. holdout) learners to the nearest training profile
70
+ - `fit_profiles(mode="provided")` with a `learner_id -> profile` mapping
71
+ (`load_profile_assignments` reads a CSV)
72
+ - `define_profiles` (manual): profiles defined by start and transition
73
+ probabilities, session lengths, sessions per learner, dwell times, and
74
+ activities, without real data; proportions alone are rejected
75
+ - one generator model per profile; profiles below `min_learners`
76
+ (default 5) are an error with guidance
77
+ - `generate_profiles`: mixture by share of synthetic learners, optional
78
+ per-profile controls and a shared calendar, ids remapped after mixing,
79
+ one learner-level `profile` annotation per synthetic learner
80
+ - `ProfileSet.save` / `load_profiles` with a content fingerprint
81
+ - `evaluate_clustering` (`eduloggen.evaluation`): adjusted Rand index,
82
+ normalised mutual information, purity, and the contingency table
83
+ - `SessionCalendar.daily`: optional per-day weights (used by learned
84
+ calendars; also available in calendar files)
85
+
86
+ ## [1.3.0] - 2026-10-09
87
+
88
+ Fine-grained analysis: per activity, over time, per group, and a ranked view
89
+ of where synthetic data differs from real data.
90
+
91
+ ### Added
92
+
93
+ - Per-activity profiles (`activity_profiles`): share, session and learner
94
+ reach, start/end shares, repeat share, dwell-time distribution,
95
+ predecessors and successors, success rate, mean score, companions
96
+ - Temporal analysis (`temporal_profile`, `deadline_effects`): timezone-aware
97
+ activity by hour and weekday, weekday x hour table, weekly trends from the
98
+ first session, daily counts, gaps between a learner's sessions, activity
99
+ ratio before deadlines
100
+ - Stratified analysis (FR-A.7; `analyze_by`, `split_by`, `session_groups`):
101
+ by `course`, `week`, `weekday`, `hour`, `learner_group`, or
102
+ `metadata:<key>`, with each group's mix compared to the overall mix
103
+ - Fine-grained validation (`compare_detailed`): ranked per-token,
104
+ per-transition (including invented and never-produced transitions),
105
+ per-length, per-hour, per-weekday, and per-group differences
106
+ - CLI: `analyze --detail --by --groups --timezone --deadlines`,
107
+ `validate --detailed --by --groups --timezone`; plot `activity_heatmap`
108
+
109
+ ## [1.2.0] - 2026-10-09
110
+
111
+ Level 2, milestone M2: run controlled experiments and prove each control
112
+ took effect.
113
+
114
+ ### Added
115
+
116
+ - Level 2, milestone M2: behavioural controls, course calendars, and
117
+ manipulation checks
118
+ - `eduloggen.scenarios.Controls` / `apply_controls`: `event_weights`
119
+ (reweight transitions into a token; `0` removes it), `dwell_scale`,
120
+ `session_length` (scale or fixed), `sessions_per_learner` (mean or fixed);
121
+ controls produce a new model whose parameters record them
122
+ - `eduloggen.generators.SessionCalendar`: period, timezone-aware hour and
123
+ weekday weights, deadline surges; `generate(..., calendar=...)` for every
124
+ generator; a learner's sessions never overlap and never start in
125
+ zero-weight hours
126
+ - `manipulation_check`: compares a controlled sample with an uncontrolled
127
+ baseline (same model, seed, size) for every control, the calendar, and
128
+ anomalies; sample-size-aware tolerances for distributional checks
129
+ - `ExperimentSettings` / `run_experiment` and CLI
130
+ `generate --experiment FILE` (controls, calendar, anomalies), writing
131
+ `manipulation_check.json` / `.md`
132
+ - Generator capability tag `supports_event_weights`
133
+ - Example `examples/configs/experiment.yaml`; experiment guide
134
+
135
+ ## [1.1.0] - 2026-10-09
136
+
137
+ Level 2, milestone M1: benchmark anomaly detectors on synthetic data with
138
+ labelled ground truth.
139
+
140
+ ### Added
141
+
142
+ - Level 2, milestone M1 (`docs/04_EXPERIMENTAL_GENERATOR.md`): labelled
143
+ anomaly injection for benchmarking detectors
144
+ - `eduloggen.scenarios`: five anomaly injectors — `event_frequency`,
145
+ `abnormal_timing`, `repetition`, `inactivity` (unusual but valid) and
146
+ `unexpected_transition` (invalid workflow); `inject_anomalies` with seeded,
147
+ disjoint session selection, one anomaly per session, no overlapping
148
+ sessions, and full id remapping so ids never reveal injected records;
149
+ `register_anomaly` for custom injectors
150
+ - `Annotations` ground-truth table in `eduloggen.models`, stored as
151
+ `annotations.csv` in corpora with its own fingerprint (`read_annotations`)
152
+ - `eduloggen.evaluation.evaluate_detection`: precision, recall, F1, false
153
+ positive rate, ROC-AUC, average precision, and recall per anomaly type and
154
+ per category
155
+ - CLI: `generate --anomalies FILE` and `evaluate --corpus --predictions`
156
+ - `privacy.remap_ids_with_mapping` returning the old-to-new id mapping
157
+ - Example `examples/configs/anomalies.yaml`; detector-testing guide
158
+
159
+ ## [1.0.0] - 2026-10-09
160
+
161
+ First stable release: the complete Level 1 log generator. Learn from real
162
+ educational interaction logs, generate privacy-conscious synthetic sessions,
163
+ validate them, compare generators, and plot the results, from Python or the
164
+ `eduloggen` command line.
165
+
166
+ ### Added
167
+
168
+ - `eduloggen.core` foundation package: exception hierarchy with machine-readable
169
+ codes, schema/artifact/report version constants, default `event_type`
170
+ vocabulary, immutable `RunContext`, and shared type aliases
171
+ - `eduloggen.models` canonical domain model: immutable, validated `LogRecord`,
172
+ `Session`, and `Participant`; `Dataset` / `SyntheticDataset` snapshots with
173
+ cross-record checks, content fingerprints, and manifests; `EventVocabulary`
174
+ with preserve / map-to-other / reject policies; `Feature`
175
+ - `eduloggen.io` ingestion and corpus I/O: streaming CSV/TSV, JSON Lines, and
176
+ Parquet readers and writers; `FieldMapping` with automatic casting,
177
+ timestamp formats and timezone policy, defaults, salted ID pseudonymization,
178
+ and metadata passthrough; `ingest()` with deduplication, sorting, strict
179
+ mode, and a value-free data quality report; atomic corpus directory
180
+ read/write with overwrite protection and fingerprint integrity checks
181
+ - `parquet` optional extra (`pyarrow`)
182
+ - `eduloggen.config`: strict, immutable `AppConfig` with sections from PRD §16.4;
183
+ YAML/TOML/JSON loading; precedence CLI > `EDULOGGEN_*` env allowlist > file >
184
+ defaults via `resolve_config`; config fingerprints; relative paths resolved
185
+ against the config file
186
+ - `FieldMapping.from_file` for YAML/TOML/JSON mapping files
187
+ - Example experiment config and field mapping under `examples/configs/`
188
+ - `pyyaml` as the first runtime dependency
189
+ - `eduloggen.utils`: versioned, order-independent seed derivation
190
+ (`derive_seed`, `make_rng`) and canonical JSON fingerprints
191
+ - `eduloggen.privacy`: seeded remapping of learner/session/event ids
192
+ (default for generated data) and metadata key stripping
193
+ - Architecture test enforcing the package dependency matrix (SAD §8.2)
194
+ - `eduloggen.analysis`: `sessionize()` with explicit / idle-timeout /
195
+ composite strategies and configurable tokenization; order-k transition
196
+ counts with start padding and additive smoothing; n-grams and rare-n-gram
197
+ detection; inter-event, sojourn, and duration statistics; session feature
198
+ rows, learner profiles, corpus features, and a navigation graph;
199
+ `analyze()` returning an `AnalysisResult` with JSON and Markdown exports
200
+ - `eduloggen.generators`: `BaseGenerator` contract (fit / generate / describe /
201
+ save / load) with shared population modelling (sessions per learner,
202
+ inter-session gaps, companion fields, courses) and seeded, id-remapped
203
+ output; `markov` (order-k with backoff and additive smoothing; empirical,
204
+ Poisson, or fixed lengths), `semi_markov` (per-token sojourn timing:
205
+ empirical, lognormal, gamma, exponential), and `independent` baseline;
206
+ generator registry; inspectable JSON model artifacts with integrity checks
207
+ - `GeneratorModel` in `eduloggen.models`
208
+ - `eduloggen.validation`: `validate()` comparing real and synthetic datasets
209
+ with 11 built-in metrics — `event_type_tvd`, `activity_jsd`,
210
+ `session_length_ks`, `session_duration_w1`, `interevent_time_ks`,
211
+ `bigram_tvd`, `transition_jsd`, `topn_path_overlap`, and privacy indicators
212
+ `exact_session_dup_rate`, `rare_ngram_replay_rate`, `nn_distance_p05`;
213
+ thresholds with pass / fail / info / skip statuses; `ValidationReport` with
214
+ JSON and Markdown output; metric registry for custom metrics
215
+ - `eduloggen.datasets.demo_dataset`: seeded, fully synthetic demo course corpus
216
+ - `eduloggen.benchmark`: protocol `session_fidelity_v1` with a learner-level
217
+ holdout split, multi-seed runs, mean/std aggregation, fit/generate timings,
218
+ a real-vs-real reference row, failure isolation per generator, and
219
+ `BenchmarkReport` JSON/Markdown output; `run_benchmark` in the API
220
+ - CLI commands `benchmark` and `demo`
221
+ - CI smoke job running the full pipeline and benchmark on the demo corpus
222
+ - `eduloggen.visualization` (optional `viz` extra): event/activity frequency,
223
+ session length and duration, inter-event time (histogram and ECDF), and
224
+ transition heatmap comparisons; sampled session timelines; validation and
225
+ benchmark charts; colour-blind-safe palette; reproducible PNG/SVG/PDF export;
226
+ `plot_datasets` for the standard set; CLI `plot` command
227
+ - `eduloggen.plugins`: entry-point discovery (`eduloggen.plugins.<kind>`) for
228
+ generators, metrics, readers, visualizers, and benchmark suites; contract
229
+ checks before registration; built-ins protected; broken plugins reported
230
+ without crashing (`strict=True` to fail); `register_plugin`,
231
+ `unregister_plugin`, `list_plugins`; CLI discovers at startup, `plugins`
232
+ shows sources, versions, and errors; run manifests record plugin versions
233
+ - Registration hooks: `register_reader` (with file suffixes),
234
+ `register_plot`, `register_protocol`; `BUILTIN_*` name sets
235
+ - Plugin author guide (`docs/plugins.md`)
236
+ - Node-link transition graph (`plot_transition_graph`) and multi-step Sankey
237
+ pathway diagram (`plot_sankey`, `sankey_flows`), matplotlib only
238
+ - `eduloggen.api` workflow façade (`load_config`, `ingest`, `load_dataset`,
239
+ `save_dataset`, `sessionize`, `analyze`, `fit_generator`, `generate`,
240
+ `validate`), re-exported from `import eduloggen`
241
+ - CLI commands `ingest`, `sessionize`, `analyze`, `fit`, `generate`,
242
+ `validate`, `info`, `plugins` with global `--config`, `--seed`, `-v`,
243
+ `--quiet`, `--json-logs`, `--force`, `--run-id`; exit codes 0/1/2;
244
+ `run_manifest.json` in every output directory; `python -m eduloggen`
245
+ - Documentation: privacy and responsible-use statement, end-to-end
246
+ getting-started guide, API reference pages for every package
247
+
248
+ ### Changed
249
+
250
+ - Atomic output-directory writing moved to `eduloggen.utils.fs` and shared by
251
+ corpus and model artifacts
252
+ - SAD §8.2: `validation` may depend on `analysis` (documented in the matrix)
253
+ - Coverage gate raised from 80% to 95% (ADR-011)
254
+ - `io.format` and `ingest(format=...)` accept plugin reader names
255
+ - `eduloggen.cli` is now a package; the `eduloggen` console script entry
256
+ point is unchanged
257
+ - `eduloggen.ingestion` now re-exports the ingest API from `eduloggen.io`
258
+
259
+ ## [0.1.0] - 2026-07-29
260
+
261
+ ### Added
262
+
263
+ - Initial production-quality package skeleton (`src` layout)
264
+ - Package metadata and build configuration via `pyproject.toml`
265
+ - Tooling: Ruff, Black, MyPy, PyTest, pre-commit, MkDocs
266
+ - GitHub Actions continuous integration workflow
267
+ - Documented subpackage namespaces for ingestion, analysis, generators,
268
+ validation, visualization, and CLI
269
+ - MIT license and Semantic Versioning policy
270
+
271
+ [Unreleased]: https://github.com/anisbey1/EduLogGen/compare/v1.4.1...HEAD
272
+ [1.4.1]: https://github.com/anisbey1/EduLogGen/compare/v1.4.0...v1.4.1
273
+ [1.4.0]: https://github.com/anisbey1/EduLogGen/compare/v1.3.0...v1.4.0
274
+ [1.3.0]: https://github.com/anisbey1/EduLogGen/compare/v1.2.0...v1.3.0
275
+ [1.2.0]: https://github.com/anisbey1/EduLogGen/compare/v1.1.0...v1.2.0
276
+ [1.1.0]: https://github.com/anisbey1/EduLogGen/compare/v1.0.0...v1.1.0
277
+ [1.0.0]: https://github.com/anisbey1/EduLogGen/compare/v0.1.0...v1.0.0
278
+ [0.1.0]: https://github.com/anisbey1/EduLogGen/releases/tag/v0.1.0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 anisbey1
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.