Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kirill Hryvicki - 0 #20

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
19 changes: 19 additions & 0 deletions Hryvicki Kirill/0/loadFiles.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require 'mechanize'
require 'open-uri'
require 'uri'
require 'webrick'

agent = Mechanize.new
page = agent.get('http://www.belstat.gov.by/ofitsialnaya-statistika/makroekonomika-i-okruzhayushchaya-sreda/tseny/operativnaya-informatsiya_4/srednie-tseny-na-potrebitelskie-tovary-i-uslugi-po-respublike-belarus')
page.links_with(href: /.xls/).each do |link|
str_link = link.href.to_s
str_link = WEBrick::HTTPUtils.unescape(str_link)
str_link = WEBrick::HTTPUtils.escape(str_link)
f_link = if %r{http:\/\/www.belstat.gov.by}.match?(str_link)
Copy link
Collaborator

Choose a reason for hiding this comment

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

можно проще) str_link.start_with?('/')

Copy link
Author

Choose a reason for hiding this comment

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

Заменил

str_link
else
'http://www.belstat.gov.by' + str_link
end
download = URI.open(f_link)
IO.copy_stream(download, "./data/#{download.base_uri.to_s.split('/')[-1]}")
end
243 changes: 243 additions & 0 deletions Hryvicki Kirill/0/run.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
require 'roo'
RGBD marked this conversation as resolved.
Show resolved Hide resolved
require 'roo-xls'

def get_file_instance(file_path)
ext = file_path.split('.')[2]
file_instance = nil
if ext == 'xls' || ext == 'xlsx'

Choose a reason for hiding this comment

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

Style/MultipleComparison: Avoid comparing a variable with multiple items in a conditional, use Array#include? instead.

Roo::Spreadsheet.open(file_path)
Copy link
Collaborator

Choose a reason for hiding this comment

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

бесполезная строка

Copy link
Author

Choose a reason for hiding this comment

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

Удалено

file_instance = conditiona_load(ext, file_path)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Очепятки

Copy link
Author

Choose a reason for hiding this comment

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

Исправлено

else
puts 'unsupported file type: ' + file_path
end
file_instance
end

def conditiona_load(ext, file_path)
case ext
when 'xls'
sheet = Roo::Excel.new(file_path)
when 'xlsx'
sheet = Roo::Excelx.new(file_path)
end
sheet
end

def find_keys(word, products)
result = []
products.keys.each { |key|

Choose a reason for hiding this comment

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

Style/BlockDelimiters: Avoid using {...} for multi-line blocks.

Copy link
Collaborator

Choose a reason for hiding this comment

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

можно использовать select, и обойтись без объявления result

Copy link
Author

Choose a reason for hiding this comment

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

Сделано

result.push(key) if key.include?(word)
}
result
end

def fetch_products_data(file_instance, products, regions)
for n in 9..file_instance.last_row

Choose a reason for hiding this comment

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

Style/For: Prefer each over for.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Enumerable.drop(9), iterate over rows.

Copy link
Author

Choose a reason for hiding this comment

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

Заменил на (9..file_instance.last_row).each do |n|

next if file_instance.cell('E', n) == nil

Choose a reason for hiding this comment

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

Style/NilComparison: Prefer the use of the nil? predicate.

year = file_instance.cell('A', 3).split(' ')[2]
month = file_instance.cell('A', 3).split(' ')[1]
key = file_instance.cell('A', n).strip.downcase
add_product(products, key, year, month, regions, file_instance, n)
end
end

def add_product(products, key, year, month, regions, file_instance, n)

Choose a reason for hiding this comment

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

Metrics/AbcSize: Assignment Branch Condition size for add_product is too high. [27.24/15]
Metrics/MethodLength: Method has too many lines. [11/10]
Metrics/ParameterLists: Avoid parameter lists longer than 5 parameters. [7/5]
Naming/UncommunicativeMethodParamName: Method parameter must be at least 3 characters long.

Copy link
Collaborator

Choose a reason for hiding this comment

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

вынеси парсинг в отдельный метод

Copy link
Author

Choose a reason for hiding this comment

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

Сделано

products[key] = {} unless products[key]
products[key][year] = {} unless products[key][year]
products[key][year][month] = {
regions[0] => format_value(file_instance.cell('G', n), year),
regions[1] => format_value(file_instance.cell('I', n), year),
regions[2] => format_value(file_instance.cell('K', n), year),
regions[3] => format_value(file_instance.cell('M', n), year),
regions[4] => format_value(file_instance.cell('O', n), year),
regions[5] => format_value(file_instance.cell('Q', n), year),
regions[6] => format_value(file_instance.cell('S', n), year)
}
end

def format_value(val, year)
if val

Choose a reason for hiding this comment

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

Style/GuardClause: Use a guard clause instead of wrapping the code inside a conditional expression.

result = val.to_f
result /= 10_000 if year.to_i < 2017
return result.round(2)

Choose a reason for hiding this comment

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

Style/RedundantReturn: Redundant return detected.

end
end

def get_recent_price_data(key, products, month_map)

Choose a reason for hiding this comment

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

Metrics/AbcSize: Assignment Branch Condition size for get_recent_price_data is too high. [15.68/15]

current_year = Time.now.strftime('%Y').to_s
current_month = Time.now.strftime('%m')

Choose a reason for hiding this comment

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

Lint/UselessAssignment: Useless assignment to variable - current_month.

current_month = parse_month(month_map)
product_year_data = products[key];

Choose a reason for hiding this comment

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

Style/Semicolon: Do not use semicolons to terminate expressions.

year_key = get_closest_year(current_year, product_year_data)
product_month_data = product_year_data[year_key]
month_key = get_closest_month(current_month, product_month_data, month_map)
form_recent_price_data(product_month_data[month_key]['Minsk'], year_key, month_key, key)
end

def form_recent_price_data(price, year, month, product)
{
'price' => price,
'year' => year,
'month' => month,
'product' => product
}
end

def parse_month(month_map)
month_map.each { |month, month_number| current_month = month if month_number == current_month }

Choose a reason for hiding this comment

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

Lint/UselessAssignment: Useless assignment to variable - current_month.

Copy link
Collaborator

Choose a reason for hiding this comment

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

==

current_month
end

def get_closest_year(current_year, product_data)
current_year if product_data[current_year]
Copy link
Collaborator

Choose a reason for hiding this comment

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

строка бесполезна

product_data.keys.max_by(&:to_i) unless product_data[current_year]
end

def get_closest_month(current_month, product_data, month_map)
current_month if product_data[current_month]
Copy link
Collaborator

Choose a reason for hiding this comment

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

если не имелось в виду return current_month if то строка бесполезна

product_data.keys.max { |a, b| month_map[a].to_i <=> month_map[b].to_i } unless product_data[current_month]
end

def get_min_price(hash)
min_year_price = 9_999_999_999_999
Copy link
Collaborator

Choose a reason for hiding this comment

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

Нельзя так делать. Ты недооцениваешь грядущую инфляцию белорусского рубля)
Есть Float::INFINITY, но лучше вычислить минимум вызовом .min на масиве с нужными данными

Copy link
Author

Choose a reason for hiding this comment

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

Заменил на Float::INFINITY

result = {}
hash.each do |year, year_hash|
min_month_data = find_min_month(year_hash)
min_year_data = find_min_year(year, min_month_data, min_year_price)
min_year_price = min_year_data['price'] if min_year_data['price']
result = actual_data(result, min_year_data)
end
result
end

def find_min_month(year_hash, min_month_price = 9_999_999_999_999, min_month = nil)
year_hash.each do |month, month_hash|
Copy link
Collaborator

Choose a reason for hiding this comment

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

параметры не нужны, объяви переменные внутри метода

price = month_hash['Minsk']
next unless price
if price < min_month_price
min_month_price = price
min_month = month
end
end
{ 'price' => min_month_price, 'month' => min_month }
end

def find_min_year(year, min_month_data, min_year_price)
result = {}
min_month_price = min_month_data['price']
result['month'] = min_month_data['month']
if min_month_price < min_year_price
result['price'] = min_month_price
result['year'] = year
end
result
end

def get_max_price(hash)
max_year_price = 0
result = {}
hash.each do |year, year_hash|
max_month_data = find_max_month(year_hash)
max_year_data = find_max_year(year, max_month_data, max_year_price)
max_year_price = max_year_data['price'] if max_year_data['price']
result = actual_data(result, max_year_data)
end
result
end

def find_max_month(year_hash, max_month_price = 0, max_month = nil)
Copy link
Collaborator

Choose a reason for hiding this comment

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

последние два параметра не нужны, объяви переменные в методе
а лучше используй select, max_by

year_hash.each do |month, month_hash|
price = month_hash['Minsk']
next unless price
if price > max_month_price
max_month_price = price
max_month = month
end
end
{ 'price' => max_month_price, 'month' => max_month }
end

def find_max_year(year, max_month_data, max_year_price)
result = {}
max_month_price = max_month_data['price']
Copy link
Collaborator

Choose a reason for hiding this comment

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

Используй max_by

result['month'] = max_month_data['month']
if max_month_price > max_year_price
result['price'] = max_month_price
result['year'] = year
end
result
end

def actual_data(result, year_data)
result['month'] = year_data['month']
result['price'] = year_data['price'] if year_data['price']
result['year'] = year_data['year'] if year_data['year']
result
end

def get_similar_price_products(data, products)

Choose a reason for hiding this comment

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

Metrics/AbcSize: Assignment Branch Condition size for get_similar_price_products is too high. [15.39/15]
Metrics/MethodLength: Method has too many lines. [11/10]

price = data['price']
year = data['year']
month = data['month']
origin_product = data['product']
form_similar_products_array(products, price, year, month, origin_product)
end

def form_similar_products_array(products, price, year, month, origin_product)
result = []
products.each { |product, product_data|

Choose a reason for hiding this comment

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

Style/BlockDelimiters: Avoid using {...} for multi-line blocks.

next unless product_data[year]
next unless product_data[year][month]
result.push(product) if product_data[year][month]['Minsk'] == price && product != origin_product
}
result
end

month_map = {
'январь' => 1,
'февраль' => 2,
'март' => 3,
'апрель' => 4,
'май' => 5,
'июнь' => 6,
'июль' => 7,
'авуст' => 8,
'сентябрь' => 9,
'октябрь' => 10,
'ноябрь' => 11,
'декабрь' => 12
}
regions = ['Brest', 'Vitebsk', 'Gomel', 'Grodno', 'Minsk', 'Minsk Region', 'Mogilyov']
Copy link
Collaborator

Choose a reason for hiding this comment

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

оберни весь исполняемый код в медот main

Copy link
Author

Choose a reason for hiding this comment

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

Сделано

products = {}
file_paths = Dir['./data/*']
file_paths.each do |file_path|
file_instance = get_file_instance(file_path)
fetch_products_data(file_instance, products, regions) if file_instance
end
loop do

Choose a reason for hiding this comment

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

Metrics/BlockLength: Block has too many lines. [27/25]

puts 'What price are you looking for?'
word = gets.chomp.downcase.encode('UTF-8')
keys = find_keys(word, products)
if keys.empty?
puts word.capitalize + ' can not be found in database'
else
keys.each do |key|
recent_price_data = get_recent_price_data(key, products, month_map)
puts ''
puts key.capitalize+' is '+recent_price_data['price'].to_s+' BYN in Minsk these days.'

Choose a reason for hiding this comment

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

Layout/SpaceAroundOperators: Surrounding space missing for operator +.

min_price = get_min_price(products[key])
puts 'Lowest was on ' + min_price['year'] + '/' + month_map[min_price['month']].to_s + ' at price '
print min_price['price'].to_s + ' BYN'
max_price = get_max_price(products[key])
puts 'Maximum was on ' + max_price['year'] + '/' + month_map[max_price['month']].to_s + ' at price '
print max_price['price'].to_s + ' BYN'
similar_products = get_similar_price_products(recent_price_data, products)
if similar_products.empty?
puts 'No products for similar price'
else
puts 'For similar price you also can afford'
puts similar_products
end
end
end
end