Easy Web Design ::
Easy Web Design
We will put your business online and teach you how to succeed. Easily. Click to get a quick
Quote. or HERE to read more.
More info MMK Web Design
Easy Marketing/Hosting ::
Easy Marketing and Hosting Packages
We combine your hosting and marketing costs to make it easy and affordable for you to get listed on the search engines.
Click to get your easy account.
Jump to MMK Host Website
Easy Media Security ::
Jump To MMK Secure Stream Web site
We can effortlessly help you protect your media or secure meetings and conversations online.
Jump To MMK Secure Stream Web site
Instant Assistance<% session("instantasst") = "YES" %>
Name area Pre Number
Your Name 800 555 3358
Internet Presence :: Words that mean much more then 'web site'. A presence on line is about being found. It's about being noticed, and it is about interactivity with your client.


Remembering Lorraine Hunt Lieberson

Boston.com: Obituary: Lorraine Hunt Lieberson; her luminous voice lifted Boston Symphony Orchestra, transported listener. I had the rare privilege of singing in the chorus behind Ms. Hunt Lieberson during the Gurrelieder this spring. She stole the show, quietly stepping on stage during the tenor’s penultimate aria in the first half to announce the downfall of his love and set the stage for the rest of the action.

I got word this weekend that our performance of the Gurrelieder on Friday at Tanglewood will be prefaced by the fourth movement from the Brahms Requiem, “Wie lieblich sind deine Wohnungen” (known in many churches by its English title, “How Lovely Is Thy Dwelling Place”). We rehearsed it last night on stage and chills went up my spine. I can’t think of a more appropriate tribute for an artist who moved so many lives with her voice.


read more:

Beck, Nelly McKay, Doves
Diamond Nights - So Fantastic 12" To quote the Kemado site, "Diamond Nights sound like Thin Lizzy & The Cars just chillin." There's an MP3 on their site.

The Beck "E-Pro" Paza Remix e-card. The bat is my favorite part.

Nelly McKay performs at Dog Show Party 2005 next Tuesday.

The new Doves single, "Black and White Town" from the March 1st release Some Cities[asx][ram]

Silver Jews news via Tim O.
read more:

cingular hit with class action lawsuit
Quite some time ago we had some issues with AT&T Wireless where our coverage on the TDMA network was gradually degrading but they wouldn’t let us cancel our contract without an early termination fee or let us upgrade to the GSM network without having to pay.Thankfully the folks at Get Gephardt took care of us [...]
read more:

How to be a better blogger -- and still keep your day job

NewsI have known David Strom for a dozen years or so. He is one of the best writers out there. Whether it is hardware, software, audio, or how to do things, David digs deep, analyzes what's out there and writes comprehensive stories. His latest is about blogging, and I was happy to provide some input. If you are looking for tips about blogging, David's story is an excellent reference. His cardinal rule is to "tell the truth". He explains why it is important to find your voice and stick to it. Above all, he says, "be professional at all times". Many organizations are not capitalizing on the power of blogging, but it is not too late. David says "Craft your corporate blogging policy now, understand the mechanics and know your tools". As in all of his stories, this one offers really solid advice.

Other stories about blogging at patrickWeb are here.


read more:

Intellectual Property

Cactus

On Monday and Tuesday of this week a number of analysts and consultants gathered with IBM at an intellectual property briefing in Greenwich, Connecticut. Not as glamorous as the meeting in Rome but exceptionally interesting. The term intellectual property reflects the idea that the subject matter is a product of the mind and that legal rights to the "IP" are protected in the same way as any other form of property. IP is a vital issue for many companies but probably no company has as much influence in this area as IBM. IP is a broad and deep subject but one of the key elements is patents.

The United States granted the first patent to Samuel Hopkins of Pittsford, Vermont in 1790. Mr. Hopkin's idea had to do with making potash which in turn was used in making glass and in various industrial processes.Two other major patents granted the same year were related to making candles and milling flour. Earlier this year the United States Patent and Trademark Office (USPTO) announced that for the thirteenth consecutive year, IBM received more patents than any other private sector organization in America. No company, other than IBM, has yet been granted 2,000 patents in any year while IBM exceeded 3,000 four years in a row and last year had 1,100 more than anybody else. IBM has a portfolio of more than 40,000 patents globally and has another 21,000 U.S. patent applications pending. Potentially more significant than IBM's leadership in creating inventions is the fact that it is giving away thousands of patents. See Patent Commons (January 2005).

The industrial age focused on proprietary innovation and patents became the key differentiator for technology companies such as IBM. In the 1970's and 1980's there was a lot of cross-licensing to provide freedom of action; e.g. IBM cross-licensed with many other technology companies so that it could be able to ship it's products without any concerns about patent infringement. Since IBM's inventiveness created a lot more patent licensing income than licensing expense, the IP business became a major source of income -- to the tune of a $1 billion per year and mostly profit. Now that the industrial age has given over to a knowledge economy based on collaborative innovation, IBM has begun to re-evaluate it's IP strategy and begin to leverage IP as a new source of business growth.

Since IBM has a very large group of engineers and scientists who are prolific inventors, the patent portfolio is sure to grow and the income from it will be significant for quite some time. The company has more than 1,000 active licenses whereby companies pay IBM to use it's patents -- that represents about a third of IBM's IP income. Another third comes from joint development; e.g. with Sony, Toshiba, and Samsung where the companies work together on a project and then share the results. A prominent example was the development of the Cell processor which is used in the new Sony PS3 game console. A final third of IBM's IP income is from the assignment of patents for things that IBM invented but does not want to pursue on it's own -- digital cameras, liquid crystal displays, the laser used in eye surgery, setup boxes, and many other things.

Technologists working in healthcare and education cheered the move by IBM to allow them royalty-free access to its patent portfolio for the development and implementation of selected open healthcare and education software standards built around web services, electronic forms and open document formats. If new application software is developed in these key industries, society is better off and IBM will get it's fair share of the hardware, software and services opportunity. Very smart. To leverage internal ideas, IBM has created ThinkPlace -- a next generation suggestion program where employees don't just submit an idea and hope to get an award but where they tee up an idea and enable others to build upon the idea and collaborate to take it to the next level. IBM is also leveraging it's IP by using it to solve problems for it's clients through services engagements. For example, a group of PhD's from IBM Research helped a limousine company optimize the routes of it's cars to minimize wait time and fuel costs

The world of patents has become ever more complex across the spectrum of collaboration and competition as the world has moved from proprietary to open -- as the world has gotten flat. Patents issued have skyrocketed in the past dozen years -- more than 150,000 patents issued in 2000, and so have patent suits. The thousands of suits are taking a huge economic toll and in many cases are stifling innovation. Patent reform has become urgent. IBM is not waiting on the sidelines. It is taking a leadership role and encouraging progressive changes. For example, it has launched initiatives to improve the quality of patents by developing and proposing an index to evaluate if a patent meets the standards of patentability -- in other words, to test if the patent is really legitimate. These efforts are not just for IBM but for the entire economy. Hopefully the politicians, many of whom have links to trial lawyer associations, won't kill the pending patent reform legislation.  

Related links
bullet Other patrickWeb patent related stories

read more:


Comcast To Pay 1-million To Settle Mass. Suit
Comcast, the giant cable company, has agreed to settle a legal action brought by the state of Mas...
[in ContactMusic Ltd
read more:

WCAG 2.0 Scripting group
The WCAG 2.0 Scripting group has opened its channels.The Web Content Accessibility Guidelines Working Group (WCAG WG) is developing best practices for the creation of JavaScript code that can be made compatible with the goals of Web accessibility. The output will be in the form of freely-available script modules to handle the most common use [...]
read more:

Implied tags in the IE HTML parser and how that can be interesting.

I recently made the verbal error of saying that for the new BASE element changes in IE 7 you had to put your tag inside the HEAD element. Well, someone pointed out to me rather quickly that on Firefox you could just have a bare TITLE and BASE followed by some body content and away you go the page would validate and parse properly. Well, we do the same thing in IE, and it is called implied tags in HTML. There are some gotchas though.

First, I'll start with the trick... What in the heck is IE doing?
<HTML id="dumpInternals"><TITLE></TITLE><BASE href="foo"><BUTTON onClick="alert(dumpInternals.outerHTML)">Click Me!</BUTTON></HTML>

That is your boilerplate. When you click on your button there you'll find that IE is actually putting the TITLE/BASE in the implied HEAD of the document and then putting the BUTTON into the implied BODY. Good stuff, and the document is still perfectly valid. Issues can arise when you do this though because you aren't necessarily realizing what elements belong in the HEAD and which belong in the BODY and so you might terminate your HEAD enclosure early and put a bunch of random elements that don't belong in the BODY into the BODY.

This won't look right without your IE 7 Beta 1, since the BASE element is going to wrap a bunch of stuff, but you can get the gist. The below will show you that the second BASE ended up inside of the BODY. That isn't good, we don't look for BASE elements there and it won't get used. (Read my previous post on IE 6 behavior and you'll see that it used to get used because of some container magic, but not anymore, we are compliant).
<HTML id="dumpInternals"><TITLE></TITLE><BASE href="foo"><BUTTON onClick="alert(dumpInternals.outerHTML)">Click Me!</BUTTON><BASE href="foo"></HTML>

The set of implied rules has impacts in other areas as well. You can, for instance, end up using document.writeln to prematurely terminate your HEAD element and move a bunch of stuff out into the BODY. So, if you are doing inline document writes you should probably do them where you want the content to go. Writing the content out in script blocks that appear in the head is the wrong way to go about it. You could hook up to some events or have a container element that you write into, and that is acceptable, but with inline writes you could get unexpected behavior.

Recently I noticed a site that was doing a document.writeln in their HEAD element about half-way through the head content. End result? Well, the content got moved into the BODY element and the object model tree for the page was completely wrong. Good thing they weren't navigating the object model looking for stuff and good thing the extra META/LINK elements weren't being used as well. With a static parse of the page you wouldn't even notice these problems, but when DHTML becomes involved it can change the structure of your document on the fly and rewrite what the object model tree looks like.

I should back this up with some samples. I'll try and get those prepared shortly.

Share this post: Email it!
read more:

New posting on MSDN about script leak patterns and how to fix them for anyone that builds dynamic web apps.

Over here on the IE team we take leaks seriously. Extremely seriously. This is contrary to the popular opinion, but I'll let you make your own informed decisions. My new posting on MSDN is specifically designed to help you identify and fix several patterns of leaks. These range from your basic circular reference to your more complex (and more popular) closure based leak. Hopefully this new material can help you identify and exterminate all of the leaks in your code. If you have questions about the article feel free to post here or over on the IE team blog and I'll try to respond to any non-flaming responses ;-)

MSDN: Leak Patterns in IE

Share this post: Email it!
read more:

Automatic Magazine Layout
You can't always count on having a professional designer around to resize and position your images for you, but you'd rather your page layout didn't look like it was created by orangutans. Harvey Kane builds a script that makes your life easier.
read more:

Messing around with Amazon S3 access on Mac OS X

For whatever reason, Amazon’s S3 has captured my attention since the day it launched.

I want to use S3 for an online backup of my most important files. (I already do nightly local backups of everything, but that’s not enough. I’m paranoid.)

I’m finally close to reaching this goal, but it’s not been terribly easy.

Here’s a brief recount of my trials with S3 so far:

  1. s3DAV. It didn’t work so well on OS X. The developer was really helpful, so we traded a few emails while he attempted to get it working on OS X from across the Atlantic. No luck.

  2. JungleDisk (via Steven Frank). Much, much better. Of course I jumped in head-first and ran my backup script immediately, which attempted to copy 10GB of data to my S3 account. That took all night and then some; I finally had to cancel the operation. But somehow I managed to bork (technically speaking, of course) my S3 bucket so JungleDisk beach-balled every time I tried to connect.

  3. S3 Browser. I found this while looking for a way to get into my account and delete the screwed-up bucket. Too bad there was no way to delete more than one file at a time — I would’ve had to press “Delete” 15,000 times. Not fun.

  4. jSh3ll. Like most things of this nature, I had to turn to the command-line to get anything done. In a rare moment of competency, I downloaded and built jSh3ll (using Ant, no less) on my Power Mac and connected to my S3 account. I deleted the troublesome bucket from the command-line and now I’m back to square one (mostly).

I’m running a much smaller backup to S3 right now. Wish me luck.

(Oh, and have a good weekend! Michelle and I are headed to Green Lake for the holiday. How about you?)


read more:

The Million Dollar Script.
The hottest new idea in internet advertising in years!
read more:

.NET Exception Handling By Edward G. Nilges
This article presents a set of general error handling principles and illustrates them in action with a downloadable VB.NET project, including a demonstration program and a reusable .NET exception handling DLL.
Click here for the full article.
read more:

Behind Closed Doors: Secrets of Great Management By Johanna Rothman and Esther Derby
One of the reasons good management is so hard to learn is that much of management takes place behind closed doors. Weâ??re going to open those doors and allow you to see great management in action.
Click here for the full article.
read more:

Free Photo Gallery Script - PHP
'Gallery' is an open source, free PHP photogallery script that allows you to easily manage photo albums online. Loaded with features like auto thumbnail generation, auto file size reduction, auto image rotation and many more, 'Gallery' is really p...
read more:

AvantMail script version turns freeware
JiRong Zhou announced through his weblog that the script version of Avantmail for Groove is available as freeware. Avantmail is an excellent email client for Groove that is broadly used throughout the Groove community. Zalba is currently working on the...
read more:

AJAX JSP Javascript Struts
Hi all<br><br>I have a question:<br><br>I use a javascript named Ajax.js that had a method called retrieveUrl(action, form). This method call the


read more:

Three More SW Applications

  1. FOAF to hCard via SPARQL "So I used the scutterplan from the FOAFBulletinBoard, going 2 steps, producing 17382 statements, containing I think it was 2035 foaf:Person nodes...To the results I applied sparql2hcard.xsl using xsltproc, script was sparql-hcard.sh (I do hope this was the latest SPARQL XML results format...), producing these hCards." XLST, querying - sounds like descriptors.

  2. Timeline "...a DHTML-based AJAXy widget for visualizing time-based events. It is like Google Maps for time-based information."

  3. iris: open your eyes to the future of the desktop "Iris is a java open source source integrated desktop environment including email, calendar, file browser, web browser, chat, and a data mining toolkit (clustering, indexing, and lots more)." Uses Jena.


read more:

Action Line: Store balks at honoring lowest advertised price
San Jose Mercury News Jul 16 2006 10:27AM GMT
read more:

Dual Action (AM-PM) Tinnitus Relief Formulas Released
Alpha Tinnitus Formulas Inc. release their long awaited new Dual-Action (AM-PM) Tinnitus Release Formula. (PRWEB Jun 30, 2006) Trackback URI: http://www.prweb.com/dingpr.php/UHJvZi1NYWduLVByb2YtQ291cC1JbnNlLVplcm8=
read more:

TurtleDate Announces Dating Site Profile Approval Policy Change
In a recent move, the little dating site www.TurtleDate.com made some big changes in their profile approval policy. TurtleDate has implemented aggressive action to protect the privacy of its members by thwarting contacts via profile approvals from scammers, spoofers and spammers who attempt to use the sites service to proliferate advertising and money phishing schemes. (PRWEB Jul 9, 2006)
read more:

Dr. Mark Sanders and World Renowned BMX Champion John Purse Join Forces to Keep Both the Sport and Athletes Strong
Sports medicine doctor and orthopedic surgeon Dr. Mark Sanders partners with professional BMX athlete to help athletes in extreme and action sports understand the importance of good conditioning -- in both avoiding injury and recovering more quickly when they do occur. (PRWEB Jun 28, 2006) Trackback URI: http://www.prweb.com/zingpr.php/SW5zZS1Mb3ZlLUhvcnItQ291cC1JbnNlLVplcm8=
read more:

Codex Chairman Seeks to Thwart Natural Solutions Foundation Pro Health Codex Initiative
Natural Solutions Foundation must be doing something right because the Chairman of the Codex Alimentarius Commission (CAC or “Codex”) took direct action last week to stop the Foundation’s pro-health initiative next week’s Geneva Codex meeting. (PRWEB Jul 5, 2006) Trackback URI: http://www.prweb.com/zingpr.php/RW1wdC1Db3VwLVNxdWEtUGlnZy1JbnNlLVplcm8=
read more:

Actors Julia Louis-Dreyfus and George Lopez Host New Video to Fight Childhood Obesity Epidemic
Well-known television actor, Julia Louis-Dreyfus (Seinfeld) and actor/comedian George Lopez (The George Lopez Show) have joined forces with Parents' Action for Children to host a new video aimed at helping parents reverse the dangerous rise in childhood obesity. The video is entitled "Food and Fitness Matter: Raising Healthy, Active Kids" and is available at http://www.parentsactionstore.org (PRWEB Jun 28, 2006) Trackback URI: http://www.prweb.com/dingpr.php/U3VtbS1Qcm9mLUZhbHUtQ291cC1JbnNlLVplcm8=
read more:

Intuita Announces New Career Development Tele-Conferences for Managers
Intuita?s Action Learning Conference Series will start in January 2006 via monthly Live Learning Forum bringing North American and international managers together for a 1-year professional development event. [PRWEB Nov 2, 2005]
read more:

Institutional And Individial Investors Continue To Retain Scott + Scott, Llc In Action Against Refco Defendants
Aggressive Litigation Draws Respect As Scott Firm Restrains $111 Million From Former CEO Phillip R. Bennett Now Indicted And Will File Updated Complaint Today. [PRWEB Nov 11, 2005]
read more:

Scott+Scott, LLC To File Lead Plaintiff Motion in Case Against DHB
Shareholders Intend To File Lead Plaintiff Motion On November 8, 2005 In DHB Industries Securities Fraud Action [PRWEB Nov 3, 2005]
read more:

Reynolds Mountain Partners With Homeland Security and WeatherBug.com
Weather Tracking Station On Reynolds Mountain Delivers Live Local Weather Conditions to First Responders, Consumers and EducatorsReliable weather allows for better planning and action to be taken in the event of severe weather. [PRWEB Nov 13, 2005]
read more:

Free Enterprise Action Fund Urges Business Roundtable to Defend Capitalism Against Congressional Overreaching
Mutual fund urges CEO group to defend profits and property rights from Congressional grandstanding. [PRWEB Nov 10, 2005]
read more:

California Investors File Complaints Against Integrated Healthcare Holdings, Inc. and Hope to Build a Class Action Lawsuit
Investors visit LawyersandSettlements.com to submit complaints of securities and stock fraud [PRWEB Nov 10, 2005]
read more:

Free Enterprise Action Fund Urges Insurers to Conduct Independent Analyses of Alleged Link Between Global Warming and Weather-Related Losses
Mutual fund cautions property and casualty insurers not to be fooled by global warming alarmism. [PRWEB Nov 1, 2005]
read more:

SEO Chat Forums - G sees only error message, yahoo and msn not
Date: July 17th, 2006 04:32 AM - phbock - UntitledPost: Thx for your hints.The script is not very well known (ilance v3). I didn't post it as I thought it might not help very much.The...
read more:

Attack of the Mac Python Zombies!
Nice title, huh?

I choose my titles in the same way I choose what to write about. The title's what I typed in to Google when I faced my most recent problem, and I'm writing this post because Google didn't furnish the answer until after I'd already solved the mystery myself.

Okay, so I didn't actually search for 'Attack of the Mac Python Zombies'. The first bit's just a bit of sensationalism to hook those of you who, like me, don't care about (or for) Python and might otherwise miss out.

My problem was the error message 'fork: resource temporarily unavailable'. I'm pretty sure I haven't seen that since university, a decade ago, when someone accidentally or deliberately (always hard to tell) fork-bombed a shared machine. It was a bummer in those days because even if you were the culprit, you couldn't necessarily fix things because your shell didn't necessarily have a 'kill' builtin, and if you tried to fork kill(1), well, 'resource temporarily unavailable'. These days, the shell wars are over, and 'most everybody runs bash(1).

I tell a lie: my problem was that opening a new window in Terminal.app would say 'Completed Command' in the title bar, and produce no output at all in the window. I'd never seen this before, and didn't understand right away what was going on. I tried opening a few more, leaving the existing ones open, because I've had trouble with permissions on pseudo-terminals before, but that didn't help. I also thought trying again might help because every few thousand terminal windows, bash(1) crashes on start-up. (I long thought that was a Mac OS problem, but I've seen it much less frequently on Linux too, so now I'm not sure.) Luckily, I already had a couple of shells, and typing 'ps aux' in one of them showed me the real problem. 'fork: resource temporarily unavailable'.

If I'd known at this point what I knew by the end of my investigations, I might have logged in as my alter-ego, 'Test Monkey', but I didn't realize that the problem wasn't the overall number of processes: it's that Mac OS has a per-user limit. All Unixes I've met do, but I can't remember the last one that didn't have the limit set to 'unlimited' by default. Here's Ubuntu 6.06's default limits, for example:

core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
max nice (-e) 20
file size (blocks, -f) unlimited
pending signals (-i) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) unlimited
max rt priority (-r) unlimited
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) unlimited
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited

And here's Mac OS 10.4.6:

core file size (blocks, -c) 0
data seg size (kbytes, -d) 6144
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 256
pipe size (512 bytes, -p) 1
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 100
virtual memory (kbytes, -v) unlimited

At this point, if you have anything to do with Mac OS machines, it might be worth committing to memory for future use that not only does Mac OS have a low per-user process limit (100 processes/user), it has a low data seg size (6144 KiB), a low number of open file descriptors per process (256), and a small pipe size (512 B). [I'm not sure the 'data seg size' matters in practice because that, as I understand it, is just the limit on the portion of the heap allocated with sbrk(2), and doesn't count heap allocated with mmap(2). Google doesn't seem to know why Apple chose this 6 MiB limit.] Jonathon Arnold points out that Mac OS also has a low default limit on the amount of shared memory (4 MiB); see, for example, here for details.

So: Terminal's broken because we've hit our 100-process limit. I didn't realize this until I'd already killed a few things to give me room to maneuver, sadly. I was now at a point where I could see plainly with ps(1) that my problem was that the system had a couple of hundred zombie processes ('Z' in the 'STAT' column) with the name '(python)'. So something was running python(1) but not waiting for the child. And that something was still running. And, judging by the fact that my girlfriend was close to hitting her 100-process limit, it was something that we both run.

This, I thought, was handy in that it meant I could rule out all the stuff related to software development that I run. As it turned out, that was a completely false conclusion.

I methodically quit all running GUI applications, checking with ps(1) each time to see if the zombies had been reaped. (Kill the process that the kernel thinks should wait, and init(8) realizes no-one's going to wait and waits for the zombies, putting their souls to rest. So if quitting an application had caused my zombies to disappear, I'd know it was that process' fault.) After eliminating all the GUI applications as possibilities, I started killing the likes of AppleSpell and ATSServer. I got right down to having killed everything but loginwindow, connected from the Ubuntu box and killed loginwindow.

Still my zombies remained.

I was a bit confused at this point, but got my girlfriend to log out, just to see that the same was true for her. It was: logged out, she still had nearly 100 '(python)' zombies.

The good news at this point was that there was little left running. I'd eliminated most of the possibilities, and one of the few processes I didn't recognize was '/System/Library/PrivateFrameworks/DedicatedNetworkBuilds.framework/Versions/A/Resources/bfobserver'. I killed that, and all the zombies on the system vanished, and various things that had got stuck for lack of the ability to fork came back to life.

Searching Google for 'bfobserver' (which I had read as 'b-fob-server', but now realize is 'b-f-observer', damn those C programmers!) 'python' and 'zombies' returned one match: a Google groups thread python at login on macintels that was exactly the same problem.

Basically, the new Distributed Builds stuff in Xcode 2.3, without you having activated it in any way or even run Xcode, runs a Python script '/System/Library/PrivateFrameworks/DedicatedNetworkBuilds.framework/Resources/sctwistd' and forgets to wait for it. It seems to do this every time you log in, and that includes fast-user-switching logins. That took us just under 20 days to reach our 100-process limits, so I expect a rash of problems soon for developers who don't reboot unless forced to, but who share a machine. If I'd installed the latest QuickTime update (which probably just gives me more DRM crap I don't want, and for that it wants me to reboot?) I'd have put it off for another 20 days.

I'm annoyed by Terminal.app's poor diagnostics. I'm annoyed by Activity Monitor's failure to indicate any problem (it doesn't show zombies, even when you've got nearly 200 of them). I'm annoyed by DedicatedNetworkBuilds' bug, and I'm extra annoyed that the Xcode installers means I have that running without having opted-in, or without any likelihood that I'll ever be in a position to make use of it. It's probably jolly useful inside Apple, but when am I going to have enough Apple machines to be able to use it? I don't have enough to use distcc(1), which they still recommend for smaller builds. Why do I have to install all the Xcode crap just to get the latest GCC and weird Apple binutils replacements anyway? Why aren't Apple's packages more transparent? 'Click OK to run arbitrary code as root.'

On the bright side, I'm thankful I'm running some variant of Unix. I told my girlfriend this is what's so great about Unix: you can do better than just throw your hands up in despair and reboot/reinstall/get a new computer.

She was so impressed.
read more:

On fights and losing them

Neil lived in a purple palace with a purple castle to sleep in. He raced around his cage at top speed, sending bits of litter out the corners as he peeled out. Neil loved cantaloupe, blueberries, cheerios, broccoli, and peppers. When he ate watermelon the juice ran down the corners of his mouth and stained his white fur red and we called him a vampire piggie. When Neil was a baby he climbed his castle and out of his aquarium and scaled a book case (a height of a foot above the aquarium) we don’t know how he did it. Neil and I used to play a game called “reverse lion tamer” where I would open my mouth and he would insert his entire head. He was not scared of the cat and would blithely ignore the paw fishing around for him until we screamed at Riley. When Neil was excited he would bounce around on your chest like a piece of popcorn popping while chittering. When he was scared he would whistle softly. When I held him in my arms with his head on my chest he would butt his head up under my chin.

When Neil’s eye was bad they said he might not even live and he got his sight back.

When he broke his teeth off he grew them back.

It turns out that Neil probably had a very inner ear infection that gave no symptoms. This ear infection went on so long it seeped into his bones, his nervous system, and his brain. Neil could not fight hard enough to win this battle.

And neither could we.

Neil died today, at 6:30 am at the specialist vet in Houston we took him to. We were supposed to plan a course of action today for the newly developed nervous system problems but it was too late to plan. We had promised him that if he lived until Monday the special vet would make it all better. He lived until Monday but she didn’t make it better.

Neil was supposed to live at least five more years.

I loved him very very much and I miss him very very much.


read more:

10,000 BBC staff to be balloted for strike as pay dispute worsens
THE BBC is facing a series of strikes next month by broadcasting workers and journalists in a bitter pay and pensions dispute after union leaders yesterday decided to ballot on industrial action.
read more:

Reflecting in action: programming other algorithms

As part of the same preparation I really enjoyed to program a classic:

Which are the 92 solutions to the 8 queen problem?

First, the usage intentions and conditions of satisfaction:

    [TestMethod]    public void validSolutions()    {      List<ChessBoard> boards = ChessBoard.AllQueens();      foreach (ChessBoard b in boards)      {        IList all=b.Pieces;        Assert.IsTrue(all.Count == 8);        for (int k = 0; k < 8; k++)        {          IList l = b.Rank[k];          Assert.IsTrue(l.Count == 1);        }        foreach (char c in 'abcdefgh')        {          IList l = b.File[c];          Assert.IsTrue(l.Count == 1);        }      }    }    [TestMethod]    public void allSolutions()    {      List<ChessBoard> boards = ChessBoard.AllQueens();      Assert.AreEqual(92, boards.Count);    }
The AllQueens method:
    public static List<ChessBoard> AllQueens()    {      ResultKeeper keeper = new ResultKeeper();      ChessBoard board = new ChessBoard();      board.OnNewSolution += new ChessBoard.OnNewSolutionHandler(keeper.OnNewSolution);      board.GetQueens();      return keeper.Results;    }
And the ancillary ResultKeeper class:
  class ResultKeeper  {    List<ChessBoard> results;    public ResultKeeper()    {      results = new List<ChessBoard>();    }    public void OnNewSolution(int count, ChessBoard board)    {      results.Add(board);    }    public List<ChessBoard> Results    {      get      {        return results;      }    }  }
And finally, the ChessBoard class:
  public class ChessBoard  {    private char[,] board;    private int hit_count;    public ChessBoard()    {      board  = new char[8, 8];      reset();    }    private ChessBoard(char[,] b)    {      board = b;    }    public delegate void OnNewSolutionHandler(int count,ChessBoard board);    public event OnNewSolutionHandler OnNewSolution;    public IList Pieces    {      get       {        ArrayList result = new ArrayList();        for (int k = 0; k < 8; ++k)          for(int j=0;j<8;++j)            if (board[k,j] == 'X')              result.Add(board[k,j]);        return result;      }    }    public FileLine File { get { return new FileLine(board); } }    public RankLine Rank { get { return new RankLine(board); } }    public char[,] InternalState    {      get { return board; }    }    public static List<ChessBoard> AllQueens()    {      ResultKeeper keeper = new ResultKeeper();      ChessBoard b = new ChessBoard();      b.OnNewSolution += new ChessBoard.OnNewSolutionHandler(keeper.OnNewSolution);      b.GetQueens();      return keeper.Results;    }    public void GetQueens()    {      find_safe_positions();    }    void reset()    {      for (int k = 0; k < 8; ++k)        for (int j = 0; j < 8; ++j)          board[k, j] = '-';    }    private void find_safe_positions()    {      int rank = 0;      find_safe_position(rank);    }    private bool find_safe_position(int rank)    {      for (int file = 0; file < 8; ++file)      {        if (is_safe(rank, file))        {          board[rank, file] = 'X';          if (rank == 7)          {            NewSolutionFound();            board[rank, file] = '-';            continue;          }          if (find_safe_position(rank + 1))            return true;          else            board[rank, file] = '-';        }      }      return false;    }    bool is_safe(int rank, int file)    {      bool safe = empty_rank(rank) && empty_file(file) && empty_cross(rank, file);      return safe;    }    bool empty_rank(int rank)    {      for (int k = 0; k < 8; ++k)        if (board[rank, k] == 'X')          return false;      return true;    }    bool empty_file(int file)    {      for (int k = 0; k < 8; ++k)        if (board[k, file] == 'X')          return false;      return true;    }    bool empty_cross(int rank, int file)    {      for (int k = rank, j = file; k >= 0 && j >= 0; --k, --j)        if (board[k, j] == 'X')          return false;      for (int k = rank, j = file; k < 8 && j < 8; ++k, ++j)        if (board[k, j] == 'X')          return false;      for (int k = rank, j = file; k < 8 && j >= 0; ++k, --j)        if (board[k, j] == 'X')          return false;      for (int k = rank, j = file; k >= 0 && j < 8; --k, ++j)        if (board[k, j] == 'X')          return false;      return true;    }    void NewSolutionFound()    {      ChessBoard b = new ChessBoard(board.Clone() as char[,]);      ++hit_count;      if (OnNewSolution != null)        OnNewSolution(hit_count, b);    }    public class FileLine    {      private char[,] board;      internal FileLine(char[,] b) { board = b; }      public IList this[char c]      {        get        {          ArrayList result = new ArrayList();          int j = (int)c - 97;          for (int k = 0; k < 8; ++k)            if (board[k, j] == 'X')              result.Add(board[k, j]);          return result;        }      }    }    public class RankLine    {      private char[,] board;      internal RankLine(char[,] b) { board = b; }      public IList this[int n]      {        get        {          ArrayList result = new ArrayList();          for (int k = 0; k < 8; ++k)            if (board[n, k] == 'X')              result.Add(board[n, k]);          return result;        }      }    }  }


read more:

Reflecting in action: programming simple algorithms

In preparation to write some papers about software design techniques, I am planning to illustrate those techniques with a variety of examples. As part of the effort I will document my thoughts while doing reflective practicum, identifying and documenting patterns of thought while programming solutions to several kinds of problems; including implementation of simple algorithms like insertion sort, selection sort, bubble sort and more complex ones. By now, let?s see the code so far.

Consider the following main function:

#include <iostream>#include <vector>#include <iterator>using namespace std;void main(){  sort( sort_by_selection<vector<int> >() );  sort( sort_by_insertion<vector<int> >() );  sort( sort_by_bubble<vector<int> >()    );}


That sort function looks like:
template<typename T>void sort(T sort_algorithm){  int v[]={100,80,70,70,60,50,40,40,20,10,-1,-2};  vector<int> V(v,v+sizeof(v)/sizeof(int));  ostream_iterator<int> out(cout,' ');  copy(V.begin(),V.end(),out);  sort_algorithm(V);  cout << endl;  copy(V.begin(),V.end(),out);  cout << endl;}


The rest:
template<typename T>class sort_by_selection{public:  void operator()(T& v)  {    T::size_type length=v.size();    if(length<2) return;    for(int k=0;k<length;++k)    {      int min=k;      for(int j=k+1;j<length;++j)        if(v[j] < v[min])          min=j;      T::value_type t=v[k];      v[k]=v[min];      v[min]=t;    }  }};template<typename T>class sort_by_insertion{public:  void operator()(T& v)  {    T::size_type length=v.size();    for(int k=1;k<length;++k)    {      T::value_type key=v[k];      int j=k-1;      while(j>=0 && key < v[j])      {        v[j+1]=v[j];        --j;      }      v[j+1]=key;    }  }};template<typename T>class sort_by_bubble{public:  void operator()(T& v)  {    T::size_type length=v.size();    for(int k=0; k<length-1; ++k)    {      for(int j=length-1; j>k; --j)      {        if( v[j] < v[j-1] )        {          T::value_type t=v[j-1];          v[j-1]=v[j];          v[j]=t;        }      }    }  }};


read more:

Web API authentication for mashups

Jason Levitt has been teasing me in our discussions on cross-domain requests about Yahoo's upcoming authentication API.
The recurring problem: how to offer web APIs that can be mashed up but involve personal data?
You want to allow for a large number of third parties to integrate with your services, but don't want phishing sites to abuse them.

Let me do a quick re-cap of the problem space before analyzing the pieces of Yahoo's solution.


Communication techniques:

Here is what is possible today for web browsers and what some people have recommended for the future:

In all these cases, there is no good authorization story, that would allow for working with personal data stored in the service in a secured way.


Authorization techniques:

A number of techniques for controlling access to web APIs are generally used: user authentication cookies (or HTTP auth), API keys and crossdomain policy files.

The problem is that API keys and crossdomain policy files are too restrictive because the service needs to decide which third-parties to let in.

On the other end, access control based on the user authentication cookies are very open to un-planned integration, but also create a huge phishing risk.
This is a classic example of the confused deputy problems that appear in principal-based security models.

As a result, most web APIs today don't involve any user data (search, maps, ...) or non sensitive user data.


Yahoo APIs:

Yahoo appears to be tackling the challenge with its announced 'browser-based authentication' (bbauth). From the little information I could gather so far, from Drew Dean's slides, it seems less of an authentication than an authorization system. Unlike cookie based approaches, which give access to any agent presenting user credentials (principal-based security), it appears to follow a capability-based security model, which only grants access if the agent uses the proper 'secure handle' or 'capability' to call the service. Such capabilities are sufficient to gain access to the service and don't need any additional authentication, they are communicable tokens of authority.

Let me re-iterate that I don't think this protocol is about Identity, unlike Passport, TypeKey or CardSpace (aka. InfoCard), but rather simply authority and access. This characteristic is important: we want services to cooperate without being tighly coupled at the identity level. Drew Dean's slides frames the issue as allowing 'Pseudonymous delegation of partial rights', which means the names of a user in different services don't have to match and the authority that is granted is granular.

What's great about this model is that the authority carried by a capability can be as granular as the design and scenario require, and are only be given out to third-parties under certain conditions, which again are chosen to fit the desired requirements and user experience.

For example, the authority granted could vary in range in action and scope: a handle could give access to the user's entire data, or maybe only partial access to part of the user's data.
The design of the capabilities could also comprise additional dimensions, such as a time restriction. For example, a capability could be only valid for 24 hours.
One of the myths of capability systems is that capabilities cannot be revoked. It is actually possible and in Yahoo's design, any granted authority can be revoked by the user at any time.

One common policy for giving out capabilities is to get consent from the user. The screenshots of the F-Spot integration with Flickr (found on this thread) show the Yahoo consent UI.
Although I don't like the desktop/web integration in this scenario and I have some concerns about repeatedly prompting the user for consent, I believe that this approach has a lot of potential for cross-domain service integrations on the web.
Cross-domain support in browsers will be the main remaining link missing to unleash some really cool web apps. In the meanwhile, you can use FlashXMLHttpRequest or some other cross-domain workaround.

I look forward to reading the documentation when the protocol is released and trying out the resulting user experience in practical scenarios. Let me know if you find any other information.
Jason mentioned that the protocol is open and can be simply implemented, which means that it could be supported by other services and hopefully used in a wide variety of mashups.


read more:

How to expose click fraud?

The 'FuckedGoogle' blog brings up a good question: how do you prove whether a company like Google is identifying and accounting for fraudulent clicks honestly?
This is important because, as that blog pointed out many times, Google has a conflict of interest in being transparent and solving this problem, as it benefits from the fraud.

The post brings up two possible scenarios: an insider releases some damning evidence or a click fraud artist reveals himself and demonstrates how to circumvent any protection that might be in place.
The problem is that the second scenario is unlikely: click fraud scammers want to keep their activities secret.

How to break this secrecy? Here's a provocative approach.
It only requires 1 million dollars of investement ;-)
You would build a contest: '1 million dollars to whomever can provide unrefutable proof of clickfraud of a certain amount over a certain period of time'.
Then you use that proof in a class action lawsuit against Google where you make your million back and more...

A variant of this would be for the DOJ and the de-frauded parties to make a deal with a click frauder, insuring that he would not be pursued and that he can get a portition of any settlement money from the class action lawsuit supported by the evidence he provided.
If the deal takes place because the click frauder was himself sued for click fraud, then the deal wouldn't need to include any financial compensation, only the 'get out of jail free' incentive.


Update (2006/07/16): FuckedGoogle now returns a 404. Not sure what's going on.


read more:

conferences-discuss list is dead.

..or at least that's what 10 months of spam is telling me.

There is this unanswered entry.

I wonder if none of the readers noticed as SpamBayes filtered it all out. :-P  Let OSCON come and go with nary a signal and let's mothball it and move the discussions to the wiki.


read more:

The Observer Pattern in Python

The Observer Pattern in Python

I find that the best way to get a deep understanding of a programming concept is to code it up yourself.  Here's my take on the standard Observer Pattern.  I wanted to fully understand it, because I expect to need it shortly.  This also gave me the opportunity to learn about the handy-dandy weakref module.

This implementation is a bit different from the standard GoF one.  For one thing, I wanted a clean way for an Observer to be able to observe multiple Observables, while being able to easily know which Observable was sending it an update notification. That's why, when registering an Observer with an Observable, the Observer tells the Observable the name of the Observer's function to call for the update notification.

Another difference has to do with the methods that the Observer base class provides.  Now, strictly speaking from a Python perspective, the Observer base class is unnecessary.  Any class that provides a method with the right signature can be used as an Observer.  But when I was talking out this design in my head, I kept using phrases like 'The observer tells the observable that it is interested in it.'  This really seemed like an action performed by the Observer, so I wanted that behaviour in an Observer base class.

The last big difference has to do with the way an Observer subscribes and unsubscribes to update notification by an Observable.  The standard GoF implementation has the Observable class having 'attach' and 'detach' methods.  I have an 'attach' method (named addObserver), and a 'detach' method (named removeObserver).  But I'm also using weakref.WeakKeyDictionary as the way that an Observable keeps a list of its Observers.  This means that the fact that there's a reference to the Observer in the Observable does not keep the Observable alive if it goes out of scope or is deleted.  The weakref to the Observer will be automatically deleted from the Observable's list (I know, a dictionary is not a list.  I'm using the word 'list' here loosely.)  So, the 'removeObserver' method is not strictly needed; just delete an Observer, and it gets removed from the list kept by any Observable it subscribed to.

Here's the code.  It should go in a file named observer.py:

import weakref
import types
##
# The Observer Pattern in Python
#
# Design goals:
# 1. An Observer should be able to observe multiple Observables.
# 2. An Observer should be able to tell an Observable what kinds of
# events it is interested in observing.
# 3. When an Observer is deleted, all Observables that it is observing
# should be notified to remove that Observer.
# 4. When an Observer is notified of an event,
# it should be able to tell which Observable is calling it,
# and which event occured.
##
##
# The abstract Observable Class.
#
class Observable(object):
   
    def __init__(self):
        # A WeakKeyDictionary is one where, if the object used as the key
        # gets deleted, automatically removes that key from the
        # dictionary.  Thus, any Observers which get deleted will be
        # automatically removed from the observers dictionary, thus having
        # two effects:
        # We won't have references to zombie objects in the dictionary, and
        # We won't have zombie objects, because the reference in this
        # dictionary won't stay around, and so won't keep the deleted object
        # alive.
        self._observers = weakref.WeakKeyDictionary()
    ##
    # Add an observer to this Observable's notification list.
    # @param observer The Observer to add.
    # @param cbname The name (as a string) of the Observer's
    # method to call for an event notification, or None for the default
    # 'update' method.
    # @param events The events the Observer is interested in being
    # notified about.  None means all events.
    def addObserver(self, observer, cbname=None, events=None):
        if cbname is None:
            cbname = 'update'
        if events is not None and type(events) not in (types.TupleType,
                types.ListType):
            events = (events,)
        self._observers[observer] = (cbname, events)
    ##
    # Remove an observer from this Observable's list of observers.
    # Note that this function is not strictly required, because when a
    # registered Observer is deleted, the weakref mechanism will cause
    # it to be removed from the notification list.
    # @param observer the Observer to remove.
    def removeObserver(self, observer):
        if observer in self._observers:
            del self._observers[observer]
    ##
    # Notify all currently-registered Observers.
    # Each observer must have an 'update' method, which should take
    # three parameters (in addition to self): the Observable, an event,
    # and a message.
    # This method will be
    # called if the event is one that the Observer is interested in,
    # or if event is 'None', or if the Observer is interested in all
    # events (it was registered with an event list of 'None').
    # @param event The event to notify the Observers about.  None
    # means no specific event.
    # @param msg A reference to any data object that should be passed
    # to the Observers, or None.
    def notifyObservers(self, event=None, msg=None):
        for observer, data in self._observers.items():
            #print 'data is', data
            cbname, events = data
            #print 'cbname is', cbname
            #print 'events is', events
            if events is None or event is None or event in events:
                cb = getattr(observer, cbname, None)
                if cb is None:
                    raise NotImplementedError, 'Observer has no %s method.' %
                        cbname
                cb(self, event, msg)

##
# The abstract Observer Class
# This class is a mix-in to add Observable registration methods to
# a concrete Observer class.  It is not strictly required.
#
class Observer(object):
    ##
    # @param observable The Observable to observe.
    # @param The events this Observer is interested in being
    # notified about.  This should be a tuple or list of events.
    def __init__(self, observable=None, cbname=None, events=None):
        if (observable is not None):
            observable.addObserver(self, cbname, events)
    ##
    # Inform an Observable that you would like to be notified when
    # an interesting event occurs in the Observable.
    # @param observable The Observable this Observer would like
    # to observe.
    # @param cbname The name (as a string) of the Observer's
    # method to call for an event notification, or None for the default
    # 'update' method.
    # @param events A tuple or list of events this Observer would like
    # to be notified of by the Observer, or None if it would like to
    # be notified of all events.
    def subscribeToObservable(self, observable, cbname=None, events=None):
        assert observable is not None, 'Observable is None'
        observable.addObserver(self, cbname, events)
    ##
    # Inform an observable that this Observer is no longer interested in it.
    # Note that this function is not strictly required, because when a
    # registered Observer is deleted, the weakref mechanism will cause
    # it to be removed from the Observable's notification list.
    # Use this function when you want to unsubscribe an Observer
    # without deleting it.
    # @param observable The Observable that this Observer no longer wants
    # to observe.
    def unsubscribeToObservable(self, observable):
        assert observable is not None, 'Observable is None'
        observable.removeObserver(self)

Here's the code for the unit tests, which also serves as usage examples.  It should go in a file named test_observer.py:

#! /usr/bin/env python
import unittest
from observer import Observable, Observer
EVENT_FOO, EVENT_UPDATE = range(2)
class Stuff(Observable):
    def __init__(self):
        Observable.__init__(self)
        self._data = None
    def setData(self, data):
        self._data = data
        self.notifyObservers(None, data)
    def setDataWithUpdateEvent(self, data):
        self._data = data
        self.notifyObservers(EVENT_UPDATE, data)
    def setDataWithFooEvent(self, data):
        self._data = data
        self.notifyObservers(EVENT_FOO, data)

class StuffWatcher(Observer):
    def __init__(self, observable=None, cbname=None, events=None):
        Observer.__init__(self, observable, cbname, events)
        self._data = None
        self._updateData = None
        self._reportData = None
    def update(self, observable, event, msg):
        self._data = msg
        self._updateData = msg
    def report(self, observable, event, msg):
        self._data = msg
        self._reportData = msg

class TestCase_01_Observer(unittest.TestCase):
    def test_01_noMethod(self):
        observable = Stuff()
        observer1 = StuffWatcher(observable, 'foo')
        self.assertRaises(NotImplementedError, observable.setData, 10)
    def test_02_simple(self):
        observable = Stuff()
        observer1 = StuffWatcher(observable)
        observer2 = StuffWatcher(observable)
        self.assertEqual(len(observable._observers), 2)
        observable.setData(10)
        self.assertEqual(observer1._data, 10)
        self.assertEqual(observer2._data, 10)
        observable.setData(20)
        self.assertEqual(observer1._data, 20)
        self.assertEqual(observer2._data, 20)
        del observer1
        self.assertEqual(len(observable._observers), 1)
        observable.setData(30)
        self.assertEqual(observer2._data, 30)
        observer3 = StuffWatcher()
        self.assertEqual(len(observable._observers), 1)
        observer3.subscribeToObservable(observable)
        self.assertEqual(len(observable._observers), 2)
 
        observable.setData(40)
        self.assertEqual(observer2._data, 40)
        self.assertEqual(observer3._data, 40)
        del observer2
        self.assertEqual(len(observable._observers), 1)
        observable.setData(50)
        self.assertEqual(observer3._data, 50)
    def test_03_specificEvents(self):
        observable = Stuff()
        observer1 = StuffWatcher(observable, events=EVENT_UPDATE)
        observer2 = StuffWatcher(observable, events=EVENT_FOO)
        observable.setDataWithUpdateEvent(10)
        self.assertEqual(observer1._data, 10)
        self.assertEqual(observer2._data, None)
        observable = Stuff()
        observer1 = StuffWatcher(observable, events=(EVENT_UPDATE, EVENT_FOO))
        observable.setDataWithUpdateEvent(10)
        self.assertEqual(observer1._data, 10)
        observable.setDataWithFooEvent(20)
        self.assertEqual(observer1._data, 20)
    def test_03_multipleObservables(self):
        observable1 = Stuff()
        observable2 = Stuff()
        observer = StuffWatcher()
        observer.subscribeToObservable(observable1, 'update', EVENT_UPDATE)
        observer.subscribeToObservable(observable2, 'report', EVENT_FOO)
        self.assertEqual(len(observable1._observers), 1)
        self.assertEqual(len(observable2._observers), 1)
        observable1.setDataWithUpdateEvent(10)
        self.assertEqual(observer._data, 10)
        self.assertEqual(observer._updateData, 10)
        self.assertEqual(observer._reportData, None)
        observable1.setDataWithFooEvent(20)
        self.assertEqual(observer._data, 10)
        self.assertEqual(observer._updateData, 10)
        self.assertEqual(observer._reportData, None)
        observable2.setDataWithUpdateEvent(30)
        self.assertEqual(observer._data, 10)
        self.assertEqual(observer._updateData, 10)
        self.assertEqual(observer._reportData, None)
        observable2.setDataWithFooEvent(40)
        self.assertEqual(observer._data, 40)
        self.assertEqual(observer._updateData, 10)
        self.assertEqual(observer._reportData, 40)

if __name__ == '__main__':
    unittest.main()

read more:

Python and X10 Home Automation, Part 1.1

Python and X10 Home Automation, Part 1.1

I wrote previously about Project WiSH, which gives you access to X10 computer interface controllers via device drivers.  I also wrote about uprading my home system to Mandrake 10.  Mandrake 10 has the new 2.6 kernel.  Sadly, WiSH does not (yet) work with that kernel.  So, I had to find an alternative.

From googling around, and comments from readers, I found the 'bottlerocket' software, for accessing the CM-17a 'Firecracker' X10 computer interface.  This gives you a simple command-line program for issuing X10 commands via the CM-17a.  It lacks the ability to watch for an X10 command coming in from a sensor, or querying the status of a status-capable X10 controller, so it's not a complete replacement for WiSH (but that functionality is not supported by the CM-17a anyway, so you don't get it with WiSH either), but it will do me for now.

When you are doing time-based automation under Linux, it makes sense to leverage Linux's built-in abilities.  The 'cron' system lets you schedule tasks for execution based on date/time, either periodically on a period of your choosing, or at one particular data/time.  The 'at' command lets you schedule a command for execution at one particular time in the furture.  For example, typing the following command at the Linux command-line prompt will schedule the running of the command '/usr/local/bin/br a2 on' for 8:00pm today ('br' is the bottlerocket command):

at 8:00pm today <<EOF
/usr/local/bin/br a2 on
EOF

To test the usability of 'at' for X10 home automation, I wrote a simple shell script that issues two 'at' commands -- one to turn on my driveway lights at dusk, and one to turn them off at 10:30pm.  I then set up a 'cron' job to run this shell script ever day at 00:05 in the morning.  Thus, each day the two 'at' jobs are reissued for the current day.  It's necessary to reissue the commands each day because an 'at' job is a one-shot deal, while 'cron' is what you use to run commands at regular intervals.

This system of 'at', shell scripts, and 'cron' works fine, and demonstrates the simplest Linux/X10 home automation setup.  For your needs, this may be all that you require.  For me, this was just baby's first steps.

What I want is a more capable solution to the X10 home automation problem.  I want to be able to schedule both periodic and one-time events.  I want a system that understands how to deal with times like 'sunset' and 'sunrise'.  I want to be able to alias the X10 house/unit code that controls my driveway lights as 'driveway lights'.  I want to be able to create macros that trigger multiple commands, so that I can execute macro 'wakeup', and have the commands sent to turn on the TV, the coffee maker, and the window blinds opener(insert images of George Jetson being ejected from bed like toast from a toaster).  I want to have a web interface to all of this.  And, of course, I want to do it all with Python.

Sure there are several other pre-existing Linux solutions for X10 home automation.  For fun and learning, stay tuned as I put together my own solution using Python.


read more:

Python and X10 Home Automation, Part 1

Python and X10 Home Automation, Part 1

I recently saw an ad from x10.com for a free (you pay shipping) X10 starter kit, including a 'Firecracker' computer interface.  That was a deal I couldn't pass up, so I ordered it through their web site, and 3 days later, the kit arrived.

The kit consists of the CM-17a 'Firecracker' serial computer interface, which transmits via radio, a transceiver module which receives the radio commands from the Firecracker and retransmits them via the X10 protocol over your house wiring, a lamp modules for controlling... lamps, and a PalmPilot-sized hand-held remote control that lets you manually do what the computer interface does.  Oh, and the transceiver module also double as an appliance module, allowing you to control appliances of up to 500 watts.

With the hand-held controller, you can control any X10 modules you have, either the ones that come with the kit, or any add-on modules you may want to buy.  You could go wild, like many do, and completely automate your home -- lights, appliances, garage door, pool heater, ferret feeder, whatever.

But with the computer interface, things get much more interesting.  You can, for example, download from x10.com a free application that duplicates the appearance and functionality of the hand-held controller on your computer screen.  Or, you can download, for $20, an application that fully utilizes your computer and the x10 interface to do full automation.  Want your hot-tub to turn on at a certain time every day?  No problem.  Want your lights to simulate an occupied house while you are on vacation?  Easy.

Naturally, hand an X10 computer interface to a Python programmer, and he'll immediately start writing code for it.  Or that was my intent, anyway.  The first thing I did was google around for any existing Python projects for X10. I found two, Pyxal and Pyx10.  Both projects seem to be unmaintaned.  Pyxal is pure Python, and does not support the recent X10 controllers, like the Firecracker.  Pyx10 uses a wrapper to turn the XAL library into a Python extention module.  It supports recent X10 controllers, including the Firecracker.

I downloaded and examined both.  Pyxal was right out, as it has no Firecracker support (why not add it yourself, you ask?  I'll get to that in a moment...).  Pyx10 and XAL looked good.  After compiling and installing XAL (a snap), I tried compiling Pyx10.  Nope.  The wrapper code for XAL would not compile.  From a quick exam, it looked like it was out-of-sync with XAL.

I could have continued hacking at it to get it to work, but further googling (the trademark police are gonna get me), I found Project WiSH, a project for turning X10 device drivers into... well, Linux device drivers.  Super!  Instead of having to do low-level device handling from my code, I can simply open a linux device driver and write commands to it, just like I was writing text to a file.  And WiSH was a snap to compile and install.  Just make sure you have your kernel source loaded on your machine.  (For the CM-17a 'Firecracker', be sure to download the 1.6.10 version of WiSH.  The later 2.0.1 version does not yet support it.  But both versions support the CM-11a, which is the other modern popular X10 computer interface controller.)

Now, I do my work under Linux, so this is just what the code doctor ordered.  Actually, it's even better than it sounds.  You see, there's this little bit of info about that Firecracker X10 controller...

If you look at one of the other X10 computer interfaces, say the CM-11a that comes with another of the home automation intro packages that x10.com sells, you will see that it is controlled via the computer in a manner rather like an external serial modem.  Connect it to your serial port, and send it strings of ASCII characters.  Not so with the CM-17a 'Firecracker'.  This little guy is a serial pass-thru 'dongle', very small.  From what I can tell from my Google research, you must directly control the radio transmitter in it via bit-tiddling the RTS and DTR lines of the serial port.  You must assemble a 5-byte command via bit masking, then bit-shift it out to the CM-17a by directly controlling the states of the RTS and DTR lines, doing the timing yourself.  There are no smarts.  Ouch.  No wonder this is the bargain-basement controller.

The CM-11a controller has another advantage, too.  It's smart, it has its own processor.  So you don't even need to leave your computer on to do real-time home automation.  Use the scheduling software to send it commands, like 'turn on my security light at local-time dusk, and turn it off at dawn', and the CM-11a will do it, all by itself.

But I don't have the CM-11a.  I have a CM-17a and a Linux box.  Add in the device drivers from Project WiSH, and from a Linux command line, I can execute 'echo 'on' >>/dev/x10/a1', and send the 'on' command to the X10 device at house code 'A', unit code '1'.  How cool is that?

OK, how can we combine equal portions of X10, Project WiSH, Linux, Python, and fun?  (OK, fun gets a bigger portion.)

Here's the deal.  I work for a major software house.  We do automated nightly compiles of our code on all of the platforms we support (Linux, various flavors of UNIX, Windoze).  The last thing you want is for some code change you made that day to 'break the build'.  The automated process sends out email giving that night's build status.  If you broke the build, it's supposed to be your first priority to fix it.

I keep forgetting to check my email.  I have many projects, they grab my attention, and it may be hours before I check my mail.  Yes, I have a little task bar thingie that tells me if I get new mail.  I don't look at it if I'm concentrating on a problem.

Python and X10 to the rescue!  (This is a fun solution looking for a problem.)  I now have a Python script that is run via cron every 10 minutes.  It uses the poplib and email modules to grab and parse my email, looking for the specific patterns that a 'you broke the build' message will contain.  If it finds such a message, it opens and writes an 'on' command to the proper X10 device driver, which then turns on the BIG RED ROTATING LIGHT.  I kid you not.

This is so much fun!


read more:

TechEd 2006 this week
I am at TechEd 2006 in Boston this week. I registered yesterday (Sunday), coming in on the subway. This is one conference that is not much of a change for me as I commute into Boston everyday anyway -- usually on the commuter rail. It's interesting to have this large conference in my 'backyard'. I already know my way around pretty well. :)

Yesterday, I attended the Malware Removal pre-conference presented by Mark Russinovich (of SysInternals fame). It was filled with a lot of great Windows security information which included the basics, descriptions of malware, descriptions of rootkits, ways to counter malware, and even a short section on running with a Limited User Account (LUA). Mark gave the warning I always give as well -- you can remove some malware off your machine, but sometimes (actually most of the time) the best course of action is to repave and reinstall the OS. You really don't know how infected you may be once the door has been opened.

I bought Bob Beauchemin's and Dan Sullivan's completed (and awaited) book on A Developer's Guide to SQL Server 2005. I thoroughly enjoyed their first book -- this one looks to be almost twice the size. I started looking at two of my favorite topics in SQL Server 2005: security and service broker, and I wasn't disappointed. This will be a book I will enjoy digesting over the next month.

While at TechEd, I will be working as a technical expert in the Connected Systems track in the Technical Learning Center (TLC) 'blue' area (what used to be called Cabanas?) Monday, Wednesday, and Friday afternoons. It's been a couple of months since I looked at WCF in detail, but I just loaded the new Vista Beta 2 on my laptop last night (from the CD found in our TechEd bag) and installed VS 2005 and the new WinFx er, correction, .NET 3.0 (since last Friday) SDK so I can play with the latest bits. This should be fun.

If you at TechEd, come on by and say hello.
Share this post: Email it!
read more:

Jerome Armstrong Pushed Second Stock
I've been trying to pin down MyDD founder Jerome Armstrong's stock-related activities in 2000, when the SEC alleges that he touted a Chinese Linux company called Bluepoint on Raging Bull without disclosing that he'd received $20,000 in stock from the company's management.

Though Armstrong's message board postings related to Bluepoint are no longer available on Raging Bull, I found dozens of messages on the InvestorsHub site in which he promoted a related company before a merger, never revealing he was issued 25,000 shares in the deal.

An SEC filing reveals that Armstrong received the shares in a reverse merger executed by the Chinese wireless startup AccessTel, which acquired a publicly traded online mall called Shopss.Com on Dec. 18, 2000.

From September 2000 to March 2002, Armstrong posted 95 messages using the account myDDdotcom on AccessTel's InvestorsHub board. He predicted great potential for its technology and a big increase in price, deriding critics as 'bashers.' He never mentioned his relationship with the company, which was formed by some of the same executives who created Bluepoint.

On the same day as the merger, Armstrong announced that he had just bought 250 shares of the company:

... i did DD call quite a bit this weekend, and am satisfied to continue holding, patient for their plan to become widely known. Today I just bought a whopping 250 shares in my son's (Jackson) educational IRA that I just set up for the toddler, hope it grows as much as he is.

Before Armstrong's SEC case went to court, he reached a December 2003 agreement with the commission to provide testimony in related investigations and never engage in stock touting. He did not admit guilt but is prohibited from denying the charges:

Defendant agrees (i) not to take any action or to make or permit to be made any public statement denying, directly or indirectly, any allegation in the complaint or creating the impression that the complaint is without factual basis ...

The agreement makes it unlikely that Armstrong will eventually 'go on the offensive' to answer these charges, as Daily Kos founder (and business partner) Markos Moulitsas asserted last week in a private mailing list post to liberal bloggers. If Armstrong does, even through intermediaries, it'll reopen the case against him.

The SEC's suit alleged that he touted Bluepoint on Raging Bull when it began to trade publicly in March 2000, receiving stock in three companies at below-market prices. He made at least $20,000 selling the shares, the commission estimated, and none of his posts revealed that he was being compensated.

Armstrong denied the allegations in an August 2003 court filing, but his denial confirmed that he was posting on Raging Bull about Bluepoint while he had a financial relationship with company insiders Michael Markow and Francois Goelo:

Armstrong recalls that at least one of the three stocks under question was bought at above the market price. ... Armstrong does not know the specific amount he gained from selling the shares of three securities in question that he purchased from 'Markow and Goelo.'

Markow operated Global Guarantee Corporation, a company that received 1.5 million shares in the AccessTel merger.

Bluepoint has gone out of business. The company laid off all employees in 2005 after an aborted attempt to develop Linux software for the car industry and exists today as an empty shell hoping for a merger. 'As of December 31, 2005, the only asset the Company owned was cash of US$514,' its annual report states.

Shares of AccessTel are worth seven-tenths of a cent now, down from around $1.25 at the time of the merger. The New Jersey company has left the wireless business and sells ladies pantyhose manufactured in Lebanon.

In an October 1, 2000, posting on InvestorsHub, Armstrong said that SEC enforcement of messages on an over-the-counter message board was extremely unlikely:

The only thing anyone ever gets nailed for in the OTC is deliberately and misleadingly pumping to dump, anything other than that is just too ordinary for the SEC to bother.


read more:

Three text editors

I love reading about the setup for other Mac users: what kind of desks, computers, and software they use. The full list of applications usually overlaps quite a bit with my own Dock, but every once in a while there is some new app that I am not using, but should be. And there are always the two killer apps that provide the most insight into how a user works: email and text.

Are they a long-time Mac user who can't live without BBEdit? Do they use Mail.app but secretly wish that it was better?

Dan starts off his post with TextMate, which has quickly taken over the Mac Rails community. Despite a rocky 1.0, I gave TextMate a second try with 1.5 and have enjoyed using it. There is some very powerful stuff in it, some of which never clicked for me until I watched this screencast of snippets in action.

But I can't use TextMate for everything. There are three text editors always running on my machine, and I don't see that changing anytime soon:

  • TextMate: My new default for general-purpose editing, and Ruby on Rails projects.
  • Xcode: Needed for C++ and Objective-C because of the integration with the debugger.
  • BBEdit: Great for batch grep processing and multiple-file diff.

On a whim a few nights ago I tried to use TextMate for editing even C++ and Objective-C. It's trivial enough to configure Xcode to use TextMate as its default editor (in Xcode, look under Preferences → File Types), and I was happily surprised that you can even run builds from within TextMate out of the box. If you have a TextMate project in the same directory as your Xcode project, the build will just work. If not, you can manually point TextMate to your Xcode project by clicking the 'i' icon in the drawer when no files are selected, then add the shell variable TM_XCODE_PROJECT that points to a full path to your project.

Unfortunately I could only keep this setup for one night before I had to abandon it. Without breakpoint support or any integration with the debugger (impossible), it breaks the workflow cycle of testing and fixing bugs quickly.


read more:

Football is war

Either that or just a complete mess. I stayed up till 4AM to watch my native country's representatives take on Portugal. It started out quite well for both sides. Nice offensive plays by Holland and then a brilliant goal by Portugal. The equalizer seemed to be coming no matter what, but then lots of weird things happened and suddenly I'm looking at two 9-men teams and a clean scoring sheet. I lost count of how many times Holland shot on goal, but today the luck was for the Portuguese. Rasheed Wallace would have said: 'Both teams played hard'. It was liberating to see Holland fight so hard, since they've always had a label of being a team that relies too much on fine plays and soft touches. They now just need to be a bit more smarter, which hopefully happens when the younger players age a bit. The way Portugal kept possession of the ball in the last couple of minutes was absolutely clever.

The English must be totally thrilled. Not only did my favorite Dutch player of this tournament, Boulahrouz, take out their best winger, Ronaldo, Portugal will also have to play without their best midfielder, Deco, and one of their regular defenders. As for Holland, they have a future, especially with fresh players from the under-23 squad that won the European Cup earlier this year ready to join. Van Basten is a young coach, but he knows his stuff and has a clear vision of what he wants the team to do. Scoring goals would be a nice thing to practice on, though.

Blossoming romance

Blossoming romance

Best action: Van Persie faking two defenders off their feet before curling a shot a hair's width past the goal. He should have laid the ball on the incoming Sneijder's path, though.

Worst substitution: Van der Vaart for Mathijssen. Holland's defense was rock-solid, the offense was going well. There was no need to shake up this balance. It was even more unfortunate as Boulahrouz was sent off just a minute later.

Best substitution: Petit for Pauleta. Scolari played it smart by reinforcing his defense and playing Figo solo up front. The Portuguese gambled on the counter and it almost got them a goal more.

Worst acting: Figo gives Van Bommel a lame head-butt, which Van Bommel initially barely noticed, but seconds later he seems to realize that could mean a red card for Figo so goes down theatrically, clutching his face as if his jaw fell off. Gets him only a meagre yellow card for Figo.

Best acting: Boulahrouz bullies Figo for the ball and his elbow gets in Figo's face in the heat of the chase. Figo goes down as if gunned down by elite commandos. His reward: A sent-off for the best Dutch defender.

Best moment: Red-carded Boulahrouz, Van Bronckhorst and Deco sitting next to each other on the stairs, chatting amicably about and watching the game.

I'll be rooting for Australia now. Go Oz!

Technorati Tags: , , ,


read more:

BizTalk Server 2006 R2

Here are some public articles surrounding R2:

BizTalk Server 2006 'R2' Feature Set Divulged
http://redmondmag.com/news/article.asp?editorialsid=7506

Microsoft Tags The Business Process
http://www.internetnews.com/ent-news/article.php/3611441

Microsoft Details Deeper Investments in End-to-End Business Process Management Functionality as Part of BizTalk Server 2006 R2
http://biz.yahoo.com/prnews/060606/sftu068.html?.v=51

Microsoft Announces Rev 2 of BizTalk Server 2006
http://news.yahoo.com/s/zd/20060606/tc_zd/180187

Microsoft Unveils Upgrade of BizTalk Server
http://news.yahoo.com/s/cmp/20060607/tc_cmp/188702197

Brief: Microsoft to release BizTalk Server 2006 R2
http://www.computerworld.com/action/article.do?command=viewArticleBasic&articleId=9000971&source=rss_topic125

Biztalk R2, BizTalk Server R2, BizTalk Server 2006 R2


read more:

Portability of Customizable and/or Adaptive User Interfaces
This March my workplace issued employees a Motorola i760 cell phone, which apart from being pretty sluggish, doesn't work the same way as my personal phone, a Nokia 3100 - the menus aren't the same, shortcuts are different, and so on. What I discovered a few minutes after receiving the phone was that the User Interface was customizable, which didn't cause the phone to suck less, but only to work the same way as my Nokia did.

Customizable and adaptive user interfaces are great, but they're not something every developer does on their own accord. Most of the time, it's 'My way or the highway' when a developer designs a user interface, and since most companies don't hire designers to design their user interfaces, this might turn into a fiasco, as many of you know or have heard about.
As with my phone, Customizable User Interfaces are interfaces that allow users to change parts of themselves using a special menu or screen chuck-full of options. Adaptive User Interfaces are interfaces that change over time in accordance with how the user interacts with them, such as Windows's Start Menu (when items you don't usually click on are hidden until you click the little arrows at the bottom).

A few days after changing the entire layout on my new phone, a coworkertried to use my phone, but due to the fact that my interface had beencustomized one way and his another and the fact that the phone presented little to no textualor graphical cues as to which button does what (unless manuallyactivated through, guess what, one of those unlabeled buttons), he was unable to do anything like he was used to, got pissed off and had to ask me how to do operate the phone.

What this means is that these types of user interfaces don't work well simply because they're not portable. When I sit on my own computer, logged in under my own username, I have no problem with the user interface - it is as I have set it. On the other hand, when I move to a different computer or even log on as a different user on the same machine, my customization is inexistent and sometimes even worse - the customization is for a different person, with their own preferences. This is a disorienting experience for most users and will usually take them more time to perform any action, as easy as it may be, which contradicts with the reason for creating such complex user interface logic in the first place.
This pretty annoying problem doesn't (or I should say shouldn't) happen in web applications, but it does in windows applications, where to date I've only seen one solution. You too may have seen it yourself - it's the 'Save my preferences to file' method, which you can find in Microsoft Office and Visual Studio, to name only two applications, but the problem with that is that you have to carry that file with you or place it somewhere where you could access it from any computer you may use.

So what can be done about this? In my opinion, the best way the problem could be solved would be to create a central server that would save these preferences (and optionally also all other configuration changes made by the user) to some database and while your application loads, it would connect to said server and download the preferences from it, depending on which user is logged into it. This, of course, does not necessitate the creation of a logon screen in your application, which would be annoying, but rather a special form that would be filled with a their own predefined username and password. Once these credentials are entered for the first time or changed, via a form that will always be accessible from the same location (you may call it the user's 'anchor' in an unknown UI), the server would be queried for the preferences and the application would transform into what the user is already familiar with.

One might argue that this solution poses a security risk, as anyone getting hold of this 'valuable' information could do malicious things with it, but this risk is also present in the current form, where the database is not centralized, but each user has their own 'configuration file' saved on their own machine. Add this to the fact that the information could be held almost anonymously and behind very powerful encryption and you have a very low security risk (I would never say there are no security issues what-so-ever as much as I will never say an application is bug-free).

This solution looks not only applicable for vendors - holding their own repository for their applications, but there may even be a few service providers that could provide a central repository for many applications by many software vendors. Payment for this service could be an agreed upon sum per-license sold (or it could even be free (as in beer)).
Share this post: Email it!
read more:


You Searched for

action script

Click action script to go to MMK Technologies
SEARCH RSS NEWS USING THE WORDS BELOW

action script | flash database programming | flash graphics | graphics design | graphics disign | flash disign | web disign | web design | website design | internet marketing | web marketing | web site marketing | programming | web sites designer | web designs | internet design | programming developer | website marketing | web development | marketing internet | web sites designing | site designs | sites designs | internet designer | internet designs | e-commerce store | web development | web site development | design webs | internet site marketing | internet hosting | internet host | web hosting | web host | sell on the internet | sell on the web | e-commerce store | internet development | webdesign | florida web site design | website development | ecommerce store | sell online | affiliate program | asp web store | marketing program | marketing software | submission software | asp programmer | cgi store | perl store | internet store | database programmer | internet database | online marketing | ecommerce software | streaming media | video streaming | secure video streams | media streams | audio streaming | MP3 security | avi security | Windows Media Security | protect video | secure web cam | webcam security | video piracy | media piracy | windows media player security | secure media | protect audio | video stream protection | MMKTechnologies | MMK Technologies | prevent audio theft | prevent video theft | web page design | ecommerce shopping cart | shopping store ASP | sell online | sell products | products to sell online | web technology | website builders | web site builder | bradenton web design | florida web design | bradenton website design | protect MP3 | keep video from being copied | sarasota web design | secure upload video | web programming | cgi programming | net hosting | net development | flash design | flash programming | cool flash | action script |


Bradenton Condos condos condos for sale villas villas for sale townhomes townhomes for sale townhouse


Web Design Hosting and internet marketing by MMK Technologies

(c) Copyright 2005 MMK Technologies.

 

  Design Forum   Support   Hosting   News   Flash Design
Copyright © 2006, MMKTechnologies. All Rights Reserved.