Monday, March 22, 2010
The mysterious Data Center Technical Specialist certification
On March 4, I received an email from Novell Technical Training that I had received a Novell certification for "Data Center Technical Specialist". This came as a surprise to me because I had not applied for this certification, taken any tests for this certification, not had I even heardof this certification.
Due to a cross marketing agreement with the Linux Professional Institute, I had applied for and received the Novell Certified Linux Administrator certification a few weeks prior. This seemed legitimate to me, as I had extensive experience with SUSE Linux and my Linux skills are still sharp. I continue to perform Linux server administration as part of my daily work.
However, I am not quite sure what the Data Center Technical Specialist is supposed to represent. Confused, I wrote to Novell Training asking what the certification meant. I received this equally mysterious reply:
I searched the official Novell Certification web site, and this certification does not appear anywhere. I suspect, but can't confirm that it may be part of the Solution Provider program. As such, it is probably more of a value to Novell sales than to an individual technician. I remain somewhat baffled.
Due to a cross marketing agreement with the Linux Professional Institute, I had applied for and received the Novell Certified Linux Administrator certification a few weeks prior. This seemed legitimate to me, as I had extensive experience with SUSE Linux and my Linux skills are still sharp. I continue to perform Linux server administration as part of my daily work.
However, I am not quite sure what the Data Center Technical Specialist is supposed to represent. Confused, I wrote to Novell Training asking what the certification meant. I received this equally mysterious reply:
Thank you for contacting Novell Training Services. You have received the certification as part of some changes we have made recently to our partner requirements. As part if these changes, some of the exams/certifications you have now count toward the new certification.
I searched the official Novell Certification web site, and this certification does not appear anywhere. I suspect, but can't confirm that it may be part of the Solution Provider program. As such, it is probably more of a value to Novell sales than to an individual technician. I remain somewhat baffled.
Wednesday, March 3, 2010
Fuzzy string matching in PostgreSQL
A recent project required me to use fuzzy string matching, or sound alike matching, in an application that searched a list of names. It turns out there is a contrib module for the PostgreSQL database called fuzzystrmatch that provides several different matching algorithms.
The task at hand involved rewriting a legacy application, originally in PICK, in Ruby on Rails. The PICK application used a soundex search to find names of people that sounded like the search string.
Three algorithms are available as PostgreSQL functions (after installation of the fuzzystrmatch module). They are soundex(), levenshtein(), and metaphone().
Both soundex and metaphone convert a string into character codes. Soundex uses 4 characters and metaphone uses a configurable number of characters. Levenshtein directly compares two strings and returns an integer indicating how well the two strings match.
After some trial and error, I found that metaphone produced better results than soundex. I didn't test the Levenshtein function.
To improve the results, I added a classic substring search using ILIKE. The combination of ILIKE and metaphone gave me a broad, but reasonably accurate fuzzy string search.
The task at hand involved rewriting a legacy application, originally in PICK, in Ruby on Rails. The PICK application used a soundex search to find names of people that sounded like the search string.
Three algorithms are available as PostgreSQL functions (after installation of the fuzzystrmatch module). They are soundex(), levenshtein(), and metaphone().
Both soundex and metaphone convert a string into character codes. Soundex uses 4 characters and metaphone uses a configurable number of characters. Levenshtein directly compares two strings and returns an integer indicating how well the two strings match.
After some trial and error, I found that metaphone produced better results than soundex. I didn't test the Levenshtein function.
To improve the results, I added a classic substring search using ILIKE. The combination of ILIKE and metaphone gave me a broad, but reasonably accurate fuzzy string search.
Friday, February 26, 2010
Linux: fuser to find processes on TCP ports
Note: This is for Linux only. The Mac (BSD) version of fuser does not handle TCP/UDP ports.
Once or twice a year, I run into a problem where a process is using a TCP port and I need to find out which one. I am documenting it here for the next time so I don't have to look it up in man pages.
To see all processes, run fuser as root or with sudo.
To list all processes connected to TCP port 22:
Once or twice a year, I run into a problem where a process is using a TCP port and I need to find out which one. I am documenting it here for the next time so I don't have to look it up in man pages.
To see all processes, run fuser as root or with sudo.
To list all processes connected to TCP port 22:
fuser -n tcp 22Thursday, January 21, 2010
Rails 2.x scaffolding field types
Dude, where's my CRUD?
One of the powerful features of Rails 1.x was the ability to generate CReate, Update, and Delete (CRUD) admin screens automatically using the scaffolding script built into Rails.
The original scaffolding read the database models and created basic, but usable screens to let you add and edit database records. When the 2.x release of Rails came out, scaffolding lost that power. Now, you have to manually specify each table field and type on the command line when running scaffold. If you don't, the generated screens will be empty.
Worse, a basic reference to all valid field types was missing. Here are all the valid types I have been able to dig up:
string
text (long text, up to 64k, often used for text areas)
datetime
date
integer
binary
boolean
float
decimal (for financial data)
time
timestamp
A mapping of the scaffolding types to data types in corresponding databases can be found on Overooped.
Here is an example of using 2.x scaffolding with data types, run from the Rails application root directory:
ruby script/generate scaffold Modelname name:string title:string employed_on:date remarks:text
Here is an example of using rails 3.x scaffolding with data types, run from the Rails application root directory:
ruby script/rails generate scaffold Modelname name:string title:string employed_on:date remarks:text
Thursday, December 24, 2009
You ARE your operating system (among other things)
Whenever you make a choice among products with similar functions, that choice spills over into the realm of social status.
Cars are a common example where social rank often goes with brand, and even within brand, by model, and even within model, by variations, upgrades, and badges. All signify some social status. I became acutely aware of this after purchasing a car that did not fit my image. It was uncomfortable for everyone.
Your operating system
You can see the social aspect tied to an operating system by looking at the Apple "I'm a Mac" campaign, and the weak Microsoft "I'm a PC" campaign response. A choice to run Linux or other operating system also carries connotations and shared group identity. In this sense, you are your operating system.
Your collection of choices
Whether conscious or not, decisions and choices about purchases you make, where choices are available, weave together part of your social tapestry. The schools you attend, where you work, your clothes, your car, where you live, and yes, your operating system. You are those things, at least socially.
The question is, in the context of a consumer society, can a choice be made without the attachment of social status?
Cars are a common example where social rank often goes with brand, and even within brand, by model, and even within model, by variations, upgrades, and badges. All signify some social status. I became acutely aware of this after purchasing a car that did not fit my image. It was uncomfortable for everyone.
Your operating system
You can see the social aspect tied to an operating system by looking at the Apple "I'm a Mac" campaign, and the weak Microsoft "I'm a PC" campaign response. A choice to run Linux or other operating system also carries connotations and shared group identity. In this sense, you are your operating system.
Your collection of choices
Whether conscious or not, decisions and choices about purchases you make, where choices are available, weave together part of your social tapestry. The schools you attend, where you work, your clothes, your car, where you live, and yes, your operating system. You are those things, at least socially.
The question is, in the context of a consumer society, can a choice be made without the attachment of social status?
Saturday, December 5, 2009
Calculating the square root of 2 longhand
There are many numerical methods to calculate square roots. This is the long hand method I learned in junior high. It produces one (accurate) digit at a time, but the working numbers get larger each iteration. Eventually, it bogs down because it is doing math with integers hundreds, then thousands of digits long.
Still, it is fun for tinkering. If you run this Ruby script as is, it will calculate the square root of 2 to 1,000 digits. To adjust the precision, change the number of iterations on this line:
Here is the entire script...
Still, it is fun for tinkering. If you run this Ruby script as is, it will calculate the square root of 2 to 1,000 digits. To adjust the precision, change the number of iterations on this line:
while iterations < 1000Here is the entire script...
#!/usr/bin/ruby
# calculate a square root of 2 using longhand
def newroot(divisor, doubleroot)
# calculate new root
# formula is doubleroot _ * _ = closest to divisor
# try 9, then 8, then 7 ...
i = 9
while i >= 0
multiple1 = (doubleroot.to_s + i.to_s).to_i
multiple2 = i
product = multiple1 * multiple2
if product <= divisor
# found new root
root = i
# get modulus
modulus = divisor - product
break
end
i = i - 1
end
return root, modulus
end
roots = Array.new
# the nearest root to 2 is 1
root = 1
roots.push(root)
remainder = 2 - root
doubleroot = root * 2
divisor = remainder * 100
iterations = 0
while iterations < 1000
root,remainder = newroot(divisor, doubleroot)
roots.push(root)
# compute new doubleroot
return root, modulus
end
roots = Array.new
# the nearest root to 2 is 1
root = 1
roots.push(root)
remainder = 2 - root
doubleroot = root * 2
divisor = remainder * 100
iterations = 0
while iterations < 1000
root,remainder = newroot(divisor, doubleroot)
roots.push(root)
# compute new doubleroot
doubleroot = roots.to_s.to_i * 2
# compute divisor
divisor = remainder * 100
iterations = iterations + 1
print "iteration " + iterations.to_s + "\n"
end
print "final roots are " + roots.to_s + "\n"
Subscribe to:
Posts (Atom)