Pythonize : Classes in Python

This series of articles, “Pythonize” will serve as an aid for python beginners. In this chapter I will try to explain all about python classes. In this series I will let python code talk to you more than me.

A few interesting things about python for you: Internet giants, Google and Yahoo, maintain a large code-base in python and promotes python to a large extent. Google apps can now be developed in python using the python APIs provided by Google. Python is famous for more functionality in less time being a scripting language and at the same time enabling OOP(Object Oriented Programming). It’s rich with libraries and online help. You can access

 

Python Class:

Class is a template or prototype that defines the fields and methods common to all objects created with this class. Classes in python starts with the keyword ‘class’ followed by the class name and then an optional set of classes separated with comma inside parenthesis, which will be inherited into your class depth-first and left-to-right order. It is then ended with a full-colon and all the indented block of statements just after that forms the body of the class. Note: Python keywords are case-sensitive. Stick with small letters. Below code won’t compile.

E.g.

Image FYI: pass is the keyword used to avoid error and it represents an empty block here. Variables: Data type of python variables is set based on the value assigned to it. Some valid variable assigning:
E.g.

Image

Hope you noted that I have reassigned ‘variable1’ from number to string without any extra code and the program worked fine. That is the extent of freedom python gives you. There is no keyword to define the scope of variables in class and all your usual variables declared inside class will be publicly accessible. Let try this with an example.

E.g.

6a Output: 6 Recent python versions came up with a solution to declare private variables. You just need to precede your variables with two underscores (__) and magic: it became private. Such private attributes are declared outside __init__ function for data hiding. Lets experiment this with a few lines of code.

E.g.

7a Output:

7

You may doubt that this is because I tried to print the variable ‘name’ where the class variable is “__name”. Lets clear your doubt.

E.g.

8a Output: 8

Here we tried to print the same variable name. Since preceding class-variables with two underscores make it private, we got an ‘AttributeError’. Python protects such private members internally by altering its name to contain the class name and we can access such members by following the template:

<objectName>._<className>__<attributeName>

Here our object name is prs, class name is Person and the variable is __name, so as per our assumption we should get the variable value by printing ‘prs._Person__name’

E.g.

8-1a Output: Note: Use “self.” with variable names to refer to instance variables and class-name followed by period (.) and then variable name to refer to class variables. Otherwise python will consider it as a global name and raise an error or give unpredictable outputs if a global variable with similar name exists. Lets have one example of class variables and then go to next topic:

E.g.

Image Output: 10 Here, you can see that by changing company name of emp2, it got reflected in emp1 as well i.e. emp1 and emp2 points to a single memory and such variables are technically called as class variables; one single memory for all the classes.

 

Class functions:

Functions of class decide the behavior of the class. They act as an interface to the outside world. Take a look at a sample class with a function ‘print_emp_details’.

E.g.

9a

Output: 4

Constructor:

Object Oriented Programmers might already know the role of constructor in a class. For those who don’t, let me explain. Constructor is the function that gets automatically invoked at the time of object-creation which is usually made use of for resource allocation. Python differs a bit from other OOP languages like java or C++ in constructor-name and it’s invocation. In python,

  • constructor of parent classes will not get invoked at the class of object creation of child class.
  • constructor function in python is always __init__().

E.g.

Image

You might be wondering about ‘self’ in __init__ function. In python, you will see this variable as the first argument in all the class functions without which the execution will fail. ‘self’ is not a keyword but instance of a class. You can use any other name for this parameter but it’s part of coding standard, which makes your code readable and easy to understand for other programmers. Lets stick to that standard.

E.g.

Image

Output: 1

A blank parameter list will raise a TypeError:

E.g. Image Output:

3

We have seen only constructors that don’t take any parameters so far. Now lets take a peek into parameterized constructors. As you guessed, the parameters of the constructor follow ‘self’.

E.g. 4a

Here name and hobby are the arguments and during object-creation we passed the arguments string “Sreejith” and “programming” as name and hobby to the constructor. One thing to note is that, with this class you won’t be able to create an object without any parameters. You will get the following error:

E.g.

4b

Output:

4c

Lets see a work around for that. Here we will assign a default value for the constructor variables and thereby the constructor assumes the default value if not explicitly specified at the time of object creation.

E.g.

4d Output: 4e

 

Destructor:

E.g.

11

Output: 11

 

Other base methods you can overload in your class:

  • __repr__(self)
    • To represent the object in evaluatable string
    • E.g.: repr(obj)
  • __str__(self)
    • To represent the object in string
    • E.g.: str(obj)
  • __cmp__(self, obj1)
    • For comparing with another object
    • E.g.: cmp(obj, obj1)

Inheritance:

Lets straight away get into a python code that successfully uses inheritance to reuse code and at the same time overrides needed functions.

E.g.

Image Output: 12 Here we override the print_name() function in Child and GrandChild class but uses the same smile() function as such. Functions are searched in the following hierarchy:

  1. Derived class
  2. Base class in the order of depth first and then left-to-right.

There are two functions which comes handy with class inheritance:

  • issubclass()
    • Returns a boolean value based on if the first parameter is a sub-class of the second parameter.
    • E.g.: issubclass( subclass1, superclass1 )
  • isinstance
    • Returns a boolean value based on if the first parameter is an object of second parameter.
    • E.g.: isinstance( object1, class1 )

Thus we have come to the end of this chapter. Lets recall what we have learned from this chapter. We learned

  1. Basic syntax of class
  2. Variables; How to make variables private; Class variables and Instance variables
  3. Class Functions/Methods
  4. Inheritance; Function overriding

Meet you next time..

Linux Device Driver: 1 of n

Lets try for a “hello world” Linux driver this time. Yeah, I know there are heck lot of tutorials dealing with the same but since I am trying it out myself, I would like to share the steps I followed and the experience I gained out of it.
Drivers, not just in Linux but in all Operating Systems, lie directly on top of hardware, abstracting the device specific operations. This reduces the dependency of Operating System on hardware and thereby it makes easy for an operating system to switch between different hardware.
Didn’t get that? Let me try that once more. Before that let me tell you one fact: devices are categorized into three sets in Linux (this one is specific to Linux and Unix):

  1. Character Devices    – devices which read one byte at a time.
  2. Block Devices        – devices which a block (usually 512 bytes) at a time.
  3. Network Devices        – devices which enables transfer(to be specific, send and receive) of packets over network.

By categorizing devices, Linux expects driver of each category to expose a standard interface. Now what is the use of that? Suppose two devices dev1 and dev2 have its own specific driver driv1 and driv2. If both drivers has a common interface (functions through which it gives out its services), say both implemented f1() and f2() functions, then a program using driv1 one will call f1() and f2() to use the dev1. Suppose at one point of time the user wants to replace dev1 with dev2; since the driver driv2 too follows the standard and has implementation of f1() and f2(), there will be no change in the calling process and it need not be recompiled. Thereby we could isolate the changes to a very small section. This is a good programming practice even outside driver-programming.
In this post, we will try to write our first driver which can be used with Linux. Driver-programming is a little bit different from our usual programming. Program execution in our everyday programming starts in ‘main’ function but in driver-programming main function disappears. Lets see our hello-world without any further ado.

#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE(“Dual BSD/GPL”);

static int hello_kernel_init(void)
{
    printk(KERN_ALERT “Hello Kernel, at your service..\n”);
    return 0;
}

static void hello_kernel_exit(void)
{
    printk( KERN_ALERT “Goodbye Kernel, I am no longer at your service..\n”);
}

module_init(hello_kernel_init);
module_exit(hello_kernel_exit);

Don’t worry about the weird function calls: printk. Hope you already got the idea about module_init and module_exit. Those are to register our functions (hello_kernel_init and hello_kernel_exit) as functions to be called at the time of module initialization and exit. Good question: “when does that happen”. A driver module is invoked as part of any software requesting for a hardware service. That request from application goes to operating system and o/s (short form for operating system) loads the driver module specific to that hardware to serve the application. Leave those topics for the time being, we will cover it in coming chapters. ‘printk’ is just a ditto of printf function in C language; the difference is it has an identifier -> KERN_ALERT at the starting of first argument which tells the kernel the priority of the message printed by that printk function. There are other similar identifiers like KERN_INFO, KERN_WARNING, etc . Driver-modules are not supposed to use any library functions other than those implemented in kernel. This is because we wont link our code with libraries at the time of compilation. Linking and loading is the job of kernel. So when kernel links our module, if it sees any reference to functions which it doesn’t implement, it will cause a failure of our code, if not an entire system failure at rare cases.
Forgot to tell you that my development environment is Ubuntu with kernel version 3.2.0
Now I need a makefile to ease my compilation. This simple code of-course should have a simple make-file as well and there it goes:
obj-m := hello_kernel.o
Yes, just one line and the kernel build system will take care of the rest.
At the time of ‘making’ we should give the path of our kernel source. To find that we should firt find the kernel version you are currently running on. Run ‘uname -r‘ at your terminal.

unamer

You will get something like “3.2.0-40-generic”, don’t worry if it’s just numbers. Now the kernel source tree path will be “/lib/modules/3.2.0-40-generic/build”. This will be a soft link to original path and this will do for us.
Now we have our source code in “hello_kernel.c” and make file “Makefile”.
Now run the command
make -C /lib/modules/3.2.0-40-generic/build/ M=`pwd` modules
This command starts by changing its directory to the one provided with -C option, which is your kernel source directory and finds the kernel’s top-level make-file. The M= option is to help the make utility to traverse back to our current directory to build target: modules

make
Now our module is ready to be loaded. Run the below commands.

insmodlsmodrmmod

You need to have sudo privilege since we are messing with kernel. insmod will load the driver module, lsmod will list all the loaded modules and we are grepping our module from the result and rmmod removes the driver.

Hope you notice that we had a few printk statements in our code but nothing appeared in the console. It is because all kernel specific logs go to “/var/log/syslog” file in Ubuntu. Likewise different Linux distros will have its own specific file. You will see whatever we printed out in our driver code in those file. Just run the below command in our case:

cat /var/log/syslog | tail

log

There ends our first step towards mastering Linux Device Drivers. Wait till the next chapter for advanced topics..

Project Euler Problem 8: Solution in C++

/*

Largest product in a series

Find the greatest product of five consecutive digits in the 1000-digit number.

73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450
*/
#include<iostream>

using namespace std;

int main()
{
string s = “7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450”;
//cin >> s;
int max_prod = 1;
int ans_start = 0; // answer ie. 5 consecutive numbers starts at ans_start
for( int i = 0; i < 5; i++ )
{
max_prod *= static_cast(s[i]-‘0’);
}

int prod = max_prod;
for( int i = 5; i < s.size(); i++ )
{

if( static_cast(s[i-5]-‘0’) != 0 )
{
prod /= static_cast(s[i-5]-‘0’);
}
if( static_cast(s[i]-‘0’) == 0 )
{
clog << “skipped ” << “i = ” << i << ” s[i] = ” << s[i] << endl;
continue;
}
clog << “i = ” << i << ” s[i] = ” << s[i];
prod *= static_cast(s[i]-‘0’);
clog << ” prod = ” << prod << ” /= ” << static_cast(s[i-5]-‘0’) << ” *= ” << static_cast(s[i]-‘0’) << ” max_prod = ” << max_prod;
if( max_prod < prod )
{

ans_start = i-4;
max_prod = prod;
}
cout << ” ans_start = ” << ans_start << endl;
}

for( int i = ans_start; i < ans_start+5; i++ )
{
cout << s[i] << ” “;
}
cout << endl << max_prod << endl;
}

//    7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883
//    99879
//    7908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450

// ANSWER IS 40824

Project Euler Problem 7: Solution in C++

/*

10001st prime

*/

#include <iostream>
#include <cmath>

using namespace std;

bool isPrime( long num )
{
switch( num )
{
case 1:
case 4:
case 6:
case 8:
case 9:
return false;
break;
case 2:
case 3:
case 5:
case 7:
return true;
break;
}
if( num % 2 == 0 || num % 3 == 0 )
return false;
long sq_root_of_num = floor( sqrt(num) );
long i = 5;
while( i <= sq_root_of_num )
{
if( num % i == 0 || num % (i+2) == 0 )
{
return false;
}
i += 6;
}

// num is prime
return true;
}

int main()
{
long num = 3;
int index = 1;

while( index < 10001 )
{
if( isPrime( num ) )
{
index++;
}
num += 2;
}
num -= 2;
cout << num << endl;
}

// ANSWER is 404743

Euler Problem: Solution of Problem-6 in C++

Q)The sum of the squares of the first ten natural numbers is,

#include  

#define N 100

using namespace std;

long raiseTo ( const long num, const long n ) {
    int ans = num;
    for ( int i = 1; i < n; i++ ) {
        ans *= num;
    }
    return ans;
}

int main ( int argc, char * argv[] ) {
    long result =     (             ( raiseTo ( N, 4 ) / 4 ) 
                            +     ( raiseTo ( N, 3 ) / 6 ) 
                            -     ( raiseTo ( N, 2 ) / 4 ) 
                            -    ( N / 6 ) 
                    ); 
    cout << result << endl;
}

// 25164150

Euler Problem: Solution of Problem-5 in C++

#include 

#define X 20

using namespace std;

long hcf ( const long & small_num, const long & big_num ) {
    if ( small_num > big_num ) {
        return hcf ( big_num, small_num );
    }
    else {
        if ( big_num % small_num == 0 ) {
            return small_num;
        }
        else {
            return hcf ( big_num % small_num, small_num );
        }
    }
}

int main ( int argc, char *argv[] ) {
    long result = 1;
    long temp_hcf;
    for ( int i = 1; i <= X; i++ ) {
        temp_hcf = hcf ( result, i );
        result /= temp_hcf;
        result *= i;
    }
    cout << "Result = " << result << endl;
    return 0;
}

// Result = 232792560