The READIN Family Album
Me and Sylvia at the Memorial (April 2009)

READIN

Jeremy's journal

The very idea of the (definitive) translation is misguided, Borges tells us; there are only drafts, approximations.

Andrew Hurley


(This is a subset of my posts)
Front page
Most recent posts about Programming
More posts about Projects

Archives index
Subscribe to RSS

This page renders best in Firefox (or Safari, or Chrome)

Tuesday, April 29th, 2003

🦋 Motivations

So why did I create this journal? The reasons are severalfold. I've been pretty fascinated by the blogging phenomenon since last summer, when I discovered a couple of the sites I've been reading regularly since -- Calpundit, Talking Points Memo, and Body and Soul are perhaps the "big three" for me -- and have been wondering if I could sustain such a steady level of posting and keep it interesting, and how it would sound if I did.

I started my first "web log" before I knew that term, back in 1999 with the READIN book diary; but page generation was manual, not automated, and maintaining the site was a hassle, and I never really got far with it. Although, take a look at the page for Faulkner's The Hamlet to get an idea of where I wanted to go with it.

Once I found out about ASP it seemed like the perfect fit -- I just had to learn how to code automatically generated journal pages and good things would come of it. Two things I wanted to learn to do formatting-wise; expressing dates and times in human terms, and displaying links in a hierarchical format. All the m/d/yyyy dates and hh:mm:ss times you see on web pages don't do it for me. They are over-determined and difficult to read. I wanted to express recent dates as "Yesterday", "Last Sunday", and posting times as just "morning", "evening", etc. I think I have come up with a pretty coherent way of doing this! And the hierarchical links, well, take a look at the left hand side of this page, I think they are good.

Update: Thinking about the two formatting goals above, I realize they are both concerned with limiting the amount of information presented in order to maximize the amound of information communicated. Funny... And the archiving system I have vaguely in mind could be thought of along the same lines too.

posted morning of April 29th, 2003: Respond
➳ More posts about The site

🦋 Useless Information

With regards to my previous post, I want to flesh out the idea of limiting information content in order to increase bandwidth. Actually -- well I guess its accurate to say "I want to flesh out" this concept -- but not sure it is currently within my ability to do so. This must be an existing meme though -- if you have any recommendations for reading on this subject, please contact me.

posted afternoon of April 29th, 2003: Respond
➳ More posts about Programming Projects

Monday, December 15th, 2003

🦋 Links that know when they are followed

It occurs to me that it might be nice to have links (to outside web sites) that knew when a reader clicked on them, in order to update statistics -- my idea is to sort my blogroll by how frequently each of the links is used. Here is an idea for how to do it: Currently the link is <a href="http://someurl">Link Text</a> -- but if the link were <a href="http://www.readin.com/blog/blog.asp?redirect='someurl'">Link Text</a>, then I could update my statistics and redirect. This might confuse some browsers' site history, causing the back button not to work properly; I'm pretty sure Explorer and Mozilla know what to do when confronted with such a situation but am not sure about earlier versions of Netscape. And I would want to have some Java code for mouseover, so that the browser's status bar would just display someurl when you hovered over the link.

Update: Weird, now (Tuesday) I see someone has browsed to my blog following a link of the type I am describing: my referrals log shows a visit from http://www.popdex.com/redir/?u=http://wampum.wabanaki.net/archives/000634.html. (The "u" redirect URL is the address of the Koufax Awards thread on Wampum.) Apparently someone followed a self-conscious link to the Koufax Awards, then followed the link on that page to my blog. And for some reason their browser remembered the self-conscious link as the referrer instead of the redirect.

posted afternoon of December 15th, 2003: Respond
➳ More posts about Projects

Thursday, June 17th, 2004

Brad DeLong pointed me to a very nice site: Joel on Software is the musings of Joel Spolsky, founder of Fog Creek Software and a very insightful guy.

posted afternoon of June 17th, 2004: Respond

Thursday, February 17th, 2005

🦋 User Interface feature

When you have a list box that gets items added to it on a continuing basis over the course of a program, it is nice for the list box to scroll downwards as items are added, so the most recent one is always visible. Except when the user is involved in reading some older items -- then this behavior is very annoying. Here is a solution, as implemented in an MFC application -- pretty easy to translate to C/C++* -- other languages, you're on your own:

int GetVisibleCount(CListBox &lb)
{
    CRect rct;
    lb.GetWindowRect(&rct);
    int iHgt = lb.GetItemHeight(0);
    return (rct.bottom - rct.top) / iHgt;
}

    // handler for a custom "Add Item" message
LRESULT CMyDlg::OnAddItem(WPARAM wp, LPARAM lp)
{
    const char *msg   = (const char *) lp;

    int iTop = m_lbRealtimeStatus.GetTopIndex();

    m_lbStatus.AddString(msg);
        // "static" because I am never resizing the 
        // lb -- if you are you will need to calc 
        // this every time.
    static visibleCount = GetVisibleCount(m_lbStatus);
		
    if (iTop == m_lbStatus.GetCount() - 1 - visibleCount)
        m_lbStatus.SetTopIndex(iTop + 1);
    return 0L;
}

So what I am doing is, every time I add an item, I check what the current topmost visible index of the list box is -- if it is not equal to the number of items in the list box less the number of visible items, then I do not scroll. (Note that this calculation doesn't work when there are fewer items in the list box than the max number that will fit on the screen; but that does not matter because there is no need to scroll anyways in that situation.)


* That is to say, C or C++ where you are not using MFC classes.

posted afternoon of February 17th, 2005: Respond

Friday, January 13th, 2006

🦋 Sum of 2 different squares, 3 different ways

Over at Unfogged, Frederick suggests that 325 is the smallest number which can be expressed as a sum of two perfect squares three different ways. I just wrote a program to check this which confirms Frederick's suspicion; here it is if you want to check my logic.

 #include 
 
 int perfect[] = {
     1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 
     11 * 11, 12 * 12, 13 * 13,
     14 * 14, 15 * 15, 16 * 16, 17 * 17, 
     18 * 18, 19 * 19, 20 * 20
     };
 
 bool IsSumOfSq(int s, int &a, int &b, int x1, int x2)
 {
     for (int i = a + 1; i < 20; ++i)
     {
         if (s < perfect[i])
             return false;
         int diff = s - perfect[i];
         for (int j = 0; j < 20; ++j)
             if (j == x1 || j == x2)
                 continue;
             else if (perfect[j] == diff)
             {
                 a = i;
                 b = j;
                 return true;
             }
     }
 }
 
 int main()
 {
     int i;
     for (i = 0; i < 400; ++i)
     {
         int a = -1, b;
         if (IsSumOfSq(i, a, b, -1, -1))
         {
             int c = a, d;
             if (IsSumOfSq(i, c, d, a, -1))
             {
                 int e = c, f;
                 if (IsSumOfSq(i, e, f, a, c))
                 {
                     printf("%d = %d^2 + %d^2\n"
                           "    = %d^2 + %d^2\n"
                           "    = %d^2 + %d^2", 
                         i, a + 1, b + 1, c + 1, 
                         d + 1, e + 1, f + 1);
                     break;
                 }
             }
         }
     }
     return 0;
 }
 

Output:

325 = 1^2 + 18^2
    = 6^2 + 17^2
    = 10^2 + 15^2

posted evening of January 13th, 2006: Respond

Sunday, March 11th, 2007

🦋 Interval

Here is a bash script to determine the interval between two date/times. Parameters are two dates, specified using any format the date utility can recognize; if the second parameter is omitted, "now" is assumed. Output is the number of seconds between the two, followed by "d h:m:s" format.

 #!/bin/bash

if [ $# -eq 0 ]
then
echo Usage: `basename $0` \ \[\\ default \"now\"\] >&2
exit -1
fi

start=`date +%s -d "$1"`
if [ $# -eq 1 ]
then
fin=`date +%s`
else
fin=`date +%s -d "$2"`
fi

res=`expr $fin - $start`
if [ $res -lt 0 ]
then
res=`expr 0 - $res`
fi

echo $res sec
d=`expr $res / 86400`
t=`expr $res % 86400`
h=`expr $t / 3600`
ms=`expr $t % 3600`
m=`expr $ms / 60`
s=`expr $ms % 60`
if [ $d -gt 0 ]
then
echo -n $d day
if [ $d -gt 1 ]
then
echo -n s
fi
echo -n \
fi
if [ $t -gt 0 ]
then
echo -n $h\:
if [ $m -lt 10 ]
then
echo -n 0
fi
echo -n $m
if [ $s -gt 0 ]
then
echo -n \:
if [ $s -lt 10 ]
then
echo -n 0
fi
echo -n $s
fi
fi
echo

posted evening of March 11th, 2007: Respond

Monday, October 8th, 2007

🦋 On reinventing the wheel

When I was new to programming, in 1994 or '5 -- when OLE was a pretty freshly minted technology -- one of the projects I was working on was a way to abstract the functionality of some of my company's libraries into a common interface so that a program could load any of the libraries dynamically at runtime, based on a string key. I came up with the stunning realization that the interface could be expressed as a pure virtual C++ base class. All the libraries had to do was to export a function called "Create_x" which would instantiate an object whose class inherited interface x.

This seemed to me like an awesome bit of innovation. By funny coincidence, another project I was working on around the same time was converting some of the company's VBX controls to OCX. (I don't think the term "ActiveX" had even been coined yet, but regardless we were not using it.) I wasn't reading the documentation of OLE very closely, relying on Microsoft's compiler to do most of the work for me; so it wasn't until a month or so later that I realized I had just reinvented a subset of OLE, and that I could have used OLE's framework to give my design a little more robustness. But whatever, the feeling that I was doing something new and inventive was payoff enough.

So why this now? Well, I've been doing some pretty intensive design work in coming up with the database that supports this blog ("READIN 2.0", I am calling it in my head), and I have come up with a pretty cool idea. It seems innovative to me because it is something I've never heard of anyone doing; but I am not at all schooled in database design. I will write it up later on or tomorrow, and hopefully somebody will write back to me and let me know who invented it and where I can find out more.

posted evening of October 8th, 2007: Respond

🦋 Programming head

Is a head I like to be in. For like a week now I've been thinking non-stop about the design of the site, how I can put features in and have the code look elegant and run quickly, what features belong in a coherent model. It gives me a real feeling of focus, like I have when I'm reading a book that I'm really absorbed in. It can be annoying not to be able to focus on other stuff, but oh well, it's pretty much worth it.

posted evening of October 8th, 2007: Respond

🦋 Categories

Like I said below, I don't have much experience with database design. I don't really have any clue how to write a design document. But I want to describe the design I've come up with and see if I can make it sound as good as it appears to me to be.

The thinking behind this is as follows: I have a lot of text records ("posts") which I want to classify by subject. I've done this, just like every other blog around, by using keywords -- if I tag a post with "food" say, or "singing", then it will show up when somebody looks at the site filtering for that subject. This is implemented with a simple search through the list of keywords on each post; not particularly fast but that's not a major problem in the context of my low-traffic site.

But when I was putting the new software together, I had the idea that it would be great if, when somebody looked at the blog filtering for "food", they would see a little sidebar explaining what I write about when I write about food, and maybe some links to food sites I like etc. And more to the point, when somebody filters for "book:namered" (which is how I've been tagging my reading posts, "book:" and then a short identifier for the title), they would see up top that the posts were about My Name is Red by Orhan Pamuk, links to some outside reviews, links to Amazon and Abebooks, maybe a list of other of Pamuk's books that I have written about. So that is the problem I am trying to solve; and I think my solution is a pretty good one.

First, simple keywords, like "food" and "singing". This is pretty easy; I have a table keyword with columns tag and description -- the description is what will be displayed in the sidebar when somebody filters by the tag. And I have a table (which I decided to name categories, for reasons that will soon become apparent) with two columns, postid and keyword -- I can join this table with posts when I want to do a filtering operation.

Now what about the complex keywords like "book:namered", which include a class and an instance? Well check it out: every time I add a keyword which has a new class, I can just add a column to the categories table with the class name as the column name. And add a table with that name, which looks the same as the keyword table. And think of simple keywords as a special case of complex keywords, as if they had "keyword:" in front of them. So if somebody requests a filter for "book:namered", I can query from "posts JOIN categories ON posts.id = categories.postid JOIN book ON categories.book = book.tag" where book.tag = "namered". This will work for movies, projects, whatever. But the really cool thing is, I can add whatever columns I want to the book table and write a custom script to display the data associated with the tag "namered" in my sidebar.

Consider these three requests:

  • SELECT posts.* FROM posts JOIN categories ON posts.id = categories.postid WHERE categories.book = 'namered';
    (This query would be represented by the keyword "book:namered".)
  • SELECT DISTINCT posts.* FROM posts JOIN categories ON posts.id = categories.postid JOIN book ON categories.book = book.tag;
    (This query would be represented by the keyword "book:".)
  • SELECT posts.* FROM posts JOIN categories ON posts.id = categories.postid JOIN book ON categories.book = book.tag WHERE book.author = 'pamuk';
    (This query would be represented by the keyword "book:author:pamuk".)

The first query will bring back all posts about My Name is Red. The second query will bring back all posts about reading any book. The third query will bring back all posts about reading any book by Orhan Pamuk. And all this is pretty easy to automate! It's all nearly in place!

The next step, which will be a bit of effort to keep it elegant but totally within reach, is to create an administrative page for writing scripts to render an informative sidebar based on the column data contained in, say, the "namered" record in books.

posted evening of October 8th, 2007: Respond
➳ More posts about SQL

More posts about Programming
Archives

Drop me a line! or, sign my Guestbook.
    •
Check out Ellen's writing at Patch.com.

Where to go from here...

Friends and Family
Programming
Texts
Music
Woodworking
Comix
Blogs
South Orange
readincategory