programming

You are currently browsing the archive for the programming category.

Despite the numerous ways in existence to quantify programming language popularity, I thought I’d throw yet another one into the mix. I made a number of Google searches of the forms below and averaged the results:

"implemented in <language>"
"written in <language>"

I’m very curious to see how these stats change over time, so I’ve added a calendar item to recompute them in six months. Leave a comment if you’d like to add a programming language to the list, and I’ll update this article and it will be included in the recomputation six months from now.

Language # Results
C 1,905,500
Java 850,000
C++ 699,000
PHP 680,000
Python 396,000
Perl 365,500
C# 349,700
Lisp Family1 176,507
JavaScript 102,700
Ruby 99,650
Scheme 86,450
Lisp 61,900
Tcl 44,800
ML Family2 29,062
Haskell 22,550
Erlang 22,285
OCaml 22,000
Common Lisp 20,600
Prolog 17,750
Lua 13,065
Smalltalk 9,105
Arc 6,775
Forth 6,465
(S)ML3 5,173
Scala 3,570
Caml 1,889
Io 1,760
Clojure 782

1 combines Lisp, Scheme, Common Lisp, Arc & Clojure
2 combines OCaml, (S)ML, Caml
3 summed separate searches for sml and ml
Update 4/23/09 added C#, Tcl per comment requests.

Tags: , , , , , , , , , , , , , , , , , , , ,

I recently obtained a mobile broadband device that has a built in GPS receiver and can emit NMEA sentences. My old Garmin portable GPS can emit NMEA also, but it’s a pain to hookup to the laptop. Combining a GPS unit in a mobile broadband device is a great idea.

Update: it appears that the accuracy radius of the wireless card is quite a bit larger than my old Garmin unit. The Garmin is usually between 15 and 30 feet, but the Sierra Wireless 598U ranges from 100 to 1,000 feet or more.

After installing the ruby-serialport gem, I was able to write a simple Ruby program to read GPS information from the device and update a remote file on my web server to allow real time location tracking.

Add a simple server side script to read the file and update an iframed Google Map and you’re all set.

The code is also in the Ruby section of my sample code repository on Github.

sudo gem install ruby-serialport
#!/usr/local/bin/ruby
# Author: Brian Adkins
# Date:   2009/04/08
# Copyright 2009 Brian Adkins - All Rights Reserved
#
# Ruby program to retrieve and parse GPS information (via NMEA sentences)
# from a Sprint Sierra Wireless 598U device.
#
# ruby gps-nmea.rb                # prints latititude/longitude info
# ruby gps-nmea.rb update-remote  # scp a file of location info to a remote server
#
# This program depends on the ruby-serialport gem:
# sudo gem install ruby-serialport
#
# From: http://www.gpsinformation.org/dale/nmea.htm#GGA
#  $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
# Where:
#      GGA          Global Positioning System Fix Data
#      123519       Fix taken at 12:35:19 UTC
#      4807.038,N   Latitude 48 deg 07.038' N
#      01131.000,E  Longitude 11 deg 31.000' E
#      1            Fix quality: 0 = invalid
#                                1 = GPS fix (SPS)
#                                2 = DGPS fix
#                                3 = PPS fix
#              4 = Real Time Kinematic
#              5 = Float RTK
#                                6 = estimated (dead reckoning) (2.3 feature)
#              7 = Manual input mode
#              8 = Simulation mode
#      08           Number of satellites being tracked
#      0.9          Horizontal dilution of position
#      545.4,M      Altitude, Meters, above mean sea level
#      46.9,M       Height of geoid (mean sea level) above WGS84
#                       ellipsoid
#      (empty field) time in seconds since last DGPS update
#      (empty field) DGPS station ID number
#      *47          the checksum data, always begins with *

require 'rubygems'
require 'serialport'

# Emacs macro to reset user modified values (highlight, then: M-x eval-region )
# ((lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ("USERNAME
\"
\372\"HOSTNAME
\"
\372\"REMOTE_DIR
\"
\372\"" 0 "%d")) arg)))

# --- MODIFY THESE -- #
USERNAME   = ""  # Username for remote host
HOSTNAME   = ""  # Remote host name e.g. foo.com
REMOTE_DIR = ""  # Remote directory e.g. /var/www/bar
# --- MODIFY THESE -- #

port_str  = '/dev/cu.sierra05'
baud_rate = 9600
data_bits = 8
stop_bits = 1
parity    = SerialPort::NONE

sp = SerialPort.new(port_str, baud_rate, data_bits, stop_bits, parity)

# lat is of the form 4807.038 where the first 2 digits are degrees and
#   the remainder is minutes.
# dir is either 'N' or 'S'
def convert_lat lat, dir
  degrees = lat[0,2].to_f + (lat[2,lat.length-2].to_f / 60.0)
  dir == 'N' ? degrees : -degrees
end

# lon is of the form 01131.000 where the first 3 digits are degrees and
#   the remainder is minutes.
# dir is either 'E', or 'W'
def convert_lon lon, dir
  degrees = lon[0,3].to_f + (lon[3,lon.length-2].to_f / 60.0)
  dir == 'E' ? degrees : -degrees
end

TEMP_PATH = '/tmp'
TEMP_FILE = 'location.txt'

def update_remote_info lat, lon
  File.open("#{TEMP_PATH}/#{TEMP_FILE}", 'w') do |tf|
    tf.puts Time.now.to_s
    tf.puts "#{lat},#{lon}"
  end
  puts 'Updating remote location info'
  `scp #{TEMP_PATH}/#{TEMP_FILE} #{USERNAME}@#{HOSTNAME}:#{REMOTE_DIR}/#{TEMP_FILE}`
  File.delete("#{TEMP_PATH}/#{TEMP_FILE}")
end

# 99 requests should be sufficient to find a $GPGGA sentence
99.times do
  if (str = sp.gets) =~ /^\$GPGGA/
    fix = str.split(',')
    if fix[6] == '1'
      lat = convert_lat(fix[2], fix[3])
      lon = convert_lon(fix[4], fix[5])
      if ARGV[0] == 'update-remote'
        update_remote_info(lat,lon)
      elsif
        puts "#{lat}, #{lon}"
      end
      exit 0
    end
  end
end

puts "Invalid data - GPS coordinates not found"

Tags: , , ,

Sunrise, Sunset & Twilight

TwilightI was curious about the exact time of sunrise & sunset at my location, so I found this US Naval Observatory site. In the process, I learned a more precise definition of twilight. I wanted to be able to automate the process of retrieving the information, so my first attempt was to simply put the query parameters used in the form in the URL as an HTTP GET request, but the server wouldn’t accept that, so I needed to issue an HTTP POST request.

Ruby Code

Ruby is a great language for this sort of task, so I put together the following simple program:

require 'net/http'

YOUR_ID    = ''    # A unique ID per comment above
YOUR_CITY  = ''    # The name of your city
YOUR_STATE = ''    # Two letter state abbreviation

now   = Time.now
month = now.month
day   = now.day + 1 # Tomorrow
year  = now.year

Net::HTTP.start('aa.usno.navy.mil') do |query|
  response = query.post('/cgi-bin/aa_pap.pl',
    "FFX=1&amp;amp;amp;ID=#{YOUR_ID}&amp;amp;amp;xxy=#{year}&amp;amp;amp;xxm=#{month}&amp;amp;amp;xxd=#{day}&amp;amp;amp;st=#{YOUR_STATE}&amp;amp;amp;place=#{YOUR_CITY}&amp;amp;amp;ZZZ=END")
  if response.body =~ /Begin civil twilight[^0-9]*(\d+:\d{2} [ap].m.).*Sunrise[^0-9]*(\d+:\d{2} [ap].m.).*Sunset[^0-9]*(\d+:\d{2} [ap].m.).*End civil twilight[^0-9]*(\d+:\d{2} [ap].m.)/m
    puts "#{month}/#{day}/#{year}"
    puts "Begin Twilight: #{$1}"
    puts "Sunrise       : #{$2}"
    puts "Sunset        : #{$3}"
    puts "End Twilight  : #{$4}"
  end
end

You just need to edit the three constants that begin with YOUR_. The id used on the Navy web form is ‘AA’, but they have a comment in the HTML that requests you use a unique id of your own up to 8 characters to help them with tracking. You can find a more complete version of the code in my github profile.

Emacs Goodness

After writing the above Ruby script, I made it executable, ‘chmod +x sunrise.rb’, and placed it in my path so I could write a simple Emacs function to invoke it.

(defun bja-sunrise ()
  "Display sunrise, sunset &amp; twilight information."
  (interactive)
  (shell-command "sunrise.rb"))

Imagine my surprise when I invoked the Emacs apropos help ‘C-h a’ to see my newly defined function and discovered that Emacs, naturally, already has several commands to display sunrise/sunset information!

calendar-mouse-sunrise/sunset
Show sunrise/sunset times for mouse-selected date.
calendar-sunrise-sunset
Local time of sunrise and sunset for date under cursor.
sunrise-sunset
Local time of sunrise and sunset for today. Accurate to a few seconds.

It doesn’t, however, display twilight information, so my simple function still has a purpose in life. Emacs is awesome :)

Tags: , , , , , ,

I saw a post on comp.lang.lisp demonstrating the suitability of Common Lisp for functional programming. The poster asked to see versions in other languages including Ruby, so I thought I’d whip something up. Here’s the original post with description of the problem:

This one was too much fun for words in re how cool it is programming
with Lisp. I would like to see this in Ruby, Clojure, Qi, and
Scheme. The precise fun part tho is typing it all in in the final form
versus dividing the thing up into steps to get intermediate results,
ie, a test of one's mastery of one's language. Non-functional
languages I guess have no choice but to stop and assign temporaries.

Given:

(defparameter *pets*
  '((dog ((blab 12)(glab 17)(cbret 82)(dober 42)(gshep 25)))
    (cat ((pers 22)(siam 7)(tibet 52)(russ 92)(meow 35)))
    (snake ((garter 10)(cobra 37)(python 77)(adder 24)(rattle 40)))
    (cow ((jersey 200)(heiffer 300)(moo 400)))))

Write:

(defun digest-tag-population (tag-population pick-tags count)...)

Such that:

(digest-tag-population *pets* '(dog cat snake) 5)

=> ((DOG CBRET 82) (DOG DOBER 42) (CAT RUSS 92) (CAT TIBET 52) (SNAKE
PYTHON 77))

...the rules being:

- consider only the populations of tags (the first symbol in each
sublist) found in the parameter pick-tags, a list

- take only the  most populous of the union of the populations

- return (tag name population) of the most populous in this order:

    firstly, by position of the tag in pick-tags
    second, ie within a tag, in descending order of population

(defun subseq-ex (st e s)
  (subseq s st (min e (length s))))

(defun digest-tag-population (tag-population pick-tags count)
  (flet ((tagpos (tag) (position tag pick-tags)))
    (stable-sort (subseq-ex 0 count
                   (sort (loop for (tag population) in tag-population
                             when (tagpos tag)
                             append (loop for pop in population
                                        collecting (list* tag pop)))
                     '> :key (lambda (x)
                               (caddr x))))
      '< :key (lambda (x) (tagpos (car x))))))

(defparameter *pets*
  '((dog ((blab 12)(glab 17)(cbret 82)(dober 42)(gshep 25)))
    (cat ((pers 22)(siam 7)(tibet 52)(russ 92)(meow 35)))
    (snake ((garter 10)(cobra 37)(python 77)(adder 24)(rattle 40)))
    (cow ((jersey 200)(heiffer 300)(moo 400)))))

#+test
(digest-tag-population *pets* '(dog cat snake) 5)

And here is my Ruby version:

PETS = [
  [:dog, [[:blab, 12], [:glab, 17], [:cbret, 82], [:dober, 42], [:gshep, 25]]],
  [:cat, [[:pers, 22], [:siam, 7], [:tibet, 52], [:russ, 92], [:meow, 35]]],
  [:snake, [[:garter, 10], [:cobra, 37], [:python, 77], [:adder, 24], [:rattle, 40]]],
  [:cow, [[:jersey, 200], [:heiffer, 300], [:moo, 400]]]
]

def digest_tag_population tag_population, pick_tags, count
  tag_population.select {|e| pick_tags.include?(e[0]) }.
    inject([]) {|memo,obj| obj[1].each {|e| memo << [obj[0], e[0], e[1]] }; memo }.
    sort {|a,b| b[2] <=> a[2] }[0,count].
    sort_by {|e| [ tag_population.map{|p| p[0]}.rindex(e[0]), e[2] * -1] }
end

digest_tag_population(PETS, [:dog, :cat, :snake], 5)

Within the function:
Line 1: select elements that match the pick tags
Line 2: map to a list of tuples of the form [:dog, :blab, 12]
Line 3: sort the list of tuples by population and select the first count of them
Line 4: sort by tag position, population

Output:

[[:dog, :cbret, 82],
[:dog, :dober, 42],
[:cat, :russ, 92],
[:cat, :tibet, 52],
[:snake, :python, 77]]

I think Ruby compares very favorably. What do you think? Feel free to submit a version in another language.

Tags: , , , ,

I had a few mis-configuration issues when setting up shoulda and rcov for a new Rails 2.2.2 project, so I thought I’d jot down a few notes (mini tutorial, quickstart) to help save others from burning time on what should be a simple task.

shoulda is a library build on Test::Unit that provides helpers, macros and assertions to make testing easier.

rcov is a code coverage tool for Ruby.

1. Install rcov

sudo gem install rcov

2. Install shoulda

sudo gem install thoughtbot-shoulda --source=http://gems.github.com

3. Create your Rails project

rails myapp

4. Modify myapp/Rakefile

require(File.join(File.dirname(__FILE__), 'config', 'boot'))
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
require 'tasks/rails'
require 'shoulda/tasks'
namespace :test do
  desc 'Measures test coverage'
  task :coverage do
    rm_f "coverage"
    rm_f "coverage.data"
    rcov = "rcov -Itest --rails --aggregate coverage.data -T -x \" rubygems/*,/Library/Ruby/Site/*,gems/*,rcov*\""
    system("#{rcov} --no-html test/unit/*_test.rb test/unit/helpers/*_test.rb")
    system("#{rcov} --no-html test/functional/*_test.rb")
    system("#{rcov} --html test/integration/*_test.rb")
    system("open coverage/index.html") if PLATFORM['darwin']
  end
end

5. Modify myapp/test/test_helper.rb

...
# Add the following line
require 'shoulda/rails'   # require 'shoulda' also worked
...

Conclusion
After you’ve written some shoulda tests, you should be able to use the following rake commands:

rake test
rake test:units
rake shoulda:list    # display specs from shoulda tests
rake test:coverage   # run rcov and display code coverage

Tags: , , , , ,

jQuery in Action

jQuery in Action cover image I just finished “jQuery in Action” by Bear Bibeault and Yehuda Katz. It’s an excellent book on the jQuery JavaScript library. The book comes with a number of example labs to try out various jQuery/JavaScript techniques w/o having to write a lot of code.

There’s plenty of jQuery information online, but “jQuery in Action” easily paid for itself in saved time in getting me up to speed quickly. It’s nicely organized, well written and the editing/quality control seems to be higher than many tech books (although that bar isn’t very high!). It also has a brief, 20 page, tutorial on JavaScript that you may find helpful.

jQuery may not satisfy the zealots on comp.lang.javascript, but I’ve found it to be an excellent JavaScript library thus far, and I think this book was the fastest way to becoming proficient.

Tags: , ,

Ruby is a very flexible and expressive language. A recent question posted by a Ruby newbie got me looking through my IRC logs for a discussion about the performance of various dynamic method invocation approaches, so I thought I’d share some performance results.

Ruby is currently my primary programming language, and I like it a lot; however, the conciseness (except for blocks) and performance of its higher order function capabilities could be improved. Scheme and Haskell beat it in this regard.

Consider three versions of a higher order function, caller, and associated ways of providing information to it to allow invoking a method dynamically given a pre-existing object and argument:

# 1. lambda
def caller fn
  fn.call(obj, arg)
end

caller(lambda {|obj,arg| obj.meth(arg) })

# 2. send
def caller sym
  obj.send(sym, arg)
end

caller(:meth)

# 3. bind/call
def caller meth
  meth.bind(obj).call(arg)
end

caller(MyClass.instance_method(:meth))

A simple benchmark of the three approaches with results follows. The benchmark uses an elide(n) method that has been added to String:

lam = lambda {|s,n| s.elide(n) }
sen = :elide
met = String.instance_method(:elide)

bm(5) do |x|
  x.report('lambda') { 100_000.times { lam.call('abcdef',4) } }
  x.report('send') { 100_000.times { 'abcdef'.send(sen,4) } }
  x.report('meth') { 100_000.times { met.bind('abc').call(4) } }
end

           user     system      total        real
lambda 1.460000   0.510000   1.970000 (  1.982085)
send   0.810000   0.260000   1.070000 (  1.075201)
meth   0.660000   0.250000   0.910000 (  0.913455)

# results with the 3 preparation lines w/in their respective loops

           user     system      total        real
lambda 1.900000   0.590000   2.490000 (  2.498358)
send   0.800000   0.250000   1.050000 (  1.068035)
meth   0.760000   0.260000   1.020000 (  1.021275)

I personally like the lambda approach, but Ruby does impose a penalty for using it.

Tags: , ,

Peter Norvig wrote a simple spelling corrector in 20 lines of Python 2.5,
so I thought I’d see what it looks like in Ruby. Here are some areas I’m not pleased with:

  1. List comprehensions in Python made the edits1 function more elegant IMO.
  2. The boolean expression in the correct function evaluates empty sets/arrays as false in Python but not in Ruby, so I had to add the “result.empty? ? nil : result” expression to several functions. I expect there’s a better way to handle this also.

Otherwise, the translation was pretty straightforward.

Here’s a link to Norvig’s page:
http://www.norvig.com/spell-correct.html

That page includes a link to a text file that I saved locally as
holmes.txt: http://www.norvig.com/holmes.txt

def words text
  text.downcase.scan(/[a-z]+/)
end

def train features
  model = Hash.new(1)
  features.each {|f| model[f] += 1 }
  return model
end

NWORDS = train(words(File.new('holmes.txt').read))
LETTERS = ("a".."z").to_a.join

def edits1 word
  n = word.length
  deletion = (0...n).collect {|i| word[0...i]+word[i+1..-1] }
  transposition = (0...n-1).collect {|i| word[0...i]+word[i+1,1]+word[i,1]+word[i+2..-1] }
  alteration = []
  n.times {|i| LETTERS.each_byte {|l| alteration << word[0...i]+l.chr+word[i+1..-1] } }
  insertion = []
  (n+1).times {|i| LETTERS.each_byte {|l| insertion << word[0...i]+l.chr+word[i..-1] } }
  result = deletion + transposition + alteration + insertion
  result.empty? ? nil : result
end

def known_edits2 word
  result = []
  edits1(word).each {|e1| edits1(e1).each {|e2| result << e2 if NWORDS.has_key?(e2) }}
  result.empty? ? nil : result
end

def known words
  result = words.find_all {|w| NWORDS.has_key?(w) }
  result.empty? ? nil : result
end

def correct word
  (known([word]) or known(edits1(word)) or known_edits2(word) or
    [word]).max {|a,b| NWORDS[a] <=> NWORDS[b] }
end

After you’ve saved the holmes.txt file, load the code into irb and call the correct function with a string as follows:

badkins:~/sync/code/ruby$ irb
irb(main):001:0> require 'spelling_corrector.rb'
=> true
irb(main):002:0> correct "whree"
=> "where"

Tags: ,

Now that I’ve switched to a Macbook Pro with OSX Leopard as my primary desktop, I’ve located my Ubuntu machine in another part of the house to be accessible to my children. Not wanting to walk to the room where it’s located just to flip the power switch, I researched how to get “wake on LAN” working, so I could power it up remotely.

1. Enable the appropriate setting in your BIOS. Mine had something to do with wake on PCI device.

2. Install ethtool if you don’t already have it.

sudo apt-get install ethtool
cd /etc/init.d
sudo vim wakeonlanconfig

Add the following lines to that file:

#!/bin/bash
ethtool -s eth0 wol g

Install the script:

sudo update-rc.d -f wakeonlanconfig defaults

Run the script:

sudo /etc/init.d/wakeonlanconfig

3. Keep the network interface alive after shut down.

sudo vim /etc/init.d/halt

Change the following line:

halt -d -f -i $poweroff $hddown

to the following line (i.e. remove the -i)

halt -d -f $poweroff $hddown

4. Get the MAC address

ifconfig | grep HW

5. Send the magic packet via the following Ruby program:

require 'socket'
mac_addr = "x21x53x39xB3x90x42"
s = UDPSocket.new
s.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1)
s.send("xff"*6 + mac_addr*16, Socket::SO_BROADCAST, '10.0.0.255', 7)

Tags: , , , , ,

This has been a long time in coming. Paul Graham and Robert Morris have released an initial version of the Arc programming language.

Announcement
Language Web Site
Software
Tutorial
Forum

They recommend using version 352 of MzScheme because the latest version apparently breaks Arc. I already had 360 installed and was in a hurry, so I tried it, and most of the tutorial seemed to work fine except for the web server which failed. I’ll try later with 352 and see how it goes.

The language is still quite volatile, so I’m not sure if anyone is too interested in investing a lot of time creating libraries yet, but when the language settles down, I’m very curious about the acceptance level of Arc.

It seems to have quite a bit of Lispy goodness, and I’ve agreed with Paul’s language philosophy from what I’ve read about what he wants Arc to become. Hopefully it will live up to those ideas. On the one hand, I can see benefits in having a standard such as the one for Common Lisp, but on the other hand, Ruby & Python have done extremely well with the BDFL model with Matz & Guido, and I think Paul Graham could pull off that role if he wants to.

A problem with a “standards” approach is the proliferation of implementations dividing the community; whereas, the single implementation languages seem to have a more unified community.

If Arc can retain the best of Lisp, add some niceties from other languages and attract an active developer community, I think it may become very interesting.

rlwrap

Probably one of the best things I’ve gotten out of the Arc release so far was a tip from a guy on the forum on how to add readline support to the Arc REPL using rlwrap. I’d never heard of rlwrap before, and it’s awesome! I can now get readline support for logo and arc without needing to rebuild them with native support.

sudo apt-get install rlwrap
rlwrap logo

What a great idea :)

Tags: , ,

« Older entries § Newer entries »