-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathduration_feedback.py
More file actions
213 lines (167 loc) · 6.83 KB
/
duration_feedback.py
File metadata and controls
213 lines (167 loc) · 6.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
"""
Duration feedback system for learning and improving time estimates.
Stores user feedback about assignment durations to improve future scheduling.
"""
import json
import os
from pathlib import Path
FEEDBACK_FILE = "duration_feedback.json"
def load_feedback():
"""Load existing feedback from JSON file."""
if not os.path.exists(FEEDBACK_FILE):
return {
"class_patterns": {},
"assignment_type_patterns": {},
"general_feedback": []
}
try:
with open(FEEDBACK_FILE, 'r') as f:
return json.load(f)
except json.JSONDecodeError:
return {
"class_patterns": {},
"assignment_type_patterns": {},
"general_feedback": []
}
def save_feedback(feedback_data):
"""Save feedback to JSON file."""
with open(FEEDBACK_FILE, 'w') as f:
json.dump(feedback_data, f, indent=2)
def add_class_duration_feedback(class_name, assignment_type, typical_duration_hours, notes=""):
"""
Add feedback about typical duration for a specific class and assignment type.
Args:
class_name: The class name (e.g., "ECEN 380", "CS 101")
assignment_type: Type of assignment (e.g., "Homework", "Project", "Lab")
typical_duration_hours: Typical hours needed (e.g., 4.5)
notes: Optional notes about the feedback
"""
feedback = load_feedback()
# Normalize class name
class_name = class_name.strip().upper()
assignment_type = assignment_type.strip().lower()
# Initialize class if not exists
if class_name not in feedback["class_patterns"]:
feedback["class_patterns"][class_name] = {}
# Store the feedback
feedback["class_patterns"][class_name][assignment_type] = {
"typical_duration_hours": typical_duration_hours,
"notes": notes,
"updated_at": __import__('datetime').datetime.now().isoformat()
}
save_feedback(feedback)
return feedback
def add_general_assignment_feedback(assignment_type, typical_duration_hours, notes=""):
"""
Add feedback about typical duration for assignment types across all classes.
Args:
assignment_type: Type of assignment (e.g., "Essay", "Lab Report", "Reading")
typical_duration_hours: Typical hours needed
notes: Optional notes
"""
feedback = load_feedback()
assignment_type = assignment_type.strip().lower()
feedback["assignment_type_patterns"][assignment_type] = {
"typical_duration_hours": typical_duration_hours,
"notes": notes,
"updated_at": __import__('datetime').datetime.now().isoformat()
}
save_feedback(feedback)
return feedback
def add_freeform_feedback(feedback_text):
"""
Add general freeform feedback about scheduling preferences.
Args:
feedback_text: Natural language feedback from user
"""
feedback = load_feedback()
feedback["general_feedback"].append({
"text": feedback_text,
"added_at": __import__('datetime').datetime.now().isoformat()
})
# Keep only last 20 feedback items
if len(feedback["general_feedback"]) > 20:
feedback["general_feedback"] = feedback["general_feedback"][-20:]
save_feedback(feedback)
return feedback
def get_feedback_summary():
"""Get a formatted summary of all feedback for LLM prompt."""
feedback = load_feedback()
summary_parts = []
# Class-specific patterns
if feedback["class_patterns"]:
summary_parts.append("**Learned Duration Patterns by Class:**")
for class_name, assignments in feedback["class_patterns"].items():
for assignment_type, data in assignments.items():
duration = data["typical_duration_hours"]
notes = f" ({data['notes']})" if data.get('notes') else ""
summary_parts.append(
f" - {class_name} {assignment_type}: typically takes {duration} hours{notes}"
)
# General assignment patterns
if feedback["assignment_type_patterns"]:
summary_parts.append("\n**Learned Duration Patterns by Assignment Type:**")
for assignment_type, data in feedback["assignment_type_patterns"].items():
duration = data["typical_duration_hours"]
notes = f" ({data['notes']})" if data.get('notes') else ""
summary_parts.append(
f" - {assignment_type.capitalize()}: typically takes {duration} hours{notes}"
)
# General feedback
if feedback["general_feedback"]:
summary_parts.append("\n**User Scheduling Preferences:**")
for item in feedback["general_feedback"][-10:]: # Last 10 items
summary_parts.append(f" - {item['text']}")
return "\n".join(summary_parts) if summary_parts else ""
def extract_class_from_text(text):
"""
Try to extract class name from text.
Looks for patterns like "ECEN 380", "CS 101", etc.
"""
import re
# Pattern: 2-4 letters followed by space and 3-4 digits
pattern = r'\b([A-Z]{2,4})\s*(\d{3,4})\b'
match = re.search(pattern, text.upper())
if match:
return f"{match.group(1)} {match.group(2)}"
return None
def extract_assignment_type(text):
"""
Try to extract assignment type from text.
Looks for keywords like homework, project, exam, etc.
"""
text_lower = text.lower()
assignment_keywords = {
'homework': ['homework', 'hw', 'assignment'],
'project': ['project'],
'exam': ['exam', 'midterm', 'final'],
'quiz': ['quiz'],
'lab': ['lab'],
'paper': ['paper', 'essay'],
'reading': ['reading'],
'study': ['study', 'review']
}
for assignment_type, keywords in assignment_keywords.items():
if any(keyword in text_lower for keyword in keywords):
return assignment_type
return None
def get_duration_suggestion(class_name=None, assignment_type=None):
"""
Get suggested duration based on learned patterns.
Returns:
float or None: Suggested duration in hours, or None if no pattern found
"""
feedback = load_feedback()
# First check for class-specific pattern
if class_name and assignment_type:
class_name = class_name.strip().upper()
assignment_type = assignment_type.strip().lower()
class_data = feedback["class_patterns"].get(class_name, {})
if assignment_type in class_data:
return class_data[assignment_type]["typical_duration_hours"]
# Fall back to general assignment type pattern
if assignment_type:
assignment_type = assignment_type.strip().lower()
if assignment_type in feedback["assignment_type_patterns"]:
return feedback["assignment_type_patterns"][assignment_type]["typical_duration_hours"]
return None