In case you still care about those mainstream folks who are not yet in the Apple and Linux clubs, now it's not too early to take a look at the usability issues of the new Microsoft Windows 8. We all understand why M$ want to introduce the Metro UI to catch up the mobile (touch screen) bandwagon, but that's not an excuse for messing up the desktop user experience.

I don't want to rant about my personal experience only. Fortunately, Jacob Nielsen has posted some results from a user testing with 12 experienced PC users to test Windows 8 on both regular computers and Microsoft's new Surface RT tablets. I cannot agree more with his conclusion: "Windows 8 UX: Weak on Tablets, Terrible for PCs... Summary: Hidden features, reduced discoverability, cognitive overhead from dual environments, and reduced power from a single-window UI and low information density. Too bad."

There are three different kinds of demands or loads that you can make on a person: cognitive, visual, and motor. Looking at something or to find something on a screen (visual load) uses up more mental resources than simply ask someone to press a button or move a mouse (motor load); asking a user to think or remember or even do a mental calculation (cognitive load) is the most mental resource intensive task, which is why "Don't make me think" and the formula for Fitt's Law.

  • Auto-hide is terrible for new user
Clearly, clicking on the old Windows start button was a simple motor load for users, maybe plus some visual load to find the program to launch. However, without the start button, simple task as launching a program become the most expensive cognitive load which require people to remember clicking on the conner or a motor switch which require people to switch between two input devices.

  • Avoid switching input devices

    The basic problem here is switching user input devices, no matter keyboard to mouse, or touch-screen to keyboard, this is exactly the type of motor load to avoid in Human Factor terminology. Without the start button, the most basic operation as running a program could involve switching between two devices, namely, press windows key, click on the start screen.

    I guess what we could all learn from this is, it's not easy to get all different user interfaces work well together, people are still fighting over keyboard-based command-line and mouse/trackpad-based point-click preferences. If not done right, adding touch-screen could be disastrous.


 
As Dr. Gautam Shroff said, the interesting relationship between SQL and Bayesian Network remains an good area for more research. Here's an example based on a NYU AI course material, Pls. find my note of SQL statements all in underlines.
Bayesian Net Example (with SQL calculation) 
Consider the following Bayesian network:
A->C->E
A->D
B->D

Thus, the independence expressed in this Bayesian net are that 
A and B are (absolutely) independent. 
C is independent of B given A. 
D is independent of C given A and B. 
E is independent of A, B, and D given C. 
Suppose that the net further records the following probabilities:

Prob(A=T) = 0.3 
Prob(B=T) = 0.6 
Prob(C=T|A=T) = 0.8 
Prob(C=T|A=F) = 0.4 
Prob(D=T|A=T,B=T) = 0.7 
Prob(D=T|A=T,B=F) = 0.8 
Prob(D=T|A=F,B=T) = 0.1 
Prob(D=T|A=F,B=F) = 0.2 
Prob(E=T|C=T) = 0.7 
Prob(E=T|C=F) = 0.2
Some sample computations:
First, create database tables a(p,a), b(p,b), c(p,c,a), d(p,d,a,b), e(p,e,c) with all probs filled in, including inferred ones like: Prob(A=F) = 0.7, Prob(D=F|A=F,B=F) = 0.8, etc.    Prob(D=T)P(D=T) =

P(D=T,A=T,B=T) + P(D=T,A=T,B=F) + P(D=T,A=F,B=T) + P(D=T,A=F,B=F) =

P(D=T|A=T,B=T) P(A=T,B=T) + P(D=T|A=T,B=F) P(A=T,B=F) + 
P(D=T|A=F,B=T) P(A=F,B=T) + P(D=T|A=F,B=F) P(A=F,B=F) = 
(since A and B are independent absolutely)

P(D=T|A=T,B=T) P(A=T) P(B=T) + P(D=T|A=T,B=F) P(A=T) P(B=F) + 
P(D=T|A=F,B=T) P(A=F) P(B=T) + P(D=T|A=F,B=F) P(A=F) P(B=F) =

0.7*0.3*0.6 + 0.8*0.3*0.4 + 0.1*0.7*0.6 + 0.2*0.7*0.4 = 0.32

Using SQL:

SELECT SUM(a.p*d.p*b.p) FROM a, d, b WHERE  d.a=a.a AND d.b=b.b AND d.d='t'

Prob(D=F,C=T)P(D=F,C=T) =P(D=F,C=T,A=T,B=T) + P(D=F,C=T,A=T,B=F) + 
P(D=F,C=T,A=F,B=T) + P(D=F,C=T,A=F,B=F) =

P(D=F,C=T|A=T,B=T) P(A=T,B=T) + P(D=F,C=T|A=T,B=F) P(A=T,B=F) + 
P(D=F,C=T|A=F,B=T) P(A=F,B=T) + P(D=F,C=T|A=F,B=F) P(A=F,B=F) = 
(since C and D are independent given A and B)

P(D=F|A=T,B=T) P(C=T|A=T,B=T) P(A=T,B=T) + P(D=F|A=T,B=F) P(C=T|A=T,B=F) P(A=T,B=F) + 
P(D=F|A=F,B=T) P(C=T|A=F,B=T) P(A=F,B=T) + P(D=F|A=F,B=F) P(C=T|A=F,B=F) P(A=F,B=F) = 
(since C is independent of B given A and A and B are independent absolutely)

P(D=F|A=T,B=T) P(C=T|A=T) P(A=T) P(B=T) + P(D=F|A=T,B=F) P(C=T|A=T) P(A=T) P(B=F) + P(D=F|A=F,B=T) P(C=T|A=F) P(A=F) P(B=T) + P(D=F|A=F,B=F) P(C=T|A=F) P(A=F) P(B=F) =

0.3*0.8*0.3*0.6 + 0.2*0.8*0.3*0.4 + 0.9*0.4*0.7*0.6 + 0.8*0.4*0.7*0.4 = 0.3032

Using SQL:

SELECT SUM(a.p*c.p*d.p*b.p) FROM a, c, d, b WHERE c.a=a.a AND d.a=a.a AND d.b=b.b AND c.c='t' AND d.d='f'

Prob(A=T|C=T)P(A=T|C=T) = P(C=T|A=T)P(A=T) / P(C=T). 


Now P(C=T) = P(C=T,A=T) + P(C=T,A=F) = 
P(C=T|A=T)P(A=T) + P(C=T|A=F)P(A=F) = 
0.8*0.3+ 0.4*0.7 = 0.52

So P(C=T|A=T)P(A=T) / P(C=T) = 0.8*0.3/0.52= 0.46.

Using SQL:

SELECT a.a, SUM(a.p*c.p) FROM a, c WHERE c.a=a.a AND c.c='t' GROUP BY a.a

Remember to normalize P(A=T)

Prob(A=T|D=F)P(A=T|D=F) =P(D=F|A=T) P(A=T)/P(D=F).

Now P(D=F) = 1-P(D=T) = 0.68 from the first question above. 


P(D=F|A=T) = P(D=T,B=T|A=T) + P(D=F,B=F|A=T) =

P(D=F|B=T,A=T) P(B=T|A=T) + P(D=F|B=F,A=T) P(B=F|A=T) = 
(since B is independent of A)

P(D=F|B=T,A=T) P(B=T) + P(D=F|B=F,A=T) P(B=F) = 0.3*0.6 + 0.2*0.4 = 0.26. 
So P(A=T|D=F) = P(D=F|A=T) P(A=T)/P(D=F) = 0.26 * 0.3 / 0.68 = 0.115

SELECT a.a, SUM(a.p*d.p*b.p) FROM a, d, b WHERE d.a=a.a AND d.b=b.b AND d.d='f' GROUP BY a.a

Remember to normalize P(A=T)

Prob(A=T,D=T|B=F).P(A=T,D=T|B=F) =P(D=T|A=T,B=F) P(A=T|B=F) = 
(since A and B are independent)

P(D=T|A=T,B=F) P(A=T) = 0.8*0.3 = 0.24.

SELECT a.a, d.d, SUM(a.p*d.p*b.p) FROM a, d, b WHERE d.a=a.a AND d.b=b.b AND b.b='f' GROUP BY a.a, d.d

Remember to normalize P(A=T,D=T)

Prob(C=T | A=F, E=T)Prob(C=T | A=F, E=T) = (By Bayes' law)Prob(E=T|C=T,A=F) * Prob(C=T|A=F) / Prob(E=T|A=F) = (since E is independent of A given C)

Prob(E=T|C=T) * Prob(C=T|A=F) / Prob(E=T|A=F).

Now Prob(E=T|A=F) = Prob(E=T,C=T|A=F) + Prob(E=T,C=F|A=F) =

Prob(E=T|C=T,A=F) Prob(C=T|A=F) + Prob(E=T|C=F,A=F) Prob(C=F|A=F) = (since E is independent of A given C)

Prob(E=T|C=T) * Prob(C=T|A=F) + Prob(E=T|C=F) * Prob(C=F|A=F).

So we have 
Prob(C=T | A=F, E=T) = 
Prob(E=T|C=T) * Prob(C=T|A=F) / (Prob(E=T|C=T) * Prob(C=T|A=F) + Prob(E=T|C=F) * Prob(C=F|A=F)) =

0.7*0.4 / (0.7 * 0.4 + 0.2 * 0.6) = 0.7

SELECT c.c, SUM(a.p*c.p*e.p) FROM a, c, e WHERE c.a=a.a AND e.c=c.c AND a.a='f' AND e.e='t' GROUP BY c.c

Remember to normalize P(C=T)


In general, just use the whole structure:
for Prob(%Apo | %Obs) 

SELECT (%Apo), SUM(a.p*d.p*b.p*c.p*e.p) FROM a, d, b, c, e WHERE  d.a=a.a AND d.b=b.b and c.a=a.a and e.c=c.c (%Obs) group by (%Apo)

 

Today, I was trying to add a cron job for mysql database backup using crontab -e, everything went well when I tried the command at console, (backup local MySQL database into a folder and removes older then 5 days backups, I got it from commandlinefu.com:)
mysqldump -uroot -ppassword  --all-databases | gzip > /var/www/nginx-default/mysql-backup/mysql-backup-`date +%Y-%m-%d`.sql.gz ;find /var/www/nginx-default/mysql-backup/* -mtime +5 -exec rm {} \; 

but when I did: 
# export EDITOR=vi  
# crontab -e
# m h  dom mon dow   command
MAILTO=zhangyong@gmail.com
 48 3  *   *   * mysqldump -uroot -ppassword  --all-databases | gzip > /var/www/nginx-default/mysql-backup/mysql-backup-`date +%Y-%m-%d`.sql.gz ;find /var/www/nginx-default/mysql-backup/* -mtime +5 -exec rm {} \;

It failed, then I tried replace the backticks with $( )
mysqldump -uroot -ppassword  --all-databases | gzip > /var/www/nginx-default/mysql-backup/mysql-backup-$(date +%Y-%m-%d).sql.gz ;find /var/www/nginx-default/mysql-backup/* -mtime +5 -exec rm {} \; 

failed still, after a few googling I find out in a blog post comment of Anonymous:
You CAN use a backtick operator in the command argument place in a crontab.

However, percent signs (%) in the command must be escaped with a backslash or else they will be interpreted as a newline.

From 'man crontab':
The ??sixth?? field (the rest of the line) specifies the command to be run. The entire command portion of the line, up to a newline or % character, will be executed by /bin/sh or by the shell specified in the SHELL variable of the crontab file.
Percent-signs (%) in the command, unless escaped with backslash (\), will be changed into newline characters, and all data after the first % will be sent to the command as standard input. There is no way to split a single command line onto multiple lines, like the shell?s trailing "\".

so the following is valid:

15 3 * * 0,2-6 echo ´date +\%a´

and

15 3 * * 0,2-6 echo $(date +\%a)

Failure to escape the backslash will result in a cron error:

/bin/sh: -c: line 1: unexpected EOF while looking for matching ´´'
/bin/sh: -c: line 2: syntax error: unexpected end of file


so, the correct command to use in crontab -e is:

 48 3  *   *   * mysqldump -uroot -ppassword  --all-databases | gzip > /var/www/nginx-default/mysql-backup/mysql-backup-$(date +\%Y-\%m-\%d).sql.gz ;find /var/www/nginx-default/mysql-backup/* -mtime +5 -exec rm {} \;
 
Sisyphus.js is a lightweight (2Kb) jQuery plugin uses HTML5 Local Storage to prevent your work being lost when you're almost done with that browser is crashed, or you closed tab mistakenly, or electricity is turned off, or something else.

The first thought when I saw this plugin was it could be very useful to save limesurvey inputs, especially in all-in-one page settings, or survey on mobile devices.

So I did a test with a simple custom-load in template.js:
jQuery(function($){
jQuery.getScript('https://raw.github.com/simsalabim/sisyphus/master/sisyphus.min.js',
function(){
$('form').sisyphus();
}
);
focusFirst();
})

It works quite well, I think many others will like that too, so there goes the patch submitted for limesurvey.
 
I started to use Excel VBA to do batch geocoding calls to Yahoo and Google Map API, it works. See Excel sheet attached (xlsm) . However, when I was trying to plot the locations on the map, using KML layer, it turned out that the simplest way to do geocoding and maping is Google Fusion Tables.
Just import the locations / addresses into a new empty Fusion Table, it will take care of geocoding and the maping in one place.
If only I knew this earlier, but isn't that what ought to be anyway?

Ps. Google Fusion Tables won't export the latitude/longitude coordinates, so the excel vba is still useful ;-)
 
How amazing to see this wonderful open source project evolve during the past 8 years!
 
If you have attempted this in Excel:IF(L3<=5,-1,IF(AND(,L3>5,L3<10),0,IF(AND(L3>=10,L3<20,1,IF(AND(L3>=20,L3=<25),2,3)))), it's kind of a painful way, and there are also limitation of 7 nested or so I heard.
Any alternatives???

First thing come to mind is some lookup method, see attached first sheet, then I suspected there are more better way of doing it. So I came across this tip, it actually suggested 6 ways to do it. So I gave some tries, the result is quite some interesting learning experience. Pls. refer to each sheet of the attached excel file.

The other thing bugged me for quite a while was the last method using Boolean Multiplication, a natural improvement was sumproduct, however I could not get sumproduct(boolean array, score) work, it always returns 0 in Excel 2010, as confirmed in another blog post I found online. After some try and errors, only the 9th sumproduct works. (Sheet attached here)

It's very interesting to see how this method can be hacked to simulate typical select from where SQL query in Excel.