graph-function 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +29 -4
- data/examples/comparing_ints.gif +0 -0
- data/examples/comparing_ints.html +303 -0
- data/examples/comparing_ints.rb +1 -1
- data/lib/graph/function/plot_config.rb +1 -1
- data/lib/graph/function/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 92c608d974ce4d380041de06d237ecb637417b9f
|
|
4
|
+
data.tar.gz: 9f8cbb58922ff8e73b632c4d241fc31ec57c3428
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: da896a4a831a22acf5104fa6778b3cbf6cdff2b410bdab15641b21fac14e198e46d439e72b243babbf9a69fcd0d21b6e24ab0728bc2bdf212a292e62b861657e
|
|
7
|
+
data.tar.gz: 7f12e15fac2f979a7ac80f455c91f7fe12a0349ed2570f43aa0c1306595010cf767883cc7098627483ad4383acf881d442153a839d306eaa341480c8c57ab662
|
data/README.md
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
```
|
|
2
|
+
.-. / \ _
|
|
3
|
+
^^ / \ /^./\__ _/ \
|
|
4
|
+
_ .--'\/\_ \__/. \ / \ ^^ ___
|
|
5
|
+
/ \_ _/ ^ \/ __ :' /\/\ /\ __/ \
|
|
6
|
+
/ \ / .' _/ / \ ^ / \/ \/ .`'\_/\
|
|
7
|
+
/\/\ /\/ :' __ ^/ ^/ `--./.' ^ `-.\ _ _:\ _
|
|
8
|
+
/ \/ \ _/ \-' __/.' ^ _ \_ .'\ _/ \ . __/ \
|
|
9
|
+
/\ .- `. \/ \ / -. _/ \ -. `_/ \ / `._/ ^ \
|
|
10
|
+
/ `-.__ ^ / .-'.--' . / `--./ .-' `-. `-. `. - `.
|
|
11
|
+
@/ `. / / `-. / .-' / . .' \ \ \ .- \%
|
|
12
|
+
@(88%@)@%% @)&@&(88&@.-_=_-=_-=_-=_-=_.8@% &@&&8(8%@%8)(8@%8 8%@)%
|
|
13
|
+
@88:::&(&8&&8::JGS:&`.~-_~~-~~_~-~_~-~~=.'@(&%::::%@8&8)::&#@8::::
|
|
14
|
+
`::::::8%@@%:::::@%&8:`.=~~-.~~-.~~=..~'8::::::::&@8:::::&8::::::'
|
|
15
|
+
`::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::'
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
|
|
1
19
|
# Graph::Function
|
|
2
20
|
|
|
3
21
|
This gem's goal is to make it easy to compare the [asymptotic performance](https://en.wikipedia.org/wiki/Asymptotic_analysis) of two or more functions via graphing.
|
|
@@ -42,15 +60,22 @@ To set up, you only need the following:
|
|
|
42
60
|
|
|
43
61
|
```ruby
|
|
44
62
|
require 'graph/function'
|
|
45
|
-
Graph::Function.
|
|
63
|
+
Graph::Function.as_x11
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
If you don't want to output to [x11](https://www.xquartz.org/), just set `config.terminal` to a different option. Two convenience methods exist for `gif` and `canvas`, you just need to provide them with a file to output to:
|
|
67
|
+
|
|
68
|
+
```ruby
|
|
69
|
+
Graph::Function.as_gif(File.expand_path('../comparing_ints.gif', __FILE__))
|
|
70
|
+
Graph::Function.as_canvas(File.expand_path('../comparing_ints.html', __FILE__))
|
|
46
71
|
```
|
|
47
72
|
|
|
48
|
-
|
|
73
|
+
You can use anything else gnuplot [respects as a terminal](http://mibai.tec.u-ryukyu.ac.jp/~oshiro/Doc/gnuplot_primer/gptermcmp.html), even outputting to just `txt`!
|
|
49
74
|
|
|
50
75
|
```ruby
|
|
51
76
|
Graph::Function.configure do |config|
|
|
52
|
-
config.terminal = '
|
|
53
|
-
config.output = File.expand_path('../your_graph_name.
|
|
77
|
+
config.terminal = 'dumb'
|
|
78
|
+
config.output = File.expand_path('../your_graph_name.txt', __FILE__)
|
|
54
79
|
config.step = (0..10_000).step(1000).to_a # default value
|
|
55
80
|
end
|
|
56
81
|
```
|
|
Binary file
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
<!DOCTYPE HTML>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Gnuplot Canvas Graph</title>
|
|
5
|
+
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
|
6
|
+
<!--[if IE]><script type="text/javascript" src="excanvas.js"></script><![endif]-->
|
|
7
|
+
<script src="/usr/local/Cellar/gnuplot/5.0.4/share/gnuplot/5.0/js/canvastext.js"></script>
|
|
8
|
+
<script src="/usr/local/Cellar/gnuplot/5.0.4/share/gnuplot/5.0/js/gnuplot_common.js"></script>
|
|
9
|
+
<script src="/usr/local/Cellar/gnuplot/5.0.4/share/gnuplot/5.0/js/gnuplot_dashedlines.js"></script>
|
|
10
|
+
<script type="text/javascript">gnuplot.init = function() {};</script>
|
|
11
|
+
<script type="text/javascript">
|
|
12
|
+
var canvas, ctx;
|
|
13
|
+
gnuplot.grid_lines = true;
|
|
14
|
+
gnuplot.zoomed = false;
|
|
15
|
+
gnuplot.active_plot_name = "gnuplot_canvas";
|
|
16
|
+
|
|
17
|
+
function gnuplot_canvas() {
|
|
18
|
+
canvas = document.getElementById("gnuplot_canvas");
|
|
19
|
+
ctx = canvas.getContext("2d");
|
|
20
|
+
// Gnuplot version 5.0.4
|
|
21
|
+
// short forms of commands provided by gnuplot_common.js
|
|
22
|
+
function DT (dt) {gnuplot.dashtype(dt);};
|
|
23
|
+
function DS (x,y) {gnuplot.dashstart(x,y);};
|
|
24
|
+
function DL (x,y) {gnuplot.dashstep(x,y);};
|
|
25
|
+
function M (x,y) {if (gnuplot.pattern.length > 0) DS(x,y); else gnuplot.M(x,y);};
|
|
26
|
+
function L (x,y) {if (gnuplot.pattern.length > 0) DL(x,y); else gnuplot.L(x,y);};
|
|
27
|
+
function Dot (x,y) {gnuplot.Dot(x/10.,y/10.);};
|
|
28
|
+
function Pt (N,x,y,w) {gnuplot.Pt(N,x/10.,y/10.,w/10.);};
|
|
29
|
+
function R (x,y,w,h) {gnuplot.R(x,y,w,h);};
|
|
30
|
+
function T (x,y,fontsize,justify,string) {gnuplot.T(x,y,fontsize,justify,string);};
|
|
31
|
+
function TR (x,y,angle,fontsize,justify,string) {gnuplot.TR(x,y,angle,fontsize,justify,string);};
|
|
32
|
+
function bp (x,y) {gnuplot.bp(x,y);};
|
|
33
|
+
function cfp () {gnuplot.cfp();};
|
|
34
|
+
function cfsp() {gnuplot.cfsp();};
|
|
35
|
+
|
|
36
|
+
gnuplot.hypertext_list = [];
|
|
37
|
+
gnuplot.on_hypertext = -1;
|
|
38
|
+
function Hypertext(x,y,w,text) {
|
|
39
|
+
newtext = {x:x, y:y, w:w, text:text};
|
|
40
|
+
gnuplot.hypertext_list.push(newtext);
|
|
41
|
+
}
|
|
42
|
+
gnuplot.dashlength = 400;
|
|
43
|
+
ctx.lineCap = "round"; ctx.lineJoin = "round";
|
|
44
|
+
CanvasTextFunctions.enable(ctx);
|
|
45
|
+
ctx.strokeStyle = "rgb(215,215,215)";
|
|
46
|
+
ctx.lineWidth = 1;
|
|
47
|
+
|
|
48
|
+
ctx.lineWidth = 1;
|
|
49
|
+
ctx.strokeStyle = "rgb(000,000,000)";
|
|
50
|
+
ctx.beginPath();
|
|
51
|
+
M(540,3680);
|
|
52
|
+
L(640,3680);
|
|
53
|
+
M(5759,3680);
|
|
54
|
+
L(5659,3680);
|
|
55
|
+
ctx.stroke();
|
|
56
|
+
ctx.closePath();
|
|
57
|
+
ctx.fillStyle = "rgb(000,000,000)";
|
|
58
|
+
T(460,3730,10.0,"Right"," 0");
|
|
59
|
+
ctx.beginPath();
|
|
60
|
+
M(540,3197);
|
|
61
|
+
L(640,3197);
|
|
62
|
+
M(5759,3197);
|
|
63
|
+
L(5659,3197);
|
|
64
|
+
ctx.stroke();
|
|
65
|
+
ctx.closePath();
|
|
66
|
+
T(460,3247,10.0,"Right"," 2");
|
|
67
|
+
ctx.beginPath();
|
|
68
|
+
M(540,2715);
|
|
69
|
+
L(640,2715);
|
|
70
|
+
M(5759,2715);
|
|
71
|
+
L(5659,2715);
|
|
72
|
+
ctx.stroke();
|
|
73
|
+
ctx.closePath();
|
|
74
|
+
T(460,2765,10.0,"Right"," 4");
|
|
75
|
+
ctx.beginPath();
|
|
76
|
+
M(540,2232);
|
|
77
|
+
L(640,2232);
|
|
78
|
+
M(5759,2232);
|
|
79
|
+
L(5659,2232);
|
|
80
|
+
ctx.stroke();
|
|
81
|
+
ctx.closePath();
|
|
82
|
+
T(460,2282,10.0,"Right"," 6");
|
|
83
|
+
ctx.beginPath();
|
|
84
|
+
M(540,1749);
|
|
85
|
+
L(640,1749);
|
|
86
|
+
M(5759,1749);
|
|
87
|
+
L(5659,1749);
|
|
88
|
+
ctx.stroke();
|
|
89
|
+
ctx.closePath();
|
|
90
|
+
T(460,1799,10.0,"Right"," 8");
|
|
91
|
+
ctx.beginPath();
|
|
92
|
+
M(540,1266);
|
|
93
|
+
L(640,1266);
|
|
94
|
+
M(5759,1266);
|
|
95
|
+
L(5659,1266);
|
|
96
|
+
ctx.stroke();
|
|
97
|
+
ctx.closePath();
|
|
98
|
+
T(460,1316,10.0,"Right"," 10");
|
|
99
|
+
ctx.beginPath();
|
|
100
|
+
M(540,784);
|
|
101
|
+
L(640,784);
|
|
102
|
+
M(5759,784);
|
|
103
|
+
L(5659,784);
|
|
104
|
+
ctx.stroke();
|
|
105
|
+
ctx.closePath();
|
|
106
|
+
T(460,834,10.0,"Right"," 12");
|
|
107
|
+
ctx.beginPath();
|
|
108
|
+
M(540,301);
|
|
109
|
+
L(640,301);
|
|
110
|
+
M(5759,301);
|
|
111
|
+
L(5659,301);
|
|
112
|
+
ctx.stroke();
|
|
113
|
+
ctx.closePath();
|
|
114
|
+
T(460,351,10.0,"Right"," 14");
|
|
115
|
+
ctx.beginPath();
|
|
116
|
+
M(540,3680);
|
|
117
|
+
L(540,3580);
|
|
118
|
+
M(540,301);
|
|
119
|
+
L(540,401);
|
|
120
|
+
ctx.stroke();
|
|
121
|
+
ctx.closePath();
|
|
122
|
+
T(540,3830,10.0,"Center"," 0");
|
|
123
|
+
ctx.beginPath();
|
|
124
|
+
M(1584,3680);
|
|
125
|
+
L(1584,3580);
|
|
126
|
+
M(1584,301);
|
|
127
|
+
L(1584,401);
|
|
128
|
+
ctx.stroke();
|
|
129
|
+
ctx.closePath();
|
|
130
|
+
T(1584,3830,10.0,"Center"," 2000");
|
|
131
|
+
ctx.beginPath();
|
|
132
|
+
M(2628,3680);
|
|
133
|
+
L(2628,3580);
|
|
134
|
+
M(2628,301);
|
|
135
|
+
L(2628,401);
|
|
136
|
+
ctx.stroke();
|
|
137
|
+
ctx.closePath();
|
|
138
|
+
T(2628,3830,10.0,"Center"," 4000");
|
|
139
|
+
ctx.beginPath();
|
|
140
|
+
M(3671,3680);
|
|
141
|
+
L(3671,3580);
|
|
142
|
+
M(3671,301);
|
|
143
|
+
L(3671,401);
|
|
144
|
+
ctx.stroke();
|
|
145
|
+
ctx.closePath();
|
|
146
|
+
T(3671,3830,10.0,"Center"," 6000");
|
|
147
|
+
ctx.beginPath();
|
|
148
|
+
M(4715,3680);
|
|
149
|
+
L(4715,3580);
|
|
150
|
+
M(4715,301);
|
|
151
|
+
L(4715,401);
|
|
152
|
+
ctx.stroke();
|
|
153
|
+
ctx.closePath();
|
|
154
|
+
T(4715,3830,10.0,"Center"," 8000");
|
|
155
|
+
ctx.beginPath();
|
|
156
|
+
M(5759,3680);
|
|
157
|
+
L(5759,3580);
|
|
158
|
+
M(5759,301);
|
|
159
|
+
L(5759,401);
|
|
160
|
+
ctx.stroke();
|
|
161
|
+
ctx.closePath();
|
|
162
|
+
T(5759,3830,10.0,"Center"," 10000");
|
|
163
|
+
ctx.beginPath();
|
|
164
|
+
M(540,301);
|
|
165
|
+
L(540,3680);
|
|
166
|
+
L(5759,3680);
|
|
167
|
+
L(5759,301);
|
|
168
|
+
L(540,301);
|
|
169
|
+
ctx.closePath();
|
|
170
|
+
ctx.stroke();
|
|
171
|
+
TR(90,2041,270,10.0,"Center","execution time");
|
|
172
|
+
T(3149,3980,10.0,"Center","input size");
|
|
173
|
+
T(3149,201,10.0,"Center","Sort vs BubbleSort");
|
|
174
|
+
if (typeof(gnuplot.hide_gp_plot_1) == "undefined"|| !gnuplot.hide_gp_plot_1) {
|
|
175
|
+
ctx.strokeStyle = "rgb(148,000,211)";
|
|
176
|
+
ctx.strokeStyle = "rgb(000,000,000)";
|
|
177
|
+
T(5099,514,10.0,"Right","sort");
|
|
178
|
+
ctx.strokeStyle = "rgb(148,000,211)";
|
|
179
|
+
ctx.beginPath();
|
|
180
|
+
M(5179,464);
|
|
181
|
+
L(5599,464);
|
|
182
|
+
M(540,3680);
|
|
183
|
+
L(1062,3680);
|
|
184
|
+
L(1584,3680);
|
|
185
|
+
L(2106,3680);
|
|
186
|
+
L(2628,3680);
|
|
187
|
+
L(3150,3680);
|
|
188
|
+
L(3671,3680);
|
|
189
|
+
L(4193,3680);
|
|
190
|
+
L(4715,3680);
|
|
191
|
+
L(5237,3680);
|
|
192
|
+
L(5759,3680);
|
|
193
|
+
ctx.stroke();
|
|
194
|
+
ctx.closePath();
|
|
195
|
+
Pt(0,540,3680,60.0);
|
|
196
|
+
Pt(0,1062,3680,60.0);
|
|
197
|
+
Pt(0,1584,3680,60.0);
|
|
198
|
+
Pt(0,2106,3680,60.0);
|
|
199
|
+
Pt(0,2628,3680,60.0);
|
|
200
|
+
Pt(0,3150,3680,60.0);
|
|
201
|
+
Pt(0,3671,3680,60.0);
|
|
202
|
+
Pt(0,4193,3680,60.0);
|
|
203
|
+
Pt(0,4715,3680,60.0);
|
|
204
|
+
Pt(0,5237,3680,60.0);
|
|
205
|
+
Pt(0,5759,3680,60.0);
|
|
206
|
+
Pt(0,5389,464,60.0);
|
|
207
|
+
} // End gp_plot_1
|
|
208
|
+
if (typeof(gnuplot.hide_gp_plot_2) == "undefined"|| !gnuplot.hide_gp_plot_2) {
|
|
209
|
+
ctx.lineWidth = 1;
|
|
210
|
+
ctx.strokeStyle = "rgb(000,000,000)";
|
|
211
|
+
DT(gnuplot.solid);
|
|
212
|
+
ctx.strokeStyle = "rgb(000,158,115)";
|
|
213
|
+
ctx.strokeStyle = "rgb(000,000,000)";
|
|
214
|
+
ctx.fillStyle = "rgb(000,000,000)";
|
|
215
|
+
ctx.beginPath();
|
|
216
|
+
M(5099,589);
|
|
217
|
+
M(4411,589);
|
|
218
|
+
ctx.stroke();
|
|
219
|
+
ctx.closePath();
|
|
220
|
+
T(4411,639,10.0,"","bubble_sort");
|
|
221
|
+
ctx.strokeStyle = "rgb(000,158,115)";
|
|
222
|
+
ctx.beginPath();
|
|
223
|
+
M(5179,589);
|
|
224
|
+
L(5599,589);
|
|
225
|
+
M(540,3680);
|
|
226
|
+
L(1062,3650);
|
|
227
|
+
L(1584,3558);
|
|
228
|
+
L(2106,3406);
|
|
229
|
+
L(2628,3187);
|
|
230
|
+
L(3150,2903);
|
|
231
|
+
L(3671,2555);
|
|
232
|
+
L(4193,2170);
|
|
233
|
+
L(4715,1722);
|
|
234
|
+
L(5237,1168);
|
|
235
|
+
L(5759,453);
|
|
236
|
+
ctx.stroke();
|
|
237
|
+
ctx.closePath();
|
|
238
|
+
Pt(1,540,3680,60.0);
|
|
239
|
+
Pt(1,1062,3650,60.0);
|
|
240
|
+
Pt(1,1584,3558,60.0);
|
|
241
|
+
Pt(1,2106,3406,60.0);
|
|
242
|
+
Pt(1,2628,3187,60.0);
|
|
243
|
+
Pt(1,3150,2903,60.0);
|
|
244
|
+
Pt(1,3671,2555,60.0);
|
|
245
|
+
Pt(1,4193,2170,60.0);
|
|
246
|
+
Pt(1,4715,1722,60.0);
|
|
247
|
+
Pt(1,5237,1168,60.0);
|
|
248
|
+
Pt(1,5759,453,60.0);
|
|
249
|
+
Pt(1,5389,589,60.0);
|
|
250
|
+
} // End gp_plot_2
|
|
251
|
+
ctx.lineWidth = 2;
|
|
252
|
+
ctx.strokeStyle = "rgb(000,000,000)";
|
|
253
|
+
DT(gnuplot.solid);
|
|
254
|
+
ctx.lineWidth = 1;
|
|
255
|
+
ctx.beginPath();
|
|
256
|
+
M(540,301);
|
|
257
|
+
L(540,3680);
|
|
258
|
+
L(5759,3680);
|
|
259
|
+
L(5759,301);
|
|
260
|
+
L(540,301);
|
|
261
|
+
ctx.closePath();
|
|
262
|
+
ctx.stroke();
|
|
263
|
+
|
|
264
|
+
// plot boundaries and axis scaling information for mousing
|
|
265
|
+
gnuplot.plot_term_xmax = 600;
|
|
266
|
+
gnuplot.plot_term_ymax = 400;
|
|
267
|
+
gnuplot.plot_xmin = 54.0;
|
|
268
|
+
gnuplot.plot_xmax = 575.9;
|
|
269
|
+
gnuplot.plot_ybot = 368.0;
|
|
270
|
+
gnuplot.plot_ytop = 30.1;
|
|
271
|
+
gnuplot.plot_width = 521.9;
|
|
272
|
+
gnuplot.plot_height = 337.9;
|
|
273
|
+
gnuplot.plot_axis_xmin = 0;
|
|
274
|
+
gnuplot.plot_axis_xmax = 10000;
|
|
275
|
+
gnuplot.plot_axis_ymin = 0;
|
|
276
|
+
gnuplot.plot_axis_ymax = 14;
|
|
277
|
+
gnuplot.plot_axis_x2min = "none"
|
|
278
|
+
gnuplot.plot_axis_y2min = "none"
|
|
279
|
+
gnuplot.plot_logaxis_x = 0;
|
|
280
|
+
gnuplot.plot_logaxis_y = 0;
|
|
281
|
+
gnuplot.plot_axis_width = gnuplot.plot_axis_xmax - gnuplot.plot_axis_xmin;
|
|
282
|
+
gnuplot.plot_axis_height = gnuplot.plot_axis_ymax - gnuplot.plot_axis_ymin;
|
|
283
|
+
gnuplot.plot_timeaxis_x = "";
|
|
284
|
+
gnuplot.plot_timeaxis_y = "";
|
|
285
|
+
}
|
|
286
|
+
</script>
|
|
287
|
+
<link type="text/css" href="/usr/local/Cellar/gnuplot/5.0.4/share/gnuplot/5.0/js/gnuplot_mouse.css" rel="stylesheet">
|
|
288
|
+
</head>
|
|
289
|
+
<body onload="gnuplot_canvas(); gnuplot.init();" oncontextmenu="return false;">
|
|
290
|
+
|
|
291
|
+
<div class="gnuplot">
|
|
292
|
+
<canvas id="Tile" width="32" height="32" hidden></canvas>
|
|
293
|
+
<table class="plot">
|
|
294
|
+
<tr><td>
|
|
295
|
+
<canvas id="gnuplot_canvas" width="600" height="400" tabindex="0">
|
|
296
|
+
Sorry, your browser seems not to support the HTML 5 canvas element
|
|
297
|
+
</canvas>
|
|
298
|
+
</td></tr>
|
|
299
|
+
</table>
|
|
300
|
+
</div>
|
|
301
|
+
|
|
302
|
+
</body>
|
|
303
|
+
</html>
|
data/examples/comparing_ints.rb
CHANGED
|
@@ -2,7 +2,7 @@ module Graph
|
|
|
2
2
|
module Function
|
|
3
3
|
module PlotConfig
|
|
4
4
|
def set_up(plot)
|
|
5
|
-
plot.ylabel 'execution time'
|
|
5
|
+
plot.ylabel 'execution time (seconds)'
|
|
6
6
|
plot.xlabel 'input size'
|
|
7
7
|
plot.terminal (t = Graph::Function.configuration.terminal)
|
|
8
8
|
plot.output Graph::Function.configuration.output unless t == 'x11'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: graph-function
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex Moore-Niemi
|
|
@@ -155,6 +155,8 @@ files:
|
|
|
155
155
|
- Rakefile
|
|
156
156
|
- bin/console
|
|
157
157
|
- bin/setup
|
|
158
|
+
- examples/comparing_ints.gif
|
|
159
|
+
- examples/comparing_ints.html
|
|
158
160
|
- examples/comparing_ints.rb
|
|
159
161
|
- graph-function.gemspec
|
|
160
162
|
- lib/graph/function.rb
|