Rakshitjan commited on
Commit
665b657
·
verified ·
1 Parent(s): 58c317e

Upload main.py

Browse files
Files changed (1) hide show
  1. main.py +214 -0
main.py ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from pydantic import BaseModel
3
+ import json
4
+ import openai
5
+ from typing import List, Dict, Any, Optional
6
+
7
+ app = FastAPI()
8
+
9
+ class RoadmapInput(BaseModel):
10
+ overall_study_pattern: str
11
+ memorization_study_pattern: str
12
+ problem_solving_study_pattern: str
13
+ visualization_study_pattern: str
14
+ obstacle_study_pattern: str
15
+ new_topic_approach: str
16
+ old_topic_approach: str
17
+ topic_ratio: str
18
+ hours_of_study: int
19
+ hours_of_study_weekends: int
20
+ revision_days: str
21
+ test_days: str
22
+ class_std: str
23
+ months_of_study: int
24
+ completed_phy_chapters: List[str]
25
+ completed_chem_chapters: List[str]
26
+ completed_maths_chapters: List[str]
27
+ startphyRoadmapFrom: str
28
+ startchemRoadmapFrom: str
29
+ startmathRoadmapFrom: str
30
+ userleft_topic_phy: Dict[str, Any]
31
+ userleft_topic_chem: List[Any]
32
+ userleft_topic_maths: List[Any]
33
+ total_time: int
34
+
35
+ output_structure = """
36
+ {
37
+ "schedule": [
38
+ "days": [
39
+ {
40
+ "dayNumber": "string",
41
+ "subjects": [
42
+ {
43
+ "name": "string",
44
+ "tasks": [
45
+ {
46
+ "type": "string",
47
+ "topic": "string",
48
+ "time": "string"
49
+ }
50
+ ]
51
+ }
52
+ ]
53
+ }
54
+ ]
55
+ ]
56
+ }
57
+ """
58
+
59
+ # Function to remove completed chapters from each subject
60
+ def remove_completed_chapters(subject_data, completed_chapters):
61
+ subject_data["chapters"] = [chapter for chapter in subject_data["chapters"]
62
+ if chapter["chapter"] not in completed_chapters]
63
+ return subject_data
64
+
65
+ # Function to get topics within timeframe
66
+ def get_topics_within_timeframe(subject, allowed_time, start_subtopic):
67
+ collected_subtopics = []
68
+ time_spent = 0
69
+ start_collecting = False
70
+
71
+ if 'chapters' not in subject:
72
+ print(f"Error: 'chapters' key not found in the subject: {subject}")
73
+ return collected_subtopics
74
+
75
+ for chapter in subject["chapters"]:
76
+ if 'subtopics' not in chapter:
77
+ print(f"Error: 'subtopics' key not found in the chapter: {chapter}")
78
+ continue
79
+
80
+ for subtopic in chapter["subtopics"]:
81
+ if subtopic["subtopic"] == start_subtopic:
82
+ start_collecting = True
83
+ continue
84
+
85
+ if start_collecting and subtopic["subtopic_hours"]:
86
+ time_spent += float(subtopic["subtopic_hours"])
87
+ if time_spent <= allowed_time:
88
+ collected_subtopics.append({
89
+ "chapter": chapter["chapter"],
90
+ "subtopic": subtopic["subtopic"],
91
+ "subtopic_hours": subtopic["subtopic_hours"]
92
+ })
93
+ else:
94
+ break
95
+ if time_spent > allowed_time:
96
+ break
97
+
98
+ return collected_subtopics
99
+
100
+ @app.post("/generate_roadmap")
101
+ async def generate_roadmap(input_data: RoadmapInput):
102
+ try:
103
+ # Load JSON data for each subject
104
+ with open('Physics.json', 'r', encoding='utf-8') as file:
105
+ phy = json.load(file)
106
+
107
+ with open('Chemistry.json', 'r', encoding='utf-8') as file:
108
+ chem = json.load(file)
109
+
110
+ with open('Maths.json', 'r', encoding='utf-8') as file:
111
+ maths = json.load(file)
112
+
113
+ # Remove completed chapters
114
+ phy = remove_completed_chapters(phy, input_data.completed_phy_chapters)
115
+ chem = remove_completed_chapters(chem, input_data.completed_chem_chapters)
116
+ maths = remove_completed_chapters(maths, input_data.completed_maths_chapters)
117
+
118
+ # Get topics within timeframe
119
+ physics_topics = get_topics_within_timeframe(phy, input_data.total_time, input_data.startphyRoadmapFrom)
120
+ chemistry_topics = get_topics_within_timeframe(chem, input_data.total_time, input_data.startchemRoadmapFrom)
121
+ mathematics_topics = get_topics_within_timeframe(maths, input_data.total_time, input_data.startmathRoadmapFrom)
122
+
123
+ physics_topics.insert(0, input_data.userleft_topic_phy)
124
+ chemistry_topics.extend(input_data.userleft_topic_chem)
125
+ mathematics_topics.extend(input_data.userleft_topic_maths)
126
+
127
+ # User persona string
128
+ userPersona = f"""
129
+ You are required to generate a highly personalized roadmap for a student studying Physics, Chemistry, and Mathematics for the JEE Main exam.
130
+ The roadmap should be tailored based on the following student-specific details:
131
+
132
+ 1. *Study Preferences:*
133
+ - Study Pattern: {input_data.overall_study_pattern}
134
+ - Memorization Approach: {input_data.memorization_study_pattern}
135
+ - Problem-Solving Approach: {input_data.problem_solving_study_pattern}
136
+ - Visualization Approach: {input_data.visualization_study_pattern}
137
+
138
+ 2. *Handling Challenges:*
139
+ - If unable to understand a topic: {input_data.obstacle_study_pattern}
140
+ - Approach to New Topics: {input_data.new_topic_approach}
141
+ - Approach to Previously Encountered Topics: {input_data.old_topic_approach}
142
+
143
+ 3. *Study Hours:*
144
+ - Weekdays: {input_data.hours_of_study} hours/day
145
+ - Weekends: {input_data.hours_of_study_weekends} hours/day
146
+ - Time Allocation Ratio (Physics:Chemistry:Mathematics): {input_data.topic_ratio}
147
+ - By weekdays I mean day 1, day 2 , day 3 , day 4 , day 5
148
+ - By weekends I mean day 6 , day 7
149
+ """
150
+
151
+ # System prompt
152
+ sys_prompt = f"""
153
+ You are required to generate a highly personalized roadmap for a student studying Physics, Chemistry, and Mathematics for the JEE Main exam.
154
+ The roadmap should be tailored based on the following student-specific details:
155
+
156
+ The roadmap must be provided in the following format:
157
+ {output_structure}
158
+
159
+ Do not include anything other than the roadmap, and ensure the focus remains strictly on the subjects {physics_topics}, {chemistry_topics}, and {mathematics_topics} and associated chapters.
160
+ MAKE SURE THAT YOU MAKE THE ROADMAP FOR ALL THE THREE CHAPTERS EACH OF PHYSICS , CHEMISTRY AND MATHS TO COMPLETE THOSE CHAPTERS WITH 4 ASPECTS i.e "CONCEPT UNDERSTANDING","QUESTION PRACTICE","REVISION","TEST". ALSO INCLUDE TIME FOR EACH TASK THAT YOU GENERATE
161
+ MAKE SURE THAT WE FIRST COMPLETE 1) CONCEPT UNDERSTANDING , 2) QUESTION PRACTICE FOR EVERY SUBTOPIC AND THEN REVISION AND TEST FOR WHOLE CHAPTER TOGETHER.
162
+ MAKE SURE THAT WE INCLUDE EACH SUBTOPIC OF EACH CHAPTER FROM {physics_topics},{chemistry_topics} and {mathematics_topics} IS FINISHED
163
+ YOU ARE NOT CONSTRAINED TO CREATE A ROADMAP FOR ONLY 'X' NUMBER OF DAYS , YOU CAN EXTEND TILL THE TOPICS ARE FINISHED BUT ONLY STICK TO THE TIMEFRAME ALLOTED FOR EACH SUBJECT AND DO NOT GO ABOVE OR BELOW THAT TIME FRAME.
164
+ """
165
+
166
+ # First LLM call
167
+ response = openai.ChatCompletion.create(
168
+ model="gpt-4o-mini",
169
+ messages=[
170
+ {
171
+ "role": "system",
172
+ "content": sys_prompt + "MAKE SURE YOU VERY VERY STRICTLY FOLLOW THE JSON STRUCTURE BECAUSE I WILL PARSE YOUR OUTPUT TO JSON"
173
+ },
174
+ {
175
+ "role": "user",
176
+ "content": userPersona
177
+ }
178
+ ]
179
+ )
180
+
181
+ answer = response['choices'][0]['message']['content'].strip()
182
+
183
+ # Calculate provided subtopics
184
+ provided_subtopics = physics_topics + chemistry_topics + mathematics_topics
185
+
186
+ # Second LLM call
187
+ response = openai.ChatCompletion.create(
188
+ model="gpt-4o-mini",
189
+ messages=[
190
+ {
191
+ "role": "system",
192
+ "content": f'''
193
+ you created a very good roadmap {answer} but you make sure that you dont forget any subtopics from {provided_subtopics}. ensure that the style is same as the previous roadmap.
194
+ MAKE SURE YOU VERY VERY STRICTLY FOLLOW THE JSON STRUCTURE BECAUSE I WILL PARSE YOUR OUTPUT TO JSON.
195
+ DO not include json at the top of the answer
196
+ '''
197
+ },
198
+ {
199
+ "role": "user",
200
+ "content": "Generate"
201
+ }
202
+ ]
203
+ )
204
+
205
+ answer = response['choices'][0]['message']['content'].strip()
206
+ parsed_json = json.loads(answer)
207
+
208
+ return parsed_json
209
+ except Exception as e:
210
+ raise HTTPException(status_code=500, detail=str(e))
211
+
212
+ if __name__ == "__main__":
213
+ import uvicorn
214
+ uvicorn.run(app, host="0.0.0.0", port=8000)