Wednesday, March 9, 2011

PHP: self versus this

If you haven't thought about it yet, self in PHP refers to class methods visible for the particular class, whereas this refers to the object methods visible for the instantiated object.

Simple example:
class a {
    function first() {
        echo 'a:first ';
    }

    function second() {
        echo 'a:second ';
        self::first();
    }
}

class b extends a {
    function first() {
        echo 'b:first ';
    }

    function third() {
        echo 'b:third ';
        self::second();
    }
}

$objB = new b();
$objB->third();

This will print:
b:third a:second a:first
because self does not care about the object instance.

If you replace, in a::second, the line
self::first()
with the line
$this->first()
the output will change to what you might have expected in the first place:
b:third a:second b:first

(As observed for PHP 5.3.3)

You have been warned :)

Sunday, February 27, 2011

Python quirks

Saw for myself a funny quirk in Python (2.6).

Suppose you want to create a list of dictionaries, which will be populated later.

My first idea was to do this:
 >>> a = [{}]*3

At the first glance, it works. But just look at this:
>>> a[0]["bbb"]=1
>>> a
[{'bbb': 1}, {'bbb': 1}, {'bbb': 1}]

Not exactly what you would expect, heh.

The way to do it right seems to be more wordly:
>>> a=[]
>>> for i in range(3):
... a[i]={}
>>> a
[{}, {}, {}]
>>> a[1]["bbb"]=1
>>> a
[{}, {'bbb': 1}, {}]

By the way, initializing a list with None is not a problem:
>>> c = [None]*5

Nevertheless, this will not work:
>>> for e in c:
... e = {}
...
>>> c
[None, None, None, None, None]

This will:
>>> c[2]={}
>>> c[1]={}
>>> c[2]["aaa"]=3
>>> c[1]["bbb"]=4
>>> c
[None, {'bbb': 4}, {'aaa': 3}, None, None]
>>> c[1]["aaa"]=5
>>> c
[None, {'aaa': 5, 'bbb': 4}, {'aaa': 3}, None, None]

Tuesday, November 16, 2010

Simple recipe for trouble (PHP)

1. In a base class, make a method which returns the date in the given format, with some specific text format as default, like this:


        class MyHumbleBaseClass {
   function getDateParam($format="Y-m-d h:m:s") {
              $timestamp = .... 
              if ($format==null) return $timestamp;
              else return $this->formattedDate($format);
           }
        }

2. Override it in some derived class like that:
class MyHumbleDerivedClass {
           function getDateParam() {
              return MyHumbleBaseClass::getDateParam();
           }
        }


3. To add some extra twist, forget that the default format is not null, and do things like that:

if ($derivedObject->getDateParam()<$timestamp) {
    // think that it should work
}
4. Enjoy.

PS In fact, simple overriding will probably not be enough; if you supply the parameters, you will end up calling the parent function. But if you use the base method as a strategy from within your other class, thus shielding the direct access to the base class completely, then the success is practically guaranteed.

Monday, July 26, 2010

little javascript discoveries, aka shame on me :)

Shame on me, after going through this cheatsheet I have realized there were some things I didn't know about javascript:
  •  variables declared with var are declared locally, variables declared without var are not;
  • to check whether the value is undefined, one has to use the following construct: 
    • if (x === undefined)
    • and NOT if (x==undefined) because it will always be true.
They forgot to clearly mention the difference between normal arrays:
  • x = [1,2,3];
and associative arrays
  • x = {'a':1, 'b':2, 'c':3};
though they do refer to those as "hash literals" (the document seems to be a bit old though).

    Friday, May 7, 2010

    Python and Quotes - how?

    More from Python interpreter:
    >>> '"Isn\'t," she said.'
    '"Isn\'t," she said.'
    Does it mean there is no way to have both single and double quotes in a Python literal???

    Update: it seems to be an interpreter bug:
    result = '"Isn\'t," she said.'
    print result
    would produce the expected
    "Isn't," she said.
    after all :)

    python and rounding

    From my Python interpreter (version 2.6.5) where I was playing with calculator:
    >>> price + 0.2342341
    22.234234099999998
    >>> round(_,3)
    22.234000000000002
    Why do I always get the stuff the wrong way?

    Tuesday, April 20, 2010

    The "binary search" script

    For some reason, it could not get pasted there.

    import util.Random
    val toFind = args(0).toInt
    val r = new Random()
    val a = (for (i<- 1 to 100) yield r.nextInt(100)).toList.sort(_<_).toArray
    def binsearch(x:Int, a:Array[Int],first:Int, last:Int):Int = {
        if (last-first<=1) {
            if (a(first)==x) return first
            else if (a(last)==x) return last
            else return -1} else {
                val mid = (last+first)/2
                if (a(mid)>=x) return binsearch(x, a, first, mid)
                    else return binsearch(x, a, mid, last)
            }
            }
    for (el<-0 to 99) println(el+":"+a(el))
    val res = binsearch(toFind, a, 0,99)
    println ("res="+res)