Seventh Octave

We're Starters. We write about culture, design and the business of software.

We believe software should be beautiful and inspired. Follow us as we build TechOctave.

C# Reading XML With Namespace Tian May 21

2 comments Latest by TVD

I've said it before and I'll say it again: .NET is a ghetto. It's my experience that once your application becomes non-trivial, there is no tried-and-true way of accomplishing a given task.

You either have to piece together what feel like desparate code in order to accomplish the most common of use cases. Case in point is using XPath to read data in XML.

Say you have this XML response:

<?xml version="1.0" encoding="utf-8"?>
<UserResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <User xmlns="http://halo.com/schemas/custom/users/GetUser_V1">
      <Result>"Successful"</Result>
      <Name>John-117</Name>
      <Age>Unknown</Age>
      <Rank>Master Chief Petty Officer</Rank>
  </User>
  <UUID xmlns="http://halo.com/schemas/custom/users/GetUser_V1">
      {61D25ABC-CD96-4838-9406-C867B6D07449}
  </UUID>
</UserResponse>

Using C#, parsing this data should be an easy task - right? You should be able to do something like this?

HaloService haloService = new HaloService();
string response = haloService.ExecuteCall("{61D25ABC-CD96-4838-9406-C867B6D07449}");

XmlDocument results = new XmlDocument();
results.LoadXml(response);

if (results.SelectSingleNode("//UserResponse/User/Result").InnerText == "Successful") {
    string Name = results.SelectSingleNode("//UserResponse/User/Name").InnerText;
}

But does that work in .NET C#? No.

Why? It doesn't work because the XML response has a namespace separating the key data notes. Here the XML namespace is:

http://halo.com/schemas/custom/users/GetUser_V1

So what are your options:

You really only have two options when confronted with this challenge. The first is to you XMLNamespaceManager. I don't care for that route as you'll see below.

The final option is to strip the Namespaces using Regex. I prefer this route and you'll see why.

Use XmlNamespaceManager

When using XPath in .NET (via SelectNodes or SelectSingleNode) on XML with namespaces you need to:

  1. Provide your own XmlNamespaceManager
  2. Explicitly prefix ALL elements in your XPath expression which are in the namespace

You do so in a similar fashion as below:

. . .

XmlDocument results = new XmlDocument();
results.LoadXml(response);

XmlNamespaceManager ns = new XmlNamespaceManager(results.NameTable);
ns.AddNamespace("ns",      
        "http://halo.com/schemas/custom/users/GetUser_V1");

string Result = results.SelectSingleNode(
"//UserResponse/ns:User/ns:Result", ns).InnerText;

. . .

This gets you the data, but it's clumsy and has several disadvantages. First, if you don't control the web service (which many people don't), the namespace could change on you at anytime.

When that happens your hardcoded namespace WILL break and you will have production downtime. Second, you can't reuse XPath that was previously valid. Finally, the namespaced XPath expression is less readable and therefore, less maintainable.

The XPath implementation in SelectNodes and SelectSingleNode should really be more flexible. Using familiar methods should not shock developers or lead to unmaintainable code. It simply shouldn't

Strip The Namespaces Using Regex

Regex is like violence - if it doesn’t solve your problems, you are not using enough of it. Generally, I don't condone the use of unnecessary Regex.

This isn't one of those scenarios. Here, Regex was not only necessary, it was downright welcomed:

string filter = @"xmlns(:\w+)?=""([^""]+)""|xsi(:\w+)?=""([^""]+)""";
response = Regex.Replace(response, filter, "");

XmlDocument results = new XmlDocument();
results.LoadXml(response);

string Name = results.SelectSingleNode("//UserResponse/User/Name").InnerText;

Here, we remove any XML Namespace (xmlns) declaration before loading the XML. Once you do that, you can read the XML using the XPath expression you expected to use in the first place.

The pros are quick and apparent. First, your application won't break if the owner of the web service need to change their namespace (this could easily happen). Second, you cna reuse previously developed XPath expressions without issue. Finally, the code is simply more readable - one to one - with the original XML.

Really hope this helps save someone some much needed development time. Wish I had this article, it definitely would have saved me time.

Code Long & Prosper!

Conflict Management Tian May 14

Post a comment

Conflict Definition

Many are uncomfortable with conflict. When faced with conflict, they are either crippled by it or don't know the best approach to use to transcend it.

We all know that conflict is inevitable. It is something that impacts us regularly. Conflict will always exist.

While conflict can at times provoke destruction, sadness and unwanted results. It can also promote positive results. For example, conflicts can lead to the creation of strong relationships, invincible teams and great nations. And we can look to history for proof of that.

The truth is, we should not view conflict as negative. Instead we should focus on the value or opportunities it can bring. Because, it is not conflict by itself that truly matters; it is how we manage it that makes the real difference.

While one may think that conflict always leads to a win/lose situation where someone wins while the other loses. This way of managing conflict is very competitive in nature and is not always the best approach.

I Win. You Lose.

Conflict Management Strategies

I recently came across the Thomas-Kilmann Conflict Mode Instrument which serves as an interesting model for handling conflict.

Thomas Kilmann Conflict Mode Instrument

Kenneth Thomas and Ralph Kilmann's model shows us that there are actually five conflict handling strategies -- Accommodation, Avoidance, Compromise, Collaboration and Competition. And, each of these are useful in different situations.

Your response to conflicts will depend on two things -- your concern for yourself (horizontal axis) and your concern for others (vertical axis).

Accommodation -- You may want to be accommodating when you believe the other party has the better solution and you also place a high value on the relationship. You may also use this approach to show others that you can be reasonable.

Avoidance -- You may want to avoid conflict when the issue is extremely trivial and of no importance to you. It is also useful when emotions are high and you need to "cool down". It is important to not overuse this approach. You don't want to side-step problems that could eventually erupt into something bigger.

Compromise -- Compromise is when two parties come in the middle to make a deal; hence each party loses something to resolve the conflict. You may want to compromise when a temporary solution is needed. However, overuse of this strategy can lead to lack of trust and lack of focus on high level goals.

Collaboration (Assertive) -- Collaboration is a the strategy used when both parties attempt to achieve both of their goals. In other words, it's a "win, win". This approach requires lots of trust and also time as you work towards reaching a consensus.

Competition (Aggressive) --Competition is a win-lose approach; One's goals are seen as most important and must be achieved without cooperating with the other party. This strategy is often used in an emergency when a quick decision is necessary and people are aware and support the approach. However, if overused, people around you become less empowered and may withhold valuable feedback.

Different Strategies for Different Conflicts.

In the business world, we often face conflicts -- whether it be with business partners, customers or employees. It is important to understand that how we respond to conflict can either enhance or limit our success.

We tend to default to one of the conflict strategies depending on our personality. But it's important to realize that different conflicts require different approaches.

Now that you know about these conflict strategies. I hope it will give you some guidance on how to think and respond to conflict. May the conflicts you face lead to your growth and opportunities to positively transform your world.

Chaos Tian May 11

Post a comment

Chaos isn't a pit. Chaos is a ladder.

Many who try to climb it fail. Never get to try again.

The fall breaks them.

And some are given a chance to climb, but they refuse.

They cling to the realm or the gods or love. Illusions.

Only the ladder is real. The climb is all there is.

-Petyr Baelish, Master of Coin, Game of Thrones

Modern JavaScript MVC With Backbone.js Tian Apr 21

Post a comment

Modern JavaScript and HTML5 applications depend on a consistent RESTful JSON API. However, consistency is not always an option when you don't control the server API:

Modern JavaScript MVC With Backbone.js

Still, even in those situations, Backbone.js can be a useful tool in taming your JavaScript. Today walk through a simple example of how to connect the dots between Backbone's Model, Collection and View.

The Backbone Basics

A basic single page application boils down to three distinct parts: Model, Collection and View.

The Model

The Model defines your class properties and methods. Here we define a class called Knot:

var Knot = Backbone.Model.extend({
    initialize: function() {
        _.extend(this, new Gauge("knots", {
            hasGlass: true,
            glassColor: "#aa0000"
        }));
    }
});

Whenever a new instance of the Knot class is created, we also inherit an instance of our JavaScript Gauges using Underscore's extend method.

The Collection

The Collection defines a list of class instances. Here we define a Collection called Knots:

var Knots = Backbone.Collection.extend({
        model: Knot,

        url: "http://query.yahooapis.com/v1/public/yql?q=select * from google.igoogle.stock where stock='lmt'&format=json&env=store://datatables.org/alltableswithkeys&callback=",

        parse: function(response) {
            return response.query.results.xml_api_reply.finance;
        }
});

window.knots = new Knots();  

First, you define which model the Collection will create a list of. Here, we also specify the collection's data source using the URL property.

Here, the data source is deeply nested. You can use the parse method to intercept the data source and get the data in a more manageable state before creating your model instance.

Finally, we immediately execute the collection to get it ready for use in our single page application (SPA).

The View

The View updates the User Interface (UI) with the data fetched from the collection:

var KnotsView = Backbone.View.extend({
    el: $("#knots"),

    initialize: function() {
        window.knots.reset();

        window.knots.bind("add", this.render);

        window.knots.fetch();
    },

    render: function() {
        window.knots.each(function(knot) {
            var value = knot.attributes.high.data;

            knot.setValue(value);
        });
    }
});

window.knotsView = new KnotsView();

First, we reset the knots collection. Next, we bind our View's render method to our Collection's add event. What this means is each time a Knot object is added to the Knots collections, we will call the Views render method to update the web application.

Then we make the actual call to the Collection's fetch method to retrieve the data from the data source. Here, we basically make a call to Google's stock webservice to retrieve some data on a company called Lockheed Martin.

Finally, in our View's render method we update each Knot Gauge with the corresponding value passed back from the server call.

Putting It All Together

Here's the final backbone example end-to-end:

window.onload = function() {
    var Knot = Backbone.Model.extend({
        initialize: function() {
            _.extend(this, new Gauge("knots", {
                hasGlass: true,
                glassColor: "#aa0000"
            }));
        }
    });

    var Knots = Backbone.Collection.extend({
        model: Knot,

        url: "http://query.yahooapis.com/v1/public/yql?q=select * from google.igoogle.stock where stock='lmt'&format=json&env=store://datatables.org/alltableswithkeys&callback=",

        parse: function(response) {
            return response.query.results.xml_api_reply.finance;
        }
    });

    window.knots = new Knots();

    var KnotsView = Backbone.View.extend({
        el: $("#knots"),

        initialize: function() {
            window.knots.reset();

            window.knots.bind("add", this.render);

            window.knots.fetch();
        },

        render: function() {
            window.knots.each(function(knot) {
                var value = knot.attributes.high.data;

                knot.setValue(value);
            });
        }
    });

    window.knotsView = new KnotsView();
};  

Backbone is a really good framework for organizing your JavaScript code. It's lightweight and gives you everything you need. It's prescriptive without being heavy-handed. I like it. Enjoy!

Impossible is just an opinion Tian Apr 17

2 comments Latest by TVD

We're gearing up to launch our suite of JavaScript Flight Gauges. Here's a look back on how we got where we are today. Enjoy!

Ten years ago, The Alchemist changed my life. It was more than a book to me at the time. At the time, it was an affirmation of my brand of life living entirely. From the Alchemist I learned a lesson that would guide me year after year, play by play: To realize one's destiny is a person's only obligation.

I would learn that lesson well.

The Art Of The Start

To be frank, I didn't set out to sell product at all. I was planning to just write and contribute to open source projects. I kinda just fell into the Business Intelligence market:

javascript gauge Version 1.0 of TechOctave JavaScript Gauges, Circa Early 2010

Just not the kind of fall where your sprain your ankle. It was more like the kind of fall you take when you meet the love of your life for the first time.

Know what I mean?

The kind of fall you take when you finally realize what you'll do for the rest of your life. That was our start too.

Three years ago, on a seemingly ordinary Friday night, I told a group of friends I could digitize one of their car dashboards in a day. One of them said, "Impossible. You're full of shit." He bet me $100 I couldn't. I bet him a date with his girl if I could.

I was always a betting man. It's in my blood. Pretty sure I got it from my grandfather - It's served me well when it counts. It served me well that night.

I won that bet.

A month later, we had a prototype for what would come to be our first product line of JavaScript dashboard gauges. Impossible is just an opinion.

What happened to the girl? Well, let's just say she's not his girl anymore. My old friend learned a very valuable lesson that day: Never bet against a lion...Best case is you lose your money.

The First Thing We Sold

Building a prototype is one thing. Making the leap to selling product is a whole different story. Initially, we gave 1.0 away for free. The money is good, but it's never been just about that for me.

Even today, I charge enough so we can be there for our customers when they need us. It's my duty to make sure we charge enough so we can always be around to make our customers (the only Investors that matter) look amazing for making their bets on us. I'll always guard that duty with the highest of care.

We have a lot of open source tools and products, so I initially thought this would just be a cool tool developers could use in their apps. A throw away. But, it wasn't a throw away.

I've been writing on TechOctave for over three years now. When you write, the traffic increases, then recedes. That's the normal state of affairs. But, not with our gauges. The interest simply never went away.

Week after week. Month after month. The interest was still there. Even today, our initial release of 1.0 is still the most read article on BI Dashboard Gauges.

Even with its tight coupling to jQuery and unnecessary use of CSS, developers still loved 1.0.

I. Stood. Breathless.

Then I set out to do what any red blooded Starter would - I filled the need. I put together a small support team. I offered product tiers. I answered presales questions. And I sold 1.0.

You know what the hardest part was? I didn't believe in 1.0. To me 1.0 was awful. 1.0 wasn't the product I wanted to use. It didn't meet my standards. But, I shipped it anyway because that's the Start. Unpolished. Unfinished. Unapologetic.

Things got serious when I sold our first Fortune 500 customer. Mike (Let's call him Mike) was building an executive dashboard for C-Level executives of his company.

Now, don't get me wrong. Our 1.0 looked amazing and the API was simple without being simplistic. Those two aspects came to form the first 2 of 6 Core Principles we use to guide our products today.

We learned a lot from 1.0, but it was static, the ticks weren't configurable, the colors weren't configurable. The needle moved to the correct value and that was it.

I talk to every customer who joins the TechOctave family. If I didn't help them through the sales process, I make sure I at-least thank them for their business and welcome them in.

Things were no different with Mike, I talked to Mike, welcomed him in and took his feedback back to the team. Mike was conservative, but I could tell he wasn't happy.

Mike needed quicker control so he could make the perfect gauge in his image. Mike needed to not have to be a Photoshop master. That day, I understood that Mike and all the other Mike's to come.

Mike deserved better. All of our future Mikes deserved better. So we sat out to build a better JavaScript Gauge suite. A few months later, we discontinued version 1.0 and launched version 2.0.

Mike was our first of ten developers on our Customer Feedback Group. Mike loved 2.0. Mike loved 2.0 so much he nearly lost his goddamn mind configuring the Gauge. I loved 2.0 as well.

Mike built his executive dashboard in-house. His looked better and out performed commercial off the shelf solutions. Mike's executives loved his solution because it was specially made for them only like a custom solution can - with care.

After his launch, Mike got a raise and a promotion to Lead Developer. But, aside from that, I like to believe Mike got something even more valuable - He learned he's a courageous developer.

Three years later, Mike and I are still close. He'll never admit it, but he's a betting man. He took a chance on a scrappy startup and won big. He learned that he doesn't have to settle for inelegant interfaces, overly complex APIs and clueless customer service reps.

I learned something too.

I learned that part of the Start is your 1.0. That's just part of the evolution because you have to start somewhere. And somewhere is better than nowhere.

Where We Are Today

We built 2.0 from the ground up to be cross-browser/cross-device compatible, 100% vector based and beautiful:

javascript gauge Version 2.0 of TechOctave JavaScript Gauges, Circa Late 2010

We built the JavaScript Gauge library we wanted to use and it is more than simply "opinionated" - Our Gauges are principled:

  1. Beautifully Illustrated
  2. Cross-Browser Compatible
  3. Lightweight Footprint
  4. Vector Based for Crisp Zoom and Print
  5. Highly Configurable
  6. Framework Agnostic

We then revisited the photorealistic qualities of our Gauges 1.0 and recaptured all it had to offer. This time with the configurability and power that only version 2.0 of our Gauges API could deliver:

javascript raphael gauge

javascript raphael svg gauge

After a consulting gig, we realized our brand of development and philosphy was needed in the full breadth of Data Visualization solutions. JavaScript Charts were a natural progression:

javascript charts svg raphael jquery Version 1.2 of TechOctave JavaScript Charts, Circa Late 2011

Thousands of customers later, Hundreds of bug fixes, I can wholeheartedly say Gauges 2.0 makes me proud of the work we've done. The spirit of innovation is alive and well in the heartland. I'm proud to be apart of that and you be should too.

But innovation doesn't rest and time waits for no man. Out beyond notions of right and wrong, fear and doubt, is a field. I'll meet any man on that field. On that field is where challenges live and innovations are birth forth into this world.

Our customers are on that field. Waiting for us. I don't intend to keep them waiting for long.

Looking Ahead To The Future

We are on the cusp of launching our line of JavaScript Flight Gauges. Our flight simulation packages will be our third major product line of JavaScript Gauges:

javascript flight gauge, gauges, flight simulation gauges, simulation gauges, simulation

Shortly, we'll branch out from the Data Visualization market and enter the Military Simulation & Training market as well.

The field is wide open. We're seasoned. We have our processes in place. We're closers. We're hungry. We're ready. Hoorah!

We will succeed on the quality of our products and our relentless pursuit of best-in-class solutions. And we will live as we always have, with strength of religion and unwavering focus of purpose.

You don't need a 100 page business plan for that. You don't need a bajillion dollars either. All you need is a little patience, some gumption and a penchant for side stepping the status quo.

We've got that. We live that. We breathe that.

Our JavaScript Flight Gauges is the last product line I'll be Lead Developer on. Each product from sales to support is in good hands. Then I'll turn my attention to the business of growing TechOctave.

All I ask is you grow with us.

TechOctave Gauges 2.2.8: Unlimited Ranges, Precision Values Tian Apr 15

Post a comment

The latest version of our JavaScript Gauges Suite is here! :)

The biggest enhancements are Multiple Bands (Ranges) and Custom Value Precision. Now you can have Unlimited Bands and Unlimited Poowerrr (muahahaha) - Wait...

Release Notes: 2.2.8 Gauge.js

[Enhancements]

  • Implemented Multiple Bands E.g. bands: [[start, end, color], [...], [...]]
  • Implemented setBands to update band ranges during runtime.
  • Implemented Custom Value Precision using majorValuesPercision property. E.g. 0 will create whole number majorValues (3, 4). Whereas 1 will create one decimal point majorValues (2.5, 3.7)
  • Added updated.html to show example of Polling, mahorValuesPercision, setBands.
  • Implemented animateNeedle property. True => Needle will animate between values, False => Needle will not animate between values.

[Defects]

  • Fixed Needle Flicker
  • Fixed Major Values Precision Lacking

[API Improvement]

  • Deprecated drawGreenBand
  • Deprecated drawYellowBand
  • Deprecated drawRedBand
  • Removed minAngle and maxAngle properties
  • Improved needle mapping algorithm
  • Improved band mapping algorithm
  • Added bandDegreeOffset for unique gauges. See, textures_ferarri.html

Game of Thrones: The Great Houses Tian Apr 07

Post a comment

"What a man sells for gold, he can never buy back. He must earn it by fire and blood." - Ser Jorah Mormont, exiled Westerosi knight

House Baratheon

Hi Everyone, I removed the other Houses, but left one of my favorites - House Baratheon.

Just too many blocking calls to the Youtube API before the page loads. But you can enjoy all the back stories in the History of the Seven Kingdoms.

Watch the entire History of the Seven Kingdoms. Then go write some code - That's an order! ;)

We Live In The Future Tian Apr 04

Post a comment

Bell Labs Circa 1970s

There is nothing more beautiful than reality. Tian Mar 31

Post a comment

The most astounding fact is that the atoms that comprise life on Earth.

The atoms that make up the human body are traceable to the crucibles that cooked light elements into heavy elements in their core, Under extreme temperatures and pressures.

These stars, the high mass ones among them, went unstable in their later years. They collapsed and then exploded - Scattering their enriched guts across the galaxy.

Guts made of carbon, nitrogen, oxygen and all the fundamental ingredients of life itself. These ingredients become part of gas clouds that condense, collapse, form the next generation of solar systems. Stars with orbiting planets. And those planets now have the ingredients for life itself.

So that when I look up at the night sky, and I know that - yes we are part of this Universe, we are in this Universe - but perhaps, more important than both of those facts is the Universe is in Us.

When I reflect on that fact, I look up. Many people feel small because they are small and the Universe is big. But I feel big, because my atoms came from those stars. There is a level of connectivity.

That's really what you want in life. You want to feel connected. You want to feel relevant. You want to feel like you're a participant in the goings on of activities and events around you.

That's precisely what we are just by being alive.

--Neil deGrasse Tyson

This is not about Google Reader Tian Mar 18

1 comment Latest by Jef Claes

I don't use Google Reader. I find the UI brings very little excitement. And the UX (ugh)...Unread post counts make me feel like I have chores to complete, a never ending todo list. I have a large enough todo list already - believe me:

Last week, Google announced it will shut down Google Reader on July 1, 2013. Some would say good riddance - I wouldn't go so far. Reader wasn't the best of applications, but it did provide some value. Reader didn't end world hunger, but I'd argue it did change the world.

Whether we admit it, or not, Reader introduced people to RSS and open data and open standards that, but for, they would not have been privy to. That's a big deal.

When a grandfather in the middle of Missouri can subscribe to his grandson's travel blog in Madrid. That's a big deal.

When there are over 500,000 people who never have to ask, "How do I subscribe to your blog?" That's a big deal.

But this is not about Google Reader.

This is about the State of the Open Web

Platforms with user generated content are becoming increasingly closed. This concerns me. Twitter and Facebook both quietly killed RSS; Opting for a proprietary API over an open standard in its place.

Believe me, it's not just RSS either. In the same move to dispatch Reader, Google also quietly killed CalDAV, an open calendar standard, in favor of it's own proprietary calendar API. What's next? Shut down IMAP for Gmail?

This isn't what the web is supposed to be. Those weren't the type of companies we thought we were helping to build.

Are there better standards? Maybe. Does it matter? Not very much.

The you create content, we sell your content business model of Twitter and Facebook has long drawn a line-in-the-sand. The writing is clear: Use our API or use nothing at all. Our way or the highway. More dictatorship than democracy.

Chillin.

We should all be concerned

If the giants of industry, companies we helped build, don't support open standards, then why should your local congressman support open government?

If the future of sharing is measured in ROI, then what will the future of freedom be measured in? Should we have to make a business case for the free flow of people and property as well? Whose property?

Everyday, millions of people ask these very questions and it sickens me. Google Reader's demise is just a painful reminder that freedom of information is slowly losing its God-given place as a foundation of our democracy.

Yet, every rally for open standards, every cry for a more perfect Union is the very deed that keeps evil at bay. What will your deed be?

Because in the final hour, this is not about one company or one product...This is not about Google Reader.

This is about the future.

Steve Jobs: Living The Unlimited Life Tian Mar 03

Post a comment

When you grow up you tend to get told that "the world is the way it is." And your life is just to live your life inside the world. Try not to bash into the walls too much. Try to have a nice family life; Have fun; Save a little money...

That's a very limited life.

Life can be much broader once you discover one simple fact... And that is, "Everything around you that you call life was made up by people that were no smarter than you."

And you can change it; You can influence it; You can build your own things that other people can use.

Once you learn that, you'll never be the same again.

The Only Higher Level Than JavaScript Is God's Word. Tian Feb 22

2 comments Latest by TVD

I'm so sick and tired of people describing JavaScript as "low-level". If you're not "MOV AL, 61h" all damn day, you're not doing low-level programming; so give it a rest:

Low-Level Programming Languages

For those who studied under Sams or some other Dummy, it's time to lay out some fundamentals.

In computer science, a low-level programming language is a programming language that provides little or no abstraction from a computer's instruction set architecture.

At this point, we're either talking machine code or assembly language.

Low-level languages can be converted to machine code without using a compiler or interpreter, and the resulting code runs directly on the processor.

Machine Code

Machine code is the only language a microprocessor can process directly without a previous transformation.

8B542408 83FA0077 06B80000 0000C383
FA027706 B8010000 00C353BB 01000000
B9010000 008D0419 83FA0376 078BD98B
C84AEBF1 5BC3

Above is a function in 32-bit x86 machine code to calculate the nth Fibonacci number.

Writing machine code was nutballs because it required memorizing or looking up numerical codes for every instruction that is used. Who the hell ever had the time for that?

Please tell me you're not doing this for a living?

Assembly Language

An assembly language is a low-level programming language for a computer, microcontroller, or other programmable device, in which each statement corresponds to a single machine code instruction:

fib:
    mov edx, [esp+8]
    cmp edx, 0
    ja @f
    mov eax, 0
    ret

    @@:
    cmp edx, 2
    ja @f
    mov eax, 1
    ret

    @@:
    push ebx
    mov ebx, 1
    mov ecx, 1

    @@:
        lea eax, [ebx+ecx]
        cmp edx, 3
        jbe @f
        mov ebx, ecx
        mov ecx, eax
        dec edx
    jmp @b

    @@:
    pop ebx
    ret

The same Fibonacci number calculator as above, but in x86 assembly language using MASM syntax.

Each microcontroller had it's own distinct assembly language instruction set. But, this was a step up because you no longer had to memorize or lookup every single instruction opcode.

A developer could more easily remember commands like move (mov) or compare (cmp) over 8B542408 or FA027706.

Statements like mov ax,0 and add ax,bx are meaningless to the microprocessor. As arcane as these statements appear, they were still human readable forms of computer instructions.

But, at the end-of-the-day, the computer only responds to commands like B80000 and 03C3. An assembly language and its corresponding assembler is a program that converts strings like mov ax,0 to architecture specific machine code like "B80000".

Surely, you're not doing this for a living either?

High-Level Programming Langauges

The latest trend is folks regurgitating phrases like "JavaScript is the lowest level programming, the assembly language of the web." I can't even begin to tell you how incredibly wrong that statement is.

It's just stinking wrong. Absolutely, unequivocally wrong:

In computer science, a high-level programming language is a programming language with strong abstraction from the details of the computer and it's machine code.

That abstraction forms the basis of what developers come to expect in a modern programming language:

  1. Advanced Control Structures
  2. Abstract Data Types
  3. Object Oriented Programming Constructs
  4. Functional Programming Constructs

JavaScript has all these fundamental constructs of a high-level programming language. That's why it's so versatile. That's why it's so ubiquitous:

var Light = (function(_super) {

    function Light(id, color) {
        _super.call(this, id);

        this.color = color;
        console.log("Start Light: " + color);

        _super.prototype.drawTerminal();
    }

    Light.prototype.setColor = function(color) {
        this.color = color;
        console.log("Change Light: " + color);
    }

    Light.prototype.getColor = function() {
        console.log("Color: " + this.color);
        return this.color;
    }

    return Light;
})(Base);

People will continue to parrot JavaScript is the assembly language for the web. Ignorance is a choice. But, that doesn't change the facts that JavaScript contains every high-level abstraction developers need to be productive.

The only higher level than JavaScript is God's word.

How did this low-level nonsense get this far?

One of my developer tweeps @HexstreamSoft summarized the madness best:

I guess the "argument" for Javascript being "low-level" is: "Any programming language used as a compilation target is low-level."

His observation is absolutely correct. This is exactly the logic folks are using to determine whether JavaScript is a low-level programming language or a high-level programming language.

The problem here is this new definition for "low-level" programming language is simply wrong. It never was and never will be the definition of "low-level".

Even if it was, when would the madness stop? If I wrote a new language which transpiles to CoffeeScript, would we then say CoffeeScript is a "low-level" programming language?

Surely not.

JavaScript isn't even close to the lowest level. Every JavaScript interpreter is written in C/C++. When JavaScript code runs through the interpreter, opcode is generated for the specific computer chipset because that's the only code a machine can understand.

Folks like to opine the terms high-level and low-level are inherently relative. That for every generation of programming language, the previous is a lower-level.

If you haven't heard it before, let me be the first to tell you that is complete and utter bullshit. A programming language either has high-level constructs or it doesn't. This isn't about feelings or transpiling or anything else.

A programming language is "low-level" if it lacks high-level abstract constructs: Functions, Classes, Inheritance, Polymorphism, etc.

It's that simple.

Since JavaScript has these "high-level" abstract constructs, it is a high-level programming language.

Blame The Wave of Designer Languages

I blame the current wave of Designer Languages for our temporary bout with insanity.

JavaScript, like many other successful programming languages is seeing it's share of designer languages. Some more successful than others.

Yet, just because another language runs on top of JavaScript, doesn't make JavaScript "low-level". That just makes JavaScript awesome!

In fact, none of these designer languages even add any new abstract constructs. Most, invariably, only add syntactic sugar to what was already an elegant language.

Designer languages are the expensive shoes you wear to impress your date or the Versace dress your girl wore to the prom. They are pomp and circumstance.

That doesn't make JavaScript "low-level", that just makes designer languages trendy.

Take a deep dive into any designer language. CoffeeScript, TypeScript, Dart, GWT, Sweet, LLJS, Opal, it really doesn't matter.

What you'll find is this...

Each has the same high-level abstract constructs that JavaScript has minus the ease of debugging, support and ultimately, maintainability.

I'm not saying these languages aren't innovative because they are. I'm not saying these languages don't add value to the JavaScript ecosystem because they do.

What I am saying is don't confuse science with fashion.

Man is a bridge, not an end. Tian Feb 03

Post a comment

What you are and what you could be are two different sides of the same equation. Too much abstract thought is wasted on pointless comparison between what is and what could be.

Pont du Gard: A masterpiece of Roman aqueduct engineering.

As if individual progress is somehow a combination of snapshots in time. Therein lies the greatest of fallacies...Social porn at its best.

The reality is progress is not a point. The man who pulls himself up by his bootstraps; The man who thrusts himself forward by sheer will alone; This man is not made of intangible glamour shots for your consumption.

He is made of sweat and blood and those tangibles which distinguish men. He, like the blood which courses through his veins, is a combination of winding roads and hidden valleys. Peaks to Valleys.

You see the peaks.

You see the glamour shots and the photo ops. You believe the press. But man is a bridge, not an end and what you see is but a fraction of his journey. A moment in time where he is seduced by rest.

A moment when only dry clothes and a warm bed will do. And for that brief moment he pulls himself out of the winding river and the winter's cold to celebrate progress...

There are no decisive victories in success. No pinnacle moment that can be identified to say unequivocally, "Yes. We ought to watch for that man." There are no signals. No pattern recognition.

There is only the Start. For each of us, that start will be different. But, for all of us, the end is the same...

In nomine Patris, et Filii, et Spiritus Sancti.

And between this time and then...Let us measure each other, not by where we've found one another, but in what we do between this day and then. But that's the hard part - isn't it?

That means that a man's worth cannot be distilled in a moment of preconception. That means that each and every one of us must be committed to conversation; Committed to celebrating the individual; Committed to Brotherhood.

And that is hard...

This is not a journey neither I nor you need take in haste. But it is a journey we must take.

Like all things of value, our commitment to each other, our individual responsibility for the future of the greater good, will take time to develop. You see, progress is like that.

But progress is worth the time. Truth be told, what higher concurrency could the Gods demand?

JavaScript Radar Charts Tian Dec 31

Post a comment

Recently, one of our customers needed a Radar Chart for an Enterprise Resource Planning (ERP) application. They thought a Radar Chart would be a great addition to our JavaScript Charts Suite:

JavaScript Radar Chart, Spider Chart, Star Chart.

We agree.

So we set out to build a Radar Chart built on the Six Core Principles we established so long ago:

  1. Beautifully Illustrated
  2. Cross-Browser Compatible
  3. Lightweight footprint
  4. Vector Based for Crisp Zoom and Print
  5. Highly Configurable
  6. Framework Agnostic

I believed then as I believe now that these principles are central to developer happiness. They inform what we do each and every day.

What are Radar Charts?

Radar charts plot the values of each category along a separate axis starting from the center of the chart and ending at the outer ring. In a Radar chart, a point close to the center indicates a low value and a point near the perimeter indicates a high value.

Radar charts will illustrate, graphically, the size of gaps amongst several organizational Key Performance Indicators (KPI) by highlighting the area where improvements are needed most.

Take a look at the radar chart above. This is a typical radar chart - sometimes called a spider chart or star chart for the way it looks. It makes concentrations, strengths and weaknesses much more visible.

If it's done well, it clearly defines full performance in each category. A well executed radar chart is a good way to answer the question, "How are we doing?"

When should you use a Radar Chart?

Use it to identify gaps among both current organizational KPI and ideal organizational KPI. You can use it to compare a variety of organizational data - Individuals, Teams and even whole Organizations.

That's why you'll often see radar charts used in the scope of Human Resources and Portfolio Management application development projects.

How to use our Radar Chart?

So let's see how we go about drawing our Radar Chart. The first thing to do is identify the categories or performances you want to compare. Then you'll want to gather the quantitative data for each category. Finally, plot the radar chart using your favorite JavaScript Charts library.

For our example, we'll analyze the change in advertising spending for National ERP Solutions, Inc. (NES) over two consecutive years:

Radar Chart advertising spending analysis.

Identify Key Categories or Performances

Here, NES advertising channels were:

  1. Internet
  2. Television
  3. Radio
  4. Newspaper
  5. Magazine

These advertising channels will make perfect Radar Categories for our example. For you, your categories will be different, but the idea is to identify areas your organization needs to analyze.

Gather Categorical Quantitative Data

Here, for Year 1, NES spending was as follows:

  1. Internet ($100,000)
  2. Television ($200,000)
  3. Radio ($175,000)
  4. Newspaper ($100,000)
  5. Magazine ($100,000)

For Year 2, NES spending habits made a pinnacle shift:

  1. Internet ($200,000)
  2. Television ($125,000)
  3. Radio ($105,000)
  4. Newspaper ($100,000)
  5. Magazine ($100,000)

Plot Your Radar Chart

Here we'll use our RadarChart component from our JavaScript Charts Suite. First, we'll create an HTML element to bind our chart too:

<div id="advertising"></div>

Next, we'll create an instance of our RadarChart class:

var advertising = new RadarChart("advertising", {
    data: [[100000, 200000, 175000, 100000, 100000], 
           [200000, 125000, 105000, 100000, 100000]],

    maxValue: 250000,

    categories: ["Internet", "Television", "Radio", 
                 "Newspaper", "Magazine"],

    legend: true,
    legendTitle: "Advertising",
    legendLabels: ["Year 1", "Year 2"],
});

Our data property can handle multiple sets of data. Here, the first set is the advertising spend gathered for Year 1. Finally, the last set is the advertising spend gathered for Year 2.

The key categories are listed in the categories property of the RadarChart class. This particular instance has the following categories: "Internet", "Television", "Radio", "Newspaper", "Magazine".

Since we'd like to give our audience a quick legend for identifying which set is which, we've turned on the legend for our RadarChart. Then we set its title to "Advertising". Finally, we label each data set: Year 1 followed by Year 2.

There are over thirty (30) properties we could set for our RadarChart, but these few should suffice for this example. Just know that our RadarChart is as flexible as the times call for.

Analyze Your Radar Chart Data

What is happening to NES here is what advertisers refer to as The Great Shift. The Great Shift refers to the time when companies will increase Internet advertising while simultaneously decreasing traditional advertising channels.

Here, NES has doubled its Internet advertising while decreasing Television advertising by 37.5% and decreasing Radio advertising by 42.9%. Newspaper and Magazine advertising remained the same.

As a best-in-class company, being able to comprehend and take action on these trends is mission critical. They help you to understand where the business is heading and what type of talent your organization needs to recruit.

From a Human Resources standpoint, Radar charts help you quickly understand you'll need to seek out folks with digital skills so you can be competitive in the market place. People like software developers, designers, user experience specialists and community managers.

From a Sourcing & Purchasing standpoint, Radar charts help you quickly understand that you'll need tools to monitor internet traffic and conversions so you can effectively measure your Return on Investment (ROI).

Thoughts and Reflections

What Great Shifts are taking place in your industry? What is your data telling you that you cannot see yet?

You have the data and you have the opportunity. Now is the time to take a fresh perspective on both. This is your day to seize.

Listen, I'm not telling you it's going to be easy. I'm telling you it's going to be worth it. We're the team to help you get there.

Tweetlr is now Galileo Tian Dec 25

Post a comment

Earlier this month, we got an email from someone at Twitter claiming people could confuse whether Tweetlr was developed by us or them. To their credit, the email was calm. No legalese, no pointed cease and desist, just a "Hey, this is probably something we should talk about."

Galileo facing the Roman Inquisition Galileo facing the Roman Inquisition, Cristiano Banti 1857

They felt our use of the name Tweetlr was infringing on their Tweet trademark. Ironic, since the word Tweet was organically created by the users of the Twitter platform itself. I doubt a single employee of Twitter was involved in creating the word Tweet.

Twitter's claim is groundless

We traded a few emails back and forth. Needless to say, we didn't agree with their claim. Fundamentally, Twitter's claim is groundless.

The legal test for trademark infringement is whether "a consumer of the goods or services will be confused as to the identity of the source or origin." Here, every Tweetlr customer knew the product was developed, marketed and sold by us.

Tweetlr is marketed as a relationship management tool for Twitter. What this means is you have to have a Twitter account leaned towards a business interest, before the need to manage relationships is even relevant to you.

When the time to manage relationships does become relevant, the consumer must then "seek out" a product to fill that need because Twitter does not make such a product.

During that process, the consumer educates himself about who offers relationship management tools and who does not. It is the very process of selecting a product like Tweetlr that eliminates any possibility of confusion.

Some of the people who sought us out were Entertainment Promoters, Rocks Bands, Singers, Song Writers, Open Source Software Promoters, Web Application Development & Design Studios, Writers and even a few Reality TV Stars.

Do these sound like people who execute by mistake? No.

While we disagreed with Twitter's claim, we didn't want to get into a protracted legal battle either. Any day you can avoid VC backed lawyers is a good day.

In the end we decided we'd just rename our Tweetlr app. Tweetlr hasn't been on the market too long so renaming wouldn't be a huge deal. But, more importantly, we play the long game because that's what matters most.

Galileo

So today we announce that Tweetlr is now called Galileo. Galileo is beautiful and inspired by Galileo Galilei - Italian physicist, mathematician, astronomer, and philosopher who played a major role in the Scientific Revolution.

Albert Einstein once called him the father of modern science. He helped us realize that it was the Earth that revolved around the Sun and not the other way around. In that, he helped mankind understand it's place in the Universe and ushered in a time of exploration and reflection.

Galilei's penchant for discovery and courage speak to the heart of our vision for Galileo. We want Galileo to be a guide and help inform you as your grow your presence on Twitter.

We want you to be interested in connecting with people again. We want Galileo to help inform who you get to know, regardless of whether that person is in a different county or a different continent.

We want Galileo to help you navigate the Twitter Universe and find your place in it. The name has changed, but our promise remains steadfast. You can begin to grow a targeted and relevant audience. One that's both professionally rewarding and personally fulfilling.

Don't just play your role. Play a major role. Or don't play at all.