File size: 7,646 Bytes
ef91894
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import streamlit as st
import openai
import time

# Set your OpenAI API key from Hugging Face Secrets
openai.api_key = st.secrets["OPENAI_API_KEY"]

# Initialize OpenAI client
client = openai.OpenAI(api_key=openai.api_key)

# Function to generate exam questions using OpenAI API with retry logic
def generate_questions_with_retry(knowledge_material, question_type, cognitive_level, extra_instructions, case_based, num_choices=None, max_retries=3):
    # Adjust the number of questions based on the type
    if question_type == "Multiple Choice":
        num_questions = 3
    elif question_type == "Fill in the Blank":
        num_questions = 10
    elif question_type == "True/False":
        num_questions = 5  # Generate 5 true/false questions
    else:  # Open-ended
        num_questions = 3

    # Base prompt
    prompt = f"Generate {num_questions} {question_type.lower()} exam questions based on {cognitive_level.lower()} level from the following material: {knowledge_material}. {extra_instructions}"

    # If case-based medical situation is selected, modify the prompt
    if case_based:
        prompt = f"Generate {num_questions} {question_type.lower()} exam questions based on {cognitive_level.lower()} level from the following medical material: {knowledge_material}. The questions should be based on case-based medical situations, such as patient scenarios. {extra_instructions}"
        if question_type != "Fill in the Blank":
            prompt += " Provide answers with short explanations."

    # Add specific handling for Multiple Choice and True/False
    if question_type == "Multiple Choice" and num_choices:
        prompt += f" Each multiple choice question should have {num_choices} choices."

    if question_type == "True/False":
        prompt += " Provide short explanations for each question based on the given material, without stating True or False explicitly."

    retries = 0
    while retries < max_retries:
        try:
            response = client.chat.completions.create(
                model="gpt-4o-mini",
                messages=[
                    {"role": "system", "content": "You are a helpful assistant for generating exam questions."},
                    {"role": "user", "content": prompt}
                ]
            )
            return response.choices[0].message.content
        except openai.error.APIConnectionError:
            retries += 1
            time.sleep(2)  # Wait for 2 seconds before retrying
            if retries == max_retries:
                st.error("Failed to connect to OpenAI API after several attempts.")
                return None

# Login page
if 'username' not in st.session_state:
    # Show the login form if the username is not set
    st.title("Login")
    username_input = st.text_input("Enter your username:")
    if st.button("Login"):
        if username_input:
            st.session_state['username'] = username_input
            st.success(f"Welcome, {username_input}!")
        else:
            st.warning("Please enter a valid username.")
else:
    # Main App after login
    st.title(f"Welcome, {st.session_state['username']}! Generate your exam questions")

    # Input field for knowledge material (text) with 3,000-word limit
    knowledge_material = st.text_area("Enter knowledge material to generate exam questions:")
    
    # Word count check
    if len(knowledge_material.split()) > 3000:
        st.warning("Please limit the knowledge material to 3,000 words or fewer.")

    # File uploader for PDFs (limited to 5 MB)
    uploaded_file = st.file_uploader("Upload a file (PDF)", type="pdf")
    
    if uploaded_file is not None:
        if uploaded_file.size > 5 * 1024 * 1024:  # 5 MB limit
            st.warning("File size exceeds 5 MB. Please upload a smaller file.")
        else:
            # Here you can add code to extract text from the PDF if needed
            # For simplicity, we're focusing on the text input for now
            st.success("File uploaded successfully! (Text extraction not implemented yet.)")

    # Select question type
    question_type = st.selectbox("Select question type:", 
                                 ["Multiple Choice", "Fill in the Blank", "Open-ended", "True/False"])

    # For multiple choice, let users select the number of choices
    num_choices = None
    if question_type == "Multiple Choice":
        num_choices = st.selectbox("Select the number of choices for each question:", [3, 4, 5])

    # Select cognitive level
    cognitive_level = st.selectbox("Select cognitive level:", 
                                   ["Recall", "Understanding", "Application", "Analysis", "Synthesis", "Evaluation"])

    # Checkbox for Case-Based Medical Situations
    case_based = st.checkbox("Generate case-based medical exam questions")

    # Extra input field for additional instructions (placed below cognitive level)
    extra_instructions = st.text_area("Enter additional instructions (e.g., how you want the questions to be phrased):")

    # Generate questions button
    if 'previous_questions' not in st.session_state:
        st.session_state['previous_questions'] = []

    if st.button("Generate Questions"):
        if len(knowledge_material.split()) <= 3000:
            # Generate questions with retry logic
            questions = generate_questions_with_retry(
                knowledge_material, 
                question_type, 
                cognitive_level, 
                extra_instructions, 
                case_based, 
                num_choices
            )
            
            if questions:
                st.write("Generated Exam Questions:")
                st.write(questions)

                # Avoid showing repeated content in future requests
                st.session_state['previous_questions'].append(questions)

                # Option to download the questions as a text file
                st.download_button(
                    label="Download Questions",
                    data=questions,
                    file_name='generated_questions.txt',
                    mime='text/plain'
                )
        else:
            st.warning("Please reduce the word count to 3,000 or fewer.")

    # Button to generate more questions based on the same material
    if st.button("Generate More Questions"):
        if len(knowledge_material.split()) <= 3000:
            # Regenerate new questions, trying to avoid repeated content
            questions = generate_questions_with_retry(
                knowledge_material, 
                question_type, 
                cognitive_level, 
                extra_instructions, 
                case_based, 
                num_choices
            )

            # Check if the new set of questions is not the same as the previous set
            if questions and questions not in st.session_state['previous_questions']:
                st.write("Generated More Exam Questions:")
                st.write(questions)

                # Append the new questions to the session state
                st.session_state['previous_questions'].append(questions)

                # Option to download the new set of questions
                st.download_button(
                    label="Download More Questions",
                    data=questions,
                    file_name='more_generated_questions.txt',
                    mime='text/plain'
                )
            else:
                st.warning("New questions seem to overlap with the previous ones. Try adjusting the instructions.")
        else:
            st.warning("Please reduce the word count to 3,000 or fewer.")