Spaces:
Sleeping
Sleeping
sync with remote
Browse files- app.py +119 -0
- requirements.txt +2 -0
app.py
ADDED
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import google.generativeai as genai
|
3 |
+
import os
|
4 |
+
import tempfile
|
5 |
+
|
6 |
+
MODEL_ID = "gemini-2.0-flash-exp"
|
7 |
+
genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
|
8 |
+
model = genai.GenerativeModel(MODEL_ID)
|
9 |
+
chat = model.start_chat()
|
10 |
+
|
11 |
+
# Initialize session state variables
|
12 |
+
if 'essay_question' not in st.session_state:
|
13 |
+
st.session_state.essay_question = ""
|
14 |
+
if 'scoring_rubric' not in st.session_state:
|
15 |
+
st.session_state.scoring_rubric = ""
|
16 |
+
if "subject" not in st.session_state:
|
17 |
+
st.session_state.subject = ""
|
18 |
+
if "topic" not in st.session_state:
|
19 |
+
st.session_state.topic = ""
|
20 |
+
|
21 |
+
def generate_essay_question(subject, topic, difficulty):
|
22 |
+
try:
|
23 |
+
prompt = f"Create an essay question on the topic '{topic}' in the context of {subject} with a {difficulty} difficulty level. Output the essay question only. Do not provide any other information."
|
24 |
+
response = model.generate_content(prompt)
|
25 |
+
return response.text
|
26 |
+
except Exception as e:
|
27 |
+
st.error(f"An error occurred: {e}")
|
28 |
+
return None
|
29 |
+
|
30 |
+
def generate_scoring_rubric(essay_question):
|
31 |
+
return f"Scoring Rubric for the essay question: {essay_question}\n\n1. Clarity: 10 points\n2. Argument Strength: 10 points\n3. Grammar: 10 points\n4. Creativity: 10 points\n5. Relevance to Topic: 10 points\n\nTotal: 50 points"
|
32 |
+
|
33 |
+
def capture_exam_photo():
|
34 |
+
img_file_buffer = None
|
35 |
+
image_path = ""
|
36 |
+
|
37 |
+
# Use the camera to capture an image
|
38 |
+
img_file_buffer = st.camera_input("Take a picture")
|
39 |
+
|
40 |
+
if img_file_buffer is not None:
|
41 |
+
# Save the image to a temporary file
|
42 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as temp_file:
|
43 |
+
temp_file.write(img_file_buffer.read())
|
44 |
+
image_path = temp_file.name
|
45 |
+
return image_path
|
46 |
+
else:
|
47 |
+
st.warning("Please capture an image of the exam paper.")
|
48 |
+
return None
|
49 |
+
|
50 |
+
def main():
|
51 |
+
|
52 |
+
# Streamlit UI
|
53 |
+
st.title("Essay Grading System")
|
54 |
+
tabs = ["Essay Question", "Scoring Rubric", "Grading Outputs"]
|
55 |
+
selected_tab = st.sidebar.radio("Select a Tab", tabs)
|
56 |
+
|
57 |
+
if selected_tab == "Essay Question":
|
58 |
+
st.header("Generate Essay Question")
|
59 |
+
if st.session_state.subject != "":
|
60 |
+
subject = st.text_input("Enter Subject", st.session_state.subject)
|
61 |
+
else:
|
62 |
+
subject = st.text_input("Enter Subject")
|
63 |
+
if st.session_state.subject != "":
|
64 |
+
topic = st.text_input("Enter Topic", st.session_state.topic)
|
65 |
+
else:
|
66 |
+
topic = st.text_input("Enter Topic")
|
67 |
+
|
68 |
+
difficulty = st.selectbox("Select Difficulty", ["Easy", "Moderate", "Difficult"])
|
69 |
+
|
70 |
+
if st.button("Generate Question"):
|
71 |
+
if subject and topic and difficulty:
|
72 |
+
st.session_state.essay_question = generate_essay_question(subject, topic, difficulty)
|
73 |
+
st.success("Essay question generated successfully!")
|
74 |
+
else:
|
75 |
+
st.warning("Please provide the subject and topic.")
|
76 |
+
if st.session_state.essay_question:
|
77 |
+
st.subheader("Generated Essay Question:")
|
78 |
+
st.write(st.session_state.essay_question)
|
79 |
+
|
80 |
+
elif selected_tab == "Scoring Rubric":
|
81 |
+
st.header("Scoring Rubric")
|
82 |
+
if not st.session_state.essay_question:
|
83 |
+
st.warning("Please generate an essay question first.")
|
84 |
+
else:
|
85 |
+
if not st.session_state.scoring_rubric:
|
86 |
+
st.session_state.scoring_rubric = generate_scoring_rubric(st.session_state.essay_question)
|
87 |
+
|
88 |
+
st.subheader("Generated Scoring Rubric:")
|
89 |
+
st.session_state.scoring_rubric = st.text_area("Edit Rubric", st.session_state.scoring_rubric, height=200)
|
90 |
+
|
91 |
+
elif selected_tab == "Grading Outputs":
|
92 |
+
st.header("Grading Outputs")
|
93 |
+
if not st.session_state.essay_question or not st.session_state.scoring_rubric:
|
94 |
+
st.warning("Please generate both an essay question and a scoring rubric first.")
|
95 |
+
else:
|
96 |
+
exam_image_path = capture_exam_photo()
|
97 |
+
mime_type = "image/jpeg"
|
98 |
+
if exam_image_path is not None:
|
99 |
+
|
100 |
+
# Upload the file with the correct MIME type
|
101 |
+
file_data = genai.upload_file(exam_image_path, mime_type=mime_type)
|
102 |
+
|
103 |
+
multimodal_prompt = f"Extract all the text from the image. Score the essay exam response to the Essay Question: {st.session_state.essay_question}\nScoring Rubric: {st.session_state.scoring_rubric}. Provide feednack on the essay response."
|
104 |
+
|
105 |
+
# Send file and prompt to Gemini API
|
106 |
+
response = chat.send_message(
|
107 |
+
[
|
108 |
+
multimodal_prompt,
|
109 |
+
file_data
|
110 |
+
]
|
111 |
+
)
|
112 |
+
|
113 |
+
st.subheader("AI Grading Response:")
|
114 |
+
# Display Gemini response
|
115 |
+
st.markdown(response.text)
|
116 |
+
|
117 |
+
|
118 |
+
if __name__ == "__main__":
|
119 |
+
main()
|
requirements.txt
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
streamlit
|
2 |
+
google-generativeai
|