string_number 0.0.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.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - jruby
7
+ - rbx
8
+ script: bundle exec rake test
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in string_number.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Gabriel Naiman
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,46 @@
1
+ # StringNumber
2
+
3
+ [![Build Status](https://travis-ci.org/gabynaiman/string_number.png?branch=master)](https://travis-ci.org/gabynaiman/string_number)
4
+
5
+ Strings as a numbers
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'string_number'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install string_number
20
+
21
+ ## Usage
22
+
23
+ str = StringNumber.new 'X'
24
+ str + 1 # => Y
25
+ str + 2 # => Z
26
+ str - 1 # => W
27
+ str + 'A' # => Y
28
+
29
+ str.to_i # => 24
30
+
31
+ StringNumber[1] # => 'A'
32
+ StringNumber[26] # => 'Z'
33
+ StringNumber[27] # => 'AA'
34
+
35
+ StringNumber[1] == (StringNumber[2] - 1) # => true
36
+
37
+ StringNumber.valid 'ABC' # => true
38
+ StringNumber.valid '123' # => false
39
+
40
+ ## Contributing
41
+
42
+ 1. Fork it
43
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
44
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
45
+ 4. Push to the branch (`git push origin my-new-feature`)
46
+ 5. Create new Pull Request
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.test_files = FileList['test/*_test.rb']
7
+ t.verbose = true
8
+ end
@@ -0,0 +1,71 @@
1
+ class StringNumber
2
+ SYMBOLS = Hash[('A'..'Z').each_with_index.map{|s,i| [s,i+1]}]
3
+
4
+ def initialize(value)
5
+ raise ArgumentError, "Invalid value for #{self.class.name} (#{value})" unless self.class.valid(value)
6
+ @value = value.upcase
7
+ end
8
+
9
+ def +(value)
10
+ self.class[to_i + number_of(value)]
11
+ end
12
+
13
+ def -(value)
14
+ number = number_of(value)
15
+ result = to_i - number
16
+ raise StandardError, "Cant substract from #{number} to #{to_s}" if result < 1
17
+ self.class[result]
18
+ end
19
+
20
+ def eql?(other)
21
+ return false unless other.is_a? self.class
22
+ to_s.eql?(other.to_s)
23
+ end
24
+
25
+ def ==(other)
26
+ return false unless other.is_a? self.class
27
+ to_s == other.to_s
28
+ end
29
+
30
+ def to_s
31
+ @value
32
+ end
33
+
34
+ def to_i
35
+ segments = @value.reverse.split('')
36
+ units = segments.each_with_index.map{ |s,i| SYMBOLS[s] * self.class.base**i }
37
+ units.inject(:+)
38
+ end
39
+
40
+ def self.[](number)
41
+ return self.new(SYMBOLS.keys[number-1]) if number <= SYMBOLS.count
42
+
43
+ quotient = number / base
44
+ reminder = number % base
45
+ quotient -= 1 if reminder == 0
46
+ recursive = self[quotient].to_s if quotient > 0
47
+ self.new((recursive || '') + SYMBOLS.keys[reminder-1])
48
+ end
49
+
50
+ def self.base
51
+ SYMBOLS.count
52
+ end
53
+
54
+ def self.valid(string)
55
+ return false unless string.is_a? String
56
+ string.match(/[A-Z]*/i).to_s == string
57
+ end
58
+
59
+ private
60
+
61
+ def number_of(value)
62
+ if value.is_a? Integer
63
+ value
64
+ elsif self.class.valid(value)
65
+ self.class.new(value).to_i
66
+ else
67
+ raise ArgumentError, "Cant convert #{value} to a number"
68
+ end
69
+ end
70
+
71
+ end
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "string_number"
7
+ spec.version = '0.0.1'
8
+ spec.authors = ["Gabriel Naiman"]
9
+ spec.email = ["gabynaiman@gmail.com"]
10
+ spec.description = "Strings as a numbers"
11
+ spec.summary = "Strings as a numbers"
12
+ spec.homepage = "https://github.com/gabynaiman/string_number"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.add_development_dependency "rake"
22
+ end
@@ -0,0 +1,92 @@
1
+ require 'test_helper'
2
+
3
+ class TestStringNumber < Test::Unit::TestCase
4
+
5
+ def test_initialization
6
+ assert_equal 'A', StringNumber.new('A').to_s
7
+ assert_equal 'STA', StringNumber.new('STA').to_s
8
+ assert_equal 'ABC', StringNumber.new('abc').to_s
9
+
10
+ assert_raise(ArgumentError) { StringNumber.new('abc123') }
11
+ assert_raise(ArgumentError) { StringNumber.new(123) }
12
+ assert_raise(ArgumentError) { StringNumber.new(Object.new) }
13
+ end
14
+
15
+ def test_valid
16
+ assert StringNumber.valid('A')
17
+ assert StringNumber.valid('STA')
18
+ assert StringNumber.valid('abc')
19
+
20
+ assert !StringNumber.valid('abc123')
21
+ assert !StringNumber.valid(123)
22
+ assert !StringNumber.valid(Object.new)
23
+ end
24
+
25
+ def test_to_number
26
+ assert_equal 1, StringNumber.new('A').to_i
27
+ assert_equal 26, StringNumber.new('Z').to_i
28
+ assert_equal 27, StringNumber.new('AA').to_i
29
+ assert_equal 36, StringNumber.new('AJ').to_i
30
+ assert_equal 52, StringNumber.new('AZ').to_i
31
+ assert_equal 53, StringNumber.new('BA').to_i
32
+ assert_equal 78, StringNumber.new('BZ').to_i
33
+ assert_equal 79, StringNumber.new('CA').to_i
34
+ assert_equal 702, StringNumber.new('ZZ').to_i
35
+ assert_equal 703, StringNumber.new('AAA').to_i
36
+ assert_equal 704, StringNumber.new('AAB').to_i
37
+ assert_equal 728, StringNumber.new('AAZ').to_i
38
+ assert_equal 729, StringNumber.new('ABA').to_i
39
+ end
40
+
41
+ def test_from_number
42
+ assert_equal 'A', StringNumber[1].to_s
43
+ assert_equal 'Z', StringNumber[26].to_s
44
+ assert_equal 'AA', StringNumber[27].to_s
45
+ assert_equal 'AJ', StringNumber[36].to_s
46
+ assert_equal 'AZ', StringNumber[52].to_s
47
+ assert_equal 'BA', StringNumber[53].to_s
48
+ assert_equal 'BZ', StringNumber[78].to_s
49
+ assert_equal 'CA', StringNumber[79].to_s
50
+ assert_equal 'ZZ', StringNumber[702].to_s
51
+ assert_equal 'AAA', StringNumber[703].to_s
52
+ assert_equal 'AAB', StringNumber[704].to_s
53
+ assert_equal 'AAZ', StringNumber[728].to_s
54
+ assert_equal 'ABA', StringNumber[729].to_s
55
+ end
56
+
57
+ def test_addition
58
+ assert_equal 'B', (StringNumber.new('A') + 1).to_s
59
+ assert_equal 'AA', (StringNumber.new('Y') + 2).to_s
60
+ assert_equal 'BA', (StringNumber.new('AX') + 3).to_s
61
+ assert_equal 'CA', (StringNumber.new('BW') + 4).to_s
62
+ assert_equal 'AAAA', (StringNumber.new('ZZV') + 5).to_s
63
+
64
+ assert_equal 'B', (StringNumber.new('A') + 'A').to_s
65
+ assert_equal 'C', (StringNumber.new('A') + 'B').to_s
66
+
67
+ assert_raise(ArgumentError) { StringNumber.new('A') + Object.new }
68
+ end
69
+
70
+ def test_substraction
71
+ assert_equal 'A', (StringNumber.new('B') - 1).to_s
72
+ assert_equal 'Y', (StringNumber.new('AA') - 2).to_s
73
+ assert_equal 'AX', (StringNumber.new('BA') - 3).to_s
74
+ assert_equal 'BW', (StringNumber.new('CA') - 4).to_s
75
+ assert_equal 'ZZV', (StringNumber.new('AAAA') - 5).to_s
76
+
77
+ assert_equal 'A', (StringNumber.new('B') - 'A').to_s
78
+ assert_equal 'A', (StringNumber.new('C') - 'B').to_s
79
+
80
+ assert_raise(ArgumentError) { StringNumber.new('A') - Object.new }
81
+ assert_raise(StandardError) { StringNumber.new('A') - 1 }
82
+ end
83
+
84
+ def test_equality
85
+ assert_equal StringNumber.new('A'), StringNumber.new('A')
86
+ assert_equal StringNumber.new('A'), StringNumber[1]
87
+ assert_equal [StringNumber.new('A')], [StringNumber[1]]
88
+
89
+ assert_not_equal StringNumber.new('A'), StringNumber.new('B')
90
+ end
91
+
92
+ end
@@ -0,0 +1,2 @@
1
+ require 'string_number'
2
+ require 'test/unit'
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: string_number
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gabriel Naiman
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Strings as a numbers
47
+ email:
48
+ - gabynaiman@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - .travis.yml
55
+ - Gemfile
56
+ - LICENSE.txt
57
+ - README.md
58
+ - Rakefile
59
+ - lib/string_number.rb
60
+ - string_number.gemspec
61
+ - test/string_number_test.rb
62
+ - test/test_helper.rb
63
+ homepage: https://github.com/gabynaiman/string_number
64
+ licenses:
65
+ - MIT
66
+ post_install_message:
67
+ rdoc_options: []
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubyforge_project:
84
+ rubygems_version: 1.8.24
85
+ signing_key:
86
+ specification_version: 3
87
+ summary: Strings as a numbers
88
+ test_files:
89
+ - test/string_number_test.rb
90
+ - test/test_helper.rb
91
+ has_rdoc: