atz21 commited on
Commit
edc9843
·
verified ·
1 Parent(s): 24bf1c8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -56
app.py CHANGED
@@ -5,11 +5,8 @@ import os
5
  from dotenv import load_dotenv
6
 
7
  # --- Configuration ---
8
- # Load environment variables from a .env file if it exists (for local development)
9
  load_dotenv()
10
 
11
- # It's recommended to set your GOOGLE_API_KEY as a secret in your Hugging Face Space settings.
12
- # The key should be named GOOGLE_API_KEY.
13
  try:
14
  api_key = os.environ.get("GOOGLE_API_KEY")
15
  if not api_key:
@@ -18,19 +15,16 @@ try:
18
  model = genai.GenerativeModel('gemini-2.5-flash')
19
  except Exception as e:
20
  print(f"Error configuring GenerativeAI: {e}")
21
- # Handle the case where the API key is not set, e.g., by disabling the interface or showing an error.
22
  model = None
23
 
24
  # --- Data Loading ---
25
  try:
26
  df = pd.read_csv('qp_with_ms_images (1).csv')
27
- # Clean up column names that might have extra spaces
28
  df.columns = df.columns.str.strip()
29
  except FileNotFoundError:
30
  print("Error: 'qp_with_ms_images (1).csv' not found. Please upload the data file to your Space.")
31
- df = pd.DataFrame() # Create an empty DataFrame to avoid errors
32
 
33
- # --- Provided Topics List ---
34
  TOPICS = """
35
  SL 1.1 - Operations with numbers in the form a × 10k where 1 < a < 10 and k is an integer.
36
  SL 1.2 - Arithmetic sequences and series. Use of the formulae for the nth term and the sum of the first n terms of the sequence. Use of sigma notation for sums of arithmetic sequences. Applications. Analysis, interpretation and prediction where a model is not perfectly arithmetic in real life.
@@ -125,57 +119,69 @@ AHL 5.19 - Maclaurin series to obtain expansions for eˣ, sinx, cosx, ln(1+x), (
125
  def generate_test(total_marks, topic_name, level):
126
  """
127
  Generates a test paper using the Gemini LLM based on user inputs.
 
128
  """
129
  if model is None or df.empty:
130
  return "Error: Application is not configured correctly. Please check API key and data file."
131
 
132
- # Filter DataFrame based on level
133
  if level == 'SL':
134
  filtered_df = df[df['Level'] == 'SL'].copy()
135
- else: # AHL can use both SL and AHL questions
136
  filtered_df = df.copy()
137
 
138
- # Prepare data for the prompt (convert relevant columns to string)
139
- # Using a sample to keep the prompt size manageable if the filtered data is too large
 
 
 
 
 
 
 
140
  if len(filtered_df) > 300:
141
- filtered_df = filtered_df.sample(n=300, random_state=42)
142
 
143
  question_data = filtered_df[[
144
  'Question Number', 'Date', 'Topic', 'Level', 'Max Marks', 'QP Content'
145
  ]].to_string(index=False)
146
 
147
- # --- Prompt for the LLM ---
148
- prompt = f"""
149
- You are an expert test creator for the International Baccalaureate (IB) Mathematics program.
150
- Your task is to create a test paper based on the user's request using a provided question bank.
151
-
152
- **User Request:**
153
- - Total Marks: {total_marks}
154
- - Topic: "{topic_name}"
155
- - Level: {level}
156
-
157
- **Instructions:**
158
- 1. Carefully select a combination of questions from the provided **QUESTION BANK** that best fit the requested topic and level.
159
- 2. The total marks of all selected questions should be as close as possible to the requested **Total Marks ({total_marks})**.
160
- 3. When selecting questions, **prioritize the most recent questions** (based on the 'Date' field) within the requested topic and level.
161
- 4. If multiple questions have similar relevance or marks, **prefer newer questions** over older ones.
162
- 5. Present the final test in a clean, well-formatted markdown format. It should look like a real test paper.
163
- 6. For each question, you **MUST** include its ID (from the 'Question Number' column), Date, Topic code, and the maximum marks.
164
- 7. Display the full question content, including all sub-questions and any included diagrams or formulas, exactly as it appears in the 'QP Content' column.
165
- 8. Use the provided **TOPICS LIST** to understand which topic codes fall under the user's requested topic name. For example, if the user requests 'Calculus', you should look for questions with topic codes like SL 5.1, SL 5.2, ..., AHL 5.19.
166
-
167
- **TOPICS LIST:**
168
- ---
169
- {TOPICS}
170
- ---
171
-
172
- **QUESTION BANK:**
173
- ---
174
- {question_data}
175
- ---
176
-
177
- Now, create the test based on the user's request, ensuring that the **latest available questions** for the topic are prioritized.
178
- """
 
 
 
 
179
 
180
  try:
181
  response = model.generate_content(prompt)
@@ -185,29 +191,23 @@ Now, create the test based on the user's request, ensuring that the **latest ava
185
 
186
  # --- Gradio Interface ---
187
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
188
- gr.Markdown("# 📝 IB Mathematics Test Generator")
189
  gr.Markdown(
190
- "Enter the desired total marks, a topic name, and the level (SL/AHL) to generate a test paper "
191
- "using a bank of past questions."
192
  )
193
 
194
  with gr.Row():
195
  with gr.Column(scale=1):
196
  total_marks_input = gr.Slider(
197
- minimum=10,
198
- maximum=150,
199
- step=1,
200
- value=50,
201
- label="Total Marks for the Test"
202
  )
203
  topic_input = gr.Textbox(
204
  label="Topic Name",
205
  placeholder="e.g., Trigonometry, Calculus, Algebra, Vectors..."
206
  )
207
  level_input = gr.Radio(
208
- choices=['SL', 'AHL'],
209
- label="Select Level",
210
- value='AHL'
211
  )
212
  generate_button = gr.Button("Generate Test", variant="primary")
213
 
@@ -221,4 +221,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
221
  )
222
 
223
  if __name__ == "__main__":
224
- demo.launch()
 
 
 
 
5
  from dotenv import load_dotenv
6
 
7
  # --- Configuration ---
 
8
  load_dotenv()
9
 
 
 
10
  try:
11
  api_key = os.environ.get("GOOGLE_API_KEY")
12
  if not api_key:
 
15
  model = genai.GenerativeModel('gemini-2.5-flash')
16
  except Exception as e:
17
  print(f"Error configuring GenerativeAI: {e}")
 
18
  model = None
19
 
20
  # --- Data Loading ---
21
  try:
22
  df = pd.read_csv('qp_with_ms_images (1).csv')
 
23
  df.columns = df.columns.str.strip()
24
  except FileNotFoundError:
25
  print("Error: 'qp_with_ms_images (1).csv' not found. Please upload the data file to your Space.")
26
+ df = pd.DataFrame()
27
 
 
28
  TOPICS = """
29
  SL 1.1 - Operations with numbers in the form a × 10k where 1 < a < 10 and k is an integer.
30
  SL 1.2 - Arithmetic sequences and series. Use of the formulae for the nth term and the sum of the first n terms of the sequence. Use of sigma notation for sums of arithmetic sequences. Applications. Analysis, interpretation and prediction where a model is not perfectly arithmetic in real life.
 
119
  def generate_test(total_marks, topic_name, level):
120
  """
121
  Generates a test paper using the Gemini LLM based on user inputs.
122
+ Prioritizes the most recent questions from the topic.
123
  """
124
  if model is None or df.empty:
125
  return "Error: Application is not configured correctly. Please check API key and data file."
126
 
127
+ # --- Filter and sort by latest date ---
128
  if level == 'SL':
129
  filtered_df = df[df['Level'] == 'SL'].copy()
130
+ else:
131
  filtered_df = df.copy()
132
 
133
+ # Sort by date descending (newest first)
134
+ if 'Date' in filtered_df.columns:
135
+ try:
136
+ filtered_df['Date'] = pd.to_datetime(filtered_df['Date'], errors='coerce')
137
+ filtered_df = filtered_df.sort_values(by='Date', ascending=False)
138
+ except Exception:
139
+ pass # If Date parsing fails, skip sorting
140
+
141
+ # Limit dataset size for LLM input
142
  if len(filtered_df) > 300:
143
+ filtered_df = filtered_df.head(300)
144
 
145
  question_data = filtered_df[[
146
  'Question Number', 'Date', 'Topic', 'Level', 'Max Marks', 'QP Content'
147
  ]].to_string(index=False)
148
 
149
+ # --- Enhanced Prompt (with latest question priority) ---
150
+ prompt = f"""
151
+ You are an expert test creator for the International Baccalaureate (IB) Mathematics program.
152
+ Your task is to create a test paper based on the user's request using a provided question bank.
153
+
154
+ **User Request:**
155
+ - Total Marks: {total_marks}
156
+ - Topic: "{topic_name}"
157
+ - Level: {level}
158
+
159
+ **Instructions:**
160
+ 1. Carefully select a combination of questions from the provided **QUESTION BANK** that best fit the requested topic and level.
161
+ 2. The total marks of all selected questions should be as close as possible to the requested **Total Marks ({total_marks})**.
162
+ 3. When choosing questions, **prioritize the latest (most recent) questions based on the 'Date' field**.
163
+ 4. If multiple questions fit equally well, choose the newest ones first.
164
+ 5. Present the final test in a clean, well-formatted markdown format. It should look like a real test paper.
165
+ 6. For each question, include:
166
+ - **Question ID** (from 'Question Number')
167
+ - **Date**
168
+ - **Topic Code**
169
+ - **Maximum Marks**
170
+ 7. Display the full question content exactly as it appears in 'QP Content'.
171
+ 8. Use the provided **TOPICS LIST** to identify relevant topic codes.
172
+
173
+ **TOPICS LIST:**
174
+ ---
175
+ {TOPICS}
176
+ ---
177
+
178
+ **QUESTION BANK (sorted by most recent first):**
179
+ ---
180
+ {question_data}
181
+ ---
182
+
183
+ Now, create the test based on the user's request, making sure to use the **latest available questions** first.
184
+ """
185
 
186
  try:
187
  response = model.generate_content(prompt)
 
191
 
192
  # --- Gradio Interface ---
193
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
194
+ gr.Markdown("# 📝 IB Mathematics Test Generator (Latest Question Priority)")
195
  gr.Markdown(
196
+ "Enter the desired total marks, a topic name, and the level (SL/AHL). "
197
+ "This version prioritizes the **latest available questions** when generating your test."
198
  )
199
 
200
  with gr.Row():
201
  with gr.Column(scale=1):
202
  total_marks_input = gr.Slider(
203
+ minimum=10, maximum=150, step=1, value=50, label="Total Marks for the Test"
 
 
 
 
204
  )
205
  topic_input = gr.Textbox(
206
  label="Topic Name",
207
  placeholder="e.g., Trigonometry, Calculus, Algebra, Vectors..."
208
  )
209
  level_input = gr.Radio(
210
+ choices=['SL', 'AHL'], label="Select Level", value='AHL'
 
 
211
  )
212
  generate_button = gr.Button("Generate Test", variant="primary")
213
 
 
221
  )
222
 
223
  if __name__ == "__main__":
224
+ demo.launch()
225
+ # --- Provided Topics List ---
226
+
227
+