ziffern 1.0.0
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 +7 -0
- data/README.md +21 -0
- data/ziffern.rb +115 -0
- data/ziffern_spec.rb +89 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 784b7651963c3d172aa3bcf7e404760f3260eefa
|
4
|
+
data.tar.gz: 75236a977a0952a3a342bc443e66dfdad03cafac
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 074a40b8cc9ab7bc119f7c9c505c0e1709cc906f012ba6b4b79b6198bb0a6b09ca09e59acde4f755810f25b59cb896db4c78af1165be399e53991a37487dbaec
|
7
|
+
data.tar.gz: 088340abdc8033fa0175629cacf60dd3a1f4c4195ade5b290aaecc6ab414d5af89a2e719b780d367e3ef948bd29d14acec593b29bc77e108250d77d73aecd338
|
data/README.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Ziffern
|
2
|
+
|
3
|
+
**Number to text, in _German_!**
|
4
|
+
|
5
|
+
Handles _positive and negative_ numbers up to **125 digits**, with _unlimited decimals_.
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
require 'ziffern'
|
9
|
+
converter = Ziffern.new
|
10
|
+
|
11
|
+
[1, -5, 12345, 99.99, '0.00', 10**63 + 1].each do |number|
|
12
|
+
puts converter.to_german(number)
|
13
|
+
end
|
14
|
+
|
15
|
+
# >> eins
|
16
|
+
# >> minus fünf
|
17
|
+
# >> zwölftausenddreihundertfünfundvierzig
|
18
|
+
# >> neunundneunzig Komma neun neun
|
19
|
+
# >> null Komma null null
|
20
|
+
# >> eine Dezilliarde eins
|
21
|
+
```
|
data/ziffern.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
class Ziffern
|
2
|
+
|
3
|
+
# http://de.wikipedia.org/wiki/Zahlennamen
|
4
|
+
|
5
|
+
NINETEEN = %w{ null ein zwei drei vier fünf sechs sieben acht neun zehn elf zwölf
|
6
|
+
dreizehn vierzehn fünfzehn sechzehn siebzehn achtzehn neunzehn }
|
7
|
+
|
8
|
+
TENS = %w{ zwanzig dreißig vierzig fünfzig sechzig siebzig achtzig neunzig }.unshift(nil, nil)
|
9
|
+
|
10
|
+
BIG = %w{ M B Tr Quadr Quint Sext Sept Okt Non Dez Undez Dodez Tredez
|
11
|
+
Quattuordez Quindez Sedez Septendez Dodevigint Undevigint Vigint }.flat_map do |prefix|
|
12
|
+
%W( #{prefix}illion #{prefix}illiarde )
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def to_german(number)
|
17
|
+
convert_integer(number) + convert_decimals(number)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def convert_integer(number)
|
23
|
+
number = number.to_i
|
24
|
+
return 'eins' if number == 1
|
25
|
+
return "minus #{convert_integer(number.abs)}" if number < 0
|
26
|
+
|
27
|
+
convert(number)
|
28
|
+
end
|
29
|
+
|
30
|
+
def convert(number)
|
31
|
+
case number
|
32
|
+
when 0..19 then NINETEEN[number]
|
33
|
+
when 20..99 then twenty_to_99(number)
|
34
|
+
when 100..999 then quantify_factor(100, 'hundert', number)
|
35
|
+
when 1000..999_999 then quantify_factor(1000, 'tausend', number)
|
36
|
+
else bignums(number)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def twenty_to_99(number)
|
41
|
+
ten, remainder = number.divmod(10)
|
42
|
+
|
43
|
+
if remainder.zero?
|
44
|
+
TENS[ten]
|
45
|
+
else
|
46
|
+
"#{NINETEEN[remainder]}und#{TENS[ten]}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def quantify_factor(factor, name, number)
|
51
|
+
amount, remainder = number.divmod(factor)
|
52
|
+
|
53
|
+
result = convert(amount) + name
|
54
|
+
result.tap do |result|
|
55
|
+
result << convert(remainder) unless remainder.zero?
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def bignums(number)
|
60
|
+
number_of_millions, remainder = number.divmod(1000_000)
|
61
|
+
|
62
|
+
convert_millions(number_of_millions).tap do |result|
|
63
|
+
result << " " << convert_integer(remainder) unless remainder.zero?
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def convert_millions(number_of_millions)
|
68
|
+
groups = group_with_big_names(number_of_millions)
|
69
|
+
fail ArgumentError, 'Number too large' if groups.size > BIG.size
|
70
|
+
|
71
|
+
groups
|
72
|
+
.reject { |amount, *| amount.zero? }
|
73
|
+
.map { |amount, name| quantify_big_name(amount, name) }
|
74
|
+
.join(' ')
|
75
|
+
end
|
76
|
+
|
77
|
+
def quantify_big_name(amount, big_name)
|
78
|
+
if amount == 1
|
79
|
+
quantity = 'eine'
|
80
|
+
else
|
81
|
+
quantity = convert(amount)
|
82
|
+
big_name = big_name.sub(/(e?)$/, 'en')
|
83
|
+
end
|
84
|
+
|
85
|
+
"#{quantity} #{big_name}"
|
86
|
+
end
|
87
|
+
|
88
|
+
# 12345678 => [[12, "Billion"], [345, "Milliarde"], [678, "Million"]]
|
89
|
+
def group_with_big_names(number_of_millions)
|
90
|
+
groups = []
|
91
|
+
|
92
|
+
until number_of_millions.zero?
|
93
|
+
number_of_millions, last_3 = number_of_millions.divmod(1000)
|
94
|
+
groups << last_3
|
95
|
+
end
|
96
|
+
|
97
|
+
groups.zip(BIG).reverse
|
98
|
+
end
|
99
|
+
|
100
|
+
def convert_decimals(number)
|
101
|
+
decimals = get_decimals_as_string(number)
|
102
|
+
return '' if decimals.empty?
|
103
|
+
|
104
|
+
' Komma ' + convert_digits(decimals)
|
105
|
+
end
|
106
|
+
|
107
|
+
def get_decimals_as_string(number)
|
108
|
+
number.to_s[/\.(\d+)/, 1].to_s
|
109
|
+
end
|
110
|
+
|
111
|
+
def convert_digits(number)
|
112
|
+
number.to_s.chars.map { |digit| convert_integer(digit) }.join(' ')
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
data/ziffern_spec.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
require './ziffern'
|
2
|
+
|
3
|
+
describe Ziffern do
|
4
|
+
|
5
|
+
subject { Ziffern.new }
|
6
|
+
|
7
|
+
def self.test_german_numbers(hash)
|
8
|
+
hash.each do |integer, german|
|
9
|
+
instance_eval do
|
10
|
+
it "converts #{integer} to #{german}" do
|
11
|
+
expect(subject.to_german(integer)).to eq german
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'numbers up to 20' do
|
18
|
+
test_german_numbers({
|
19
|
+
0 => "null",
|
20
|
+
1 => "eins",
|
21
|
+
13 => "dreizehn",
|
22
|
+
19 => "neunzehn",
|
23
|
+
})
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'numbers up to 100' do
|
27
|
+
test_german_numbers({
|
28
|
+
20 => "zwanzig",
|
29
|
+
21 => "einundzwanzig",
|
30
|
+
63 => "dreiundsechzig",
|
31
|
+
99 => "neunundneunzig",
|
32
|
+
})
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'numbers up to 1000' do
|
36
|
+
test_german_numbers({
|
37
|
+
100 => "einhundert",
|
38
|
+
234 => "zweihundertvierunddreißig",
|
39
|
+
999 => "neunhundertneunundneunzig",
|
40
|
+
})
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'up to one million' do
|
44
|
+
test_german_numbers({
|
45
|
+
1000 => "eintausend",
|
46
|
+
1234 => "eintausendzweihundertvierunddreißig",
|
47
|
+
10_000 => "zehntausend",
|
48
|
+
999_999 => "neunhundertneunundneunzigtausendneunhundertneunundneunzig",
|
49
|
+
})
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'really big numbers' do
|
53
|
+
test_german_numbers({
|
54
|
+
1_000_000 => "eine Million",
|
55
|
+
1_000_001 => "eine Million eins",
|
56
|
+
2_204_510 => "zwei Millionen zweihundertviertausendfünfhundertzehn",
|
57
|
+
1_203_400_021 => "eine Milliarde zweihundertdrei Millionen vierhunderttausendeinundzwanzig",
|
58
|
+
3_000_000_000_000_099 => "drei Billiarden neunundneunzig",
|
59
|
+
10 ** 123 => "eine Vigintilliarde"
|
60
|
+
})
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'throws an ArgumentError if the number is bigger than it can handle' do
|
64
|
+
expect { subject.to_german(10 ** 126) }.to raise_error ArgumentError
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'negative numbers' do
|
68
|
+
test_german_numbers({
|
69
|
+
-1 => "minus eins",
|
70
|
+
-20 => "minus zwanzig",
|
71
|
+
-21 => "minus einundzwanzig",
|
72
|
+
-63 => "minus dreiundsechzig",
|
73
|
+
-99 => "minus neunundneunzig",
|
74
|
+
})
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
context 'decimals' do
|
79
|
+
test_german_numbers({
|
80
|
+
0.1234 => "null Komma eins zwei drei vier",
|
81
|
+
5.6789 => "fünf Komma sechs sieben acht neun",
|
82
|
+
-5.6 => "minus fünf Komma sechs",
|
83
|
+
-567.89 => "minus fünfhundertsiebenundsechzig Komma acht neun",
|
84
|
+
5.0 => "fünf Komma null",
|
85
|
+
'5.00' => "fünf Komma null null"
|
86
|
+
})
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ziffern
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jimmy Börjesson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-08-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
description:
|
56
|
+
email: lagginglion@gmail.com
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- README.md
|
62
|
+
- ziffern.rb
|
63
|
+
- ziffern_spec.rb
|
64
|
+
homepage: https://github.com/alcesleo/ziffern
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
metadata: {}
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- "."
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 2.2.2
|
85
|
+
signing_key:
|
86
|
+
specification_version: 4
|
87
|
+
summary: Converts numbers to text, in German.
|
88
|
+
test_files:
|
89
|
+
- ziffern_spec.rb
|