Saturday, January 31, 2009

Stardate

As promised, today was to be a celebration of one year of Reusable Code. That celebration was overshadowed by a catastrophic hard drive failure early this morning, but luckily I managed to perform a successful recovery with Windows Home Server (after much trial and error).

The function I'm going to share this week is my favorite: calculating the stardate for a given Gregorian calendar date. If you're not familiar with the various Star Trek television series, you might not know what a stardate is. It's a fictional method of measuring time, which is supposed to solve the problems of relativistic time dilation caused by travelling at high velocity. In reality, it progressed at the same rate as time here on Earth.

The method of stardate calculation used here is based on Star Trek: the Next Generation, Star Trek: Deep Space Nine, and Star Trek: Voyager. It does not take the Original Series into account. Also, it is calibrated with the airdates of the television series, not with real world dates. That is to say, if you pass in today's date, it does not return the stardate corresponding to today's date in the 21st century, but today's date in the 24th century Star Trek universe. This is intended to be beneficial for roleplaying games.

ASP

  1. function stardate(someDateTime)
  2.     dim season
  3.     dim episode
  4.     dim fractime
  5.     season = cStr(Year(someDateTime) - 1947)
  6.     episode = str_pad(Round(1000 / 366 * DatePart("y", someDateTime), 0), 3, "0", "left")
  7.     fractime = left(cStr((Hour(someDateTime) * 60 + Minute(someDateTime)) / 144), 1)
  8.     stardate = season & episode & "." & fractime
  9. end function

It is important to note here that for the above function, you will also need my str_pad() function.

PHP

  1. function stardate($timestamp)
  2. {
  3.     $season = date("Y", $timestamp) - 1947;
  4.     $episode = str_pad(round(1000 / 366 * (date("z", $timestamp) + 1)), 3, "0", STR_PAD_LEFT);
  5.     $fractime = substr((date("g", $timestamp) * 60 + date("i", $timestamp)) / 144, 0, 1);
  6.     return $season . $episode . "." . $fractime;
  7. }

I'm somewhat ashamed to admit that there are some "magic" numbers at play here. When I originally wrote this function, I had not intended to make it open source, but events over the past year have led me to the realization that if I did not, it would become lost in the sands of time.

Once upon a time I also wrote some code to calculate the difference between two stardates, but it was only written in PHP. I'll have to port it to ASP and perhaps have it ready for next Saturday's posting, but no promises.


Saturday, January 24, 2009

A year of reusable code

In just a few more days, it will be one year since I started this blog. Next week Saturday I plan to mark the occasion by sharing with you, one of my most favorite functions. In the weeks following that, I'll be bringing you some larger functions and function libraries which will hopefully make up for some of the less interesting things I've posted over the past year. Unfortunately I can't promise no more boring code, because eventually the good stuff will run out.


If I'm going to be completely honest, some of the functions I've posted here, I wrote specifically for here. The tag line of this blog purports "Practical examples for real-world progrmaming", and I feel that sometimes I wasn't really living up to that. However, I feel to a certain extent that I lived up to what I resolved not to do, which was post silly examples about animals and cars just to illustrate how code works.


Since this is Saturday, I owe you folks some source code. Since next week's code is going to super awesome, I'm going to shamefully post two quick snippets which might seem lackluster, but these were honestly written out of desire/need. Both are re-creations of PHP functions, requested by a PHP programmer that worked for me and had to code in ASP because that's what the existing code was written in.


First we have the echo() function. Our PHP programmer friends are spoiled with not having to type Response.Write every time they want to put something on the screen. Then again, are we not entitled to the same luxuries? Rather than merely aliasing Response.Write, you can also use \n instead of typing vbCrLf.


  1. sub echo(someText)
  2.     Response.Write Replace(someText, "\n", vbCrLf)
  3. end sub

Our second function for today was written for use with HTML's textarea element and SQL data types that contain text with line breaks.


  1. function nl2br(someText)
  2.     nl2br = Replace(someText, vbCrLf, "<br />")
  3. end function

Saturday, January 17, 2009

Triangular Numbers

A triangular number is the sum of the n natural numbers from 1 to n.


ASP

  1. function triangularNumber(someNumber)
  2.     dim i
  3.     dim result
  4.     result = 0
  5.     for i = 1 to someNumber
  6.         result = result + i
  7.     next
  8.     triangularNumber = result
  9. end function

PHP

  1. function triangularNumber($number)
  2. {
  3.     for($i = 1; $i <= $number; $i++)
  4.     {
  5.         $result += $i;
  6.     }
  7.     return $result;
  8. }

Saturday, January 10, 2009

Array Merge

Did you ever have two arrays that you needed to merge together? If you were programming in PHP, you used the array_merge() function. If you were programming in ASP, you had to write a whole bunch of code because there is no array_merge() function... until now.


ASP

  1. function array_merge(byVal firstArray, byVal secondArray)
  2.     dim totalSize
  3.     dim i
  4.     dim combinedArray
  5.     ' Ensure that we're dealing with arrays.
  6.     if not isArray(firstArray) then
  7.         firstArray = Array(firstArray)
  8.     end if
  9.     if not isArray(secondArray) then
  10.         secondArray = Array(secondArray)
  11.     end if
  12.     ' Set up the new array.
  13.     totalSize = uBound(firstArray) + uBound(secondArray) + 1
  14.     combinedArray = firstArray
  15.     redim preserve combinedArray(totalSize)
  16.     for i = 0 to uBound(secondArray)
  17.         combinedArray(uBound(firstArray) + 1 + i) = secondArray(i)
  18.     next
  19.     array_merge = combinedArray
  20. end function

View ASP implementation on Snipplr

Saturday, January 3, 2009

Perfect Numbers

This week's function is for checking if an integer is a perfect number.


ASP

  1. function isPerfect(someNumber)
  2.     dim i
  3.     dim arrFactors
  4.     arrFactors = Array()
  5.     ' Only positive integers can be perfect.
  6.     if someNumber < 1 then
  7.         isPerfect = false
  8.         exit function
  9.     end if
  10.     ' Calculate the factors for the given number.
  11.     for i = 1 to someNumber
  12.         if someNumber mod i = 0 then
  13.             redim preserve arrFactors(UBound(arrFactors) + 1)
  14.             arrFactors(UBound(arrFactors)) = i
  15.         end if
  16.     next
  17.     ' A perfect number is a number that is half the sum of all of its positive divisors (including itself).
  18.     if someNumber = eval(join(arrFactors, " + ")) / 2 then
  19.         isPerfect = true
  20.     else
  21.         isPerfect = false
  22.     end if
  23. end function

PHP

  1. function isPerfect($number)
  2. {
  3.     // Only positive integers can be perfect.
  4.     if ($number < 1)
  5.     {
  6.         return false;
  7.     }
  8.     // Calculate the factors for the given number.
  9.     for($i = 1; $i <= $number; $i++)
  10.     {
  11.         if ($number % $i == 0)
  12.         {
  13.             $arrFactors[] = $i;
  14.         }
  15.     }
  16.     // A perfect number is a number that is half the sum of all of its positive divisors (including itself).
  17.     return ($number == array_sum($arrFactors) / 2) ? true : false;
  18. }