All pastes #276281 Raw Edit

Something

public text v1 · immutable
·published 2006-12-12 04:32 UTC
rendered paste body
"""A retarded little bot program written in honor of a retarded little man.

This module implements BrtBot, which scans textual input from strings and
produces random responses from a YAML database file.
"""

__version__ = '1.02'

import os
import random
import re
import yaml

class BrtBot:
  """BrtBot main class."""

  def __init__(self, filename='bedrocktruth'):
    """Constructor.
   
    Arguments:
      filename: str, identifies the file named 'brt-%s.yaml' containing quote
      data in same directory as source file. Defaults to 'bedrocktruth'.
    """

    quotes_file = open(os.path.split(__file__)[0] + 'brt-%s.yaml' % filename)
    self.quotes = yaml.load(quotes_file)
    quotes_file.close()

    self.keywords = set()
    self.quote_sets = {}

    for quote, keywords in self.quotes['specific']:
      for keyword in keywords:
        # Add all keywords to the master keyword set
        self.keywords.add(keyword)
        # Generate mapping from keyword to quote
        if keyword not in self.quote_sets:
          self.quote_sets[keyword] = set()
        self.quote_sets[keyword].add(quote)

  def _scan(self, input):
    """Scan input for keywords from the quotes file.
  
    Arguments:
      input: str, contains search text

    Returns:
      Tuple of keywords found.
    """

    keywords = []

    for keyword in self.keywords:
      if re.search(keyword, input, re.IGNORECASE):
        keywords.append(keyword)

    return tuple(keywords)

  def _find_quotes(self, keywords):
    """ Find quotes related to keywords.

    Arguments:
      keywords: iterable, gives keywords for which to search

    Returns:
      Tuple of found quotes.
    """
    quotes = set()

    # The union of all keyword sets can produce heavily discursive,
    # non-sequitur responses.
    #
    # ...and that's a vital feature for any wingnut emulator

    for keyword in keywords:
      quotes = quotes.union(self.quote_sets[keyword])

    return tuple(quotes)

  def blather(self, input):
    """Crank out some good old-fashioned BRT blather.
   
    Arguments:
      input: str, contains search text

    Returns:
      One randomly selected quote relevant to keywords found in input, or one
      randomly selected off-hand remark if no keywords match.
    """

    keywords = self._scan(input)

    # Produce a response relevant to keywords if possible
    if keywords:
      quotes = self._find_quotes(keywords)
    # Use a stock answer if all else fails
    else:
      quotes = self.quotes['off-hand']
    
    return quotes[random.randint(0, len(quotes) - 1)]