PyKubeGrader 0.1.2__py3-none-any.whl → 0.1.3__py3-none-any.whl

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.
@@ -1 +1,10 @@
1
+ # Auto-generated __init__.py
1
2
 
3
+ from . import select_many
4
+ from . import multiple_choice
5
+ from . import true_false
6
+ from . import reading_question
7
+ from . import student_info
8
+ from . import types_question
9
+
10
+ __all__ = ['select_many', 'multiple_choice', 'true_false', 'reading_question', 'student_info', 'types_question']
@@ -1,6 +1,13 @@
1
1
  import panel as pn
2
2
 
3
3
  from ..widgets_base.multi_select import MultiSelectQuestion
4
+ from ..widgets.style import drexel_colors, raw_css
5
+
6
+ # Pass the custom CSS to Panel
7
+ pn.extension(design="material", global_css=[drexel_colors], raw_css=[raw_css])
8
+
9
+ # Add the custom CSS to Panel
10
+ pn.config.raw_css.append(raw_css)
4
11
 
5
12
  #
6
13
  # Style function
@@ -50,6 +57,8 @@ def MultiSelect(
50
57
  # Question class
51
58
  #
52
59
 
60
+ # TODO: add grade all or grade in parts.
61
+
53
62
 
54
63
  class SelectMany(MultiSelectQuestion):
55
64
  def __init__(
@@ -98,6 +107,7 @@ class SelectMany(MultiSelectQuestion):
98
107
  """,
99
108
  ],
100
109
  points=1,
110
+ grade="all",
101
111
  ):
102
112
  super().__init__(
103
113
  title=title,
@@ -0,0 +1,47 @@
1
+ import panel as pn
2
+
3
+ # Extend the Material Design with custom Drexel colors
4
+ drexel_colors = """
5
+ :root {
6
+ --panel-primary-color: #07294D; /* Drexel Blue */
7
+ --design-primary-color: #07294D; /* Drexel Blue */
8
+ --design-primary-text-color: #FFFFFF; /* White text on primary */
9
+ --design-secondary-color: #FFC600; /* Drexel Gold */
10
+ --design-secondary-text-color: #07294D; /* Blue text on secondary */
11
+ --design-background-color: #F8F8F8; /* Soft background */
12
+ --design-background-text-color: #07294D; /* Blue text on background */
13
+ --design-surface-color: #FFFFFF; /* White surface */
14
+ --design-surface-text-color: #07294D; /* Blue text on surface */
15
+ }
16
+ :host {
17
+ --design-primary-color: #07294D; /* Drexel Blue */
18
+ --design-primary-text-color: #FFFFFF; /* White text on primary */
19
+ --design-secondary-color: #FFC600; /* Drexel Gold */
20
+ --design-secondary-text-color: #07294D; /* Blue text on secondary */
21
+ --design-background-color: #F8F8F8; /* Soft background */
22
+ --design-background-text-color: #07294D; /* Blue text on background */
23
+ --design-surface-color: #FFFFFF; /* White surface */
24
+ --design-surface-text-color: #07294D; /* Blue text on surface */}
25
+ """
26
+
27
+ raw_css = """
28
+ /* Styling for the labels */
29
+ .bk-input-group label {
30
+ color: #07294D !important; /* Drexel Blue label text color */
31
+ }
32
+
33
+ /* Styling for CheckBoxGroup and RadioBoxGroup inputs */
34
+ .bk-input-group input[type="radio"] {
35
+ accent-color: #07294D !important; /* Drexel Blue accent for inputs */
36
+ }
37
+
38
+ input[type='checkbox']:checked {
39
+ accent-color: #07294D !important;
40
+ }
41
+
42
+ input[type='checkbox'] {
43
+ width: 16px;
44
+ height: 16px;
45
+ margin-right: 8px;
46
+ }
47
+ """
@@ -0,0 +1,101 @@
1
+ from typing import Tuple
2
+
3
+ import panel as pn
4
+
5
+ from ..utils import list_of_lists
6
+ from ..widgets_base.select import SelectQuestion
7
+ from .style import drexel_colors, raw_css
8
+
9
+ import panel as pn
10
+
11
+ # Pass the custom CSS to Panel
12
+ pn.extension(design="material", global_css=[drexel_colors], raw_css=[raw_css])
13
+
14
+ #
15
+ # Style function
16
+ #
17
+
18
+
19
+ import panel as pn
20
+ from typing import List, Tuple
21
+
22
+
23
+ def TrueFalse_style(
24
+ descriptions: List[str],
25
+ options: List[str] | List[List[str]],
26
+ initial_vals: List[str],
27
+ ) -> Tuple[List[pn.pane.HTML], List[pn.widgets.RadioBoxGroup]]:
28
+ """
29
+ Creates a styled True/False question layout with descriptions and radio buttons.
30
+
31
+ Args:
32
+ descriptions (List[str]): List of question descriptions.
33
+ options (List[str] or List[List[str]]): List of options, either as a single list or list of lists.
34
+ initial_vals (List[str]): Initial selected values for each question.
35
+
36
+ Returns:
37
+ Tuple[List[pn.pane.HTML], List[pn.widgets.RadioBoxGroup]]: Styled description panes and radio button groups.
38
+ """
39
+ desc_width = "100%" # Responsive width for descriptions
40
+ button_width = "100%" # Responsive width for radio buttons
41
+
42
+ # Create description widgets
43
+ desc_widgets = [
44
+ pn.pane.HTML(
45
+ f"""
46
+ <div style="text-align: left; width: {desc_width}; padding: 10px 0;">
47
+ <b>{desc}</b>
48
+ </div>
49
+ """,
50
+ sizing_mode="stretch_width",
51
+ )
52
+ for desc in descriptions
53
+ ]
54
+
55
+ # Create radio button groups
56
+ radio_buttons = [
57
+ pn.widgets.RadioBoxGroup(
58
+ options=option,
59
+ value=value,
60
+ width_policy="max", # Automatically scales to fit content
61
+ sizing_mode="stretch_width", # Make width responsive
62
+ )
63
+ for value, option in zip(
64
+ initial_vals,
65
+ options if isinstance(options[0], list) else [options] * len(initial_vals),
66
+ )
67
+ ]
68
+
69
+ return desc_widgets, radio_buttons
70
+
71
+
72
+ #
73
+ # Question class
74
+ #
75
+
76
+ class TFQuestion(SelectQuestion):
77
+
78
+ def __init__(
79
+ self,
80
+ title="Select if the statement is True or False",
81
+ style=TrueFalse_style,
82
+ question_number=2,
83
+ keys=["MC1", "MC2", "MC3", "MC4"],
84
+ options=None,
85
+ descriptions=[
86
+ "Which of the following stores key:value pairs?",
87
+ "The following condition returns to the next iteration of the loop",
88
+ "Which operator is used for exponentiation in Python?",
89
+ "Which method is used to add an element to the end of a list in Python?",
90
+ ],
91
+ points=2,
92
+ ):
93
+ super().__init__(
94
+ title=title,
95
+ style=style,
96
+ question_number=question_number,
97
+ keys=keys,
98
+ options=[["True", "False"] for _ in range(len(keys))],
99
+ descriptions=descriptions,
100
+ points=points,
101
+ )
@@ -1,9 +1,17 @@
1
1
  from typing import Callable, Tuple
2
2
 
3
3
  import panel as pn
4
+ import time
4
5
 
5
6
  from ..telemetry import ensure_responses, update_responses
6
7
  from ..utils import shuffle_questions
8
+ from ..widgets.style import drexel_colors, raw_css
9
+
10
+ # Pass the custom CSS to Panel
11
+ pn.extension(design="material", global_css=[drexel_colors], raw_css=[raw_css])
12
+
13
+ # Add the custom CSS to Panel
14
+ pn.config.raw_css.append(raw_css)
7
15
 
8
16
 
9
17
  class MultiSelectQuestion:
@@ -50,7 +58,7 @@ class MultiSelectQuestion:
50
58
  descriptions, options, self.initial_vals
51
59
  )
52
60
 
53
- self.submit_button = pn.widgets.Button(name="Submit")
61
+ self.submit_button = pn.widgets.Button(name="Submit", button_type="primary")
54
62
  self.submit_button.on_click(self.submit)
55
63
 
56
64
  widget_pairs = shuffle_questions(description_widgets, self.widgets, seed)
@@ -93,7 +101,9 @@ class MultiSelectQuestion:
93
101
  for key, value in zip(self.keys, responses_flat):
94
102
  update_responses(key, value)
95
103
 
96
- print("Responses recorded successfully")
104
+ self.submit_button.name = "Responses Submitted"
105
+ time.sleep(1)
106
+ self.submit_button.name = "Submit"
97
107
 
98
108
  def show(self):
99
109
  return self.layout
@@ -4,6 +4,12 @@ import panel as pn
4
4
 
5
5
  from ..telemetry import ensure_responses, update_responses
6
6
  from ..utils import shuffle_questions
7
+ from ..widgets.style import drexel_colors
8
+ import time
9
+ from IPython.display import update_display, display
10
+
11
+ # Pass the custom CSS to Panel
12
+ pn.extension(design="material", global_css=[drexel_colors])
7
13
 
8
14
 
9
15
  class SelectQuestion:
@@ -66,7 +72,19 @@ class SelectQuestion:
66
72
  for key, value in selections.items():
67
73
  update_responses(key, value)
68
74
 
69
- print("Responses recorded successfully")
75
+ self.submit_button.name = "Responses Submitted"
76
+ time.sleep(1)
77
+ self.submit_button.name = "Submit"
78
+
79
+ # # Display the message with a unique display_id
80
+ # display_id = "temp_message"
81
+ # display("Responses recorded successfully", display_id=display_id)
82
+
83
+ # # Wait for 1 second
84
+ # time.sleep(1)
85
+
86
+ # # Update the display with an empty string to clear it
87
+ # update_display('', display_id=display_id)
70
88
 
71
89
  def show(self):
72
90
  return self.layout
@@ -1,20 +0,0 @@
1
- pykubegrader/__init__.py,sha256=AoAkdfIjDDZGWLlsIRENNq06L9h46kDGBIE8vRmsCfg,311
2
- pykubegrader/initialize.py,sha256=PACquuxFkvOKUx51Rv6_RVu1YnYXf9L_W3hmMY5IxMw,706
3
- pykubegrader/telemetry.py,sha256=eAzb54-lHFcgv0IsLFwsWr4nm_D7u-n-zOdR4cKGID4,3291
4
- pykubegrader/utils.py,sha256=dKw6SyRYU3DWRgD3xER7wq-C9e1daWPkqr901LpcwiQ,642
5
- pykubegrader/validate.py,sha256=QzdsjSS7rBzvBj_s_VHk-shjkPE-NYHQrYI3UHbq7Yo,10632
6
- pykubegrader/widgets/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
7
- pykubegrader/widgets/multiple_choice.py,sha256=NjD3-uXSnibpUQ0mO3hRp_O-rynFyl0Dz6IXE4tnCRI,2078
8
- pykubegrader/widgets/reading_question.py,sha256=y30_swHwzH8LrT8deWTnxctAAmR8BSxTlXAqMgUrAT4,3031
9
- pykubegrader/widgets/select_many.py,sha256=NRRs9P3Jygl9eUVW16nxMLNlHfFDuINgsFhMyXiOsXU,3826
10
- pykubegrader/widgets/student_info.py,sha256=xhQgKehk1r5e6N_hnjAIovLdPvQju6ZqQTOiPG0aevg,3568
11
- pykubegrader/widgets/types_question.py,sha256=kZdRRXyFzOtYTmGdC7XWb_2oaxqg1WSuLcQn_sTj6Qc,2300
12
- pykubegrader/widgets_base/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
13
- pykubegrader/widgets_base/multi_select.py,sha256=o9FwOSkfjarSZuC0wgBJLSRNtnY1-q_og1k_cdyJki8,3105
14
- pykubegrader/widgets_base/reading.py,sha256=4uTLmlPzCwxVzufFhPjM7W19uMGguRb6y4eAV3x-zAc,5314
15
- pykubegrader/widgets_base/select.py,sha256=5k-LoD3fTZYUOubRiTeQcVN5YDGK28x4Qb2l1aRVKzo,2181
16
- PyKubeGrader-0.1.2.dist-info/LICENSE.txt,sha256=YTp-Ewc8Kems8PJEE27KnBPFnZSxoWvSg7nnknzPyYw,1546
17
- PyKubeGrader-0.1.2.dist-info/METADATA,sha256=2S4jh--r5j8sNCgtk5YKn0ZHJ9OdvPmXDEZOu4a5VmI,2640
18
- PyKubeGrader-0.1.2.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
19
- PyKubeGrader-0.1.2.dist-info/top_level.txt,sha256=e550Klfze6higFxER1V62fnGOcIgiKRbsrl9CC4UdtQ,13
20
- PyKubeGrader-0.1.2.dist-info/RECORD,,