mcqpy-core 0.2.0__tar.gz → 0.2.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 (53) hide show
  1. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/PKG-INFO +1 -1
  2. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/pyproject.toml +1 -1
  3. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/grading/analysis/overall_analysis.py +1 -1
  4. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/question/filter/base_filter.py +11 -0
  5. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/question/filter/date.py +1 -0
  6. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/question/filter/manifest.py +1 -0
  7. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/question/filter/stratified.py +2 -1
  8. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/question/question_bank.py +3 -0
  9. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/README.md +0 -0
  10. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/__init__.py +0 -0
  11. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/__init__.py +0 -0
  12. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/_selection.py +0 -0
  13. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/build.py +0 -0
  14. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/check_latex.py +0 -0
  15. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/config.py +0 -0
  16. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/export/__init__.py +0 -0
  17. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/export/main.py +0 -0
  18. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/export/token.py +0 -0
  19. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/export/web.py +0 -0
  20. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/grade.py +0 -0
  21. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/init.py +0 -0
  22. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/main.py +0 -0
  23. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/question/__init__.py +0 -0
  24. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/question/check_tags.py +0 -0
  25. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/question/init.py +0 -0
  26. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/question/main.py +0 -0
  27. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/question/render.py +0 -0
  28. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/question/validate.py +0 -0
  29. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/utils/__init__.py +0 -0
  30. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/utils/autofill.py +0 -0
  31. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/utils/check_filter.py +0 -0
  32. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/cli/utils/main.py +0 -0
  33. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/front_config.py +0 -0
  34. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/grading/__init__.py +0 -0
  35. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/grading/analysis/__init__.py +0 -0
  36. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/grading/analysis/question_analysis.py +0 -0
  37. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/grading/analysis/utils.py +0 -0
  38. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/grading/grader.py +0 -0
  39. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/grading/rubric.py +0 -0
  40. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/grading/types.py +0 -0
  41. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/header_config.py +0 -0
  42. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/manifest.py +0 -0
  43. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/question/__init__.py +0 -0
  44. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/question/filter/__init__.py +0 -0
  45. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/question/filter/difficulty.py +0 -0
  46. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/question/filter/factory.py +0 -0
  47. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/question/filter/slug.py +0 -0
  48. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/question/filter/tag.py +0 -0
  49. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/question/question.py +0 -0
  50. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/question/utils.py +0 -0
  51. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/web/__init__.py +0 -0
  52. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/web/bundle.py +0 -0
  53. {mcqpy_core-0.2.0 → mcqpy_core-0.2.2}/src/mcqpy_core/web/token.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: mcqpy-core
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Core question, manifest, grading, analysis, and browser-safe runtime logic for MCQPy
5
5
  Author: Mads-Peter
6
6
  Author-email: Mads-Peter <machri@phys.au.dk>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mcqpy-core"
3
- version = "0.2.0"
3
+ version = "0.2.2"
4
4
  description = "Core question, manifest, grading, analysis, and browser-safe runtime logic for MCQPy"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -9,7 +9,7 @@ from scipy.stats import pearsonr
9
9
  from mcqpy_core.grading.analysis.utils import AnalysisFigure
10
10
 
11
11
  def get_points_array(graded_sets: list[GradedSet]):
12
- point_arrays = np.zeros((len(graded_sets), 20))
12
+ point_arrays = np.zeros((len(graded_sets), len(graded_sets[0].graded_questions)))
13
13
  for i, graded_set in enumerate(graded_sets):
14
14
  for j, question in enumerate(graded_set.graded_questions):
15
15
  point_arrays[i, j] = question.point_value
@@ -1,6 +1,7 @@
1
1
  """Module for base-class for question filters."""
2
2
  from abc import ABC, abstractmethod
3
3
  from typing import TYPE_CHECKING, Any, Callable
4
+ import random
4
5
 
5
6
  if TYPE_CHECKING:
6
7
  from mcqpy_core.question.question import Question
@@ -15,6 +16,16 @@ class BaseFilter(ABC):
15
16
  def __and__(self, other: 'BaseFilter') -> 'CompositeFilter':
16
17
  """Allow chaining filters with & operator."""
17
18
  return CompositeFilter([self, other])
19
+
20
+ def set_rng(self, rng: random.Random):
21
+ """Set the random number generator for this filter and any sub-filters."""
22
+ self._rng = rng
23
+
24
+ def get_rng(self) -> random.Random:
25
+ """Get the random number generator for this filter."""
26
+ if hasattr(self, '_rng'):
27
+ return self._rng
28
+ return random.Random() # Return a default RNG if not set
18
29
 
19
30
 
20
31
  class CompositeFilter(BaseFilter):
@@ -1,6 +1,7 @@
1
1
  """
2
2
  Date filter for questions.
3
3
  """
4
+ import random
4
5
  from typing import TYPE_CHECKING
5
6
 
6
7
  from mcqpy_core.question.filter.base_filter import BaseFilter
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import random
5
6
  from typing import TYPE_CHECKING
6
7
 
7
8
  from mcqpy_core.question.filter.base_filter import BaseFilter
@@ -58,11 +58,12 @@ class StratifiedFilter(BaseFilter):
58
58
  def apply(self, questions: list["Question"]) -> list["Question"]:
59
59
  selected_questions = []
60
60
  total_questions = self.number_of_questions
61
+ rng = self.get_rng()
61
62
 
62
63
  for filt, prop in zip(self.filters, self.proportions):
63
64
  num_to_select = int(total_questions * prop)
64
65
  filtered = list(filt.apply(questions))
65
- random.shuffle(filtered)
66
+ rng.shuffle(filtered)
66
67
  selected_questions.extend(filtered[:num_to_select])
67
68
 
68
69
  return selected_questions
@@ -168,6 +168,9 @@ class QuestionBank:
168
168
  if not self._filters:
169
169
  questions = self.get_all_questions()
170
170
  else:
171
+ for f in self._filters:
172
+ f.set_rng(self._rng)
173
+
171
174
  comp_filter = CompositeFilter(self._filters)
172
175
  questions = comp_filter.apply(self.get_all_questions())
173
176
 
File without changes