unique_names_generator 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UniqueNamesGenerator
4
+ module Dictionaries
5
+ # Dictionary containing numbers
6
+ module Numbers
7
+ TERMS = (1..999).freeze
8
+
9
+ def self.list_all
10
+ TERMS.map(&:to_s)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -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,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UniqueNamesGenerator
4
+ VERSION = '0.1.1'
5
+ 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: []