ziffern 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|