Tech Archives, page 8

All things technology. Very popular here on Justinsomnia.

Burn Rate, a dotcom time capsule

Do you ever find yourself wondering what it would have been like to live through the dotcom craze, circa 1996? More specifically, a New York based publishing-cum-media company with grandiose aspirations? Probably not, but still the fact that an artifact like Burn Rate exists is interesting in and of itself. Burn Rate is the story of a company that I’d never heard of, written by the founder himself, whom I’d never heard of. Which means the book could only end badly. But for that reason alone it was entirely fascinating, watching all the wrong turns and moments of personal hubris lead towards greater and greater humiliations.

Cover of Burn Rate, by Michael Wolff
Burn Rate, by Michael Wolff

Burn Rate was published in 1998, and concerned events that occurred roughly within a three year period starting in 1994. Let’s put this in context. “The first funding for Google as a company was secured in August 1998, in the form of a $100,000 contribution from Andy Bechtolsheim, co-founder of Sun Microsystems, given to a corporation which did not yet exist”. So the book ended with nary a mention of Google—the 800 pound gorilla was not yet a figment in the minds of its eventual founders. And yet all throughout the book I could sense it right around the corner.

It was a fun read because I knew how it was going to turn out. Well, I know how things are now. When the author mused on whether the future would go this way or that, I knew exactly which way it went. When he nailed the future on the head, he sounded completely prescient, but when he was doubtful, he ended up parroting the recycled fears of the traditional media world—that we still hear to this day. Still, I really enjoyed reading one history of what led to where we are now, even though this book mostly encompassed the wrong turns, dead ends, and “corrections”.

In some ways it read like a work of historical fiction. I knew all the major companies at the time, like AOL, Excite, CNet, Yahoo, and Microsoft, and yet the names of all the players seemed imagined. I found myself wondering, what ever happened to Michael Wolff, the author, and his company Wolff New Media? A quick Google search told me that he’s involved in yet another online venture I’d never heard of (Newser) that sounded like wistful throwback to the days of traditional media. And in somewhat sadder news, I found his recent affair and divorce plastered all over Gawker. Telling.

Ubuntu 9.04, first impressions

Ubuntu logoJust upgraded to the latest release of Ubuntu tonight, 9.04 (aka Jaunty Jackalope). Chintzy login screen aside, it looks really good.

Some SQL tricks you may not know

I flipped through the MySQL Cookbook and jotted down anything I didn’t know and thought might be useful. There was a lot of stuff I didn’t know and thought was probably useless, especially if you do most of your data munging in a programming language outside of pure SQL. But there was still some pretty cool stuff in there. Here are five things that stood out to me.

Note: to run the queries below, you’ll need the EMP and DEPT tables for MySQL.

Inline view subqueries

Apparently these came to MySQL in version 4.1 (from the land of Oracle). I’m not quite sure what I’d really use it for, since I rarely alias column names, but it’s neat to know you can substitute a from clause with a whole query. Note the strange requirement that you have to alias the subquery, hence the seemingly out of place “x”:

select * 
from (select sal as salary, comm as commission from emp) x 
where salary < 5000;

CASE expression

How have I not stumbled upon this before? I’ve always just used the if() function. I guess this is SQL-proper way of doing the same. MySQL’s docs on using case are here.

select ename, 
sal, 
case 
when sal <= 2000 then 'underpaid' 
when sal >= 4000 then 'overpaid' 
else 'ok' 
end as status 
from emp;

Create table as select

This looks super super handy. The first query just copies the table’s structure, the second copies structure and data.

create table dept_2 as select * from dept where 1=0;
create table dept_2 as select * from dept;

Deleting duplicate records

Clever way of using a subquery with a group by to delete duplicate records. I like this, but it has the problem of not being immediately transparent about what’s being accomplished.

delete from dupes 
where id not in (select min(id) from dupes group by name)

group_concat()

This MySQL-specific function has to be seen to be believed. It allows you to take your normalized one-to-many relationships and string them back together together in a comma-separated list. MySQL’s docs on using group_concat() are here.

select deptno, 
group_concat(ename order by empno separator ',') as emps 
from emp 
group by deptno;

The EMP and DEPT tables for MySQL

So I’m reading through the introduction of O’Reilly’s SQL Cookbook and I get to this part that says:

The majority of the examples in this book involve the use of two tables, EMP and DEPT. The EMP table is a simple 14-row table with only numeric, string, and date fields. The DEPT table is a simple four-row table with only numeric and string fields. These tables appear in many old database texts, and the many-to-one relationship between departments and employees is well understood.

I love it when I stumble upon historical gems like this. So I went searching for a quick dump of the SQL to create and populate these sample tables, and I couldn’t find any. Well, that’s not entirely true. I did stumble upon a few variations, but it appears that the canonical version comes to us courtesy of Oracle. Of course I was looking for something a little more MySQL-friendly.

So I ran the Oracle SQL through MySQL with a few changes: I changed the HIREDATE datetime column to a date column, and I changed the format of the date in the insert statements from dd-mon-yyyy to yyyy-mm-dd. Then I mysqldump-ed out the SQL to get the version you see below. Just for my own sanity, I also lowercased the table and column names. You should be able to copy and paste it directly into the MySQL command line. Happy SQLing.

DROP TABLE IF EXISTS emp;

CREATE TABLE emp (
  empno decimal(4,0) NOT NULL,
  ename varchar(10) default NULL,
  job varchar(9) default NULL,
  mgr decimal(4,0) default NULL,
  hiredate date default NULL,
  sal decimal(7,2) default NULL,
  comm decimal(7,2) default NULL,
  deptno decimal(2,0) default NULL
);

DROP TABLE IF EXISTS dept;

CREATE TABLE dept (
  deptno decimal(2,0) default NULL,
  dname varchar(14) default NULL,
  loc varchar(13) default NULL
);

INSERT INTO emp VALUES ('7369','SMITH','CLERK','7902','1980-12-17','800.00',NULL,'20');
INSERT INTO emp VALUES ('7499','ALLEN','SALESMAN','7698','1981-02-20','1600.00','300.00','30');
INSERT INTO emp VALUES ('7521','WARD','SALESMAN','7698','1981-02-22','1250.00','500.00','30');
INSERT INTO emp VALUES ('7566','JONES','MANAGER','7839','1981-04-02','2975.00',NULL,'20');
INSERT INTO emp VALUES ('7654','MARTIN','SALESMAN','7698','1981-09-28','1250.00','1400.00','30');
INSERT INTO emp VALUES ('7698','BLAKE','MANAGER','7839','1981-05-01','2850.00',NULL,'30');
INSERT INTO emp VALUES ('7782','CLARK','MANAGER','7839','1981-06-09','2450.00',NULL,'10');
INSERT INTO emp VALUES ('7788','SCOTT','ANALYST','7566','1982-12-09','3000.00',NULL,'20');
INSERT INTO emp VALUES ('7839','KING','PRESIDENT',NULL,'1981-11-17','5000.00',NULL,'10');
INSERT INTO emp VALUES ('7844','TURNER','SALESMAN','7698','1981-09-08','1500.00','0.00','30');
INSERT INTO emp VALUES ('7876','ADAMS','CLERK','7788','1983-01-12','1100.00',NULL,'20');
INSERT INTO emp VALUES ('7900','JAMES','CLERK','7698','1981-12-03','950.00',NULL,'30');
INSERT INTO emp VALUES ('7902','FORD','ANALYST','7566','1981-12-03','3000.00',NULL,'20');
INSERT INTO emp VALUES ('7934','MILLER','CLERK','7782','1982-01-23','1300.00',NULL,'10');

INSERT INTO dept VALUES ('10','ACCOUNTING','NEW YORK');
INSERT INTO dept VALUES ('20','RESEARCH','DALLAS');
INSERT INTO dept VALUES ('30','SALES','CHICAGO');
INSERT INTO dept VALUES ('40','OPERATIONS','BOSTON');

Judging by the data, this has been around since 1982.

How to use the command line

This “howto” is intended for people who may be new to Ubuntu (or Linux in general), or who spend most of their time using the graphical user interface (aka GNOME), but are occasionally confronted by other howtos that assume knowledge of “the terminal”. My hope is to provide a helpful reference (or cheatsheet) for the most common commands you’ll need to navigate using the command line interface.

How to open the terminal

In the top left, go to Applications > Accessories > Terminal:
How to open GNOME Terminal

A window should open that looks like this:
GNOME Terminal

What is a command prompt?

The text displayed in the terminal window before the dollar-sign is called the “command prompt”. In my case it is jwatt@x200:~$ where jwatt is my username, x200 is the name of my computer, and ~ (tilde) is short for my home directory (which happens to be /home/jwatt).

All the commands you type will appear after the dollar sign, and some commands, like those that change directories, actually change the appearance of the command prompt (to help you remember where you are). In the examples below, I’ve copied all the commands I’ve typed, along with their results and the command prompt, for added realism.

After you type a command, hit the Enter key to execute it. If the command outputs any results, they will be printed out, followed by a new command prompt.

Figure out where you are

pwd – present working directory

jwatt@x200:~$ pwd
/home/jwatt
jwatt@x200:~$

List out the files and directories where you are

ls – list

jwatt@x200:~$ ls
Desktop  test
jwatt@x200:~$

Change directories

cd – change directory

Use cd x to bring you into the “x” directory:

jwatt@x200:~$ cd test
jwatt@x200:~/test$ pwd
/home/jwatt/test
jwatt@x200:~/test$

Use cd .. to bring up a directory:

jwatt@x200:~/test$ cd ..
jwatt@x200:~$ pwd
/home/jwatt
jwatt@x200:~$

Use cd alone to bring you back to your home directory:

jwatt@x200:~$ cd test
jwatt@x200:~/test$ cd
jwatt@x200:~$ pwd
/home/jwatt
jwatt@x200:~$

Create a file

touch – touch a file to make it exist

jwatt@x200:~$ cd test
jwatt@x200:~/test$ touch notes.txt
jwatt@x200:~/test$ ls
notes.txt
jwatt@x200:~/test$

Create a directory

mkdir – make directory

jwatt@x200:~/test$ mkdir notes
jwatt@x200:~/test$ ls
notes  notes.txt
jwatt@x200:~/test$

Move or rename a file

mv – move

To move a file, provide the file plus the destination directory:

jwatt@x200:~/test$ mv notes.txt notes
jwatt@x200:~/test$ ls
notes
jwatt@x200:~/test$ cd notes
jwatt@x200:~/test/notes$ ls
notes.txt
jwatt@x200:~/test/notes$

To rename a file, provide the file plus a new filename:

jwatt@x200:~/test/notes$ mv notes.txt notes2.txt 
jwatt@x200:~/test/notes$ ls
notes2.txt
jwatt@x200:~/test/notes$

Copy a file

cp – copy

jwatt@x200:~/test/notes$ cp notes2.txt notes3.txt 
jwatt@x200:~/test/notes$ ls
notes2.txt  notes3.txt
jwatt@x200:~/test/notes$

Remove a file

rm – remove

Be careful, there is no undo!

jwatt@x200:~/test/notes$ rm notes3.txt 
jwatt@x200:~/test/notes$ ls
notes2.txt
jwatt@x200:~/test/notes$

Remove a directory

rmdir – remove directory

Note: the directory must be free of all files before it can be deleted.

jwatt@x200:~/test/notes$ ls
notes2.txt
jwatt@x200:~/test/notes$ rm notes2.txt 
jwatt@x200:~/test/notes$ cd ..
jwatt@x200:~/test$ rmdir notes/
jwatt@x200:~/test$ ls
jwatt@x200:~/test$

Run a command with elevated privileges

sudo – superuser do

Typically this is required when installing software (see below). sudo will prompt you for your password before executing the command that follows, making sure the change is being made by a user with the appropriate privileges, as well as giving you a moment to make sure you really want to run the command.

Install something on Ubuntu

apt-get install – apt package installer

Most other online howtos usually take the form of a long line of apt-get install commands, as this is the quickest way to instruct someone to install several software packages at once. If the site instructing you to install software is a trusted source, you can simply copy the apt-get install command, paste it into the terminal, and hit enter to run.

Because installing software on your computer requires elevated privileges, you’ll need to preface the apt-get install command with sudo.

jwatt@x200:~$ sudo apt-get install sl
[sudo] password for jwatt: 
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
  sl
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 0B/25.3kB of archives.
After this operation, 197kB of additional disk space will be used.
Selecting previously deselected package sl.
(Reading database ... 145527 files and directories currently installed.)
Unpacking sl (from .../archives/sl_3.03-15_i386.deb) ...
Processing triggers for man-db ...
Setting up sl (3.03-15) ...

jwatt@x200:~$