Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -3,7 +3,7 @@ import os
|
|
| 3 |
import datetime
|
| 4 |
import json
|
| 5 |
import tempfile
|
| 6 |
-
import datetime
|
| 7 |
|
| 8 |
|
| 9 |
# === Import Groq API ===
|
|
@@ -203,6 +203,7 @@ progress_data = {
|
|
| 203 |
"incorrect_count": 0,
|
| 204 |
"streak": 0,
|
| 205 |
"badges": []
|
|
|
|
| 206 |
}
|
| 207 |
# added part
|
| 208 |
def reset_daily_progress():
|
|
@@ -213,23 +214,43 @@ def reset_daily_progress():
|
|
| 213 |
"incorrect_count": 0,
|
| 214 |
"streak": 0,
|
| 215 |
"badges": []
|
|
|
|
| 216 |
})
|
| 217 |
|
| 218 |
-
|
| 219 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 220 |
today = str(datetime.date.today())
|
| 221 |
-
|
| 222 |
-
# Reset if new day
|
| 223 |
if progress_data["today"] != today:
|
| 224 |
reset_daily_progress()
|
| 225 |
-
# progress_data.update({
|
| 226 |
-
# "today": today,
|
| 227 |
-
# "correct_count": 0,
|
| 228 |
-
# "incorrect_count": 0,
|
| 229 |
-
# "streak": 0,
|
| 230 |
-
# "badges": []
|
| 231 |
-
# })
|
| 232 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 233 |
|
| 234 |
if is_correct:
|
| 235 |
progress_data["correct_count"] += 1
|
|
@@ -240,40 +261,28 @@ def update_daily_stats(is_correct: bool):
|
|
| 240 |
progress_data["incorrect_count"] += 1
|
| 241 |
progress_data["streak"] = 0
|
| 242 |
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
def evaluate_sentence(user_sentence: str) -> bool:
|
| 246 |
"""
|
| 247 |
-
|
| 248 |
-
Style suggestions (informal/difficult words) do not count as incorrect.
|
| 249 |
-
|
| 250 |
-
# TODO: Replace this with your grammar-checking logic
|
| 251 |
"""
|
| 252 |
-
|
| 253 |
-
is_correct =
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
update_daily_stats(is_correct)
|
| 257 |
-
|
| 258 |
-
return is_correct
|
| 259 |
|
| 260 |
def get_progress_summary():
|
| 261 |
-
"""Return a formatted summary for Gradio UI."""
|
| 262 |
today = progress_data["today"]
|
| 263 |
-
correct = progress_data["correct_count"]
|
| 264 |
-
incorrect = progress_data["incorrect_count"]
|
| 265 |
-
streak = progress_data["streak"]
|
| 266 |
badges = ", ".join(progress_data["badges"]) if progress_data["badges"] else "None yet"
|
| 267 |
-
|
| 268 |
-
summary = (
|
| 269 |
f"π
Date: {today}\n"
|
| 270 |
-
f"β
Correct: {
|
| 271 |
-
f"β Incorrect: {
|
| 272 |
-
f"π₯ Current Streak: {streak}\n"
|
| 273 |
f"π
Badges: {badges}"
|
| 274 |
)
|
| 275 |
-
return summary
|
| 276 |
-
|
| 277 |
|
| 278 |
|
| 279 |
# # === Inside Gradio UI ===
|
|
@@ -293,7 +302,7 @@ with gr.Blocks() as demo:
|
|
| 293 |
|
| 294 |
with gr.Tab("Practice"):
|
| 295 |
with gr.Row():
|
| 296 |
-
text_input = gr.Textbox(label="Type in English", placeholder="Write something...")
|
| 297 |
mic_input = gr.Audio(sources=["microphone"], type="filepath")
|
| 298 |
|
| 299 |
output_text = gr.Textbox(label="AI Response")
|
|
|
|
| 3 |
import datetime
|
| 4 |
import json
|
| 5 |
import tempfile
|
| 6 |
+
import datetime, hashlib
|
| 7 |
|
| 8 |
|
| 9 |
# === Import Groq API ===
|
|
|
|
| 203 |
"incorrect_count": 0,
|
| 204 |
"streak": 0,
|
| 205 |
"badges": []
|
| 206 |
+
"last_submission_id": None, # for dedupe
|
| 207 |
}
|
| 208 |
# added part
|
| 209 |
def reset_daily_progress():
|
|
|
|
| 214 |
"incorrect_count": 0,
|
| 215 |
"streak": 0,
|
| 216 |
"badges": []
|
| 217 |
+
"last_submission_id": None,
|
| 218 |
})
|
| 219 |
|
| 220 |
+
# ---- 1) Make correctness explicitly boolean ----
|
| 221 |
+
def normalize_is_correct(raw):
|
| 222 |
+
"""
|
| 223 |
+
Convert output of grammar_checker(...) to a strict boolean for GRAMMAR only.
|
| 224 |
+
Adjust these rules to match your checker.
|
| 225 |
+
"""
|
| 226 |
+
if isinstance(raw, bool):
|
| 227 |
+
return raw
|
| 228 |
+
if isinstance(raw, dict):
|
| 229 |
+
# prefer a clear key from your checker
|
| 230 |
+
if "grammar_ok" in raw:
|
| 231 |
+
return bool(raw["grammar_ok"])
|
| 232 |
+
if "errors" in raw:
|
| 233 |
+
return len(raw["errors"]) == 0
|
| 234 |
+
if isinstance(raw, (list, tuple, set)):
|
| 235 |
+
# treat as list of grammar errors
|
| 236 |
+
return len(raw) == 0
|
| 237 |
+
if isinstance(raw, str):
|
| 238 |
+
s = raw.strip().lower()
|
| 239 |
+
# map typical responses from LLMs/tools
|
| 240 |
+
return s in ("true", "correct", "ok", "no errors", "no error", "grammatically correct")
|
| 241 |
+
# last resort
|
| 242 |
+
return bool(raw)
|
| 243 |
+
|
| 244 |
+
# ---- 2) Update stats (with dedupe + badge) ----
|
| 245 |
+
def update_daily_stats(is_correct: bool, submission_id: str = None):
|
| 246 |
today = str(datetime.date.today())
|
|
|
|
|
|
|
| 247 |
if progress_data["today"] != today:
|
| 248 |
reset_daily_progress()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 249 |
|
| 250 |
+
# de-dupe: if the same submission hits the function twice, ignore the second
|
| 251 |
+
if submission_id and progress_data.get("last_submission_id") == submission_id:
|
| 252 |
+
return
|
| 253 |
+
progress_data["last_submission_id"] = submission_id
|
| 254 |
|
| 255 |
if is_correct:
|
| 256 |
progress_data["correct_count"] += 1
|
|
|
|
| 261 |
progress_data["incorrect_count"] += 1
|
| 262 |
progress_data["streak"] = 0
|
| 263 |
|
| 264 |
+
# ---- 3) Evaluate exactly once per submission ----
|
| 265 |
+
def evaluate_sentence(user_sentence: str):
|
|
|
|
| 266 |
"""
|
| 267 |
+
Call your checker ONCE, normalize to boolean, update stats ONCE.
|
|
|
|
|
|
|
|
|
|
| 268 |
"""
|
| 269 |
+
raw_result = grammar_checker(user_sentence) # <- your existing checker
|
| 270 |
+
is_correct = normalize_is_correct(raw_result) # <- strict boolean
|
| 271 |
+
# robust per-input dedupe id (same sentence => same id; adjust if you want to allow repeats)
|
| 272 |
+
submission_id = hashlib.sha1(user_sentence.strip().encode("utf-8")).hexdigest()
|
| 273 |
+
update_daily_stats(is_correct, submission_id=submission_id)
|
| 274 |
+
return is_correct, raw_result
|
|
|
|
| 275 |
|
| 276 |
def get_progress_summary():
|
|
|
|
| 277 |
today = progress_data["today"]
|
|
|
|
|
|
|
|
|
|
| 278 |
badges = ", ".join(progress_data["badges"]) if progress_data["badges"] else "None yet"
|
| 279 |
+
return (
|
|
|
|
| 280 |
f"π
Date: {today}\n"
|
| 281 |
+
f"β
Correct: {progress_data['correct_count']}\n"
|
| 282 |
+
f"β Incorrect: {progress_data['incorrect_count']}\n"
|
| 283 |
+
f"π₯ Current Streak: {progress_data['streak']}\n"
|
| 284 |
f"π
Badges: {badges}"
|
| 285 |
)
|
|
|
|
|
|
|
| 286 |
|
| 287 |
|
| 288 |
# # === Inside Gradio UI ===
|
|
|
|
| 302 |
|
| 303 |
with gr.Tab("Practice"):
|
| 304 |
with gr.Row():
|
| 305 |
+
text_input = gr.Textbox(label="Type in English", placeholder="Write something...",submit=False)
|
| 306 |
mic_input = gr.Audio(sources=["microphone"], type="filepath")
|
| 307 |
|
| 308 |
output_text = gr.Textbox(label="AI Response")
|