Cookie Notice

As far as I know, and as far as I remember, nothing in this page does anything with Cookies.

2012/01/18

More Gripes and Misunderstandings about Dancer

It has been suggested that I'm not using MVC separation, which is fair, as I don't really see MVC separation. I found the POD for Dancer::Plugin::Database, and have modified my package to use it. weather is the old one, weather2 is the new one using the plugin.

package TestApp ;
use Dancer ':syntax' ;
use Dancer::Plugin::Database ;
use lib '/home/jacoby/lib' ;
use MyDB 'db_connect' ;
use DateTime ;
use Data::Dumper ;

our $VERSION = '0.1' ;

get '/' => sub {
    template 'index' ;
    } ;
 
get '/weather' => sub {
    my $dbh = db_connect() ;
    my $sql = <<SQL;
    # Last Eight Hours
    SELECT  time , AVG( temp_f )
    FROM weather WHERE zip = "47909"
    AND HOUR( TIMEDIFF( SYSDATE() , time ) ) < 9
    GROUP BY HOUR(time)
    ORDER BY time
SQL
    my $hr = $dbh->selectall_arrayref( $sql ) or croak $dbh->errstr ;
    my @hr ;
    for my $point ( @$hr ) {
        my ( $time, $temp ) = @$point ;
        my @time = split /\D+/ ,  $time ;
        my $dt = DateTime->new(
            year  => $time[0] ,
            month => $time[1] ,
            day   => $time[2] ,
            hour => $time[3] ,
            minute => $time[4] ,
            second => $time[5] ,
            ) ;
        my $data ;
        $data->{ time } = $dt->format_cldr( 'h:mm a' ) ;
        $data->{ temp } = sprintf '%.1f', $temp ;
        next if $data->{ time } !~ /00/ ;
        push @hr, $data ;
        }
    my $string = 'Temperature in West Lafayette for the last 8 hours' ;
    my $hr_ptr = \@hr ;
    template 'weather' , {
        string => $string ,
        weather => $hr_ptr
        } ;
    } ;

get '/weather2' => sub {
    my $string = 'Temperature in West Lafayette for the last 8 hours' ;
    my $sth = database->prepare(
        'SELECT  time , AVG( temp_f ) temp
        FROM weather WHERE zip = "47909"
        AND HOUR( TIMEDIFF( SYSDATE() , time ) ) < 9
        GROUP BY HOUR(time)
        ORDER BY time '
        ) ;
    $sth->execute( ) ;
    template 'weather' , {
        string => $string ,
        xxx => $sth->fetchall_arrayref( ) ,
        } ;
    } ;

true ;

I have been pointed to http://search.cpan.org/~xsawyerx/Dancer-1.3091/lib/Dancer/Tutorial.pod, and, beyond my wanting to be more specific in the munging of the data, weather is very similar to "Our First Route Handler". (How I store some data is not necessarily how I want to display some data.)

weather2 uses http://search.cpan.org/~bigpresh/Dancer-Plugin-Database-1.60/lib/Dancer/Plugin/Database.pm and you can see that there's much less code in there. The stuff I put into  MyDB exists in Dancer::Plugin::Database, and I probably could mess with the data before sending it on, instead of hooking up $sth->fetchall_arrayref() to the output.

The big thing I see here, which I could do something about with weather but probably not with the plugin-using weather2, is the SQL code being here. I would much rather shove that SQL off into a library somewhere, which I've done elsewhere, than have it at this point. But maybe, that's an aspect of me not really getting the MVC thing yet.

I Can't Help Feeling Stupid Standing 'Round

We're jumping from straight Perl and CGI.pm for web applications to an MVC, a jump we've been wanting to do for years. I've tried Catalyst a couple times, and both times, I spend most of my learning curve thinking "If I wrote this up without an MVC, I'd be done and on to the next thing by now", and in general, I get told much the same thing by my bosses, in the form of "move on  to this other, non-MVC-related task".

But that was Catalyst, which seemingly brings along half of CPAN with it. This time, I'm trying Dancer with Template Toolkit, and I'm getting some progress. Here's a chunk of code I have working.

package TestApp ;
use Dancer ':syntax' ;
use lib '/home/jacoby/lib' ;
use MyDB 'db_connect' ;
use DateTime ;

our $VERSION = '0.1' ;

get '/' => sub {
    template 'index' ;
    } ;

get '/weather' => sub {
    my $dbh = db_connect() ;
    my $sql = <<SQL;
    # Last Eight Hours
    SELECT  time , AVG( temp_f )
    FROM weather WHERE zip = "47909"
    AND HOUR( TIMEDIFF( SYSDATE() , time ) ) < 9
    GROUP BY HOUR(time)
    ORDER BY time
SQL
    my $hr = $dbh->selectall_arrayref( $sql ) or croak $dbh->errstr ;
    my @hr ;
    for my $point ( @$hr ) {
        my ( $time, $temp ) = @$point ;
        my @time = split /\D+/ ,  $time ;
        my $dt = DateTime->new(
            year  => $time[0] ,
            month => $time[1] ,
            day   => $time[2] ,
            hour => $time[3] ,
            minute => $time[4] ,
            second => $time[5] ,
            ) ;
        my $data ;
        $data->{ time } = $dt->format_cldr( 'h:mm a' ) ;
        $data->{ temp } = sprintf '%.1f', $temp ;
        next if $data->{ time } !~ /00/ ;
        push @hr, $data ;
        }
    my $vars = {
        string => 'Temperature in West Lafayette for the last 8 hours' ,
        weather => \@hr ,
        } ;

    template 'weather' , { var => $vars } ;
    } ;

true ;

A few notes here: MyDB.pm is a module I use to get a DBI object without putting the DB connection info into the code, making it safer for me to dump it in public like this. I've been collecting weather data for the West Lafayette area so I have a significant set to use when I want to play around with SQL and R.

Normally, when I pass things around, I pass, for example, a hash of hashes, then sort on the keys of the hash. Here, I'm making an array of hashes, so it's pre-sorted. I'm liking that. Still wrapping my head around how to put data where Template Toolkit can get to it. I like having my HTML as HTML, with occasional <code>[% FOREACH object IN array %] [% object.value %] [% END %] </code> sorts of thing added. I used to have lots of <code> print qq{<div> $div_contents </div>} ;</code> in my code, before I got here, where the coding standard is <code> print $cgi->div( $div_contents ) ; </code>, which is fine and all, but I always was very proud of my HTML and it feels good to be getting back into writing it in the midst of the coming of HTML5 and all.

But I'm curious if I did this the correct way of putting together the data, or if there's an easier better way that isn't apparent from the Dancer::Cookbook POD. It seems like I should be expecting a greater leap than this seems to give. What am I missing, if anything?

2012/01/14

Ubuntu on the Big Screen


So, Google TV, Apple TV, Roku, Boxee, and now Ubuntu TV. I think there's going to be problems making it a standard install because there's no standard setup on TVs. A big hamstring is the lack of Blu-Ray support in Linux (true last time I checked, maybe not now) but I can easily see a point soon where that doesn't matter anymore.

So, the set-top is the new desktop? And is this reason to go to Linux Mint or even straight Debian on machines you want to run at work? 

2012/01/11

Belkin Offers Wireless Home Automation


Home Automation is cool. This has been the opinion of this blog since the beginning. I have tested some X10 stuff before, and have found data-over-power-line to be unreliable. This is why the wireless setup that was mentioned in Google I/O last year (but not in any way delivered, as far as I can tell ) draws so much interest from me, and why I feel the need to show this video here. Wireless is so the way to go with this stuff. I wonder if you can put together little command-line apps to turn things on and off, which you can then set up via crontab on your Linux box to turn the lights on or start the coffee machine at 7am or so.

I also like the motion sensor. In rooms where you're not going to want to darken while you're in them (bedroom, living room for movie night) and rooms where you're not likely going to be blocked from the motion sensor during your time there (bathroom, kitchen), lights on a motion sensor make all the sense in the world to me. I used to have one in my den and I loved it.

Belkin's normally the "Hey! Cheap cable! Cool!" company for me, but I'd be more than happy to give this one a shot.

"Did the HTTP Headers tell you about Comcast?"

There's some buzz about an article in Forbes called "Why Best Buy is Going out of Business ... Gradually" (and the followup) about how specific decisions (such as training their workforce to talk to people about buying other stuff, not knowing what's in the store) is hurting their customer relations. Long article, go read.

Part of it is telling the story of a trip to Best Buy, looking for How To Train Your Dragon in 3D, when a sales person with no knowledge of Blu-Ray placement came up and tried to push him onto another cable system. I've come to expect that when I walk into Best Buy. It doesn't deter me from shopping at Best Buy yet, the way that the old-school, "ask for a page of personal information for a $2 cash purchase" kept me from shopping at Radio Shack for over 15 years, but it is annoying.

I went to Menards yesterday. I had three things I was looking for: stuff I saw on Make or Lifehacker or something where you dip the handles of your tools to get a comfortable and insulated grip (called Plasti Dip and to be found in the the same aisle as the Leathermen), cheap masking tape and Dremel tools I could use to recess the bottom of my son's Pinewood Derby car so the weights don't drag on the track. What I did not want is a young woman to try to sell me on Comcast. In my apartment complex, I have the choice between DishTV and cable-cutting, anyway, so I'm not the market anyway.

First guy I talked to didn't know about Plasti Dip, so he called a co-worker who directed me right to it. I don't count that as a customer service fail at all. What I do count as a fail is the free-range Comcast girl interrupting my tool-hunting experience, for two reasons. First, when men shop, they are expected to know what they want and where it is, or at least use the game-seeking sections of his brain to scope out the environment and find it. It's a hunt. There are people there whose job it is to maintain the game preserve and point out where to find the beast. The shopper respects the worker by interrupting him only after looking for himself first, and the worker respects the shopper by being available to ask questions but not forcing an interaction before the hunt has finished. That is the male way of shopping, and the Comcast girl breaks that.

Second, cable TV connects to home electronics via a coaxial connection in the back of the unit. It's more than a natural fit, it's an engineered fit. You're looking at big HD TVs? You'll want something to watch on it, and man, I have just the thing. Cable TV is as much a fit for hardware stores as Legos or tampons: not much.

I first heard of something like this in college: at the bar, a cute girl in a tight Jagermeister T-shirt comes up and asks if you've ever tried Jager, which you try because, hey, cute girl. Maybe there's even a Jager Face contest and she has a Polaroid camera (OK, think back to 1991 on this one, OK?) Suddenly, everyone you know drinks Jager shots and beer. I guess I don't mind it in the bar, in part because I don't do that anymore, but I increasingly mind it in the stores. I hope this is a dying trend.

2012/01/06

My Song of Love for Unix


My first computer was a DOS-running TRS-80 in the 1980s. In 1988, when I was heading off to college, my parents got me a Tandy PC with an 8088 processor and a green monochrome monitor that took a composite video cable. I still have it but I don't use it. The only modification I did on it was to add a modem (2400 baud, I think, but maybe 1200 baud) and I mostly used it to connect to BBSes and mostly to the campus' big machine, MUSIC (Multi-User System for Interactive Computing). I know I touched some GNU tools for DOS at the time, and I heard about UNIX systems and felt an awe about them that I don't think it's possible to express these days, when you can download Linux for free and all of Apple's computers run BSD, but I never got close to a real UNIX system back then.

In fact, the first I really touched a Unix system was when I went to school again, to get my Computer Science degree. I learned C as a subset of C++ on SunOS systems, and I have to say that I was somewhat underwhelmed with Unix. X looked positively crufty compared to Windows 95, much less MacOS, even in 1996. What I didn't get, what it took me a while to get, is that the windows don't really matter. Once you get into the Unix mindset, CDE is KDE is Gnome is Windows is MacOS. The way windowing doesn't matter, and what does matter is the command line.

And why is that? Windows has CMD and now Powershell, and Macs could be coerced to give you a prompt even back then, even if few people used them. What makes Unix systems different? In a word, pipes.

Pipes?

So, you have an MP3 of a song, somewhere in your music collection. For example, "Never Ending Love" by Delaney and Bonnie. You don't know where it is and you want to copy it to your phone. So, first you have to go through your music collection.

find Music/.

That gives you a big list of all your music. tl;dr

find Music/. | grep -i delaney

OK, so, that gives you the whole album, plus "Delaney's Dream" by Seth Austin, too.

find Music/. | grep -i delaney | grep -i "never ending"

And, if your music collection is mine, that cuts it down to two. And a great many other problems can be broken down in similar ways.

It gets deeper, but in essence, the command line, the basic way you connect with a machine, is a programming language in and of itself. You write small things that filter the information, learn the flags to control the output of the tools, and only display it when it is down to what you need to see. To the extent it is possible to script a windowing system, it is a cast-iron PITA. When you want to script things in the command line, it is baked in at a fundamental level.

So, if someone suggests you learn Unix, yeah, it's great to run Ubuntu and get the Unity shell (the current term for window manager, I guess), but you'll either be using things that are ported to all the platforms (Chrome, Firefox, Komodo Edit, in my case), things that are equivalent to things on other platforms (Nautilus vs Windows Explorer, for example) or things that are hoped to be equivalent to things on other platforms but just aren't (GIMP vs Photoshop). This makes Mac vs PC vs Linux largely a matter of taste, but the command line, or shell, is the thing that makes Unix different, that makes it powerful, which makes it powerful and user-friendly to those who it excepts as users.

Yes, I have just largely restated Neal Stephenson's "In the Beginning was the Command Line". I still enjoyed the trip, and hope you did too.

2012/01/01

Information Diet Commentary, or Sniping At An Idea I Have Some Sympathy For

I hit an idea on my Google+ feed about Information Diet. This has been presented as a summation of the concept:
#1 Productivity Tip: Spend 10% of your time consuming and 90% of your time producing. Make more stuff. Watch less. Read less. Do.
Really, this is hard to argue with, but hard to follow, as Tim O'Reilly said.

So, I go around looking at more. While I think the author of Information Diet and I probably wildly disagree on key points of ideology, I would guess that I could find lots of points of commonality. I'll have to do some reading to decide that.

But I found something else that I strongly and intensely disagree with
#2 Decentralise your media consumption This is a bit of a heretical idea too - technology is geared towards central entertainment systems for our homes. But you know what? They are hateful, terrible devices. Ten years ago, if I'd wanted to listen to music, my flow chart would have looked like this:
SWITCH ON STEREO > INSERT CD > PRESS PLAY
Now it looks something like this
SWITCH ON PC > WAIT TO BOOT > LOG IN > MORE BOOTING > UPDATES START ROLLING > CLICK ON ITUNES > WAIT SEVERAL MINUTES WHILE IT BOOTS > GET BORED, OPEN EMAIL/BROWSER > ITUNES UPDATE REQUIRED > START DOWNLOAD > START CLICKING ON FEEDS > ITUNES UPDATE DOWNLOADED > INSTALLING > RESTARTING ITUNES, MORE WAITING > ITUNES OPEN > ! WINDOWS UPDATE FINISHED, MANDATORY REBOOT...
Funny, in 2001 and before, my process for listening to music, more often than not, was:
OPEN WINAMP > CHOOSE A SONG > PRESS PLAY
I was and still am a computer guy at that time, and because I was coding and otherwise working on the PC, my stuff is by and large already updated to current versions. If the "now" case from Sciencepunk is every single time, iTunes must suck. But yeah, for the last 10 years, my CDs would get ripped and filed almost immediately, and I would listen to the original media rarely. Let me contrast it with my listening to a CD in 2001:
EITHER GO TO MY WALL OF CDS (HOME) OR MY SMALL MOBILE COLLECTION > LOOK FOR CD > LOOK AGAIN BECAUSE WITH THAT MANY CDS, YOU NEVER FIND IT ON FIRST ATTEMPT > IF FOUND, INSERT CD AND PRESS PLAY, ELSE FAIL
And things like Google Music and Spotify make this much much easier. And never ends in fail.