separate from lesson graph class
Browse files
app.py
CHANGED
@@ -1,157 +1,5 @@
|
|
1 |
import gradio as gr
|
2 |
-
|
3 |
-
import matplotlib.pyplot as plt
|
4 |
-
from io import BytesIO
|
5 |
-
from PIL import Image
|
6 |
-
import matplotlib.patches as mpatches
|
7 |
-
import mplcursors
|
8 |
-
import json
|
9 |
-
|
10 |
-
class LessonGraph:
|
11 |
-
"""
|
12 |
-
Class to handle the lesson plan graph construction and manipulation.
|
13 |
-
This encapsulates graph-related logic and avoids using global variables.
|
14 |
-
"""
|
15 |
-
|
16 |
-
def __init__(self):
|
17 |
-
self.graph = nx.DiGraph()
|
18 |
-
self.color_map = {
|
19 |
-
"User": "#FF9999", # Light Red
|
20 |
-
"Subject": "#66B2FF", # Light Blue
|
21 |
-
"Grade Level": "#99FF99", # Light Green
|
22 |
-
"Learning Objective": "#FFCC99", # Light Orange
|
23 |
-
"Activity": "#FF99FF", # Light Purple
|
24 |
-
"Assessment": "#FFFF99", # Light Yellow
|
25 |
-
"Resource": "#99FFFF", # Light Cyan
|
26 |
-
"School Board": "#CCCCCC" # Light Gray
|
27 |
-
}
|
28 |
-
|
29 |
-
def add_lesson_plan(self, teacher_name, subject, grade_level, learning_objective, activity, assessment, resource, school_board):
|
30 |
-
"""
|
31 |
-
Add nodes and edges to the lesson plan graph for the given inputs.
|
32 |
-
Returns a search string and the graph image.
|
33 |
-
"""
|
34 |
-
self.graph.clear() # Clear previous graph
|
35 |
-
|
36 |
-
# Define node details and add them to the graph
|
37 |
-
nodes = {
|
38 |
-
teacher_name: {"type": "User", "role": "Teacher"},
|
39 |
-
subject: {"type": "Subject", "description": "Core subject area"},
|
40 |
-
grade_level: {"type": "Grade Level", "description": "Target grade for the lesson"},
|
41 |
-
learning_objective: {"type": "Learning Objective", "description": "Main goal of the lesson"},
|
42 |
-
activity: {"type": "Activity", "description": "Main class activity"},
|
43 |
-
assessment: {"type": "Assessment", "description": "Method of evaluating learning"},
|
44 |
-
resource: {"type": "Resource", "description": "Materials needed for the lesson"},
|
45 |
-
school_board: {"type": "School Board", "description": "Governing educational body"}
|
46 |
-
}
|
47 |
-
|
48 |
-
for node, attributes in nodes.items():
|
49 |
-
self.graph.add_node(node, **attributes)
|
50 |
-
|
51 |
-
# Define the relationships between nodes
|
52 |
-
self.graph.add_edges_from([
|
53 |
-
(teacher_name, subject, {"relationship": "TEACHES"}),
|
54 |
-
(subject, learning_objective, {"relationship": "COVERS"}),
|
55 |
-
(subject, grade_level, {"relationship": "HAS_GRADE"}),
|
56 |
-
(activity, learning_objective, {"relationship": "ACHIEVES"}),
|
57 |
-
(activity, resource, {"relationship": "REQUIRES"}),
|
58 |
-
(learning_objective, assessment, {"relationship": "EVALUATED_BY"}),
|
59 |
-
(teacher_name, school_board, {"relationship": "BELONGS_TO"}),
|
60 |
-
(learning_objective, school_board, {"relationship": "ALIGNS_WITH"})
|
61 |
-
])
|
62 |
-
|
63 |
-
# Generate the search string for content discovery
|
64 |
-
search_string = f"{subject} {grade_level} {learning_objective} {activity} {resource}".strip()
|
65 |
-
|
66 |
-
# Get the graph image
|
67 |
-
image = self.draw_graph()
|
68 |
-
|
69 |
-
# Return the search string and the graph image
|
70 |
-
return search_string, image
|
71 |
-
|
72 |
-
def draw_graph(self):
|
73 |
-
"""
|
74 |
-
Visualize the graph using Matplotlib, handling layout, labels, and interactivity.
|
75 |
-
"""
|
76 |
-
fig, ax = plt.subplots(figsize=(14, 10))
|
77 |
-
pos = nx.spring_layout(self.graph, k=0.9, iterations=50)
|
78 |
-
|
79 |
-
# Draw nodes with color coding
|
80 |
-
node_colors = [self.color_map[self.graph.nodes[node]['type']] for node in self.graph.nodes()]
|
81 |
-
nx.draw_networkx_nodes(self.graph, pos, node_color=node_colors, node_size=3000, alpha=0.8, ax=ax)
|
82 |
-
|
83 |
-
# Draw edges and labels
|
84 |
-
nx.draw_networkx_edges(self.graph, pos, edge_color='gray', arrows=True, arrowsize=20, ax=ax)
|
85 |
-
nx.draw_networkx_labels(self.graph, pos, font_size=10, font_weight="bold", ax=ax)
|
86 |
-
|
87 |
-
edge_labels = nx.get_edge_attributes(self.graph, 'relationship')
|
88 |
-
nx.draw_networkx_edge_labels(self.graph, pos, edge_labels=edge_labels, font_size=8, ax=ax)
|
89 |
-
|
90 |
-
# Add legend for node types
|
91 |
-
legend_elements = [mpatches.Patch(color=color, label=node_type) for node_type, color in self.color_map.items()]
|
92 |
-
plt.legend(handles=legend_elements, loc='upper left', bbox_to_anchor=(1, 1), title="Node Types")
|
93 |
-
|
94 |
-
plt.title("Your Educational Landscape", fontsize=16)
|
95 |
-
plt.axis('off')
|
96 |
-
plt.tight_layout()
|
97 |
-
|
98 |
-
# Add interactivity for hovering over nodes
|
99 |
-
cursor = mplcursors.cursor(hover=True)
|
100 |
-
@cursor.connect("add")
|
101 |
-
def on_add(sel):
|
102 |
-
node = list(self.graph.nodes())[sel.target.index]
|
103 |
-
node_data = self.graph.nodes[node]
|
104 |
-
sel.annotation.set_text(f"Node: {node}\nType: {node_data['type']}\n{node_data.get('description', '')}")
|
105 |
-
|
106 |
-
# Save the plot to a BytesIO object
|
107 |
-
buf = BytesIO()
|
108 |
-
plt.savefig(buf, format="png", dpi=300, bbox_inches="tight")
|
109 |
-
buf.seek(0)
|
110 |
-
plt.close(fig)
|
111 |
-
|
112 |
-
return Image.open(buf)
|
113 |
-
|
114 |
-
def clear_graph(self):
|
115 |
-
"""
|
116 |
-
Clears the lesson plan graph, allowing users to start fresh.
|
117 |
-
"""
|
118 |
-
self.graph.clear()
|
119 |
-
return "Landscape cleared. You can start a new lesson plan."
|
120 |
-
|
121 |
-
def graph_to_json(self):
|
122 |
-
"""
|
123 |
-
Converts the current lesson plan graph into a JSON string format and returns the result.
|
124 |
-
|
125 |
-
Returns:
|
126 |
-
- str: JSON string representation of the graph or an error message.
|
127 |
-
"""
|
128 |
-
try:
|
129 |
-
# Convert the lesson_graph to a dictionary format
|
130 |
-
graph_data = {
|
131 |
-
"nodes": [
|
132 |
-
{
|
133 |
-
"id": node,
|
134 |
-
"type": self.graph.nodes[node]["type"],
|
135 |
-
"description": self.graph.nodes[node].get("description", "")
|
136 |
-
}
|
137 |
-
for node in self.graph.nodes()
|
138 |
-
],
|
139 |
-
"edges": [
|
140 |
-
{
|
141 |
-
"source": u,
|
142 |
-
"target": v,
|
143 |
-
"relationship": self.graph.edges[u, v]["relationship"]
|
144 |
-
}
|
145 |
-
for u, v in self.graph.edges()
|
146 |
-
]
|
147 |
-
}
|
148 |
-
|
149 |
-
# Convert dictionary to JSON string
|
150 |
-
return json.dumps(graph_data, indent=4)
|
151 |
-
|
152 |
-
except Exception as e:
|
153 |
-
# If any error occurs, catch it and display it in the message_output
|
154 |
-
return f"An error occurred: {str(e)}"
|
155 |
|
156 |
# Instantiate the LessonGraph class
|
157 |
lesson_graph = LessonGraph()
|
@@ -164,20 +12,20 @@ with demo:
|
|
164 |
gr.Markdown("Welcome to EduScape, where lesson planning becomes an adventure in crafting educational journeys. Design, visualize, and perfect your learning landscapes with ease.")
|
165 |
|
166 |
with gr.Row():
|
167 |
-
teacher_name = gr.Textbox(label="Teacher Name")
|
168 |
-
school_board = gr.Textbox(label="School Board/Region")
|
169 |
|
170 |
with gr.Row():
|
171 |
-
subject = gr.Textbox(label="Subject")
|
172 |
-
grade_level = gr.Textbox(label="Grade Level")
|
173 |
|
174 |
with gr.Row():
|
175 |
-
learning_objective = gr.Textbox(label="Learning Objective")
|
176 |
-
activity = gr.Textbox(label="Activity")
|
177 |
|
178 |
with gr.Row():
|
179 |
-
assessment = gr.Textbox(label="Assessment")
|
180 |
-
resource = gr.Textbox(label="Resource/Material")
|
181 |
|
182 |
with gr.Row():
|
183 |
generate_btn = gr.Button("Map Your Lesson Plan")
|
@@ -195,10 +43,17 @@ with demo:
|
|
195 |
graph_output = gr.Image(label="Your Educational Landscape")
|
196 |
message_output = gr.Textbox(label="Landscape Status")
|
197 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
198 |
generate_btn.click(
|
199 |
-
|
200 |
inputs=[teacher_name, subject, grade_level, learning_objective, activity, assessment, resource, school_board],
|
201 |
-
outputs=[search_output, graph_output]
|
202 |
)
|
203 |
|
204 |
graph_btn.click(
|
@@ -206,9 +61,13 @@ with demo:
|
|
206 |
outputs=[message_output]
|
207 |
)
|
208 |
|
|
|
|
|
|
|
|
|
209 |
clear_btn.click(
|
210 |
-
|
211 |
-
outputs=[
|
212 |
)
|
213 |
|
214 |
# Add Markdown section explaining the purpose and use of the app
|
@@ -222,21 +81,25 @@ with demo:
|
|
222 |
- **Graph Visualization**: Each element of the lesson plan is represented as a node, and the connections between these elements (like how an activity achieves the learning objective) are visualized through edges.
|
223 |
- **Content Discovery**: The system generates a search string based on input, which can help the teacher discover content or resources to support their lesson plan.
|
224 |
|
|
|
|
|
|
|
|
|
225 |
### Logical Flow of the Knowledge Graph:
|
226 |
1. The **Teacher** node connects to the **Subject** node (representing what the teacher teaches).
|
227 |
-
2. The **Subject** node connects to
|
228 |
-
3.
|
229 |
-
4.
|
230 |
-
5.
|
231 |
-
6.
|
232 |
-
7.
|
|
|
233 |
|
234 |
### Example Use Case:
|
235 |
-
A teacher, Sarah Johnson, inputs her lesson plan for Grade 7 Earth Science
|
236 |
|
237 |
-
EduScape ensures that teachers can organize their lessons effectively while aligning with the curriculum and discovering resources to enhance their lesson delivery.
|
238 |
""")
|
239 |
-
|
240 |
-
# Launch the EduScape app
|
241 |
-
demo.launch()
|
242 |
|
|
|
|
|
|
1 |
import gradio as gr
|
2 |
+
from lesson_graph import LessonGraph
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
|
4 |
# Instantiate the LessonGraph class
|
5 |
lesson_graph = LessonGraph()
|
|
|
12 |
gr.Markdown("Welcome to EduScape, where lesson planning becomes an adventure in crafting educational journeys. Design, visualize, and perfect your learning landscapes with ease.")
|
13 |
|
14 |
with gr.Row():
|
15 |
+
teacher_name = gr.Textbox(label="Teacher Name (Required)", placeholder="Enter the teacher's full name", info="e.g., Sarah Johnson")
|
16 |
+
school_board = gr.Textbox(label="School Board/Region (Optional)", placeholder="Enter the school board or region", info="e.g., Oakville District School Board")
|
17 |
|
18 |
with gr.Row():
|
19 |
+
subject = gr.Textbox(label="Subject (Required)", placeholder="Enter the subject name", info="e.g., Earth Science")
|
20 |
+
grade_level = gr.Textbox(label="Grade Level (Required)", placeholder="Enter the grade level", info="e.g., Grade 7")
|
21 |
|
22 |
with gr.Row():
|
23 |
+
learning_objective = gr.Textbox(label="Learning Objective (Optional)", placeholder="Enter the main learning goal", info="e.g., Understand the water cycle and its impact on Earth's climate")
|
24 |
+
activity = gr.Textbox(label="Activity (Optional)", placeholder="Enter the main class activity", info="e.g., Create a terrarium to model the water cycle")
|
25 |
|
26 |
with gr.Row():
|
27 |
+
assessment = gr.Textbox(label="Assessment (Optional)", placeholder="Enter the assessment method", info="e.g., Group presentation on terrarium observations")
|
28 |
+
resource = gr.Textbox(label="Resource/Material (Optional)", placeholder="Enter required resources", info="e.g., Terrarium kit, climate diagrams")
|
29 |
|
30 |
with gr.Row():
|
31 |
generate_btn = gr.Button("Map Your Lesson Plan")
|
|
|
43 |
graph_output = gr.Image(label="Your Educational Landscape")
|
44 |
message_output = gr.Textbox(label="Landscape Status")
|
45 |
|
46 |
+
def handle_generate(teacher_name, subject, grade_level, learning_objective, activity, assessment, resource, school_board):
|
47 |
+
try:
|
48 |
+
search_string, image = lesson_graph.process_inputs(teacher_name, subject, grade_level, learning_objective, activity, assessment, resource, school_board)
|
49 |
+
return search_string, image, "Lesson plan mapped successfully!"
|
50 |
+
except ValueError as e:
|
51 |
+
return "", None, f"Error: {str(e)}. Please fill in all required fields."
|
52 |
+
|
53 |
generate_btn.click(
|
54 |
+
handle_generate,
|
55 |
inputs=[teacher_name, subject, grade_level, learning_objective, activity, assessment, resource, school_board],
|
56 |
+
outputs=[search_output, graph_output, message_output]
|
57 |
)
|
58 |
|
59 |
graph_btn.click(
|
|
|
61 |
outputs=[message_output]
|
62 |
)
|
63 |
|
64 |
+
def handle_reset():
|
65 |
+
reset_state = lesson_graph.reset_state()
|
66 |
+
return list(reset_state)
|
67 |
+
|
68 |
clear_btn.click(
|
69 |
+
handle_reset,
|
70 |
+
outputs=[teacher_name, subject, grade_level, learning_objective, activity, assessment, resource, school_board, message_output]
|
71 |
)
|
72 |
|
73 |
# Add Markdown section explaining the purpose and use of the app
|
|
|
81 |
- **Graph Visualization**: Each element of the lesson plan is represented as a node, and the connections between these elements (like how an activity achieves the learning objective) are visualized through edges.
|
82 |
- **Content Discovery**: The system generates a search string based on input, which can help the teacher discover content or resources to support their lesson plan.
|
83 |
|
84 |
+
### Required and Optional Fields:
|
85 |
+
- **Required Fields**: Teacher Name, Subject, and Grade Level
|
86 |
+
- **Optional Fields**: Learning Objective, Activity, Assessment, Resource/Material, and School Board/Region
|
87 |
+
|
88 |
### Logical Flow of the Knowledge Graph:
|
89 |
1. The **Teacher** node connects to the **Subject** node (representing what the teacher teaches).
|
90 |
+
2. The **Subject** node connects to the **Grade Level** (defining what is taught and to whom).
|
91 |
+
3. If provided, the **Learning Objective** node links to the **Subject** (showing what specific goal is covered).
|
92 |
+
4. If both are provided, the **Activity** node links to the **Learning Objective** (showing how the objective is achieved through student engagement).
|
93 |
+
5. If provided, the **Assessment** node connects to the **Learning Objective** (indicating how learning is evaluated).
|
94 |
+
6. If both are provided, the **Resource** node connects to the **Activity** (detailing what materials are needed for the activity).
|
95 |
+
7. If provided, the **Teacher** also connects to the **School Board** (showing which governing body the teacher belongs to).
|
96 |
+
8. If both are provided, the **Learning Objective** aligns with **School Board** standards (ensuring that the lesson adheres to curriculum requirements).
|
97 |
|
98 |
### Example Use Case:
|
99 |
+
A teacher, Sarah Johnson, inputs her lesson plan for Grade 7 Earth Science. She must provide her name, the subject, and the grade level. Optionally, she can add a learning objective about understanding the water cycle, an activity to create a terrarium, a group presentation for assessment, and specify resources like a terrarium kit. The system visualizes the relationships between these elements in the graph and generates a content discovery string to help her find additional resources.
|
100 |
|
101 |
+
EduScape ensures that teachers can organize their lessons effectively while aligning with the curriculum and discovering resources to enhance their lesson delivery, with flexibility to include as much or as little detail as they prefer.
|
102 |
""")
|
|
|
|
|
|
|
103 |
|
104 |
+
# Launch the EduScape app
|
105 |
+
demo.launch()
|