Spaces:
Sleeping
Sleeping
import streamlit as st | |
import random | |
import json | |
import sqlite3 | |
# Database setup | |
DB_PATH = "shared_state.db" | |
def init_db(): | |
"""Initialize the SQLite database with required tables.""" | |
with sqlite3.connect(DB_PATH) as conn: | |
cursor = conn.cursor() | |
cursor.execute( | |
""" | |
CREATE TABLE IF NOT EXISTS state ( | |
id INTEGER PRIMARY KEY, | |
keys TEXT, | |
completed_words TEXT, | |
current_index INTEGER | |
) | |
""" | |
) | |
# Initialize with default state if empty | |
cursor.execute("SELECT COUNT(*) FROM state") | |
if cursor.fetchone()[0] == 0: | |
# Populate the keys with words from the JSON file | |
with open("./data/words_list.json", "r") as f: | |
data = json.load(f) | |
default_keys = list(data.keys()) | |
random.shuffle(default_keys) | |
default_state = { | |
"keys": default_keys, | |
"completed_words": {"skip": [], "correct": [], "incorrect": []}, | |
"current_index": 0, | |
} | |
cursor.execute( | |
"INSERT INTO state (keys, completed_words, current_index) VALUES (?, ?, ?)", | |
( | |
json.dumps(default_state["keys"]), | |
json.dumps(default_state["completed_words"]), | |
default_state["current_index"], | |
), | |
) | |
conn.commit() | |
def get_state(): | |
"""Retrieve the shared state from the database.""" | |
with sqlite3.connect(DB_PATH) as conn: | |
cursor = conn.cursor() | |
cursor.execute("SELECT keys, completed_words, current_index FROM state") | |
row = cursor.fetchone() | |
return { | |
"keys": json.loads(row[0]), | |
"completed_words": json.loads(row[1]), | |
"current_index": row[2], | |
} | |
def update_state(new_state): | |
"""Update the shared state in the database.""" | |
with sqlite3.connect(DB_PATH) as conn: | |
cursor = conn.cursor() | |
cursor.execute( | |
""" | |
UPDATE state | |
SET keys = ?, completed_words = ?, current_index = ? | |
""", | |
( | |
json.dumps(new_state["keys"]), | |
json.dumps(new_state["completed_words"]), | |
new_state["current_index"], | |
), | |
) | |
conn.commit() | |
# Initialize the database | |
init_db() | |
# Load the words list | |
try: | |
with open("./data/words_list.json", "r") as f: | |
data = json.load(f) | |
except FileNotFoundError: | |
st.error( | |
"Error: The file 'words_list.json' was not found in the './data' directory." | |
) | |
st.stop() | |
except json.JSONDecodeError: | |
st.error( | |
"Error: Failed to decode 'words_list.json'. Ensure it is a valid JSON file." | |
) | |
st.stop() | |
# Fetch the shared state | |
state = get_state() | |
# Functions | |
def draw_word(): | |
"""Get the current word and move to the next.""" | |
if state["current_index"] < len(state["keys"]): | |
curr_word = state["keys"][state["current_index"]] | |
return curr_word | |
else: | |
return None | |
def game_play(curr_word, action): | |
"""Update the completed_words dictionary and move to the next word.""" | |
if curr_word: | |
state["completed_words"][action].append(curr_word) | |
state["current_index"] += 1 | |
# Avoid duplicates in the list | |
state["keys"] = list(set(state["keys"]) - set(state["completed_words"][action])) | |
update_state(state) | |
def complete_round(): | |
"""Complete the round and reset the state.""" | |
state["keys"].extend(state["completed_words"]["skip"]) | |
random.shuffle(state["keys"]) | |
state["completed_words"] = {"skip": [], "correct": [], "incorrect": []} | |
state["current_index"] = 0 | |
update_state(state) | |
# UI | |
st.title("Word List Game") | |
st.markdown( | |
"Manage your words by marking them as correct, incorrect, or skipping them. Complete the round to reset!" | |
) | |
# Display scores | |
scores = { | |
"correct": len(state["completed_words"]["correct"]), | |
"incorrect": len(state["completed_words"]["incorrect"]), | |
"skip": len(state["completed_words"]["skip"]), | |
} | |
col1, col2, col3 = st.columns(3) | |
col1.metric("\u2705 Correct", scores["correct"]) | |
col2.metric("\u274C Incorrect", scores["incorrect"]) | |
col3.metric("\u23ED Skipped", scores["skip"]) | |
# Draw a word | |
curr_word = draw_word() | |
if curr_word: | |
st.header(f"Word: {curr_word}") | |
st.subheader("Values:") | |
for value in data[curr_word]: | |
st.text(value) | |
# Buttons for actions | |
col1, col2, col3 = st.columns(3) | |
with col1: | |
if st.button("Skip"): | |
game_play(curr_word, "skip") | |
with col2: | |
if st.button("Correct"): | |
game_play(curr_word, "correct") | |
with col3: | |
if st.button("Incorrect"): | |
game_play(curr_word, "incorrect") | |
# Handle no more words scenario | |
if not curr_word: | |
st.warning("No more words! Please complete the round.") | |
# Button to complete the round | |
if st.button("Complete Round"): | |
complete_round() | |
st.success("Round completed! Words reset.") | |