Jay4769 commited on
Commit
c97f4e1
·
verified ·
1 Parent(s): e7d17f9

Upload 4 files

Browse files
Files changed (4) hide show
  1. app.py +219 -0
  2. firebase_key.json +13 -0
  3. quiz_data.json +36 -0
  4. requirements.txt +2 -0
app.py ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import json
3
+ import random
4
+
5
+ from datetime import date
6
+ from datetime import datetime
7
+ from datetime import timedelta
8
+
9
+ import firebase_admin
10
+
11
+ from firebase_admin import credentials
12
+ from firebase_admin import firestore
13
+
14
+ # =========================
15
+ # FIREBASE
16
+ # =========================
17
+
18
+ cred = credentials.Certificate(
19
+ "firebase_key.json"
20
+ )
21
+
22
+ firebase_admin.initialize_app(cred)
23
+
24
+ db = firestore.client()
25
+
26
+ # =========================
27
+ # QUIZ DATA
28
+ # =========================
29
+
30
+ with open(
31
+ "quiz_data.json",
32
+ "r",
33
+ encoding="utf-8"
34
+ ) as f:
35
+
36
+ quiz_data = json.load(f)
37
+
38
+ # Daily stable random
39
+ random.seed(str(date.today()))
40
+
41
+ daily_questions = random.sample(
42
+ quiz_data,
43
+ 3
44
+ )
45
+
46
+ # =========================
47
+ # STREAK SYSTEM
48
+ # =========================
49
+
50
+ def update_streak(username):
51
+
52
+ user_ref = db.collection(
53
+ "users"
54
+ ).document(username)
55
+
56
+ doc = user_ref.get()
57
+
58
+ today = date.today()
59
+
60
+ if not doc.exists:
61
+
62
+ user_ref.set({
63
+ "streak": 1,
64
+ "best_streak": 1,
65
+ "last_completed": str(today)
66
+ })
67
+
68
+ return 1
69
+
70
+ data = doc.to_dict()
71
+
72
+ last_completed = datetime.strptime(
73
+ data["last_completed"],
74
+ "%Y-%m-%d"
75
+ ).date()
76
+
77
+ streak = data["streak"]
78
+
79
+ if last_completed == today:
80
+ return streak
81
+
82
+ if last_completed == today - timedelta(days=1):
83
+ streak += 1
84
+ else:
85
+ streak = 1
86
+
87
+ best = max(
88
+ streak,
89
+ data.get("best_streak", 1)
90
+ )
91
+
92
+ user_ref.update({
93
+ "streak": streak,
94
+ "best_streak": best,
95
+ "last_completed": str(today)
96
+ })
97
+
98
+ return streak
99
+
100
+ # =========================
101
+ # VOCAB TRACKER
102
+ # =========================
103
+
104
+ def update_vocab(username, word, correct):
105
+
106
+ vocab_ref = (
107
+ db.collection("users")
108
+ .document(username)
109
+ .collection("vocab")
110
+ .document(word)
111
+ )
112
+
113
+ doc = vocab_ref.get()
114
+
115
+ if not doc.exists:
116
+
117
+ vocab_ref.set({
118
+ "correct": 0,
119
+ "wrong": 0,
120
+ "mastered": False
121
+ })
122
+
123
+ data = vocab_ref.get().to_dict()
124
+
125
+ correct_count = data["correct"]
126
+ wrong_count = data["wrong"]
127
+
128
+ if correct:
129
+ correct_count += 1
130
+ else:
131
+ wrong_count += 1
132
+
133
+ mastered = correct_count >= 5
134
+
135
+ vocab_ref.set({
136
+ "correct": correct_count,
137
+ "wrong": wrong_count,
138
+ "mastered": mastered
139
+ })
140
+
141
+ # =========================
142
+ # QUIZ LOGIC
143
+ # =========================
144
+
145
+ def grade_quiz(
146
+ username,
147
+ q1,
148
+ q2,
149
+ q3
150
+ ):
151
+
152
+ answers = [q1, q2, q3]
153
+
154
+ score = 0
155
+
156
+ for i, q in enumerate(daily_questions):
157
+
158
+ correct = answers[i] == q["answer"]
159
+
160
+ if correct:
161
+ score += 1
162
+
163
+ update_vocab(
164
+ username,
165
+ q["word"],
166
+ correct
167
+ )
168
+
169
+ streak = update_streak(username)
170
+
171
+ return (
172
+ f"🔥 Streak: {streak} days\n"
173
+ f"✅ Score: {score}/3"
174
+ )
175
+
176
+ # =========================
177
+ # UI
178
+ # =========================
179
+
180
+ with gr.Blocks() as demo:
181
+
182
+ gr.Markdown(
183
+ "# 🇷🇺 Russian Learning Hub"
184
+ )
185
+
186
+ gr.Markdown(
187
+ "## 🔥 Daily Quiz"
188
+ )
189
+
190
+ username = gr.Textbox(
191
+ label="Username"
192
+ )
193
+
194
+ q_inputs = []
195
+
196
+ for q in daily_questions:
197
+
198
+ radio = gr.Radio(
199
+ choices=q["choices"],
200
+ label=q["question"]
201
+ )
202
+
203
+ q_inputs.append(radio)
204
+
205
+ output = gr.Textbox(
206
+ label="Result"
207
+ )
208
+
209
+ submit_btn = gr.Button(
210
+ "Submit Quiz"
211
+ )
212
+
213
+ submit_btn.click(
214
+ grade_quiz,
215
+ inputs=[username] + q_inputs,
216
+ outputs=output
217
+ )
218
+
219
+ demo.launch(share=True)
firebase_key.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "type": "service_account",
3
+ "project_id": "russian-learning-hub",
4
+ "private_key_id": "bc7d8472526ec94f4d73c04981cd4bffd2e2c5cb",
5
+ "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCdrZBcgVarQWGN\nmaNyXoYMCn80QrI2AZv62U0yRI/BJgGVN/6FP+CUwd4WE70yNN6/wYK55KJOgAxm\nTjqx+MPjnrtMlFZikSyegYLnTW9IUns9hjWQwHA+yRFKP0KMXLxuZ1cdhEMpPQmk\nhlMTiCs48b97vLSSDj+BsYVgo4INjsk57O5nM7fywZEz+/62ieLVZIuquosMEHEf\nEWOPpJZaKTAULXVYGoOvx5wIUrPXaRfCs6BB7+b6dt3ejOitWr0LEWkP/Mi8Rnar\nqB5Re9didmDPKUat31a/J7waPyLXNqQncwimjNJ10bMq3zrZ4jHiGZ3HvfZCV+Ez\nLXMDquptAgMBAAECggEAFOJXb80otcuV2GusSJpo7kDYqssXsAwEBRRRg3ItySMX\nzBQLx8nXXNSVrf5kzXjPtP20KxtzfOq8WbOMViSxC12riJ/QFkOMsZzNQgYRUnas\nQJCdWSQH6eT3P4qD7bPduFDDKtNpEtX1CD/LUpezQ9pPJpwunXa6JhslY5Ccid91\nnXpvVie8Zln4NRLiJG5RqynxF9LhJ03nRB3XJ/NKM9lMf11UbavXgRac/456w0T/\nSu67YAUGsD4oDqw6GyyfOu7TmgP3vm1GXeSuP4R3sXPQPKLS0zU0nGNgRlZ+nGbD\nrG2x0JFlHlAmmb7pj+quZvDMaPz5qvuqtBfUxwvP2QKBgQDOWdVVqyS63okFuPwk\nhwfNswgtGduUt1aYXVwJo9Rbb3exF0II6kCFxey7sWqXwikb+V13wZ/4yehcTE0h\no4sNdDkLDm7X7vvQjnwDPI80qj1yMP6FNUi4Yf0GxU/9aoFIT2uLRRJ/0WuWolmM\nVNthYd8rYez+G+muBty4YacY+QKBgQDDnbnNUQ0bWaZC+PcpE06stcgpz6sI0TI/\nJzPqoYgLGxNIN0/dj7F6pUZSRTZE+zzL6k7i/Ot7KXnJTw6zmTXmxIE/Acu0WI+O\nY84HXD62s/XnyNVH8KK3POU0fvmLMNA5VvIUH2MMRmJpqJZV872c2VkSU19NOMHk\ns4sqEqpOFQKBgQDNog4LciKHKk6H6mEykXGAViIWt8bvO4jLC3Y1kRKFD97KFnBS\n7AXiiWuxW0rq8qz+2JCBT+34AlVQ7SSMGiru/FwAHaDuBJTir6r7mrTm+aOEETkC\nTCgsvlFlFunwkttE0QhN4EZgI7TAhwcP5lw8fkjkNZDzZaOILgR0pbPcGQKBgHty\nN+T39zuBUckF8IP9aTLY7N5l7Vt9GSZ9iOfS1FWd2odCUKZTnf71+fDFOMBDhFRz\nIyFf1wM8Y1zFBVQVpcxhyeaHLZQ8JywGk+hVMEaAPvjs5puloincxhBg6P4L6ful\ngNNuE0WVzVk8SNMpJEmtZ+aGsqe637GCFJqSeOMZAoGAFgpE1DINA1IamCCqpDk9\nxvsXJWm5iQPFd6RI3t9gkODX0sTsNtaBHciyUueTgiT6VZQKcy1ceKbqibYxKv4q\nHIaw/mPirbZvAEknkE/ESYPm6UO1Y16Y6o420/vBJJLC3IX6MYbtFk3vEml3+6Ev\nVtAXdZ4lR5WhHlhLN9LqVvI=\n-----END PRIVATE KEY-----\n",
6
+ "client_email": "firebase-adminsdk-fbsvc@russian-learning-hub.iam.gserviceaccount.com",
7
+ "client_id": "115016420012463420142",
8
+ "auth_uri": "https://accounts.google.com/o/oauth2/auth",
9
+ "token_uri": "https://oauth2.googleapis.com/token",
10
+ "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
11
+ "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fbsvc%40russian-learning-hub.iam.gserviceaccount.com",
12
+ "universe_domain": "googleapis.com"
13
+ }
quiz_data.json ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "question": "дом nghĩa là gì?",
4
+ "choices": ["house", "book", "water"],
5
+ "answer": "house",
6
+ "word": "дом"
7
+ },
8
+
9
+ {
10
+ "question": "книга nghĩa là gì?",
11
+ "choices": ["book", "car", "food"],
12
+ "answer": "book",
13
+ "word": "книга"
14
+ },
15
+
16
+ {
17
+ "question": "Я ___ книгу",
18
+ "choices": ["читаю", "читать", "читал"],
19
+ "answer": "читаю",
20
+ "word": "читать"
21
+ },
22
+
23
+ {
24
+ "question": "работа nghĩa là gì?",
25
+ "choices": ["work", "school", "paper"],
26
+ "answer": "work",
27
+ "word": "работа"
28
+ },
29
+
30
+ {
31
+ "question": "хороший nghĩa là gì?",
32
+ "choices": ["good", "bad", "fast"],
33
+ "answer": "good",
34
+ "word": "хороший"
35
+ }
36
+ ]
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio
2
+ firebase-admin