Private method `gets' called for (NoMethodError) Ruby [duplicate] - ruby

This question already has an answer here:
"private method 'gets' called for "parker":String
(1 answer)
Closed 6 years ago.
Getting the error
"private method `gets' called for `ot,Room 203,Healthcare Info Session,2014,6,17,14,0\n":String (NoMethodError)"
and not sure where my code is wrong.
Also the first line in appointments.txt:
ot,Room 203,Healthcare Info Session,2014,6,17,14,0
Can someone please let me know what needs to be changed in my code:
appointments = [ ]
file_object = File.open("appointments.txt", "r")
while line = file_object.gets
fields = line.gets.chomp.split(',')
appointment_type = [0]
if appointment_type == 'ot'
location = fields[1]
purpose = fields[2]
year = fields[3].to_i
month = fields[4].to_i
day = fields[5].to_i
hour = fields[6].to_i
minute = fields[7].to_i
appt1 = OneTimeAppointment.new("Dentist", "Cleaning", 4, 45, 5, 20, 2017)
appointments.push(appt1)
else
location = fields[1]
purpose = fields[2]
hour = fields[3].to_i
minute = fields[4].to_i
day = fields[5].to_i
appt2 = MonthlyAppointment.new("Doctor", "Cold", 2, 30, 15)
appointments.push(appt2)
end
end

You can't call gets on a string. You call gets on the file to retrieve the line, but then you go and call gets on that line for some reason. This is incorrect.
A fix looks like this:
File.readlines('appointments.txt') do |line|
fields = line.chomp.split(',')
# ...
end
If you're reading CSV data you may want to consider using the CSV library that comes with Ruby.

Related

Ruby with Java swing is saying that count is nil

Hello so i am new to javax.swing and i wanted to ask you guys why am i getting this error(i am going to put the exact error after my code). I have tried everything i can find. Thank you guys and im sorry if this is an easy fix i really suck at ruby right now
testGui.rb
# javaSwingHello.rb
require 'java' # Line 2
JFrame = javax.swing.JFrame
JLabel = javax.swing.JLabel
JPanel = javax.swing.JPanel
JButton = javax.swing.JButton
BorderFactory = javax.swing.BorderFactory
BorderLayout = java.awt.BorderLayout
GridLayout = java.awt.GridLayout
count = 1
frame = JFrame.new
panel = JPanel.new
button = JButton.new "Click me"
button.addActionListener self
label = JLabel.new "Number of clicks: 0"
panel.setBorder BorderFactory.createEmptyBorder(70, 70, 20, 70)
panel.setLayout GridLayout.new(0, 1)
panel.add button
panel.add label
frame.add panel, BorderLayout::CENTER
frame.setDefaultCloseOperation(JFrame::EXIT_ON_CLOSE)
frame.setTitle "TEST GUI"
frame.pack
frame.setVisible true
def actionPerformed(event)
count += 1
texttoset = "Number of clicks " + count
label.setText(texttoset)
end
Error( I am getting this when i press the button )
Exception in thread "AWT-EventQueue-0" org.jruby.exceptions.NoMethodError: (NoMethodError) undefined method `+' for nil:NilClass
at testGui.actionPerformed(testGui.rb:26)
more of a Ruby question - local variables won't be copied into a new scope:
def actionPerformed(event)
count += 1
texttoset = "Number of clicks " + count
label.setText(texttoset)
end
count is a local variable for the method (initially nil) thus the failure.
if you're just testing things out you can work-around this using a global:
$count = 1
def actionPerformed(event)
$count += 1
texttoset = "Number of clicks " + count
label.setText(texttoset)
end
that being said do not use globals and rather setup a proper object that will encapsulate the state and 'implement' the actionPerformed inteface.
You did not say, how you are going to use actionPerformed, but one possibility would be make the method a lambda:
count = 1
$ActionPerformed = -> (event) do
count += 1
texttoset = "Number of clicks " + count
label.setText(texttoset)
end
You would have to invoke it as
$ActionPerformed.call(myEvent)

Time Delta problem in Hackerrank not taking good answer / Python 3

The hackerrank challenge is in the following url: https://www.hackerrank.com/challenges/python-time-delta/problem
I got testcase 0 correct, but the website is saying that I have wrong answers for testcase 1 and 2, but in my pycharm, I copied the website expected output and compared with my output and they were exactly the same.
Please have a look at my code.
#!/bin/pyth
# Complete the time_delta function below.
from datetime import datetime
def time_delta(tmp1, tmp2):
dicto = {'Jan':1, 'Feb':2, 'Mar':3,
'Apr':4, 'May':5, 'Jun':6,
'Jul':7, 'Aug':8, 'Sep':9,
'Oct':10, 'Nov':11, 'Dec':12}
# extracting t1 from first timestamp without -xxxx
t1 = datetime(int(tmp1[2]), dicto[tmp1[1]], int(tmp1[0]), int(tmp1[3][:2]),int(tmp1[3][3:5]), int(tmp1[3][6:]))
# extracting t1 from second timestamp without -xxxx
t2 = datetime(int(tmp2[2]), dicto[tmp2[1]], int(tmp2[0]), int(tmp2[3][:2]), int(tmp2[3][3:5]), int(tmp2[3][6:]))
# converting -xxxx of timestamp 1
t1_utc = int(tmp1[4][:3])*3600 + int(tmp1[4][3:])*60
# converting -xxxx of timestamp 2
t2_utc = int(tmp2[4][:3])*3600 + int(tmp2[4][3:])*60
# absolute difference
return abs(int((t1-t2).total_seconds()-(t1_utc-t2_utc)))
if __name__ == '__main__':
# fptr = open(os.environ['OUTPUT_PATH'], 'w')
t = int(input())
for t_itr in range(t):
tmp1 = list(input().split(' '))[1:]
tmp2 = list(input().split(' '))[1:]
delta = time_delta(tmp1, tmp2)
print(delta)
t1_utc = int(tmp1[4][:3])*3600 + int(tmp1[4][3:])*60
For a time zone like +0715, you correctly add “7 hours of seconds” and “15 minutes of seconds”
For a timezone like -0715, you are adding “-7 hours of seconds” and “+15 minutes of seconds”, resulting in -6h45m, instead of -7h15m.
You need to either use the same “sign” for both parts, or apply the sign afterwards.

Subtract Time from CSV using Ruby

Hi I would like to subtract time from a CSV array using Ruby
time[0] is 12:12:00AM
time[1] is 12:12:01AM
Here is my code
time_converted = DateTime.parse(time)
difference = time_converted[1].to_i - time_converted[0].to_i
p difference
However, I got 0
p time[0].to_i gives me 12
is there a way to fix this?
You can use Time#strptime to define the format of the parsed string.
In your case the string is %I:%M:%S%p.
%I = 12 hour time
%M = minutes
%S = seconds
%p = AM/PM indicator
So to parse your example:
require 'time'
time = %w(12:12:00AM 12:12:01AM)
parsed_time = time.map { |t| Time.strptime(t, '%I:%M:%S%p').to_i }
parsed_time.last - parsed_time.first
=> 1
Use the Ruby DateTime class and parse your dates into objects of that class.

how to exclude from counting holidays in rails4

I am trying to make an app for vacation requests but i am facing a problem.I have e model called VacationRequest and a view of VacationRequest where the result will be shown.
VacationRequest.rb model
def skip_holidays
count1 = 0
special_days = Date.parse("2017-05-09", "2017-05-12")
special_days.each do |sd|
if ((start_data..end_data) === sd)
numero = (end_data - start_data).to_i
numro1 = numero - sd
else
numero = (end_data - start_data).to_i
end
end
end
VacationRequest show.htm.erb
here i called the method from model
#vacation_request.skip_holidays
this is showing errors and is not working. Please help me with that!
My approach to this would be the following:
def skip_holidays
special_days = ["2017-05-09", "2017-05-12"].map(&:to_date)
accepted_days = []
refused_days = []
(start_data..end_data).each do |requested_date|
accepted_days << requested_date unless special_days.include?(requested_date)
refused_days << requested_date if special_days.include?(requested_date)
end
accepted_day_count = accepted_days.count
refused_days_count = refused_days.count
end
This way you iterated over all requested dates (the range), checked if the date is a special day - If so, refuse it, otherwise accept it.
In the end you can display statistics about accepted and refused dates.
You cannot create a date range by passing multiple argument to the constructor. Instead call the constructor twice to create a range:
special_days = Date.parse("2017-05-09") .. Date.parse("2017-05-12")
Or if instead you want only the two dates, do:
special_days = ["2017-05-09", "2017-05-12"].map &:to_date
This Date.parse("2017-05-09", "2017-05-12") don`t create a range, only return the first params parsed:
#irb
Date.parse("2017-05-09", "2017-05-12")
=> Tue, 09 May 2017
You can do it this way:
initial = Date.parse("2017-05-09")
final = Date.parse("2017-05-12")
((initial)..final).each do |date|
#rules here.
end

Date-time comparison in Ruby

I have one date, let's say '2010-12-20' of a flight departure, and two times, for instance, '23:30' and '02:15'.
The problem: I need to get datetimes (yyyy-MM-dd HH:mm:ss, for example, 2010-12-17 14:38:32) of both of these dates, but I don't know the day of the second time (it can be the same day as departure, or the next one).
I am looking for the best solution in Ruby on Rails. In PHP would just use string splitting multiple times, but I believe, that Rails as usually, has a much more elegant way.
So, here is my pseudo code, which I want to turn into Ruby:
depart_time = '23:30'
arrive_time = '02:15'
depart_date = '2010-12-20'
arrive_date = (arrive.hour < depart.hour and arrive.hour < 5) ? depart_date + 1 : depart_date
# Final results
depart = depart_date + ' ' + depart_time
arrive = arrive_date + ' ' + arrive_time
I want to find the best way to implement this in Ruby on Rails, instead of just playing with strings.
This is just pure Ruby, nothing to do with Rails:
require 'date'
depart_time = DateTime.strptime '23:30', '%H:%M'
arrive_time = DateTime.strptime '02:15', '%H:%M'
arrive_date = depart_date = Date.parse( '2010-12-20' )
arrive_date += 1 if arrive_time.hour < depart_time.hour and arrive_time.hour < 5
puts "#{depart_date} #{depart_time.strftime '%H:%M'}",
"#{arrive_date} #{arrive_time.strftime '%H:%M'}"
#=> 2010-12-20 23:30
#=> 2010-12-21 02:15

Resources