-
Notifications
You must be signed in to change notification settings - Fork 21
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
base: master
Are you sure you want to change the base?
Changes from 13 commits
3795389
c595793
ee82336
2f58ca2
f282d32
f427a7e
b3dcf46
56858bd
98ab240
e7812bc
aae184e
a497d5f
bfa5dcb
a970933
1dd7ba8
448c419
ad5d76d
c477f85
2d51305
8fecc37
5c964c4
38add5b
8097555
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,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) | ||
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 |
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' | ||
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. Style/MultipleComparison: Avoid comparing a variable with multiple items in a conditional, use Array#include? instead. |
||
Roo::Spreadsheet.open(file_path) | ||
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. бесполезная строка 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. Удалено |
||
file_instance = conditiona_load(ext, file_path) | ||
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. Очепятки 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. Исправлено |
||
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| | ||
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. Style/BlockDelimiters: Avoid using {...} for multi-line blocks. 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. можно использовать select, и обойтись без объявления result 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. Сделано |
||
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 | ||
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. Style/For: Prefer each over for. 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. Enumerable.drop(9), iterate over rows. 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. Заменил на (9..file_instance.last_row).each do |n| |
||
next if file_instance.cell('E', n) == nil | ||
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. 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) | ||
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. Metrics/AbcSize: Assignment Branch Condition size for add_product is too high. [27.24/15] 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. вынеси парсинг в отдельный метод 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. Сделано |
||
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 | ||
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. 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) | ||
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. Style/RedundantReturn: Redundant return detected. |
||
end | ||
end | ||
|
||
def get_recent_price_data(key, products, month_map) | ||
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. 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 = parse_month(month_map) | ||
product_year_data = products[key] | ||
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) | ||
current_month = Time.now.strftime('%m') | ||
month_map.each { |month, month_number| current_month = month if month_number == current_month } | ||
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/UselessAssignment: Useless assignment to variable - current_month. 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. == |
||
current_month | ||
end | ||
|
||
def get_closest_year(current_year, product_data) | ||
current_year if product_data[current_year] | ||
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. строка бесполезна |
||
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] | ||
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. если не имелось в виду 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 | ||
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. Нельзя так делать. Ты недооцениваешь грядущую инфляцию белорусского рубля) 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. Заменил на 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| | ||
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. параметры не нужны, объяви переменные внутри метода |
||
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) | ||
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. последние два параметра не нужны, объяви переменные в методе |
||
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'] | ||
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. Используй 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) | ||
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. Metrics/AbcSize: Assignment Branch Condition size for get_similar_price_products is too high. [15.39/15] |
||
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| | ||
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. 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'] | ||
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. оберни весь исполняемый код в медот main 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. Сделано |
||
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 | ||
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. 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.' | ||
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/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 |
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.
можно проще) str_link.start_with?('/')
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.
Заменил