# import os # import base64 # from PIL import Image # import streamlit as st # from evaluator import ( # IELTSTask1Evaluator, # IELTSTask1ExerciseGenerator, # IELTSTask2Evaluator, # IELTSTask2ExerciseGenerator # ) # # Initialize session state for login # if 'logged_in' not in st.session_state: # st.session_state.logged_in = False # def check_password(): # """Returns `True` if the user had the correct password.""" # def password_entered(): # """Checks whether a password entered by the user is correct.""" # if st.session_state["password"] == "hamid1377" and st.session_state["username"] == "afarinesh": # st.session_state.logged_in = True # del st.session_state["password"] # Don't store password # del st.session_state["username"] # Don't store username # else: # st.session_state.logged_in = False # if not st.session_state.logged_in: # st.text_input("Username", key="username") # st.text_input("Password", type="password", key="password") # st.button("Login", on_click=password_entered) # return False # return True # # Configure Streamlit page # st.set_page_config( # page_title="IELTS Writing Evaluator", # page_icon="📝", # layout="wide", # initial_sidebar_state="expanded" # ) # # Custom CSS # st.markdown(""" # # """, unsafe_allow_html=True) # # Initialize session state # if 'current_task' not in st.session_state: # st.session_state.current_task = 'Task 1' # if 'evaluation_results' not in st.session_state: # st.session_state.evaluation_results = None # if 'graph_analysis' not in st.session_state: # st.session_state.graph_analysis = None # def create_evaluator_instance(task_type): # """Creates and returns appropriate evaluator instance based on task type""" # try: # if task_type == "Task 1": # return IELTSTask1Evaluator(), IELTSTask1ExerciseGenerator() # else: # return IELTSTask2Evaluator(), IELTSTask2ExerciseGenerator() # except Exception as e: # st.error(f"Error initializing evaluator: {str(e)}") # return None, None # def display_task1_interface(): # """Displays Task 1 interface and handles evaluation""" # st.header("Academic Writing Task 1 Evaluation") # with st.container(): # col1, col2 = st.columns([1, 1]) # with col1: # st.subheader("Upload Graph/Chart") # uploaded_file = st.file_uploader( # "Upload image (JPG, PNG)", # type=['jpg', 'jpeg', 'png'], # help="Upload the graph or chart you're describing" # ) # # Add question input field # question = st.text_area( # "Enter the Task 1 question", # height=100, # help="Paste the task question here" # ) # if uploaded_file and question: # try: # image = Image.open(uploaded_file) # st.image(image, use_column_width=True) # # Save image temporarily # temp_path = "temp_graph.jpg" # image.save(temp_path) # # Analyze graph but don't display analysis # evaluator, generator = create_evaluator_instance("Task 1") # if evaluator: # with st.spinner("Analyzing image..."): # graph_analysis = evaluator.analyze_graph(temp_path, question) # # Store graph analysis in session state without displaying # st.session_state.graph_analysis = graph_analysis # st.success("Image analysis complete") # except Exception as e: # st.error(f"Error processing image: {str(e)}") # finally: # if os.path.exists("temp_graph.jpg"): # os.remove("temp_graph.jpg") # with col2: # st.subheader("Your Response") # written_response = st.text_area( # "Enter your response here", # height=300, # help="Write your Task 1 response here" # ) # if st.button("Evaluate Response", type="primary"): # if not uploaded_file: # st.warning("Please upload a graph/chart first.") # return # if not question: # st.warning("Please enter the task question.") # return # if not written_response: # st.warning("Please enter your written response.") # return # # Pass both question and graph analysis to evaluation # if st.session_state.graph_analysis is not None: # process_evaluation( # written_response, # "Task 1", # { # 'question': question, # 'graph_analysis': st.session_state.graph_analysis # } # ) # else: # st.warning("Please wait for image analysis to complete.") # def display_task2_interface(): # """Displays Task 2 interface and handles evaluation""" # st.header("Academic Writing Task 2 Evaluation") # with st.container(): # st.subheader("Essay Question") # essay_question = st.text_area( # "Enter the Task 2 question", # height=100, # help="Paste the essay question here" # ) # st.subheader("Your Response") # written_response = st.text_area( # "Enter your response here", # height=300, # help="Write your Task 2 response here" # ) # if st.button("Evaluate Essay", type="primary"): # if not essay_question: # st.warning("Please enter the essay question.") # return # if not written_response: # st.warning("Please enter your written response.") # return # process_evaluation(written_response, "Task 2", essay_question) # def display_evaluation_results(task_type): # """Displays evaluation results in organized tabs""" # if not st.session_state.evaluation_results: # return # results = st.session_state.evaluation_results # tabs = st.tabs([ # "📊 Overall Score", # "🔤 Grammar Analysis", # "📚 Vocabulary Analysis", # "🎯 Task Achievement", # "📝 Practice Exercises" # ]) # with tabs[0]: # st.markdown("### Overall Assessment") # st.markdown(results['evaluation']) # with tabs[1]: # st.markdown("### Grammar Analysis") # st.markdown(results['grammar']) # with tabs[2]: # st.markdown("### Vocabulary Analysis") # st.markdown(results['vocabulary']) # with tabs[3]: # st.markdown("### Task Achievement") # st.markdown(results['task_achievement']) # with tabs[4]: # if st.button("Generate Practice Exercises", type="secondary"): # with st.spinner("Generating exercises..."): # evaluator, generator = create_evaluator_instance(task_type) # if generator: # grammar_exercises = generator.generate_grammar_exercises( # results['grammar'], # results['written_response'] # ) # vocab_exercises = generator.generate_vocabulary_exercises( # results['vocabulary'] # ) # st.markdown("### Grammar Exercises") # st.markdown(grammar_exercises) # st.markdown("### Vocabulary Exercises") # st.markdown(vocab_exercises) # def process_evaluation(written_response, task_type, additional_info=None): # """Processes the evaluation request and stores results""" # try: # evaluator, _ = create_evaluator_instance(task_type) # if not evaluator: # return # with st.spinner("Evaluating your response..."): # if task_type == "Task 1": # question = additional_info['question'] # graph_analysis = additional_info['graph_analysis'] # evaluation = evaluator.evaluate_task1_response(question, graph_analysis, written_response) # grammar = evaluator.analyze_grammar(written_response) # vocabulary = evaluator.analyze_vocabulary(written_response) # task_achievement = evaluator.analyze_task_achievement(question, graph_analysis, written_response) # cohesion = evaluator.analyze_cohesion_coherence(written_response, graph_analysis) # else: # evaluation = evaluator.evaluate_essay(additional_info, written_response) # grammar = evaluator.analyze_grammar(written_response) # vocabulary = evaluator.analyze_vocabulary(written_response) # task_achievement = evaluator.analyze_task_achievement(additional_info, written_response) # cohesion = evaluator.analyze_cohesion_coherence(written_response) # st.session_state.evaluation_results = { # 'evaluation': evaluation, # 'grammar': grammar, # 'vocabulary': vocabulary, # 'task_achievement': task_achievement, # 'cohesion': cohesion, # 'written_response': written_response # } # st.success("Evaluation complete! View results in the tabs below.") # except Exception as e: # st.error(f"Error during evaluation: {str(e)}") # def main(): # """Main application function""" # st.title("IELTS Writing Evaluation System") # if not check_password(): # st.stop() # Do not continue if check_password is not True # # Task selection in sidebar # with st.sidebar: # st.title("Navigation") # st.session_state.current_task = st.radio( # "Select Task Type", # ["Task 1", "Task 2"], # key="task_selection" # ) # st.markdown("---") # st.markdown("### About") # st.markdown(""" # This tool helps evaluate IELTS Writing responses and provides: # - Detailed scoring # - Grammar analysis # - Vocabulary feedback # - Task achievement assessment # - Practice exercises # """) # # Display appropriate interface based on task selection # if st.session_state.current_task == "Task 1": # display_task1_interface() # else: # display_task2_interface() # # Display evaluation results if available # if st.session_state.evaluation_results: # display_evaluation_results(st.session_state.current_task) # if __name__ == "__main__": # main() import os import gradio as gr from PIL import Image from evaluator import ( IELTSTask1Evaluator, IELTSTask1ExerciseGenerator, IELTSTask2Evaluator, IELTSTask2ExerciseGenerator ) # ------------------------- # AUTHENTICATION # ------------------------- USERNAME = "afarinesh" PASSWORD = "hamid1377" def login(username, password): if username == USERNAME and password == PASSWORD: return gr.update(visible=False), gr.update(visible=True), "" return gr.update(visible=True), gr.update(visible=False), "❌ Incorrect username or password" # ------------------------- # EVALUATION LOGIC # ------------------------- def create_evaluators(task): if task == "Task 1": return IELTSTask1Evaluator(), IELTSTask1ExerciseGenerator() return IELTSTask2Evaluator(), IELTSTask2ExerciseGenerator() def analyze_task1_graph(image, question): if image is None: return None, "❌ Please upload an image." if not question.strip(): return None, "❌ Please enter a Task 1 question." temp_path = "temp_graph.jpg" image.save(temp_path) evaluator, _ = create_evaluators("Task 1") analysis = evaluator.analyze_graph(temp_path, question) os.remove(temp_path) return analysis, "✅ Image analyzed successfully" def evaluate_task1(image, question, response, graph_analysis): if image is None: return "Please upload an image", "", "", "", "" if not question.strip(): return "Please enter the question", "", "", "", "" if not response.strip(): return "Please write your response", "", "", "", "" if graph_analysis is None: return "Graph not analyzed yet", "", "", "", "" evaluator, _ = create_evaluators("Task 1") evaluation = evaluator.evaluate_task1_response(question, graph_analysis, response) grammar = evaluator.analyze_grammar(response) vocabulary = evaluator.analyze_vocabulary(response) task_achievement = evaluator.analyze_task_achievement(question, graph_analysis, response) cohesion = evaluator.analyze_cohesion_coherence(response, graph_analysis) return evaluation, grammar, vocabulary, task_achievement, cohesion def evaluate_task2(question, response): if not question.strip(): return "Please enter the question", "", "", "", "" if not response.strip(): return "Please write your response", "", "", "", "" evaluator, _ = create_evaluators("Task 2") evaluation = evaluator.evaluate_essay(question, response) grammar = evaluator.analyze_grammar(response) vocabulary = evaluator.analyze_vocabulary(response) task_achievement = evaluator.analyze_task_achievement(question, response) cohesion = evaluator.analyze_cohesion_coherence(response) return evaluation, grammar, vocabulary, task_achievement, cohesion def generate_exercises(task, grammar_text, vocab_text, response): _, generator = create_evaluators(task) g = generator.generate_grammar_exercises(grammar_text, response) v = generator.generate_vocabulary_exercises(vocab_text) return g, v # ------------------------- # BUILD INTERFACE # ------------------------- with gr.Blocks() as demo: # ------------------------- # LOGIN SCREEN # ------------------------- login_box = gr.Group(visible=True) with login_box: gr.Markdown("## 🔐 Login") user = gr.Textbox(label="Username") pwd = gr.Textbox(label="Password", type="password") login_btn = gr.Button("Login") login_msg = gr.Markdown("") # ------------------------- # MAIN APP # ------------------------- main = gr.Group(visible=False) with main: gr.Markdown("# 📝 IELTS Writing Evaluator") task_selector = gr.Radio(["Task 1", "Task 2"], label="Choose Task Type", value="Task 1") # ------------------------- # TASK 1 UI # ------------------------- with gr.Tab("Task 1"): image = gr.Image(type="pil", label="Upload Graph/Chart") t1_question = gr.Textbox(label="Task 1 Question", lines=3) analyze_btn = gr.Button("Analyze Graph") graph_output = gr.Markdown("") graph_state = gr.State() response1 = gr.Textbox(label="Your Response", lines=10) eval_btn1 = gr.Button("Evaluate Response") evaluation1 = gr.Markdown() grammar1 = gr.Markdown() vocabulary1 = gr.Markdown() task_ach1 = gr.Markdown() cohesion1 = gr.Markdown() # ------------------------- # TASK 2 UI # ------------------------- with gr.Tab("Task 2"): t2_question = gr.Textbox(label="Task 2 Question", lines=3) response2 = gr.Textbox(label="Your Response", lines=10) eval_btn2 = gr.Button("Evaluate Essay") evaluation2 = gr.Markdown() grammar2 = gr.Markdown() vocabulary2 = gr.Markdown() task_ach2 = gr.Markdown() cohesion2 = gr.Markdown() # ------------------------- # EXERCISE GENERATION # ------------------------- gr.Markdown("---\n## 📚 Practice Exercises") exercise_btn = gr.Button("Generate Exercises") exercises_grammar = gr.Markdown() exercises_vocab = gr.Markdown() # ------------------------- # BIND FUNCTIONS # ------------------------- login_btn.click( login, [user, pwd], [login_box, main, login_msg] ) analyze_btn.click( analyze_task1_graph, [image, t1_question], [graph_state, graph_output] ) eval_btn1.click( evaluate_task1, [image, t1_question, response1, graph_state], [evaluation1, grammar1, vocabulary1, task_ach1, cohesion1] ) eval_btn2.click( evaluate_task2, [t2_question, response2], [evaluation2, grammar2, vocabulary2, task_ach2, cohesion2] ) exercise_btn.click( generate_exercises, [task_selector, grammar1, vocabulary1, response1], [exercises_grammar, exercises_vocab] ) # ------------------------- # RUN # ------------------------- demo.launch()