Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -558,7 +558,7 @@ css_styles = """
|
|
| 558 |
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 559 |
padding: 30px;
|
| 560 |
border-radius: 15px;
|
| 561 |
-
color:
|
| 562 |
margin-bottom: 20px;
|
| 563 |
}
|
| 564 |
|
|
@@ -797,11 +797,40 @@ with gr.Blocks(title="UNEB Exam Prep - Primary 6 & 7", theme=gr.themes.Soft(), c
|
|
| 797 |
|
| 798 |
# Method 3: Type
|
| 799 |
with gr.Tab(" Type Answers"):
|
| 800 |
-
gr.Markdown("
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 801 |
typed_answers = gr.Textbox(
|
| 802 |
-
label="Type
|
| 803 |
-
lines=
|
| 804 |
-
placeholder="
|
|
|
|
| 805 |
)
|
| 806 |
|
| 807 |
# Combined submit button
|
|
@@ -814,44 +843,92 @@ with gr.Blocks(title="UNEB Exam Prep - Primary 6 & 7", theme=gr.themes.Soft(), c
|
|
| 814 |
lines=2
|
| 815 |
)
|
| 816 |
|
| 817 |
-
#
|
| 818 |
def submit_answers(canvas_input, upload_input, typed_input):
|
| 819 |
if not session.current_questions:
|
| 820 |
return " Generate questions first in Step 1!"
|
| 821 |
|
| 822 |
# Check which method was used
|
| 823 |
if canvas_input is not None:
|
| 824 |
-
# Convert canvas to text representation
|
| 825 |
session.current_answers = {0: "[Canvas drawing - sent to AI for analysis]"}
|
| 826 |
return f" Canvas submission received with {len(session.current_questions)} questions. Processing..."
|
|
|
|
| 827 |
elif upload_input is not None:
|
| 828 |
session.current_answers = {0: "[Uploaded image - sent to AI for analysis]"}
|
| 829 |
return f" Photo submission received with {len(session.current_questions)} questions. Processing..."
|
|
|
|
| 830 |
elif typed_input and typed_input.strip():
|
| 831 |
-
# Parse typed answers
|
| 832 |
session.current_answers = {}
|
| 833 |
-
lines = typed_input.split('\n')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 834 |
for line in lines:
|
| 835 |
-
|
| 836 |
-
|
| 837 |
-
|
| 838 |
-
|
| 839 |
-
|
| 840 |
-
|
| 841 |
-
|
| 842 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 843 |
|
| 844 |
if session.current_answers:
|
| 845 |
-
|
|
|
|
|
|
|
| 846 |
else:
|
| 847 |
-
return "⚠️ Could not
|
| 848 |
else:
|
| 849 |
-
return "⚠️ Please provide answers using one of the three methods."
|
| 850 |
|
| 851 |
submit_btn.click(
|
| 852 |
fn=submit_answers,
|
| 853 |
inputs=[canvas, upload_image, typed_answers],
|
| 854 |
outputs=submit_status
|
|
|
|
| 855 |
)
|
| 856 |
|
| 857 |
# ===== TAB 3: AI CORRECTION =====
|
|
|
|
| 558 |
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 559 |
padding: 30px;
|
| 560 |
border-radius: 15px;
|
| 561 |
+
color: white;
|
| 562 |
margin-bottom: 20px;
|
| 563 |
}
|
| 564 |
|
|
|
|
| 797 |
|
| 798 |
# Method 3: Type
|
| 799 |
with gr.Tab(" Type Answers"):
|
| 800 |
+
gr.Markdown("""
|
| 801 |
+
### 📝 Type Your Answers
|
| 802 |
+
|
| 803 |
+
**Instructions:** Type each answer in the box below. Use one of these formats:
|
| 804 |
+
|
| 805 |
+
- **Option A (Recommended):** Type answers separated by blank lines
|
| 806 |
+
```
|
| 807 |
+
Answer to question 1 goes here
|
| 808 |
+
|
| 809 |
+
Answer to question 2 goes here
|
| 810 |
+
|
| 811 |
+
Answer to question 3 goes here
|
| 812 |
+
```
|
| 813 |
+
|
| 814 |
+
- **Option B:** Type with labels
|
| 815 |
+
```
|
| 816 |
+
Answer 1: Your answer here
|
| 817 |
+
Answer 2: Your answer here
|
| 818 |
+
Answer 3: Your answer here
|
| 819 |
+
```
|
| 820 |
+
|
| 821 |
+
- **Option C:** Type with Q labels
|
| 822 |
+
```
|
| 823 |
+
Q1: Your answer here
|
| 824 |
+
Q2: Your answer here
|
| 825 |
+
Q3: Your answer here
|
| 826 |
+
```
|
| 827 |
+
""")
|
| 828 |
+
|
| 829 |
typed_answers = gr.Textbox(
|
| 830 |
+
label="Type Your Answers Here",
|
| 831 |
+
lines=20,
|
| 832 |
+
placeholder="Type your answers using any of the formats shown above...",
|
| 833 |
+
elem_classes="answer-input"
|
| 834 |
)
|
| 835 |
|
| 836 |
# Combined submit button
|
|
|
|
| 843 |
lines=2
|
| 844 |
)
|
| 845 |
|
| 846 |
+
# Improved submission handler with better parsing
|
| 847 |
def submit_answers(canvas_input, upload_input, typed_input):
|
| 848 |
if not session.current_questions:
|
| 849 |
return " Generate questions first in Step 1!"
|
| 850 |
|
| 851 |
# Check which method was used
|
| 852 |
if canvas_input is not None:
|
|
|
|
| 853 |
session.current_answers = {0: "[Canvas drawing - sent to AI for analysis]"}
|
| 854 |
return f" Canvas submission received with {len(session.current_questions)} questions. Processing..."
|
| 855 |
+
|
| 856 |
elif upload_input is not None:
|
| 857 |
session.current_answers = {0: "[Uploaded image - sent to AI for analysis]"}
|
| 858 |
return f" Photo submission received with {len(session.current_questions)} questions. Processing..."
|
| 859 |
+
|
| 860 |
elif typed_input and typed_input.strip():
|
| 861 |
+
# Parse typed answers with improved logic
|
| 862 |
session.current_answers = {}
|
| 863 |
+
lines = typed_input.strip().split('\n')
|
| 864 |
+
|
| 865 |
+
# First, try to detect the format
|
| 866 |
+
# Format detection: Look for patterns like "Answer 1:", "Q1:", or just free text separated by blank lines
|
| 867 |
+
answer_list = []
|
| 868 |
+
current_answer = []
|
| 869 |
+
answer_number = 0
|
| 870 |
+
|
| 871 |
for line in lines:
|
| 872 |
+
line = line.strip()
|
| 873 |
+
|
| 874 |
+
# Skip completely empty lines if we have content in current_answer
|
| 875 |
+
if not line:
|
| 876 |
+
if current_answer:
|
| 877 |
+
answer_list.append('\n'.join(current_answer))
|
| 878 |
+
current_answer = []
|
| 879 |
+
continue
|
| 880 |
+
|
| 881 |
+
# Check for labeled formats (Q1:, Answer 1:, etc.)
|
| 882 |
+
is_labeled = False
|
| 883 |
+
label_content = None
|
| 884 |
+
|
| 885 |
+
# Check for "Q1:", "Q2:" pattern
|
| 886 |
+
if ':' in line:
|
| 887 |
+
parts = line.split(':', 1)
|
| 888 |
+
label_part = parts[0].strip().upper()
|
| 889 |
+
content_part = parts[1].strip() if len(parts) > 1 else ""
|
| 890 |
+
|
| 891 |
+
# Matches "Q1", "ANSWER 1", "ANS 1", etc.
|
| 892 |
+
if (label_part.startswith('Q') and label_part[1:].split()[0].isdigit()) or \
|
| 893 |
+
('ANSWER' in label_part) or \
|
| 894 |
+
('ANS' in label_part):
|
| 895 |
+
is_labeled = True
|
| 896 |
+
# Save previous answer if exists
|
| 897 |
+
if current_answer:
|
| 898 |
+
answer_list.append('\n'.join(current_answer))
|
| 899 |
+
current_answer = []
|
| 900 |
+
# Start new answer with content
|
| 901 |
+
if content_part:
|
| 902 |
+
current_answer.append(content_part)
|
| 903 |
+
answer_number += 1
|
| 904 |
+
continue
|
| 905 |
+
|
| 906 |
+
# If not labeled format, treat as continuation of current answer
|
| 907 |
+
current_answer.append(line)
|
| 908 |
+
|
| 909 |
+
# Don't forget the last answer
|
| 910 |
+
if current_answer:
|
| 911 |
+
answer_list.append('\n'.join(current_answer))
|
| 912 |
+
|
| 913 |
+
# Map answers to question indices
|
| 914 |
+
for i, answer_text in enumerate(answer_list):
|
| 915 |
+
if answer_text.strip(): # Only include non-empty answers
|
| 916 |
+
session.current_answers[i] = answer_text.strip()
|
| 917 |
|
| 918 |
if session.current_answers:
|
| 919 |
+
answered = len(session.current_answers)
|
| 920 |
+
total = len(session.current_questions)
|
| 921 |
+
return f"✅ Received {answered}/{total} answer(s). Processing for AI correction..."
|
| 922 |
else:
|
| 923 |
+
return "⚠️ Could not find any answers. Please type your answers using one of the suggested formats."
|
| 924 |
else:
|
| 925 |
+
return "⚠️ Please provide answers using one of the three methods (draw, upload, or type)."
|
| 926 |
|
| 927 |
submit_btn.click(
|
| 928 |
fn=submit_answers,
|
| 929 |
inputs=[canvas, upload_image, typed_answers],
|
| 930 |
outputs=submit_status
|
| 931 |
+
|
| 932 |
)
|
| 933 |
|
| 934 |
# ===== TAB 3: AI CORRECTION =====
|