j1-template 2022.2.3 → 2022.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/_includes/themes/j1/modules/navigator/generator.html +1 -1
  3. data/assets/data/cookieconsent.html +4 -4
  4. data/assets/data/nbinteract.html +128 -0
  5. data/assets/data/quicklinks.html +15 -0
  6. data/assets/data/translator.html +15 -15
  7. data/assets/themes/j1/adapter/js/analytics.js +13 -13
  8. data/assets/themes/j1/adapter/js/cookieConsent.js +1 -1
  9. data/assets/themes/j1/adapter/js/mmenu.js +25 -3
  10. data/assets/themes/j1/adapter/js/navigator.js +2 -2
  11. data/assets/themes/j1/adapter/js/nbinteract.js +588 -146
  12. data/assets/themes/j1/core/css/themes/unodark/bootstrap.css +30 -40
  13. data/assets/themes/j1/core/css/themes/unodark/bootstrap.min.css +1 -1
  14. data/assets/themes/j1/core/css/themes/unolight/bootstrap.css +50 -66
  15. data/assets/themes/j1/core/css/themes/unolight/bootstrap.min.css +1 -1
  16. data/assets/themes/j1/core/js/template.js +15 -4
  17. data/assets/themes/j1/core/js/template.min.js +1 -1
  18. data/assets/themes/j1/core/js/template.min.js.map +1 -1
  19. data/assets/themes/j1/modules/carousel/css/theme/uno.css +5 -0
  20. data/assets/themes/j1/modules/carousel/css/theme/uno.min.css +1 -1
  21. data/assets/themes/j1/modules/cookieConsent/js/cookieConsent.js +1 -0
  22. data/assets/themes/j1/modules/justifiedGallery/css/justifiedGallery.css +6 -0
  23. data/assets/themes/j1/modules/justifiedGallery/css/justifiedGallery.min.css +1 -1
  24. data/assets/themes/j1/modules/mmenuLight/css/mmenu-light.css +2 -2
  25. data/assets/themes/j1/modules/mmenuLight/css/mmenu-light.min.css +1 -2
  26. data/assets/themes/j1/modules/nbInteract/css/theme/uno/nbinteract-core.css +33 -33
  27. data/assets/themes/j1/modules/nbInteract/css/theme/uno/nbinteract-core.min.css +1 -1
  28. data/assets/themes/j1/modules/nbInteract/js/nbinteract/nbinteract-core.js +1 -1
  29. data/assets/themes/j1/modules/nbInteract/js/nbinteract/nbinteract-core.js.map +1 -1
  30. data/assets/themes/j1/modules/nbInteract/js/nbinteract/nbinteract-core.min.js +1 -1
  31. data/assets/themes/j1/modules/nbInteract/js/requireJS/require.js +2068 -0
  32. data/assets/themes/j1/modules/nbInteract/js/requireJS/require.min.js +36 -0
  33. data/assets/themes/j1/modules/plotly/LICENSE +21 -0
  34. data/assets/themes/j1/modules/plotly/README.md +32 -0
  35. data/assets/themes/j1/modules/plotly/js/plotly.js +265345 -0
  36. data/assets/themes/j1/modules/plotly/js/plotly.min.js +65 -0
  37. data/assets/themes/j1/modules/requirejs/LICENSE +45 -0
  38. data/assets/themes/j1/modules/requirejs/README.md +79 -0
  39. data/assets/themes/j1/modules/requirejs/js/require.js +2068 -0
  40. data/assets/themes/j1/modules/requirejs/js/require.min.js +36 -0
  41. data/lib/j1/version.rb +3 -3
  42. data/lib/starter_web/Gemfile +1 -1
  43. data/lib/starter_web/_config.yml +1 -1
  44. data/lib/starter_web/_data/modules/analytics.yml +8 -23
  45. data/lib/starter_web/_data/modules/defaults/analytics.yml +1 -1
  46. data/lib/starter_web/_data/modules/defaults/cookieconsent.yml +55 -42
  47. data/lib/starter_web/_data/modules/defaults/navigator.yml +4 -0
  48. data/lib/starter_web/_data/modules/defaults/nbinteract.yml +95 -1
  49. data/lib/starter_web/_data/modules/defaults/translator.yml +24 -12
  50. data/lib/starter_web/_data/modules/justifiedGallery.yml +14 -8
  51. data/lib/starter_web/_data/modules/navigator_menu.yml +6 -3
  52. data/lib/starter_web/_data/modules/nbinteract.yml +12 -48
  53. data/lib/starter_web/_data/resources.yml +56 -0
  54. data/lib/starter_web/_includes/attributes.asciidoc +11 -0
  55. data/lib/starter_web/_plugins/lunr_index.rb +1 -1
  56. data/lib/starter_web/assets/images/pages/nbinteract/mandelbrot-menge-1920x1200.jpg +0 -0
  57. data/lib/starter_web/assets/images/pages/nbinteract/mandelbrot-menge.png +0 -0
  58. data/lib/starter_web/assets/images/pages/nbinteract/manual/nbi_bar.jpg +0 -0
  59. data/lib/starter_web/assets/images/pages/nbinteract/manual/nbi_hist.jpg +0 -0
  60. data/lib/starter_web/assets/images/pages/nbinteract/manual/nbi_line.jpg +0 -0
  61. data/lib/starter_web/assets/images/pages/nbinteract/manual/nbi_multiple_choice.jpg +0 -0
  62. data/lib/starter_web/assets/images/pages/nbinteract/manual/nbi_scatter.jpg +0 -0
  63. data/lib/starter_web/assets/images/pages/nbinteract/manual/nbi_scatter_drag.jpg +0 -0
  64. data/lib/starter_web/assets/images/pages/nbinteract/manual/nbi_short_answer.jpg +0 -0
  65. data/lib/starter_web/assets/videos/gallery/kick-it-old-school-poster.jpg +0 -0
  66. data/lib/starter_web/assets/videos/gallery/nye-party-shop-poster.jpg +0 -0
  67. data/lib/starter_web/assets/videos/gallery/stay-colorful-poster.jpg +0 -0
  68. data/lib/starter_web/collections/posts/public/series/_posts/2020-01-01-post-wiki-series.adoc +1 -0
  69. data/lib/starter_web/collections/posts/public/series/_posts/2020-01-02-post-wiki-series.adoc +1 -0
  70. data/lib/starter_web/collections/posts/public/series/_posts/2020-01-03-post-wiki-series.adoc +1 -0
  71. data/lib/starter_web/package.json +1 -2
  72. data/lib/starter_web/pages/public/jupyter/docs/j1-nbinteract-doc.adoc +34 -20
  73. data/lib/starter_web/pages/public/jupyter/docs/nbi-widget-manual.adoc +154 -7
  74. data/lib/starter_web/pages/public/jupyter/docs/nbinteract-doc.adoc +24 -19
  75. data/lib/starter_web/pages/public/jupyter/examples/j1-circular-times-table.adoc +135 -0
  76. data/lib/starter_web/pages/public/jupyter/examples/j1-interactive-widgets.adoc +8 -5
  77. data/lib/starter_web/pages/public/jupyter/examples/j1-odes-in-python.adoc +15 -7
  78. data/lib/starter_web/pages/public/jupyter/examples/j1-testing-plotly.adoc +94 -0
  79. data/lib/starter_web/pages/public/jupyter/examples/j1_climate-change-forecast.adoc +8 -8
  80. data/lib/starter_web/pages/public/jupyter/notebooks/j1/.ipynb_checkpoints/j1_circular_times_table-checkpoint.ipynb +12387 -0
  81. data/lib/starter_web/pages/public/jupyter/notebooks/j1/.ipynb_checkpoints/j1_climate_change_forecast-checkpoint.ipynb +1058 -0
  82. data/lib/starter_web/pages/public/jupyter/notebooks/j1/{j1_ode_selected.ipynb → .ipynb_checkpoints/j1_docs_example_dynamic-checkpoint.ipynb} +1 -1
  83. data/lib/starter_web/pages/public/jupyter/notebooks/j1/.ipynb_checkpoints/j1_interactive_widgets-checkpoint.ipynb +26 -26
  84. data/lib/starter_web/pages/public/jupyter/notebooks/j1/.ipynb_checkpoints/{j1_altair_interactive_test-checkpoint.ipynb → j1_ode_selected-checkpoint.ipynb} +99 -318
  85. data/lib/starter_web/pages/public/jupyter/notebooks/j1/.ipynb_checkpoints/j1_odes_in_python-checkpoint.ipynb +15227 -0
  86. data/lib/starter_web/pages/public/jupyter/notebooks/j1/factor_by_factor.mp4 +0 -0
  87. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_circular_times_table.ipynb +12387 -0
  88. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_climate_change_forecast.ipynb +2 -2
  89. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_docs_example_dynamic.ipynb +1 -1
  90. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_interactive_widgets.ipynb +26 -26
  91. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_odes_in_python.ipynb +15227 -0
  92. data/lib/starter_web/pages/public/jupyter/notebooks/j1/line_by_line.mp4 +0 -0
  93. data/lib/starter_web/pages/public/jupyter/notebooks/j1/point_by_point.mp4 +0 -0
  94. data/lib/starter_web/pages/public/jupyter/notebooks/nbi-docs/.ipynb_checkpoints/nbi_docs_examples_central_limit_theorem-checkpoint.ipynb +247 -0
  95. data/lib/starter_web/pages/public/jupyter/notebooks/nbi-docs/.ipynb_checkpoints/nbi_docs_examples_variability_of_the_sample_mean-checkpoint.ipynb +323 -0
  96. data/lib/starter_web/pages/public/jupyter/notebooks/nbi-docs/.ipynb_checkpoints/nbi_docs_recipes_graphing-checkpoint.ipynb +387 -0
  97. data/lib/starter_web/pages/public/jupyter/notebooks/nbi-docs/.ipynb_checkpoints/nbi_docs_recipes_layout-checkpoint.ipynb +384 -0
  98. data/lib/starter_web/pages/public/jupyter/notebooks/nbi-docs/.ipynb_checkpoints/nbi_docs_tutorial_interact-checkpoint.ipynb +254 -0
  99. data/lib/starter_web/pages/public/jupyter/notebooks/nbi-docs/.ipynb_checkpoints/nbi_docs_tutorial_monty_hall-checkpoint.ipynb +732 -0
  100. data/lib/starter_web/pages/public/jupyter/notebooks/nbi-docs/nbi_docs_examples_central_limit_theorem.ipynb +1 -2
  101. data/lib/starter_web/pages/public/jupyter/notebooks/nbi-docs/nbi_docs_recipes_graphing.ipynb +18 -18
  102. data/lib/starter_web/pages/public/jupyter/notebooks/nbi-docs/nbi_docs_tutorial_monty_hall.ipynb +25 -26
  103. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_circular_times_table.html +746 -0
  104. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_climate_change_forecast.html +2 -2
  105. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_docs_example_dynamic.html +186 -186
  106. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_interactive_widgets.html +3 -3
  107. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_odes_in_python.html +955 -0
  108. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/nbi_docs_recipes_graphing.html +473 -473
  109. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/nbi_docs_recipes_interactive_questions.html +242 -242
  110. data/lib/starter_web/pages/public/jupyter/services/binderhub.adoc +3 -3
  111. data/lib/starter_web/pages/public/jupyter/services/jupyterhub.adoc +6 -7
  112. data/lib/starter_web/pages/public/learn/roundtrip/100_present_images.adoc +1 -1
  113. data/lib/starter_web/pages/public/learn/roundtrip/100_present_videos.adoc +9 -15
  114. data/lib/starter_web/pages/public/learn/roundtrip/200_typography.adoc +1 -1
  115. data/lib/starter_web/pages/public/learn/roundtrip/300_icon_fonts.adoc +1 -1
  116. data/lib/starter_web/pages/public/learn/roundtrip/400_asciidoc_extensions.adoc +1 -1
  117. data/lib/starter_web/pages/public/learn/roundtrip/410_bs_modals_extentions.adoc +1 -1
  118. data/lib/starter_web/pages/public/learn/roundtrip/420_responsive_tables_extensions.adoc +1 -1
  119. data/lib/starter_web/pages/public/legal/en/300_privacy.adoc +117 -12
  120. data/lib/starter_web/pages/public/se/se-fake.adoc +47 -0
  121. data/lib/starter_web/utilsrv/_defaults/package.json +1 -1
  122. data/lib/starter_web/utilsrv/package.json +1 -1
  123. metadata +45 -22
  124. data/lib/starter_web/assets/videos/gallery/adriana-lima-poster.jpg +0 -0
  125. data/lib/starter_web/pages/public/jupyter/notebooks/binder/binder-launches.ipynb +0 -385
  126. data/lib/starter_web/pages/public/jupyter/notebooks/j1/.ipynb_checkpoints/Untitled-checkpoint.ipynb +0 -6
  127. data/lib/starter_web/pages/public/jupyter/notebooks/j1/.ipynb_checkpoints/binder-launches-checkpoint.ipynb +0 -385
  128. data/lib/starter_web/pages/public/jupyter/notebooks/j1/.ipynb_checkpoints/google_altair-checkpoint.ipynb +0 -33
  129. data/lib/starter_web/pages/public/jupyter/notebooks/j1/binder-launches.ipynb +0 -411
  130. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/binder-launches.html +0 -670
  131. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_ode_selected.html +0 -186
  132. data/lib/starter_web/pages/public/jupyter/notebooks/themes/altair/excel.py +0 -55
  133. data/lib/starter_web/pages/public/jupyter/notebooks/themes/altair/ggplot.py +0 -108
  134. data/lib/starter_web/pages/public/jupyter/notebooks/themes/altair/ggplot2.py +0 -108
  135. data/lib/starter_web/pages/public/jupyter/notebooks/themes/altair/husky.py +0 -121
  136. data/lib/starter_web/pages/public/jupyter/notebooks/themes/altair/latimes.py +0 -149
  137. data/lib/starter_web/pages/public/jupyter/notebooks/themes/altair/pcolor.py +0 -6
  138. data/lib/starter_web/pages/public/jupyter/notebooks/themes/altair/quartz.py +0 -55
  139. data/lib/starter_web/pages/public/jupyter/notebooks/themes/altair/spacy_base.py +0 -94
  140. data/lib/starter_web/pages/public/jupyter/notebooks/themes/altair/spacy_mono.py +0 -158
  141. data/lib/starter_web/pages/public/jupyter/notebooks/themes/altair/sunsentinel.py +0 -125
@@ -1,411 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "markdown",
5
- "metadata": {},
6
- "source": [
7
- "# Analysing mybinder.org launches\n",
8
- "\n",
9
- "The first few cells download and massage the data. Later on we answer questions on which repositories are popular and such."
10
- ]
11
- },
12
- {
13
- "cell_type": "code",
14
- "execution_count": 1,
15
- "metadata": {},
16
- "outputs": [],
17
- "source": [
18
- "%matplotlib inline\n",
19
- "\n",
20
- "import matplotlib.pyplot as plt\n",
21
- "import datetime\n",
22
- "import pandas as pd"
23
- ]
24
- },
25
- {
26
- "cell_type": "code",
27
- "execution_count": 2,
28
- "metadata": {},
29
- "outputs": [],
30
- "source": [
31
- "index = pd.read_json(\"https://archive.analytics.mybinder.org/index.jsonl\",\n",
32
- " lines=True)"
33
- ]
34
- },
35
- {
36
- "cell_type": "code",
37
- "execution_count": 3,
38
- "metadata": {},
39
- "outputs": [
40
- {
41
- "ename": "HTTPError",
42
- "evalue": "HTTP Error 503: Service Unavailable",
43
- "output_type": "error",
44
- "traceback": [
45
- "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
46
- "\u001b[1;31mHTTPError\u001b[0m Traceback (most recent call last)",
47
- "\u001b[1;32m<ipython-input-3-dc969cf0de9b>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 9\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0midx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mday\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mindex\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msort_index\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mascending\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0miterrows\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10\u001b[0m df = pd.read_json(\"https://archive.analytics.mybinder.org/{}\".format(day['name']),\n\u001b[1;32m---> 11\u001b[1;33m lines=True, )\n\u001b[0m\u001b[0;32m 12\u001b[0m \u001b[0mframes\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdf\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 13\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mframes\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m>\u001b[0m \u001b[0mn\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
48
- "\u001b[1;32mc:\\devtools\\python-3.7.9\\lib\\site-packages\\pandas\\util\\_decorators.py\u001b[0m in \u001b[0;36mwrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 197\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 198\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mnew_arg_name\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnew_arg_value\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 199\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 200\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 201\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mcast\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mF\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mwrapper\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
49
- "\u001b[1;32mc:\\devtools\\python-3.7.9\\lib\\site-packages\\pandas\\util\\_decorators.py\u001b[0m in \u001b[0;36mwrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 297\u001b[0m )\n\u001b[0;32m 298\u001b[0m \u001b[0mwarnings\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwarn\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmsg\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mFutureWarning\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mstacklevel\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mstacklevel\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 299\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 300\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 301\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mwrapper\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
50
- "\u001b[1;32mc:\\devtools\\python-3.7.9\\lib\\site-packages\\pandas\\io\\json\\_json.py\u001b[0m in \u001b[0;36mread_json\u001b[1;34m(path_or_buf, orient, typ, dtype, convert_axes, convert_dates, keep_default_dates, numpy, precise_float, date_unit, encoding, lines, chunksize, compression, nrows, storage_options)\u001b[0m\n\u001b[0;32m 554\u001b[0m \u001b[0mcompression\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mcompression\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 555\u001b[0m \u001b[0mnrows\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mnrows\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 556\u001b[1;33m \u001b[0mstorage_options\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mstorage_options\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 557\u001b[0m )\n\u001b[0;32m 558\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
51
- "\u001b[1;32mc:\\devtools\\python-3.7.9\\lib\\site-packages\\pandas\\io\\json\\_json.py\u001b[0m in \u001b[0;36m__init__\u001b[1;34m(self, filepath_or_buffer, orient, typ, dtype, convert_axes, convert_dates, keep_default_dates, numpy, precise_float, date_unit, encoding, lines, chunksize, compression, nrows, storage_options)\u001b[0m\n\u001b[0;32m 620\u001b[0m \u001b[1;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"nrows can only be passed if lines=True\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 621\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 622\u001b[1;33m \u001b[0mdata\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_get_data_from_filepath\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfilepath_or_buffer\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 623\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdata\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_preprocess_data\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 624\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
52
- "\u001b[1;32mc:\\devtools\\python-3.7.9\\lib\\site-packages\\pandas\\io\\json\\_json.py\u001b[0m in \u001b[0;36m_get_data_from_filepath\u001b[1;34m(self, filepath_or_buffer)\u001b[0m\n\u001b[0;32m 662\u001b[0m \u001b[0mencoding\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mencoding\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 663\u001b[0m \u001b[0mcompression\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcompression\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 664\u001b[1;33m \u001b[0mstorage_options\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstorage_options\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 665\u001b[0m )\n\u001b[0;32m 666\u001b[0m \u001b[0mfilepath_or_buffer\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mhandles\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mhandle\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
53
- "\u001b[1;32mc:\\devtools\\python-3.7.9\\lib\\site-packages\\pandas\\io\\common.py\u001b[0m in \u001b[0;36mget_handle\u001b[1;34m(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options)\u001b[0m\n\u001b[0;32m 561\u001b[0m \u001b[0mcompression\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mcompression\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 562\u001b[0m \u001b[0mmode\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mmode\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 563\u001b[1;33m \u001b[0mstorage_options\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mstorage_options\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 564\u001b[0m )\n\u001b[0;32m 565\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
54
- "\u001b[1;32mc:\\devtools\\python-3.7.9\\lib\\site-packages\\pandas\\io\\common.py\u001b[0m in \u001b[0;36m_get_filepath_or_buffer\u001b[1;34m(filepath_or_buffer, encoding, compression, mode, storage_options)\u001b[0m\n\u001b[0;32m 287\u001b[0m \u001b[1;34m\"storage_options passed with file object or non-fsspec file path\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 288\u001b[0m )\n\u001b[1;32m--> 289\u001b[1;33m \u001b[0mreq\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0murlopen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfilepath_or_buffer\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 290\u001b[0m \u001b[0mcontent_encoding\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mreq\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mheaders\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Content-Encoding\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 291\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mcontent_encoding\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m\"gzip\"\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
55
- "\u001b[1;32mc:\\devtools\\python-3.7.9\\lib\\site-packages\\pandas\\io\\common.py\u001b[0m in \u001b[0;36murlopen\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 193\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0murllib\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrequest\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 194\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 195\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0murllib\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrequest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0murlopen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 196\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 197\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
56
- "\u001b[1;32mc:\\devtools\\python-3.7.9\\lib\\urllib\\request.py\u001b[0m in \u001b[0;36murlopen\u001b[1;34m(url, data, timeout, cafile, capath, cadefault, context)\u001b[0m\n\u001b[0;32m 220\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 221\u001b[0m \u001b[0mopener\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_opener\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 222\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mopener\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mopen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0murl\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 223\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 224\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0minstall_opener\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mopener\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
57
- "\u001b[1;32mc:\\devtools\\python-3.7.9\\lib\\urllib\\request.py\u001b[0m in \u001b[0;36mopen\u001b[1;34m(self, fullurl, data, timeout)\u001b[0m\n\u001b[0;32m 529\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mprocessor\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mprocess_response\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mprotocol\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 530\u001b[0m \u001b[0mmeth\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mprocessor\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmeth_name\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 531\u001b[1;33m \u001b[0mresponse\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmeth\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mreq\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 532\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 533\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
58
- "\u001b[1;32mc:\\devtools\\python-3.7.9\\lib\\urllib\\request.py\u001b[0m in \u001b[0;36mhttp_response\u001b[1;34m(self, request, response)\u001b[0m\n\u001b[0;32m 639\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;36m200\u001b[0m \u001b[1;33m<=\u001b[0m \u001b[0mcode\u001b[0m \u001b[1;33m<\u001b[0m \u001b[1;36m300\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 640\u001b[0m response = self.parent.error(\n\u001b[1;32m--> 641\u001b[1;33m 'http', request, response, code, msg, hdrs)\n\u001b[0m\u001b[0;32m 642\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 643\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mresponse\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
59
- "\u001b[1;32mc:\\devtools\\python-3.7.9\\lib\\urllib\\request.py\u001b[0m in \u001b[0;36merror\u001b[1;34m(self, proto, *args)\u001b[0m\n\u001b[0;32m 567\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mhttp_err\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 568\u001b[0m \u001b[0margs\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mdict\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'default'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'http_error_default'\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0morig_args\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 569\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_call_chain\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 570\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 571\u001b[0m \u001b[1;31m# XXX probably also want an abstract factory that knows when it makes\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
60
- "\u001b[1;32mc:\\devtools\\python-3.7.9\\lib\\urllib\\request.py\u001b[0m in \u001b[0;36m_call_chain\u001b[1;34m(self, chain, kind, meth_name, *args)\u001b[0m\n\u001b[0;32m 501\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mhandler\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mhandlers\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 502\u001b[0m \u001b[0mfunc\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mhandler\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmeth_name\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 503\u001b[1;33m \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 504\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mresult\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 505\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
61
- "\u001b[1;32mc:\\devtools\\python-3.7.9\\lib\\urllib\\request.py\u001b[0m in \u001b[0;36mhttp_error_default\u001b[1;34m(self, req, fp, code, msg, hdrs)\u001b[0m\n\u001b[0;32m 647\u001b[0m \u001b[1;32mclass\u001b[0m \u001b[0mHTTPDefaultErrorHandler\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mBaseHandler\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 648\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mhttp_error_default\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mreq\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfp\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcode\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmsg\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mhdrs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 649\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mHTTPError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mreq\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfull_url\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcode\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmsg\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mhdrs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfp\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 650\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 651\u001b[0m \u001b[1;32mclass\u001b[0m \u001b[0mHTTPRedirectHandler\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mBaseHandler\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
62
- "\u001b[1;31mHTTPError\u001b[0m: HTTP Error 503: Service Unavailable"
63
- ]
64
- }
65
- ],
66
- "source": [
67
- "# get all days since start of 2019\n",
68
- "now = datetime.datetime.now()\n",
69
- "n = (now - datetime.datetime(2019, 1, 1)).days\n",
70
- "\n",
71
- "# small range for previewing\n",
72
- "#n = 30\n",
73
- "\n",
74
- "frames = []\n",
75
- "for idx, day in index.sort_index(ascending=False).iterrows():\n",
76
- " df = pd.read_json(\"https://archive.analytics.mybinder.org/{}\".format(day['name']),\n",
77
- " lines=True, )\n",
78
- " frames.append(df)\n",
79
- " if len(frames) > n:\n",
80
- " break\n",
81
- " \n",
82
- "print(f\"Fetched data for {n} days.\")"
83
- ]
84
- },
85
- {
86
- "cell_type": "code",
87
- "execution_count": null,
88
- "metadata": {},
89
- "outputs": [],
90
- "source": [
91
- "df = pd.concat(frames)"
92
- ]
93
- },
94
- {
95
- "cell_type": "code",
96
- "execution_count": null,
97
- "metadata": {},
98
- "outputs": [],
99
- "source": [
100
- "# make it easier to grab the ref\n",
101
- "def get_repo(spec):\n",
102
- " s = spec.rsplit(\"/\", 1)[0]\n",
103
- " if s.endswith('.git'):\n",
104
- " s = s[:-4]\n",
105
- " return s\n",
106
- "df['repo'] = df['spec'].apply(get_repo) #lambda s: s.rsplit(\"/\", 1)[0].replace(\".git\", \"\"))\n",
107
- "df['org'] = df['spec'].apply(lambda s: s.split(\"/\", 1)[0])\n",
108
- "df['ref'] = df['spec'].apply(lambda s: s.rsplit(\"/\", 1)[1])"
109
- ]
110
- },
111
- {
112
- "cell_type": "code",
113
- "execution_count": null,
114
- "metadata": {},
115
- "outputs": [],
116
- "source": [
117
- "# take a look at the data, does it look sensible?\n",
118
- "df.sample(10)"
119
- ]
120
- },
121
- {
122
- "cell_type": "code",
123
- "execution_count": null,
124
- "metadata": {},
125
- "outputs": [],
126
- "source": [
127
- "df = df.drop(columns=['schema', 'version', 'spec', 'status'])"
128
- ]
129
- },
130
- {
131
- "cell_type": "code",
132
- "execution_count": null,
133
- "metadata": {},
134
- "outputs": [],
135
- "source": [
136
- "df.head()"
137
- ]
138
- },
139
- {
140
- "cell_type": "markdown",
141
- "metadata": {},
142
- "source": [
143
- "## Monthly, weekly, daily active repos"
144
- ]
145
- },
146
- {
147
- "cell_type": "code",
148
- "execution_count": null,
149
- "metadata": {},
150
- "outputs": [],
151
- "source": [
152
- "df_ = df.set_index(\"timestamp\")"
153
- ]
154
- },
155
- {
156
- "cell_type": "code",
157
- "execution_count": null,
158
- "metadata": {},
159
- "outputs": [],
160
- "source": [
161
- "def n_active_repos(period=30):\n",
162
- " \"\"\"Unique active repos over the period\n",
163
- " \n",
164
- " With period=30 this gives monthly active repos\n",
165
- " With period=1 you get daily active repos\n",
166
- " \"\"\"\n",
167
- " now = datetime.datetime.now()\n",
168
- " start = datetime.datetime(2019, 1, 1)\n",
169
- " days_since_start = (now - start).days\n",
170
- "\n",
171
- " data = []\n",
172
- "\n",
173
- " for n in range(days_since_start):\n",
174
- " s = start + datetime.timedelta(days=n)\n",
175
- " e = start + datetime.timedelta(days=n+period)\n",
176
- " if e > now:\n",
177
- " break\n",
178
- "\n",
179
- " # our \"monthly\" data\n",
180
- " monthly = df_.loc[s.isoformat():e.isoformat()]\n",
181
- " data.append(dict(timestamp=e, repos=len(set(monthly.repo))))\n",
182
- " \n",
183
- " return pd.DataFrame.from_records(data).set_index(\"timestamp\")"
184
- ]
185
- },
186
- {
187
- "cell_type": "code",
188
- "execution_count": null,
189
- "metadata": {},
190
- "outputs": [],
191
- "source": [
192
- "monthly_active = n_active_repos(30)\n",
193
- "weekly_active = n_active_repos(7)\n",
194
- "daily_active = n_active_repos(1)"
195
- ]
196
- },
197
- {
198
- "cell_type": "code",
199
- "execution_count": null,
200
- "metadata": {},
201
- "outputs": [],
202
- "source": [
203
- "activity = pd.merge(monthly_active, daily_active,\n",
204
- " suffixes=(\"_monthly\", \"_daily\"), left_index=True, right_index=True)\n",
205
- "activity = pd.merge(activity, weekly_active, left_index=True, right_index=True)\n",
206
- "\n",
207
- "activity.columns = ['30day active', '1d active', '7d active']\n",
208
- "activity.plot();"
209
- ]
210
- },
211
- {
212
- "cell_type": "markdown",
213
- "metadata": {},
214
- "source": [
215
- "## Total launches"
216
- ]
217
- },
218
- {
219
- "cell_type": "code",
220
- "execution_count": null,
221
- "metadata": {},
222
- "outputs": [],
223
- "source": [
224
- "# Sneak peek: total launches!\n",
225
- "df.shape"
226
- ]
227
- },
228
- {
229
- "cell_type": "markdown",
230
- "metadata": {},
231
- "source": [
232
- "## Launches per day"
233
- ]
234
- },
235
- {
236
- "cell_type": "code",
237
- "execution_count": null,
238
- "metadata": {},
239
- "outputs": [],
240
- "source": [
241
- "daily = df.set_index(\"timestamp\").resample('D').count()"
242
- ]
243
- },
244
- {
245
- "cell_type": "code",
246
- "execution_count": null,
247
- "metadata": {},
248
- "outputs": [],
249
- "source": [
250
- "daily['repo'].plot()"
251
- ]
252
- },
253
- {
254
- "cell_type": "markdown",
255
- "metadata": {},
256
- "source": [
257
- "## Estimate number of unique repositories\n",
258
- "\n",
259
- "Expect the raw number of launches to be bigger than the number of repositories launched more than once. Those launched only once might have been accidents."
260
- ]
261
- },
262
- {
263
- "cell_type": "code",
264
- "execution_count": null,
265
- "metadata": {
266
- "scrolled": true
267
- },
268
- "outputs": [],
269
- "source": [
270
- "len(set(df.repo))"
271
- ]
272
- },
273
- {
274
- "cell_type": "code",
275
- "execution_count": null,
276
- "metadata": {},
277
- "outputs": [],
278
- "source": [
279
- "from collections import Counter\n",
280
- "\n",
281
- "sum(1 for k,v in Counter(df.repo).items() if v > 3)"
282
- ]
283
- },
284
- {
285
- "cell_type": "markdown",
286
- "metadata": {},
287
- "source": [
288
- "## Popular repositories and their branches\n",
289
- "\n",
290
- "Twenty most popular repos:"
291
- ]
292
- },
293
- {
294
- "cell_type": "code",
295
- "execution_count": null,
296
- "metadata": {},
297
- "outputs": [],
298
- "source": [
299
- "top20 = df.groupby(\"repo\").count().sort_values(\"timestamp\", ascending=False).head(20)\n",
300
- "top20"
301
- ]
302
- },
303
- {
304
- "cell_type": "code",
305
- "execution_count": null,
306
- "metadata": {},
307
- "outputs": [],
308
- "source": [
309
- "print(\"Cumulative top20 launches:\", top20['ref'].sum())\n",
310
- "print(\"The top20 repos are {:.1f}% of all \"\n",
311
- " \"launches.\".format(100 * top20['ref'].sum() / df.shape[0]))"
312
- ]
313
- },
314
- {
315
- "cell_type": "markdown",
316
- "metadata": {},
317
- "source": [
318
- "## Per org stats\n",
319
- "\n",
320
- "Needs more RAM than mybinder.org gives us for now"
321
- ]
322
- },
323
- {
324
- "cell_type": "code",
325
- "execution_count": null,
326
- "metadata": {},
327
- "outputs": [],
328
- "source": [
329
- "# add a new column showing total launches per repo\n",
330
- "totals_per_repo = (df.groupby([\"repo\"])\n",
331
- " .size()\n",
332
- " .reset_index(name='repo_counts'))"
333
- ]
334
- },
335
- {
336
- "cell_type": "code",
337
- "execution_count": null,
338
- "metadata": {},
339
- "outputs": [],
340
- "source": [
341
- "# add a nnew column showing total launches per org\n",
342
- "totals_per_org = (df.groupby([\"org\"])\n",
343
- " .size()\n",
344
- " .reset_index(name='org_counts'))"
345
- ]
346
- },
347
- {
348
- "cell_type": "code",
349
- "execution_count": null,
350
- "metadata": {},
351
- "outputs": [],
352
- "source": [
353
- "df_ = pd.merge(df, totals_per_repo, on='repo')\n",
354
- "df_ = pd.merge(df_, totals_per_org, on='org')\n",
355
- "#df_.sample(10)"
356
- ]
357
- },
358
- {
359
- "cell_type": "code",
360
- "execution_count": null,
361
- "metadata": {},
362
- "outputs": [],
363
- "source": [
364
- "(df.groupby(\"provider\")\n",
365
- " .size()\n",
366
- " .reset_index(name='Launches')\n",
367
- " .sort_values('Launches', ascending=False))"
368
- ]
369
- },
370
- {
371
- "cell_type": "code",
372
- "execution_count": null,
373
- "metadata": {
374
- "scrolled": false
375
- },
376
- "outputs": [],
377
- "source": [
378
- "(df_.groupby([\"org\", \"repo\", \"ref\", \"repo_counts\", \"org_counts\"])\n",
379
- " .size()\n",
380
- " # give the column a nice name\n",
381
- " .reset_index(name='ref_counts')\n",
382
- " # sort first by total launches, then within a repo by ref launches\n",
383
- " .sort_values(['org_counts', 'repo_counts', 'ref_counts'],\n",
384
- " ascending=[False,False, False])\n",
385
- " .set_index([\"org\", 'repo', 'ref'])\n",
386
- ")"
387
- ]
388
- }
389
- ],
390
- "metadata": {
391
- "kernelspec": {
392
- "display_name": "Python 3",
393
- "language": "python",
394
- "name": "python3"
395
- },
396
- "language_info": {
397
- "codemirror_mode": {
398
- "name": "ipython",
399
- "version": 3
400
- },
401
- "file_extension": ".py",
402
- "mimetype": "text/x-python",
403
- "name": "python",
404
- "nbconvert_exporter": "python",
405
- "pygments_lexer": "ipython3",
406
- "version": "3.7.9"
407
- }
408
- },
409
- "nbformat": 4,
410
- "nbformat_minor": 2
411
- }