Monday, December 21, 2009

The Influence of the Stars

Right around the time I found out Brittany Murphy died yesterday, I finished reading Eating Animals by Jonathan Safran Foer. In an eye-opening piece on the 1918 Spanish flu pandemic (which killed more humans faster than any other disease, or any other anything, has before or since), the author goes into the history behind the word 'influenza':
Much like the virus it names, the word influenza comes to us by way of a mutation. The word itself was first used in Italian and originally referred to the influence of the stars - that is, astral or occult influences that would have been felt by many people at once. By the 16th century, though, the word has begun mixing and blending with the meanings of other words and come to refer to epidemic and pandemic flues that simultaneously strike multiple communities (as if the result of some malevolent will).
Reference: page 13 in Eating Animals.

Much like an Italian villager in the 1500s, I feel like the universe is conspiring against me, trying to prevent me from discovering more about three Asian American actresses in a movie with Brittany. I searched IMDB, on Google, and even posted a question on Yahoo Answers, all to no avail. So I ask you, Gentle Reader, what are the names of the actresses who portrayed Janet Hong and 2 other unnamed Asian female characters in the movie Clueless (1995) ?

Wednesday, September 23, 2009

how to import data into R and SAS

What is bio-statistics and how does it relate to me ? I am often asked this question, and now I think I may have an answer. With the advent of the Internet, we are now in the Age of Information, and when it comes to "statistical data analysis", a rather imposing mouthful, to quote a recent article in the New York Times (and I paraphrase):
In field after field, computing and the Web are creating new realms of data to explore - sensor signals, surveillance tapes, social network chatter, public records and more. We're rapidly entering a world where everything can be monitored and measured, but the big problem is going to be the ability of humans to use, analyze and make sense of the data. Strong correlations of data do not necessarily prove a cause-and-effect link. For example, in the late 1940s, before there was a polio vaccine, public health experts in America noted that polio cases increased in step with the consumption of ice cream and soft drinks. Eliminating such treats was even recommended as part of an anti-polio diet. It turned out that polio outbreaks were most common in the hot months of summer, when people naturally ate more ice cream, showing only an association. Computers do what they are good at, which is trawling these massive data sets for something that is mathematically odd, and humans do what they are good at and explain these anomalies.
To analyze statistical data, we use computer programs as tools to work with such information as biological data. Yet another recent article in the New York Times compares and contrasts two of these computer programs, R and SAS (and again I paraphrase):
SAS Institute (the privately held business software company that specializes in data analysis)'s namesake SAS has been the preferred tool of scholars and corporate managers. But the R Project has also quickly found a following because statisticians, engineers and scientists without computer programming skills find it easy to use.
Reference:
http://www.nytimes.com/2009/08/06/technology/06stats.html
http://www.nytimes.com/2009/01/07/technology/business-computing/07program.html?pagewanted=all

So "Statistical Data Analysis" in the abstract sense is a formidable journey of a thousand miles, but the bite-size journey's first step involves importing a set of data into the tool (I'm assuming you already obtained, installed, and are running the software). For purposes of demonstration, I've created a data set using the actual previous year's receipts I had gathered and saved from each and every time I filled my car's tank with gasoline:
    18AUG2009  6 12.815 37.66
14JUL2009 12 4.340 11.8
28MAY2009 6 9.532 24.39
22APR2009 4 7.348 16.01
25MAR2009 2 5.509 11.12
15MAR2009 7 4.230 8.62
04MAR2009 3 11.989 25.16
21FEB2009 7 13.298 27.91
29JAN2009 15 13.989 27.68
03JAN2009 6 12.620 22.70
29NOV2008 16 11.239 20.78
25SEP2008 8 13.929 51.80
Note that on the tail end of the second line, in the last figure, 11.8, I omitted a zero ('0') when I was typing the data in. We'll come back to that later. I decided to record the following four fields for each time I filled the gas tank (all took place at Costco in San Leandro):
  1. date of purchase
  2. pump number
  3. quantity of gas obtained, in gallons
  4. cost of the transaction
In both tools, R and SAS, we will then divide cost by quantity and generate a fifth field, price per gallon.

To import a dataset into your software, you can either read from a file, or copy and paste it in (although for R, you will copy the data set, but you won't actually paste anything). The following scripts have been tested on R versions 2.8.1, 2.9.2 and SAS version 9.1.3 Service Pack 4.
  • To read data from a file within R and SAS:
    1. identify the path to the file containing your data set. Let's say the path is:
      G:\tpc247\petrol.txt
      if you're on Windows, the convention is to delimit or separate folders with a backslash, but this poses a problem for software that is trained to recognize tabs and carriage returns and newlines as '\t', '\r' and '\n' respectively. For reasons of cross-platform compatibility, if there are backslashes in your Windows path, add another one right next to it:
      G:\\tpc247\\petrol.txt
      or replace the backslash with a forward slash:
      G:/tpc247/petrol.txt
    2. at the command prompt, input and run the following incantations:
      • R:
        petrol_01 = read.table("G:/tpc247/petrol.txt", header=FALSE, col.names=c('date', 'pump', 'quantity', 'cost'))
        petrol_01$per_gallon <- petrol_01$cost / petrol_01$quantity
        petrol_01
      • SAS:
        data petrol_01;
        infile "G:/tpc247/petrol.txt";
        input date_of_sale$ 5-13 pump_number$ 16-17 quantity 20-25 cost 28-32;
        per_gallon = cost / quantity;
        proc print data=petrol_01;
        title 'Unleaded gasoline purchase history for 1 year, San Leandro, California Costco';
        run;
  • To read data from computer memory in R and SAS:
    • R:
      1. copy and paste this into R, but don't actually run the incantation yet:
        petrol_01 = read.table("clipboard", col.names=c('date', 'pump', 'quantity', 'cost'))
      2. copy your data set, then run the previous incantation

      3. run the rest as you normally would:
        petrol_01$price_per_gallon <- petrol_01$cost / petrol_01$quantity
        petrol_01
    • SAS:
      data petrol_01;
      input date_of_sale$ 5-13 pump_number$ 15-16 quantity 18-23 cost 25-29;
      per_gallon = cost / quantity;
      datalines;
      18AUG2009 6 12.815 37.66
      14JUL2009 12 4.340 11.8
      28MAY2009 6 9.532 24.39
      22APR2009 4 7.348 16.01
      25MAR2009 2 5.509 11.12
      15MAR2009 7 4.230 8.62
      04MAR2009 3 11.989 25.16
      21FEB2009 7 13.298 27.91
      29JAN2009 15 13.989 27.68
      03JAN2009 6 12.620 22.70
      29NOV2008 16 11.239 20.78
      25SEP2008 8 13.929 51.80
      proc print data=petrol_01;
      title 'Unleaded gasoline purchase history for 1 year, Costco in San Leandro, California';
      run;
Coming back to the omitted zero ('0') on the second line in our last figure, 11.8, you might find it amusing how finicky R and SAS are about what they eat. Putting this tutorial together gave me the opportunity to learn some valuable things about the two tools. Just like a toddler can be very picky about the food she feels like taking in her, feeding data to R and SAS and ensuring they digest the data correctly may require some forethought and planning. When importing the dataset into both tools from a file, I noticed that in:
  • R, if I didn't include in my incantation:
    header = FALSE
    I would find the first record in my dataset on file would be missing from my dataset in R
  • SAS, omitting the zero ('0') when I typed the following into my dataset, for July 14, 2009:
    14JUL2009 12  4.340 11.8
    did not pose a problem, as long as I ran a previous incarnation of my SAS script:
    data petrol_01;
    infile "G:/tpc247/petrol.txt";
    input date_of_sale$ pump_number$ quantity cost;
    per_gallon = cost / quantity;
    proc print data=petrol_01;
    run;
    However, I didn't like the resulting output in SAS. I have developed a preference for a specific way of representing dates that is 9 characters long and in a format that, to my eyes, is more easy to read. However, when I ran the aforementioned script on my data set, my dates were truncated:
    SAS fill gas tank dataset
    It seemed that SAS preferred data in columns to be 8 characters or less, or else it would truncate any value greater than 8 characters. So even though running my SAS script resulted in SAS correctly reading in my data, and there was no problem with my omitting the zero ('0'), I decided to modify the incantations in my script and specify the columns so that the dates in my desired format would not be cut off. When I did this, I noticed that data in SAS was different from the data on file:
    SAS fill gas tank dataset
    As you can see, the information from the fill_the_gas_tank event for 28MAY2009 has disappeared, and the line in my dataset on file:
    14JUL2009 12  4.340 11.8
    has been replaced in SAS with
    14JUL2009 12  4.340 2.00 0.46083
    I imagine SAS would read 11.8 and then be confused because there were no more numbers and I had told it to expect one more, but I can't explain how SAS computed a cost of 2.00. However, I can explain that the price_per_gallon of around 46 cents is simply derived from dividing 2.00 dollars by 4.34 gallons. The fact that the record for May 28, 2009 is missing leads me to conclude that when reading data from file, and your SAS statement specifies columns, SAS seems to expect values for the entire range of columns you specify. I've confirmed this phenomenon, of a missing record when you specify in your SAS statement the columns where values can be found, manifests itself in SAS only when reading data from file, and not from the copy and paste of data.
Other separators and delimiters

If you have commas separating your data:
    18AUG2009,  6, 12.815, 37.66
14JUL2009, 12, 4.340, 11.8
28MAY2009, 6, 9.532, 24.39
22APR2009, 4, 7.348, 16.01
25MAR2009, 2, 5.509, 11.12
15MAR2009, 7, 4.230, 8.62
04MAR2009, 3, 11.989, 25.16
21FEB2009, 7, 13.298, 27.91
29JAN2009, 15, 13.989, 27.68
03JAN2009, 6, 12.620, 22.70
29NOV2008, 16, 11.239, 20.78
25SEP2008, 8, 13.929, 51.80
In:When importing data into R or SAS, you need to look at your dataset, and tell R or SAS exactly what to expect, or your statistical data analysis software may complain.

Reference: http://www.stat.psu.edu/online/program/stat481/01importingI/02importingI_styles.html

Thursday, September 10, 2009

how to install a seat leash to prevent theft of saddle & seat post

Protect your bike from those who may see an opportunity to abscond with the valuable, quick-released perch for your peachy derriere.
IMG_0621IMG_0629
a tempting target for a would-be thiefFoiled again! Thanks seat leash

IMG_0602
Were anyone to happen upon this scene, look around and see no one watching, the thought might cross your mind to simply loosen the quick release and walk off with someone else's property like it was yours. The Great Recession created lean and mean times, changing the way Americans spend. With such general apprehension and fear, you can find some amazing bargains in the bicycle market right now. I decided to overcome my reluctance to spend and make the big purchase that, as an avid bicyclist, you might be saving for as well. My new second-hand bicycle is a lightly used 1997 Marin Team Titanium that has a quick release binder bolt for adjusting the height of the seat post.

Let's start by getting our vocabulary straight (thanks to Sheldon Brown for helping me put names to bike parts):
  • saddle (also called bicycle seat)
  • saddle clamp (also called seat sandwich)
  • seat leash (also seat security cable)
  • seatpost or seat post (also called seat mast, seat pillar, or seat pin)
  • stolen (also pilfered, nicked, or made off with)
  • Y hex wrench (also 3 way hex wrench. This is a tool, commonly seen in bike repair shops, that has the 3 wrench sizes to fit the socket heads on most modern bicycles. 'Hex wrench' can be used interchangeably with Allen wrench or L wrench)
Reference:
http://www.sheldonbrown.com/gloss_sa-o.html
http://en.wikipedia.org/wiki/Allen_wrench

To prevent your seatpost and saddle from being stolen, you will need:
  1. seat leash
  2. Y hex wrench
I tried numerous times to figure out a way to use a seat leash to secure my bicycle seat and seat-post, but the closest I got was a half-baked solution where I added the end-loop as an ingredient into the seat clamp mechanism, so that the clamp was gripping a combination of saddle rail and seat leash loop. This made for not the best grip on the saddle rails, and, while you were riding, the bicycle seat was prone to moving horizontally back and forth, a rather unpleasant event for any rider. The light bulb flashed atop my head last Sunday, September 6, at around 11:25am, when I stepped into the Missing Link repair shop and spoke with Andy Renteria, who told me it's possible to secure the saddle and seatpost to the bike with a security cable. He used his forefinger and thumb as an analog for the end-point loop of the seat security cable, and wrapped it around the saddle clamp, between the seatpost and the saddle rail. The breakthrough for me on how to secure your bike seat was using the saddle clamp itself as the focal point on which to anchor the endpoint loop:
IMG_0603
Thanks Andy, at Missing Link repair shop

IMG_0666
The seat security cable has end loop which uses the saddle clamp (I call it a seat sandwich) as a focal point. Also in the picture is my beloved Planet Bike Superflash Stealth Tail Rear Light

IMG_0617

IMG_9880_rotated right

IMG_0612

From start to finish:
  1. use the Y hex wrench, or any appropriate Allen or 'L' wrench, to remove the saddle
  2. insert one loop through the other and wrap your seat security cable around the seat stay, or any focal point that has stops and forms a closed area. Take care when wrapping your security cable around the seat stay that you avoid the part of the frame closest to the tire
  3. with the remainder of the bike security cable in your hands, visualize the saddle clamp itself as the focal point on which to anchor the endpoint loop, and affix said loop on the clamp
  4. now install (or rather, reinstall) the saddle into the seat clamp mechanism, making sure the seat leash end-point loop is between, and stopped by, the seat rail and the seat post.

Monday, August 24, 2009

how to use Google's mail server to send email

Just a little over 2 years ago I enrolled in a 3 month course from Wesley Chun in Intermediate Python, held in Los Altos Hills on the main campus of Foothill College. I found Wesley's lesson plan to be very challenging, but in my journey as a computer programmer since, one of the nuggets of wisdom I come back to is his lesson on writing internet clients. One small task he prompted us with was a valuable exercise on how to write clients that use the servers run by free email providers (yahoo, aol, hotmail, gmail). First, a little history on the instruction leading up to the in-class assignment... Why, I remember like it was yesterday (swirling, squiggly lines as harp strings are plucked & played by unseen angels should now be occupying your visual and aural landscape):

Internet Client programming
All internet clients are built on top of TCP

We talked about four internet clients: ftp, nntp, pop3, smtp
After covering ftp and nntp, Wesley began with an overview of email, how electronic mail as a system is complex and to operate it requires lots of working pieces:
  • Message Transport Agent
    • responsible for moving email, routing, queueing, sending of email.
    • sendmail, postfix, qmail, exim (unix)
    • exchange (windows)
  • Message Transport System
    • protocol used by MTAs to transfer email host-to-host
    • Simple Mail Transfer Protocol
  • Message User Agent
    • protocol used to get email from servers client-to-host
    • post office protocols
    • internet message access protocols
At one time, every desk with a workstation had an email server, but this framework was not scalable. Wesley talked about Python's poplib, and about the SMTP interface in smtplib:
  1. connect
  2. login
  3. send email
  4. quit
then he challenged us to write our own POP and SMTP clients.

As we go to press, the code below, tailored specifically to work with Google's SMTP server, was tested to work on Windows 2000 & Vista, and Debian Linux 5.0 (Lenny):
def use_gmail_smtp(te, tffn, ttfs, subject, msg_body):
from smtplib import SMTP
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart
SMTP_server = 'smtp.gmail.com'
username = 'your gmail handle'
passwd = 'your gmail password'
msg = MIMEMultipart()
msg['From'] = tffn
msg['To'] = ttfs
msg['Subject'] = subject
msg.attach(MIMEText(msg_body))
server = SMTP(SMTP_server, 587)
server.ehlo() # see note below for Python 2.5 and 2.6 users
ssl_connection_errors = server.starttls()
ehlo_connection_errors = server.ehlo()
server.login(username, passwd)
server.sendmail('tpc247', (te, ), msg.as_string())
server.close()
A primer for the acronyms in the use_gmail_smtp() argument list:
  1. te is the target_email, the email address where you want the message to arrive
  2. tffn is the_from_field_name, what you want the user to see in the From: field's name portion. To tffn, Gmail will append <your_gmail_handle@gmail.com>
  3. ttfs is the_to_field_string, what you want the user to see in the To: field, usually in the format:
    "Your Name <yourname@company.com>"
A previous incarnation of the code behaved correctly on Python 2.5, but strangely enough, not on Python 2.6, because it called:
...
server.helo()
ssl_connection_errors = server.starttls()
...
resulting in the error:
Traceback (most recent call last):
...
File "", line 11, in use_gmail_smtp
ssl_connection_errors = send_server.starttls()
File "C:\Python26\lib\smtplib.py", line 611, in starttls
...
SMTPException: STARTTLS extension not supported by server.
It's a mystery to me why this error is only on the aforementioned version of Python, but switching the call out was the answer.

I tested my script on 3 different operating systems, each running at least two different versions of Python:
  • Windows
    • 2000: Python 2.6.1, 2.6.2
    • Vista: Python 2.5.4, 2.6.1, 2.6.2
  • Debian Linux 5.0 Lenny: Python 2.5.2, 2.6.1, 2.6.2
Other notes: when installing Python 2.6.1 on Windows Vista, for the first time ever I saw:
Please wait while the installer finishes
determining your disk space requirements
and then the installation would stall and never complete. The workaround is to open a command prompt, and type:
msiexec.exe -package <mypackage.msi> –qr
Reference: http://bloggingabout.net/blogs/jpsmit/archive/2009/08/28/please-wait-while-the-installer-finishes-determining-your-disk-space-requirements-message-drives-me-nuts.aspx

For you who would like to use gmail to send emails that look like they come from your workplace, you can now do so without the "on behalf of" that make you look less than authentic.

Reference: http://gadgetwise.blogs.nytimes.com/2009/07/31/gmail-drops-the-dreaded-on-behalf-of-lingo/

Thursday, August 20, 2009

Spanish Lesson 1, or Leccion de EspaƱol Uno

Thanks to Tim Goodman, two of my favorite television shows are Breaking Bad, and Dexter. Both take place in cities with a relatively large percentage of native Spanish speakers: Albuquerque, New Mexico and Miami, Florida. As someone who has made a living with associates who grew up speaking a different language, knowing the native tongue of your coworkers can serve as a social lubricant and engender a degree of respect and consideration from your bilingual colleagues when it comes time for a promotion, or, who to invite to that party. I was fortunate to walk into my first Spanish class at a young age, in my preteen years, and with the teacher talking very fast in her foreign language (then immediately in English to translate). From that point forth it was almost a settled matter: two years of Spanish in high school, the community college summer course in conversational Spanish, and two summer trips in Mexico to help erect a church in a small village near the border, were foundational events that made me want to build on that knowledge and spend time figuring out and understanding what exactly people were saying (sometimes about me).

For your benefit and mine, I have transcribed and translated two pieces of content where the characters are talking rapidly in a foreign language:

In this scene, Hank has just been promoted to a Drug Enforcement Administration tri-state task force based in Texas near the Mexican border. The three speaking roles are, in order of speech, Dean Norris as Hank, Todd Terry as the SAC (Special Agent in Charge), and J.D. Garfield as Vanco:

voy atravesar sobre esos bastardos como caca pasando pato, fijate (or fija te).
I'm going to run through those bastards like feces through a duck, you watch.

The two leads in this scene are Jimmy Smits as Miguel Prado (seated) and Michael C. Hall as Dexter Morgan. The shopkeeper Francisco is played by Rudy Quintanilla.

Olvida te, que ese pide lo de siempre
Forget it, that one always orders the same thing.

One might substitute "that one" with "he" but doing that wouldn't tell you the whole story. In context, the shopkeeper understands that Miguel is talking about Dexter, but the shopkeeper also would have known that in Spanish, he is el, but you use ese, meaning that one, when you point to someone, or indicate a person, you don't particularly care for.

Thanks to the lovely and pregnant custodian Sandra Barron, and to mi bibliotecaria preferida Patricia Medina, for the respective transcription and translation. I should also mention David Montgomery for the heads up about Scott Aaronson and the following piece of wisdom:
Why do native speakers of the language you’re studying talk too fast for you to understand them? Because otherwise, they could talk faster and still understand each other.
Reference: http://scottaaronson.com/blog/?p=418

Saturday, August 15, 2009

Isabella at Disneyland, post 9/11

On July 21 and 22, my sister and brother-in-law took a trip to celebrate my beautiful niece turning the terrible 2. At the Magic Kingdom, the little princess explored a potential career as a freedom fighter in the war on terror.

21JUL2009TUE Disneyland
Marine Corps sniper (223rd Battalion, Mickey Mouse company) Monica Wickman-Mroch spots a possible jihadist and instructs Isabella, private-in-training, on the finer points of target shooting:
  1. Breathe in
  2. Breathe out
  3. Aim
  4. Squeeze
22JUL2009WED Dumpling House in Artesia, 1 of 4
The next day, at Dumpling House in Artesia, Monica Wickman-Mroch mulls a run for her assault rifle (not pictured) as my niece, in her dress blues, poses with my sister.

22JUL2009WED Dumpling House in Artesia, 2 of 4
Isabella discovers an affinity for this thing called 'cake'. Seconds before, she performed a visual sweep of the table for any sugar packets, her favorite IED (improvised entertainment device).

22JUL2009WED Dumpling House in Artesia, 3 of 4
Light, fluffy & sweet (don't think Isabella wouldn't hesitate taking your eye out with that fork!), cake is a refreshing change from the relentless battlefield stressors of people in costume, clowns, and tea cup rides.

22JUL2009WED Dumpling House in Artesia, 4 of 4
The life of a patriot can make a freedom fighter hungry for food and company, as evidenced in this photo, seated with (left to right) Monica Wickman-Mroch, brother-in-law Brian Moffat, my dad, step-mom & half-sister, and Walter Mroch.

Saturday, August 8, 2009

how to host and serve your audio files on Youtube

I recently created this video:


Reference: http://tpc247.blogspot.com/2009/07/while-on-my-bike-i-recently-hit-car.html

It's not really a video per se, more of a slide-show with narration. As we go to press, Youtube does not allow uploading of audio files, even if your song, radio program, or interview recording is in mp3, wma or wav file format. If you have aural content you'd like to share with members of the general public, and you'd like to use Youtube, you might as well have hit a dead end. However, there is a way around the restriction so that one of the most popular video sharing services can host and serve your file:
create a video with your audio file content as the soundtrack.
It's easier than it sounds. You'll need uMusic (free open-source software):
uMusic 0.3

If you have a set of photographs or images, and an audio file, you have all you need for uMusic to create a Windows Media Video (wmv) file which you upload to Youtube. However, to prepare your images for public consumption, you may want to give proper attribution to the owners of the photos, or enhance your brand by imprinting a visible watermark that lets users know about you. Also, your audio file may contain commercials, announcements, or something unrelated to what your audience may want to hear, so you'd like to edit your content to remove unwanted blocks of time and extract only what you desire. In either case, you'll need the following free tools, respectively:How to insert text into an image in Irfanview

First open the image in Irfanview
  1. Select an area, an outline rectangle, wherein your text will sit
  2. Select 'Edit'/'Insert text into selection'
  3. Type in your text
  4. 'Choose Font' and determine the proper font face, size and colorIrfanview_Choose Font
The negative about using this method is Irfanview doesn't give you a way to undo the text you insert into the outline rectangle. If you don't like the result, you have to start over at step 1.

If you're new to Audacity, we showed earlier how to use Audacity to edit an audio file

Reference: http://www.pcworld.com/article/136089/top_10_video_sharing_sites.html