123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- # Copyright 2016 The Chromium Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- import copy
- import functools
- import math
- import random
- def RandomLowInteger(low, high, beta=31.0):
- """Like random.randint, but heavily skewed toward the low end"""
- assert low <= high
- return low + int(math.floor(random.betavariate(1.0, beta) * (high - low)))
- def UniformExpoInteger(low, high, base=2):
- """Returns base to a power uniformly distributed between low and high.
- This is useful for exploring large ranges of integers while ensuring that
- values of all different sizes are represented.
- """
- return int(math.floor(math.pow(base, random.uniform(low, high))))
- def WeightedChoice(choices): # pylint: disable=inconsistent-return-statements
- """Chooses an item given a sequence of (choice, weight) tuples"""
- total = sum(w for c, w in choices)
- r = random.uniform(0, total)
- upto = 0
- for c, w in choices:
- upto += w
- if upto >= r:
- return c
- assert False
- def Pipeline(*funcs):
- """Given a number of single-argument functions, returns a single-argument
- function which computes their composition. Each of the functions are applied
- to the input in order from left to right, with the result of each function
- passed as the argument to the next function."""
- return reduce(lambda f, g: lambda x: g(f(x)), funcs)
- def DeepMemoize(obj):
- """A memoizing decorator that returns deep copies of the function results."""
- cache = obj.cache = {}
- @functools.wraps(obj)
- def Memoize(*args):
- if args not in cache:
- cache[args] = copy.deepcopy(obj(*args))
- return copy.deepcopy(cache[args])
- return Memoize
|