| | 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() |
| |
|