示例#1
0
 def __init__(self, internal_state):
     self.messages = WanderingMonsterTable()
     self.messages.common = self.COMMON
     self.messages.uncommon = self.UNCOMMON
     self.messages.rare = self.RARE
     self.messages.very_rare = self.VERY_RARE
     self.materials = self.setup_materials(internal_state)
示例#2
0
    def make_wmt(cls, alphabet, num_spaces=0):
        if isinstance(alphabet, list) or isinstance(alphabet, tuple):
            alphabet = "".join(alphabet)
        try:
            alphabet = Alphabet.characters(alphabet)
        except KeyError as e:
            pass
        common = uncommon = rare = None

        if len(alphabet) == 1:
            if not num_spaces:
                raise ValueError("Can't make a mosaic from a single character")
            common = alphabet
        elif len(alphabet) == 2:
            common = alphabet
        else:
            common, uncommon, rare = random.sample(alphabet, 3)
        common += u"\N{EM SPACE}" * num_spaces
        return (WanderingMonsterTable(common, uncommon,
                                      rare), SymmetryList(alphabet))
示例#3
0
    def __init__(b, mean_transforms=1.4, stdev_transforms=0.5):
        """Simulate someone hacking away at a typewriter

        :param mean_transforms: The mean number of mistakes per 100
        characters.

        :param stdev_stransforms: The acceptable standard
        deviation from the mean.
        """
        b.mean_transforms = mean_transforms
        b.stdev_transforms = stdev_transforms
        b.wmt = WanderingMonsterTable(
            common=[b.typo, b.typo, b.duplicate, b.transpose],
            uncommon=[b.omit_period, b.delete_space, b.typo_add, b.delete],
            rare=[
                b.delete, b.lowercase_uppercase_letter,
                b.extra_space_at_beginning, b.uppercase_letter
            ],
            very_rare=[
                b.uppercase_word, b.uppercase_entire_string,
                b.lowercase_entire_string, b.remove_word, b.delete
            ],
        )
示例#4
0
    def setup_materials(self, internal_state):
        """Build a WanderingMonsterTable of materials from different sources.
        """
        def load_local(x):
            """Load a data file from bot-specific storage 
            rather than through Corpora.
            """
            base_dir = os.path.split(__file__)[0]
            path = os.path.join(base_dir, "data", x)
            return [x.strip() for x in open(path)]

        exclude = set(load_local("real_life.txt"))

        def filter_materials(materials):
            """Exclude materials that are actually used as anniversary gifts."""
            if isinstance(materials, dict):
                # This may be a corpora object -- extract the thing that's
                # not the description or source.
                if 'description' in materials:
                    del materials['description']
                if 'source' in materials:
                    del materials['source']
                if len(materials) == 1:
                    [materials] = materials.values()
                else:
                    raise ValueError("Unrecognized materials: %r" % materials)

            return [x for x in materials if x and x.lower() not in exclude]

        def filtered_local(filename):
            """Combine load_local and filter_materials."""
            return filter_materials(load_local(filename))

        dwarf_fortress_materials = filtered_local("dwarf_fortress.txt")
        moma_materials = filtered_local("moma.txt")
        gutenberg_materials = filtered_local("gutenberg.txt")

        scribblenauts_words = filter_materials(corpora.words.scribblenauts)
        concrete_nouns = filter_materials(
            corpora.words.common_nouns['concrete_nouns'])

        # Put all the materials in corpus into one big list.
        corpora_materials = []
        for corpus in ('abridged-body-fluids', 'building-materials',
                       'carbon-allotropes', 'decorative-stones',
                       'decorative-stones', 'fabrics', 'fibers', 'gemstones',
                       'layperson-metals', 'metals', 'natural-materials',
                       'packaging', 'plastic-brands', 'sculpture-materials',
                       'technical-fabrics'):
            corpora_materials.extend(filter_materials(corpora.load(corpus)))

        # Unlike the other lists of materials, we need to do some
        # minimal processing here.
        seen_minecraft = set()
        for i in load_local("minecraft.txt"):
            material = i.strip()
            if '(' in material:
                paren = material.index('(')
                material = material[:paren]
            material = material.strip().lower()
            seen_minecraft.add(material)
        minecraft_materials = filter_materials(sorted(seen_minecraft))

        # Add materials obtained by semi-real-time searches of
        # data sources such as Twitter.
        external_materials = set()
        if internal_state:
            for source, materials in internal_state.items():
                external_materials.update(filter_materials(materials))
        external_materials = list(external_materials)

        m = WanderingMonsterTable()
        if external_materials:
            m.common.append(list(external_materials))
        m.common.append(gutenberg_materials)
        m.uncommon.append(moma_materials)
        m.uncommon.append(corpora_materials)
        m.rare.append(scribblenauts_words)
        m.rare.append(concrete_nouns)
        m.rare.append(dwarf_fortress_materials)
        m.very_rare.append(minecraft_materials)
        return m
示例#5
0
class Advisor(object):
    """Has lots of advice about anniversary presents.
    """

    COMMON = [
        u"%(nth)s anniversary - %(Material)s",
        u"%(nth)s anniverary - %(Material)s (traditional), %(Material2)s (modern)",
        u"%(nth)s anniversary - %(Material)s",
        u"%(nth)s anniverary - %(Material)s (traditional), %(Material2)s (modern)",
        u"%(Material)s - the traditional gift for the %(nth)s anniversary",
        u"%(Material)s - the modern gift for the %(nth)s anniversary",
        u"The modern %(nth)s anniversary gift: %(material)s",
        u"The traditional %(nth)s anniversary gift: %(material)s",
        u'The %(nth)s is the "%(material)s" anniversary.',
    ]

    UNCOMMON = [
        u"Traditionally, one gives %(material)s for the %(nth)s anniversary.",
        u'The %(nth)s has always been the "%(material)s" anniversary.',
        u"For the %(nth)s anniversary, it's %(material)s.",
        u"For the %(nth)s anniversary, it's got to be %(material)s.",
        u'Remember, the %(nth)s is the "%(material)s" anniversary.',
        u"It's your %(nth)s… say it with %(material)s.",
        u"%(Material)s for the %(nth)s… how romantic!",
        u"Make your %(nth)s anniversary special… give %(material)s.",
        u"%(Material)s? That's a bit old-fashioned. For your %(nth)s, consider %(material2)s instead.",
        u"For the %(nth)s, there's no better gift than %(material)s.",
        u"For your %(nth)s, a symbol of your enduring love: %(material)s.",
        u"I don't need any fancy %(material)s for our %(nth)s… simple %(material2)s will do.",
        u"%(He)s just couldn't wait… %(he)s gave me %(material)s for our %(nth)s anniversary instead of our %(next_one)s!",
        u"Why settle for less? Give genuine %(material)s for your %(nth)s anniversary.",
        u"%(Material)s - the perfect gift for your %(nth)s anniversary!",
    ]

    RARE = [
        u"As long as there have been marriages, %(nth)s anniversaries have been celebrated with %(material)s.",
        u"Can you believe %(he)s gave me %(material)s for our %(nth)s instead of %(material2)s?",
        u"For your %(nth)s, consider %(material)s as an ethical alternative to %(material2)s.",
        u"The only appropriate gift for the %(nth)s anniversary is %(material)s.",
        u"A good practical gift for the %(nth)s anniversary is %(material)s.",
        u"I've never understood why %(material)s is given for the %(nth)s... doesn't %(material2)s make more sense?",
        u"I'm trying to find %(material)s for our %(nth)s, but it's so expensive!",
        u"It's your %(nth)s anniversary. Show that you love %(him)s… with %(material)s.",
        u"The %(nth)s anniversary was once for %(material)s, but more and more couples are giving %(material2)s.",
        u"I'll never understand why the %(nth)s is the \"%(material)s\" anniversary…",
        u"%(Material)s for your %(nth)s… because %(hes)s worth it.",
        u"Is it old-fashioned to still expect %(material)s for your %(nth)s anniversary?",
        u"No, you've got it mixed up. You give %(material)s for the %(nth)s, and %(material2)s for the %(next_one)s.",
    ]

    VERY_RARE = [
        u"Call me old fashioned, but for my %(nth)s anniversary I'd better be getting %(material)s!",
        u"%(He)s won't say it, but for your %(nth)s, %(hes)s expecting %(material)s.",
        u"If your %(nth)s anniversary is coming up, you'd better start shopping for %(material)s.",
        u"%(Material)s? For the %(nth)s anniversary? Everyone knows it's %(material2)s!",
        u"Frankly, I'd be insulted if I didn't get %(material)s for my %(nth)s anniversary.",
        u"I got the greatest %(material)s for my %(nth)s!",
        u"I don't care what %(he)s gives me for our %(nth)s, so long as it's %(material)s!",
        u"In my family, we give %(material)s for the %(nth)s instead of %(material2)s.",
        u"%(Material)s for your %(nth)s… isn't %(hes)s worth it?",
        u"If I don't get %(material)s for my %(nth)s, there won't be a %(next_one)s.",
        u"Sure, I'll be buying %(material)s for the %(nth)s, but the price has to be right.",
        u"The perfect %(nth)s anniversary… a romantic dinner and a gift of %(material)s.",
    ]

    def __init__(self, internal_state):
        self.messages = WanderingMonsterTable()
        self.messages.common = self.COMMON
        self.messages.uncommon = self.UNCOMMON
        self.messages.rare = self.RARE
        self.messages.very_rare = self.VERY_RARE
        self.materials = self.setup_materials(internal_state)

    def setup_materials(self, internal_state):
        """Build a WanderingMonsterTable of materials from different sources.
        """
        def load_local(x):
            """Load a data file from bot-specific storage 
            rather than through Corpora.
            """
            base_dir = os.path.split(__file__)[0]
            path = os.path.join(base_dir, "data", x)
            return [x.strip() for x in open(path)]

        exclude = set(load_local("real_life.txt"))

        def filter_materials(materials):
            """Exclude materials that are actually used as anniversary gifts."""
            if isinstance(materials, dict):
                # This may be a corpora object -- extract the thing that's
                # not the description or source.
                if 'description' in materials:
                    del materials['description']
                if 'source' in materials:
                    del materials['source']
                if len(materials) == 1:
                    [materials] = materials.values()
                else:
                    raise ValueError("Unrecognized materials: %r" % materials)

            return [x for x in materials if x and x.lower() not in exclude]

        def filtered_local(filename):
            """Combine load_local and filter_materials."""
            return filter_materials(load_local(filename))

        dwarf_fortress_materials = filtered_local("dwarf_fortress.txt")
        moma_materials = filtered_local("moma.txt")
        gutenberg_materials = filtered_local("gutenberg.txt")

        scribblenauts_words = filter_materials(corpora.words.scribblenauts)
        concrete_nouns = filter_materials(
            corpora.words.common_nouns['concrete_nouns'])

        # Put all the materials in corpus into one big list.
        corpora_materials = []
        for corpus in ('abridged-body-fluids', 'building-materials',
                       'carbon-allotropes', 'decorative-stones',
                       'decorative-stones', 'fabrics', 'fibers', 'gemstones',
                       'layperson-metals', 'metals', 'natural-materials',
                       'packaging', 'plastic-brands', 'sculpture-materials',
                       'technical-fabrics'):
            corpora_materials.extend(filter_materials(corpora.load(corpus)))

        # Unlike the other lists of materials, we need to do some
        # minimal processing here.
        seen_minecraft = set()
        for i in load_local("minecraft.txt"):
            material = i.strip()
            if '(' in material:
                paren = material.index('(')
                material = material[:paren]
            material = material.strip().lower()
            seen_minecraft.add(material)
        minecraft_materials = filter_materials(sorted(seen_minecraft))

        # Add materials obtained by semi-real-time searches of
        # data sources such as Twitter.
        external_materials = set()
        if internal_state:
            for source, materials in internal_state.items():
                external_materials.update(filter_materials(materials))
        external_materials = list(external_materials)

        m = WanderingMonsterTable()
        if external_materials:
            m.common.append(list(external_materials))
        m.common.append(gutenberg_materials)
        m.uncommon.append(moma_materials)
        m.uncommon.append(corpora_materials)
        m.rare.append(scribblenauts_words)
        m.rare.append(concrete_nouns)
        m.rare.append(dwarf_fortress_materials)
        m.very_rare.append(minecraft_materials)
        return m

    def ordinal(self, x):
        x = int(x)
        if x == 11:
            return '11th'
        if x == 12:
            return '12th'
        if x == 13:
            return '13th'
        m = x % 10
        if m == 1:
            t = "%sst"
        elif m == 2:
            t = "%snd"
        elif m == 3:
            t = "%srd"
        else:
            t = "%sth"
        return t % x

    def number(self):
        x = 0
        while x < 1:
            x = random.randint(1, 5)
            if x == 1:
                x = random.gauss(5, 2)
            elif x == 2:
                x = random.gauss(10, 5)
            elif x == 3:
                x = random.gauss(20, 5)
            elif x == 4:
                x = random.gauss(30, 5)
            elif x == 5:
                x = random.gauss(40, 20)
        return int(x)

    def choose2(self, m):
        """Call m() until it gives two different choices. Return them both."""
        choice1 = m()
        choice2 = choice1
        while choice2 == choice1:
            choice2 = m()
        return choice1, choice2

    @property
    def pronoun(self):
        """Choose a random gendered pronoun and associated words."""
        if random.randint(1, 2) == 1:
            return "He", "he", "he's", "him"
        else:
            return "She", "she", "she's", "her"

    def choose(self):
        """Advise as to an anniversary present."""
        # Choose a list to get materials from.
        list = self.materials.choice()
        material1 = random.choice(list)

        # 20% of the time, choose the second material from a
        # totally different list. Otherwise, choose a different
        # material from the same list.
        if random.random() >= 0.8:
            list = self.materials.choice()
        material2 = None
        while not material2 or material2 == material1:
            material2 = random.choice(list)

        number1, number2 = self.choose2(self.number)
        next_anniversary = self.ordinal(number1 + 1)
        number1 = self.ordinal(number1)
        number2 = self.ordinal(number2)

        He, he, hes, him = self.pronoun
        message = self.messages.choice()
        vars = dict(
            He=He,
            he=he,
            hes=hes,
            him=him,
            nth=number1,
            mth=number2,
            next_one=next_anniversary,
            material=material1,
            material2=material2,
            Material=material1.capitalize(),
            Material2=material2.capitalize(),
        )

        return message % vars