Archive for the ‘ Technical ’ Category

.NET Math.Round() #EPICFAIL

Consider this: you have a number, say 392.865, and you want to round that number to two decimal places. The resulting value should be 392.87, right?

Well… well, yeah… let me just gather my breath for a second here…

If you’re using the .NET framework’s Math.Round() method then boy do I have a surprise for you! The result of Math.Round(392.865, 2) will be 392.86.

This is because .NET uses “banker’s rounding” by default.

You think I’m joking don’t you?

I should be joking, but I’m not… see MSDN for confirmation.

I’ve been writing .NET code for 11 years and I never knew about this until today. I wonder how many calculations (not just mine, but everyone’s around the world) have been and will continue to be incorrect because of this default behavior?

You have been warned.


VB.NET Replace(Replace(input, “”, “”), “”, “”) issue / quirk / bug

I ran into a very strange issue the other day. This was in VB.NET and as you’ll see in a moment is rather un-googleable. Someone checked in a change that essentially did this:

    Dim strExample as String = "ab"
    Return Replace(Replace(strExample, "a", ""), "b", "")

What do you think was returned?

I expected it to return empty string “” but for some reason it returned Nothing! (?!?)

Yet this returns empty string:

    Dim strExample as String = "a"
    Return Replace(strExample, "a", "")

So it appears that passing in Replace() as the first parameter to Replace() will convert empty string to Nothing. If the result isn’t empty string it’s fine, the issue is only when the result is empty string (which in the real world was only ever an issue if the input string was empty to begin with).

This works as expected:

    Dim strExample as String = "ab"
    Return strExample.Replace("a", "").Replace("b", "")


Advocate For Your Users

This is a long winded IT / Software Development post, so bear with me…

My wife works in the health care industry. We were recently discussing a lecture that she attended where the speaker was a woman with Rheumatoid Arthritis. Now I’m not sure whether the lecture was specifically about this, or whether this was the resulting point that my wife got from the talk, but the point was how important it is for therapists to advocate for their patients. For example, a patient with a complex chronic condition such as Rheumatoid Arthritis could have many health care professionals working with them:

  • A General Practitioner
  • A Rheumatologist
  • An Orthopedic Surgeon
  • A Plastic Surgeon
  • A Gastroenterologist
  • An Occupational Therapist
  • A Physical Therapist
  • A Massage Therapist
  • A Naturopath
  • Et cetera

So who manages all these relationships? The patient…? That sounds absurd! Yet unfortunately that is the reality. These specialists are a mesh network of peers. They do not report to a single supervisor or project manager. The patient/practitioner power dynamic leaves the patient as a “client” and yet if the patient wants a reasonable level of service they must somehow also be the “supervisor” that manages their own care. The patient must do their best to hold each office accountable, to coordinate time sensitive matters, to ensure the offices are communicating correctly and following up with each other.

The patient doesn’t always know who the right person is to talk to about a problem they experience, or what the right thing to do is, or when they need to stand up for themselves and take matters into their own hands. Patients will have varying degrees of knowledge, comfort and experience dealing with their condition (much like users of software have varying levels of technical knowledge, varying willingness to ask for help, or the desire to share their opinions about the software to improve it). Most patients either can’t or don’t know how to manage their own care, meaning that the best health care professionals are the ones that advocate for their clients. The ones that go the extra mile to try and help their clients navigate through the sea of red tape that is our medical system.

Continuing with this patient scenario, here is a specific example: let’s say the patient develops a problem with a tendon and is of the “wait and see if it goes away” mindset but a therapist recognizes that if the patient isn’t seen immediately by a surgeon within a week that the result will be permanent damage to the tendon. I believe it is that therapists obligation to champion for their patient in any way they can! We can’t just assume that someone else will deal with the problem. We can’t just assume that the secretary at the surgeons office knows how little time there is left before the damage is permanent. The therapist must take action and be directly involved in helping the patient move to the next step in the healthcare process.

I can see a great deal of similarities between this healthcare scenario and my personal IT career experiences. While that was a long winded example I think it was important to demonstrate the importance of why someone with domain knowledge needs to advocate for their users. I was thinking about that and how it applies to my job as a Software Developer. I work for a small company, so I’m involved in all aspects of our software including dealing with both technical and non-technical users while performing business analysis, customer support, feature development, customization and system maintenance.

I’ve always felt that serving the client is my primary responsibility. Maybe that’s because I’ve had more access to my user base than other developers may have, but still, in my experience the user always comes first. We’d be out of business if there were no customers. This is similar to the customer service mantra that “the customer is always right.”

Now I don’t know what other developers think of me. Do they think I’m too opinionated? Aggressive? That I’m being difficult? Do I sound like a broken record every time I open my mouth to offer an alternate opinion, champion another change request or when I play devil’s advocate? Who knows. What I do know is that I advocate for my users. I push for a better user experience. I fight for their needs first.

It’s easy to get caught in a trap of this [approach / design / method / technique] will be easier, that will be faster, this will be more flexible, etc. But you know what? I don’t vote for the quick way or the easy way, I vote for whatever is best for my users.

Do you advocate for your users?

Querying messy XML in Oracle

I found some XML stored in a XMLType column in an Oracle table that doesn’t conform to a structured XML schema. It looks like this:


Note how all the nodes under /root/fields are named after the field name, rather than each node being named <field>. So I can’t just ask for all the nodes named field or all the field nodes in the fields collection, and I don’t know what the field names are or how many there are either.

I can’t easily change the format of the XML to conform to a schema since this table has been in production for a few years on a few dozen Oracle instances.

So how can I query and/or loop through all the children in the /root/fields path without knowing the child node names? It turns out to be fairly easy!

Example Query:

SELECT EXTRACTVALUE (VALUE (xml), '*/name') AS "name",
       EXTRACTVALUE (VALUE (xml), '*/value') AS "value",
       EXTRACTVALUE (VALUE (xml), '*/enabled') AS "enabled"
  FROM my_table_with_xml tbl,
       TABLE (XMLSEQUENCE (EXTRACT (tbl.xml_type_col, '/root/fields/*'))) xml
 WHERE tbl.primary_key = 1234;

Example Output:

name        value   enabled
field_abc   1       true
field_def   2       false

The trick is this line:

TABLE (XMLSEQUENCE (EXTRACT (tbl.xml_type_col, '/root/fields/*')))

What we do is we EXTRACT() all the nodes below the /root/fields path regardless of their names (* wildcard). Then XMLSEQUENCE() will split the extracted nodes into a VARRAY of XMLTypes. Finally, the TABLE() function allows us to query the VARRAY results by converting the multiple array values into a pseudo table containing multiple rows.

We could even apply a WHERE clause against the XML data to further restrict the results:

Example Query:

SELECT EXTRACTVALUE (VALUE (xml), '*/name') AS "name",
       EXTRACTVALUE (VALUE (xml), '*/value') AS "value",
       EXTRACTVALUE (VALUE (xml), '*/enabled') AS "enabled"
  FROM my_table_with_xml tbl,
       TABLE (XMLSEQUENCE (EXTRACT (tbl.xml_type_col, '/root/fields/*'))) xml
 WHERE tbl.primary_key = 1234
   AND EXTRACTVALUE (VALUE(xml), '*/enabled') = 'true';