├── LICENSE.md
├── README.md
├── apt.txt
├── examples
├── Elman_srnn.png
├── Feed-Forward-Recurrent-NN.ipynb
├── Feed_forward_neural_net.gif
├── Pattern-Recognition.ipynb
├── Simple-Example.ipynb
├── Stateful-Goroutines.ipynb
├── Time-Formatting-Parsing.ipynb
├── Worker-Pools.ipynb
└── iris.jpg
├── index.ipynb
└── postBuild
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | mybinder-go
2 | =========
3 |
4 | A [mybinder](https://mybinder.org) compatible Jupyter notebook for [Go](https://golang.org).
5 |
6 | [](https://mybinder.org/v2/gh/gopherdata/mybinder-go/master?urlpath=lab)
7 |
8 |
--------------------------------------------------------------------------------
/apt.txt:
--------------------------------------------------------------------------------
1 | build-essential
2 | ca-certificates
3 | curl
4 | gcc
5 | git
6 | libgles2
7 | libgles2-mesa-dev
8 | mercurial
9 | pkg-config
10 | python3-pip
11 |
--------------------------------------------------------------------------------
/examples/Elman_srnn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gopherdata/mybinder-go/5416b6cd1576b545a8d8c98574b4df55d8cfbd23/examples/Elman_srnn.png
--------------------------------------------------------------------------------
/examples/Feed-Forward-Recurrent-NN.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {
7 | "collapsed": true
8 | },
9 | "outputs": [],
10 | "source": [
11 | "import \"github.com/goml/gobrain\""
12 | ]
13 | },
14 | {
15 | "cell_type": "code",
16 | "execution_count": 2,
17 | "metadata": {
18 | "collapsed": true
19 | },
20 | "outputs": [],
21 | "source": [
22 | "import \"math/rand\""
23 | ]
24 | },
25 | {
26 | "cell_type": "markdown",
27 | "metadata": {},
28 | "source": [
29 | "# Feed Forward vs. Recurrent Neural Networks"
30 | ]
31 | },
32 | {
33 | "cell_type": "markdown",
34 | "metadata": {},
35 | "source": [
36 | "(comments from [wikipedia](https://en.wikipedia.org), examples from the [gobrain](https://github.com/goml/gobrain) documentation)"
37 | ]
38 | },
39 | {
40 | "cell_type": "markdown",
41 | "metadata": {},
42 | "source": [
43 | "## Feed Forward Description:"
44 | ]
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "metadata": {},
49 | "source": [
50 | "
"
51 | ]
52 | },
53 | {
54 | "cell_type": "markdown",
55 | "metadata": {},
56 | "source": [
57 | "A feedforward neural network is an artificial neural network where connections between the units do not form a cycle. This is different from recurrent neural networks.\n",
58 | "\n",
59 | "The feedforward neural network was the first and simplest type of artificial neural network devised. In this network, the information moves in only one direction, forward, from the input nodes, through the hidden nodes (if any) and to the output nodes. There are no cycles or loops in the network."
60 | ]
61 | },
62 | {
63 | "cell_type": "markdown",
64 | "metadata": {},
65 | "source": [
66 | "## [Gobrain](https://github.com/goml/gobrain) Example - Feed Forward Function"
67 | ]
68 | },
69 | {
70 | "cell_type": "code",
71 | "execution_count": 3,
72 | "metadata": {
73 | "collapsed": true
74 | },
75 | "outputs": [],
76 | "source": [
77 | "// set the random seed to 0\n",
78 | "rand.Seed(0)"
79 | ]
80 | },
81 | {
82 | "cell_type": "code",
83 | "execution_count": 4,
84 | "metadata": {
85 | "collapsed": false
86 | },
87 | "outputs": [
88 | {
89 | "data": {
90 | "text/plain": [
91 | "&gobrain.\u001b[32mFeedForward\u001b[0m{\n",
92 | " \u001b[33mNInputs\u001b[0m: \u001b[34m\u001b[1m0\u001b[0m,\n",
93 | " \u001b[33mNHiddens\u001b[0m: \u001b[34m\u001b[1m0\u001b[0m,\n",
94 | " \u001b[33mNOutputs\u001b[0m: \u001b[34m\u001b[1m0\u001b[0m,\n",
95 | " \u001b[33mRegression\u001b[0m: \u001b[36m\u001b[1mfalse\u001b[0m,\n",
96 | " \u001b[33mInputActivations\u001b[0m: []\u001b[32mfloat64\u001b[0m{},\n",
97 | " \u001b[33mHiddenActivations\u001b[0m: []\u001b[32mfloat64\u001b[0m{},\n",
98 | " \u001b[33mOutputActivations\u001b[0m: []\u001b[32mfloat64\u001b[0m{},\n",
99 | " \u001b[33mContexts\u001b[0m: []\u001b[32m[]float64\u001b[0m{},\n",
100 | " \u001b[33mInputWeights\u001b[0m: []\u001b[32m[]float64\u001b[0m{},\n",
101 | " \u001b[33mOutputWeights\u001b[0m: []\u001b[32m[]float64\u001b[0m{},\n",
102 | " \u001b[33mInputChanges\u001b[0m: []\u001b[32m[]float64\u001b[0m{},\n",
103 | " \u001b[33mOutputChanges\u001b[0m: []\u001b[32m[]float64\u001b[0m{},\n",
104 | "}\n"
105 | ]
106 | },
107 | "execution_count": 4,
108 | "metadata": {},
109 | "output_type": "execute_result"
110 | }
111 | ],
112 | "source": [
113 | "// create the XOR representation patter to train the network\n",
114 | "patterns := [][][]float64{\n",
115 | " {{0, 0}, {0}},\n",
116 | " {{0, 1}, {1}},\n",
117 | " {{1, 0}, {1}},\n",
118 | " {{1, 1}, {0}},\n",
119 | "}\n",
120 | "\n",
121 | "// instantiate the Feed Forward\n",
122 | "ff := &gobrain.FeedForward{}"
123 | ]
124 | },
125 | {
126 | "cell_type": "code",
127 | "execution_count": 5,
128 | "metadata": {
129 | "collapsed": true
130 | },
131 | "outputs": [],
132 | "source": [
133 | "// initialize the Neural Network;\n",
134 | "// the networks structure will contain:\n",
135 | "// 2 inputs, 2 hidden nodes and 1 output.\n",
136 | "ff.Init(2, 2, 1)"
137 | ]
138 | },
139 | {
140 | "cell_type": "code",
141 | "execution_count": 6,
142 | "metadata": {
143 | "collapsed": false
144 | },
145 | "outputs": [
146 | {
147 | "data": {
148 | "text/plain": [
149 | "0 0.5524794213542835\n",
150 | "[0 0] -> [0.05750394570844524] : [0]\n",
151 | "[0 1] -> [0.9301006350712102] : [1]\n",
152 | "[1 0] -> [0.927809966227284] : [1]\n",
153 | "[1 1] -> [0.09740879532462095] : [0]\n"
154 | ]
155 | },
156 | "execution_count": 6,
157 | "metadata": {},
158 | "output_type": "execute_result"
159 | }
160 | ],
161 | "source": [
162 | "// train the network using the XOR patterns\n",
163 | "// the training will run for 1000 epochs\n",
164 | "// the learning rate is set to 0.6 and the momentum factor to 0.4\n",
165 | "// use true in the last parameter to receive reports about the learning error\n",
166 | "ff.Train(patterns, 1000, 0.6, 0.4, true)\n",
167 | "ff.Test(patterns)"
168 | ]
169 | },
170 | {
171 | "cell_type": "markdown",
172 | "metadata": {},
173 | "source": [
174 | "Where the first values are the inputs, the values after the arrow `->` are the output values from the network and the values after `:` are the expected outputs."
175 | ]
176 | },
177 | {
178 | "cell_type": "markdown",
179 | "metadata": {},
180 | "source": [
181 | "## Recurrent Description:"
182 | ]
183 | },
184 | {
185 | "cell_type": "markdown",
186 | "metadata": {},
187 | "source": [
188 | "
"
189 | ]
190 | },
191 | {
192 | "cell_type": "markdown",
193 | "metadata": {},
194 | "source": [
195 | "A recurrent neural network (RNN) is a class of artificial neural network where connections between units form a directed cycle. This creates an internal state of the network which allows it to exhibit dynamic temporal behavior. Unlike feedforward neural networks, RNNs can use their internal memory to process arbitrary sequences of inputs. This makes them applicable to tasks such as unsegmented connected handwriting recognition or speech recognition."
196 | ]
197 | },
198 | {
199 | "cell_type": "markdown",
200 | "metadata": {},
201 | "source": [
202 | "## [Gobrain](https://github.com/goml/gobrain) - Recurrent Example"
203 | ]
204 | },
205 | {
206 | "cell_type": "markdown",
207 | "metadata": {},
208 | "source": [
209 | "Gobrain implements Elman's Simple Recurrent Network. To take advantage of this, one can use the `SetContexts` function."
210 | ]
211 | },
212 | {
213 | "cell_type": "code",
214 | "execution_count": 7,
215 | "metadata": {
216 | "collapsed": false
217 | },
218 | "outputs": [
219 | {
220 | "data": {
221 | "text/plain": [
222 | "0 0.5524794213542835\n",
223 | "[0 0] -> [0.05750394570844524] : [0]\n",
224 | "[0 1] -> [0.9301006350712102] : [1]\n",
225 | "[1 0] -> [0.927809966227284] : [1]\n",
226 | "[1 1] -> [0.09740879532462095] : [0]\n"
227 | ]
228 | },
229 | "execution_count": 7,
230 | "metadata": {},
231 | "output_type": "execute_result"
232 | }
233 | ],
234 | "source": [
235 | "ff.SetContexts(1, nil)"
236 | ]
237 | },
238 | {
239 | "cell_type": "markdown",
240 | "metadata": {},
241 | "source": [
242 | "In the example above, a single context will be created initilized with 0.5. "
243 | ]
244 | }
245 | ],
246 | "metadata": {
247 | "kernelspec": {
248 | "display_name": "Golang",
249 | "language": "go",
250 | "name": "gophernotes"
251 | },
252 | "language_info": {
253 | "name": "go"
254 | }
255 | },
256 | "nbformat": 4,
257 | "nbformat_minor": 0
258 | }
259 |
--------------------------------------------------------------------------------
/examples/Feed_forward_neural_net.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gopherdata/mybinder-go/5416b6cd1576b545a8d8c98574b4df55d8cfbd23/examples/Feed_forward_neural_net.gif
--------------------------------------------------------------------------------
/examples/Pattern-Recognition.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Imports"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": 1,
13 | "metadata": {
14 | "collapsed": true
15 | },
16 | "outputs": [],
17 | "source": [
18 | "import \"fmt\""
19 | ]
20 | },
21 | {
22 | "cell_type": "code",
23 | "execution_count": 2,
24 | "metadata": {
25 | "collapsed": false
26 | },
27 | "outputs": [],
28 | "source": [
29 | "import \"github.com/sjwhitworth/golearn/base\""
30 | ]
31 | },
32 | {
33 | "cell_type": "code",
34 | "execution_count": 3,
35 | "metadata": {
36 | "collapsed": true
37 | },
38 | "outputs": [],
39 | "source": [
40 | "import \"github.com/sjwhitworth/golearn/evaluation\""
41 | ]
42 | },
43 | {
44 | "cell_type": "code",
45 | "execution_count": 4,
46 | "metadata": {
47 | "collapsed": true
48 | },
49 | "outputs": [],
50 | "source": [
51 | "import \"github.com/sjwhitworth/golearn/knn\""
52 | ]
53 | },
54 | {
55 | "cell_type": "markdown",
56 | "metadata": {},
57 | "source": [
58 | "# Problem/Data Description"
59 | ]
60 | },
61 | {
62 | "cell_type": "markdown",
63 | "metadata": {},
64 | "source": [
65 | "
"
66 | ]
67 | },
68 | {
69 | "cell_type": "markdown",
70 | "metadata": {},
71 | "source": [
72 | "Information about this dataset comes from [here](https://archive.ics.uci.edu/ml/datasets/Iris)"
73 | ]
74 | },
75 | {
76 | "cell_type": "markdown",
77 | "metadata": {},
78 | "source": [
79 | "## Data Set Information:"
80 | ]
81 | },
82 | {
83 | "cell_type": "markdown",
84 | "metadata": {},
85 | "source": [
86 | "This is perhaps the best known database to be found in the pattern recognition literature. Fisher's paper is a classic in the field and is referenced frequently to this day. (See Duda & Hart, for example.) The data set contains 3 classes of 50 instances each, where each class refers to a type of iris plant. One class is linearly separable from the other 2; the latter are NOT linearly separable from each other. \n",
87 | "\n",
88 | "Predicted attribute: class of iris plant. "
89 | ]
90 | },
91 | {
92 | "cell_type": "markdown",
93 | "metadata": {},
94 | "source": [
95 | "## Attribute Information:"
96 | ]
97 | },
98 | {
99 | "cell_type": "markdown",
100 | "metadata": {},
101 | "source": [
102 | "1. sepal length in cm \n",
103 | "2. sepal width in cm \n",
104 | "3. petal length in cm \n",
105 | "4. petal width in cm \n",
106 | "5. class: \n",
107 | "-- Iris Setosa \n",
108 | "-- Iris Versicolour \n",
109 | "-- Iris Virginica"
110 | ]
111 | },
112 | {
113 | "cell_type": "markdown",
114 | "metadata": {},
115 | "source": [
116 | "# Building a Pattern Recognition Model"
117 | ]
118 | },
119 | {
120 | "cell_type": "markdown",
121 | "metadata": {},
122 | "source": [
123 | "This example model comes from the [golearn](https://github.com/sjwhitworth/golearn) documentation."
124 | ]
125 | },
126 | {
127 | "cell_type": "code",
128 | "execution_count": 5,
129 | "metadata": {
130 | "collapsed": false
131 | },
132 | "outputs": [
133 | {
134 | "data": {
135 | "text/plain": [
136 | "Optimisations are switched off\n",
137 | "KNN: 1.14 % done\n",
138 | "KNN: 2.27 % done\n",
139 | "KNN: 3.41 % done\n",
140 | "KNN: 4.55 % done\n",
141 | "KNN: 5.68 % done\n",
142 | "KNN: 6.82 % done\n",
143 | "KNN: 7.95 % done\n",
144 | "KNN: 9.09 % done\n",
145 | "KNN: 10.23 % done\n",
146 | "KNN: 11.36 % done\n",
147 | "KNN: 12.50 % done\n",
148 | "KNN: 13.64 % done\n",
149 | "KNN: 14.77 % done\n",
150 | "KNN: 15.91 % done\n",
151 | "KNN: 17.05 % done\n",
152 | "KNN: 18.18 % done\n",
153 | "KNN: 19.32 % done\n",
154 | "KNN: 20.45 % done\n",
155 | "KNN: 21.59 % done\n",
156 | "KNN: 22.73 % done\n",
157 | "KNN: 23.86 % done\n",
158 | "KNN: 25.00 % done\n",
159 | "KNN: 26.14 % done\n",
160 | "KNN: 27.27 % done\n",
161 | "KNN: 28.41 % done\n",
162 | "KNN: 29.55 % done\n",
163 | "KNN: 30.68 % done\n",
164 | "KNN: 31.82 % done\n",
165 | "KNN: 32.95 % done\n",
166 | "KNN: 34.09 % done\n",
167 | "KNN: 35.23 % done\n",
168 | "KNN: 36.36 % done\n",
169 | "KNN: 37.50 % done\n",
170 | "KNN: 38.64 % done\n",
171 | "KNN: 39.77 % done\n",
172 | "KNN: 40.91 % done\n",
173 | "KNN: 42.05 % done\n",
174 | "KNN: 43.18 % done\n",
175 | "KNN: 44.32 % done\n",
176 | "KNN: 45.45 % done\n",
177 | "KNN: 46.59 % done\n",
178 | "KNN: 47.73 % done\n",
179 | "KNN: 48.86 % done\n",
180 | "KNN: 50.00 % done\n",
181 | "KNN: 51.14 % done\n",
182 | "KNN: 52.27 % done\n",
183 | "KNN: 53.41 % done\n",
184 | "KNN: 54.55 % done\n",
185 | "KNN: 55.68 % done\n",
186 | "KNN: 56.82 % done\n",
187 | "KNN: 57.95 % done\n",
188 | "KNN: 59.09 % done\n",
189 | "KNN: 60.23 % done\n",
190 | "KNN: 61.36 % done\n",
191 | "KNN: 62.50 % done\n",
192 | "KNN: 63.64 % done\n",
193 | "KNN: 64.77 % done\n",
194 | "KNN: 65.91 % done\n",
195 | "KNN: 67.05 % done\n",
196 | "KNN: 68.18 % done\n",
197 | "KNN: 69.32 % done\n",
198 | "KNN: 70.45 % done\n",
199 | "KNN: 71.59 % done\n",
200 | "KNN: 72.73 % done\n",
201 | "KNN: 73.86 % done\n",
202 | "KNN: 75.00 % done\n",
203 | "KNN: 76.14 % done\n",
204 | "KNN: 77.27 % done\n",
205 | "KNN: 78.41 % done\n",
206 | "KNN: 79.55 % done\n",
207 | "KNN: 80.68 % done\n",
208 | "KNN: 81.82 % done\n",
209 | "KNN: 82.95 % done\n",
210 | "KNN: 84.09 % done\n",
211 | "KNN: 85.23 % done\n",
212 | "KNN: 86.36 % done\n",
213 | "KNN: 87.50 % done\n",
214 | "KNN: 88.64 % done\n",
215 | "KNN: 89.77 % done\n",
216 | "KNN: 90.91 % done\n",
217 | "KNN: 92.05 % done\n",
218 | "KNN: 93.18 % done\n",
219 | "KNN: 94.32 % done\n",
220 | "KNN: 95.45 % done\n",
221 | "KNN: 96.59 % done\n",
222 | "KNN: 97.73 % done\n",
223 | "KNN: 98.86 % done\n",
224 | "Reference Class\tTrue Positives\tFalse Positives\tTrue Negatives\tPrecision\tRecall\tF1 Score\n",
225 | "---------------\t--------------\t---------------\t--------------\t---------\t------\t--------\n",
226 | "Iris-setosa\t30\t\t0\t\t58\t\t1.0000\t\t1.0000\t1.0000\n",
227 | "Iris-virginica\t27\t\t1\t\t58\t\t0.9643\t\t0.9310\t0.9474\n",
228 | "Iris-versicolor\t28\t\t2\t\t57\t\t0.9333\t\t0.9655\t0.9492\n",
229 | "Overall accuracy: 0.9659\n",
230 | "\n"
231 | ]
232 | },
233 | "execution_count": 5,
234 | "metadata": {},
235 | "output_type": "execute_result"
236 | }
237 | ],
238 | "source": [
239 | "// Load in a dataset, with headers. Header attributes will be stored.\n",
240 | "// Think of instances as a Data Frame structure in R or Pandas.\n",
241 | "// You can also create instances from scratch.\n",
242 | "rawData, err := base.ParseCSVToInstances(\"datasets/iris.csv\", false)\n",
243 | "\n",
244 | "//Initialises a new KNN classifier\n",
245 | "cls := knn.NewKnnClassifier(\"euclidean\", 2)\n",
246 | "\n",
247 | "//Do a training-test split\n",
248 | "trainData, testData := base.InstancesTrainTestSplit(rawData, 0.50)\n",
249 | "cls.Fit(trainData)\n",
250 | "\n",
251 | "//Calculates the Euclidean distance and returns the most popular label\n",
252 | "predictions := cls.Predict(testData)\n",
253 | "\n",
254 | "// Calculate precision/recall metrics, and summarize results\n",
255 | "confusionMat, err := evaluation.GetConfusionMatrix(testData, predictions)\n",
256 | "fmt.Println(evaluation.GetSummary(confusionMat))"
257 | ]
258 | }
259 | ],
260 | "metadata": {
261 | "kernelspec": {
262 | "display_name": "Golang",
263 | "language": "go",
264 | "name": "gophernotes"
265 | },
266 | "language_info": {
267 | "name": "go"
268 | }
269 | },
270 | "nbformat": 4,
271 | "nbformat_minor": 0
272 | }
273 |
--------------------------------------------------------------------------------
/examples/Simple-Example.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Imports"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": 1,
13 | "metadata": {
14 | "collapsed": true
15 | },
16 | "outputs": [],
17 | "source": [
18 | "import \"fmt\""
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {},
24 | "source": [
25 | "# Hello World"
26 | ]
27 | },
28 | {
29 | "cell_type": "code",
30 | "execution_count": 2,
31 | "metadata": {
32 | "collapsed": false
33 | },
34 | "outputs": [
35 | {
36 | "data": {
37 | "text/plain": [
38 | "\u001b[31m\u001b[1m\"\u001b[0m\u001b[31mworld\u001b[0m\u001b[31m\u001b[1m\"\u001b[0m\n"
39 | ]
40 | },
41 | "execution_count": 2,
42 | "metadata": {},
43 | "output_type": "execute_result"
44 | }
45 | ],
46 | "source": [
47 | "world := \"world\""
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": 3,
53 | "metadata": {
54 | "collapsed": false
55 | },
56 | "outputs": [
57 | {
58 | "data": {
59 | "text/plain": [
60 | "\u001b[31m\u001b[1m\"\u001b[0m\u001b[31mhello world\u001b[0m\u001b[31m\u001b[1m\"\u001b[0m\n"
61 | ]
62 | },
63 | "execution_count": 3,
64 | "metadata": {},
65 | "output_type": "execute_result"
66 | }
67 | ],
68 | "source": [
69 | "fmt.Sprintf(\"hello %s\", world)"
70 | ]
71 | },
72 | {
73 | "cell_type": "markdown",
74 | "metadata": {},
75 | "source": [
76 | "# Channels"
77 | ]
78 | },
79 | {
80 | "cell_type": "markdown",
81 | "metadata": {},
82 | "source": [
83 | "Here is a simple example of a channel. "
84 | ]
85 | },
86 | {
87 | "cell_type": "code",
88 | "execution_count": 4,
89 | "metadata": {
90 | "collapsed": false
91 | },
92 | "outputs": [
93 | {
94 | "data": {
95 | "text/plain": [
96 | "(\u001b[32mchan string\u001b[0m)(\u001b[34m\u001b[1m0xc820018120\u001b[0m)\n"
97 | ]
98 | },
99 | "execution_count": 4,
100 | "metadata": {},
101 | "output_type": "execute_result"
102 | }
103 | ],
104 | "source": [
105 | "messages := make(chan string)"
106 | ]
107 | },
108 | {
109 | "cell_type": "code",
110 | "execution_count": 5,
111 | "metadata": {
112 | "collapsed": true
113 | },
114 | "outputs": [],
115 | "source": [
116 | "go func() { messages <- \"ping\" }()"
117 | ]
118 | },
119 | {
120 | "cell_type": "code",
121 | "execution_count": 6,
122 | "metadata": {
123 | "collapsed": false
124 | },
125 | "outputs": [
126 | {
127 | "data": {
128 | "text/plain": [
129 | "\u001b[31m\u001b[1m\"\u001b[0m\u001b[31mping\u001b[0m\u001b[31m\u001b[1m\"\u001b[0m\n"
130 | ]
131 | },
132 | "execution_count": 6,
133 | "metadata": {},
134 | "output_type": "execute_result"
135 | }
136 | ],
137 | "source": [
138 | "msg := <- messages"
139 | ]
140 | },
141 | {
142 | "cell_type": "code",
143 | "execution_count": null,
144 | "metadata": {
145 | "collapsed": true
146 | },
147 | "outputs": [],
148 | "source": []
149 | }
150 | ],
151 | "metadata": {
152 | "kernelspec": {
153 | "display_name": "Golang",
154 | "language": "go",
155 | "name": "gophernotes"
156 | },
157 | "language_info": {
158 | "name": "go"
159 | }
160 | },
161 | "nbformat": 4,
162 | "nbformat_minor": 0
163 | }
164 |
--------------------------------------------------------------------------------
/examples/Stateful-Goroutines.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Stateful Goroutines"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "To synchronize access to shared state across multiple goroutines, one option is to use the built-in synchronization features of goroutines and channels. This channel-based approach aligns with Go’s ideas of sharing memory by communicating and having each piece of data owned by exactly 1 goroutine.\n",
15 | "\n",
16 | "Comments from [Go by Example](https://gobyexample.com)."
17 | ]
18 | },
19 | {
20 | "cell_type": "code",
21 | "execution_count": 1,
22 | "metadata": {
23 | "collapsed": true
24 | },
25 | "outputs": [],
26 | "source": [
27 | "import \"fmt\""
28 | ]
29 | },
30 | {
31 | "cell_type": "code",
32 | "execution_count": 2,
33 | "metadata": {
34 | "collapsed": true
35 | },
36 | "outputs": [],
37 | "source": [
38 | "import \"math/rand\""
39 | ]
40 | },
41 | {
42 | "cell_type": "code",
43 | "execution_count": 3,
44 | "metadata": {
45 | "collapsed": true
46 | },
47 | "outputs": [],
48 | "source": [
49 | "import \"sync/atomic\""
50 | ]
51 | },
52 | {
53 | "cell_type": "code",
54 | "execution_count": 4,
55 | "metadata": {
56 | "collapsed": true
57 | },
58 | "outputs": [],
59 | "source": [
60 | "import \"time\""
61 | ]
62 | },
63 | {
64 | "cell_type": "markdown",
65 | "metadata": {},
66 | "source": [
67 | "## `structs` to Encapsulate Requests"
68 | ]
69 | },
70 | {
71 | "cell_type": "markdown",
72 | "metadata": {},
73 | "source": [
74 | "In this example our state will be owned by a single goroutine. This will guarantee that the data is never corrupted with concurrent access. In order to read or write that state, other goroutines will send messages to the owning goroutine and receive corresponding replies. These readOp and writeOp structs encapsulate those requests and a way for the owning goroutine to respond."
75 | ]
76 | },
77 | {
78 | "cell_type": "code",
79 | "execution_count": 5,
80 | "metadata": {
81 | "collapsed": true
82 | },
83 | "outputs": [],
84 | "source": [
85 | "type readOp struct {\n",
86 | " key int\n",
87 | " resp chan int\n",
88 | "}"
89 | ]
90 | },
91 | {
92 | "cell_type": "code",
93 | "execution_count": 6,
94 | "metadata": {
95 | "collapsed": true
96 | },
97 | "outputs": [],
98 | "source": [
99 | "type writeOp struct {\n",
100 | " key int\n",
101 | " val int\n",
102 | " resp chan bool\n",
103 | "}"
104 | ]
105 | },
106 | {
107 | "cell_type": "markdown",
108 | "metadata": {},
109 | "source": [
110 | "## Definitions"
111 | ]
112 | },
113 | {
114 | "cell_type": "markdown",
115 | "metadata": {},
116 | "source": [
117 | "Count how many operations we perform."
118 | ]
119 | },
120 | {
121 | "cell_type": "code",
122 | "execution_count": 7,
123 | "metadata": {
124 | "collapsed": true
125 | },
126 | "outputs": [],
127 | "source": [
128 | "var ops int64 = 0"
129 | ]
130 | },
131 | {
132 | "cell_type": "markdown",
133 | "metadata": {},
134 | "source": [
135 | "The reads and writes channels will be used by other goroutines to issue read and write requests, respectively."
136 | ]
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": 8,
141 | "metadata": {
142 | "collapsed": false
143 | },
144 | "outputs": [
145 | {
146 | "data": {
147 | "text/plain": [
148 | "(chan *main.\u001b[32mwriteOp\u001b[0m)(\u001b[34m\u001b[1m0xc820018180\u001b[0m)\n"
149 | ]
150 | },
151 | "execution_count": 8,
152 | "metadata": {},
153 | "output_type": "execute_result"
154 | }
155 | ],
156 | "source": [
157 | "reads := make(chan *readOp)\n",
158 | "writes := make(chan *writeOp)"
159 | ]
160 | },
161 | {
162 | "cell_type": "markdown",
163 | "metadata": {},
164 | "source": [
165 | "## Goroutines"
166 | ]
167 | },
168 | {
169 | "cell_type": "markdown",
170 | "metadata": {},
171 | "source": [
172 | "Here is the goroutine that owns the state, which is a map as in the previous example but now private to the stateful goroutine. This goroutine repeatedly selects on the reads and writes channels, responding to requests as they arrive. A response is executed by first performing the requested operation and then sending a value on the response channel resp to indicate success (and the desired value in the case of reads)."
173 | ]
174 | },
175 | {
176 | "cell_type": "code",
177 | "execution_count": 9,
178 | "metadata": {
179 | "collapsed": true
180 | },
181 | "outputs": [],
182 | "source": [
183 | "go func() {\n",
184 | " var state = make(map[int]int)\n",
185 | " for {\n",
186 | " select {\n",
187 | " case read := <-reads:\n",
188 | " read.resp <- state[read.key]\n",
189 | " case write := <-writes:\n",
190 | " state[write.key] = write.val\n",
191 | " write.resp <- true\n",
192 | " }\n",
193 | " }\n",
194 | "}()"
195 | ]
196 | },
197 | {
198 | "cell_type": "markdown",
199 | "metadata": {},
200 | "source": [
201 | "This starts 100 goroutines to issue reads to the state-owning goroutine via the reads channel. Each read requires constructing a readOp, sending it over the reads channel, and the receiving the result over the provided resp channel."
202 | ]
203 | },
204 | {
205 | "cell_type": "code",
206 | "execution_count": 10,
207 | "metadata": {
208 | "collapsed": true
209 | },
210 | "outputs": [],
211 | "source": [
212 | "for r := 0; r < 100; r++ {\n",
213 | " go func() {\n",
214 | " for {\n",
215 | " read := &readOp{\n",
216 | " key: rand.Intn(5),\n",
217 | " resp: make(chan int)}\n",
218 | " reads <- read\n",
219 | " <-read.resp\n",
220 | " atomic.AddInt64(&ops, 1)\n",
221 | " }\n",
222 | " }()\n",
223 | "}"
224 | ]
225 | },
226 | {
227 | "cell_type": "markdown",
228 | "metadata": {},
229 | "source": [
230 | "We start 10 writes as well, using a similar approach."
231 | ]
232 | },
233 | {
234 | "cell_type": "code",
235 | "execution_count": 11,
236 | "metadata": {
237 | "collapsed": true
238 | },
239 | "outputs": [],
240 | "source": [
241 | "for w := 0; w < 10; w++ {\n",
242 | " go func() {\n",
243 | " for {\n",
244 | " write := &writeOp{\n",
245 | " key: rand.Intn(5),\n",
246 | " val: rand.Intn(100),\n",
247 | " resp: make(chan bool)}\n",
248 | " writes <- write\n",
249 | " <-write.resp\n",
250 | " atomic.AddInt64(&ops, 1)\n",
251 | " }\n",
252 | " }()\n",
253 | "}\n",
254 | "// let the goroutines work for a second\n",
255 | "time.Sleep(time.Second)"
256 | ]
257 | },
258 | {
259 | "cell_type": "markdown",
260 | "metadata": {},
261 | "source": [
262 | "## Collect the Ops Count"
263 | ]
264 | },
265 | {
266 | "cell_type": "markdown",
267 | "metadata": {},
268 | "source": [
269 | "Let the goroutines work for a second. Finally, capture and report the ops count."
270 | ]
271 | },
272 | {
273 | "cell_type": "code",
274 | "execution_count": 12,
275 | "metadata": {
276 | "collapsed": false
277 | },
278 | "outputs": [
279 | {
280 | "data": {
281 | "text/plain": [
282 | "\u001b[34m\u001b[1m892297\u001b[0m\n"
283 | ]
284 | },
285 | "execution_count": 12,
286 | "metadata": {},
287 | "output_type": "execute_result"
288 | }
289 | ],
290 | "source": [
291 | "opsFinal := atomic.LoadInt64(&ops)"
292 | ]
293 | },
294 | {
295 | "cell_type": "markdown",
296 | "metadata": {},
297 | "source": [
298 | "Running our program shows that the goroutine-based state management example achieves about 800,000 operations per second."
299 | ]
300 | }
301 | ],
302 | "metadata": {
303 | "kernelspec": {
304 | "display_name": "Golang",
305 | "language": "go",
306 | "name": "gophernotes"
307 | },
308 | "language_info": {
309 | "name": "go"
310 | }
311 | },
312 | "nbformat": 4,
313 | "nbformat_minor": 0
314 | }
315 |
--------------------------------------------------------------------------------
/examples/Time-Formatting-Parsing.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Time Formatting / Parsing"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "Go supports time formatting and parsing via pattern-based layouts. Comments from [Go by Example](https://gobyexample.com)."
15 | ]
16 | },
17 | {
18 | "cell_type": "markdown",
19 | "metadata": {},
20 | "source": [
21 | "## Imports"
22 | ]
23 | },
24 | {
25 | "cell_type": "code",
26 | "execution_count": 1,
27 | "metadata": {
28 | "collapsed": true
29 | },
30 | "outputs": [],
31 | "source": [
32 | "import \"fmt\""
33 | ]
34 | },
35 | {
36 | "cell_type": "code",
37 | "execution_count": 2,
38 | "metadata": {
39 | "collapsed": true
40 | },
41 | "outputs": [],
42 | "source": [
43 | "import \"time\""
44 | ]
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "metadata": {},
49 | "source": [
50 | "## Basic Time Formatting"
51 | ]
52 | },
53 | {
54 | "cell_type": "markdown",
55 | "metadata": {},
56 | "source": [
57 | "Here’s a basic example of formatting a time according to RFC3339, using the corresponding layout constant."
58 | ]
59 | },
60 | {
61 | "cell_type": "code",
62 | "execution_count": 3,
63 | "metadata": {
64 | "collapsed": false
65 | },
66 | "outputs": [
67 | {
68 | "data": {
69 | "text/plain": [
70 | "\u001b[34m\u001b[1m2016\u001b[0m-\u001b[34m\u001b[1m01\u001b[0m-\u001b[34m\u001b[1m23\u001b[0m \u001b[34m\u001b[1m20\u001b[0m:\u001b[34m\u001b[1m14\u001b[0m:\u001b[34m\u001b[1m59\u001b[0m \u001b[34m\u001b[1mLocal\u001b[0m\n"
71 | ]
72 | },
73 | "execution_count": 3,
74 | "metadata": {},
75 | "output_type": "execute_result"
76 | }
77 | ],
78 | "source": [
79 | "t := time.Now()"
80 | ]
81 | },
82 | {
83 | "cell_type": "code",
84 | "execution_count": 4,
85 | "metadata": {
86 | "collapsed": false
87 | },
88 | "outputs": [
89 | {
90 | "data": {
91 | "text/plain": [
92 | "\u001b[31m\u001b[1m\"\u001b[0m\u001b[31m2016-01-23T20:15:00-06:00\u001b[0m\u001b[31m\u001b[1m\"\u001b[0m\n"
93 | ]
94 | },
95 | "execution_count": 4,
96 | "metadata": {},
97 | "output_type": "execute_result"
98 | }
99 | ],
100 | "source": [
101 | "t.Format(time.RFC3339)"
102 | ]
103 | },
104 | {
105 | "cell_type": "markdown",
106 | "metadata": {},
107 | "source": [
108 | "## Time Parsing"
109 | ]
110 | },
111 | {
112 | "cell_type": "markdown",
113 | "metadata": {},
114 | "source": [
115 | "Time parsing uses the same layout values as Format."
116 | ]
117 | },
118 | {
119 | "cell_type": "code",
120 | "execution_count": 5,
121 | "metadata": {
122 | "collapsed": false
123 | },
124 | "outputs": [
125 | {
126 | "data": {
127 | "text/plain": [
128 | "\u001b[34m\u001b[1m2012\u001b[0m-\u001b[34m\u001b[1m11\u001b[0m-\u001b[34m\u001b[1m01\u001b[0m \u001b[34m\u001b[1m22\u001b[0m:\u001b[34m\u001b[1m08\u001b[0m:\u001b[34m\u001b[1m41\u001b[0m \u001b[34m\u001b[1m\u001b[0m\n"
129 | ]
130 | },
131 | "execution_count": 5,
132 | "metadata": {},
133 | "output_type": "execute_result"
134 | }
135 | ],
136 | "source": [
137 | "t1, _ := time.Parse(\n",
138 | " time.RFC3339,\n",
139 | " \"2012-11-01T22:08:41+00:00\")"
140 | ]
141 | },
142 | {
143 | "cell_type": "markdown",
144 | "metadata": {},
145 | "source": [
146 | "Parse will return an error on malformed input explaining the parsing problem."
147 | ]
148 | },
149 | {
150 | "cell_type": "code",
151 | "execution_count": 6,
152 | "metadata": {
153 | "collapsed": false
154 | },
155 | "outputs": [
156 | {
157 | "data": {
158 | "text/plain": [
159 | "&time.\u001b[32mParseError\u001b[0m{\n",
160 | " \u001b[33mLayout\u001b[0m: \u001b[31m\u001b[1m\"\u001b[0m\u001b[31mMon Jan _2 15:04:05 2006\u001b[0m\u001b[31m\u001b[1m\"\u001b[0m,\n",
161 | " \u001b[33mValue\u001b[0m: \u001b[31m\u001b[1m\"\u001b[0m\u001b[31m8:41PM\u001b[0m\u001b[31m\u001b[1m\"\u001b[0m,\n",
162 | " \u001b[33mLayoutElem\u001b[0m: \u001b[31m\u001b[1m\"\u001b[0m\u001b[31mMon\u001b[0m\u001b[31m\u001b[1m\"\u001b[0m,\n",
163 | " \u001b[33mValueElem\u001b[0m: \u001b[31m\u001b[1m\"\u001b[0m\u001b[31m8:41PM\u001b[0m\u001b[31m\u001b[1m\"\u001b[0m,\n",
164 | " \u001b[33mMessage\u001b[0m: \u001b[31m\u001b[1m\"\u001b[0m\u001b[31m\u001b[1m\"\u001b[0m,\n",
165 | "}\n"
166 | ]
167 | },
168 | "execution_count": 6,
169 | "metadata": {},
170 | "output_type": "execute_result"
171 | }
172 | ],
173 | "source": [
174 | "ansic := \"Mon Jan _2 15:04:05 2006\"\n",
175 | "_, e := time.Parse(ansic, \"8:41PM\")"
176 | ]
177 | },
178 | {
179 | "cell_type": "markdown",
180 | "metadata": {},
181 | "source": [
182 | "## Custom Layouts"
183 | ]
184 | },
185 | {
186 | "cell_type": "markdown",
187 | "metadata": {},
188 | "source": [
189 | "Format and Parse use example-based layouts. Usually you’ll use a constant from time for these layouts, but you can also supply custom layouts. Layouts must use the reference time Mon Jan 2 15:04:05 MST 2006 to show the pattern with which to format/parse a given time/string. The example time must be exactly as shown: the year 2006, 15 for the hour, Monday for the day of the week, etc."
190 | ]
191 | },
192 | {
193 | "cell_type": "code",
194 | "execution_count": 7,
195 | "metadata": {
196 | "collapsed": false
197 | },
198 | "outputs": [
199 | {
200 | "data": {
201 | "text/plain": [
202 | "\u001b[31m\u001b[1m\"\u001b[0m\u001b[31m8:15PM\u001b[0m\u001b[31m\u001b[1m\"\u001b[0m\n"
203 | ]
204 | },
205 | "execution_count": 7,
206 | "metadata": {},
207 | "output_type": "execute_result"
208 | }
209 | ],
210 | "source": [
211 | "t.Format(\"3:04PM\")"
212 | ]
213 | },
214 | {
215 | "cell_type": "code",
216 | "execution_count": 8,
217 | "metadata": {
218 | "collapsed": false
219 | },
220 | "outputs": [
221 | {
222 | "data": {
223 | "text/plain": [
224 | "\u001b[31m\u001b[1m\"\u001b[0m\u001b[31mSat Jan 23 20:15:01 2016\u001b[0m\u001b[31m\u001b[1m\"\u001b[0m\n"
225 | ]
226 | },
227 | "execution_count": 8,
228 | "metadata": {},
229 | "output_type": "execute_result"
230 | }
231 | ],
232 | "source": [
233 | "t.Format(\"Mon Jan _2 15:04:05 2006\")"
234 | ]
235 | },
236 | {
237 | "cell_type": "code",
238 | "execution_count": 9,
239 | "metadata": {
240 | "collapsed": false
241 | },
242 | "outputs": [
243 | {
244 | "data": {
245 | "text/plain": [
246 | "\u001b[31m\u001b[1m\"\u001b[0m\u001b[31m2016-01-23T20:15:02.006035-06:00\u001b[0m\u001b[31m\u001b[1m\"\u001b[0m\n"
247 | ]
248 | },
249 | "execution_count": 9,
250 | "metadata": {},
251 | "output_type": "execute_result"
252 | }
253 | ],
254 | "source": [
255 | "t.Format(\"2006-01-02T15:04:05.999999-07:00\")"
256 | ]
257 | },
258 | {
259 | "cell_type": "code",
260 | "execution_count": 10,
261 | "metadata": {
262 | "collapsed": false
263 | },
264 | "outputs": [
265 | {
266 | "data": {
267 | "text/plain": [
268 | "\u001b[34m\u001b[1m0\u001b[0m-\u001b[34m\u001b[1m01\u001b[0m-\u001b[34m\u001b[1m01\u001b[0m \u001b[34m\u001b[1m20\u001b[0m:\u001b[34m\u001b[1m41\u001b[0m:\u001b[34m\u001b[1m00\u001b[0m \u001b[34m\u001b[1mUTC\u001b[0m\n"
269 | ]
270 | },
271 | "execution_count": 10,
272 | "metadata": {},
273 | "output_type": "execute_result"
274 | }
275 | ],
276 | "source": [
277 | "form := \"3 04 PM\"\n",
278 | "t2, _ := time.Parse(form, \"8 41 PM\")"
279 | ]
280 | },
281 | {
282 | "cell_type": "markdown",
283 | "metadata": {},
284 | "source": [
285 | "## String Formatting"
286 | ]
287 | },
288 | {
289 | "cell_type": "markdown",
290 | "metadata": {},
291 | "source": [
292 | "For purely numeric representations you can also use standard string formatting with the extracted components of the time value."
293 | ]
294 | },
295 | {
296 | "cell_type": "code",
297 | "execution_count": 11,
298 | "metadata": {
299 | "collapsed": false
300 | },
301 | "outputs": [
302 | {
303 | "data": {
304 | "text/plain": [
305 | "2016-01-23T20:15:02-00:00\n",
306 | "\u001b[34m\u001b[1m26\u001b[0m\n",
307 | "\u001b[36m\u001b[1mnil\u001b[0m\n"
308 | ]
309 | },
310 | "execution_count": 11,
311 | "metadata": {},
312 | "output_type": "execute_result"
313 | }
314 | ],
315 | "source": [
316 | "fmt.Printf(\"%d-%02d-%02dT%02d:%02d:%02d-00:00\\n\",\n",
317 | " t.Year(), t.Month(), t.Day(),\n",
318 | " t.Hour(), t.Minute(), t.Second())"
319 | ]
320 | }
321 | ],
322 | "metadata": {
323 | "kernelspec": {
324 | "display_name": "Golang",
325 | "language": "go",
326 | "name": "gophernotes"
327 | },
328 | "language_info": {
329 | "name": "go"
330 | }
331 | },
332 | "nbformat": 4,
333 | "nbformat_minor": 0
334 | }
335 |
--------------------------------------------------------------------------------
/examples/Worker-Pools.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Worker Pools"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "In this example we’ll look at how to implement a worker pool using goroutines and channels.\n",
15 | "\n",
16 | "Comments from [Go by Example](https://gobyexample.com)."
17 | ]
18 | },
19 | {
20 | "cell_type": "code",
21 | "execution_count": 1,
22 | "metadata": {
23 | "collapsed": true
24 | },
25 | "outputs": [],
26 | "source": [
27 | "import \"fmt\""
28 | ]
29 | },
30 | {
31 | "cell_type": "code",
32 | "execution_count": 2,
33 | "metadata": {
34 | "collapsed": true
35 | },
36 | "outputs": [],
37 | "source": [
38 | "import \"time\""
39 | ]
40 | },
41 | {
42 | "cell_type": "markdown",
43 | "metadata": {},
44 | "source": [
45 | "## Worker Function"
46 | ]
47 | },
48 | {
49 | "cell_type": "markdown",
50 | "metadata": {},
51 | "source": [
52 | "Here’s the worker, of which we’ll run several concurrent instances. These workers will receive work on the jobs channel and send the corresponding results on results. We’ll sleep a second per job to simulate an expensive task."
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": 3,
58 | "metadata": {
59 | "collapsed": true
60 | },
61 | "outputs": [],
62 | "source": [
63 | "func worker(id int, jobs <-chan int, results chan<- int) {\n",
64 | " for j := range jobs {\n",
65 | " fmt.Println(\"worker\", id, \"processing job\", j)\n",
66 | " time.Sleep(time.Second)\n",
67 | " results <- j * 2\n",
68 | " }\n",
69 | "}"
70 | ]
71 | },
72 | {
73 | "cell_type": "markdown",
74 | "metadata": {},
75 | "source": [
76 | "## Utilize Workers"
77 | ]
78 | },
79 | {
80 | "cell_type": "markdown",
81 | "metadata": {},
82 | "source": [
83 | "In order to use our pool of workers we need to send them work and collect their results. We make 2 channels for this."
84 | ]
85 | },
86 | {
87 | "cell_type": "code",
88 | "execution_count": 4,
89 | "metadata": {
90 | "collapsed": false
91 | },
92 | "outputs": [
93 | {
94 | "data": {
95 | "text/plain": [
96 | "(\u001b[32mchan int\u001b[0m)(\u001b[34m\u001b[1m0xc820061500\u001b[0m)\n"
97 | ]
98 | },
99 | "execution_count": 4,
100 | "metadata": {},
101 | "output_type": "execute_result"
102 | }
103 | ],
104 | "source": [
105 | "jobs := make(chan int, 100)\n",
106 | "results := make(chan int, 100)"
107 | ]
108 | },
109 | {
110 | "cell_type": "markdown",
111 | "metadata": {},
112 | "source": [
113 | "Next, start up 3 workers, initially blocked because there are no jobs yet:"
114 | ]
115 | },
116 | {
117 | "cell_type": "code",
118 | "execution_count": 5,
119 | "metadata": {
120 | "collapsed": false
121 | },
122 | "outputs": [],
123 | "source": [
124 | "for w := 1; w <= 3; w++ {\n",
125 | " go worker(w, jobs, results)\n",
126 | "}"
127 | ]
128 | },
129 | {
130 | "cell_type": "markdown",
131 | "metadata": {},
132 | "source": [
133 | "Send 9 jobs and then close that channel to indicate that’s all the work we have:"
134 | ]
135 | },
136 | {
137 | "cell_type": "code",
138 | "execution_count": 6,
139 | "metadata": {
140 | "collapsed": true
141 | },
142 | "outputs": [],
143 | "source": [
144 | "for j := 1; j <= 9; j++ {\n",
145 | " jobs <- j\n",
146 | "}\n",
147 | "close(jobs)"
148 | ]
149 | },
150 | {
151 | "cell_type": "markdown",
152 | "metadata": {},
153 | "source": [
154 | "## Collect Results"
155 | ]
156 | },
157 | {
158 | "cell_type": "markdown",
159 | "metadata": {},
160 | "source": [
161 | "Finally we collect all the results of the work:"
162 | ]
163 | },
164 | {
165 | "cell_type": "code",
166 | "execution_count": 7,
167 | "metadata": {
168 | "collapsed": false
169 | },
170 | "outputs": [
171 | {
172 | "data": {
173 | "text/plain": [
174 | "worker 3 processing job 1\n",
175 | "worker 1 processing job 2\n",
176 | "worker 2 processing job 3\n",
177 | "worker 3 processing job 5\n",
178 | "worker 2 processing job 4\n",
179 | "worker 1 processing job 6\n",
180 | "worker 3 processing job 8\n",
181 | "worker 1 processing job 7\n",
182 | "worker 2 processing job 9\n"
183 | ]
184 | },
185 | "execution_count": 7,
186 | "metadata": {},
187 | "output_type": "execute_result"
188 | }
189 | ],
190 | "source": [
191 | "for a := 1; a <= 9; a++ {\n",
192 | " <-results\n",
193 | "}"
194 | ]
195 | },
196 | {
197 | "cell_type": "markdown",
198 | "metadata": {},
199 | "source": [
200 | "Our running program shows the 9 jobs being executed by various workers. The program only takes about 3 seconds despite doing about 9 seconds of total work because there are 3 workers operating concurrently."
201 | ]
202 | }
203 | ],
204 | "metadata": {
205 | "kernelspec": {
206 | "display_name": "Golang",
207 | "language": "go",
208 | "name": "gophernotes"
209 | },
210 | "language_info": {
211 | "name": "go"
212 | }
213 | },
214 | "nbformat": 4,
215 | "nbformat_minor": 0
216 | }
217 |
--------------------------------------------------------------------------------
/examples/iris.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gopherdata/mybinder-go/5416b6cd1576b545a8d8c98574b4df55d8cfbd23/examples/iris.jpg
--------------------------------------------------------------------------------
/index.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Imports"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": 1,
13 | "metadata": {
14 | "collapsed": true
15 | },
16 | "outputs": [],
17 | "source": [
18 | "import \"fmt\""
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {},
24 | "source": [
25 | "# Hello World"
26 | ]
27 | },
28 | {
29 | "cell_type": "code",
30 | "execution_count": 2,
31 | "metadata": {
32 | "collapsed": false
33 | },
34 | "outputs": [
35 | {
36 | "data": {
37 | "text/plain": [
38 | "\u001b[31m\u001b[1m\"\u001b[0m\u001b[31mworld\u001b[0m\u001b[31m\u001b[1m\"\u001b[0m\n"
39 | ]
40 | },
41 | "execution_count": 2,
42 | "metadata": {},
43 | "output_type": "execute_result"
44 | }
45 | ],
46 | "source": [
47 | "world := \"world\""
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": 3,
53 | "metadata": {
54 | "collapsed": false
55 | },
56 | "outputs": [
57 | {
58 | "data": {
59 | "text/plain": [
60 | "\u001b[31m\u001b[1m\"\u001b[0m\u001b[31mhello world\u001b[0m\u001b[31m\u001b[1m\"\u001b[0m\n"
61 | ]
62 | },
63 | "execution_count": 3,
64 | "metadata": {},
65 | "output_type": "execute_result"
66 | }
67 | ],
68 | "source": [
69 | "fmt.Sprintf(\"hello %s\", world)"
70 | ]
71 | }
72 | ],
73 | "metadata": {
74 | "kernelspec": {
75 | "display_name": "Golang",
76 | "language": "go",
77 | "name": "gophernotes"
78 | },
79 | "language_info": {
80 | "name": "go"
81 | }
82 | },
83 | "nbformat": 4,
84 | "nbformat_minor": 0
85 | }
86 |
--------------------------------------------------------------------------------
/postBuild:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | GOVERS=1.17.6
6 |
7 | mkdir -p \
8 | $HOME/.local/go/$GOVERS \
9 | $HOME/go
10 |
11 | echo "::: install Go ${GOVERS}..."
12 | curl -O -L https://golang.org/dl/go${GOVERS}.linux-amd64.tar.gz
13 | tar -C $HOME/.local/go/$GOVERS -zxf go${GOVERS}.linux-amd64.tar.gz
14 | /bin/rm go${GOVERS}.linux-amd64.tar.gz
15 |
16 | export GOROOT=$HOME/.local/go/$GOVERS/go
17 | export GOPATH=$HOME/go
18 | export GO111MODULE=on
19 | export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
20 |
21 | ## install interesting packages
22 | echo "::: installing gophernotes, gonum..."
23 | go get golang.org/x/tools/cmd/goimports
24 | go install github.com/gopherdata/gophernotes@latest
25 | go get github.com/goml/gobrain
26 |
27 | go get gonum.org/v1/plot/...
28 | go get gonum.org/v1/gonum/...
29 | go get github.com/go-gota/gota/...
30 | go get github.com/sajari/regression
31 | go get github.com/sjwhitworth/golearn/...
32 | go get go-hep.org/x/hep/csvutil/...
33 | go get go-hep.org/x/hep/fit
34 | go get go-hep.org/x/hep/hbook
35 | go get github.com/montanaflynn/stats
36 | go get github.com/boltdb/bolt
37 | go get github.com/patrickmn/go-cache
38 | go get github.com/chewxy/math32
39 | go get github.com/chewxy/hm
40 | go get gorgonia.org/vecf64
41 | go get gorgonia.org/vecf32
42 | go get github.com/awalterschulze/gographviz
43 | go get github.com/leesper/go_rng
44 | go get github.com/pkg/errors
45 | go get github.com/stretchr/testify/assert
46 |
47 | echo "::: installing gophernotes, gonum... [done]"
48 |
49 | ## setup environment for Go
50 |
51 | cat >> $HOME/.setup-go << EOF
52 | ## setup Go
53 | export GOROOT=$GOROOT
54 | export GOPATH=$GOPATH
55 | export GO111MODULE=on
56 | export PATH=\$GOPATH/bin:\$GOROOT/bin:\$PATH
57 | EOF
58 |
59 | cat >> $HOME/.bashrc << EOF
60 | . ~/.setup-go
61 | EOF
62 |
63 | ## install the Go kernel
64 | mkdir -p ./binder/gophernotes
65 | cat >| ./binder/gophernotes/kernel.json << EOF
66 | {
67 | "argv": [
68 | "$GOPATH/bin/gophernotes",
69 | "{connection_file}"
70 | ],
71 | "display_name": "Go",
72 | "language": "go",
73 | "name": "go",
74 | "env": {
75 | "GOPATH": "$GOPATH",
76 | "GOROOT": "$GOROOT",
77 | "GO111MODULE": "on",
78 | "PATH": "$GOPATH/bin:$GOROOT/bin:$PATH"
79 | }
80 | }
81 | EOF
82 | jupyter kernelspec install ./binder/gophernotes --user
83 |
84 | /bin/rm -rf binder
85 |
86 | echo "::: kernel list"
87 | jupyter kernelspec list
88 |
--------------------------------------------------------------------------------