donb-hf commited on
Commit
0f5db8a
Β·
verified Β·
1 Parent(s): d35ce58

add country authority

Browse files
Files changed (1) hide show
  1. lesson_graph.py +43 -63
lesson_graph.py CHANGED
@@ -17,6 +17,8 @@ class NodeType(Enum):
17
  ASSESSMENT = "Assessment"
18
  RESOURCE = "Resource"
19
  SCHOOL_BOARD = "School Board"
 
 
20
 
21
  class ResetState(NamedTuple):
22
  teacher_name: str
@@ -27,6 +29,7 @@ class ResetState(NamedTuple):
27
  assessment: str
28
  resource: str
29
  school_board: str
 
30
  message: str
31
 
32
  class LessonGraph:
@@ -38,7 +41,8 @@ class LessonGraph:
38
  "activity": "",
39
  "assessment": "",
40
  "resource": "",
41
- "school_board": ""
 
42
  }
43
 
44
  REQUIRED_FIELDS = ["teacher_name", "subject", "grade_level"]
@@ -51,7 +55,8 @@ class LessonGraph:
51
  NodeType.ACTIVITY: "#FF99FF",
52
  NodeType.ASSESSMENT: "#FFFF99",
53
  NodeType.RESOURCE: "#99FFFF",
54
- NodeType.SCHOOL_BOARD: "#CCCCCC"
 
55
  }
56
 
57
  def __init__(self):
@@ -72,20 +77,25 @@ class LessonGraph:
72
  Add nodes and edges to the lesson plan graph for the given inputs.
73
  Returns a search string and the graph image.
74
  """
75
- self.graph.clear() # Clear previous graph
76
  self.inputs.update(kwargs)
77
-
78
- # Validate only required fields
79
  self.validate_required_fields()
80
-
81
- # Define node details and add them to the graph
82
  nodes = {
83
  self.inputs["teacher_name"]: {"type": NodeType.USER, "role": "Teacher"},
84
  self.inputs["subject"]: {"type": NodeType.SUBJECT, "description": "Core subject area"},
85
  self.inputs["grade_level"]: {"type": NodeType.GRADE_LEVEL, "description": "Target grade for the lesson"},
86
  }
87
-
88
- # Add optional nodes if they exist
 
 
 
 
 
 
 
89
  optional_nodes = {
90
  "learning_objective": NodeType.LEARNING_OBJECTIVE,
91
  "activity": NodeType.ACTIVITY,
@@ -93,88 +103,58 @@ class LessonGraph:
93
  "resource": NodeType.RESOURCE,
94
  "school_board": NodeType.SCHOOL_BOARD
95
  }
96
-
97
  for field, node_type in optional_nodes.items():
98
  if self.inputs.get(field):
99
  nodes[self.inputs[field]] = {"type": node_type, "description": f"{node_type.value}"}
100
-
101
  # Add nodes to the graph
102
  for node, attributes in nodes.items():
103
  self.graph.add_node(node, **attributes)
104
-
105
- # Define the relationships between nodes
106
  edges = [
107
  (self.inputs["teacher_name"], self.inputs["subject"], {"relationship": "TEACHES"}),
108
  (self.inputs["subject"], self.inputs["grade_level"], {"relationship": "HAS_GRADE"})
109
  ]
110
-
111
- # Add optional edges
 
 
 
 
 
 
 
112
  if self.inputs.get("learning_objective"):
113
- edges.extend([
114
- (self.inputs["subject"], self.inputs["learning_objective"], {"relationship": "COVERS"}),
115
- (self.inputs["learning_objective"], self.inputs["school_board"], {"relationship": "ALIGNS_WITH"}) if self.inputs.get("school_board") else None
116
- ])
117
-
118
  if self.inputs.get("activity") and self.inputs.get("learning_objective"):
119
  edges.append((self.inputs["activity"], self.inputs["learning_objective"], {"relationship": "ACHIEVES"}))
120
-
121
  if self.inputs.get("activity") and self.inputs.get("resource"):
122
  edges.append((self.inputs["activity"], self.inputs["resource"], {"relationship": "REQUIRES"}))
123
-
124
  if self.inputs.get("learning_objective") and self.inputs.get("assessment"):
125
  edges.append((self.inputs["learning_objective"], self.inputs["assessment"], {"relationship": "EVALUATED_BY"}))
126
-
127
  if self.inputs.get("school_board"):
128
  edges.append((self.inputs["teacher_name"], self.inputs["school_board"], {"relationship": "BELONGS_TO"}))
129
-
130
  # Remove None entries from edges list
131
  edges = [edge for edge in edges if edge is not None]
132
  self.graph.add_edges_from(edges)
133
-
134
  # Generate the search string for content discovery
135
  search_string = f"{self.inputs['subject']} {self.inputs['grade_level']} {self.inputs.get('learning_objective', '')} {self.inputs.get('activity', '')} {self.inputs.get('resource', '')}".strip()
136
-
137
  # Get the graph image
138
  image = self.draw_graph()
139
-
140
- # Return the search string and the graph image
141
  return search_string, image
142
 
143
- def draw_graph(self) -> Image.Image:
144
- """
145
- Visualize the graph using Matplotlib, handling layout, labels, and interactivity.
146
- """
147
- fig, ax = plt.subplots(figsize=(14, 10))
148
- pos = nx.spring_layout(self.graph, k=0.9, iterations=50)
149
-
150
- self._draw_nodes(ax, pos)
151
- self._draw_edges(ax, pos)
152
- self._add_legend(ax)
153
-
154
- plt.title("Your Educational Landscape", fontsize=16)
155
- plt.axis('off')
156
- plt.tight_layout()
157
-
158
- self._add_interactivity()
159
-
160
- # Save the plot to a BytesIO object
161
- buf = BytesIO()
162
- plt.savefig(buf, format="png", dpi=300, bbox_inches="tight")
163
- buf.seek(0)
164
- plt.close(fig)
165
-
166
- return Image.open(buf)
167
-
168
- def _draw_nodes(self, ax, pos):
169
- node_colors = [self.COLOR_MAP[self.graph.nodes[node]['type']] for node in self.graph.nodes()]
170
- nx.draw_networkx_nodes(self.graph, pos, node_color=node_colors, node_size=3000, alpha=0.8, ax=ax)
171
- nx.draw_networkx_labels(self.graph, pos, font_size=10, font_weight="bold", ax=ax)
172
-
173
- def _draw_edges(self, ax, pos):
174
- nx.draw_networkx_edges(self.graph, pos, edge_color='gray', arrows=True, arrowsize=20, ax=ax)
175
- edge_labels = nx.get_edge_attributes(self.graph, 'relationship')
176
- nx.draw_networkx_edge_labels(self.graph, pos, edge_labels=edge_labels, font_size=8, ax=ax)
177
-
178
  def _add_legend(self, ax):
179
  legend_elements = [mpatches.Patch(color=color, label=node_type.value) for node_type, color in self.COLOR_MAP.items()]
180
  ax.legend(handles=legend_elements, loc='upper left', bbox_to_anchor=(1, 1), title="Node Types")
 
17
  ASSESSMENT = "Assessment"
18
  RESOURCE = "Resource"
19
  SCHOOL_BOARD = "School Board"
20
+ COUNTRY_AUTHORITY = "Country Authority" # New NodeType
21
+
22
 
23
  class ResetState(NamedTuple):
24
  teacher_name: str
 
29
  assessment: str
30
  resource: str
31
  school_board: str
32
+ country_authority: str # New field
33
  message: str
34
 
35
  class LessonGraph:
 
41
  "activity": "",
42
  "assessment": "",
43
  "resource": "",
44
+ "school_board": "",
45
+ "country_authority": "" # New field
46
  }
47
 
48
  REQUIRED_FIELDS = ["teacher_name", "subject", "grade_level"]
 
55
  NodeType.ACTIVITY: "#FF99FF",
56
  NodeType.ASSESSMENT: "#FFFF99",
57
  NodeType.RESOURCE: "#99FFFF",
58
+ NodeType.SCHOOL_BOARD: "#CCCCCC",
59
+ NodeType.COUNTRY_AUTHORITY: "#FFA07A" # New color for Country Authority
60
  }
61
 
62
  def __init__(self):
 
77
  Add nodes and edges to the lesson plan graph for the given inputs.
78
  Returns a search string and the graph image.
79
  """
80
+ self.graph.clear()
81
  self.inputs.update(kwargs)
 
 
82
  self.validate_required_fields()
83
+
84
+ # Define required nodes
85
  nodes = {
86
  self.inputs["teacher_name"]: {"type": NodeType.USER, "role": "Teacher"},
87
  self.inputs["subject"]: {"type": NodeType.SUBJECT, "description": "Core subject area"},
88
  self.inputs["grade_level"]: {"type": NodeType.GRADE_LEVEL, "description": "Target grade for the lesson"},
89
  }
90
+
91
+ # Include country authority if provided
92
+ if self.inputs.get("country_authority"):
93
+ nodes[self.inputs["country_authority"]] = {
94
+ "type": NodeType.COUNTRY_AUTHORITY,
95
+ "description": "Sets national curriculum standards"
96
+ }
97
+
98
+ # Optional nodes
99
  optional_nodes = {
100
  "learning_objective": NodeType.LEARNING_OBJECTIVE,
101
  "activity": NodeType.ACTIVITY,
 
103
  "resource": NodeType.RESOURCE,
104
  "school_board": NodeType.SCHOOL_BOARD
105
  }
106
+
107
  for field, node_type in optional_nodes.items():
108
  if self.inputs.get(field):
109
  nodes[self.inputs[field]] = {"type": node_type, "description": f"{node_type.value}"}
110
+
111
  # Add nodes to the graph
112
  for node, attributes in nodes.items():
113
  self.graph.add_node(node, **attributes)
114
+
115
+ # Define relationships between nodes
116
  edges = [
117
  (self.inputs["teacher_name"], self.inputs["subject"], {"relationship": "TEACHES"}),
118
  (self.inputs["subject"], self.inputs["grade_level"], {"relationship": "HAS_GRADE"})
119
  ]
120
+
121
+ # Relationships involving country authority
122
+ if self.inputs.get("country_authority"):
123
+ if self.inputs.get("learning_objective"):
124
+ edges.append((self.inputs["country_authority"], self.inputs["learning_objective"], {"relationship": "DEFINES"}))
125
+ if self.inputs.get("school_board"):
126
+ edges.append((self.inputs["country_authority"], self.inputs["school_board"], {"relationship": "OVERSEES"}))
127
+
128
+ # Existing optional edges
129
  if self.inputs.get("learning_objective"):
130
+ edges.append((self.inputs["subject"], self.inputs["learning_objective"], {"relationship": "COVERS"}))
131
+ if self.inputs.get("school_board"):
132
+ edges.append((self.inputs["learning_objective"], self.inputs["school_board"], {"relationship": "ALIGNS_WITH"}))
133
+
 
134
  if self.inputs.get("activity") and self.inputs.get("learning_objective"):
135
  edges.append((self.inputs["activity"], self.inputs["learning_objective"], {"relationship": "ACHIEVES"}))
136
+
137
  if self.inputs.get("activity") and self.inputs.get("resource"):
138
  edges.append((self.inputs["activity"], self.inputs["resource"], {"relationship": "REQUIRES"}))
139
+
140
  if self.inputs.get("learning_objective") and self.inputs.get("assessment"):
141
  edges.append((self.inputs["learning_objective"], self.inputs["assessment"], {"relationship": "EVALUATED_BY"}))
142
+
143
  if self.inputs.get("school_board"):
144
  edges.append((self.inputs["teacher_name"], self.inputs["school_board"], {"relationship": "BELONGS_TO"}))
145
+
146
  # Remove None entries from edges list
147
  edges = [edge for edge in edges if edge is not None]
148
  self.graph.add_edges_from(edges)
149
+
150
  # Generate the search string for content discovery
151
  search_string = f"{self.inputs['subject']} {self.inputs['grade_level']} {self.inputs.get('learning_objective', '')} {self.inputs.get('activity', '')} {self.inputs.get('resource', '')}".strip()
152
+
153
  # Get the graph image
154
  image = self.draw_graph()
155
+
 
156
  return search_string, image
157
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  def _add_legend(self, ax):
159
  legend_elements = [mpatches.Patch(color=color, label=node_type.value) for node_type, color in self.COLOR_MAP.items()]
160
  ax.legend(handles=legend_elements, loc='upper left', bbox_to_anchor=(1, 1), title="Node Types")