File indexing completed on 2024-04-28 07:51:09
0001 # -*- coding: utf-8 -*- 0002 0003 """ 0004 Copyright (C) 2008-2016 Wolfgang Rohdewald <wolfgang@rohdewald.de> 0005 0006 SPDX-License-Identifier: GPL-2.0 0007 0008 """ 0009 0010 import weakref 0011 from random import Random 0012 0013 from util import callers 0014 from common import Debug 0015 0016 class CountRandomCalls: 0017 0018 """a helper class for logging count of random calls""" 0019 0020 def __init__(self, rnd, what): 0021 self.rnd = rnd 0022 self.what = what 0023 self.oldCount = CountingRandom.count 0024 0025 def __enter__(self): 0026 return self 0027 0028 def __exit__(self, exc_type, exc_value, trback): 0029 if Debug.random: 0030 self.rnd.game.debug( 0031 '{} out of {} calls to random by {} from {}'.format( 0032 CountingRandom.count - self.oldCount, 0033 CountingRandom.count, 0034 self.what, 0035 callers())) 0036 0037 0038 class CountingRandom(Random): 0039 0040 """counts how often random() is called and prints debug info""" 0041 0042 count = 0 0043 0044 def __init__(self, game, value=None): 0045 self._game = weakref.ref(game) 0046 Random.__init__(self, value) 0047 CountingRandom.count = 0 0048 0049 @property 0050 def game(self): 0051 """hide the fact that game is a weakref""" 0052 return self._game() 0053 0054 def random(self): 0055 """the central randomizator""" 0056 CountingRandom.count += 1 0057 return Random.random(self) 0058 0059 def seed(self, a=None, version=2): 0060 CountingRandom.count = 0 0061 Random.seed(self, a, version) 0062 if Debug.random: 0063 self.game.debug('Random gets seed %s' % a) 0064 0065 def randrange(self, start, stop=None, step=1): 0066 with CountRandomCalls(self, 'randrange({},{},step={})'.format( 0067 start, stop, step)): 0068 return Random.randrange(self, start, stop, step) 0069 0070 def choice(self, seq): 0071 """Choose a random element from a non-empty sequence.""" 0072 if len(seq) == 1: 0073 return seq[0] 0074 with CountRandomCalls(self, 'choice({})'.format(seq)): 0075 return Random.choice(self, seq) 0076 0077 def sample(self, population, k, *, counts=None): 0078 """add debug output to sample. Chooses k unique random elements""" 0079 with CountRandomCalls(self, 'sample({}, {})'.format(population, k)): 0080 return Random.sample(self, population, k, counts=counts) 0081 0082 def shuffle(self, x): 0083 """add debug output to shuffle. Shuffles list x in place.""" 0084 with CountRandomCalls(self, 'shuffle({})'.format(x)): 0085 Random.shuffle(self, x)