{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# de Méré's paradox\n", "\n", "https://carnotcycle.files.wordpress.com/2017/11/mere01.jpg?w=614&h=458\n", "\n", "Chevalier de Méré (Antoine Gombaud 1607-1684) was a big spender in gambling circles. He found that it is worth to bet on the event of getting at least one 6 in four rolls of a die. He thought (misleaded by wrong calculation) that rolling two dice 24 times with a bet on having at least one double 6 has the same winning chance. But he found by experimenting that it is not true. \n", "\n", "He wrote in 1654 to Blaise Pascal (1623-1662), who in turn shared the news of “De Méré’s paradox” with Pierre Fermat (1607-1665). They solved the “paradox” and with this the theory of probability was born." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Simulation with 4 dice (relative frequency)\n", "Calculate the **relative frequency** of at least one 6 in four rolls of a die!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from random import randint" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "seq = [randint(1,6) for i in range(4)]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "seq" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Run the next code several times! Does it seem true that the relative frequency is more times greater than 0.5 than less, i.e. that it is worth betting that there will be at least one 6 among the 4 dice rolls?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "n = 100\n", "count = 0\n", "for _ in range(n):\n", " seq = [randint(1,6) for _ in range(4)]\n", " if 6 in seq:\n", " count += 1\n", "print(count/n)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Probability with 4 dice\n", "Calculate the **exact probability** of at least one 6 in four rolls of a die!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "lst = [[i1, i2, i3, i4] for i1 in range(1,7) for i2 in range(1,7) \\\n", " for i3 in range(1,7) for i4 in range(1,7)]\n", "count = 0\n", "for i in lst:\n", " if 6 in i:\n", " count += 1\n", "print(count, 6**4, count/6**4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The next is almost the same code but there is a big difference in running. Instead of **list comprehension** use **generator expression**, as it does not construct a big list. It generates the elements when needed, that is in the `for` loop." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gen = ([i1, i2, i3, i4] for i1 in range(1,7) for i2 in range(1,7) \\\n", " for i3 in range(1,7) for i4 in range(1,7))\n", "count = 0\n", "for i in gen:\n", " if 6 in i:\n", " count += 1\n", "print(count, 6**4, count/6**4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Compair `lst` and `gen`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "lst # this is a long list of 1296 elements" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gen" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Example:** Write a complete program putting the codes above into functions (simulation and calculating probability) and call them in the main funcion! **Save this code into a file and run it from terminal!**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from random import randint\n", "\n", "def simulate(n):\n", " count = 0\n", " for _ in range(n):\n", " seq = [randint(1,6) for i in range(4)]\n", " if 6 in seq:\n", " count += 1\n", " return count/n\n", "\n", "def probability():\n", " gen = ([i1, i2, i3, i4] for i1 in range(1,7) for i2 in range(1,7) \\\n", " for i3 in range(1,7) for i4 in range(1,7))\n", " count = 0\n", " for i in gen:\n", " if 6 in i:\n", " count += 1\n", " return count/6**4\n", "\n", "def main():\n", " print(f\" winning\")\n", " print(f\"100 experiments {simulate(100):.5f}\")\n", " print(f\"10000 experiments {simulate(10000):.5f}\")\n", " print(f\"probability {probability():.5f}\")\n", " \n", "if __name__ == \"__main__\":\n", " main()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using a little mathematics, we could calculate the probability without listing all possibilities:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "1-(5/6)**4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A programming tip: listing the results of several embedded loops we may use the `product` function of `itertools` module." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "from itertools import product\n", "dice = range(1, 7)\n", "four = product(dice, dice, dice, dice)\n", "for _ in four:\n", " print(_)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Simulation and probability with 24 times 2 dice" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "n = 1000\n", "count = 0\n", "for _ in range(n):\n", " for __ in range(24):\n", " seq = [randint(1,6), randint(1,6)]\n", " if [6,6] == seq:\n", " count += 1\n", " break\n", "print(count/n)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "6**4, 36**24" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Checking all possibilities and counting the number of double 6 is impossible, so we need to use math!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "1-(35/36)**24" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** For practice, write a complete program (similar to the one above) for the case of two dice rolled 24 times!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(\"The value of __name__ is:\", repr(__name__))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Fill in and rewrite the next code:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def simulation():\n", " \"\"\"\n", " Describe the function here!\n", " \"\"\"\n", " print(\"This is the simulation function!\")\n", " \n", "def probability():\n", " \"\"\"\n", " Describe the function here!\n", " \"\"\"\n", " print(\"This is the probability function!\")\n", " \n", "def main():\n", " print(\"Call here the functions!\")\n", " simulation()\n", " probability()\n", " \n", "if __name__ == \"__main__\":\n", " # execute only if run as a script\n", " main()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "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.12.3" } }, "nbformat": 4, "nbformat_minor": 4 }