File size: 5,820 Bytes
213f539
 
6d71955
213f539
a417e3e
 
213f539
a417e3e
30cf447
 
6d71955
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9f4a1d9
6d71955
 
 
 
 
 
 
 
 
 
 
 
a417e3e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9f4a1d9
a417e3e
9f4a1d9
 
 
 
 
 
a417e3e
9f4a1d9
 
 
 
a417e3e
 
 
 
 
 
 
 
 
9f4a1d9
a28ec90
 
a417e3e
6d71955
 
 
a417e3e
9f4a1d9
6d71955
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a417e3e
9f4a1d9
511dc51
6d71955
 
9f4a1d9
6d71955
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9f4a1d9
 
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
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, 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
    else:  # Open-ended
        num_questions = 3

    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 question_type != "Fill in the Blank":
        prompt += " Provide answers with short explanations."

    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.")

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

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

    # 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)
            
            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)

            # 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.")