generated from lambda-feedback/Evaluation-Function-Boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparse_json_to_prompt.py
217 lines (196 loc) · 10.8 KB
/
parse_json_to_prompt.py
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
214
215
216
217
from typing import List, Optional, Union, Dict
# questionSubmissionSummary type
class StudentLatestSubmission:
def __init__(
self,
universalResponseAreaId: Optional[str] = None,
answer: Optional[str] = None,
submission: Optional[str] = None,
feedback: Optional[str] = None,
rawResponse: Optional[dict] = None,
):
self.universalResponseAreaId = universalResponseAreaId
self.answer = answer
self.submission = submission
self.feedback = feedback
self.rawResponse = rawResponse
class StudentWorkResponseArea:
def __init__(
self,
publishedPartId: Optional[str] = None,
publishedPartPosition: Optional[int] = None,
publishedResponseAreaId: Optional[str] = None,
publishedResponseAreaPosition: Optional[int] = None,
responseAreaUniversalId: Optional[str] = None,
publishedResponseAreaPreResponseText: Optional[str] = None,
publishedResponseType: Optional[str] = None,
publishedResponseConfig: Optional[dict] = None,
totalSubmissions: Optional[int] = None,
totalWrongSubmissions: Optional[int] = None,
latestSubmission: Optional[StudentLatestSubmission] = None,
):
self.publishedPartId = publishedPartId
self.publishedPartPosition = publishedPartPosition
self.publishedResponseAreaId = publishedResponseAreaId
self.publishedResponseAreaPosition = publishedResponseAreaPosition
self.responseAreaUniversalId = responseAreaUniversalId
self.publishedResponseAreaPreResponseText = publishedResponseAreaPreResponseText
self.publishedResponseType = publishedResponseType
self.publishedResponseConfig = publishedResponseConfig
self.latestSubmission = StudentLatestSubmission(**latestSubmission) if latestSubmission else None
self.totalSubmissions = totalSubmissions
self.totalWrongSubmissions = totalWrongSubmissions
# questionInformation type
class ResponseAreaDetails:
def __init__(
self,
id: Optional[str] = None,
position: Optional[int] = None,
universalResponseAreaId: Optional[str] = None,
preResponseText: Optional[str] = None,
responseType: Optional[str] = None,
answer: Optional[dict] = None,
Response: Optional[dict] = None,
):
self.id = id
self.position = position
self.universalResponseAreaId = universalResponseAreaId
self.preResponseText = preResponseText
self.responseType = responseType
self.answer = answer
self.Response = Response
class PartDetails:
def __init__(
self,
publishedPartId: Optional[str] = None,
publishedPartPosition: Optional[int] = None,
publishedPartContent: Optional[str] = None,
publishedPartAnswerContent: Optional[str] = None,
publishedWorkedSolutionSections: Optional[List[dict]] = [],
publishedResponseAreas: Optional[List[Optional[ResponseAreaDetails]]] = [],
):
self.publishedPartId = publishedPartId
self.publishedPartPosition = publishedPartPosition
self.publishedPartContent = publishedPartContent
self.publishedPartAnswerContent = publishedPartAnswerContent
self.publishedWorkedSolutionSections = publishedWorkedSolutionSections
self.publishedResponseAreas = [ResponseAreaDetails(**publishedResponseArea) for publishedResponseArea in publishedResponseAreas]
class QuestionDetails:
def __init__(
self,
setNumber: Optional[int] = None,
setName: Optional[str] = None,
setDescription: Optional[str] = None,
questionNumber: Optional[int] = None,
questionTitle: Optional[str] = None,
questionGuidance: Optional[str] = None,
questionContent: Optional[str] = None,
durationLowerBound: Optional[int] = None,
durationUpperBound: Optional[int] = None,
parts: Optional[List[PartDetails]] = [],
):
self.setNumber = setNumber
self.setName = setName
self.setDescription = setDescription
self.questionNumber = questionNumber
self.questionTitle = questionTitle
self.questionGuidance = questionGuidance
self.questionContent = questionContent
self.durationLowerBound = durationLowerBound
self.durationUpperBound = durationUpperBound
self.parts = [PartDetails(**part) for part in parts]
# questionAccessInformation type
class CurrentPart:
def __init__(self, id: str = None, position: int = None, timeTakenPart: Optional[str] = None, markedDonePart: Optional[str] = None):
self.id = id
self.position = position
self.timeTakenPart = timeTakenPart
self.markedDonePart = markedDonePart
class QuestionAccessInformation:
def __init__(
self,
estimatedMinimumTime: Optional[str] = None,
estimaredMaximumTime: Optional[str] = None,
timeTaken: Optional[str] = None,
accessStatus: Optional[str] = None,
markedDone: Optional[str] = None,
currentPart: Optional[Dict[str, Union[str, int]]] = {},
):
self.estimatedMinimumTime = estimatedMinimumTime
self.estimaredMaximumTime = estimaredMaximumTime
self.timeTaken = timeTaken
self.accessStatus = accessStatus
self.markedDone = markedDone
self.currentPart = CurrentPart(**currentPart)
def convert_index_to_lowercase_letter(index: int) -> str:
return chr(96 + (index + 1)) # 1-indexed
def parse_json_to_prompt( questionSubmissionSummary: Optional[List[StudentWorkResponseArea]],
questionInformation: Optional[QuestionDetails],
questionAccessInformation: Optional[QuestionAccessInformation]
) -> Optional[str]:
if not questionInformation or not questionAccessInformation:
return "There must have been an error in fetching the question details. So ask me about the question I am working on such that you can still help me."
questionSubmissionSummary = [StudentWorkResponseArea(**submissionsSummary) for submissionsSummary in questionSubmissionSummary]
questionInformation = QuestionDetails(**questionInformation)
questionAccessInformation = QuestionAccessInformation(**questionAccessInformation)
def format_response_area_details(responseArea: ResponseAreaDetails, studentSummary: List[StudentWorkResponseArea]) -> str:
submissionDetails = "\n".join(
[
f"Latest Response: {ra.latestSubmission.submission};\n"
f"Latest Feedback Received: {ra.latestSubmission.feedback};\n"
f"Total Responses: {ra.totalSubmissions};\n"
f"Total Wrong Responses: {ra.totalWrongSubmissions};\n"
for ra in studentSummary
if ra.publishedResponseAreaId == responseArea.id and ra.latestSubmission
]
)
if not submissionDetails:
submissionDetails = 'Latest Response: none made;'
return f"""
## Response Area: {responseArea.position + 1}
{f'Area task: What is {responseArea.preResponseText} ?' if responseArea.preResponseText else ''}
(Keep it Secret) Expected Answer: {responseArea.answer};
{submissionDetails}"""
def format_part_details(part: PartDetails, currentPart: CurrentPart, summary: List[StudentWorkResponseArea]) -> str:
if not part:
return ''
responseAreas = "\n".join(
[format_response_area_details(responseArea, summary) for responseArea in part.publishedResponseAreas]
)
workedSolutions = (
"\n".join(
[
f"## Worked Solution {ws.get('position') + 1}: {ws.get('title', '')}\n"
f"{ws.get('content', '').strip() or 'No content'}\n"
for ws in part.publishedWorkedSolutionSections
]
) if part.publishedWorkedSolutionSections else f"No worked solutions for part ({convert_index_to_lowercase_letter(part.publishedPartPosition)});"
)
return f"""
# {'[CURRENTLY WORKING ON] ' if currentPart.id == part.publishedPartId else ''}Part ({convert_index_to_lowercase_letter(part.publishedPartPosition)}):
{f"Time spent on this part: {currentPart.timeTakenPart if currentPart.timeTakenPart is not None else 'No recorded duration'}" if currentPart.id == part.publishedPartId else ''}
Part Content: {part.publishedPartContent.strip() if part.publishedPartContent else 'No content'};
{responseAreas}
{f'Final Part Answer: {part.publishedPartAnswerContent}' if part.publishedPartAnswerContent else 'No direct answer for this part.'}
{workedSolutions}
"""
questionDetails = f"""This is the question I am currently working on. I am currently working on Part ({convert_index_to_lowercase_letter(questionAccessInformation.currentPart.position)}). Below, you'll find its details, including the parts of the question, my responses for each response area, and the feedback I received. This information highlights my efforts and progress so far. Use this this information to inform your understanding about the question materials provided to me and my work on them.
Maths equations are in KaTex format, preserve them the same. Use British English spellings.
{f'# Question Set {questionInformation.setNumber + 1}: {questionInformation.setName};' if ((questionInformation.setName is not None) and (questionInformation.setNumber is not None)) else ''}
# Question {f' {questionInformation.setNumber + 1}.{questionInformation.questionNumber + 1}' if ((questionInformation.setNumber is not None) and (questionInformation.questionNumber is not None)) else ''}: {questionInformation.questionTitle};
Guidance to Solve the Question: {questionInformation.questionGuidance or 'None'};
Description of Question: {questionInformation.questionContent};
Expected Time to Complete the Question: {f'{questionInformation.durationLowerBound} - {questionInformation.durationUpperBound} min;' if questionInformation.durationLowerBound and questionInformation.durationUpperBound else 'No specified duration.'}
Time Spent on the Question today: {questionAccessInformation.timeTaken or 'No recorded duration'} {f'which is {questionAccessInformation.accessStatus}' if questionAccessInformation.accessStatus else ''} {f'{questionAccessInformation.markedDone}' if questionAccessInformation.markedDone else ''};
"""
partsDetails = "\n".join(
[
format_part_details(
part,
questionAccessInformation.currentPart,
questionSubmissionSummary
) for part in questionInformation.parts
]
)
result = f"{questionDetails}\n{partsDetails}".replace("  ", "").replace(" ", "").replace("\n\n", "\n")
return result