Simple Chatbot with Pattern Matching

import re

import random

import json

from datetime import datetime

from pathlib import Path

 

# ============================================================

# KNOWLEDGE BASE — Patterns & Responses

# ============================================================

 

PATTERNS = [

 

    # ---------- Greetings ----------

    {

        "tag": "greeting",

        "patterns": [

            r"\b(hi|hello|hey|howdy|hiya|greetings|good morning|good afternoon|good evening)\b"

        ],

        "responses": [

            "Hey there! How can I help you today?",

            "Hello! Great to see you. What's on your mind?",

            "Hi! I'm ready to chat. What can I do for you?",

            "Howdy! Ask me anything!"

        ]

    },

 

    # ---------- How are you ----------

    {

        "tag": "how_are_you",

        "patterns": [

            r"\b(how are you|how are you doing|how do you do|how's it going|are you ok)\b"

        ],

        "responses": [

            "I'm doing great, thanks for asking! How about you?",

            "Running at full capacity! What can I help with?",

            "All systems go! What's up?",

            "Fantastic! Ready to chat. How are YOU doing?"

        ]

    },

 

    # ---------- Name ----------

    {

        "tag": "name",

        "patterns": [

            r"\b(what is your name|what's your name|who are you|tell me your name)\b"

        ],

        "responses": [

            "I'm PyBot - your Python-powered chatbot!",

            "My name is PyBot! Nice to meet you.",

            "Call me PyBot. I'm a rule-based chatbot built in Python."

        ]

    },

 

    # ---------- Creator ----------

    {

        "tag": "creator",

        "patterns": [

            r"\b(who made you|who created you|who built you|who programmed you|who is your creator)\b"

        ],

        "responses": [

            "I was built using Python with regex pattern matching!",

            "A Python developer created me using re, random, and json.",

            "I'm powered by Python! Check out pythonforengineers.in for the code."

        ]

    },

 

    # ---------- Time ----------

    {

        "tag": "time",

        "patterns": [

            r"\b(what time is it|current time|tell me the time|what's the time|what is the time)\b"

        ],

        "responses": ["__TIME__"]

    },

 

    # ---------- Date ----------

    {

        "tag": "date",

        "patterns": [

            r"\b(what is today's date|what's today's date|what day is it|today's date|current date)\b"

        ],

        "responses": ["__DATE__"]

    },

 

    # ---------- Weather ----------

    {

        "tag": "weather",

        "patterns": [

            r"\b(weather|temperature|forecast|is it hot|is it cold|is it raining|is it sunny)\b"

        ],

        "responses": [

            "I can't check live weather, but try weather.com or Google Weather!",

            "I don't have internet access, but a quick Google search will give you the forecast!",

        ]

    },

 

    # ---------- Math ----------

    {

        "tag": "math",

        "patterns": [

            r"(\d+)\s*[\+\-\*\/]\s*(\d+)"

        ],

        "responses": ["__MATH__"]

    },

 

    # ---------- Jokes ----------

    {

        "tag": "joke",

        "patterns": [

            r"\b(tell me a joke|joke|make me laugh|say something funny|funny)\b"

        ],

        "responses": [

            "Why do Python programmers prefer dark mode? Because light attracts bugs!",

            "Why was the developer broke? Because he used up all his cache!",

            "What do you call a bear with no teeth? A gummy bear!",

            "Why did the programmer quit? Because he didn't get arrays (a raise)!",

            "Debugging: Being the detective in a crime movie where you're also the murderer."

        ]

    },

 

    # ---------- Python ----------

    {

        "tag": "python",

        "patterns": [

            r"\b(python|programming|code|coding|developer|script)\b"

        ],

        "responses": [

            "Python is one of the most popular languages! Great for automation, AI, web dev and more.",

            "Python is beginner-friendly yet powerful. What would you like to build?",

            "Love Python! Check out pythonforengineers.in for cool Python programs."

        ]

    },

 

    # ---------- Help ----------

    {

        "tag": "help",

        "patterns": [

            r"\b(help|what can you do|your features|capabilities|what do you know)\b"

        ],

        "responses": [

            "I can:\n  * Chat with you\n  * Tell jokes\n  * Answer basic questions\n  * Do simple math\n  * Tell time and date\n  * Remember your name\n\nJust type naturally!"

        ]

    },

 

    # ---------- Name capture ----------

    {

        "tag": "user_name",

        "patterns": [

            r"\bmy name is (\w+)\b",

            r"\bi am (\w+)\b",

            r"\bcall me (\w+)\b"

        ],

        "responses": ["__REMEMBER_NAME__"]

    },

 

    # ---------- Goodbye ----------

    {

        "tag": "goodbye",

        "patterns": [

            r"\b(bye|goodbye|see you|see ya|take care|quit|exit|later)\b"

        ],

        "responses": [

            "Goodbye! Have a great day!",

            "See you later! It was nice chatting!",

            "Take care! Come back anytime.",

            "Bye! Keep coding!"

        ]

    },

 

    # ---------- Thanks ----------

    {

        "tag": "thanks",

        "patterns": [

            r"\b(thank you|thanks|thank u|thx|ty|appreciated)\b"

        ],

        "responses": [

            "You're welcome!",

            "Happy to help!",

            "Anytime! That's what I'm here for.",

            "No problem at all!"

        ]

    },

 

    # ---------- Age ----------

    {

        "tag": "age",

        "patterns": [

            r"\b(how old are you|what's your age|what is your age|when were you born)\b"

        ],

        "responses": [

            "I was born the moment someone ran this Python script! So pretty young.",

            "Age is just a number, but I'm freshly compiled!"

        ]

    },

 

    # ---------- Favorites ----------

    {

        "tag": "favorites",

        "patterns": [

            r"\b(favorite language|favorite food|favorite color|what do you like)\b"

        ],

        "responses": [

            "My favorite language is obviously Python!",

            "I like Python, clean code, and well-commented scripts! What about you?",

        ]

    },

 

    # ---------- Meaning of life ----------

    {

        "tag": "meaning",

        "patterns": [

            r"\b(meaning of life|purpose of life|why are we here|42)\b"

        ],

        "responses": [

            "42. Obviously.",

            "The meaning of life is to write clean, well-documented Python code. At least, that's my belief.",

        ]

    },

 

]

 

# ============================================================

# SPECIAL RESPONSE HANDLERS

# ============================================================

 

def handle_special(response, user_input, memory):

    if response == "__TIME__":

        now = datetime.now().strftime("%I:%M %p")

        return f"The current time is {now}"

 

    if response == "__DATE__":

        today = datetime.now().strftime("%A, %d %B %Y")

        return f"Today is {today}"

 

    if response == "__MATH__":

        try:

            expr = re.search(r"(\d+\s*[\+\-\*\/]\s*\d+)", user_input)

            if expr:

                result = eval(expr.group(0))

                return f"The answer is: {result}"

        except:

            return "Hmm, I couldn't calculate that. Try something like: 5 + 3"

 

    if response == "__REMEMBER_NAME__":

        name_match = re.search(

            r"\b(?:my name is|i am|call me)\s+(\w+)\b",

            user_input, re.IGNORECASE

        )

        if name_match:

            name = name_match.group(1).capitalize()

            memory["user_name"] = name

            return f"Nice to meet you, {name}! I'll remember that."

        return "Nice name! What's it again?"

 

    return response

 

 

# ============================================================

# MATCH USER INPUT TO PATTERN

# ============================================================

 

def get_response(user_input, memory):

    text = user_input.lower().strip()

 

    for rule in PATTERNS:

        for pattern in rule["patterns"]:

            if re.search(pattern, text, re.IGNORECASE):

                response = random.choice(rule["responses"])

                response = handle_special(response, text, memory)

 

                # Occasionally personalize with name if known

                if "user_name" in memory and random.random() < 0.3:

                    response = f"{memory['user_name']}, " + response[0].lower() + response[1:]

 

                return response

 

    # Fallback

    fallbacks = [

        "Hmm, I'm not sure I understand. Could you rephrase that?",

        "Interesting! Tell me more.",

        "I don't have an answer for that yet, but I'm learning!",

        "That's a good one! I'm still a work in progress.",

        "Could you ask that differently? I want to help!",

        "I'm not sure about that. Try asking me something else!"

    ]

    return random.choice(fallbacks)

 

 

# ============================================================

# SAVE CHAT HISTORY

# ============================================================

 

def save_chat_history(history, session_start):

    filename = f"chat_history_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"

    with open(filename, "w", encoding="utf-8") as f:

        json.dump({

            "session": session_start,

            "messages": history

        }, f, indent=2, ensure_ascii=False)

    print(f"\n  Chat saved to {filename}")

 

 

# ============================================================

# MAIN CHAT LOOP

# ============================================================

 

def main():

    print("\n" + "="*55)

    print("     PYBOT - Pattern Matching Chatbot")

    print("="*55)

    print("\n  Type 'help'    - see what I can do")

    print("  Type 'history' - save chat log to file")

    print("  Type 'bye'     - exit\n")

    print("-"*55)

 

    memory        = {}

    history       = []

    session_start = datetime.now().strftime("%d-%m-%Y %H:%M:%S")

 

    while True:

        try:

            user_input = input("\n  You: ").strip()

        except (EOFError, KeyboardInterrupt):

            print("\n\n  Interrupted. Goodbye!")

            break

 

        if not user_input:

            continue

 

        # Save history command

        if user_input.lower() == "history":

            save_chat_history(history, session_start)

            continue

 

        # Get and print response

        response = get_response(user_input, memory)

        print(f"\n  PyBot: {response}")

 

        # Log conversation

        history.append({

            "user": user_input,

            "bot":  response,

            "time": datetime.now().strftime("%H:%M:%S")

        })

 

        # Exit trigger

        if any(re.search(p, user_input.lower())

               for p in [r"\b(bye|goodbye|quit|exit)\b"]):

            break

 

    print("\n" + "="*55)

    print("  Thanks for chatting! Session ended.")

    print("="*55 + "\n")

 

 

# ============================================================

# RUN

# ============================================================

 

if __name__ == "__main__":

    main()

 

No comments: