Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Monday, August 5, 2013

Readability Measures in C#

Readability measures, such as the Gunning-Fog Index, Automated Readability Index or the Flesh-Kincaid Index are well established and widely used formulas that basically compute and roughly assess the difficulty in reading a piece of text. These scores generally produce an approximate representation of the US / UK grade level needed to comprehend the text. For instance a score of 8.2 would indicate that a text is expected to be understandable by an average student in year 8 in the United Kingdom or an 8th grade student in the United States. These kinds of scores are used to assess readability of school-books before their publication, or as a requirements by law of certain maximum scores for insurance policies and terms and conditions (see the Wikipedia page links, above for example uses).

There are some online websites that allow to score texts in such a way, e.g. http://www.readability-score.com/. However, when you need to use these scores in your own code and applications, it's preferable to have your own implementation or third party library that you can call upon to get things done.

Unfortunately, C#.net suffers from a limited open-source repertoire of libraries and code-snippets (relative to e.g. Python or JAVA).  This is why I've written up a quick implementation of some readability indices in C#.
  • Automated Readability Index
  • Gunning-Fog Index
  • Flesh-Kincaid Index
Automated Readability Index is probably the easiest one to compute, as it is the only one of the three measures that relies on character counts as a measure of word-complexity, rather than syllables count. This also means that it can be applied to different languages, and not just to English.

public static double CalculateAutomatedReadabilityIndex(string inputstring)
        {
            int charcount = BasicNLP.RemoveWhitespace(inputstring).Length;  //space characters need to be ignored in character count.
            int wordcount = BasicNLP.Tokenise(inputstring).Length;
            int sentencecount = BasicNLP.SegmentSentences(inputstring).Length;

            double indexval = 4.71 * ((double)charcount / wordcount) + 0.5 * ((double)wordcount / sentencecount) - 21.43;
            return indexval;
        }

The fourth line of code inside the function is the actual formula for the index computation. As you can imagine characercount, wordount and sentencecount are relatively straight-forward (for sentence segmentation I've simply checked for few common sentence punctuation symbols). Also to note is that in my code I've set-up a separate static class called BasicNLP that contains these utility functions, in order to keep the code organised.

The formula to compute the Gunning-Fog index (5th line in the code below) is very simple again, except that instead of character count, count of complex words (i.e. words consisting of three or more syllables) is used.

public static double CalculateGunningFogIndex(string inputstring)
        {
            int sentencecount = BasicNLP.SegmentSentences(inputstring).Length;
            string[] tokens = BasicNLP.Tokenise(inputstring);
            int complexwords = BasicNLP.CountComplexWords(tokens);
            int wordcount = tokens.Length;

            double indexval = 0.4 * (((double)wordcount / sentencecount) + 100 * ((double)complexwords / wordcount));
            return indexval;
        }

Finally Flesh-Kincaid uses the total count of syllables rather than the count of complex words (i.e. words that have three or more syllables), but is otherwise a rather similar formula.

public static double CalculateFleshKincaidIndex(string inputstring)
        {
            int sentencecount = BasicNLP.SegmentSentences(inputstring).Length;
            string[] tokens = BasicNLP.Tokenise(inputstring);
            int syllablescount = BasicNLP.SyllableCount(tokens);
            int wordcount = tokens.Length;

            double indexval = 0.39 * (((double)wordcount / sentencecount) + 11.8 * ((double)syllablescount / wordcount) - 15.59);
            return indexval;
        }

Computing the syllable-count isn't too difficult either, especially as I found a function on the web that readily achieves this, and roughly does the syllable counting job.

     public static int SyllableCount(string word)  
     {  
       word = word.ToLower().Trim();  
       int count = System.Text.RegularExpressions.Regex.Matches(word, "[aeiouy]+").Count;  
       if ((word.EndsWith("e") || (word.EndsWith("es") || word.EndsWith("ed"))) && !word.EndsWith("le"))  
         count--;  
       return count;  
     }  

A simple console application in C#.net is available for download (MIT open source license, unless otherwise stated, .net v. 4.5), please use with care and at your own risk! Some of the measures can also vary slightly from other tools, which mostly has to do with how the syllables are counted and slight differences in the indices measures. The way I use it at the moment is that I calculate an average of all three, to get a more stable measure.

Download c#.net code

Wednesday, May 11, 2011

AJAX UpdatePanel in ASP.net fully explained!

Tip: avoid the ASP.NET update panel whenever you can!

Update Panel is a quick and (very) dirty way to enable some AJAX on an asp.net webpage. Simply put one or several Update Panels onto a page, with one scriptmanager for the page, usually you'll want to set UpdateMode of the Update Panel(s) to "Conditional", and in case you have user-controls on your page, you might need to set EnablePartialRendering="true"  (this is by default set to true I believe) and it often seems to work just great, you get those famous flicker free partial page postbacks that are soo characteristic of AJAX. Unfortunately under the hood the updatepanel causes a full reinstantiationation of the Page’s control tree and every single control runs through its life cycle events.

Problems

I can understand that this abstraction offers certain amount of familiarity and simplicity that maybe some naive programmers will welcome very much, however it is misleading and utterly non-"ajaxy". Just imagine that you generate request and other parameter specific HTML for the same resource on the fly (this is altogether not at all uncommon with many dynamic web 2.0 applications), and you need some AJAX functionality on that HTML-page then the update panel will be an utter nightmare. Since the so called AJAX update-panel actually re-instantiates the entire control tree and runs plugs into the page-life cycle behind the scenes so that all the control events can be accessed nicely from code-behind, your dynamically generated page would need to be re-loaded from the viewstate or session state manually (kinda sucks)!!! See this post, but especially this post to illustrate the extra overhead on your side to achieve this.

Try... get this :-)

Obviously this seems too much work on server side, when all you wanted to do is send/retrieve a little bit of data to your web/db-server asynchronously. The whole idea of AJAX is that you update a small area of the page that needs updating since most of the HTML can stay the way it is a lot of bits on the wire & server processing time can be potentially saved. The side effect of which is a flicker free, quick, responsive web-page. With the asp.net update-panel it seems the main goal of the control is a flicker free update. I found a post that highlights the common mistakes with the update panel where some comments sadly point out the misleading opinion that this is a down to earth logical design. The truth is that once you know what the update-panel does exactly you can live with it, in some basic situations it might be quite alright to use it, but  it certainly isn't good AJAX by design by any standard.

The illustration below illustrates the desired AJAX scenario:


So problems begin if for example you generate controls dynamically based on the first page load, or by user-interaction, this is very common in todays dynamic web. If an update panel is used in such a common scenario then it is necessary to keep track of the controls that have been generated - usually this has to be done in the viewstate, and the framework doesnt do it for you, you do have to code up the viewstate state preservation (i.e. saving / retrieving from viewstate at the right time of the page lifecycle) yourself. This can bring a great deal of unexpected and most importantly unneeded complexity.

Of-course you can decide to stick with the update panel [for some very, highly, extremely strange reason :-)], and you can take care of the state management of dynamically generated controls as it is described in this stackoverflow.com post, or this one. Have fun ;-)...

The Solution (page methods, etc...):

Fortunatelly we can simply use direct AJAX calls. As Microsoft engineers realised that update panel (in most non-trivial scenarious) simply sucks and provided us with alternatives, specifically page methods, these are great, essentially a webservice type of method that can be declared as a static public method in my webpage class, raher than having to create a new web-service to expose the method. Page-methods allow to keep code in one place and I love them. Data is by default returned in JSON, but the format can easily be changed to XML for example (since JSON, isn't capable of representing certain complicated self-referential data-item). Check out this page for a good example of pagemethod in use.... Of course standard webservices can also be used, the options are discussed in some detail withing this great MSDN Magazine article written by Jeff Prosise on some options, other than the UpdatePanel.

JQuery or for that matter any other ajax supporting javascript library can be used instead (quite easily) to take care of asynchronous server communications, the guy from Encosia shows in a neat short article how to do this in jQuery - check it out.

Finally don't forget that if you use any postback controls, such as HTML Buttons, or ASPButton, ASPLink, the OnClientClick must contain something like "return false;" otherwise a page post-back occurs anyway as the server-side generated button click-event triggers. If you follow up these resources above, you will find that using AJAX instead of the update panel is actually very easy once you've done it a few times.

Conclusion

In conclusion update panel is nasty, it costs a lot of bandwidth and a lot of control is lost due to the nature Microsoft decided to hook it up with a pages's lifecycle. Some of that control can be regained by using the client side page-scrip-manager object as described on this page, however it doesn't resolve need for manual state-management of dynamically generated controls!

Thursday, January 27, 2011

Fuzzy Logic (Building a Fuzzy Inference System)

Boolean Logic has been around for many years now, however "Fuzzy Logic" is a somewhat more recent "beast", Prof. Lofti Zadeh proposed fuzzy set theory back in 1965.

In this post I want to show online resources that will illustrate that Fuzzy Systems can be simple and most of all are very elegant way to solve some problems.

I had fuzzy set theory in one of my data-mining modules during my university time, studying comp science. It was straight forward but then I never had to make much use of it (only a tiny bit in my PhD). So anyway, let's just jump into it!

  1. A great way to start is to work through a real illustrative example, in which a Non-Fuzzy solution is explained, and then the Fuzzy solution is introduced and is shown that it actually does work better... <<This page does exactly that>>
  2. Get this by looking at many more examples... <<Here>>
  3. Try to build a Fuzzy Inference System yourself - based on the idea of "learning by doing"... <<this can be done here>> (note: this is Matlab based, but this doesn't matter at all)
  4. Research papers making use of Fuzzy sets might be usefull cheap option to learn more (<<for example>>), check out a book (or two) and play with a relevant code library.
Software Libraries

Python: pyFuzzy, peach || Java: RockOn Fuzzy, Funzy || C#.net: DotFuzzy

Great Books