426 lines
11 KiB
Plaintext
426 lines
11 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"nbgrader": {
|
|
"grade": false,
|
|
"grade_id": "cell-25e346adccbfbbd1",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
},
|
|
"tags": []
|
|
},
|
|
"source": [
|
|
"# The Monty Hall problem (Deutsch: Ziegenproblem)\n",
|
|
"\n",
|
|
"Read about it [on Wikipedia](https://en.wikipedia.org/wiki/Monty_Hall_problem) or [in German as the Ziegenproblem](https://de.wikipedia.org/wiki/Ziegenproblem) and come back. I'll wait.\n",
|
|
"\n",
|
|
"In this notebook, you will write a program to simulated the Monty Hall problem.\n",
|
|
"\n",
|
|
"We are going to make extensive use of the function `random.randint(a, b)`. From its docstring, it returns a `random integer in range [a, b], including both end points.`"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {
|
|
"nbgrader": {
|
|
"grade": false,
|
|
"grade_id": "cell-b19b617da52a3bc6",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
},
|
|
"tags": []
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import random"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {
|
|
"nbgrader": {
|
|
"grade": false,
|
|
"grade_id": "cell-8d3e7b29ddec3069",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
},
|
|
"tags": []
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"1\n",
|
|
"2\n",
|
|
"0\n",
|
|
"0\n",
|
|
"2\n",
|
|
"0\n",
|
|
"0\n",
|
|
"0\n",
|
|
"0\n",
|
|
"1\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"for i in range(10):\n",
|
|
" print(random.randint(0,2))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"nbgrader": {
|
|
"grade": false,
|
|
"grade_id": "cell-474fcacf28983b26",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
},
|
|
"tags": []
|
|
},
|
|
"source": [
|
|
"### Q1\n",
|
|
"\n",
|
|
"For your first task, create a function called `sample_not` which takes two positional arguments (call them `not1` and `not2`) and will return a random integer between 0 and 2 (endpoints included) but which is not either of the arguments. The positional arguments will always be integers between 0 and 2 (inclusive)."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {
|
|
"nbgrader": {
|
|
"grade": false,
|
|
"grade_id": "cell-f0ca4e3187e53217",
|
|
"locked": false,
|
|
"schema_version": 3,
|
|
"solution": true,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Write your function here\n",
|
|
"def sample_not(not1, not2):\n",
|
|
" while True:\n",
|
|
" this_guess = random.randint(0,2)\n",
|
|
" if this_guess != not1:\n",
|
|
" if this_guess != not2:\n",
|
|
" return this_guess"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {
|
|
"nbgrader": {
|
|
"grade": true,
|
|
"grade_id": "cell-50feeabd1f4f7d07",
|
|
"locked": true,
|
|
"points": 1,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# This is a test of the above, do not change this code.\n",
|
|
"assert sample_not(0,1)==2\n",
|
|
"assert sample_not(0,2)==1\n",
|
|
"assert sample_not(1,0)==2\n",
|
|
"assert sample_not(1,2)==0\n",
|
|
"assert sample_not(2,0)==1\n",
|
|
"assert sample_not(2,1)==0\n",
|
|
"assert sample_not(0,1)==2\n",
|
|
"assert sample_not(0,0) in (1,2)\n",
|
|
"assert sample_not(1,1) in (0,2)\n",
|
|
"assert sample_not(2,2) in (0,1)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"nbgrader": {
|
|
"grade": false,
|
|
"grade_id": "cell-8fdbeafabef55703",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
},
|
|
"tags": []
|
|
},
|
|
"source": [
|
|
"### Q2\n",
|
|
"\n",
|
|
"For your next task, consider the following code:\n",
|
|
"\n",
|
|
"```python\n",
|
|
"\n",
|
|
"# generate what is behind the doors\n",
|
|
"doors = ['goat', 'goat', 'goat']\n",
|
|
"car_door = random.randint(0,2)\n",
|
|
"doors[car_door] = 'car'\n",
|
|
"\n",
|
|
"# Now, the guest makes a first guess.\n",
|
|
"guess1 = random.randint(0,2)\n",
|
|
"\n",
|
|
"# Now, the host opens a door, which is not the guess or the car.\n",
|
|
"host_open_door = sample_not(guess1,car_door)\n",
|
|
"\n",
|
|
"# Based on the variable `do_switch` (which is not set here), the guess will either make a new choice or stay with the original guess.\n",
|
|
"if do_switch:\n",
|
|
" guess2 = sample_not(guess1,host_open_door)\n",
|
|
" final_guess = guess2\n",
|
|
"else:\n",
|
|
" final_guess = guess1\n",
|
|
"\n",
|
|
"# Finally, determine what was behind the door for the final guess.\n",
|
|
"result = doors[final_guess]\n",
|
|
"```\n",
|
|
"\n",
|
|
"Put this code in a function called `run_game` which takes a single argument, `do_switch`, and returns a boolean, indicating a win with `True` or a loss with `False`."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {
|
|
"nbgrader": {
|
|
"grade": false,
|
|
"grade_id": "cell-c087e3c1a6e2d2dd",
|
|
"locked": false,
|
|
"schema_version": 3,
|
|
"solution": true,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Write your function here\n",
|
|
"def run_game(do_switch=True):\n",
|
|
" # generate what is behind the doors\n",
|
|
" doors = ['goat', 'goat', 'goat']\n",
|
|
" car_door = random.randint(0,2)\n",
|
|
" doors[car_door] = 'car'\n",
|
|
"\n",
|
|
" # Now, the guest makes a first guess.\n",
|
|
" guess1 = random.randint(0,2)\n",
|
|
"\n",
|
|
" # Now, the host opens a door, which is not the guess or the car.\n",
|
|
" host_open_door = sample_not(guess1,car_door)\n",
|
|
"\n",
|
|
" # Based on the variable `do_switch` (which is not set here), the guess will either make a new choice or stay with the original guess.\n",
|
|
" if do_switch:\n",
|
|
" guess2 = sample_not(guess1,host_open_door)\n",
|
|
" final_guess = guess2\n",
|
|
" else:\n",
|
|
" final_guess = guess1\n",
|
|
"\n",
|
|
" # Finally, determine what was behind the door for the final guess.\n",
|
|
" result = doors[final_guess]\n",
|
|
" win = result=='car'\n",
|
|
" return win"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {
|
|
"nbgrader": {
|
|
"grade": true,
|
|
"grade_id": "cell-a3750cd0c13cf6c0",
|
|
"locked": true,
|
|
"points": 1,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"do_switch: True, wins: 207, count: 300\n",
|
|
"do_switch: False, wins: 100, count: 300\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# This is a test of the above, do not change this code.\n",
|
|
"count = 300\n",
|
|
"for do_switch in (True, False):\n",
|
|
" wins = 0\n",
|
|
" for i in range(count):\n",
|
|
" this_run_win = run_game(do_switch)\n",
|
|
" assert(type(this_run_win)==bool)\n",
|
|
" wins += int(this_run_win)\n",
|
|
" print('do_switch: %s, wins: %d, count: %d'%(do_switch, wins, count))\n",
|
|
" if do_switch:\n",
|
|
" assert abs(wins/count - 2/3) < 0.1\n",
|
|
" else:\n",
|
|
" assert abs(wins/count - 1/3) < 0.1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"nbgrader": {
|
|
"grade": false,
|
|
"grade_id": "cell-5626ba67e0f6f701",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
},
|
|
"tags": []
|
|
},
|
|
"source": [
|
|
"Note the above results. You have numerically simulated the Monty Hall problem."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"nbgrader": {
|
|
"grade": false,
|
|
"grade_id": "cell-054774247e7bc87a",
|
|
"locked": true,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
},
|
|
"tags": []
|
|
},
|
|
"source": [
|
|
"## Q3\n",
|
|
"\n",
|
|
"Make a new game where there are 100 doors and the host opens 98 of them after the initial guess. Make a new function called `run_game_100`, and any other functions you need, which plays a single round of this game. Again, this function should take an argument `do_switch`."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {
|
|
"nbgrader": {
|
|
"grade": false,
|
|
"grade_id": "cell-718f81e609214623",
|
|
"locked": false,
|
|
"schema_version": 3,
|
|
"solution": true,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Write your code here\n",
|
|
"def sample_not_list(n,not_list):\n",
|
|
" while True:\n",
|
|
" this_guess = random.randint(0,n-1)\n",
|
|
" if this_guess not in not_list:\n",
|
|
" return this_guess\n",
|
|
" \n",
|
|
"def run_game_100(do_switch=True):\n",
|
|
" n_doors = 100\n",
|
|
" n_open = 98\n",
|
|
" doors = ['goat']*n_doors\n",
|
|
" car_door = sample_not_list(n_doors,[])\n",
|
|
" doors[car_door] = 'car'\n",
|
|
"\n",
|
|
" guess1 = sample_not_list(n_doors,[])\n",
|
|
" host_list = []\n",
|
|
" for i in range(n_open):\n",
|
|
" host_open_door = sample_not_list(n_doors,host_list+[guess1]+[car_door])\n",
|
|
" host_list.append(host_open_door)\n",
|
|
"\n",
|
|
" if do_switch:\n",
|
|
" guess2 = sample_not_list(n_doors,host_list+[guess1])\n",
|
|
" final_guess = guess2\n",
|
|
" else:\n",
|
|
" final_guess = guess1\n",
|
|
"\n",
|
|
" result = doors[final_guess]\n",
|
|
" win = result=='car'\n",
|
|
" return win"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {
|
|
"nbgrader": {
|
|
"grade": true,
|
|
"grade_id": "cell-0b76bb5440f73c22",
|
|
"locked": true,
|
|
"points": 1,
|
|
"schema_version": 3,
|
|
"solution": false,
|
|
"task": false
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"do_switch: True, wins: 992, count: 1000\n",
|
|
"do_switch: False, wins: 7, count: 1000\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# This is a test of the above, do not change this code.\n",
|
|
"count = 1000\n",
|
|
"for do_switch in (True, False):\n",
|
|
" wins = 0\n",
|
|
" for i in range(count):\n",
|
|
" this_run_win = run_game_100(do_switch)\n",
|
|
" assert(type(this_run_win)==bool)\n",
|
|
" wins += int(this_run_win)\n",
|
|
" print('do_switch: %s, wins: %d, count: %d'%(do_switch, wins, count))\n",
|
|
" if do_switch:\n",
|
|
" assert abs(wins/count - 0.99) < 0.02\n",
|
|
" else:\n",
|
|
" assert abs(wins/count - 0.01) < 0.02"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"celltoolbar": "Create Assignment",
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.11.10"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
}
|