|
|
import gradio as gr |
|
|
import pandas as pd |
|
|
import random |
|
|
import os |
|
|
from datetime import datetime |
|
|
import requests |
|
|
|
|
|
|
|
|
try: |
|
|
from groq import Groq |
|
|
except ImportError: |
|
|
os.system('pip install groq') |
|
|
from groq import Groq |
|
|
|
|
|
groq_api_key = os.getenv("groq_key") |
|
|
notion_api_key = os.getenv("Notion_API_Key") |
|
|
notion_db_id = os.getenv("Notion_DB_ID") |
|
|
|
|
|
if not groq_api_key: |
|
|
raise ValueError("'groq_key' is missing. Please set the API key.") |
|
|
if not notion_api_key or not notion_db_id: |
|
|
raise ValueError("Notion API Key or Database ID is missing.") |
|
|
|
|
|
client = Groq(api_key=groq_api_key) |
|
|
|
|
|
|
|
|
vocabulary = [] |
|
|
matches = {} |
|
|
score = 0 |
|
|
|
|
|
def parse_csv(file): |
|
|
global vocabulary |
|
|
try: |
|
|
df = pd.read_csv(file.name, header=None) |
|
|
vocabulary = [{'word': row[0], 'definition': row[1]} for _, row in df.iterrows()] |
|
|
return "CSV file successfully uploaded! Ready to start the quiz!" |
|
|
except Exception as e: |
|
|
return f"Error parsing file: {e}" |
|
|
|
|
|
def add_word(word, definition): |
|
|
global vocabulary |
|
|
if word and definition: |
|
|
vocabulary.append({'word': word.strip(), 'definition': definition.strip()}) |
|
|
return f'Word "{word}" added to vocabulary!' |
|
|
return "Please provide both word and definition." |
|
|
|
|
|
def start_quiz(): |
|
|
if not vocabulary: |
|
|
return "Vocabulary is empty. Please upload a file or add words manually.", [], [] |
|
|
|
|
|
shuffle_vocabulary = vocabulary[:] |
|
|
random.shuffle(shuffle_vocabulary) |
|
|
words = [item['word'] for item in shuffle_vocabulary] |
|
|
definitions = [item['definition'] for item in shuffle_vocabulary] |
|
|
random.shuffle(definitions) |
|
|
return "Quiz started! Match words to definitions.", words, definitions |
|
|
|
|
|
def check_match(word, definition): |
|
|
global score |
|
|
for item in vocabulary: |
|
|
if item['word'] == word and item['definition'] == definition: |
|
|
score += 1 |
|
|
return f"Correct! '{word}' matches its definition. Total score: {score}", True |
|
|
return f"Incorrect! '{word}' does not match the definition.", False |
|
|
|
|
|
def reset_quiz(): |
|
|
global vocabulary, matches, score |
|
|
matches = {} |
|
|
score = 0 |
|
|
return "Quiz reset! Ready for a new start." |
|
|
|
|
|
|
|
|
def chat_with_groq(input_text, chat_history): |
|
|
try: |
|
|
messages = [ |
|
|
{"role": "system", "content": ( |
|
|
"You are an English dictionary and quiz designer tutor. When given a vocabulary word, " |
|
|
"you should provide the following:\n(1) A concise definition (max 50 words)\n(2) A sample sentence (max 20 words)." |
|
|
)} |
|
|
] |
|
|
messages.extend( |
|
|
{"role": "user", "content": user_msg} if idx % 2 == 0 else {"role": "assistant", "content": assistant_msg} |
|
|
for idx, (user_msg, assistant_msg) in enumerate(chat_history) |
|
|
) |
|
|
messages.append({"role": "user", "content": input_text}) |
|
|
|
|
|
response = client.chat.completions.create( |
|
|
model="llama-3.3-70b-versatile", |
|
|
messages=messages, |
|
|
temperature=1, |
|
|
max_tokens=1024, |
|
|
) |
|
|
return response.choices[0].message.content |
|
|
except Exception as e: |
|
|
return f"Error: {e}" |
|
|
|
|
|
def log_to_notion(name, user_input, bot_response): |
|
|
url = "https://api.notion.com/v1/pages" |
|
|
headers = { |
|
|
"Authorization": f"Bearer {notion_api_key}", |
|
|
"Content-Type": "application/json", |
|
|
"Notion-Version": "2022-06-28" |
|
|
} |
|
|
data = { |
|
|
"parent": {"database_id": notion_db_id}, |
|
|
"properties": { |
|
|
"Name": {"title": [{"text": {"content": name}}]}, |
|
|
"Timestamp": {"date": {"start": datetime.now().isoformat()}}, |
|
|
"User Input": {"rich_text": [{"text": {"content": user_input}}]}, |
|
|
"Bot Response": {"rich_text": [{"text": {"content": bot_response}}]} |
|
|
} |
|
|
} |
|
|
requests.post(url, headers=headers, json=data) |
|
|
|
|
|
|
|
|
with gr.Blocks() as app: |
|
|
with gr.Row(): |
|
|
gr.Markdown("# 📚 Personal English Vocabulary App & Chatbot") |
|
|
|
|
|
|
|
|
with gr.Tab("Upload Vocabulary"): |
|
|
with gr.Row(): |
|
|
file_input = gr.File(label="Upload Vocabulary CSV") |
|
|
file_output = gr.Textbox(label="Upload Status") |
|
|
upload_button = gr.Button("Upload") |
|
|
upload_button.click(parse_csv, inputs=file_input, outputs=file_output) |
|
|
|
|
|
with gr.Tab("Add Vocabulary"): |
|
|
word_input = gr.Textbox(label="Word") |
|
|
definition_input = gr.Textbox(label="Definition") |
|
|
add_button = gr.Button("Add Word") |
|
|
add_status = gr.Textbox(label="Status") |
|
|
add_button.click(add_word, inputs=[word_input, definition_input], outputs=add_status) |
|
|
|
|
|
with gr.Tab("Quiz"): |
|
|
quiz_status = gr.Textbox(label="Status") |
|
|
start_button = gr.Button("Start Quiz") |
|
|
words_list = gr.Dropdown(label="Select Word", choices=[]) |
|
|
definitions_list = gr.Dropdown(label="Select Definition", choices=[]) |
|
|
check_button = gr.Button("Check Match") |
|
|
match_status = gr.Textbox(label="Result") |
|
|
|
|
|
def refresh_quiz(): |
|
|
quiz_message, words, definitions = start_quiz() |
|
|
return quiz_message, gr.update(choices=words), gr.update(choices=definitions) |
|
|
|
|
|
start_button.click(refresh_quiz, inputs=None, outputs=[quiz_status, words_list, definitions_list]) |
|
|
check_button.click(check_match, inputs=[words_list, definitions_list], outputs=match_status) |
|
|
|
|
|
with gr.Tab("Vocabulary Chatbot"): |
|
|
gr.Markdown("## AI-Powered Vocabulary Chatbot") |
|
|
chatbot = gr.Chatbot() |
|
|
user_input = gr.Textbox(label="Ask about a word or usage:") |
|
|
name_input = gr.Textbox(label="Name", placeholder="Enter your name") |
|
|
send_button = gr.Button("Submit") |
|
|
chat_history = gr.State([]) |
|
|
|
|
|
def respond(name, message, chat_history): |
|
|
bot_response = chat_with_groq(message, chat_history) |
|
|
chat_history.append((message, bot_response)) |
|
|
log_to_notion(name, message, bot_response) |
|
|
return chat_history, "" |
|
|
|
|
|
send_button.click(respond, [name_input, user_input, chat_history], [chatbot, user_input]) |
|
|
|
|
|
with gr.Row(): |
|
|
reset_button = gr.Button("Reset Quiz") |
|
|
reset_status = gr.Textbox(label="Reset Status") |
|
|
reset_button.click(reset_quiz, inputs=None, outputs=reset_status) |
|
|
|
|
|
app.launch() |
|
|
|