Tuesday, July 14, 2009
Twitter and the Web 2.0 Hype
Twitter is the latest fan boy in the town. A free social messaging utility that allows you to broadcast to the world what you are doing under 140 characters, it enjoyed a meteoric rise after a few well known celebrities started to use it. For a simple service that can be cloned in a week ( or so a tweet claims), Twitter's success is nothing short of astounding.
But despite the role it played in the Iranian election, despite that it's such a huge disrupter to any authoritarian regime, despite its ability to convey real time information in such a wide and spontaneous manner that no other
type of media can hope to convey, Twitter is really lacking of a business model.
Well, it's not exactly a sin to have a startup that lacks a business model; I don't have a problem with that. I do have a problem, however, with the kind of hype associates with it.
For quite sometime already people has been talking about Twitter and real time search, and why should Google worries about it. Even the venerable Wired magazine, which should really have known better, also asked Eric Schmidt whether he's worried about the threat Twitter posted to Google because of real time search.
So, by having "real time search" Twitter is posted to be a Google killer? C'mmon, you gotta be serious. For one, Google does have a real time search-- if your article or news are important enough. For example, I can expect to get my blog post from Google minutes after it has been posted ( and I am in NO WAY consider my post to be important, except perhaps to myself). And if you are a venerable news agency, you can expect to see your article appears on Google news right after it appears on your website ( I searched 'obama' and the first item I got was a news item from AFP-- updated 39 minutes ago).
It seems that the only strength Twitter has over Google is the " real time ability" to search for common terms, such as "Gmail outage" that won't normally appear in Google searches because these kinds of events are quite frivolous and don't register a lasting impact. But as far as I know Technorati, a blog search engine also has this feature since long time ago. Obviously, the ability to see "what is percolating in blogs now"( Technorati motto) doesn't save Technorati at all; the last time I checked the website it's slow, and the indexing service is unreliable, and according to all the metric I have Technorati is not exactly prospering now, even though it did started off with a big bang.
Twitter could as well turn into another Technorati, we don't know.
Which leads to the question of why all the hype? As mentioned, although Twitter is obviously a good tool, but the fact that people seems to take it too seriously has always bother me. It seems that the Internet media is always on a lookout for the next poster child to talk about, and of course the poster child will welcome all the attention ( but not the downtime that associates with the traffic spike, please). But we as the user, do we have to chase from one trend to another? From one next-hot-service to another-hot-service?
Oh yes, one last thing. Before I forget, Twitter, please enable OpenID support. I am sure it would be useful.
Thank you for listening to my rant.
Posted by
Soon Hui
at
12:18 AM
0
comments
Links to this post
Friday, July 10, 2009
Understanding Lambda Expression via Step By Step Debugging
Lambda Expression, anonymous function and the likes can be difficult to understand for C# programmers, partly because they don't work in a strict procedural manner, and partly because the abstract level one has to raise in order to grasp the concept is comparatively high. Lambda expression is the essence of functional programming, and the ability to understand and master functional programming will make you a better programmer, or deliver killer products at a rate so fast that your competitors won't even stand half a chance to play catch up with you... if you believe in Paul Graham.
No, this post is not about Lisp, or the superiority of another functional programming. This post is just a step by step step through over a simple lambda expression code, completed with screen captures, and debug values, so that hopefully at the end of this post, you will have a better understanding about what lambda expression is, and how it operates.
Let me start off with a code snippet:
public void RunTest2()
{
DisplayValue((b, h) => b + h, 5.0, 10.0);
DisplayValue((b, h) => b*h, 5.0, 10.0);
DisplayValue((b, h) => b - h, 5.0, 10.0);
DisplayValue((b, h) => b / h, 5.0, 10.0);
}
private void DisplayValue<T, U>(Func<T , U, double> delegateReturnValue,
T input1, U input2)
{
Console.WriteLine("The calculated value is " + delegateReturnValue(input1, input2));
}
Basically this is a subroutine to get the following output:
The calculated value is 15 The calculated value is 50 The calculated value is -5 The calculated value is 0.5
If you don't understand what's going on, don't worry. Because I am going to show you how lambda expression works, in a step-by-step manner.
Launch your debugger, place a break point at the the first line:
Note that at this point, the b and h are not defined. There is really nothing to see at this stage.
Press F11, step into the DisplayValue method. Note that we are stepping into DisplayValue, the lambda expression we define above hasn't been executed, yet.
Note the function delegate delegateReturnValue, the T and U refer to the type of the two inputs, respectively, and the double is the return type. In this case, we dictate that the return type is a double. delegateReturnValue is a function handler, meaning that instead of storing a variable, or a pointer to a variable, it is storing a pointer to a method.
Think about this for a moment, the delegateReturnValue is a pointer to a method, which means that we can invoke the method at anytime we want inside the DisplayValue! So the break point, we can invoking the delegateReturnValue and pass in two input parameters, in this case, it's {input1=5.0, input2=10.0}.
Press F11 again, note that only now the lambda expression is invoked:
b, and h assume the input1 and input2 values. The delegateReturnValue is thus equivalent to the following function:
double PlusValue(double b, double h)
{
return b+h;
}
But instead of declaring a function, we use lambda expression to reduce the amount of typing.
Press F11 again, this time you are back to the DisplayValue function, in order to display the calculation result.
So that's it! That's how you can see lambda expression in action!
Posted by
Soon Hui
at
7:11 PM
0
comments
Links to this post
Labels: .Net, Code Sample
Wednesday, July 8, 2009
Gmail is Officially Out of Beta
For those of you who still don't know, our much-beloved Gmail is finally out of beta!! After staying in beta for 5 years, and long after it vanquished other webmail clients to emerge as the best email system, not to mention twisting the stretching the definition of beta to a point that the term "beta" no longer conveys any meaning, finally it decides to scrap the beta label, hurray!
Also, I note how hard it's to post to news aggregator sites such as reddit.com, digg.com or hacker news. The moment I got the announcement from my rss, the link had already being posted on those aggregator sites. Internet has really taken the meaning of "breaking news" to a new level.
Saturday, July 4, 2009
把悲伤留给自己
能不能让我 陪着你走 即然你说 留不住你
回去的路 有些黑暗 担心让你 一个人走
我想是因为 我不够温柔 不能分担 你的忧愁
如果这样 说不出口 就把遗憾 放在心中
把我的悲伤 留给自己 你的美丽 让你带走
从此以后 我再没有 快乐起来的理由
把我的悲伤 留给自己 你的美丽 让你带走
我想我可以忍住悲伤 可不可以 你也会想起我
是不是可以 牵你的手呢 从来没有 这样要求
怕你难过 转身就走 那就这样吧 我会了解的
那一年,大概是五年前吧,我跟朋友去看《江湖》这部戏。那是一部怎样的烂戏啊!故事情节狗屁不通,导演用时光交错的方法来交错拍主角的命运,搞到观众一头雾水。戏散了之后,我和我朋友怔怔望着对方,不约而同的问彼此到底这部戏是讲什么?从那天起“江湖”就是烂戏的代名词。
戏虽然烂,可是还是有一个亮点,就是林苑在戏中唱的一首歌。
对了,就是这首:把悲伤留给自己。
这其实是一首老歌,如果没记错应该是民歌年代所创。蔡琴唱过,陈升也唱过。蔡琴版本低沉婉约,听起来像在月光下,与爱侣互道别离,不知相见在何时。两人之间没有哭天喊地,没有大吵大闹,只有深深的遗憾。月有阴晴阳缺,人有悲欢离合。只是希望夜深人静的时候,你会想起我。
陈升的版本感觉没有那么沉重。陈升的歌声激昂,转到低沉之处则流露出淡淡悲哀。这像是在火车站送走女友,想起过去的点点滴滴,一丝丝不舍。若干年后,当我们想起这一幕时,心里还会有点刺痛,偶而还会埋怨为何自己年少轻狂,不懂珍惜一段感情。
林苑歌声活泼跳脱。在江湖那部戏里,余文乐认识了一个妓女,然后跟她发生了感情。余文乐跟她说他要去刺杀一个老大,然后最好笑的是他还说他爱她。杀手爱妓女,这当然不是普通的爱情。那妓女觉得他很傻,把他痛骂了一顿。看见他没有反应之后,突然牵着他的手往前跑,到了一间夜总会方停下。她就在他手上写了她的地址,凝视着他,忽然抱着他,哭着对他说如果还活着的话可以去那里找她。
背景就是这一首歌。林苑的歌声带出了两个社会边沿人的爱情的无奈。一个逢场作戏,一个命不保夕,两人相识,激情过后,彼此对对方有了归宿感。可是命运却不允许他们在一起,所以只能把悲伤留给自己。那幕结束后我看看四周围,发现不少人在悄悄饮泣,这应该就是整部戏里面最感人的一幕了。
下面就是这首歌不同的版本,希望你会喜欢。
忽然想起,其实还有一个民歌版本的,可是由于我找不到,所以就不在这里介绍了。
Saturday, June 27, 2009
Celebrating the Achievement of Geeks--Netflix Price 10% Barrier is Finally Broken
Nexflix challenge, the challenge that is offered to anyone or any team who can improve the current Netflix movie recommendation system by a margin of 10%, is finally over.
Two front runners in the contest, Team Pragmatic Theory and Team Bellkor, joined forces and submitted an algorithm that was 10.05 percent better than the current system, that makes them eligible for the prize.
Machine learning and Artificial Intelligence have a sweet spot in me, and although I didn't join the challenge, but I also feel happy for their achievement.
The geeks have done a great contribution to the world, but the monetary reward they got was paltry at best. Nonetheless, I am happy to see that Nexflix challenge is finally broken.
Friday, June 26, 2009
The Bugs in wsdl.exe
wsdl.exe is a tool, come bundled with .Net SDK, that allows the generation of XML web services and XML web service clients from WSDL contract files, XSD schemas, and .discomap discovery documents. But unlike other excellent offerings from Microsoft, wsdl.exe is buggy, and is unable to handle a slightly complicated situation, let alone a real world wsdl file.
I've used wsdl.exe, and I spent 2 days of frustrating time to learn about it, wrestled with the bugs-- and I failed to get what I want. I have to write this, and hope that Microsoft people will notice and take action.
The first issue it fails to handle sequence with complex element. You would think that in today's webservice environment, a sequence of complex elements is a norm. But apparently Microsoft doesn't think so, and this results in inability of wsdl.exe to handle a sequence of complex elements.
What if you insist on using wsdl.exe to generate proxy class for element with a sequence of complex types? You will get a cryptic exception:
unable to import binding * from namespace *- unable to import operation *- the datatype * is missing
The second bug wsdl has is that it is not permissible to have two web methods that have the same return signature. Yes, if one method returns a type of ComplexType, the other methods must have a different return type. Failing to do so will result in an System.InvalidOperationException: The XML element * from namespace * references a references a method and a type exception.
Note that in both cases the messages are cryptic. You won't actually know what's going on behind the hood. And this is the most frustrating of all. You don't know whether you fail because the tool is lousy, or because you are not doing things right.
I would like to hear suggestion about alternative proxy code generation tool that can really handle a real world wsdl. Any ideas?
Posted by
Soon Hui
at
7:57 PM
0
comments
Links to this post
Labels: .Net, Microsoft, WebService
Wednesday, June 24, 2009
How to Encrypt a String in .Net and Decrypt it Using mcrypt_encrypt in PHP
Sometimes you have to encrypt a string using .Net library, and decrypt it back in PHP, or vice versa, or across other languages. I have a webservice which is written in PHP and a .Net program that calls the webservice. In the exchange I would have to encrypt a string at .Net's end and decrypt it in PHP end.
The encryption and decryption in .Net is pretty straightforward; all you have to use is the Cryptography library in .Net. Examples are abound on Internet, so you don't have to crack your head to find a working solution and modify them to suit your needs. Similarly, it's easy if you want to do encryption and decryption in PHP.
But to get encryption and decryption thing to work on different languages can be a bit tricky. I have spent quite a lot of time to make things to work. So here I am now posting my code, and hope that it will help other people.
Encryption in .Net. In this example I take a string, and convert it into encrypted hexadecimal string.
private static string CreateEncryptedString(string myString, string hexiv, string key)
{
RijndaelManaged alg = new RijndaelManaged();
alg.Padding = PaddingMode.Zeros;
alg.Mode = CipherMode.CBC;
alg.BlockSize = 16 * 8;
alg.Key = ASCIIEncoding.UTF8.GetBytes(key);
alg.IV = StringToByteArray(hexiv);
ICryptoTransform encryptor = alg.CreateEncryptor(alg.Key, alg.IV);
MemoryStream msStream = new MemoryStream();
CryptoStream mCSWriter = new CryptoStream(msStream, encryptor, CryptoStreamMode.Write);
StreamWriter mSWriter = new StreamWriter(mCSWriter);
mSWriter.Write(myString);
mSWriter.Flush();
mCSWriter.FlushFinalBlock();
var EncryptedByte = new byte[msStream.Length];
msStream.Position = 0;
msStream.Read(EncryptedByte, 0, (int)msStream.Length);
return ByteArrayToHexString(EncryptedByte);
}
public static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}
public static string ByteArrayToHexString(byte[] ba)
{
StringBuilder hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}
There is one thing to note. The key size must be 16. Which means that key parameter must be a string with 16 characters. Or else the encryption won't work and will throw a System.Security.Cryptography.CryptographicException : Specified key is not a valid size for this algorithm exception. Also note that the hexiv must be a hexadecimal string with 32 characters, meaning that every character inside the hexiv must be hexadecimal (0-9, a-f).
On the PHP end, here's how you do the decoding:
$cipher_alg = MCRYPT_RIJNDAEL_128; $decrypted_string = mcrypt_decrypt($cipher_alg, $key, $encrypted_string , MCRYPT_MODE_CBC, trim(hex2bin(trim($hexiv))));
Where $encrypted_string is the encrypted string returned by the above function, and the hexiv is the same as the hexiv in the .Net code.
Subscribe to:
Posts (Atom)





