| OLD | NEW |
| (Empty) | |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 import copy |
| 6 import functools |
| 7 import math |
| 8 import random |
| 9 |
| 10 |
| 11 def RandomLowInteger(low, high, beta=31.0): |
| 12 """Like random.randint, but heavily skewed toward the low end""" |
| 13 assert low <= high |
| 14 return low + int(math.floor(random.betavariate(1.0, beta) * (high - low))) |
| 15 |
| 16 |
| 17 def UniformExpoInteger(low, high, base=2): |
| 18 """Returns base to a power uniformly distributed between low and high. |
| 19 |
| 20 This is useful for exploring large ranges of integers while ensuring that |
| 21 values of all different sizes are represented. |
| 22 """ |
| 23 return int(math.floor(math.pow(base, random.uniform(low, high)))) |
| 24 |
| 25 |
| 26 def WeightedChoice(choices): |
| 27 """Chooses an item given a sequence of (choice, weight) tuples""" |
| 28 total = sum(w for c, w in choices) |
| 29 r = random.uniform(0, total) |
| 30 upto = 0 |
| 31 for c, w in choices: |
| 32 upto += w |
| 33 if upto >= r: |
| 34 return c |
| 35 assert False |
| 36 |
| 37 |
| 38 def Pipeline(*funcs): |
| 39 """Given a number of single-argument functions, returns a single-argument |
| 40 function which computes their composition. Each of the functions are applied |
| 41 to the input in order from left to right, with the result of each function |
| 42 passed as the argument to the next function.""" |
| 43 return reduce(lambda f, g: lambda x: g(f(x)), funcs) |
| 44 |
| 45 |
| 46 def DeepMemoize(obj): |
| 47 """A memoizing decorator that returns deep copies of the function results.""" |
| 48 cache = obj.cache = {} |
| 49 @functools.wraps(obj) |
| 50 def Memoize(*args): |
| 51 if args not in cache: |
| 52 cache[args] = copy.deepcopy(obj(*args)) |
| 53 return copy.deepcopy(cache[args]) |
| 54 return Memoize |
| OLD | NEW |