Author name: Prasanna

Python Data Persistence – Structured Python

Python Data Persistence – Structured Python

The previous two chapters explained some basic features of Python, which will empower you to develop a programming solution for just about any algorithm. Now it’s time to learn how to make the solution more tidy, efficient, and easy to maintain.
In the previous chapter, the factorial.py code calculates the factorial value of a number. Based on the same algorithm, let us calculate a combination of two numbers. In mathematics, a combination is a selection of items from a collection, such that (unlike permutations) the order of selection does not matter. Its mathematical notation is nCr. Following script uses for loop in its solution.

Example

#combinations.py
n=int ( input ( " enter n . . " ) )
r=int ( input ( " enter r . . " ) )
t=n-r
#calculating factorial of n - fn
fn=1
for i in range ( 1 ,n+1 ) :
fn=fn*i
#calculating factorial of r - fr
fr=1
for i in range(1,r+1):
fr=fr*i
#calculating factorial of t - tr
ft = 1
for i in range ( 1 , t+1 ) :
ft=ft*i
combinations=fn/(fr*ft)
print ( " C ( { } , { } )={ }". format ( n , r , combinations ) )

Output

E:\python37>python combinations.py
enter n . . 5 
enter r . . 2 
C ( 5 , 2 ) = 10 . 0 
E:\python37 >python combinations.py 
enter n . . 10 
enter r . . 5 
C ( 10 , 5) = 252 . 0

Looks alright, isn’t it? However, looking at the above code, the thing that strikes immediately is that it uses for loop thrice to calculate the factorial value of three numbers. Following code is the alternative solution to the same problem but appears to be cleaner and more concise.

Example

#combinations-2.py
#calculate factorial
def factorial ( x ) :
f = 1
for i in range ( 1 , x+1 ) :
f = f*i
return f
n=int ( input ( " enter n . . " ) )
r=int ( input ( " enter r . . " ) )
combinations=factorial(n)/
(factorial(r)*factorial(n-r))
print ( " C ( { } / { } )={ } " - format ( n , r , combinations ) )

sys Module

This module defines some important system-specific parameters and functions. In this section, you will learn one such parameter which is useful in the scripting mode of Python.
sys. argv stores a list of all command-line arguments provided to Python script. We know that the input ( ) function in a Python script is used to collect user inputs. However, inputs can also be given to the script from the command line. They are made available to the program in the form of this list object. For example:

E:\python37>python example.py aa bb

This is the command line to execute ‘example.py’ providing ‘aa’ and ‘bb’ as arguments. Three strings are stored in sys.argv list and can be accessed in the script. Name of script – sysexample.py in this case is stored at sys.argv[0]. Other arguments are stored at successive indexes. Let sysexample.py script be as follows:

Example

#example.py
import sys
args=sys.argv
print ("Hello { }".format(sys.argv [ 1 ] ) )

It is now executed from the command line, (figure 3.3)

E:\python37>python sysexample.py Python
Hello Python
E:\python37>python sysexample.py Java
Hello Java

We are going to learn few more built-in modules and their functions in the following chapters:

  • Serialization: CSV module,pickle module,dbmmodule,JSON module.
  • DB-API: sqlite3 module, pymysql module, pyodbc module.

Function with Parameters

A parameter (also called an argument) is certain data passed on to the function while calling it. The previous section (sys module) showed how command-line arguments passed to a Python script can be processed by using sys. argv parameter. Similarly, one or more parameters can be passed to function from inside a script. Values of received parameters are then processed inside the function.

Two things must be kept in mind here. First, the function should be defined taking into consideration the number of parameters it is going to receive. Secondly, the function call should ensure it passes an adequate number of parameters as anticipated in the function’s definition. Variables used in function’s definition to receive passed values are often called formal arguments. Actual arguments are the values passed while calling.
In the following script, the LoveUO function is defined with one argument with a formal name as Hang’. Its value is used in the function to print relevant messages. User input is passed to this function as an actual argument.

Example

#function-2.py
def LoveU(lang):
'function with one parameter'
print ('I love { }'.format(lang))
return
#call above function
lang=input('enter name of a language..')
LoveU(lang)

Output:

E:\python37>python function-2.py 
enter name of a language..Python 
I love Python 
E:\python3 7 >python function-2.py 
enter name of a language..Hindi 
I love Hindi

return Keyword

The return keyword at the end of the function block is merely to indicate that program flow would be returned to the calling position after the block is over. Use of return is optional in the sense program flow anyway goes back to calling position even if it is not used. However, if you intend to send some data back to the calling environment, then the return keyword must be used along with the expression to be returned.
Following script is a simple example of a function returning its result. It defines add () function to receive two numbers, perform addition, and return the result.

Example

#func-with-return.py
def add ( num1 , num2 ) :
'function assumes a two numbers to be passed'
result=num1+num2
return result
#call above function
x=int(input('enter a number..'))
y=int(input(1 enter another number.. '))
z=add(x,y)
print ( ' addition of { } and { } is { } ' . format ( x , y , z ) )

Output

E:\python37>python func-with-return.py 
enter a number..100 
enter another number..200 
addition of 100 and 200 is 300

Required Arguments

The statement that calls a function should pass exactly the same number of values as a number of actual arguments in its definition, otherwise, Python raises TypeError as in the following example, where the function is defined with two parameters but there is an attempt to call it with three values.

Example

#function-3.py
def LoveU( lang1 , lang2 ) :
'function with two parameters'
print ( ' I love { } and { } ' . format ( lang1 , lang2 ) )
return
#call above function
LoveU( 'Hindi ', ' Python ' , ' Java ' )

Output

E:\python37>python function-3.py 
Tracebaok (most recent call last): 
File "function-3.py", line 7, in <module> 
LoveU('Hindi' , 'Python' , 'Java') 
TypeError: LoveU( ) takes 2 positional arguments but 
3 were given 
E:\python37>

Values passed to a function are picked up by formal arguments in positional order. Since Python doesn’t enforce static typing, any formal argument may hold any type of data. However, there still may be errors raised inside a function if the treatment of the variable is not as per its value.

Look at the following script. The function in it receives two values. First, one is expected to be a string, and second a number. The function calculates the length of the string – the first parameter and determines if the number – second argument – is odd/even. Therefore, the function receives two values but with mismatching types, TypeError is raised when trying to compute len ( ) on a number data type.

Example

#function-4.py
def function(string,num):
'function assumes a string and number to be passed'
print ('parameter received', string, num)
print ('length of string:', len(string))
if num%2==0:
print (num,' is 'even')
else:
print (num, ' is ','odd')
return
#call above function
function ('Hello', 10)
function (10, ’Hello')

Output

E:\python37>python function-4.pyOutput
parameter received Hello 10
length of string: 5
10 is even
parameter received 10 Hello
Traceback (most recent call last) :
File "function-4.py", line 13, in <module>
function (10, 'Hello')
File "function-4.py", line 5, in function
print ('length of string:', lend string))
TypeError: object of type 'int' has no len( )

Parameter with Default Value

You can have a function that defines one or more parameters with default values. If the function call doesn’t explicitly give any value to the said parameter, the default will be used inside the function. If however, the call does pass a value, it will override the default settings in the function’s definition.

Example

#func-with-default.py 
def dress(trouser, shirt='White'): 
            print ( 'Trouser is { }. Shirt is { }'. 
format ( trouser , shirt ) ) 
dress( ' Black ' ) 
dress( ' Blue ' , ' Green ' )

You can see that the second argument is having a default value. The first call doesn’t give any value to it, so default is used. The second call overrides the default value. The output demonstrates this behavior (figure 3.9):

Trouser is Black. Shirt is White
Trouser is Blue. Shirt is Green

There is one precaution to be taken. Arguments with default values must appear after the required arguments in the parameter list of the function definition.

Function with Variable Arguments

We have already seen how arguments can be passed to Python script from the command line. All arguments are stored in a list object (sys. argv). On similar lines, if a function is called by passing the variable number of arguments from within the script, they are stored in a parameter prefixed with ‘*\ It is a list object of all values passed. Treat it as a normal list object and process it accordingly within the function. The following script is a very appropriate example of a function with variable parameters.

Example

#func-with-var-args.py
def addall(*nums):
tt1 = 0
for num in nums:
tt1=tt1+num
return tt1
total=adda11 ( 10 , 20 , 50 , 70 )
print ( ' Total of 4 numbers: ' , total )
total=adda11 ( 11 , 34 , 43 )
print ( ' Total of 3 numbers : ' , total )

Output

E:\python37>python func-with-var-args.py 
Total of 4 numbers: 150 
Total of 3 numbers: 88

Python Data Persistence – Structured Python Read More »

Python Data Persistence – Reading a File

Python Data Persistence – Reading a File

Let us now read ‘top-quotes.txt programmatically by opening it with r mode. When in R mode, the file object can call read (), readline ( ) , and readlines () methods.

Out of these, the read ( ) method can read a specified number of bytes from the file, the size defaults to file size. However, if the file is very big, the available memory restrictions may not allow the entire file to be read, so you may have to provide size parameters to read bytes at once.

Example

>>> file=open ( ' top-quotes . txt' , ' r')
>>> text=file . read ()
>>> text
"'The best way to predict the future is to invent it.' - Alan Kay'\nThere are only two kinds of programming languages: 
those people always bitch about and those nobody uses.' - 
Bjarne Stroustrup\ n'The only way to learn a new programming language is by writing programs in it.' 
-Dennis Ritchie\n'A computer would deserve to be called intelligent if it could deceive a human into believing that 
it was human.' - Alan Turing\nprogramming languages have a devious influence. They shape our thinking habits 
- Edsger W. Dijkstra\nprogrammers do programming not because they expect to get paid or get adulation by the public, 
but because it is fun to program - Linus Torvalds\nA computer would deserve to be called intelligent if it could deceive 
a human into believing that it was human - Alan Turing"
>>>file . close ( )

To read specified number of bytes from the beginning of file

Example

>>> file=open (' top-quotes . txt' , ' r' )
>>> text =file . read (65)
>>> text
" ' The best way to predict the future is to invent it.' - Alan Kay\n"
>>> file . close ()

Reading a File Line-by-Line

The readline () method reads all bytes till a newline character ‘\n’ is encountered. It returns an empty string when no more lines are left to be read. Hence, we can call readline ( ) method in a loop till empty string is returned, (figure 5.2)

>>> file=open ( ' top-quotes . txt1 , ' r ' )
>>> while True:
line=file . readline () 
if line=='':break 
print (line, end='')

'The best way to predict the future is to invent it.1 - Alan Kay 1 There are only two kinds of programming languages: 
those people always bitch about and those nobody uses.' - Bjarne Stroustrup 'The only way to learn a new programming 
language is by writing programs in it.1 -Dennis Ritchie
'A computer would deserve to be called intelligent if it could deceive a human into believing that it was human.' 
- Alan Turing programming languages haile a devious influence. They shape our thinking habits - Edsger W. Dijkstra
programmers do programming not because they expect to get paid or get adulation by the public, but because 
it is fun to program - Linus Torvalds
A computer would deserve to be called intelligent if it could deceive a human into believing that it was human - Alan Turing

The file object is a data stream that acts as an iterator. An iterator serves subsequent object every time next() function 
is called till stream is exhausted and Stoplteration exception is encountered. 
We can use the next () method on the file object to read a file line by line.

Example

f=open("top-quotes.txt", "r")
while True:
           try:
               line=next(f)
               print (line, end=" ")
      except StopIteration:
                  break
f . close ( )

Or simply use a for loop over each line in the file iterator:

Example

file=open ("top-quotes . txt", " r") 
for line in file:
print (line, end="") 
file. close ( )

The readlines ( ) method returns list of lines in the file.

>>> file=open( top-quotes.txt ' 'r')
>>> lines=file.readlines( )

Python Data Persistence – Reading a File Read More »

Python Data Persistence – Opening File

Python Data Persistence – Opening File

The open ( ) function takes a string corresponding to the disk file’s name along with its path as an argument. The second argument indicates the mode in which the file is intended to be opened. Default file opening is ‘r’ which stands for ‘read’ mode which means data in the file is read into program variables. In order to use the file as the output destination, use ‘w’ as the value of the mode parameter. The function returns a file object.

Example

>>> obj=open( ' test.txt' , 'r')
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
obj =open('test.txt' , ' r ')
FileNotFoundError: [Errno 2] No such file or
directory: 'test.txt'
>>> obj=open('test.txt' , 'w')
>>> obj.close()
>>>

Noth that when in ‘r’ mode open( ) function can open existing file otherwise raises FileNotFoundError. Always ensure that the opened file object is closed to flush data if any in the buffer.

Python Data Persistence – Opening File Read More »

Python Data Persistence – File I0

Python Data Persistence – File I0

‘File’ is an indispensable word in the vocabulary of even an ordinary computer (even mobile) user. Every day, he is required to deal with files which may be documents, spreadsheets, presentations, images, and so on. Slightly advanced users, to whom we may call developer, prepare scripts, build executables which are also files.

When a user starts an application, he enters certain data, either through a keyboard or any other device such as a mouse, camera, scanner, and so on. The data goes into the computer’s main memory and is further processed as per the process defined in the application. If this data – input or resulting from the process – is needed for subsequent use, it is saved in a computer file, because if left in the computer memory, it will be erased when a computer is turned off. In this chapter, we shall discuss how data from Python program is stored in persistent disk files.

A Python console application interacts with peripheral devices through its built-in input ( ) and print ( ) functions. Channels of interaction between processor and peripheral devices are called streams. A stream is an object that sends/receives a continuous flow of data. Python’s input ( ) function reads data from standard input streaming device i.e. keyboard that is recognized as sys. stdin object defined in sys built-in the module. Similarly, the print ( ) function sends data to a standard output device which is a computer display screen (monitor), defined as sys. stdout object.

The stdin object has read ( ) and readline ( ) methods to accept user input through the keyboard. The read ( ) method accepts data till the stream is terminated by Ctrl+D character. On the other hand readline ( ) method accepts all keystrokes till the ‘Enter’ key is pressed. Both methods leave ‘\n’ at the end of the input.

Example

>>> data=sys.stdin.read( )
Hello
How are you?
>>> data
'Hello\nHow are you?\n'
>>> data=sys.stdin.readline()
Hello How are you?
>>> data
'Hello How are you?\n'
>>>

In fact, the input ( ) function performs stdin. readline ( ) and returns by stripping the trailing ‘\n! character. The write ( ) method available to the stdout object does exactly what the print ( ) function does. It sends the argument data to the default output device – the computer monitor. However, when using interactive mode, it also displays the size of the object in bytes.

Example

>>> sys.stdout.write(data)
Hello, How are you?
19
>>>

Any object that can send/receive the stream of bytes is called ‘File like object in Python. A file (like) object can invoke read ( ) or write ( ) methods depending upon the stream to which it is connected. Hence, stdin and stdout objects are file-like objects too. Python can perform 10 operations with objects representing disk files, network sockets, memory arrays, and so on. In this chapter, we shall deal with computer disk files. These files store data in a persistent manner, which is often the need as the same collection of data may be needed repeatedly. Instead of laboriously keying in the same data again and again from the keyboard, reading it from a file becomes more efficient and less error-prone. Similarly, screen output being temporary and limited, can instead be stored in files, (figure 5.1)

Python Data Presistence - File 10 chapter 5 img 1

Standard 10 streams communicating with stdin and stdout objects are always available. To use a disk file for reading/writing purposes file object needs to be declared first, by using the built-in open () function.

Python Data Persistence – File I0 Read More »

Python Data Persistence – Magic Methods

Python Data Persistence – Magic Methods

Each Python class inherits methods from its ultimate parent class – object class. Methods in objects are peculiarly named – having double underscores on either side. One such method is well known to you by now. The __init__( ) method. To display a list of methods, we have to use the built-in dir ( ) function.

Example

>>> dir(object)
['__class__' , '__delattr__' , '___dir___' , ___doc___' , '__eq__' , 
'__format__' , __ge__' , '__getattribute__' , '__get__' , '__hash___' , '__init__' , 
'___init_subclass__' , '__le__' , '___lt___' , '__ne__' , '__new___' , '__reduce__' , 
'__reduce_ex__' , '__repr__' , '___setattr__' , '___sizeof___' , '___str__' , '__subclasshook__']

These double underscored methods are known as ‘magic’ methods. They have a very important role in the Pythonic brand of object-oriented programming. What is so ‘magical’ about them? You’ll soon come to know.

These methods (sometimes referred to as ‘special’ or ‘dunder’ – short for double underscore) in object class are really abstract methods in the sense they don’t have any particular implementation. Its subclasses override them as per necessity. Take int class for example. It overrides___str___( ) method to return a printable string version of integer object.

Example

>>> a=123
>>> a.__str___( )

Incidentally, many of these ‘dunder’ methods are rarely called directly. A corresponding built-in function internally calls them. The str( ) function implements the __str__( ) method.

Example

>>> a=123 
>>> str(a)
'123'

Another example is setattr( ) function we used earlier in this chapter. It dynamically adds attribute to an object. It in fact performs operation of__setattr__( ) method. Have a look at following code:

Example

>>> class MyClass:
pass
>>> obj1=MyClass( )
>>> setattr(obj1,'myname','Madhav')
>>> #using__setattr__( ) method
>>> obj1.__setattr__(’myage',21)

Even the dir ( ) method used at the beginning of this section actually calls__dir__( ) magic method.

Example

>>> a. dir _( ) 
['__repr__' , '__hash__' , '__str__' , '___getattribute___' , '__lt__' , '___le__' , '__eq__' , '___ne___' , '__gt__' , '___ge__' ,
 '__add__' , '__radd__' ,'___sub__' , '__rsub__' , '__mul__' , ' ___rmul___', '___mod___' , '___rmod___' , '___divmod__' ,
'___rdivmod__' ,'__pow___' , ' ___rpow___' , ' __neg__' , '___pos___ ' , '___ abs__' ,'___bool___ ' , '__invert___' , '___shift__' , 
'___rlshift__ ' , '__rshift___' , '___rrshift___' , '___and___', '___rand___', '___xor__' , '__rxor__' , '__or___' , '___ror__' , '__int__' ,
 ' __float__' , '___floordiv__' , '__rfloordiv__' ,'___truediv___' , '__rtruediv__' , '__index___' , '___new__' , '___conjugate___ ' , 
'__bit length__' , '___to_bytes___' , '___from bytes__' , '___t rune__' , '__floor__' , '___ceil__' , ' ___round___', '__getnewargs___' , 
'__format __', ' __sizeof___' , '___real___', '___imag___ ' , '__numerator__ ' , '____denominator____ ' , '____doc__' , '___setattr__' 
,'___delattr____' , '__init___' , '___reduce_ex__' , '___reduce__' , '__subclasshook___ ' , '__init_subclass___ ' , '__dir__' , '__class__']
>>> #is equivalent to 
>>> dir(int)

It may be noted that dir (int) shows a lot more attributes than that of the object class. These are actually inherited from abstract Number class and overridden in int class. Of particular interest are methods with names indicating arithmetic operations (such as__add__, ___sub___ , ___ mul__ , and so on.) and logical operations (like ___ge__ , __ gt___ , ___eq___ , and so on.) They are mapped to respective operators so that a conventional arithmetic/logical operator invokes the respective method. In other words, a+b actually performs a . __add__(b) call.

Example

>>> a=20
>>> b=10
>>> a+b
30
>>> a.__add__(b)
30
>>> a.__mul__(b)
200
>>> a*b
200
>>> a>b
True
>>> a.__le__(b)
False

The real magic lies ahead. You can override these methods to customize the behavior of operators to achieve operator overloading.

Example

#timerclass.py
class timer:
         def__init__(self, hr=None, min=None):
               self.hrs=hr
               self.mins=min
         def__add__(self, arg):
               temp=timer( )
               temp.hrs=self.hrs+arg.hrs
               temp.mins=self.mins+arg.mins
               if temp.mins>=60:
                        temp.mins=temp.mins-60
                        temp.hrs=temp.hrs+1
                  return temp
         def__str__(self):
                  timestring='{ } Hrs. { }
mins.'.format(self.hrs,self.mins)
                  return timestring

In the above script, the timer class has two instance attributes hrs and mins. The __add__( ) method performs addition of two timer objects. This method is invoked in response to the use of the ‘+’ operator along with two timer object operands. By the way timer class also has overridden the implementation of __str___( ) method to produce string representation of its object.

Example

>>> from timerclass import timer
>>> t1=timer(2,45)
>>> t2=timer(3,30)
>>> t3=t1+t2
>>> print (t3)
6 Hrs. 15 mins.
>>> t3=t1.__add__(t2)
>>> print (t3)
6 Hrs. 15 mins.

Go ahead and overload any operator to suit the needs of your application. A list of all magic methods is provided in Appendix E.
This chapter is a very brief discussion on object-oriented programming as implemented in Python. Only those facets that are required in subsequent chapters of this book have been explained here.

Python Data Persistence – Magic Methods Read More »

Python Data Persistence – Overriding

Python Data Persistence – Overriding

With two similar radii for the circle, the equation of the area of the ellipse (Ï€*r1 *r2) turns out to be 7rr2, and the equation of perimeter of the ellipse (2Ï€ effectively becomes 27Ï€r. However, we would like to redefine area( ) and perimeter( ) methods, which are inherited by circle class, to implement these specific formulae. Such redefinition of inherited methods is called method overriding.
Modify circle class as per following code:

Example

class circle(ellipse):
        def___init___(self, r1, r2=None):
                super().__init___(r1,r2)
                self.radius2=self.radiusl
        def area(self) :
                 area=math.pi*pow(self.radius1,2)
                  return area
       def perimeter (self) :
           perimeter=2*math.pi*self.radius1
           return perimeter

The result will be unaffected though. Python class can be inherited from multiple classes by putting names of more than one class in parentheses of the class definition.

Protected?

As mentioned earlier, Python doesn’t believe in restricting access to attributes. To emulate the behavior of Java-like protected access specifier, a single underscore character is prefixed to the instance attribute. However, for all practical purposes, it behaves like a public attribute, not even requiring name mangling syntax as in the case of the ‘private’ attribute (prefixed by double underscores). The _ character serves merely as a deterrent expecting responsible programmer to refrain from using it outside inherited class.

Python Data Persistence – Overriding Read More »

Python Data Persistence – Inheritance

Python Data Persistence – Inheritance

Of all features of object-oriented programming methodology, inheritance is arguably the most important, and hence the most used feature in software development. Leaving aside its literary meaning, inheritance in the context of programming refers to the mechanism by which features of one class (attributes and methods) are made available to another class that has the option to define additional resources or modify the functionality of inherited methods.

Python makes extensive use of inheritance. As we have seen, each class is inherited from the built-in object class. Inheritance enables a template definition of properties in a parent class to be implemented by its subclass for a more specific purpose.

One such case in point is the relationship between built-in classes ‘int’ and ‘bool’. Inheritance comes into the picture whenever there is ‘IS A’ kind of relationship between classes. Here a ‘bool’ object IS A(n) ‘int’ right? Hence ‘int’ class is a superclass of the ‘bool’ class. As you know a bool object has only two possible values True and False. They are equivalent to 1 and 0 respectively which are integers by the way.

Let us establish the inheritance of two customized classes with the following example. Ellipse an elongated circle with two radii and one radius is larger than the other. The circle can be seen as a more specific case of ellipse where two radii are equal. So circle IS an A(n) ellipse! We are going to define an ellipse class with two instance attributes and two methods area( ) and perimeter( ).

Example

#inheritEllipse.py
import math
class ellipse:
      def__init__(self, r1, r2):
            self.radius1=r1
            self.radius2=r2
     def area(self):
           area=math.pi*self.radiusl*self.radius2
             return area
def perimeter(self):
            perimeter=2 *math.pi*math. 
sqrt((pow(self.radius1,2)+pow(self.radius2,2))/2)
           return perimeter

 

Note that formula for area of ellipse = π*rl *r2 and perimeter of ellipse =2π

Let us import this class in the interpreter and declare objects as follows:

Example

>>> from inheritEllipse import ellipse
>>> e1=ellipse (20,30)
>>> e1.area()
1884.9555921538758
>>> e1.perimeter()
160.19042244414092
>>> e1=ellipse(20,20)
>>> e1.area()
1256.6370614359173
>>> e1.perimeter()
125.66370614359172

Note that in the second case both radii are equal, hence the ellipse happens to be a circle. We now design a circle class using the ellipse class as its parent. Add following lines in inheritEllipse .py code.

Example

class circle(ellipse) :
           def__init___(self, r1, r2=None):
                    super ( ) .__init__(r1 , r2)
                             self.radius2=self.radius1

Just import this inherited circle class, declare an object with a radius of 20. The result shows that the perimeter and area match that of the ellipse object with identical radii.

Example

>>> from inheritEllipse import ellipse, circle
>>> c1=circle(20)
>>> c1.area()
1256.6370614359173
>>> c1.perimeter()
125.66370614359172
> > >

 

Python Data Persistence – Inheritance Read More »

Python Data Persistence – Class Level Attributes and Methods

Python Data Persistence – Class Level Attributes and Methods

In the above example, MyClass defines two data variables __myname and __myage that are instance attributes. They are invariably initialized through __init__( ) constructor. Their values are different for each object. A class however may have an attribute such that its value is the same for all existing objects. In other words, such attribute is a shared or common resource and defined outside the __init__( ) method, for that matter outside any instance method.

In the following script, the total is a class variable of a player class. It is defined with the purpose of maintaining a running sum of runs scored by each player. The player class defines a name and runs as instance attributes initialized through __init__( ) method as usual which also keeps on adding runs of each object.

Example

#classattr.py
class player:
      __total=0
      def__init__(self, name, runs):
            self.__name=name
            self.___runs=runs
            player.__total+=self.__runs
            print ('Total runs so far:',player.___total)

Let us import the player class and set up a few objects. Following interpreter, activity shows that the ___total variable is being cumulatively updated by ___runs of each object.

Example

>>> from classattr import player
>>> p1=player('Virat', 60)
Total runs so far: 60
>>> p2=player('Rahul', 45)
Total runs so far: 105

Two things are to be noted here. First, the use of the += operator. It is an in¬place addition operator effectively assigning the addition of two operands back to the left operand. Hence player. total==+=self. runs actually becomes player. total=player. total+self.runs . In-place variations of other operators defined in Python are +=, -=, *=, /=, and so on.

Secondly, the value of __total is retrieved with the help of the name of the class (player.__total) rather than self. This is obvious because the total is a class variable and not an instance variable specific to any particular object.
In view of this feature, Python has a provision to define methods that can access such class attributes. A class method needs the name of the class to be passed to it as an argument (conventionally using ‘cls’ identifier). The class can also have a static method that doesn’t need an explicit reference to either class or object which means there’s no argument to it in the form of self or els.

Class method and static method is decorated by built-in @classmethod and @statiemethod directives.

Example

#classattr.py
class player:
       ___total = 0
       def__init__(self, name, runs):
               self.___name=name
               self.___runs=runs
               player.___total+=self.___runs
               print ('Total runs so far:',player.___total)
      @classmethod
      def printtotal(cls):
          print ('Total runs so far:',els.___total)
      @staticmethod
      def displaytotal( ):
                print ('Total runs so far:',player.__total)

Output

>>> from classattr import player 
>>> p1=player('Virat',60)
Total runs so far: 60 
>>> p2=player('Rahul',45)
Total runs so far: 105 
>>> player.printtotal( )
Total runs so far: 105 
>>> player.displaytotal( )
Total runs so far: 105

Python Data Persistence – Class Level Attributes and Methods Read More »

Python Data Persistence – Relational Database

Python Data Persistence – Relational Database

The term ‘database’ refers to an organized collection of data so as to remove redundancy and inconsistency, and to ensure data integrity. Over the years, different database models have been in use. The early days of computing observed the use of hierarchical and network database models. Soon, they were replaced by the relational database model, which is still used very predominantly. The last 10-15 years have seen the emergence of NoSQL databases like MongoDB and Cassandra.

The relational database model, proposed by Edgar Codd in 1970, aims to arrange data according to the entities. Each entity is represented by a table (called a relation). You can think of the entity as a class. Just as a class, an entity is characterized by attributes (also called fields, in the database terminology) that form columns of the table. Each instance of the entity is described in subsequent rows, below the heading row. The entity table structure provides one attribute whose value is unique for each row. Such an attribute is called the ‘primary key’.

If we analyze the pricelist example above, it involves three entities, Customers, Products, and Invoices. We have prepared three tables representing them, as fol\o\\;s:(figure7.1)

Python Data Presistence - Relational Database chapter 7 img 1

The important aspect of relational database design is to establish a relationship between tables. In the three tables above, the attributes ‘prodlD’, ‘CustID’, and ‘InvNo’ are primary keys in products, customers, and invoices tables respectively.
Further, the structure of the ‘invoices’ table uses ‘CustID’ and ‘ProductID’ attributes which are the primary keys of the other two tables. When the primary key of one table appears in the structure of other tables, it is called ‘Foreign key’ and this forms the basis of the relationship between the two.

This approach of database design has two distinct advantages. Firstly, using the relationship between primary and foreign keys, details of the corresponding row can be fetched without repetition. For example, the ‘invoices’ table has the ‘ProdlD’ foreign key which is the primary key in the ‘Products’ table, hence the ‘name’ and ‘price’ attributes can be fetched using this relationship. The same is true about ‘CustID’ which appears as the foreign key in ‘invoices’ and is the primary key in the ‘customers’ table. We can thus reconstruct the original price list table by using relationships.

Inv NoCustIDCustomers.CustNameProdIDProducts.PronameProduct.PriceQtyTotal
11Ravikumar1Laptop25000250000
22John2TV40000140000
33Divya1Laptop25000125000
43Divya3Mobile15000345000
52John3Mobile15000230000
61Ravikumar2TV40000140000

Secondly, you need not make any changes in the ‘invoices’ table, if either name of product or price changes, change in the ‘Products’ table will automatically reflect in all rows of invoices table because of the primary- foreign key relationship. Also, the database engine won’t allow deleting a certain row in the customers or products table, if its primary key is being used as foreign keys in the invoices table. This ensures data integrity.

Software products based on this relational model are popularly called Relational Database Systems (RDBMS). Some of the renowned RDBMS brands are Oracle, MySQL, MS SQL Server, Postgre SQL, DB2. SQLite, etc.

Python Data Persistence – Relational Database Read More »

Python Data Persistence – INSERT Statement

Python Data Persistence – INSERT Statement

Now that we have created tables in our database, let us add few records to them. SQL provides an INSERT statement for the purpose. Its standard syntax is as follows:

Example

INSERT INTO table name (coll, col2, ...) VALUES (vail, val2 , val3 , ...) ;

Name of the table in which a new record (row) is to be added, follows mandatory keywords INSERT INTO. The column list is given after the name in parentheses, which is followed by the VALUES clause. The data corresponding to each column is given in another set of parentheses. The following statement adds one record in the Products table:

sqlite> INSERT INTO Products (Name, Price) VALUES ('Laptop1, 40000);

We insert a row in the ‘Customers’ table by executing the following statement in the SQLite console:

sqlite> INSERT INTO Customers (Name, GSTIN) VALUES ('Ravikumar', 127AAJPL7103N1ZF');

Similarly, the following statement adds a record in the ‘Invoices’ table:

sqlite> INSERT INTO Invoices (CUSTID, PRODUCTID, Quantity) VALUES (1, 1, 2);

Note that, in the above INSERT statements, we have not included ProductID, CustID, and InvID columns in respective column list parentheses because they have been defined as autoincrement fields. The column list may be omitted altogether if you intend to provide values for all columns in the table (excluding autoincrement fields). They must be given in the VALUES list exactly in the same order in which their fields have been defined. You may add a few more records to these three tables. Sample data for these tables is given below: (table 7.3, table 7.4, and table 7.5)

Product IDNamePrice
1Laptop25000
2TV40000
3Router2000
4Scanner5000
5Printer9000
6Mobile15000
CustIDNameGSTIN
1Ravikumar27AAJPL7103N1ZF
2Patel24ASDFG1234N1ZN
3Nitin27AABBC7895N1ZT
4Nair32MMAF8963N1ZK
5Shah24BADEF2002N1ZB
6Khurana07KABCS1002N1Z V
7Irfan05IIAAV 5103N1ZA
8Kiran12PPSDF22431ZC
9Divya15ABCDE1101N1ZA
10John29AAEEC4258E1ZK
Inv IDCustIDProduct IDQuantity
1112
21021
3963
4416
51053
6225
7214
85310
9752
10343

 

 

Python Data Persistence – INSERT Statement Read More »