Add files via upload
This commit is contained in:
1 parent
9192250eff
commit
96aae11e86
2 files changed
+808
No files matched your search
@@ -0,0 +1,331 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"<div align=\"right\" style=\"text-align: right\"><i>Peter Norvig<br>Aug 2019</i></div>\n",
|
||||||
|
"\n",
|
||||||
|
"# Photography Focal Length Charts\n",
|
||||||
|
"\n",
|
||||||
|
"Photographers with interchangable-lens cameras often obsess about which lenses they use. This is especially true when planning a trip, and trying to balance how much to pack versus what might be needed. One big factor is the **focal lengths** to be covered. This notebook will help understand what range of focal lengths was used in a collection of photos, to help you plan the next trip. Charts from this notebook appear in my [Galapagos Photography Trip Report](https://norvig.com/galapagos-photography.html).\n",
|
||||||
|
"\n",
|
||||||
|
"<p><a href=\"https://www.the-digital-picture.com/Photography-Tips/packing-for-landscape-photography-trip.aspx\"><img src=\"https://media.the-digital-picture.com/Images/Other/Lowepro-Photo-Trekker-AW-II-Backpack-Loaded.jpg\" width=\"300\"></a>\n",
|
||||||
|
"\n",
|
||||||
|
"# Preparing the Focal Length Data\n",
|
||||||
|
"\n",
|
||||||
|
"In your photo editing system, export (or copy down manually) a table of focal lengths of photos. (I did it only for my **best** photos.) Arrange the data in the following Python format:\n",
|
||||||
|
"\n",
|
||||||
|
" {trip_name: {\n",
|
||||||
|
" lens_name: [focal_length, ...]}}\n",
|
||||||
|
" \n",
|
||||||
|
"For example:\n",
|
||||||
|
" \n",
|
||||||
|
" {2008: {\n",
|
||||||
|
" '100-400': [100, 100, 100, 115, 130, ... 400, 400, 400, 400, 400, 400]}}\n",
|
||||||
|
" \n",
|
||||||
|
"For each of my photos I considered two variations of focal length:\n",
|
||||||
|
"1. The actual focal length setting of the lens when the photo was taken (as recorded in the EXIF data).\n",
|
||||||
|
"2. The [35mm equivalent focal length](https://en.wikipedia.org/wiki/35_mm_equivalent_focal_length), taking account both the crop factor of the sensor (if any), and any cropping done in photo editing. For example, if the focal length of the lens/photo was 200mm, but I was using a camera with a 1.5x crop, and then I further cropped the image down to half the size in both width and height, then the equivalent focal length would be 200mm x 1.5 x 2 = 600mm. \n",
|
||||||
|
"\n",
|
||||||
|
"I collected these two data sets at different times, and over time my definition of **best** changed, so they are not for the exact same photos.\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 1,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"actual = { # Actual focal lengths \n",
|
||||||
|
" 2008: {\n",
|
||||||
|
" '17-40': (*[17]*9, *[40]*5),\n",
|
||||||
|
" '24-105': (24, 24, 105),\n",
|
||||||
|
" '100-400': (*[100]*3, 115, 130, 135, *[150]*3, 210, 220, 260, 300, 330, \n",
|
||||||
|
" 350, 350, 360, 365, 365, 380, 380, *[400]*36)},\n",
|
||||||
|
" 2014: {\n",
|
||||||
|
" '16-35': (*[16]*7, 17, 26, *[35]*4),\n",
|
||||||
|
" '24-70': (*[24]*3, 28, 28, 45, 47, 58, *[70]*3),\n",
|
||||||
|
" '70-300': (70, 70, 116, 170, 170, 176, 200, 221, 244, 260, 277, 277, *[300]*24),\n",
|
||||||
|
" '150-600': (150, 165, 173, 200, 250, 256, 300, 309, 309, 309, 309, 329, 350, \n",
|
||||||
|
" 350, 350, 400, 400, 428, 450, 483, 483, 483, 483, 483, 483, \n",
|
||||||
|
" 500, 500, 500, 500, 500, 552, 552, *[600]*25)},\n",
|
||||||
|
" 2019: {\n",
|
||||||
|
" '16-35': (*[35]*5, *[16]*3, 23, 24),\n",
|
||||||
|
" '70-200': (*[200]*9, *[280]*5, 168, 170, 142, 168, 185, *[180]*5, 105, 190, 145, 155),\n",
|
||||||
|
" '100-400': (*[400]*28, 278, 286, 300, 286, 371, 300, 300, 300, 349, 330, 371, 200, 164, \n",
|
||||||
|
" 349, 397, 100),\n",
|
||||||
|
" '400': (*[400]*6, 560, *[800]*3)}}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 2,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"(150, 165, 173, 200, 250, 256, 300, 309, 309, 309, 309, 329, 350, 350, 350, 400, 400, 428, 450, 483, 483, 483, 483, 483, 483, 500, 500, 500, 500, 500, 552, 552)\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"print(tuple(sorted((150, 150, 165, 173, 173, 182, 200, 250, 250, 256, 256, 300, 300, \n",
|
||||||
|
" *[309]*9, 329, 329, *[350]*5, 375, *[400]*4, 428, 428, 450, 450, \n",
|
||||||
|
" *[483]*11, *[500]*11, *[552]*4))[0::2]))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 3,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"equiv = { # 35mm equivalent focal lengths (after cropping)\n",
|
||||||
|
" 2008: {\n",
|
||||||
|
" '17-40': (75, 55, 27, 62, 17, 17, 17, 17, 17, 24, 17, 17, 17, 17),\n",
|
||||||
|
" '24-105': (58, 105, 116),\n",
|
||||||
|
" '100-400': (668, 400, 766, 549, 509, 130, 150, 548, 428, 588, 405, 247, 656, 858,\n",
|
||||||
|
" 400, 159, 559, 398, 295, 427, 513, 554, 694, 317, 666, 562, 507, 491,\n",
|
||||||
|
" 552, 861, 528, 252, 304, 100, 554, 400, 248, 400, 545, 542, 145, 533,\n",
|
||||||
|
" 234, 538, 577, 667, 648, 400, 188, 407, 400, 400, 400, 400, 400, 400, 200)},\n",
|
||||||
|
" 2014: {\n",
|
||||||
|
" '16-35': (16, 26, 24, 45, 36, 25, 16, 35, 18, 16, 47, 16),\n",
|
||||||
|
" '24-70': (24, 47, 49, 24),\n",
|
||||||
|
" '70-300': (262, 270, 208, 1037, 675, 425, 382, 738, 428, 673, 70, 309, 215, 416,\n",
|
||||||
|
" 221, 503, 462, 300, 551, 512, 471, 296, 423, 947, 758, 232, 373, 476,\n",
|
||||||
|
" 656, 532, 664, 1004, 664, 537, 439),\n",
|
||||||
|
" '150-600': (1406, 331, 254, 552, 393, 758, 934, 725, 935, 875, 727, 991, 751, 949,\n",
|
||||||
|
" 804, 1172, 1304, 1037, 197, 472, 422, 468, 413, 892, 797, 965, 1191,\n",
|
||||||
|
" 1061, 885, 167, 395, 1059, 946, 868, 1227, 453, 444, 592, 1468, 372,\n",
|
||||||
|
" 1469, 970, 240, 1103, 689, 592)},\n",
|
||||||
|
" 2019: {\n",
|
||||||
|
" '16-35': (35, 26, 35, 35, 34, 16, 24, 16, 16),\n",
|
||||||
|
" '70-200': (200, 200, 168, 170, 142, 207, 475, 168, 185, 180, 141, 280, 280, 385,\n",
|
||||||
|
" 425, 254, 358, 262, 200, 190, 206, 187, 221, 212, 336, 242, 209, 477),\n",
|
||||||
|
" '100-400': (438, 724, 583, 703, 278, 300, 286, 286, 400, 431, 371, 335, 481, 400, 400,\n",
|
||||||
|
" 621, 525, 308, 400, 406, 427, 371, 606, 400, 400, 261, 476, 188, 588, 397),\n",
|
||||||
|
" '400': (1414, 1381, 800, 836, 668, 491, 668, 491, 400, 400)}}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Plotting Histograms\n",
|
||||||
|
"\n",
|
||||||
|
"I want to see the range of shots made with each lens, and I also want to see the overall number and range of shots. So I got the idea to make a plot where every shot gets a hashmark, where the x-axis of the hashmark is the focal length, and the y-axis is the cumulative number of shots for that lens, sorted in ascending focal-length order. In other words, a kind of cumulative step histogram. This would get messy if the lenses overlapped in focal length a lot, but for me they didn't. The function `shot_plots` does this. "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 4,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%matplotlib inline\n",
|
||||||
|
"import matplotlib.pyplot as plt\n",
|
||||||
|
"\n",
|
||||||
|
"def shot_plots(table, label='35mm equivalent', hidden=None):\n",
|
||||||
|
" \"\"\"Display and save to a file a chart of focal lengths.\"\"\"\n",
|
||||||
|
" for name, trip in table.items():\n",
|
||||||
|
" filename = f'shots-{name}-{label[:2]}.png'.lower()\n",
|
||||||
|
" N = sum(len(trip[lens]) for lens in trip)\n",
|
||||||
|
" plt.figure(figsize=(6.5, 4.5))\n",
|
||||||
|
" plt.rcParams.update({'font.size': 12})\n",
|
||||||
|
" plt.xlabel(f'Focal length ({label})')\n",
|
||||||
|
" plt.ylabel('Cumulative number of shots')\n",
|
||||||
|
" plt.title(f'{name} Best {N} shots ({label} focal length)')\n",
|
||||||
|
" plt.grid(b=True, which='major', color='grey', linestyle=':')\n",
|
||||||
|
" if hidden: plt.plot(*hidden, color='white', alpha=0)\n",
|
||||||
|
" for lens, mark in zip(trip, '_x.+'*9):\n",
|
||||||
|
" X = sorted(trip[lens])\n",
|
||||||
|
" Y = range(1, len(X) + 1)\n",
|
||||||
|
" plt.plot(X, Y, '_', ms=9, mew=1.5, label=lens + f'mm: {len(X)}', marker=mark)\n",
|
||||||
|
" plt.legend(loc=2, fontsize='small')\n",
|
||||||
|
" plt.savefig(filename)\n",
|
||||||
|
" plt.show()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Actual Focal Length Plots\n",
|
||||||
|
"\n",
|
||||||
|
"The actual lens focal length data. This makes it clear how often I was at the very far end of my 400mm, 300mm, and 600mm zooms:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 5,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"image/png": "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 truncated
|
||||||
|
"text/plain": [
|
||||||
|
"<Figure size 468x324 with 1 Axes>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"needs_background": "light"
|
||||||
|
},
|
||||||
|
"output_type": "display_data"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"image/png": "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 truncated
|
||||||
|
"text/plain": [
|
||||||
|
"<Figure size 468x324 with 1 Axes>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"needs_background": "light"
|
||||||
|
},
|
||||||
|
"output_type": "display_data"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"image/png": "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 truncated
|
||||||
|
"text/plain": [
|
||||||
|
"<Figure size 468x324 with 1 Axes>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"needs_background": "light"
|
||||||
|
},
|
||||||
|
"output_type": "display_data"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"shot_plots(actual, label='actual', hidden=([800], [60]))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# 35mm Equivalent Focal Length Plots"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 6,
|
||||||
|
"metadata": {
|
||||||
|
"scrolled": false
|
||||||
|
},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"image/png": "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 truncated
|
||||||
|
"text/plain": [
|
||||||
|
"<Figure size 468x324 with 1 Axes>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"needs_background": "light"
|
||||||
|
},
|
||||||
|
"output_type": "display_data"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"image/png": "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 truncated
|
||||||
|
"text/plain": [
|
||||||
|
"<Figure size 468x324 with 1 Axes>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"needs_background": "light"
|
||||||
|
},
|
||||||
|
"output_type": "display_data"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"image/png": "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 truncated
|
||||||
|
"text/plain": [
|
||||||
|
"<Figure size 468x324 with 1 Axes>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"needs_background": "light"
|
||||||
|
},
|
||||||
|
"output_type": "display_data"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"shot_plots(equiv, hidden=([1400], [60]))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Totals (Actual and Equivalent)\n",
|
||||||
|
"\n",
|
||||||
|
"Here I aggregate all the shots (all lens and all trips) together. Again, the two data sets (actual and equivalent) were collected at different times with different definitions of **best** photos, so they have different totals."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 7,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"image/png": "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 truncated
|
||||||
|
"text/plain": [
|
||||||
|
"<Figure size 468x324 with 1 Axes>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"needs_background": "light"
|
||||||
|
},
|
||||||
|
"output_type": "display_data"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"image/png": "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 truncated
|
||||||
|
"text/plain": [
|
||||||
|
"<Figure size 468x324 with 1 Axes>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"needs_background": "light"
|
||||||
|
},
|
||||||
|
"output_type": "display_data"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"def all_shots(table): return [m for y in table for lens in table[y] \n",
|
||||||
|
" for m in table[y][lens]]\n",
|
||||||
|
"\n",
|
||||||
|
"shot_plots({'All': {'actual ': all_shots(actual)}}, 'actual') \n",
|
||||||
|
"shot_plots({'All': {'equiv ': all_shots(equiv)}})"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 2
|
||||||
|
}
|
||||||
@@ -0,0 +1,477 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"<div align=\"right\" style=\"text-align: right\"><i>Peter Norvig<br>Aug 2018</i></div>\n",
|
||||||
|
"\n",
|
||||||
|
"# Tour de 538\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"You are the coach for a bicycle racing team, one of 20 teams entered in the [Tour de FiveThirtyEight](https://fivethirtyeight.com/features/can-you-win-the-tour-de-fivethirtyeight/) time trial, which has these rules:\n",
|
||||||
|
"\n",
|
||||||
|
">*Each team rides as a group throughout the course at some fixed pace, specified by that team’s coach. Teams that can’t maintain their pace are said to have **cracked,** and don’t **finish** the course.\n",
|
||||||
|
"The team that finishes the course with the fastest pace is the winner.\n",
|
||||||
|
"Teams ride the course one at a time. After each team completes its attempt, the next team quickly consults with its coach (who assigns a pace) and then begins its ride. Coaches are aware of the results of all previous teams when choosing their own team’s pace.\n",
|
||||||
|
"Assume that all teams are of equal ability: At any given pace, they have the exact same probability of cracking, and the faster the pace, the greater the probability of cracking. Teams’ chances of cracking are independent, and each team’s coach knows exactly what a team’s chances of cracking are for each pace. You are the first team to attempt the course. To maximize your chances of winning, what’s the probability that your team will finish the course? What’s the probability you’ll ultimately win? How about the other teams?*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 1,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# PRELIMINARIES\n",
|
||||||
|
"%matplotlib inline\n",
|
||||||
|
"import matplotlib.pyplot as plt\n",
|
||||||
|
"import random\n",
|
||||||
|
"from functools import lru_cache\n",
|
||||||
|
"from collections import Counter"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Analysis\n",
|
||||||
|
"\n",
|
||||||
|
"At first it might seem like we don't have enough information: we don't know the relation between probability of finishing and the actual pace/speed. But after a little thought, it is clear we don't need to know how fast each team goes. Probability of finishing may not be related linearly to speed, but whatever the function that relates probability of finishing to speed, it is **monotonic**: the the faster the pace, the lower the probability of finishing. Thus, the team that chooses the lowest probability and actually finishes will be the winner (even if we don't know their speed/time).\n",
|
||||||
|
"\n",
|
||||||
|
"Let's start with **a simpler case: just two teams**. The first team chooses a probability $p$ of finishing. If the first team cracks, the second team chooses probability 1 of finishing, rides the race at a nice leisurly pace, and wins. If the first team finishes, the second team chooses probability $p - 𝜖$ of finishing, where 𝜖 is an arbitrarily small number; that gives them an ever-so-slightly-faster pace than the first team. But let's just write $p$ instead of $p - 𝜖$, with the understanding that the $𝜖$ is so small that it doesn't matter for our calculations—another way of saying this is that a tie goes to the team that goes later. So the first team wins if they finish and the second team doesn't, and since \"chances of cracking are independent,\" that joint event has probabilty $p (1 - p)$. What pace $p$ maximizes that? I'm going to enumerate 1001 different $p$ values and find the one that maximizes $p (1 - p)$:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 2,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"0.5"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 2,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"probabilities = [x/1000 for x in range(1001)] # [0.000, 0.001, 0.002, ... 1.000]\n",
|
||||||
|
"\n",
|
||||||
|
"max(probabilities, key=lambda p: p * (1 - p))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"That says the first team's best choice is a pace that gives them a probability 0.5 of finishing. They win the race with probability 0.5 × (1 - 0.5) = 0.25; the second team wins with probability 0.75. There is value in the information gained by going second! \n",
|
||||||
|
"\n",
|
||||||
|
"Now for **the case of $n$ teams**. The first team wins if they finish (with probability $p$), and if *all* the other teams crack (with probability $(1 - p)^{n - 1}$, assuming they also choose pace $p$). All together, that's $p(1 - p)^{n - 1}$. Again, I can try out all the probabilities in `probabilities` and see which is the best pace for the first team, for various values of `n` teams in the race:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 3,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"{1: 1.0, 2: 0.5, 3: 0.333, 4: 0.25, 5: 0.2, 6: 0.167}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 3,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"def best_pace(n) -> float:\n",
|
||||||
|
" \"\"\"The pace p with highest probability of winning for the first of `n` teams.\"\"\"\n",
|
||||||
|
" return max(probabilities, key=lambda p: win_prob(p, n))\n",
|
||||||
|
"\n",
|
||||||
|
"def win_prob(p, n) -> float:\n",
|
||||||
|
" \"\"\"Probability of first team winning if all n teams choose pace `p`.\"\"\"\n",
|
||||||
|
" return p * (1 - p) ** (n - 1)\n",
|
||||||
|
" \n",
|
||||||
|
"{n: best_pace(n) for n in range(1, 7)}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Notice a pattern? It looks like `best_pace(n)` is $1/n$. But can we prove it? \n",
|
||||||
|
"\n",
|
||||||
|
"# Using Calculus to Find Best Pace \n",
|
||||||
|
"\n",
|
||||||
|
"Calculus says that the extrema (maximum or minimum) of a function is where the derivative is zero. What's the derivative of $p (1 - p)^{n - 1}$?\n",
|
||||||
|
"\n",
|
||||||
|
"$$\\frac{d}{dp} p (1 - p)^{n - 1} = (1 - p)^{n - 2} (1 - n p) $$\n",
|
||||||
|
"\n",
|
||||||
|
"This is indeed zero when $p = 1/n$. We can check that `best_pace(n)` agrees with `1 / n` (to within 3 decimal places):"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 4,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"for n in range(1, 21):\n",
|
||||||
|
" assert abs(best_pace(n) - 1/n) < 0.001 "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"We now know how every race will play out:\n",
|
||||||
|
"- The first of $n$ teams chooses pace $p = 1/n$.\n",
|
||||||
|
"- If they crack, it is like starting a race with $n - 1$ teams, and the next team chooses pace $1/(n - 1)$.\n",
|
||||||
|
"- If they finish, every team from then on will choose a pace that is $𝜖$ faster than the previous finisher.\n",
|
||||||
|
"- The only way for the first team to win is if every other chooses $p$ and cracks.\n",
|
||||||
|
"- This confirms that the win probability for the first team is $p(1 - p)^{n - 1}$, where $p = 1/n$.\n",
|
||||||
|
"\n",
|
||||||
|
"# Tabulating Results\n",
|
||||||
|
"\n",
|
||||||
|
"We can print a table of three columns: the number of teams $n$, the best pace for the first of $n$ teams, and the probability that the first team will win if it adopts that pace:\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 5,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
" n pace P(win)\n",
|
||||||
|
" 1 1.00000 1.00000\n",
|
||||||
|
" 2 0.50000 0.25000\n",
|
||||||
|
" 3 0.33333 0.14815\n",
|
||||||
|
" 4 0.25000 0.10547\n",
|
||||||
|
" 5 0.20000 0.08192\n",
|
||||||
|
" 6 0.16667 0.06698\n",
|
||||||
|
" 7 0.14286 0.05665\n",
|
||||||
|
" 8 0.12500 0.04909\n",
|
||||||
|
" 9 0.11111 0.04330\n",
|
||||||
|
"10 0.10000 0.03874\n",
|
||||||
|
"11 0.09091 0.03505\n",
|
||||||
|
"12 0.08333 0.03200\n",
|
||||||
|
"13 0.07692 0.02944\n",
|
||||||
|
"14 0.07143 0.02726\n",
|
||||||
|
"15 0.06667 0.02538\n",
|
||||||
|
"16 0.06250 0.02374\n",
|
||||||
|
"17 0.05882 0.02230\n",
|
||||||
|
"18 0.05556 0.02102\n",
|
||||||
|
"19 0.05263 0.01989\n",
|
||||||
|
"20 0.05000 0.01887\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"print(' n pace P(win)')\n",
|
||||||
|
"for n in range(1, 21):\n",
|
||||||
|
" print(f'{n:2d} {1 / n:0.5f} {win_prob(1 / n, n):0.5f}')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Visualizing Results\n",
|
||||||
|
"\n",
|
||||||
|
"Here is a plot for various numbers of teams of the probability of the first team winning, as a function of the pace that the first team chooses. Each curve is for a different number of teams participating in the race (as shown by the label number)."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 6,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"image/png": "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 truncated
|
||||||
|
"text/plain": [
|
||||||
|
"<Figure size 432x288 with 1 Axes>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"needs_background": "light"
|
||||||
|
},
|
||||||
|
"output_type": "display_data"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"def annotate(x, y, text):\n",
|
||||||
|
" plt.text(x - 0.04, y - 0.014, text)\n",
|
||||||
|
" plt.plot([x], [y], 'kx')\n",
|
||||||
|
" \n",
|
||||||
|
"for n in [2, 3, 4, 5, 7, 10, 20]:\n",
|
||||||
|
" plt.plot(probabilities, [win_prob(p, n) for p in probabilities])\n",
|
||||||
|
" annotate(1 / n, win_prob(1 / n, n), f'n={n}')\n",
|
||||||
|
"plt.xlabel('First team pace, denoted by P(finish)')\n",
|
||||||
|
"plt.ylabel('P(first team wins)')\n",
|
||||||
|
"plt.grid(True);"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Calculation of Win Probability for All Teams\n",
|
||||||
|
"\n",
|
||||||
|
"What is the full probability distribution of winners over all the teams? I'll define `winners(teams)` to answer the question, where `teams` is a tuple of teams, such as `(1, 2, 3, 4)`. Here's how it works:\n",
|
||||||
|
"- `winners(teams)` gives the probability of winning the race for each team. The result is a `Dist`, a probability distribution of `{team: probability}` pairs. For example, we want `winners((1, 2))` to return `Dist({1: 0.25, 2: 0.75})`.\n",
|
||||||
|
"- A recursive call to `winners(teams, leader, leader_pace)` means that `teams` is the collection of teams who have not raced yet, `leader` is the fastest finishing team among those who have already raced, and `leader_pace` is the pace that the leader rode.\n",
|
||||||
|
"- If there are no `teams` remaining to race, then the winner (with probability 1) is the `leader` so far.\n",
|
||||||
|
"- If there are $n$ teams left to race, then the next team up will choose a pace $p$ that is the faster of $1/n$ and the current leader's pace. \n",
|
||||||
|
"- There are two possible cases to consider:\n",
|
||||||
|
" - That `team` finishes, with probability `p`, and becomes the new leader. The probability distribution in this case is computed by a recursive call `winners(other_teams, team, p)`.\n",
|
||||||
|
" - That `team` cracks, with probability `1 - p`, and the leader is unchanged. The probability distribution in this case is computed by a recursive call `winners(other_teams, leader, leader_pace)`.\n",
|
||||||
|
"- We combine the two cases, weighted by their probability.\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 7,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"class Dist(Counter):\n",
|
||||||
|
" \"\"\"A {outcome: frequency} distribution. Can multiply values by a constant.\"\"\"\n",
|
||||||
|
" def __mul__(self, c): return Dist({x: c * self[x] for x in self})\n",
|
||||||
|
" __rmul__ = __mul__\n",
|
||||||
|
" \n",
|
||||||
|
"@lru_cache(None)\n",
|
||||||
|
"def winners(teams, leader=None, leader_pace=1) -> Dist:\n",
|
||||||
|
" \"\"\"Calculate the probability of each team winning.\"\"\"\n",
|
||||||
|
" if not teams:\n",
|
||||||
|
" return Dist({leader: 1})\n",
|
||||||
|
" else:\n",
|
||||||
|
" team, other_teams = teams[0], teams[1:]\n",
|
||||||
|
" p = min(1/len(teams), leader_pace)\n",
|
||||||
|
" finish = winners(other_teams, team, p)\n",
|
||||||
|
" crack = winners(other_teams, leader, leader_pace)\n",
|
||||||
|
" return Dist(p * finish + (1 - p) * crack)\n",
|
||||||
|
" \n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 8,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"Dist({2: 0.75, 1: 0.25})"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 8,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"winners((1, 2))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Simulation of Winners\n",
|
||||||
|
"\n",
|
||||||
|
"As a check, let's do a simulation where each team chooses their `pace`, and we randomly see if they crack, and eventually see who wins the race. Repeat that for a million races and count the winners. I'll define `race` to be as similar to `winners` as possible, but to follow one of the two paths (finish or crack) at random, rather than following both."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 9,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def race(teams, leader=None, leader_pace=1):\n",
|
||||||
|
" \"Simulate a single race with given teams; return the winning team.\"\n",
|
||||||
|
" if not teams:\n",
|
||||||
|
" return leader\n",
|
||||||
|
" else:\n",
|
||||||
|
" team, other_teams = teams[0], teams[1:]\n",
|
||||||
|
" p = min(1/len(teams), leader_pace)\n",
|
||||||
|
" return (race(other_teams, team, p) if random.random() < p else\n",
|
||||||
|
" race(other_teams, leader, leader_pace))\n",
|
||||||
|
"\n",
|
||||||
|
"def races(teams, repeat=1000000):\n",
|
||||||
|
" \"Simulate `repeat` races with given teams; return a probability distribution over winners.\"\n",
|
||||||
|
" counts = Counter(race(teams) for _ in range(repeat))\n",
|
||||||
|
" return Dist({team: counts[team] / repeat for team in teams})"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 10,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"Dist({1: 0.249669, 2: 0.750331})"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 10,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"races((1, 2))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Comparison of Calculation to Simulation\n",
|
||||||
|
"\n",
|
||||||
|
"Now we can compare the theoretical calculated results with the simulated results:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 11,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
" n Calcul Simul Delta\n",
|
||||||
|
" 1 0.0189 0.0192 -0.0003\n",
|
||||||
|
" 2 0.0199 0.0200 -0.0001\n",
|
||||||
|
" 3 0.0210 0.0211 -0.0001\n",
|
||||||
|
" 4 0.0223 0.0223 +0.0000\n",
|
||||||
|
" 5 0.0237 0.0237 +0.0000\n",
|
||||||
|
" 6 0.0253 0.0253 -0.0000\n",
|
||||||
|
" 7 0.0270 0.0270 -0.0000\n",
|
||||||
|
" 8 0.0290 0.0289 +0.0001\n",
|
||||||
|
" 9 0.0313 0.0313 +0.0001\n",
|
||||||
|
" 10 0.0340 0.0340 +0.0000\n",
|
||||||
|
" 11 0.0370 0.0371 -0.0001\n",
|
||||||
|
" 12 0.0406 0.0406 -0.0001\n",
|
||||||
|
" 13 0.0448 0.0446 +0.0001\n",
|
||||||
|
" 14 0.0498 0.0499 -0.0001\n",
|
||||||
|
" 15 0.0560 0.0561 -0.0000\n",
|
||||||
|
" 16 0.0639 0.0639 +0.0000\n",
|
||||||
|
" 17 0.0742 0.0739 +0.0003\n",
|
||||||
|
" 18 0.0889 0.0889 -0.0001\n",
|
||||||
|
" 19 0.1126 0.1122 +0.0003\n",
|
||||||
|
" 20 0.1799 0.1801 -0.0003\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"image/png": "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 truncated
|
||||||
|
"text/plain": [
|
||||||
|
"<Figure size 432x288 with 1 Axes>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"needs_background": "light"
|
||||||
|
},
|
||||||
|
"output_type": "display_data"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"def compare(teams=range(1, 21)):\n",
|
||||||
|
" \"\"\"Print and plot comparison between `races` simulation and `winners` calculation.\"\"\"\n",
|
||||||
|
" wins = winners(teams)\n",
|
||||||
|
" sims = races(teams)\n",
|
||||||
|
" print(f' n Calcul Simul Delta')\n",
|
||||||
|
" for team in teams:\n",
|
||||||
|
" print(f'{team:3d} {wins[team]:.4f} {sims[team]:.4f} {wins[team]-sims[team]:+.4f}')\n",
|
||||||
|
" plt.plot(teams, [wins[i] for i in teams], 'rx', label='calculation', ms=10, mew=2)\n",
|
||||||
|
" plt.plot(teams, [sims[i] for i in teams], 'b+', label='simulation', ms=10, mew=2)\n",
|
||||||
|
" plt.xticks(ticks=teams); plt.grid(True);\n",
|
||||||
|
" plt.xlabel('Team Number'); plt.ylabel('P(win)'); plt.legend()\n",
|
||||||
|
"\n",
|
||||||
|
"compare()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"We see there is excellent agreement The `×` and `+` markers are all on top of each other. The agreement extends to a different number of teams:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 12,
|
||||||
|
"metadata": {
|
||||||
|
"scrolled": false
|
||||||
|
},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
" n Calcul Simul Delta\n",
|
||||||
|
" 1 0.0387 0.0387 +0.0001\n",
|
||||||
|
" 2 0.0433 0.0434 -0.0001\n",
|
||||||
|
" 3 0.0489 0.0489 -0.0000\n",
|
||||||
|
" 4 0.0561 0.0554 +0.0007\n",
|
||||||
|
" 5 0.0653 0.0657 -0.0004\n",
|
||||||
|
" 6 0.0775 0.0769 +0.0006\n",
|
||||||
|
" 7 0.0945 0.0948 -0.0003\n",
|
||||||
|
" 8 0.1198 0.1198 +0.0001\n",
|
||||||
|
" 9 0.1629 0.1633 -0.0004\n",
|
||||||
|
" 10 0.2929 0.2931 -0.0002\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"image/png": "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Bsya1SEo3IO7t4G9gTFrVt5Hbyoswsu6spdeChJ51arglafLuTPOOIPGxkY2b94MwDvvvMO7777LkUcGU13df//9nR535plncvfddwPBdBrvvvsulZWVtLW1sXnzZt5//30eeeSRfY7LBMPQoUPZtm1bhxFShx56KFu3bt3nmPHjx/O73/2Ot99+m927dzN//nwmTpzY63+ziCRoxozum8crKhIZ5l/aYRFp/9t93HF707qzuyR7GRijRo3iG9/4BhMnTqS6upprrrmGm2++mfr6empqatqbp7LdeeedNDU1MWbMGGpqalizZg0DBgzgpptuYvz48Zx99tkcd9xx+xz3sY99jMsvv5zRo0dzzjnncPLJJ7dvu/TSS7niiivaO7gzPvGJT3DrrbdSV1dHdXU1Y8eOZcqUKft8toiUsFzmBDkQXp3NDbVmzZruJ0WZNat9HpWtr7227/boXCuzZnX/WXlwIM4NlRH7u+6Fkp3/pwuqI101uPeNOshxbqg+81jVXslcqtXX45HRQe0yVxiNjbp7W0RKWmmHBewNgU7a8oHE2v9ERA4kpd1nISIiOVFYiIhILIWFiIjEUlhkMctMASwiIhkKiyLI59TgI0aM4O233+52n+9+97sdlj/zmc/k5dwiUjoUFkVQ6KnBs8Pi6aefLti5RaRvUFgkbPv27Zx33nlUV1czevRoHnrooQ5Tg5eXlzNz5kxGjRrF5MmTee6556itreXoo49m4cLgkeX33Xdfh4cinX/++TQ3N+9zri984QvU1NQwatQofvzjHwNw/fXXs2PHDsaOHctFF13Ufk4IbsicOXMmo0ePZsyYMTz00EMAPPXUU9TW1jJt2jSOO+44LrroIjyJCfJF5IBR8mGR6aP4yEcO7dBXkVm/v30Yjz76KEcccQQrVqxg1apVTJo0qcP27du3c8YZZ7B69WrKy8u58cYbefzxx1mwYEGH50rkYu7cuSxbtoylS5dy1113sXnzZm699VYOPvhgWlpaeOCBBzrs/8tf/pKWlhZWrFjBE088wcyZM/nTn/4EwPPPP88Pf/hD1qxZw7p16/jDH/7Q+1+CiBzwSj4skjZmzBgef/xxrrvuOp566ql9phofOHBge4BUVVUxceJEBgwYwJgxY3o8Hfhdd93V/pCi9evX8+qrr3a7/+9//3suvPBCysrKqKysZOLEiSxZsgQIJhccPnw4/fr1Y+zYsZqaXKTElfwd3JnWla1bt3LooXuvLvLV6nLssceyfPlyFi1axI033siZZ57ZYXt0CvB+/fpx0EEHtb/PTAeey9Tkzc3NPPHEEzzzzDMccsgh1NbW7tfU5Jk6QFOTi4iuLBK3ceNGDjnkEL70pS8xc+ZMli9f3uPPGDFiBC0tLezZs4f169fz3HPP7bPPu+++y5AhQzjkkEN46aWXePbZZ9u3DRgwgA8//HCfYz73uc/x0EMPsXv3bjZt2sSTTz7J+PHje1yfiPR9JX9lkbSVK1cyc+ZM+vXrx4ABA7j77ru59tpre/QZp512GiNHjqSqqorjjz+ek046aZ99Jk2axI9+9COOP/54Pv3pT3PKKae0b5s+fTonnHACJ510Uod+i6lTp/LMM89QXV2NmXHbbbfx8Y9/vPf/WBHpu3KZmvZAePVqivKIzLTcQQNUzofllaYo76gvTP+cT6ojXTW494060BTlvaMRoiIi+1KfhYiIxOrzYeG6VEicfscifV+fDotBgwaxefNmfZklyN3ZvHkzgwYNKnYpIpKgPt1nMXz4cDZs2MCmTZti9925c2fRv/DSUENv6hg0aBDDhw9PsCIRKbY+HRYDBgxg5MiROe3b3NzMiSeemHBF6a8hTXWISHok2gxlZpPM7GUzW2tm13ey/RozW2NmL5jZb83sqMi23WbWEr4WJlmniIh0L7ErCzMrA2YDZwMbgCVmttDdow9yeB4Y5+5/MbOvArcB/zPctsPdxyZVn4iI5C7JK4vxwFp3X+fuHwDzgCnRHdy9yd3/Ei4+C6jhW0QkhZIMiyOB9ZHlDeG6rnwZ+M/I8iAzW2pmz5rZF5IoUEREcmNJDSs1s2nAJHe/LFy+GJjg7g2d7PsloAGY6O7vh+uOdPe3zOxoYDFwpru/lnXcdGA6QGVlZc28efN6Xe+2bdvaHwpULGmoQXWojgOhjjTU0FfqqKurW+bu42J3zGVOkN68gFOBxyLLNwA3dLLfWcCLQEU3n3UfMK2783U2N1RPpGGOlzTU4K46sqmOjtJQRxpqcO8bdZDj3FBJNkMtAY4xs5FmNhC4AOgwqsnMTgTuASa7e1tk/RAzOyh8PxQ4DYh2jIuISAElNhrK3XeZWQPwGFAGzHX31WZ2C0GSLQRuB8qBxvABQG+6+2TgeOAeM9tD0K9yq3ccRSUiIgWU6E157r4IWJS17qbI+7O6OO5pYEyStYmISO769NxQIiKSHwoLERGJpbAQEZFYCgsREYmlsBARkVgKCxERiaWwEBGRWAoLERGJpbAQEZFYCgsREYmlsBARkVgKCxERiaWwEBGRWAoLERGJpbAQEZFYCgsREYmlsBARkVgKCxERiaWLine truncated
|
||||||
|
"text/plain": [
|
||||||
|
"<Figure size 432x288 with 1 Axes>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"needs_background": "light"
|
||||||
|
},
|
||||||
|
"output_type": "display_data"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"compare(range(1, 11))"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 2
|
||||||
|
}
|
||||||
Reference in new issue
Block a user