My project is supposed to fetch specific values from multiple hashes a put those values in a text file. Ideally what I need my code to do is to have every date for the employees be seven days apart, so the text file would look something like this:
"Rachel Thorndike
2017-10-09-T04:29:46-05:00
Stacie Smith
2017-10-16-T04:29:46-05:00"
What this is supposed to do is fetch employee's names and put the time of their "handoff" on the line under them. I looked online and found the DateTime that Ruby features but it looks like whatever I do isn't working. My code is this:
require 'date'
jsonUser["users"].each do |user|
somefile.puts user["user"]["summary"]
print 'Handoff Date + Time: '
parsed = DateTime.strptime(jsonUser["start"], '%d-%m-%Y %H:%M')
utc = parsed.next_day(7).strftime('%d-%m-%Y %H:%M')
puts utc
end
But terminal returns this code with an error 'strptime': invalid date (ArgumentError). Would anybody help me get this code to work the way I want to? Anything that points me to the right direction? With explanations, if it isn't too much.
Thank you so much!
Update
I was able to get the iso8601 to appear under their name. My new code is
require 'date'
jsonUser["users"].each do |user|
somefile.puts user["user"]["summary"]
print 'Handoff Date + Time: '
parsed = DateTime.iso8601(jsonUser["start"])
utc = parsed.next_day(7).iso8601
somefile.puts utc
end
BUT the .next_day method isn't increasing by 7 days that I want too. Thought? I have only got one value that is appearing and that is going under every line. Its the value of jsonUser["start"] + 7 days...so `2017-
10-16T04:29:46-05:00`
This is what parse.next_day(7) gives me.
"Sr Chid
Handoff Date + Time: 2017-10-16T04:29:46-05:00
Ash A
Handoff Date + Time: 2017-10-16T04:29:46-05:00
Ven D
Handoff Date + Time: 2017-10-16T04:29:46-05:00
Abhi S
Handoff Date + Time: 2017-10-16T04:29:46-05:00"
The value of jsonUser["start"] is 2017-10-09T04:29:46-05:00 so the good thing is that it did increase by 7 but it only did it once.
Update for Amadan
require 'date'
date = DateTime.iso8601(jsonUser["start"])
jsonUser["users"].each do |user|
if user["user"]["self"] == nil
nil
else
somefile.puts user["user"]["summary"].gsub(/\w+/, &:capitalize).gsub(/[.]/, ' ')
somefile.print 'Handoff Date + Time: '
date = date.next_day(7)
somefile.puts date.iso8061
end
end
i am using Stripe. I would like to know how can calculate number of day prorated
I want display something like that
1 additional seat ($9/month each - prorated for 26 days)
in the api i don't see any item prorate_day
Bolo
subscription_proration_date what you are looking for? Then it will calculate it for you.
See more at https://stripe.com/docs/subscriptions/guide
The example of pro-rated subscription in ruby is as follows
# Set your secret key: remember to change this to your live secret key in production
# See your keys here https://dashboard.stripe.com/account/apikeys
Stripe.api_key = "sk_test_9OkpsFpKa1HDHaZa7e0BeGaO"
proration_date = Time.now.to_i
invoice = Stripe::Invoice.upcoming(:customer => "cus_3R1W8PG2DmsmM9", :subscription => "sub_3R3PlB2YlJe84a",
:subscription_plan => "premium_monthly", :subscription_proration_date => proration_date)
current_prorations = invoice.lines.data.select { |ii| ii.period.start == proration_date }
cost = 0
current_prorations.each do |p|
cost += p.amount
end
# Display the cost of these prorations invoice items to the end user,
# and actually do the update when they agree.
# To make sure that the proration is calculated the same as when it was previewed,
# you need to pass in the proration_date parameter
# later...
subscription = Stripe::Subscription.retrieve("sub_3R3PlB2YlJe84a")
subscription.plan = "premium_monthly"
subscription.proration_date = proration_date
subscription.save
I have the following function in one of my classes
def intraday_time_series(opts)
### Guard block ###
valid_resource = opts[:resource] && [:calories, :steps, :distance, :floors, :elevation].include?(opts[:resource])
valid_date = opts[:date]
valid_detail_level = opts[:detailLevel] && %w(1min 15min).include?(opts[:detailLevel])
raise FitgemOauth2::InvalidArgumentError,
'Must specify resource to fetch intraday time series data for.'\
' One of (:calories, :steps, :distance, :floors, or :elevation) is required.' unless valid_resource
raise FitgemOauth2::InvalidArgumentError, 'Must specify the date to fetch intraday time series data for.' unless valid_date
raise FitgemOauth2::InvalidArgumentError,
'Must specify the data resolution to fetch intraday time series data for.'\
' One of (\"1d\" or \"15min\") is required.' unless valid_detail_level
### actual logic ###
resource = opts.delete(:resource)
date = format_date(opts.delete(:date))
detail_level = opts.delete(:detailLevel)
time_window_specified = opts[:startTime] || opts[:endTime]
resource_path = "user/#{#user_id}/activities/"
if time_window_specified
start_time = format_time(opts.delete(:startTime))
end_time = format_time(opts.delete(:endTime))
resource_path += "#{resource}/date/#{date}/1d/#{detail_level}/time/#{start_time}/#{end_time}.json"
else
resource_path += "#{resource}/date/#{date}/1d/#{detail_level}.json"
end
get_call(resource_path)
end
The function has a guard block that checks for any issues with the arguments (the guard block) and if no error is found it does stuff with those arguments.
Now, when I use rubocop to analyze my code, it reports high cyclometic complexity due to the guard blocks. One way I can reduce the complexity is to define another function guard_for_intraday_time_series and move all the guard blocks there. I do not think it as an appropriate solution though because it will populate my code with a guard block for every function that I have in my project.
What is an appropriate way to reduce this complexity, or is it just unavoidable?
You have many intermediate local variables that make the code complicated.
I would refactor it like this:
def intraday_time_series(resource: nil, date: nil,
detailLevel: nil, startTime: nil, endTime: nil)
unless %i[calories steps distance floors elevation].include?(resource)
raise FitgemOauth2::InvalidArgumentError,
"Must specify resource to fetch intraday time series data for."\
" One of (:calories, :steps, :distance, :floors, or :elevation) is required."
end
unless date
raise FitgemOauth2::InvalidArgumentError,
"Must specify the date to fetch intraday time series data for."
end
unless %w(1min 15min).include?(detailLevel)
raise FitgemOauth2::InvalidArgumentError,
"Must specify the data resolution to fetch intraday time series data for."\
" One of (\"1d\" or \"15min\") is required."
end
resource_path = [
"user", #user_id,
"activities", resource,
"date", format_date(date),
"1d", detailLevel
].join("/")
if startTime || endTime
resource_path =
[resource_path, "time", format_time(startTime), format_time(endTime)].join("/")
end
get_call("#{resource_path}.json")
end
I am trying to change one example to take a user input rather than using hard coded values then use those local variables to work out items needed.
So far my code looks like this:
print "Number of cars available today."
cars = gets.chomp()
print "Number of available seats in the car."
space_in_a_car = gets.chomp()
print "Number of drivers available."
drivers = gets.chomp()
print "Number of passagers that need transport."
passangers = gets.chomp
cars_not_driven = #{cars} - #{drivers}
cars_driven = drivers
carpool_capacity = #{cars_driven} * #{space_in_a_car}
average_passanger_per_car = #{passangers} / #{drivers}
print "The number of cars being driven today is #{cars_driven}.\n"
print "The number of cars not being driven today is #{cars_not_driven}.\n"
print "We have #{carpool_capacity} cars available.\n"
print "So we need to carry #{average_passanger_per_car} passangers per car to make sure we can transport everyone.\n"
The code will run without throwing any errors but of course because I am not getting the correct commands in:
cars_not_driven = #{cars} - #{drivers}
cars_driven = drivers
carpool_capacity = #{cars_driven} * #{space_in_a_car}
average_passanger_per_car = #{passangers} / #{drivers}
the only value I am getting in the return is:
print "The number of cars being driven today is #{cars_driven}.\n"
How should I be writing:
cars_not_driven = #{cars} - #{drivers} etc
to get the number of cars_not_driven?
I don't understand very well why you use this #{var} and <br>. If I am right that you want to use plain ruby, this should be the solution:
print "Number of cars available today."
cars = gets.chomp().to_i
print "Number of available seats in the car."
space_in_a_car = gets.chomp().to_i
print "Number of drivers available."
drivers = gets.chomp().to_i
print "Number of passagers that need transport."
passangers = gets.chomp.to_i
cars_not_driven = cars - drivers
cars_driven = drivers
carpool_capacity = cars_driven * space_in_a_car
average_passanger_per_car = passangers / drivers
print "The number of cars being driven today is #{cars_driven}.\n"
print "The number of cars not being driven today is #{cars_not_driven}.\n"
print "We have #{carpool_capacity} cars available.\n"
print "So we need to carry #{average_passanger_per_car} passangers per car to make sure we can transport everyone.\n"
When you use gets Ruby is expecting and returning a String. So variables car, drivers etc are all String.
In order to do integer operation over them, you need to convert them to integers. In Ruby you can do this using .to_i.
Now with that information, try:
cars_not_driven = cars.to_i - drivers.to_i
cars_driven = drivers.to_i
carpool_capacity = cars_driven * space_in_a_car.to_i
average_passanger_per_car = passangers.to_i / drivers.to_i
You can check the class of a variable using .class. Here:
cars = gets.chomp()
10
# => "10"
cars.class
# => String
drivers = gets.chomp()
20
# => "20"
drivers.class
# => String
Now lets add them:
cars + drivers
# => "1020"
Since they are string, + operator is adding two strings to one. Not something you intended. Now try this:
cars.to_i + drivers.to_i
# => 30
Hi Im working on writing a script that pulls data out of a ticketing system. Once it pulls the data it analyze the content of it and if it the content match a specific criteria then it needs to build a data structure file that will be dump in the same server.
I was able to parse the data in JSON format, listed below is the content:
[{"id"=>10423,
"type"=>"Ticket",
"lastUpdated"=>"2014-11-04T10:58:47Z",
"shortSubject"=>"FOO STATUS UPDATE",
"shortDetail"=>"Reply to this message if all systems are functional..",
"displayClient"=>"No Client",
"updateFlagType"=>0,
"prettyLastUpdated"=>"54 minutes ago",
"latestNote"=>
{"id"=>16850,
"type"=>"TechNote",
"mobileListText"=>"<b>t. trust: </b> All Systems are OK",
"noteColor"=>"clear",
"noteClass"=>"bubble right"}},
{"id"=>10422,
"type"=>"Ticket",
"lastUpdated"=>"2014-11-04T10:54:07Z",
"shortSubject"=>"FOO STATUS UPDATE",
"shortDetail"=>"Reply to this message if all systems are functional..",
"displayClient"=>"No Client",
"updateFlagType"=>0,
"prettyLastUpdated"=>"58 minutes ago",
"latestNote"=>nil},
{"id"=>10421,
"type"=>"Ticket",
"lastUpdated"=>"2014-11-04T10:53:17Z",
"shortSubject"=>"FOO STATUS UPDATE",
"shortDetail"=>"Reply to this message if all systems are functional..",
"displayClient"=>"No Client",
"updateFlagType"=>0,
"prettyLastUpdated"=>"59 minutes ago",
"latestNote"=>nil}]
In the data above you can see that each ticket has an id, lastupdate, short Subject, short Detail and lastest note the value of the latest note will be nill if no one reply to the ticket but if someone does reply then the value mobileListText will have something.
So what I need to do pretty much is once I get this data the script will look for the subject that complies with "FOO STATUS UPDATE" if that value matches then looks for the content of the shortDetail matches "Reply to this message if all systems are functional.." and if this complies then looks for its latestNote, if latestNote is nill then it will create a log file specifiying date and time when it run, the id of the ticket with this state and a message saying, ticket has not being reply, but if the latest note has the value "mobileListText"=>"t. trust: All Systems are OK", then creates the follwing data structure:
{"LastUpdate":1415130257,"Service":[{"time":"11-04-2014 10:58:47 GMT","region:":"","id":"","description":"All Systems are OK","service":""},{"time":"11-04-2014 10:54:07 GMT","region:":"","id":"","description":"All Systems are OK","service":""},{"time":"11-04-2014 10:53:17 GMT","region:":"","id":"","description":"All Systems are OK","service":""}]}
Im able to have part of this however, based on the data above, only one ticket has All Systems are OK, meaining that only one of the tickets has being reply, and it only should write something like this:
{"LastUpdate":1415130257,"Service":[{"time":"11-04-2014 10:58:47 GMT","region:":"","id":"","description":"All Systems are OK","service":""}]}
But Instead repeats this only ticket that has being replied serveral times.
this my code so far:
require 'rubygems'
require 'json'
require 'net/http'
require 'highline/import'
require 'pp'
require 'logger'
#usersol='foo'
#passol= 'foo123'
#urlsol= "http://dev-webhelpdesk.foo.corp:8081/helpdesk/WebObjects/Helpdesk.woa/ra/Tickets?list=group&page=1&limit=#{#limit}&username=#{#usersol}&password=#{#passol}"
#limit = '25'
#log = #log= Logger.new( 'message_solar.log')
def ticket_data #looks for ticket data in solarwinds
resp = Net::HTTP.get_response(URI.parse(#urlsol))
url_output = resp.body
JSON.parse(url_output)
end
#CRONJOB THAT START ALL
#echo "Reply to this message if all systems are functional.." | mail -r noc#foo.com -s "FOO STATUS UPDATE:" noc-team#FOO.com >> /dev/null
# Looking for all the tickets with the following content
# ticket id, ticket subject and content
def search_allok(allok)
description = []
allok.each do |systems|
output1 = systems.has_key?'id'
if output1
systems.values_at('shortSubject').each do | subject |
output2 = subject.match(%r(TRUST STATUS UPDATE))
if output2
latestnote = systems.values_at('latestNote')
latestnote.each do |content|
if content
final = content.values_at('mobileListText')
final_ok = final[0].sub!(/^\<b\>.*\<\/b\>\s/, "")
systems_ok = final_ok.match(%r(All Systems are OK))
if systems_ok
ids = systems['id']
notify = {"LastUpdate" => Time.now.to_i, "Service" => []}
allok.each do |lastup|
reference = lastup.has_key? 'id'
if reference
timeid = lastup.values_at('lastUpdated')
timeid.each do |lines|
final=lines.split(/[-, T, Z]/)
notify["Service"] << { "time" => "#{final[1]}-#{final[2]}-#{final[0]} #{final[3]} GMT", "region:" => "", "id" => "#{ids}", "description" => "#{systems_ok}" , "service" => ''}
end
end
end
File.open("notify.json", "w") do |fileformatted|
fileformatted.puts (JSON.dump(notify))
end
else
time = Time.now
#log.info("#{time} - Ticket ID #{systems['id']} has not being updated")
end
else
#log.info("#{time} - Ticket ID #{systems['id']} has not being reply")
end
end
end
end
end
end
end
# If the content is there then it need to create
# the data structure including the lastupdated
# (time when it run the script), and the lastupdate for the ticket
# and the description All Systems OK
#This method below I added to the one above, but I was thinking on doing it separate but I encouter issues passing the information needed from above to below
def datastructure(format_file) #creates JSON file lastupdated of each ticket in the queue
notify = {"LastUpdate" => Time.now.to_i, "Service" => []}
format_file.each do |lastup|
reference = lastup.has_key? 'id'
if reference
timeid = lastup.values_at('lastUpdated')
timeid.each do |lines|
final=lines.split(/[-, T, Z]/)
notify["Service"] << { "time" => "#{final[1]}-#{final[2]}-#{final[0]} #{final[3]} GMT", "region:" => "", "id" => "", "description" => region , "service" => ''}
end
end
end
File.open("notify.json", "w") do |fileformatted|
fileformatted.puts (JSON.dump(notify))
end
end
#ticket_data
#datastructure(ticket_data)
search_allok(ticket_data)
The code you've written is basically doing a roundabout version of what is achieved by using ruby's map and select methods. See this article: Ruby Explained: Map, Select, and Other Enumerable Methods