"random" --- 疑似乱数を生成する
*******************************

**ソースコード:** Lib/random.py

======================================================================

このモジュールでは様々な分布をもつ擬似乱数生成器を実装しています。

整数用に、ある範囲からの一様な選択があります。 シーケンス用には、シー
ケンスからのランダムな要素の一様な選択、リストのランダムな置換をインプ
レースに生成する関数、選んだ要素を母集団に戻さずにランダムサンプリング
する関数があります。

実数用としては、一様分布、正規分布 (ガウス分布)、対数正規分布、負の指
数分布、ガンマおよびベータ分布を計算する関数があります。角度の分布を生
成するにはフォン・ミーゼス分布が利用できます。

ほとんど全てのモジュール関数は、基礎となる関数 "random()" に依存します
。この関数はランダムな浮動小数点数を半開区間 "0.0 <= X < 1.0" 内に一様
に生成します。Python は中心となる乱数生成器としてメルセンヌツイスタを
使います。これは 53 ビット精度の浮動小数点を生成し、周期は 2**19937-1
です。本体は C で実装されていて、高速でスレッドセーフです。メルセンヌ
ツイスタは、現存する中で最も広範囲にテストされた乱数生成器のひとつです
。しかしながら、メルセンヌツイスタは完全に決定論的であるため、全ての目
的に合致しているわけではなく、暗号化の目的には全く向いていません。

このモジュールで提供されている関数は、実際には "random.Random" クラス
の隠蔽されたインスタンスのメソッドに束縛されています。内部状態を共有し
ない生成器を取得するため、自分で "Random" のインスタンスを生成すること
ができます。

独自に考案した別の基本生成器を使う場合は、"Random" クラスをサブクラス
化することもできます。 詳しくは同クラスのドキュメントを参照してくださ
い。

"random" モジュールは "SystemRandom" クラスも提供しています。 このクラ
スはシステム関数 "os.urandom()" を使い、オペレーティングシステムが提供
する発生源から乱数を生成します。

警告:

  このモジュールの擬似乱数生成器をセキュリティ目的に使用してはいけませ
  ん。セキュリティや暗号学的な用途については "secrets" モジュールを参
  照してください。

参考:

  M. Matsumoto and T. Nishimura, "Mersenne Twister: A
  623-dimensionally equidistributed uniform pseudorandom number
  generator", ACM Transactions on Modeling and Computer Simulation
  Vol. 8, No. 1, January pp.3--30 1998.

  Complementary-Multiply-with-Carry recipe  長い周期と比較的シンプルな
  更新操作を備えた互換性のある別の乱数生成器。

注釈:

  グローバルな乱数生成器と "Random" のインスタンスはスレッドセーフです
  。 ただし、フリースレッドビルドでは、グローバルな生成器や同じ
  "Random" インスタンスを同時に呼び出すと、競合によって性能が低下する
  場合があります。 代わりにスレッドごとに別の "Random" インスタンスを
  使うことを検討してください。


保守 (bookkeeping) 関数
=======================

random.seed(a=None, version=2)

   乱数生成器を初期化します。

   *a* が省略されるか "None" の場合、現在のシステム時刻が使用されます
   。乱数のソースがオペレーティングシステムによって提供される場合、シ
   ステム時刻の代わりにそれが使用されます (利用可能性についての詳細は
   "os.urandom()" 関数を参照)。

   *a* が int の場合は、その絶対値が直接使用されます。

   バージョン2 (デフォルト) では、 "str", "bytes", "bytearray" オブジ
   ェクトは "int" に変換され、そのビットがすべて使用されます。

   バージョン1 (Python の古いバージョンでの乱数列を再現するために提供
   される) では、 "str" と "bytes" に対して適用されるアルゴリズムは、
   より狭い範囲のシードを生成します。

   バージョン 3.2 で変更: 文字列シードのすべてのビットを使うバージョン
   2スキームに移行。

   バージョン 3.11 で変更: *seed* は次の型の内のいずれかでなければなり
   ません: "None"、"int"、"float"、"str"、"bytes"、"bytearray"。

random.getstate()

   乱数生成器の現在の内部状態を記憶したオブジェクトを返します。このオ
   ブジェクトを "setstate()" に渡して内部状態を復元することができます
   。

random.setstate(state)

   *state* は予め "getstate()" を呼び出して得ておかなくてはなりません
   。 "setstate()" は "getstate()" が呼び出された時の乱数生成器の内部
   状態を復元します。


バイト列用の関数
================

random.randbytes(n)

   *n* バイトのランダムなバイト列を生成します。

   セキュリティトークンを生成する目的で、このメソッドを使用しないでく
   ださい。代わりに "secrets.token_bytes()" を使用してください。

   Added in version 3.9.


整数用の関数
============

random.randrange(stop)
random.randrange(start, stop[, step])

   "range(start, stop, step)" の要素からランダムに選ばれた要素を返しま
   す。

   これはおおむね "choice(range(start, stop, step))" と等価ですが、任
   意の大きさの範囲を扱え、一般的なケース向けに最適化されています。

   位置引数のパターンは "range()" 関数の引数と一致します。

   キーワード引数は予期しない解釈をされることがあるため、使わないでく
   ださい。 例えば "randrange(start=100)" は "randrange(0, 100, 1)" と
   解釈されます。

   バージョン 3.2 で変更: 一様に分布した値の生成に関して "randrange()"
   がより洗練されました。以前は "int(random()*n)" のようなやや一様でな
   い分布を生成するスタイルを使用していました。

   バージョン 3.12 で変更: 整数以外の型の自動変換はサポートされなくな
   りました。"randrange(10.0)" や "randrange(Fraction(10, 1))" のよう
   な呼び出しは "TypeError" を送出します。

random.randint(a, b)

   "a <= N <= b" であるようなランダムな整数 *N* を返します。
   "randrange(a, b+1)" のエイリアスです。

random.getrandbits(k)

   *k* 桁の乱数ビットを持つ Python の非負整数を生成し、返します。 この
   メソッドはメルセンヌツイスタ生成器で提供されており、その他の乱数生
   成器でもオプションの API として提供されている場合があります。
   "getrandbits()" が使用可能な場合、"randrange()" は任意の範囲の乱数
   を生成できるようになります。

   バージョン 3.9 で変更: *k* の値として 0 が許されるようになりました
   。


シーケンス用の関数
==================

random.choice(seq)

   空でないシーケンス *seq* からランダムに要素を返します。 *seq* が空
   のときは、 "IndexError" が送出されます。

random.choices(population, weights=None, *, cum_weights=None, k=1)

   *population* から重複ありで選んだ要素からなる大きさ *k* のリストを
   返します。*population* が空の場合 "IndexError" を送出します。

   *weights* シーケンスが与えられた場合、相対的な重みに基づいて要素が
   選ばれます。あるいは、*cum_weights* シーケンスが与えられた場合、累
   積的な重み ("itertools.accumulate()" を用いて計算されるかもしれませ
   ん) で要素が選ばれます。例えば、相対的な重み "[10, 5, 30, 5]" は累
   積的な重み "[10, 15, 45, 50]" と等価です。内部的には、相対的な重み
   は要素選択の前に累積的な重みに変換されるため、累積的な重みを渡すと
   手間を省けます。

   *weights* および *cum_weights* が与えられなかった場合、要素は同じ確
   率で選択されます。重みのシーケンスが与えられた場合、その長さは
   *population* シーケンスと同じでなければなりません。*weights* と
   *cum_weights* を同時に与えると "TypeError" が送出されます。

   *weights* や *cum_weights* には、"random()" が返す "float" 値と組み
   合わせて演算できる任意の数値型を使用できます (整数、浮動小数点数、
   有理数は含みますが、十進数は除きます)。 重みは非負かつ有限であるこ
   とが前提です。 すべての重みが 0 の場合、"ValueError" が送出されます
   。

   与えられた種に対して、同じ重みを持つ "choices()" 関数は、一般に
   "choice()" を繰り返し呼び出す場合とは異なるシーケンスを生成します。
   "choices()" で使用されるアルゴリズムは、内部の一貫性とスピードのた
   めに浮動小数点演算を使用します。 "choice()" で使われるアルゴリズム
   は、丸め誤差による小さな偏りを避けるために、デフォルトでは選択を繰
   り返す整数演算になっています。

   Added in version 3.6.

   バージョン 3.9 で変更: 全ての重みが 0 の場合、例外 "ValueError" を
   送出します。

random.shuffle(x)

   シーケンス *x* をインプレースにシャッフルします。

   イミュータブルなシーケンスをシャッフルしてシャッフルされたリストを
   新たに返すには、代わりに "sample(x, k=len(x))" を使用してください。

   たとえ "len(x)" が小さくても、*x* の並べ替えの総数 (訳注: 要素数の
   階乗) は大半の乱数生成器の周期よりもすぐに大きくなることに注意して
   ください。つまり、長いシーケンスの大半の並べ替えは決して生成されな
   いだろう、ということです。例えば、長さ 2080 のシーケンスがメルセン
   ヌツイスタ生成器の周期に収まる中で最大のものになります。

   バージョン 3.11 で変更: オプション引数 *random* が削除されました。

random.sample(population, k, *, counts=None)

   母集団のシーケンスから選ばれた長さ *k* の一意な要素からなるリストを
   返します。 選んだ要素を母集団に戻さない非復元抽出に用いられます。

   母集団自体を変更せずに、母集団内の要素を含む新たなリストを返します
   。返されたリストは選択された順に並んでいるので、このリストの部分ス
   ライスもランダムなサンプルになります。これにより、くじの当選者 (サ
   ンプル) を1等賞と2等賞（の部分スライス）に分けることも可能です。

   母集団の要素は *ハッシュ可能* でなくても、ユニークでなくてもかまい
   ません。母集団が繰り返しを含む場合、出現するそれぞれがサンプルに選
   択されえます。

   母集団に重複がある場合はその分だけ1つずつ指定するか、キーワード専用
   オプション引数 *counts* で指定することができます。例えば、
   "sample(['red', 'blue'], counts=[4, 2], k=5)" は "sample(['red',
   'red', 'red', 'red', 'blue', 'blue'], k=5)" と等価になります。

   ある範囲の整数からサンプルを取る場合、引数に "range()" オブジェクト
   を使用してください。大きな母集団の場合、これは特に速く、メモリ効率
   が良いです: "sample(range(10000000), k=60)"。

   サンプルの大きさが母集団の大きさより大きい場合 "ValueError" が送出
   されます。

   バージョン 3.9 で変更: *counts* 引数が追加されました。

   バージョン 3.11 で変更: *population* 変数はシーケンスでなければなり
   ません。 setsのリストへの暗黙の型変換はサポートされていません。


離散分布
========

次の関数は離散分布に従う乱数を生成します。

random.binomialvariate(n=1, p=0.5)

   二項分布。 各試行の成功確率が *p* である *n* 回の独立した試行の成功
   回数を返します。

   数学的には次と等価です。

      sum(random() < p for i in range(n))

   試行回数 *n* は非負の整数でなければなりません。 成功確率 *p* は
   "0.0 <= p <= 1.0" の範囲でなければなりません。 結果は "0 <= X <= n"
   の範囲の整数です。

   Added in version 3.12.


実数分布
========

以下の関数は特定の実数値分布を生成します。関数の引数の名前は、一般的な
数学の慣例で使われている分布の公式の対応する変数から取られています; こ
れらの公式のほとんどはどんな統計学のテキストにも載っています。

random.random()

   ランダムな浮動小数点数（範囲は "0.0 <= X < 1.0"）を返します。

random.uniform(a, b)

   "a <= b" であれば "a <= N <= b" 、"b < a" であれば "b <= N <= a" で
   あるようなランダムな浮動小数点数 *N* を返します。

   端点の値 "b" が範囲に含まれるかどうかは、式 "a + (b-a) * random()"
   における浮動小数点の丸めに依存します。

random.triangular(low, high, mode)

   "low <= N <= high" でありこれら境界値の間に指定された最頻値 *mode*
   を持つようなランダムな浮動小数点数 *N* を返します。境界 *low* と
   *high* のデフォルトは 0 と 1 です。最頻値 *mode* 引数のデフォルトは
   両境界値の中点になり、対称な分布を与えます。

random.betavariate(alpha, beta)

   ベータ分布です。引数の満たすべき条件は "alpha > 0" および "beta >
   0" です。 0 から 1 の範囲の値を返します。

random.expovariate(lambd=1.0)

   指数分布です。 *lambd* は求める平均値で 1.0 を割った値で、ゼロであ
   ってはなりません。 (引数名は本来 "lambda" としたいところですが、
   Python の予約語なので使えません。) 返される値の範囲は、*lambd* が正
   なら 0 から正の無限大、負なら負の無限大から 0 です。

   バージョン 3.12 で変更: "lambd" にデフォルト値を追加しました。

random.gammavariate(alpha, beta)

   ガンマ分布です (ガンマ関数では *ありません*)。 形状パラメーター
   *alpha* と尺度パラメーター *beta* は正の値でなければなりません。 (
   引数の指定方法は資料によって異なり、'beta' を尺度の逆数と定義する資
   料もあります。)

   確率分布関数は:

                x ** (alpha - 1) * math.exp(-x / beta)
      pdf(x) =  --------------------------------------
                  math.gamma(alpha) * beta ** alpha

random.gauss(mu=0.0, sigma=1.0)

   正規分布、またはガウス分布と呼ばれます。 *mu* は平均であり、
   *sigma* は標準偏差です。この関数は後で定義する関数
   "normalvariate()" より少しだけ高速です。

   マルチスレッドでの注意: 2 つのスレッドがこの関数を同時に呼び出すと
   、同じ戻り値を受け取る可能性があります。 これは 3 つの方法で避けら
   れます。 1) スレッドごとに別の乱数生成器のインスタンスを使う。 2)
   すべての呼び出しをロックで保護する。 3) 速度は遅いもののスレッドセ
   ーフな "normalvariate()" 関数を代わりに使う。

   バージョン 3.11 で変更: *mu* と *sigma* にデフォルト値を追加しまし
   た。

random.lognormvariate(mu, sigma)

   対数正規分布です。この分布を自然対数を用いた分布にした場合、平均
   *mu* で標準偏差 *sigma* の正規分布になります。 *mu* は任意の値を取
   ることができ、*sigma* はゼロより大きくなければなりません。

random.normalvariate(mu=0.0, sigma=1.0)

   正規分布です。 *mu* は平均で、 *sigma* は標準偏差です。

   バージョン 3.11 で変更: *mu* と *sigma* にデフォルト値を追加しまし
   た。

random.vonmisesvariate(mu, kappa)

   *mu* は平均の角度で、0 から 2**pi* までのラジアンで表されます。
   *kappa* は濃度パラメータで、ゼロ以上でなければなりません。*kappa*
   がゼロに等しい場合、この分布は範囲 0 から 2**pi* の一様でランダムな
   角度の分布に退化します。

random.paretovariate(alpha)

   パレート分布です。 *alpha* は形状パラメータです。

random.weibullvariate(alpha, beta)

   ワイブル分布です。 *alpha* は尺度パラメタで、 *beta* は形状パラメー
   タです。


他の生成器
==========

class random.Random([seed])

   "random" モジュールが使うデフォルトの疑似乱数生成器を実装するクラス
   です。

   バージョン 3.11 で変更: 以前は *seed* は任意のハッシュ可能オブジェ
   クトが設定可能でした。現在は "None", "int", "float", "str",
   "bytes", "bytearray" に制限されています。

   異なる基本生成器を使う "Random" のサブクラスでは、次のメソッドをオ
   ーバーライドしてください。

   seed(a=None, version=2)

      "Random" インスタンスの "seed()" の動作を変更するには、サブクラ
      スでこのメソッドをオーバーライドします。

   getstate()

      "Random" インスタンスの "getstate()" の動作を変更するには、サブ
      クラスでこのメソッドをオーバーライドします。

   setstate(state)

      "Random" インスタンスの "setstate()" の動作を変更するには、サブ
      クラスでこのメソッドをオーバーライドします。

   random()

      "Random" インスタンスの "random()" の動作を変更するには、サブク
      ラスでこのメソッドをオーバーライドします。

   カスタムの生成器のサブクラスでは、必要に応じて次のメソッドも提供で
   きます。

   getrandbits(k)

      "Random" インスタンスの "getrandbits()" の動作を変更するには、サ
      ブクラスでこのメソッドをオーバーライドします。

   randbytes(n)

      "Random" インスタンスの "randbytes()" の動作を変更するには、サブ
      クラスでこのメソッドをオーバーライドします。

class random.SystemRandom([seed])

   オペレーティングシステムの提供する発生源によって乱数を生成する
   "os.urandom()" 関数を使うクラスです。 すべてのシステムで使えるメソ
   ッドではありません。 ソフトウェアの状態に依存せず、生成される乱数列
   は再現できません。 従って、 "seed()" メソッドは何の影響も及ぼさず、
   無視されます。 "getstate()" と "setstate()" メソッドが呼び出される
   と、例外 "NotImplementedError" が送出されます。


再現性について
==============

疑似乱数生成器から与えられたシーケンスを再現できると便利なことがありま
す。シード値を再利用することで、複数のスレッドが実行されていない限り、
実行ごとに同じシーケンスが再現できます。

random モジュールのアルゴリズムやシード処理関数のほとんどは、Python バ
ージョン間で変更される対象となりますが、次の二点は変更されないことが保
証されています:

* 新しいシード処理メソッドが追加されたら、後方互換なシード処理器が提供
  されます。

* 生成器の "random()" メソッドは、互換なシード処理器に同じシードが与え
  られた場合、引き続き同じシーケンスを生成します。


使用例
======

基礎的な例:

   >>> random()                          # ランダムな浮動小数点数:  0.0 <= x < 1.0
   0.37444887175646646

   >>> uniform(2.5, 10.0)                # ランダムな浮動小数点数:  2.5 <= x <= 10.0
   3.1800146073117523

   >>> expovariate(1 / 5)                # 平均 5 秒の到着間隔
   5.148957571865031

   >>> randrange(10)                     # 0 から 9 までの整数 (両端を含む)
   7

   >>> randrange(0, 101, 2)              # 0 から 100 までの偶数 (両端を含む)
   26

   >>> choice(['win', 'lose', 'draw'])   # シーケンスからランダムに選んだ 1 要素
   'draw'

   >>> deck = 'ace two three four'.split()
   >>> shuffle(deck)                     # リストをシャッフルする。
   >>> deck
   ['four', 'two', 'ace', 'three']

   >>> sample([10, 20, 30, 40, 50], k=4) # 非復元抽出で選んだ 4 要素
   [40, 10, 50, 30]

シミュレーション:

   >>> # ルーレットを 6 回回す (重み付きの復元抽出)。
   >>> choices(['red', 'black', 'green'], [18, 18, 2], k=6)
   ['red', 'green', 'black', 'black', 'red', 'black']

   >>> # 52 枚のトランプから 20 枚を非復元抽出で配り、
   >>> # 値が 10 となるカード (10、ジャック、クイーン、キング) の
   >>> # 割合を求める。
   >>> deal = sample(['tens', 'low cards'], counts=[16, 36], k=20)
   >>> deal.count('tens') / 20
   0.15

   >>> # 表が出る確率が 60% の偏ったコインを 7 回投げて、
   >>> # 表が 5 回以上出る確率を推定する。
   >>> sum(binomialvariate(n=7, p=0.6) >= 5 for i in range(10_000)) / 10_000
   0.4169

   >>> # 5 個のサンプルの中央値が中央の 2 つの四分位区間に入る確率
   >>> def trial():
   ...     return 2_500 <= sorted(choices(range(10_000), k=5))[2] < 7_500
   ...
   >>> sum(trial() for i in range(10_000)) / 10_000
   0.7958

サンプルの平均の信頼区間を推定するのに、重複ありでリサンプリングして
統計的ブートストラップ を行う例:

   # https://www.thoughtco.com/example-of-bootstrapping-3126155
   from statistics import fmean as mean
   from random import choices

   data = [41, 50, 29, 37, 81, 30, 73, 63, 20, 35, 68, 22, 60, 31, 95]
   means = sorted(mean(choices(data, k=len(data))) for i in range(100))
   print(f'The sample mean of {mean(data):.1f} has a 90% confidence '
         f'interval from {means[5]:.1f} to {means[94]:.1f}')

薬と偽薬の間に観察された効果の違いについて、統計的有意性、すなわち p
値 を決定するために、リサンプリング順列試験 を行う例:

   # Dennis Shasha と Manda Wilson の "Statistics is Easy" に掲載された例
   from statistics import fmean as mean
   from random import shuffle

   drug = [54, 73, 53, 70, 73, 68, 52, 65, 65]
   placebo = [54, 51, 58, 44, 55, 52, 42, 47, 58, 46]
   observed_diff = mean(drug) - mean(placebo)

   n = 10_000
   count = 0
   combined = drug + placebo
   for i in range(n):
       shuffle(combined)
       new_diff = mean(combined[:len(drug)]) - mean(combined[len(drug):])
       count += (new_diff >= observed_diff)

   print(f'{n} label reshufflings produced only {count} instances with a difference')
   print(f'at least as extreme as the observed difference of {observed_diff:.1f}.')
   print(f'The one-sided p-value of {count / n:.4f} leads us to reject the null')
   print(f'hypothesis that there is no difference between the drug and the placebo.')

マルチサーバーキューにおける到達時間とサービス提供のシミュレーション:

   from heapq import heapify, heapreplace
   from random import expovariate, gauss
   from statistics import mean, quantiles

   average_arrival_interval = 5.6
   average_service_time = 15.0
   stdev_service_time = 3.5
   num_servers = 3

   waits = []
   arrival_time = 0.0
   servers = [0.0] * num_servers  # 各サーバーが利用可能になる時刻
   heapify(servers)
   for i in range(1_000_000):
       arrival_time += expovariate(1.0 / average_arrival_interval)
       next_server_available = servers[0]
       wait = max(0.0, next_server_available - arrival_time)
       waits.append(wait)
       service_duration = max(0.0, gauss(average_service_time, stdev_service_time))
       service_completed = arrival_time + wait + service_duration
       heapreplace(servers, service_completed)

   print(f'Mean wait: {mean(waits):.1f}   Max wait: {max(waits):.1f}')
   print('Quartiles:', [round(q, 1) for q in quantiles(waits)])

参考:

  Statistics for Hackers Jake Vanderplas による統計解析のビデオ。シミ
  ュレーション、サンプリング、シャッフル、交差検定といった基本的な概念
  のみを用いています。

  Economics Simulation Peter Norvig による市場価格のシミュレーション。
  このモジュールが提供する多くのツールや分布 (gauss, uniform, sample,
  betavariate, choice, triangular, randrange) の活用法を示しています。

  A Concrete Introduction to Probability (using Python) Peter Norvig
  によるチュートリアル。確率論の基礎、シミュレーションの書き方、Python
  を使用したデータ解析法をカバーしています。


レシピ
======

以下のレシピは、"itertools" モジュールや more-itertools プロジェクトの
組合せイテレータから効率よくランダムに選択する方法を示します。

   import random

   def random_product(*iterables, repeat=1):
       "次からランダムに選択: itertools.product(*iterables, repeat=repeat)"
       pools = tuple(map(tuple, iterables)) * repeat
       return tuple(map(random.choice, pools))

   def random_permutation(iterable, r=None):
       "次からランダムに選択: itertools.permutations(iterable, r)"
       pool = tuple(iterable)
       r = len(pool) if r is None else r
       return tuple(random.sample(pool, r))

   def random_combination(iterable, r):
       "次からランダムに選択: itertools.combinations(iterable, r)"
       pool = tuple(iterable)
       n = len(pool)
       indices = sorted(random.sample(range(n), r))
       return tuple(pool[i] for i in indices)

   def random_combination_with_replacement(iterable, r):
       """復元抽出で r 個の要素を選ぶ。
       結果は iterable 内の順序に合わせて並べる。
       """
       # 結果は set(itertools.combinations_with_replacement(iterable, r)) に含まれる。
       pool = tuple(iterable)
       n = len(pool)
       indices = sorted(random.choices(range(n), k=r))
       return tuple(pool[i] for i in indices)

   def random_derangement(iterable):
       "どの要素も元の位置に残らない順列を選ぶ。"
       seq = tuple(iterable)
       if len(seq) < 2:
           if not seq:
               return ()
           raise IndexError('No derangments to choose from')
       perm = list(range(len(seq)))
       start = tuple(perm)
       while True:
           random.shuffle(perm)
           if all(p != q for p, q in zip(start, perm)):
               return tuple([seq[i] for i in perm])

デフォルトの "random()" は、*0.0 ≤ x < 1.0* の範囲にある 2⁻⁵³ の倍数を
返します。 これらの数はすべて等間隔で、Python の浮動小数点数として正確
に表現できます。 ただし、この区間内にある他の多くの表現可能な浮動小数
点数は選ばれません。 例えば、"0.05954861408025609" は 2⁻⁵³ の整数倍で
はありません。

次のレシピは別の方法を使います。 区間内のすべての浮動小数点数が選択対
象になります。 仮数は *2⁵² ≤ mantissa < 2⁵³* の範囲の整数の一様分布か
ら得ます。 指数は幾何分布から得られ、*-53* より小さい指数の出現頻度は
、1 つ大きい指数の半分です。

   from random import Random
   from math import ldexp

   class FullRandom(Random):

       def random(self):
           mantissa = 0x10_0000_0000_0000 | self.getrandbits(52)
           exponent = -53
           x = 0
           while not x:
               x = self.getrandbits(32)
               exponent += x.bit_length() - 32
           return ldexp(mantissa, exponent)

このクラスのすべての 実数値分布 は、新しいメソッドを使います。

   >>> fr = FullRandom()
   >>> fr.random()
   0.05954861408025609
   >>> fr.expovariate(0.25)
   8.87925541791544

The recipe is conceptually equivalent to an algorithm that chooses
from all the multiples of 2⁻¹⁰⁷⁴ in the range *0.0 ≤ x < 1.0*.  All
such numbers are evenly spaced, but most have to be rounded down to
the nearest representable Python float.  (The value 2⁻¹⁰⁷⁴ is the
smallest positive unnormalized float and is equal to "math.ulp(0.0)".)

参考:

  Generating Pseudo-random Floating-Point Values は、通常の "random()"
  より細かい間隔の浮動小数点数を生成する方法について述べた Allen B.
  Downey の論文です。


コマンドラインでの使用
======================

Added in version 3.13.

"random" モジュールはコマンドラインから実行できます。

   python -m random [-h] [-c CHOICE [CHOICE ...] | -i N | -f N] [input ...]

以下のオプションが使用できます:

-h, --help

   ヘルプメッセージを表示して終了します。

-c CHOICE [CHOICE ...]
--choice CHOICE [CHOICE ...]

   "choice()" を使用してランダムに選択して出力します。

-i <N>
--integer <N>

   "randint()" を使用して1からNの間(Nを含む)のランダムな整数を出力しま
   す。

-f <N>
--float <N>

   "uniform()" を使用して0からNの間(Nを含む)のランダムな浮動小数点数を
   出力します。

オプションが指定されない場合、出力は入力に依存します。

* 文字列または複数: "--choice" と同じ。

* 整数: "--integer" と同じ。

* 浮動小数点数: "--float" と同じ。


コマンドラインの例
==================

以下は "random" のコマンドラインインターフェースの例です:

   $ # ランダムに 1 つ選ぶ。
   $ python -m random egg bacon sausage spam "Lobster Thermidor aux crevettes with a Mornay sauce"
   Lobster Thermidor aux crevettes with a Mornay sauce

   $ # ランダムな整数
   $ python -m random 6
   6

   $ # ランダムな浮動小数点数
   $ python -m random 1.8
   1.7080016272295635

   $ # 明示的な引数を使う。
   $ python  -m random --choice egg bacon sausage spam "Lobster Thermidor aux crevettes with a Mornay sauce"
   egg

   $ python -m random --integer 6
   3

   $ python -m random --float 1.8
   1.5666339105010318

   $ python -m random --integer 6
   5

   $ python -m random --float 6
   3.1942323316565915
