Translate

Showing posts with label Jv Ravichandran. Show all posts
Showing posts with label Jv Ravichandran. Show all posts

Sunday, 19 March 2017

#IAmNewIndia

A new vision proposed by the Prime Minister of India, Mr. Narendra Modi, in the India Today conclave, 2017, in which the new India would be all about opportunities and hard work, sets the tone just right for out of the box solutions to some persistent problems over the past century.

That the Prime Minister has announced more reforms in redundant legislative and legal practices and laws is another right step in the right direction for the BJP led government that promises the people of India for some breathtaking changes and initiatives in the near future. The existing techniques used by the human resources, administrative affairs, planning have more often than not led to more problems than resolving them.

The approach, as the Prime Minister said in his address, has to change into a more holistic one. Current planning, at least since 2000, has heavily focused and relied on the Information Technology sector to provide jobs and stabilize the employment ratio but this has caused innumerable side effects like nurturing rogue real estate manipulators, which has resulted in greedy land grabbers taking control over a region, to the effect that even the politics of the country got changed due to it but more importantly, it increased the corruption mafia's hold on many administrative matters as well as affecting the business due to the swing in favor of the greedy manipulators and the whole situation gets back to square one for the people.

To reduce the burden of employment in the IT industry, which projects 'lottery' like dreams to the education sector that there are more riches in the IT jobs than in show biz, a parallel and alternate means to earn should be made available to the people so that anyone, of any age, could do some work and earn money from the government directly, increasing the bonding of people with the country and the government, thereby reducing the scope to favor criminal ways to earn money and reducing the scope for terrorism in the country, and make way for a robust economy with a steadily improving employment ratio. The mafia mentality that ultimately shows up as a mob culture to the outside world, when activists whip up chaos in cities, is actually a product of this system of the 'controlled' and 'organized' sector of the country that has, somehow perfected, 'organized dishonesty'.

So, the agenda-based 'planning' measures and processes should be forsaken for newer approaches with a focus on a leaner approach in governance.

There are only two elements that bother the progress of the country - one, work and the other, money. With just these two elements, the approach is to provide a new model of work - earn from anywhere doing anything!

This new model of work, earn, from anywhere, for any type of work, would also reduce the burden on the government to plan for employment with uncertain data and improve the unemployment scenario in the economy plus it will greatly reduce crime as the means and opportunity to earn for everybody will be readily available.

Other advantages of such a work model are that it will enable social changes with increased, healthy interactions between the people and the various segments of governance. For instance, in India, the saddest of all social evils is the fear to help a rape victim or an accident victim even if the inclinations are right, due to the many pitfalls with hospital regulations and the police, which is, anyway, the most abhorred unit in the country.

When this model of work is implemented, due to the associated evidences of work (that need to be submitted for the government to approve that it is part of the category for which a payment rate is set), the transparency will act as deterrent for the corrupt or ignorant laws 
and the confidence, that the government knows that the accident victim or the rape victim was helped by this citizen and vouched for by a witness, will help reduce the fear of getting framed, .

#IAMNewIndia


A government enabled/driven. powered service that would provide for means to earn money by doing any work that a citizen may want to like cleaning the street, helping an accident victim (which is the most troublesome and feared of events due to the various red tape associated with the hospitals and the police and the bribes associated with it would majorly improve public welfare because this service model will not only have everything documented and the police that there would be no possibility that the person helping an accident victim would not get harassed for doing a good job), catching some miscreant on the streets, providing food to some needy, helping an old woman or man crossing the street, fighting against over-charging auto rickshaw driver or helping a girl in distress or helping some needy and if the government cares, just about anything that is considered useful for governance.

This model would accept work done on the streets or at any place, which could be logged in by the citizen with a valid Aadhar card and attested by any other citizen that "Yes, the work for which the person is seeking compensation has been validated" with a screenshot or a mobile picture uploaded to the server for which adequate, appropriate compensation could be remitted by the government, online, directly into the work submitter's bank account or even a PayTm account.
The country has lots of problems - cleanliness, waste management, fringe elements that have no clue nor business to be in any region as they have nothing to do and this lot numbers in millions, in the country, traffic discipline, bribery as a culture in many departments of many organizations (even now, in 2017, driving license can be obtained through bribes), tax evaders at the level of employees of well paying organizations where producing and getting away with fake travel bills, fake fuel bills, undeclared income, false declarations of investments, fake rent receipts to claim HRA is all considered as the 'normal' and anyone who thinks otherwise loses their job or is targeted - and the diktat that it is the government that should handle all the problems and provide solutions is the wrong attitude and the chief cause for such blatant practices to be there in our daily, routine life. 

Thursday, 4 August 2016

Angular material - Cards tip

The fact is, that many times, we miss some obvious solutions that exist in the form of a simple attribute of an object and waste time using techniques that are no longer applicable because of the way technology and tools have emerged and those who do not recognize either end up with redundancies - in practices, techniques and attitudes.

So, when I read a question that was about managing a user login that was not returning to the login page after the user logs out or the session expires, I noticed the usage of a 'localStorage' object, which is the most common thing to do but if instead, the sessionStorage object were to be used, many knowledgeable would see that it solves some major problems straight away, without the usage of any special 'routers' (the software ones), it became clear to me that what the knowledgeable know is not through knowledge or more years of study but due to their experience.

AngularJS and Material (or for that matter, any technology that uses declarative forms of programming - declarative, in this context, does not mean annotations (as in Java) or attributes (as in C#), but as in programming through attribute (as in XML) values and directives (as in AngularJS)) are quite likely to put many of its programmer users in such situations.

One such instance that I wanted to share is inspired by another question on the same forum that was about deciding on AngularJS as a language to use in the project and what should be the criteria in making such decisions.

Rather than elaborating far too much on what could be bread and butter for many, suffice it to say, here goes !





Layouts, for the mobile, any-size-device, and the web, can be as simple as

<md-content layout-gt-sm="row" layout-gt-xs="row" layout-padding border="solid">

and the same layout fits for any device.

One of the most effective example of what should be the criteria for deciding on a language for a requirement (web or mobile app, though, only!)


Monday, 7 December 2015

The Scrum Planner

Organizing the story board is usually dependant on the automated tool that is used. Often, when we use a real life story board like a white board, there are the same maintenance issues that usually pertain to communication. How to convey the right picture to the team?



When a task is slipping or lagging, do simple updates in stand-ups help or do you need an additional input? And if you do, where should the output, a graph or alerts, be conveyed to - the team, the management or presuming you are doing Scrum, with the ScrumMaster?


Role based users - the Scrum Planner is accessible only for Scrum-mers and the Sprint Planner only for the Sprint-ers !


The Scrum / Sprint Planner does just this - it helps you with a template of pre-assigned roles and responsibilities as defined in Scrum and as an experienced Agile practitioner, like me, would use it. Developed for Excel, this add-in is the complete solution for all your Scrum needs. Follow my blog to stay updated on the release date for this tool.


Sunday, 1 March 2015

OMG, my Blog is a genius ! ;)

On 27th February, my blog had 203 visitors.

I frequently look at the stats of my blog and this stat seemed singular to me. So I decided to apply my mind a little to see what was it that could have generated so much interest on a particular day. I dwelt on my blogging style, the content and external factors like a new domain name, a new product etc. Here is what I discovered.

My blogging style

Somehow, I had adopted a practice not to ever blog on my personal life or write in a certain style that I use while writing an article or in a casual form.

I had maintained this blogging practice for over 7 years of blogging but since last year, I have noticed, on hindsight, that I have used that 'funny', descriptive tone in a few posts and not the bland, descriptive style that I use for technical/technological posts. I attribute this 'change' to either my recovering my health for over two years and due to which I have more myself as company or to working on my own and by myself.

The reason I mention this is so that I could share another fact that could not have been shared without this preamble.



The content

The reason I also want to mention this in such a tone is not to brag about it but because during this period, I had added a widget for my Calendar Pane app for Excel 365 without checking its size !

And I had 203 visitors to the blog to see such a great event, when without the over-sized (full size) image, the number would be in mid-20s !

It is remarkable that so many become so interested to make note of a 'deviation' than if the blog were in a perfect condition. It is quite likely that the 'sick' state of the blog was 'symbolically' represented to such visitors as a human being with an ailment, who people visited out of care and concern !

To elaborate on this rampant human trait nowadays, due to the 'comparison techniques of communication' - the 'like a' (just like 'is a' in Object-oriented terminology) style - that many adopt in their zest to be cleverer than others, a mouse enters a home and a nutcase landlord that believes he/she has a 'right' to disturb tenants living below randomly because they live in the building that they own (even if the other is a rightful owner or pays rent to some other landlord!) because they have heard that a mouse also lives in that house for which rent has not been paid because they have created some rent agreement with such a clause that no other living being must live in the house other than the registered names, the deviation is represented for certain crass people as a breach in agreement (unreasonable people is not the word to describe them, they are ridiculously insane people, who live because they have the money to indulge in whatever they want) but without making any charges.

To elaborate more in the same 'like a' way, the mouse is a deviation from what was agreed (not agreed is not what you can argue is their belief - such insanely unreasonable mindsets) in the tenancy so, in return, they believe that they can indulge in their psychotic pleasures.

It is no co-incidence but a serious fact that if addressed correctly can solve a lot of 'humane' problems that face us all in our daily lives.

Of course there is another reason why I found it necessary to share this fact, aside from the preamble that it afforded me, it also helped me draw a parallel to how my products have fared.

I have had more than one career (much like how many mention that they have had more than three wives and are in the process for more !) - one, as a software programmer, two, as a technical trainer, three, as a mentor/coach/evangelist in Agile and of late, as a consequence of my stint at recovering from the injury to my shoulder and arm, as a freelance software consultant and as a product specialist.

It is as the product developer that I am more concerned with, which because of not making me money, puts me in a different light, probably a spot (pun unintended)!

The fact is, I started developing products way back in 1994 under the label of GREYcells and although it found mention in PCQuest and in the form of a press release, it never made any money. The possible reasons were not sufficient financial backing nor the required marketing thrust or help.

Then recently, I developed a few Android apps and put it on the Google Play Store.

Again, I was under duress, but this time, due to the injury. Again, as previously, I turned to jobs (!) as a means to earn money and now, for the third time, as I hit the market, with a product for the Microsoft Online Store, I find that I have not got the response that I was looking for although, a lot better than what the predecessors got, I find a rather simple phenomenon (of course, there are humans involved, too.

External factors

For instance, if a certain practice (angry retaliation or spite would be a more appropriate description) is adopted in a city or town or village, where every mistake committed by a government or an official or a superior, is replicated as another mistake of the same kind, elsewhere, to not only serve as a reminder but as also a form of revenge in a fit of jealousy then people in the 'replicated' city or village would not know it is a vengeful act but only as it was in the other context, a mistake or incompetence) that explains why many problems, social and political, seem the same within the same country or region.

The problems are not because of laws or regulations but because of people and their attitude.

And it is here that the parallel that I wished to draw with the 203 visitors visiting my blog to see a ill-placed image, when the blog had been doing well for more than 7 years !

Some people associate themselves in a certain way to life and so expose themselves to be manipulated in a certain way (like Greenpeace in India) that they become a 'representation' of a certain stereotype, of a 'curse' even, and who, due to years of doing the same things, and without having the 'varied' windows of different careers or different talent as a 'contrast', don't even get to know how they have become a 'curse' !

In India, many would know it from historical reference, where caste-ism used to expose such people; it is known as discrimination in today's world.

Incidentally, it was around the same dates that I suffered the brain hemorrhage that caused injury to my right shoulder and arm and around the same date/month, that another member of my family had a similar but more fatal injury. 

I must be more careful around the month of February because it seems during this month, as astrologers put it in India, 'Shani' hovers over me, in the form of  some factors that make people confused between 'something wrong' with a thing (a blog) - it was the Television that blew up smoke ('phook gaya' is also used in the context of the brain and the car), when I got injured - and 'something wrong' with a person ! :D 

Does it mean that around this month 

(and why only February? Maybe the person visits India or near my house or known to me? Or some psycho who knows me more than I do), 

somebody takes special interest in me and says, "Ok so tell me what is he doing nowadays?" or "how is he?"

Be what may, many 'prejudices', 'religious misgivings' (for example, "Lord Siva is calling you" !)) is likely to get solved by simply co-relating Google Search (SEO) or web marketing/network and human networks and word-of-mouth gossip or vendetta mercenaries. ;)



Friday, 5 December 2014

$.when then and then JavaScript...a single-threaded-monolith-of-interpreted-disaster-for-maintenance :) !

The funny thing is that when JavaScript and jQuery are used in conjunction, it can often be a little puzzling as to which event is getting propagated when and whether to use event propagation or event bubbling to ensure that the right sequence of events have been handled or not and when all these aspects did get resolved, as I sat back to contemplate on the immense, combined destructive power of JavaScript and jQuery together not through any power tools but in the way that they resolve each others' problems such that the end result looks more like a compound that could have confounded the best of scientists put together, I realized that that here is an example that could be likened to the splattering of debris from space, to the 'distributed' missile that "Iron Man" goes to demonstrate to the terrorists, to the 'open for interception' messages strewn across the social media that eventually conjoin (if such a word exists) like in the Terminator (the villainous ones who roll back from liquid droplets to human form!) and serves, best, as the prototype to the theory that if art is a reflection of life then software, AI and design patterns (software ones that is) are 'represented' algorithms of human's interactions. 

Tough and tasking, this may be, I can understand, especially if you are reading my blog with a cuppa and thought it would be a breeze to read through my blog ! 

But it was necessary, believe you me, this roundabout, Thomas Hardy-like obscurity-bordering-on-controlled-rant narrative because it is only upon describing the problem statement in detail can you understand or comprehend what the above observation, and the title above it, means !

The problem statement is the usage of two asynchronous mechanisms (not methods) that need to 'listen' (change in location position co-ordinates), 'communicate' (save the change in location to the DB) 'intelligently' (i.e., not as a dumb client that can simply wait for any response and 'redirect' as if passing the blame to the next page!) through an AJAX call to a VB.Net WebScript Service method (which means server-side technology) via JavaScript, as a JSON object, and to finally (the compound), ensure that the GeoLocation call has been successfully completed before calling the Web Service Script method and on return (I had never experienced before (in my mind, that is) how many different places that a call to a function could return to - a JavaScript call can return to any DOM object, it can return to the last line of the calling function, it can return to a callback, 

(Ah, we all know that? Read on for a few minutes more and you will realize why dismissive attitudes are not only demeaning to progressive minds but also needless !))

behave like the dancing hurricane (or typhoon) that deceives to deceive - that is quite a lot of integrity for a scripted, interpreted language,

despite all that junk said about JavaScript being a single-threaded-monolith-of-interpreted-disaster-for-maintenance - ah, so here we are,

So. when a call to a location services and a call to save the consolidated data occur synchronously but also must ensure that the save data will occur only upon successful location seek, the one best way that is known to be used is the 'callback' - which is much like an illusion in JavaScript because, whether you like it or not, the subsequent lines of code after the location seek will be executed.

For instance,

// Lines n to n+25 in "some .js file"
function somefff....{
    if (navigator.geolocation) {
        var positionOptions = {
            enableHighAccuracy: true
        };
Line 1     navigator.geolocation.getCurrentPosition(function success1(position) {
                var brlat = position.coords.latitude;
                var brlongitude = position.coords.longitude;
                sessionStorage.setItem("breakStartlocation", brlat + "," + brlongitude);
             }, function (err) {
                 showError(err);
                 wctr = true;
                 sessionStorage.setItem("breakStartlocation", strlocationErrorMessage);
            },positionOptions);
        } else {
              alert("Location setting is not enabled or supported in your current browser!");
        }

// Lines n+26 

 Line n if (confirm("You have disabled location seek. Press Ok to reset your browser settings or Cancel to deny location information.")) {

}

else if ....{}

// Lines n+200 to 30 (or so!)

        options.success = function (result) {
            alert("Break saved");
        }
        options.error = function (err) { alert("Error");}
Line n+1        setTimeout(function() {
                          $.ajax(options)},3000);
                        }
Line n+1+1 (for the sake of brevity!)

return saveResult;

}

In the above lines of code, Line 1, Line n and Line n+1 and Line n+1+1 fall into a sequence because of JavaScript's execution mechanism, despite the logical requirements, which is to ensure the sequence of the calls. Not a big deal, as the flippantly inexperienced may quickly quip not knowing that the Geolocation provider has made their service an async service, by specs and design!

This means that the calling code or object would have continued on to display the Confirm message, without waiting for the user to acknowledge to the browser (that has already received the location provider's request to seek out the user's location) that their location could be sought.

It also means that the Line n+1 Ajax call to the webservice method is already underway (even the Confirm dialogs can be of no use if the user clicks the Ok buttons real fast!) and while we are at it, we may as well consider the fact that the Ajax call may have already returned back to the calling page ie. Line n+1+1, too, has executed. So, the calling page that has to display (render) a different set of buttons and UI elements (CSS elements), must have a mechanism to determine if the save data call has been a success and here, is where jQuery and Ajax come to the rescue of JavaScript.

The zest for patching up is an age-old technique that has both its 'pros' and 'cons' (probably why it is called the 'jugaad' in India) and this zest is evident with the way many JS developers and designers felt and being more seamlessly tuned to each other's needs than the 'boxed' up Microsoft or Java developers, jQuery is almost the way a poor man or woman cater to their family, a 'patch' here, a patch there - "Oh, does the event bubble up to the document object? ('Daya', in Hindi, means compassion but since CID, a Hindi TV serial of monumental moronity, has become symbolic of a person breaking open doors, unlawfully, it has now become synonymous with 'show some compassion for wooden doors'. What I mean is, desist. Desist from that lust to argue that a Document is part of the DOM.). Let us change the Ajax calls to return to the DOM than to elements or objects..."

This comparison is not meant to be derogatory because it is a "kind of" representation of how nature, too, responds (though in a more perfectly harmonized manner), adjusts and responds to adjustments again (much like the shifting of the tectonic plates to create mountains to change the paths of rivers to cause floods to cause erosion again to level up).

So, to keep the thread of continuity tight as I lead you through this incredible maze of Ajax event handlers, DOM and plain old JavaScript timeouts, let me quickly warm you up to the "Promise" offered by AJAX/jQuery.

Unlike the build-up, this post's ending is pretty abrupt - all you need is a $.when to wrap around the method call  -

// The calling method from another page (can also be interpreted as a DOM, for the sake of understanding this example.) From different page.aspx

$.when('methodTocall').then(func,func1); 


and a .then() with func and func1 representing the 'success' and 'not success' in the function call when it completes! So, what is the promise? All this can be handled with simple callbacks.

The 'Promise' is that you can line up any number of sequence to calls made to asynchronous methods

(ie., methods that make asynchronous calls but which desperately need a mechanism, not provided in JavaScript, that execute async calls, synchronously, but require coherence in sequence to enable manageable logic in execution, not just to tackle complex business models and demands but also for the benefit of testing frameworks and testability)!

but more importantly, as I experienced, I could manage two 'disconnected' events that had 'committed' synchronous activities attached, 'post-' the async call, that relied not on the 'traditional' HTML post or 'form' methods or elements but on CSS elements, which meant callbacks-had-to-'trigger'-an-execution-thread on the client-side upon successful completion (or not), which cannot happen until it happens at the DOM level and which the Ajax's document level event handlers like AjaxStart, AjaxStop, AjaxComplete, AjaxSuccess and many more provide.

But the real joke is in the parameters to the then() method - they, too, execute synchronously !! :D

Wednesday, 3 December 2014

A normal life, after all...

(Dedicated in aid of the victims of the Bhopal tragedy, who need lifelong support and help.)

A terrible, terrible sight
a terrible, terrible plight
it is not a matter of right
nor is it a matter of oversight

if riches are given more weight
over nature's might
then such, that does not become a human sight,
becomes the common's terrible, terrible plight.

Utter not nor hear not nor listen not to no evil
See not nor show not nor teach not to know evil
Make not nor buy not nor sell not no evil
Let not nor allow not nor bear not no evil

for the devil is not in the evil
nor in the 'evil' preached as the devil
the evil is the evil
not preached nor practiced nor known as 'evil'.

Normal work that lead to tragedies
normal play end in disaster
but time flies, faster,
to leave normal life that usually dies

all well said and done and taken in the right spirit,
but this terrible plight, that, that makes such a sight
that does not become common sight, a common, every day plight
still persists to be known as an 'oversight'.

Sunday, 30 November 2014

How to add dynamic rows in Javascript

One of the most curious case has come my way and it pertains to many aspects of software development but most importantly, to testing and the purpose of testers so I think this post becomes necessary as due to online projects and work done more than earlier, many 'unqualified' testers are giving 'opinions' on projects like 'user feedback' on products.

It is also possible that before going 'live' some project owners try to get 'user feedback' to make their system more robust, in which case, it can only be called an 'innovative' approach, but which obviously is more often than not called 'too smart' or 'too stupid' because what is applicable on a 'product development life cycle' is usually not applicable for a 'project development life cycle' and the resulting confusion can only be called 'immaturity' and 'malignant' because it only gives 'support' for 'excuses' made by the project owners to manipulate the 'quality' of delivery to their teams or to vendors or to service providers.

Many testers take it upon themselves to take 'moral' stands, where the issue is either a bug or a feature that may not be working properly. They are 'conveniently' backed by 'time to market' and 'management' theories on how much it costs them if their product is delayed and so undue pressures and compromises and 'jugaads' are initiated.

The whole point is in 'planning' and many get it right and many do not, as happens in the whole software development life cycle of any project.

So, when a solution 'demands' that rows must be added to a table and must be infinite in number upon the click of a user action at the client-side, Javascript and jQuery are the best languages (everybody in the software industry acknowledges this and knows it!) but the problem is how to test a scenario where the events, data and the actions themselves are to be dynamic.

I know, as do many mature Agile developers, that I can use Jasmine to unit test Javascript.

The 'wise' know the pitfalls and prepare a 'plan' to take care of the 'unforeseen' bugs that may occur at runtime for which it becomes important to be 'proactive' enough to identify the 'run time' aspects of the scenario and instead of preparing 'contingency' plans to mitigate the possible delay that may or would be caused by the complexity, they, instead, prepare 'plans' to 'corner' the developers. Seriously !

And many actually 'glare' at others who may know the technique and can do it but they themselves cannot!!

Now, why is such arrogance necessary when you can do your simple work properly by identifying test scenarios and have them tracked in a Google doc or a project management bug tracking system rather than indulging in blame games. The answer could be in the political atmosphere that surrounds a company or some problem totally unrelated to the project or work but which can be identified and best solved by the people themselves.

A question that normal people's culture and etiquette does not allow and some try to take advantage of it all that since the management or the HR are not tech savvy, they can get away with 'bluster' and 'bravado'.

And this is why it is necessary for HRs of organizations to read blogs and consult 'experienced' and 'mature' people before hiring and not rely on Facebook and other 'rigged' references. I remember when working with an organization, I would be called upon plus shared with, the technical and technological plans of projects and the necessary plans for the HR and the teams to make.

Simple thumb of rule for young developers or testers is be humble to ask for help. politely. When you have established yourself then you can go around stomping on everyone's feet but when it is time to learn, do not teach others more capable than yourself ! :)

All that is required is to understand your position and be humble enough to ask for help from other team members, and not 'grand stand' around that such scenarios cannot be tested or even developed !

The greatest disservice anybody could do to their team or even friends and family is to not admit that they were wrong but instead persist with blaming others for their own incapability in either 'testing' or in technique unless of course, hiring 'goons' to enforce that others do it for you without having to pay for the service and without admitting to your own incapability (as happens in Indian movies, where a 'goon' becomes a Doctor by having somebody else taking the medical entrance test to become a MBBS doctor) is an option available for you.

So, it does not even make it lack of knowledge or inexperience or immaturity but sheer 'unprofessional' attitude that does not exist in the IT industry.

I have had this experience and so speak from first hand experience that it is tantamount to a kind of 'cunning' and 'cleverness' that no management would want to associate with, so if you wish to make a career in the IT industry, do not indulge in such practices nor allow others, who may be doing it 'secretively' from 'outside'.

Here is one scenario, where you can add any number of rows to a table, using Javascript (knowledge of Html, JS, jQuery and CSS is required to run the example) and which somebody seems to have professed as 'impossible' and then trying too darned hard to prove themselves right!

// the output as it should be

                          








// Javascript


                        // HTML string to add to table breaks
                        var strBreak = null;
                        var strTxtBreak = null;
                        var rowTxt = null;

                        // used for determining number of rows added to table
                        var xx = 0;

                        // used for calculating distance of textboxes
                        var jk = 5;

                        // used for array index

                        var cell3 = "
";
                        for (var i = 0; i < w; i++) {                      
                            row = table.insertRow(i);
                            strBreak = "
 +
";
                            jk = jk + 5;
                            strTxtBreak = "

";
                            row.innerHTML = strBreak + strTxtBreak;
                            yy = yy + 2;
                            xx = i;
                            jk = jk - 5;
                            jk = jk + 55;
                        }
                        var j = 0;
                     
                        j = xx+1;
                        // Row for Notes
                        var rowN = table.insertRow(j);
                        //var rowN1 = table.insertRow(j+1);

                        // For vertical ruler

                        //var t1cell1 = "
";

                        // Set initial position values of elements
                        notesIconLeftValue = 14;
                        notesIconTopValue = jk;
                        notesAreaLeftValue = 40;

                        // creating style str for Notes
                        styleStrForNotesIcon = "style=" + "'position:absolute;top:" + notesIconTopValue + "px;left:-14px;" + notesIconLeftValue + ";" + "'";
                        styleStrForNotesArea = "style=" + "'position:absolute;top:" + notesIconTopValue + "px;left:" + notesAreaLeftValue + "px;width:310px;height:65px;text-align:left;background-color:lightgray;border-color:lightgray;'"
                        var cell5 = "
";

                        // HTML for Notes box row
                        var strNotesIcon = "
 +

";
                        var strNotesArea = "

"

                        // Inserting Notes row HTML
                        rowN.innerHTML = strNotesIcon + strNotesArea;
                        //rowN1.innerHTML = t1cell1;
                        jk = jk + 50;

                        // HTML for buttons
                                             
                        // Table 'tablebtns' into which to add buttons
                        var table1 = document.getElementById("tablebtns");
                        var k = jk + 55;
                        var l = k + 55;

                        // For continue shift button
                        var m = jk + 30;
                        var nn = m + 25;
                        var t1row1 = table1.insertRow(0);
                        // Table style and position
                        var cell1 = "
 +
Continue Work
";
                        t1row1.innerHTML = cell1;

                        eDiv.appendChild(table);
                        eDiv.appendChild(table1);

                        $('#box1').show();
                        $('#tablebrks').show();
                        $('#tablebtns').show();
                        document.getElementById("continueWork").onclick = clickContinueWork;

// HTML
<html>
     <div id="boxMiddle">
         <table style="position:absolute;top:10px;left:25px;width:305px;display:none" id="tablebrks">
         </table>
     </div>

        <table id="tablebtns" style="display:none"></table>

<style>

#box1 {    position:absolute;
    height:110px;
    top:180px;
    padding: 5px 5px 5px 5px;
    border:none;
    margin:25px;
    background-color:white;
    display:none;
}

#boxMiddle {
    position:relative;
    height:260px;
    /*top:145px;*/
    padding:4px 7px 2px 4px;
    border:none;
    margin:25px;
    background-color:white;
    display:none;
}

div.calloutContinue {
    background-color: #8EC127;
    background-image: -moz-linear-gradient(top, #444, #444);
    position: absolute;
    top:30px;
    left:42px;
    color: #000000;
    padding: 10px;
    border-radius: 3px;
    /*box-shadow: 0px 0px 20px #8EC127;*/
    margin: 25px;
    min-height: 20px;
    /*border: 1px solid #333;*/
    text-shadow: 0 0 1px #000;
    text-align:center;
    height:40px;
    width:145px;
}
.calloutContinue::before {
    content:"";
    width: 0px;
    height: 0px;
    border: 0.4em solid transparent;
    position: absolute;
}

.calloutContinue.right::before {
    left: -16px;
    top: 10%;
    border-right: 10px solid #8EC127;
}
.calloutContinue.right:hover {  
    cursor:pointer;
}
</style>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">

// The javascript code here

<script/>

Friday, 31 October 2014

1500 and Counting (no, not Tigers)

The most popular post in my blog is the one that has no tags to help search engines find it !! :)

Eh, what Google?

And I paid for Google AdWords spending an hour to figure out the right words to use ! :D

Wednesday, 29 October 2014

A little more CSS magic !

One of the coolest things about CSS and jQuery is the simplicity that you can achieve in design.

Here is an example of a simple timeline that I created with css



The vertical line is not a .gif or an image but a line drawn, given co-ordinates in pixels.

The CSS for the same is in this fiddle that I have created for you to play around with.

And with a little jQuery, the animation of the timeline becomes simply simple!

Monday, 25 August 2014

What to Unit test?

Going by the book is not really encouraged in today's wildly advancing technology world. If you, do, it will most probably leave you staring at the behinds of many. :)

Best way to keep yourself ahead is to be really good in your skill set; if it is a programming language, be on top by participating in discussion forums and communities. This will help knowing about scenarios that may never appear in your own project or lifetime.

Close to what I am getting at is this definition of unit tests by Martin Fowler -
Like most software development terminology, however, it's very ill-defined, and I see confusion can often occur when people think that it's more tightly defined than it actually is. 
First and foremost,  what to unit test depends on your commitment to testing. If you are very committed then chances are that your code coverage will be good. But over and above this,  you also need the skill with the unit test tool. For instance, the most common statement possibly used by almost all programmers across the world is the if (!fileExists) or within a try...catch block.

Is this statement testable? Should it be tested? To answer the second question first, the reason the answer is 'Yes' is because the line of code is expected to throw many exceptions -  DirectoryNotFoundException, FileNotFoundException and (yes) etc...So, the first question becomes important - is it testable?

Again, the answer is 'Yes' (left out italicizing it to make it more interesting! :)) but if you really do not know any syntax of existing unit test tool, how to write the test?

This question has always seemed important to me (to make a programmer move from the "Code-first syndrome" to a "Test-first-and-let-the-test-tell-you-what-code-to-write avatar") and so, I decided to list (well, sharing just one technique now (how to get and test a list of files from the file system in a unit test)...will share more later) here some of these common scenarios.

Aside from helping the code achieve the necessary quality benchmarks, unit tests should also be efficient and lean so that it does not weigh down the overall build or CI framework.

So, to write a unit test in the 'file exists' scenario,

1. If not file exists

Scenarios - as many as there are files (wild possibilities! :)) in a specified directory.

So, the unit test will want a list of files against which to test for some criteria.

The code will be something like this -

using System.Collections.Generic;
using System.Linq;
using System.IO;
namespace NUnit_Tests
{
    public class ClassUnderTest
    {            
        public List getListOfFiles()
        {
            string[] filePaths=null;
            filePaths = Directory.GetFiles(@"c:\cambridge\");
            return filePaths.ToList();
        }
    }
}

In  NUnit, here is an example of how to test the method most efficiently and ALSO in such a way that maximum scenarios can be tested with this approach !!

using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
namespace NUnit_Tests
{
    [TestFixture]
    public class TestClass
    {
        ClassUnderTest objInstance;
        string[] filesToExist = { "abc.jpg", "a.htm" };
        [Category("LongRunning")]
        [Test]
        public void LongRunningTest([ValueSource("Files")] string filePath)
        {
            Assert.That(Files.ToList().LastOrDefault(),Is.EqualTo("zzz.jpg"));
        }

        private IEnumerable Files
        {          
            get
            {
                objInstance = new ClassUnderTest();
                return objInstance.getListOfFiles();
            }
        }
    }
}

The snapshot below (before refactoring class names) shows the number of scenarios (equivalent of unit tests / asserts in NUnit or unit testing tools) that are now possible with this approach.



For example, you could test if the path is returned correctly with Is.SamePath or can test the number of files existing or if a particular file has a required extension and the possibilities are endless.



Sunday, 24 August 2014

KnockoutJS and AutoPostBack="true" - I

I had to check this out. What could be the difference if the developer were to use KO and not ASP.Net?

The only difference is the programming language of use - C# or jQuery / Javascript.

The resultant output is this below


No button click event just the AutoPostBack property of the drop down list set to true.

I will first share the ASP.Net code and then dwell into the equivalent KO code.

You need JSon.Net installed and referenced to the project, an app_id to consume the JSon data resultset from openexchangerates.org, VS 2012 for web and you are good to go.

The HTML source of the .aspx page

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="GetExchangeRates.aspx.cs" Inherits="GetExchangeRates" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
        Currency  
        <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
        </asp:DropDownList>
  
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>

    
    </div>
    </form>
</body>
</html>


Here is the aspx code behind.

using System;
using System.Collections.Generic;
using System.Net;
using Newtonsoft.Json;
    public partial class GetExchangeRates : System.Web.UI.Page
    {
        static JSon_SampleData.CurrencyRates obj;
        Dictionary rateValues;
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                obj = new JSon_SampleData.CurrencyRates();
                obj = Download_Serialized_ExchangeRate("http://openexchangerates.org/api/latest.json?app_id=");
                rateValues = new Dictionary();
                rateValues = obj.Rates;
                foreach (var raate in rateValues)
                {
                    DropDownList1.Items.Add(raate.Key);
                }
                Session["rateValues"] = rateValues;
            }
        }

        private static T Download_Serialized_ExchangeRate(string url) where T : new()
        {
            using (var w = new WebClient())
            {
                var json_data = string.Empty;                
                try
                {
                    json_data= w.DownloadString(url);
                }
                catch (Exception) { }
                return !string.IsNullOrEmpty(json_data) ? JsonConvert.DeserializeObject(json_data) : new T();
            }
        }

        protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
        {
            rateValues = (Dictionary)Session["rateValues"];
            foreach (var raate in rateValues)
            {
                if (raate.Key == DropDownList1.SelectedItem.Text)
                {
                    TextBox1.Text = raate.Value.ToString();
                    break;
                }
            }

        }
}


And the Class to hold the JSon data.

using System.Collections.Generic;

namespace JSon_SampleData
{
    public class CurrencyRates
    {
        public string Disclaimer { get; set; }
        public string License { get; set; }
        public int TimeStamp { get; set; }
        public string Base { get; set; }
        public Dictionary Rates { get; set; }
    } 
    
}

Reference the JSon Data class in your ASP.Net website.

I will post the KO code in the next part and get back to the BDD and Agile part.

Saturday, 23 August 2014

KnockoutJS, Jasmine and Phantom - I

What AngularJS or Javascript with RegisterClientScript blocks could not do, KnockoutJS does and satisfactorily simply !!

What this means, in Asp.Net terms, is equivalent to setting AutopostBack=true or using a jQuery callback function.

Working on client-server technology, especially for Asp.Net developers, frequently makes one think, "If only the code did not do so many round-trips to the server with post-backs and could do simple UI changes that reflect back instantly to the user...".

I mention this, not as a declaration of my own long-felt personal wish but, because this is what the KnockoutJS documentation or the help resources miss out that does not make more ASP.Net developers take to KO nor is there sufficient mention that because it is plain Javascript, it helps Agile development methods to quickly tap into the many already available unit testing and functional testing tools like Jasmine, Slim or PhantomJS and set up a robust team of "high speed development" corridors!

KO also makes things more interesting to the technical-jargon-smitten-adrenaline junkies, who must have a technical discussion on design patterns and architecture to even say "Hello World!" !.

Because KO enables client-client 'post', it means a fresh look at the way the view-model works and is understood in MVM becomes important - now, it becomes MVVM (the additonal 'V' in the model is actually viewmodel together).

The additional tier in the architecture is ok, not as a compromise that you cannot do anything about anyway, but seriously as an efficient workaround that not only improves performance but also helps Agile immensely!! How?

With and because of KO, you do not need to think of Selenium as an additional tool to burden your team with because testing the VM itself with Jasmine or other unit testing tools should suffice !!

And also, there is no need to learn an additional tool like Slim to integrate your tests because PhantomJs provides a command-line executable (or rather, an executable).

That is a lot of advantages of KO, I hope I am not putting down other equally or more efficient language tools. Yes, KO is not a framework as AngularJS probably is.

So, here goes as I whet my appetite...

HelloWorld.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Hello, KnockoutJS</title>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
  <script type="text/javascript" src="knockoutjs.3.2.0\content\scripts\knockout-3.2.0.js"></script>
    <script type="text/javascript" src="HelloKO-Script.js"></script>
</head>
<body>
    <p>First name: <input data-bind="value: firstName" /></p>
    <p>Last name: <input data-bind="value: lastName" /></p>
    <h3>Hello, <span data-bind="text: fullName"> </span>!</h3>
  </body>
</html>

Of course, the reference to the jQuery script is still necessary because of the $ functiion callback in the below script.

And the Knockout script (and no pun intended!)

// HelloKO-Script.js

var HelloViewModel = function (firstname, lastname) {
    var self = this;

    self.firstName = ko.observable(firstname);
    self.lastName = ko.observable(lastname);

    self.fullName = ko.computed(function () {
        return self.firstName() + " " + self.lastName();
    }, self);
};

$(function () {
    ko.applyBindings(new HelloViewModel("Ravichandran", "Jv"));
});

Simple four terms to explain is all that is required - the ViewModel that is, quite apparently, the viewmodel, the observable method of KO that 'observes' the 'fields', the computed keyword of KO to take an action   and the applyBindings that applies - here is the magic! - the KO bindings, in this example the 'data-bind' to the 'value:' binding.

The above program will simply output this - 


But the magic is when you make any change to either of the field and,

The applyBindings is what activates KO and the callback magic with the help of the $ jQuery callback mechanism to make the UI update happen!

You can download KO separately or use the NuGet tool in VS 2012. I used the latter - copy the package after downloading with NuGet into the relevant folder and modify the script src path.

The Jasmine tests are equally simple !

All you need in Jasmine is a spec file (same name as the CUT or Script Under Test) and the Jasmine framework.

The spec file

"HelloKO-Script-spec.js"

describe("My Name", function () {
    it("concatenates firstName and lastName and displays full name", function () {
        var target = new HelloViewModel("Ravichandran", "Jv");
        expect(target.fullName()).toBe("Ravichandran Jv");
    });
});

The describe keyword describes the function and gives it a name as parameters, defines a target variable 'target' and calls the 'expect' method of the Jasmine framework to match a given value with a call to the HelloKO-Script.js method, fullName().


To run and see the test results, you could use your own CSS or PhantomJS or Slim.

Step 1
Download Jasmine and PhantomJS and place the downloaded folders in the bin/root or wherever you have the HTML page.

Step 2
Create a new HTML page and insert the below code -

<!DOCTYPE HTML>
<html>
<head>
  <title>Jasmine Test Runner</title>
  <link rel="stylesheet" type="text/css" href="Jasmine\lib\jasmine-1.2.0\jasmine.css" />
    <script type="text/javascript" src="Jasmine\lib\jasmine-1.2.0\jasmine.js"></script>
    <script type="text/javascript" src="Jasmine\lib\jasmine-1.2.0\jasmine-html.js"></script>

    <script type="text/javascript" src="phantom-jasmine-master\lib\console-runner.js"></script>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
  <script type="text/javascript" src="knockoutjs.3.2.0\content\scripts\knockout-3.2.0.js"></script>

  <!-- The KnockoutJS script source file -->
  <script type="text/javascript" src="helloko-script.js"></script>

  <!-- The spec Jasmine file -->
  <script type="text/javascript" src="helloko-script-spec.js"></script>
</head>
<body>

    <!-- The Phantom script to invoke the console0runner -->
<script type="text/javascript">
    var console_reporter = new jasmine.ConsoleReporter()
    jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
    jasmine.getEnv().addReporter(console_reporter);
    jasmine.getEnv().execute();
</script>

</body>
</html>

That is it! Run the above HTML page and see the results. If your steps 1 & 2 were correct, you should see the below result screen else make sure the <script tags' src location are matching with your path.

If you do not like the PhantomJS script, you could use Slim instead but for that you will need to download Slim, know how to use and start the fitNesse server, write the Slim test suite and finally run the Slim fixture !!

With PhantomJS, you modify just the TestRunner HTML page as and when you need to modify the path to the script source file and the Jasmine spec file.

Ideally, they say, you should mock the jQuery $ method, too, but that, again, as they say, is yet another story - more in the context of TDD !