davidrichards-sirb 0.6.14

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.
Files changed (38) hide show
  1. data/README.rdoc +227 -0
  2. data/VERSION.yml +4 -0
  3. data/bin/sirb +33 -0
  4. data/lib/overrides/array.rb +6 -0
  5. data/lib/overrides/file.rb +17 -0
  6. data/lib/overrides/module.rb +70 -0
  7. data/lib/overrides/symbol.rb +39 -0
  8. data/lib/sirb/enumerable_statistics.rb +350 -0
  9. data/lib/sirb/functional.rb +114 -0
  10. data/lib/sirb/general_statistics.rb +72 -0
  11. data/lib/sirb/inter_enumerable_statistics.rb +139 -0
  12. data/lib/sirb/lib_loader.rb +45 -0
  13. data/lib/sirb/runner.rb +274 -0
  14. data/lib/sirb/sproc/proc.rb +5 -0
  15. data/lib/sirb/sproc/proc_source.rb +130 -0
  16. data/lib/sirb/sproc/sproc.rb +79 -0
  17. data/lib/sirb/sproc/usage_notes.txt +25 -0
  18. data/lib/sirb/sproc.rb +29 -0
  19. data/lib/sirb/thread_support.rb +20 -0
  20. data/lib/sirb/unbound_method.rb +5 -0
  21. data/lib/sirb.rb +52 -0
  22. data/lib/stored_procedures.rb +10 -0
  23. data/spec/lib/overrides/array_spec.rb +7 -0
  24. data/spec/lib/overrides/file_spec.rb +13 -0
  25. data/spec/lib/overrides/module_spec.rb +86 -0
  26. data/spec/lib/overrides/symbol_spec.rb +39 -0
  27. data/spec/lib/sirb/enumerable_statistics_spec.rb +85 -0
  28. data/spec/lib/sirb/functional_spec.rb +75 -0
  29. data/spec/lib/sirb/general_statistics_spec.rb +40 -0
  30. data/spec/lib/sirb/inter_enumerable_statistics_spec.rb +55 -0
  31. data/spec/lib/sirb/lib_loader_spec.rb +39 -0
  32. data/spec/lib/sirb/runner_spec.rb +9 -0
  33. data/spec/lib/sirb/sproc/proc_spec.rb +9 -0
  34. data/spec/lib/sirb/sproc/sproc_spec.rb +25 -0
  35. data/spec/lib/sirb/unbound_method_spec.rb +12 -0
  36. data/spec/lib/sirb_spec.rb +9 -0
  37. data/spec/spec_helper.rb +15 -0
  38. metadata +97 -0
data/README.rdoc ADDED
@@ -0,0 +1,227 @@
1
+ = Sirb
2
+
3
+ * http://github.com/davidrichards/sirb/tree/master
4
+
5
+ == DESCRIPTION:
6
+
7
+ Statistics + IRB. This offers a series of useful tools that a console should probably have, if your goal is to crunch a few numbers. It includes all the packages that I use, if you have them. Statisticus will have a standard library of statistical methods that you may want to have access to, so it's probably worth loading that gem as well.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ === Statistical Functions
12
+
13
+ Sirb has a set of rather useful functions setup:
14
+
15
+ * max
16
+ * min
17
+ * sum
18
+ * mean
19
+ * median
20
+ * range
21
+ * variance (also var)
22
+ * standard_deviation (also std)
23
+ * sort
24
+ * rank
25
+ * order
26
+ * quantile
27
+ * cumulative_sum (also cum_sum)
28
+ * cumulative_product (also cum_prod)
29
+ * cumulative_max (also cum_max)
30
+ * cumulative_min (also cum_min)
31
+
32
+ For comparing lists, you can use:
33
+
34
+ * correlation (also cor)
35
+ * p_max
36
+ * p_min
37
+
38
+ For other things, you can use:
39
+
40
+ * max
41
+ * min
42
+ * product
43
+ * to_pairs
44
+
45
+ === Libraries Loaded
46
+
47
+ Right now, Sirb attempts to load the following libraries (when available):
48
+
49
+ * NArray
50
+ * RGL
51
+ * matrix
52
+ * set
53
+ * RNum
54
+ * Statisticus
55
+ * RBTree
56
+ * mathn
57
+ * This library
58
+
59
+ === Stored Procedures
60
+
61
+ As you work, you can choose to store a procedure and use it between sessions. I do this with pstore (part of Ruby's standard library) and some code I found on Ruby Quiz by Florian Groß. The storage process is a little draconian, so in the short-term, you can call sirb with -w (sirb -w) and this feature is taken away from the runtime.
62
+
63
+ This is a very useful tool to have if you have some R code that you tend to use often, say, or some other functions that you discover while working with some data.
64
+
65
+ == SYNOPSIS:
66
+
67
+ === Functions
68
+
69
+ From command line:
70
+ sirb
71
+ >> @a = [3,2,6,7,14]
72
+ => [3, 2, 6, 7, 14]
73
+ >> @b = [4,6,2,1,19]
74
+ => [4, 6, 2, 1, 19]
75
+ >> @a.max
76
+ => 14
77
+ >> @a.min
78
+ => 2
79
+ >> @a.sum
80
+ => 32.0
81
+ >> # Most methods have meaningful block semantics
82
+ ?> @a.sum {|x| x ** x}
83
+ => 1.11120068264282e+16
84
+ >> @a.mean
85
+ => 6.4
86
+ >> @a.median
87
+ => 6
88
+ >> @a.range
89
+ => [2, 14]
90
+ >> @a.var
91
+ => 22.3
92
+ >> @a.std
93
+ => 4.72228758124704
94
+ >> @a.sort
95
+ => [2, 3, 6, 7, 14]
96
+ >> @a.rank
97
+ => [2, 1, 3, 4, 5]
98
+ >> @a.order
99
+ => [2, 1, 3, 4, 5]
100
+ >> @a.quantile
101
+ => [2, 3, 6, 7, 14]
102
+ >> @a.cum_sum
103
+ => [3.0, 5.0, 11.0, 18.0, 32.0]
104
+ >> @a.cum_prod
105
+ => [3.0, 6.0, 36.0, 252.0, 3528.0]
106
+ >> @a.cum_max
107
+ => [3, 3, 6, 7, 14]
108
+ >> @a.cum_min
109
+ => [3, 2, 2, 2, 2]
110
+ >> # And some methods between lists
111
+ ?> cor(@a,@b)
112
+ => 0.755599551729267
113
+ >> # This is the max of each pair (or set)
114
+ ?> p_max(@a,@b)
115
+ => [4, 6, 6, 7, 19]
116
+ >> # These take an arbitrary sized list
117
+ ?> p_max(@a,@b, [1,2,3,4,5])
118
+ => [4, 6, 6, 7, 19]
119
+ >> # And the min
120
+ ?> p_min(@a,@b)
121
+ => [3, 2, 2, 1, 14]
122
+ >> p_min(@a,@b, [1,2,3,4,5])
123
+ => [1, 2, 2, 1, 5]
124
+ >> # Finally, some methods out in the wild for general use:
125
+ ?> max(1,2,3,4,5)
126
+ => 5
127
+ >> min(1,2,3,4,5)
128
+ => 1
129
+ >> product(1,2,3,4,5)
130
+ => 120.0
131
+ >> to_pairs(@a,@b) { |a, b| a * b }
132
+ => [12, 12, 12, 7, 266]
133
+ >> sum_pairs(@a,@b) { |a, b| a * b }
134
+ => 309.0
135
+
136
+ === Stored Procedures
137
+
138
+ [sirb]$: bin/sirb
139
+ Loading sirb (Statistics + Irb: 0.6.3)
140
+ >> set :add, lambda {|x,y| x + y}, "This is my general-use adder, that adds a set of numbers"
141
+ => "add added"
142
+ >> add 1, 2, 3
143
+ => 6
144
+ >> sirb_help :add
145
+ * add (takes 2 arguments, returns a single value--reduce function)
146
+ This is my general-use adder, that adds a set of numbers
147
+ Source: |x,y| x + y
148
+ => nil
149
+ >> sirb_help
150
+
151
+ This is Irb, with some extra libraries and commands loaded.
152
+ You have loaded the following libraries:
153
+ narray
154
+ rgl
155
+ matrix
156
+ rnum
157
+ set
158
+ statisticus
159
+ rbtree
160
+ rubygems
161
+ command runner
162
+ enumerable statistics
163
+ general statistics
164
+ mathn
165
+
166
+ You have setup the following commands:
167
+
168
+ * add (takes 2 arguments, returns a single value--reduce function)
169
+ This is my general-use adder, that adds a set of numbers
170
+ Source: |x,y| x + y
171
+
172
+ You can store a command like this:
173
+ set :command_name, lambda{|list params| command }, "Optional description"
174
+
175
+ >> commands
176
+ => [:add]
177
+ >> remove_command :add
178
+ => #<Sirb::Runner:0x23df728 @block=proc {|x,y| x + y}, @name="add", @description="This is my general-use adder, that adds a set of numbers">
179
+ >> commands
180
+ => []
181
+
182
+ === Functional-style Programming
183
+
184
+ Sometimes it is useful to have a bit of functional flair when implementing equations. I've slurped up a bit of that and included it:
185
+
186
+ .... Fill these in
187
+
188
+ == Known Issues
189
+
190
+ I'm generally dissatisfied with quantile, which I think matches the way that R does their quantile. However, R is inconsistent, and the community has inconsistent interpretations of how to handle that, so I just used R as the standard for today.
191
+
192
+ I only mix this into Array right now. I need to work through the various other classes that I use, and see if this will mix into all of those: Vector, Matrix, Hash, RBTree, etc.
193
+
194
+ I am a little uncomfortable with my stored procedures library. I want to review it, because it so aggressively walk on Proc. There are other ideas out there that I will want to review when I get the chance.
195
+
196
+ == REQUIREMENTS:
197
+
198
+ * All the libraries are optional, but every time you log in, you will get a list of libraries that you may want to install.
199
+
200
+ == INSTALL:
201
+
202
+ * sudo gem install davidrichards-sirb
203
+
204
+ == LICENSE:
205
+
206
+ (The MIT License)
207
+
208
+ Copyright (c) 2009 David Richards
209
+
210
+ Permission is hereby granted, free of charge, to any person obtaining
211
+ a copy of this software and associated documentation files (the
212
+ 'Software'), to deal in the Software without restriction, including
213
+ without limitation the rights to use, copy, modify, merge, publish,
214
+ distribute, sublicense, and/or sell copies of the Software, and to
215
+ permit persons to whom the Software is furnished to do so, subject to
216
+ the following conditions:
217
+
218
+ The above copyright notice and this permission notice shall be
219
+ included in all copies or substantial portions of the Software.
220
+
221
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
222
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
223
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
224
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
225
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
226
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
227
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 6
4
+ :patch: 14
data/bin/sirb ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby -wKU
2
+ require 'yaml'
3
+
4
+ version_hash = YAML.load_file(File.join(File.dirname(__FILE__), %w(.. VERSION.yml)))
5
+ version = [version_hash[:major].to_s, version_hash[:minor].to_s, version_hash[:patch].to_s].join(".")
6
+ sirb_file = File.join(File.dirname(__FILE__), %w(.. lib sirb))
7
+ stored_procedures_file = File.join(File.dirname(__FILE__), %w(.. lib stored_procedures))
8
+
9
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
10
+
11
+ require 'optparse'
12
+ options = { :sandbox => false, :irb => irb, :without_stored_procedures => false }
13
+ OptionParser.new do |opt|
14
+ opt.banner = "Usage: console [environment] [options]"
15
+ opt.on("--irb=[#{irb}]", 'Invoke a different irb.') { |v| options[:irb] = v }
16
+ opt.on("--without-stored_procedures",
17
+ 'Run without storing proedures.') { |v| options[:without_stored_procedures] = true }
18
+ opt.on("-w", 'Run without storing procedures') { |v| options[:without_stored_procedures] = true }
19
+ opt.parse!(ARGV)
20
+ end
21
+
22
+ libs = " -r irb/completion -r #{sirb_file}"
23
+ libs += " -r #{stored_procedures_file}" unless options[:without_stored_procedures]
24
+
25
+ puts "Loading sirb (Statistics + Irb: #{version})"
26
+
27
+ if options[:sandbox]
28
+ puts "I'll have to think about how the whole sandbox concept should work for the sirb"
29
+ elsif options[:without_stored_procedures]
30
+ puts "You cannot read or write stored procedures in this session."
31
+ end
32
+
33
+ exec "#{options[:irb]} #{libs} --simple-prompt"
@@ -0,0 +1,6 @@
1
+ class Array
2
+ alias :single_include? :include?
3
+ def include?(*args)
4
+ args.inject(true) {|val, x| val = self.single_include?(x)}
5
+ end
6
+ end
@@ -0,0 +1,17 @@
1
+ class File
2
+ # From setup.rb. Since I only need one method, I've added it here
3
+ # instead of using the whole setup.rb lib.
4
+ def self.mkdir_p(dirname, prefix = nil)
5
+ dirname = prefix + File.expand_path(dirname) if prefix
6
+ # Does not check '/', it's too abnormal.
7
+ dirs = File.expand_path(dirname).split(%r<(?=/)>)
8
+ if /\A[a-z]:\z/i =~ dirs[0]
9
+ disk = dirs.shift
10
+ dirs[0] = disk + dirs[0]
11
+ end
12
+ dirs.each_index do |idx|
13
+ path = dirs[0..idx].join('')
14
+ Dir.mkdir path unless File.directory?(path)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,70 @@
1
+ class Module
2
+ # Stolen wholesale out of active_support. I didn't want the whole gem
3
+ # in this gem.
4
+ def alias_method_chain(target, feature)
5
+ # Strip out punctuation on predicates or bang methods since
6
+ # e.g. target?_without_feature is not a valid method name.
7
+ aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
8
+ yield(aliased_target, punctuation) if block_given?
9
+
10
+ with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}"
11
+
12
+ alias_method without_method, target
13
+ alias_method target, with_method
14
+
15
+ case
16
+ when public_method_defined?(without_method)
17
+ public target
18
+ when protected_method_defined?(without_method)
19
+ protected target
20
+ when private_method_defined?(without_method)
21
+ private target
22
+ end
23
+ end
24
+
25
+ # Moves a method safely into a new name, only if it exists. The default
26
+ # name is original_#{method_name}. So, archive_method(:x) creates
27
+ # original_x as a method, and removes x, so that a module can then use
28
+ # the x method name for something else. To be honest, I'm not really
29
+ # sure why I can't create a new method without overriding the old one,
30
+ # it seems like it used to work, and I may have something boinked in my
31
+ # system, but it's late and I could be wrong too.
32
+ def archive_method(target, new_name=nil)
33
+ new_name ||= ("original_" + target.to_s).to_sym
34
+ begin
35
+ alias_method(new_name, target)
36
+
37
+ case
38
+ when public_method_defined?(target)
39
+ public new_name
40
+ when protected_method_defined?(target)
41
+ protected new_name
42
+ when private_method_defined?(target)
43
+ private new_name
44
+ end
45
+
46
+ remove_method(target)
47
+ rescue
48
+ # The instance_methods show that the soon-to-be-defined methods are
49
+ # defined before they are, really weird. Need to see if this is a
50
+ # problem with 1.9. For now, fail silently.
51
+ end
52
+ end
53
+
54
+ # Access instance methods with array notation. Returns UnboundMethod,
55
+ alias [] instance_method
56
+
57
+ # Define a instance method with name sym and body f.
58
+ # Example: String[:backwards] = lambda { reverse }
59
+ def []=(sym, f)
60
+ self.instance_eval { define_method(sym, f) }
61
+ end
62
+ alias :save_lambda :[]=
63
+
64
+ # Only defines the method if it hasn't been defined before. It's a call
65
+ # for monkey patching, instead of gorilla patching.
66
+ def safe_def(sym, &block)
67
+ return true if self.instance_methods.include?(sym.to_s)
68
+ self.[]=(sym, block)
69
+ end
70
+ end
@@ -0,0 +1,39 @@
1
+ class Symbol
2
+ def to_proc
3
+ lambda {|receiver, *args| receiver.method(self)[*args]}
4
+ end
5
+
6
+ # Add [] and []= operators to the Symbol class for accessing and setting
7
+ # singleton methods of objects. Read : as "method" and [] as "of".
8
+ # So :m[o] reads "method m of o".
9
+
10
+ # Return the Method of obj named by this symbol. This may be a singleton
11
+ # method of obj (such as a class method) or an instance method defined
12
+ # by obj.class or inherited from a superclass.
13
+ # Examples:
14
+ # creator = :new[Object] # Class method Object.new
15
+ # doubler = :*[2] # * method of Fixnum 2
16
+ #
17
+ def [](obj)
18
+ obj.method(self)
19
+ end
20
+
21
+ # Define a singleton method on object o, using Proc or Method f as its body.
22
+ # This symbol is used as the name of the method.
23
+ # Examples:
24
+ #
25
+ # :singleton[o] = lambda { puts "this is a singleton method of o" }
26
+ # :class_method[String] = lambda { puts "this is a class method" }
27
+ #
28
+ # Note that you can't create instance methods this way. See Module.[]=
29
+ #
30
+ def []=(o,f)
31
+ # We can't use self in the block below, as it is evaluated in the
32
+ # context of a different object. So we have to assign self to a variable.
33
+ sym = self
34
+ # This is the object we define singleton methods on.
35
+ eigenclass = (class << o; self end)
36
+ # define_method is private, so we have to use instance_eval to execute it.
37
+ eigenclass.instance_eval { define_method(sym, f) }
38
+ end
39
+ end