Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
137 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# -*- coding: utf-8 -*- | ||
"""blueprint.collections -- a collection class for blueprints. | ||
""" | ||
import sys | ||
import collections | ||
|
||
__all__ = ['BlueprintCollection'] | ||
|
||
|
||
class BlueprintCollection(collections.Sequence, collections.Callable): | ||
def __init__(self, blueprint, seed='', **kwargs): | ||
self.blueprint = blueprint | ||
self.seed = seed | ||
self.kwargs = kwargs | ||
|
||
def __len__(self): | ||
return sys.maxint | ||
|
||
def __iter__(self): | ||
return iter(self) | ||
|
||
def __contains__(self): | ||
return True | ||
|
||
def __call__(self, parent=None, seed=None, **kwargs): | ||
options = {} | ||
options.update(self.kwargs) | ||
options.update(kwargs) | ||
return self.blueprint(parent=parent, | ||
seed=seed if seed is not None else self.seed, | ||
**options) | ||
|
||
def __getitem__(self, idx): | ||
if isinstance(idx, slice): | ||
seed = u"%s%%s" % self.seed | ||
if idx.stop is None: | ||
return (self(seed=seed % i, **self.kwargs) | ||
for i in it.count(idx.start or 0, idx.step or 1)) | ||
else: | ||
return [self(seed=seed % i) | ||
for i in xrange(idx.start or 0, | ||
idx.stop, idx.step or 1)] | ||
else: | ||
seed = u"%s%s" % (self.seed, idx) | ||
return self(seed=seed) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# -*- coding: utf-8 -*- | ||
"""blueprint.markov -- Markov Chain generator. | ||
""" | ||
import collections | ||
|
||
from blueprint import fields | ||
|
||
__all__ = ['MarkovChain'] | ||
|
||
|
||
class MarkovChain(fields.Field, collections.Mapping): | ||
"""Uses a Markov Chain to generate random sequences. | ||
Derived from Peter Corbett's CGI random name generator, with input | ||
from the ElderLore object-oriented variation. | ||
http://www.pick.ucam.org/~ptc24/mchain.html | ||
""" | ||
def __init__(self, source_list, chainlen=2, max_length=10): | ||
if 1 > chainlen > 10: | ||
raise ValueError("Chain length must be between 1 and 10, inclusive") | ||
self._dict = collections.defaultdict(list) | ||
self.chainlen = chainlen | ||
self.max_length = max_length | ||
self.readData(source_list) | ||
|
||
def next(self): | ||
return self.getRandomName() | ||
|
||
def readData(self, names, destroy=False): | ||
if destroy: | ||
self._dict.clear() | ||
|
||
oldnames = [] | ||
chainlen = self.chainlen | ||
|
||
for name in names: | ||
oldnames.append(name) | ||
spacer = u''.join((u" " * chainlen, name)) | ||
name_len = len(name) | ||
for num in xrange(name_len): | ||
self.add_key(spacer[num:num+chainlen], spacer[num+chainlen]) | ||
self.add_key(spacer[name_len:name_len+chainlen], "\n") | ||
|
||
def getRandomName(self, parent): | ||
"""Return a random name. | ||
""" | ||
prefix = u" " * self.chainlen | ||
name = u"" | ||
suffix = u"" | ||
while 1: | ||
suffix = self.get_suffix(prefix, parent) | ||
if suffix == u"-": | ||
continue | ||
elif suffix == u"\n" or len(name) == self.max_length: | ||
break | ||
else: | ||
name = u''.join((name, suffix)) | ||
prefix = u''.join((prefix[1:], suffix)) | ||
return name | ||
|
||
def __call__(self, parent): | ||
return self.getRandomName(parent) | ||
|
||
def __getitem__(self, key): | ||
return self._dict[key] | ||
|
||
def __len__(self): | ||
return len(self._dict) | ||
|
||
def __iter__(self): | ||
return iter(self._dict) | ||
|
||
def add_key(self, prefix, suffix): | ||
self._dict[prefix].append(suffix) | ||
|
||
def get_suffix(self, prefix, parent): | ||
return parent.meta.random.choice(self[prefix]) |