12 May, 2007

Bikes


So today we ride for the first time. 250's, and not any faster than 25mph. Some of you may know that we have both recently fallen in love with Ducatis. The good news is, there are not only Ducati dealers in Taiwan, there is a Ducati Monster Club!

11 May, 2007

Writing

I just got a little bit of writing done. I'm deep in the pit of despair that is where all my writing comes from, and a bit of it needed to get "to paper." But here's the good news:


  • Naked asian chick
  • Swinging boobies
  • Milla Jovovitch moves (think RE)
  • Trouts
  • And a variant on Reynolds' melding plague.... only I explain it.

10 May, 2007

Listening to GPS

I am actually able to read a raw NMEA stream from my GPS device now. Here is the code:


# this socket is our prolific driver to the GPS
pro = '/dev/cu.PL2303-12345678'

gpssocket = File.open(pro, 'r+')
deciphered = String.new()
decoded = Array.new()

while FileTest.readable?(pro)
82.times { |i| c = gpssocket.getc; deciphered << c.chr }
puts deciphered
decoded << deciphered
end


Easy 'nuff, right? Problem is the sucker goes to sleep and needs to be awake with the command "ASTRAL". GPSy X knows how to wake the device, so I'd like to be able to watch its traffic. Unfortunately, all the "usb sniffers" out there are for catching chating spouses and password snarfing. Nothing so pedestrian as just trying to see the data. Anyways, to talk to the GPS, we need this code:


def self.marshal()
payload.split(//) { |chr| checksum = checksum ^ chr.unpack("%C") }
payload + "*" + checksum.to_s
end


Only I don't know what else has to go with the ASTRAL message. Sending it just ASTRAL nets garbage. I suspect there are a bunch of other things to send (my guess is eleven items, for eighty-two chars).

I'm still figuring out how to make objects in Ruby, and a lot of the literature is very confusing. When I do get my objects, though, I've got a marshalling method (it's not a sub! it's not a function! this is Ruby! it's a method!!), so all I gotta do is come up with a perl script to parse the NMEA spec and output Ruby objects.

09 May, 2007

The biggest problem with Ruby

The biggest problem with Ruby, in my experience, has been the community. A few years back I was interested (I looked at it in 2003, but all the japanese scared me away; I looked at it again in 2004, but there was no real "place" for it at the office – a perl shop), but this time around, I decided I was just going to trudge through it. Afterall, this Rails stuff is really catching on, right?

I own a deadtree copy of the "Pickaxe Book." This book is now available online. Back when I bought it, I thought it showed a language with promise. I really liked the idea of everything being an object, and was ready to get into it. But the code samples were icky, and the authors kept harping on the same kind of example (the infernal music jukebox).

Any programmer who is worth a damn will know and love list functions, like map (and in the case of perl, we have grep and sort. These functions allow us to do very, very powerful things. Here's an example:


my %db_lexicon = map {
shift @{ $oracle_sth->fetchrow_arrayref() } => $_
} @{ $postgres_sth->fetchrow_arrayref() }


My perl is a little rusty, especially with regards to DBI, but the notion is I can iterate through an Oracle database based upon data from a Postgres database, in the same operation. Once you've figured map out, using anything else (including traditional iterators and such) becomes silly, boring, or both.

Today (and really, last night), I find myself working with data coming from my GPS. It's a lot easier to read when you've run chr() (the perl convention) or b.chr (the ruby convention). Since it's a huge pile of text, I figure the best way to go through it is with map.

Well, let's go looking for the map documentation.

The perldoc available online is precisely two clicks from the front page to the page I want.

With Ruby, I get this very cute and pretty page. However, it's not exactly clear where I should be looking for the list of methods available to an object (such as an array). If you were to click the "programming ruby" link, you descend into the Pickaxe Book. If instead you scroll down (I have a 13" screen, so yes, I have to scroll down to see that), you see Core Documentation which looks like it might be the right thing. Turns out, it is, but you'll only find map (and there are many different maps!) after you've scrolled through an interminable list of eight thousand lines of... stuff.

And of course, I love to harp on the IRC people. When I was on DALnet #perl ages and ages ago, I was happy to help anyone with one exception (no web!). I was told to "stop reading five year old documentation" when referring to the Pickaxe book.

So my impression of the Ruby community is about the same as it was in 2004, and in 2003. It's a language that's coming along, getting a community, documentation is taking form, and so on. Maybe in two or three years it will have something that looks like this and not this:

08 May, 2007

Bits per second




Not bytes, not MiB, nor any of that stuff you kids grew up with. We had bits per second, and we liked 'em. My god, the day my father brought home a Supra 14.4 (that's kilobits) to replace our Supra 2400 was like Christmas. Sure, it was for his job and stuff, but that didn't preclude me spending hours and hours and hours on the internet.

But does anyone actually know how to configure a serial port these days? I remember a few years ago having to scrounge around for DB9 to DB25 adapters, and those nefarious Sparcs who were built null (most of the time you had to nullify the adapters, too). Even back in 2001-2003 people seemed to get it.

By way of segue, that's the last time Ruby/SerialPort was updated. And not, I might add, by the original author. I have been trying very hard to get that cheap GPS of mine to talk to this cheap MacBook of mine, and having very little success. Of particular consternation is that I chose to record telemetry from the GPS with Ruby and SQLite (rather than my de rigeur Perl and Postgres).

And so here I sit. Do I read it as a file, just pretending there's data in there that will never end? Some sort of suspicious tail -f routine? Or, do I take the more appropriate approach and treat a unix socket as, well, a Unix socket?

I've never really had to ask just how fast the IO library of perl reads from a file, but my guess is it's a skosh faster than 4800bps. I surmise ruby is the same way. But, deciding to try anyways:


# this socket is our prolific driver to the GPS
pro = '/dev/cu.PL2303-12345678'


gpssocket = File.open(pro, 'r')
deciphered = String.new()

iter = 0

while (input = gpssocket.getc and iter < 100)
iter += 1
deciphered << input
end

puts deciphered.dump


There's that "iter" limit there because it tends to wander off into la-la land, not having found anything resembling $/ (this is also why I use getc instead of gets). The output is interesting, in that it contains many repeated characters. This makes me think that I'm missing something.

The "socket" method (as opposed to the above, "file" method) fares no better:


require 'socket'
require 'serialport.so'

# this socket is our prolific driver to the GPS
pro = '/dev/cu.PL2303-12345678'

begin
gpsstream = SerialPort.new(pro, 4800, 8, 1, 0)
deciphered = String.new()
iter = 0

while (input = gpsstream.getc and iter < 100)
iter += 1
deciphered << input
end
end

puts deciphered


Ruby is a really cool language. I am enjoying the time I am spending in it. But it would seem that the Rails folks and the Web folks have taken a perfectly respectable language, and removed some of the more useful parts, or glossed them over, saying things like "why in the hell do you want to talk to a serial port anyways? use C!"

What makes me sad about this is I see a lot of perl's youth in ruby of today. It's by their own admission not incredibly popular, but it gets more and more popular. The documentation continues to get better, and products like Locomotive make it very shiny indeed.

But does anyone remember when perl was the "CGI language?" That people were learning perl to write the most hideous html the internet has ever seen (some of them still doing so!)? Is it possible that Ruby, Rails, and Web 2.0 are going to lead to the stagnation that is perl today (disclaimer: I've seen and used Pugs, and think it's really cool. But do I expect to ever see perl6 in production? No.)?

Furthermore, will anyone care? I've been asked if I know the difference between RS-232 and RJ-45 on interview questions, but it was more of a joke to see if I knew it. I'm thirty years old, and I'm already an old fart to these guys. Sooner or later, serial devices will disappear. Maybe even IP4 will disappear. DECNet probably won't, but then, they're the only ones that will survive the apocalypse.

Shampoo and conditioner.

[An important tip: use conditioner instead of soap as your solo shower lube; soap isn’t supposed to go inside a vagina and it can really sting if it gets inside a penis.]


(via)

This, ladies and gentlemen, is the reason I read Shay's column (NSFW, of course). Not the hentai porn, not the discussions of futanari (and there are more!), or even the "cockblogging wednesdays." (you can figure that one out without links)

No, I read the column because I want to know which hair products are appropriate for internal use. In the shower.

07 May, 2007

Ruby and NMEA

It appears there's a guy who already has Ruby code to read a NMEA stream, but it's not exactly what he's interested in. I'm also having trouble finding something in Ruby resembling a state machine (like POE or Twisted).

Since, really, all I'm doing is reading a stream from a file (in this case, it's a UNIX socket), and looking for data that feels like NMEA. When that happens, I can create any number of classes for the protocol (hey, it's complicated and ugly, but it's nowhere near as bad as IMAP4).

Admittedly, my googling hasn't been overly aggressive, but all I've found is people who have implemented their own project-oriented state machines. I could gank their code and make it work for me, but I prefer one of two options: either a well-accepted and used library (in the case of POE) or one I wrote myself (one neck to choke... uh.. mine).

There is probably somebody screaming at me that I can use a big conditional statement (because NMEA isn't really asynchronous) to handle this. Well, I grow tired of adding new conditionals when data changes or the unthinkable happens ("TIFFs? in MY integer string? Never!").

More ruby code for Last.fm

Disclaimer: I am nominally a perl coder. This means I can read Ruby, and more or less can "pick up Ruby" pretty quickly. But I am not a professional Ruby programmer, and this code may be ugly, inefficient, outright broken, or all three of the above.

Disclaimer 2: (this one's from Last.fm)
Note: Do not exceed one request per second to ws.audioscrobbler.com or any other Last.fm webservice without prior arrangement. If you're attemping anything high-traffic, we'd appreciate a heads-up first, as we don't have infinite resources. Either post in the audioscrobbler forums or contact Russ.

I didn't hear back from Russ, but as I haven't been pounding the site at all, I don't expect this to get anyone's knickers in a wad (except Ruby experts who think I did things the wrong way).

So, here's the code (apologies if the Blogger engine breaks it).


#!/usr/bin/ruby

# More stuff here
require 'net/http'
require 'rexml/document'
include REXML

# Some constants
baseurl = 'http://ws.audioscrobbler.com/1.0/user/'
username = 'avriette'
datafile = '/neighbours.xml'

# Let's make the user class up here.
class LFpeer
def initialize(username, url, avatar, matchpct)
@username = username
@url = url
@avatar = avatar
@matchpct = matchpct
end
end

# Grab the neighbors list from last.fm, turning it into xml
neighbors = [ ]
neighbor_data = Document.new( Net::HTTP.get_response( URI.parse( baseurl + username + datafile ) ).body )

XPath.each( neighbor_data, "//user" ) { |element|
neighbors << LFpeer.new(
XPath.match( element, "//user:username" ),
XPath.match( element, "//url" ),
XPath.match( element, "//image" ),
XPath.match( element, "//match" )
)
}



That should get you started. It just pulls down a list of your neighbors and makes them into objects. Upon having your neighbors, you should be able to do a Net::HTTP.get_response using baseurl from above, LFpeer.url, and re-iterate over the whole thing again. However, in so doing, you'd make one request, followed by fifty requests (and you could then traverse that list, etc), which violates their request for no more than one request per second.

Posting this feels a little like WP:BEANS, but I don't think I've published anything too "beansy." That having been said, please don't abuse last.fm.

Oh, and they're hiring. So maybe if you do something spiffy, they'd be cool with that.

Also, advogato, advice on any screwups I made in my Ruby are appreciated. I am truly and totally infatuated with the language, and expect to be finding uses around the house for it (my GPS daemon, some robotics projects, and so on...)

06 May, 2007

Writing Ruby for tools


(not likely to be taken for Nina Simone or KRS-One)

Rather than figure out the current state of perl, I decided today I was going to hack together my tool in Ruby. The notion is pretty simple. Last.fm gives us the ability to see what our "friends" are listening to. They also give us the ability to listen to "radio" (which they don't clarify whether it's sponsored or not) that is "recommended" based upon our tastes. Minor digression here, but what exactly is the recommendation for somebody who loves Velvet Acid Christ, Nina Simone, and KRS-One? It strikes me that that particular Venn Diagram would be, uh, distorted.

So I got to thinking, if I find what other people who are listening to, who also listen to the same things I am listening to, and I get enough of a sample size, there should be a reasonable amount of overlap. Maybe there are five records out of the fifty or so "neighbours" I have at Last.fm listen to the same thing, and maybe I haven't got it.

This leaves the statistics. I'm very surprised that Last.fm doesn't have a simple "recommend music" feature. Anyways, so I now have a script that will pull down all of my neighbors' recently listened to music, and stores it in Sqlite. The problem now is that I have a script that takes a second to pull down fifty of my friends. I can then pull down untold numbers of records that they listen to, and do this in seconds. I'd even like to ruby-on-rails it so that others could do the same with their accounts. But Last.fm requests that we don't make more than one request a second. I have an email in to them asking permission.

And things start to get very curious if I add in the Amazon interface (Amazon has a SOAP interface where I can pull data from them) so that I could pull down Amazon reviews of that music (which I occasionally pay attention to). But Amazon itself has recommendations for me, based on my ten-year purchase history with them. Sounds to me like I could have just written myself a new toy.

Oh. And, it's 45 lines of Ruby code, with ample commenting. I could probably have done it in less code in perl, but boy would it have been ugly.