-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmemory10.py
More file actions
327 lines (288 loc) · 13.2 KB
/
memory10.py
File metadata and controls
327 lines (288 loc) · 13.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
from gtts import gTTS
import os
import pygame
import json
from openai import OpenAI
import speech_recognition as sr
import io
import re
import time
import threading
from pynput import keyboard
from num2words import num2words
from sumy.parsers.plaintext import PlaintextParser
from sumy.nlp.tokenizers import Tokenizer
from sumy.summarizers.lex_rank import LexRankSummarizer
from sumy.utils import get_stop_words
from text2digits import text2digits
pygame.init()
pygame.mixer.init()
pygame.mixer.get_init()
client = OpenAI()
class UserProfileManager:
def summarize(text, word_count=15):
parser = PlaintextParser.from_string(text, Tokenizer("english"))
summarizer = LexRankSummarizer()
summarizer.stop_words = get_stop_words("english")
summary = summarizer(parser.document, word_count)
return " ".join([str(sentence) for sentence in summary])
def __init__(self, file_path):
self.file_path = file_path
self.profiles = self.load_profiles()
OpenAI.api_key = os.getenv("OPENAI_API_KEY")
self.recognizer = sr.Recognizer()
self.skip_current_tts = False # Renamed from skip_tts
self.t2d = text2digits.Text2Digits()
# Set up keyboard listener
self.listener = keyboard.Listener(on_press=self.on_press)
self.listener.start()
def on_press(self, key):
if key == keyboard.KeyCode.from_char('s'):
self.skip_current_tts = True # Updated to use skip_current_tts
print("Skipping current TTS output...")
else:
self.skip_current_tts = False # Updated to use skip_current_tts
def text_to_speech(self, text):
if not self.skip_current_tts:
# Convert numbers to words using num2words
text = re.sub(r'\b(\d+)\b', lambda m: num2words(int(m.group(0))), text)
tts = gTTS(text=text, lang='en')
output_file_path = "output.wav"
audio_data = io.BytesIO()
tts.write_to_fp(audio_data)
audio_data.seek(0)
try:
pygame.mixer.music.load(audio_data)
except pygame.error as e:
if "unsupported audio format" in str(e):
print("Unsupported audio format. Skipping TTS output...")
else:
raise e
else:
print(f"Text-to-speech audio saved as '{output_file_path}'.")
def play_tts():
try:
pygame.mixer.music.play()
while pygame.mixer.music.get_busy():
if self.skip_current_tts:
pygame.mixer.music.stop()
print("Current TTS output skipped.")
break
except pygame.error as e:
if "unsupported audio format" in str(e):
print("Unsupported audio format. Skipping TTS output...")
else:
raise e
# Start the TTS playback in a separate thread
tts_thread = threading.Thread(target=play_tts)
tts_thread.start()
# Print the TTS output while the TTS is playing
for char in text:
if self.skip_current_tts:
break
print(char, end='', flush=True)
time.sleep(0.075) # Adjust the sleep time to control the speed of printing (lower value = faster)
# Wait for the TTS thread to finish
tts_thread.join()
self.skip_current_tts = False
def speech_to_text(self):
with sr.Microphone() as source:
print("Speak now...")
audio = self.recognizer.listen(source)
try:
text = self.recognizer.recognize_whisper_api(audio)
print(f"You said: {text}")
return text
except sr.UnknownValueError:
print("Sorry, I could not understand your speech.")
self.text_to_speech("Sorry, I could not understand your speech.")
return None
except sr.RequestError as e:
print(f"Could not request results from the speech recognition service; {e}")
self.text_to_speech(f"Could not request results from the speech recognition service; {e}")
return None
def play_wav(self, output):
try:
pygame.mixer.music.load(output)
pygame.mixer.music.play()
while pygame.mixer.music.get_busy():
continue
except pygame.error as e:
if "unsupported audio format" in str(e):
print("Unsupported audio format. Skipping WAV playback...")
else:
raise e
def load_profiles(self):
try:
with open(self.file_path, 'r') as file:
return json.load(file)
except FileNotFoundError:
return {}
except json.JSONDecodeError:
print("Error: Invalid JSON file. Creating a new empty dictionary.")
return {}
def save_profiles(self):
with open(self.file_path, 'w') as file:
json.dump(self.profiles, file, indent=2)
def create_profile(self, name, age, interests):
# Convert number words to digits in the age
age = self.t2d.convert(age)
# Remove any non-digit characters from the age``
age = ''.join(char for char in age if char.isdigit())
if name not in self.profiles:
self.profiles[name] = {'age': age, 'interests': interests}
print(f"Profile created for {name}")
self.save_profiles()
# Perform TTS and save as WAV
self.text_to_speech(f"Great, I've created a new profile for {name}. "
"Is there anything else you'd like to do?")
else:
print(f"Sorry, a profile with the name '{name}' already exists. "
"Would you like to try again with a different name?")
def words_to_number(self, text):
word_to_number = {
'zero': '0',
'one': '1',
'two': '2',
'three': '3',
'four': '4',
'five': '5',
'six': '6',
'seven': '7',
'eight': '8',
'nine': '9',
'ten': '10',
# Add more mappings as needed
}
words = text.split()
numbers = []
for word in words:
if word.lower() in word_to_number:
numbers.append(word_to_number[word.lower()])
else:
numbers.append(word)
return ' '.join(numbers)
def activate_profile(self, name):
for profile_name in self.profiles:
if profile_name.lower() == name.lower():
profile = self.profiles[profile_name]
self.name = profile_name
self.age = profile['age']
self.interests = profile['interests']
print(f"{profile_name}'s profile has been activated!")
self.text_to_speech(f"{profile_name}'s profile has been activated!")
return True
print(f"{name}'s profile does not exist. Please enter a valid Name.")
self.text_to_speech(f"{name}'s profile does not exist. Please enter a valid Name.")
return False
def edit_profile(self, name, field, new_value):
valid_fields = ['age', 'interests', 'name']
for profile_name in self.profiles:
if profile_name.lower() == name.lower():
if field.lower() in valid_fields:
if field.lower() == 'name':
self.profiles[new_value.capitalize()] = self.profiles.pop(profile_name)
else:
self.profiles[profile_name][field] = new_value
print(f"{profile_name}'s profile has been updated!")
self.save_profiles()
self.text_to_speech(f"{profile_name}'s profile has been updated!")
return True
else:
print(f"{field} is not a valid field in {profile_name}'s profile. Valid fields are 'age', 'interests', and 'name'.")
self.text_to_speech(f"{field} is not a valid field in {profile_name}'s profile. Valid fields are 'age', 'interests', and 'name'.")
return False
print(f"{name}'s profile does not exist. Please enter a valid Name.")
self.text_to_speech(f"{name}'s profile does not exist. Please enter a valid Name.")
return False
def view_profiles(self):
print("User Profiles:")
for profile_name in self.profiles:
profile = self.profiles[profile_name]
print(f"Name: {profile_name}, Age: {profile['age']}, Interests: {profile['interests']}")
def chat(self, user_input):
conversation_history = [{"role": "system", "content": f"You are an assistant talking to {self.name} who is {self.age} years old. They enjoy {self.interests}."}]
# Append user input to conversation history
conversation_history.append({"role": "user", "content": user_input})
# Call the OpenAI API with the conversation history
completion = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=conversation_history,
)
# Append the bot's response to the conversation history
response = completion.choices[0].message.content
conversation_history.append({"role": "assistant", "content": response})
return response
def chat_with_gpt(self):
while True:
user_input = self.speech_to_text()
if user_input.lower() == "quit" or user_input.lower() == "exit":
break
response = self.chat(user_input)
print("ChatGPT: ", response)
self.text_to_speech(response)
# Example usage
file_path = "user_profiles.json"
user_manager = UserProfileManager(file_path)
first_time = True
activate = False
choice = True
while True:
if first_time == True:
user_manager.text_to_speech("1. Create Profile\n2. Activate Profile\n3. Edit Profile\n4. View Profiles\n5. Exit")
user_manager.text_to_speech("Please pick an option by speaking:")
first_time = False
elif first_time == False:
user_manager.text_to_speech("Please pick one of the options.")
choice = user_manager.speech_to_text()
if choice is None:
user_manager.text_to_speech("None were picked")
continue
choice = choice.lower()
if "1" in choice or "one" in choice or "create" in choice or "number one" in choice:
print("Okay, I'll create a new profile. Please tell me the name, age, and interests for the profile.")
user_manager.text_to_speech("What is the name of the new profile?")
name = user_manager.speech_to_text()
if name is None:
break
user_manager.text_to_speech("What is the age of the new profile?")
age = user_manager.speech_to_text()
if age is None:
continue
user_manager.text_to_speech("What are the interests of the new profile?")
interests = user_manager.speech_to_text()
if interests is None:
continue
user_manager.create_profile(name, age, interests)
elif "2" in choice or "two" in choice or "activate" in choice or "number two" in choice:
activated = True
user_manager.text_to_speech("What is the name of the profile you want to activate?")
name = user_manager.speech_to_text()
if name is None:
continue
user_manager.text_to_speech(f"Activating profile for {name}.")
user_manager.activate_profile(name)
user_manager.chat_with_gpt()
elif "3" in choice or "three" in choice or "edit" in choice or "number three" in choice:
user_manager.text_to_speech("What is the name of the profile you want to edit?")
name = user_manager.speech_to_text()
if name is None:
continue
user_manager.text_to_speech("Which field of the profile would you like to edit, (age or interests)?")
field = user_manager.speech_to_text()
if field is None:
continue
user_manager.text_to_speech(f"What is the new value for {field}?")
new_value = user_manager.speech_to_text()
if new_value is None:
continue
user_manager.edit_profile(name, field, new_value)
elif "4" in choice or "four" in choice or "view" in choice or "number four" in choice:
user_manager.view_profiles()
elif "5" in choice or "five" in choice or "exit" in choice or "number five" in choice:
user_manager.text_to_speech("Exiting the program. Goodbye!")
import time
time.sleep(1.5)
break
else:
user_manager.text_to_speech("Invalid choice. Please enter a valid option.")