Path: csiph.com!usenet.pasdenom.info!news.redatomik.org!newsfeed.xs4all.nl!newsfeed4a.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.117 X-Spam-Level: * X-Spam-Evidence: '*H*': 0.77; '*S*': 0.01; '[0]': 0.07; 'default.': 0.07; 'run,': 0.07; 'cc:addr:python-list': 0.10; 'def': 0.14; 'output': 0.15; '18:': 0.16; '8:40': 0.16; 'code),': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'subject:random': 0.16; 'wrote:': 0.16; 'cc:2**0': 0.21; 'cc:addr:python.org': 0.21; 'fairly': 0.22; 'so.': 0.22; '2015': 0.23; 'wrote': 0.23; 'this:': 0.23; 'header:In-Reply-To:1': 0.24; 'equivalent': 0.27; 'parameters': 0.27; 'least': 0.27; 'see,': 0.27; 'message-id:@mail.gmail.com': 0.28; "i'm": 0.29; 'looks': 0.29; 'dictionary': 0.29; 'once.': 0.29; 'routine': 0.29; 'starts': 0.29; 'function': 0.30; "skip:' 10": 0.30; 'values': 0.30; 'code': 0.31; 'similar': 0.32; 'received:google.com': 0.34; 'minimum': 0.35; 'could': 0.35; 'list:': 0.35; 'but': 0.36; 'there': 0.36; 'should': 0.37; 'subject:: ': 0.37; "won't": 0.38; 'rather': 0.38; 'pm,': 0.39; 'test': 0.39; 'expect': 0.39; 'sure': 0.40; 'maximum': 0.61; 'simple': 0.61; 'entire': 0.61; 'more': 0.62; 'thomas': 0.63; 'picked': 0.66; '11:': 0.84; '12:': 0.84; '13:': 0.84; '14:': 0.84; '15:': 0.84; '9995': 0.84; 'cecil': 0.84; 'chrisa': 0.84; 'proves': 0.84; 'subject:Testing': 0.84; 'westerhof': 0.84; 'to:none': 0.90; 'crucial': 0.91; 'game,': 0.91; 'serious': 0.97 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type; bh=HRKUkAOaLn3YNOviDo6OoSGMiVRV4vMO1CRufWNu+EA=; b=hclC9vbx4TA7bofebhcnEsnNnRJSd54XexRMiuaUAY8OZmnbANJ+TrO/Pv+jViVxZL zi6jDT/SMT8dG+9zADPRFxnHb3pCAtWI7DUtjF20rIQemS8UQkRrhkyGpJ3K0ACdlE5P xHZ/Wd5umUanpfXnoA5bLqhmHm8jkzNjo99YZndyDCrgOoNWlhQidDCjbYfsTm1Dv+Ie 31E/ZSPY1pua9sSNw1YcVwXG5WIGEmNzwYiz+x2ximgC+ALeoLfN4KbK7A8OmGV8Ib60 ObAiFPsGcJoMpfC4Iy4rzsFNdw4ZaDULvFGbqf2Y66NNRO951BDEmPTL5oJQLkEtr4Sa l/tA== MIME-Version: 1.0 X-Received: by 10.50.61.241 with SMTP id t17mr7731348igr.34.1433677907064; Sun, 07 Jun 2015 04:51:47 -0700 (PDT) In-Reply-To: <1451048.pW9z17ilMA@PointedEars.de> References: <87oaksowwg.fsf@Equus.decebal.nl> <1451048.pW9z17ilMA@PointedEars.de> Date: Sun, 7 Jun 2015 21:51:47 +1000 Subject: Re: Testing random From: Chris Angelico Cc: "python-list@python.org" Content-Type: text/plain; charset=UTF-8 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20+ Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 57 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1433677915 news.xs4all.nl 2839 [2001:888:2000:d::a6]:58137 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:92236 On Sun, Jun 7, 2015 at 8:40 PM, Thomas 'PointedEars' Lahn wrote: > Cecil Westerhof wrote: > >> I wrote a very simple function to test random: >> def test_random(length, multiplier = 10000): >> number_list = length * [0] >> for i in range(length * multiplier): >> number_list[random.randint(0, length - 1)] += 1 >> minimum = min(number_list) >> maximum = max(number_list) >> return (minimum, maximum, minimum / maximum) > > As there is no guarantee that every number will occur randomly, using a > dictionary at first should be more efficient than a list: Hmm, I'm not sure that's actually so. His code is aiming to get 'multiplier' values in each box; for any serious multiplier (he starts with 10 in the main code), you can be fairly confident that every number will come up at least once. The distribution of numbers won't ever be perfectly even, but you'd expect it to be reasonably close. I have a similar routine on my Dungeons & Dragons server; since a roll of a twenty-sided dice is crucial to most of the game, I have a simple tester that proves to people that the in-built dice roller is fair. Its output looks like this: > roll test 1: 10017 2: 10003 3: 9966 4: 9728 5: 10088 6: 9888 7: 10087 8: 9971 9: 10052 10: 10061 11: 10130 12: 9942 13: 10062 14: 10075 15: 10050 16: 9948 17: 9880 18: 10052 19: 9995 20: 10005 Standard deviation: 90.18 (0.90%) This is about equivalent to test_random(20), and as you see, he and I both picked a multiplier of 10K to use by default. (I call the parameters "max" and "avg" rather than "length" and "multiplier", but they have the exact same semantics.) The hard part is figuring out what "looks reasonable"; a true RNG could legitimately produce nothing but 7s for the entire run, it's just extremely unlikely. ChrisA