Monday, December 21, 2015

Python : Metaclass

Classes are objects


"In Python, everything is an object"

That applies for classes as well which means that classes:

  • can be created at runtime
  • passed as paramters
  • returned from funtions
  • assigned to variables

Builtin type function


The simplest way to create class dynamically is to use type :

def create_klass(name, **kwattrs):
    return type(name, (object,), dict(**kwattrs))

>> my_test_klass = create_klass('MyTestClass', id=0, counter=0)
>> my_test_klass
<class __main__.MyTestClass>
>> mtk = my_test_klass()
>> mtk
<__main__.MyTestClass object at 0x01F8C150>
>> mtk.id, mtk.counter
(1, 0)

my_test_klass is equivalent to

class MyTestClass(object):
    id = 1
    counter = 0

Created at runtime, returned from a function and assigned to a variable.

Class of class


Wait a minute, if everyting is an object, it would mean that my_test_klass is an instance
of a class as well... In Python, you can check the type of a class with __class__ attribute,
let's do some tests :

>> mtk.__class__
<class __main__.MyTestClass>
>> my_test_klass.__class__
>> <type 'type'>

So type is the class of Python classes.

Metaclass


Any class whose instances are themselves classes, is a metaclass.
It means that type is a metaclass : yes, the default one. We will see later how to create our own metaclasses.

When Python parses your script, it runs a routine when detecting the class keyword thats will
collect the attributes and methods into a dictionary. When the class definition is over, python determines the metaclass of the class. Let's call it Meta. At this moment, python executes Meta(name, bases, dct) where :

  • Meta is the metaclass, so this invocation is instantiating it
  • name is the name of the newly created class
  • bases is a tuple of the class's base classes
  • dct maps attribute names to objects, listing all of the class's attributes

A metaclass is defined by setting a __metaclass__ attribute to either a class or one of its bases.

The following class has metaclass definition :

class MyExampleClass(object):
   age = 30

so type is used instead and we can create this class dynamically with the following line of code :

MyExampleClass = type('MyExampleClass', (object,), {'age' : 30})

But if it has been defined like this :

class MyExampleClass(object):
   __metaclass__ = MetaPerson
   age = 30

the creation would have been done with :

MyExampleClass = MetaPerson('MyExampleClass', (object,), {'age' : 30})

__new__ and __init__


To control the creation and initialization of the class in the metaclass, you can implement the metaclass's __new__ (to control the creation of the object) and __init__ (to control the instanciation of the object) methods.

The call to MetaPerson implicitely executes the following operations :

MyExampleClass = MetaPerson.__new__(MetaPerson, 'MyExampleClass', (object,), {'age' : 30})
MetaPerson.__init__(MetaPerson, 'MyExampleClass', (object,), {'age' : 30})

Concretely, with :

class MetaPerson(type):
    def __new__(meta, name, bases, dct):
        print '-----------------------------------'
        print "Allocating memory for class", name
        print meta
        print bases
        print dct
        return super(MetaPerson, meta).__new__(meta, name, bases, dct)
    def __init__(cls, name, bases, dct):
        print '-----------------------------------'
        print "Initializing class", name
        print cls
        print bases
        print dct
        super(MetaPerson, cls).__init__(name, bases, dct)

python will print :

-----------------------------------
Allocating memory for class MyKlass
<class '__main__.MetaPerson'>
(<type 'object'>,)
{'barattr': 2, '__module__': '__main__',
 'foo': <function foo at 0x00B502F0>,
 '__metaclass__': <class '__main__.MetaPerson'>}
-----------------------------------
Initializing class MyKlass
<class '__main__.MyKlass'>
(<type 'object'>,)
{'barattr': 2, '__module__': '__main__',
 'foo': <function foo at 0x00B502F0>,
 '__metaclass__': <class '__main__.MetaPerson'>}

when  parsing the fllowing class definition (done at module import only):

class MyKlass(object):
    __metaclass__ = MetaPerson

    def foo(self, param):
        pass

    barattr = 2


Inherited metaclass


A very common error when dealing with metaclasses is the following error code :

TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

It happens with the following scheme when the identification of the metaclass fails.
Check the example below :


>>> class M_A(type):
...     pass
>>> class M_B(type):
...     pass
>>> class A(object):
...     __metaclass__=M_A
>>> class B(object):
...     __metaclass__=M_B
>>> class C(A,B):
...     pass
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

Python is lost because it does not know what is the metaclass of C : is it M_A or M_B ?
To get around this issue, the solution is to create a metaclass that inherits from both M_A and M_B. It will ensure C to have a unique and identifiable metaclass :

M_A     M_B
 : \   / :
 :  \ /  :
 A  M_C  B
  \  :  /
   \ : /
     C

which in terms of code is :

>>> class M_C(M_A,M_B): pass
...
>>> class C(A,B):
...     __metaclass__=M_C
>>> C,type(C)
(<class 'C'>, <class 'M_AM_B'>)

Automatic metaclass resolution


If you are planning to code a complex class factory and you're preparing to face metaclass conflict errors, know that out there, there is a generic metaclass creator for your classes :

http://code.activestate.com/recipes/204197-solving-the-metaclass-conflict/

Tuesday, December 15, 2015

Python : filter(), map() and reduce()

filter(), map() and reduce() tools are functional programming methods that can be
applied to iterable objects.

filter(<function>, <object>)

Iterates on object and returns the list of elements from <object> for which <function> returned True.
Usually, lambda functions are used for <function>. A lambda function returns True when the condition is met (example : lambda x: x <= 10).

values = range(100)
print filter(lambda x: x < 50, values)
# prints [0, 1, 2, 3, ..., 49]
print filter(lambda x: x > 50, values)
# prints [51, 52, 53, ..., 100]
print filter(lambda x: x%2 == 0)
# prints [0, 2, 4, ..., 100]



map(<function>, <object>)

Applies a function to every element of a list and returns the modified list.

cities = ['paris', 'london', 'berlin']
print map(lambda n: n.upper(), cities)
# prints ['PARIS', 'LONDON', 'BERLIN']


reduce(<function>, <list>)


Recursive process : at each step, passes the current operation result with the next item from the list.
By default, the first item in the list initializes the first operation result.
Note : reduce takes two parameters

print reduce(lambda x,y: x*y, [1,2,3,4])
# prints 24
# 1st cycle : multiplies 1 (first element) with 2
# 2nd cycle : multiplies 2 (result of previous operation) with 3 (next element)
# 3rd cycle : multiplies 6 (result of previous operation) with 4 (next element)


Monday, November 30, 2015

Three-tier application architecture

The three tier architecture is a client-server software architecture pattern which consists of 3 layers :

Presentation layer (or tier)

Application's topmost level, also called graphical user interface or GUI.
It displays the services to the user as well as the results of operations.
Example of technologies used for this tier : WPF, HTML.

Logic layer (or tier)

Application's processing tier. The business logic is taken care of at this level, this is the brain of the application.

Data layer (or tier)

Application's data management tier. It handles data storage and data access services. Usually, databases are used in this layer.



Advantages of this architecture:

  • Lightweight client workstation
  • Heterogeneous :  many technologies live together (client, server, ..)
  • Safer due the absence of direct link between the client and the data
  • Better distribution of processing load (e.g. load balancing)

Thursday, November 26, 2015

C++ : Private pure virtual method

class Engine
{
public:
    void SetState( int var, bool val );
    {   SetStateBool( int var, bool val ); }

    void SetState( int var, int val );
    {   SetStateInt( int var, int val ); }
private:
    virtual void SetStateBool(int var, bool val ) = 0;   
    virtual void SetStateInt(int var, int val ) = 0;   
};

Although they are private, private virtual functions can be overridden in the derived classes.
This
"allows for better separation of the specification of interface from the specification of the implementation's customizable behavior
(Herb Sutter).

Why ?


Imagine that the clas was written like this, with non-pure virtual methods :

 class Engine
{
private:
    virtual void SetState(bool val ) { // blablablabla };   
    virtual void SetState(int val )
{ // blablablabla };   
};
 and consider the following child class which overloads one method only:

 class MyEngine : public Engine
{
public:
    void SetState(int val )
{ // blablablabla };   
};

One would get in trouble by calling :

MyEngine* myEng = new MyEngine();
myEng->SetState(true);

This statement would  call SetState(int val), converting bool to int.
To have a proper inheritance, the child class shall use the using keyword to hide base class method:

class MyEngine : public Engine
{
          // To prevent SetState( int var, bool val ) from the base class,
          // from being hidden by the new implementation of the other overload

          // (below),
          // you have to put using declaration in the derived class

         using Engine::SetState;

public:
    void SetState(int val )
{ // blablablabla };   
};

This is something that the developer should always keep in mind and it can end to unexpected behaviors if not applied.
With private non-virtual, the developer could have written the first version of derived class without caring about non-hidden methods.

C++ : Inheritance types

class A
{
public:
    int x;
protected:
    int y;
private:
    int z;
};

class B : public A
{
    // x is public
    // y is protected
    // z is not accessible from B
};

class C : protected A
{
    // x is protected
    // y is protected
    // z is not accessible from C
};

class D : private A
{
    // x is private
    // y is private
    // z is not accessible from D
};

 Note that x,y and z exists in all subclasses but are not accessible in all cases.

Thursday, November 12, 2015

C++ : copy constructor

We already know the basic constructor utility which is : initializing internal members. If not constructor is specified, the default constructor initializes each of class' members with their constructor.

Now let's take a look to the copy constructor :

Point (const Point & p);

This constructor will initialize our object by copying another one :

Point p1 (otherPoint);

Note: It is also possible to define our own copy constructor to define more specifically which members should be copied.

Monday, November 9, 2015

c++ : lvalue and rvalue

l-value

C-definition

An object is a manipulatable region of storage; an lvalue is an expression referring to an object....The name 'lvalue' comes from the assignment expression E1 = E2 in which the left operand E1 must be an lvalue expression.
 C Programming Language (Prentice-Hall, 1988)

r-value


C-definition


What is sometimes called 'rvalue' is in this standard described as the 'value of an expression'.
C-Standard 

C++ definition


Every expression is either an lvalue or an rvalue.
C++ 2003 Standard 

Translation

lvalues and rvalues got their names from their roles in assignment expressions 
lvalues refers to objects and are addressable.

int a; // lvalue
char* p;
// *p is an lvalue. '*' operator returns an l-value
*p = 'c'; // OK, we can assign an l-value
*(p + 1) = 'd'; // OK

Conceptually, an rvalue is just a value; it doesn't refer to an object

int a = 5; // 5 is an rvalue
int b = 8; // 8 is an rvalue
State_te state = State_Idle; // State_Idle is an rvalue;

5 = b; // Error ! we can not assign an rvalue
State_Idle = 8; // Error ! we can not assign an rvalue
a = &5; // Error ! & Operator requires an lvalue and returns an rvalue
&b = 8; // Error ! & returns an rvalue 

Note: In C++, rvalues can refer to objects but are still not lvalues.

Sunday, April 12, 2015

Mount external hard drive with write permissions

This post has been created to keep a track of this very usual issue that I encountered recently. There are many discussions around it already but I thought that adding a very simple article with a few explanations couldn't harm. So here it is.

Linux permissions do not apply to VFAT external drives


When auto-mounted, you may see with a simple ls -la that the mounted partition is not accessible with write permission. No matter how many chmod you do, the result will remain the same : no write access. Don't worry, this is a normal behavior as the FAT32 filesystem do not support linux permissions.

Forget auto-mount


To resolve this issue, you should reconsider it. The permissions do not apply to the partition but they do to the mount point. It means that you'll have to tell linux to grant write permissions at mounting time.

Unmount your disk

umount /dev/sda1

Now mount it back with the following options

mkdir /mnt/mydisk
mount -t vfat /dev/sda1 /mnt/mydisk -o umask=0

It should now work as expected. The key option is umask which is the opposite mask to the one you give to chmod. 0 means that all users have all rights (Note: keeping it like this may be dangerous)

Automatically mount the disk at startup


This is done by editing the /etc/fstab file. Simply add the following line to it

UUID="BF12-2F81" /mnt/mydisk vfat  defaults,uid=me,gid=mylinux,umask=0    0    0

The UUID is the unique identifier of your disk (you can get it by running blkid in a console).
As you can see, I have added uid (user) and gid (group) options to allow one specific user to have write access on my disk.

A few reminders


If you're used to have your disk mounted on  /media and you're wondering why /mnt is often used, here is the explanation :

/media is usually used for auto-mounted disks
/mnt is the one that should be used when manually mounted

 
biz.