I have a class for writing recurring entries. The initializer verifies that the start date (#date_1) is after the end date (#date_2).
class Recurrent
include Format
attr_accessor :intitule, :categorie, :sens
attr_reader :mensualite, :date_1, :date_2
def initialize (user, date_1, date_2 = date_1.next_year)
#date_1 = date_1
#date_2 = date_2
#jour = Date.today
#user = user
#compte = #user.compte
# start date before end date ? :
inversees?
end
# cut for brievity
private
def inversees?
if #date_1 < #date_2
return true
else
raise StandardError.new("start date must be before end date.")
end
end
begin
inversees?(false)
rescue => error
puts error.message
end
end
when I start the server I get this error message :
[me#manjaro accountsapp]$ rackup
undefined method `inversees?' for Recurrent:Class
Although, when I provoke the error by entering wrong dates (and disabling the javascript test that I do before data is sent to the server) , I does work. Why does this error message appear?
Related
I'm building a simple web-scraper (scraping jobs from indeed.com) for practice and I'm trying to implement the following method (low_salary?(salary)). The aim is for the method to compare a minimum (i.e. desired) salary, compare it with the offered salary contained in the job object (#salary):
class Job
attr_reader :title, :company, :location, :salary, :url
def initialize(title, company, location, salary, url)
#title = title
#company = company
#location = location
#salary = salary
#url = url
end
def low_salary?(minimum_salary)
return if !#salary
minimum_salary < #salary.split(/[^\d]/)[1..2].join.to_i
end
end
The method works fine when comapring #salary and the min_salary variable given to it, the delete_if appropriately deletes the elements that return true for low_salary? and returns correctly when #salary is nil (indeed listings don't always include the salary so my assumption is that there will be some nil values) in the following test program (Also: I am unsure as to why minimum_salary < #salary works but #salary < minimum_salary doesn't, but this does exactly what I want it to do):
require_relative('job_class.rb')
job = Job.new("designer", "company", "location", "£23,000 a year", "url")
job_results = []
job_results.push(job)
min_salary = 50000
print job.low_salary?(min_salary)
job_results.delete_if { |job| job.low_salary?(min_salary) }
print job_results
However in my scraper program, I get a no method error when calling the method: job_class.rb:16:in "low_salary?": undefined method `join' for nil:NilClass (NoMethodError)
require 'nokogiri'
require 'open-uri'
require_relative 'job_class.rb'
class JobSearchTool
def initialize(job_title, location, salary)
#document = Nokogiri::HTML(open("https://uk.indeed.com/jobs?q=#{job_title.gsub('-', '+')}&l=#{location}"))
#job_listings = #document.css('div.mosaic-provider-jobcards > a')
#salary = salary.to_i
#job_results = []
end
def scrape_jobs
#job_listings.each do |job_card|
#job_results.push(Job.new(
job_card.css('h2 > span').text, #title
job_card.css('span.companyName').text, #company
job_card.css('div.companyLocation').text, #location
job_card.css('span.salary-snippet').text, #salary
job_card['href']) #url
)
end
end
def format_jobs
#job_results.each do |job|
puts <<~JOB
#{job.title} - #{job.company} in #{job.location} :#{job.salary}
Apply at: #{job.url}
---------------------------------------------------------------------------------
JOB
end
end
def check_salary
#job_results.delete_if { |job| job.low_salary?(#salary) }
end
def run
scrape_jobs
check_salary
format_jobs
end
if __FILE__ == $0
job_search_tool = JobSearchTool.new(ARGV[0], ARGV[1], ARGV[2])
job_search_tool.run
end
Obviously something from the scraper programme is influencing the method somehow, but I can't understand what it could be. I'm using the method in the exact same way as the test program, so what difference is causing the method not to return when #salary is nil?
A quick search on the URL you're scraping shows there are job posts that don't have a salary, so, when you get the data from that HTML element and initialize a new Job object, the salary is an empty string, and knowing that "".split(/[^\d]/)[1..2] returns nil, that's the error you get.
You must add a way to handle job posts without a salary:
class Job
attr_reader :title, :company, :location, :salary, :url
def initialize(title, company, location, salary, url)
#title = title
#company = company
#location = location
#salary = salary.to_s # Explicit conversion of nil to string
#url = url
end
def low_salary?(minimum_salary)
return if parsed_salary.zero? # parsed_salary returns always an integer,
# so you can check when is zero,
# and not just when is falsy
minimum_salary < parsed_salary
end
private
def parsed_salary
salary[/(?<=£)(\d|,)*(?=\s)/]
.to_s # converts nil to "" if the regex doesn't capture anything
.tr(",", "") # removes the commas to parse the string as an integer
.to_i # parses the string to its corresponding integer representation
end
end
Notice the regex isn't meant to capture everything, but it works with the salary as rendered in the website.
I am run this code but I am getting an error.
code here :-
class Text
def post(success, error)
if authenticate?(#user, #password)
success.call
else
erro.call
end
end
end
text = Text.new('Ruby Bits!')
success = ->{ puts "Sent!"}
error = ->{ raise 'Auth error'}
text.post(success,error)
Please tell us. How to solve this problem?
Look closely at which line number the ArgumentError is raised from (in your case, line 25).
You are passing one argument to the Text#initialize, but have not defined a version of initialize that takes one argument.
Try this instead (calling the default, zero argument Text constructor):
class Text
def post(success, error)
if authenticate?(#user, #password)
success.call
else
error.call
end
end
end
text = Text.new
success = ->{ puts "Sent!"}
error = ->{ raise 'Auth error'}
text.post(success, error)
Or define initialize with one argument:
class Text
def initialize(your_meaningful_argument)
# do stuff
end
def post(success, error)
if authenticate?(#user, #password)
success.call
else
error.call
end
end
end
I'm learning how to work with HTTParty and API and I'm having an issue with my code.
Users/admin/.rbenv/versions/2.0.0-p481/lib/ruby/2.0.0/uri/generic.rb:214:in `initialize': the scheme http does not accept registry part: :80 (or bad hostname?)
I've tried using debug_output STDOUT both as an argument to my method and after including HTTParty to have a clue but with no success. Nothing gets displayed:
require 'httparty'
class LolObserver
include HTTParty
default_timeout(1) #timeout after 1 second
attr_reader :api_key, :playerid
attr_accessor :region
def initialize(region,playerid,apikey)
#region = region_server(region)
#playerid = playerid
#api_key = apikey
end
def region_server(region)
case region
when "euw"
self.class.base_uri "https://euw.api.pvp.net"
self.region = "EUW1"
when "na"
self.class.base_uri "https://na.api.pvp.net"
self.region = "NA1"
end
end
def handle_timeouts
begin
yield
#Timeout::Error, is raised if a chunk of the response cannot be read within the read_timeout.
#Timeout::Error, is raised if a connection cannot be created within the open_timeout.
rescue Net::OpenTimeout, Net::ReadTimeout
#todo
end
end
def base_path
"/observer-mode/rest/consumer/getSpectatorGameInfo"
end
def current_game_info
handle_timeouts do
url = "#{ base_path }/#{region}/#{playerid}?api_key=#{api_key}"
puts '------------------------------'
puts url
HTTParty.get(url,:debug_output => $stdout)
end
end
end
I verified my URL which is fine so I'm lost as to where the problem is coming from.
I tested with a static base_uri and it doesn't change anything.
The odd thing is when I do:
HTTParty.get("https://euw.api.pvp.net/observer-mode/rest/consumer/getSpectatorGameInfo/EUW1/randomid?api_key=myapikey")
Everything is working fine and I'm getting a response.
HTTParty doesn't seem to like the way you set your base_uri.
Unless you need it to be like that just add another attr_reader called domain and it will work.
require 'httparty'
class LolObserver
include HTTParty
default_timeout(1) #timeout after 1 second
attr_reader :api_key, :playerid, :domain
attr_accessor :region
def initialize(region,playerid,apikey)
#region = region_server(region)
#playerid = playerid
#api_key = apikey
end
def region_server(region)
case region
when "euw"
#domain = "https://euw.api.pvp.net"
self.region = "EUW1"
when "na"
#domain = "https://na.api.pvp.net"
self.region = "NA1"
end
end
def handle_timeouts
begin
yield
#Timeout::Error, is raised if a chunk of the response cannot be read within the read_timeout.
#Timeout::Error, is raised if a connection cannot be created within the open_timeout.
rescue Net::OpenTimeout, Net::ReadTimeout
#todo
end
end
def base_path
"/observer-mode/rest/consumer/getSpectatorGameInfo"
end
def current_game_info
handle_timeouts do
url = "#{domain}/#{ base_path }/#{region}/#{playerid}?api_key=#{api_key}"
puts '------------------------------'
puts url
HTTParty.get(url,:debug_output => $stdout)
end
end
end
I'm picking up ruby language and get stuck at playing with the chatterbot i have developed. Similar issue has been asked here Click here , I did what they suggested to change the rescue in order to see the full message.But it doesn't seem right, I was running basic_client.rb at rubybot directory and fred.bot is also generated at that directory . Please see the error message below: Your help very be very much appreciated.
Snailwalkers-MacBook-Pro:~ snailwalker$ cd rubybot
Snailwalkers-MacBook-Pro:rubybot snailwalker$ ruby basic_client.rb
/Users/snailwalker/rubybot/bot.rb:12:in `rescue in initialize': Can't load bot data because: No such file or directory - bot_data (RuntimeError)
from /Users/snailwalker/rubybot/bot.rb:9:in `initialize'
from basic_client.rb:3:in `new'
from basic_client.rb:3:in `<main>'
basic_client.rb
require_relative 'bot.rb'
bot = Bot.new(:name => 'Fred', :data_file => 'fred.bot')
puts bot.greeting
while input = gets and input.chomp != 'end'
puts '>> ' + bot.response_to(input)
end
puts bot.farewell
bot.rb:
require 'yaml'
require './wordplay'
class Bot
attr_reader :name
def initialize(options)
#name = options[:name] || "Unnamed Bot"
begin
#data = YAML.load(File.read('bot_data'))
rescue => e
raise "Can't load bot data because: #{e}"
end
end
def greeting
random_response :greeting
end
def farewell
random_response :farewell
end
def response_to(input)
prepared_input = preprocess(input).downcase
sentence = best_sentence(prepared_input)
reversed_sentence = WordPlay.switch_pronouns(sentence)
responses = possible_responses(sentence)
responses[rand(responses.length)]
end
private
def possible_responses(sentence)
responses = []
#data[:responses].keys.each do |pattern|
next unless pattern.is_a?(String)
if sentence.match('\b' + pattern.gsub(/\*/, '') + '\b')
if pattern.include?('*')
responses << #data[:responses][pattern].collect do |phrase|
matching_section = sentence.sub(/^.*#{pattern}\s+/, '')
phrase.sub('*', WordPlay.switch_pronouns(matching_section))
end
else
responses << #data[:responses][pattern]
end
end
end
responses << #data[:responses][:default] if responses.empty?
responses.flatten
end
def preprocess(input)
perform_substitutions input
end
def perform_substitutions(input)
#data[:presubs].each {|s| input.gsub!(s[0], s[1])}
input
end
# select best_sentence by looking at longest sentence
def best_sentence(input)
hot_words = #data[:responses].keys.select do |k|
k.class == String && k =~ /^\w+$/
end
WordPlay.best_sentence(input.sentences, hot_words)
end
def random_response(key)
random_index = rand(#data[:responses][key].length)
#data[:responses][key][random_index].gsub(/\[name\]/, #name)
end
end
I'm assuming that you are trying to load the :data_file passed into Bot.new, but right now you are statically loading a bot_data file everytime. You never mentioned about bot_data in the question. So if I'm right it should be like this :
#data = YAML.load(File.read(options[:data_file]))
Instead of :
#data = YAML.load(File.read('bot_data'))
I am unable to send emails. i have already tried the following:
Converting type of handler from text to long text does'nt work as i am using postgres.
I have also tried restarting my workers and delayed jobs
and my delayed job is version is 3.0.1.
I am having problem on the line:
Notifier.delay.delivery_alert(u)
and my delivery_alert method is
def delivery_alert(user)
#user = user
#deliveries = #user.issues.includes(:copy => [:rentable]).current.by_last_status("to_be_delivered").map(&:copy).map(&:rentable)
#returns = #user.issues.includes(:copy => [:rentable]).current.by_last_status("marked_for_return").map(&:copy).map(&:rentable)
mail(:to => #user.email)
end
While on localhost i am getting the error:
[Worker(host:ubuntu pid:12169)] Class#delivery_alert failed with NoMethodError: undefined method `delivery_alert' for # - 5 failed attempts
for which i have added a patch in my lib folder
require 'yaml'
module Delayed
module Backend
module Base
def payload_object
YAML::ENGINE.yamler = 'psych'
#payload_object ||= YAML.load(self.handler)
rescue TypeError, LoadError, NameError, ArgumentError => e
raise DeserializationError,
"Job failed to load: #{e.message}. Handler: #{handler.inspect}"
end
end
end
class PerformableMailer
def perform
double = object.is_a?( String ) ? object.constantize : object
double.send(method_name, *args).deliver
end
end
end
by taking reference of
https://gist.github.com/oelmekki/2181381
but still my email are not going. Thanks in advance?