Source code for dice.core.symbol

import os
import random
import string


[docs]class SymbolBase(object): """ Base class for a symbol object represent a catalog of data to be randomized. """ def __init__(self, scope=None, excs=None, exc_types=None): """ :param scope: A list limits the scope of generated results. :param excs: A list won't exist in generated results. :param exc_types: A list of types won't exist in generated results. """ self.scope = scope self.excs = excs self.exc_types = exc_types
[docs] def generate(self): """ Generate a random instance of this symbol without considering scope, excs or exc_types. Must be overridden. """ raise NotImplementedError("Method 'generate' not implemented for %s" % self.__class__.__name__)
[docs] def model(self): """ Generate a random instance of this symbol. """ if self.scope is None: res = self.generate() if self.excs is not None: while res in self.excs: res = self.generate() return res else: res = random.choice(self.scope) if self.excs is not None: while res in self.excs: res = random.choice(self.scope) return res
[docs]class Bytes(SymbolBase): """ Symbol class for a string contains random bytes (1~255). """
[docs] def generate(self): """ Generate a random bytes string. """ cnt = int(random.weibullvariate(65535, 1)) return ''.join(bt for bt in os.urandom(cnt) if bt != b'\x00')
[docs]class NonEmptyBytes(Bytes): """ Symbol class for a random byte(1-255) string except empty string. """
[docs] def generate(self): """ Generate a random non-empty bytes string. """ cnt = int(random.weibullvariate(65535, 1)) + 1 return ''.join(bt for bt in os.urandom(cnt) if bt != b'\x00')
[docs]class String(Bytes): """ Symbol class for a random printable string. """
[docs] def generate(self): """ Generate a random printable string. """ cnt = int(random.weibullvariate(20, 1.8)) return ''.join(random.choice(string.printable) for _ in range(cnt))
[docs]class StringList(SymbolBase): """ Symbol class for a list of random printable strings. """ def __init__(self, scope=None, excs=None, exc_types=None): """ :param scope: A list limits the scope of generated results. :param excs: A list won't exist in generated results. :param exc_types: A list of types won't exist in generated results. """ super(StringList, self).__init__() self.scopes = []
[docs] def generate(self): """ Generate a random printable strings. """ cnt = int(random.weibullvariate(20, 1.8)) return ''.join(random.choice(string.printable) for _ in range(cnt))
[docs] def model(self): """ Generate a random-numbered list contains random printable strings. """ cnt = int(random.weibullvariate(20, 1.8)) res = set() for _ in range(cnt): entry = None if self.scopes: for scope, _, _ in self.scopes: if scope: entry = random.choice(scope) else: entry = self.generate() if entry: res.add(entry) return list(res)
[docs]class Integer(SymbolBase): """ Symbol class for a random integer. """ def __init__(self, scope=None, excs=None, exc_types=None): """ :param scope: A list limits the scope of generated results. :param excs: A list won't exist in generated results. :param exc_types: A list of types won't exist in generated results. """ super(Integer, self).__init__(scope) self.maximum = None self.minimum = None self.exc_types = [] if exc_types is not None: self.exc_types = exc_types def __repr__(self): maximum, minimum = self.maximum, self.minimum if self.maximum is None: maximum = 'Inf' if self.minimum is None: minimum = '-Inf' return '<%s %s~%s>' % (self.__class__.__name__, minimum, maximum)
[docs] def generate(self): """ Generate a random integer. """ scale = 50.0 maximum = self.maximum minimum = self.minimum while True: sign = 1.0 if random.random() > 0.5 else -1.0 res = sign * (2.0 ** (random.expovariate(1.0 / scale)) - 1.0) if maximum is not None: if maximum >= 0 and res > maximum + 1: continue if maximum < 0 and res > maximum: continue if minimum is not None: if minimum >= 0 and res < minimum: continue if minimum < 0 and res < minimum - 1: continue return int(res)