diff --git a/Joke Bot Upgrade_ SQLite Database Integration _ Beginner's Guide.html b/Joke Bot Upgrade_ SQLite Database Integration _ Beginner's Guide.html index c29734a..70c20db 100644 --- a/Joke Bot Upgrade_ SQLite Database Integration _ Beginner's Guide.html +++ b/Joke Bot Upgrade_ SQLite Database Integration _ Beginner's Guide.html @@ -1,5 +1,5 @@ - + @@ -161,6 +161,62 @@ font-size: 0.9rem; } + /* Points System */ + .points-system { + background: #fff3cd; + padding: 25px; + border-radius: 10px; + margin: 25px 0; + border: 2px solid #ffc107; + } + + .points-header { + display: flex; + align-items: center; + margin-bottom: 20px; + } + + .points-emoji { + font-size: 2.5rem; + margin-right: 15px; + } + + .points-title { + color: #856404; + font-weight: 700; + font-size: 1.4rem; + } + + .points-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 15px; + margin-top: 20px; + } + + .point-card { + background: white; + padding: 15px; + border-radius: 8px; + border-left: 4px solid #28a745; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + } + + .point-emoji { + font-size: 1.8rem; + margin-bottom: 10px; + } + + .point-value { + background: #28a745; + color: white; + padding: 2px 8px; + border-radius: 12px; + font-size: 0.9rem; + font-weight: bold; + margin-right: 5px; + } + /* Database Concepts */ .database-concept { background: #fff; @@ -177,6 +233,58 @@ display: block; } + /* Setup Box */ + .setup-box { + background: #e8f4f8; + padding: 20px; + border-radius: 8px; + margin: 15px 0; + border-left: 4px solid #3498db; + } + + .setup-step { + margin-bottom: 15px; + padding-left: 10px; + } + + .setup-step:last-child { + margin-bottom: 0; + } + + .step-number { + background: #3498db; + color: white; + width: 24px; + height: 24px; + border-radius: 12px; + display: inline-flex; + align-items: center; + justify-content: center; + margin-right: 10px; + font-weight: bold; + font-size: 0.9rem; + } + + /* Terminal */ + .terminal { + background: #2c3e50; + color: #ecf0f1; + padding: 15px; + border-radius: 6px; + font-family: 'Courier New', monospace; + font-size: 0.9rem; + margin: 15px 0; + overflow-x: auto; + } + + .terminal-command { + color: #3498db; + } + + .terminal-comment { + color: #7f8c8d; + } + /* Navigation */ .navigation { display: flex; @@ -216,6 +324,28 @@ font-size: 0.95rem; } + /* Learning Outcomes */ + .outcomes-box { + background: #d4edda; + padding: 25px; + border-radius: 10px; + margin: 25px 0; + border: 2px solid #c3e6cb; + } + + .outcome-item { + display: flex; + align-items: flex-start; + margin-bottom: 15px; + } + + .outcome-check { + color: #155724; + font-size: 1.2rem; + margin-right: 15px; + flex-shrink: 0; + } + /* Responsive */ @media (max-width: 768px) { .slide { @@ -238,6 +368,10 @@ padding: 20px; font-size: 0.85rem; } + + .points-grid { + grid-template-columns: 1fr; + } } @@ -256,12 +390,540 @@

Goal: Upgrade joke bot with database, user submissions, and ratings

Prerequisites: Basic Python knowledge, our existing joke bot

Time: 60 minutes to complete upgrade

+

Tools: Python IDLE, Command Line/PowerShell

- +
+

How You Earn Points in Class! 🌟

+ +
+
+
šŸ†
+
+

EARN UP TO 5 POINTS EACH DAY!

+

Track your progress and earn rewards for active participation

+
+
+ +
+
+
āœ…
+

+2 You Came to Class!

+

Great job! Just by being in class, you get 2 points. Yay!

+
+ +
+
šŸ‘‚
+

+1 You Listened Quietly!

+

You didn't talk when the teacher was talking. Good listening!

+
+ +
+
āœļø
+

+1 You Tried Your Work!

+

You didn't finish everything? That's OK! If you tried, you still get a point.

+
+ +
+
šŸŽ‰
+

+1 You Finished ALL Your Work!

+

Wow! You did every single part — even the last task! You get a big high-five!

+
+
+ +
+

šŸ“Š Points Legend:

+

H = You were here! Points depend on what you did.

+

— = You were absent → 0 points

+
+
+ +
+ Today's Goal: +

Complete ALL steps of the joke bot upgrade to earn the full 5 points! šŸŽÆ

+

Follow along, ask questions, and help your classmates to maximize your learning!

+
+
+ + +
+

Learning Outcomes

+

By the end of this session, you will be able to:

+ +
+
+
āœ“
+
+

1. Understand SQLite Database Basics

+

Explain what SQLite is and why it's perfect for small Python projects

+
+
+ +
+
āœ“
+
+

2. Design Database Tables

+

Create tables with proper columns, data types, and relationships

+
+
+ +
+
āœ“
+
+

3. Implement CRUD Operations

+

Write Python code to Create, Read, Update, and Delete database records

+
+
+ +
+
āœ“
+
+

4. Integrate Database with Telegram Bot

+

Connect your existing joke bot to a persistent database

+
+
+ +
+
āœ“
+
+

5. Add User Interaction Features

+

Implement joke submission, rating system, and statistics

+
+
+ +
+
āœ“
+
+

6. Use Virtual Environments

+

Set up and manage Python dependencies using venv

+
+
+
+ +
+

Why These Skills Matter:

+
+
šŸ’¼
+
Industry Standard: Databases are used in 99% of real-world applications
+
+ +
+
šŸš€
+
Career Boost: Database skills are highly sought after by employers
+
+ +
+
🧠
+
Problem Solving: Learn to structure and manage complex data
+
+ +
+
šŸ“±
+
App Development: Build apps that remember user data between sessions
+
+
+
+ + +
+

Why Databases Matter

+

Moving beyond simple lists to persistent storage

+ +
+ The Problem with Lists: +

Our current joke bot stores jokes in a Python list:

+
+JOKE_LIST = [ + "Why did the robot go to school? To recharge his brain! šŸ”‹", + "Knock knock!\nWho's there?\nLettuce!\nLettuce who?\nLettuce in!", + "Why don't eggs tell jokes? They'd crack each other up! 🄚" +]
+

Problems:

+

• Jokes are lost when bot restarts

+

• No way for users to add jokes

+

• Can't track ratings or popularity

+

• Hard to search or organize jokes

+
+ +
+

Database Advantages:

+
+
šŸ’¾
+
Persistence: Data survives bot restarts and crashes
+
+ +
+
šŸ‘„
+
User Contributions: Community can add content
+
+ +
+
šŸ“Š
+
Analytics: Track what jokes are popular
+
+ +
+
šŸ”
+
Searchability: Find jokes by keywords or ratings
+
+ +
+
⚔
+
Scalability: Handle thousands of jokes efficiently
+
+
+ +
+

Real-World Examples:

+

Reddit: Database stores posts, votes, comments, user profiles

+

YouTube: Database stores videos, views, likes, subscriptions

+

Banking Apps: Database stores accounts, transactions, balances

+

Games: Database stores player scores, achievements, progress

+
+
+ + +
+

Step-by-Step Setup Guide

+

Before We Start - Check Your Python Installation

+ +
+
+ 1 + Open Command Prompt or PowerShell: +

Press Windows + R, type cmd or powershell, press Enter

+
+ +
+ 2 + Check Python Version: +

Type the following command and press Enter:

+
+
+ +
+ python --version
+ # Should show: Python 3.x.x

+ + # If that doesn't work, try:
+ python3 --version
+ # Or on some systems:
+ py --version +
+ +
+ Troubleshooting: +

If Python is not installed:

+

1. Go to python.org/downloads

+

2. Download Python 3.9 or later

+

3. Run installer (CHECK "Add Python to PATH" option!)

+

4. Restart your computer, then try again

+
+ +
+

Verify Installation:

+

Open Python IDLE to test:

+
+ python
+ # You should see Python interactive shell:
+ Python 3.9.0 (tags/v3.9.0:9cf6752, Oct 5 2020, 15:34:40) ...
+ Type "help", "copyright", "credits" or "license" for more information.
+ >>> print("Hello, World!")
+ Hello, World!
+ >>> exit()
+ # Type exit() to leave Python shell +
+
+
+ + +
+

Create Your Project Folder

+

Organize your files properly from the start

+ +
+
+ 1 + Open PowerShell or Command Prompt: +

Make sure you're not in the Python shell (should see C:\> or PS C:\>)

+
+ +
+ 2 + Navigate to Desktop or Documents: +

Let's create a folder on your Desktop for easy access:

+
+
+ +
+ # Go to Desktop (Windows)
+ cd Desktop

+ + # Create a new folder for your joke bot
+ mkdir joke_bot_upgrade

+ + # Go into your new folder
+ cd joke_bot_upgrade

+ + # Verify you're in the right place
+ pwd
+ # Should show: C:\Users\YourName\Desktop\joke_bot_upgrade
+ # Or use 'dir' to see files (should be empty)
+ dir +
+ +
+ Folder Structure: +
+joke_bot_upgrade/ +ā”œā”€ā”€ app.py # Main bot file +ā”œā”€ā”€ database.py # SQLite database class +ā”œā”€ā”€ joke_bot.db # Database file (auto-created) +ā”œā”€ā”€ requirements.txt # Python dependencies +└── venv/ # Virtual environment (we'll create this)
+

Best Practice: Keep all related files in one folder for easy management!

+
+
+ + +
+

Set Up Virtual Environment (venv)

+

Isolate project dependencies for clean development

+ +
+
+ 1 + Why Virtual Environment? +

• Keeps project dependencies separate

+

• Avoids version conflicts between projects

+

• Makes sharing and deployment easier

+
+ +
+ 2 + Create Virtual Environment: +

Make sure you're in your joke_bot_upgrade folder, then run:

+
+
+ +
+ # Create virtual environment named 'venv'
+ python -m venv venv

+ + # Check if venv folder was created
+ dir
+ # You should see a 'venv' folder in the list +
+ +
+ What Happened? +

The venv command created a complete Python installation in the venv folder:

+

• Python interpreter copy

+

• pip (package installer)

+

• Standard library

+

• Empty site-packages for our libraries

+
+ +
+

Activate Virtual Environment:

+

Windows PowerShell:

+
+ venv\Scripts\Activate.ps1
+ # If you get an error about execution policy, run this first:
+ Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
+ venv\Scripts\Activate.ps1 +
+ +

Windows Command Prompt:

+
+ venv\Scripts\activate.bat +
+ +

Mac/Linux Terminal:

+
+ source venv/bin/activate +
+ +

Success Indicator: You should see (venv) at the start of your command line!

+
+
+ + +
+

Install Required Libraries

+

Get the Python packages we need for our upgraded bot

+ +
+
+ 1 + First, activate your venv: +

Make sure you see (venv) before the prompt

+
+ +
+ 2 + Install python-telegram-bot: +

This is the main library for creating Telegram bots

+
+
+ +
+ # Install the Telegram bot library (version 20.3)
+ pip install python-telegram-bot==20.3

+ + # Verify installation
+ pip show python-telegram-bot
+ # Should show version 20.3 +
+ +
+ What We're Installing: +

python-telegram-bot: Official library for Telegram Bot API

+

Version 20.3: Specific version that matches our code examples

+

Note: SQLite comes built-in with Python - no need to install!

+
+ +
+

Create Requirements File:

+

Save the list of dependencies for future use:

+
+ pip freeze > requirements.txt

+ + # View the requirements file
+ type requirements.txt
+ # (Mac/Linux: use 'cat requirements.txt' instead of 'type') +
+ +

requirements.txt contents:

+
+python-telegram-bot==20.3
+ +

Why this matters: Anyone can install exact same versions with pip install -r requirements.txt

+
+ +
+
+ 3 + Test Your Setup: +

Open Python IDLE or use Python shell to test imports:

+
+
+ +
+ # Open Python interactive shell
+ python

+ + # Try importing the libraries
+ >>> import sqlite3
+ >>> from telegram import Update
+ >>> from telegram.ext import Application
+ >>> print("All imports successful!")
+ All imports successful!
+ >>> exit() +
+
+ + +
+

Copy Existing Bot Code

+

Start with our working joke bot and upgrade it

+ +
+
+ 1 + Create app.py file: +

In your joke_bot_upgrade folder, create a new file:

+
+
+ +
+ # Using Python IDLE or any text editor:
+ notepad app.py
+ # (Or use VS Code, Sublime Text, or Python's IDLE) +
+ +
+ Our Starting Code: +

Copy this code into app.py - this is our current working bot:

+
from telegram import Update +from telegram.ext import Application, CommandHandler, ContextTypes +import random + +JOKE_LIST = [ + "Why did the robot go to school? To recharge his brain! šŸ”‹", + "Knock knock!\nWho's there?\nLettuce!\nLettuce who?\nLettuce in!", + "Why don't eggs tell jokes? They'd crack each other up! 🄚" +] + +async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): + await update.message.reply_text("Hi! Type /joke for a funny joke! šŸ˜„") + +async def send_joke(update: Update, context: ContextTypes.DEFAULT_TYPE): + joke = random.choice(JOKE_LIST) + await update.message.reply_text(joke) + +def main(): + # Using the provided bot token + BOT_TOKEN = "YOUR_BOT_TOKEN_HERE" + + app = Application.builder().token(BOT_TOKEN).build() + app.add_handler(CommandHandler("start", start)) + app.add_handler(CommandHandler("joke", send_joke)) + print("Bot is running... Press Ctrl+C to stop.") + app.run_polling() + +if __name__ == "__main__": + main()
+
+ +
+

Important: Get Your Bot Token

+
+
1
+
Open Telegram: Search for @BotFather
+
+ +
+
2
+
Create New Bot: Type /newbot and follow instructions
+
+ +
+
3
+
Get Token: Copy the token (looks like: 1234567890:ABCdefGHIjklMNOpqrsTUVwxyz)
+
+ +
+
4
+
Replace in Code: Change YOUR_BOT_TOKEN_HERE with your actual token
+
+
+ +
+
+ 2 + Test Current Bot: +

Make sure the basic bot works before we upgrade it:

+
+
+ +
+ # Make sure venv is activated and you're in the right folder
+ (venv) C:\Users\YourName\Desktop\joke_bot_upgrade> python app.py

+ + # Should see:
+ Bot is running... Press Ctrl+C to stop.

+ + # Open Telegram, find your bot, type /start and /joke
+ # Press Ctrl+C to stop the bot when done testing +
+
+ + +

What Is SQLite?

Serverless, self-contained SQL database perfect for Telegram bots

@@ -321,8 +983,8 @@ conn.commit() conn.close()
- -
+ +

Our Upgrade Goals

From static list to dynamic, user-powered joke database

@@ -378,8 +1040,8 @@ conn.close()
- -
+ +

Step 1: Database Setup (10 minutes)

Create the SQLite database and connection functions

@@ -475,8 +1137,8 @@ conn.close()
- -
+ +

Step 2: Database Operations (15 minutes)

Add CRUD (Create, Read, Update, Delete) functions

@@ -568,8 +1230,8 @@ conn.close()
- -
+ +

Step 3: Rating System (15 minutes)

Implement like/dislike functionality with vote tracking

@@ -597,7 +1259,7 @@ conn.close()
cursor.execute('''DELETE FROM ratings WHERE user_id = ? AND joke_id = ?''', (user_id, joke_id)) - # Update joke counts + # Update joke counts if old_vote == 1: cursor.execute('''UPDATE jokes SET likes = likes - 1 WHERE id = ?''', (joke_id,)) @@ -605,11 +1267,11 @@ conn.close()
cursor.execute('''UPDATE jokes SET dislikes = dislikes - 1 WHERE id = ?''', (joke_id,)) elif old_vote != vote: - # Change vote + # Change vote cursor.execute('''UPDATE ratings SET vote = ? WHERE user_id = ? AND joke_id = ?''', (vote, user_id, joke_id)) - # Update joke counts (remove old, add new) + # Update joke counts (remove old, add new) if old_vote == 1 and vote == -1: cursor.execute('''UPDATE jokes SET likes = likes - 1, dislikes = dislikes + 1 @@ -620,11 +1282,11 @@ conn.close() WHERE id = ?''', (joke_id,)) else: if vote != 0: - # New vote + # New vote cursor.execute('''INSERT INTO ratings (user_id, joke_id, vote) VALUES (?, ?, ?)''', (user_id, joke_id, vote)) - # Update joke counts + # Update joke counts if vote == 1: cursor.execute('''UPDATE jokes SET likes = likes + 1 WHERE id = ?''', (joke_id,)) @@ -634,14 +1296,14 @@ conn.close() conn.commit() - # Get updated joke info + # Get updated joke info cursor.execute("SELECT likes, dislikes FROM jokes WHERE id = ?", (joke_id,)) result = cursor.fetchone() conn.close() return { 'likes': result[0] if result else 0, - 'dislikes': result[1] if result else 0 + 'dislikes': result[1] else 0 } def get_user_vote(self, user_id, joke_id): @@ -678,8 +1340,8 @@ conn.close() - -
+ +

Step 4: Telegram Bot Integration (15 minutes)

Update app.py to use the database

@@ -766,7 +1428,7 @@ Now with database, user submissions, and ratings!"""
User Context: Remember last joke for rating
- šŸ“Š
+ šŸ“Š
Real Stats: Display actual like/dislike counts
@@ -776,699 +1438,6 @@ Now with database, user submissions, and ratings!"""
- -
-

Step 5: Rating Commands (10 minutes)

-

Add like/dislike commands and callback handlers

- -
async def like_joke(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handle /like command""" - user_id = update.effective_user.id - - # Get last joke from context or arguments - if context.args and context.args[0].isdigit(): - joke_id = int(context.args[0]) - elif 'last_joke_id' in context.user_data: - joke_id = context.user_data['last_joke_id'] - else: - await update.message.reply_text( - "Please view a joke first with /joke, or specify a joke ID: /like 123" - ) - return - - # Rate the joke - result = db.rate_joke(user_id, joke_id, 1) - joke = db.get_joke_by_id(joke_id) - - if joke: - await update.message.reply_text( - f"šŸ‘ Liked joke #{joke_id}!\n" - f"Current rating: {result['likes']} šŸ‘ {result['dislikes']} šŸ‘Ž" - ) - else: - await update.message.reply_text("Joke not found!") - -async def dislike_joke(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handle /dislike command""" - user_id = update.effective_user.id - - if context.args and context.args[0].isdigit(): - joke_id = int(context.args[0]) - elif 'last_joke_id' in context.user_data: - joke_id = context.user_data['last_joke_id'] - else: - await update.message.reply_text( - "Please view a joke first with /joke, or specify a joke ID: /dislike 123" - ) - return - - result = db.rate_joke(user_id, joke_id, -1) - joke = db.get_joke_by_id(joke_id) - - if joke: - await update.message.reply_text( - f"šŸ‘Ž Disliked joke #{joke_id}!\n" - f"Current rating: {result['likes']} šŸ‘ {result['dislikes']} šŸ‘Ž" - ) - else: - await update.message.reply_text("Joke not found!") - -async def button_callback(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Handle inline button clicks""" - query = update.callback_query - await query.answer() - - data = query.data - user_id = query.from_user.id - - if data.startswith('like_'): - joke_id = int(data.split('_')[1]) - result = db.rate_joke(user_id, joke_id, 1) - await query.edit_message_text( - text=query.message.text.split('\n\n')[0] + - f"\n\nšŸ‘ {result['likes']} šŸ‘Ž {result['dislikes']}", - reply_markup=query.message.reply_markup - ) - elif data.startswith('dislike_'): - joke_id = int(data.split('_')[1]) - result = db.rate_joke(user_id, joke_id, -1) - await query.edit_message_text( - text=query.message.text.split('\n\n')[0] + - f"\n\nšŸ‘ {result['likes']} šŸ‘Ž {result['dislikes']}", - reply_markup=query.message.reply_markup - )
- -
-

Rating Features:

-
-
1
-
Multiple Methods: Command or inline button
-
-
-
2
-
Flexible Targeting: By ID or last viewed joke
-
-
-
3
-
Real-time Updates: Buttons update instantly
-
-
-
4
-
Feedback: Users see their vote was counted
-
-
-
- - -
-

Step 6: Additional Features (10 minutes)

-

Add statistics, top jokes, and admin commands

- -
async def top_jokes(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Show top-rated jokes""" - limit = 5 - if context.args and context.args[0].isdigit(): - limit = min(int(context.args[0]), 20) # Max 20 jokes - - jokes = db.get_top_jokes(limit) - - if not jokes: - await update.message.reply_text("No jokes in database yet!") - return - - response = f"šŸ† TOP {len(jokes)} JOKES šŸ†\n\n" - - for i, joke in enumerate(jokes, 1): - score = joke['likes'] - joke['dislikes'] - response += f"{i}. ID {joke['id']}: Score {score} (šŸ‘{joke['likes']} šŸ‘Ž{joke['dislikes']})\n" - response += f" \"{joke['joke_text'][:50]}...\"\n\n" - - await update.message.reply_text(response) - -async def bot_stats(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Show bot statistics""" - total_jokes = db.get_total_jokes() - - # Get total likes/dislikes - conn = db.get_connection() - cursor = conn.cursor() - cursor.execute("SELECT SUM(likes), SUM(dislikes) FROM jokes") - result = cursor.fetchone() - total_likes = result[0] or 0 - total_dislikes = result[1] or 0 - conn.close() - - stats_text = f"""šŸ“Š JOKE BOT STATISTICS šŸ“Š - -Total Jokes: {total_jokes} -Total Ratings: {total_likes + total_dislikes} -šŸ‘ Total Likes: {total_likes} -šŸ‘Ž Total Dislikes: {total_dislikes} -šŸ“ˆ Approval Rate: {(total_likes/(total_likes+total_dislikes)*100 if (total_likes+total_dislikes) > 0 else 0):.1f}% - -Commands Today: -/joke - Get random joke -/addjoke - Submit your joke -/top - See top jokes -/stats - View these stats""" - - await update.message.reply_text(stats_text) - -async def my_jokes(update: Update, context: ContextTypes.DEFAULT_TYPE): - """Show user's submitted jokes""" - user_id = update.effective_user.id - - conn = db.get_connection() - cursor = conn.cursor() - cursor.execute('''SELECT id, joke_text, likes, dislikes - FROM jokes WHERE user_id = ? - ORDER BY created_at DESC LIMIT 10''', (user_id,)) - - user_jokes = [dict(row) for row in cursor.fetchall()] - conn.close() - - if not user_jokes: - await update.message.reply_text("You haven't submitted any jokes yet! Use /addjoke") - return - - response = f"šŸ“ YOUR JOKES ({len(user_jokes)} total)\n\n" - - for joke in user_jokes: - score = joke['likes'] - joke['dislikes'] - response += f"ID {joke['id']}: Score {score} (šŸ‘{joke['likes']} šŸ‘Ž{joke['dislikes']})\n" - response += f" \"{joke['joke_text'][:60]}...\"\n\n" - - await update.message.reply_text(response)
- -
-

Enhanced Features:

-
-
šŸ“Š
-
Statistics: Track bot usage and engagement
-
-
-
šŸ†
-
Leaderboard: Top jokes ranking system
-
-
-
šŸ‘¤
-
Personal Stats: Users see their own contributions
-
-
-
šŸ“ˆ
-
Analytics: Approval rate and engagement metrics
-
-
-
- - -
-

Step 7: Complete Main Function (5 minutes)

-

Put it all together and run the upgraded bot

- -
def main(): - # Using the provided bot token - BOT_TOKEN = "YOUR_BOT_TOKEN_HERE" - - # Create application - app = Application.builder().token(BOT_TOKEN).build() - - # Add command handlers - app.add_handler(CommandHandler("start", start)) - app.add_handler(CommandHandler("joke", send_joke)) - app.add_handler(CommandHandler("addjoke", add_joke_command)) - app.add_handler(CommandHandler("like", like_joke)) - app.add_handler(CommandHandler("dislike", dislike_joke)) - app.add_handler(CommandHandler("top", top_jokes)) - app.add_handler(CommandHandler("stats", bot_stats)) - app.add_handler(CommandHandler("myjokes", my_jokes)) - - # Add callback handler for inline buttons - app.add_handler(CallbackQueryHandler(button_callback)) - - print("šŸ¤– Joke Bot 2.0 is running...") - print("šŸ“Š Database initialized: joke_bot.db") - print("šŸŽÆ Features: User submissions, ratings, leaderboard") - print("Press Ctrl+C to stop.\n") - - app.run_polling() - -if __name__ == "__main__": - main()
- -
-

Project Structure:

-
-joke_bot_2.0/ -ā”œā”€ā”€ app.py # Main bot file (updated) -ā”œā”€ā”€ database.py # SQLite database class -ā”œā”€ā”€ joke_bot.db # SQLite database (auto-created) -ā”œā”€ā”€ requirements.txt # python-telegram-bot==20.3 -└── README.md # Setup instructions
- -
-
1
-
Install: pip install python-telegram-bot==20.3
-
- -
-
2
-
Run: python app.py
-
- -
-
3
-
Test: Open Telegram, find your bot, type /start
-
- -
-
4
-
Deploy: Can run on Raspberry Pi, VPS, or cloud
-
-
-
- - -
-

Database Administration Tools

-

Tools to view and manage your SQLite database

- -
# admin_tools.py - Database management utilities - -import sqlite3 -import pandas as pd -from datetime import datetime - -class JokeAdmin: - def __init__(self, db_name='joke_bot.db'): - self.db_name = db_name - - def export_to_csv(self, filename='jokes_export.csv'): - """Export all jokes to CSV""" - conn = sqlite3.connect(self.db_name) - df = pd.read_sql_query("SELECT * FROM jokes", conn) - df.to_csv(filename, index=False, encoding='utf-8') - conn.close() - print(f"Exported {len(df)} jokes to {filename}") - - def show_stats(self): - """Show detailed statistics""" - conn = sqlite3.connect(self.db_name) - cursor = conn.cursor() - - # Basic counts - cursor.execute("SELECT COUNT(*) FROM jokes") - total_jokes = cursor.fetchone()[0] - - cursor.execute("SELECT COUNT(DISTINCT user_id) FROM jokes WHERE user_id != 0") - unique_users = cursor.fetchone()[0] - - cursor.execute("SELECT SUM(likes), SUM(dislikes) FROM jokes") - likes, dislikes = cursor.fetchone() - - # Top contributors - cursor.execute('''SELECT username, COUNT(*) as joke_count - FROM jokes WHERE user_id != 0 - GROUP BY user_id ORDER BY joke_count DESC LIMIT 5''') - top_contributors = cursor.fetchall() - - conn.close() - - print(f"""šŸ“Š DATABASE STATISTICS šŸ“Š - -Total Jokes: {total_jokes} -Unique Contributors: {unique_users} -Total Likes: {likes or 0} -Total Dislikes: {dislikes or 0} - -šŸ† Top Contributors:""") - - for username, count in top_contributors: - print(f" {username}: {count} jokes") - - def backup_database(self): - """Create a backup of the database""" - timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') - backup_name = f"backup_joke_bot_{timestamp}.db" - - import shutil - shutil.copy2(self.db_name, backup_name) - print(f"Backup created: {backup_name}") - -# Usage example -if __name__ == "__main__": - admin = JokeAdmin() - admin.show_stats() - admin.export_to_csv() - admin.backup_database()
- -
-

Admin Features:

-
-
šŸ’¾
-
Backups: Automatic database backups
-
-
-
šŸ“Š
-
Analytics: Detailed usage statistics
-
-
-
šŸ“¤
-
Export: CSV export for analysis
-
-
-
šŸ‘‘
-
Leaderboards: Top contributors recognition
-
-
- -
- SQLite Browser Tool: -

Download DB Browser for SQLite (free) to visually explore your database:

-

• View tables and data

-

• Run SQL queries

-

• Export/import data

-

• Available for Windows, Mac, Linux

-
-
- - -
-

Advanced Features (Optional)

-

Take your joke bot to the next level

- -
# advanced_features.py - Optional enhancements - -# 1. Joke Categories -def add_categories(): - """Add category support to jokes""" - conn = sqlite3.connect('joke_bot.db') - cursor = conn.cursor() - - # Add category column - try: - cursor.execute("ALTER TABLE jokes ADD COLUMN category TEXT DEFAULT 'general'") - except sqlite3.OperationalError: - pass # Column already exists - - # Create categories table - cursor.execute('''CREATE TABLE IF NOT EXISTS categories ( - id INTEGER PRIMARY KEY, - name TEXT UNIQUE, - description TEXT - )''') - - # Insert default categories - categories = [ - ('programming', 'Programming and tech jokes'), - ('dad', 'Classic dad jokes'), - ('animal', 'Animal jokes'), - ('school', 'School and education jokes') - ] - - cursor.executemany('''INSERT OR IGNORE INTO categories (name, description) - VALUES (?, ?)''', categories) - - conn.commit() - conn.close() - -# 2. Daily Joke Notification -async def send_daily_joke(context: ContextTypes.DEFAULT_TYPE): - """Send daily joke to subscribed users""" - joke = db.get_random_joke() - if joke: - # Get subscribed users from database - conn = db.get_connection() - cursor = conn.cursor() - cursor.execute("SELECT user_id FROM subscribers WHERE active = 1") - users = cursor.fetchall() - conn.close() - - for user_id in users: - try: - await context.bot.send_message( - chat_id=user_id[0], - text=f"šŸ“… Daily Joke!\n\n{joke['joke_text']}" - ) - except Exception as e: - print(f"Failed to send to user {user_id}: {e}") - -# 3. Joke Search Function -def search_jokes(search_term, limit=10): - """Search jokes by keyword""" - conn = sqlite3.connect('joke_bot.db') - cursor = conn.cursor() - - cursor.execute('''SELECT * FROM jokes - WHERE joke_text LIKE ? - ORDER BY (likes - dislikes) DESC - LIMIT ?''', (f'%{search_term}%', limit)) - - jokes = [dict(row) for row in cursor.fetchall()] - conn.close() - return jokes
- -
-

Optional Enhancements:

-
-
šŸ·ļø
-
Categories: Organize jokes by type
-
-
-
šŸ””
-
Notifications: Daily joke subscriptions
-
-
-
šŸ”
-
Search: Find jokes by keyword
-
-
-
šŸ¤–
-
AI Integration: Generate jokes with GPT API
-
-
-
🌐
-
Web Dashboard: View stats in browser
-
-
-
- - -
-

Testing Your Upgraded Bot

-

Comprehensive testing guide

- -
- Test Commands Sequence: -

1. /start - See welcome message with all commands

-

2. /joke - Get random joke with rating buttons

-

3. Click šŸ‘ and šŸ‘Ž buttons - Test inline rating

-

4. /addjoke Why did the Python cross the road? To get to the other side!

-

5. /joke again - See if new joke appears

-

6. /like and /dislike - Test command rating

-

7. /top 3 - See top jokes leaderboard

-

8. /stats - Check bot statistics

-

9. /myjokes - View your submissions

-
- -
-

Expected Results:

-
-
āœ…
-
Database File: joke_bot.db created automatically
-
-
-
āœ…
-
Default Jokes: 3 jokes pre-loaded
-
-
-
āœ…
-
Rating Persistence: Votes saved between restarts
-
-
-
āœ…
-
User Tracking: Your username saved with submissions
-
-
-
āœ…
-
Weighted Random: Better jokes appear more often
-
-
- -
-# Quick database check -import sqlite3 -conn = sqlite3.connect('joke_bot.db') -cursor = conn.cursor() -cursor.execute("SELECT name FROM sqlite_master WHERE type='table'") -tables = cursor.fetchall() -print("Tables:", tables) -cursor.execute("SELECT COUNT(*) FROM jokes") -count = cursor.fetchone()[0] -print(f"Total jokes: {count}") -conn.close()
-
- - -
-

Deployment Options

-

Where to run your upgraded joke bot 24/7

- -
-

Free Options:

-
-
šŸ–„ļø
-
- Raspberry Pi:
- • Always-on at home
- • Low power consumption
- • Full control -
-
- -
-
ā˜ļø
-
- PythonAnywhere:
- • Free tier available
- • Web-based IDE
- • Scheduled tasks -
-
- -
-
šŸš€
-
- Replit:
- • Free cloud IDE
- • Always-on option
- • Easy sharing -
-
-
- -
-

Paid Options:

-
-
šŸ’»
-
- VPS (DigitalOcean, Linode):
- • $5/month
- • Full root access
- • Scalable -
-
- -
-
⚔
-
- Heroku:
- • Easy deployment
- • Add-ons available
- • Good free tier (with limits) -
-
- -
-
🐳
-
- Docker:
- • Containerized deployment
- • Runs anywhere
- • Easy updates -
-
-
- -
- Deployment Checklist: -

1. Test locally first

-

2. Backup your database

-

3. Set up proper logging

-

4. Configure automatic restarts (using systemd or supervisor)

-

5. Set up regular database backups

-

6. Monitor bot activity

-
-
- - -
-

Complete Project Review

-

What you've accomplished in 60 minutes

- -
- šŸŽ‰ CONGRATULATIONS! šŸŽ‰ -

You've successfully upgraded your simple joke bot to a full-featured application with:

-
- -
-

Core Upgrades:

-
-
āœ…
-
SQLite Database: Persistent storage for jokes
-
-
-
āœ…
-
User Submissions: Community-driven content
-
-
-
āœ…
-
Rating System: Like/dislike with tracking
-
-
-
āœ…
-
Inline Buttons: Better user experience
-
-
-
āœ…
-
Statistics: Track bot usage and engagement
-
-
-
āœ…
-
Leaderboard: Top jokes ranking
-
-
- -
-

Technical Skills Learned:

-
-
šŸ
-
Python: Advanced Python programming
-
-
-
šŸ—„ļø
-
SQLite: Database design and queries
-
-
-
šŸ¤–
-
Telegram Bot API: Advanced bot features
-
-
-
šŸ“Š
-
Data Modeling: Table design and relationships
-
-
-
šŸ”§
-
Software Architecture: Modular, maintainable code
-
-
- -
- Next Steps: -

1. Add joke categories (/programming, /dadjokes)

-

2. Implement daily joke notifications

-

3. Create a web dashboard for statistics

-

4. Add joke search functionality

-

5. Implement user profiles and achievements

-

6. Add multi-language support

-
- -
-

Your Joke Bot is Now Production-Ready! šŸš€

-

Share it with friends, deploy it online, and watch your joke collection grow!

-
-
- - +