unique_names_generator 0.1.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.
- checksums.yaml +7 -0
- data/.github/workflows/ruby.yml +31 -0
- data/.pryrc +8 -0
- data/.rspec +1 -0
- data/.rubocop.yml +31 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +32 -0
- data/LICENSE +21 -0
- data/README.md +93 -0
- data/Rakefile +6 -0
- data/lib/unique_names_generator/dictionaries/adjectives.rb +1217 -0
- data/lib/unique_names_generator/dictionaries/animals.rb +370 -0
- data/lib/unique_names_generator/dictionaries/colors.rb +67 -0
- data/lib/unique_names_generator/dictionaries/languages.rb +111 -0
- data/lib/unique_names_generator/dictionaries/names.rb +4955 -0
- data/lib/unique_names_generator/dictionaries/numbers.rb +14 -0
- data/lib/unique_names_generator/dictionaries/star_wars.rb +97 -0
- data/lib/unique_names_generator/seed.rb +42 -0
- data/lib/unique_names_generator/version.rb +5 -0
- data/lib/unique_names_generator.rb +192 -0
- data/unique_names_generator.gemspec +28 -0
- metadata +81 -0
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UniqueNamesGenerator
|
4
|
+
module Dictionaries
|
5
|
+
# Dictionary containing star-wars characters
|
6
|
+
module StarWars
|
7
|
+
TERMS = [
|
8
|
+
'Ackbar',
|
9
|
+
'Adi Gallia',
|
10
|
+
'Anakin Skywalker',
|
11
|
+
'Arvel Crynyd',
|
12
|
+
'Ayla Secura',
|
13
|
+
'Bail Prestor Organa',
|
14
|
+
'Barriss Offee',
|
15
|
+
'Ben Quadinaros',
|
16
|
+
'Beru Whitesun lars',
|
17
|
+
'Bib Fortuna',
|
18
|
+
'Biggs Darklighter',
|
19
|
+
'Boba Fett',
|
20
|
+
'Bossk',
|
21
|
+
'C-3PO',
|
22
|
+
'Chewbacca',
|
23
|
+
'Cliegg Lars',
|
24
|
+
'Cordé',
|
25
|
+
'Darth Maul',
|
26
|
+
'Darth Vader',
|
27
|
+
'Dexter Jettster',
|
28
|
+
'Dooku',
|
29
|
+
'Dormé',
|
30
|
+
'Dud Bolt',
|
31
|
+
'Eeth Koth',
|
32
|
+
'Finis Valorum',
|
33
|
+
'Gasgano',
|
34
|
+
'Greedo',
|
35
|
+
'Gregar Typho',
|
36
|
+
'Grievous',
|
37
|
+
'Han Solo',
|
38
|
+
'IG-88',
|
39
|
+
'Jabba Desilijic Tiure',
|
40
|
+
'Jango Fett',
|
41
|
+
'Jar Jar Binks',
|
42
|
+
'Jek Tono Porkins',
|
43
|
+
'Jocasta Nu',
|
44
|
+
'Ki-Adi-Mundi',
|
45
|
+
'Kit Fisto',
|
46
|
+
'Lama Su',
|
47
|
+
'Lando Calrissian',
|
48
|
+
'Leia Organa',
|
49
|
+
'Lobot',
|
50
|
+
'Luke Skywalker',
|
51
|
+
'Luminara Unduli',
|
52
|
+
'Mace Windu',
|
53
|
+
'Mas Amedda',
|
54
|
+
'Mon Mothma',
|
55
|
+
'Nien Nunb',
|
56
|
+
'Nute Gunray',
|
57
|
+
'Obi-Wan Kenobi',
|
58
|
+
'Owen Lars',
|
59
|
+
'Padmé Amidala',
|
60
|
+
'Palpatine',
|
61
|
+
'Plo Koon',
|
62
|
+
'Poggle the Lesser',
|
63
|
+
'Quarsh Panaka',
|
64
|
+
'Qui-Gon Jinn',
|
65
|
+
'R2-D2',
|
66
|
+
'R4-P17',
|
67
|
+
'R5-D4',
|
68
|
+
'Ratts Tyerel',
|
69
|
+
'Raymus Antilles',
|
70
|
+
'Ric Olié',
|
71
|
+
'Roos Tarpals',
|
72
|
+
'Rugor Nass',
|
73
|
+
'Saesee Tiin',
|
74
|
+
'San Hill',
|
75
|
+
'Sebulba',
|
76
|
+
'Shaak Ti',
|
77
|
+
'Shmi Skywalker',
|
78
|
+
'Sly Moore',
|
79
|
+
'Tarfful',
|
80
|
+
'Taun We',
|
81
|
+
'Tion Medon',
|
82
|
+
'Wat Tambor',
|
83
|
+
'Watto',
|
84
|
+
'Wedge Antilles',
|
85
|
+
'Wicket Systri Warrick',
|
86
|
+
'Wilhuff Tarkin',
|
87
|
+
'Yarael Poof',
|
88
|
+
'Yoda',
|
89
|
+
'Zam Wesell'
|
90
|
+
].freeze
|
91
|
+
|
92
|
+
def self.list_all
|
93
|
+
TERMS
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UniqueNamesGenerator
|
4
|
+
# Generate a reproducible seed from a given string
|
5
|
+
module Seed
|
6
|
+
class << self
|
7
|
+
def generate_seed(seed)
|
8
|
+
return nil if seed.nil?
|
9
|
+
|
10
|
+
transformed_string = transform_string(seed)
|
11
|
+
seed_decimal = mulberry32(transformed_string)
|
12
|
+
remove_decimal(seed_decimal)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def transform_string(seed)
|
18
|
+
return seed if seed.is_a?(Integer)
|
19
|
+
|
20
|
+
seed += "\x00"
|
21
|
+
ascii_values = seed.bytes
|
22
|
+
|
23
|
+
joined_values = ascii_values.join
|
24
|
+
joined_values.to_i
|
25
|
+
end
|
26
|
+
|
27
|
+
def remove_decimal(seed)
|
28
|
+
(seed * 10**16).to_i
|
29
|
+
end
|
30
|
+
|
31
|
+
def mulberry32(seed)
|
32
|
+
t = (seed + 0x6d2b79f5) & 0xffffffff
|
33
|
+
|
34
|
+
t = ((t ^ (t >> 15)) * (t | 1)) & 0xffffffff
|
35
|
+
t = (t ^ (t >> 7)) & 0xffffffff
|
36
|
+
t = (t ^ (t + ((t ^ (t >> 7)) * (t | 61) & 0xffffffff))) & 0xffffffff
|
37
|
+
|
38
|
+
((t ^ (t >> 14)) & 0xffffffff) / 4294967296.0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# An implementation of a unique_names_generator in Ruby
|
4
|
+
# with support for PRNG/seeds
|
5
|
+
|
6
|
+
require_relative './unique_names_generator/seed'
|
7
|
+
|
8
|
+
require_relative './unique_names_generator/dictionaries/adjectives'
|
9
|
+
require_relative './unique_names_generator/dictionaries/animals'
|
10
|
+
require_relative './unique_names_generator/dictionaries/colors'
|
11
|
+
require_relative './unique_names_generator/dictionaries/languages'
|
12
|
+
require_relative './unique_names_generator/dictionaries/names'
|
13
|
+
require_relative './unique_names_generator/dictionaries/numbers'
|
14
|
+
require_relative './unique_names_generator/dictionaries/star_wars'
|
15
|
+
|
16
|
+
# UniqueNamesGenerator implementation
|
17
|
+
module UniqueNamesGenerator
|
18
|
+
module_function
|
19
|
+
|
20
|
+
def generate(dictionaries, separator: '_', style: :lowercase, seed: nil, creativity: 0)
|
21
|
+
@separator = separator
|
22
|
+
@style = style
|
23
|
+
@seed = seed
|
24
|
+
@creativity = creativity
|
25
|
+
|
26
|
+
if creativity.negative? || creativity > 10
|
27
|
+
raise ArgumentError, 'Outside creativity range. Must be between 0 and 10.'
|
28
|
+
end
|
29
|
+
|
30
|
+
generate_name(dictionaries)
|
31
|
+
end
|
32
|
+
|
33
|
+
def match_word_list(dictionary)
|
34
|
+
module_name = camelize_dictionary(dictionary)
|
35
|
+
begin
|
36
|
+
dictionary = Dictionaries.const_get(module_name)
|
37
|
+
dictionary.list_all
|
38
|
+
rescue NameError
|
39
|
+
raise_invalid_dictionary(dictionary)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def word_list(dictionary)
|
44
|
+
case dictionary
|
45
|
+
when Array
|
46
|
+
dictionary if dictionary.all? { |item| item.is_a?(String) }
|
47
|
+
when Symbol
|
48
|
+
match_word_list(dictionary)
|
49
|
+
else
|
50
|
+
raise ArgumentError, 'Dictionary contains invalid dictionary type'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def random_seeded_float
|
55
|
+
seed_value = Seed.generate_seed(@seed)
|
56
|
+
|
57
|
+
prng = @seed.nil? ? Random.new : Random.new(seed_value)
|
58
|
+
prng.rand
|
59
|
+
end
|
60
|
+
|
61
|
+
def map_dictionaries(dictionaries)
|
62
|
+
dictionaries.map { |dictionary| word_list(dictionary) }
|
63
|
+
end
|
64
|
+
|
65
|
+
def split_with_separator(word)
|
66
|
+
if @separator.nil?
|
67
|
+
word.split(/(?=[A-Z])/)
|
68
|
+
else
|
69
|
+
word.split(@separator)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def format_parts(parts)
|
74
|
+
parts.map do |part|
|
75
|
+
if part.match?(/[^a-zA-Z]/) && @style == :capital
|
76
|
+
# Preserve original capitalization for parts with non-letter characters
|
77
|
+
part
|
78
|
+
else
|
79
|
+
format_word(part, @style)
|
80
|
+
end
|
81
|
+
end.join(@separator)
|
82
|
+
end
|
83
|
+
|
84
|
+
def format_multi_word(word, original_word)
|
85
|
+
if original_word.include?(' ') || original_word.include?('-')
|
86
|
+
parts = split_with_separator(word)
|
87
|
+
format_parts(parts)
|
88
|
+
else
|
89
|
+
format_word(word, @style)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def generate_name(dictionaries)
|
94
|
+
if @creativity.nil? || @creativity.zero?
|
95
|
+
generate_name_original(dictionaries)
|
96
|
+
else
|
97
|
+
generate_name_creatively(dictionaries)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def generate_name_original(dictionaries)
|
102
|
+
map_dictionaries(dictionaries).reduce(nil) do |acc, x|
|
103
|
+
rnd = (random_seeded_float * x.length).floor
|
104
|
+
original_word = x[rnd]
|
105
|
+
|
106
|
+
output_word(acc, original_word)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def generate_name_creatively(dictionaries)
|
111
|
+
word_lists = map_dictionaries(dictionaries)
|
112
|
+
|
113
|
+
word_lists.each_with_index.reduce(nil) do |acc, (word_list, index)|
|
114
|
+
creativity = calculate_creativity(index)
|
115
|
+
rnd = (random_seeded_float * word_list.length * creativity).floor
|
116
|
+
original_word = word_list[rnd % word_list.length] # Ensure we don't go out of bounds
|
117
|
+
|
118
|
+
output_word(acc, original_word)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def output_word(acc, original_word)
|
123
|
+
word = format_with_separator(original_word)
|
124
|
+
word = format_multi_word(word, original_word)
|
125
|
+
|
126
|
+
if acc
|
127
|
+
"#{acc}#{@separator}#{word}"
|
128
|
+
else
|
129
|
+
word
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def calculate_creativity(index)
|
134
|
+
if index.zero?
|
135
|
+
@creativity # Base creativity for the first dictionary
|
136
|
+
else
|
137
|
+
@creativity * (2 + index * 0.5) # Increase creativity for subsequent dictionaries
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def camelize_dictionary(dictionary)
|
142
|
+
dictionary.to_s.split('_').map(&:capitalize).join
|
143
|
+
end
|
144
|
+
|
145
|
+
def raise_invalid_dictionary(dictionary)
|
146
|
+
raise ArgumentError, "Invalid dictionary: #{dictionary}"
|
147
|
+
end
|
148
|
+
|
149
|
+
def format_with_separator(word)
|
150
|
+
if @separator.nil?
|
151
|
+
# If separator is empty, just remove spaces without changing case
|
152
|
+
word.gsub(/\s+/, '')
|
153
|
+
else
|
154
|
+
# If there's a separator, use it to replace spaces
|
155
|
+
word.gsub(/\s+/, @separator)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def format_word(word, style)
|
160
|
+
case style
|
161
|
+
when :lowercase
|
162
|
+
word.downcase
|
163
|
+
when :uppercase
|
164
|
+
word.upcase
|
165
|
+
when :capital
|
166
|
+
word.capitalize
|
167
|
+
else
|
168
|
+
word
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
private_class_method(
|
173
|
+
*%i[
|
174
|
+
generate_name
|
175
|
+
match_word_list
|
176
|
+
word_list
|
177
|
+
random_seeded_float
|
178
|
+
map_dictionaries
|
179
|
+
camelize_dictionary
|
180
|
+
raise_invalid_dictionary
|
181
|
+
format_with_separator
|
182
|
+
format_multi_word
|
183
|
+
format_parts
|
184
|
+
format_word
|
185
|
+
split_with_separator
|
186
|
+
generate_name_original
|
187
|
+
generate_name_creatively
|
188
|
+
calculate_creativity
|
189
|
+
output_word
|
190
|
+
]
|
191
|
+
)
|
192
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/unique_names_generator/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'unique_names_generator'
|
7
|
+
s.version = UniqueNamesGenerator::VERSION
|
8
|
+
s.summary = 'Ruby library for generating random and unique names'
|
9
|
+
s.description = <<~DESC
|
10
|
+
Generate random and unique names in Ruby with support for PRNG
|
11
|
+
seeded/deterministic generation using a built in collection of
|
12
|
+
dictionaries, or your own.
|
13
|
+
DESC
|
14
|
+
s.authors = ['Jon Girard']
|
15
|
+
s.email = 'jongirard03@gmail.com'
|
16
|
+
s.homepage = 'https://github.com/jongirard/unique_names_generator_ruby'
|
17
|
+
s.metadata = { 'homepage_uri' => 'https://github.com/jongirard/unique_names_generator_ruby',
|
18
|
+
'source_code_uri' => 'https://github.com/jongirard/unique_names_generator_ruby' }
|
19
|
+
s.require_paths = ['lib']
|
20
|
+
s.license = 'MIT'
|
21
|
+
s.files = Dir.chdir(File.expand_path(__dir__)) do
|
22
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
23
|
+
end
|
24
|
+
|
25
|
+
s.required_ruby_version = '>= 2.6.0'
|
26
|
+
|
27
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: unique_names_generator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jon Girard
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-07-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
description: |
|
28
|
+
Generate random and unique names in Ruby with support for PRNG
|
29
|
+
seeded/deterministic generation using a built in collection of
|
30
|
+
dictionaries, or your own.
|
31
|
+
email: jongirard03@gmail.com
|
32
|
+
executables: []
|
33
|
+
extensions: []
|
34
|
+
extra_rdoc_files: []
|
35
|
+
files:
|
36
|
+
- ".github/workflows/ruby.yml"
|
37
|
+
- ".pryrc"
|
38
|
+
- ".rspec"
|
39
|
+
- ".rubocop.yml"
|
40
|
+
- Gemfile
|
41
|
+
- Gemfile.lock
|
42
|
+
- LICENSE
|
43
|
+
- README.md
|
44
|
+
- Rakefile
|
45
|
+
- lib/unique_names_generator.rb
|
46
|
+
- lib/unique_names_generator/dictionaries/adjectives.rb
|
47
|
+
- lib/unique_names_generator/dictionaries/animals.rb
|
48
|
+
- lib/unique_names_generator/dictionaries/colors.rb
|
49
|
+
- lib/unique_names_generator/dictionaries/languages.rb
|
50
|
+
- lib/unique_names_generator/dictionaries/names.rb
|
51
|
+
- lib/unique_names_generator/dictionaries/numbers.rb
|
52
|
+
- lib/unique_names_generator/dictionaries/star_wars.rb
|
53
|
+
- lib/unique_names_generator/seed.rb
|
54
|
+
- lib/unique_names_generator/version.rb
|
55
|
+
- unique_names_generator.gemspec
|
56
|
+
homepage: https://github.com/jongirard/unique_names_generator_ruby
|
57
|
+
licenses:
|
58
|
+
- MIT
|
59
|
+
metadata:
|
60
|
+
homepage_uri: https://github.com/jongirard/unique_names_generator_ruby
|
61
|
+
source_code_uri: https://github.com/jongirard/unique_names_generator_ruby
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 2.6.0
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubygems_version: 3.2.3
|
78
|
+
signing_key:
|
79
|
+
specification_version: 4
|
80
|
+
summary: Ruby library for generating random and unique names
|
81
|
+
test_files: []
|