class RandomWords::Generator
Random character, word, and sentence generator
def bad_length
Define a bad length for testing purposes
def bad_length define_length(:bad_length) end
def characters(min, max = nil, whole_words: true, whitespace: true, dead_switch: 0)
-
(String)- The generated string of random words
Parameters:
-
dead_switch(Integer) -- (Optional) A counter to prevent infinite loops -
whole_words(Boolean) -- (Optional) Whether to generate whole words or not -
max(Integer) -- (Optional) The maximum length of the generated string -
min(Integer) -- The minimum length of the generated string
def characters(min, max = nil, whole_words: true, whitespace: true, dead_switch: 0) result = '' max ||= min raise ArgumentError, 'Infinite loop detected' if dead_switch > 40 whole_words = false if dead_switch > 15 space = whitespace ? ' ' : '' current_part = 0 while result.length < max && result.length < min word = send(SENTENCE_PARTS[current_part].to_sym) word.gsub!(/ +/, '') unless whitespace current_part = (current_part + 1) % SENTENCE_PARTS.length new_result = "#{result}#{space}#{word}".compress if new_result.length > max return handle_overflow(OverflowConfig.new(new_result, result, min, max, whole_words, whitespace, dead_switch)) end return new_result if new_result.length == max result = new_result end result.strip end
def code_lang
-
(Symbol)- A randomly selected code language
def code_lang code_langs = %i[python ruby swift javascript css rust go java] code_langs[Random.rand(code_langs.count)] end
def code_snippet(lang = nil)
-
(String)- A randomly generated code snippet
Parameters:
-
lang(Symbol) -- The language of the code snippet
def code_snippet(lang = nil) code_snippets = { python: %(def hello_world():\n print("Hello, World!")), ruby: %(def hello_world\n puts "Hello, World!"\nend), swift: %(func helloWorld() {\n print("Hello, World!")\n}), javascript: %(function helloWorld() {\n console.log("Hello, World!");\n}), css: %(body {\n background-color: #f0f0f0;\n font-family: Arial, sans-serif;\n}\nh1 {\n color: #333;\n}), rust: %(fn main() {\n println!("Hello, World!");\n}), go: %(package main\nimport "fmt"\nfunc main() {\n fmt.Println("Hello, World!")\n}), java: %(public class HelloWorld {\n public static void main(String[] args) {\n System.out.println("Hello, World!");\n }\n}) } lang ||= code_lang code_snippets[lang.to_sym] end
def create_dictionary(title)
-
(Symbol)- The symbolized name of the dictionary
Parameters:
-
title(String) -- The title of the user dictionary
def create_dictionary(title) @config.create_user_dictionary(title) end
def debug(msg)
def debug(msg) return unless @debug "%#{msg}%" end
def define_all_lengths
define all lengths for testing purposes
def define_all_lengths @lengths = { short: 20, medium: 60, long: 100, very_long: 300 } res = [] res << define_length(:short) res << define_length(:medium) res << define_length(:long) res << define_length(:very_long) res end
def define_length(length)
-
(Integer)- The corresponding length value
Parameters:
-
length(Symbol) -- The length symbol (:short, :medium, :long, or :very_long)
def define_length(length) case length when :short @lengths[:short] || 60 when :medium @lengths[:medium] || 200 when :long @lengths[:long] || 300 when :very_long @lengths[:very_long] || 500 else raise ArgumentError, "Invalid length: #{length}. Use :short, :medium, or :long." end end
def generate_additional_clauses
def generate_additional_clauses Array.new(rand(1..2)) { random_clause } end
def generate_combined_sentence(length = nil)
-
(String)- A randomly generated sentence
Parameters:
-
length(Symbol) -- The desired length of the sentence, :short, :medium, :long, or :very_long
def generate_combined_sentence(length = nil) length ||= define_length(@sentence_length) sentence = generate_sentence return sentence.to_sent(random_terminator).fix_caps(terminators).expand_debug if sentence.length > length while sentence.length < length # Generate a random number of sentences to combine new_sentence = generate_sentence(length / 2) # Combine the sentences with random conjunctions sentence = "#{sentence.strip.no_term(terminators)}, #{random_coordinating_conjunction} #{new_sentence.no_term(terminators)}" end sentence.to_sent(random_terminator).fix_caps(terminators).expand_debug end
def generate_main_clause
-
(String)- A randomly generated main clause
def generate_main_clause beginning = case rand(10) when 0..1 random_phrase when 2..3 "#{random_number_with_plural} #{random_adverb} #{random_plural_verb}" when 4..5 random_name when 6..7 noun = random_noun "#{random_adverb}, #{random_article_for_word(noun)} #{noun} #{random_verb}" else noun = random_noun adjective = random_adjective "#{random_article_for_word(adjective)} #{adjective} #{noun} #{random_adverb} #{random_verb}" end tail = roll(50) ? " #{random_prepositional_phrase}" : '' separator = random_separator tail += roll(10) ? "#{separator} #{random_clause}" : '' "#{beginning.strip.sub(/[#{Regexp.escape(separator)}]*$/, separator)}#{tail}" end
def generate_sentence(length = nil)
-
(String)- A randomly generated sentence
Parameters:
-
length(Integer) -- The desired length of the sentence
def generate_sentence(length = nil) length ||= define_length(@sentence_length) sentence_components = [] # Randomly decide if we include a plural noun with a number # sentence_components << random_number_with_plural if roll(10) # 10% chance to include a plural noun # Construct main clause sentence_components << generate_main_clause # Include any additional clauses # sentence_components.concat(generate_additional_clauses) while sentence_components.join(' ').strip.length < length # Randomly include a subordinate conjunction additional_clauses = generate_additional_clauses sentence_components.concat(additional_clauses) sentence_components.map!(&:strip) # break if sentence_components.join(' ').length >= length # conjunction = if roll(50) || (RandomWords.testing && !RandomWords.tested.include?('subordinate_conjunction')) # RandomWords.tested << 'subordinate_conjunction' if RandomWords.testing # random_subordinate_conjunction.strip # else # RandomWords.tested << 'coordinating_conjunction' if RandomWords.testing # random_coordinating_conjunction.strip # end # # sentence_components.unshift(conjunction.capitalize) # Place conjunction at the start # sentence_components << conjunction unless conjunction.empty? end # Join all parts into a single sentence output = sentence_components.shift sentence_components.each do |part| output << " #{roll(50) ? random_coordinating_conjunction : random_subordinate_conjunction} #{part}" end output.strip.compress end
def generate_word
-
(String)- A randomly generated word
def generate_word send(SENTENCE_PARTS.sample) end
def handle_overflow(config)
- See: #nouns_of_length -
See: #words_of_length -
See: #characters -
See: OverflowConfig -
Returns:
-
(String)- The modified result after handling overflow
Parameters:
-
config(OverflowConfig) -- The configuration for handling overflow
def handle_overflow(config) space = config.whitespace ? ' ' : '' needed = config.max - config.result.compress.length needed -= space.length if needed > 0 && config.result.compress.length.positive? config.min = config.max if config.min > config.max if needed > 1 options = words_of_length(needed) return "#{config.result}#{space}#{options.sample}".compress unless options.empty? end if config.whole_words return characters(config.min, config.max, whole_words: config.whole_words, whitespace: config.whitespace, dead_switch: config.dead_switch + 1) end truncated = config.new_result.compress[0...config.max] truncated.compress.length == config.max ? truncated.compress : nil end
def html(settings = {})
-
(String)- A randomly generated HTML string
Parameters:
-
settings(Hash) -- Settings for generating HTML
def html(settings = {}) RandomWords::LoremMarkdown.new(settings).output end
def initialize(source = :english, options = {})
-
options(Hash) -- Options for the generator (e.g., length, paragraph_length) -
source(Symbol) -- The source of the words (e.g., :english)
def initialize(source = :english, options = {}) @debug = options[:debug] || false @tested = [] @config = RandomWords::Config.new(source) @source = source @nouns = @config.dictionary[:nouns] @plural_nouns = @config.dictionary[:plural_nouns] @verbs = @config.dictionary[:verbs] @plural_verbs = @config.dictionary[:plural_verbs] @passive_verbs = @config.dictionary[:passive_verbs] @adverbs = @config.dictionary[:adverbs] @adjectives = @config.dictionary[:adjectives] @articles = @config.dictionary[:articles] @plural_articles = @config.dictionary[:plural_articles] @prepositions = @config.dictionary[:prepositions] @clauses = @config.dictionary[:clauses] @coordinating_conjunctions = @config.dictionary[:coordinating_conjunctions] @subordinate_conjunctions = @config.dictionary[:subordinate_conjunctions] @numbers = @config.dictionary[:numbers] @sources = @config.sources @terminators = @config.dictionary[:terminators] @names = [@config.dictionary[:first_names], @config.dictionary[:last_names], @config.dictionary[:full_names]] @phrases = @config.dictionary[:phrases] @all_words = @config.dictionary[:all_words] @options = { sentence_length: :medium, paragraph_length: 5, use_extended_punctuation: false } @options.merge!(options) if options.is_a?(Hash) @sentence_length = @options[:sentence_length] @paragraph_length = @options[:paragraph_length] @use_extended_punctuation = @options[:use_extended_punctuation] @terminators.concat(@config.dictionary[:extended_punctuation]) if @use_extended_punctuation lengths end
def lengths
The default lengths are set to the following values:
This method returns the lengths of sentences
Refactored lengths and lengths= methods
def lengths @lengths ||= { short: 20, medium: 60, long: 100, very_long: 300 } end
def lengths=(new_lengths)
-
(Hash)- The updated lengths hash
Parameters:
-
new_lengths(Hash) -- A hash containing the new lengths for the sentences
def lengths=(new_lengths) @lengths = lengths.merge(new_lengths) end
def markdown(settings = {})
-
(String)- A randomly generated markdown string
Parameters:
-
settings(Hash) -- Settings for generating markdown
def markdown(settings = {}) input = RandomWords::LoremMarkdown.new(settings).output RandomWords::HTML2Markdown.new(input).markdown end
def name
-
(String)- A randomly generated name
def name "#{debug('NAM')}#{random_name}" end
def nouns_of_length(length)
-
(Array)- An array of nouns with the specified length
Parameters:
-
length(Integer) -- The desired length of the nouns
def nouns_of_length(length) nouns.select { |word| word.length == length } end
def paragraph(length = @paragraph_length)
- See: #generate_combined_sentence -
Returns:
-
(String)- A randomly generated paragraph
Parameters:
-
length(Integer) -- The desired number of sentences in the paragraph
def paragraph(length = @paragraph_length) sentences = [] length.times do sentences << generate_combined_sentence end sentences.join(' ').strip.compress end
def paragraph_length=(length)
-
length(Integer) -- The number of sentences in the paragraph
def paragraph_length=(length) raise ArgumentError, 'Paragraph length must be a positive integer' unless length.is_a?(Integer) && length.positive? @paragraph_length = length end
def random_adjective
-
(String)- A randomly selected adjective
def random_adjective "#{debug('ADJ')}#{adjectives.sample}" end
def random_adverb
-
(String)- A randomly selected adverb
def random_adverb "#{debug('ADV')}#{adverbs.sample}" end
def random_article
-
(String)- A randomly selected article
def random_article "#{debug('ART')}#{articles.rotate[0]}" end
def random_article_for_word(word)
-
(String)- A randomly selected article for the given noun
Parameters:
-
word(String) -- The noun for which to generate an article
def random_article_for_word(word) article = plural_nouns.include?(word) ? random_plural_article : random_article # puts [word, article].inspect article = 'an' if RandomWords.testing && !RandomWords.tested.include?('random_article_for_word') RandomWords.tested << 'random_article_for_word' if RandomWords.testing if word.start_with?(/[aeiou]/i) && article =~ /^an?$/i article = 'an' elsif /^an$/i.match?(article) article = 'a' end article end
def random_clause
-
(String)- A randomly selected clause
def random_clause "#{debug('CLA')}#{clauses.sample}" end
def random_conjunction
-
(String)- A randomly selected conjunction
def random_conjunction "#{debug('COC')}#{coordinating_conjunctions.sample}" end
def random_coordinating_conjunction
-
(String)- A randomly selected coordinating conjunction
def random_coordinating_conjunction "#{debug('COC')}#{coordinating_conjunctions.rotate[0]}" end
def random_name
def random_name return @names[2].sample if (@names[0].empty? || @names[1].empty?) && !@names[2].empty? return @names[2].sample if !@names[2].empty? && roll(60) first_name = @names[0].sample middle_initial = roll(20) ? " #{('A'..'Z').to_a.sample}" : '' last_name = @names[1].sample "#{first_name}#{middle_initial} #{last_name}" end
def random_noun
-
(String)- A randomly selected noun
def random_noun "#{debug('NOU')}#{nouns.sample}" end
def random_number_with_plural
-
(String)- A string containing a number and a plural noun
def random_number_with_plural num = rand(1000) number = if roll(50) num.to_word(@numbers) else num.to_commas end if num == 1 || (RandomWords.testing && !RandomWords.tested.include?('random_noun')) RandomWords.tested << 'random_noun' if RandomWords.testing "#{debug('NUM')}#{number} #{random_noun}" else RandomWords.tested << 'random_plural_noun' if RandomWords.testing "#{debug('NUM')}#{number} #{random_plural_noun}" end end
def random_passive_verb
-
(String)- A randomly selected passive verb
def random_passive_verb "#{debug('PAV')}#{passive_verbs.sample}" end
def random_phrase
-
(String)- A randomly selected phrase
def random_phrase "#{debug('PHR')}#{phrases.sample}" end
def random_plural_article
-
(String)- A randomly selected plural article
def random_plural_article "#{debug('PLA')}#{plural_articles.rotate[0]}" end
def random_plural_noun
-
(String)- A randomly selected plural noun
def random_plural_noun "#{debug('PLN')}#{plural_nouns.sample}" end
def random_plural_verb
-
(String)- A randomly selected plural verb
def random_plural_verb "#{debug('PLV')}#{plural_verbs.sample}" end
def random_preposition
-
(String)- A randomly selected preposition
def random_preposition "#{debug('PRE')}#{prepositions.rotate[0]}" end
def random_prepositional_phrase
-
(String)- A randomly generated prepositional phrase
def random_prepositional_phrase preposition = random_preposition phrase = if roll(20) || (@testing && !@tested.include?('random_plural_article')) @tested << 'random_plural_article' if @testing "#{random_plural_article} #{random_number_with_plural}" else @tested << 'random_article_for_word' if @testing noun = random_noun "#{random_article_for_word(noun)} #{noun}" end "#{debug('PRP')}#{preposition} #{phrase}" end
def random_separator
-
(String)- A randomly selected separator
def random_separator "#{debug('SEP')}#{random_separators.sample}" end
def random_separators
def random_separators [',', ',', ',', ';', ':', ' —'] end
def random_subordinate_conjunction
-
(String)- A randomly selected subordinate conjunction
def random_subordinate_conjunction "#{debug('SUC')}#{subordinate_conjunctions.rotate[0]}" end
def random_terminator
-
(Array)- A randomly selected terminator pair
def random_terminator terminators.sample end
def random_verb
-
(String)- A randomly selected verb
def random_verb "#{debug('VER')}#{verbs.sample}" end
def roll(percent)
-
(Boolean)- True if the action occurs, false otherwise
Parameters:
-
percent(Integer) -- 1-100 percent chance of the action occurring (1-100)
def roll(percent) rand(1..100) <= percent end
def sentence(length = nil)
-
(String)- A randomly generated sentence
Parameters:
-
length(Integer) -- The desired length of the sentence in characters
def sentence(length = nil) generate_combined_sentence(length) end
def sentence_length=(length)
-
length(Symbol) -- :short, :medium, :long, or :very_long
def sentence_length=(length) to_set = case length.to_s when /^s/ :short when /^m/ :medium when /^l/ :long when /^v/ :very_long else raise ArgumentError, "Invalid length: #{length}. Use :short, :medium, :long, or :very_long." end @sentence_length = to_set end
def sentences(number)
-
(Array)- An array of generated sentences
Parameters:
-
number(Integer) -- The number of sentences to generate
def sentences(number) Array.new(number) { generate_combined_sentence } end
def source=(new_source)
def source=(new_source) initialize(new_source) end
def test_random
These methods are used to test the random generation of words and sentences
Test random generators
def test_random RandomWords.testing = true @debug = true @use_extended_punctuation = true res = [] res << random_noun res << random_verb res << random_adjective res << random_adverb res << random_article res << random_article_for_word('apple') res << random_article_for_word('apples') res << random_article_for_word('banana') res << random_article_for_word('bananas') res << random_plural_article res << random_clause res << random_separator res << random_subordinate_conjunction res << random_coordinating_conjunction res << random_number_with_plural res << random_phrase res << random_conjunction res << random_name res << random_passive_verb res << random_plural_noun res << random_plural_verb res << random_preposition res << random_prepositional_phrase res << random_terminator.join(' ') res << generate_additional_clauses.join(' ') res << words_of_length(5).join(' ') res << nouns_of_length(5).join(' ') res end
def use_extended_punctuation=(use_extended_punctuation)
def use_extended_punctuation=(use_extended_punctuation) raise ArgumentError, 'use_extended_punctuation must be a boolean' unless [true, false].include?(use_extended_punctuation) @use_extended_punctuation = use_extended_punctuation @terminators.concat(@config.dictionary[:extended_punctuation]) if use_extended_punctuation end
def word
-
(String)- A randomly generated word
def word generate_word end
def words(number)
-
number(Integer) -- The number of words to generate
def words(number) result = SENTENCE_PARTS.cycle.take(number).map { |part| send(part.to_sym) }.take(number) result.map do |word| word.split(/ /).last end.join(' ').compress end
def words_of_length(length)
- See: #nouns_of_length -
Returns:
-
(Array)- An array of words with the specified length
Parameters:
-
length(Integer) -- The desired length of the words
def words_of_length(length) all_words.select { |word| word.length == length } end