using hash within Regexp - Can't convert Regexp into Integer [closed] - ruby

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I have a rake task that is pretty simple and works as I expect.
task :qualify => :environment do
require 'classifier'
# encoding: utf-8
test = Skirt.where(:asin => "B007O9MXF0")
w = %w{ rayon wool cotton polyester nylon spandex}
a = test.first.content
b = test.first.title
c = a + b
w.each do |w|
if c[/#{w}/]
c = w
else
c
end
end
good ={}
skirt = Skirt.where(:quality => "Good")
skirt.each do |f|
good[f.content] = [f.quality]
end
bad = {}
skirt = Skirt.where(:quality => "Bad")
skirt.each do |f|
bad[f.content] = [f.quality]
end
classifier = Classifier::Bayes.new('Good', 'Bad')
good.each {|good| classifier.train_good "Good"}
bad.each {|bad| classifier.train_bad "Bad"}
puts classifier.classify(a),
c,
test.first.color,
a+b
end
Now I am trying to get something a little more complex, but using the exact same idea and it does not work.
See the code below:
desc "Import details"
task :import_clean => :environment do
require 'sucker'
require 'mechanize'
require 'nokogiri'
require 'open-uri'
require 'carrierwave'
require 'rmagick'
require 'csv'
# encoding: utf-8
skirt = Skirt.where(:quality => "Good")
good = {}
skirt_type = ""
skirt.each do |f|
content_title = f.content + f.title
good[content_title] = [f.quality]
end
bad = {}
skirt = Skirt.where(:quality => "Bad")
skirt.each do |f|
content_title = f.content + f.title
bad[content_title] = [f.quality]
end
classifier = Classifier::Bayes.new('Good', 'Bad')
good.each {|good| classifier.train_good "Good"}
bad.each {|bad| classifier.train_bad "Bad"}
request = Sucker.new(
:associate_tag => 'thenewoutpro-20',
:key => 'AKIAJXNLXYCBU3NJAIJQ',
:secret => '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',
:locale => :us)
request << {
"Operation" => "ItemSearch",
"SearchIndex" => "Apparel",
"Keywords" => ["women", "skirt"],
"ResponseGroup" => ["BrowseNodes"] }
rep = request.get
url = "#{rep.find('MoreSearchResultsUrl')}"
new_url = url[2, url.length-4]
agent = Mechanize.new
agent.get(new_url)
i = (0..47)
i.each do |i|
b = "#{i}"
item = "#result_" + b
doc = agent.page.search(item)
link = doc.css("a")[0]["href"]
asin = link[-10,10]
request2 = Sucker.new(
:associate_tag => 'thenewoutpro-20',
:key => 'KEY',
:secret => 'SECRET',
:locale => :us)
request2 << {
"Operation" => "ItemLookup",
"IdType" => "ASIN",
"ItemId" => asin,
"ResponseGroup" => ["Large"] }
response = request2.get
images = response.find('LargeImage').first.to_a
image_new = images[0].to_s
image = image_new[8, image_new.length-9]
color_string = response.find('Color')
color = color_string[6, color_string.length]
brand_string = response.find('Manufacturer')
brand = brand_string[5, brand_string.length]
content = response.find('Content')
title = response.find('Title')
combined = content + title
f = %w{ polyester rayon nylon cotton silk chiffon wool knit jersey viscose corduroy velvet lace }
s = %w{ pencil A-line mini maxi long pleated panel }
p = %w{ pettite 'plus size' maternity }
f.each do |f|
if combined[/#{f}/]
fabric = f
else
fabric = ""
end
end
s.each do |s|
a = combined[/#{s}/]
if a > 0
skirt_type = s
else
skirt_type = ""
end
end
p.each do |p|
if combined[/#{p}/]
size = p
else
size = "Regular"
end
end
quality = classifier.classify(combined)
Bottom.create!(
:asin => asin,
:title => response.find('Title'),
:price => response.find('FormattedPrice'),
:manufacturer => brand,
:content => response.find('Content'),
:color => color,
:fabric => fabric,
:size => size,
:skirt_type => skirt_type,
:images => image,
:link => link)
end
end
end
I get the following error when I try to run the rake: rake aborted!
can't convert Regexp into Integer
The part I don't understand is that the same portion of the code (using the hash within the Regexp to run over an array) is working just fine on rake task :qualify.
Any ideas?
Thanks!

combined = (content + title).to_s
in combined[regex], if combined is not a string, Ruby thinks you are accessing an Array and therefore expects regex to be an integer...

Related

How can I add a key-value pair to a hash without name?

This is my ruby file with hash:
book.rb
class Book
attr_accessor :title, :author, :language, :classification, :isbn, :book_id, :borrow_status
def initialize(title, author, language, classification, isbn, book_id, borrow_status)
#title = title
#author = author
#language = language
#classification = classification
#isbn = isbn
#book_id = book_id
#borrow_status = borrow_status
end
def bookid
#book_id
end
def booklist
#title = #title.split(/ |\_|\-/).map(&:capitalize).join(" ")
#author = #author.split(/ |\_|\-/).map(&:capitalize).join(" ")
#language = #language.capitalize
#isbn.to_s
#book_id.to_s
{
:Title => #title,
:Author => #author,
:Language => #language,
:Classification => #classification,
:ISBN => #isbn,
:Book_ID => #book_id,
:Status => #borrow_status,
}
end
end
for now, I already have five key-value pair for this hash, they are in ruby file named top.rb:
$books1 = Book.new("lonely planet: ireland","damian harper","english","tourism",9781786574459,1,"available")
$books2 = Book.new("ninteen eighty four","george orwell","english","literature",9781374677817, 2,"available")
$books3 = Book.new("japanese in 30 days","naomi ono","japanese","education",9787928365729,3,"available")
$books4 = Book.new("brand famous: how to get everyone talking about your business","linzi boyd","english","business",9780857084903,4,"borrowed")
$books5 = Book.new("SQL in 10 mins","ming zhong, xiaoxia liu","chinese","hi tech",9787115313980,5,"unavailable")
and using the method below to output the result:
def status
bookstatus = gets.chomp.to_s
if bookstatus == "status"
puts "Status:" + "\n" + "#{$books1.booklist[:Book_ID]}: #{$books1.booklist[:Title]}: #{$books1.booklist[:Status]}"
puts "#{$books2.booklist[:Book_ID]}:#{$books2.booklist[:Title]}: #{$books2.booklist[:Status]}"
puts "#{$books3.booklist[:Book_ID]}:#{$books3.booklist[:Title]}: #{$books3.booklist[:Status]}"
puts "#{$books4.booklist[:Book_ID]}:#{$books4.booklist[:Title]}: #{$books4.booklist[:Status]}"
puts "#{$books5.booklist[:Book_ID]}:#{$books5.booklist[:Title]}: #{$books5.booklist[:Status]}"
else
puts "error"
end
end
For now, I am going to add some more value, I am going to let user enter the information of books (e.g., title = gets.chomp.to_s), and make a new key-value pair for the book added.
As I know, add new key-value pair to ruby is like below:
my_hash = {:a => 5}
my_hash[:key] = "value"
But, the hash in book.rb does not have any name, I tried to give it a name like
book_list = {
:Title => #title,
:Author => #author,
:Language => #language,
:Classification => #classification,
:ISBN => #isbn,
:Book_ID => #book_id,
:Status => #borrow_status,
}
it will output error.
My question is, I would like to know how can I add a new key-value pair to the hash in my ruby file, which has no name?
Thanks.
Changing the booklist method to this will solve your immediate problem:
def booklist
#booklist ||= {
:Title => #title.split(/ |\_|\-/).map(&:capitalize).join(" "),
:Author => #author.split(/ |\_|\-/).map(&:capitalize).join(" "),
:Language => #language.capitalize,
:Classification => #classification,
:ISBN => #isbn.to_s,
:Book_ID => #book_id.to_s,
:Status => #borrow_status,
}
end
Now you can do booklist[:Xyz] = 'xyz'.
The code in your question has so many "Hello world!" -level mistakes, that it appears you still seem to have a bit to learn about Ruby basics, such as using variables, the difference between #isbn, isbn, $isbn, ISBN, or ##isbn, etc.
There are better "learn ruby" tutorials online than I'm ready to start here, so my answer is probably not very helpful.

How can I shrink and make a better use of this method? - RUBY (raw)

Working on a project and trying to turn this method (I Have some more similar methods like that in my project) into a more dynamic and concise way
Data from image
def proficiency_parser(stored_data, name, race, year, title, percentage)
if stored_data.has_key?(name)
if stored_data[name].has_key?(race)
if stored_data[name][race].has_key?(year)
stored_data[name][race][year][title] = percentage
else
stored_data[name][race][year] = {title => percentage}
end
else
stored_data[name][race] = {year => {title => percentage}}
end
else
stored_data[name] = {race => {year => {title => percentage}}}
end
end
so essentially this method through my data to identify whether it meets so of those specification showing in the code, essentially I just don't want to use this amount of "elses" and "Ifs" if at all possible.
Data
stored_data
# => {"COLORADO"=>{3=>{2008=>{:math=>0.697}}}}
name
# => "COLORADO"
race
# => 3
year
# => 2008
title
# => :math
percentage
# => 0.697
Take a look at Hash#dig which is included in Ruby versions 2.3.0 or newer.
To summarize:
hash_1 = { a: { a: { a: "b" } } }
hash_2 = { c: { c: { c: "d" } } }
hash_1.dig(:a, :a, :a) # returns "b"
hash_2.dig(:a, :a, :a) # returns nil
So you could say if hash_1.dig(:a, :a) instead of
if hash_1[:a]
if hash_1[:a][:a]
# etc
There's also another way to do it, which is to rescue your NoMethod [] errors.
Here's an example of that:
if hash_1[:a][:a][:a] rescue false
puts "the key exists"
else
puts "the key doesnt exist"
end
You can use some recursive call
Input data
stored_data = {}
name = 'COLORADO'
race = 3
year = 2008
title = :math
percentage = 0.697
Methods
def proficiency_parser(stored_data, name, race, year, title, percentage)
parser(stored_data, name, {race => {year => {title => percentage}}})
end
def parser(data, key, value)
data[key] ? value.each { |k, v| parser(data[key], k, v) } : data[key] = value
end
call
proficiency_parser(stored_data, name, race, year, title, percentage)
p stored_data
# => {"COLORADO"=>{3=>{2008=>{:math=>0.697}}}}
I hope this helps

Ruby: Rerunning a loop with different code if end criteria is met

I have this program I wrote to automate a task I have at work. This is my first attempt at programming, with zero experience or training so forgive any silly mistakes. (I removed the website and my username/password)
require "rubygems"
require "selenium-webdriver"
require "nokogiri"
browser = Selenium::WebDriver.for :firefox
wait = Selenium::WebDriver::Wait.new(:timeout => 15)
#loads to unassigned results page
browser.get "-----------------"
p browser.title
browser.find_element(name: "user[username]").send_keys "--------"
browser.find_element(name: "user[password]").send_keys "--------"
browser.find_element(name: "commit").click
p browser.title
browser.find_element(class_name: "status_notification").click
begin
browser.find_element(:xpath => ".//*[#id='sub_nav_content']/table/tbody/tr[2]/td[3]/a").click
table = wait.until {
element = browser.find_element(id: "possible_matched")
element if element.displayed?
}
if table
puts "Table Found"
else
puts "Table Error"
end
#creates an 2D array containing patient name, admit date and prints to screen
names = browser.find_elements(:xpath => ".//*[#id='possible_matched']/table/tbody/tr/td[1]")
name_array = []
names.each { |name| name_array << name.text}
admits = browser.find_elements(:xpath => ".//*[#id='possible_matched']/table/tbody/tr/td[5]")
admit_array = []
admits.each { |date| admit_array << date.text }
name_admit_array = name_array.zip(admit_array)
name_admit_array.each do |name, date|
puts "#{name}: #{date}"
end
#finds the location of the sub-array containing patient name and collection associated admit date
patient_name = browser.find_element(:xpath => ".//*[#id='dialog-modal-cancel-hl7-preview']/table/tbody/tr[2]/td[1]").text
collected_date = browser.find_element(:xpath => ".//*[#id='dialog-modal-cancel-hl7-preview']/table/tbody/tr[2]/td[4]").text
mo, da, yr = collected_date.split('/').map(&:to_i)
cd = [yr, mo, da]
bl = name_admit_array.each_with_index.select { |(name, date), i|
m, d, y = date.split('/').map(&:to_i)
dt = [y, m, d]
name.downcase == patient_name.downcase and (dt <=> cd)<0
}.map {|x, i| i }
# presses the button associated with the correct sub-array
blf = name_admit_array.values_at(*bl)
if bl.any?
bf = blf.rindex(blf.max) + 2
browser.find_element(:xpath => ".//*[#id='possible_matched']/table/tbody/tr[#{bf}]/td[6]/div/a").click
else
browser.find_element(:xpath => "html/body/div[6]/div[1]/a/span").click
end
end while bl.any?
puts "no name :("
So it runs the loop until there is nothing found in the array bl. What I want to do is have this loop run again but with the next link on the list of links. So at the beginning of the loop it should do browser.find_element(:xpath => ".//*[#id='sub_nav_content']/table/tbody/tr[3]/td[3]/a").clickinstead of browser.find_element(:xpath => ".//*[#id='sub_nav_content']/table/tbody/tr[2]/td[3]/a").click. Then is should run the rest of the loop in the same way. I want it to continue to increment tr[] each time the loop runs into br.any? => false.
you can create an array of xpaths, and run this code for each of them:
[
".//*[#id='sub_nav_content']/table/tbody/tr[3]/td[3]/a",
".//*[#id='sub_nav_content']/table/tbody/tr[2]/td[3]/a"
].each do |path|
begin
browser.find_element(:xpath => path).click
// etc....
end while bl.any?
end
I believe that more changes need to adjust your code reusable, depending on your needs

Rally Ruby toolkit: how to get URL of Portfolio Item's state?

Is there an example in Ruby using rally_api how to set State of a feature as mentioned here?
Specifically, is there a way to query the ObjectID or the fully qualified path of state to use
"State" => "Developing"
instead of
"State" => "/state/<ObjectID>"
It is possible to query State, create a hash, and populate the hash with the query results, where State Name is the key and State _ref is the value:
state_results.each do |s|
s.read
state_hash[s["Name"]] = s["_ref"]
end
Then we can update a State:
features.each do |f|
field_updates={"State" => state_hash["Developing"]}
f.update(field_updates)
end
Here is a code example:
#rally = RallyAPI::RallyRestJson.new(config)
queryState = RallyAPI::RallyQuery.new()
queryState.type = :state
queryState.fetch = "true"
queryState.workspace = {"_ref" => "https://rally1.rallydev.com/slm/webservice/v2.0/workspace/11111" }
queryState.project = {"_ref" => "https://rally1.rallydev.com/slm/webservice/v2.0/project/22222" } #use valid OIDs
queryState.query_string = "(TypeDef.Name = \"Feature\")"
state_hash = Hash.new
state_results = #rally.find(queryState)
state_results.each do |s|
s.read
#puts "Ref: #{s["_ref"]}, Name: #{s["Name"] }, TypeDef: #{s["TypeDef"]}"
state_hash[s["Name"]] = s["_ref"]
end
query = RallyAPI::RallyQuery.new()
query.type = "portfolioitem/feature"
query.fetch = "Name,FormattedID"
query.workspace = {"_ref" => "https://rally1.rallydev.com/slm/webservice/v2.0/workspace/1111" }
query.project = {"_ref" => "https://rally1.rallydev.com/slm/webservice/v2.0/project/22222" } #use valid OIDs
query.query_string = "(Name = \"my feature\")"
results = #rally.find(query)
features = [];
results.each do |f|
f.read
puts "Current state of Feature #{f["FormattedID"]}: #{f["State"].to_s}"
features << f
end
features.each do |f|
field_updates={"State" => state_hash["Developing"]}
f.update(field_updates)
puts "Feature #{f["FormattedID"]} is now in State: #{f["State"].to_s}"
end

Adding groups to Projects in Redmine

i'm working on this script -> http://www.redmine.org/plugins/default_members <- by Sajin Andrei
I've completely modified the hook to suite my needs, but i realized that it actually adds every single user that is member of the defined group.
what i want to do is, instead, add the entire group to the project, so that if i add anyone else to the same group i'll not have to update every project.
this is my code:
# Debuggin [Default: commented/disabled]
#require 'logger'
class DefmembersHook < Redmine::Hook::ViewListener
def controller_projects_new_after_save(context={ })
#log = Logger.new('/usr/local/share/redmine/log/plugin.log')
params = context[:params]
project = context[:project]
roles = Role.find_all_givable
setting_group = Setting.plugin_redmine_default_members[:group] ? Setting.plugin_redmine_default_members[:group] : 'Manager'
groups ||= setting_group.split(",")
groups.each do |gp|
#log.error "gp: #{gp}"
group = Group.find(:first, :conditions => ["LOWER(lastname) = ?", gp.to_s.downcase])
#log.error "group: #{group}"
users = User.active.in_group(group).all(:limit => 100)
users.each do |user|
if user[:lastname] != 'Admin' && user[:lastname] != 'Anonymous'
#log.error "inizio per #{user}"
rs = Role.find_by_name(group.to_s)
#log.error "rs: #{rs}"
m = Member.new(:user => user, :roles => [rs])
project.members << m
#log.error "fine per #{user}"
end
end
end
end
end
and is actually working as intended by Sajin Andrei, adding single users from a group.
i want to do something like this
m = Member.new(:group => group, :roles => [rs])
project.members << m
but it doesn't work (obviously)...
hope someone can help
found the solution:
# Modificata da CARLO RUGGIERO per RETINA
# Permette di aggiungere interi gruppi ad un progetto in automatico!
class DefmembersHook < Redmine::Hook::ViewListener
def controller_projects_new_after_save(context={ })
params = context[:params]
project = context[:project]
#roles = Role.find_all_givable
setting_group = Setting.plugin_redmine_default_members[:group] ? Setting.plugin_redmine_default_members[:group] : 'Manager'
groups ||= setting_group.split(",")
groups.each do |gp|
group = Group.find(:first, :conditions => ["LOWER(lastname) = ?", gp.to_s.downcase])
rs = Role.find_by_name(group.to_s)
project.members << Member.new(:principal => group, :roles => [rs])
end
end
end
the problem was that the :user tag only accepts user elements
changing it to :principal i've got it to work
m = Member.new(:principal => group, :roles => [rs])
project.members << m
hope that someone find this usefull

Resources