diff --git a/Three Math Games.ipynb b/Three Math Games.ipynb new file mode 100644 index 0000000..6f03c00 --- /dev/null +++ b/Three Math Games.ipynb @@ -0,0 +1,354 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 128, + "id": "e4365f4a-71af-4b54-8000-e549c34df127", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "from ipywidgets import interactive, fixed\n", + "from IPython import display\n", + "from random import randint\n", + "from time import sleep\n", + "from sympy import symbols, Eq\n", + "from sympy.solvers import solve\n", + "from sympy.parsing.sympy_parser import parse_expr" + ] + }, + { + "cell_type": "markdown", + "id": "23fa0780-17a8-4801-ae5a-f4ee0172ae40", + "metadata": {}, + "source": [ + "# Projectile game" + ] + }, + { + "cell_type": "markdown", + "id": "0740f36c-6c52-422f-9db0-a6619a9a5ffb", + "metadata": {}, + "source": [ + "## Easy Mode" + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "id": "f39607ff-7776-4d49-8de9-2f79bff89a92", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "6016d1e3623c4376bcf7aa7041f2beaf", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(FloatSlider(value=0.0, description='a', max=25.0, min=-25.0), FloatSlider(value=0.0, des…" + ] + }, + "execution_count": 116, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "xlo = -2\n", + "xhi = 20\n", + "ylo = -20\n", + "yhi = 120\n", + "\n", + "def graph(a, b, c, height, distance):\n", + " plt.clf()\n", + " fix = plt.subplot()\n", + " plt.axis([xlo, xhi, ylo, yhi])\n", + " plt.plot([0, 0], [ylo, yhi], \"black\")\n", + " plt.plot([xlo, xhi], [0, 0], \"black\")\n", + " wall_height = height\n", + " wall_distance = distance\n", + " plt.plot([wall_distance, wall_distance], [0, wall_height], \"brown\")\n", + " plt.grid()\n", + " plt.title(f\"{a:.1f}*x**2 + {b:.1f}*x + {c:.1f}\")\n", + " \n", + " x = np.linspace(0, xhi, xhi*1000)\n", + " y = a*x**2 + b*x + c\n", + " success = a*wall_distance**2 + b*wall_distance + c > wall_height\n", + " x2 = []\n", + " y2 = []\n", + " for i in range(len(y)):\n", + " if y[i] < 0:\n", + " break\n", + " if not success and x[i] > wall_distance:\n", + " break\n", + " x2.append(x[i])\n", + " y2.append(y[i])\n", + " \n", + " y2[-1] = 0 # finally ball hits the ground (handling imprecisions and ball hitting walls)\n", + " plt.plot([x2[-1]], [y2[-1]], 'ro')\n", + " plt.plot(x2, y2, \"b\")\n", + " plt.show()\n", + "\n", + "\n", + "slider_range = (-25, 25, 0.1)\n", + "wall_height = randint(2, yhi-20)\n", + "wall_distance = randint(2, xhi-2)\n", + "interactive_graph = interactive(graph, a=slider_range, b=slider_range, c=slider_range, height=fixed(wall_height), distance=fixed(wall_distance))\n", + "interactive_graph" + ] + }, + { + "cell_type": "markdown", + "id": "810b43cb-8289-4952-8259-648add3bbb0e", + "metadata": {}, + "source": [ + "## Hard Mode\n", + "Now guess projectile paramaters without fiddloing with slider" + ] + }, + { + "cell_type": "code", + "execution_count": 127, + "id": "8b65fbea-7647-4e29-902e-ddd80170cdc8", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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jRry8ssvy61bt8oVdAo/7Ldu3Spz586VunXriq2trfTq1UuuXLmiN37btm3Spk0bsbOzE3d3dwkNDZXbt2/rPA8A9C4lGT9+vLi5uem878LDwwWALF++XDstISFB7/2bmJgoI0aMkDp16oitra20bNlSNm7cqLP8wtfEokWLZOnSpdKoUSOxsLCQc+fOFRt0srOz5aWXXhJnZ2f58ccfS33ubty4IZcuXdKZ9vvvvwsAvTqo8vjVVTX37bffomHDhujatWux87t164aGDRti9+7d2mkXL15E165d8dNPP2HixImYNm0a4uPj0aNHD5w4cUJvGeHh4bh06RJmzpyJN998E5s2bcKAAQMgIgCA+/fvIzAwENevX8fkyZOxcuVKhIaG4vjx48Zpuoj09HSkp6ejVq1apY4rKCjAzz//jHbt2unN69ChA65du4a0tDTtNAsLC50dMote79WrF959911ERkbi7NmzAIB79+7hvffeQ0BAAN55551il1O4T0VRFhYWOt+xl3cn0ISEBDg4OMDBwaFc46tajx49kJqaijFjxuDSpUu4ceMG1qxZg+3bt2PKlCml3vfOnTu4f/9+ievq3Llz2tsqlUrv+Sv6HL711lvo168fIiIicOvWLQDAhQsXMGvWLIwcORIvvvji47ZapTIzM+Hs7AwXFxe4ubkhLCwM6enpZd5PRBAcHIwvv/wSQ4cOxdy5c3H79m0MGzasXI/79ttvY9myZQgMDMSCBQtgbW2Nl156qUK1L1iwADt27MBHH32EKVOm4Pjx4wgNDdUZs3HjRgwePBiWlpaIjIzEqFGjsH37dnTp0gXJyckAgDFjxqBPnz4AoPMVXkm6du2Khw8f6uyveOTIEVhYWODIkSM60wDN30wAyMrKQo8ePfDll18iNDQUixYtgouLC4YPH47ly5frPc6GDRuwcuVKjB49Gp988gnc3Nz0xmRlZeHll1/GsWPHsG/fPnTq1KnU5+zNN9/U+5rz2LFjAIA2bdqUel+qAFMnLSpZcnKyAJDg4OBSx/Xv31/nf/8DBgwQGxsbna+z7t69K05OTtKtWzfttMItOm3btpXc3Fzt9IULFwoA2bVrl4iI7NixQwDIqVOnDNhd+cyZM0cASExMTKnjHjx4IABk9uzZevNWrVolAOTy5cuSlpYmffr0kT59+sjvv/+u89XV66+/rv1f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qFQ81xUREREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESlWpYPO4cOH8fLLL8Pb2xsqlQo7d+7UmS8imD59Ory8vGBvb4+AgABcuXJFZ8zDhw8RGhoKZ2dnuLq6YuTIkUhPT69sSUREREQ6Kh10MjIy0KpVK6xatarY+QsXLsSKFSuwZs0anDhxAo6OjggKCkJ2drZ2TGhoKC5evIjo6Gh89913OHz4MEaPHl3ZkoiIiIh0WFX2ji+88AJeeOGFYueJCJYtW4apU6ciODgYAPDFF1/Aw8MDO3fuREhICC5duoQ9e/bg1KlTaNeuHQBg5cqVePHFF7F48WJ4e3sXu+ycnBzk5ORob6empgIA1Go11Gp1ZdupMkVrNJeaK6qwJyX2VkjpPbI/86f0Htmf+auq3ioddEoTHx+PhIQEBAQEaKe5uLigY8eOiI2NRUhICGJjY+Hq6qoNOQAQEBAACwsLnDhxAq+88kqxy46MjMSsWbP0pv/www9wcHAwfDMGVnSL1v79+2FnZ2fCaowrOjra1CUYndJ7ZH/mT+k9sj/zlZmZWSWPY5Sgk5CQAADw8PDQme7h4aGdl5CQgDp16ugWY2UFNzc37ZjiTJkyBREREdrbqampqF+/PgIDA+Hs7GyoFowmIyNDe71Xr15wdXU1XTFGolarER0djT59+sDa2trU5RiF0ntkf+ZP6T2yP/OXlJRUJY9jlKBjTLa2trC1tdWbbm1tbRYvhqI1mkvNlaX0/gDl98j+zJ/Se2R/5quq+jLKz8s9PT0BAImJiTrTExMTtfM8PT1x//59nfl5eXl4+PChdgwRERHR4zBK0PH19YWnpydiYmK001JTU3HixAn4+/sDAPz9/ZGcnIwzZ85ox+zfvx8FBQXo2LGjMcoiIiKiJ0ylv7pKT0/H1atXtbfj4+Nx/vx5uLm5wcfHB+PGjcPcuXPRpEkT+Pr6Ytq0afD29saAAQMAAM2aNUPfvn0xatQorFmzBmq1GuHh4QgJCSnxF1dEREREFVHpoHP69Gn07NlTe7twB+Fhw4Zh48aNmDhxIjIyMjB69GgkJyejS5cu2LNnj86vjDZt2oTw8HD07t0bFhYWGDRoEFasWPEY7RARERH9pdJBp0ePHhCREuerVCrMnj0bs2fPLnGMm5sbvv7668qWQERERFQqnuuKiIiIFItBh4iIiBSLQYeIiIgUi0GHiIiIFItBh4iIiBSLQYeIiIgUi0GHiIiIFItBh4iIiBSLQYeIiIgUi0GHiIiIFItBh4iIiBSLQYeIiIgUi0GHiIiIFItBh4iIiBSLQYeIiIgUi0GHiIiIFItBh4iIiBSLQYeIiIgUi0GHiIiIFItBh4iIiBSLQYeIiIgUi0GHiIiIFItBh4iIiBSLQYeIiIgUi0GHiIiIFItBh4iIiBSLQYeIiIgUi0GHiIiIFItBh4iIiBSLQYeIiIgUi0GHiIiIFItBh4iIiBSLQYeIiIgUi0GHiIiIFItBh4iIiBTLytQFEJGGiCA/KwsAYGlvD5VKZeKKiIjMH7foEFUT+VlZ2Na+Pba1b68NPERE9HgYdIiIiEixGHSIiIhIsRh0iIiISLEYdIiIiEixjBp08vPzMW3aNPj6+sLe3h6NGzfGnDlzICLaMSKC6dOnw8vLC/b29ggICMCVK1eMWRYRERE9IYwadKKiorB69Wp8+umnuHTpEqKiorBw4UKsXLlSO2bhwoVYsWIF1qxZgxMnTsDR0RFBQUHIzs42ZmlERET0BDDqcXSOHTuG4OBgvPTSSwCAhg0bYvPmzTh58iQAzdacZcuWYerUqQgODgYAfPHFF/Dw8MDOnTsREhJizPKIiIhI4YwadDp16oTPP/8cv/32G55++mn89NNPOHr0KJYsWQIAiI+PR0JCAgICArT3cXFxQceOHREbG1ts0MnJyUFOTo72dmpqKgBArVZDrVYbsx2DKFqjudRcUYU9KbG3QsboMS8v76/l5+VBTPj8KX0dKr0/QPk9sj/zV1W9GTXoTJ48GampqfDz84OlpSXy8/Mxb948hIaGAgASEhIAAB4eHjr38/Dw0M57VGRkJGbNmqU3/YcffoCDg4OBOzC8ol/J7d+/H3Z2diasxriio6NNXYLRGbJHyc3VXt+7dy9UNjYGW3ZlKX0dKr0/QPk9sj/zlZmZWSWPY9Sgs23bNmzatAlff/01mjdvjvPnz2PcuHHw9vbGsGHDKrXMKVOmICIiQns7NTUV9evXR2BgIJydnQ1VutFkZGRor/fq1Quurq6mK8ZI1Go1oqOj0adPH1hbW5u6HKMwRo95WVnYMXMmACAoKAhW9vYGWW5lKH0dKr0/QPk9sj/zl5SUVCWPY9SgM2HCBEyePFn7FVSLFi1w48YNREZGYtiwYfD09AQAJCYmwsvLS3u/xMREPPfcc8Uu09bWFra2tnrTra2tzeLFULRGc6m5spTeH2DYHlVFNuNaW1nBqho8d0pfh0rvD1B+j+zPfFVVX0b91VVmZiYsLHQfwtLSEgUFBQAAX19feHp6IiYmRjs/NTUVJ06cgL+/vzFLIyIioieAUbfovPzyy5g3bx58fHzQvHlznDt3DkuWLMGIESMAACqVCuPGjcPcuXPRpEkT+Pr6Ytq0afD29saAAQOMWRoRERE9AYwadFauXIlp06bh3Xffxf379+Ht7Y0xY8Zg+vTp2jETJ05ERkYGRo8ejeTkZHTp0gV79uxR9E66REREVDWMGnScnJywbNkyLFu2rMQxKpUKs2fPxuzZs41ZChERET2BeK4rIiIiUiwGHSIiIlIsBh0iIiJSLAYdIiIiUiwGHSIiIlIsBh0iIiJSLAYdIiIiUiwGHSIiIlIsBh0iIiJSLAYdIiIiUiwGHSIiIlIsBh0iIiJSLAYdIiIiUiwGHSIiIlIsBh0iIiJSLAYdIiIiUiwGHSIiIlIsBh0iIiJSLAYdIiIiUiwGHSIiIlIsBh0iIiJSLAYdIiIiUiwGHSIiIlIsBh0iIiJSLAYdIiIiUiwGHSIiIlIsBh0iIiJSLAYdIiIiUiwGHSIiIlIsBh0iIiJSLAYdIiIiUiwGHSIiIlIsBh0iIiJSLAYdIiIiUiwGHSIiIlIsBh0iIiJSLAYdIiIiUiwGHSIiIlIsBh0iIiJSLAYdIiIiUiwGHSIiIlIsBh0iIiJSLKMHnTt37mDo0KFwd3eHvb09WrRogdOnT2vniwimT58OLy8v2NvbIyAgAFeuXDF2WURERPQEMGrQ+fPPP9G5c2dYW1vjf//7H3799Vd88sknqFmzpnbMwoULsWLFCqxZswYnTpyAo6MjgoKCkJ2dbczSiIiI6AlgZcyFR0VFoX79+tiwYYN2mq+vr/a6iGDZsmWYOnUqgoODAQBffPEFPDw8sHPnToSEhBizPCIiIlI4owad//73vwgKCsKrr76KQ4cOoW7dunj33XcxatQoAEB8fDwSEhIQEBCgvY+Liws6duyI2NjYYoNOTk4OcnJytLdTU1MBAGq1Gmq12pjtGETRGs2l5ooq7EmJvRUyRo95eXl/LT8vD2LC50/p61Dp/QHK75H9mb+q6s2oQef333/H6tWrERERgY8//hinTp3C+++/DxsbGwwbNgwJCQkAAA8PD537eXh4aOc9KjIyErNmzdKb/sMPP8DBwcHwTRhY0a/k9u/fDzs7OxNWY1zR0dGmLsHoDNmj5OZqr+/duxcqGxuDLbuylL4Old4foPwe2Z/5yszMrJLHUYmIGGvhNjY2aNeuHY4dO6ad9v777+PUqVOIjY3FsWPH0LlzZ9y9exdeXl7aMYMHD4ZKpcLWrVv1llncFp369evjjz/+gLOzs7FaMZiMjAztPkr379+Hq6uraQsyArVajejoaPTp0wfW1tamLscojNFjXlYWdvj7AwBeiY2Flb29QZZbGUpfh0rvD1B+j+zP/CUlJcHLywspKSlG/fw26hYdLy8vPPPMMzrTmjVrhv/85z8AAE9PTwBAYmKiTtBJTEzEc889V+wybW1tYWtrqzfd2traLF4MRWs0l5orS+n9AYbtUVVkM661lRWsqsFzp/R1qPT+AOX3yP7MV1X1ZdRfXXXu3BlxcXE603777Tc0aNAAgGbHZE9PT8TExGjnp6am4sSJE/D////ZEhEREVWWUbfojB8/Hp06dcL8+fMxePBgnDx5Ep9//jk+//xzAIBKpcK4ceMwd+5cNGnSBL6+vpg2bRq8vb0xYMAAY5ZGRERETwCjBp327dtjx44dmDJlCmbPng1fX18sW7YMoaGh2jETJ05ERkYGRo8ejeTkZHTp0gV79uxR9E66REREVDWMGnQAoF+/fujXr1+J81UqFWbPno3Zs2cbuxQiIiJ6wvBcV0RERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFhWpi6AqCqJAH/8Ady9Czx4oLmekgLk5wMFBZr5NWoAzs6Aiwvg5QU0bAg4Opq6ciIiqgwGHVKsnBzg/HngxAng9Gng8mXgyhUgObniy6pdG2jSBGjdGmjTBmjZUhOMiIioemPQIcUQAS5eBP73P2DPHuDoUSA3V3+cSgXUqaMJL7VqabbcWFkBlpaa+Wlpmq08ycnAnTua6w8eaC7HjhUuxRpOTi8gIMASffoA/foB9etXUaNERFRuVRZ0FixYgClTpuCDDz7AsmXLAADZ2dn48MMPsWXLFuTk5CAoKAifffYZPDw8qqosUoBffwU2bQI2bwbi43XnubsDHTtqLi1aaLbKNG4M2NuXf/nJyZrlXroEnD2ruZw+LUhLs8GOHcCOHcC77wLPPw+8+qrmwtBDRFQ9VEnQOXXqFNauXYuWLVvqTB8/fjx2796Nb775Bi4uLggPD8fAgQPx448/VkVZZMYyMjThZs0a4Ny5v6bb2QE9egAvvAAEBQFPP63ZgvM4XF01X1m1bg28/rpmWmZmHlaujEVWVmfs22eJY8eA48c1lwkTNI8/ejTw4ouarUVERGQaRv/VVXp6OkJDQ/GPf/wDNWvW1E5PSUnBunXrsGTJEvTq1Qtt27bFhg0bcOzYMRw/ftzYZZGZun4d+PBDoF49YMwYTcixsgJefhnYskWzc/H//ge8/z7QtOnjh5ySWFsDfn5/4u9/L8DRo8Dt28DKlUDXrpp9d3bvBoKDNTsyL16s+TqMiIiqntH/rxkWFoaXXnoJAQEBmDt3rnb6mTNnoFarERAQoJ3m5+cHHx8fxMbG4vnnny92eTk5OcjJydHeTk1NBQCo1Wqo1WojdWE4RWs0l5orqrAnQ/YWHw9ERVniiy9UyMvTpJfGjQXvvFOAoUML4O5e9PEN9rAlerTH2rU1wWvMGOC334D16y3wxRcWuHNHhQkTgPnzBWPHFiA8vAC1ahW/zLy8vL+Wn5cHMeFrwxjrsDpRen+A8ntkf+avqnozatDZsmULzp49i1OnTunNS0hIgI2NDVxdXXWme3h4ICEhocRlRkZGYtasWXrTf/jhBzg4ODx2zcaWnZ2tvb5//37Y2dmZsBrjio6OfuxlJCXZYfNmPxw4UB/5+ZoNkC1bPkD//tfQpk0iLCw0v6oylZJ67NYN8Pe3wOHD9bB9+1O4c8cJ8+dbYunSAgwceBX9+1+DrW2+zn2kyJ7Te/fuhcrGxqi1l4ch1mF1pvT+AOX3yP7MV2ZmZpU8jtGCzq1bt/DBBx8gOjraoB/mU6ZMQUREhPZ2amoq6tevj8DAQDg7OxvscYwlIyNDe71Xr156QU8J1Go1oqOj0adPH1hbW1dqGZmZwJIlFli82AKZmZotOH36FGDq1AL4+7sCaGu4giuhvD0GBwMLFwK7duUhMtISP/1kjU2bmuHAAT9Mn56PYcNE+2uvvKws7Jg5EwAQFBQEq4rsMW1ghliH1ZnS+wOU3yP7M39JSUlV8jhGCzpnzpzB/fv30aZNG+20/Px8HD58GJ9++in27t2L3NxcJCcn63zYJyYmwtPTs8Tl2trawtbWVm+6tbW1WbwYitZoLjVXVmX6EwG++UazH87t25ppnTsDixZptpBUt4N5l6dHa2vgtdc0v8basgX4+9+B69dVeOcdK6xbp9mhuk0bQFVkM661lRWsqsFrg69R86f0Htmf+aqqvoz2qdG7d29cuHAB58+f117atWuH0NBQ7XVra2vExMRo7xMXF4ebN2/C39/fWGVRNXb7NtC/vyYU3L4NNGgAbN0KHDkCKOElYWGh+dXW5cvAkiWaoy+fOgW0bw988AHw/7ubERGRARlti46TkxOeffZZnWmOjo5wd3fXTh85ciQiIiLg5uYGZ2dnvPfee/D39y9xR2RSpoICYO1aYNIkza+TrK01Wz0mTdL8XFxpbG2B8eOBkBAgIkKzlWfFCmDHdjuEWvijRY1YU5dIRKQYJj3Cx9KlS2FhYYFBgwbpHDCQnhwJCcCwYcAPP2hu+/sD//wn8Mwzpq2rKnh5aQ5yOGIE8M47wO+/W2AB/onAmpswKJ+HLSciMoQq/Vt68OBBndt2dnZYtWoVVq1aVZVlUDWxezfw1luaUyvY2wMLFgBhYX+diuFJ0acP8PPPwMSP1PhsjTV++DMUP1/IQvtOpq6MiMj8Va89O+mJkJur2SelXz9NyGnVCjhzRnOQvyct5BRydASWf6JGbWvNHti5aiMd6ZCI6AnDreNUpRISgL/9DSg8y8e4cUBkpDL3xakcMXUBRESKwqBDVeb4cWDQIODuXc0Zw7/6SrNVh4iIyFj41RVViXXrNEcLvntXs6PxqVMMOUREZHwMOmRUIpqfir/9tuYcVH/7m+aUDU2amLoyIiJ6EjDokNHk5ABDhwLz52tuz5gBbNsG1Khh2rqIiOjJwX10yCjS063x0kuWOHwYsLIC/vEPYPhwU1dFRERPGgYdMrjERGDq1M64ft0CTk7Af/6jOVYMERFRVWPQIYO6fRvo3dsK16+7wNNTsGePCq1amboqIiJ6UjHokMH8/jvQu7fmzNy1amUiJsYazzyjzLPuEhGReeDOyGQQcXGan49fvw489ZRg/vyj/GUVERGZHIMOPbZr14BevYA7d4DmzYGYmDzUqZNl6rKIiIgYdOjx3LypCTl372pCzoEDmrNyExERVQcMOlRpd+9qQs7Nm8DTTwP79gG1a5u6KiIior8w6FClPHig2fH42jXA1xeIiQE8PU1dFRERkS4GHaqw9HTgxReBy5eBevWA/fs1/xIREVU3DDpUIWo18OqrwOnTgLu75uuqhg1NXZXyiJi6AiIiZWDQoXITAUaNAvbsAeztgd27gaZNTV0VERFRyRh0qNymTQP+9S/A0lJzcs6OHU1dERERUekYdKhcPv8cmDdPc33NGqBfP9PWQ0REVB4MOlSmAweAsDDN9RkzgLffNm09SqYCd84hIjIkBh0q1dWrwKBBQF4eMGSIJugQERGZCwYdKlFKCtC/P/Dnn0D79sC6dYBKZeqqiIiIyo9Bh4qVnw+EhACXLgF16wK7dml+aUVERGROGHSoWJMn//Uz8l27eP4qIiIyTww6pOff/wYWL9Zc37gRaNvWpOUQERFVGoMO6YiLA956S3N9wgRg8GDT1kNERPQ4GHRIKz0dGDhQ82+3bsD8+aauiIiI6PEw6BAAzekdRo8Gfv1Vsz/O1q2AlZWpqyIiIno8DDoEAFi1Cti8+a/TO3h6mroiIiKix8egQzh7FoiI0FxftAjo0sW09RARERkKg84TLj1dc8RjtRoIDgbGjTN1RURERIbDoPOE++AD4LffNAcF5JGPqw/hKa+IiAyCQecJtnUrsH69Jtx89RXg7m7qioiIiAyLQecJFR+v+ZUVAHz8MdCjh0nLISIiMgoGnSdQXh4QGgqkpgL+/jwjORERKReDzhMoKgqIjQWcnYGvvwasrU1dERERkXEw6Dxhzp8HZs3SXP/0U6BhQ1NWQ0REZFwMOk+QnBzgzTc1PyV/5RVg6FBTV0RERGRcDDpPkFmzgAsXgFq1gDVr+FNyIiJSPgadJ8Tx45p9cwBg7VqgTh3T1kPFY/YkIjIsBp0nQGYmMGwYUFCg+bpq4EBTV0RERFQ1jBp0IiMj0b59ezg5OaFOnToYMGAA4uLidMZkZ2cjLCwM7u7uqFGjBgYNGoTExERjlvXEmTpVc/Rjb29gxQpTV0NERFR1jBp0Dh06hLCwMBw/fhzR0dFQq9UIDAxERkaGdsz48ePx7bff4ptvvsGhQ4dw9+5dDOQmB4M5eRJYvlxz/Z//BGrWNG09REREVcnKmAvfs2ePzu2NGzeiTp06OHPmDLp164aUlBSsW7cOX3/9NXr16gUA2LBhA5o1a4bjx4/j+eefN2Z5iqdWA2+//ddXVi+8YOqKiIiIqpZRg86jUlJSAABubm4AgDNnzkCtViMgIEA7xs/PDz4+PoiNjS026OTk5CAnJ0d7OzU1FQCgVquhVquNWb5BFK3R2DUvWGCBCxcs4e4uiIrKQ1U9PYU9mcP6qCxj9JiXl6e9np+fb9LnT+nrUOn9Acrvkf2Zv6rqrcqCTkFBAcaNG4fOnTvj2WefBQAkJCTAxsYGrq6uOmM9PDyQkJBQ7HIiIyMxq/CId0X88MMPcHBwMHjdhpadna29vn//ftjZ2Rnlce7cccScOT0BAG+8cRanTt02yuOUJjo6usofs6oZskfJzQXQEQBw/MRxpGSkG2zZlaX0daj0/gDl98j+zFdmZmaVPE6VBZ2wsDD88ssvOHr06GMtZ8qUKYiIiNDeTk1NRf369REYGAhnZ+fHLdPoiu6f1KtXL72QZwgFBUBgoCXUagsEBhYgKqolVKqWBn+ckqjVakRHR6NPnz6wVuj5JYzRY15WFoBkAMDzHZ9H5+42BlluZSh9HSq9P0D5PbI/85eUlFQlj1MlQSc8PBzfffcdDh8+jHr16mmne3p6Ijc3F8nJyTof+ImJifD09Cx2Wba2trC1tdWbbm1tbRYvhqI1Gqvmf/wDOHwYcHAA1q61gI2NaY4iYC7r5HEYskdVkc24lpaW1eK5U/o6VHp/gPJ7ZH/mq6r6MuonoIggPDwcO3bswP79++Hr66szv23btrC2tkZMTIx2WlxcHG7evAl/f39jlqZYCQnAhAma6/Pm8VxW5krE1BUQESmDUbfohIWF4euvv8auXbvg5OSk3e/GxcUF9vb2cHFxwciRIxEREQE3Nzc4Ozvjvffeg7+/P39xVUkTJwIpKUC7dsB775m6GiIiItMyatBZvXo1AKBHjx460zds2IDhw4cDAJYuXQoLCwsMGjQIOTk5CAoKwmeffWbMshTr8GHgyy8157D67DPA0tLUFREREZmWUYOOlGP7u52dHVatWoVVq1YZsxTFU6uBsDDN9dGjgfbtTVsPERFRdcBzXSnEypXAL78A7u7A/PmmroaIiKh6YNBRgLt3gRkzNNejooD/Px4jERHRE49BRwE+/BBITweefx546y1TV0NERFR9MOiYuf37gS1bAAsLYNUqzb9ERESkwY9FM5aXB7z/vub62LFAmzamrYeIiKi6YdAxY59/Dly8qNknZ84cU1dDRERU/TDomKk//wSmT9dcnz0bqFnTtPUQERFVRww6ZmrOHCApCXjmGWDMGFNXQwaj4rkfiIgMiUHHDP32m+a4OQCwZAlgVWXnoCciIjIvDDpm6KOPNDsiv/giEBRk6mqIiIiqLwYdMxMdDXz7reY8Vp98YupqiIiIqjcGHTOSlwdERGiuh4UBfn6mrYeIiKi6Y9AxI+vXa85nVbPmX6d8ICIiopIx6JiJjAxg5kzN9enTeT4rpRP++IqIyCAYdMzE8uXAvXtAw4aaoyATERFR2Rh0zMAff2jOSg4A8+YBtramrYeIiMhcMOiYgXnzgNRU4LnngJAQU1dDRERkPhh0qrn4eM1ZyQHNVh2enZyIiKj8+LFZzU2fDqjVQEAAEBho6mqIiIjMC4NONXb+PLBpk+b6ggUmLYWIiMgsMehUY5Mna35mHBICtG1r6mqIiIjMD4NONXXwILB3L2BtrdkZmYiIiCqOQacaEgGmTdNcHzUKaNTItPUQERGZKwadaig6Gjh6VHO8nI8/NnU1RERE5otBp5opujVn7Figbl3T1kNERGTOGHSqmd27gZMnAQcHzc7IREREVHkMOtWIiOa4OQAQHg54eJi2HiIiInPHoFON7NgBnDsHODkBEyeauhoyBRV42nIiIkNi0Kkm8vP/2pozbhzg7m7ScoiIiBSBQaea2LYNuHgRcHUFIiJMXQ2ZmnDDDhGRQTDoVAP5+cCsWZrrH36oCTtERET0+Bh0qoGtW4G4OMDNDfjgA1NXQ0REpBwMOiZWUPDXKR4iIjQ7IhMREZFhMOiY2I4dwK+/Ai4ump+UExERkeEw6JiQCDB3rub6++9rwg4REREZDoOOCe3da4Xz54EaNbhvDhERkTEw6JjQJ5/YAQDefZfHzSEiIjIGBh2TCcDp01awt9f8pJyIiIgMj0HHZKYCAEaPBurUMXEpRERECsWgYxJdAXSHjY1gwgRT10JERKRcDDomodmaExqai7p1TVwKVR/5+bAsKAAAqM6f1xwym4iIHguDThU7dcoCQCAANcaNyzF1OVRdbN8Oy2bN4JCXBwCwnPAR0LAhsH27aesiIjJz1SLorFq1Cg0bNoSdnR06duyIkydPmroko/HzKwAwEcBS+PgUmLocqg62bwf+9jfgzh3d6XfuaKYz7BARVZqVqQvYunUrIiIisGbNGnTs2BHLli1DUFAQ4uLiUKcCe+lmZGTA0tLSiJUahoVFBoBFAICMjFBYW1ubtiAjUKvVyM7ORkZGhiL7AwzYY34+7N9/HyoRqB6dJwJRqSAffICsgACgCl/fSl+HSu8PUH6P7M/8ZWRkVM0DiYl16NBBwsLCtLfz8/PF29tbIiMjix2fnZ0tKSkp2sutW7cEAC+8mOWlOyBS5NIEcQKIHEFnnendq0GtvPDCCy/GuKSkpBg1Z5j0q6vc3FycOXMGAQEB2mkWFhYICAhAbGxssfeJjIyEi4uL9lK/fv2qKpfI4LwMPI6IiHSZ9KurP/74A/n5+fDw8NCZ7uHhgcuXLxd7nylTpiAiIkJ7OzU1FfXr18eNGzfg7Oxs1HoNISMjA/Xq1QMAxMfHw9XV1bQFGYFarcb+/fvRq1cvxW5yNVSPVkePAi+/rL09FqvxB2qhHm7rjPvHt99idZculX6cilL6OlR6f4Dye2R/5u/hw4do3Lix0R/H5PvoVJStrS1sbW31pru6uppF0Cn6gnV1dVVs0LGzs4Orq6ti36AG6/GFF4B69TQ7HotgPJbpzlepgHr1UOOFF6p8Hx0lr0Ol9wcov0f2Z/7yq+gQGib96qpWrVqwtLREYmKizvTExER4enqaqCqiKmRpCSxfrrmuemR35MLby5ZVacghIlISkwYdGxsbtG3bFjExMdppBQUFiImJgb+/vwkrI6pCAwcC//439I4eWa+eZvrAgaapi4hIAUz+1VVERASGDRuGdu3aoUOHDli2bBkyMjLw1ltvmbo0oqozcCAQHAwcOQLcuwd4eQFdu3JLDhHRYzJ50Hnttdfw4MEDTJ8+HQkJCXjuueewZ88evR2UiRTP0hLo0cPUVRARKYrJgw4AhIeHIzw83NRlEBERkcJUi1NAEBERERkDgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpllGCzvXr1zFy5Ej4+vrC3t4ejRs3xowZM5Cbm6sz7ueff0bXrl1hZ2eH+vXrY+HChcYoh4iIiJ5QVsZY6OXLl1FQUIC1a9fiqaeewi+//IJRo0YhIyMDixcvBgCkpqYiMDAQAQEBWLNmDS5cuIARI0bA1dUVo0ePNkZZRERE9IQxStDp27cv+vbtq73dqFEjxMXFYfXq1dqgs2nTJuTm5mL9+vWwsbFB8+bNcf78eSxZsoRBh4iIiAzCKEGnOCkpKXBzc9Pejo2NRbdu3WBjY6OdFhQUhKioKPz555+oWbNmscvJyclBTk6OznIB4OHDh1Cr1Uaq3nAyMjK01x8+fIj8/HwTVmMcarUamZmZSEpKgrW1tanLMQql98j+zJ/Se2R/5u/hw4cAABEx6uNUSdC5evUqVq5cqd2aAwAJCQnw9fXVGefh4aGdV1LQiYyMxKxZs/SmP7osc9C4cWNTl0BERGRSSUlJcHFxMdryKxR0Jk+ejKioqFLHXLp0CX5+ftrbd+7cQd++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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "xlo = -2\n", + "xhi = 20\n", + "ylo = -20\n", + "yhi = 120\n", + "\n", + "wall_height = randint(2, yhi-20)\n", + "wall_distance = randint(2, xhi-2)\n", + "\n", + "plt.clf()\n", + "fix = plt.subplot()\n", + "plt.axis([xlo, xhi, ylo, yhi])\n", + "plt.plot([0, 0], [ylo, yhi], \"black\")\n", + "plt.plot([xlo, xhi], [0, 0], \"black\")\n", + "plt.plot([wall_distance, wall_distance], [0, wall_height], \"brown\")\n", + "plt.grid()\n", + "display.display(plt.gcf())\n", + "\n", + "print(\"You're at origin, provide A, B and C values for projectile to get across wall.\")\n", + "a = float(input(\"A: \"))\n", + "b = float(input(\"B: \"))\n", + "c = float(input(\"C: \"))\n", + "\n", + "x = np.linspace(0, xhi, xhi*1000)\n", + "y = a*x**2 + b*x + c\n", + "success = a*wall_distance**2 + b*wall_distance + c > wall_height\n", + "x2 = []\n", + "y2 = []\n", + "for i in range(len(y)):\n", + " if y[i] < 0:\n", + " break\n", + " if not success and x[i] > wall_distance:\n", + " break\n", + " x2.append(x[i])\n", + " y2.append(y[i])\n", + "\n", + "if success:\n", + " plt.title(f\"Awesome, {a:.1f}*x**2 + {b:.1f}*x + {c:.1f} worked!\")\n", + "else:\n", + " plt.title(f\"Oops, {a:.1f}*x**2 + {b:.1f}*x + {c:.1f} did not work :(\")\n", + " y2[-1] = 0 # ball hits the ground after hitting wall\n", + "\n", + "plt.plot([x2[-1]], [y2[-1]], 'ro')\n", + "plt.plot(x2, y2, \"b\")\n", + "display.clear_output(wait=True)\n", + "plt.show()\n" + ] + }, + { + "cell_type": "markdown", + "id": "5ef5840e-9c5a-41b0-8f79-2588f6915f78", + "metadata": {}, + "source": [ + "# Algebra practice game " + ] + }, + { + "cell_type": "code", + "execution_count": 144, + "id": "56df3e31-3cfe-47b8-bde5-2096cff8d941", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Solve for x in following equation:\n", + "34 - x / 18 = -49\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "answer: 1494\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pretty accurate!\n" + ] + } + ], + "source": [ + "def rn(): # random integer\n", + " return randint(-100, 100)\n", + "\n", + "def rop(): # random operation\n", + " op = randint(1, 4)\n", + " if op == 1:\n", + " return '+'\n", + " elif op == 2:\n", + " return '-'\n", + " elif op == 3:\n", + " return '*'\n", + " elif op == 4:\n", + " return '/'\n", + "\n", + "def rpm(): # random plus minus\n", + " if randint(0, 1):\n", + " return '-'\n", + " return ''\n", + "\n", + "x = symbols(\"x\")\n", + "\n", + "eq = \"\"\n", + "if randint(0, 1): # one step problem\n", + " eq = f\"x {rop()} {rn()} = {rn()}\"\n", + "else:\n", + " eq = f\"{rn()} {rop()} {rpm()}x {rop()} {rn()} = {rn()}\"\n", + "eq = eq.replace('- -', '+ ').replace('+ -', '- ').replace('- +=', '- ')\n", + "lhs, rhs = [parse_expr(part) for part in eq.split(' = ')]\n", + "sympy_eq = Eq(lhs, rhs)\n", + "\n", + "solution = round(solve(sympy_eq, x)[0], 2)\n", + "\n", + "print(\"Solve for x in following equation:\")\n", + "print(eq)\n", + "ans = [float(num) for num in input(\"answer: \").split('/')]\n", + "if len(ans) == 2:\n", + " ans = ans[0]/ans[1]\n", + "else:\n", + " ans = ans[0]\n", + "\n", + "if abs(ans-solution) < 0.01:\n", + " print(\"Pretty accurate!\")\n", + "else:\n", + " print(f\"Oops! correct answer was {solution} but your answer was {ans}\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "4354b487-229b-40b3-92e9-74610bc74030", + "metadata": {}, + "source": [ + "# Scatter Plot Game " + ] + }, + { + "cell_type": "code", + "execution_count": 146, + "id": "4dac8ed5-b7dd-42d5-a4ed-e51af3324867", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "Guess the location of point (x, y) on graph: -28, 22\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Sorry, the correct answer was (-25, 24) but you provided (-28, 22)\n" + ] + } + ], + "source": [ + "plt.clf()\n", + "xlo = -50\n", + "xhi = 50\n", + "ylo = -50\n", + "yhi = 50\n", + "\n", + "x = randint(xlo, xhi)\n", + "y = randint(ylo, yhi)\n", + "\n", + "fig = plt.subplot()\n", + "plt.axis([xlo, xhi, ylo, yhi])\n", + "plt.plot([x], [y], 'ro')\n", + "plt.show()\n", + "\n", + "gussed_x, gussed_y = [int(round(float(num.strip(' ')), 0)) for num in input(\"Guess the location of point (x, y) on graph: \").split(', ')]\n", + "\n", + "if gussed_x == x and gussed_y == y:\n", + " print(\"You got it!\")\n", + "else:\n", + " print(f\"Sorry, the correct answer was ({x}, {y}) but you provided ({gussed_x}, {gussed_y})\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8d9745ef-fe26-477f-a480-e146542b04c1", + "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.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/hree Math Games.md b/hree Math Games.md new file mode 100644 index 0000000..079d6d5 --- /dev/null +++ b/hree Math Games.md @@ -0,0 +1,231 @@ +```python +%matplotlib inline +import matplotlib.pyplot as plt +import numpy as np +from ipywidgets import interactive, fixed +from IPython import display +from random import randint +from time import sleep +from sympy import symbols, Eq +from sympy.solvers import solve +from sympy.parsing.sympy_parser import parse_expr +``` + +# Projectile game + +## Easy Mode + + +```python +xlo = -2 +xhi = 20 +ylo = -20 +yhi = 120 + +def graph(a, b, c, height, distance): + plt.clf() + fix = plt.subplot() + plt.axis([xlo, xhi, ylo, yhi]) + plt.plot([0, 0], [ylo, yhi], "black") + plt.plot([xlo, xhi], [0, 0], "black") + wall_height = height + wall_distance = distance + plt.plot([wall_distance, wall_distance], [0, wall_height], "brown") + plt.grid() + plt.title(f"{a:.1f}*x**2 + {b:.1f}*x + {c:.1f}") + + x = np.linspace(0, xhi, xhi*1000) + y = a*x**2 + b*x + c + success = a*wall_distance**2 + b*wall_distance + c > wall_height + x2 = [] + y2 = [] + for i in range(len(y)): + if y[i] < 0: + break + if not success and x[i] > wall_distance: + break + x2.append(x[i]) + y2.append(y[i]) + + y2[-1] = 0 # finally ball hits the ground (handling imprecisions and ball hitting walls) + plt.plot([x2[-1]], [y2[-1]], 'ro') + plt.plot(x2, y2, "b") + plt.show() + + +slider_range = (-25, 25, 0.1) +wall_height = randint(2, yhi-20) +wall_distance = randint(2, xhi-2) +interactive_graph = interactive(graph, a=slider_range, b=slider_range, c=slider_range, height=fixed(wall_height), distance=fixed(wall_distance)) +interactive_graph +``` + + + + + interactive(children=(FloatSlider(value=0.0, description='a', max=25.0, min=-25.0), FloatSlider(value=0.0, des… + + + +## Hard Mode +Now guess projectile paramaters without fiddloing with slider + + +```python +xlo = -2 +xhi = 20 +ylo = -20 +yhi = 120 + +wall_height = randint(2, yhi-20) +wall_distance = randint(2, xhi-2) + +plt.clf() +fix = plt.subplot() +plt.axis([xlo, xhi, ylo, yhi]) +plt.plot([0, 0], [ylo, yhi], "black") +plt.plot([xlo, xhi], [0, 0], "black") +plt.plot([wall_distance, wall_distance], [0, wall_height], "brown") +plt.grid() +display.display(plt.gcf()) + +print("You're at origin, provide A, B and C values for projectile to get across wall.") +a = float(input("A: ")) +b = float(input("B: ")) +c = float(input("C: ")) + +x = np.linspace(0, xhi, xhi*1000) +y = a*x**2 + b*x + c +success = a*wall_distance**2 + b*wall_distance + c > wall_height +x2 = [] +y2 = [] +for i in range(len(y)): + if y[i] < 0: + break + if not success and x[i] > wall_distance: + break + x2.append(x[i]) + y2.append(y[i]) + +if success: + plt.title(f"Awesome, {a:.1f}*x**2 + {b:.1f}*x + {c:.1f} worked!") +else: + plt.title(f"Oops, {a:.1f}*x**2 + {b:.1f}*x + {c:.1f} did not work :(") + y2[-1] = 0 # ball hits the ground after hitting wall + +plt.plot([x2[-1]], [y2[-1]], 'ro') +plt.plot(x2, y2, "b") +display.clear_output(wait=True) +plt.show() + +``` + + + +![png](output_5_0.png) + + + +# Algebra practice game + + +```python +def rn(): # random integer + return randint(-100, 100) + +def rop(): # random operation + op = randint(1, 4) + if op == 1: + return '+' + elif op == 2: + return '-' + elif op == 3: + return '*' + elif op == 4: + return '/' + +def rpm(): # random plus minus + if randint(0, 1): + return '-' + return '' + +x = symbols("x") + +eq = "" +if randint(0, 1): # one step problem + eq = f"x {rop()} {rn()} = {rn()}" +else: + eq = f"{rn()} {rop()} {rpm()}x {rop()} {rn()} = {rn()}" +eq = eq.replace('- -', '+ ').replace('+ -', '- ').replace('- +=', '- ') +lhs, rhs = [parse_expr(part) for part in eq.split(' = ')] +sympy_eq = Eq(lhs, rhs) + +solution = round(solve(sympy_eq, x)[0], 2) + +print("Solve for x in following equation:") +print(eq) +ans = [float(num) for num in input("answer: ").split('/')] +if len(ans) == 2: + ans = ans[0]/ans[1] +else: + ans = ans[0] + +if abs(ans-solution) < 0.01: + print("Pretty accurate!") +else: + print(f"Oops! correct answer was {solution} but your answer was {ans}") + +``` + + Solve for x in following equation: + 34 - x / 18 = -49 + + + answer: 1494 + + + Pretty accurate! + + +# Scatter Plot Game + + +```python +plt.clf() +xlo = -50 +xhi = 50 +ylo = -50 +yhi = 50 + +x = randint(xlo, xhi) +y = randint(ylo, yhi) + +fig = plt.subplot() +plt.axis([xlo, xhi, ylo, yhi]) +plt.plot([x], [y], 'ro') +plt.show() + +gussed_x, gussed_y = [int(round(float(num.strip(' ')), 0)) for num in input("Guess the location of point (x, y) on graph: ").split(', ')] + +if gussed_x == x and gussed_y == y: + print("You got it!") +else: + print(f"Sorry, the correct answer was ({x}, {y}) but you provided ({gussed_x}, {gussed_y})") +``` + + + +![png](output_9_0.png) + + + + Guess the location of point (x, y) on graph: -28, 22 + + + Sorry, the correct answer was (-25, 24) but you provided (-28, 22) + + + +```python + +``` diff --git a/output_5_0.png b/output_5_0.png new file mode 100644 index 0000000..69679ad Binary files /dev/null and b/output_5_0.png differ diff --git a/output_9_0.png b/output_9_0.png new file mode 100644 index 0000000..48ff6db Binary files /dev/null and b/output_9_0.png differ