maciej-simply_useful 0.1.2
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.
- data/VERSION.yml +4 -0
- data/lib/bsearch.rb +125 -0
- data/lib/format.rb +6 -0
- data/lib/has_attributes.rb +19 -0
- data/lib/java_native2ascii.rb +42 -0
- data/lib/simply_useful.rb +3 -0
- data/spec/bsearch_spec.rb +58 -0
- data/spec/has_attributes_spec.rb +55 -0
- data/spec/java_native2ascii_spec.rb +32 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +5 -0
- metadata +64 -0
data/VERSION.yml
ADDED
data/lib/bsearch.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
#
|
2
|
+
# Ruby/Bsearch - a binary search library for Ruby.
|
3
|
+
#
|
4
|
+
# Copyright (C) 2001 Satoru Takabayashi <satoru@namazu.org>
|
5
|
+
# All rights reserved.
|
6
|
+
# This is free software with ABSOLUTELY NO WARRANTY.
|
7
|
+
#
|
8
|
+
# You can redistribute it and/or modify it under the terms of
|
9
|
+
# the Ruby's licence.
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# % irb -r ./bsearch.rb
|
14
|
+
# >> %w(a b c c c d e f).bsearch_first {|x| x <=> "c"}
|
15
|
+
# => 2
|
16
|
+
# >> %w(a b c c c d e f).bsearch_last {|x| x <=> "c"}
|
17
|
+
# => 4
|
18
|
+
# >> %w(a b c e f).bsearch_first {|x| x <=> "c"}
|
19
|
+
# => 2
|
20
|
+
# >> %w(a b e f).bsearch_first {|x| x <=> "c"}
|
21
|
+
# => nil
|
22
|
+
# >> %w(a b e f).bsearch_last {|x| x <=> "c"}
|
23
|
+
# => nil
|
24
|
+
# >> %w(a b e f).bsearch_lower_boundary {|x| x <=> "c"}
|
25
|
+
# => 2
|
26
|
+
# >> %w(a b e f).bsearch_upper_boundary {|x| x <=> "c"}
|
27
|
+
# => 2
|
28
|
+
# >> %w(a b c c c d e f).bsearch_range {|x| x <=> "c"}
|
29
|
+
# => 2...5
|
30
|
+
# >> %w(a b c d e f).bsearch_range {|x| x <=> "c"}
|
31
|
+
# => 2...3
|
32
|
+
# >> %w(a b d e f).bsearch_range {|x| x <=> "c"}
|
33
|
+
# => 2...2
|
34
|
+
|
35
|
+
module Bsearch
|
36
|
+
#VERSION = '1.5'
|
37
|
+
|
38
|
+
#
|
39
|
+
# The binary search algorithm is extracted from Jon Bentley's
|
40
|
+
# Programming Pearls 2nd ed. p.93
|
41
|
+
#
|
42
|
+
|
43
|
+
#
|
44
|
+
# Return the lower boundary. (inside)
|
45
|
+
#
|
46
|
+
def bsearch_lower_boundary (range = 0 ... self.length, &block)
|
47
|
+
lower = range.first() -1
|
48
|
+
upper = if range.exclude_end? then range.last else range.last + 1 end
|
49
|
+
while lower + 1 != upper
|
50
|
+
mid = ((lower + upper) / 2).to_i # for working with mathn.rb (Rational)
|
51
|
+
if yield(self[mid]) < 0
|
52
|
+
lower = mid
|
53
|
+
else
|
54
|
+
upper = mid
|
55
|
+
end
|
56
|
+
end
|
57
|
+
return upper
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# This method searches the FIRST occurrence which satisfies a
|
62
|
+
# condition given by a block in binary fashion and return the
|
63
|
+
# index of the first occurrence. Return nil if not found.
|
64
|
+
#
|
65
|
+
def bsearch_first (range = 0 ... self.length, &block)
|
66
|
+
boundary = bsearch_lower_boundary(range, &block)
|
67
|
+
if boundary >= self.length || yield(self[boundary]) != 0
|
68
|
+
return nil
|
69
|
+
else
|
70
|
+
return boundary
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
alias bsearch bsearch_first
|
75
|
+
|
76
|
+
#
|
77
|
+
# Return the upper boundary. (outside)
|
78
|
+
#
|
79
|
+
def bsearch_upper_boundary (range = 0 ... self.length, &block)
|
80
|
+
lower = range.first() -1
|
81
|
+
upper = if range.exclude_end? then range.last else range.last + 1 end
|
82
|
+
while lower + 1 != upper
|
83
|
+
mid = ((lower + upper) / 2).to_i # for working with mathn.rb (Rational)
|
84
|
+
if yield(self[mid]) <= 0
|
85
|
+
lower = mid
|
86
|
+
else
|
87
|
+
upper = mid
|
88
|
+
end
|
89
|
+
end
|
90
|
+
return lower + 1 # outside of the matching range.
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# This method searches the LAST occurrence which satisfies a
|
95
|
+
# condition given by a block in binary fashion and return the
|
96
|
+
# index of the last occurrence. Return nil if not found.
|
97
|
+
#
|
98
|
+
def bsearch_last (range = 0 ... self.length, &block)
|
99
|
+
# `- 1' for canceling `lower + 1' in bsearch_upper_boundary.
|
100
|
+
boundary = bsearch_upper_boundary(range, &block) - 1
|
101
|
+
|
102
|
+
if (boundary <= -1 || yield(self[boundary]) != 0)
|
103
|
+
return nil
|
104
|
+
else
|
105
|
+
return boundary
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
#
|
110
|
+
# Return the search result as a Range object.
|
111
|
+
#
|
112
|
+
def bsearch_range (range = 0 ... self.length, &block)
|
113
|
+
lower = bsearch_lower_boundary(range, &block)
|
114
|
+
upper = bsearch_upper_boundary(range, &block)
|
115
|
+
return lower ... upper
|
116
|
+
end
|
117
|
+
|
118
|
+
def bfind(range = 0 ... self.length, &block)
|
119
|
+
pos = self.bsearch(range, &block)
|
120
|
+
return nil if pos.nil?
|
121
|
+
self[pos]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
Array.send :include, Bsearch
|
data/lib/format.rb
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
# Taken from Mephisto (http://mephistoblog.com/)
|
2
|
+
module Format
|
3
|
+
DOMAIN = /^([a-z0-9]([-a-z0-9]*[a-z0-9])?\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|(h[kmnrtu]#{RAILS_ENV=='test'?'|host':''})|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw])$/ unless const_defined?(:DOMAIN)
|
4
|
+
STRING = /^[a-z0-9-]+$/
|
5
|
+
EMAIL = /(\A(\s*)\Z)|(\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z)/i
|
6
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module HasAttributes
|
2
|
+
def initialize(attributes = nil)
|
3
|
+
self.attributes = attributes
|
4
|
+
yield self if block_given?
|
5
|
+
end
|
6
|
+
|
7
|
+
def attributes=(attributes) # , guard_protected_attributes = true
|
8
|
+
#attributes = filter_attributes(attributes) if !attributes.blank? && guard_protected_attributes
|
9
|
+
attributes.each do |key,value|
|
10
|
+
send(key.to_s + '=', value)
|
11
|
+
end if attributes
|
12
|
+
end
|
13
|
+
|
14
|
+
def attributes
|
15
|
+
attributes = instance_variables
|
16
|
+
attributes.delete("@errors")
|
17
|
+
Hash[*attributes.collect { |attribute| [attribute[1..-1].to_sym, instance_variable_get(attribute)] }.flatten]
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require('iconv')
|
2
|
+
|
3
|
+
# Mimics Java's native2ascii tool
|
4
|
+
class JavaNative2Ascii
|
5
|
+
def self.ascii2native str
|
6
|
+
str.gsub(/\\u[0-9a-f]{4}/i) do |s|
|
7
|
+
out = ""
|
8
|
+
i = s[2,4].hex
|
9
|
+
out << (i & 0xFF)
|
10
|
+
out << (i >> 8)
|
11
|
+
out = Iconv.conv("UTF-8", "UNICODE", out)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.native2ascii str
|
16
|
+
out = ""
|
17
|
+
|
18
|
+
arr = str.unpack("U*")
|
19
|
+
return out if arr.nil?
|
20
|
+
# arr_s = arr.size
|
21
|
+
# i = 0
|
22
|
+
#
|
23
|
+
# while i < arr_s
|
24
|
+
# c = arr[i]
|
25
|
+
# if c > 127
|
26
|
+
# out << sprintf("\\u%04x", c)
|
27
|
+
# else
|
28
|
+
# out << c
|
29
|
+
# end
|
30
|
+
# i+=1
|
31
|
+
# end
|
32
|
+
arr.each do |c|
|
33
|
+
if c > 127
|
34
|
+
out << sprintf("\\u%04x", c)
|
35
|
+
else
|
36
|
+
out << c
|
37
|
+
end
|
38
|
+
end
|
39
|
+
out
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'bsearch'
|
3
|
+
|
4
|
+
describe Bsearch do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@sorted_array = [0,1,2,3,8,16,32,64,100]
|
8
|
+
@array_with_duplicates = [1,1,1,3,4,4,5,10,14,14,20]
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should add BSearch to Array" do
|
12
|
+
# Were looking only for two most important methods here
|
13
|
+
@sorted_array.should respond_to(:bsearch)
|
14
|
+
@sorted_array.should respond_to(:bfind)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe ".bfind" do
|
18
|
+
|
19
|
+
it "should return the object when it finds it" do
|
20
|
+
@sorted_array.bfind{|x| x <=> 16}.should == 16
|
21
|
+
@sorted_array.bfind{|x| x <=> 100}.should == 100
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return nil if it doesn't find it" do
|
25
|
+
@sorted_array.bfind{|x| x <=> 4}.should == nil
|
26
|
+
@sorted_array.bfind{|x| x <=> -10}.should == nil
|
27
|
+
@sorted_array.bfind{|x| x <=> 120}.should == nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe ".bsearch" do
|
32
|
+
it "should return the first position of an object" do
|
33
|
+
@array_with_duplicates.bsearch{|x| x <=> 1}.should == 0
|
34
|
+
@array_with_duplicates.bsearch{|x| x <=> 3}.should == 3
|
35
|
+
@array_with_duplicates.bsearch{|x| x <=> 4}.should == 4
|
36
|
+
@array_with_duplicates.bsearch{|x| x <=> 14}.should == @array_with_duplicates.length-3
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe ".bsearch_last" do
|
41
|
+
it "should return the last position of an object" do
|
42
|
+
@array_with_duplicates.bsearch_last{|x| x <=> 1}.should == 2
|
43
|
+
@array_with_duplicates.bsearch_last{|x| x <=> 3}.should == 3
|
44
|
+
@array_with_duplicates.bsearch_last{|x| x <=> 4}.should == 5
|
45
|
+
@array_with_duplicates.bsearch_last{|x| x <=> 14}.should == @array_with_duplicates.length-2
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe ".bsearch_range" do
|
50
|
+
it "should return a range of matching objects" do
|
51
|
+
@array_with_duplicates.bsearch_range{|x| x <=> 1}.should == (0...3)
|
52
|
+
@array_with_duplicates.bsearch_range{|x| x <=> 3}.should == (3...4)
|
53
|
+
@array_with_duplicates.bsearch_range{|x| x <=> 4}.should == (4...6)
|
54
|
+
@array_with_duplicates.bsearch_range{|x| x <=> 14}.should ==
|
55
|
+
(@array_with_duplicates.length-3...@array_with_duplicates.length-1)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'has_attributes'
|
3
|
+
|
4
|
+
class ObjectWithAttributes
|
5
|
+
include HasAttributes
|
6
|
+
|
7
|
+
attr_accessor :foo
|
8
|
+
|
9
|
+
def set_some_variables
|
10
|
+
@foo = "foo"; @bar = "bar"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe HasAttributes do
|
15
|
+
|
16
|
+
before(:each) do
|
17
|
+
@object_with_attributes = ObjectWithAttributes.new
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should define attributes methods" do
|
21
|
+
@object_with_attributes.should respond_to("attributes", "attributes=")
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should be add an initialize method" do
|
25
|
+
@object_with_attributes = ObjectWithAttributes.new(:foo => "new value")
|
26
|
+
@object_with_attributes.foo.should == "new value"
|
27
|
+
end
|
28
|
+
|
29
|
+
describe ".attributes" do
|
30
|
+
it "should return all instance variables" do
|
31
|
+
@object_with_attributes.set_some_variables
|
32
|
+
@object_with_attributes.attributes.keys.should include(:foo, :bar)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should return instance variables values" do
|
36
|
+
@object_with_attributes.set_some_variables
|
37
|
+
@object_with_attributes.attributes[:foo].should == "foo"
|
38
|
+
@object_with_attributes.foo = "foo2"
|
39
|
+
@object_with_attributes.attributes[:foo].should == "foo2"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe ".attributes=" do
|
44
|
+
it "should set properties" do
|
45
|
+
attributes = {:foo => "value1"}
|
46
|
+
@object_with_attributes.attributes= attributes
|
47
|
+
@object_with_attributes.attributes.should == attributes
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should raise an error when you try to set a non-property attribute" do
|
51
|
+
attributes = {:foo => "value1", :bar => "value2"}
|
52
|
+
lambda { @object_with_attributes.attributes=(attributes) }.should raise_error
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'java_native2ascii'
|
3
|
+
|
4
|
+
class JavaNative2AsciiHelper
|
5
|
+
def native_ascii_pairs
|
6
|
+
[
|
7
|
+
["foo=ęéëèAZ中文", "foo=\\u0119\\u00e9\\u00eb\\u00e8AZ\\u4e2d\\u6587"],
|
8
|
+
["foo=\304\231", "foo=\\u0119"],
|
9
|
+
["bar=bbzz", "bar=bbzz"]
|
10
|
+
] # Believe me! Those characters are there (even if they are not in your fontset!
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe JavaNative2Ascii do
|
15
|
+
before(:all) do
|
16
|
+
@helper = JavaNative2AsciiHelper.new
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should convert from ascii to native" do
|
20
|
+
@helper.native_ascii_pairs.each do |native_ascii|
|
21
|
+
native,ascii = native_ascii
|
22
|
+
JavaNative2Ascii.ascii2native(ascii).should == native
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should convert from native to ascii" do
|
27
|
+
@helper.native_ascii_pairs.each do |native_ascii|
|
28
|
+
native,ascii = native_ascii
|
29
|
+
JavaNative2Ascii.native2ascii(native).should == ascii
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: maciej-simply_useful
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Maciej Bilas
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-02-28 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: A set of simply useful classes
|
17
|
+
email: maciej@inszy.org
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- VERSION.yml
|
26
|
+
- lib/java_native2ascii.rb
|
27
|
+
- lib/format.rb
|
28
|
+
- lib/has_attributes.rb
|
29
|
+
- lib/simply_useful.rb
|
30
|
+
- lib/bsearch.rb
|
31
|
+
- spec/spec_helper.rb
|
32
|
+
- spec/spec.opts
|
33
|
+
- spec/bsearch_spec.rb
|
34
|
+
- spec/has_attributes_spec.rb
|
35
|
+
- spec/java_native2ascii_spec.rb
|
36
|
+
has_rdoc: true
|
37
|
+
homepage: http://github.com/maciej/simply_useful
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options:
|
40
|
+
- --inline-source
|
41
|
+
- --charset=UTF-8
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
version:
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
version:
|
56
|
+
requirements: []
|
57
|
+
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 1.2.0
|
60
|
+
signing_key:
|
61
|
+
specification_version: 2
|
62
|
+
summary: A set of simply useful classes
|
63
|
+
test_files: []
|
64
|
+
|