the steep learning curve misunderstanding

June 15th, 2009

I keep bumping into articles or presentations where “steep learning curve” is improperly used, so I’ve decided to clear up the confusion. People often think that steep learning curve means something that requires a great deal of effort to learn. Well, it doesn’t.

Given the most common agreement about graphs of functions, we put effort (time, number of trials) on x-axis, and knowledge (skill) on y-axis. Knowledge is a function of effort; this means that f(x) will tell us the amount of knowledge a person has, given the amount of effort the person has put into something.

Let’s take a look at a shallow learning curve.

Gradual (shallow) learning curve

Gradual (shallow) learning curve


You can see that knowledge rises rather slowly as effort is put in learning. This means that something is hard to learn.

Now let’s take a look at a steep learning curve.

Steep learning curve

Steep learning curve


It’s obvious that knowledge is gained very fast. Even with a small amount of effort, skill gets high quite fast. This means that something is easy to learn.

So, remember that steep learning curve means easy to learn, and gradual learning curve means hard to learn, and stop misusing the term. :)

Author: Categories: Thoughts Tags: , ,

Talk: PHP in varnost

June 7th, 2009

I just published the slides and accompanying files for my <?php konferenca 2009 talk. You can download them here.

Update: video of my talk is available. And also other videos from the conference. All in Slovene.

Author: Categories: Talks Tags: , , , ,

Slovenian PHP conference

May 12th, 2009

Getting ready for <?php konferenca, the Slovenian PHP conference. I’ll try to shed some light on security issues (and why they are bad), and on how to properly secure a web site (and why that’s good). The workshop is wonderfully imaginatively titled PHP and security.

Author: Categories: Talks Tags: , , ,

the dark side of IE6Update

April 21st, 2009

Most of you probably know about IE6 Update (implementation of which is, in fact, a fork of Activebar2), a movement that is supposed to help us developers force users to move away of the browser that is long past due. Well, while this project has a good intention, things shouldn’t be done that way.

Let’s categorize people in three groups. The first group are the tech-savvy users that know their way around their computers. The second group are people that know how to use a computer and the internet, but still take advice from the first group on matters like what program for recording DVDs is the best, what graphics card to buy etc. The third group are the ones that use computers, but don’t know much. This is the group that installs the most viruses on their computers. If I had to estimate the number of all people that belong to this group, I’d say about 50%, and I’m probably being generous. These are also the folks that we, users from group 1 and 2, are always yelling to: don’t install software from the web! Be careful what you click! You can get your computer infected if you install things from websites! If the website you’re visiting offers you to buy/install something suspicious, close it!

Which of these still use IE6? The third group, obviously, unless somebody from the first or second group installed Firefox on their computer. And who else? The people that work in companies that have more or less strict software-upgrading policies. The upgrades in these companies are performed by system administrators (or their slaves), that in most cases know what they’re doing.

Now let’s throw these people on the web and add this IE6 information bar on the websites they visit. The first and second group won’t see them, because they’re already using a better browser. The only people that will see it are the ones that don’t know what the hell the message is saying and the ones that can’t upgrade their browser by themselves.

If the group 3 does what we’ve been telling them for years, they’re gonna get scared, leave the site, and surely won’t install anything. So, not only the IE6Update didn’t reach its most-targeted users, it actually did worse: it scared the users off of a site that’s most likely a perfectly legitimate company site, a blog, or whatnot. Keep in mind that users from group 3 don’t visit slashdot.org, and the information bar is most likely out of the context of the website they’re visiting.

And what will the people that can’t upgrade their own browsers do? Not much, because they can’t. Most of them won’t even suggest it to their system administrators, because they don’t get to talk to them, and even if they could, they wouldn’t, because system administrators bite. So, another target group missed. Is there anybody left? No. Well, yes, the system admins themselves. Well, this is actually the group that the project should be targeting, but not by making random websites show the message.

To recap this point; the majority of people that will see this notice, will either ignore it, be confused by it, or even be scared off of a website, but they won’t upgrade their browser.

The other thing that’s wrong with this approach is that it’s exploiting (yes, exploiting) the information bar UI. It’s not meant to relay custom messages to users, it’s purpose is to let users know something from the specific tool they’re using — the browser. It should only be used by the browser. By using the information bar to show custom messages, you cross the line between good and bad practices, and are no better than spammers and attackers, which try to disguise their messages to gain users’ attention. Like a chatbox coming from the lower right corner, which is supposed to make you think you’re attractive, because a nice girl wants to talk to you. Or the Windows95 dialogue box that tells you you’ve won a car (probably the seventh car this year).

The Browser Information Bar is so useful only because through it the browser relays self-related important messages to the user. It has a distinctive UI, and lets users immediately know that their browser has something relevant to say. To push this thought further, it sends two messages to the user; the first message is that there is a state of the environment (the browser itself) that the user should be aware of — this is relayed immediately by the bar’s UI. The second message is the message itself. And while “having IE6″ could be considered to be a “defective system state”, this just isn’t a browser-created message, and is not legitimate. Where would we end if we start using this bar for everything? For notifying people they have private messages, for news, for advertisements? Well, it wouldn’t be the end of the world, but the browser’s messages would get lost among these less important ones.

So, even though I strongly agree that IE6 should be burned, and its ashes should be eaten by zombies, which should then also be burned, I strongly disagree with this project. It’s for a very good cause, but that’s a wrong way to achieve it.

Author: Categories: Thoughts Tags: ,

Linux isn’t safe enough?

March 28th, 2009

Slovenian government decided that Linux and open-source aren’t appropriate for government usage. The reasons being (a recap from the source):

  1. Using open-source browser instead of horrible MSIE is inappropriate because “MSIE is free anyway, and using other browsers can cause problems with existing applications”. The facts that MSIE is the least secure A-grade browser on the market, and that in Slovenia Firefox has the biggest share apparently aren’t important.
  2. OpenOffice is a viable option (wow!)
  3. “Linux isn’t appropriate for workstations because it’s code is too open and it can become too vulnerable in case of mass usage.” I’m speechless.
  4. Linux is already used on most servers. Impressive.
  5. “Security is an issue with OSS, because the source code is available to general public.” Just as for #3, I remain speechless.

Source: slo-tech.com (in Slovene)

This is what you get if uninformed people make decisions. It’s utter non-sense with no solid arguments. Some of the points can in all fairness be called STUPID.

Author: Categories: Thoughts Tags: , , , ,

Avoid micro-optimizations

March 10th, 2009

I’ve read this post about micro-optimization today, and I think many of the listed hints are wrong. Not wrong in way of being false, but in a way that you shouldn’t use them. Sebastian already wrote something about it, but more can be said.

The difference between static and object method call isn’t about speed at all, it’s about what you’re dealing with and what you’re trying to do. If you have an object, you call an object method. If you have a class with a static method, you call the static method. You shouldn’t choose between the two just for the sake of speed. You shouldn’t even have the option of choosing. They’re not interchangeable. And, in most cases you should be using objects, not classes, for testability’s sake.

A similar case can be made for “accessing a global variable is faster then an object property”. If I start developing with this hint in mind, and I start putting object properties in the global scope, what I am going to get? A mess, that’s what. You should never think about putting an object property in the global scope, for any reason, optimization included.

Another example would be “an array is a faster alternative to a class with several fields”. (Should be object, not class.) Again, this makes little sense. An array is a hash-like storage of data, an object is a black box that receives and sends messages, it’s encapsulated data with behavior attached. These two are two different things, and if I change the code to use arrays instead of objects, the change ripples throughout the rest of the code. Again, this leads to messy code. Not to mention that in the spirit of OOP you should be aiming to use objects, not arrays. Sure, there are cases where this hint would be suitable, but optimization like this should be the last thing you think about.

There are more hints like this, but I’m not going to list them all, because I’ve made my point: most of the hints are invalid, because they compare non-interchangeable things. If I push it a little, it’s almost like saying: not using echo is faster than using it. Yes, it’s completely true, but these two options don’t do the same thing.

I can’t help myself, so I’ll say a little something about the famous PHP quotes optimization: single quotes are faster than double quotes. First, these two aren’t the same, so changing one to another ripples out. Second, with quotes it’s only about readability and taste. Third, the speed gain is literally negligible. This is another hint you should forget as soon as possible. A second spent on quotes optimization is a second lost. I just lost a few minutes writing this, but some readers will hopefully gain them by not bothering about optimizing quotes.

A lot can be said about optimization, but most of these hints sure aren’t worth remembering. Even more; forget them as soon as possible. If you have a speed problem, find out where it is, and fix it. In the vast majority of the time it’s IO-related resources: the database and files, maybe network shares, or whatnot. I’ve never seen a real-life problem where for statement was causing problems and foreach solved them. This just doesn’t happen, except maybe if you’re computing Pi in php-cli.

The path to optimization should be:

  1. Write working code, no matter how slow it is. It’s a million times better than fast code with bugs.
  2. If and only if you undoubtedly have performance issues, profile your code, locate and measure slow code.
  3. Optimize the slowest thing. Only the slowest thing.
  4. Loop.

Also keep in your mind that by optimizing your code, you reduce readability, and consequently maintainability. This means that you’ll lose more time the next time you come back to update or fix the code.

There are also some good points that Alex makes, so I’ll repeat them here, because these are worth remembering:

  • use prepared database statements,
  • avoid @ (error control operator),
  • avoid notices and warnings in your scripts.
Author: Categories: Thoughts Tags: ,

array() == false

March 7th, 2009

Yesterday I’ve noticed that too many queries are sent to the database server, even though the result should be cached in memcache. After digging into the source and testing, I’ve discovered something like this:

  1. $results = $memcache->get('key');
  2. if (!$results)
  3. {
  4.   $results = $this->fetchFromDb();
  5.   $memcache->set('key', $results);
  6. }
  7. return $results;

The fetchFromDb() method returned an empty array, which was stored in memcache. But, as it turns out, the bug was in checking of $results. An empty array evaluates to false when checking for true/false. I knew that already, but I missed this one.

So, the script issued a query, even though it already had a result. Luckily, this only happened with empty result sets, so the query was fast, and didn’t overload the server.

The correct code would be:

  1. if ($results === false)

I’ve lost quite some time over this, so I’m posting this as a reminder: if possible, use strict checking.

Author: Categories: Thoughts Tags: ,

WideImage 1.0 beta 2 released

February 19th, 2009

I’ve just released it. You can download it here. Optionally, you can use the 1.0-beta-2 svn tag.

This is the last release before RC1, which is coming soon (Q1 2009 expected). The main purpose for this release is stabilization, new unit tests, bug fixes, and some features. The online documentation is left behind (mostly still for beta 1), but no major API changes were made. The inline docs hold a more up-to-date documentation.

Magic dimensions
WideImage now supports an extended notation of dimensions for some operations (resize, crop, merge, …). The possible uses are:

  • integer/float – literal value is taken for coordinate
  • percent string – the coordinate in percent of the dimension
  • center-relative coordinate – specify the coordinate relative to center, rather than absolute

Examples:

// crops a 50x40 rectangle, starting at 10, 20
$cropped = $img->crop(10, 20, 50, 40);

// crops a 50% (half of the width) x20 rectangle,
//   starting at 0, 20% (20% of the height)
$cropped = $img->crop(0, '20%', '50%', 20);

// crops a 100x50 rectangle directly
//   in the middle of the image (center-relative coordinates are used)
$cropped = $img->crop('c-50', 'c-25', 100, 50);

These “magic dimensions” will acquire a less silly name (smart coordinates) in RC1, and will be developed further.

Loading from files without extension/mime-type
Is now supported. That’s it :) . I’ve decided to use imagecreatefromstring(file_get_contents($filename)), so now the image format is detected automatically. No more format or mime-type hinting is necessary. The other side-effect is that now WideImage suddenly supports all GD2-supported formats for reading. For writing, it’s still GIF, JPEG, PNG, GD, GD2. BMP is scheduled for RC1, but may end up in RC2.

Other stuff

  • AutoCrop — See demos in the package for details.
  • PS font support added
  • Canvas magic supported: the Canvas object now supports all functions that start with “image”, and you don’t have to pass an image handle to it.

    For example, to draw a red line:

    // you had to do this:
    imageline($image->getHandle(), 0, 0, 50, 50, $image->allocateColor(255, 0, 0));
    // now you can do this:
    $canvas = $image->getCanvas();
    $canvas->line(0, 0, 50, 50, $image->allocateColor(255, 0, 0));
    

    At first, it may not seem much, and maybe it isn’t. But at least I can say that Canvas supports custom drawing. :)

All in all, this is not a feature release. If you’re annoyed by bugs in beta1, or are looking forward to try AutoCrop, then upgrade, otherwise it’s not really necessary. :)

Author: Categories: WideImage Tags: ,

WideImage class/file naming scheme will change in RC1

February 13th, 2009

I’ve been thinking a lot about this, and I’ve decided that I’ll change the class/file naming pattern in WideImage RC1 at the cost of breaking BC. There are two reasons for that: standardization and namespaces.

While I’m not really fond of PEAR-like naming (I prefer class names short and neat), it’s the current unofficial standard for user-base packages. Plus, class names can only be short and pretty if you can ensure you’ll have no class-name collisions. This means that only classes that are very specific (i.e. DirectoryIterator), or end-user can have such names, not the ones that come with libraries, or are introduced in the language itself when it’s already mature (PHP’s Date class collision, hint hint).

The other upside to this change is that it’s namespace-ready. When PHP 5.3 will be installed by most hosts, packages will start making a move towards the use of namespaces, and WideImage will be no exception. Changing the naming scheme now ensures that the users will have time to adopt the new scheme and will not have much trouble when the change towards namespaces is made.

Along with this change I’ll also drop support for autoloaders in WideImage. Autoloading is a great feature, but isn’t the right tool to use here, and caused a few problems when the library was embedded within some other project that already had autoloaders. So, the files will be included directly from WideImage.php, which shouldn’t cause much of an overhead, since the number of files is rather small.

Hopefully, I’ll also manage to put all this into a PEAR package, although for now not through the official PEAR repository. I believe these changes will make it easier for the developers to install and use this library. The price will be quite high, because backwards-compatibility will be broken by these changes, but it’s better now than never.

When are the changes expected? I’ll soon publish a beta2 version of the library, which will still have the old scheme, but will also create a RC1 branch in which I’ll make the changes. Both releases are scheduled in Q1 2009, which means quite soon.

Author: Categories: WideImage Tags:

hi, a/s/l

February 7th, 2009

I’ve decided to start up a blog where I’m going to write about my developing activities, experiences and thoughts. This will also serve as a main blog for my open source project WideImage, an object-oriented PHP5 library for managing images.

I’ve also written a bit about myself, so you can have a look-see of who I am.

Author: Categories: General Tags: ,