Files
freeCodeCamp's Camper Bot 9c20069eb2 chore(i18n,learn): processed translations (#53819)
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
2024-03-12 22:29:52 +05:30

260 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: 5e44414f903586ffb414c950
title: 概率计算器
challengeType: 23
forumTopicId: 462364
dashedName: probability-calculator
---
# --description--
假设有一顶帽子,里面有 5 个蓝球、4 个红球和 2 个绿球。 随机抽取的 4 个球中至少包含 1 个红球和 2 个绿球的概率是多少? 虽然可以使用高等数学来计算概率,但更简单的方法是编写一个程序来执行大量实验来估计近似概率。
对于这个项目,你将编写一个程序来确定从帽子中随机抽取某些球的大致概率。
First, create a `Hat` class in `main.py`. 该类应该采用可变数量的参数来指定帽子中每种颜色的球数。 例如,可以通过以下任何一种方式创建类对象:
```py
hat1 = Hat(yellow=3, blue=2, green=6)
hat2 = Hat(red=5, orange=4)
hat3 = Hat(red=5, orange=4, black=1, blue=0, pink=2, striped=9)
```
一顶帽子总是至少有一个球。 创建时传递给 hat 对象的参数应转换为 `contents` 实例变量。 `contents` 应该是一个字符串列表,其中包含帽子中每个球的一个项目。 列表中的每一项都应该是一个颜色名称,代表该颜色的单个球。 例如,如果你的帽子是 `{"red": 2, "blue": 1}``contents` 应该是 `["red", "red", "blue"]`
`Hat` 类应该有一个 `draw` 方法,该方法接受一个参数,该参数指示要从帽子中抽取的球数。 此方法应该从 `contents` 中随机删除球,并将这些球作为字符串列表返回。 在抽取过程中球不应回到帽子中,类似于没有放回的黑盒实验。 如果要抽的球数量超过可用数量,则返回所有球。
Next, create an `experiment` function in `main.py` (not inside the `Hat` class). 此函数应接受以下参数:
- `hat`:一个包含球的帽子对象,应该在函数内复制。
- `expected_balls`:一个对象,指示尝试从帽子中抽取的确切球组以进行实验。 例如,要确定从帽子中抽取 2 个蓝球和 1 个红球的概率,将 `expected_balls` 设置为 `{"blue":2, "red":1}`
- `num_balls_drawn`:每次实验中从帽子中抽出的球数。
- `num_experiments`:要执行的实验数量。 (进行的实验越多,近似概率就越准确。)
`experiment` 函数应该返回一个概率。
例如,如果你想确定当你从一个包含 6 个黑球、4 个红球和 3 个绿球的帽子中抽出 5 个球时,至少得到 2 个红球和 1 个绿球的概率, 你将进行 `N` 次实验,记录其中你至少得到 2 个红球和 1 个绿球的次数 `M`,并估计概率为 `M/N`。 每个实验都包括从一个装有指定球的帽子开始,抽出几个球,并检查你是否抽到了你试图抽出的球。
以下是基于上面的示例调用 `experiment` 函数的方法,其中包含 2000 个实验:
```py
hat = Hat(black=6, red=4, green=3)
probability = experiment(hat=hat,
expected_balls={"red":2,"green":1},
num_balls_drawn=5,
num_experiments=2000)
```
The output would be something like this:
```bash
>>> 0.356
```
由于这是基于随机抽取的,因此每次运行代码时概率会略有不同。
_Hint: Consider using the modules that are already imported at the top. Do not initialize random seed within the file._
# --hints--
Creation of `hat` object should add correct contents.
```js
({
test: () => {
pyodide.FS.writeFile("/home/pyodide/probability_calculator.py", code);
pyodide.FS.writeFile(
"/home/pyodide/test_module.py",
`
import unittest
import probability_calculator
from importlib import reload
reload(probability_calculator)
probability_calculator.random.seed(95)
class UnitTests(unittest.TestCase):
maxDiff = None
def test_hat_class_contents(self):
hat = probability_calculator.Hat(red=3,blue=2)
actual = hat.contents
expected = ["red","red","red","blue","blue"]
self.assertEqual(actual, expected, 'Expected creation of hat object to add correct contents.')
`
);
const testCode = `
from unittest import main
import test_module
from importlib import reload
reload(test_module)
t = main(module='test_module', exit=False)
t.result.wasSuccessful()
`;
const out = __pyodide.runPython(testCode);
assert(out);
},
});
```
The `draw` method in `hat` class should reduce number of items in contents.
```js
({
test: () => {
pyodide.FS.writeFile("/home/pyodide/probability_calculator.py", code);
pyodide.FS.writeFile(
"/home/pyodide/test_module.py",
`
import unittest
import probability_calculator
from importlib import reload
reload(probability_calculator)
probability_calculator.random.seed(95)
def test_hat_draw(self):
hat = probability_calculator.Hat(red=5,blue=2)
actual = hat.draw(2)
expected = ['blue', 'red']
self.assertEqual(actual, expected, 'Expected hat draw to return two random items from hat contents.')
actual = len(hat.contents)
expected = 5
self.assertEqual(actual, expected, 'Expected hat draw to reduce number of items in contents.')
`
);
const testCode = `
from unittest import main
import test_module
from importlib import reload
reload(test_module)
t = main(module='test_module', exit=False)
t.result.wasSuccessful()
`;
const out = __pyodide.runPython(testCode);
assert(out);
},
});
```
The `experiment` method should return a different probability.
```js
({
test: () => {
pyodide.FS.writeFile("/home/pyodide/probability_calculator.py", code);
pyodide.FS.writeFile(
"/home/pyodide/test_module.py",
`
import unittest
import probability_calculator
from importlib import reload
reload(probability_calculator)
probability_calculator.random.seed(95)
class UnitTests(unittest.TestCase):
maxDiff = None
def test_prob_experiment(self):
hat = probability_calculator.Hat(blue=3,red=2,green=6)
probability = probability_calculator.experiment(hat=hat, expected_balls={"blue":2,"green":1}, num_balls_drawn=4, num_experiments=1000)
actual = probability
expected = 0.272
self.assertAlmostEqual(actual, expected, delta = 0.01, msg = 'Expected experiment method to return a different probability.')
hat = probability_calculator.Hat(yellow=5,red=1,green=3,blue=9,test=1)
probability = probability_calculator.experiment(hat=hat, expected_balls={"yellow":2,"blue":3,"test":1}, num_balls_drawn=20, num_experiments=100)
actual = probability
expected = 1.0
self.assertAlmostEqual(actual, expected, delta = 0.01, msg = 'Expected experiment method to return a different probability.')
`
);
const testCode = `
from unittest import main
import test_module
from importlib import reload
reload(test_module)
t = main(module='test_module', exit=False)
t.result.wasSuccessful()
`;
const out = __pyodide.runPython(testCode);
assert(out);
},
});
```
# --seed--
## --seed-contents--
```py
import copy
import random
class Hat:
pass
def experiment(hat, expected_balls, num_balls_drawn, num_experiments):
pass
```
# --solutions--
```py
import copy
import random
class Hat:
def __init__(self, **hat):
self.hat = hat
contents = []
for i in hat:
for j in range(hat[i]):
contents.append(i)
self.contents = contents
def draw(self, number):
drawn = []
if number >= len(self.contents):
return self.contents
else:
for i in range(number):
drawn.append(
self.contents.pop(random.randrange(len(self.contents)))
)
return drawn
def experiment(hat, expected_balls, num_balls_drawn, num_experiments):
expected_balls_list = []
drawn_list = []
success = 0
for i in expected_balls:
for j in range(expected_balls[i]):
expected_balls_list.append(i)
for j in range(num_experiments):
hat_copy = copy.deepcopy(hat)
drawn_list.append(hat_copy.draw(num_balls_drawn))
exp_ball_list_copy = expected_balls_list[:]
for k in range(len(drawn_list[j])):
try:
ind = exp_ball_list_copy.index(drawn_list[j][k])
exp_ball_list_copy.pop(ind)
except:
continue
if len(exp_ball_list_copy) == 0:
success += 1
probability = success/num_experiments
return probability
```