easy_to_dictate_numbers 0.1.2 → 0.1.4
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 +4 -4
- data/.rubocop.yml +340 -1
- data/CHANGELOG.md +14 -0
- data/README.md +22 -2
- data/easy_to_dictate_numbers.gemspec +2 -2
- data/lib/easy_to_dictate_numbers/dictable_number.rb +114 -0
- data/lib/easy_to_dictate_numbers/exceptions.rb +11 -0
- data/lib/easy_to_dictate_numbers/extend_primitives.rb +7 -1
- data/lib/easy_to_dictate_numbers/version.rb +1 -1
- data/lib/easy_to_dictate_numbers.rb +2 -52
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aad1aad5f6f04f1c1788f38a5b5698a247198f1fedb8a811c997128bef520344
|
4
|
+
data.tar.gz: 79192439f74c5525eb578dff92542a78231c8237e4a37bb48e52bea13137f68f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3903d276514862a8c8a8f870109b2ab6e7be5e7ae1e6b664f4aca5c129654d11a2503c0254e8dc516cbd04a99ba6ecd6ecd326f5913b2ee6c9a6b928401a9431
|
7
|
+
data.tar.gz: 037e26765bba96e29941dce83e4abdaab9a7a86ea30324ae8f6bbce9769fba2bbab323b95ca8f31b3ccc97432e2ed9d3d7fb44bb41cbddd41aad59e92b35291f
|
data/.rubocop.yml
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
|
2
|
+
require:
|
3
|
+
- rubocop-performance
|
4
|
+
- rubocop-rspec
|
5
|
+
- rubocop-rake
|
6
|
+
|
1
7
|
AllCops:
|
2
8
|
TargetRubyVersion: 2.6
|
3
9
|
|
@@ -8,4 +14,337 @@ Style/Documentation:
|
|
8
14
|
Enabled: false
|
9
15
|
|
10
16
|
Metrics/BlockLength:
|
11
|
-
Enabled: false
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
Gemspec/DeprecatedAttributeAssignment: # new in 1.30
|
20
|
+
Enabled: true
|
21
|
+
Gemspec/DevelopmentDependencies: # new in 1.44
|
22
|
+
Enabled: true
|
23
|
+
Gemspec/RequireMFA: # new in 1.23
|
24
|
+
Enabled: true
|
25
|
+
Layout/LineContinuationLeadingSpace: # new in 1.31
|
26
|
+
Enabled: true
|
27
|
+
Layout/LineContinuationSpacing: # new in 1.31
|
28
|
+
Enabled: true
|
29
|
+
Layout/LineEndStringConcatenationIndentation: # new in 1.18
|
30
|
+
Enabled: true
|
31
|
+
Layout/SpaceBeforeBrackets: # new in 1.7
|
32
|
+
Enabled: true
|
33
|
+
Lint/AmbiguousAssignment: # new in 1.7
|
34
|
+
Enabled: true
|
35
|
+
Lint/AmbiguousOperatorPrecedence: # new in 1.21
|
36
|
+
Enabled: true
|
37
|
+
Lint/AmbiguousRange: # new in 1.19
|
38
|
+
Enabled: true
|
39
|
+
Lint/ConstantOverwrittenInRescue: # new in 1.31
|
40
|
+
Enabled: true
|
41
|
+
Lint/DeprecatedConstants: # new in 1.8
|
42
|
+
Enabled: true
|
43
|
+
Lint/DuplicateBranch: # new in 1.3
|
44
|
+
Enabled: true
|
45
|
+
Lint/DuplicateMagicComment: # new in 1.37
|
46
|
+
Enabled: true
|
47
|
+
Lint/DuplicateMatchPattern: # new in 1.50
|
48
|
+
Enabled: true
|
49
|
+
Lint/DuplicateRegexpCharacterClassElement: # new in 1.1
|
50
|
+
Enabled: true
|
51
|
+
Lint/EmptyBlock: # new in 1.1
|
52
|
+
Enabled: true
|
53
|
+
Lint/EmptyClass: # new in 1.3
|
54
|
+
Enabled: true
|
55
|
+
Lint/EmptyInPattern: # new in 1.16
|
56
|
+
Enabled: true
|
57
|
+
Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
|
58
|
+
Enabled: true
|
59
|
+
Lint/LambdaWithoutLiteralBlock: # new in 1.8
|
60
|
+
Enabled: true
|
61
|
+
Lint/LiteralAssignmentInCondition: # new in 1.58
|
62
|
+
Enabled: true
|
63
|
+
Lint/MixedCaseRange: # new in 1.53
|
64
|
+
Enabled: true
|
65
|
+
Lint/NoReturnInBeginEndBlocks: # new in 1.2
|
66
|
+
Enabled: true
|
67
|
+
Lint/NonAtomicFileOperation: # new in 1.31
|
68
|
+
Enabled: true
|
69
|
+
Lint/NumberedParameterAssignment: # new in 1.9
|
70
|
+
Enabled: true
|
71
|
+
Lint/OrAssignmentToConstant: # new in 1.9
|
72
|
+
Enabled: true
|
73
|
+
Lint/RedundantDirGlobSort: # new in 1.8
|
74
|
+
Enabled: true
|
75
|
+
Lint/RedundantRegexpQuantifiers: # new in 1.53
|
76
|
+
Enabled: true
|
77
|
+
Lint/RefinementImportMethods: # new in 1.27
|
78
|
+
Enabled: true
|
79
|
+
Lint/RequireRangeParentheses: # new in 1.32
|
80
|
+
Enabled: true
|
81
|
+
Lint/RequireRelativeSelfPath: # new in 1.22
|
82
|
+
Enabled: true
|
83
|
+
Lint/SymbolConversion: # new in 1.9
|
84
|
+
Enabled: true
|
85
|
+
Lint/ToEnumArguments: # new in 1.1
|
86
|
+
Enabled: true
|
87
|
+
Lint/TripleQuotes: # new in 1.9
|
88
|
+
Enabled: true
|
89
|
+
Lint/UnexpectedBlockArity: # new in 1.5
|
90
|
+
Enabled: true
|
91
|
+
Lint/UnmodifiedReduceAccumulator: # new in 1.1
|
92
|
+
Enabled: true
|
93
|
+
Lint/UselessRescue: # new in 1.43
|
94
|
+
Enabled: true
|
95
|
+
Lint/UselessRuby2Keywords: # new in 1.23
|
96
|
+
Enabled: true
|
97
|
+
Metrics/CollectionLiteralLength: # new in 1.47
|
98
|
+
Enabled: true
|
99
|
+
Naming/BlockForwarding: # new in 1.24
|
100
|
+
Enabled: true
|
101
|
+
Security/CompoundHash: # new in 1.28
|
102
|
+
Enabled: true
|
103
|
+
Security/IoMethods: # new in 1.22
|
104
|
+
Enabled: true
|
105
|
+
Style/ArgumentsForwarding: # new in 1.1
|
106
|
+
Enabled: true
|
107
|
+
Style/ArrayIntersect: # new in 1.40
|
108
|
+
Enabled: true
|
109
|
+
Style/CollectionCompact: # new in 1.2
|
110
|
+
Enabled: true
|
111
|
+
Style/ComparableClamp: # new in 1.44
|
112
|
+
Enabled: true
|
113
|
+
Style/ConcatArrayLiterals: # new in 1.41
|
114
|
+
Enabled: true
|
115
|
+
Style/DataInheritance: # new in 1.49
|
116
|
+
Enabled: true
|
117
|
+
Style/DirEmpty: # new in 1.48
|
118
|
+
Enabled: true
|
119
|
+
Style/DocumentDynamicEvalDefinition: # new in 1.1
|
120
|
+
Enabled: true
|
121
|
+
Style/EmptyHeredoc: # new in 1.32
|
122
|
+
Enabled: true
|
123
|
+
Style/EndlessMethod: # new in 1.8
|
124
|
+
Enabled: true
|
125
|
+
Style/EnvHome: # new in 1.29
|
126
|
+
Enabled: true
|
127
|
+
Style/ExactRegexpMatch: # new in 1.51
|
128
|
+
Enabled: true
|
129
|
+
Style/FetchEnvVar: # new in 1.28
|
130
|
+
Enabled: true
|
131
|
+
Style/FileEmpty: # new in 1.48
|
132
|
+
Enabled: true
|
133
|
+
Style/FileRead: # new in 1.24
|
134
|
+
Enabled: true
|
135
|
+
Style/FileWrite: # new in 1.24
|
136
|
+
Enabled: true
|
137
|
+
Style/HashConversion: # new in 1.10
|
138
|
+
Enabled: true
|
139
|
+
Style/HashExcept: # new in 1.7
|
140
|
+
Enabled: true
|
141
|
+
Style/IfWithBooleanLiteralBranches: # new in 1.9
|
142
|
+
Enabled: true
|
143
|
+
Style/InPatternThen: # new in 1.16
|
144
|
+
Enabled: true
|
145
|
+
Style/MagicCommentFormat: # new in 1.35
|
146
|
+
Enabled: true
|
147
|
+
Style/MapCompactWithConditionalBlock: # new in 1.30
|
148
|
+
Enabled: true
|
149
|
+
Style/MapToHash: # new in 1.24
|
150
|
+
Enabled: true
|
151
|
+
Style/MapToSet: # new in 1.42
|
152
|
+
Enabled: true
|
153
|
+
Style/MinMaxComparison: # new in 1.42
|
154
|
+
Enabled: true
|
155
|
+
Style/MultilineInPatternThen: # new in 1.16
|
156
|
+
Enabled: true
|
157
|
+
Style/NegatedIfElseCondition: # new in 1.2
|
158
|
+
Enabled: true
|
159
|
+
Style/NestedFileDirname: # new in 1.26
|
160
|
+
Enabled: true
|
161
|
+
Style/NilLambda: # new in 1.3
|
162
|
+
Enabled: true
|
163
|
+
Style/NumberedParameters: # new in 1.22
|
164
|
+
Enabled: true
|
165
|
+
Style/NumberedParametersLimit: # new in 1.22
|
166
|
+
Enabled: true
|
167
|
+
Style/ObjectThen: # new in 1.28
|
168
|
+
Enabled: true
|
169
|
+
Style/OpenStructUse: # new in 1.23
|
170
|
+
Enabled: true
|
171
|
+
Style/OperatorMethodCall: # new in 1.37
|
172
|
+
Enabled: true
|
173
|
+
Style/QuotedSymbols: # new in 1.16
|
174
|
+
Enabled: true
|
175
|
+
Style/RedundantArgument: # new in 1.4
|
176
|
+
Enabled: true
|
177
|
+
Style/RedundantArrayConstructor: # new in 1.52
|
178
|
+
Enabled: true
|
179
|
+
Style/RedundantConstantBase: # new in 1.40
|
180
|
+
Enabled: true
|
181
|
+
Style/RedundantCurrentDirectoryInPath: # new in 1.53
|
182
|
+
Enabled: true
|
183
|
+
Style/RedundantDoubleSplatHashBraces: # new in 1.41
|
184
|
+
Enabled: true
|
185
|
+
Style/RedundantEach: # new in 1.38
|
186
|
+
Enabled: true
|
187
|
+
Style/RedundantFilterChain: # new in 1.52
|
188
|
+
Enabled: true
|
189
|
+
Style/RedundantHeredocDelimiterQuotes: # new in 1.45
|
190
|
+
Enabled: true
|
191
|
+
Style/RedundantInitialize: # new in 1.27
|
192
|
+
Enabled: true
|
193
|
+
Style/RedundantLineContinuation: # new in 1.49
|
194
|
+
Enabled: true
|
195
|
+
Style/RedundantRegexpArgument: # new in 1.53
|
196
|
+
Enabled: true
|
197
|
+
Style/RedundantRegexpConstructor: # new in 1.52
|
198
|
+
Enabled: true
|
199
|
+
Style/RedundantSelfAssignmentBranch: # new in 1.19
|
200
|
+
Enabled: true
|
201
|
+
Style/RedundantStringEscape: # new in 1.37
|
202
|
+
Enabled: true
|
203
|
+
Style/ReturnNilInPredicateMethodDefinition: # new in 1.53
|
204
|
+
Enabled: true
|
205
|
+
Style/SelectByRegexp: # new in 1.22
|
206
|
+
Enabled: true
|
207
|
+
Style/SingleLineDoEndBlock: # new in 1.57
|
208
|
+
Enabled: true
|
209
|
+
Style/StringChars: # new in 1.12
|
210
|
+
Enabled: true
|
211
|
+
Style/SuperWithArgsParentheses: # new in 1.58
|
212
|
+
Enabled: true
|
213
|
+
Style/SwapValues: # new in 1.1
|
214
|
+
Enabled: true
|
215
|
+
Style/YAMLFileRead: # new in 1.53
|
216
|
+
Enabled: true
|
217
|
+
Capybara/ClickLinkOrButtonStyle: # new in 2.19
|
218
|
+
Enabled: true
|
219
|
+
Capybara/MatchStyle: # new in 2.17
|
220
|
+
Enabled: true
|
221
|
+
Capybara/NegationMatcher: # new in 2.14
|
222
|
+
Enabled: true
|
223
|
+
Capybara/RedundantWithinFind: # new in 2.20
|
224
|
+
Enabled: true
|
225
|
+
Capybara/SpecificActions: # new in 2.14
|
226
|
+
Enabled: true
|
227
|
+
Capybara/SpecificFinders: # new in 2.13
|
228
|
+
Enabled: true
|
229
|
+
Capybara/SpecificMatcher: # new in 2.12
|
230
|
+
Enabled: true
|
231
|
+
Capybara/RSpec/HaveSelector: # new in 2.19
|
232
|
+
Enabled: true
|
233
|
+
Capybara/RSpec/PredicateMatcher: # new in 2.19
|
234
|
+
Enabled: true
|
235
|
+
FactoryBot/AssociationStyle: # new in 2.23
|
236
|
+
Enabled: true
|
237
|
+
FactoryBot/ConsistentParenthesesStyle: # new in 2.14
|
238
|
+
Enabled: true
|
239
|
+
FactoryBot/ExcessiveCreateList: # new in 2.25
|
240
|
+
Enabled: true
|
241
|
+
FactoryBot/FactoryAssociationWithStrategy: # new in 2.23
|
242
|
+
Enabled: true
|
243
|
+
FactoryBot/FactoryNameStyle: # new in 2.16
|
244
|
+
Enabled: true
|
245
|
+
FactoryBot/IdSequence: # new in 2.24
|
246
|
+
Enabled: true
|
247
|
+
FactoryBot/RedundantFactoryOption: # new in 2.23
|
248
|
+
Enabled: true
|
249
|
+
FactoryBot/SyntaxMethods: # new in 2.7
|
250
|
+
Enabled: true
|
251
|
+
RSpec/BeEmpty: # new in 2.20
|
252
|
+
Enabled: true
|
253
|
+
RSpec/BeEq: # new in 2.9.0
|
254
|
+
Enabled: true
|
255
|
+
RSpec/BeNil: # new in 2.9.0
|
256
|
+
Enabled: true
|
257
|
+
RSpec/ChangeByZero: # new in 2.11
|
258
|
+
Enabled: true
|
259
|
+
RSpec/ContainExactly: # new in 2.19
|
260
|
+
Enabled: true
|
261
|
+
RSpec/DuplicatedMetadata: # new in 2.16
|
262
|
+
Enabled: true
|
263
|
+
RSpec/EmptyMetadata: # new in 2.24
|
264
|
+
Enabled: true
|
265
|
+
RSpec/Eq: # new in 2.24
|
266
|
+
Enabled: true
|
267
|
+
RSpec/ExcessiveDocstringSpacing: # new in 2.5
|
268
|
+
Enabled: true
|
269
|
+
RSpec/IdenticalEqualityAssertion: # new in 2.4
|
270
|
+
Enabled: true
|
271
|
+
RSpec/IndexedLet: # new in 2.20
|
272
|
+
Enabled: true
|
273
|
+
RSpec/MatchArray: # new in 2.19
|
274
|
+
Enabled: true
|
275
|
+
RSpec/MetadataStyle: # new in 2.24
|
276
|
+
Enabled: true
|
277
|
+
RSpec/NoExpectationExample: # new in 2.13
|
278
|
+
Enabled: true
|
279
|
+
RSpec/PendingWithoutReason: # new in 2.16
|
280
|
+
Enabled: true
|
281
|
+
RSpec/ReceiveMessages: # new in 2.23
|
282
|
+
Enabled: true
|
283
|
+
RSpec/RedundantAround: # new in 2.19
|
284
|
+
Enabled: true
|
285
|
+
RSpec/RedundantPredicateMatcher: # new in 2.26
|
286
|
+
Enabled: true
|
287
|
+
RSpec/RemoveConst: # new in 2.26
|
288
|
+
Enabled: true
|
289
|
+
RSpec/SkipBlockInsideExample: # new in 2.19
|
290
|
+
Enabled: true
|
291
|
+
RSpec/SortMetadata: # new in 2.14
|
292
|
+
Enabled: true
|
293
|
+
RSpec/SpecFilePathFormat: # new in 2.24
|
294
|
+
Enabled: true
|
295
|
+
RSpec/SpecFilePathSuffix: # new in 2.24
|
296
|
+
Enabled: true
|
297
|
+
RSpec/SubjectDeclaration: # new in 2.5
|
298
|
+
Enabled: true
|
299
|
+
RSpec/VerifiedDoubleReference: # new in 2.10.0
|
300
|
+
Enabled: true
|
301
|
+
RSpec/Rails/AvoidSetupHook: # new in 2.4
|
302
|
+
Enabled: true
|
303
|
+
RSpec/Rails/HaveHttpStatus: # new in 2.12
|
304
|
+
Enabled: true
|
305
|
+
RSpec/Rails/InferredSpecType: # new in 2.14
|
306
|
+
Enabled: true
|
307
|
+
RSpec/Rails/MinitestAssertions: # new in 2.17
|
308
|
+
Enabled: true
|
309
|
+
RSpec/Rails/NegationBeValid: # new in 2.23
|
310
|
+
Enabled: true
|
311
|
+
RSpec/Rails/TravelAround: # new in 2.19
|
312
|
+
Enabled: true
|
313
|
+
Performance/AncestorsInclude: # new in 1.7
|
314
|
+
Enabled: true
|
315
|
+
Performance/BigDecimalWithNumericArgument: # new in 1.7
|
316
|
+
Enabled: true
|
317
|
+
Performance/BlockGivenWithExplicitBlock: # new in 1.9
|
318
|
+
Enabled: true
|
319
|
+
Performance/CollectionLiteralInLoop: # new in 1.8
|
320
|
+
Enabled: true
|
321
|
+
Performance/ConcurrentMonotonicTime: # new in 1.12
|
322
|
+
Enabled: true
|
323
|
+
Performance/ConstantRegexp: # new in 1.9
|
324
|
+
Enabled: true
|
325
|
+
Performance/MapCompact: # new in 1.11
|
326
|
+
Enabled: true
|
327
|
+
Performance/MapMethodChain: # new in 1.19
|
328
|
+
Enabled: true
|
329
|
+
Performance/MethodObjectAsBlock: # new in 1.9
|
330
|
+
Enabled: true
|
331
|
+
Performance/RedundantEqualityComparisonBlock: # new in 1.10
|
332
|
+
Enabled: true
|
333
|
+
Performance/RedundantSortBlock: # new in 1.7
|
334
|
+
Enabled: true
|
335
|
+
Performance/RedundantSplitRegexpArgument: # new in 1.10
|
336
|
+
Enabled: true
|
337
|
+
Performance/RedundantStringChars: # new in 1.7
|
338
|
+
Enabled: true
|
339
|
+
Performance/ReverseFirst: # new in 1.7
|
340
|
+
Enabled: true
|
341
|
+
Performance/SortReverse: # new in 1.7
|
342
|
+
Enabled: true
|
343
|
+
Performance/Squeeze: # new in 1.7
|
344
|
+
Enabled: true
|
345
|
+
Performance/StringIdentifierArgument: # new in 1.13
|
346
|
+
Enabled: true
|
347
|
+
Performance/StringInclude: # new in 1.7
|
348
|
+
Enabled: true
|
349
|
+
Performance/Sum: # new in 1.8
|
350
|
+
Enabled: true
|
data/CHANGELOG.md
CHANGED
@@ -11,3 +11,17 @@
|
|
11
11
|
## [0.1.2] - 2024-01-14
|
12
12
|
|
13
13
|
- Moved extend primitives require to lib/easy_to_dictate_numbers.rb.
|
14
|
+
|
15
|
+
## [0.1.3] - 2024-01-14
|
16
|
+
|
17
|
+
- Refactored to cover special cases:
|
18
|
+
- 100 -> one hundred
|
19
|
+
- 1000 -> one thousand
|
20
|
+
- 2334 -> twenty three thirty four
|
21
|
+
- Extended string with `to_dictable_number`
|
22
|
+
- Add support for leading zeroes
|
23
|
+
|
24
|
+
## [0.1.4] - 2024-01-14
|
25
|
+
|
26
|
+
- Refactor to use instance methods to avoid exposing so many
|
27
|
+
- Added rubocop and fixed all errors
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# EasyToDictateNumbers
|
2
2
|
|
3
|
-
EasyToDictateNumbers is
|
3
|
+
GitHub Copilot: EasyToDictateNumbers is an opinionated Ruby gem designed to convert numbers into their spoken equivalents. This gem is particularly useful in situations where precise verbal communication of numbers is required, such as during phone calls or dictation. It makes certain decisions about the "best" way to pronounce numbers, which may be subject to debate.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -30,9 +30,29 @@ To use EasyToDictateNumbers, simply call the `to_dictable` method on any `Intege
|
|
30
30
|
require 'easy_to_dictate_numbers'
|
31
31
|
|
32
32
|
puts 123.to_dictable
|
33
|
-
# Output: "one
|
33
|
+
# Output: "one twenty three"
|
34
|
+
|
35
|
+
puts "1243".to_dictable_number
|
36
|
+
# Output: "twelve forty three"
|
34
37
|
```
|
35
38
|
|
39
|
+
## Example
|
40
|
+
List of samples from specs:
|
41
|
+
|
42
|
+
- `100` is converted to `one hundred`
|
43
|
+
- `123` is converted to `one twenty three`
|
44
|
+
- `'001'` is converted to `zero zero one`
|
45
|
+
- `'010'` is converted to `zero ten`
|
46
|
+
- `'0000'` is converted to `zero zero zero zero`
|
47
|
+
- `1000` is converted to `one thousand`
|
48
|
+
- `4321` is converted to `forty three twenty one`
|
49
|
+
- `4300` is converted to `forty three hundred`
|
50
|
+
- `'0001'` is converted to `zero zero zero one`
|
51
|
+
- `'0010'` is converted to `zero zero ten`
|
52
|
+
- `'0100'` is converted to `zero one hundred`
|
53
|
+
|
54
|
+
Please note that the numbers in quotes are treated as strings, which allows leading zeroes to be preserved.
|
55
|
+
|
36
56
|
## Development
|
37
57
|
|
38
58
|
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'lib/easy_to_dictate_numbers/version'
|
4
|
-
require_relative 'lib/easy_to_dictate_numbers/extend_primitives'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
6
|
spec.name = 'easy_to_dictate_numbers'
|
@@ -11,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
11
10
|
|
12
11
|
spec.summary = 'Transform numbers into words to dictate them easily.'
|
13
12
|
spec.description = 'Transform numbers into words to dictate them easily.' \
|
14
|
-
|
13
|
+
"For example 1234 becomes twelve thirty four and 123456 becomes 'one two three, four five six'"
|
15
14
|
spec.homepage = 'https://github.com/matismasters/easy_to_dictate_numbers'
|
16
15
|
spec.required_ruby_version = '>= 2.6.0'
|
17
16
|
|
@@ -37,4 +36,5 @@ Gem::Specification.new do |spec|
|
|
37
36
|
|
38
37
|
# For more information and examples about making a new gem, check out our
|
39
38
|
# guide at: https://bundler.io/guides/creating_gem.html
|
39
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
40
40
|
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EasyToDictateNumbers
|
4
|
+
class DictableNumber
|
5
|
+
attr_reader :number_to_dictate, :dictable_number_in_words
|
6
|
+
|
7
|
+
ONES = %w[zero one two three four five six seven eight nine].freeze
|
8
|
+
TEENS = %w[ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen].freeze
|
9
|
+
TENS = %w[twenty thirty forty fifty sixty seventy eighty ninety].freeze
|
10
|
+
|
11
|
+
def initialize(number_to_dictate)
|
12
|
+
@number_to_dictate = number_to_dictate.to_s
|
13
|
+
validate_number(@number_to_dictate)
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_dictable
|
17
|
+
@to_dictable ||= number_to_words
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def number_to_words
|
23
|
+
number_as_string = @number_to_dictate
|
24
|
+
|
25
|
+
leading_zeroes_words = leading_zeroes_to_words(number_as_string)
|
26
|
+
|
27
|
+
number_without_leading_zeroes = number_without_leading_zeroes(number_as_string)
|
28
|
+
number_without_leading_zeroes_words = number_without_leading_zeroes_to_words(number_without_leading_zeroes)
|
29
|
+
|
30
|
+
[leading_zeroes_words, number_without_leading_zeroes_words].reject(&:empty?).join(' ')
|
31
|
+
end
|
32
|
+
|
33
|
+
def validate_number(number_as_string)
|
34
|
+
raise NonNumberCharactersPresent if number_as_string.match?(/[^0-9]/)
|
35
|
+
end
|
36
|
+
|
37
|
+
def number_without_leading_zeroes_to_words(number_as_string)
|
38
|
+
case number_as_string.length
|
39
|
+
when 1 then one_digit_number_to_words(number_as_string)
|
40
|
+
when 2 then two_digit_number_to_words(number_as_string)
|
41
|
+
when 3 then three_digit_number_to_words(number_as_string)
|
42
|
+
when 4 then four_digit_number_to_words(number_as_string)
|
43
|
+
else large_number_to_words(number_as_string)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def repeat_zeroes(number_of_zeroes)
|
48
|
+
Array.new(number_of_zeroes) { ONES[0] }.join(' ')
|
49
|
+
end
|
50
|
+
|
51
|
+
def leading_zeroes_to_words(number_as_string)
|
52
|
+
leading_zeroes = number_as_string.match(/^0+/).to_s
|
53
|
+
return '' if leading_zeroes.empty?
|
54
|
+
|
55
|
+
repeat_zeroes(leading_zeroes.length)
|
56
|
+
end
|
57
|
+
|
58
|
+
def number_without_leading_zeroes(number_as_string)
|
59
|
+
number_as_string.sub(/^0+/, '')
|
60
|
+
end
|
61
|
+
|
62
|
+
def single_thousands_to_words(number_as_string)
|
63
|
+
number = number_as_string.to_i / 1000
|
64
|
+
|
65
|
+
[one_digit_number_to_words(number), 'thousand'].join(' ')
|
66
|
+
end
|
67
|
+
|
68
|
+
def one_digit_number_to_words(number_as_string)
|
69
|
+
number = number_as_string.to_i
|
70
|
+
return repeat_zeroes(1) if number.zero?
|
71
|
+
|
72
|
+
ONES[number]
|
73
|
+
end
|
74
|
+
|
75
|
+
def two_digit_number_to_words(number_as_string)
|
76
|
+
number = number_as_string.to_i
|
77
|
+
|
78
|
+
return repeat_zeroes(2) if number.zero?
|
79
|
+
return TEENS[number - 10] if number < 20
|
80
|
+
|
81
|
+
div, mod = number.divmod(10)
|
82
|
+
TENS[div - 2] + (mod.zero? ? '' : " #{ONES[mod]}")
|
83
|
+
end
|
84
|
+
|
85
|
+
def three_digit_number_to_words(number_as_string)
|
86
|
+
number = number_as_string.to_i
|
87
|
+
return repeat_zeroes(3) if number.zero?
|
88
|
+
|
89
|
+
first_digit, remainder = number.divmod(100)
|
90
|
+
words = [ONES[first_digit]]
|
91
|
+
words << (remainder.zero? ? 'hundred' : two_digit_number_to_words(remainder))
|
92
|
+
words.join(' ')
|
93
|
+
end
|
94
|
+
|
95
|
+
def four_digit_number_to_words(number_as_string)
|
96
|
+
number = number_as_string.to_i
|
97
|
+
|
98
|
+
return repeat_zeroes(4) if number.zero?
|
99
|
+
return single_thousands_to_words(number_as_string) if (number % 1000).zero?
|
100
|
+
|
101
|
+
high_pair = number_as_string[0..1]
|
102
|
+
low_pair = number_as_string[2..3]
|
103
|
+
|
104
|
+
[
|
105
|
+
two_digit_number_to_words(high_pair),
|
106
|
+
low_pair.to_i.zero? ? 'hundred' : two_digit_number_to_words(low_pair)
|
107
|
+
].join(' ')
|
108
|
+
end
|
109
|
+
|
110
|
+
def large_number_to_words(number_as_string)
|
111
|
+
number_as_string.chars.map { |digit| ONES[digit.to_i] }.each_slice(3).map { |digit| digit.join(' ') }.join(', ')
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
class Integer
|
4
4
|
def to_dictable
|
5
|
-
EasyToDictateNumbers::
|
5
|
+
EasyToDictateNumbers::DictableNumber.new(self).to_dictable
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class String
|
10
|
+
def to_dictable_number
|
11
|
+
EasyToDictateNumbers::DictableNumber.new(self).to_dictable
|
6
12
|
end
|
7
13
|
end
|
@@ -3,55 +3,5 @@
|
|
3
3
|
# lib/easy_to_dictate_numbers.rb
|
4
4
|
require_relative 'easy_to_dictate_numbers/version'
|
5
5
|
require_relative 'easy_to_dictate_numbers/extend_primitives'
|
6
|
-
|
7
|
-
|
8
|
-
class Error < StandardError; end
|
9
|
-
|
10
|
-
class NumberToDictable
|
11
|
-
ONES = %w[zero one two three four five six seven eight nine].freeze
|
12
|
-
TEENS = %w[ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen].freeze
|
13
|
-
TENS = %w[twenty thirty forty fifty sixty seventy eighty ninety].freeze
|
14
|
-
|
15
|
-
def self.number_to_words(number)
|
16
|
-
validate_number(number)
|
17
|
-
|
18
|
-
case number.digits.count
|
19
|
-
when 1, 2 then two_digit_number_to_words(number)
|
20
|
-
when 3 then three_digit_number_to_words(number)
|
21
|
-
when 4 then four_digit_number_to_words(number)
|
22
|
-
else large_number_to_words(number)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.validate_number(number)
|
27
|
-
raise Error, 'Please enter a non-negative number' if number.negative?
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.two_digit_number_to_words(number)
|
31
|
-
return ONES[number] if number < 10
|
32
|
-
return TEENS[number - 10] if number < 20
|
33
|
-
|
34
|
-
div, mod = number.divmod(10)
|
35
|
-
TENS[div - 2] + (mod.zero? ? '' : " #{ONES[mod]}")
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.three_digit_number_to_words(number)
|
39
|
-
first_digit, remainder = number.divmod(100)
|
40
|
-
words = [ONES[first_digit], 'hundred']
|
41
|
-
words << two_digit_number_to_words(remainder) unless remainder.zero?
|
42
|
-
words.join(' ')
|
43
|
-
end
|
44
|
-
|
45
|
-
def self.four_digit_number_to_words(number)
|
46
|
-
high_pair, low_pair = number.divmod(100)
|
47
|
-
words = []
|
48
|
-
words << "#{two_digit_number_to_words(high_pair)} hundred" unless high_pair.zero?
|
49
|
-
words << two_digit_number_to_words(low_pair) unless low_pair.zero? || high_pair.zero?
|
50
|
-
words.join(' ')
|
51
|
-
end
|
52
|
-
|
53
|
-
def self.large_number_to_words(number)
|
54
|
-
number.to_s.chars.map { |digit| ONES[digit.to_i] }.each_slice(3).map { |digit| digit.join(' ') }.join(', ')
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
6
|
+
require_relative 'easy_to_dictate_numbers/exceptions'
|
7
|
+
require_relative 'easy_to_dictate_numbers/dictable_number'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easy_to_dictate_numbers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matias Verges
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-01-
|
11
|
+
date: 2024-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Transform numbers into words to dictate them easily.For example 1234
|
14
14
|
becomes twelve thirty four and 123456 becomes 'one two three, four five six'
|
@@ -26,6 +26,8 @@ files:
|
|
26
26
|
- Rakefile
|
27
27
|
- easy_to_dictate_numbers.gemspec
|
28
28
|
- lib/easy_to_dictate_numbers.rb
|
29
|
+
- lib/easy_to_dictate_numbers/dictable_number.rb
|
30
|
+
- lib/easy_to_dictate_numbers/exceptions.rb
|
29
31
|
- lib/easy_to_dictate_numbers/extend_primitives.rb
|
30
32
|
- lib/easy_to_dictate_numbers/version.rb
|
31
33
|
- sig/easy_to_dictate_numbers.rbs
|
@@ -36,6 +38,7 @@ metadata:
|
|
36
38
|
homepage_uri: https://github.com/matismasters/easy_to_dictate_numbers
|
37
39
|
source_code_uri: https://github.com/matismasters/easy_to_dictate_numbers
|
38
40
|
changelog_uri: https://github.com/matismasters/easy_to_dictate_numbers/blob/main/CHANGELOG.md
|
41
|
+
rubygems_mfa_required: 'true'
|
39
42
|
post_install_message:
|
40
43
|
rdoc_options: []
|
41
44
|
require_paths:
|