Launch21 Text
Launch21 Rocket Logo

Quick-to-market Web 2.0 Development Consulting

Launch21 is a Seattle-based technology consulting group specializing in quick-to-market development of next-generation Web sites. Our partners have pioneered the development of the web, AJAX, Web 2.0 and WPF technologies and bring a unique depth of experience in these areas. While typical web-development projects take months to get off the ground, our combination of attitude, experience and Web 2.0 code libraries enable us to get your business off the ground in as little as 21 days.

Contact us to discuss your project.

CouponLooker Search Processing

May 10th, 2007

Today we launched yet another update of CouponLooker, this time with a display of popular searches and also recommendations at the end of your search results that suggest additional terms to get better results.

I’d like to go into some interesting details of how the search processing actually works but I’m not going to share the specific details of how we do rankings. It is a pretty well known phenomena that any system you can create that has some benefit to people will get gamed as much as possible by someone out there. Since we provide links and traffic to successful coupon sites, there is some pretty strong motivation (hopefully) for them to want to be the top coupons we feature.

Having said that, sharing general hints about what I consider a “good” coupon and how the actual processing works shouldn’t hurt. Since the goal is to provide end-users the best possible results (good coupons) by reinforcing the creation of good coupon data we just help the system.

First of all, the actual process of interpreting the user’s query and scoring all the possible coupons is pretty much live. There is a small amount of caching of first page results, but we do only limited pre-processing of our data. The thought process here is that CPU resources are relatively cheap in today’s world and by keeping the search ranking engine in-memory and live it makes it much easier for us to iterate on the algorithm. At some point in the future when we are so successful that we have filled a full rack with machines and the algorithm is just being fine-tuned to give great results is fairly well understood, we can move to a more complicated higher performance pre-processing model. For now we are focusing all the sophistication on the search techniques themselves.

First step is to process the search input that the user typed in. Break the query into separate words, deal with punctuation and throw away words that are garbage. For example, searching for the word “coupon” on CouponLooker is not helpful- they are all coupons. So we drop it. “a”, “the”, and other similar words are also thrown-away.

The next step is to scan through all the coupons in our system. Unlike Google that needs to index the whole Internet, CouponLooker works with a relatively finite source of data so (thanks to the amazing advances in CPUs) its feasible to scan through the whole thing. Our search engine generates a score for how well each coupon matches the user’s query (more on the scoring later). Once it scores every coupon, it sorts of the list by score and those represent the results returned to the user.

But first there is one more phase- we scan through the coupons and for each coupon we look for other’s that are basically the same thing. For a given set of related coupons the highest scoring one is displayed to the user and the others are collapsed under it. This is also the stage at which we generate the list of recommended search terms- we analyze the text of all the result coupons and pick out terms that you didn’t search for that are common in their descriptions. This relies on a much longer set of stop-words since there are many many terms that appear frequently that are not going to actually mean anything to differentiate different coupons.

CouponLooker Updates

April 22nd, 2007

Rahul writes about our latest update to CouponLooker. This is our third and its one of the more exciting things to me how quick it is to update and tweak the search algorithm. There are some pretty sophisticated things going on inside the engine but things have been designed with an eye towards flexibility and rapid iteration. I’m sure the equivalent results could be done with an approach that uses half as many CPU cycles, but frankly CPU cycles are relatively cheap now and making rapid improvements are invaluable.

One detail that you won’t see using the service directly is that I’ve put in some A-B logic for our own development purposes. I can put the site into a special mode where whenever it does a search it does it twice using random different permutations of our algorithm. We can then experiment with this in the office or with test subjects and ask people to search for useful things and give the system feedback on which of the result-sets look more useful.

CouponLooker Vertical Search Behind the Scenes

April 19th, 2007

One of the interesting projects I’ve worked on recently is building the CouponLooker vertical search engine for Judy’s Book along with some of their in-house developers and designers. Vertical search is a recently popular category as people have realized that Google, while it does a great job for general content topics, often returns poor results when in various specific categories. Those categories are often marked by either structured data or else a commerce related reason why people have spammed the general search results (or ideally both). My own CalendarData.com site tackles one such vertical search category (public events) and CouponLooker aims at another one that is covered by both of the good criteria.

The scenario for CouponLooker is pretty simple. You are buying your favorite stuff somewhere on the Internet and are checking out when you see a textbox that looks like this-

Apply Coupon Code

Promo code? Coupon code? I dunno, is there a coupon for this vendor? Am I the chump who is paying full price while others are saving? But go search on Google and you will likely get lots of results that try to steer your purchase to other stores, that provide old expired info or just generic results that aren’t very useful at all.

The search site we build has 4 main components-

1) Data acquisition- pulling in coupon data, processing it and storing it.

2) The search engine- picking which coupons are the best matches for a user’s search.

3) The web-site itself

4) The blog widgets that let you host CouponLooker search on your own blog.

I’ll go into more details about the designs of these components in subsequent posts (but I’m not saying I’m going to cover them in any specific order).

Cross domain security

March 4th, 2007
Peyman and I are planning a few posts on common techniques to get around cross-domain security limitations. Cross-domain scripting attacks were something that was first noticed sometime in 1997/1998 as browsers started to support more capabilities. Web-sites were typically doing authentication via cookies and other user state so mechanisms like XmlHttpRequest could be used by one web-app to impersonate the user to other web-services and steal data from them. Unfortunately this same mechanism is also very useful in building complex web-apps, mash-ups, and other such desirable things and the limitation has been a big frustration for a long time- here is a post from 1999 where I discussed some of the issues involved with Dave Winer.


One thing to keep in mind is that cross-domain data access isn’t always bad. Its only bad when the target web-service wasn’t designed with it in mind and can’t tell the difference between the normal user sitting in front of their web-browser at the site, vs. a different web-page invisibly making the same requests. Hopefully soon web-browsers will support the target site explicitly allowing these cross-domain requests. This is a feature that has been supported by Flash for some time I believe but for various reasons has been slow to get into XmlHttpRequest and other mechanisms that are native in the web/Ajax platform.


Over the years several techniques have evolved depending on your goals- these include use of script tags and JSON, various iframe techniques, invisible widgets and more. Keep your eyes open on this space for details of each approach.

Writing controls for WPF/E

February 24th, 2007
One of my old buddies from the Avalon team Nick Kramer has a great post on building controls for WPF/E. This article has a ton of great tips for how to work with the current builds.
For controls he uses an interesting technique of putting the control in the WPF/E markup as a <Canvas> with an onLoaded event on each control that triggers the control creation-

<Canvas Loaded="javascript:MakeButton" Canvas.Top="100" Canvas.Left="20"/>

This brings up another thing that I was working on for the next build of LaunchE. I’m hoping to enable full markup of the controls more like this-
<TextBlock x:Name="ScrollText" Canvas.Top="50" Canvas.Left="20"
  FontFamily="Verdana" FontSize="12">Scroll value:</TextBlock>
<l:Button x:Name="Button1" Left="50" Top="100" Width="100" Height="20"
  Text="A Button" />
<TextBlock x:Name="ScrollText" Canvas.Top="150" Canvas.Left="20"
  FontFamily="Verdana" FontSize="12">More Text</TextBlock>
The idea is that a pre-processor scans through your XAML and interprets the tags in the LaunchE namespace (l: prefix). Those get reparsed an the XAML parser is fed the new tree.

Coming in the next build of LaunchE

February 22nd, 2007

The first build of LaunchE that is online now is pretty basic. We considered waiting to make more progress but it made sense to try to get it out in the public sooner and get feedback as soon as possible. So please, let us know what you think either in the comments here or by email. We also welcome code submissions as long as you are willing to grant us the necessary copyright so that we can continue with our existing license.

Also I thought it would be useful to give everyone a heads up on the next things that are coming in the library. RadioButton and ScrollBar are both pretty much done and after that we will probably start working on some layout concepts like Grid.

One important decision that we are still wrestling with is control composition. Real WPF controls are all pretty much built out of other controls and can have any other controls embedded in them. In that model ScrollBar gets built out of 5+ other controls for the various regions.

So far we are not taking the same approach for LaunchE. My concern is that the quantity of controls was sometimes a perf issue even with compiled C# code, with the JavaScript platform we need to be careful to make sure it runs fast enough. So ScrollBar is itself one control that deals with its own sub-parts. This reduces some degree of flexibility, but I hope to still enable a Button control that has arbitrary other stuff embedded for its content.

DNS Issues

February 21st, 2007

When we switched over to WordPress we switched which server (actually virtual server) that this site is running on. For some reason the DNS for www.launch21.com is being very slow to update to the correct IP address (.233) everywhere so we have been seeing this site bounce between the new one (this) and the old one (with a black background). Sorry about the inconvenience and we hope to have anything straightened up soon.

Introducing LaunchE WPF/E Library

February 20th, 2007

Since Microsoft first introduced WPF/E in December we have been pretty excited to do some cool stuff with it. WPF/E itself is a very basic vector and media rendering tool, so building a framework for controls (and eventually layout) seemed like an obvious project to enable the use of this tool in real-world applications.

Today we are putting online the very first early-preview build of LaunchE, the WPF/E controls library. This version only supports Button and Checkbox, and only very basic support for those, but more controls and capabilities are coming soon.

LaunchE Basics Demo

Some key features-

Uses JavaScript inheritance to build sub-classed controls.

Ability to re-skin a control without inheritance (just replace the template XAML).

Support for adaptive layouts (for example, centering the text in the button control).

Events (just Click for right now).

Please check it out and send us feedback. Feel free to use it in your own projects, but at this point we are still likely to make breaking changes as we flush out its capabilites.

Check out a very simple demo of LaunchE

Download the JavaScript Source code (version 0.001)

WPF/E Photo Gallery Example

February 17th, 2007

Mike Harsh shows Lester Lobo’s WPF/E photo viewer example that uses some nice reflections and some fake-3d. Unfortunately WPF/E only supports skews and rotations so you can’t do real perspective at all. Its possible to do some simple fake-3d that looks real, but the effects in this example just give me a “wrong” feeling. This is one of those cases where a visual designer can really earn their pay, since there are some careful things you can do to make the scene look more right by realizing that the vanishing point is in effect at infinity.

The history of this limitation is a bit interesting. WPF (Avalon) didn’t need the more complex transformations since it supports real 3D. WPF/E in theory is a strict subset of the WPF functionality so they didn’t add support for transformations that WPF itself can’t do. It would be great to see this improved over time so we can really emulate 3D.

 

The pain of updating the web site

February 11th, 2007

All that I can say is that we got off to a good start, getting our first web-site up within a week of getting rolling on Launch21. From there we quickly faltered on the “often” part of the phrase “ship early and often”. I thought its worthwhile to reflect on what happened.

The really positive take on things is that both Peyman and I have been incredibly busy working for clients and haven’t had much time to work on the site. I know it sounds like some form of posing, but if anything the demand for the stuff we do has exceeded my expectations. I’m incredibly grateful for the clients that we have signed up so far and want to focus on keeping them happy, which hasn’t left much time for fixing up this site.

That alone wouldn’t have kept us from some simple improvements, but we decided to make two major improvements both of which put us in that “there is no point doing the small stuff until these others are done” limbo. This is a common situation for software development projects to encounter- sometimes its unavoidable, but often you are better off making the effort to figure out how to break things down into smaller chunks.

The first major improvement is our new design. We have had some help designing a logo and a look for our site that better reflects the type of professional design and web-sites that we like to build. The site isn’t perfect today, but from my point of view its a 1000% improvement and enough in the right direction that it was time to get it online and iterate from here.

The second big change is that the site is now running on WordPress. For years I have done blogs using my own hand-rolled software because it forced me to stay familiar with all the technologies involved in delivering one of these sites at a low level. The down side is that when you do it yourself the publishing mechanisms are never as convenient as nice polished software like WordPress so posting becomes a big pain, leading to fewer posts and lots of missed opportunities at interesting things to say. I’m thick into RSS and all of those other technologies in a dozen ways now anyway, so I don’t need the blog to keep me real with that stuff and its nice to have the convenience. Speaking of which, my next project is to move AlexHopmann.com to WordPress too, which will likely be a bigger undertaking given my existing content there.