atz21 commited on
Commit
fc348d2
·
verified ·
1 Parent(s): 54b0ef9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -41
app.py CHANGED
@@ -1,17 +1,19 @@
1
  import os
2
  import gradio as gr
3
  import google.generativeai as genai
 
4
  from markdown_pdf import MarkdownPdf, Section
5
 
6
  # -------------------- CONFIG --------------------
7
- genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
8
-
9
- # ---------- PROMPTS ----------
10
-
11
- # Student transcription prompt
12
- TRANSCRIPTION_PROMPT = """Your Role: You are an expert technical transcriber specializing in mathematical and scientific documents.
 
 
13
  Your mission is to convert handwritten solutions from a provided image or PDF into a clean, accurate, and logically structured Markdown format.
14
-
15
  Instructions:
16
  - Use ## for questions, ### for subquestions.
17
  - Transcribe only the corrected, final version of the solution (ignore scribbles, cancellations, mistakes).
@@ -19,11 +21,12 @@ Instructions:
19
  - If something is illegible, use [illegible].
20
  - Do not recreate graphs, only describe them.
21
  """
 
22
 
23
- # Markscheme transcription prompt
24
- MARKSCHEME_TRANSCRIPTION_PROMPT = """Your Role: You are an expert transcriber.
 
25
  Convert the official marking scheme from the provided PDF into clean, structured Markdown.
26
-
27
  Instructions:
28
  - Preserve all structure (questions, subquestions).
29
  - Keep M, A, R annotations exactly as written.
@@ -32,71 +35,61 @@ Instructions:
32
  - Format in Markdown using ## and ### for hierarchy.
33
  - Use code blocks for equations.
34
  """
 
35
 
36
- # Grading prompt with rules + red highlighting
37
- GRADING_PROMPT = """You are an official examiner. Use the following grading rules strictly.
38
-
39
  Abbreviations:
40
  - M: Marks awarded for attempting to use a correct Method.
41
  - A: Marks awarded for an Answer or for Accuracy; often dependent on preceding M marks.
42
  - R: Marks awarded for clear Reasoning.
43
  - AG: Answer given in the question and so no marks are awarded.
44
  - FT: Follow through. The practice of awarding marks, despite candidate errors in previous parts, for their correct methods/answers using incorrect results.
45
-
46
  --------------------------------------------
47
  ## 1. General
48
  Award marks using the annotations as noted in the markscheme (e.g., M1, A2).
49
-
50
  ## 2. Method and Answer/Accuracy marks
51
  - Do not automatically award full marks for a correct answer; all working must be checked.
52
  - It is generally not possible to award M0 followed by A1.
53
  - Where M and A marks are noted on the same line (M1A1), M is for method, A is for accuracy.
54
  - Multiple A marks can be independent.
55
-
56
  ## 3. Implied marks
57
  Implied marks (M1) can only be awarded if correct work is seen or implied.
58
-
59
  ## 4. Follow through (FT) marks
60
  - Award FT if an earlier wrong answer is used consistently later.
61
  - Do not award FT if the result contradicts the question (e.g., probability > 1).
62
-
63
  ## 5. Mis-read (MR)
64
  - Penalize once if the candidate misreads a value.
65
  - Award other marks as appropriate.
66
-
67
  ## 6. Alternative methods
68
- - Accept valid alternatives unless "Hence" forbids it.
69
-
70
  ## 7. Alternative forms
71
  - Accept equivalent numeric/algebraic forms unless specified otherwise.
72
-
73
  ## 8. Format and accuracy of answers
74
  - Use correct accuracy (3 s.f. if not specified).
75
  - Arithmetic and algebra should be simplified.
76
-
77
  ## 9. Presentation of candidate work
78
  - Ignore crossed-out work unless indicated.
79
  - Mark only the first solution unless candidate specifies otherwise.
80
-
81
  --------------------------------------------
82
-
83
  ### OUTPUT FORMAT
84
  Produce a GitHub-flavored Markdown table with 3 columns:
85
-
86
  | Student wrote | Marks Awarded | Reason |
87
  |---------------|---------------|--------|
88
-
89
  Special Formatting Rule:
90
- - Whenever a mark is lost (M0, A0, R0 etc.), wrap it in red using: `<span style="color:red">M0</span>`.
 
91
  - Keep awarded marks (M1, A1, etc.) in plain text.
92
  - If mixed (e.g., M1A0A1), only highlight the lost marks (`A0`).
93
-
94
  After the table, provide:
95
  ### Summary & Final Mark
96
  - Total marks obtained vs total available
97
  - Any FT (follow-through) applied
98
  - Classification of errors (Conceptual, Silly mistake, Misread, etc.)
99
  """
 
 
100
 
101
  # ---------- HELPER: Save to PDF ----------
102
  def save_as_pdf(text, filename="output.pdf"):
@@ -109,9 +102,16 @@ def save_as_pdf(text, filename="output.pdf"):
109
  def transcribe_student(ans_file):
110
  try:
111
  ans_uploaded = genai.upload_file(path=ans_file, display_name="Answer Sheet")
112
- model = genai.GenerativeModel("gemini-2.5-pro", generation_config={"temperature": 0})
 
 
 
 
 
 
 
 
113
 
114
- resp = model.generate_content([TRANSCRIPTION_PROMPT, ans_uploaded])
115
  transcription = getattr(resp, "text", None)
116
  if not transcription and resp.candidates:
117
  transcription = resp.candidates[0].content.parts[0].text
@@ -125,9 +125,16 @@ def transcribe_student(ans_file):
125
  def transcribe_ms(ms_file):
126
  try:
127
  ms_uploaded = genai.upload_file(path=ms_file, display_name="Markscheme")
128
- model = genai.GenerativeModel("gemini-2.5-pro", generation_config={"temperature": 0})
 
 
 
 
 
 
 
 
129
 
130
- resp = model.generate_content([MARKSCHEME_TRANSCRIPTION_PROMPT, ms_uploaded])
131
  ms_transcription = getattr(resp, "text", None)
132
  if not ms_transcription and resp.candidates:
133
  ms_transcription = resp.candidates[0].content.parts[0].text
@@ -141,14 +148,17 @@ def transcribe_ms(ms_file):
141
  def grade(qp_file, ms_transcription, student_transcription):
142
  try:
143
  qp_uploaded = genai.upload_file(path=qp_file, display_name="Question Paper")
144
- model = genai.GenerativeModel("gemini-2.5-pro", generation_config={"temperature": 0})
145
-
146
- response = model.generate_content([
147
- GRADING_PROMPT,
148
- qp_uploaded,
149
- "### Markscheme Transcription:\n" + ms_transcription,
150
- "### Student Transcription:\n" + student_transcription
151
- ])
 
 
 
152
 
153
  grading = getattr(response, "text", None)
154
  if not grading and response.candidates:
 
1
  import os
2
  import gradio as gr
3
  import google.generativeai as genai
4
+ from google.generativeai.types import HarmCategory, HarmBlockThreshold
5
  from markdown_pdf import MarkdownPdf, Section
6
 
7
  # -------------------- CONFIG --------------------
8
+ API_KEY = os.getenv("GOOGLE_AI_STUDIO_API_KEY")
9
+ genai.configure(api_key=API_KEY)
10
+
11
+ # ---------- PROMPTS IN JSON ----------
12
+ PROMPTS = {
13
+ "TRANSCRIPTION_PROMPT": {
14
+ "role": "system",
15
+ "content": """Your Role: You are an expert technical transcriber specializing in mathematical and scientific documents.
16
  Your mission is to convert handwritten solutions from a provided image or PDF into a clean, accurate, and logically structured Markdown format.
 
17
  Instructions:
18
  - Use ## for questions, ### for subquestions.
19
  - Transcribe only the corrected, final version of the solution (ignore scribbles, cancellations, mistakes).
 
21
  - If something is illegible, use [illegible].
22
  - Do not recreate graphs, only describe them.
23
  """
24
+ },
25
 
26
+ "MARKSCHEME_TRANSCRIPTION_PROMPT": {
27
+ "role": "system",
28
+ "content": """Your Role: You are an expert transcriber.
29
  Convert the official marking scheme from the provided PDF into clean, structured Markdown.
 
30
  Instructions:
31
  - Preserve all structure (questions, subquestions).
32
  - Keep M, A, R annotations exactly as written.
 
35
  - Format in Markdown using ## and ### for hierarchy.
36
  - Use code blocks for equations.
37
  """
38
+ },
39
 
40
+ "GRADING_PROMPT": {
41
+ "role": "system",
42
+ "content": """You are an official examiner. Use the following grading rules strictly.
43
  Abbreviations:
44
  - M: Marks awarded for attempting to use a correct Method.
45
  - A: Marks awarded for an Answer or for Accuracy; often dependent on preceding M marks.
46
  - R: Marks awarded for clear Reasoning.
47
  - AG: Answer given in the question and so no marks are awarded.
48
  - FT: Follow through. The practice of awarding marks, despite candidate errors in previous parts, for their correct methods/answers using incorrect results.
 
49
  --------------------------------------------
50
  ## 1. General
51
  Award marks using the annotations as noted in the markscheme (e.g., M1, A2).
 
52
  ## 2. Method and Answer/Accuracy marks
53
  - Do not automatically award full marks for a correct answer; all working must be checked.
54
  - It is generally not possible to award M0 followed by A1.
55
  - Where M and A marks are noted on the same line (M1A1), M is for method, A is for accuracy.
56
  - Multiple A marks can be independent.
 
57
  ## 3. Implied marks
58
  Implied marks (M1) can only be awarded if correct work is seen or implied.
 
59
  ## 4. Follow through (FT) marks
60
  - Award FT if an earlier wrong answer is used consistently later.
61
  - Do not award FT if the result contradicts the question (e.g., probability > 1).
 
62
  ## 5. Mis-read (MR)
63
  - Penalize once if the candidate misreads a value.
64
  - Award other marks as appropriate.
 
65
  ## 6. Alternative methods
66
+ - Accept valid alternatives unless \"Hence\" forbids it.
 
67
  ## 7. Alternative forms
68
  - Accept equivalent numeric/algebraic forms unless specified otherwise.
 
69
  ## 8. Format and accuracy of answers
70
  - Use correct accuracy (3 s.f. if not specified).
71
  - Arithmetic and algebra should be simplified.
 
72
  ## 9. Presentation of candidate work
73
  - Ignore crossed-out work unless indicated.
74
  - Mark only the first solution unless candidate specifies otherwise.
 
75
  --------------------------------------------
 
76
  ### OUTPUT FORMAT
77
  Produce a GitHub-flavored Markdown table with 3 columns:
 
78
  | Student wrote | Marks Awarded | Reason |
79
  |---------------|---------------|--------|
 
80
  Special Formatting Rule:
81
+ - Whenever a mark is lost (M0, A0, R0 etc.), wrap it in red using: `<span style=\"color:red\">M0</span>`.
82
+ - Also make the corresponding **Reason column text red** when a mark is lost.
83
  - Keep awarded marks (M1, A1, etc.) in plain text.
84
  - If mixed (e.g., M1A0A1), only highlight the lost marks (`A0`).
 
85
  After the table, provide:
86
  ### Summary & Final Mark
87
  - Total marks obtained vs total available
88
  - Any FT (follow-through) applied
89
  - Classification of errors (Conceptual, Silly mistake, Misread, etc.)
90
  """
91
+ }
92
+ }
93
 
94
  # ---------- HELPER: Save to PDF ----------
95
  def save_as_pdf(text, filename="output.pdf"):
 
102
  def transcribe_student(ans_file):
103
  try:
104
  ans_uploaded = genai.upload_file(path=ans_file, display_name="Answer Sheet")
105
+ model = genai.GenerativeModel("gemini-2.5-pro-exp-03-25")
106
+
107
+ resp = model.generate_content(
108
+ [PROMPTS["TRANSCRIPTION_PROMPT"]["content"], ans_uploaded],
109
+ safety_settings={
110
+ HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE,
111
+ HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_NONE,
112
+ }
113
+ )
114
 
 
115
  transcription = getattr(resp, "text", None)
116
  if not transcription and resp.candidates:
117
  transcription = resp.candidates[0].content.parts[0].text
 
125
  def transcribe_ms(ms_file):
126
  try:
127
  ms_uploaded = genai.upload_file(path=ms_file, display_name="Markscheme")
128
+ model = genai.GenerativeModel("gemini-2.5-pro-exp-03-25")
129
+
130
+ resp = model.generate_content(
131
+ [PROMPTS["MARKSCHEME_TRANSCRIPTION_PROMPT"]["content"], ms_uploaded],
132
+ safety_settings={
133
+ HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE,
134
+ HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_NONE,
135
+ }
136
+ )
137
 
 
138
  ms_transcription = getattr(resp, "text", None)
139
  if not ms_transcription and resp.candidates:
140
  ms_transcription = resp.candidates[0].content.parts[0].text
 
148
  def grade(qp_file, ms_transcription, student_transcription):
149
  try:
150
  qp_uploaded = genai.upload_file(path=qp_file, display_name="Question Paper")
151
+ model = genai.GenerativeModel("gemini-2.5-pro-exp-03-25")
152
+
153
+ response = model.generate_content(
154
+ [PROMPTS["GRADING_PROMPT"]["content"], qp_uploaded,
155
+ "### Markscheme Transcription:\n" + ms_transcription,
156
+ "### Student Transcription:\n" + student_transcription],
157
+ safety_settings={
158
+ HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE,
159
+ HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_NONE,
160
+ }
161
+ )
162
 
163
  grading = getattr(response, "text", None)
164
  if not grading and response.candidates: