random-words 1.0.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 +7 -0
- data/.irbrc +4 -0
- data/.rspec +4 -0
- data/.rspec_status +39 -0
- data/.rubocop.yml +64 -0
- data/CHANGELOG.md +29 -0
- data/Gemfile +18 -0
- data/Gemfile.lock +111 -0
- data/README.md +90 -0
- data/Rakefile +85 -0
- data/bin/randw +334 -0
- data/lib/random-words/generator.rb +533 -0
- data/lib/random-words/string.rb +56 -0
- data/lib/random-words/version.rb +4 -0
- data/lib/random-words/words/bacon/adjectives.txt +329 -0
- data/lib/random-words/words/bacon/adverbs.txt +69 -0
- data/lib/random-words/words/bacon/articles-plural.txt +10 -0
- data/lib/random-words/words/bacon/articles-singular.txt +10 -0
- data/lib/random-words/words/bacon/clauses.txt +639 -0
- data/lib/random-words/words/bacon/conjunctions-subordinate.txt +29 -0
- data/lib/random-words/words/bacon/nouns-plural.txt +168 -0
- data/lib/random-words/words/bacon/nouns-singular.txt +200 -0
- data/lib/random-words/words/bacon/numbers.txt +21 -0
- data/lib/random-words/words/bacon/verbs-passive.txt +105 -0
- data/lib/random-words/words/bacon/verbs-plural.txt +154 -0
- data/lib/random-words/words/bacon/verbs-singular.txt +106 -0
- data/lib/random-words/words/corporate/adjectives.txt +196 -0
- data/lib/random-words/words/corporate/adverbs.txt +462 -0
- data/lib/random-words/words/corporate/articles-plural.txt +10 -0
- data/lib/random-words/words/corporate/articles-singular.txt +10 -0
- data/lib/random-words/words/corporate/clauses.txt +101 -0
- data/lib/random-words/words/corporate/conjunctions-subordinate.txt +29 -0
- data/lib/random-words/words/corporate/nouns-plural.txt +321 -0
- data/lib/random-words/words/corporate/nouns-singular.txt +474 -0
- data/lib/random-words/words/corporate/numbers.txt +21 -0
- data/lib/random-words/words/corporate/verbs-passive.txt +495 -0
- data/lib/random-words/words/corporate/verbs-plural.txt +173 -0
- data/lib/random-words/words/corporate/verbs-singular.txt +146 -0
- data/lib/random-words/words/english/adjectives.txt +325 -0
- data/lib/random-words/words/english/adverbs.txt +462 -0
- data/lib/random-words/words/english/articles-plural.txt +10 -0
- data/lib/random-words/words/english/articles-singular.txt +10 -0
- data/lib/random-words/words/english/clauses.txt +639 -0
- data/lib/random-words/words/english/conjunctions-subordinate.txt +29 -0
- data/lib/random-words/words/english/nouns-plural.txt +524 -0
- data/lib/random-words/words/english/nouns-singular.txt +530 -0
- data/lib/random-words/words/english/numbers.txt +21 -0
- data/lib/random-words/words/english/verbs-passive.txt +495 -0
- data/lib/random-words/words/english/verbs-plural.txt +325 -0
- data/lib/random-words/words/english/verbs-singular.txt +350 -0
- data/lib/random-words/words/latin/adjectives.txt +188 -0
- data/lib/random-words/words/latin/adverbs.txt +212 -0
- data/lib/random-words/words/latin/articles-plural.txt +122 -0
- data/lib/random-words/words/latin/articles-singular.txt +19 -0
- data/lib/random-words/words/latin/clauses.txt +89 -0
- data/lib/random-words/words/latin/conjunctions-subordinate.txt +104 -0
- data/lib/random-words/words/latin/nouns-plural.txt +190 -0
- data/lib/random-words/words/latin/nouns-singular.txt +193 -0
- data/lib/random-words/words/latin/numbers.txt +21 -0
- data/lib/random-words/words/latin/verbs-passive.txt +171 -0
- data/lib/random-words/words/latin/verbs-plural.txt +177 -0
- data/lib/random-words/words/latin/verbs-singular.txt +218 -0
- data/lib/random-words.rb +6 -0
- data/random-words.gemspec +36 -0
- data/src/_README.md +92 -0
- metadata +119 -0
@@ -0,0 +1,533 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Random Sentence Generator
|
5
|
+
# This script generates random sentences using a variety of words and structures.
|
6
|
+
# It includes nouns, verbs, adjectives, adverbs, articles, clauses, and more.
|
7
|
+
module RandomWords
|
8
|
+
# Random character, word, and sentence generator
|
9
|
+
class Generator
|
10
|
+
# @return [Array<String>] arrays of elements of speech
|
11
|
+
attr_accessor :nouns, :verbs, :passive_verbs, :adverbs, :adjectives, :articles, :clauses, :subordinate_conjunctions,
|
12
|
+
:terminators, :numbers, :plural_nouns, :plural_verbs, :plural_articles
|
13
|
+
|
14
|
+
# @return [Integer] Number of sentences in paragraphs
|
15
|
+
attr_reader :paragraph_length
|
16
|
+
|
17
|
+
# @return [Symbol] Sentence length (:short, :medium, :long, :very_long)
|
18
|
+
attr_reader :sentence_length
|
19
|
+
|
20
|
+
# @return [Symbol] Dictionary in use
|
21
|
+
attr_reader :source
|
22
|
+
|
23
|
+
# @return [Boolean] Testing mode
|
24
|
+
attr_accessor :testing
|
25
|
+
|
26
|
+
# Define the default sentence parts
|
27
|
+
# These parts will be used to generate random sentences and character strings
|
28
|
+
SENTENCE_PARTS = %w[random_article random_adjective random_noun random_adverb random_verb random_adjective
|
29
|
+
random_verb random_adverb].freeze
|
30
|
+
|
31
|
+
# Initialize the generator with a source and options
|
32
|
+
# @param source [Symbol] The source of the words (e.g., :english)
|
33
|
+
# @param _options [Hash] Options for the generator (e.g., length, paragraph_length)
|
34
|
+
# @example
|
35
|
+
# generator = RandomWords::Generator.new(:english, sentence_length: :medium, paragraph_length: 5)
|
36
|
+
# generator.source = :french
|
37
|
+
# generator.lengths = { short: 50, medium: 150 }
|
38
|
+
# generator.sentence_length = :long
|
39
|
+
# generator.paragraph_length = 3
|
40
|
+
def initialize(source = :english, options = {})
|
41
|
+
@source = source
|
42
|
+
@nouns = from_file('nouns-singular.txt')
|
43
|
+
@plural_nouns = from_file('nouns-plural.txt')
|
44
|
+
@verbs = from_file('verbs-singular.txt')
|
45
|
+
@plural_verbs = from_file('verbs-plural.txt')
|
46
|
+
@passive_verbs = from_file('verbs-passive.txt')
|
47
|
+
@adverbs = from_file('adverbs.txt')
|
48
|
+
@adjectives = from_file('adjectives.txt')
|
49
|
+
@articles = from_file('articles-singular.txt')
|
50
|
+
@plural_articles = from_file('articles-plural.txt')
|
51
|
+
@clauses = from_file('clauses.txt')
|
52
|
+
@subordinate_conjunctions = from_file('conjunctions-subordinate.txt')
|
53
|
+
|
54
|
+
@numbers = from_file('numbers.txt')
|
55
|
+
|
56
|
+
@options = {
|
57
|
+
sentence_length: :medium,
|
58
|
+
paragraph_length: 5
|
59
|
+
}
|
60
|
+
@options.merge!(options) if options.is_a?(Hash)
|
61
|
+
@sentence_length = @options[:sentence_length]
|
62
|
+
@paragraph_length = @options[:paragraph_length]
|
63
|
+
lengths
|
64
|
+
end
|
65
|
+
|
66
|
+
# Define number of sentences in paragraphs
|
67
|
+
# @param length [Integer] The number of sentences in the paragraph
|
68
|
+
def paragraph_length=(length)
|
69
|
+
raise ArgumentError, 'Paragraph length must be a positive integer' unless length.is_a?(Integer) && length.positive?
|
70
|
+
|
71
|
+
@paragraph_length = length
|
72
|
+
end
|
73
|
+
|
74
|
+
# Define sentence length
|
75
|
+
# @param length [Symbol] :short, :medium, :long, or :very_long
|
76
|
+
def sentence_length=(length)
|
77
|
+
to_set = case length.to_s
|
78
|
+
when /^s/
|
79
|
+
:short
|
80
|
+
when /^m/
|
81
|
+
:medium
|
82
|
+
when /^l/
|
83
|
+
:long
|
84
|
+
when /^v/
|
85
|
+
:very_long
|
86
|
+
else
|
87
|
+
raise ArgumentError, "Invalid length: #{length}. Use :short, :medium, :long, or :very_long."
|
88
|
+
end
|
89
|
+
@sentence_length = to_set
|
90
|
+
end
|
91
|
+
|
92
|
+
# Bad init method for testing purposes
|
93
|
+
# @!visibility private
|
94
|
+
def bad_init
|
95
|
+
@nouns = from_file('nouns-noent.txt')
|
96
|
+
end
|
97
|
+
|
98
|
+
# define all lengths for testing purposes
|
99
|
+
# @!visibility private
|
100
|
+
def define_all_lengths
|
101
|
+
@lengths = {
|
102
|
+
short: 60,
|
103
|
+
medium: 200,
|
104
|
+
long: 300,
|
105
|
+
very_long: 500
|
106
|
+
}
|
107
|
+
res = []
|
108
|
+
res << define_length(:short)
|
109
|
+
res << define_length(:medium)
|
110
|
+
res << define_length(:long)
|
111
|
+
res << define_length(:very_long)
|
112
|
+
res
|
113
|
+
end
|
114
|
+
|
115
|
+
# Define a bad length for testing purposes
|
116
|
+
# @!visibility private
|
117
|
+
def bad_length
|
118
|
+
define_length(:bad_length)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Test random generators
|
122
|
+
# These methods are used to test the random generation of words and sentences
|
123
|
+
# @!visibility private
|
124
|
+
def test_random
|
125
|
+
@testing = true
|
126
|
+
res = []
|
127
|
+
res << random_noun
|
128
|
+
res << random_verb
|
129
|
+
res << random_adjective
|
130
|
+
res << random_adverb
|
131
|
+
res << random_article
|
132
|
+
res << random_article_for_noun('apple')
|
133
|
+
res << random_article_for_noun('apples')
|
134
|
+
res << random_article_for_noun('banana')
|
135
|
+
res << random_article_for_noun('bananas')
|
136
|
+
res << random_plural_article
|
137
|
+
res << random_clause
|
138
|
+
res << random_subordinate_conjunction
|
139
|
+
res << random_number_with_plural
|
140
|
+
res << random_conjunction
|
141
|
+
res << random_passive_verb
|
142
|
+
res << random_plural_noun
|
143
|
+
res << random_plural_verb
|
144
|
+
res << generate_additional_clauses.join(' ')
|
145
|
+
res
|
146
|
+
end
|
147
|
+
|
148
|
+
# Define a new source dictionary and re-initialize
|
149
|
+
def source=(new_source)
|
150
|
+
initialize(new_source)
|
151
|
+
end
|
152
|
+
|
153
|
+
# Refactored lengths and lengths= methods
|
154
|
+
# This method returns the lengths of sentences
|
155
|
+
# The default lengths are set to the following values:
|
156
|
+
# short: 60, medium: 200, long: 300, very_long: 500
|
157
|
+
def lengths
|
158
|
+
@lengths ||= { short: 60, medium: 200, long: 300, very_long: 500 }
|
159
|
+
end
|
160
|
+
|
161
|
+
# This method allows you to set new lengths for the sentences
|
162
|
+
# It merges the new lengths with the existing ones
|
163
|
+
# Example: lengths = { short: 50, medium: 150 }
|
164
|
+
# @param new_lengths [Hash] A hash containing the new lengths for the sentences
|
165
|
+
# @return [Hash] The updated lengths hash
|
166
|
+
# @example
|
167
|
+
# lengths = { short: 50, medium: 150 }
|
168
|
+
def lengths=(new_lengths)
|
169
|
+
@lengths = lengths.merge(new_lengths)
|
170
|
+
end
|
171
|
+
|
172
|
+
# Generate a random word
|
173
|
+
# @return [String] A randomly generated word
|
174
|
+
def word
|
175
|
+
generate_word
|
176
|
+
end
|
177
|
+
|
178
|
+
# Generate a set number of random words
|
179
|
+
# @param number [Integer] The number of words to generate
|
180
|
+
def words(number)
|
181
|
+
result = SENTENCE_PARTS.cycle.take(number).map { |part| send(part.to_sym) }.take(number)
|
182
|
+
result.map do |word|
|
183
|
+
word.split(/ /).last
|
184
|
+
end.join(' ').compress
|
185
|
+
end
|
186
|
+
|
187
|
+
# Generate a series of random words up to a specified length
|
188
|
+
# @param min [Integer] The minimum length of the generated string
|
189
|
+
# @param max [Integer] (Optional) The maximum length of the generated string
|
190
|
+
# @param whole_words [Boolean] (Optional) Whether to generate whole words or not
|
191
|
+
# @param dead_switch [Integer] (Optional) A counter to prevent infinite loops
|
192
|
+
# @return [String] The generated string of random words
|
193
|
+
# @example
|
194
|
+
# characters(50) # Generates a string with at least 50 characters
|
195
|
+
# characters(50, 100) # Generates a string with between 50 and 100 characters
|
196
|
+
# characters(50, whole_words: false) # Generates a string with 50 characters allowing word truncation
|
197
|
+
def characters(min, max = nil, whole_words: true, whitespace: true, dead_switch: 0)
|
198
|
+
result = ''
|
199
|
+
max ||= min
|
200
|
+
raise ArgumentError, 'Infinite loop detected' if dead_switch > 20
|
201
|
+
|
202
|
+
whole_words = false if dead_switch > 15
|
203
|
+
|
204
|
+
space = whitespace ? ' ' : ''
|
205
|
+
current_part = 0
|
206
|
+
while result.length < max && result.length < min
|
207
|
+
word = send(SENTENCE_PARTS[current_part].to_sym)
|
208
|
+
word.gsub!(/ +/, '') unless whitespace
|
209
|
+
current_part = (current_part + 1) % SENTENCE_PARTS.length
|
210
|
+
new_result = "#{result}#{space}#{word}".compress
|
211
|
+
|
212
|
+
if new_result.length > max
|
213
|
+
return handle_overflow(OverflowConfig.new(new_result, result, min, max, whole_words, whitespace,
|
214
|
+
dead_switch))
|
215
|
+
end
|
216
|
+
return new_result if new_result.length == max
|
217
|
+
|
218
|
+
result = new_result
|
219
|
+
end
|
220
|
+
|
221
|
+
result.strip
|
222
|
+
end
|
223
|
+
|
224
|
+
# Generate a random sentence
|
225
|
+
# @param length [Integer] The desired length of the sentence in characters
|
226
|
+
# @return [String] A randomly generated sentence
|
227
|
+
def sentence(length = nil)
|
228
|
+
generate_combined_sentence(length)
|
229
|
+
end
|
230
|
+
|
231
|
+
# Generate a specified number of random sentences
|
232
|
+
# @param number [Integer] The number of sentences to generate
|
233
|
+
# @return [Array] An array of generated sentences
|
234
|
+
# @example
|
235
|
+
# sentences(5) # Generates an array of 5 random sentences
|
236
|
+
def sentences(number)
|
237
|
+
Array.new(number) { generate_combined_sentence }
|
238
|
+
end
|
239
|
+
|
240
|
+
# Generate a random sentence, combining multiple sentences if necessary
|
241
|
+
# @param length [Symbol] The desired length of the sentence, :short, :medium, :long, or :very_long
|
242
|
+
# @return [String] A randomly generated sentence
|
243
|
+
# This method generates a random sentence and checks its length.
|
244
|
+
# If the length is less than the defined length, it combines it with another sentence.
|
245
|
+
# The final sentence is returned with proper capitalization and termination.
|
246
|
+
# @example
|
247
|
+
# generate_combined_sentence # Generates a combined sentence
|
248
|
+
def generate_combined_sentence(length = nil)
|
249
|
+
length ||= define_length(@sentence_length)
|
250
|
+
sentence = generate_sentence
|
251
|
+
return sentence.capitalize.compress.terminate if sentence.length > length
|
252
|
+
|
253
|
+
while sentence.length < length
|
254
|
+
# Generate a random number of sentences to combine
|
255
|
+
new_sentence = generate_sentence(length / 2)
|
256
|
+
|
257
|
+
# Combine the sentences with random conjunctions
|
258
|
+
sentence = "#{sentence.strip.no_term}, #{random_conjunction} #{new_sentence}"
|
259
|
+
end
|
260
|
+
|
261
|
+
sentence.capitalize.compress.terminate
|
262
|
+
end
|
263
|
+
|
264
|
+
# Generate a random paragraph
|
265
|
+
# @param length [Integer] The desired number of sentences in the paragraph
|
266
|
+
# @return [String] A randomly generated paragraph
|
267
|
+
# This method generates a random paragraph by combining multiple sentences.
|
268
|
+
# It uses the generate_combined_sentence method to create each sentence.
|
269
|
+
# @see #generate_combined_sentence
|
270
|
+
def paragraph(length = @paragraph_length)
|
271
|
+
sentences = []
|
272
|
+
length.times do
|
273
|
+
sentences << generate_combined_sentence
|
274
|
+
end
|
275
|
+
sentences.join(' ').strip.compress
|
276
|
+
end
|
277
|
+
|
278
|
+
private
|
279
|
+
|
280
|
+
# Handle overflow when the new result exceeds the maximum length
|
281
|
+
OverflowConfig = Struct.new(:new_result, :result, :min, :max, :whole_words, :whitespace, :dead_switch)
|
282
|
+
|
283
|
+
def handle_overflow(config)
|
284
|
+
space = config.whitespace ? ' ' : ''
|
285
|
+
needed = config.max - config.result.compress.length - space.length
|
286
|
+
config.min = config.max if config.min > config.max
|
287
|
+
|
288
|
+
if needed > 1
|
289
|
+
options = nouns_of_length(needed)
|
290
|
+
return "#{config.result}#{space}#{options.sample}".compress unless options.empty?
|
291
|
+
end
|
292
|
+
|
293
|
+
if config.whole_words
|
294
|
+
return characters(config.min, config.max, whole_words: config.whole_words, whitespace: config.whitespace,
|
295
|
+
dead_switch: config.dead_switch + 1)
|
296
|
+
end
|
297
|
+
|
298
|
+
truncated = config.new_result.compress[0...config.max]
|
299
|
+
truncated.strip if truncated.strip.length.between?(config.min, config.max)
|
300
|
+
end
|
301
|
+
|
302
|
+
# Generate a random sentence with a specified length
|
303
|
+
# @param length [Integer] The desired length of the sentence
|
304
|
+
# @return [String] A randomly generated sentence
|
305
|
+
# This method generates a random sentence with a specified length.
|
306
|
+
# It has a 20% chance of including a random number with a plural noun and a main clause.
|
307
|
+
# The sentence is constructed using various components such as nouns, verbs, adjectives, and adverbs.
|
308
|
+
# @example
|
309
|
+
# generate_sentence(100) # Generates a sentence with a length of 100 characters
|
310
|
+
# generate_sentence # Generates a sentence with the default length
|
311
|
+
def generate_sentence(length = nil)
|
312
|
+
length ||= define_length(@sentence_length)
|
313
|
+
sentence_components = []
|
314
|
+
|
315
|
+
# Randomly decide if we include a plural noun with a number
|
316
|
+
sentence_components << random_number_with_plural if roll(20) # 20% chance to include a plural noun
|
317
|
+
|
318
|
+
# Construct main clause
|
319
|
+
sentence_components << generate_main_clause
|
320
|
+
|
321
|
+
# Include any additional clauses
|
322
|
+
# sentence_components.concat(generate_additional_clauses)
|
323
|
+
|
324
|
+
# while sentence_components.join(' ').strip.length < length
|
325
|
+
# # Randomly include a subordinate conjunction
|
326
|
+
# additional_clauses = generate_additional_clauses
|
327
|
+
# sentence_components.concat(additional_clauses)
|
328
|
+
# sentence_components.map!(&:strip)
|
329
|
+
# break if sentence_components.join(' ').length >= length
|
330
|
+
|
331
|
+
# conjunction = random_subordinate_conjunction.strip
|
332
|
+
# sentence_components.unshift(conjunction.capitalize) # Place conjunction at the start
|
333
|
+
# end
|
334
|
+
|
335
|
+
# Join all parts into a single sentence
|
336
|
+
sentence_components.join(' ').strip.compress
|
337
|
+
end
|
338
|
+
|
339
|
+
# Load words from a dictionary file
|
340
|
+
# Files are plain text with one word or phrase per line
|
341
|
+
# The @source variable defines which dictionary to be used and should be defined before calling this method
|
342
|
+
# @param filename [String] The name of the file to load
|
343
|
+
# @return [Array] An array of words loaded from the file
|
344
|
+
# @example
|
345
|
+
# from_file('nouns.txt') # Loads words from words/[source]/nouns.txt
|
346
|
+
def from_file(filename)
|
347
|
+
filename = "#{filename.sub(/\.txt$/, '')}.txt"
|
348
|
+
path = File.join(__dir__, 'words', @source.to_s, filename)
|
349
|
+
|
350
|
+
path = File.join(__dir__, 'words', 'english', filename) unless File.exist?(path)
|
351
|
+
|
352
|
+
File.read(path).split("\n").map(&:strip) # Changed from split_lines to split("\n")
|
353
|
+
rescue Errno::ENOENT
|
354
|
+
warn "File not found: #{filename}"
|
355
|
+
[]
|
356
|
+
end
|
357
|
+
|
358
|
+
# Convert a length symbol to a specific length value
|
359
|
+
# @param length [Symbol] The length symbol (:short, :medium, :long, or :very_long)
|
360
|
+
# @return [Integer] The corresponding length value
|
361
|
+
# @example
|
362
|
+
# define_length(:short) # Returns the length for :short
|
363
|
+
def define_length(length)
|
364
|
+
case length
|
365
|
+
when :short
|
366
|
+
@lengths[:short] || 60
|
367
|
+
when :medium
|
368
|
+
@lengths[:medium] || 200
|
369
|
+
when :long
|
370
|
+
@lengths[:long] || 300
|
371
|
+
when :very_long
|
372
|
+
@lengths[:very_long] || 500
|
373
|
+
else
|
374
|
+
raise ArgumentError, "Invalid length: #{length}. Use :short, :medium, or :long."
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
# Get a list of nouns matching a specific length
|
379
|
+
# @param length [Integer] The desired length of the nouns
|
380
|
+
# @return [Array] An array of nouns with the specified length
|
381
|
+
# @example
|
382
|
+
# nouns_of_length(5) # Returns an array of nouns with a length of 5 characters
|
383
|
+
def nouns_of_length(length)
|
384
|
+
nouns.select { |word| word.length == length }
|
385
|
+
end
|
386
|
+
|
387
|
+
# Generate a random conjunction
|
388
|
+
# @return [String] A randomly selected conjunction
|
389
|
+
# @example
|
390
|
+
# random_conjunction # Returns a random conjunction
|
391
|
+
def random_conjunction
|
392
|
+
%w[and or but].sample
|
393
|
+
end
|
394
|
+
|
395
|
+
# Generate a random number with a plural noun
|
396
|
+
# @return [String] A string containing a number and a plural noun
|
397
|
+
# Number names will be sourced from the numbers.txt file and provided in written not numeric form
|
398
|
+
# @example
|
399
|
+
# random_number_with_plural # Returns a string like "three cats"
|
400
|
+
def random_number_with_plural
|
401
|
+
number = numbers.sample
|
402
|
+
"#{number} #{random_plural_noun}"
|
403
|
+
end
|
404
|
+
|
405
|
+
# Generate a random noun
|
406
|
+
# @return [String] A randomly selected noun
|
407
|
+
def random_noun
|
408
|
+
nouns.sample
|
409
|
+
end
|
410
|
+
|
411
|
+
# Generate a random plural noun
|
412
|
+
# @return [String] A randomly selected plural noun
|
413
|
+
def random_plural_noun
|
414
|
+
plural_nouns.sample
|
415
|
+
end
|
416
|
+
|
417
|
+
# Generate a random verb
|
418
|
+
# @return [String] A randomly selected verb
|
419
|
+
def random_verb
|
420
|
+
verbs.sample
|
421
|
+
end
|
422
|
+
|
423
|
+
# Generate a random plural verb
|
424
|
+
# @return [String] A randomly selected plural verb
|
425
|
+
def random_plural_verb
|
426
|
+
plural_verbs.sample
|
427
|
+
end
|
428
|
+
|
429
|
+
# Generate a random passive verb
|
430
|
+
# @return [String] A randomly selected passive verb
|
431
|
+
def random_passive_verb
|
432
|
+
passive_verbs.sample
|
433
|
+
end
|
434
|
+
|
435
|
+
# Generate a random adverb
|
436
|
+
# @return [String] A randomly selected adverb
|
437
|
+
def random_adverb
|
438
|
+
adverbs.sample
|
439
|
+
end
|
440
|
+
|
441
|
+
# Generate a random adjective
|
442
|
+
# @return [String] A randomly selected adjective
|
443
|
+
def random_adjective
|
444
|
+
adjectives.sample
|
445
|
+
end
|
446
|
+
|
447
|
+
# Generate a random article
|
448
|
+
# @return [String] A randomly selected article
|
449
|
+
def random_article
|
450
|
+
articles.sample
|
451
|
+
end
|
452
|
+
|
453
|
+
# Generate a random article for a noun
|
454
|
+
# @param noun [String] The noun for which to generate an article
|
455
|
+
# @return [String] A randomly selected article for the given noun
|
456
|
+
# This method checks if the noun is plural and selects an appropriate article.
|
457
|
+
# If the noun starts with a vowel, it uses 'an' instead of 'a'.
|
458
|
+
# @example
|
459
|
+
# random_article_for_noun('apple') # Returns 'an'
|
460
|
+
def random_article_for_noun(noun)
|
461
|
+
article = plural_nouns.include?(noun) ? random_plural_article : random_article
|
462
|
+
article = 'an' if @testing
|
463
|
+
if noun.start_with?(/[aeiou]/i) && article =~ /^an?$/
|
464
|
+
article = 'an' if article == 'a'
|
465
|
+
elsif article == 'an'
|
466
|
+
article = 'a'
|
467
|
+
end
|
468
|
+
article
|
469
|
+
end
|
470
|
+
|
471
|
+
# Generate a random plural article
|
472
|
+
# @return [String] A randomly selected plural article
|
473
|
+
def random_plural_article
|
474
|
+
plural_articles.sample
|
475
|
+
end
|
476
|
+
|
477
|
+
# Generate a random clause
|
478
|
+
# @return [String] A randomly selected clause
|
479
|
+
def random_clause
|
480
|
+
clauses.sample
|
481
|
+
end
|
482
|
+
|
483
|
+
# Generate a random subordinate conjunction
|
484
|
+
# @return [String] A randomly selected subordinate conjunction
|
485
|
+
def random_subordinate_conjunction
|
486
|
+
subordinate_conjunctions.sample
|
487
|
+
end
|
488
|
+
|
489
|
+
# Generate a random main clause
|
490
|
+
# @return [String] A randomly generated main clause
|
491
|
+
# This method constructs a main clause using a random number of words.
|
492
|
+
# It randomly selects a noun, verb, adjective, and adverb to create a "coherent" sentence.
|
493
|
+
# It has a 50% chance of including a random number with a plural noun.
|
494
|
+
# It has a 20% chance of including a random clause at the end.
|
495
|
+
# @example
|
496
|
+
# generate_main_clause # Returns a random main clause
|
497
|
+
def generate_main_clause
|
498
|
+
beginning = if roll(50)
|
499
|
+
"#{random_number_with_plural} #{random_adverb} #{random_plural_verb}"
|
500
|
+
else
|
501
|
+
noun = random_noun
|
502
|
+
"#{random_article_for_noun(noun)} #{random_adjective} #{noun} #{random_adverb} #{random_verb}"
|
503
|
+
end
|
504
|
+
|
505
|
+
tail = roll(20) ? ", #{random_clause}" : ''
|
506
|
+
"#{beginning.strip}#{tail.strip}"
|
507
|
+
end
|
508
|
+
|
509
|
+
# Simplified generate_additional_clauses
|
510
|
+
def generate_additional_clauses
|
511
|
+
Array.new(rand(1..2)) { random_clause }
|
512
|
+
end
|
513
|
+
|
514
|
+
# Roll a random number to determine if an action should occur
|
515
|
+
# @param percent [Integer] 1-100 percent chance of the action occurring (1-100)
|
516
|
+
# @return [Boolean] True if the action occurs, false otherwise
|
517
|
+
# @example
|
518
|
+
# roll(50) # 50% chance of returning true
|
519
|
+
def roll(percent)
|
520
|
+
rand(1..100) <= percent
|
521
|
+
end
|
522
|
+
|
523
|
+
# Generate a random word
|
524
|
+
# @return [String] A randomly generated word
|
525
|
+
# This method constructs a random word using various components such as articles, adjectives, nouns, verbs, and adverbs.
|
526
|
+
# It randomly decides whether to include each component based on a 50% chance.
|
527
|
+
# @example
|
528
|
+
# generate_word # Returns a random word
|
529
|
+
def generate_word
|
530
|
+
send(SENTENCE_PARTS.sample)
|
531
|
+
end
|
532
|
+
end
|
533
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# String extensions for RandomWords
|
5
|
+
# This module extends the String class with additional methods for cleaning,
|
6
|
+
# compressing, and manipulating strings.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# str = " Hello, World! "
|
10
|
+
# str.clean # => "Hello World"
|
11
|
+
# str.compress # => "Hello World"
|
12
|
+
# str.terminate # => "Hello World."
|
13
|
+
#
|
14
|
+
class ::String
|
15
|
+
# Remove unwanted characters and whitespace from a string.
|
16
|
+
# @return [String] The string with unwanted characters removed.
|
17
|
+
# @example
|
18
|
+
# "Hello, World!".clean # => "Hello World"
|
19
|
+
#
|
20
|
+
# @return [String] The cleaned string.
|
21
|
+
def clean
|
22
|
+
gsub(/[^-a-zA-Z0-9\s]/, '').strip
|
23
|
+
end
|
24
|
+
|
25
|
+
# Split a string by newlines, clean each line, and remove empty lines.
|
26
|
+
# @return [Array<String>] The string split into lines, cleaned, and empty lines removed.
|
27
|
+
# @example
|
28
|
+
# "Hello, World!\n\nThis is a test.".split_lines # => ["Hello World", "This is a test"]
|
29
|
+
#
|
30
|
+
def split_lines
|
31
|
+
strip.split("\n").map(&:clean).reject(&:empty?)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Compress multiple spaces into a single space and remove leading/trailing spaces.
|
35
|
+
# @return [String] The string with extra spaces compressed.
|
36
|
+
def compress
|
37
|
+
gsub(/\s+/, ' ').strip
|
38
|
+
end
|
39
|
+
|
40
|
+
# Terminate a string with a random punctuation mark.
|
41
|
+
# @return [String] The string with a random punctuation mark at the end.
|
42
|
+
# @example
|
43
|
+
# "Hello World".terminate # => "Hello World."
|
44
|
+
#
|
45
|
+
def terminate
|
46
|
+
terminators = %w[. . . ! ! ?]
|
47
|
+
terminator = terminators.sample
|
48
|
+
sub(/[.!?;,-]*$/, terminator)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Remove any punctuation mark from the end of a string.
|
52
|
+
# @return [String] The string with the last punctuation mark removed.
|
53
|
+
def no_term
|
54
|
+
sub(/[.!?;,-]*$/, '')
|
55
|
+
end
|
56
|
+
end
|