mll 2.3.0 → 2.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +0 -1
- data/Gemfile.lock +15 -17
- data/README.md +66 -21
- data/core_ext.rb +7 -0
- data/lib/mll.rb +23 -14
- data/mll.gemspec +3 -3
- data/spec/_spec.rb +50 -5
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4578ca0a16a98bc1a8ab3336d073e3520b85cdc9
|
4
|
+
data.tar.gz: 78ef02a3c5081a97b4bf7fa7278d0da84d2e4f3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b24b4691ada481ae2150e7f073b5e77f151d38d823a76743dc4bfcd1b0e52b55da52e61b5fdb9855108a6b2e9de3d04a563e9a9b8f1309ae414c88aac267d8db
|
7
|
+
data.tar.gz: 4972ad59f90b6cddfd2c000144960a8850571682661037aed329923c21da3325450be4032586816b7462fa10c5f3fbd240d4a7dbd3463876883042b233adf0ce
|
data/.rspec
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,32 +1,30 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mll (2.
|
4
|
+
mll (2.4.1)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
9
|
diff-lcs (1.2.5)
|
10
|
-
rspec (3.
|
11
|
-
rspec-core (~> 3.
|
12
|
-
rspec-expectations (~> 3.
|
13
|
-
rspec-mocks (~> 3.
|
14
|
-
rspec-core (3.
|
15
|
-
rspec-support (~> 3.
|
16
|
-
rspec-expectations (3.1
|
10
|
+
rspec (3.3.0)
|
11
|
+
rspec-core (~> 3.3.0)
|
12
|
+
rspec-expectations (~> 3.3.0)
|
13
|
+
rspec-mocks (~> 3.3.0)
|
14
|
+
rspec-core (3.3.2)
|
15
|
+
rspec-support (~> 3.3.0)
|
16
|
+
rspec-expectations (3.3.1)
|
17
17
|
diff-lcs (>= 1.2.0, < 2.0)
|
18
|
-
rspec-support (~> 3.
|
19
|
-
rspec-mocks (3.
|
20
|
-
|
21
|
-
|
18
|
+
rspec-support (~> 3.3.0)
|
19
|
+
rspec-mocks (3.3.2)
|
20
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
21
|
+
rspec-support (~> 3.3.0)
|
22
|
+
rspec-support (3.3.0)
|
22
23
|
|
23
24
|
PLATFORMS
|
24
25
|
ruby
|
25
26
|
|
26
27
|
DEPENDENCIES
|
27
|
-
bundler (~> 1.7)
|
28
|
+
bundler (~> 1.7.0)
|
28
29
|
mll!
|
29
|
-
rspec (~> 3.
|
30
|
-
|
31
|
-
BUNDLED WITH
|
32
|
-
1.11.2
|
30
|
+
rspec (~> 3.3.0)
|
data/README.md
CHANGED
@@ -18,6 +18,7 @@ The main goal is to make Ruby more powerful by including the most used functions
|
|
18
18
|
4. `::fold_list` was wanted [here](http://stackoverflow.com/q/1475808/322020) in Ruby while being already implemented as [FoldList[]](http://reference.wolfram.com/language/ref/FoldList.html) in Mathematica and [scanl](http://hackage.haskell.org/package/base-4.8.0.0/docs/Prelude.html#v:scanl) in Haskell
|
19
19
|
5. `::nest` (n times) and `::nest_list` for repetitive applying the same function -- `::nest_while` and `::nest_while_list` are going to be implemented later
|
20
20
|
6. `::tally` -- shortcut to a probably the most common usage of `#group_by` -- calculating total occurences.
|
21
|
+
7. TODO write smth about `::riffle`, `::subdivide`, `::grid`
|
21
22
|
|
22
23
|
### How
|
23
24
|
|
@@ -25,56 +26,82 @@ The main goal is to make Ruby more powerful by including the most used functions
|
|
25
26
|
MLL::range[[2, 3]] # => [1..2, 1..3]
|
26
27
|
MLL::range[ 1..3 ] # => [1..1, 1..2, 1..3]
|
27
28
|
|
29
|
+
MLL::table[ MLL::times, 9, 9 ]
|
30
|
+
# => [[1, 2, 3, 4, 5, 6, 7, 8, 9],
|
31
|
+
[2, 4, 6, 8, 10, 12, 14, 16, 18],
|
32
|
+
[3, 6, 9, 12, 15, 18, 21, 24, 27],
|
33
|
+
[4, 8, 12, 16, 20, 24, 28, 32, 36],
|
34
|
+
[5, 10, 15, 20, 25, 30, 35, 40, 45],
|
35
|
+
[6, 12, 18, 24, 30, 36, 42, 48, 54],
|
36
|
+
[7, 14, 21, 28, 35, 42, 49, 56, 63],
|
37
|
+
[8, 16, 24, 32, 40, 48, 56, 64, 72],
|
38
|
+
[9, 18, 27, 36, 45, 54, 63, 72, 81]]
|
39
|
+
|
40
|
+
# similar to Ruby's #product with #map...
|
28
41
|
t = MLL::table[ ->(i,j){ i+j }, [[1, 0, 1]], [[0, 2, 0]] ]
|
29
42
|
# => [[1, 3, 1],
|
30
43
|
[0, 2, 0],
|
31
44
|
[1, 3, 1]]
|
45
|
+
# ... but our #map...
|
32
46
|
t = MLL::map[ ->(i){ [i] }, t, [2] ]
|
33
47
|
# => [[ [1], [3], [1] ],
|
34
48
|
[ [0], [2], [0] ],
|
35
49
|
[ [1], [3], [1] ]]
|
50
|
+
# ... can go deeper
|
36
51
|
MLL::map[ ->(i){ -i }, t, [3] ]
|
37
52
|
# => [[ [-1], [-3], [-1] ],
|
38
53
|
[ [ 0], [-2], [ 0] ],
|
39
54
|
[ [-1], [-3], [-1] ]]
|
40
55
|
|
41
|
-
MLL::table[ MLL::times, 9, 9 ]
|
42
|
-
# => [[1, 2, 3, 4, 5, 6, 7, 8, 9],
|
43
|
-
[2, 4, 6, 8, 10, 12, 14, 16, 18],
|
44
|
-
[3, 6, 9, 12, 15, 18, 21, 24, 27],
|
45
|
-
[4, 8, 12, 16, 20, 24, 28, 32, 36],
|
46
|
-
[5, 10, 15, 20, 25, 30, 35, 40, 45],
|
47
|
-
[6, 12, 18, 24, 30, 36, 42, 48, 54],
|
48
|
-
[7, 14, 21, 28, 35, 42, 49, 56, 63],
|
49
|
-
[8, 16, 24, 32, 40, 48, 56, 64, 72],
|
50
|
-
[9, 18, 27, 36, 45, 54, 63, 72, 81]]
|
51
56
|
# ::times means *
|
52
57
|
# ::divide means /
|
53
58
|
# ::subtract means -
|
54
59
|
# ::plus means +
|
55
60
|
|
56
|
-
|
57
|
-
# => [1,2,6,24,120,720,5040,40320,362880,3628800]
|
58
|
-
|
59
|
-
# here is `Listable' magic, allowing to zip arrays
|
61
|
+
# here is another `Listable' magic, allowing to zip arrays
|
60
62
|
# even of different dimensions with basic operations
|
61
63
|
MLL::times[ [[1,2],[3,4]], [5,6] ]
|
62
64
|
# => [[5,10], [18,24]]
|
65
|
+
|
66
|
+
# listing factorials # http://stackoverflow.com/a/3590520/322020
|
67
|
+
MLL::fold_list[ MLL::times, MLL::range[8] ]
|
68
|
+
# => [1, 2, 6, 24, 120, 720, 5040, 40320]
|
63
69
|
|
70
|
+
MLL::fold_list[ ->(a,b){ 10*a + b }, 0, [4,5,1,6,7,8] ]
|
71
|
+
# => [0, 4, 45, 451, 4516, 45167, 451678]
|
72
|
+
|
64
73
|
# http://en.wikipedia.org/wiki/Collatz_conjecture
|
65
74
|
MLL::nest_list[ ->(i){ i.even? ? i/2 : (i*3+1)/2 }, 20, 10 ]
|
66
75
|
# => [20, 10, 5, 8, 4, 2, 1, 2, 1, 2, 1]
|
67
76
|
|
68
|
-
|
69
|
-
|
77
|
+
# counting characters and nice printing the resulting table
|
78
|
+
MLL::grid[ MLL::tally[ "the quick brown fox jumps over the lazy dog".chars ].
|
79
|
+
sort_by(&:last).reverse.take(10),
|
80
|
+
frame: :all, spacings: [2, 0] ]
|
81
|
+
# => ┏━━━┳━━━┓
|
82
|
+
┃ ┃ 8 ┃
|
83
|
+
┃ o ┃ 4 ┃
|
84
|
+
┃ e ┃ 3 ┃
|
85
|
+
┃ u ┃ 2 ┃
|
86
|
+
┃ h ┃ 2 ┃
|
87
|
+
┃ r ┃ 2 ┃
|
88
|
+
┃ t ┃ 2 ┃
|
89
|
+
┃ n ┃ 1 ┃
|
90
|
+
┃ p ┃ 1 ┃
|
91
|
+
┃ m ┃ 1 ┃
|
92
|
+
┗━━━┻━━━┛
|
93
|
+
# current implementation of #grid sucks and needs your help ,.)
|
94
|
+
|
95
|
+
MLL::riffle[ "4345252523535".chars, ",", [-4,1,-4] ]
|
96
|
+
# => "4,345,252,523,535"
|
70
97
|
|
71
98
|
MLL::subdivide[ 5, 10, 4 ]
|
72
99
|
# => [5.0, 6.25, 7.5, 8.75, 10.0]
|
73
|
-
|
74
|
-
MLL::
|
75
|
-
#
|
76
|
-
|
77
|
-
|
100
|
+
|
101
|
+
MLL::most[ [1, 2, 3, 4] ] # => [1, 2, 3]
|
102
|
+
# now it's possible to extend core classes with some of those methods
|
103
|
+
require "mll/core_ext"
|
104
|
+
[1, 2, 3, 4].most # => [1, 2, 3]
|
78
105
|
|
79
106
|
Note that to see some of above examples working in the same way you need `.to_a`, `.map(&:to_a)` or even `.to_a.map(&:to_a)` since lazyness is intensively used.
|
80
107
|
|
@@ -90,6 +117,10 @@ or
|
|
90
117
|
|
91
118
|
rake spec
|
92
119
|
|
120
|
+
or
|
121
|
+
|
122
|
+
rake # to implicitly run 'rake todo'
|
123
|
+
|
93
124
|
### TODO (this section is filled automatically by `rake todo` task -- do not remove)
|
94
125
|
|
95
126
|
#### lib/mll.rb
|
@@ -121,6 +152,13 @@ module MLL
|
|
121
152
|
# TODO negative spacings?
|
122
153
|
# TODO smth with this #.all?
|
123
154
|
# TODO https://reference.wolfram.com/language/ref/Alignment.html
|
155
|
+
def riffle
|
156
|
+
lambda do |*args|
|
157
|
+
case args.size
|
158
|
+
when 3
|
159
|
+
Enumerator.new do |e|
|
160
|
+
args[0].each_with_index do |x, i|
|
161
|
+
# TODO make it not destructive
|
124
162
|
# TODO not sure if we need any other kind of Listability except of #range[[Array]]
|
125
163
|
# TODO #power[]
|
126
164
|
```
|
@@ -145,6 +183,11 @@ describe MLL do
|
|
145
183
|
# TODO: "Make a triangular array:"
|
146
184
|
describe "#range" do
|
147
185
|
# TODO take from docs more examples that involve other functions
|
186
|
+
describe "Rearranging & Restructuring Lists" do
|
187
|
+
describe "#riffle" do
|
188
|
+
describe "Scope:" do
|
189
|
+
example "intersperse two lists" do
|
190
|
+
# TODO check how it works for list2.size == list1.size + 1 in Mathematica
|
148
191
|
describe "Applying Functions to Lists" do
|
149
192
|
describe "#fold_list" do
|
150
193
|
describe "Applications:" do
|
@@ -164,6 +207,8 @@ describe MLL do
|
|
164
207
|
# TODO #mapthread ?
|
165
208
|
# TODO #mapindexed ?
|
166
209
|
# TODO "negative levels"
|
210
|
+
describe "Elements of Lists" do
|
211
|
+
# TODO #rest
|
167
212
|
# TODO http://reference.wolfram.com/language/guide/RearrangingAndRestructuringLists.html
|
168
213
|
# TODO http://reference.wolfram.com/language/guide/MathematicalAndCountingOperationsOnLists.html
|
169
214
|
describe "Functional Programming" do
|
data/core_ext.rb
ADDED
data/lib/mll.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module MLL
|
2
2
|
|
3
|
+
VERSION = "2.4.1"
|
4
|
+
|
3
5
|
class << self
|
4
6
|
|
5
7
|
def dimensions
|
@@ -203,23 +205,30 @@ module MLL
|
|
203
205
|
end
|
204
206
|
end
|
205
207
|
|
206
|
-
def
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
208
|
+
def most
|
209
|
+
# not Enumerator because if the end is invisible we can't stop at -2
|
210
|
+
lambda do |list|
|
211
|
+
list[0..-2]
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
def self.define_listable_function name, &block
|
218
|
+
(class << self; self end).class_eval do
|
219
|
+
define_method name do
|
220
|
+
lambda do |*args|
|
221
|
+
case args.map{ |i| i.respond_to? :map }
|
222
|
+
when [true] ; args.first.lazy.map &method(name).call
|
223
|
+
when [true, true] ; args.first.lazy.zip(args.last).map{ |i, j| send(name)[i, j] }
|
224
|
+
when [true, false] ; args.first.lazy.map{ |i| send(name)[i, args.last] }
|
225
|
+
when [false, true] ; args.last.lazy.map{ |i| send(name)[args.first, i] }
|
226
|
+
else
|
227
|
+
block.call *args
|
218
228
|
end
|
219
229
|
end
|
220
230
|
end
|
221
231
|
end
|
222
|
-
|
223
232
|
end
|
224
233
|
|
225
234
|
# TODO not sure if we need any other kind of Listability except of #range[[Array]]
|
@@ -269,7 +278,7 @@ module MLL
|
|
269
278
|
|
270
279
|
define_orderless_function(:plus, 0) { |a, b| _plus.call a, b }
|
271
280
|
define_orderless_function(:times, 1) { |a, b| _times.call a, b }
|
272
|
-
|
281
|
+
|
273
282
|
def self.mean
|
274
283
|
lambda do |list|
|
275
284
|
divide[times[plus[*list], 1.0], list.size]
|
data/mll.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = "mll"
|
3
|
-
spec.version = "
|
3
|
+
spec.version = (require_relative "lib/mll"; MLL::VERSION)
|
4
4
|
spec.authors = ["Victor Maslov"]
|
5
5
|
spec.email = ["nakilon@gmail.com"]
|
6
6
|
spec.summary = "Mathematica Language Library in Ruby"
|
@@ -13,9 +13,9 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.test_files = ["spec/"]
|
14
14
|
# spec.require_paths = ["lib"]
|
15
15
|
|
16
|
-
spec.add_development_dependency "bundler", "~> 1.7"
|
16
|
+
spec.add_development_dependency "bundler", "~> 1.7.0"
|
17
17
|
# spec.add_development_dependency "rake", "~> 10.0"
|
18
|
-
spec.add_development_dependency "rspec", "~> 3.
|
18
|
+
spec.add_development_dependency "rspec", "~> 3.3.0"
|
19
19
|
|
20
20
|
spec.required_ruby_version = ">= 2.0.0"
|
21
21
|
# spec.post_install_message = ""
|
data/spec/_spec.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
require_relative
|
2
|
-
|
1
|
+
require_relative "../lib/mll"
|
3
2
|
|
4
3
|
# PERMATODO test all implemented exceptions
|
5
4
|
# PERMATODO test all types returned (not actually all but about lazyness)
|
@@ -183,7 +182,7 @@ describe MLL do
|
|
183
182
|
expect(fold_list[0, [1,2,3], plus]).to be_a Enumerator
|
184
183
|
expect(fold_list[0, [1,2,3], plus].to_a).to eq [0,1,3,6]
|
185
184
|
end
|
186
|
-
|
185
|
+
|
187
186
|
end
|
188
187
|
|
189
188
|
end
|
@@ -798,6 +797,34 @@ describe MLL do
|
|
798
797
|
# http://reference.wolfram.com/language/guide/ElementsOfLists.html
|
799
798
|
describe "Elements of Lists" do
|
800
799
|
|
800
|
+
# https://reference.wolfram.com/language/ref/Most.html
|
801
|
+
describe "#most" do
|
802
|
+
|
803
|
+
example "#most[expr] is equivalent to Array#[](0..-2)" do
|
804
|
+
expect(most[[1,2,3,4]].to_a).to eq [1,2,3,4][0..-2]
|
805
|
+
end
|
806
|
+
|
807
|
+
describe "Basic Examples:" do
|
808
|
+
|
809
|
+
example "???" do
|
810
|
+
expect(most[[1,2,3,4]].to_a).to eq [1,2,3]
|
811
|
+
end
|
812
|
+
|
813
|
+
end
|
814
|
+
|
815
|
+
describe "Applications:" do
|
816
|
+
|
817
|
+
example "nest the operation of finding most of a list" do
|
818
|
+
expect(nest_list[[1,2,3,4], 3, most].to_a).to eq [[1,2,3,4], [1,2,3], [1,2], [1]]
|
819
|
+
end
|
820
|
+
|
821
|
+
end
|
822
|
+
|
823
|
+
end
|
824
|
+
|
825
|
+
# TODO #rest
|
826
|
+
|
827
|
+
# https://reference.wolfram.com/language/ref/Dimensions.html
|
801
828
|
describe "#dimensions" do
|
802
829
|
|
803
830
|
describe "Basic Examples:" do
|
@@ -959,7 +986,7 @@ describe MLL do
|
|
959
986
|
describe "#tally" do
|
960
987
|
|
961
988
|
describe "Details:" do
|
962
|
-
|
989
|
+
|
963
990
|
example "#tally[list] is equivalent to #tally[list,#sameq]" do
|
964
991
|
skip "#sameq is yet to be implemented"
|
965
992
|
end
|
@@ -1218,7 +1245,7 @@ describe MLL do
|
|
1218
1245
|
end
|
1219
1246
|
|
1220
1247
|
end
|
1221
|
-
|
1248
|
+
|
1222
1249
|
end
|
1223
1250
|
|
1224
1251
|
describe "Options:" do
|
@@ -1272,6 +1299,24 @@ end
|
|
1272
1299
|
# TODO http://reference.wolfram.com/language/guide/HandlingArraysOfData.html
|
1273
1300
|
# TODO http://reference.wolfram.com/language/guide/ComputationWithStructuredDatasets.html
|
1274
1301
|
|
1302
|
+
|
1303
|
+
describe "core_ext" do
|
1304
|
+
|
1305
|
+
example "by default core classes are not patched" do
|
1306
|
+
expect{ [1,2,3,4].most }.to raise_error NoMethodError
|
1307
|
+
end
|
1308
|
+
|
1309
|
+
example "after core_ext required" do
|
1310
|
+
require_relative "../core_ext"
|
1311
|
+
aggregate_failures "everything is fine" do
|
1312
|
+
expect([1,2,3,4].most).to eq [1,2,3]
|
1313
|
+
|
1314
|
+
end
|
1315
|
+
end
|
1316
|
+
|
1317
|
+
end
|
1318
|
+
|
1319
|
+
|
1275
1320
|
__END__
|
1276
1321
|
|
1277
1322
|
Table Array
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mll
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Victor Maslov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-05-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.7.0
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.7.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 3.
|
33
|
+
version: 3.3.0
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 3.
|
40
|
+
version: 3.3.0
|
41
41
|
description: ''
|
42
42
|
email:
|
43
43
|
- nakilon@gmail.com
|
@@ -51,6 +51,7 @@ files:
|
|
51
51
|
- Gemfile.lock
|
52
52
|
- README.md
|
53
53
|
- Rakefile
|
54
|
+
- core_ext.rb
|
54
55
|
- lib/mll.rb
|
55
56
|
- mll.gemspec
|
56
57
|
- spec/_spec.rb
|