Skip to content

Commit 0374d1c

Browse files
colinleachBethanyG
andauthored
new random concept (#3556)
* new `random` concept * changed unused variables to underscore * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md I have been avoiding $\LaTeX$ (very reluctantly, but Jeremy and Erik insist). I guess Unicode will save us here. Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Update concepts/random/about.md Co-authored-by: BethanyG <[email protected]> * Added Introduction.md and Links * Small touchups and link fixes * More Typo Fixes --------- Co-authored-by: BethanyG <[email protected]>
1 parent a706592 commit 0374d1c

File tree

5 files changed

+377
-0
lines changed

5 files changed

+377
-0
lines changed

concepts/random/.meta/config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"blurb": "The random module contains functionality to generate random values for modelling, simulations and games. It should not be used for security or cryptographic applications.",
3+
"authors": ["BethanyG", "colinleach"],
4+
"contributors": []
5+
}

concepts/random/about.md

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
# About
2+
3+
Many programs need (apparently) random values to simulate real-world events.
4+
5+
Common, familiar examples include:
6+
- A coin toss: a random value from `('H', 'T')`.
7+
- The roll of a die: a random integer from 1 to 6.
8+
- Shuffling a deck of cards: a random ordering of a card list.
9+
10+
Generating truly random values with a computer is a [surprisingly difficult technical challenge][truly-random], so you may see these results referred to as "pseudorandom".
11+
12+
In practice, a well-designed library like the [`random`][random] module in the Python standard library is fast, flexible, and gives results that are amply good enough for most applications in modelling, simulation and games.
13+
14+
The rest of this page will list a few of the most common functions in `random`.
15+
We encourage you to explore the full `random` documentation, as there are many more options than what we cover here.
16+
17+
18+
19+
~~~~exercism/caution
20+
21+
The `random` module should __NOT__ be used for security and cryptographic applications.
22+
23+
Instead, Python provides the [`secrets`][secrets] module.
24+
This is specially optimized for cryptographic security.
25+
Some of the prior issues and reasons for creating the secrets module can be found in [PEP 506][PEP 506].
26+
27+
[secrets]: https://docs.python.org/3.11/library/secrets.html#module-secrets
28+
[PEP 506]: https://peps.python.org/pep-0506/
29+
~~~~
30+
31+
32+
33+
## Importing
34+
35+
Before you can utilize the tools in the `random` module, you must first import it:
36+
37+
```python
38+
>>> import random
39+
40+
# Choose random integer from a range
41+
>>> random.randrange(1000)
42+
360
43+
44+
>>> random.randrange(-1, 500)
45+
228
46+
47+
>>> random.randrange(-10, 11, 2)
48+
-8
49+
50+
# Choose random integer between two values (inclusive)
51+
>>> random.randint(5, 25)
52+
22
53+
54+
```
55+
56+
To avoid typing the name of the module, you can import specific functions by name:
57+
58+
```python
59+
>>> from random import choice, choices
60+
61+
# Using choice() to pick Heads or Tails 10 times
62+
>>> tosses = []
63+
>>> for side in range(10):
64+
>>> tosses.append(choice(['H', 'T']))
65+
66+
>>> print(tosses)
67+
['H', 'H', 'H', 'H', 'H', 'H', 'H', 'T', 'T', 'H']
68+
69+
70+
# Using choices() to pick Heads or Tails 8 times
71+
>>> picks = []
72+
>>> picks.extend(choices(['H', 'T'], k=8))
73+
>>> print(picks)
74+
['T', 'H', 'H', 'T', 'H', 'H', 'T', 'T']
75+
```
76+
77+
78+
## Creating random integers
79+
80+
The `randrange()` function has three forms, to select a random value from `range(start, stop, step)`:
81+
1. `randrange(stop)` gives an integer `n` such that `0 <= n < stop`
82+
2. `randrange(start, stop)` gives an integer `n` such that `start <= n < stop`
83+
3. `randrange(start, stop, step)` gives an integer `n` such that `start <= n < stop` and `n` is in the sequence `start, start + step, start + 2*step...`
84+
85+
For the common case where `step == 1`, the `randint(a, b)` function may be more convenient and readable.
86+
Possible results from `randint()` _include_ the upper bound, so `randint(a, b)` is the same as using `randrange(a, b+1)`:
87+
88+
```python
89+
>>> import random
90+
91+
# Select one number at random from the range 0, 499
92+
>>> random.randrange(500)
93+
219
94+
95+
# Select 10 numbers at random between 0 and 9 two steps apart.
96+
>>> numbers = []
97+
>>> for integer in range(10):
98+
>>> numbers.append(random.randrange(0, 10, 2))
99+
>>> print(numbers)
100+
[2, 8, 4, 0, 4, 2, 6, 6, 8, 8]
101+
102+
# roll a die
103+
>>> random.randint(1, 6)
104+
4
105+
```
106+
107+
108+
109+
## Working with sequences
110+
111+
The functions in this section assume that you are starting from some [sequence][sequence-types], or other container.
112+
113+
114+
This will typically be a `list`, or with some limitations a `tuple` or a `set` (_a `tuple` is immutable, and `set` is unordered_).
115+
116+
117+
118+
### `choice()` and `choices()`
119+
120+
The `choice()` function will return one entry chosen at random from a given sequence.
121+
At its simplest, this might be a coin-flip:
122+
123+
```python
124+
# This will pick one of the two values in the list at random 5 separate times
125+
>>> [random.choice(['H', 'T']) for _ in range(5)]
126+
['T', 'H', 'H', 'T', 'H']
127+
128+
We could accomplish essentially the same thing using the `choices()` function, supplying a keyword argument with the list length:
129+
130+
131+
```python
132+
>>> random.choices(['H', 'T'], k=5)
133+
['T', 'H', 'T', 'H', 'H']
134+
```
135+
136+
137+
In the examples above, we assumed a fair coin with equal probability of heads or tails, but weights can also be specified.
138+
For example, if a bag contains 10 red balls and 15 green balls, and we would like to pull one out at random:
139+
140+
```python
141+
>>> random.choices(['red', 'green'], [10, 15])
142+
['red']
143+
```
144+
145+
146+
147+
### `sample()`
148+
149+
The `choices()` example above assumes what statisticians call ["sampling with replacement"][sampling-with-replacement].
150+
Each pick or choice has **no effect** on the probability of future choices, and the distribution of potential choices remains the same from pick to pick.
151+
152+
153+
In the example with red and green balls: after each choice, we _return_ the ball to the bag and shake well before the next pick.
154+
This is in contrast to a situation where we pull out a red ball and _it stays out_.
155+
Not returning the ball means there are now fewer red balls in the bag, and the next choice is now _less likely_ to be red.
156+
157+
To simulate this "sampling without replacement", the random module provides the `sample()` function.
158+
The syntax of `sample()` is similar to `choices()`, except it adds a `counts` keyword parameter:
159+
160+
161+
```python
162+
>>> random.sample(['red', 'green'], counts=[10, 15], k=10)
163+
['green', 'green', 'green', 'green', 'green', 'red', 'red', 'red', 'red', 'green']
164+
```
165+
166+
Samples are returned in the order they were chosen.
167+
168+
169+
170+
### `shuffle()`
171+
172+
Both `choices()` and `sample()` return new lists when `k > 1`.
173+
In contrast, `shuffle()` randomizes the order of a list _**in place**_, and the original ordering is lost:
174+
175+
```python
176+
>>> my_list = [1, 2, 3, 4, 5]
177+
>>> random.shuffle(my_list)
178+
>>> my_list
179+
[4, 1, 5, 2, 3]
180+
```
181+
182+
183+
## Working with Distributions
184+
185+
Until now, we have concentrated on cases where all outcomes are equally likely.
186+
For example, `random.randrange(100)` is equally likely to give any integer from 0 to 99.
187+
188+
Many real-world situations are far less simple than this.
189+
As a result, statisticians have created a wide variety of [`distributions`][probability-distribution] to describe "real world" results mathematically.
190+
191+
192+
193+
### Uniform distributions
194+
195+
For integers, `randrange()` and `randint()` are used when all probabilities are equal.
196+
This is called a [`uniform`][uniform-distribution] distribution.
197+
198+
199+
There are floating-point equivalents to `randrange()` and `randint()`.
200+
201+
__`random()`__ gives a `float` value `x` such that `0.0 <= x < 1.0`.
202+
203+
__`uniform(a, b)`__ gives `x` such that `a <= x <= b`.
204+
205+
```python
206+
>>> [round(random.random(), 3) for _ in range(5)]
207+
[0.876, 0.084, 0.483, 0.22, 0.863]
208+
209+
>>> [round(random.uniform(2, 5), 3) for _ in range(5)]
210+
[2.798, 2.539, 3.779, 3.363, 4.33]
211+
```
212+
213+
214+
215+
### Gaussian distribution
216+
217+
Also called the "normal" distribution or the "bell-shaped" curve, this is a very common way to describe imprecision in measured values.
218+
219+
For example, suppose the factory where you work has just bought 10,000 bolts which should be identical.
220+
You want to set up the factory robot to handle them, so you weigh a sample of 100 and find that they have an average (or `mean`) weight of 4.731g.
221+
This is extremely unlikely to mean that they all weigh exactly 4.731g.
222+
Perhaps you find that values range from 4.627 to 4.794g but cluster around 4.731g.
223+
224+
This is the [`Gaussian distribution`][gaussian-distribution], for which probabilities peak at the mean and tails off symmetrically on both sides (hence "bell-shaped").
225+
To simulate this in software, we need some way to specify the width of the curve (_typically, expensive bolts will cluster more tightly around the mean than cheap bolts!_).
226+
227+
By convention, this is done with the [`standard deviation`][standard-deviation]: small values for a sharp, narrow curve, large for a low, broad curve.
228+
Mathematicians love Greek letters, so we use `μ` ('mu') to represent the mean and `σ` ('sigma') to represent the standard deviation.
229+
Thus, if you read that "95% of values are within 2σ of μ" or "the Higgs boson has been detected with 5-sigma confidence", such comments relate to the standard deviation.
230+
231+
```python
232+
>>> mu = 4.731
233+
>>> sigma = 0.316
234+
>>> [round(random.gauss(mu, sigma), 3) for _ in range(5)]
235+
[4.72, 4.957, 4.64, 4.556, 4.968]
236+
```
237+
238+
[gaussian-distribution]: https://simple.wikipedia.org/wiki/Normal_distribution
239+
[probability-distribution]: https://simple.wikipedia.org/wiki/Probability_distribution
240+
[random]: https://docs.python.org/3/library/random.html
241+
[sampling-with-replacement]: https://www.youtube.com/watch?v=LnGFL_A6A6A
242+
[sequence-types]: https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range
243+
[standard-deviation]: https://simple.wikipedia.org/wiki/Standard_deviation
244+
[truly-random]: https://www.malwarebytes.com/blog/news/2013/09/in-computers-are-random-numbers-really-random
245+
[uniform-distribution]: https://www.investopedia.com/terms/u/uniform-distribution.asp#:~:text=In%20statistics%2C%20uniform%20distribution%20refers,a%20spade%20is%20equally%20likely.

concepts/random/introduction.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Introduction
2+
3+
Many programs need (apparently) random values to simulate real-world events.
4+
5+
Common, familiar examples include:
6+
- A coin toss: a random value from `('H', 'T')`.
7+
- The roll of a die: a random integer from 1 to 6.
8+
- Shuffling a deck of cards: a random ordering of a card list.
9+
- The creation of trees and bushes in a 3-D graphics simulation.
10+
11+
Generating _truly_ random values with a computer is a [surprisingly difficult technical challenge][truly-random], so you may see these results referred to as "pseudorandom".
12+
13+
In practice, a well-designed library like the [`random`][random] module in the Python standard library is fast, flexible, and gives results that are amply good enough for most applications in modelling, simulation and games.
14+
15+
For this brief introduction, we show the four most commonly used functions from the module.
16+
We encourage you to explore the full [`random`][random] documentation, as there are many tools and options.
17+
18+
19+
~~~~exercism/caution
20+
21+
The `random` module should __NOT__ be used for security and cryptographic applications!!
22+
23+
Instead, Python provides the [`secrets`][secrets] module.
24+
This is specially optimized for cryptographic security.
25+
Some of the prior issues and reasons for creating the secrets module can be found in [PEP 506][PEP 506].
26+
27+
[secrets]: https://docs.python.org/3.11/library/secrets.html#module-secrets
28+
[PEP 506]: https://peps.python.org/pep-0506/
29+
~~~~
30+
31+
32+
Before you can utilize the tools in the `random` module, you must first import it:
33+
34+
```python
35+
>>> import random
36+
37+
# Choose random integer from a range
38+
>>> random.randrange(1000)
39+
360
40+
41+
>>> random.randrange(-1, 500)
42+
228
43+
44+
>>> random.randrange(-10, 11, 2)
45+
-8
46+
47+
# Choose random integer between two values (inclusive)
48+
>>> random.randint(5, 25)
49+
22
50+
51+
```
52+
53+
To avoid typing the name of the module, you can import specific functions by name:
54+
55+
```python
56+
>>> from random import choice, choices
57+
58+
# Using choice() to pick Heads or Tails 10 times
59+
>>> tosses = []
60+
>>> for side in range(10):
61+
>>> tosses.append(choice(['H', 'T']))
62+
63+
>>> print(tosses)
64+
['H', 'H', 'H', 'H', 'H', 'H', 'H', 'T', 'T', 'H']
65+
66+
67+
# Using choices() to pick Heads or Tails 8 times
68+
>>> picks = []
69+
>>> picks.extend(choices(['H', 'T'], k=8))
70+
>>> print(picks)
71+
['T', 'H', 'H', 'T', 'H', 'H', 'T', 'T']
72+
```
73+
74+
75+
76+
## `randrange()` and `randint()`
77+
78+
Shown in the first example above, the `randrange()` function has three forms:
79+
80+
1. `randrange(stop)` gives an integer `n` such that `0 <= n < stop`
81+
2. `randrange(start, stop)` gives an integer `n` such that `start <= n < stop`
82+
3. `randrange(start, stop, step)` gives an integer `n` such that `start <= n < stop`
83+
and `n` is in the sequence `start, start + step, start + 2*step...`
84+
85+
For the most common case where `step == 1`, `randint(a, b)` may be more convenient and readable.
86+
Possible results from `randint()` _include_ the upper bound, so `randint(a, b)` is the same as using `randrange(a, b+1)`.
87+
88+
89+
90+
## `choice()` and `choices()`
91+
92+
These two functions assume that you are starting from some [sequence][sequence-types], or other container.
93+
This will typically be a `list`, or with some limitations a `tuple` or a `set` (_a `tuple` is immutable, and `set` is unordered_).
94+
95+
The `choice()` function will return one entry chosen at random from a given sequence, and `choices()` will return `k` number of entries chosen at random from a given sequence.
96+
In the examples shown above, we assumed a fair coin with equal probability of heads or tails, but weights can also be specified.
97+
98+
For example, if a bag contains 10 red balls and 15 green balls, and we would like to pull one out at random:
99+
100+
101+
```python
102+
>>> random.choices(['red', 'green'], [10, 15])
103+
['red']
104+
```
105+
106+
[random]: https://docs.python.org/3/library/random.html
107+
[sequence-types]: https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range
108+
[truly-random]: https://www.malwarebytes.com/blog/news/2013/09/in-computers-are-random-numbers-really-random

concepts/random/links.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[
2+
{
3+
"url": "https://docs.python.org/3/library/random.html/",
4+
"description": "Official documentation for the random module."
5+
},
6+
{
7+
"url": "https://engineering.mit.edu/engage/ask-an-engineer/can-a-computer-generate-a-truly-random-number/",
8+
"description": "MIT Engineering: Can a computer generate a truly random number?"
9+
},
10+
{
11+
"url": "https://www.malwarebytes.com/blog/news/2013/09/in-computers-are-random-numbers-really-random",
12+
"description": "Are Random Numbers Really Random?"
13+
}
14+
]

config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2573,6 +2573,11 @@
25732573
"slug": "with-statement",
25742574
"name": "With Statement"
25752575
},
2576+
{
2577+
"uuid": "af6cad74-50c2-48f4-a6ce-cfeb72548d00",
2578+
"slug": "random",
2579+
"name": "Random"
2580+
},
25762581
{
25772582
"uuid": "000e7768-38b9-4904-9ae2-9a4e448f366c",
25782583
"slug": "fractions",

0 commit comments

Comments
 (0)