Saturday, November 1, 2008

Nth Day

This week I want to share with you a function that I personally got a lot of use out of. Several years ago I had a situation where there was a calendar with several hundreds recurring events. It was desired to have these events fall on roughly the same day each year. The person responsible for this was spending two or three days at the end of each year planning all the occurrences for the next year on a giant wet-eraseable calendar.


Here's what all the fuss was about: Last year, November 1 was a Thursday. This year, November 1 is a Saturday. Saturday is not a working day for most people, so these events we are scheduling need to fall on week days. Because it fell on a Thursday last year, we'd prefer to have it on a Thursday again this year. This means either pushing it back to October 30 or forward to November 6.


To make the event occur on the same day of the week, we'll store this information in our database and use it to generate the date for a given year. This is called the Nth Day. In the above example, our Nth Day is the first Thursday in November.


ASP

  1. function nthDay(someYear, someMonth, someWeek, someWeekday)
  2.     dim firstDay
  3.     dim someDay
  4.     firstDay = weekday(dateSerial(someYear, someMonth, 1))
  5.     ' Check if the week day of the first day of the month is before or after the given week day.
  6.     if (someWeekday - firstDay) >= 0 then
  7.         someDay = 1 + (someWeekday - firstDay) + ((someWeek - 1) * 7)
  8.     else
  9.         someDay = 1 + (someWeekday - firstDay) + (someWeek * 7)
  10.     end if
  11.     nthDay = dateSerial(someYear, someMonth, someDay)
  12. end function

If developing a system around this concept like I did, it's important to know that some months have a fifth week, depending on how late in the week the first day of the month is. You can't really schedule anything recurring during the fifth week. We kept it open both to give the people conducting the events a little time off, as well as for a place to move an event from the following month in situations where the customer thought it would be too late in the year otherwise.


An idea I had to improve the system, but didn't get around to exploring, was to ignore the months entirely and use the weeks of the year. Nobody wants to schedule anything around Christmas and New Year's anyway, so you don't run into problems around the beginning/end of the year like you do at the beginning/end of a month. Under this system, first Thursday of November becomes Thursday of Week 44. Scheduling a recurring event this way is not only easier, but also more consistent from year to year.


View ASP implementation on Snipplr

Saturday, October 25, 2008

Golden function

The golden function is the upper branch of the hyperbola.


ASP

  1. function gold(x)
  2.     gold = (x + sqr(x^2 + 4)) / 2
  3. end function

PHP

  1. function gold($x)
  2. {
  3.     return ($x + sqrt($x^2 + 4)) / 2;
  4. }

Sorry if this is not exciting stuff. I've got some better stuff coming, but I want to clear out some older stuff that has been waiting a while.


Saturday, October 18, 2008

Levenshtein distance

The Levenshtein distance between two strings is a measurement of similarity. The smaller the distance, the more similar two strings are. Our PHP programmer friends have a function to calculate this distance; we deserve one too.


ASP

  1. function levenshtein(byVal first, byVal second)
  2.     dim distance
  3.     dim truncateLength
  4.     if first = second then
  5.         ' The distance is zero if the strings are identical.
  6.         distance = 0

  7.     else
  8.         ' The distance is at least the difference of the lengths of the two strings.
  9.         distance = abs(len(first) - len(second))
  10.         ' Force the strings to be the same length to prevent overflows.
  11.         truncateLength = ((len(first) + len(second)) - distance) / 2
  12.         first = Left(first, truncateLength)
  13.         second = Left(second, truncateLength)
  14.         ' Compare the corresponding characters in each string.
  15.         for i = 1 to truncateLength
  16.             if Mid(first, i, 1) <> Mid(second, i, 1) then
  17.                 distance = distance + 1
  18.             end if
  19.         next
  20.     end if
  21.     levenshtein = distance
  22. end function

View ASP implementation on Snipplr

Saturday, October 11, 2008

WordCount

PHP has a function called str_word_count() which allows you to count the number of words in a string, and an array or associative array of those words. Unfortunately for us, ASP doesn't support optional parameters, so we can't duplicate all of this functionality in a single function, so we'll just concentrate on the main feature of counting the number of words.


ASP

  1. function WordCount(byVal someString)
  2.     dim position
  3.     dim spaces
  4.     spaces = 1
  5.     someString = trim(someString)
  6.     for position = 1 to len(someString)
  7.         if mid(someString, position, 1) = " " and not mid(someString, position - 1, 1) = " " then
  8.             spaces = spaces + 1
  9.         end if
  10.     next
  11.     WordCount = spaces
  12. end function

View ASP implementation on Snipplr

Saturday, October 4, 2008

Nth Root

Both ASP and PHP have a function that allows you to calculate the square root of a number. What if we wanted the cubic root of a number, or some deeper root? Calculating the root of a number is the same as raising that number to a fractional exponent.


ASP

  1. function root(x, y)
  2.     root = x ^ (1 / y)
  3. end function

PHP

  1. function root($x, $y)
  2. {
  3.     return pow($x, 1/$y);
  4. }

x
the number you want the root of
y
the depth you want to go (2 = square, 3 = cubic, etc.)

Saturday, September 27, 2008

Format a number in scientific notation

Surprisingly, neither ASP nor PHP seem to have a built-in way of formatting a number in scientific notation. Today we're going to change that.


ASP

  1. function formatScientific(someFloat)
  2.     dim power
  3.     power = (someFloat mod 10) - 1
  4.     formatScientific = cStr(cDbl(someFloat) / 10^power) & "e" & cStr(power)
  5. end function

PHP

  1. function formatScientific($someFloat)
  2. {
  3.     $power = ($someFloat % 10) - 1;
  4.     return ($someFloat / pow(10, $power)) . "e" . $power;
  5. }

Sunday, September 21, 2008

Logarithms

ASP's log() function returns the natural logarithm of a number. But what if we want a different base? The same problem exists with handheld calculators, and the same trick we use to get around it there can be used here too.


ASP

  1. function logx(number, base)
  2.     logx = log(number) / log(base)
  3. end function

View ASP implementation on Snipplr