基于Python开发语音助手并实现用户输入存储的技术问询
Hey Lea, let's tackle your three technical questions step by step, plus fix up your existing code to make the storage work smoothly:
1. Dictionary or DataFrame? Which to Choose?
- List of dictionaries is perfect for lightweight, in-memory storage if you only need basic append operations and don’t plan on complex data tasks later. It’s simple, low-overhead, and easy to get started with.
- Pandas DataFrame is better if you want to:
- Filter stories by timestamp, user, or content down the line
- Export stories to CSV/Excel for family sharing
- Run quick analytics (like counting stories added per week)
For your family story keeper use case, I’d recommend starting with a list of dicts (easy to implement) and converting it to a DataFrame later if you need more features. Or go straight for a DataFrame if you know you’ll want those advanced capabilities.
2. How to Split Input into Timestamp & User Input Columns?
You just need to capture the exact time when the user finishes speaking, then pair it with their story. Use datetime.datetime.now() to generate a timestamp, and format it for readability.
Here’s how to structure each entry:
from datetime import datetime # Create a single story entry with timestamp and content story_entry = { "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), # Formatted as "YYYY-MM-DD HH:MM:SS" "user_input": captured_story # The story you get from takeCommand() }
3. How to Add a New Row on Each New User Input?
- If using a list of dicts: Initialize an empty list at the start (e.g.,
story_log = []), then append eachstory_entryto this list every time a user shares a story. - If using a DataFrame: Initialize an empty DataFrame with your columns, then use
pd.concat()(sincedf.append()is deprecated) to add new rows, or assign directly withdf.loc[len(df)] = new_entry.
Fixed & Updated Code
Let’s integrate all this into your existing code, fixing gaps in getstory() and append():
import speech_recognition as sr from datetime import datetime import pandas as pd import pyttsx3 # Initialize speech engine (you likely had this but it was missing in your snippet) engine = pyttsx3.init() def speak(audio): engine.say(audio) engine.runAndWait() def wishMe(): hour = int(datetime.now().hour) if hour >= 0 and hour < 12: speak("Good Morning!") elif hour >= 12 and hour < 18: speak("Good Afternoon!") else: speak("Good Evening!") assistantname = "Anna" speak("I am your personal storykeeper " + assistantname) # Note: Speech might have a tiny delay due to engine processing, but it will follow sequentially def username(): speak("I would love to know more about you, so let's start off right away. What's your name?") username = takeCommand() while username == "None": # Retry if recognition fails username = takeCommand() speak("Nice to meet you " + username + ".") print("Nice to meet you " + username + ".") return username # Return name to link with stories def storykeepergoal(): speak("Would you like to know more about my goal to conserve your family's stories?") query = takeCommand().lower() if "yes" in query: msg = "Happy that you are interested to learn more about me. You've probably experienced the moment at a family's birthday party when it's all about telling stories from when you were little, or a funny story about a vacation. As life goes on, those stories might be forgotten or cannot be told anymore. This is where I come in - by telling me stories about your favourite moments in life, I can store these forever. Your family can do the same thing. And if you would like to hear a story that your family members told me, you can tune in." speak(msg) print(msg) else: speak("Alright, no problem.") print("Alright, no problem.") def takeCommand(): r = sr.Recognizer() with sr.Microphone() as source: print("Listening...") r.pause_threshold = 1 audio = r.listen(source) try: print("Recognizing...") query = r.recognize_google(audio, language='en-GB') print(f"User said: {query}\n") except Exception as e: print(e) speak("My apologies, I did not understand that. Could you please say that again?") print("My apologies, I did not understand that. Could you please say that again?") return "None" return query # Initialize storage (pick one option) # Option 1: Lightweight list of dicts story_log = [] # Option 2: Feature-rich DataFrame # story_df = pd.DataFrame(columns=["timestamp", "user_input", "username"]) def getstory(username): speak("I am curious to hear what memories and stories you have about your family. Please tell me your favourite memory with, or about your family.") user_story = takeCommand() while user_story == "None": # Ensure we get a valid story user_story = takeCommand() # Create timestamped entry timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") story_entry = { "timestamp": timestamp, "user_input": user_story, "username": username # Optional: Track who shared the story } # Add to storage story_log.append(story_entry) # For DataFrame: # global story_df # story_df = pd.concat([story_df, pd.DataFrame([story_entry])], ignore_index=True) speak("Thank you for sharing that story! I've saved it for you.") print(f"Story saved at {timestamp}:\n{user_story}\n") def view_stories(): # Optional: View all saved stories print("=== Saved Family Stories ===") # For list of dicts for idx, entry in enumerate(story_log, 1): print(f"\nStory {idx}:") print(f"Timestamp: {entry['timestamp']}") print(f"Shared by: {entry['username']}") print(f"Content: {entry['user_input']}") # For DataFrame: # print(story_df.to_string(index=False)) # Run the assistant if __name__ == "__main__": wishMe() user_name = username() storykeepergoal() getstory(user_name) # Example: Add another story later # speak("Would you like to share another story?") # if "yes" in takeCommand().lower(): # getstory(user_name) # View all saved stories view_stories()
Key Improvements:
- Added speech engine initialization (missing in your original snippet)
- Made
username()return the user’s name to link stories with contributors - Fixed
getstory()to capture valid input, create timestamped entries, and save them - Added a
view_stories()function to check stored entries - Included retry logic in
takeCommand()to handle recognition failures - Offered both storage options so you can pick what fits your needs
内容的提问来源于stack exchange,提问作者Lea

