mll 2.3.0 → 2.4.1
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/.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
|