📄 C3_W2_Lab_2_Dice_Simulations.ipynb
/home/palash/git/misc/maths/Mathematics for Machine Learning and Data Science by DeepLearning.ai/Probablity/C3_W2_Lab_2_Dice_Simulations.ipynb
Language: ipynb • Lines: 568
{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "56c31ec0",
   "metadata": {},
   "source": [
    "# Lab: Simulate Dice Throws with NumPy 🎲🤖\n",
    "\n",
    "Welcome! This lab shows how you can use Numpy to simulate rolling dice from rolling a single die up to summing the results from multiple rolls. You will also see how to handle situations in which one of the sides of the dice is loaded (it has a greater probability of landing on that side comparing to the rest).\n",
    "\n",
    "Let's get started! "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "af4835c6",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0968af94",
   "metadata": {},
   "source": [
    "## Represent a dice\n",
    "\n",
    "The first thing you will need is to define how many sides your dice will have. You can even go a step further and represent a dice by using a NumPy array and assigning to each side a label which will be equal to the number of that side:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "70b01f08",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 2, 3, 4, 5, 6])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Define the desired number of sides (try changing this value!)\n",
    "n_sides = 6\n",
    "\n",
    "# Represent a dice by using a numpy array\n",
    "dice = np.array([i for i in range(1, n_sides+1)])\n",
    "\n",
    "dice"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6be050b4",
   "metadata": {},
   "source": [
    "## Roll the dice\n",
    "\n",
    "With your dice ready it is time to roll it. For now you will assume that the dice is fair, which means the probability of landing on each side is the same (it follows a uniform distribution). To achieve this behaviour you can use the function [np.random.choice](https://numpy.org/doc/stable/reference/random/generated/numpy.random.choice.html), which given a NumPy array returns one of the entries in it randomnly:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "154f10d6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Run this cell multiple times (every time you should get a different result at random)\n",
    "np.random.choice(dice)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "12750521",
   "metadata": {},
   "source": [
    "This is great but if you wanted to roll the dice 20 times you will need to run the cell 20 times and record each result. Now you need a way to simulate several rolls at the same time. For this you can define the number of rolls you desire and use a list comprehension to roll the dice as many times as you like, you can also save every roll in a NumPy array:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "a6f516d3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5, 2, 4, 6, 6, 1, 4, 4, 1, 6, 4, 1, 3, 2, 1, 2, 3, 2, 1, 2])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Roll the dice 20 times\n",
    "n_rolls = 20\n",
    "\n",
    "# Save the result of each roll\n",
    "rolls = np.array([np.random.choice(dice) for _ in range(n_rolls)])\n",
    "\n",
    "rolls"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "acc775fb",
   "metadata": {},
   "source": [
    "Now you have a convenient way of keeping track of the result of each roll, nice!\n",
    "\n",
    "What is you would like to know the mean and variance of this process. For this you can use NumPy's functions [np.mean](https://numpy.org/doc/stable/reference/generated/numpy.mean.html) and [np.var](https://numpy.org/doc/stable/reference/generated/numpy.var.html):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "bb5fbb69",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mean of rolls: 3.00\n",
      "variance of rolls: 3.00\n"
     ]
    }
   ],
   "source": [
    "# Compute mean of 20 rolls\n",
    "m = np.mean(rolls)\n",
    "\n",
    "# Compute variance of 20 rolls\n",
    "v = np.var(rolls)\n",
    "\n",
    "print(f\"mean of rolls: {m:.2f}\\nvariance of rolls: {v:.2f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0f8a9054",
   "metadata": {},
   "source": [
    "You can even check the distribution of the rolls by plotting a histogram of the NumPy array that holds the result of each throw. For this you will use the plotting library Seaborn, concretely the [sns.histplot](https://seaborn.pydata.org/generated/seaborn.histplot.html) function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "52fe0fd6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAioAAAGxCAYAAABMeZ2uAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy88F64QAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAmuElEQVR4nO3df1xUdb7H8fcoOKICKopB8kstEBU1KYOsUNKN1C3dvWt302hbt19kP8hbi2aIV6V0a2vL8GKFuXvNbg+13B9ZpmLuVUpgzR9LZJuGKf4OBxEnhHP/2AdzY0EFQs8XeT0fj3nsnjNnZj5z8pGvzjkz47AsyxIAAICB2tk9AAAAwLkQKgAAwFiECgAAMBahAgAAjEWoAAAAYxEqAADAWIQKAAAwFqECAACMRagAAABjESpAC1i6dKkcDofy8/MbvH/cuHEKDw+vsy48PFz33HNPk15ny5Ytmj17tsrKypo3aBv09ttva8CAAfLx8ZHD4dD27dsb3K6goEApKSkaNGiQfH191atXL91yyy3asGFDg9t/9dVXmjhxorp27aouXbpo9OjRKiwsvIjv5P/t27dPDodDS5cu9ayr/TO4b9++SzIDcKkQKoBNVq9erVmzZjXpMVu2bFFGRgah0khHjx7VlClT1LdvX61du1Zbt27V1Vdf3eC2b731lj799FPde++9eu+99/Taa6/J6XQqMTFRy5Ytq/e8N954o7744gu98cYb+p//+R+dOXNGCQkJKi4uvhRvDWgzvOweAGirhg4davcITVZVVSWHwyEvr9bxr44vvvhCVVVVmjx5sm6++ebzbvvkk0/qN7/5TZ11t912m6655hrNmTNHd999t2f9woULdfToUW3ZskVhYWGSpBEjRqhv37565pln9Pbbbzd51srKSvn4+DT5ccDljiMqgE3+9dRPTU2N5s6dq8jISPn4+Khr166KiYnRSy+9JEmaPXu2/uM//kOSFBERIYfDIYfDodzcXM/jFyxYoKioKDmdTgUGBuruu+/WN998U+d1LcvS/PnzFRYWpo4dOyo2Nlbr1q1TQkKCEhISPNvl5ubK4XDo97//vZ544gldeeWVcjqd+vLLL3X06FE99NBDio6OVpcuXRQYGKhRo0Zp8+bNdV6r9hTFwoUL9dxzzyk8PFw+Pj5KSEjwRMSvf/1rBQcHy9/fXxMmTNCRI0catf/WrFmjuLg4derUSb6+vho9erS2bt3quf+ee+7RiBEjJEmTJk2Sw+Go8/7+VWBgYL117du317Bhw7R///4661evXq1Ro0Z5IkWS/Pz8NHHiRP3xj3/U2bNnzzt7eHi4xo0bp1WrVmno0KHq2LGjMjIyJEm7du3S7bffrm7duqljx44aMmSI3nzzzQvuj4b87W9/07hx4xQYGCin06ng4GCNHTu23p8JwGSt4z+LgFaiurq6wb+kGvMj5QsWLNDs2bP19NNP66abblJVVZU+//xzz2meqVOn6sSJE3r55Ze1atUqBQUFSZKio6MlSQ8++KCys7P18MMPa9y4cdq3b59mzZql3NxcFRYWqkePHpKkmTNnKjMzU/fdd58mTpyo/fv3a+rUqaqqqmrwtEhaWpri4uK0ePFitWvXToGBgTp69KgkKT09XVdccYVOnTql1atXKyEhQevXr68XBIsWLVJMTIwWLVqksrIyPfHEExo/fryGDx8ub29vvfHGG/r66681ffp0TZ06VWvWrDnvvlq+fLnuuusujRkzRm+99ZbcbrcWLFjgef0RI0Zo1qxZuu6665SSkqL58+dr5MiR8vPzu+A/h+87e/asNm/erAEDBnjWVVZW6h//+IcmTJhQb/uYmBhVVlbqq6++OucpplqFhYUqKirS008/rYiICHXu3FnFxcWKj49XYGCgfve73ykgIEB/+MMfdM899+jw4cN68sknGz17RUWFRo8erYiICC1atEi9evXSoUOHtHHjRpWXlzd+JwB2swD8YDk5OZak897CwsLqPCYsLMxKTk72LI8bN84aMmTIeV9n4cKFliRr7969ddYXFRVZkqyHHnqozvpPPvnEkmTNmDHDsizLOnHihOV0Oq1JkybV2W7r1q2WJOvmm2/2rNu4caMlybrpppsu+P7Pnj1rVVVVWYmJidaECRM86/fu3WtJsgYPHmxVV1d71r/44ouWJOvHP/5xned57LHHLEnWyZMnz/la1dXVVnBwsDVo0KA6z1leXm4FBgZa8fHx9d7DO++8c8H30JCZM2dakqx3333Xs+7AgQOWJCszM7Pe9suXL7ckWVu2bDnv84aFhVnt27e3iouL66y/8847LafTaZWUlNRZn5SUZHXq1MkqKyuzLOv/92tOTo5nm9o/g7V/NvLz8+vNDrRGnPoBWtCyZcu0bdu2erfaUxDnc9111+mzzz7TQw89pA8++EAul6vRr7tx40ZJqvcpouuuu079+/fX+vXrJUl5eXlyu9362c9+Vme766+/vt6nkmr95Cc/aXD94sWLdc0116hjx47y8vKSt7e31q9fr6Kionrb3nbbbWrX7v//ddO/f39J0tixY+tsV7u+pKTkHO9UKi4u1sGDBzVlypQ6z9mlSxf95Cc/UV5enk6fPn3OxzfWa6+9pnnz5umJJ57Q7bffXu9+h8Nxzsee775aMTEx9Y66bNiwQYmJiQoJCamz/p577tHp06frnNq6kH79+qlbt2566qmntHjxYv39739v9GMBkxAqQAvq37+/YmNj6938/f0v+Ni0tDT95je/UV5enpKSkhQQEKDExMRzfuT5+44fPy5JntNB3xccHOy5v/Z/e/XqVW+7htad6zlfeOEFPfjggxo+fLhWrlypvLw8bdu2TbfeeqsqKyvrbd+9e/c6yx06dDjv+jNnzjQ4y/ffw7nea01Njb799ttzPr4xcnJydP/99+u+++7TwoUL69zXrVs3ORwOzxzfd+LECUn131dDGpr/+PHj53xftfc3lr+/vzZt2qQhQ4ZoxowZGjBggIKDg5Wenq6qqqpGPw9gN0IFMISXl5dSU1NVWFioEydO6K233tL+/fv1ox/96IJHCAICAiRJpaWl9e47ePCg5/qU2u0OHz5cb7tDhw41+NwNHR34wx/+oISEBGVlZWns2LEaPny4YmNjL8m1Dxd6r+3atVO3bt2a/fw5OTmaOnWqkpOTtXjx4nrv38fHR/369dPOnTvrPXbnzp3y8fFRnz59Lvg6De3XgICAc74vSZ5/jo01aNAgrVixQsePH9f27ds1adIkzZkzR88//3yTngewE6ECGKhr16766U9/qpSUFJ04ccLzJV5Op1OS6h21GDVqlKR/BsT3bdu2TUVFRUpMTJQkDR8+XE6ns97HZ/Py8vT11183ej6Hw+GZpdaOHTuadGqiuSIjI3XllVdq+fLldS5Srqio0MqVKz2fBGqOpUuXaurUqZo8ebJee+21c57CmTBhgjZs2FDn00Dl5eVatWqVfvzjHzf749uJiYnasGGDJ0xqLVu2TJ06ddL111/frOd1OBwaPHiwfvvb36pr166X7IvpgJbAp34AQ4wfP14DBw5UbGysevbsqa+//lovvviiwsLCdNVVV0n6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\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Display histogram of 20 rolls\n",
    "n_rolls_hist = sns.histplot(rolls, discrete=True)\n",
    "n_rolls_hist.set(title=f\"Histogram of {n_rolls} rolls\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2d210eb7",
   "metadata": {},
   "source": [
    "You probably didn't get a distribution that looks uniform (since the results are random). This happened because you are only simulating 20 rolls so far. Now try doing the same but for 20000 rolls:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "01b974f5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mean of rolls: 3.48\n",
      "variance of rolls: 2.90\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkQAAAGxCAYAAACDV6ltAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy88F64QAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA8HUlEQVR4nO3df1xW9f3/8eelwAUqXAp08SMRnalhqDV1CKtEUZSFlrp0uZhuplb+GFPXZ+qa1Kek2Se1j5aVM38rbSvNVlGaP5ZT/EFfljoyW7owQSzhAhyC4vn+0cezLgFFUq9Lz+N+u53bOO/zus71Oqc2njvnvA82wzAMAQAAWFgTTzcAAADgaQQiAABgeQQiAABgeQQiAABgeQQiAABgeQQiAABgeQQiAABgeQQiAABgeQQiAABgeQQi4BpbtmyZbDab9u7dW+f21NRUtW3b1m2sbdu2Gj169GV9z44dO5SRkaHS0tLGNWpBr732mm677TYFBATIZrMpLy+vzrrc3FxNmDBBXbp0UWBgoMLCwtSvXz9t3ry5zvrPP/9cQ4cOVcuWLdWiRQv1799fH330UZ21WVlZuv322+Xv76/IyEilp6eroqKiVl1FRYXS09MVGRkpf39/3X777crKyqpznx999JH69eunFi1aqGXLlho6dKg+//zzhp2U72jr1q2y2WzaunWrOZaRkSGbzXZNvh9oKAIRcB1Yt26dHn/88cv6zI4dO/TEE08QiBroxIkTSktLU/v27ZWdna2dO3eqY8eOddauXbtWu3fv1i9+8Qu9+eab+sMf/iC73a6kpCStWLGi1n7vuusuffrpp3r11Vf1xz/+UadPn1ZiYqIOHjzoVrt69Wo98MAD6tmzp959913NmjVLy5Yt09ChQ2v1MHToUC1fvlyzZs3Su+++q549e+qBBx7QmjVr3Oo++eQTJSYmqrq6Wn/84x/16quv6tNPP9Vdd92lEydOfMezBtxADADX1NKlSw1Jxp49e+rcfs899xjR0dHf+XueffZZQ5Jx+PDh77yvxqiurjbOnDnjke9ujO3btxuSjNdee+2StcePH681dvbsWaNr165G+/bt3cZ//etfG76+vsaRI0fMMZfLZYSGhhrDhw93+3xERISRnJzs9vnVq1cbkox33nnHHHv77bcNScaaNWvcavv3729ERkYaZ8+eNcfuv/9+IzQ01HC5XObYkSNHDF9fX+Oxxx675LFe6Ny5c8a///3vBtdv2bLFkGRs2bLFHJs1a5bBrx94G64QAdeBC2+ZnTt3Tk899ZQ6deqkgIAAtWzZUl27dtXzzz8v6ZtbEr/+9a8lSe3atZPNZnO7bXHu3DnNmTNHt956q+x2u5xOp372s5/p6NGjbt9rGIZmz56t6Oho+fv7q0ePHtq4caMSExOVmJho1p2/LbJy5UpNnTpVN998s+x2uz777DOdOHFCjz76qDp37qwWLVrI6XSqb9+++vDDD92+68iRI7LZbHr22Wf1+9//Xm3btlVAQIASExP16aef6syZM/rNb36jyMhIORwODRkyRMXFxQ06fxs2bFB8fLyaNWumwMBA9e/fXzt37jS3jx49WnfeeackacSIEbLZbG7HdyGn01lrrGnTpurevbsKCgrcxtetW6e+ffsqOjraHAsKCtLQoUP11ltv6ezZs5KknJwcFRYW6uc//7nb5++//361aNFC69atc9tnixYtdP/997vV/vznP9exY8e0a9cuSdLZs2f1l7/8RcOGDVNQUJBZFx0drT59+rjtsz42m00TJ07USy+9pJiYGNntdi1fvlyStH37diUlJSkwMFDNmjVTQkKC3n777Uvusy6bN29WYmKiQkJCFBAQoDZt2mjYsGH697//3aj9AZfLx9MNAFZVU1Nj/jL8NsMwLvnZOXPmKCMjQ7/97W91991368yZM/rkk0/M22MPPfSQTp48qQULFuiNN95QRESEJKlz586SpEceeUSvvPKKJk6cqNTUVB05ckSPP/64tm7dqo8++kihoaGSpJkzZyozM1Pjxo3T0KFDVVBQoIceekhnzpyp83bS9OnTFR8fr5deeklNmjSR0+k0b8vMmjVL4eHhqqio0Lp165SYmKgPPvigVvB44YUX1LVrV73wwgsqLS3V1KlTNWjQIMXFxcnX11evvvqq/vWvf2natGl66KGHtGHDhoueqzVr1uinP/2pkpOTtXbtWlVVVWnOnDnm99955516/PHH9YMf/EATJkzQ7Nmz1adPH7cA0RBnz57Vhx9+qNtuu80cq6ys1D//+U8NGTKkVn3Xrl1VWVmpzz//XB07dtT+/fvN8W/z9fXVrbfeam6XpP379ysmJkY+Pj619nl+e0JCgv75z3+qsrKy1j7P127cuFGnT5+Wv7//RY9t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rhCdO3dOvr6+tcZ9fX117ty579wUAADAtdSoQNS3b1/98pe/1LFjx8yxL7/8Ur/61a+UlJR0xZoDAAC4FhoViBYuXKjy8nK1bdtW7du31y233KJ27dqpvLxcCxYsuNI9AgAAXFWNeoYoKipKH330kTZu3KhPPvlEhmGoc+fO6tev35XuDwAA4Kq7rCtEmzdvVufOnVVWViZJ6t+/vyZNmqTJkyerZ8+euu222/Thhx9elUYBAACulssKRPPnz9fYsWMVFBRUa5vD4dD48eM1d+7cK9YcAADAtXBZgejvf/+7Bg4cWO/25ORk5ebmfuemAAAArqXLCkTHjx+vc7r9eT4+Pjpx4sR3bgoAAOBauqxAdPPNN2vfvn31bv/4448VERHxnZsCAAC4li4rEP3oRz/S7373O50+fbrWtsrKSs2aNUupqalXrDkAAIBr4bKm3f/2t7/VG2+8oY4dO2rixInq1KmTbDab8vPz9cILL6impkYzZ868Wr0CAABcFZcViMLCwrRjxw498sgjmj59ugzDkCTZbDYNGDBAL774osLCwq5KowAAAFfLZb+YMTo6Wu+8845KSkr02WefyTAMdejQQa1atboa/QEAAFx1jXpTtSS1atVKPXv2vJK9AAAAeESj/pYZAADAjYRABAAALM+jgeivf/2rBg0apMjISNlsNq1fv95t++jRo2Wz2dyWXr16udVUVVVp0qRJCg0NVfPmzTV48GAdPXrUraakpERpaWlyOBxyOBxKS0tTaWnpVT46AABwvfBoIDp16pS6deumhQsX1lszcOBAFRYWmss777zjtj09PV3r1q1TVlaWtm/froqKCqWmpqqmpsasGTlypPLy8pSdna3s7Gzl5eUpLS3tqh0XAAC4vjT6oeorISUlRSkpKRetsdvtCg8Pr3Oby+XSkiVLtHLlSvXr10+StGrVKkVFRWnTpk0aMGCA8vPzlZ2drZycHMXFxUmSFi9erPj4eB08eFCdOnW6sgcFAACuO17/DNHWrVvldDrVsWNHjR07VsXFxea23NxcnTlzRsnJyeZYZGSkYmNjtWPHDknSzp075XA4zDAkSb169ZLD4TBr6lJVVaWysjK3BQAA3Ji8OhClpKRo9erV2rx5s5577jnt2bNHffv2VVVVlSSpqKhIfn5+td6BFBYWpqKiIrPG6XTW2rfT6TRr6pKZmWk+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\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "n_rolls = 20_000\n",
    "\n",
    "rolls = np.array([np.random.choice(dice) for _ in range(n_rolls)])\n",
    "\n",
    "print(f\"mean of rolls: {np.mean(rolls):.2f}\\nvariance of rolls: {np.var(rolls):.2f}\")\n",
    "\n",
    "n_rolls_hist = sns.histplot(rolls, discrete=True)\n",
    "n_rolls_hist.set(title=f\"Histogram of {n_rolls} rolls\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "00c6a396",
   "metadata": {},
   "source": [
    "Does this plot and the metrics of mean and variance align with what you have learned about the uniform distribution during the course?\n",
    "\n",
    "Simulations are a great way of contrasting results against analytical solutions. For example, in this case the theoretical mean and variance are 3.5 and 2.916 respectively (you can check the formulas to get this results [here](https://en.wikipedia.org/wiki/Discrete_uniform_distribution)). The important thing to keep in mind is that the more simulations you perform the closer your results will be to the analytical values so always choose an appropriate number of simulations! \n",
    "\n",
    "NumPy is quite fast so performing 20 thousand runs is done fairly quick."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "654b7935",
   "metadata": {},
   "source": [
    "## Summing the result of rolling twice\n",
    "\n",
    "Now you want to throw the dice twice and record the sum of the two rolls. For this you can do as before and save all results of the first roll in a NumPy array but this time you will have a second array that saves the results for the second rolls. \n",
    "\n",
    "To get the sum you can simply sum the two arrays. This is possible because NumPy allows for vectorized operations such as this one. When you sum two NumPy arrays you will get a new array that includes the element-wise sum of the elements in the arrays you summed up.\n",
    "\n",
    "Notice that now you can compute the the mean and variance for the first rolls, the second rolls and the sum of rolls. You can also compute the covariance between the first and second rolls:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "5dcce70f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mean of first_rolls: 3.49\n",
      "variance of first_rolls: 2.93\n",
      "\n",
      "mean of second_rolls: 3.52\n",
      "variance of second_rolls: 2.92\n",
      "\n",
      "mean of sum_of_rolls: 7.00\n",
      "variance of sum_of_rolls: 5.86\n",
      "\n",
      "covariance between first and second roll:\n",
      "[[2.92745316e+00 2.79199960e-03]\n",
      " [2.79199960e-03 2.92434346e+00]]\n"
     ]
    },
    {
     "data": {
      "image/png": "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7e2N8ePHQ61W6+1fWVmJPn36IDIyEoMHD2507AsXLmDx4sXw9vZuj9KJiIioE5M0AK1btw7z5s1DYGAgXFxcEBcXBzs7O2zatElvf0dHR7z77ruYPXs2zMzMGhy3trYWzz33HFatWoV+/fq1V/lERETUSUkWgKqqqpCZmQlfX1+tdl9fX6Snp9/R2NHR0ejTpw/mzZvXrP6VlZUoLS3VWoiIiOjeJVkAKioqQm1tLaysrLTaraysUFhY2Opxv//+e2zZsgWbN29u9jqxsbEwMzPTLHZ2dq3ePhEREXV8hlIXoFAotF4LIXTamqusrAz+/v7YvHkzLCwsmr1eREQEwsPDNa9LS0sZgkg21Go1ioqKpC6jQTk5OVKX0GwdvVYLCwvY29tLXQZRhyBZALKwsICBgYHO0Z7Lly/rHBVqrt9//x25ubmYNGmSpq2urg4AYGhoiDNnzqB///466ymVSiiVylZtk6gzU6vVcHZ2QUVFudSlNKm6skrqEhpUUVIMQAF/f3+pS2mUiUlX/PprDkMQESQMQMbGxnB3d0daWhqmTp2qaU9LS8NTTz3VqjGdnZ1x+vRprbbly5ejrKwM7777Lo/qEN2mqKgIFRXlGDY3Cj1sHKUuR6+C0xn4aU8iampqpC6lQdXlZQAEhsxagj5OzlKXo1dpQS6OJa1CUVERAxARJD4FFh4ejoCAAHh4eMDT0xOJiYlQq9UICgoCcOvUVH5+PrZu3apZJzs7GwBw/fp1XLlyBdnZ2TA2NsbAgQOhUqng6uqqtY2ePXsCgE47Ef2fHjaO6G0/QOoy9CotyJW6hGbrbmnfYfcjEWmTNAD5+fmhuLgY0dHRKCgogKurK1JTU+Hg4ADg1oMPb38m0NChQzVfZ2ZmYseOHXBwcEBubu7dLJ2IiIg6Mckvgg4ODkZwcLDe95KTk3XahBAtGl/fGERERCRvkn8UBhEREdHdxgBEREREssMARERERLLDAERERESywwBEREREssMARERERLLDAERERESywwBEREREssMARERERLLDAERERESywwBEREREssMARERERLLDAERERESywwBEREREssMARERERLLDAERERESywwBEREREssMARERERLLDAERERESywwBEREREssMARERERLLDAERERESywwBEREREssMARERERLLDAERERESywwBEREREssMARERERLLDAERERESywwBEREREssMARERERLLDAERERESyI3kAio+Ph5OTE1QqFdzd3XHkyJEG+xYUFGDWrFkYMGAAunTpgtDQUJ0+mzdvhre3N3r16oVevXph7NixOH78eDvOgIiIiDobSQNQSkoKQkNDERkZiVOnTsHb2xvjx4+HWq3W27+yshJ9+vRBZGQkBg8erLfPN998g5kzZ+LQoUPIyMiAvb09fH19kZ+f355TISIiok5E0gC0bt06zJs3D4GBgXBxcUFcXBzs7OywadMmvf0dHR3x7rvvYvbs2TAzM9PbZ/v27QgODsaQIUPg7OyMzZs3o66uDgcOHGjPqRAREVEnIlkAqqqqQmZmJnx9fbXafX19kZ6e3mbbKS8vR3V1NXr37t1gn8rKSpSWlmotREREdO+SLAAVFRWhtrYWVlZWWu1WVlYoLCxss+0sXboUffv2xdixYxvsExsbCzMzM81iZ2fXZtsnIiKijkfyi6AVCoXWayGETltrrVmzBjt37sTu3buhUqka7BcREYGSkhLNkpeX1ybbJyIioo7JUKoNW1hYwMDAQOdoz+XLl3WOCrXG2rVrERMTg/3798PNza3RvkqlEkql8o63SURERJ2DZEeAjI2N4e7ujrS0NK32tLQ0eHl53dHYb7/9Nt544w3s3bsXHh4edzQWERER3XskOwIEAOHh4QgICICHhwc8PT2RmJgItVqNoKAgALdOTeXn52Pr1q2adbKzswEA169fx5UrV5CdnQ1jY2MMHDgQwK3TXitWrMCOHTvg6OioOcLUvXt3dO/e/e5OkIiIiDokSQOQn58fiouLER0djYKCAri6uiI1NRUODg4Abj348PZnAg0dOlTzdWZmJnbs2AEHBwfk5uYCuPVgxaqqKsyYMUNrvaioKKxcubJd50NE1NHl5ORIXUKjLCwsYG9vL3UZJAOSBiAACA4ORnBwsN73kpOTddqEEI2OVx+EiIjo/1SUFANQwN/fX+pSGmVi0hW//prDEETtTvIARERE7a+6vAyAwJBZS9DHyVnqcvQqLcjFsaRVKCoqYgCidscAREQkI90t7dHbfoDUZRBJTvLnABERERHdbQxAREREJDsMQERERCQ7DEBEREQkOwxAREREJDsMQERERCQ7DEBEREQkOwxAREREJDsMQERERCQ7DEBEREQkOwxAREREJDsMQERE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tbtWXQO0fv16nDt3Dra2tnBwcEC3bt203m/sOT1EREREUmtVAJoyZQoUCgU/W4uIiIg6pRYFoPLycrz22mv49NNPUV1djTFjxuC9996DhYVFe9VHRERE1OZadA1QVFQUkpOTMXHiRMycORP79+/H/Pnz26s2IiIionbRoiNAu3fvxpYtW/Dss88CAJ577jkMHz4ctbW1/KR1IiIi6jRadAQoLy8P3t7emtePPvooDA0NtT4Sg4iIiKija1EAqq2thbGxsVaboaEhampq2rQoIiIiovbUolNgQgg8//zzUCqVmrabN28iKChI61b43bt3t12FRERERG2sRQFozpw5Om3+/v5tVgwRERHR3dCiAPTBBx+0Vx1EREREd02rPgqDiIiIqDNjACIiIiLZYQAiIiIi2WEAIiIiItlhACIiIiLZYQAiIiIi2WEAIiIiItlhACIiIiLZYQAiIiIi2WEAIiIiItlhACIiIiLZYQAiIiIi2WEAIiIiItlhACIiIiLZkTwAxcfHw8nJCSqVCu7u7jhy5Eij/Q8fPgx3d3eoVCr069cPCQkJOn2uXbuGkJAQ2NjYQKVSwcXFBampqe01BSIiIupkJA1AKSkpCA0NRWRkJE6dOgVvb2+MHz8earVab//z589jwoQJ8Pb2xqlTp7Bs2TIsWLAAu3bt0vSpqqqCj48PcnNz8fHHH+PMmTPYvHkz+vbte7emRURERB2coZQbX7duHebNm4fAwEAAQFxcHL7++mts2rQJsbGxOv0TEhJgb2+PuLg4AICLiwtOnjyJtWvXYvr06QCApKQkXL16Fenp6TAyMgIAODg43J0JERERUacg2RGgqqoqZGZmwtfXV6vd19cX6enpetfJyMjQ6T9u3DicPHkS1dXVAIA9e/bA09MTISEhsLKygqurK2JiYlBbW9tgLZWVlSgtLdVaiIiI6N4lWQAqKipCbW0trKystNqtrKxQWFiod53CwkK9/WtqalBUVAQA+OOPP/Dxxx+jtrYWqampWL58Od555x2sXr26wVpiY2NhZmamWezs7O5wdkRERNSRSX4RtEKh0HothNBpa6r/39vr6upgaWmJxMREuLu749lnn0VkZCQ2bdrU4JgREREoKSnRLHl5ea2dDhEREXUCkl0DZGFhAQMDA52jPZcvX9Y5ylPP2tpab39DQ0OYm5sDAGxsbGBkZAQDAwNNHxcXFxQWFqKqqgrGxsY64yqVSiiVyjudEhEREXUSkh0BMjY2hru7O9LS0rTa09LS4OXlpXcdT09Pnf779u2Dh4eH5oLn4cOH49y5c6irq9P0OXv2LGxsbPSGHyIiIpIfSU+BhYeH4/3330dSUhJycnIQFhYGtVqNoKAgALdOTc2ePVvTPygoCBcuXEB4eDhycnKQlJSELVu2YPHixZo+8+fPR3FxMRYuXIizZ8/iyy+/RExMDEJCQu76/IiIiKhjkvQ2eD8/PxQXFyM6OhoFBQVwdXVFamqq5rb1goICrWcCOTk5ITU1FWFhYdi4cSNsbW2xfv16zS3wAGBnZ4d9+/YhLCwMbm5u6Nu3LxYuXIglS5bc9fkRERFRxyRpAAKA4OBgBAcH630vOTlZp23kyJHIyspqdExPT08cPXq0LcojIiKie5Dkd4ERERER3W0MQERERCQ7DEBEREQkOwxAREREJDuSXwRNHZNardZ8vEhHlJOTI3UJRETUiTEAkQ61Wg1nZxdUVJRLXUqTqiurpC6BiIg6IQYg0lFUVISKinIMmxuFHjaOUpejV8HpDPy0JxE1NTVSl0JERJ0QAxA1qIeNI3rbD5C6DL1KC3KlLoGIiDoxXgRNREREssMjQERERC3U0W/EsLCwgL29vdRldGgMQERERM1UUVIMQAF/f3+pS2mUiUlX/PprDkNQIxiAiIiImqm6vAyAwJBZS9DHyVnqcvQqLcjFsaRVKCoqYgBqBAMQERFRC3W3tO+wN4lQ8/AiaCIiIpIdBiAiIiKSHQYgIiIikh0GICIiIpIdBiAiIiKSHQYgIiIikh0GICIiIpIdBiAiIiKSHQYgIiIikh0GICIiIpIdBiAiIiKSHQYgIiIikh0GICIiIpIdBiAiIiKSHQYgIiIikh0GICIiIpIdBiAiIiKSHQYgIiIikh0GICIiIpIdyQNQfHw8nJycoFKp4O7ujiNHjjTa//Dhw3B3d4dKpUK/fv2QkJDQYN8PP/wQCoUCU6ZMaeOqiYiIqDOTNAClpKQgNDQUkZGROHXqFLy9vTF+/Hio1Wq9/c+fP48JEybA29sbp06dwrJly7BgwQLs2rVLp++FCxewePFieHt7t/c0iIiIqJORNACtW7cO8+bNQ2BgIFxcXBAXFwc7Ozts2rRJb/+EhATY29sjLi4OLi4uCAwMxNy5c7F27VqtfrW1tXjuueewatUq9OvX725MhYiIiDoRyQJQVVUVMjMz4evrq9Xu6+uL9PR0vetkZGTo9B83bhxOnjyJ6upqTVt0dDT69OmDefPmNauWyspKlJaWai1ERER075IsABUVFaG2thZWVlZa7VZWVigsLNS7TmFhod7+NTU1KCoqAgB8//332LJlCzZv3tzsWmJjY2FmZqZZ7OzsWjgbIiIi6kwkvwhaoVBovRZC6LQ11b++vaysDP7+/ti8eTMsLCyaXUNERARKSko0S15eXgtmQERERJ2NoVQbtrCwgIGBgc7RnsuXL+sc5alnbW2tt7+hoSHMzc3x888/Izc3F5MmTdK8X1dXBwAwNDTEmTNn0L9/f51xlUollErlnU6JiIiIOgnJjgAZGxvD3d0daWlpWu1paWnw8vLSu46np6dO/3379sHDwwNGRkZwdnbG6dOnkZ2drVkmT56M0aNHIzs7m6e2iIiICICER4AAIDw8HAEBAfDw8ICnpycSExOhVqsRFBQE4Napqfz8fGzduhUAEBQUhA0bNiA8PBwvvvgiMjIysGXLFuzcuRMAoFKp4OrqqrWNnj17AoBOOxEREcmXpAHIz88PxcXFiI6ORkFBAVxdXZGamgoHBwcAQEFBgdYzgZycnJCamoqwsDBs3LgRtra2WL9+PaZPny7VFIiIiKgTkjQAAUBwcDCCg4P1vpecnKzTNnLkSGRlZTV7fH1jEBERkbxJfhcYERER0d3GAERERESywwBEREREssMARERERLLDAERERESywwBEREREssMARERERLLDAERERESywwBEREREssMARERERLLDAERERESywwBEREREsiP5h6ESERFR28vJyZG6hEZZWFjA3t5esu0zABEREd1DKkqKASjg7+8vdSmNMjHpil9/zZEsBDEAERER3UOqy8sACAyZtQR9nJylLkev0oJcHEtahaKiIgYgOVGr1SgqKpK6jAZ19MOmRETUtO6W9uhtP0DqMjosBqC7TK1Ww9nZBRUV5VKX0qTqyiqpSyAiImoXDEB3WVFRESoqyjFsbhR62DhKXY5eBacz8NOeRNTU1EhdChERUbtgAJJIDxvHDntosrQgV+oSiIiI2hWfA0RERESywwBEREREssMARERERLLDAERERESywwBEREREssMARERERLLDAERERESywwBEREREssMA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\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "n_rolls = 20_000\n",
    "\n",
    "# First roll (same as before)\n",
    "first_rolls = np.array([np.random.choice(dice) for _ in range(n_rolls)])\n",
    "\n",
    "# Second roll (code is the same but saved in a new numpy array)\n",
    "second_rolls = np.array([np.random.choice(dice) for _ in range(n_rolls)])\n",
    "\n",
    "# Sum both rolls (this is easy since numpy allows vectorization)\n",
    "sum_of_rolls = first_rolls + second_rolls\n",
    "\n",
    "# Print mean, variance and covariance\n",
    "print(f\"mean of first_rolls: {np.mean(first_rolls):.2f}\\nvariance of first_rolls: {np.var(first_rolls):.2f}\\n\")\n",
    "print(f\"mean of second_rolls: {np.mean(second_rolls):.2f}\\nvariance of second_rolls: {np.var(second_rolls):.2f}\\n\")\n",
    "print(f\"mean of sum_of_rolls: {np.mean(sum_of_rolls):.2f}\\nvariance of sum_of_rolls: {np.var(sum_of_rolls):.2f}\\n\")\n",
    "print(f\"covariance between first and second roll:\\n{np.cov(first_rolls, second_rolls)}\")\n",
    "\n",
    "# Plot histogram\n",
    "sum_2_rolls_hist = sns.histplot(sum_of_rolls, stat = \"probability\", discrete=True)\n",
    "sum_2_rolls_hist.set(title=f\"Histogram of {n_rolls} rolls (sum of rolling twice)\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1bf4dbd4",
   "metadata": {},
   "source": [
    "The resulting plot looks pretty Gaussian, as you might expect. Notice that the covariance between the first and second rolls is very close to zero since these two processes are independant of one another.\n",
    "\n",
    "Also notice that you can change the stat displayed in the histogram by changing the `stat` parameter of the `sns.histplot` function. In the previous exercises you were displaying the frequency but in this latter one you are plotting the probability, which makes more sense in this context. To check what other stats are available you can check the [docs](https://seaborn.pydata.org/generated/seaborn.histplot.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f70efe53",
   "metadata": {},
   "source": [
    "## Using loaded dice\n",
    "\n",
    "So far you have only simulated dice that are fair (all of the sides on them have the same probability of showing up), but what about simulating loaded dice (one or more of the sides have a greater probability of showing up)?\n",
    "\n",
    "It is actually pretty simple. [np.random.choice](https://numpy.org/doc/stable/reference/random/generated/numpy.random.choice.html) has support for these kind of scenarios by having a parameter `p` you can set. This parameter controls the probability of selecting each one of the entries in the array.\n",
    "\n",
    "To see it in action, code a function that returns the probabilities of the dice landing on each side given that one of the sides must have twice as much probability as the rest of them:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "84478b71",
   "metadata": {},
   "outputs": [],
   "source": [
    "def load_dice(n_sides, loaded_number):\n",
    "    \n",
    "    # All probabilities are initially the same\n",
    "    probs = np.array([1/(n_sides+1) for _ in range(n_sides)])\n",
    "    \n",
    "    # Assign the loaded side a probability that is twice as the other ones\n",
    "    probs[loaded_number-1] = 1 - sum(probs[:-1])\n",
    "    \n",
    "    # Check that all probabilities sum up to 1\n",
    "    if not np.isclose(sum(probs), 1):\n",
    "        print(\"All probabilities should add up to 1\")\n",
    "        return\n",
    "    \n",
    "    return probs "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "45768e32",
   "metadata": {},
   "source": [
    "Before using this function, check how the probabilities of a fair dice would look like:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "c63f659b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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pmfPnmb58uWmV69eblfC1HcFSUVFhbnvvvvMOeecY/z9/U3fvn3Nm2++acaPH+/2Oo9dXfDkk0+6ja9r2yebx4b0e/75503Pnj2Nn5+fCQ4ONiNHjjRffvmlW5/x48ebwMDAevfRkHp37txprr76anP22Webli1bmiuuuMJ88cUXNd7buq6m8aQGY4x56623XK+tY8eO5vHHHzczZsw46dU0xhy92uiee+4xHTt2NL6+viY0NNQMGzbMfP31164+lZWVZs6cOaZXr17G39/ftGjRwkRHR5vbbrvNfPfddyet79NPPzWSzPnnn+/W/uijjxpJJi0trcaY2mpdsmSJiY6ONr6+vkaSmTFjhjGm7jmrbQ7q8vnnn5thw4aZli1bGn9/f3PRRReZt99++6Tjli9fblJSUsw555xj/Pz8TGhoqBk6dKhZu3atq09tV9MY0/D3zRhjFixYYOLj401gYKAJCAgwnTt3NuPGjTObNm0yxhjz9ddfm+uuu8507tzZBAQEmODgYNOvXz+zaNGiBr1+nL4cxjTgJhDAGWzbtm2Kjo7WjBkzNG3aNNvlAMDvDmEEvyuffvqplixZosTERAUFBembb77RE088ofLycn3xxRd1XlUDAPjtcM4IflcCAwO1adMmvfDCC9q3b5+Cg4M1ePBgPfroowQRALCElREAAGDVKV3am52draioKPn7+ys2NrbGF4Qd79iXZJ34OP4LqgAAwO+Xx2Fk6dKlmjx5sqZPn67NmzdrwIABSklJOektrL/55hsVFxe7Ho25JTIAADhzeHyYJj4+Xn379nW7+2RMTIxGjRqlrKysGv1Xr16tSy65RL/88stvcv8BAADg3Tw6gfXw4cMqKCioccvd5ORkrV+/vt6xffr00a+//qquXbvqwQcf1CWXXFJn34qKClVUVLieV1dXa+/evWrTpk2jb2MNAAD+bxhjtH//foWHh9d7Y0mPwsiePXtUVVVV46qDsLCwOr8jon379srNzVVsbKwqKir04osvKikpSatXr9bAgQNrHZOVlaWZM2d6UhoAADhNFRUV1fuFlad0ae+JqxPGmDpXLI7drvuYhIQEFRUVac6cOXWGkfT0dKWlpbmel5WVqWPHjioqKmr0N40CAID/G+Xl5YqIiDjpl016FEZCQkLUvHnzGqsgu3fv9ugeDRdddFGNL/Q6ntPprPWb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rV+/vkHbqK6u1v79+9W6des6+2RlZSk4ONj1iIiI8KRMAADgRTwKI3v27FFVVZXCwsLc2sPCwlRSUtKgbTz11FM6ePCgrr322jr7pKenq6yszPUoKirypEwAAOBFfE5lkMPhcHtujKnRVpslS5YoIyNDf//73xUaGlpnP6fTKafTeSqlAQAAL+NRGAkJCVHz5s1rrILs3r27xmrJiZYuXapbbrlFr732mi699FLPKwUAAGckjw7T+Pn5KTY2Vnl5eW7teXl5SkxMrHPckiVLdOONN+rll1/WsGHDTq1SAABwRvL4ME1aWprGjh2ruLg4JSQkKDc3V4WFhZo4caKko+d77Nq1S4sXL5Z0NIiMGzdO8+bN00UXXeRaVQkICFBwcHATvhQAAOCNPA4jqampKi0tVWZmpoqLi9W9e3etWLFCkZGRkqTi4mK3e4789a9/1ZEjRzRp0iRNmjTJ1T5+/HgtWrSo8a8AAAB4NY/vM2JDQ69TBgAAp4/f5D4jAAAATY0wAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwysd2AU0l9o+LbZdwWih4clyjt1GY2aMJKvF+HR/+vFHj+z/Tv4kq8X4f3/Vxo8avGTioiSrxboM+WtPobfxlyttNUIn3u/OpEY0a/+gN1zRRJd5v+t/+X6O3wcoIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsIowAgAArCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAsOqUwkh2draioqLk7++v2NhYrV27ts6+xcXFuv7669WlSxc1a9ZMkydPPtVaAQDAGcjjMLJ06VJNnjxZ06dP1+bNmzVgwAClpKSo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pCFDhmjkyJH68ssvbZfmtfLz85Wbm6uePXvaLsVrdevWTcXFxa7H559/brskr/TLL7+of//+8vX11TvvvKOvvvpKTz31lNd8ZUpdTumL8vBvKSkpSklJsV2G13v33Xfdni9cuFChoaEqKCjQwIEDLVXlnUaMGOH2/NFHH1VOTo42btyobt26WarKex04cED/8R//oeeee06zZs2yXY7X8vHxYTWkCcyePVsRERFauHChq61Tp072CmoirIzgtFRWViZJat26teVKvFtVVZVeeeUVHTx4UAkJCbbL8UqTJk3SsGHDdOmll9ouxat99913Cg8PV1RUlMaMGaMffvjBdkle6a233lJcXJz+8Ic/KDQ0VH369NFzzz1nu6xGI4zgtGOMUVpami6++GJ1797ddjle6fPPP1eLFi3kdDo1ceJEvfHGG+ratavtsrzOK6+8ok8++URZWVm2S/Fq8fHxWrx4sVauXKnnnntOJSUlSkxMVGlpqe3SvM4PP/ygnJwcnX/++Vq5cqUmTpyou+++W4sXL7ZdWqNwmAannTvvvFOfffaZ1q1bZ7sUr9WlSxdt2bJF+/bt07JlyzR+/HitWbOGQOKBoqIi3XPPPXrvvffk7+9vuxyvdvyh7B49eighIUGdO3fWf/3XfyktLc1iZd6nurpacXFxeuyxxyRJffr00ZdffqmcnBy3L6n1NqyM4LRy11136a233tKqVavUoUMH2+V4LT8/P5133nmKi4tTVlaWevXqpXnz5tkuy6sUFBRo9+7dio2NlY+Pj3x8fLRmzRr9+c9/lo+Pj6qqqmyX6LUCAwPVo0cPfffdd7ZL8Trt27ev8R8VMTExbl9Q641YGcFpwRiju+66S2+88YZWr16tqKgo2yWdUYwxqqiosF2GV0lKSqpxxcdNN92k6OhoPfDAA2revLmlyrxfRUWFtm7dqgEDBtguxev079+/xm0Pvv32W0VGRlqqqGkQRhrpwIED+v77713Pt23bpi1btqh169bq2LGjxcq8y6RJk/Tyyy/r73//u1q2bKmSkhJJUnBwsAICAixX512mTZumlJQURUREaP/+/XrllVe0evXqGlcsoX4tW7ascc5SYGCg2rRpw7lMHrrvvvs0YsQIdezYUbt379asWbNUXl6u8ePH2y7N69x7771KTEzUY489pmuvvVb//Oc/lZubq9zcXNulNY5Bo6xatcpIqvEYP3687dK8Sm1zKMksXLjQdmle5+abbzaRkZHGz8/PtG3b1iQlJZn33nvPdllnhEGDBpl77rnHdhleJzU11bRv3974+vqa8PBwc9VVV5kvv/zSdlle6+233zbdu3c3TqfTREdHm9zcXNslNZrDGGMs5SAAAABOYAUAAHYRRgAAgFWEEQAAYBVhBAAAWEUYAQAAVhFGAACAVYQRAABgFWEEAABYRRgBAABWEUYAAIBVhBEAAGDV/wecuByK/H6WfAAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Compute same probabilities for every side\n",
    "probs_fair_dice = np.array([1/n_sides]*n_sides)\n",
    "\n",
    "# Plot probabilities\n",
    "fair_dice_sides = sns.barplot(x=dice, y=probs_fair_dice)\n",
    "fair_dice_sides.set(title=f\"Histogram for fair dice with {n_sides} sides\")\n",
    "fair_dice_sides.set_ylim(0,0.5)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8bbf1913",
   "metadata": {},
   "source": [
    "Now get the probabilities by using the `load_dice` function. Try changing the loaded side!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "67536017",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get probabilities if dice is loaded towards side 2\n",
    "probs_loaded_dice = load_dice(n_sides, loaded_number=2)\n",
    "\n",
    "# Plot probabilities\n",
    "loaded_dice_sides = sns.barplot(x=dice, y=probs_loaded_dice)\n",
    "loaded_dice_sides.set(title=f\"Histogram for loaded dice with {n_sides} sides\")\n",
    "loaded_dice_sides.set_ylim(0,0.5)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7cdf0ec5",
   "metadata": {},
   "source": [
    "Now, feed the `probs_loaded_dice` array into `np.random.choice` and see how this affect the metrics and plot:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d98459f9",
   "metadata": {},
   "outputs": [],
   "source": [
    "n_rolls = 20_000\n",
    "\n",
    "# Notice that the p parameter is being set\n",
    "first_rolls = np.array([np.random.choice(dice, p=probs_loaded_dice) for _ in range(n_rolls)])\n",
    "\n",
    "second_rolls = np.array([np.random.choice(dice, p=probs_loaded_dice) for _ in range(n_rolls)])\n",
    "\n",
    "sum_of_rolls = first_rolls + second_rolls\n",
    "\n",
    "print(f\"mean of first_rolls: {np.mean(first_rolls):.2f}\\nvariance of first_rolls: {np.var(first_rolls):.2f}\\n\")\n",
    "print(f\"mean of second_rolls: {np.mean(second_rolls):.2f}\\nvariance of second_rolls: {np.var(second_rolls):.2f}\\n\")\n",
    "print(f\"mean of sum_of_rolls: {np.mean(sum_of_rolls):.2f}\\nvariance of sum_of_rolls: {np.var(sum_of_rolls):.2f}\\n\")\n",
    "print(f\"covariance between first and second roll:\\n{np.cov(first_rolls, second_rolls)}\")\n",
    "\n",
    "# Plot histogram\n",
    "loaded_rolls_hist = sns.histplot(sum_of_rolls, stat = \"probability\", discrete=True)\n",
    "loaded_rolls_hist.set(title=f\"Histogram of {n_rolls} rolls (sum of rolling twice a loaded dice)\")\n",
    "loaded_rolls_hist.set_xticks(range(min(sum_of_rolls),max(sum_of_rolls)+1))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5af6e690",
   "metadata": {},
   "source": [
    "Now the histogram is skewed towards some values since some sums are now more likely than others. Try changing the loaded side and see how the histogram changes!\n",
    "\n",
    "Notice that covariance is still very close to zero since there is not any dependance between rolls of the dice."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "06b40238",
   "metadata": {},
   "source": [
    "## Dependant Rolls\n",
    "\n",
    "To finish this lab you will now simulate the scenario in which the second roll depends on the result of the first one. Say that you are playing a variant of the game you have played so far and you only roll the dice a second time if the result of the first roll is greater or equal to 4.\n",
    "\n",
    "Before doing the simulations reflect on what might happen in this scenario. Some behavior you will probably see:\n",
    "\n",
    "- 1 is now a possible result since if you get a 1 in the first roll you don't roll again\n",
    "- 1, 2 and 3 now have a greater chance of showing up\n",
    "- 4 is now not a possible result since you need to roll again if you get a 4 in the first roll\n",
    "\n",
    "To achieve this behaviour you can use the [np.where](https://numpy.org/doc/stable/reference/generated/numpy.where.html) function, which given a condition can be used to zero-out the elements that don't meet its criteria:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f6ea0bed",
   "metadata": {},
   "outputs": [],
   "source": [
    "n_rolls = 20_000\n",
    "\n",
    "first_rolls = np.array([np.random.choice(dice) for _ in range(n_rolls)])\n",
    "\n",
    "second_rolls = np.array([np.random.choice(dice) for _ in range(n_rolls)])\n",
    "\n",
    "# Preserve the result of the second throw only if the first roll was greater or equal to 4\n",
    "second_rolls = np.where(first_rolls>=4, second_rolls, 0)\n",
    "\n",
    "sum_of_rolls = first_rolls + second_rolls\n",
    "\n",
    "print(f\"mean of first_rolls: {np.mean(first_rolls):.2f}\\nvariance of first_rolls: {np.var(first_rolls):.2f}\\n\")\n",
    "print(f\"mean of second_rolls: {np.mean(second_rolls):.2f}\\nvariance of second_rolls: {np.var(second_rolls):.2f}\\n\")\n",
    "print(f\"mean of sum_of_rolls: {np.mean(sum_of_rolls):.2f}\\nvariance of sum_of_rolls: {np.var(sum_of_rolls):.2f}\\n\")\n",
    "print(f\"covariance between first and second roll:\\n{np.cov(first_rolls, second_rolls)}\")\n",
    "\n",
    "# Plot histogram\n",
    "dependant_rolls_hist = sns.histplot(sum_of_rolls, stat = \"probability\", discrete=True)\n",
    "dependant_rolls_hist.set(title=f\"Histogram of {n_rolls} rolls (dependant sum of rolling twice)\")\n",
    "dependant_rolls_hist.set_xticks(range(min(sum_of_rolls),max(sum_of_rolls)+1))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "970303f1",
   "metadata": {},
   "source": [
    "Looks like all of the predictions of this new scenario indeed happened. Notice that the covariance now is nowhere near zero since there is a dependency between the first and the second roll!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1b016cd1",
   "metadata": {},
   "source": [
    "**Now you have finished this ungraded lab, nice job!**"
   ]
  }
 ],
 "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.10.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}