Technology

Posts filed under Technology

Stealing Intellectual Property is Good for Consumers?

Filed in Current Affairs, General, TechnologyTags: , , , , , , ,

It is intriguing that companies who steal intellectual property frequently complain that the original inventors are hurting consumers and inhibiting innovation when they sue them for theft. Unfortunately, most of the public is naive and prefers to believe the "victim's" hype, usually because they want to buy what the thieving company is now producing, usually at a discounted price to the products produced by the original inventors; eg, Apple vs Google/Android Samsung/Galaxy.

Great ideas are very hard to conceptualise and develop, but usually cheap and quick to copy. I realised a great analogy of this recently while playing The Cave on my computer. There are approximately ten puzzles in The Cave. Without instructions, a single clue or a cheat-sheet, any of the puzzles could take me up to 10 hours to understand and solve, and one or two of the puzzles completely stumped me. BUT, once I knew the answer, those same puzzles would take less than 15 minutes to complete. The same principle applies to ideas. Before the idea exists, there are no clues and the idea can take a very long time to conceptualise, develop and perfect. But once the idea exists and is made public, anyone else can copy the idea with very little effort, time or expense.

Apple's slide-to-unlock method took many many months to conceptualise and perfect. It takes less than a day for a competitor (like Google) to copy it.

So when Apple sues Samsung (i.e., Google's Android) for using its slide-to-unlock invention, is it hurting consumers and innovation as Google and Samsung like to assert? In a short time frame, it might affect consumers because they won't be able to use this cool feature on competitors' products. In the long term however, it's a different story. If competitors are free to copy and steal ideas/inventions, they won't need to invent their own. If they don't need to invent their own, there will be no innovation and consumers will be worse off because of it. (many examples of this can be found on the 'net)

An additional argument is that if a company needs to spend a year and vast amounts of money to create a feature to distinguish their product and make life better for their consumers, a feature that their competitors can then copy at will, why then should the company create those features?

Consumers need to think. If you hear a company complaining about consumer rights/choice and innovation, ask yourself; are they really helping consumers and supporting innovation by copying someone else's ideas? The answer will almost always be "no".

Unfortunately, while the Apple/Samsung legal battle wages on for two, three or more years, Samsung profits from the ideas they (and Google) have stolen from Apple and will continue to do so until the legal battle hands down a verdict. Samsung is proving to the world that it profits to steal ideas. They are also proving that there is no profit in creating new ideas or in being truly innovative.

PCCW 剛叫我參加新的三星智能電話計劃。我回答我不會幫襯大賊。 :-) (喜歡三星的朋友可以不理我)

蘋果 iPhone 保養的問題

Filed in Current Affairs, General, Technology, 中文文章Tags: , , ,

由83年的 Apple IIe 到現在擁有的 iPhone 4S,我用蘋果的產品已30年了。我喜歡他的完美主義,不會為了省一點錢而把產品的質素降低。好看亦好用。

提到 iPhone 的保養,除了國家規定消費品保養期最少為兩年之外(例,法國)蘋果的保養在全世界(包括香港)都只是一年。iPhone 的確是非常好的電話卻實在不便宜。我把它扔壞或弄濕而蘋果不保是合理的(我曾經駕車的時候意外地把我的蘋果 iPhone 3GS 放了在一杯港式奶茶裡邊!笨!)不過如果機內的東西壞了,那就不同,尤其電池。所以在 iPhone 方面,我也覺得保養期為兩年比較合理和公平。

我也有興趣知道。在中國,別的聰明手提電話的公司提供的保養都為期兩年嗎?是的話就真好的。

iOS v6 Maps app - MTR station description

Apple’s iOS Maps dangerous???

Filed in General, TechnologyTags: , , , ,

iOS v6 Maps app - MTR station description

Since Apple released iOS v6 and the new Maps app with it, the iPhone has not been a very good helper when you need to find your way around. While many of the trips I've navigated with the iOS Maps have worked out fine, there were at least two different occasions where my destination as directed by Maps was far from the actual location.

In Kowloon Bay while trying to find my way to Miele, Maps took me to a location a full two blocks away. I had to walk the distance because I had already parked my car believing that Maps was accurate. whoops!

In Cheung Sha Wan where I had an interview with a group of middle-school students, Maps took me to a location three blocks away from the actual location. Again, I had to walk the distance because I wasn't driving that day. I arrived 20 mins late for the interview as a result.

Maps is definitely not great in Hong Kong. There are multiple problems with it in general.

There are no street numbers in Maps so you can't locate a street and then identify which block your destination is in.

Building names are extremely important in Hong Kong but Maps doesn't know/display them.

MTR stations are important in Hong Kong but when clicked, many of the MTR station icons in Maps display information about the MTR line that the station is part of, but not the station's actual name; for example, "Mtr-tsuen Wan Line_kcr-west Rail Line" (I didn't make that up!) instead of "Sham Shui Po".

Apparently, Maps is using data from Apple's partner TomTom. You have to wonder how reliable (or not) TomTom's own products are.

But the problem doesn't apply only to Hong Kong. In Australia, people have been stranded in extremely remote areas of Australia while following directions given by Maps. A screenshot on AppleInsider's site demonstrates the problem quite nicely. The situation has occurred so many times that the Australian police have issued an official warning against relying on Maps! WOW!

So if you plan on using Maps and you're strapped for time, or arriving in the wrong place might be life threatening, don't rely on Maps alone. Get another app, or maybe consider getting a traditional hard copy street directory, what we in Australia used to call a 'refidex'.

Cheers all :)

iPad Reflections

Filed in General, TechnologyTags: , ,

Before leaving home for L.A., I took possession of a new iPad. I knew I'd be carrying my computer with me wherever I went, and the MacBook Pro can get heavy after a while. I should clarify that when I'm in L.A., I invariably walk everywhere, only taking the public transport when I have to travel longer distances. It's not unusual for me to walk 4 to 5 miles in a single day while I'm here. Needless to say, my waist is getting smaller :-)

So, I brought the iPad with me. Right from the beginning, it has been a great help to me, especially allowing me to communicate with others when I couldn't speak (I can speak now btw). It's small, light, and the display is great. I have no idea how the PC companies are going to beat it except perhaps in I.T. and geek communities where access to everything under the hood is preferred.

It does have its flaws however.

Typing is difficult to get used to. You cannot rest your hands downward between taps because every contact with the screen types another character. It's also difficult to keep your hands in the right place positionally when you're typing. With a physical keyboard, you're calibrating your hand positions every time you press a key. It happens automatically. It's not possible with a meta-physical keyboard though.

To make things more difficult, I usually type using the Dvorak keyboard layout, and Apple has not provided that layout on the iPad. I hope it arrives with iOS 4.

Speaking of omissions in the current iPad OS, there's no Traditional Chinese on the iPad. Ouch! Hopefully, we'll see it with iOS 4 too.

And if you're a touch typist, the iPad might not be able to sense your fingers on the 'keyboard' when you're typing very quickly.

But all of those problems aren't overly difficult to deal with. There is one problem however that is potentially very serious. Ergonomically, the iPad is a nightmare.

The ideal posture for someone on a computer is to sit with the screen just below their horizontal line of sight, and with the keyboard lower than the wrists which are in turn lower than the elbows. That's not possible when the screen and keyboard are one and the same. The result is significant back strain and pain if you type for any length of time. I spent 4 hours today editing and updating my web site and I can certainly feel the pain in my back.

The solution is an external keyboard. The iPad supports Bluetooth keyboards, so I'm going to have to get one soon. Another advantage of having an external keyboard is that I'll be able to use the Dvorak layout again, because while the iPad doesn't provide a Dvorak meta-physical keyboard, it does support the Dvorak mapping on external keyboards. And incidentally, when using an external keyboard, you get to see all of the screen rather than just half.

There is one disadvantage to using an external keyboard though. The iPad by its very nature is interactive. If you have the iPad in front of you and the keyboard near or on your knees, the distance between the keyboard and the iPad will be a long way to move your hands every time you need to interact directly with the iPad. Oh well. You can't win them all.

Last note. Trying to edit a web site on the iPad is extremely challenging. None of the code editors available for the iPad are even close to being capable and useful editors, unless you're someone who can code with one eye closed. CSS and HTML editors on the iPad have a long way to go. If only we had something like Espresso on the iPad.

I need to stop now so my back can relax.

Take care all.

Blown away!

Filed in Entertainment Ind., General, Music, TechnologyTags: , , ,

I'm blown away by the Apple iTunes system.

I'm getting myself organised for a musical future, and part of that involved converting and importing into iTunes all of the Karaoke VCDs and DVDs we have in the house. When the tracks become part of the system, they're easily accessible, and they'll get listened to. The process of converting and importing the Karaoke tracks took three days of AppleScript scripting to automate and process, along with lots of Chinese typing, but I now have more than 700 karaoke tracks; both audio and video; in my iTunes library. Being a perfectionist, I then proceeded to correct the data for the tracks in my library, and create playlists (unrated, not played within the last month, ≤xGB) that I could use on our Apple TV and iPhones.

Did I say iPhones? Yep! I've waited more than a year for Apple to release the iPhone in Hong Kong, and I was registered with Hutchison 3 in both the local store and the online database weeks before the official launch. Even though we can't really afford it at the moment (who can?), we went ahead and purchased one white 16GB and one black 16GB, two colours so that my wife and I wouldn't accidentally pick up the wrong phone. Before buying the phones, I calculated the Total Cost of Ownership for the All-You-Can-Eat package. It comes out to HK$12,000 over two years per phone which is a lot of money, but not as expensive as the TOC in some other countries. The HK$12,000 included an upfront payment of $6,000 including the 'iPhone' cost, the 'Plan Prepayment' and the first month's subscription fee; ouch!

The iPhone is so cool. It has its bugs but the current functionality is great, and the potential is simply awesome. When comparing the iPhone to other 'smart' phones, people need to remember that the iPhone is not so much a phone as a portable computer with added phone functionality. It's a completely new paradigm. For the purposes of this article though, I'll only describe one function; Apple's included Remote application.

Here at home, we have two desktop Macs, one Apple TV, two portable Macs, and now two iPhones, and iTunes is completely interlinked through our wi-fi network. It's incredible. At this very moment, my iPhone is controlling the iTunes library on my iMac which is broadcasting the music through the Apple TV connected to our hi-fi system! How cool is that??? I could remote control the Apple TV directly but I don't get to set ratings while connected to the Apple TV, only when connected to an iTunes library on one of the Macs.

Life is suddenly becoming so much more musical ;-)

Hierarchical threaded comments; How I did it.

Filed in General, Technology

(Announced in "New blog feature: Hierarchical threaded comments!")

WARNING: Lots of technical jargon!

My blog is a MovableType blog developed by Six Apart Ltd. They also have other blog systems. They're a very smart company. You can read about their products on their web site. Like many other systems, MovableType allows you to add functionality via plugins.

One such plugin designed to implement threaded comments is called MTSimplyThreaded which I installed and experimented with. It could link comments to other comments but it couldn't produce a hierarchical comment scheme so it wasn't what I wanted.

Then I was told about MTThreadedComments. I read the documentation and it seemed to be exactly what I wanted, but it was old and apparently not compatible with my version of MovableType. Not to be dissuaded too easily, I searched for tips about running MTThreadedComments with my version of MovableType on google and I came across a couple of sites; one of them in Korean; which explained what adjustments to MovableType's code needed to be done. Strangely enough, it was the Korean site that told me exactly what I needed to know. I couldn't read the Korean but their code screen shots were self explanatory.

I examined MTThreadedComments' documentation and everything I could find on the internet. I didn't like MTThreadedComments' suggested method of responding to comments. Clicking on any 'Respond' link redirected the reader to another page with a copy of the article text or the comment text that the reader was responding to along with the comment form. This is normally ok but I don't like unnecessary page loads and wanted to come up with a more ideal (in my opinion) way of doing it. I liked the way MTSimplyThreaded worked and after analysing what data MTThreadedComments needed to work, I decided to implement a simple Ajax comment system. The investigation of MTThreadedComments and the analysis of what I wanted to do and how to do it took two full days.

What started out as a simple JavaScript script turned into something much more complicated (it's always the same), and IE's many css bugs made me reconsider my plan to implement MTThreadedComments via Ajax more than once, but I eventually finished it and I'm pretty pleased with it. I just wish that IE supported opacity (without requiring ActiveX). I can fully understand now why so many web developers despise IE. Why is it that a humongous company with unlimited resources can't make a decent (standards based) browser??? All I can say is thank God for Dean Edwards and his IE7 JavaScript script.

Now for the details.

MTThreadedComments on MT 3.3: The details

MT 3.33
MTThreadedComments 0.1.1 (Date: 2003/02/19 17:18:16)

MT Code Edits

You'll need to apply the following edits to MT's code:

(Taking a cue from the Korean site, the new code is coloured red.)

File: mt/lib/MT/App/Comments.pm

Subroutine: _make_comment()


$comment->ip($app->remote_ip);
$comment->blog_id($entry->blog_id);
$comment->entry_id($entry->id);
$comment->author(remove_html($nick));
$comment->email(remove_html($email));
$comment->url(is_valid_url($url, 'stringent'));
$comment->text($text);

## MTThreadedComments patch start ##
$comment->subject($q->param('subject'));
$comment->parent_id($q->param('parent_id'));
## MTThreadedComments patch end ##

File: mt/lib/MT/App/Comments.pm

Subroutine: _send_comment_notification()


my %param = (
blog_name => $blog->name,
entry_id => $entry->id,
entry_title => $entry->title,
view_url => $comment_link,
edit_url => $base . $app->uri_params('mode' => 'view', args => { blog_id => $blog->id, '_type' => 'comment', id => $comment->id}),
ban_url => $base . $app->uri_params('mode' => 'save', args => {'_type' => 'banlist', blog_id => $blog->id, ip => $comment->ip}),
comment_ip => $comment->ip,
comment_name => $comment->author,
(is_valid_email($comment->email)?
(comment_email => $comment->email):()),
comment_url => $comment->url,

## MTThreadedComments patch start ##
comment_subject => $comment->subject,
## MTThreadedComments patch end ##

File: mt/lib/MT/App/Comments.pm

Subroutine: view()


my $ctx = MT::Template::Context->new;
$ctx->stash('entry', $entry);

## MTThreadedComments patch start ##
$ctx->stash('comment_parent_id', $q->param('parent_id'));
## MTThreadedComments patch end ##

File: mt/lib/MT/Comment.pm

Subroutine: the root (i.e., the implicit) routine, at the beginning of the file


column_defs => {
'id' => 'integer not null auto_increment',
'blog_id' => 'integer not null',
'entry_id' => 'integer not null',
'author' => 'string(100)',
'commenter_id' => 'integer',
'visible' => 'boolean',
'junk_status' => 'smallint',
'email' => 'string(75)',
'url' => 'string(255)',

## MTThreadedComments patch start ##
'subject' => 'text',
'parent_id' => 'integer',
## MTThreadedComments patch end ##

and…


indexes => {
ip => 1,
created_on => 1,
entry_id => 1,
blog_id => 1,
email => 1,
commenter_id => 1,

## MTThreadedComments patch start ##
parent_id => 1,
## MTThreadedComments patch end ##

mt_comments Table

Next, you'll need to add two columns to the mt_comments table. I used phpMyAdmin.


comment_subject (text)
comment_parent_id (int)

Implementing my Ajax comments script: The details

If you plan on using my Ajax comments script (which you can get directly from my server) or something based on it:

MT Code Edits

File: mt/lib/MT/App/Comments.pm

Subroutine: post()
at the end of the routine:



return do_preview($app, $app->{query}, '');

return $app->redirect($comment_link);

This returns the comment preview html to the Ajax script which then inserts it into the existing individual archive page.

Comment Preview Template

You will need to edit your Comment Preview Template so that it only returns the html required to preview the comment. That means no <head>, no <body>, nothing except the comment itself and any tags that you need to format it. My xhtml code looks like this:


<MTIfNonEmpty tag="CommentPreviewSubject">
<h2><$MTCommentPreviewSubject$></h2></MTIfNonEmpty>
<$MTCommentPreviewBody$>
<div class="posted">
<p>Posted by: <$MTCommentPreviewAuthorLink spam_protect="1"$> |
<$MTCommentPreviewDate format="%a, %B %e, %Y, %H:%M"$></p>
</div>

Incidentally, the MTThreadedComments plugin does not provide a MTIfCommentPreviewSubject container tag so I had to use MTIfNotEmpty provided by Brad Choate's ifempty plugin.

Comment Error Template

You will also need to edit your Comment Error Template so that it only returns the minimum html required to view it within the Comment Form Error div if an error should occur during final submission of the comment. My xhtml code (it's just 3 lines) looks like this:


<h3>Comment Submission Error</h3>
<p>Your comment submission failed for the following reasons:</p>
<$MTErrorMessage$>

Individual Entry Archive edits

You'll need to add MTThreadedComments tags and JavaScript code to your template. For example;

The code that produces the comments list:


<MTIfCommentsActive>
<div id="comments-list">
<h3 id="comments">Comments</h3>
<MTRootComments>
<div id="comment-<$MTCommentID$>-parent" class="comment-parent">
<$MTInclude module="comments nested"$>
</div><!-- comment_parent -->
</MTRootComments>
</div> <!-- comments list -->
</MTIfCommentsActive>

The code for the 'comments nested' module:


<div id="comment-<$MTCommentID$>" class="comments-body">
<MTIfCommentSubject><h2><$MTCommentSubject$></h2></MTIfCommentSubject>
<div id="comment-<$MTCommentID$>-body">
<$MTCommentBody$>
</div> <!-- comment-<$MTCommentID$>-body -->
<div class="posted">
<p>Posted by: <$MTCommentAuthorLink spam_protect="1"$> | <$MTCommentDate format="%a, %B %e, %Y, %H:%M"$>
<MTIfCommentsAccepted> | <a href="javascript:void(0);" onclick="respond(<$MTCommentID$>, '<$MTCommentSubject remove_html="1" encode_js="1"$>', '<$MTCommentAuthor remove_html="1" encode_js="1"$>')">Respond to this comment</a></MTIfCommentsAccepted></p>
</div>
</div> <!-- comment-<$MTCommentID$> comments-body -->
<MTCommentIfChildren>
<div id="comment-<$MTCommentID$>-children" class="comments-children">
<MTCommentChildren>
<div id="comment-<$MTCommentID$>-child" class="comments-child">
<$MTInclude module="comments nested"$>
</div> <!-- comment-<$MTCommentID$>-child -->
</MTCommentChildren>
</div> <!-- comment-<$MTCommentID$>-children -->
</MTCommentIfChildren>

The code in my template that produces the "Create a comment regarding this article." link at the end of the comment list:


<MTIfCommentsAccepted>
<p><a href="javascript:void(0);" onclick="respond (0, '<$MTEntryTitle remove_html="1" encode_js="1"$>', '河國榮')">
Create a comment regarding this article.</a></p>
<MTElse>
<p>Comments to this entry are no longer being accepted.</p>
</MTElse>
</MTIfCommentsAccepted>

For reference, the MTThreadedComments plugin provides the following tags:


<MTRootComments>, <MTCommentChildren>, <MTCommentIfChildren>
<MTIfCommentSubject>, <MTUnlessCommentSubject>, <$MTCommentSubject$>
<$MTCommentPreviewSubject$>, <$MTCommentResponseSubject$>
<MTCommentParent>, <$MTCommentParentID$>, <MTCommentIfParent>, <MTCommentUnlessParent>
<MTCommentPreviewParent>, <$MTCommentPreviewParentID$>, <MTCommentPreviewIfParent>, <MTCommentPreviewUnlessParent>

Optional: An improved link to the comment upon comment submission.

When you submit a comment, MT currently usually in the Comment Notification email returns a link to the Individual Entry Archive page without including the comment # anchor. You can rectify this if you wish.

File: mt/lib/MT/App/Comments.pm

Subroutine: post()
in the # Form a link to the comment section:


# $comment_link = $entry->permalink;
$comment_link = $entry->permalink . '#comment-' . $comment->id;

Note. My Individual Entry Archive template assigns ids to each of the comments
using the format id="comment-<$MTCommentID$>". Your format may and probably does differ. You will need to adjust the $comment_link code accordingly.

MT 3.34/3.35 and FastCGI

Note. This setup works with MT 3.34/3.35 and FastCGI as long as you don't use the FastCGI version of AdminScript; i.e., in the config file;


AdminScript mt.cgi
CommentScript mt-c.fcgi
TrackbackScript mt-t.fcgi
SearchScript mt-search.fcgi
ViewScript mt-view.fcgi

If you use the FastCGI version of AdminScript, building the Individual Entry Archive pages will fail; something to do with this line of code in the get_comments() subroutine of the MTThreadedComments.pl code:


my @comments = sort { $a->created_on <=> $b->created_on }

MT produces an error which begins with these three lines:


unknown column: parent_id for class MT::Comment at lib/MT/Object.pm line 283
MT::Object::AUTOLOAD('MT::Comment=HASH(0x92a1cc8)') called at /path_to_cgi-bin/mt/plugins/MTThreadedComments.pl line 123
MT::get_comments('MT::Template::Context=HASH(0x9168aa4)', 'MT::Entry=HASH(0x9175904)', 'undef') called at /path_to_cgi-bin/mt/plugins/MTThreadedComments.pl line 153

If anyone knows why this line doesn't work, please leave a comment.

Other details

You will of course need to write (or copy) the css for the form, etc. I use Dean Edwards' IE7 JavaScript script to help standardise the look of my blog on IE so don't count on my css to help you code for IE.

No support!   I can offer no support for this implementation of MTThreadedComments. If you don't understand the instructions, then it's probably too difficult for you and you shouldn't attempt it.

Above all else; and it should go without saying; back up your MT installation before you begin editing the code and templates.

That's all folks!

New blog feature: Hierarchical threaded comments!

Filed in General, Technology

After finishing "They’re Playing Our Song (2007)", I needed rest. My vocal chords needed rest. More than a week before the show began, my chords had begun to inflame. I had worked them too hard with strenuous vocal exercises in the mornings followed by rehearsals every day for 8 weeks. When my chords began to feel tight, I consulted my doctor and was informed that my chords were inflaming. I halted the morning vocal exercises but it was too late. For the entire week that we performed "They're Playing Our Song", my chords were straining through every single show. I was only able to perform successfully and get through the ordeal by not speaking between shows, taking anti-inflammatories at night before sleep and using a Japanese powder known as 龍角散 'Dragon Horn Powder' before each show. Still, my vocal chords suffered tremendously; especially during those shows when our microphones weren't working; and they needed rest. I needed to shut up.

The week after the show, I couldn't completely abstain from talking. My parents were here and I don't get many opportunities to be with them so chatting with them was a blessing not to be ignored. Only after they had left Hong Kong and returned to Australia could I really allow my vocal chords to relax; no singing and as little talking as possible.

No talking meant no going out to eat and chat with friends. It meant staying at home.

For the first three days, I spent countless tiring hours identifying and verifying the content on my backup DVDs and CDs. I have 15,000 photographs in my Aperture library and none of them are backed up. My DVD backups haven't been very reliable and backing up to normal DVDs is frankly unrealistic because of the number of discs involved (approx. 40 to back up my Aperture library) and the amount of time required (more than 24 uninterrupted hours), so I've had to consider other options for a better backup plan. I have decided to backup incrementally to an external 750G Seagate Barracuda drive which I have ordered. I am also experimenting with backing up to DVD+R DL (double layer) discs which would halve the number of disc swaps required for every backup operation. Eventually, I will investigate Blu-Ray backups. With up to 25G per disc, it would simplify backups immensely.

Then I began working on something else blog related which might or might not interest you although it will affect many of you.

I have never been satisfied with the comment system in my blog. It didn't allow people to respond to other comments and there was no comment hierarchy. I reply to quite a few comments but usually a long time after those comments have been submitted and my replies consequently get separated from the comments I'm replying to. I didn't like it so I decided to change it ;-)

For those of you not interested in the intricacies of how I did it, here is the short story. It took 7 full days of coding (perl, javascript, css and xhtml) but my blog now has full hierarchical threaded comments!!! You can now respond directly to another comment and your comment will be displayed immediately beneath that comment. My implementation is a simple version of Ajax and does not require a page reload. IE (Internet Explorer) was a terror to work with but I eventually worked out the problems so my comment system is working with IE too.

So that's it. You can now reply to each other's comments. No arguments please ;-)

Incidentally, my vocal chords are much better although not yet fully recovered. I won't be singing for at least another two weeks.

(For those of you interested in how I did it, you can find all the gory details here.