Commit
·
1de4963
1
Parent(s):
1302ebb
new main
Browse files
main.py
CHANGED
@@ -119,49 +119,64 @@ def compute_answers():
|
|
119 |
@app.route('/compute_marks', methods=['POST'])
|
120 |
def compute_marks():
|
121 |
try:
|
122 |
-
#
|
123 |
-
|
124 |
-
|
|
|
125 |
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
print("=== Starting compute_marks in temporary directory ===")
|
138 |
-
print(f"Using temporary directory: {temp_dir}")
|
139 |
-
|
140 |
-
# Process answers with validation
|
141 |
-
try:
|
142 |
-
a = request.form.get('answers')
|
143 |
-
if not a:
|
144 |
-
return jsonify({"error": "No answers provided"}), 400
|
145 |
-
|
146 |
-
answers = json.loads(a)
|
147 |
-
if not isinstance(answers, list):
|
148 |
-
return jsonify({"error": "Invalid answer format"}), 400
|
149 |
-
|
150 |
-
processed_answers = []
|
151 |
-
for ans in answers:
|
152 |
-
if isinstance(ans, str):
|
153 |
-
processed_answers.append([ans])
|
154 |
-
elif isinstance(ans, list):
|
155 |
-
processed_answers.append(ans)
|
156 |
-
else:
|
157 |
-
return jsonify({"error": "Invalid answer format"}), 400
|
158 |
-
|
159 |
-
answers = processed_answers
|
160 |
-
|
161 |
-
except json.JSONDecodeError:
|
162 |
-
return jsonify({"error": "Invalid JSON format for answers"}), 400
|
163 |
|
164 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
sen_vec_answers = []
|
166 |
word_vec_answers = []
|
167 |
for answer_set in answers:
|
@@ -172,159 +187,56 @@ def compute_marks():
|
|
172 |
temp_w.append(question_vector_word(ans))
|
173 |
sen_vec_answers.append(temp_v)
|
174 |
word_vec_answers.append(temp_w)
|
175 |
-
|
176 |
-
# Process uploaded files with better validation
|
177 |
-
files = request.files.getlist('files[]')
|
178 |
-
if not files:
|
179 |
-
return jsonify({"error": "No files uploaded"}), 400
|
180 |
-
|
181 |
-
data = {}
|
182 |
-
invalid_files = []
|
183 |
-
|
184 |
-
for file in files:
|
185 |
-
try:
|
186 |
-
if not validate_file_structure(file.filename):
|
187 |
-
invalid_files.append(file.filename)
|
188 |
-
continue
|
189 |
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
# Create student folder in temp directory
|
197 |
-
student_dir = os.path.join(temp_dir, student_folder)
|
198 |
-
os.makedirs(student_dir, exist_ok=True)
|
199 |
-
|
200 |
-
# Save file with secure filename
|
201 |
-
secure_name = secure_filename(file_name)
|
202 |
-
save_path = os.path.join(student_dir, secure_name)
|
203 |
-
file.save(save_path)
|
204 |
-
|
205 |
-
# Store in data structure with better organization
|
206 |
-
if student_folder not in data:
|
207 |
-
data[student_folder] = []
|
208 |
-
|
209 |
-
data[student_folder].append({
|
210 |
-
'path': save_path.replace('\\', '/'),
|
211 |
-
'name': os.path.splitext(secure_name)[0],
|
212 |
-
'original_path': relative_path,
|
213 |
-
'original_name': file_name
|
214 |
-
})
|
215 |
-
print(data)
|
216 |
-
print(f"Saved file: {save_path} for student: {student_folder}")
|
217 |
-
|
218 |
-
except Exception as e:
|
219 |
-
print(f"Error processing file {file.filename}: {str(e)}")
|
220 |
-
invalid_files.append(file.filename)
|
221 |
-
|
222 |
-
print("\nProcessed folder structure:")
|
223 |
-
for student, files in data.items():
|
224 |
-
print(f"\nStudent folder: {student}")
|
225 |
-
for f in files:
|
226 |
-
print(f" - {f['name']}")
|
227 |
-
|
228 |
-
# Calculate marks with better error handling
|
229 |
-
results = []
|
230 |
-
errors = []
|
231 |
-
|
232 |
-
for student_folder, images in sorted(data.items()):
|
233 |
-
student_total = 0
|
234 |
-
student_count = 0
|
235 |
-
|
236 |
-
sorted_images = sorted(images, key=lambda x: x['name'])
|
237 |
-
|
238 |
-
for idx, image_info in enumerate(sorted_images):
|
239 |
try:
|
240 |
-
image_path = image_info['path']
|
241 |
-
if not os.path.exists(image_path):
|
242 |
-
raise FileNotFoundError(f"Image file not found: {image_path}")
|
243 |
-
|
244 |
s_answer = extract_text_from_image(image_path)
|
245 |
-
|
246 |
-
print(f"Warning: No text extracted from {image_path}")
|
247 |
-
s_answer = ""
|
248 |
-
|
249 |
-
print(f"\nProcessing {student_folder}/{image_info['name']}:")
|
250 |
print(f"Extracted answer: {s_answer}")
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
|
|
256 |
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
student_count += 1
|
261 |
else:
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
results.append({
|
266 |
-
'student': student_folder,
|
267 |
-
'image_name': image_info['name'],
|
268 |
-
'marks': mark_value,
|
269 |
-
'answer_extracted': bool(s_answer)
|
270 |
-
})
|
271 |
|
|
|
|
|
|
|
272 |
except Exception as e:
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
'error': str(e)
|
281 |
-
})
|
282 |
-
|
283 |
-
# Add student average
|
284 |
-
if student_count > 0:
|
285 |
-
results.append({
|
286 |
-
'student': student_folder,
|
287 |
-
'image_name': 'AVERAGE',
|
288 |
-
'marks': round(student_total / student_count, 2)
|
289 |
-
})
|
290 |
-
|
291 |
-
# Clean up temporary files
|
292 |
try:
|
293 |
import shutil
|
294 |
-
shutil.rmtree(
|
295 |
-
print(f"
|
296 |
except Exception as e:
|
297 |
print(f"Warning: Could not clean up temporary directory: {e}")
|
298 |
|
299 |
-
|
300 |
-
results.sort(key=lambda x: (x['student'], x['image_name']))
|
301 |
-
|
302 |
-
# Prepare final response
|
303 |
-
response_data = {
|
304 |
-
"message": results,
|
305 |
-
"summary": {
|
306 |
-
"total_files_processed": sum(len(files) for files in data.values()),
|
307 |
-
"total_students": len(data),
|
308 |
-
"invalid_files": invalid_files,
|
309 |
-
"errors": errors if errors else None
|
310 |
-
}
|
311 |
-
}
|
312 |
-
|
313 |
-
print("\nFinal Results Table:")
|
314 |
-
print("Student Folder\tImage Name\tMarks")
|
315 |
-
print("-" * 50)
|
316 |
-
for r in results:
|
317 |
-
print(f"{r['student']}\t{r['image_name']}\t{r['marks']}")
|
318 |
-
|
319 |
-
return jsonify(response_data), 200
|
320 |
|
321 |
except Exception as e:
|
322 |
print("Error in compute_marks:", str(e))
|
323 |
-
# Clean up temporary files in case of error
|
324 |
try:
|
325 |
import shutil
|
326 |
-
shutil.rmtree(
|
327 |
-
print(f"Cleaned up temporary directory after error: {temp_dir}")
|
328 |
except:
|
329 |
pass
|
330 |
return jsonify({"error": str(e)}), 500
|
|
|
119 |
@app.route('/compute_marks', methods=['POST'])
|
120 |
def compute_marks():
|
121 |
try:
|
122 |
+
# Get and process answers
|
123 |
+
a = request.form.get('answers')
|
124 |
+
if not a:
|
125 |
+
return jsonify({"error": "No answers provided"}), 400
|
126 |
|
127 |
+
print("Received answers:", a)
|
128 |
+
a = json.loads(a)
|
129 |
+
answers = []
|
130 |
+
for i in a:
|
131 |
+
ans = i.split('\n\n')
|
132 |
+
answers.append(ans)
|
133 |
+
print("Processed answers:", answers)
|
134 |
+
|
135 |
+
# Process files and create data structure
|
136 |
+
data = {}
|
137 |
+
parent_folder = os.path.join(cache_dir, 'student_answers') # Use temp directory
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
|
139 |
+
# First, save uploaded files
|
140 |
+
files = request.files.getlist('files[]')
|
141 |
+
if not files:
|
142 |
+
return jsonify({"error": "No files uploaded"}), 400
|
143 |
+
|
144 |
+
# Save files to temporary directory
|
145 |
+
for file in files:
|
146 |
+
if file.filename.endswith(('.jpg', '.jpeg', '.png')):
|
147 |
+
relative_path = file.filename.replace('\\', '/')
|
148 |
+
path_parts = relative_path.split('/')
|
149 |
+
|
150 |
+
if len(path_parts) >= 2:
|
151 |
+
student_folder = path_parts[1]
|
152 |
+
file_name = path_parts[-1]
|
153 |
+
|
154 |
+
# Create student folder
|
155 |
+
student_dir = os.path.join(parent_folder, student_folder)
|
156 |
+
os.makedirs(student_dir, exist_ok=True)
|
157 |
+
|
158 |
+
# Save file
|
159 |
+
save_path = os.path.join(student_dir, file_name)
|
160 |
+
file.save(save_path)
|
161 |
+
print(f"Saved file: {save_path}")
|
162 |
+
|
163 |
+
print("Files saved, now processing folders...")
|
164 |
+
|
165 |
+
# Process the saved files
|
166 |
+
for student_folder in os.listdir(parent_folder):
|
167 |
+
student_path = os.path.join(parent_folder, student_folder)
|
168 |
+
if os.path.isdir(student_path):
|
169 |
+
for image_file in os.listdir(student_path):
|
170 |
+
if image_file.endswith(('.jpg', '.jpeg', '.png')):
|
171 |
+
full_path = os.path.join(student_path, image_file).replace("\\", "/")
|
172 |
+
if student_folder in data:
|
173 |
+
data[student_folder].append(full_path)
|
174 |
+
else:
|
175 |
+
data[student_folder] = [full_path]
|
176 |
+
|
177 |
+
print("Folder structure:", data)
|
178 |
+
|
179 |
+
# Create vectors for reference answers
|
180 |
sen_vec_answers = []
|
181 |
word_vec_answers = []
|
182 |
for answer_set in answers:
|
|
|
187 |
temp_w.append(question_vector_word(ans))
|
188 |
sen_vec_answers.append(temp_v)
|
189 |
word_vec_answers.append(temp_w)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
190 |
|
191 |
+
# Calculate marks
|
192 |
+
s_marks = {}
|
193 |
+
for student_folder in data:
|
194 |
+
s_marks[student_folder] = []
|
195 |
+
count = 0
|
196 |
+
for image_path in sorted(data[student_folder]): # Sort to ensure consistent order
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
try:
|
|
|
|
|
|
|
|
|
198 |
s_answer = extract_text_from_image(image_path)
|
199 |
+
print(f"\nProcessing {student_folder}'s answer {count + 1}:")
|
|
|
|
|
|
|
|
|
200 |
print(f"Extracted answer: {s_answer}")
|
201 |
+
print(f"Reference answer: {answers[count]}")
|
202 |
+
|
203 |
+
if s_answer:
|
204 |
+
tf_idf_word_values, max_tfidf = create_tfidf_values(answers[count])
|
205 |
+
m = marks(s_answer, sen_vec_answers[count], word_vec_answers[count],
|
206 |
+
tf_idf_word_values, max_tfidf, answers[count])
|
207 |
|
208 |
+
if isinstance(m, torch.Tensor):
|
209 |
+
m = m.item()
|
210 |
+
m = round(float(m), 2)
|
|
|
211 |
else:
|
212 |
+
print(f"Warning: No text extracted from {image_path}")
|
213 |
+
m = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
214 |
|
215 |
+
s_marks[student_folder].append(m)
|
216 |
+
print(f"Marks awarded: {m}")
|
217 |
+
count += 1
|
218 |
except Exception as e:
|
219 |
+
print(f"Error processing {image_path}: {str(e)}")
|
220 |
+
s_marks[student_folder].append(0)
|
221 |
+
count += 1
|
222 |
+
|
223 |
+
print("\nFinal marks:", s_marks)
|
224 |
+
|
225 |
+
# Clean up temporary directory
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
226 |
try:
|
227 |
import shutil
|
228 |
+
shutil.rmtree(parent_folder)
|
229 |
+
print(f"Cleaned up temporary directory: {parent_folder}")
|
230 |
except Exception as e:
|
231 |
print(f"Warning: Could not clean up temporary directory: {e}")
|
232 |
|
233 |
+
return jsonify({"message": s_marks}), 200
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
234 |
|
235 |
except Exception as e:
|
236 |
print("Error in compute_marks:", str(e))
|
|
|
237 |
try:
|
238 |
import shutil
|
239 |
+
shutil.rmtree(parent_folder)
|
|
|
240 |
except:
|
241 |
pass
|
242 |
return jsonify({"error": str(e)}), 500
|