-
Notifications
You must be signed in to change notification settings - Fork 43
2355 - 2 #243
base: master
Are you sure you want to change the base?
2355 - 2 #243
Changes from 7 commits
bf43651
e3957b9
b0fa517
c93ee85
ac98a92
6ee0321
4303212
6fc17d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# Инструкция по применению | ||
|
||
Запустить в консоли файл __main.rb__ командой __ruby main.rb__, добавив в конце записи необходимые команды. | ||
Список доступных команд: | ||
* __--top-bad-words=__ | ||
* __--top-words=__ | ||
* __--name=__ | ||
|
||
### Команда __--top-bad-words=__ | ||
|
||
Использование данной команды приводит к тому, что на экране выводится топ исполнителей, в текста баттлов которых входит наибольшее количество нецензурных выражений. Принимает целочисленные агрументы и выводит столько исполнителей, сколько запросил пользователь. По умолчанию(если аргументы не были переданы) выводит только самого нецензурного исполнителя. Также в виде таблицы выводит данные о количестве поединков(баттлов), среднее количество нецензурных слов в поединке и среднее количество слов в раунде. | ||
|
||
Пример работы программы. | ||
|
||
``` | ||
ruby main.rb --top-bad-words=6 | ||
|
||
+--------------------------+-------------------------+---------------------+----------------------+ | ||
| Леха Медь | 276 нецензурных слов(а) | 92 слов(а) на баттл | 626 слов(а) в раунде | | ||
| Rickey F | 268 нецензурных слов(а) | 44 слов(а) на баттл | 541 слов(а) в раунде | | ||
| Хип-хоп одинокой старухи | 237 нецензурных слов(а) | 79 слов(а) на баттл | 620 слов(а) в раунде | | ||
| Букер | 162 нецензурных слов(а) | 40 слов(а) на баттл | 322 слов(а) в раунде | | ||
| Эмио Афишл | 155 нецензурных слов(а) | 77 слов(а) на баттл | 574 слов(а) в раунде | | ||
+--------------------------+-------------------------+---------------------+----------------------+ | ||
|
||
``` | ||
|
||
### Команды __--top-words=__ и __--name=__ | ||
|
||
Данные команды используются вместе и их исполнение приводит к тому, что на экране выводится топ наиболее часто используемых слов заданного исполнителя. | ||
Команда __--top-words=__ принимает целочисленные аргументы и по умолчанию имеет параметр 30, т.е. выводится топ-30 наиболее часто используемых слов. | ||
Команда __--name=__ принимает строковые данные и является обязательной для заполнения, т.к. при отсутствии агрументов выдает ошибку. Также при отсутствии заданного исполнителя в списке баттлеров для анализа, программа выдаст список доступных исполнителей. | ||
|
||
Пример работы программы. | ||
|
||
``` | ||
|
||
ruby main.rb --top-words=10 --name=Толик | ||
|
||
Рэпер Толик не известен мне. Зато мне известны: | ||
Гнойный | ||
Oxxxymiron | ||
Галат | ||
... | ||
|
||
ruby main.rb --top-words=5 --name=Oxxxymiron | ||
|
||
просто - 32 раз(а) | ||
рэп - 21 раз(а) | ||
быть - 17 раз(а) | ||
ты, - 16 раз(а) | ||
против - 15 раз(а) | ||
``` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
require './parser.rb' | ||
require 'optparse' | ||
|
||
OptionParser.new do |opts| | ||
opts.on('--top-bad-words=') do |bad| | ||
task = Parser.new | ||
task.top_bad_words_values | ||
task.print_table(bad) | ||
end | ||
opts.on('--top-words=') do |most| | ||
task = Parser.new | ||
opts.on('--name=') do |battler_name| | ||
task.name_value(battler_name) | ||
task.name_check(most) | ||
end | ||
end | ||
end.parse! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
require 'russian_obscenity' | ||
|
||
# This class is needed to find and collect all obscenity from text files | ||
class Obscenity | ||
attr_reader :obscenity | ||
|
||
def initialize(battler) | ||
@battler = battler | ||
@mistakes = [] | ||
@obscenity = [] | ||
end | ||
|
||
def dir_count | ||
Dir[File.join("./rap-battles/#{@battler}/", '**', '*')].count { |file| File.file?(file) } | ||
end | ||
|
||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wtf? |
||
def first_check | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please fix all reek smells. |
||
1.upto(dir_count) do |text| | ||
File.new("./rap-battles/#{@battler}/#{text}").each do |line| | ||
line.split.each do |word| | ||
if word =~ /.*\*.*[А-Яа-я.,]$/ | ||
word = word.delete '.', ',', '?»', '"', '!', ';' | ||
@obscenity << word | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
# This method smells of :reek:NestedIterators | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wtf? |
||
def check_rus_obs | ||
1.upto(dir_count) do |text| | ||
File.new("./rap-battles/#{@battler}/#{text}").each do |line| | ||
RussianObscenity.find(line).each do |word| | ||
@mistakes.each { |mis| @obscenity << word unless mis.casecmp(word) } | ||
end | ||
end | ||
end | ||
end | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Layout/TrailingBlankLines: 1 trailing blank lines detected. |
||
def check_battles_for_obscenity | ||
initialize_mistakes | ||
first_check | ||
check_rus_obs | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
require './top_bad_words.rb' | ||
require './top_words.rb' | ||
require 'terminal-table' | ||
|
||
# This class is needed to parsing console params | ||
class Parser | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
def initialize | ||
@top_bad_words = [] | ||
@top = TopBad.new | ||
@name = '' | ||
end | ||
|
||
# This method is needed in Parser class, but is doesn't depend on instance state | ||
# This method smells of :reek:UtilityFunction | ||
def bad_words(bad) | ||
!bad.empty? ? bad.to_i : 1 | ||
end | ||
|
||
# This method is needed in Parser class, but is doesn't depend on instance state | ||
# This method smells of :reek:UtilityFunction | ||
def top_words(most) | ||
!most.empty? ? most.to_i : 30 | ||
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 name_value(battler_name) | ||
@name = battler_name | ||
end | ||
|
||
def print_top_words(most) | ||
t_w = TopWord.new(@name) | ||
t_w.ready_top_words | ||
t_w.res(top_words(most)) | ||
end | ||
|
||
def raper | ||
@top.battlers_names | ||
@top.battlers | ||
end | ||
|
||
def name_check(most) | ||
if @name.empty? | ||
puts 'Choose your destiny!' | ||
elsif !raper.include?(@name) | ||
puts 'Я не знаю рэпера ' + @name + ', но знаю таких: ' | ||
raper.each { |battler| puts battler } | ||
else | ||
print_top_words(most) | ||
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 table_content(table, bad) | ||
bad_words(bad).times do |index| | ||
value = @top_bad_words[index] | ||
elem = value[0] | ||
table << [elem, value[1].to_s + ' нецензурных слов(а)', | ||
words_per_battle(elem) + ' слов(а) на баттл', | ||
words_per_round(elem) + ' слов(а) в раунде'] | ||
end | ||
end | ||
|
||
def print_table(bad) | ||
table = Terminal::Table.new do |tb| | ||
table_content(tb, bad) | ||
end | ||
puts table | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
require './find_obscenity.rb' | ||
|
||
# This class is needed for first level of Task 2 | ||
class TopBad | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lint/Syntax: class definition in method body There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Syntax: This file has class definition in method body. More info. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lint/Syntax: class definition in method body There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Syntax: This file has class definition in method body. More info. |
||
attr_reader :battlers, :top_obscenity | ||
|
||
def initialize | ||
@battlers = [] | ||
@top_obscenity = {} | ||
@dir_count = 0 | ||
@words_count = 0 | ||
end | ||
|
||
def battlers_names | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you explain logic of this method? |
||
file = File.new('./battlers') | ||
file.each { |line| @battlers << line.delete("\n") } | ||
end | ||
|
||
def dir_count(battler) | ||
@dir_count = Dir[File.join("./rap-battles/#{battler}/", '**', '*')].count { |file| File.file?(file) } | ||
end | ||
|
||
def top_obscenity_check | ||
0.upto(battlers.size - 1) do |index| | ||
name = @battlers[index] | ||
check = Obscenity.new(name) | ||
check.check_battles_for_obscenity | ||
top_obscenity[name] = check.obscenity.size | ||
end | ||
end | ||
|
||
def words_in_text(battler, text) | ||
File.new("./rap-battles/#{battler}/#{text}").each do |line| | ||
line.split.each { @words_count += 1 } | ||
end | ||
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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please remove magic number |
||
end | ||
|
||
def average_bad_words_in_battle(battler) | ||
dir_count(battler) | ||
top_obscenity[battler] / @dir_count | ||
end | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lint/Syntax: unexpected token kEND There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Syntax: This file has unexpected token kEND. More info. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lint/Syntax: unexpected token kEND There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Syntax: This file has unexpected token kEND. More info. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# This class is needed to find most popular words from text files | ||
class TopWord | ||
attr_reader :battler | ||
|
||
def initialize(battler) | ||
@battler = battler | ||
@pretexts = [] | ||
@words = [] | ||
@top_words = {} | ||
end | ||
|
||
def dir_count | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you have code duplication between two classes. |
||
Dir[File.join("./rap-battles/#{@battler}/", '**', '*')].count { |file| File.file?(file) } | ||
end | ||
|
||
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| | ||
check_words_in_text(text) | ||
end | ||
end | ||
|
||
def pretexts_value | ||
File.new('./pretexts').each { |word| @pretexts << word.delete("\n") } | ||
end | ||
|
||
def top_words_counter | ||
while @words.any? | ||
check = @words.first | ||
@top_words[check] = 0 | ||
@words.each { |word| @top_words[check] += 1 if word == check && [email protected]?(word) } | ||
@words.delete(check) | ||
end | ||
end | ||
|
||
def res(value) | ||
@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 | ||
|
||
def ready_top_words | ||
check_all_words | ||
pretexts_value | ||
top_words_counter | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you read task requirements? how should I guess where to put texts of battles?