CoolFace
Apppublic

opinder2906/Software_engineering

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
app.py215 linesDownload Raw Back to root
1import torch2import torch.nn as nn3import torch.nn.functional as F4import random5from textblob import TextBlob6import pandas as pd7import requests8from io import StringIO9import gradio as gr10import speech_recognition as sr11import json12 13# ----- Dummy Model and vocab -----14vocab = {'<PAD>': 0, '<UNK>': 1, 'i': 2, 'am': 3, 'feeling': 4, 'sad': 5, 'happy': 6, 'angry': 7, 'love': 8, 'stressed': 9, 'anxious': 10}15MAX_LEN = 1616 17class DummyLabelEncoder:18    def __init__(self):19        self.classes_ = ['sadness', 'anger', 'love', 'happiness', 'neutral']20    def transform(self, x): return [self.classes_.index(i) for i in x]21    def inverse_transform(self, x): return [self.classes_[i] for i in x]22 23le = DummyLabelEncoder()24 25class DummyModel(nn.Module):26    def __init__(self):27        super().__init__()28        self.embedding = nn.Embedding(len(vocab), 8)29        self.fc = nn.Linear(8, len(le.classes_))30    def forward(self, x):31        x = self.embedding(x)32        x = x.mean(dim=1)33        return self.fc(x)34 35model = DummyModel()36 37def preprocess_input(text):38    tokens = text.lower().split()39    encoded = [vocab.get(token, vocab['<UNK>']) for token in tokens]40    padded = encoded[:MAX_LEN] + [vocab['<PAD>']] * max(0, MAX_LEN - len(encoded))41    return torch.tensor([padded], dtype=torch.long).to(next(model.parameters()).device)42 43# ----- Load CSV from Google Drive -----44file_id = "1yVJh_NVL4Y4YqEXGym47UCK5ZNZgVZYv"45url = f"https://drive.google.com/uc?export=download&id={file_id}"46response = requests.get(url)47csv_text = response.text48 49if csv_text.strip().startswith('<'):50    raise Exception("ERROR: Google Drive link is not returning CSV! Check your sharing settings.")51 52solutions_df = pd.read_csv(StringIO(csv_text), header=0, on_bad_lines='skip')53 54used_solutions = {emotion: set() for emotion in solutions_df['emotion'].unique()}55 56# ----- Data and responses -----57negative_words = [58    "not", "bad", "sad", "anxious", "anxiety", "depressed", "upset", "shit", "stress",59    "worried", "unwell", "struggling", "low", "down", "terrible", "awful",60    "nervous", "panic", "afraid", "scared", "tense", "overwhelmed", "fear", "uneasy"61]62 63responses = {64    "sadness": [65        "It’s okay to feel down sometimes. I’m here to support you.",66        "I'm really sorry you're going through this. Want to talk more about it?",67        "You're not alone — I’m here for you."68    ],69    "anger": [70        "That must have been frustrating. Want to vent about it?",71        "It's okay to feel this way. I'm listening.",72        "Would it help to talk through it?"73    ],74    "love": [75        "That’s beautiful to hear! What made you feel that way?",76        "It’s amazing to experience moments like that.",77        "Sounds like something truly meaningful."78    ],79    "happiness": [80        "That's awesome! What’s bringing you joy today?",81        "I love hearing good news. 😊",82        "Yay! Want to share more about it?"83    ],84    "neutral": [85        "Got it. I’m here if you want to dive deeper.",86        "Thanks for sharing that. Tell me more if you’d like.",87        "I’m listening. How else can I support you?"88    ]89}90 91# --- Helper functions ---92 93def correct_spelling(text):94    return str(TextBlob(text).correct())95 96def get_sentiment(text):97    return TextBlob(text).sentiment.polarity98 99def is_negative_input(text):100    text_lower = text.lower()101    return any(word in text_lower for word in negative_words)102 103def get_unique_solution(emotion):104    available = solutions_df[solutions_df['emotion'] == emotion]105    unused = available[~available['solution'].isin(used_solutions[emotion])]106    if unused.empty:107        used_solutions[emotion] = set()108        unused = available109    solution_row = unused.sample(1).iloc[0]110    used_solutions[emotion].add(solution_row['solution'])111    return solution_row['solution']112 113def get_emotion(user_input):114    if is_negative_input(user_input):115        return "sadness"116    sentiment = get_sentiment(user_input)117    x = preprocess_input(user_input)118    model.train()119    with torch.no_grad():120        probs = torch.stack([F.softmax(model(x), dim=1) for _ in range(5)])121        avg_probs = probs.mean(dim=0)122        prob, idx = torch.max(avg_probs, dim=1)123    pred_emotion = le.classes_[idx.item()]124    if prob.item() < 0.6:125        return "neutral"126    if sentiment < -0.25 and pred_emotion == "happiness":127        return "sadness"128    if sentiment > 0.25 and pred_emotion == "sadness":129        return "happiness"130    return pred_emotion131 132def audio_to_text(audio_file):133    if audio_file is None:134        return ""135    recog = sr.Recognizer()136    with sr.AudioFile(audio_file) as source:137        audio = recog.record(source)138    try:139        text = recog.recognize_google(audio)140        return text141    except Exception:142        return ""143 144# ----- Chat function -----145GLOBAL_CONVO_HISTORY = []146USER_FEEDBACK_STATE = {}147 148def emoti_chat(audio, text, history_json=""):149    if text and text.strip():150        user_input = text151    elif audio is not None:152        user_input = audio_to_text(audio)153    else:154        user_input = ""155    if not user_input.strip():156        return "Please say something or type your message.", json.dumps(GLOBAL_CONVO_HISTORY[-5:], indent=2), ""157 158    user_input = correct_spelling(user_input)159 160    exit_phrases = ["exit", "quit", "goodbye", "bye", "close"]161    if user_input.lower().strip() in exit_phrases:162        return "Take care! I’m here whenever you want to talk. 👋", json.dumps(GLOBAL_CONVO_HISTORY[-5:], indent=2), gr.update(visible=False)163 164    user_id = "default_user"165    state = USER_FEEDBACK_STATE.get(user_id, {"emotion": None, "pending": False})166 167    if state["pending"]:168        feedback = user_input.lower().strip()169        GLOBAL_CONVO_HISTORY[-1]["feedback"] = feedback170        if feedback == "no":171            suggestion = get_unique_solution(state["emotion"])172            reply = f"Here's another suggestion for you: {suggestion}\nDid this help? (yes/no/skip)"173            USER_FEEDBACK_STATE[user_id]["pending"] = True174            return reply, json.dumps(GLOBAL_CONVO_HISTORY[-5:], indent=2), ""175        else:176            USER_FEEDBACK_STATE[user_id] = {"emotion": None, "pending": False}177            return "How can I help you further?", json.dumps(GLOBAL_CONVO_HISTORY[-5:], indent=2), ""178 179    pred_emotion = get_emotion(user_input)180    support = random.choice(responses.get(pred_emotion, responses["neutral"]))181    try:182        suggestion = get_unique_solution(pred_emotion)183    except Exception:184        suggestion = get_unique_solution("neutral")185 186    reply = f"{support}\n\nHere's a suggestion for you: {suggestion}\nDid this help? (yes/no/skip)"187    GLOBAL_CONVO_HISTORY.append({188        "user_input": user_input,189        "emotion": pred_emotion,190        "bot_support": support,191        "bot_suggestion": suggestion,192        "feedback": ""193    })194    USER_FEEDBACK_STATE[user_id] = {"emotion": pred_emotion, "pending": True}195    return reply, json.dumps(GLOBAL_CONVO_HISTORY[-5:], indent=2), ""196 197# ---- Gradio interface ----198iface = gr.Interface(199    fn=emoti_chat,200    inputs=[201        gr.Audio(type="filepath", label="🎤 Speak your message"),202        gr.Textbox(lines=2, placeholder="Or type your message here...", label="💬 Type message"),203        gr.Textbox(lines=1, value="", visible=False)  # hidden, history state204    ],205    outputs=[206        gr.Textbox(label="EmotiBot Reply"),207        gr.Textbox(label="Hidden", visible=False)208    ],209    title="EmotiBot Connect",210    description="Talk to EmotiBot using your voice or by typing. Detects your emotion, gives dynamic suggestions, remembers your feedback, and keeps a conversation history! Type 'exit' to leave."211)212 213if __name__ == "__main__":214    iface.launch(debug=True) 215