IE 5.2 over Mac OS bug with Localized Strings

While testing our application over multiple browsers/OS combination we came across a pretty odd problem. IE over Mac OS wouldn’t show all the items in the drop down list controls. The html markup was correct, but the drop down lists would show empty spaces when the text string had accented characters, or characters that are not in the English alphabet.

The solution? Unknown, Microsoft is no longer developing IE browsers for Mac Operating Systems, is also no longer giving support for IE over Mac. What we are doing is detecting the browser and OS combination and rendering a disclaimer note on the page.

This post is just a curious note on a so far undocumented bug.

Here’s a very useful browser detection script taken from QuirksMode.org

var detect = navigator.userAgent.toLowerCase();
var OS,browser,version,total,thestring;

if (checkIt('konqueror'))
{
browser = "Konqueror";
OS = "Linux";
}
else if (checkIt('safari')) browser = "Safari"
else if (checkIt('omniweb')) browser = "OmniWeb"
else if (checkIt('opera')) browser = "Opera"
else if (checkIt('webtv')) browser = "WebTV";
else if (checkIt('icab')) browser = "iCab"
else if (checkIt('msie')) browser = "Internet Explorer"
else if (!checkIt('compatible'))
{
browser = "Netscape Navigator"
version = detect.charAt(8);
}
else browser = "An unknown browser";

if (!version) version = detect.charAt(place + thestring.length);

if (!OS)
{
if (checkIt('linux')) OS = "Linux";
else if (checkIt('x11')) OS = "Unix";
else if (checkIt('mac')) OS = "Mac"
else if (checkIt('win')) OS = "Windows"
else OS = "an unknown operating system";
}

function checkIt(string)
{
place = detect.indexOf(string) + 1;
thestring = string;
return place;
}

Fun with Globalization, Double.Parse method and French strings

Friday was a dead line for one of our applications. As usual there were some late bugs detected. One of them caused us a terrible headache. I was pulling out a string from the database representing a float number “1.609”. I had to parse that string on my code and convert it to float, Double type in VB.NET.
The string was converted fine for all the cultures in the application but French.
I was complete puzzled, aren’t doubles the same in all cultures? Isn’t mathematics the same? The Earth is round, the Pi number is the same no matter what language you speak, then why this statement will throw an “Expression cannot be evaluated” exception when the Current Thread culture is fr-FR????? Nonsense.

intUserRadius = Round(intUserRadius * Double.Parse(strRadiusUnits)

The same happened with

intUserRadius = Round(intUserRadius * CDbl(strRadiusUnits)

Both Functions failed on French, it seemed that French doubles are not the same.
Ok, the decimal separator in fr-FR is a comma and not a point, but the strRadiusUnits string is a string that is not culture biased and has a decimal point as separator.
It looks like this parsing functions were expecting a comma instead of a decimal point, so the following work around had to be applied:

intUserRadius = Round(intUserRadius * Double.Parse(strRadiusUnits, CultureInfo.InvariantCulture))

So, beware of the string parsing when you’re handling Global applications.

I got these two replies from a developers list:

Mathematics is the same in all cultures, but the character-based
representations of them may not be.

English is 1.5, others are 1,5

The default behavior Microsoft decided upon was basically “you can write
lazy code to your own current culture and not have to worry about
globalization”. This means that people who use 1,5 to represent one and a
half don’t have to do anything to write code to parse their own cultural
representation of the value. Once you get into multiple cultures, you have
to stop being lazy and use the supplied culture-aware overloads.

In your case, you have an English-centric view of data in your database
(1.609) which just so happens to be the “invariant” culture Microsoft
decided upon in their libraries. So to parse the data you’d need to use
Double.Parse(“1.609”, CultureInfo.InvariantCulture)

Thanks Adam for the reply.

Double.Parse(string)

You are parsing *from* a string, and “1.609” as a string
does not match the local culture. Any and all conversions
to/from strings need to be scrutinised for culture issues.

Far better would have been to store & retrieve a double
value from the database, rather than relying on using
strings as an intermediate format.

Thanks John for that reply.

Hth,

PG

Why there shouldn’t be primary keys with business meaning…

I could explain why you shouldn’t implement composite PKs in real life databases, I could quote a few articles on the subject (my favorites are Scott Ambler’s writings at Ronin) and point out that eventhough composite primary keys look good and make sense in theory, they make the life of programmers like me, difficult. Why? simply because when you have a composite foreign key, things get complicated, you no longer can use this simple and straighforward constructuction to filter values:

SELECT field1, field2 from ChildTable where FKField in (Select PKfield from ParentTable where fileteringfield=’value’)

If the FK is a composite key, this is two fields instead of one field as FK, the statement:

SELECT field1 from ChildTable where FKField1, FKField2 in (Select PKfield1, PKfield2 from ParentTable where fileteringfield=’value’)

will fail.
I know someone might point out, why not using joins? Sure that would be the only solution, but you would be joining on two fields instead of one…and why consuming more resources on a nested loop for the inner join?

Alternatives to Ajax

Finally I found a good article comparing Ajax with the rest of the equivalent technologies out there. It seems like a good resource to present to the team at Resources. I had mention before that I find web UIs quite rigid and the main alternative I had seen for this in the industry was Flash. However, Flash movies can be big to download, specially if you are on a dial up connection, need the Flash viewver plugin and the skills are rare to obtain. The original article

Weighing the alternatives

Why is Ajax getting so much attention

can be found at the Ajax info site. Enjoy!

Google’s having DNS problems


When you do a search in sogo it shows up results like the first image. They even have a privacy policy, second image…

This is fun, I can’t seem to find any recent problem like this on the
news today, the last one I heard of was in May 2005 :D. Still on the discussion list there are several users complaining about this problem.

I found this on a forum though
“sogo owns www.google.com.net, so when google has DNS problems some
browsers will try to append .com, .net, and .org to whatever url you
typed and redirect you there.”

But I bet it’s not unintentional…having a search engine in the net domain 😉
Here’s the original discussion:
http://digg.com/technology/Google.com_has_been_Hacked

Come on Google, buy www.google.com.net!

Running a very long php script…

I think I mentioned before that I did php on my spare time, sometimes.
I used to work with it on my day work, but not anymore. A friend had requested me to do a clean up on a MySQL table. This table had email text imported from an inbox that to be shown in a forum site. The problem was: the emails had lots of footers with the Original Message, promotions etc and he wanted to clean up the emails before showing them on the website. The php algorithm wasn’t a big deal, just detecting the strings, removing the text from that position to the end of the email and making sure the markup in the email (if it had HTML format) wouldn’t break. We left this last task to Tidy.
Anyways, I had to run the final clean up script on the whole table with about 30MB of information, so I knew the script would be running for quite some time. I had no shell access on the server so I had to run the script from my browser. I had set up some output on the script so it would show what record had been updated and what was the final cleaned up text.
After making a backup of the table, I pointed my FireFox 1.7 to run the clean up script, oh my, what a pain.
First I couldn’t make the script run for more than 60 seconds. I solved that with the following statement:
ini_set(‘max_execution_time’, ‘0’);
Then Firefox started to complain the script was too long and I should cancel it cause it was making FF to run slow and the computer might become unresponsive.
I commented out most of the echo statements and tried again, the script ran longer without the pop up window, but again FF complained 🙁 and eventually the FF window would disappear from the task bar. It was a burden cause I wasn’t able to know where the script had ended.
IE came to save my…situation 🙂 I must confess I had stopped using IE almost completely because I kept being infected with spyware and it would download ActiveX on my back from time to time…but now the relashionship has improved considerably again :). IE never complained and ran the script a lot faster. The task was done!

Smells to refactoring between classes.

Primitive Obsession

Use small objects to represent data such as money (which combines quantity and currency) or a date range object

Data Class

Classes with fields and getters and setters and nothing else (aka, Data Transfer Objects – DTO)

Data Clumps Clumps of data items that are always found together.
Refused Bequest Subclasses don’t want or need everything they inherit.

The Liskov Substitution Principle (LSP) says that you should be able to treat any subclass of a class as an example of that class.

Inappropriate Intimacy

Two classes are overly entertwined.

Lazy Class

Classes that aren’t doing enough should be refactored away.

Feature Envy

Often a method that seems more interested in a class other than the one it’s actually in. In general, try to put a method in the class that contains most of the data the method needs.

Message Chains

This is the case in which a client has to use one object to get another, and then use that one to get to another, etc. Any change to the intermediate relationships causes the client to have to change.

Middle Man

When a class is delegating almost everything to another class, it may be time to refactor out the middle man.

Divergent Change

Occurs when one class is commonly changed in different ways for different reasons. Any change to handle a variation should change a single class.

Shotgun Surgery

The opposite of Divergent Change. A change results in the need to make a lot of little changes in several classes.

Parallel Inheritance Hierarchies A special case of Shotgun Surgery. Every time you make a subclass of one class, you also have to make a subclass of another.

Smells to refactoring. Beautiful code continues…

I just found this good resource with a summary of techniques to identify and refactor smelly code.
It’s a good summary of what you get explained with examples and detailed comments in the Fowler’s book.

The original post is at the java.net wiki SmellsToRefactorings

Smells Within Classes


Comments Should only be used to clarify “why” not “what”.
Can quickly become verbose and reduce code clarity.
Long Method The longer the method the harder it is to see what it’s doing.
Long Parameter List Don’t pass in everything the method needs; pass in enough so that the method can get to everything it needs.
Duplicated Code
Large Class A class that is trying to do too much can usually be identified by looking at how many instance variables it has. When a class has too many instance variables, duplicated code cannot be far behind.
Type Embedded in Name Avoid redundancy in naming. Prefer schedule.add(course) to schedule.addCourse(course)
Uncommunicative Name Choose names that communicate intent (pick the best name for the time, change it later if necessary).
Inconsistent Names Use names consistently.
Dead Code A variable, parameter, method, code fragment, class, etc is not used anywhere (perhaps other than in tests).
Speculative Generality Don’t over-generalize your code in an attempt to predict future needs.

This post will be moved to TNW Wiki and Resources area… with the full list.

I had mentioned in another post I found a refactoring tool for VB.NET 2003 at KnowDotNet. I just wanted to thank their developers for saving the VB.NET 2003 community from doing refactoring manually, and special thanks to Les Smith for correcting some problems and giving a fast support.
For those curious about the tool, the url is here

Beautiful, beautiful, beatiful, beautiful code…

A programmer should take great pride on what she does, coding in a hurry and with a tight deadline often produces unreadable code, it might work, but yikes! who’s gonna be able to maintain it afterwards…Only when you are a zen on identifying code smells you can create beautiful code from the beginning and in a hurry. It takes practice, it’s an art and you don’t become a sensei in a blink.
I think I mentioned before I was embedding myself into the pages of this book:

My programmer’s life has been more fixing someone else’s code than creating code from scratch. No programmer likes to do maintainance, but hey! welcome to real world, code has to be maintained.

I just found this great article on what can be defined as beautiful code. It doesn’t have Fowler’s technical explanations but coming from a mathematician (Matthew Heusser) it’s certainly concise: (taken from the original article at DDJ)

  1. Beautiful Code is readable. Perhaps nothing is worse than trying to maintain software that does everything yet no one understands. This means that our functions shouldn’t be too long and should accept a reasonable number of variables. What’s “reasonable”? Military science (and chess, for that matter) teaches us that most people can only keep 3-7 variables in our head at the same time. When we get beyond that, we lose track of things, and that means we have forgotten things, which means defects. At that point, it’s time to consider breaking our software into smaller chunks.
  2. Beautiful Code is Focused. Code should do one thing, and do it well. All the object oriented theory about model-view-controller is essentially an attempt to separate the user interface from the business logic from the back-end system. Mixing these up limits reuse and makes test automation look more and more like fantasyland. I will just say that we should strive for simplicity and generality–to do one thing and do it well. I would submit, however, that this subject is worth researching.
  3. Beautiful Code is Testable. A well-defined function, given specific input, should have a clear expected output. This makes sense, yet many functions are written with “out of bounds” behaviors that are undefined. For example, consider a function designed to take in a coupon_id and determine if that coupon is valid. You can write the function signature in pseudocode in two different ways:

    • Option 1:
      sub get_eligibility_of_coupon(coupon_id)
      returns boolean;
    • Option 2:
      struct eligibility_type(ok boolean, msg string, good_coupon boolean);
      sub get_eligibility_of_coupon(coupon_id, optional date assume sysdate)
      returns eligibility_type;

      Assume a coupon_id is an integer. What happens in option 1 when you pass in -1? Or, for that matter, any value that isn’t a valid coupon? Or Null? We don’t know. To test option 1, we need to know some coupons that are valid or not valid as of right now. We probably have to write a query.

      For option 2, we can create a list of coupons that are valid as of a certain date, then pass in that date. We can test all kinds of interesting scenarios like “what happens on leap years?” We can provide a different response if the coupon_id was invalid than if the coupon_id was just expired. In short, option 2 is testable. Murphy’s Law applied means that testable code is better code.

  4. Beautiful Code is Elegant. I’ve heard it said that the charlatan makes the simple seem hard to understand, and the genius makes the complex easy to understand. Elegant Code (like recursion) shows up when the complex program has a simple solution. When the specification is three pages and the code implementation is one. It’s hard to grasp “elegance”, but we’ve all seen bloated, bug-ridden code that was not elegant. If you’re like me and can’t clearly define elegant, then my suggestion is simple: When coding, remember buggy, junky code, and create software that is the opposite. Elegant code is powerful code… As Antoine de Saint-Exupiry said so eloquently: “Perfection (in design) is achieved not when there is nothing more to add, but rather when there is nothing more to take away.”

Continues on next post…