diff --git a/NINJA CODERS/.env b/NINJA CODERS/.env
new file mode 100644
index 000000000..db41e6067
--- /dev/null
+++ b/NINJA CODERS/.env
@@ -0,0 +1,2 @@
+GOOGLE_API_KEY = "AIzaSyAbUsuvTBUugpPGe1t0gyrNrbdnqa7bEJg"
+HUGGINGFACE_API_TOKEN = "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"
diff --git a/NINJA CODERS/Pitch Deck - Languito.ai.pdf b/NINJA CODERS/Pitch Deck - Languito.ai.pdf
new file mode 100644
index 000000000..e0df0b080
Binary files /dev/null and b/NINJA CODERS/Pitch Deck - Languito.ai.pdf differ
diff --git a/NINJA CODERS/app/app.py b/NINJA CODERS/app/app.py
new file mode 100644
index 000000000..26077cbdd
--- /dev/null
+++ b/NINJA CODERS/app/app.py
@@ -0,0 +1,19 @@
+import streamlit as st
+
+
+pages = {
+ "Principal": [
+ st.Page("pages/home/main.py", title="๐ Home "),
+ ],
+ "Activities": [
+ st.Page("pages/features/quiz.py", title="๐ Quiz "),
+ st.Page("pages/features/block_quiz.py", title="๐ Block Quiz"),
+ st.Page("pages/features/languito_chat.py", title="๐ฌ Chat"),
+ st.Page("pages/features/languito_translator.py", title="๐ Translator"),
+ st.Page("pages/features/text2speech.py", title="๐ฃ Prononciation"),
+ st.Page("pages/features/languito_dictionnary.py", title="๐ Dictionnary"),
+ ],
+}
+
+pg = st.navigation(pages)
+pg.run()
\ No newline at end of file
diff --git a/NINJA CODERS/app/images/banner.png b/NINJA CODERS/app/images/banner.png
new file mode 100644
index 000000000..c36dd1fee
Binary files /dev/null and b/NINJA CODERS/app/images/banner.png differ
diff --git a/NINJA CODERS/app/images/logo.png b/NINJA CODERS/app/images/logo.png
new file mode 100644
index 000000000..ede5d2c99
Binary files /dev/null and b/NINJA CODERS/app/images/logo.png differ
diff --git a/NINJA CODERS/app/images/workflow.png b/NINJA CODERS/app/images/workflow.png
new file mode 100644
index 000000000..e9cb7bf36
Binary files /dev/null and b/NINJA CODERS/app/images/workflow.png differ
diff --git a/NINJA CODERS/app/pages/dataset/Multimodal RAG.pdf b/NINJA CODERS/app/pages/dataset/Multimodal RAG.pdf
new file mode 100644
index 000000000..d27418e3a
Binary files /dev/null and b/NINJA CODERS/app/pages/dataset/Multimodal RAG.pdf differ
diff --git a/NINJA CODERS/app/pages/dataset/imagenet_b_darija.pdf b/NINJA CODERS/app/pages/dataset/imagenet_b_darija.pdf
new file mode 100644
index 000000000..b4b437029
Binary files /dev/null and b/NINJA CODERS/app/pages/dataset/imagenet_b_darija.pdf differ
diff --git a/NINJA CODERS/app/pages/dataset/valid_1.pdf b/NINJA CODERS/app/pages/dataset/valid_1.pdf
new file mode 100644
index 000000000..7d107a52b
Binary files /dev/null and b/NINJA CODERS/app/pages/dataset/valid_1.pdf differ
diff --git a/NINJA CODERS/app/pages/features/block_quiz.py b/NINJA CODERS/app/pages/features/block_quiz.py
new file mode 100644
index 000000000..8bf603da1
--- /dev/null
+++ b/NINJA CODERS/app/pages/features/block_quiz.py
@@ -0,0 +1,103 @@
+import streamlit as st
+import random
+from gtts import gTTS
+from io import BytesIO
+
+# Simple sentence generator
+def generate_sentence():
+ templates = [
+ "The {adjective} {noun} {verb} {adverb}.",
+ "{subject} {verb} {object} {adverb}.",
+ "In the {place}, {subject} {verb} {object}.",
+ "{timeframe}, {subject} will {verb} {object}.",
+ "{subject} {verb} {object} because {reason}."
+ ]
+
+ words = {
+ "adjective": ["happy", "sad", "excited", "curious", "friendly", "brave"],
+ "noun": ["cat", "dog", "bird", "child", "teacher", "student"],
+ "verb": ["runs", "jumps", "sings", "reads", "writes", "plays"],
+ "adverb": ["quickly", "slowly", "loudly", "quietly", "carefully", "happily"],
+ "subject": ["The boy", "The girl", "The teacher", "The dog", "My friend", "The student"],
+ "object": ["the ball", "a book", "the guitar", "homework", "a game", "the puzzle"],
+ "place": ["park", "school", "library", "garden", "playground", "museum"],
+ "timeframe": ["Tomorrow", "Next week", "In the future", "Soon", "Later today"],
+ "reason": ["it's fun", "it's important", "they enjoy it", "it's a hobby", "it's challenging"]
+ }
+
+ template = random.choice(templates)
+ sentence = template.format(**{k: random.choice(v) for k, v in words.items()})
+ return sentence
+
+# Function to scramble a sentence into words and add tricky words
+def scramble_sentence(sentence):
+ words = sentence.lower().split()
+ scrambled = words.copy()
+ random.shuffle(scrambled)
+
+ # Add tricky words
+ tricky_words = ["however", "although", "nevertheless", "suddenly", "meanwhile"]
+ scrambled.extend(random.sample(tricky_words, 2))
+ random.shuffle(scrambled)
+
+ return words, scrambled
+
+# Function to generate audio for the sentence
+def text_to_speech_quiz(sentence):
+ tts = gTTS(text=sentence, lang="en", slow=False)
+ buf = BytesIO()
+ tts.write_to_fp(buf)
+ buf.seek(0)
+ return buf
+
+# Streamlit setup
+st.title("๐ค๏ธ Languito Block Quiz!")
+st.markdown("**Listen to the audio and arrange the blocks in the correct order. Watch out for tricky words!**")
+
+# Generate or retrieve a sentence
+if "original_sentence" not in st.session_state:
+ st.session_state.original_sentence = generate_sentence()
+
+# Generate or retrieve scrambled words
+if "correct_words" not in st.session_state or "scrambled_words" not in st.session_state:
+ st.session_state.correct_words, st.session_state.scrambled_words = scramble_sentence(st.session_state.original_sentence)
+
+# Play the audio
+audio_bytes = text_to_speech_quiz(st.session_state.original_sentence)
+st.audio(audio_bytes, format="audio/mp3")
+
+# Display scrambled words as buttons
+st.write("### Arrange the words:")
+selected_order = st.empty()
+
+selected_words = st.session_state.get("selected_words", [])
+
+# Show buttons for scrambled words
+cols = st.columns(4)
+for i, word in enumerate(st.session_state.scrambled_words):
+ if word not in selected_words:
+ if cols[i % 4].button(word, key=word):
+ selected_words.append(word)
+ st.session_state.selected_words = selected_words
+
+# Display selected words
+st.write("### Your sentence:")
+st.write(" ".join(selected_words))
+
+# Check the answer
+if len(selected_words) == len(st.session_state.correct_words):
+ if selected_words == st.session_state.correct_words:
+ st.success("๐ Correct! Great job!")
+ else:
+ st.error("โ Incorrect. The correct sentence was: " + " ".join(st.session_state.correct_words))
+
+ if st.button("New Quiz"):
+ st.session_state.original_sentence = generate_sentence()
+ st.session_state.correct_words, st.session_state.scrambled_words = scramble_sentence(st.session_state.original_sentence)
+ st.session_state.selected_words = []
+
+# Reset state when user wants a new quiz
+if st.button("Reset Quiz"):
+ st.session_state.original_sentence = generate_sentence()
+ st.session_state.correct_words, st.session_state.scrambled_words = scramble_sentence(st.session_state.original_sentence)
+ st.session_state.selected_words = []
\ No newline at end of file
diff --git a/NINJA CODERS/app/pages/features/languito_chat.py b/NINJA CODERS/app/pages/features/languito_chat.py
new file mode 100644
index 000000000..669ece22c
--- /dev/null
+++ b/NINJA CODERS/app/pages/features/languito_chat.py
@@ -0,0 +1,239 @@
+from dotenv import load_dotenv
+import streamlit as st
+import os
+import logging
+import json
+from datetime import datetime
+from langchain import PromptTemplate
+from langchain_google_genai import ChatGoogleGenerativeAI
+from langchain.memory import ConversationBufferMemory
+from langchain.chains import ConversationChain
+import warnings
+
+warnings.filterwarnings("ignore")
+
+# Configure logging
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+class GeminiChat:
+ def __init__(self):
+ load_dotenv()
+ # self.api_key = os.getenv("GOOGLE_API_KEY")
+ try:
+ self.api_key = os.getenv("GOOGLE_API_KEY") or st.secrets["GOOGLE_API_KEY"]
+ except KeyError:
+ st.error("Google API Key is not set. Please provide it as an environment variable or in Streamlit secrets.")
+
+ if not self.api_key:
+ raise ValueError("GOOGLE_API_KEY not found in environment variables")
+
+ self.setup_chat()
+
+ def setup_chat(self) -> None:
+ """Initialize the ChatGoogleGenerativeAI with memory"""
+ try:
+ self.llm = ChatGoogleGenerativeAI(
+ model="gemini-pro",
+ google_api_key=self.api_key,
+ temperature=0.7
+ )
+
+ # Initialize conversation memory
+ self.memory = ConversationBufferMemory()
+
+ # Create conversation chain with memory
+ self.conversation = ConversationChain(
+ llm=self.llm,
+ memory=self.memory,
+ verbose=False
+ )
+
+ self.template = """
+ You are a multilingual language teacher specializing in teaching and translating various languages.
+ your name is Languito.
+ When answering questions:
+ 1. If the user asks for translations, provide accurate translations for the requested languages.
+ 2. If the user asks for grammar rules or language tips, explain them clearly and concisely.
+ 3. If the user asks for examples, provide them with practical, everyday scenarios.
+ 4. If the user asks for a quiz, create a brief, fun language quiz with answers.
+
+ Previous conversation:
+ {history}
+
+ Current Question: {question}
+ if it is no question answer as human
+ Response:
+ """
+ self.prompt_template = PromptTemplate(
+ template=self.template,
+ input_variables=["history", "question"]
+ )
+ except Exception as e:
+ logger.error(f"Error setting up Chat: {str(e)}")
+ raise
+
+ def get_response(self, question: str, chat_history: list) -> str:
+ """Get response from ChatGoogleGenerativeAI with conversation history"""
+ try:
+ # Format chat history
+ history_text = "\n".join([f"{role}: {msg}" for role, msg in chat_history])
+
+ # Get response using the conversation chain
+ response = self.conversation.predict(
+ input=self.prompt_template.format(
+ history=history_text,
+ question=question
+ )
+ )
+ return response
+ except Exception as e:
+ logger.error(f"Error getting response: {str(e)}")
+ raise
+
+class StreamlitApp:
+ def __init__(self):
+ self.setup_page()
+ self.initialize_session_state()
+ self.load_chat_history()
+ self.gemini = GeminiChat()
+
+ def setup_page(self) -> None:
+ """Configure Streamlit page settings"""
+ st.set_page_config(
+ page_title="Language Teacher",
+ page_icon="๐ค",
+ layout="wide"
+ )
+
+ def initialize_session_state(self) -> None:
+ """Initialize session state variables"""
+ if 'chats' not in st.session_state:
+ st.session_state['chats'] = {}
+ if 'current_chat_id' not in st.session_state:
+ st.session_state['current_chat_id'] = None
+ if 'chat_history' not in st.session_state:
+ st.session_state['chat_history'] = []
+
+ def save_chat_history(self) -> None:
+ """Save chat history to a JSON file"""
+ try:
+ data = {
+ 'chats': st.session_state['chats'],
+ 'current_chat_id': st.session_state['current_chat_id']
+ }
+ with open('chat_history.json', 'w') as f:
+ json.dump(data, f)
+ except Exception as e:
+ logger.error(f"Error saving chat history: {str(e)}")
+
+ def load_chat_history(self) -> None:
+ """Load chat history from JSON file"""
+ try:
+ if os.path.exists('chat_history.json'):
+ with open('chat_history.json', 'r') as f:
+ data = json.load(f)
+ st.session_state['chats'] = data.get('chats', {})
+ st.session_state['current_chat_id'] = data.get('current_chat_id')
+ if st.session_state['current_chat_id']:
+ st.session_state['chat_history'] = st.session_state['chats'][st.session_state['current_chat_id']]['messages']
+ except Exception as e:
+ logger.error(f"Error loading chat history: {str(e)}")
+
+ def create_new_chat(self) -> None:
+ """Create a new chat session"""
+ if st.session_state['current_chat_id']:
+ current_chat = st.session_state['chats'][st.session_state['current_chat_id']]
+ if not current_chat['messages']:
+ st.warning("The current chat is empty. Use it before creating a new one.")
+ return
+
+ chat_id = datetime.now().strftime("%Y%m%d_%H%M%S")
+ st.session_state['chats'][chat_id] = {
+ 'name': f"Chat {len(st.session_state['chats']) + 1}",
+ 'messages': []
+ }
+ st.session_state['current_chat_id'] = chat_id
+ st.session_state['chat_history'] = []
+ self.save_chat_history()
+
+ def switch_chat(self, chat_id: str) -> None:
+ """Switch to a different chat session"""
+ st.session_state['current_chat_id'] = chat_id
+ st.session_state['chat_history'] = st.session_state['chats'][chat_id]['messages']
+ self.save_chat_history()
+
+ def display_chat_selector(self) -> None:
+ """Display chat selection sidebar"""
+ with st.sidebar:
+ st.title("Chats")
+
+ if st.button("New Chat", type="secondary", key="new_chat", use_container_width=True):
+ self.create_new_chat()
+ st.rerun()
+
+ for chat_id, chat_data in list(st.session_state['chats'].items()):
+ cols = st.columns([5, 1])
+
+ if cols[0].button(
+ chat_data['name'],
+ key=f"chat_{chat_id}",
+ type="secondary" if chat_id != st.session_state['current_chat_id'] else "primary",
+ use_container_width=True
+ ):
+ self.switch_chat(chat_id)
+ st.rerun()
+
+ if cols[1].button("๐๏ธ", key=f"delete_{chat_id}"):
+ del st.session_state['chats'][chat_id]
+
+ if st.session_state['current_chat_id'] == chat_id:
+ st.session_state['current_chat_id'] = None
+ st.session_state['chat_history'] = []
+
+ self.save_chat_history()
+ st.rerun()
+
+ def display_chat_messages(self) -> None:
+ """Display chat messages"""
+ for role, text in st.session_state['chat_history']:
+ with st.chat_message("user" if role == "You" else "assistant"):
+ st.write(text)
+
+ def main(self) -> None:
+ """Main application logic"""
+ if not st.session_state['chats']:
+ self.create_new_chat()
+
+ self.display_chat_selector()
+
+ st.title("๐ฌ Languito Chat!")
+
+ self.display_chat_messages()
+ if prompt := st.chat_input("Type your message here..."):
+ try:
+ with st.chat_message("user"):
+ st.write(prompt)
+ st.session_state['chat_history'].append(("You", prompt))
+
+ with st.chat_message("assistant"):
+ with st.spinner("Thinking..."):
+ response = self.gemini.get_response(prompt, st.session_state['chat_history'])
+ st.write(response)
+
+ st.session_state['chat_history'].append(("Bot", response))
+
+ if st.session_state['current_chat_id']:
+ st.session_state['chats'][st.session_state['current_chat_id']]['messages'] = st.session_state['chat_history']
+ self.save_chat_history()
+
+ except Exception as e:
+ st.error(f"An error occurred: {str(e)}")
+ logger.error(f"Error in main loop: {str(e)}")
+
+try:
+ app = StreamlitApp()
+ app.main()
+except Exception as e:
+ st.error(f"Application failed to start: {str(e)}")
+ logger.error(f"Application error: {str(e)}")
diff --git a/NINJA CODERS/app/pages/features/languito_dictionnary.py b/NINJA CODERS/app/pages/features/languito_dictionnary.py
new file mode 100644
index 000000000..c782586f5
--- /dev/null
+++ b/NINJA CODERS/app/pages/features/languito_dictionnary.py
@@ -0,0 +1,314 @@
+import streamlit as st
+import google.generativeai as genai
+from dotenv import load_dotenv
+import os
+import warnings
+import json
+from gtts import gTTS
+import base64
+from io import BytesIO
+
+# Load environment variables
+load_dotenv()
+GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
+
+# Configure Gemini API
+genai.configure(api_key=GOOGLE_API_KEY)
+
+# Suppress warnings
+warnings.filterwarnings("ignore")
+
+# Streamlit app configuration
+st.set_page_config(page_title="Languito Dictionnary", page_icon="๐", layout="wide")
+
+# Language mapping for gTTS
+LANGUAGE_CODES = {
+ "English": "en",
+ "French": "fr",
+ "Spanish": "es",
+ "German": "de",
+ "Italian": "it",
+ "Portuguese": "pt",
+ "Chinese": "zh-CN",
+ "Arabic": "ar",
+ "Russian": "ru",
+ "Darija (Moroccan)": "ar" # Using Arabic code as closest approximation
+}
+
+# Title
+st.markdown("""
+
+
+
+
+""", unsafe_allow_html=True)
+
+# Language selection for input (word language)
+input_language = st.selectbox(
+ "Select Language for Word Input:",
+ list(LANGUAGE_CODES.keys())
+)
+
+# Language selection for output (contextual explanation language)
+output_language = st.selectbox(
+ "Select Language for Output:",
+ list(LANGUAGE_CODES.keys())
+)
+
+def text_to_speech(text, lang_code):
+ """
+ Convert text to speech using gTTS
+ """
+ try:
+ # Ensure text is not empty
+ if not text or not text.strip():
+ return None
+
+ tts = gTTS(text=text, lang=lang_code, slow=False)
+ buf = BytesIO()
+ tts.write_to_fp(buf)
+ buf.seek(0)
+ return buf
+ except Exception as e:
+ st.error(f"Audio generation error for '{text}': {str(e)}")
+ return None
+
+def get_audio_player(audio_bytes, key=None):
+ """
+ Create an HTML5 audio player for the generated speech
+ """
+ if audio_bytes is None:
+ return ""
+
+ b64 = base64.b64encode(audio_bytes.getvalue()).decode()
+ # Add unique key to prevent audio player conflicts
+ unique_key = f'key="{key}"' if key else ''
+ return f' '
+
+def generate_audio_for_content(content, lang_code):
+ """
+ Generate audio for different content types
+ """
+ audio_dict = {}
+
+ # Check if content is a list or string
+ if isinstance(content, list):
+ for i, item in enumerate(content):
+ if item and item.strip():
+ audio = text_to_speech(item, lang_code)
+ if audio:
+ audio_dict[f"item_{i}"] = audio
+ elif isinstance(content, str) and content.strip():
+ audio = text_to_speech(content, lang_code)
+ if audio:
+ audio_dict["main"] = audio
+
+ return audio_dict
+
+def get_word_context(word, input_language, output_language):
+ """
+ Retrieve contextual information for a given word using Gemini API
+ """
+ prompt = f"""
+ Provide a comprehensive linguistic analysis of the word "{word}" in {input_language}, and return the explanation in {output_language}. Include:
+ 1. Definition
+ 2. Parts of Speech
+ 3. Etymology
+ 4. 3-4 Example Sentences
+ 5. Synonyms
+ 6. Related Words or Nuanced Meanings
+
+ Return the response as a valid JSON string with these keys:
+ {{
+ "definition": "",
+ "parts_of_speech": "",
+ "etymology": "",
+ "examples": [],
+ "synonyms": [],
+ "related_words": []
+ }}
+ """
+
+ try:
+ model = genai.GenerativeModel('gemini-pro')
+ response = model.generate_content(prompt)
+
+ import re
+ json_match = re.search(r'\{.*\}', response.text, re.DOTALL)
+
+ if json_match:
+ json_str = json_match.group(0)
+ return json_str
+ else:
+ return json.dumps({
+ "definition": "Unable to extract structured context.",
+ "parts_of_speech": "Unknown",
+ "etymology": "Not available",
+ "examples": ["No examples could be generated."],
+ "synonyms": [],
+ "related_words": []
+ })
+
+ except Exception as e:
+ return json.dumps({
+ "definition": f"Error retrieving context: {str(e)}",
+ "parts_of_speech": "Unknown",
+ "etymology": "Not available",
+ "examples": ["No examples could be generated."],
+ "synonyms": [],
+ "related_words": []
+ })
+
+# Word input
+col1, col2 = st.columns([3, 1])
+
+with col1:
+ word_input = st.text_input("Enter a word to explore:", placeholder="Type a word...")
+
+with col2:
+ st.write("") # Spacer
+ st.write("") # Spacer
+ context_button = st.button("๐ Explore", type="primary")
+
+# Context display
+if context_button and word_input:
+ with st.spinner('Fetching word context...'):
+ context_result_str = get_word_context(word_input, input_language, output_language)
+
+ try:
+ context_result = json.loads(context_result_str)
+ except json.JSONDecodeError:
+ context_result = {
+ "definition": context_result_str,
+ "parts_of_speech": "Unknown",
+ "etymology": "Not available",
+ "examples": ["No examples could be generated."],
+ "synonyms": [],
+ "related_words": []
+ }
+
+ # Determine language code for audio generation from the output language
+ audio_lang_code = LANGUAGE_CODES.get(output_language, 'en')
+
+ # Generate audio for various content
+ audio_contents = {
+ "word": generate_audio_for_content(word_input, audio_lang_code),
+ "definition": generate_audio_for_content(context_result.get('definition', ''), audio_lang_code),
+ "parts_of_speech": generate_audio_for_content(context_result.get('parts_of_speech', ''), audio_lang_code),
+ "etymology": generate_audio_for_content(context_result.get('etymology', ''), audio_lang_code),
+ "examples": generate_audio_for_content(context_result.get('examples', []), audio_lang_code),
+ "synonyms": generate_audio_for_content(context_result.get('synonyms', []), audio_lang_code),
+ "related_words": generate_audio_for_content(context_result.get('related_words', []), audio_lang_code)
+ }
+
+ # Display word with audio in the same line but with added space
+ st.markdown(f"""
+ ### ๐ค Word:
+
+ {word_input}
+
+ {get_audio_player(audio_contents['word'].get('main'), 'word') if audio_contents['word'] else ''}
+
+
+ """, unsafe_allow_html=True)
+
+ # Display the results in card layout
+ st.markdown("", unsafe_allow_html=True)
+
+ # Definition Card
+ st.markdown(f"""
+
+
๐ Definition
+
{context_result.get('definition', 'No definition found.')}
+
+ {get_audio_player(next(iter(audio_contents['definition'].values()), None), 'definition') if audio_contents['definition'] else ''}
+
+
+ """, unsafe_allow_html=True)
+
+ # Parts of Speech Card
+ st.markdown(f"""
+
+
๐ Parts of Speech
+
{context_result.get('parts_of_speech', 'Unknown')}
+
+ {get_audio_player(next(iter(audio_contents['parts_of_speech'].values()), None), 'parts_of_speech') if audio_contents['parts_of_speech'] else ''}
+
+
+ """, unsafe_allow_html=True)
+
+ # Example Sentences Card
+ st.markdown("""
+
+
๐ฃ๏ธ Example Usage
+
+ """, unsafe_allow_html=True)
+
+ examples = context_result.get('examples', ['No examples available.'])
+ for i, example in enumerate(examples):
+ st.markdown(f"""
+
+ {example}
+
+ {get_audio_player(audio_contents['examples'].get(f'item_{i}'), f'example_{i}') if audio_contents['examples'] else ''}
+
+
+ """, unsafe_allow_html=True)
+
+ st.markdown(" ", unsafe_allow_html=True)
+
+ # Etymology Card
+ st.markdown(f"""
+
+
๐ฐ๏ธ Etymology
+
{context_result.get('etymology', 'Etymology not found.')}
+
+ {get_audio_player(next(iter(audio_contents['etymology'].values()), None), 'etymology') if audio_contents['etymology'] else ''}
+
+
+ """, unsafe_allow_html=True)
+
+ # Synonyms Card
+ synonyms = context_result.get('synonyms', [])
+ if synonyms:
+ st.markdown("""
+
+
๐ Synonyms
+
+ """, unsafe_allow_html=True)
+
+ for i, synonym in enumerate(synonyms):
+ st.markdown(f"""
+
+ {synonym}
+
+ {get_audio_player(audio_contents['synonyms'].get(f'item_{i}'), f'synonym_{i}') if audio_contents['synonyms'] else ''}
+
+
+ """, unsafe_allow_html=True)
+
+ st.markdown("
", unsafe_allow_html=True)
+
+ # Related Words Card
+ related_words = context_result.get('related_words', [])
+ if related_words:
+ st.markdown("""
+
+
๐ Related Words
+
+ """, unsafe_allow_html=True)
+
+ for i, related_word in enumerate(related_words):
+ st.markdown(f"""
+
+ {related_word}
+
+ {get_audio_player(audio_contents['related_words'].get(f'item_{i}'), f'related_{i}') if audio_contents['related_words'] else ''}
+
+
+ """, unsafe_allow_html=True)
+
+ st.markdown("
", unsafe_allow_html=True)
+
+ st.markdown("
", unsafe_allow_html=True)
+
diff --git a/NINJA CODERS/app/pages/features/languito_translator.py b/NINJA CODERS/app/pages/features/languito_translator.py
new file mode 100644
index 000000000..067537aa6
--- /dev/null
+++ b/NINJA CODERS/app/pages/features/languito_translator.py
@@ -0,0 +1,169 @@
+import streamlit as st
+import requests
+import os
+from dotenv import load_dotenv
+from gtts import gTTS
+import base64
+from io import BytesIO
+
+# Load environment variables
+load_dotenv()
+
+# Hugging Face API setup
+API_URL = "https://api-inference.huggingface.co/models/Helsinki-NLP/opus-mt-{}-{}"
+try:
+ API_TOKEN = os.getenv("HUGGINGFACE_API_TOKEN") or st.secrets["HUGGINGFACE_API_TOKEN"]
+except KeyError:
+ st.error("Google API Key is not set. Please provide it as an environment variable or in Streamlit secrets.")
+
+headers = {"Authorization": f"Bearer {API_TOKEN}"}
+
+def translate(text, source_lang, target_lang):
+ model_url = API_URL.format(source_lang, target_lang)
+ payload = {"inputs": text}
+ response = requests.post(model_url, headers=headers, json=payload)
+ if response.status_code == 200:
+ return response.json()[0]['translation_text']
+ else:
+ st.error(f"Translation failed. Status code: {response.status_code}")
+ return None
+
+def text_to_speech(text, lang):
+ try:
+ tts = gTTS(text=text, lang=lang, slow=False)
+ buf = BytesIO()
+ tts.write_to_fp(buf)
+ buf.seek(0)
+ return buf
+ except Exception as e:
+ st.error(f"An error occurred during speech synthesis: {str(e)}")
+ return None
+
+def get_audio_player(audio_bytes):
+ b64 = base64.b64encode(audio_bytes.getvalue()).decode()
+ return f' '
+
+# Initialize session state for audio containers
+if 'audio_container_input' not in st.session_state:
+ st.session_state.audio_container_input = None
+if 'audio_container_output' not in st.session_state:
+ st.session_state.audio_container_output = None
+
+# Streamlit app
+st.set_page_config(page_title="Languito Translator", page_icon="๐", layout="wide")
+
+# Title section
+st.markdown("""
+
+
๐ Languito Translator
+
Your Advanced Language Translation Platform
+
+""", unsafe_allow_html=True)
+
+# Language selection
+languages = {
+ "en": "English",
+ "fr": "French",
+ "es": "Spanish",
+ "de": "German",
+ "it": "Italian",
+ "ja": "Japanese",
+ "zh": "Chinese",
+ "ru": "Russian",
+ "ar": "Arabic",
+ "hi": "Hindi",
+ "pt": "Portuguese",
+ "nl": "Dutch",
+ "ko": "Korean",
+ "tr": "Turkish",
+ "pl": "Polish",
+ "sv": "Swedish"
+}
+
+col1, col2 = st.columns(2)
+
+with col1:
+ source_lang = st.selectbox("Translate from:", list(languages.values()), index=0, key="source")
+ source_code = [code for code, lang in languages.items() if lang == source_lang][0]
+
+with col2:
+ target_lang = st.selectbox("Translate to:", list(languages.values()), index=1, key="target")
+ target_code = [code for code, lang in languages.items() if lang == target_lang][0]
+
+# Input and output areas side by side
+col_input, col_output = st.columns(2)
+
+with col_input:
+ st.markdown(f"### Enter {source_lang} text:")
+ col1, col2 = st.columns([0.9, 0.1])
+ with col1:
+ input_text = st.text_area("", height=200, key="input", placeholder="Type or paste your text here...", help="Enter the text you want to translate", max_chars=5000)
+ with col2:
+ # Create a container for the audio player
+ audio_container_input = st.empty()
+ if st.button("๐", key="input_speech", help="Listen to text", kwargs={"className": "speech-button"}):
+ if input_text:
+ audio_bytes = text_to_speech(input_text, source_code)
+ if audio_bytes:
+ audio_container_input.markdown(get_audio_player(audio_bytes), unsafe_allow_html=True)
+ char_count = len(input_text)
+ word_count = len(input_text.split())
+ st.text(f"Character count: {char_count} | Word count: {word_count}")
+
+with col_output:
+ st.markdown(f"### Translated {target_lang} text:")
+ if 'translated_text' not in st.session_state:
+ st.session_state.translated_text = ""
+
+ col3, col4 = st.columns([0.9, 0.1])
+ with col3:
+ output_placeholder = st.empty()
+ output_char_count = st.empty()
+ with col4:
+ # Create a container for the audio player
+ audio_container_output = st.empty()
+ if st.button("๐", key="output_speech", help="Listen to translation", kwargs={"className": "speech-button"}):
+ if st.session_state.translated_text:
+ audio_bytes = text_to_speech(st.session_state.translated_text, target_code)
+ if audio_bytes:
+ audio_container_output.markdown(get_audio_player(audio_bytes), unsafe_allow_html=True)
+
+# Translate button
+if st.button("๐ Translate", type="primary"):
+ if input_text:
+ try:
+ with st.spinner("Translating..."):
+ translated_text = translate(input_text, source_code, target_code)
+ if translated_text:
+ st.session_state.translated_text = translated_text
+ output_placeholder.markdown(f'{translated_text}
', unsafe_allow_html=True)
+ output_char_count.text(f"Character count: {len(translated_text)} | Word count: {len(translated_text.split())}")
+ except Exception as e:
+ st.error(f"An error occurred: {str(e)}")
+ else:
+ st.warning("Please enter some text to translate.")
+
+# Additional features
+st.markdown("---")
+col3, col4 = st.columns(2)
+
+with col3:
+ st.markdown("### Recent Updates")
+ st.info("""
+ - Added text-to-speech functionality for input and output text
+ - Added support for more language pairs
+ - Improved error handling
+ - Enhanced UI with custom styling
+ - Added character and word count for both input and output
+ """)
+
+with col4:
+ st.markdown("### Usage Tips")
+ st.success("""
+ - For best results, enter clear and complete sentences
+ - Maximum recommended length: 5000 characters per translation
+ - Supports multiple paragraphs
+ - Use the language selection dropdowns to choose your desired languages
+ - Click on the speaker icon to hear the text spoken
+ """)
+
diff --git a/NINJA CODERS/app/pages/features/quiz.py b/NINJA CODERS/app/pages/features/quiz.py
new file mode 100644
index 000000000..fdedd7d03
--- /dev/null
+++ b/NINJA CODERS/app/pages/features/quiz.py
@@ -0,0 +1,401 @@
+
+from dotenv import load_dotenv
+import streamlit as st
+import os
+import google.generativeai as genai
+from typing import Iterator, Dict, List
+import logging
+import json
+import random
+import hashlib
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+class GeminiQuiz:
+ def __init__(self):
+ load_dotenv()
+ # self.api_key = os.getenv("GOOGLE_API_KEY")
+ try:
+ self.api_key = os.getenv("GOOGLE_API_KEY") or st.secrets["GOOGLE_API_KEY"]
+ except KeyError:
+ st.error("Google API Key is not set. Please provide it as an environment variable or in Streamlit secrets.")
+
+
+
+ if not self.api_key:
+ raise ValueError("GOOGLE_API_KEY not found in environment variables")
+
+ self.setup_genai()
+ self.max_retries = 5
+
+ # Initialize question history in session state if not exists
+ if 'question_history' not in st.session_state:
+ st.session_state.question_history = set()
+
+ # Track used difficulties to ensure variety
+ if 'used_difficulties' not in st.session_state:
+ st.session_state.used_difficulties = []
+
+ def setup_genai(self) -> None:
+ try:
+ genai.configure(api_key=self.api_key)
+ self.model = genai.GenerativeModel("gemini-pro")
+ except Exception as e:
+ logger.error(f"Error setting up Gemini: {str(e)}")
+ raise
+
+ def get_balanced_difficulty(self) -> str:
+ """Ensure a balanced distribution of difficulty levels"""
+ difficulties = ["beginner", "intermediate", "advanced"]
+
+ if len(st.session_state.used_difficulties) >= 10: # Reset after 10 questions
+ st.session_state.used_difficulties = []
+
+ # Count current difficulty distribution
+ difficulty_counts = {diff: st.session_state.used_difficulties.count(diff) for diff in difficulties}
+
+ # Filter out overused difficulties (more than 1/3 of total questions)
+ available_difficulties = [
+ diff for diff in difficulties
+ if difficulty_counts[diff] < (len(st.session_state.used_difficulties) + 1) / 3
+ ]
+
+ # If all difficulties are equally distributed, allow any
+ if not available_difficulties:
+ available_difficulties = difficulties
+
+ selected_difficulty = random.choice(available_difficulties)
+ st.session_state.used_difficulties.append(selected_difficulty)
+ return selected_difficulty
+
+ def get_language_prompt(self, user_language: str, target_language: str, category: str) -> str:
+ """Generate appropriate prompt based on languages and category"""
+ difficulty_levels = {
+ "beginner": "basic vocabulary and simple structures",
+ "intermediate": "moderate complexity and common usage patterns",
+ "advanced": "complex language features and nuanced usage"
+ }
+
+ base_difficulty = self.get_balanced_difficulty()
+
+ # Add specific constraints to ensure uniqueness
+ base_constraints = f"""
+ Constraints for generating unique questions:
+ - Use diverse question formats (fill-in-blank, scenario-based, translation, etc.)
+ - Include practical, real-world contexts
+ - Vary the topics within the category
+ - Ensure cultural relevance to {target_language}-speaking regions
+ - Don't repeat common textbook examples
+ """
+
+ prompts = {
+ "Grammar": f"""
+ Generate a {base_difficulty}-level multiple-choice question for language learning.
+ Context: Question about {target_language} grammar, written in {user_language}.
+ Focus Area: {difficulty_levels[base_difficulty]}
+ {base_constraints}
+ Additional Grammar-specific requirements:
+ - Include varied sentence structures
+ - Focus on practical usage rather than technical terms
+ - Incorporate common language patterns
+
+ Return strictly in this JSON format:
+ {{
+ "question": "Clear, well-formulated question",
+ "options": ["Option 1", "Option 2", "Option 3", "Option 4"],
+ "correct_answer": "The correct option exactly as written in options",
+ "explanation": "Detailed explanation of why the answer is correct",
+ "difficulty": "{base_difficulty}",
+ "topic": "Specific grammar topic covered"
+ }}
+ """,
+ "Vocabulary": f"""
+ Generate a {base_difficulty}-level vocabulary question for language learning.
+ Context: Question about {target_language} vocabulary, written in {user_language}.
+ Focus Area: {difficulty_levels[base_difficulty]}
+ {base_constraints}
+ Additional Vocabulary-specific requirements:
+ - Use words in context-rich situations
+ - Include collocations and common word pairs
+ - Focus on frequency-based vocabulary selection
+
+ Return strictly in this JSON format:
+ {{
+ "question": "Clear, well-formulated question",
+ "options": ["Option 1", "Option 2", "Option 3", "Option 4"],
+ "correct_answer": "The correct option exactly as written in options",
+ "explanation": "Detailed explanation including usage examples",
+ "difficulty": "{base_difficulty}",
+ "topic": "Specific vocabulary theme"
+ }}
+ """,
+ "Common Phrases": f"""
+ Generate a {base_difficulty}-level question about common phrases.
+ Context: Question about {target_language} expressions, written in {user_language}.
+ Focus Area: {difficulty_levels[base_difficulty]}
+ {base_constraints}
+ Additional Phrase-specific requirements:
+ - Include contemporary expressions
+ - Focus on situational appropriateness
+ - Cover various social contexts
+
+ Return strictly in this JSON format:
+ {{
+ "question": "Clear, well-formulated question",
+ "options": ["Option 1", "Option 2", "Option 3", "Option 4"],
+ "correct_answer": "The correct option exactly as written in options",
+ "explanation": "Detailed explanation with cultural context",
+ "difficulty": "{base_difficulty}",
+ "topic": "Specific phrase category or situation"
+ }}
+ """
+ }
+
+ return prompts[category] + "\nProvide only the JSON response without any additional text."
+
+ def calculate_question_hash(self, question_data: Dict) -> str:
+ """Calculate a unique hash for a question based on its content"""
+ # Create a string combining multiple aspects of the question
+ question_string = (
+ f"{question_data['question'].lower()}"
+ f"{','.join(sorted(opt.lower() for opt in question_data['options']))}"
+ f"{question_data['correct_answer'].lower()}"
+ f"{question_data.get('topic', '').lower()}"
+ )
+ return hashlib.md5(question_string.encode()).hexdigest()
+
+ def is_question_unique(self, question_data: Dict) -> bool:
+ """Check if a question is unique based on its content"""
+ question_hash = self.calculate_question_hash(question_data)
+ if question_hash in st.session_state.question_history:
+ return False
+ st.session_state.question_history.add(question_hash)
+ return True
+
+ def generate_question(self, user_language: str, target_language: str, category: str) -> Dict:
+ for attempt in range(self.max_retries):
+ try:
+ prompt = self.get_language_prompt(user_language, target_language, category)
+ response = self.model.generate_content(prompt)
+
+ # Clean and parse response
+ response_text = response.text.strip()
+ if "```json" in response_text:
+ response_text = response_text.split("```json")[1].split("```")[0]
+ elif "```" in response_text:
+ response_text = response_text.split("```")[1]
+
+ response_text = (
+ response_text.strip()
+ .replace('\n', '')
+ .replace('\r', '')
+ .replace('\t', '')
+ )
+
+ question_data = json.loads(response_text)
+
+ # Validate question format
+ required_fields = ["question", "options", "correct_answer", "explanation", "difficulty"]
+ if not all(field in question_data for field in required_fields):
+ logger.warning("Missing required fields, retrying...")
+ continue
+
+ if not isinstance(question_data["options"], list) or len(question_data["options"]) != 4:
+ logger.warning("Invalid options format, retrying...")
+ continue
+
+ if question_data["correct_answer"] not in question_data["options"]:
+ logger.warning("Correct answer not in options, retrying...")
+ continue
+
+ if self.is_question_unique(question_data):
+ return question_data
+
+ logger.info(f"Duplicate question on attempt {attempt + 1}, retrying...")
+
+ except Exception as e:
+ logger.error(f"Error on attempt {attempt + 1}: {str(e)}")
+ continue
+
+ raise ValueError("Failed to generate a valid unique question after maximum retries")
+
+class QuizApp:
+ def __init__(self):
+ self.setup_page()
+ self.initialize_session_state()
+ self.quiz = GeminiQuiz()
+ self.available_languages = {
+ "English": "๐ฌ๐ง",
+ "Spanish": "๐ช๐ธ",
+ "French": "๐ซ๐ท",
+ "German": "๐ฉ๐ช",
+ "Italian": "๐ฎ๐น",
+ "Portuguese": "๐ต๐น",
+ "Chinese": "๐จ๐ณ",
+ "Japanese": "๐ฏ๐ต",
+ "Korean": "๐ฐ๐ท"
+ }
+ self.categories = ["Grammar", "Vocabulary", "Common Phrases"]
+ self.num_questions = 10
+
+ def setup_page(self) -> None:
+ st.set_page_config(
+ page_title="Languito Quiz",
+ page_icon="๐",
+ layout="wide"
+ )
+
+ def initialize_session_state(self) -> None:
+ if 'quiz_started' not in st.session_state:
+ st.session_state['quiz_started'] = False
+ if 'current_questions' not in st.session_state:
+ st.session_state['current_questions'] = []
+ if 'current_question_idx' not in st.session_state:
+ st.session_state['current_question_idx'] = 0
+ if 'score' not in st.session_state:
+ st.session_state['score'] = 0
+ if 'user_answers' not in st.session_state:
+ st.session_state['user_answers'] = {}
+ if 'quiz_completed' not in st.session_state:
+ st.session_state['quiz_completed'] = False
+
+ def generate_quiz_questions(self, user_language: str, target_language: str, category: str) -> List[Dict]:
+ questions = []
+ for _ in range(self.num_questions):
+ try:
+ question = self.quiz.generate_question(user_language, target_language, category)
+ questions.append(question)
+ except Exception as e:
+ logger.error(f"Error generating question: {str(e)}")
+ continue
+ return questions
+
+ def display_progress(self) -> None:
+ progress = (st.session_state['current_question_idx'] + 1) / self.num_questions
+ st.progress(progress)
+ st.write(f"Question {st.session_state['current_question_idx'] + 1} of {self.num_questions}")
+
+ def display_final_results(self) -> None:
+ st.title("Quiz Complete! ๐")
+ final_score = st.session_state['score']
+ percentage = (final_score / self.num_questions) * 100
+
+ st.header(f"Your Score: {final_score}/{self.num_questions} ({percentage:.1f}%)")
+
+ if percentage >= 90:
+ st.balloons()
+ st.success("Outstanding! You're a language master! ๐")
+ elif percentage >= 70:
+ st.success("Great job! Keep up the good work! ๐")
+ elif percentage >= 50:
+ st.info("Good effort! Keep practicing! ๐ช")
+ else:
+ st.warning("Keep studying! You'll improve! ๐")
+
+ # Display question review
+ st.subheader("Review Your Answers")
+ for idx, question in enumerate(st.session_state['current_questions']):
+ with st.expander(f"Question {idx + 1}: {question['question']}"):
+ user_answer = st.session_state['user_answers'].get(idx, "Not answered")
+ st.write(f"Your answer: {user_answer}")
+ st.write(f"Correct answer: {question['correct_answer']}")
+ if user_answer == question['correct_answer']:
+ st.success("Correct! โ
")
+ else:
+ st.error("Incorrect โ")
+ st.info(f"Explanation: {question['explanation']}")
+
+ def main(self) -> None:
+ st.title("๐ Languito Quiz")
+
+ # Sidebar selections
+ with st.sidebar:
+ st.title("Quiz Settings")
+ user_language = st.selectbox(
+ "Select your language:",
+ list(self.available_languages.keys()),
+ format_func=lambda x: f"{self.available_languages[x]} {x}",
+ key="user_language"
+ )
+
+ target_language = st.selectbox(
+ "Select language to learn:",
+ [lang for lang in self.available_languages.keys() if lang != user_language],
+ format_func=lambda x: f"{self.available_languages[x]} {x}",
+ key="target_language"
+ )
+
+ selected_category = st.selectbox(
+ "Select a category:",
+ self.categories,
+ help="Grammar: Learn language rules\nVocabulary: Learn new words\nCommon Phrases: Learn expressions"
+ )
+
+ if not st.session_state['quiz_started']:
+ if st.button("Start Quiz"):
+ st.session_state['current_questions'] = self.generate_quiz_questions(
+ user_language, target_language, selected_category
+ )
+ st.session_state['quiz_started'] = True
+ st.session_state['current_question_idx'] = 0
+ st.session_state['score'] = 0
+ st.session_state['user_answers'] = {}
+ st.session_state['quiz_completed'] = False
+ st.rerun()
+
+ st.divider()
+ st.metric("Current Score", f"{st.session_state['score']}/{self.num_questions}")
+
+ # Main content area
+ if st.session_state['quiz_started'] and not st.session_state['quiz_completed']:
+ self.display_progress()
+
+ current_q = st.session_state['current_questions'][st.session_state['current_question_idx']]
+
+ st.subheader(current_q["question"])
+
+ user_answer = st.radio(
+ "Choose your answer:",
+ current_q["options"],
+ key=f"q_{st.session_state['current_question_idx']}"
+ )
+
+ col1, col2 = st.columns(2)
+
+ with col1:
+ if st.button("Submit Answer"):
+ st.session_state['user_answers'][st.session_state['current_question_idx']] = user_answer
+ if user_answer == current_q["correct_answer"]:
+ st.session_state['score'] += 1
+
+ if st.session_state['current_question_idx'] < self.num_questions - 1:
+ st.session_state['current_question_idx'] += 1
+ else:
+ st.session_state['quiz_completed'] = True
+ st.rerun()
+
+ with col2:
+ if st.session_state['current_question_idx'] > 0:
+ if st.button("Previous Question"):
+ st.session_state['current_question_idx'] -= 1
+ st.rerun()
+
+ elif st.session_state['quiz_completed']:
+ self.display_final_results()
+
+ if st.button("Start New Quiz"):
+ st.session_state['quiz_started'] = False
+ st.session_state['current_questions'] = []
+ st.session_state['current_question_idx'] = 0
+ st.session_state['score'] = 0
+ st.session_state['user_answers'] = {}
+ st.session_state['quiz_completed'] = False
+ st.rerun()
+
+try:
+ app = QuizApp()
+ app.main()
+except Exception as e:
+ st.error(f"Application failed to start: {str(e)}")
+ logger.error(f"Application error: {str(e)}")
diff --git a/NINJA CODERS/app/pages/features/text2speech.py b/NINJA CODERS/app/pages/features/text2speech.py
new file mode 100644
index 000000000..f478345c9
--- /dev/null
+++ b/NINJA CODERS/app/pages/features/text2speech.py
@@ -0,0 +1,108 @@
+import streamlit as st
+import os
+from gtts import gTTS
+import base64
+from io import BytesIO
+
+# Streamlit page configuration
+st.set_page_config(page_title="PolyGlot Speech", page_icon="๐", layout="wide")
+
+# Load the CSS
+# with open("pages/styles/style.css") as f:
+# st.markdown(f"", unsafe_allow_html=True)
+
+# Main app container
+# Title section
+st.markdown("""
+
+
๐ Languito Speech
+
Your Advanced Multi-Language Text-to-Speech Platform
+
+""", unsafe_allow_html=True)
+
+# Language selection
+languages = {
+ 'en': 'English',
+ 'fr': 'French',
+ 'es': 'Spanish',
+ 'de': 'German',
+ 'it': 'Italian',
+ 'ja': 'Japanese',
+ 'ko': 'Korean',
+ 'pt': 'Portuguese',
+ 'nl': 'Dutch',
+ 'zh-CN': 'Chinese (Simplified)'
+}
+
+selected_lang = st.selectbox("Select Language:", list(languages.values()), index=0)
+lang_code = [code for code, lang in languages.items() if lang == selected_lang][0]
+
+# Text input
+st.markdown(f"### Enter {selected_lang} text:")
+input_text = st.text_area("", height=150, max_chars=500, help="Enter the text you want to convert to speech")
+
+# Character and word count
+char_count = len(input_text)
+word_count = len(input_text.split()) if input_text.strip() else 0
+st.text(f"Character count: {char_count} | Word count: {word_count}")
+
+def text_to_speech(text, lang):
+ try:
+ tts = gTTS(text=text, lang=lang, slow=False)
+ buf = BytesIO()
+ tts.write_to_fp(buf)
+ buf.seek(0)
+ return buf
+ except Exception as e:
+ st.error(f"An error occurred during speech synthesis: {str(e)}")
+ return None
+
+def get_audio_player(audio_bytes):
+ b64 = base64.b64encode(audio_bytes.getvalue()).decode()
+ return f' '
+
+# Generate speech button
+if st.button("๐ Generate Speech", type="primary"):
+ if input_text.strip():
+ with st.spinner("Generating speech..."):
+ audio_bytes = text_to_speech(input_text, lang_code)
+ if audio_bytes:
+ st.markdown("### Generated Speech:")
+ st.markdown(get_audio_player(audio_bytes), unsafe_allow_html=True)
+
+ # Download button
+ st.download_button(
+ label="Download Audio",
+ data=audio_bytes,
+ file_name=f"speech_{lang_code}.mp3",
+ mime="audio/mp3"
+ )
+ else:
+ st.warning("Please enter some text to convert to speech.")
+
+# Additional features
+st.markdown("---")
+col1, col2 = st.columns(2)
+
+with col1:
+ st.markdown("### Features")
+ st.info("""
+ - High-quality speech synthesis
+ - Support for 10 languages
+ - Download audio files
+ - Real-time character and word counting
+ - Modern, user-friendly interface
+ """)
+
+with col2:
+ st.markdown("### Usage Tips")
+ st.success("""
+ - For best results, use proper punctuation
+ - Keep texts under 500 characters for optimal performance
+ - Try different languages to hear the variations
+ - Use the download feature to save audio for offline use
+ """)
+
+# Footer
+st.markdown("---")
+st.markdown("Created with โค using Streamlit and gTTS")
\ No newline at end of file
diff --git a/NINJA CODERS/app/pages/home/main.py b/NINJA CODERS/app/pages/home/main.py
new file mode 100644
index 000000000..6d97bd32d
--- /dev/null
+++ b/NINJA CODERS/app/pages/home/main.py
@@ -0,0 +1,145 @@
+import streamlit as st
+
+# Page configuration
+st.set_page_config(
+ page_title="LanguitoAI - Your Advanced Language Assistant",
+ layout="wide",
+ initial_sidebar_state="collapsed"
+)
+
+# Add logo at the top of sidebar
+import os
+
+# Get the absolute path to the image
+# image_path = os.path.join(os.getcwd(), 'images', 'logo.png')
+image_path = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AABhg0lEQVR4nO3deZwdVZk38N/znFNVd+k1W6ezQgigERENbogkkU0cddSZMK+OyrDYiIrKMO5Lk9FxGRdUZIuioowzgs6MIiBrwio4wVEHImCALJ10FpL0eu+tqnPO8/5RdTvdnc4KIQ2c7/vpeaW7b926nb5Pn+U5zwN4nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nud5nvcCQAf7BjzPO3g6O8GLMU8DwMqVK+3p18Ee7HvaHR+wPO8FqLMTfMKmaYcr4/5KmI4mcQrGrgPrFXFQuueUK57YQoAc7PsczQcsz3uBEYBuPXPqCSWqfaOI2tGWdAARkBMxjMEaFf5HqPxtSvnmRVevqR3s+x3OByzPe4G58dy58xrM1h8VpXosAQQBQA4OOvsPAWooPJVAX+qCxotPXvpE78G+5zofsDzvBeTGM6dOLrG9tOhqf0MkzDDIYtTOoSCBqlSo+WKXmC+fes2mwYNwuzvhg30Dnuc9O+67YEax5OIPl23/W1gMkxOQCNwYwxYSQYik1Oh6PhAW7Fs7O8dHrBgXN+F53oF17WIo+1Tl9CLVPuiIC5YUtCQQYsiwMCAiEBE4IjgARK5VuaRjYXf7hIN39zv4gOV5z3MC0OSmttcTJ58XUCsJQHAwTEhJQYvF6A1BEgdC9gGil8YSHHFw7n4kH7A873nu5jNmH8nWfFkjOTRbrXIgcRAQ2KVwEAgcBBYgl30AoPz/BWIatcOcg/wyAPiA5XnPays65gcBVc8LpfYqIU1a3IivE2QXyVYCB4aAkCIAlHo2bnePfMDyvOex+dsfdBp2HeC2AyKWacwARQIwaOiDiMAAGBaBMz3OJaue7Xsfiz7YN+B53jPnvgtmFCt97iRAasqE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"
+# Display the image in the sidebar
+st.sidebar.image(image_path, width=300)
+
+# Custom CSS
+st.markdown("""
+
+""", unsafe_allow_html=True)
+
+
+
+# Header
+# banner_path = os.path.join(os.getcwd(), 'images', 'banner.png')
+
+
+st.image("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA5MAAADECAYAAAACjHVbAABDDUlEQVR4nO3debiVV302/nut9Qx7Hs4MHOCEeYYAIQlJLKhtjbW+vipprU0bjaJG0Trb1gFTh6rRtI1GX5yi/mxtcKpaNTEJKEIGDhAIQwjTAQ6c+Zw9D8+w1u+PAxECISQhEuP9uS6uXGQ/+9nrWeePfW6+a30XQERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERELxjiYg+AiIiIXvg6Vy6y02Os6EBB+ktvvb96scdDRETPHsMkERERPac637logmhu+1StNLgsGksdU9HkV/39D69dvOZg/mKPjYiInjmGSSIiInrOdK4c01QI8D9WX89SOw6EIVCtA+6keT+Xuv7mq7+49/jFHiMRET0zDJNERET0nNh+fWu83Nj4De/g7usSjU5oIAUgAB2a6rCn/Ka2dVFZee3SrxeGL/ZYiYjo6ZMXewBERET0wrNuGSxcMv0fK4/tvi6edbWAVFpICUAaoUSk0dXo713utEx/97plsC72eImI6OljmCQiIqILygAie9VVr+nt/M17ko22NlIgEBLKhDAwALQUABIp6FLfwZdjVnPkYo+ZiIiePoZJIiIiuqC2rGxqO7p54ydSCURtyzIwkMIE0KNBEhBm9I8EvGrZTQaButhjJiKip49hkoiIiJ41A4jOldm0WQ0J2PnGKdO35crwvFpVQUAbjDZqUBBQEJBCIKhAJhrH7S16I/WLPX4iInr6GCaJiIjoWdv+8T991VAl3vlI7DUfA6J2amDv37bNu/KvikgcrA/XpDKhFqNlSQBCm1pdVi11yNX44PI7ULvY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yrGOiFAc1F7hoMyPHM2X/OIVTfd74l/Pr3L4+7RzBZx6qvltIkS7UZYWJhSeB51tmnC/tXtD7WzvEYAxX9j64NZ3L3wlkpmZfnX40Wr0wUPL78A5O+ESERH9oWCYJCKiM3XACmrlDiGBUNg+TCANhEDgKR0YpWuBrhnUjUAJrpWTsYZhK5YesiKpnojjHgVMj9bhQOh5fdKrDAdCl/zAK0dLdW+4Xguby4/q3UC4Yi30H8LewJGmdFwc3XWVigCAMNpoBY2+oDT03wvOcf6jAAxu3bofwP7f22CJiIh+TxgmiYjoDM1l6EI96PYrgB2t2LU6EAYoaVcMWJn2o7H21t1Jy3nYeJVdKBaPBOVczrJKQb8wYTSxP1wGaKyG+UMIiucj1TDt6tyuzROimROdXIMQIhPrq1aO7bq4IyMiIrp4GCaJiOgMc9bC+/Wbhm7z21rmFOvFWbGOGZuibuzHYWHw/lw+198wssWfPRuB+PTzb0nqhWYAsSUQyXoZkVjKAAo6rEDFps08IEeO14H8xR4iERHRRcGjQYiI6En99gPTk5HQuJ6ulK+8tbv2Qqk0Pl0PvL4h5adbv1ndv+dV6QTkcBGF1sVXXX/ppzf+9I91ToiIiBgmiYiIzsMDr5+SsqdNurHae+TvVTJzf6Hn0Pv+/Dt95Ys9LiIioouFYZKIiOg8mdWQO0rzorF6JZh62/76xR4PEREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREdEL0v8PAQUojcAhtw4AAAAASUVORK5CYII=", use_container_width=True)
+
+
+st.markdown("""
+
+""", unsafe_allow_html=True)
+
+# Feature sections
+st.markdown("""
+
+
Features
+
+ Quizes
+ AI chat assistant
+ Translator
+ Prononciation guide
+ Dictionnary
+
+
+
+""", unsafe_allow_html=True)
+
+# workflow
+st.markdown("""
+ Workflow
+""", unsafe_allow_html=True)
+# st.image("images/workflow.png")
+# workflow_path = os.path.join(os.getcwd(), 'images', 'workflow.png')
+workflow_path = "data:image/png;base64,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"
+st.image(workflow_path)
+
+
+# Call to action
+st.markdown("""
+
+
Ready to Get Started?
+
Choose a feature from the sidebar to begin your learning journey!
+
+""", unsafe_allow_html=True)
diff --git a/NINJA CODERS/app/pages/styles/style.css b/NINJA CODERS/app/pages/styles/style.css
new file mode 100644
index 000000000..3c3d08fcb
--- /dev/null
+++ b/NINJA CODERS/app/pages/styles/style.css
@@ -0,0 +1,139 @@
+@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;700&display=swap');
+
+body {
+ font-family: 'Nunito', sans-serif;
+ background: linear-gradient(135deg, #f0f9ff, #cbebff);
+ color: #333;
+}
+
+.main .block-container {
+ background-color: white;
+ border-radius: 20px;
+ padding: 2rem;
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
+}
+
+h1 {
+ font-size: 2.5em !important;
+ color: #0077be;
+ text-shadow: 2px 2px 0 #ffd700;
+ margin-bottom: 20px;
+}
+
+h2, h3 {
+ color: #0077be;
+}
+
+.stButton > button {
+ background: linear-gradient(45deg, #0077be, #00a86b);
+ color: white;
+ border: none;
+ border-radius: 10px;
+ padding: 10px 20px;
+ font-size: 1.2em;
+ font-weight: bold;
+ transition: all 0.3s;
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+}
+
+.stButton > button:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
+}
+
+.stRadio > div {
+ background: #f0f9ff;
+ padding: 15px;
+ border-radius: 10px;
+ border: 2px solid #0077be;
+ margin: 10px 0;
+ transition: all 0.3s;
+}
+
+.stRadio > div:hover {
+ transform: scale(1.02);
+ background: #e1f1ff;
+}
+
+.stSelectbox > div > div {
+ background: white;
+ border: 2px solid #00a86b;
+ border-radius: 10px;
+ transition: all 0.3s;
+}
+
+.stSelectbox > div > div:hover {
+ border-color: #0077be;
+}
+
+.stMetric {
+ background: linear-gradient(135deg, #f0f9ff, #e1f1ff);
+ border-radius: 10px;
+ padding: 10px;
+ border: 2px solid #0077be;
+}
+
+.stSuccess, .stError, .stInfo, .stWarning {
+ border-radius: 10px;
+ padding: 15px;
+ font-size: 1.1em;
+}
+
+.stSuccess {
+ background: #e6ffe6;
+ border: 2px solid #00a86b;
+}
+
+.stError {
+ background: #ffe6e6;
+ border: 2px solid #ff6b6b;
+}
+
+.stInfo {
+ background: #e6f2ff;
+ border: 2px solid #0077be;
+}
+
+.stWarning {
+ background: #fff9e6;
+ border: 2px solid #ffd700;
+}
+
+.streamlit-expanderHeader {
+ background: #f0f9ff;
+ border-radius: 10px;
+ border: 2px solid #0077be;
+ padding: 10px;
+ transition: all 0.3s;
+}
+
+.streamlit-expanderHeader:hover {
+ background: #e1f1ff;
+}
+
+.css-1d391kg, .css-12oz5g7 {
+ background: linear-gradient(170deg, #f0f9ff 0%, #e1f1ff 100%);
+ border-right: 2px solid #0077be;
+}
+
+/* Emoji for younger kids */
+.emoji-icon {
+ font-size: 1.5em;
+ margin-right: 5px;
+}
+
+/* Progress bar for older kids */
+.progress-bar {
+ width: 100%;
+ height: 20px;
+ background-color: #f0f9ff;
+ border-radius: 10px;
+ overflow: hidden;
+}
+
+.progress-bar-fill {
+ height: 100%;
+ background-color: #0077be;
+ transition: width 0.5s ease-in-out;
+}
+
diff --git a/NINJA CODERS/app/requirements.txt b/NINJA CODERS/app/requirements.txt
new file mode 100644
index 000000000..2a82f93b5
--- /dev/null
+++ b/NINJA CODERS/app/requirements.txt
@@ -0,0 +1,7 @@
+python-dotenv==1.0.0
+streamlit==1.40.2
+google-generativeai
+typing-extensions==4.9.0
+langchain
+langchain_google_genai
+gtts
diff --git a/README.md b/README.md
index 92ec67790..8c0d49bca 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,61 @@
-# About The Hackathon
-The MoroccoAI InnovAI Hackathon is a unique opportunity for AI enthusiasts, professionals, and innovators to collaborate and create transformative AI-based solutions addressing real-life challenges in Morocco and across Africa. As part of the annual MoroccoAI Annual Conference, this hackathon is set under the theme โDriving the Future of Innovation Through AIโ, inspiring participants to harness AIโs capabilities to make a meaningful societal impact. Participants will join teams to develop Proof of Concepts (PoCs) using applications or APIs that address challenges in various domains. Education, Healthcare, Environment, Finance or Customer Services .
-
-In line with MoroccoAIโs mission, this hackathon centers around โDriving the Future of Innovation Through AIโ. AI has the power to redefine industries, address community needs, and propel sustainable growth. Through this event, participants will dive into AIโs potential by developing impactful solutions that address challenges unique to Morocco and Africa in fields such as agriculture, education, health, and finance, fostering innovation in response to real-world needs.
-
-# The Challenge
-Connect with the MoroccoAI community, join teams and brainstorm ideas then come up with a project that leverages AI in 5 areas of focus:
-* Innovation
-* Healthcare
-* Environment
-* Finance
-* CustomerServices
-
-# Mentorship
-Join the Hackathon server on discord and meet the mentors to learn more about their proposed projects.
-
-# Why should you participate in this Hackathon?
-* Hands-on experience in AI project development that targets relevant issues in Morocco and Africa.
-* Mentorship and networking opportunities with experts and peers in the AI community.
-* Showcase their solutions to a jury of AI specialists at the awards ceremony, creating visibility and opportunities for further development.
-* Win great prizes offered by MoroccoAI's sponsors
-* Obtain your MoroccoAI certificate of recognition
-
-# For more information
-https://morocco.ai/events/conferences/MoroccoAI-Conference-2024/pages/hackathon.html
+
+
+
+
+
+# Languito.ai ๐๐
+
+Languito.ai is an innovative AI-powered language learning platform designed to transform language education for Moroccan children. Our mission is to make language learning engaging, interactive, and culturally relevant.
+
+
+
+## ๐ Problem Statement
+
+40% of students struggle with language learning due to:
+- Intimidating traditional classroom environments.
+- Lack of interactive and engaging learning tools.
+- Difficulty connecting classroom learning to real-life contexts.
+- Fear of making mistakes.
+
+## ๐ก Solution
+
+Our solution is to provide an all-in-one platform that enhances language learning through an interactive AI chat assistant for real-time, judgment-free practice and instant feedback. We offer a comprehensive Darija dictionary with contextual explanations, pronunciation guides, and real-life examples. Additionally, our gamified language quizzes adapt to your skill level, track performance, and make learning fun. Finally, a personalized learning space ensures customized content, progress monitoring, and a tailored experience for effective skill development.
+
+
+
+## ๐ Links :
+* ๐ด Demo : [Languito.ai](https://languito-ai.streamlit.app/)
+* ๐ฅ Video Demo : [Link](https://www.youtube.com/watch?v=BnsCVRAObdo&ab_channel=NinjaCoders)
+* ๐ฅ Pitch Deck (video) : [Link](https://www.youtube.com/watch?v=whh51FjzBlo)
+* ๐ Pitch : [Link](https://drive.google.com/file/d/1I0eP3mn7s8vPLR1jSQjHMyTL92T8jH5V/view)
+
+## ๐ฅ Team
+
+Languito.ai was founded by a passionate team of software engineering students from FSTT:
+
+- *Mohamed Amine Bahassou*
+ 2nd Year Software Engineering Student @FSTT
+
+- *Zakariae Azarkan*
+ 2nd Year Software Engineering Student @FSTT
+
+- *Hodaifa Echffani*
+ 2nd Year Software Engineering Student @FSTT
+
+## ๐ Installation
+
+### Prerequisites
+- Python 3.12+
+- pip
+
+### Setup Instructions
+```bash
+# Clone the repository
+git clone https://github.com/Medamine-Bahassou/languito-ai.git
+cd NINJA CODERS/app
+
+# Install dependencies
+pip install -r requirements.txt
+
+# Run the application
+streamlit run app.py