Skip to content
This repository has been archived by the owner on Jun 27, 2019. It is now read-only.

2355 - 2 #243

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions 2355/2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Инструкция по применению

Запустить в консоли файл __main.rb__ командой __ruby main.rb__, добавив в конце записи необходимые команды.
Copy link
Member

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?

Список доступных команд:
* __--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 раз(а)
```

17 changes: 17 additions & 0 deletions 2355/2/app.rb
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!
56 changes: 56 additions & 0 deletions 2355/2/find_obscenity.rb
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wtf?

def first_check
Copy link
Member

Choose a reason for hiding this comment

The 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 '.', ',', '?»', '&quot', '!', ';'
@obscenity << word
end
end
end
end
end

# This method smells of :reek:NestedIterators
Copy link
Member

Choose a reason for hiding this comment

The 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

Choose a reason for hiding this comment

The 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
81 changes: 81 additions & 0 deletions 2355/2/parser.rb
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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InstanceVariableAssumption: Parser assumes too much for instance variable '@bad_words'. More info.
InstanceVariableAssumption: Parser assumes too much for instance variable '@name'. More info.
TooManyInstanceVariables: Parser has at least 5 instance variables. More info.

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
51 changes: 51 additions & 0 deletions 2355/2/top_bad_words.rb
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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lint/Syntax: class definition in method body

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Syntax: This file has class definition in method body. More info.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lint/Syntax: class definition in method body

Choose a reason for hiding this comment

The 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
Copy link
Member

Choose a reason for hiding this comment

The 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)
Copy link
Member

Choose a reason for hiding this comment

The 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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lint/Syntax: unexpected token kEND

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Syntax: This file has unexpected token kEND. More info.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lint/Syntax: unexpected token kEND

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Syntax: This file has unexpected token kEND. More info.

61 changes: 61 additions & 0 deletions 2355/2/top_words.rb
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
Copy link
Member

Choose a reason for hiding this comment

The 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 '.', ',', '?»', '&quot', '!', ';'
@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