{ "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 }