358 lines
15 KiB
Python
358 lines
15 KiB
Python
# jokes_v4.py
|
|
import sqlite3
|
|
import random
|
|
from datetime import datetime
|
|
|
|
def initialize_database():
|
|
"""Create the database and tables if they don't exist"""
|
|
conn = sqlite3.connect('jokes.db')
|
|
cursor = conn.cursor()
|
|
|
|
# Create jokes table
|
|
cursor.execute('''CREATE TABLE IF NOT EXISTS jokes (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
joke TEXT NOT NULL,
|
|
contributor TEXT NOT NULL,
|
|
created_date TEXT NOT NULL,
|
|
approved BOOLEAN DEFAULT 0,
|
|
sentiment_score REAL DEFAULT 0.0,
|
|
sentiment_label TEXT DEFAULT '😐 Neutral'
|
|
)''')
|
|
|
|
# Create user_sentiments table with user identifier
|
|
cursor.execute('''CREATE TABLE IF NOT EXISTS user_sentiments (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
joke_id INTEGER NOT NULL,
|
|
user_sentiment TEXT CHECK(user_sentiment IN ('up', 'down', 'neutral')) DEFAULT 'neutral',
|
|
user_identifier TEXT NOT NULL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (joke_id) REFERENCES jokes(id) ON DELETE CASCADE
|
|
)''')
|
|
|
|
# Check if jokes table is empty
|
|
cursor.execute('SELECT COUNT(*) FROM jokes')
|
|
joke_count = cursor.fetchone()[0]
|
|
|
|
if joke_count == 0:
|
|
# Insert sample jokes if table is empty
|
|
sample_jokes = [
|
|
('Why don\'t scientists trust atoms? Because they make up everything!', 'ScienceFan', '2024-01-15 10:30:00', 1),
|
|
('I told my wife she was drawing her eyebrows too high. She looked surprised.', 'Joker123', '2024-01-16 14:20:00', 1),
|
|
('Why did the scarecrow win an award? He was outstanding in his field!', 'FarmLife', '2024-01-17 09:15:00', 1),
|
|
('What do you call a fish with no eyes? Fsh!', 'MarineBio', '2024-01-18 16:45:00', 1),
|
|
('I\'m reading a book on anti-gravity. It\'s impossible to put down!', 'PhysicsNerd', '2024-01-19 11:30:00', 1),
|
|
('Why did the computer go to the doctor? Because it had a virus.', 'TechSupport', '2024-01-20 13:10:00', 1),
|
|
('What do you call a bear with no teeth? A gummy bear.', 'WildlifeFan', '2024-01-21 15:25:00', 1),
|
|
('Why did the bicycle fall over? Because it was two-tired.', 'Cyclist', '2024-01-22 10:00:00', 1),
|
|
('What do you call a sleeping bull? A bulldozer.', 'Cowboy', '2024-01-23 14:35:00', 1),
|
|
('Why did the math book look so sad? Because it had too many problems.', 'Student', '2024-01-24 09:50:00', 1)
|
|
]
|
|
|
|
cursor.executemany('''
|
|
INSERT INTO jokes (joke, contributor, created_date, approved)
|
|
VALUES (?, ?, ?, ?)
|
|
''', sample_jokes)
|
|
|
|
# Add some sample user sentiments with user identifiers
|
|
sample_sentiments = [
|
|
(1, 'up', 'User123'), (1, 'up', 'FunnyPerson'), (1, 'neutral', 'JokeLover'),
|
|
(2, 'down', 'CritiqueMaster'), (2, 'up', 'HappyViewer'),
|
|
(3, 'up', 'User123'), (3, 'up', 'FunnyPerson'), (3, 'up', 'ComedyFan')
|
|
]
|
|
|
|
cursor.executemany('''
|
|
INSERT INTO user_sentiments (joke_id, user_sentiment, user_identifier)
|
|
VALUES (?, ?, ?)
|
|
''', sample_sentiments)
|
|
|
|
conn.commit()
|
|
print(f"✅ Database initialized with {len(sample_jokes)} sample jokes and {len(sample_sentiments)} sample sentiments!")
|
|
else:
|
|
print(f"✅ Connected to database with {joke_count} jokes already present.")
|
|
|
|
conn.close()
|
|
|
|
def get_user_sentiment_for_joke(db, joke_id):
|
|
"""Get the average user sentiment for a specific joke"""
|
|
cursor = db.execute('''
|
|
SELECT
|
|
CASE
|
|
WHEN AVG(CASE WHEN user_sentiment = 'up' THEN 1
|
|
WHEN user_sentiment = 'down' THEN -1
|
|
ELSE 0 END) > 0.1 THEN '👍 Up'
|
|
WHEN AVG(CASE WHEN user_sentiment = 'up' THEN 1
|
|
WHEN user_sentiment = 'down' THEN -1
|
|
ELSE 0 END) < -0.1 THEN '👎 Down'
|
|
ELSE '😐 Neutral'
|
|
END as avg_sentiment,
|
|
COUNT(*) as total_votes
|
|
FROM user_sentiments
|
|
WHERE joke_id = ?
|
|
''', (joke_id,))
|
|
|
|
result = cursor.fetchone()
|
|
avg_sentiment, total_votes = result if result else ('😐 Neutral', 0)
|
|
return avg_sentiment, total_votes
|
|
|
|
def get_detailed_sentiment_stats(db, joke_id):
|
|
"""Get detailed sentiment statistics including user breakdown"""
|
|
cursor = db.execute('''
|
|
SELECT
|
|
user_sentiment,
|
|
COUNT(*) as count,
|
|
GROUP_CONCAT(user_identifier) as users
|
|
FROM user_sentiments
|
|
WHERE joke_id = ?
|
|
GROUP BY user_sentiment
|
|
ORDER BY count DESC
|
|
''', (joke_id,))
|
|
|
|
return cursor.fetchall()
|
|
|
|
def get_user_sentiment_history(db, user_identifier):
|
|
"""Get sentiment history for a specific user"""
|
|
cursor = db.execute('''
|
|
SELECT
|
|
j.id,
|
|
j.joke,
|
|
us.user_sentiment,
|
|
us.created_at
|
|
FROM user_sentiments us
|
|
JOIN jokes j ON us.joke_id = j.id
|
|
WHERE us.user_identifier = ?
|
|
ORDER BY us.created_at DESC
|
|
''', (user_identifier,))
|
|
|
|
return cursor.fetchall()
|
|
|
|
def get_popular_jokes_by_user(db, user_identifier):
|
|
"""Get jokes that a specific user has rated highly"""
|
|
cursor = db.execute('''
|
|
SELECT
|
|
j.id,
|
|
j.joke,
|
|
j.contributor,
|
|
us.user_sentiment,
|
|
us.created_at
|
|
FROM user_sentiments us
|
|
JOIN jokes j ON us.joke_id = j.id
|
|
WHERE us.user_identifier = ? AND us.user_sentiment = 'up'
|
|
ORDER BY us.created_at DESC
|
|
''', (user_identifier,))
|
|
|
|
return cursor.fetchall()
|
|
|
|
def add_user_sentiment(db, joke_id, user_choice, user_identifier):
|
|
"""Add user sentiment for a specific joke with user identification"""
|
|
try:
|
|
# Check if user already rated this joke
|
|
cursor = db.execute('''
|
|
SELECT id FROM user_sentiments
|
|
WHERE joke_id = ? AND user_identifier = ?
|
|
''', (joke_id, user_identifier))
|
|
|
|
existing_rating = cursor.fetchone()
|
|
|
|
if existing_rating:
|
|
# Update existing rating
|
|
db.execute('''
|
|
UPDATE user_sentiments
|
|
SET user_sentiment = ?, created_at = CURRENT_TIMESTAMP
|
|
WHERE joke_id = ? AND user_identifier = ?
|
|
''', (user_choice, joke_id, user_identifier))
|
|
action = "updated"
|
|
else:
|
|
# Insert new rating
|
|
db.execute('''
|
|
INSERT INTO user_sentiments (joke_id, user_sentiment, user_identifier)
|
|
VALUES (?, ?, ?)
|
|
''', (joke_id, user_choice, user_identifier))
|
|
action = "recorded"
|
|
|
|
db.commit()
|
|
return True, action
|
|
except Exception as e:
|
|
print(f"❌ Error saving sentiment: {e}")
|
|
return False, None
|
|
|
|
def get_top_users_by_joke_preference(db):
|
|
"""Get analytics on which users prefer which types of jokes"""
|
|
cursor = db.execute('''
|
|
SELECT
|
|
user_identifier,
|
|
COUNT(*) as total_ratings,
|
|
SUM(CASE WHEN user_sentiment = 'up' THEN 1 ELSE 0 END) as positive_ratings,
|
|
SUM(CASE WHEN user_sentiment = 'down' THEN 1 ELSE 0 END) as negative_ratings,
|
|
ROUND(AVG(CASE WHEN user_sentiment = 'up' THEN 1
|
|
WHEN user_sentiment = 'down' THEN 0
|
|
ELSE 0.5 END) * 100, 1) as positivity_percentage
|
|
FROM user_sentiments
|
|
GROUP BY user_identifier
|
|
HAVING COUNT(*) >= 2
|
|
ORDER BY positivity_percentage DESC, total_ratings DESC
|
|
''')
|
|
|
|
return cursor.fetchall()
|
|
|
|
def main():
|
|
# Initialize database and tables on startup
|
|
initialize_database()
|
|
|
|
db = sqlite3.connect('jokes.db')
|
|
|
|
# Get user identifier for session
|
|
print("🤖 Welcome to Joke Bot! 🤖")
|
|
user_identifier = input("Please enter your username (or press Enter for 'Guest'): ").strip() or "Guest"
|
|
print(f"👤 Logged in as: {user_identifier}")
|
|
|
|
while True:
|
|
print("\n" + "="*40)
|
|
print("🤖 JOKE BOT MENU 🤖")
|
|
print("="*40)
|
|
print("1. Get random joke")
|
|
print("2. Add new joke")
|
|
print("3. View your joke ratings")
|
|
print("4. See what jokes you liked")
|
|
print("5. View community analytics")
|
|
print("6. Quit")
|
|
|
|
choice = input("\nYour choice: ").strip()
|
|
|
|
if choice == "1":
|
|
# Get random approved joke
|
|
cursor = db.execute('''
|
|
SELECT id, joke, contributor
|
|
FROM jokes
|
|
WHERE approved = 1
|
|
ORDER BY RANDOM()
|
|
LIMIT 1
|
|
''')
|
|
joke_data = cursor.fetchone()
|
|
|
|
if joke_data:
|
|
joke_id, joke, contributor = joke_data
|
|
print(f"\n🤣 {joke}")
|
|
print(f" 👤 Contributor: {contributor}")
|
|
|
|
# Get and display user sentiment stats
|
|
avg_sentiment, total_votes = get_user_sentiment_for_joke(db, joke_id)
|
|
if total_votes > 0:
|
|
print(f" 👥 Community Rating: {avg_sentiment} ({total_votes} votes)")
|
|
|
|
# Show detailed breakdown
|
|
detailed_stats = get_detailed_sentiment_stats(db, joke_id)
|
|
if detailed_stats:
|
|
print(" 🔍 Detailed Breakdown:")
|
|
for sentiment, count, users in detailed_stats:
|
|
sentiment_icon = {'up': '👍', 'down': '👎', 'neutral': '😐'}[sentiment]
|
|
print(f" {sentiment_icon} {sentiment.capitalize()}: {count} votes")
|
|
|
|
# Ask user for their sentiment
|
|
print(f"\n🎯 Rate this joke: 👍 (U)p, 👎 (D)own, or (N)eutral?")
|
|
user_input = input("Your choice (u/d/n): ").strip().lower()
|
|
user_choice = 'up' if user_input in ['u', 'up'] else 'down' if user_input in ['d', 'down'] else 'neutral'
|
|
|
|
success, action = add_user_sentiment(db, joke_id, user_choice, user_identifier)
|
|
if success:
|
|
sentiment_text = '👍 Up' if user_choice == 'up' else '👎 Down' if user_choice == 'down' else '😐 Neutral'
|
|
print(f"✅ Your rating ({sentiment_text}) has been {action}!")
|
|
else:
|
|
print("❌ Could not save your rating.")
|
|
else:
|
|
print("❌ No approved jokes in the database yet!")
|
|
|
|
elif choice == "2":
|
|
new_joke = input("Enter your joke: ").strip()
|
|
if not new_joke:
|
|
print("❌ Joke cannot be empty!")
|
|
continue
|
|
|
|
name = input("Your name (or press Enter for 'Anonymous'): ").strip() or "Anonymous"
|
|
|
|
# Get current date/time
|
|
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
try:
|
|
cursor = db.cursor()
|
|
cursor.execute('''
|
|
INSERT INTO jokes (joke, contributor, created_date, approved)
|
|
VALUES (?, ?, ?, 0)
|
|
''', (new_joke, name, current_time))
|
|
|
|
# Get the ID of the newly inserted joke
|
|
new_joke_id = cursor.lastrowid
|
|
|
|
db.commit()
|
|
print("✅ Submitted for approval!")
|
|
except Exception as e:
|
|
print(f"❌ Error saving joke: {e}")
|
|
|
|
elif choice == "3":
|
|
# View user's rating history
|
|
user_history = get_user_sentiment_history(db, user_identifier)
|
|
if user_history:
|
|
print(f"\n📊 Your Joke Ratings History ({len(user_history)} ratings):")
|
|
print("-" * 50)
|
|
for joke_id, joke_text, sentiment, created_at in user_history[:10]: # Show last 10
|
|
sentiment_icon = {'up': '👍', 'down': '👎', 'neutral': '😐'}[sentiment]
|
|
print(f"{sentiment_icon} {joke_text[:50]}{'...' if len(joke_text) > 50 else ''}")
|
|
print(f" Rated: {created_at}")
|
|
print()
|
|
else:
|
|
print(f"📝 {user_identifier}, you haven't rated any jokes yet!")
|
|
|
|
elif choice == "4":
|
|
# See what jokes the user liked
|
|
liked_jokes = get_popular_jokes_by_user(db, user_identifier)
|
|
if liked_jokes:
|
|
print(f"\n😄 Jokes You Liked ({len(liked_jokes)} favorites):")
|
|
print("-" * 50)
|
|
for joke_id, joke_text, contributor, sentiment, created_at in liked_jokes:
|
|
print(f"👍 {joke_text}")
|
|
print(f" 👤 By: {contributor} | ⏰ {created_at}")
|
|
print()
|
|
else:
|
|
print(f"😢 {user_identifier}, you haven't liked any jokes yet!")
|
|
|
|
elif choice == "5":
|
|
# View community analytics
|
|
print("\n📈 COMMUNITY ANALYTICS")
|
|
print("=" * 30)
|
|
|
|
# Top users by positivity
|
|
top_users = get_top_users_by_joke_preference(db)
|
|
if top_users:
|
|
print("\n🏆 Most Positive Users:")
|
|
print("-" * 25)
|
|
for i, (username, total, positive, negative, positivity_pct) in enumerate(top_users[:5], 1):
|
|
print(f"{i}. {username}: {positivity_pct}% positive ({positive}/{total} ratings)")
|
|
|
|
# Overall joke statistics
|
|
cursor = db.execute('''
|
|
SELECT
|
|
COUNT(DISTINCT joke_id) as total_rated_jokes,
|
|
COUNT(*) as total_ratings,
|
|
AVG(CASE WHEN user_sentiment = 'up' THEN 1
|
|
WHEN user_sentiment = 'down' THEN 0
|
|
ELSE 0.5 END) * 100 as overall_positivity
|
|
FROM user_sentiments
|
|
''')
|
|
stats = cursor.fetchone()
|
|
if stats and stats[0] > 0:
|
|
total_jokes, total_ratings, positivity = stats
|
|
print(f"\n📊 Overall Statistics:")
|
|
print(f" Total jokes rated: {total_jokes}")
|
|
print(f" Total ratings: {total_ratings}")
|
|
print(f" Community positivity: {positivity:.1f}%")
|
|
|
|
elif choice == "6":
|
|
print(f"\n👋 Goodbye, {user_identifier}!")
|
|
break
|
|
|
|
else:
|
|
print("❌ Invalid choice. Please select 1-6.")
|
|
|
|
db.close()
|
|
|
|
if __name__ == "__main__":
|
|
main() |