PJamila commited on
Commit
3576983
β€’
1 Parent(s): 7cda089

Create streamlit_app.py

Browse files
Files changed (1) hide show
  1. streamlit_app.py +130 -0
streamlit_app.py ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from helpers.youtube_utils import extract_video_id_from_url, get_transcript_text
3
+ from helpers.openai_utils import get_quiz_data
4
+ from helpers.quiz_utils import string_to_list, get_randomized_options
5
+ from helpers.toast_messages import get_random_toast
6
+
7
+
8
+ st.set_page_config(
9
+ page_title="QuizTube",
10
+ page_icon="🧠",
11
+ layout="centered",
12
+ initial_sidebar_state="collapsed"
13
+ )
14
+
15
+ # Check if user is new or returning using session state.
16
+ # If user is new, show the toast message.
17
+ if 'first_time' not in st.session_state:
18
+ message, icon = get_random_toast()
19
+ st.toast(message, icon=icon)
20
+ st.session_state.first_time = False
21
+
22
+ with st.sidebar:
23
+ st.header("πŸ‘¨β€πŸ’» About the Author")
24
+ st.write("""
25
+ **Sven Bosau** is a tech enthusiast, educator, and coder. Driven by passion and a love for sharing knowledge, he's created this platform to make learning more interactive and fun.
26
+
27
+ Connect, contribute, or just say hi!
28
+ """)
29
+
30
+ st.divider()
31
+ st.subheader("πŸ”— Connect with Me", anchor=False)
32
+ st.markdown(
33
+ """
34
+ - [πŸ™ Source Code](https://github.com/Sven-Bo/streamlit-quiztube)
35
+ - [πŸŽ₯ YouTube Channel](https://youtube.com/@codingisfun)
36
+ - [β˜• Buy me a Coffee](https://pythonandvba.com/coffee-donation)
37
+ - [🌐 Personal Website](https://pythonandvba.com)
38
+ - [πŸ‘” LinkedIn](https://www.linkedin.com/in/sven-bosau/)
39
+ """
40
+ )
41
+
42
+ st.divider()
43
+ st.subheader("πŸ† Streamlit Hackathon 2023", anchor=False)
44
+ st.write("QuizTube proudly stands as Sven's innovative entry for the Streamlit Hackathon held in September 2023. A testament to the power of imagination and code!")
45
+
46
+ st.divider()
47
+ st.write("Made with β™₯ in Dresden, Germany")
48
+
49
+
50
+
51
+ st.title(":red[QuizTube] β€” Watch. Learn. Quiz. 🧠", anchor=False)
52
+ st.write("""
53
+ Ever watched a YouTube video and wondered how well you understood its content? Here's a fun twist: Instead of just watching on YouTube, come to **QuizTube** and test your comprehension!
54
+
55
+ **How does it work?** πŸ€”
56
+ 1. Paste the YouTube video URL of your recently watched video.
57
+ 2. Enter your [OpenAI API Key](https://platform.openai.com/account/api-keys).
58
+
59
+ ⚠️ Important: The video **must** have English captions for the tool to work.
60
+
61
+ Once you've input the details, voilΓ ! Dive deep into questions crafted just for you, ensuring you've truly grasped the content of the video. Let's put your knowledge to the test!
62
+ """)
63
+
64
+ with st.expander("πŸ’‘ Video Tutorial"):
65
+ with st.spinner("Loading video.."):
66
+ st.video("https://youtu.be/yzBr3L2BIto", format="video/mp4", start_time=0)
67
+
68
+ with st.form("user_input"):
69
+ YOUTUBE_URL = st.text_input("Enter the YouTube video link:", value="https://youtu.be/bcYwiwsDfGE?si=qQ0nvkmKkzHJom2y")
70
+ OPENAI_API_KEY = st.text_input("Enter your OpenAI API Key:", placeholder="sk-XXXX", type='password')
71
+ submitted = st.form_submit_button("Craft my quiz!")
72
+
73
+ if submitted or ('quiz_data_list' in st.session_state):
74
+ if not YOUTUBE_URL:
75
+ st.info("Please provide a valid YouTube video link. Head over to [YouTube](https://www.youtube.com/) to fetch one.")
76
+ st.stop()
77
+ elif not OPENAI_API_KEY:
78
+ st.info("Please fill out the OpenAI API Key to proceed. If you don't have one, you can obtain it [here](https://platform.openai.com/account/api-keys).")
79
+ st.stop()
80
+
81
+ with st.spinner("Crafting your quiz...πŸ€“"):
82
+ if submitted:
83
+ video_id = extract_video_id_from_url(YOUTUBE_URL)
84
+ video_transcription = get_transcript_text(video_id)
85
+ quiz_data_str = get_quiz_data(video_transcription, OPENAI_API_KEY)
86
+ st.session_state.quiz_data_list = string_to_list(quiz_data_str)
87
+
88
+ if 'user_answers' not in st.session_state:
89
+ st.session_state.user_answers = [None for _ in st.session_state.quiz_data_list]
90
+ if 'correct_answers' not in st.session_state:
91
+ st.session_state.correct_answers = []
92
+ if 'randomized_options' not in st.session_state:
93
+ st.session_state.randomized_options = []
94
+
95
+ for q in st.session_state.quiz_data_list:
96
+ options, correct_answer = get_randomized_options(q[1:])
97
+ st.session_state.randomized_options.append(options)
98
+ st.session_state.correct_answers.append(correct_answer)
99
+
100
+ with st.form(key='quiz_form'):
101
+ st.subheader("🧠 Quiz Time: Test Your Knowledge!", anchor=False)
102
+ for i, q in enumerate(st.session_state.quiz_data_list):
103
+ options = st.session_state.randomized_options[i]
104
+ default_index = st.session_state.user_answers[i] if st.session_state.user_answers[i] is not None else 0
105
+ response = st.radio(q[0], options, index=default_index)
106
+ user_choice_index = options.index(response)
107
+ st.session_state.user_answers[i] = user_choice_index # Update the stored answer right after fetching it
108
+
109
+
110
+ results_submitted = st.form_submit_button(label='Unveil My Score!')
111
+
112
+ if results_submitted:
113
+ score = sum([ua == st.session_state.randomized_options[i].index(ca) for i, (ua, ca) in enumerate(zip(st.session_state.user_answers, st.session_state.correct_answers))])
114
+ st.success(f"Your score: {score}/{len(st.session_state.quiz_data_list)}")
115
+
116
+ if score == len(st.session_state.quiz_data_list): # Check if all answers are correct
117
+ st.balloons()
118
+ else:
119
+ incorrect_count = len(st.session_state.quiz_data_list) - score
120
+ if incorrect_count == 1:
121
+ st.warning(f"Almost perfect! You got 1 question wrong. Let's review it:")
122
+ else:
123
+ st.warning(f"Almost there! You got {incorrect_count} questions wrong. Let's review them:")
124
+
125
+ for i, (ua, ca, q, ro) in enumerate(zip(st.session_state.user_answers, st.session_state.correct_answers, st.session_state.quiz_data_list, st.session_state.randomized_options)):
126
+ with st.expander(f"Question {i + 1}", expanded=False):
127
+ if ro[ua] != ca:
128
+ st.info(f"Question: {q[0]}")
129
+ st.error(f"Your answer: {ro[ua]}")
130
+ st.success(f"Correct answer: {ca}")