{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import random \n",
"\n",
"def random_door():\n",
" \"\"\"\n",
" Randomly choose Door #1, #2, or #3.\n",
" @return 1, 2, or 3 with equal probability.\n",
" \"\"\"\n",
" return random.randint(1, 3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def monty_hides_car_behind_door():\n",
" \"\"\"\n",
" Monty hides the car behind Door #1, #2, or #3.\n",
" @return the number of the door hiding the car.\n",
" \"\"\"\n",
" return random_door()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def you_choose_first_door():\n",
" \"\"\"\n",
" You choose your first Door #1, #2, or #3.\n",
" @return the door number of your first choice.\n",
" \"\"\"\n",
" return random_door()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def monty_opens_door(car_behind_door, first_choice_door):\n",
" \"\"\"\n",
" Monty opens a door that isn't your first choice and that\n",
" doesn't hide the car.\n",
" @param car_behind_door the number of the door hiding the car.\n",
" @param first_choice_door the number of your first choice door\n",
" @return the number of the door that Monty opens.\n",
" \"\"\"\n",
" # Monty randomly opens a door that isn't your first choice\n",
" # and isn't the one hiding the car.\n",
" door = random_door()\n",
" while (door == car_behind_door) or (door == first_choice_door):\n",
" door = random_door()\n",
" \n",
" return door # the door that Monty opens"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def you_choose_second_door(first_choice_door, opened_door):\n",
" \"\"\"\n",
" You choose a second door. It can't be your first choice door\n",
" or the door that Monty has opened.\n",
" @param first_choice_door the number of your first choice door\n",
" @param opened_door the number of the door that Monty opened\n",
" @return the door number of your second choice.\n",
" \"\"\"\n",
" # Check Door #1 and Door #2\n",
" for door in (1, 2):\n",
" if (door != first_choice_door) and (door != opened_door):\n",
" return door\n",
" \n",
" return 3 # not Door #1 or #2, so it must be Door #3"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def simulate(index):\n",
" \"\"\"\n",
" Perform a single simulation. Monty hides the car behind a door \n",
" and you make your first choice door. Monty opens a door, and\n",
" you make your second choice door. Determine if you win the car\n",
" if you stay with your first choice or switch to your second choice.\n",
" Print the results of this simulation.\n",
" @param index the simulation index.\n",
" @return a tuple indicating winning with the first or second choice.\n",
" \"\"\"\n",
" first_choice_wins = 0\n",
" second_choice_wins = 0\n",
" \n",
" # Perform a simulation.\n",
" car_behind_door = monty_hides_car_behind_door();\n",
" first_choice_door = you_choose_first_door()\n",
" opened_door = monty_opens_door(car_behind_door, first_choice_door)\n",
" second_choice_door = you_choose_second_door(first_choice_door, opened_door)\n",
" \n",
" # Print the results of this simulation. \n",
" print(f'{index:10,d}{car_behind_door:8d}{first_choice_door:8d}' +\n",
" f'{opened_door:8d}{second_choice_door:8d}', end='')\n",
"\n",
" # Would you win the car by staying or by switching?\n",
" if (first_choice_door == car_behind_door):\n",
" first_choice_wins = 1\n",
" print(' yes')\n",
" else:\n",
" second_choice_wins = 1\n",
" print(' yes')\n",
" \n",
" return (first_choice_wins, second_choice_wins)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def run_simulations(simulation_count):\n",
" \"\"\"\n",
" Run the simulations.\n",
" @param simulation_count the count of simulations to run.\n",
" @return the number of wins if stay and the number of wins if switch\n",
" \"\"\"\n",
" random.seed();\n",
" \n",
" stay_win_count = 0\n",
" switch_win_count = 0\n",
" \n",
" print(' Car Your Monty Your Win Win')\n",
" print('Simulation hidden first opened second if if')\n",
" print(' index here! choice door choice stay? switch?')\n",
" print()\n",
" \n",
" for index in range(simulation_count):\n",
" first_choice_wins, second_choice_wins = simulate(index+1)\n",
" \n",
" # Update the number of wins by staying or by switching.\n",
" stay_win_count += first_choice_wins\n",
" switch_win_count += second_choice_wins\n",
" \n",
" return (stay_win_count, switch_win_count)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"SIMULATION_COUNT = 100;\n",
"\n",
"# Run the simulations.\n",
"stay_win_count, switch_win_count = run_simulations(SIMULATION_COUNT)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Print the final stats.\n",
"print()\n",
"print(f'{stay_win_count:10,d} wins if you stayed with your first choice')\n",
"print(f'{switch_win_count:10,d} wins if you switched to your second choice')\n",
"print()\n",
"print('Win ratio of switching over staying: ' +\n",
" f'{switch_win_count/stay_win_count:3.1f}')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"import seaborn as sns\n",
"\n",
"def graph_win_percentages(stay_win_count, simulation_count):\n",
" \"\"\"\n",
" Generate a bar chart of the percentage of wins by staying\n",
" and the percentage of wins by switching.\n",
" @param stay_win_count the number of wins if stay.\n",
" @param simulation_count the count of simulations to run.\n",
" \"\"\"\n",
" stay_pct = 100*stay_win_count/simulation_count\n",
" switch_pct = 100 - stay_pct\n",
" percentages = (stay_pct, switch_pct)\n",
" \n",
" # Generate a bar chart of the win percentages.\n",
" sns.set_style('whitegrid') # white background with gray grid lines\n",
" axes = sns.barplot(['Stay', 'Switch'], (stay_pct, switch_pct),\n",
" palette='bright')\n",
" axes.set_title('Stay vs. Switch Win Percentages after ' +\n",
" f'{simulation_count} Simulations')\n",
" axes.set(ylabel='Percentage') # label the axes\n",
" axes.set_ylim(top=105)\n",
" \n",
" # Label the top of each patch (bar) with its percentage.\n",
" for bar, pct in zip(axes.patches, percentages):\n",
" text_x = bar.get_x() + bar.get_width()/2 \n",
" text_y = bar.get_height() \n",
" axes.text(text_x, text_y, f'{pct:4.1f}%', \n",
" fontsize=11, ha='center', va='bottom')\n",
" \n",
" plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Graph the win percentages.\n",
"graph_win_percentages(stay_win_count, SIMULATION_COUNT)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.7.7"
}
},
"nbformat": 4,
"nbformat_minor": 4
}