# 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):
  """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
