pycall 1.0.1-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +41 -0
  5. data/CHANGES.md +39 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +91 -0
  9. data/Rakefile +29 -0
  10. data/appveyor.yml +138 -0
  11. data/bin/console +10 -0
  12. data/bin/guard +17 -0
  13. data/bin/rspec +17 -0
  14. data/bin/runner +6 -0
  15. data/bin/setup +8 -0
  16. data/config/Guardfile +30 -0
  17. data/docker/Dockerfile +191 -0
  18. data/docker/Gemfile +12 -0
  19. data/docker/README.md +22 -0
  20. data/examples/classifier_comparison.rb +135 -0
  21. data/examples/datascience_rb_20170519.ipynb +4836 -0
  22. data/examples/hist.rb +32 -0
  23. data/examples/notebooks/classifier_comparison.ipynb +226 -0
  24. data/examples/notebooks/forest_importances.ipynb +238 -0
  25. data/examples/notebooks/iruby_integration.ipynb +183 -0
  26. data/examples/notebooks/lorenz_attractor.ipynb +214 -0
  27. data/examples/notebooks/polar_axes.ipynb +209 -0
  28. data/examples/notebooks/sum_benchmarking.ipynb +374 -0
  29. data/examples/notebooks/xkcd_style.ipynb +149 -0
  30. data/examples/plot_forest_importances_faces.rb +46 -0
  31. data/examples/sum_benchmarking.rb +49 -0
  32. data/ext/pycall/extconf.rb +3 -0
  33. data/ext/pycall/gc.c +74 -0
  34. data/ext/pycall/libpython.c +217 -0
  35. data/ext/pycall/pycall.c +2184 -0
  36. data/ext/pycall/pycall_internal.h +700 -0
  37. data/ext/pycall/range.c +69 -0
  38. data/ext/pycall/ruby_wrapper.c +432 -0
  39. data/lib/2.1/pycall.so +0 -0
  40. data/lib/2.2/pycall.so +0 -0
  41. data/lib/2.3/pycall.so +0 -0
  42. data/lib/2.4/pycall.so +0 -0
  43. data/lib/pycall/conversion.rb +173 -0
  44. data/lib/pycall/dict.rb +48 -0
  45. data/lib/pycall/error.rb +10 -0
  46. data/lib/pycall/gc_guard.rb +84 -0
  47. data/lib/pycall/import.rb +120 -0
  48. data/lib/pycall/init.rb +55 -0
  49. data/lib/pycall/iruby_helper.rb +40 -0
  50. data/lib/pycall/libpython/finder.rb +170 -0
  51. data/lib/pycall/libpython/pyobject_struct.rb +30 -0
  52. data/lib/pycall/libpython/pytypeobject_struct.rb +273 -0
  53. data/lib/pycall/libpython.rb +12 -0
  54. data/lib/pycall/list.rb +45 -0
  55. data/lib/pycall/pretty_print.rb +9 -0
  56. data/lib/pycall/pyerror.rb +30 -0
  57. data/lib/pycall/pyobject_wrapper.rb +212 -0
  58. data/lib/pycall/python/PyCall/__init__.py +1 -0
  59. data/lib/pycall/python/PyCall/six.py +23 -0
  60. data/lib/pycall/python/investigator.py +7 -0
  61. data/lib/pycall/pytypeobject_wrapper.rb +90 -0
  62. data/lib/pycall/set.rb +19 -0
  63. data/lib/pycall/slice.rb +8 -0
  64. data/lib/pycall/tuple.rb +46 -0
  65. data/lib/pycall/version.rb +3 -0
  66. data/lib/pycall/wrapper_object_cache.rb +61 -0
  67. data/lib/pycall.rb +91 -0
  68. data/pycall.gemspec +40 -0
  69. data/tasks/docker.rake +21 -0
  70. data/tasks/pycall.rake +7 -0
  71. metadata +228 -0
@@ -0,0 +1,374 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "metadata": {},
7
+ "outputs": [
8
+ {
9
+ "data": {
10
+ "text/plain": [
11
+ ":sns"
12
+ ]
13
+ },
14
+ "execution_count": 1,
15
+ "metadata": {},
16
+ "output_type": "execute_result"
17
+ }
18
+ ],
19
+ "source": [
20
+ "require 'matplotlib/iruby'\n",
21
+ "Matplotlib::IRuby.activate\n",
22
+ "\n",
23
+ "require 'pycall/import'\n",
24
+ "include PyCall::Import\n",
25
+ "\n",
26
+ "pyimport :pandas, as: :pd\n",
27
+ "pyimport :seaborn, as: :sns"
28
+ ]
29
+ },
30
+ {
31
+ "cell_type": "code",
32
+ "execution_count": 2,
33
+ "metadata": {},
34
+ "outputs": [
35
+ {
36
+ "data": {
37
+ "text/plain": [
38
+ "true"
39
+ ]
40
+ },
41
+ "execution_count": 2,
42
+ "metadata": {},
43
+ "output_type": "execute_result"
44
+ }
45
+ ],
46
+ "source": [
47
+ "require 'benchmark'"
48
+ ]
49
+ },
50
+ {
51
+ "cell_type": "code",
52
+ "execution_count": 3,
53
+ "metadata": {},
54
+ "outputs": [
55
+ {
56
+ "data": {
57
+ "text/plain": [
58
+ "[]"
59
+ ]
60
+ },
61
+ "execution_count": 3,
62
+ "metadata": {},
63
+ "output_type": "execute_result"
64
+ }
65
+ ],
66
+ "source": [
67
+ "n = 100_000\n",
68
+ "trials = 100\n",
69
+ "array = Array.new(n) { rand }\n",
70
+ "enum = array.each\n",
71
+ "method = []\n",
72
+ "runtime = []"
73
+ ]
74
+ },
75
+ {
76
+ "cell_type": "code",
77
+ "execution_count": 4,
78
+ "metadata": {},
79
+ "outputs": [
80
+ {
81
+ "data": {
82
+ "text/plain": [
83
+ "100"
84
+ ]
85
+ },
86
+ "execution_count": 4,
87
+ "metadata": {},
88
+ "output_type": "execute_result"
89
+ }
90
+ ],
91
+ "source": [
92
+ "# Array#sum\n",
93
+ "trials.times do\n",
94
+ " method << 'array.sum'\n",
95
+ " runtime << Benchmark.realtime { array.sum }\n",
96
+ "end"
97
+ ]
98
+ },
99
+ {
100
+ "cell_type": "code",
101
+ "execution_count": 5,
102
+ "metadata": {},
103
+ "outputs": [
104
+ {
105
+ "data": {
106
+ "text/plain": [
107
+ "100"
108
+ ]
109
+ },
110
+ "execution_count": 5,
111
+ "metadata": {},
112
+ "output_type": "execute_result"
113
+ }
114
+ ],
115
+ "source": [
116
+ "# Array#sum\n",
117
+ "trials.times do\n",
118
+ " method << 'enum.sum'\n",
119
+ " runtime << Benchmark.realtime { enum.sum }\n",
120
+ "end"
121
+ ]
122
+ },
123
+ {
124
+ "cell_type": "code",
125
+ "execution_count": 6,
126
+ "metadata": {},
127
+ "outputs": [
128
+ {
129
+ "data": {
130
+ "text/plain": [
131
+ "100"
132
+ ]
133
+ },
134
+ "execution_count": 6,
135
+ "metadata": {},
136
+ "output_type": "execute_result"
137
+ }
138
+ ],
139
+ "source": [
140
+ "# Array#inject\n",
141
+ "trials.times do\n",
142
+ " method << 'array.inject'\n",
143
+ " runtime << Benchmark.realtime { array.inject :+ }\n",
144
+ "end"
145
+ ]
146
+ },
147
+ {
148
+ "cell_type": "code",
149
+ "execution_count": 7,
150
+ "metadata": {},
151
+ "outputs": [
152
+ {
153
+ "data": {
154
+ "text/plain": [
155
+ "100"
156
+ ]
157
+ },
158
+ "execution_count": 7,
159
+ "metadata": {},
160
+ "output_type": "execute_result"
161
+ }
162
+ ],
163
+ "source": [
164
+ "# Enumerable#inject\n",
165
+ "trials.times do\n",
166
+ " method << 'enum.inject'\n",
167
+ " runtime << Benchmark.realtime { enum.inject :+ }\n",
168
+ "end"
169
+ ]
170
+ },
171
+ {
172
+ "cell_type": "code",
173
+ "execution_count": 8,
174
+ "metadata": {},
175
+ "outputs": [
176
+ {
177
+ "data": {
178
+ "text/plain": [
179
+ "100"
180
+ ]
181
+ },
182
+ "execution_count": 8,
183
+ "metadata": {},
184
+ "output_type": "execute_result"
185
+ }
186
+ ],
187
+ "source": [
188
+ "# while\n",
189
+ "def while_sum(array)\n",
190
+ " sum, i, cnt = 0, 0, array.length\n",
191
+ " while i < cnt\n",
192
+ " sum += array[i]\n",
193
+ " i += 1\n",
194
+ " end\n",
195
+ " sum\n",
196
+ "end\n",
197
+ "\n",
198
+ "trials.times do\n",
199
+ " method << 'while'\n",
200
+ " runtime << Benchmark.realtime { while_sum(array) }\n",
201
+ "end"
202
+ ]
203
+ },
204
+ {
205
+ "cell_type": "code",
206
+ "execution_count": 9,
207
+ "metadata": {},
208
+ "outputs": [
209
+ {
210
+ "data": {
211
+ "text/html": [
212
+ "<table border=\"1\" class=\"dataframe\">\n",
213
+ " <thead>\n",
214
+ " <tr>\n",
215
+ " <th></th>\n",
216
+ " <th colspan=\"8\" halign=\"left\">runtime</th>\n",
217
+ " </tr>\n",
218
+ " <tr>\n",
219
+ " <th></th>\n",
220
+ " <th>count</th>\n",
221
+ " <th>mean</th>\n",
222
+ " <th>std</th>\n",
223
+ " <th>min</th>\n",
224
+ " <th>25%</th>\n",
225
+ " <th>50%</th>\n",
226
+ " <th>75%</th>\n",
227
+ " <th>max</th>\n",
228
+ " </tr>\n",
229
+ " <tr>\n",
230
+ " <th>method</th>\n",
231
+ " <th></th>\n",
232
+ " <th></th>\n",
233
+ " <th></th>\n",
234
+ " <th></th>\n",
235
+ " <th></th>\n",
236
+ " <th></th>\n",
237
+ " <th></th>\n",
238
+ " <th></th>\n",
239
+ " </tr>\n",
240
+ " </thead>\n",
241
+ " <tbody>\n",
242
+ " <tr>\n",
243
+ " <th>array.inject</th>\n",
244
+ " <td>100.0</td>\n",
245
+ " <td>0.013103</td>\n",
246
+ " <td>0.001518</td>\n",
247
+ " <td>0.012029</td>\n",
248
+ " <td>0.012350</td>\n",
249
+ " <td>0.012590</td>\n",
250
+ " <td>0.013337</td>\n",
251
+ " <td>0.022215</td>\n",
252
+ " </tr>\n",
253
+ " <tr>\n",
254
+ " <th>array.sum</th>\n",
255
+ " <td>100.0</td>\n",
256
+ " <td>0.001882</td>\n",
257
+ " <td>0.000372</td>\n",
258
+ " <td>0.001498</td>\n",
259
+ " <td>0.001587</td>\n",
260
+ " <td>0.001804</td>\n",
261
+ " <td>0.002008</td>\n",
262
+ " <td>0.003009</td>\n",
263
+ " </tr>\n",
264
+ " <tr>\n",
265
+ " <th>enum.inject</th>\n",
266
+ " <td>100.0</td>\n",
267
+ " <td>0.023528</td>\n",
268
+ " <td>0.002267</td>\n",
269
+ " <td>0.021078</td>\n",
270
+ " <td>0.021782</td>\n",
271
+ " <td>0.023041</td>\n",
272
+ " <td>0.024574</td>\n",
273
+ " <td>0.033859</td>\n",
274
+ " </tr>\n",
275
+ " <tr>\n",
276
+ " <th>enum.sum</th>\n",
277
+ " <td>100.0</td>\n",
278
+ " <td>0.010069</td>\n",
279
+ " <td>0.001304</td>\n",
280
+ " <td>0.009078</td>\n",
281
+ " <td>0.009221</td>\n",
282
+ " <td>0.009463</td>\n",
283
+ " <td>0.010708</td>\n",
284
+ " <td>0.018378</td>\n",
285
+ " </tr>\n",
286
+ " <tr>\n",
287
+ " <th>while</th>\n",
288
+ " <td>100.0</td>\n",
289
+ " <td>0.011932</td>\n",
290
+ " <td>0.001089</td>\n",
291
+ " <td>0.011079</td>\n",
292
+ " <td>0.011357</td>\n",
293
+ " <td>0.011491</td>\n",
294
+ " <td>0.012085</td>\n",
295
+ " <td>0.018309</td>\n",
296
+ " </tr>\n",
297
+ " </tbody>\n",
298
+ "</table>"
299
+ ],
300
+ "text/plain": [
301
+ "#<Object:0x007fd93f0727e8 @__pyptr__=#<PyCall::PyPtr:0x007fd93f0727c0 type=DataFrame addr=0x00000117195c50>>"
302
+ ]
303
+ },
304
+ "execution_count": 9,
305
+ "metadata": {},
306
+ "output_type": "execute_result"
307
+ }
308
+ ],
309
+ "source": [
310
+ "df = pd.DataFrame.new(data: {method: method, runtime: runtime})\n",
311
+ "df.groupby('method').describe()"
312
+ ]
313
+ },
314
+ {
315
+ "cell_type": "code",
316
+ "execution_count": 10,
317
+ "metadata": {},
318
+ "outputs": [
319
+ {
320
+ "data": {
321
+ "image/png": "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cPDgQbRu3VrtOq1bt1aqDwD79+9Xql+ULCUmJuLAgQOwtrZWaePJkyc4f/68WHbo0CEoFAp4enqWx64RERHRG0SvPUwAEBYWhuDgYDRv3hwtW7ZEZGQksrOzMXjwYABAUFAQatWqhYiICADA+PHj4eXlhSVLlsDX1xebN2/GuXPnsG7dOgDPk6V+/fohLi4Ou3fvRmFhoTguycrKClKpFI0aNcIHH3yAYcOGYc2aNXj27BnGjh2LAQMGaHWHHBEREb1d9J4wBQQE4MGDB5g1axZSU1Ph7u6OmJgYcWB3cnIyjIz+6whr06YNNm3ahJkzZ2L69Olo0KABdu7cCVdXVwDAnTt3sGvXLgCAu7u70rYOHz6Mjh07AgCio6MxduxYdOnSBUZGRujbty+WLVv2CvaYiIiIXjd6n4fpdcV5mIjoTcF5mF4O52F6vbyW8zARERERvQ6YMBERERFpwISJiIiISAMmTEREREQaMGEiIiIi0oAJExEREZEGTJiIiIiINGDCRERERKQBEyYiIiIiDZgwEREREWnAhImIiIhIAyZMRERERBowYSIiIiLSgAkTERERkQZMmIiIiIg0YMJEREREpAETJiIiIiINmDARERERacCEiYiIiEgDJkxEREREGjBhIiIiItKACRMRERGRBkyYiIiIiDRgwkRERESkARMmIiIiIg2YMBERERFpUEmbSsuWLdO54cGDB6NKlSo6r0dERERkaLRKmCZMmIDatWvD2NhYq0Zv376NHj16MGEiIiKiN4JWCRMAnDt3DjVq1NCqLhMlIiIiepNoNYYpPDwccrlc60anT58OKyurMgdFREREZEgkgiAI+g7idZSRkQFLS0ukp6fDwsJC3+EQEZXZ0Q5e+g7hteZ17Ki+QyAdlPXvt853ySUlJSExMVGlPDExETdv3tS1OSIiIiKDp3PCFBISglOnTqmUnz59GiEhIeURExEREZFB0Tlhio+PR9u2bVXKW7VqhQsXLpRLUERERESGROeESSKRIDMzU6U8PT0dhYWF5RIUERERkSHROWHq0KEDIiIilJKjwsJCREREoF27duUaHBEREZEh0HoepiILFy5Ehw4d0LBhQ7Rv3x4AcPz4cWRkZODQoUPlHiARERGRvuncw9S4cWMkJCSgf//+uH//PjIzMxEUFIQrV67A1dW1ImIkIiIi0iude5gAwN7e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ERGR3ujcwxQWFoaQkBAkJiZCJpOJ5d27d8exY8fKNTgiIiIiQ6BzwnT27FmMGDFCpbxWrVpITU0tl6CIiIiIDInOCZOpqSkyMjJUyv/55x/Y2NiUS1BEREREhkTnhKlnz5744osv8OzZMwCARCJBcnIypkyZgr59+5Z7gERERET6pnPCtGTJEmRlZaFGjRrIycmBl5cX6tevjypVquDLL7+siBiJiIiI9Ernu+QsLS2xf/9+nDhxAgkJCcjKysJ7770Hb2/vioiPiIiISO90Tphu376NOnXqoF27dmjXrl1FxERERERkUHS+JFevXj14eXlh/fr1ePz4cUXERERERGRQdE6Yzp07h5YtW+KLL75AzdE0wWYAACAASURBVJo14efnh23btiEvL68i4iMiIiLSO50TpnfffReLFy9GcnIyfv/9d9jY2GD48OGwtbXFkCFDKiJGIiIiIr0q02/JAc+nE+jUqRPWr1+PAwcOwNHRET/88EN5xkZERERkEMqcMP37779YtGgR3N3d0bJlS8jlcqxcubI8YyMiIiIyCDrfJbd27Vps2rQJJ0+ehIuLCwYNGoRffvkFDg4OFREfERERkd7pnDDNmzcPgYGBWLZsGZo1a1YRMREREREZFJ0TpuTkZEgkErXLLl26BFdX15cOioiIiMiQ6DyG6cVkKTMzE+vWrUPLli3Z40RERERvpDIP+j527BiCg4NRs2ZNfPXVV+jcuTP++OOP8oyNiIiIyCDodEkuNTUVGzZswHfffYeMjAz0798feXl52LlzJxo3blxRMRIRERHpldY9TB9++CEaNmyIhIQEREZG4u7du1i+fHlFxkZERERkELTuYfr9998RGhqKUaNGoUGDBhUZExEREZFB0bqH6cSJE8jMzISHhwc8PT2xYsUKPHz4sCJjIyIiIjIIWidMrVq1wvr165GSkoIRI0Zg8+bNsLe3h0KhwP79+5GZmVmRcRIRERHpjc53yZmbm2PIkCE4ceIELl68iE8//RQLFixAjRo10LNnz4qIkYiIiEivyjytAAA0bNgQixYtwr///ov//e9/5RUTERERkUF5qYSpiLGxMfz8/LBr167yaI6IiIjIoJRLwkRERET0JmPCRERERKQBEyYiIiIiDZgwEREREWnAhImIiIhIAyZMRERERBowYSIiIiLSgAkTERERkQZMmIiIiIg0YMJEREREpAETJiIiIiINmDARERERacCEiYiIiEgDJkxEREREGjBhIiIiItKACRMRERGRBkyYiIiIiDRgwkRERESkARMmIiIiIg2YMBERERFpwITp/7d353FR1fv/wF8DCAy7gA5gCnhFGBMXtEjShhQFtwtZaWaChsvVXBCXpC/gQl5cck2L3AjKwmyxbiaWJK4EAqKpiGh4tRuIaywKwvD5/eGPU6ODI4oOyOv5ePDQ+Zz3+Zz35yzwnnPOnCEiIiLSgQUTERERkQ4smIiIiIh0YMFEREREpAMLJiIiIiIdWDARERER6cCCiYiIiEiHRlEwrVu3Di4uLjA1NYW3tzcyMjLuGb9t2zZ4eHjA1NQUnp6e+OGHHzSmCyEQHR0NR0dHyOVy+Pn5IT8/XyPGxcUFMplM42fx4sUNPjYiIiJq+vReMG3duhXh4eGYN28esrOz0bVrV/j7+6O4uFhr/KFDhzBy5EiEhobiyJEjCAoKQlBQEI4fPy7FLF26FGvWrEFcXBzS09Nhbm4Of39/VFRUaPS1cOFCFBYWSj9Tp059pGMlIiKipknvBdOKFSswfvx4jB07Fp06dUJcXBzMzMywefNmrfGrV69GQEAAZs+eDaVSiZiYGHh5eWHt2rUAbp9dWrVqFSIjIxEYGIguXbogMTERf/zxB7Zv367Rl6WlJRwcHKQfc3PzRz5eIiIianr0WjDdunULWVlZ8PPzk9oMDAzg5+eHtLQ0rfOkpaVpxAOAv7+/FF9QUICioiKNGGtra3h7e9/V5+LFi2FnZ4fu3btj2bJlqK6urjPXyspKlJSUaPwQERFR82Ckz4VfvnwZarUaCoVCo12hUODUqVNa5ykqKtIaX1RUJE2vbasrBgCmTZsGLy8v2Nra4tChQ4iIiEBhYSFWrFihdbmxsbFYsGBB/QZIRERETwS9Fkz6FB4eLv2/S5cuMDY2xsSJExEbGwsTE5O74iMiIjTmKSkpQdu2bR9LrkRERKRfer0kZ29vD0NDQ1y8eFGj/eLFi3BwcNA6j4ODwz3ja/+tT58A4O3tjerqapw7d07rdBMTE1hZWWn8EBERUfOg14LJ2NgYPXr0QEpKitRWU1ODlJQU9OrVS+s8vXr10ogHgJ9++kmKd3V1hYODg0ZMSUkJ0tPT6+wTAHJycmBgYIDWrVs/zJCIiIjoCaT3S3Lh4eEICQlBz5498eyzz2LVqlUoLy/H2LFjAQDBwcFo06YNYmNjAQDTp0+HSqXC8uXLMXjwYCQlJSEzMxPr168HAMhkMoSFheHdd9+Fm5sbXF1dERUVBScnJwQFBQG4feN4eno6XnzxRVhaWiItLQ0zZszAG2+8gZYtW+pnRRAREVGjpfeCacSIEbh06RKio6NRVFSEbt26ITk5Wbpp+/z58zAw+OtEmI+PDz777DNERkbinXfegZubG7Zv347OnTtLMXPmzEF5eTkmTJiA69evo3fv3khOToapqSmA25fXkpKSMH/+fFRWVsLV1RUzZszQuEeJiIiIqJZMCCH0nURTVFJSAmtra/z555+8n6kJOb/QU98pNFnton9t0P6ef//5Bu2vOTk49WCD9rf3BVWD9tfcqPbtbbC+1s78T4P11RxNWT5UZ8yD/v3W+4MriYiIiBo7FkxEREREOrBgIiIiItKBBRMRERGRDiyYiIiIiHRgwURERESkAwsmIiIiIh1YMBERERHpwIKJiIiISAcWTEREREQ6sGAiIiIi0oEFExEREZEOLJiIiIiIdGDBRERERKQDCyYiIiIiHVgwEREREenAgomIiIhIBxZMRERERDqwYCIiIiLSgQUTERERkQ4smIiIiIh0YMFEREREpAMLJiIiIiIdWDARERER6cCCiYiIiEgHFkxEREREOrBgIiIiItKBBRMRERGRDiyYiIiIiHRgwURERESkAwsmIiIiIh1YMBERERHpwIKJiIiISAcWTEREREQ6sGAiIiIi0oEFExEREZEORvpOgB6vsrIyFBQU4ObNmygsLJTaHR0dIZfL4erqCgsLCz1mSERE1PiwYGpmCgoKEBYWVuf0VatWwdPT8zFmRERE1Pjxklwzc/PmzYeaTkRE1BzxDNNj0GN2or5TkBhfOgWze0yf/sF23Np26rHlo0vWsmB9p0BERMQzTM2N2vje9yfpmk5ERNQcsWBqbgxbPNx0IiKiZoiX5JoZtbwlSjsGAOpqGN4q/avd2BIwNIJa3lKP2RERETVOLJiaG0NjqC0UAAC1nlMhIiJqKnhJjoiIiEgHFkxEREREOrBgIiIiItKBBRMRERGRDiyYiIiIiHRgwURERESkAwsmIiIiIh1YMBERERHpwIKJiIiISAcWTEREREQ6sGAiIiIi0oEFExEREZEOLJiIiIiIdGDBRERERKQD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",
322
+ "text/plain": [
323
+ "#<Matplotlib::Figure:0x007fd93f02a650 @__pyptr__=#<PyCall::PyPtr:0x007fd93f02a6a0 type=Figure addr=0x00000117192358>>"
324
+ ]
325
+ },
326
+ "execution_count": 10,
327
+ "metadata": {},
328
+ "output_type": "execute_result"
329
+ },
330
+ {
331
+ "data": {
332
+ "text/plain": [
333
+ "#<Object:0x007fd93f020088 @__pyptr__=#<PyCall::PyPtr:0x007fd93f020010 type=Text addr=0x000001176abe10>>"
334
+ ]
335
+ },
336
+ "execution_count": 10,
337
+ "metadata": {},
338
+ "output_type": "execute_result"
339
+ }
340
+ ],
341
+ "source": [
342
+ "sns.barplot(x: 'method', y: 'runtime', data: df, errwidth: 2.5, capsize: 0.04)\n",
343
+ "plt = Matplotlib::Pyplot\n",
344
+ "plt.title(\"Array and Enumerable summation benchmark (#{trials} trials)\")\n",
345
+ "plt.xlabel(\"Summation method\")\n",
346
+ "plt.ylabel(\"Average runtime [sec]\")"
347
+ ]
348
+ },
349
+ {
350
+ "cell_type": "code",
351
+ "execution_count": null,
352
+ "metadata": {
353
+ "collapsed": true
354
+ },
355
+ "outputs": [],
356
+ "source": []
357
+ }
358
+ ],
359
+ "metadata": {
360
+ "kernelspec": {
361
+ "display_name": "Ruby 2.4.1",
362
+ "language": "ruby",
363
+ "name": "ruby"
364
+ },
365
+ "language_info": {
366
+ "file_extension": ".rb",
367
+ "mimetype": "application/x-ruby",
368
+ "name": "ruby",
369
+ "version": "2.4.1"
370
+ }
371
+ },
372
+ "nbformat": 4,
373
+ "nbformat_minor": 2
374
+ }