import re import yaml from collections import deque from fuzzywuzzy import process from nltk.corpus import stopwords from nltk.tokenize import word_tokenize from nltk import download from rich.console import Console download('punkt') download('stopwords') def apply_rule(sentence, pattern, transformation): pattern = pattern.replace("*", "(.*)") # Replace * with a capturing group match = re.search(pattern, sentence, re.IGNORECASE) if match: if match.groups(): # Check if there are any capturing groups return transformation.replace("*", match.group(1)) else: return transformation return sentence class ElizaBot: def __init__(self, config_file): try: with open(config_file) as file: config = yaml.safe_load(file) self.keywords = config['keywords'] self.rules = {key: [(rule['pattern'], rule['response']) for rule in rules] for key, rules in config['rules'].items()} self.memory_queue = deque(maxlen=5) self.console = Console() self.stop_words = set(stopwords.words('english')) except Exception as e: print(f"Error loading YAML file: {e}") exit(1) def preprocess_sentence(self, sentence): words = word_tokenize(sentence.lower()) return ' '.join([word for word in words if word not in self.stop_words]) def find_closest_keyword(self, sentence, threshold=70): processed_sentence = self.preprocess_sentence(sentence) matches = process.extractOne(processed_sentence, self.keywords.keys(), score_cutoff=threshold) return matches[0] if matches else None def eliza_generator(self, user_sentence): selected_word = self.find_closest_keyword(user_sentence) if selected_word: for pattern, transformation in self.rules.get(selected_word, []): response = apply_rule(user_sentence, pattern, transformation) if response != user_sentence: if selected_word == 'my': future_response = apply_rule(user_sentence, "my *", "Earlier, you mentioned your *.") self.memory_queue.append(future_response) return response return self.memory_queue.popleft() if self.memory_queue else "Tell me more." def chat(self): self.console.print("ELISE: Hi! I'm here to chat. What's on your mind?", style="bold green") while True: user_input = self.console.input("[bold blue]You: [/]") if user_input.lower() == 'quit': self.console.print("ELISE: Goodbye! Take care.", style="bold green") break response = self.eliza_generator(user_input) self.console.print(f"ELISE: {response}", style="bold green") if __name__ == "__main__": eliza = ElizaBot("eliza_rules.yaml") eliza.chat()