Ignore no such file found - ruby

Greetings,
I've a ruby script thats opening files and inserting the data inside the file into a database. Some of the files are missing so when the script attempts to open the file it throws a file not found exception.
Can anyone tell me how I can continue the process instead of the whole thing coming to an abrupt end. Please note this is the first thing I've ever done with ruby so be gentle! :-)
The code I'm using is as follows
def insertData
for i in (1..93)
puts "now looking at #{i}"
file = File.new("callspan/#{i}", "r")
while(line = file.gets)
with_db do |db|
db.query(line)
end
end
end

Either wrap the opening of the file with a call to File.exists?, or rescue from the exception. I prefer the former, if you expect it to be a common case (exceptions are for "exceptional" problems).
def insertData
for i in (1..93)
puts "now looking at #{i}"
next if !File.exists?("callspan/#{1}")
file = File.new("callspan/#{i}", "r")
while(line = file.gets)
with_db do |db|
db.query(line)
end
end
end
end

Simple one line exception handling:
10 / 0 rescue nil
Rescue only file not found exceptions:
def insert_data
(1..93).each do |i|
puts "now looking at #{i}"
begin
file = File.new("callspan/#{i}", 'r')
while(line = file.gets)
with_db do |db|
db.query(line)
end
end
rescue Errno::ENOENT
puts "skipping #{i}"
end
end
end

Use rescue nil to catch exceptions, like this:
def insertData
for i in (1..93)
puts "now looking at #{i}"
File.open("callspan/#{i}", "r").each_line do |line|
with_db do |db|
db.query(line)
end
end rescue nil
end
end
(i'd also put with_db around the cycle, it's probably more efficient)

Related

Receiving undefined method error in ruby (no rails)

I am really new to this so I apologize for my ignorance and I have searched for resources before asking.
I am using regular ruby and I am using an API.
I keep receiving undefined method error when I run things and I cannot figure out why.
So, this is my code.... the issue is the last two methods I think... but I don't understand what it is that is cause the method I am calling #print_lighting_time to come up as undefined. Other resources have stated that it is usually an issue with an object but I guess that isn't making sense to me...
here is the code for the CLI that isn't working
class Cli
def start
puts "Shabbat Shalom!"
Api.get_data
check_date_options
end
def check_date_options
puts "Curious when to light your candles for Shabbos? Type 'Dates' to find out!"
check_date
end
def check_date
input = get_input
if input == "Dates"
list_dates
else
invalid_date
end
end
def get_input
gets.chomp
end
def invalid_date
puts "Invalid date! Check your date and reenter!"
binding.pry
end
def list_dates
CandleLighting.all.each_with_index do |title, index|
puts "#{index}. #{title.date}"
end
lighting_times_info_list
end
def lighting_times_info_list
puts "Select the date to view the lighting time!"
lighting_times_info
end
def lighting_times_info
input = get_input
if input.to_i.between?(0, 60)
index = input.to_i
date = CandleLighting.all[index]
print_lighting_time(date)
else
invalid_date
lighting_times_info_list
end
def print_lighting_time(date)
puts "Shabbos is:#{date}"
puts "Light candles by: #{date.title}"
end
end
end
and here is the code for the CandleLighting class
class CandleLighting
attr_accessor :title, :date
##all = []
def initialize(title, date)
#title = title
#date = date
##all << self
end
def self.all
##all
end
end
and the code for the API
class Api
def self.get_data
load_candlelightings
end
def self.load_candlelightings
response = RestClient.get("https://www.hebcal.com/hebcal?v=1&cfg=json&maj=on&min=on&mod=on&nx=on&year=now&month=x&ss=on&mf=on&c=on&geo=geoname&geonameid=5128581&m=50&s=on")
data = JSON.parse(response.body)
data["items"].each do |hash|
CandleLighting.new(hash["title"], hash["date"]) if hash["title"].include?("Candle lighting")
end
end
end
and finally the error message that relates to line 52 of the CLI the line being "print_lighting_time(date)
Traceback (most recent call last):
6: from bin/run:4:in `<main>'
5: from /Users/allisonperry/Development/code/Mod1/candle-lighting-times/lib/cli.rb:5:in `start'
4: from /Users/allisonperry/Development/code/Mod1/candle-lighting-times/lib/cli.rb:10:in `check_date_options'
3: from /Users/allisonperry/Development/code/Mod1/candle-lighting-times/lib/cli.rb:17:in `check_date'
2: from /Users/allisonperry/Development/code/Mod1/candle-lighting-times/lib/cli.rb:37:in `list_dates'
1: from /Users/allisonperry/Development/code/Mod1/candle-lighting-times/lib/cli.rb:42:in `lighting_times_info_list'
/Users/allisonperry/Development/code/Mod1/candle-lighting-times/lib/cli.rb:52:in `lighting_times_info': undefined method `print_lighting_time' for #<Cli:0x00007fa94f883e48> (NoMethodError)
I am not sure if all this code is even necessary in order to help... but I have been trying to fix this for quite some time and its not happening.
Thank you in advance!
Putting this into a code editor and properly indenting it reveals the problem. print_lighting_time is defined inside lighting_times_info.
def lighting_times_info
input = get_input
if input.to_i.between?(0, 60)
index = input.to_i
date = CandleLighting.all[index]
print_lighting_time(date)
else
invalid_date
lighting_times_info_list
end
def print_lighting_time(date)
puts "Shabbos is:#{date}"
puts "Light candles by: #{date.title}"
end
end
It should instead be...
def lighting_times_info
input = get_input
if input.to_i.between?(0, 60)
index = input.to_i
date = CandleLighting.all[index]
print_lighting_time(date)
else
invalid_date
lighting_times_info_list
end
end
def print_lighting_time(date)
puts "Shabbos is:#{date}"
puts "Light candles by: #{date.title}"
end
Indentation is an important visual guide to prevent these sorts of mistakes.
A good editor like Atom or VSCode will indent for you and can warn you of common mistakes. Tools such as rubocop will audit your code for common mistakes.

ArgumentError on Ruby

I have been trying to run the Ruby code below but I keep on getting the following error:
Failed: ArgumentError: wrong number of arguments (given 1, expected 0)
stacktrace: ./basic_read_write.rb:3:in write_data_to_file'
/tmp/test.rb:5:inblock (2 levels) in
# writes the number of lines then each line as a string.
def write_data_to_file()
a_file=File.new("mydata.txt","w")
a_file.puts('5')
a_file.puts('Fred')
a_file.puts('Sam')
a_file.puts('Jill')
a_file.puts('Jenny')
a_file.puts('Zorro')
a_file.close
end
def read_data_from_file()
a_file=File.new("mydata.txt","r")
count = a_file.gets.to_i
puts count.to_s
for i in 0..count.to_i
puts a_file.gets
end
a_file.close
def main
# open for writing
write_data_to_file()
# open for reading
read_data_from_file()
end
main
end
The above code looks good except for the end statement in the methods. Every method ends with end.
According to your code, the def read_data_from_file() has an end at the end after the def main.
def write_data_to_file()
a_file=File.new("mydata.txt","w")
a_file.puts('5')
a_file.puts('Fred')
a_file.puts('Sam')
a_file.puts('Jill')
a_file.puts('Jenny')
a_file.puts('Zorro')
a_file.close
end
def read_data_from_file()
a_file=File.new("mydata.txt","r")
count = a_file.gets.to_i
puts count.to_s
for i in 0..count.to_i
puts a_file.gets
end
a_file.close
end
def main
# open for writing
write_data_to_file()
# open for reading
read_data_from_file()
end
main

FIFO Ruby Queues algorithm not working

Build the now_serving method which should call out (i.e. puts) the next person in line and then remove them from the front. If there is nobody in line, it should call out (puts) that "There is nobody waiting to be served!". When I try to use the shift method to get rid of the first element in the array. I end up with the wrong output. Here is the Ruby code:
def now_serving(array)
while array.length != 0
array.each do |name|
puts "Currently serving #{name}."
array.shift
end
end
puts "There is nobody waiting to be served!"
end
But the array.shift is only working once, How do I get it to drop the first element of an array continuously. Here is the code for the Rspec:
describe "#now_serving" do
context "there are no people in line" do
it "should say that the line is empty" do
expect($stdout).to receive(:puts).with("There is nobody waiting to be served!")
now_serving(katz_deli)
end
end
context "there are people in line" do
it "should serve the first person in line and remove them from the queue" do
expect($stdout).to receive(:puts).with("Currently serving Logan.")
now_serving(other_deli)
expect(other_deli).to eq(%w(Avi Spencer))
end
end
end
end
It is a bad idea to shift an array at the same time you loop through it.
def now_serving(array)
while name = array.shift
puts "Currently serving #{name}."
end
puts "There is nobody waiting to be served!"
end
So this fixed my bug
def now_serving(array)
queue = Queue.new
queue = array
if array.length > 0
puts "Currently serving #{array[0]}."
array.shift
else
puts "There is nobody waiting to be served!"
end
end

Debugging simple Ruby class method?

class DobbsyKretts
def initialize
#Receive idea
puts "Enter an idea, a secret or anything else you want to secretize; hit enter to stop typing and save the file"
(#idea = gets).reverse.upcase
#Filename and saving - to encrypt the file
puts "Enter the file name you'd like to have this saved as; Type PLAN at the beginning for plans and REM for reminders"
(#file_name = gets.chomp.upcase)
File::open("DobbsyKrett-"+ #file_name + ".txt", "w") do |f|
f << #idea
end
end
def unzip
puts "Do you want to withdraw PLAN or REM"
response = gets.chomp.upcase!
puts "Invalid" if !["PLAN","REM"].include?(response)
file_contents = nil
Dir['DobbsyKrett-'+response+"*.txt"].each do |file_nom|
file_contents = File.read(file_nom)
end
puts file_contents
end
end
somethingsomething1 = DobbsyKretts.new
somethingsomething1.unzip
def unzip
puts "Do you want to withdraw PLAN or REM"
#response = gets.strip
if #response.downcase != "plan" and #response.downcase != "rem"
puts "Invalid" end
Dir["DobbsyKrett-"+#response+".txt"].each do |file_nom|
#value = file.read(file_nom)
end
puts #value
end
end
The function gets will return a string with the line-ending character at the end which is not what you expected. To remove it, use the chomp function:
#response = gets.chomp
It is okay for a method (e.g. unzip) to create new instance variables (e.g. #valueholder). In general it's always better for your variables to have the smallest possible scope, so unless you need to read valueholder later, you should just use a local variable (remove the # from the name):
Dir["DobbsyKrett-"+#response+".txt"].each do |file_nom|
valueholder = File.read(file_nom)
end
puts valueholder
Also, valueholder is a terrible name for a variable but if you made it a local variable that could be excused.
Also, your block startings/endings are mismatched. Here's a fixed version of your function that shouldn't result in syntax errors:
def unzip
puts "Do you want to withdraw PLAN or REM"
response = gets.chomp.downcase
if !["plan","rem"].include? response
puts "Invalid"
else
Dir["DobbsyKrett-#{response}.txt"].each do |file_nom|
valueholder = file.read(file_nom)
end
puts valueholder
end
end
Edit: You should capitalize File to correctly call File.read.

Read from stdin or file in single stagment in ruby

I have this code
if filename
begin
if filename == '-'
ARGF.each{|url|
begin
check(url)
rescue Timeout::Error, Errno::ETIMEDOUT
puts "Timeout Error, try again"
redo
end
}
else
File.open(filename) {|file|
file.each{|url|
begin
check(url)
rescue Timeout::Error, Errno::ETIMEDOUT
puts "Timeout Error, try again"
redo
end
}
}
end
rescue Interrupt, Errno::EINTR
exit(1)
end
end
But I don't want repeated code for stdin and file, how can I rewrite it?
You can pull out your repeated code into a method and call that on ARGF or file as they respond to the same methods.
def do_check(to_check)
to_check.each do |url|
begin
check(url)
rescue Timeout::Error, Errno::ETIMEDOUT
puts "Timeout Error, try again"
redo
end
end
end
Then your example becomes:
if filename
begin
if filename == '-'
do_check(ARGF)
else
File.open(filename) do |file|
do_check(file)
end
end
rescue Interrupt, Errno::EINTR
exit(1)
end
end
I've used do ... end rather than {} simply because I find it easier to read.
Try using $< special variable: http://ruby.wikia.com/wiki/Special_variable

Resources