diff --git a/2355/2/README.md b/2355/2/README.md index 74d816f9c..475f987c5 100644 --- a/2355/2/README.md +++ b/2355/2/README.md @@ -17,18 +17,12 @@ ruby main.rb --top-bad-words=6 +--------------------------+-------------------------+---------------------+----------------------+ | Леха Медь | 276 нецензурных слов(а) | 92 слов(а) на баттл | 626 слов(а) в раунде | -+--------------------------+-------------------------+---------------------+----------------------+ | Rickey F | 268 нецензурных слов(а) | 44 слов(а) на баттл | 541 слов(а) в раунде | -+--------------------------+-------------------------+---------------------+----------------------+ | Хип-хоп одинокой старухи | 237 нецензурных слов(а) | 79 слов(а) на баттл | 620 слов(а) в раунде | -+--------------------------+-------------------------+---------------------+----------------------+ | Букер | 162 нецензурных слов(а) | 40 слов(а) на баттл | 322 слов(а) в раунде | -+--------------------------+-------------------------+---------------------+----------------------+ | Эмио Афишл | 155 нецензурных слов(а) | 77 слов(а) на баттл | 574 слов(а) в раунде | +--------------------------+-------------------------+---------------------+----------------------+ -| Mytee Dee | 129 нецензурных слов(а) | 25 слов(а) на баттл | 225 слов(а) в раунде | -+--------------------------+-------------------------+---------------------+----------------------+ - | + ``` ### Команды __--top-words=__ и __--name=__ diff --git a/2355/2/app.rb b/2355/2/app.rb new file mode 100644 index 000000000..b57ee743f --- /dev/null +++ b/2355/2/app.rb @@ -0,0 +1,19 @@ +require './parser.rb' +require 'optparse' + +OptionParser.new do |opts| + opts.on('--top-bad-words=') do |bad| + task = Parser.new + task.bad_words = bad + task.top_bad_words_values + task.print_table + end + opts.on('--top-words=') do |most| + task = Parser.new + task.top_words = most + opts.on('--name=') do |battler_name| + task.name_value(battler_name) + task.name_check + end + end +end.parse! diff --git a/2355/2/find_obscenity.rb b/2355/2/find_obscenity.rb index 8368981c8..9efcbd341 100644 --- a/2355/2/find_obscenity.rb +++ b/2355/2/find_obscenity.rb @@ -1,7 +1,7 @@ require 'russian_obscenity' # This class is needed to find and collect all obscenity from text files -class FindObscenity +class Obscenity attr_reader :obscenity def initialize(battler) @@ -18,6 +18,11 @@ def initialize_mistakes File.new('./mistakes').each { |line| @mistakes << line.delete("\n") } end + # In methods first_check and check_rus_obs I use disabling reek:NestedIterators, + # because I believe that this method of implementing the search for specific words + # in a large text is the most acceptable. + # I would have each block do-end to make a separate function and call them all one by one, + # but in my opinion, this will lower the readability of the code. # This method smells of :reek:NestedIterators def first_check 1.upto(dir_count) do |text| diff --git a/2355/2/main.rb b/2355/2/main.rb deleted file mode 100644 index 5b5c84ce4..000000000 --- a/2355/2/main.rb +++ /dev/null @@ -1,63 +0,0 @@ -require './top_bad_words.rb' -require './top_words.rb' -require 'optparse' -require 'terminal-table' - -# rubocop:disable Metrics/BlockLength -# This disable is needed because this block is the main logic of the program. -OptionParser.new do |opts| - opts.on('--top-bad-words=') do |bad| - bad_words = if !bad.empty? - bad.to_i - else - 1 - end - top = TopBad.new - top.set_battlers_names - top.set_top_obscenity - top_bad_words = top.top_obscenity.sort_by { |_key, val| val } - top_bad_words = top_bad_words.reverse - table = Terminal::Table.new do |t| - (bad_words - 1).times do |i| - t << [top_bad_words[i][0], - top_bad_words[i][1].to_s + ' нецензурных слов(а)', - top.average_bad_words_in_battle(top_bad_words[i][0]).to_s + ' слов(а) на баттл', - top.average_words_in_round(top_bad_words[i][0]).to_s + ' слов(а) в раунде'] - t << :separator - end - i = bad_words - 1 - t << [top_bad_words[i][0], - top_bad_words[i][1].to_s + ' нецензурных слов(а)', - top.average_bad_words_in_battle(top_bad_words[i][0]).to_s + ' слов(а) на баттл', - top.average_words_in_round(top_bad_words[i][0]).to_s + ' слов(а) в раунде'] - end - puts table - end - - opts.on('--top-words=') do |top_w| - top_words = if !top_w.empty? - top_w.to_i - else - 30 - end - opts.on('--name=') do |b_name| - if b_name.empty? - puts 'Choose your destiny!' - else - name_b = b_name - top = TopBad.new - top.set_battlers_names - if !top.battlers.include?(name_b) - puts 'Я не знаю рэпера ' + name_b + ', но знаю таких: ' - top.battlers.each { |battler| puts battler } - else - t_w = TopWord.new(name_b) - t_w.check_all_words - t_w.top_words_counter - t_w.res(top_words) - end - end - end - end -end.parse! -# rubocop:enable Metrics/BlockLength diff --git a/2355/2/parser.rb b/2355/2/parser.rb new file mode 100644 index 000000000..4c062d8d5 --- /dev/null +++ b/2355/2/parser.rb @@ -0,0 +1,76 @@ +require './top_bad_words.rb' +require './top_words.rb' +require 'terminal-table' + +# This class is needed to parsing console params +class Parser + attr_reader :bad_words, :top_words, :name + + def initialize + @top_bad_words = [] + @top = TopBad.new + end + + def bad_words=(bad) + @bad_words = !bad.empty? ? bad.to_i : 1 + end + + def top_bad_words_values + @top.battlers_names + @top.top_obscenity_check + @top_bad_words = (@top.top_obscenity.sort_by { |_key, val| val }).reverse + end + + def top_words=(most) + @top_words = !most.empty? ? most.to_i : 30 + end + + def name_value(battler_name) + @name = battler_name + end + + def print_top_words + t_w = TopWord.new(@name) + t_w.check_all_words + t_w.pretexts_value + t_w.top_words_counter + t_w.res(top_words) + end + + def raper + @top.battlers_names + @top.battlers + end + + def name_check + if @name.empty? + puts 'Choose your destiny!' + elsif !raper.include?(@name) + puts 'Я не знаю рэпера ' + @name + ', но знаю таких: ' + raper.each { |battler| puts battler } + else + print_top_words + end + end + + def words_per_battle(elem) + @top.average_bad_words_in_battle(elem).to_s + end + + def words_per_round(elem) + @top.average_words_in_round(elem).to_s + end + + def print_table + table = Terminal::Table.new do |tb| + @bad_words.times do |index| + value = @top_bad_words[index] + elem = value[0] + tb << [elem, value[1].to_s + ' нецензурных слов(а)', + words_per_battle(elem) + ' слов(а) на баттл', + words_per_round(elem) + ' слов(а) в раунде'] + end + end + puts table + end +end diff --git a/2355/2/top_bad_words.rb b/2355/2/top_bad_words.rb index a266761b4..a1e533c4a 100644 --- a/2355/2/top_bad_words.rb +++ b/2355/2/top_bad_words.rb @@ -7,39 +7,45 @@ class TopBad def initialize @battlers = [] @top_obscenity = {} + @dir_count = 0 + @words_count = 0 end - def set_battlers_names + def battlers_names file = File.new('./battlers') file.each { |line| @battlers << line.delete("\n") } end - # This method smells of :reek:UtilityFunction def dir_count(battler) - Dir[File.join("./rap-battles/#{battler}/", '**', '*')].count { |file| File.file?(file) } + @dir_count = Dir[File.join("./rap-battles/#{battler}/", '**', '*')].count { |file| File.file?(file) } end - # This method smells of :reek:DuplicateMethodCall - def set_top_obscenity + def top_obscenity_check 0.upto(battlers.size - 1) do |index| - check = FindObscenity.new(@battlers[index]) + name = @battlers[index] + check = Obscenity.new(name) check.check_battles_for_obscenity - top_obscenity[@battlers[index]] = check.obscenity.size + top_obscenity[name] = check.obscenity.size end end - # This method smells of :reek:DuplicateMethodCall - # This method smells of :reek:NestedIterators - def average_words_in_round(battler, counter = 0) - 1.upto(dir_count(battler)) do |text| - File.new("./rap-battles/#{battler}/#{text}").each do |line| - line.split.each { counter += 1 } - end + def words_in_text(battler, text) + File.new("./rap-battles/#{battler}/#{text}").each do |line| + line.split.each { @words_count += 1 } end - counter / (dir_count(battler) * 3) + end + + def average_words_in_round(battler) + @words_count = 0 + dir_count(battler) + 1.upto(@dir_count) do |text| + words_in_text(battler, text) + end + @words_count / (@dir_count * 3) end def average_bad_words_in_battle(battler) - top_obscenity[battler] / dir_count(battler) + dir_count(battler) + top_obscenity[battler] / @dir_count end end diff --git a/2355/2/top_words.rb b/2355/2/top_words.rb index 6d1595e4c..973716e73 100644 --- a/2355/2/top_words.rb +++ b/2355/2/top_words.rb @@ -4,6 +4,7 @@ class TopWord def initialize(battler) @battler = battler + @pretexts = [] @words = [] @top_words = {} end @@ -12,35 +13,43 @@ def dir_count Dir[File.join("./rap-battles/#{@battler}/", '**', '*')].count { |file| File.file?(file) } end - # This method smells of :reek:NestedIterators + def clear_words(line) + line.split.each do |word| + word = word.delete '.', ',', '?»', '"', '!', ';' + @words << word + end + end + + def check_words_in_text(text) + File.new("./rap-battles/#{@battler}/#{text}").each do |line| + clear_words(line) + end + end + def check_all_words 1.upto(dir_count) do |text| - File.new("./rap-battles/#{@battler}/#{text}").each do |line| - line.split.each do |word| - word = word.delete '.', ',', '?»', '"', '!', ';' - @words << word - end - end + check_words_in_text(text) end end - # This method smells of :reek:DuplicateMethodCall - # This method smells of :reek:TooManyStatements + def pretexts_value + File.new('./pretexts').each { |word| @pretexts << word.delete("\n") } + end + def top_words_counter - pretexts = [] - File.new('./pretexts').each { |line| pretexts << line.delete("\n") } while @words.any? - counter = 0 - @words.each { |word| counter += 1 if word == @words[0] && !pretexts.include?(word) } - @top_words[@words[0]] = counter - @words.delete(@words[0]) + check = @words.first + @top_words[check] = 0 + @words.each { |word| @top_words[check] += 1 if word == check && !@pretexts.include?(word) } + @words.delete(check) end end - # This method smells of :reek:DuplicateMethodCall def res(value) - @top_words = @top_words.sort_by { |_key, val| val } - @top_words = @top_words.reverse - 0.upto(value - 1) { |index| puts @top_words[index][0] + ' - ' + @top_words[index][1].to_s + ' раз(а)' } + @top_words = (@top_words.sort_by { |_key, val| val }).reverse + 0.upto(value - 1) do |index| + word = @top_words[index] + puts word[0] + ' - ' + word[1].to_s + ' раз(а)' + end end end