Ruby Business Days in the Future

written by justin on May 7th, 2008 @ 09:38 AM

Going the other way now


    1 def business_days_future(num,start_date=nil)
    2   # takes the number of days in the past you are looking for
    3   # like 10 business days ago
    4   start_date ||= Date.today
    5   start_day_of_week = start_date.cwday #Date.today.cwday
    6   ans = 0
    7   # find the number of weeks
    8   weeks = num / 5.0
    9   #puts "yields #{weeks} weeks"
   10     
   11   temp_num = num > 5 ? 5 : num
   12   #puts "first temp num #{temp_num}"
   13   
   14   begin
   15     
   16     ans += days_to_adjust_f(start_day_of_week,temp_num)
   17     #puts "ans in loop #{ans}"
   18     
   19     weeks -= 1.0
   20     #puts "weeks in loop #{weeks}"
   21     
   22     temp_num = (weeks >= 1) ? 5 : num % 5
   23     #puts "temp_num after loop #{temp_num}"
   24   end while weeks > 0
   25   
   26   #puts "#{start_date} - #{num} - #{ans}"
   27   days_ago = start_date + num + ans
   28   
   29 end
   30 
   31 
   32 
   33 def days_to_adjust_f(start_day_of_week,num)
   34   ansr = 0
   35   case start_day_of_week
   36   when 1
   37     if 5 == num then ansr += 2 end
   38   when 2
   39     if (4..5).include?(num) then ansr += 2 end
   40   when 3
   41     if (3..5).include?(num) then ansr += 2 end
   42   when 4
   43     if (2..5).include?(num) then ansr += 2 end
   44   when 5
   45     if (1..5).include?(num) then ansr += 2 end
   46   when 6
   47     if (1..5).include?(num) then ansr += 1 end
   48   when 7
   49     #do nothing 
   50   end
   51   return ansr
   52 end

Ruby Business Days ago

written by justin on May 7th, 2008 @ 08:57 AM

My attempt at writing a solution to finding the number of business days ago from a specific date. I am using this in a Rails App.


    1 def business_days_ago(num,start_date=nil)
    2   # takes the number of days in the past you are looking for
    3   # like 10 business days ago
    4   start_date ||= Date.today
    5   start_day_of_week = start_date.cwday #Date.today.cwday
    6   ans = 0
    7   # find the number of weeks
    8   weeks = num / 5.0
    9   #puts "yields #{weeks} weeks"
   10 
   11   temp_num = num > 5 ? 5 : num
   12   #puts "first temp num #{temp_num}"
   13 
   14   begin
   15 
   16     ans += days_to_adjust(start_day_of_week,temp_num)
   17     #puts "ans in loop #{ans}"
   18 
   19     weeks -= 1.0
   20     #puts "weeks in loop #{weeks}"
   21 
   22     temp_num = (weeks >= 1) ? 5 : num % 5
   23     #puts "temp_num after loop #{temp_num}"
   24   end while weeks > 0
   25 
   26   #puts "#{start_date} - #{num} - #{ans}"
   27   days_ago = start_date - num - ans
   28 
   29 end
   30 
   31 
   32 
   33 def days_to_adjust(start_day_of_week,num)
   34   ansr = 0
   35   case start_day_of_week
   36   when 1
   37     if (1..5).include?(num) then ansr += 2 end
   38   when 2
   39     if (2..5).include?(num) then ansr += 2 end
   40   when 3
   41     if (3..5).include?(num) then ansr += 2 end
   42   when 4
   43     if (4..5).include?(num) then ansr += 2 end
   44   when 5
   45     if 5 == num then ansr += 2 end
   46   when 6
   47     # no adj
   48   when 7
   49     if (1..5).include?(num) then ansr += 1 end
   50   end
   51   return ansr
   52 end

jRuby Rails mssql server

written by justin on April 15th, 2008 @ 09:41 AM

Database.yml for connecting to a MS Sql Server using jdbc


development:
  adapter: jdbc
  driver: com.microsoft.jdbc.sqlserver.SQLServerDriver
  url: jdbc:microsoft:sqlserver://someserver.domain.local:1433;databaseName=some_db;AutoCommit=false;
  username: someuser
  password: somepassword

Ruby Procs

written by justin on January 24th, 2008 @ 11:43 AM

I was writing a script to port some data to a new database last night when I noticed that I had used the same bit of logic several times. I thought I'd better DRY up my code. I could have written a method, but I thought I'd try a proc instead. Below is the result:

Before:

if ssr[27] == 1
  cc3 = 1
elsif ssr[28] == 1
  cc3 = 2
end

if ssr[33] == 1
  cc8 = 1
elsif ssr[34] == 1
  cc8 = 2
end
 
if ssr[39] == 1
  cc13 = 1
elsif ssr[40] == 1
  cc13 = 2
end


if ssr[82] == 1
  da5 = 1
elsif ssr[83] == 1
  da5 = 2
end
After: 

find_true = Proc.new { |field1, field2|
	if field1 == 1
		1
	elsif field2 == 1
		2
	end
}

cc3 = find_true.call(ssr[27],ssr[28])

cc8 = find_true.call(ssr[33],ssr[34])

cc13 = find_true.call(ssr[39],ssr[40])
 
da5 = find_true.call(ssr[82],ssr[83])

Rails select options

written by justin on August 24th, 2007 @ 03:48 PM

I am developing an application where I have a dropdown list of hours worked on a project. The spec is that it should be in quarter hour increments using a decimal notation. So, 0, 0.25, 0.50, 0.75, etc. The select helper in rails takes an array of arrays that would look like this: [[0,0],[.25,.25], etc...]. I needed to generate that array and this is what I came up with:

  def labor_hours
    ar = []
    (0..39).each do |n| 
    	a = n.to_f
    	b = a + 0.25
    	c = a + 0.50
    	d = a + 0.75
    	ar.push([sprintf('%0.2f', a), a],[sprintf('%0.2f', b), b],[sprintf('%0.2f', c), c],[sprintf('%0.2f', d), d])
    end
    ar.push(["40.00",40])
  end

I start by creating the array that I'm going to return. I then use a range and a block to loop over 0 to 39. I have to made sure that I convert the integers to floats and add my partial hours. I then create my arrays for this integer and add them to the final array. At the last second, I add the last array for a nice even 40 hours. Works pretty well. I used sprintf to format the floats so that everything has 2 decimal places instead of some with one and some with two.

So, my view code looks like this:

<%= form.select 'labor', labor_hours, :include_blank => true %>

enum#inject

written by justin on August 20th, 2007 @ 04:23 PM

One of the very handy features of Ruby is the use of blocks. Blocks allow us to interate over a collection of some kind (think arrays) and perform some action on each item in the collection. This gives rise to methods like enum#inject. This handy little method of the enumerable module allows us to do summation operations on the contents of a collection. It looks like this:

(1..5).inject {|sum, n| sum + n}
=> 15

If you are new to Ruby, the (1..5) is a range, basically equal to [1,2,3,4,5] an array of 1 through 5. The inject method uses an accumulator object, sum in this case. It loops over the array passing in each object and adding the object to sum and finally returning sum which is 15 in this case.

One very handy use for this method is summing totals for tables in RoR. If you have a collection of objects that have a price variable for instance, you could do something like this to get a total instead of trying to keep a running total as you output the rows containing the objects' data.

@items.inject(0.0) {|memo, u| u.price + memo}

Here each item object in the @items array has a price. We give it a starting value of 0.0 to create a float object for our accumulator and let inject add all of the prices together to get our total. It is a slick way to accumulate totals on a array. Hopefully you can find a use for it too.