[go: up one dir, main page]

0% found this document useful (0 votes)
6 views92 pages

C4 Py

The document discusses the limitations of using files for data persistence and advocates for the use of RDBMS software for better security, data handling, and ease of querying. It outlines the steps for Python programs to communicate with Oracle databases using the cx_Oracle module, including connection setup, query execution, and result processing. Additionally, it categorizes database queries into DDL, DML, and DRL, providing syntax and examples for each type.

Uploaded by

Kumaran K
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views92 pages

C4 Py

The document discusses the limitations of using files for data persistence and advocates for the use of RDBMS software for better security, data handling, and ease of querying. It outlines the steps for Python programs to communicate with Oracle databases using the cx_Oracle module, including connection setup, query execution, and result processing. Additionally, it categorizes database queries into DDL, DML, and DRL, providing syntax and examples for each type.

Uploaded by

Kumaran K
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 92

=============================================

Python DataBase Communication ( PDBC )


=============================================
=>Even we acheived the Data Persistency by using Files, Files has the following Limitations.

1. Files of any language does not contain security bcoz Files are unable to provide
security in the form of User Name and Password.
2. Files are unable to store large amount of data
3. File are differing from One OS to another OS (Files are OS depenedent)
4. Querying and Processing the data from Files is Very Complex bcoz file data is
organized w.r.t Indices and idenfying the indices is very complex.
5. Files does not contain Column Names (Except CSV Files)

=>To Overcome the limitation of files and to acheive the Data Persistency, we must use the concept of any
RDBMS DataBase Softwares ( Oracle, MYSQL, Mongo DB, DB2, SQL Server, Postgey SQL,
SQLITE3...........etc).

1. All RDBMS DataBase Softwares Provides Security bcoz RDBMS DataBase


Softwares considers User names and Password.
2. All RDBMS DataBase Softwares stores large amount of data
3. All RDBMS DataBase Softwares Arch Remains Same on all types of OSes ( OS
Independent)
4. Querying and Processing the data from All RDBMS DataBase Softwares is Very
Simple bcoz data of All RDBMS DataBase Softwares oranganized in the of Tables with
Column Names.
5. The Data Present in any RDBMS DataBase Softwares oranganized in the of Tables
with Column Names.

=>If Python Program want to communicate with any RDBMS DataBase Softwares then we must use a PRE-
DEFINED MODULE and such PRE-DEFINED MODULE does not exist in Python Software.
=>Some Third Party Software Vendors( Ex: "Anthony Tuininga") developed a Module for Python
Programmers to communicate with RDBMS DataBase Softwares and placed in github and Third Party
Software Modules must be installed.
=>To install any Third Party Software Modules in python , we use a tool called pip and it is present in C:\
Users\KVR\AppData\Local\Programs\Python\Python310\Scripts folder.

=>Syntax : pip install Module Name (at any Windows command prompt)

=>If Python Program want to communicate with Oracle Database, then we must install
cx_Oracle Module.
=>Examples : pip install cx_Oracle

=>If Python Program want to communicate with MySQL Database, then we must install
mysql-connector or mysql-connector-python Module.

=>Examples : pip install mysql-connector


=>Examples : pip install mysql-connector-python
====================================x========================================
=================================================================
Communication between Python Program and Oracle Database
=================================================================
=>In order to write python program to communicate with Oracle Database, we must follow 6 steps. They
are

1. import cx_Oracle module


2. Python Program must get the connection from Oracle DB
3. Create an object of Cursor
4. Python program must Prepare the Query and Execute the Query in Oracle DB
5. Python Program Process the Result of the Query.
6. Python Program closes the connection.
--------------------------------------------------------------------------------------------------------------------------------
Explanation:
-----------------------
1. import cx_Oracle module:
----------------------------------------------------
=>If a python Program want to perform any database operations(insert , delete , update record , read
records..etc) then we must import a pre-defined third party module "cx_Oracle".
=>We know that a module is a collection of Variables, Function Name and Class Names.

Examples: import cx_Oracle


-------------------------------------------------------------------------------------------------------------------------------
2. Python Program must get the connection from Oracle DB
-------------------------------------------------------------------------------------------------------------------------------
=>To do any Data Base Operations, First python program must get the connection from Oracle.
=>To get the connection from any Database, we use connect() which is present in cx_Oracle module.
=>Syntax:- varame=cx_Oracle.connect("Connection URL")

=>Here connection URL Represents " UserName/Password@DNS/Serviceid "


(OR)
" UserName/Password@IPAddress/Serviceid "

=>Here Varname is an object of <class, cx_Oracle.Connection>


=>Here "UserName" represents User Name of Oracle Data Base (Ex: scott )
=>here "password" represents Password of Oracle Data Base (Ex: tiger )
=>here DNS(Domain Naming Service) represents name of the machine where Database
Software Installed. The default Name of Every Machine is "localhost".
=>Here IPAddress (Internet Protocal Address) represents An address of Physical Machine where Database
software Installed. The default IP Address of Every Machine is 127.0.0.1 (Loop back address)
=>Here "serviceid" represents on which name Oracle data base Installed in current working machine. To
find Service Id in Oracle Data base, we use the following at SQL Environment

SQL> select * from global_name;

GLOBAL_NAME
--------------------------------------
ORCL <---------------Service id

=>When we use / write Invalid Connection URL then we get cx_Oracle.DatabaseError as an exception and
must handle.
-------------------------------------------------------------------------------------------------------------------------------------
3. Create an object of Cursor
-------------------------------------------------------------------------------------
=>The purpose of creating an object of Cursor is that "To carry the Query from Python Program, hand over
to Database, and obtains Result from Database and Gives to Python Program".
=>To create an object of Cursor, we use cursor() which is present in Connection Object.
=>Syntax: varname=conobject.cursor()
=>Here Varname reprsents an object of <class, cx_Oracle.Cursor>
---------------------------------------------------------------------------------------------------------------------------
4. Python program must Prepare the Query and Execute the Query in Oracle DB
---------------------------------------------------------------------------------------------------------------------------
=>A Query is a statement or Request or Question to database software for obtaining data base
results.
=>To execute the query in any Database software from Python Program, we use execute() which is
present in cursor object.
=>Syntax: cursorobj.execute("Query")
=>Here Query is of type str and In any database software we have different Queries (DDL,DML,DRL )
----------------------------------------------------------------------------------------------------------------------------------
5. Python Program Process the Result of the Query.
--------------------------------------------------------------------------------
=>After Executing DML statements, the result of DML statements is present in cursor object. To extract the
result from cursor object, we use "rowcount" attribute of cursor object. "rowcount" attribute gives
number of updated / deleted / inserted in the the data base.

=>After Executing DRL statements, the result of DRL statements is present in cursor object. To extract the
from cursor object, have 3 Functions in cursor object. They are
a) fetchone()
b) fetchmany(no. of records)
c) fetchall()
=>fetchone() is used for obtaining One Record at a Time in the form of tuple. if no records found then this
function returns None.
=>fetchmany(no. of records) is used for obtaining specified number of records.
case-1: if specified number of records==0 then this function obtains all records
case-2: if specified number of records<=Total Number of Records then this function
gives specified number of records
case-3: if specified number of records>Total Number of Records then this function
obtains all records
case-4: if specified number of records<0 then this function never gives any records.

=>fetchall() is used for obtaining all the records from cursor object.
=================================================================
Communication between Python Program and Oracle Database
=================================================================
=>In order to write python program to communicate with Oracle Database, we must follow 6 steps. They
are

1. import cx_Oracle module


2. Python Program must get the connection from Oracle DB
3. Create an object of Cursor
4. Python program must Prepare the Query and Execute the Query in Oracle DB
5. Python Program Process the Result of the Query.
6. Python Program closes the connection.
--------------------------------------------------------------------------------------------------------------------------------
Explanation:
-----------------------
1. import cx_Oracle module:
----------------------------------------------------
=>If a python Program want to perform any database operations(insert , delete , update record , read
records..etc) then we must import a pre-defined third party module "cx_Oracle".
=>We know that a module is a collection of Variables, Function Name and Class Names.

Examples: import cx_Oracle


-------------------------------------------------------------------------------------------------------------------------------
2. Python Program must get the connection from Oracle DB
-------------------------------------------------------------------------------------------------------------------------------
=>To do any Data Base Operations, First python program must get the connection from Oracle.
=>To get the connection from any Database, we use connect() which is present in cx_Oracle module.
=>Syntax:- varame=cx_Oracle.connect("Connection URL")

=>Here connection URL Represents " UserName/Password@DNS/Serviceid "


(OR)
" UserName/Password@IPAddress/Serviceid "

=>Here Varname is an object of <class, cx_Oracle.Connection>


=>Here "UserName" represents User Name of Oracle Data Base (Ex: scott )
=>here "password" represents Password of Oracle Data Base (Ex: tiger )
=>here DNS(Domain Naming Service) represents name of the machine where Database
Software Installed. The default Name of Every Machine is "localhost".
=>Here IPAddress (Internet Protocal Address) represents An address of Physical Machine where Database
software Installed. The default IP Address of Every Machine is 127.0.0.1 (Loop back address)
=>Here "serviceid" represents on which name Oracle data base Installed in current working machine. To
find Service Id in Oracle Data base, we use the following at SQL Environment

SQL> select * from global_name;

GLOBAL_NAME
--------------------------------------
ORCL <---------------Service id

=>When we use / write Invalid Connection URL then we get cx_Oracle.DatabaseError as an exception and
must handle.
-------------------------------------------------------------------------------------------------------------------------------------
3. Create an object of Cursor
-------------------------------------------------------------------------------------
=>The purpose of creating an object of Cursor is that "To carry the Query from Python Program, hand over
to Database, and obtains Result from Database and Gives to Python Program".
=>To create an object of Cursor, we use cursor() which is present in Connection Object.
=>Syntax: varname=conobject.cursor()
=>Here Varname reprsents an object of <class, cx_Oracle.Cursor>
---------------------------------------------------------------------------------------------------------------------------
4. Python program must Prepare the Query and Execute the Query in Oracle DB
---------------------------------------------------------------------------------------------------------------------------
=>A Query is a statement or Request or Question to database software for obtaining data base
results.
=>To execute the query in any Database software from Python Program, we use execute() which is
present in cursor object.
=>Syntax: cursorobj.execute("Query")
=>Here Query is of type str and In any database software we have different Queries (DDL,DML,DRL )
----------------------------------------------------------------------------------------------------------------------------------
5. Python Program Process the Result of the Query.
--------------------------------------------------------------------------------
=>After Executing DML statements, the result of DML statements is present in cursor object. To extract the
result from cursor object, we use "rowcount" attribute of cursor object. "rowcount" attribute gives
number of updated / deleted / inserted in the the data base.

=>After Executing DRL statements, the result of DRL statements is present in cursor object. To extract the
from cursor object, have 3 Functions in cursor object. They are
a) fetchone()
b) fetchmany(no. of records)
c) fetchall()
=>fetchone() is used for obtaining One Record at a Time in the form of tuple. if no records found then this
function returns None.
=>fetchmany(no. of records) is used for obtaining specified number of records.
case-1: if specified number of records==0 then this function obtains all records
case-2: if specified number of records<=Total Number of Records then this function
gives specified number of records
case-3: if specified number of records>Total Number of Records then this function
obtains all records
case-4: if specified number of records<0 then this function never gives any records.

=>fetchall() is used for obtaining all the records from cursor object.
=============================================
Types of Queries in Database Softwares
=============================================
=>In any database, we have 3 types of Queries. They are

1. DDL( Data Definition Language) Queries


2. DML (Data Manipulation Language) Queries
3. DRL (Data Retrieval Language ) Queries
-------------------------------------------------------------------------------------------------------------------------------
==============================================
1. DDL( Data Definition Language) Queries
==============================================
=>The purpose of DDL Queries is that to deal with Physical Level of Database software such as creation of
Tables, altering column sizes, adding new Columns etc.
=>In any Database software , we have 3 types of DDL Queries. They are

1. create
2. alter
3. drop
-----------------------------------------------------------------------------------------------------------------------
1) create:
---------------------
=>This Query is used for creating a table in Oracle Database
=>Syntax:-
SQL> create table <table-name> ( col name1 database data type, col name2 database data
type, ......col name-n database data type )
SQL> create table employee(eno number(2) primary key ,ename varchar2(10) not null , sal number (6,2)
not null);
---------------------------------------------------------------------------------------------------------------------------
2. alter :
-------------------------------------
=>This Query is used for alter the table structure such as modifying (modify) the column sizes and adding
(add) new columns.

Syntax1:- SQL> alter table <table-name> modify ( existing col name1 database data type....
existing col name-n database data type )

Syntax2:- SQL> alter table <table-name> add ( new col name1 database data type....
new col name-n database data type )

Examples: SQL> alter table employee add(cname varchar2(10));


SQL> alter table employee modify(ename varchar2(20), sal number(8,2));
-------------------------------------------------------------------------------------------------------------------------------
3) drop :
----------------------------------------------------------------------------
=>This query is used for removing the table from Database Software
=>Syntax:- SQL> drop table <table-name>
=>Example:- SQL> drop table employee
-------------------------------------------------------------------------------------------------------------------------------
================================================
2. DML (Data Manipulation Language) Queries
================================================
=>The purpose of DML operations is that To manipulate the table such Inserting the records, deleting the
records and updating the records.
=>In RDBMS database softwares, we have 3 types of DML Operations. They are

1. insert
2. delete
3. update
=>When we execute any DML Operation through python program, we must use commit() for permanent
change / update / modification and to roll back we use roolback().
=>commit() and rollback() are present in connection object.
-----------------------------------------------------------------------------------------------------------------
1. insert:
------------------------------------
=>This query is used for inserting a record in table of database.
=>Syntax:- SQL> insert into <table-name> values( val1 for column1, val2 for column2.....
val-n for column-n)
Example: SQL> insert into student values (20,'DR',33.45,'C');
SQL>insert into student values (10,'RS',23.45,'Python');
SQL> commit ;
-----------------------------------------------------------------------------------------------------------------
2. delete
-----------------------------------------------------------------------------------------------------------------
=>This query is used for deleting a record .
=>Syntax1: delete from <table name>

=>Syntax2: delete from <table-name> where cond list;


=>Example: SQL> delete from student where sno=70;
---------------------------------------------------------------------------------------------------------------------
3. update
---------------------------------------------------------------------------------------------------------------------
=>This query is used for updating the record values

=>Syntax1:
SQL> update <table-name> set col1=val1,col2=val2.....col-n=val-n;

=>Syntax2:
SQL> update <table-name> set col1=val1,col2=val2.....col-n=val-n where cond list;

Examples: SQL> update student set marks=marks+marks*0.02;


Examples: SQL> update student set marks=marks+marks*0.05,crs='Django' where sno=90;
----------------------------------------------------------------------------------------------------------------------------------
============================================
3. DRL (Data Retrieval Language ) Queries
============================================
=>DRL (Data Retrieval Language ) Queries are used for Reading the records from table.
=>To read the records from table, we use "select"
=>In Otherwords "select" comes under DRL (Data Retrieval Language ) Query.
=>Syntax1: SQL>select col1,col2,.....col-n from <table-name>
=>Syntax2: SQL>select col1,col2,.....col-n from <table-name> where cond list
=>Syntax3: SQL>select * from <table-name>
=>Syntax4: SQL>select * from <table-name> where cond list
-----------------------------------------------------------------------------------------------------------------------------
=>Once the select query executed, all records are present in the object of cursor in Python.
=>To get the records from cusror object, we have 3 functions. They are
1) fetchone()
2) fetchmany(no. of records)
3) fetchall()
-----------------------------------------------------------------------
1) fetchone():
=>This function is used obtaining One Record at a time, where cursor object pointing
-----------------------------------------------------------------------------
2) fetchmany(no. of records)
-----------------------------------------------------------------------------
=>fetchmany(no. of records) is used for obtaining specified number of records.
case-1: if specified number of records==0 then this function obtains all records
case-2: if specified number of records<=Total Number of Records then this function
gives specified number of records
case-3: if specified number of records>Total Number of Records then this function
obtains all records
case-4: if specified number of records<0 then this function never gives any records.
-----------------------------------------------------------------------------
3) fetchall()
-----------------------------------------------------------------------------
=>fetchall() is used for obtaining all the records from cursor object.
-----------------------------------------------------------------------------
=======================================================
Index Object Oriented Principles or Features or Concepts(10 days)
=======================================================
Index:
---------
=>What are the advantages of OOPs
=>List of Object Oriented Principles
1. Classes
2. Objects
3. Data Encapsulation
4. Data Abstraction
5. Inheritance
6. Polymorphism
7. Message Passing(already)
--------------------------------------------------------------------
1. Classes
=>Importaance and purpose of Classes concept
=>Syntax for Defining Class
=>Types of Data Members
a) Instance Data Members
b) Class Level Data Members
=>Types of Methods
a) Instance Method
b) Class Level Method
c) Static Method
=>What is "self" and "cls"
=>Programming Examples
2. Object
=>Importaance and purpose of Object Concept
=>Syntax for creating Object
=>Programming Examples
=>PRAMMING eXamples related to pickling and Data base communication with Classes and objects.
-------------------------------------------------------------------------------------------------------------------------------------
=>Constructors in OOPs
=>Importance and purpose of Constructors
=>Types of Constructors
a) Default Constructors
b) Parameterized Constructors
=>Rules for Constructors
=>Programming Examples
--------------------------------------------------------------------------
=>Detstructrors in OOPs with Garbage Collector
=>Importance and purpose of Detstructrors
=>Syntax for defining Detstructrors
=>Internal flow of Detstructrors
=>relation between Detstructrors and Garbage Collector
=>gc module
=>Pgramming Examples
----------------------------------------------------------------------------------------
3. Data Encapsulation and Data Abstraction
=>Importance and purpose of Data Encapsulation
=>Importaance and purpose of Data Abstraction
=>Implementation of data encapsulation and Data Abstraction
=>Programming Examples
--------------------------------------------------
5. Inheritance
=>Importaance and purpose of Inheritance
=>Types of Inheritances
a) single
b) multi level
c) hierarchical
d) multiple
e) Hybrid
=>Syntax for Inheritance
=>Programming Examples
--------------------------------------------------
Method Overriding in OOPs
=>Importance and purpose of Method Overriding
=>memory management in Method Overriding
=>Programming Examples
----------------------------------------------
6.Polymorphism
----------------------------------------------
=>Importance and purpose of Polymorphism
=>Difference between Polymorphism and Inheritance
=>Method Overring with Polymorphism
=>super() and class name approaches in Polymorphism
=>Programming Examples
----------------------------------------------------------------------------------------------------------------

=================================================
Object Oriented Principles or Features or Concepts
=================================================
=>In real time, to develop any project or application, we must choose a language and it can satisfy two
types of principles. They are
1. Functional(Procedure) Oriented Principles-----C,Pascal, cobol,8086,oracle7.3,PYTHON
2. Object Oriented Priciples.--------PYTHON C++ JAVA, .NET, from Oracle8 onwadrs.......
=>Even though, PYTHON programming Belongs to both Functional and Object Oriented Programming
language and internally every thing is treated as object.

-------------------------------------------------------------------------------------------------------
"Every Thing is an object " --Benifits
(OR)
Adavtanges of Object Oriented Principles
--------------------------------------------------------------------------------------------------------
1. Objects allows us to store Large Volume of Data (Platform Indepenedent)
2. The Data is visiting between two machines in the form of Ciphet Text (encrypted Format).
So that we can achieve the Security
3. The Large Volume of Data can be transfered between multiple machines all at once in the
form of objects and obtains effective communication.
4. With Objects we can build high effective Re-Usable Applications(Redundency of the Code is
Minimized).
5. The Data is always available arround Objects (Effective Memory Usage) and functions can operate on
the objects.
-----------------------------------------------------------------------------------------------------------------------------------
=================================================
List of Object Oriented Principles
=================================================
=>To say a languge is Object Oriented , It has to sastisfy the following Principles.

1. Classes
2. Objects
3. Data Encapsulation
4. Data Abstraction
5. Inheritance
6. Polymorphism
7. Message Passing(already discussed )
===================================
Classes
===================================
=>The Purpose of Classes Concept is that "To Develop Programmer-Defined Data Type+To
develop any real Time Application in OOPs"
=>The Purpose of Developing Programmer-Defined Data Type is that "To Store Customized
Data and To Perform Customized Operations".
=>To Develop Programmer-Defined Data Type by using Classes concept, we use "class"
keyword
=>In Python Programming, All Class Names are treated as Programmer-Defined Data Type.
=>Every Program in OOPs, Must starts with Classes concept.
--------------------------------------------------
Definition:
--------------------------------------------------
=>A Class is a collection Variables (Data Members) and Methods .
--------------------------------------------------
=>When we define a class, Memory space is not created for Data Members and Methods But Whose
Memory Space is created when we create an object w.r.t Class Name.
===================================x====================================
===================================================
Syntax for Defining a class in Python
===================================================

class <class-name>:
Class Level Data Members
def InstanceMethodName(self,List of formal params if any):
---------------------------------
Specify Instance Data Members---Perform Specific Operations
--------------------------------

@classmethod
def classlevelmethodname(cls,list of Formal params if any)
--------------------------------------
Specify Class Level Data Members--Perform Common Operations
--------------------------------------
@staticmethod
def staticmethodname(list of formal params if any):
--------------------------------------
Performs Utility / Universal Operations
--------------------------------------
===========================================
Types of Data Members in a Class
===========================================
=>In class of Python, we can define Two Types of Data Members. They are
1. Instance Data Members
2. Class Level Data Members
-----------------------------------------------------------------------------------------------------------
1. Instance Data Members
-----------------------------------------------------------------------------------------------------------
=>Instance Data Members are those which are used for Storing Specific Values
=>Instance Data Members are those whose memory space created Each Every Time when an object is
crated.
=>Instance Data Members Must be Accessed w.r.t Object Name or self
ObjName . InstanceData Member Name
(OR)
self.InstanceData Member Name
=>To Add the Instance Data Members to the corresponding object, we use 3 approaches. They are
a) By Using Object Name
b) By Using Instance Methods
c) By using Constructors.
-----------------------------------------------------------------------------------------------------------
2. Class Level Data Members
-----------------------------------------------------------------------------------------------------------
=>Class Level Data Members are those which are used for Common Values.
=>Class Level Data Members are those Whose Memory space created One time irrespective of Number of
Objects are Created.
=>Class Level Data Members can be accssed w.r.t Class Name.
Class Name.Class Level Data Member Name
(OR)
cls.Class Level Data Member Name
(OR)
ObjectName.Class Level Data Member Name
(OR)
self.Class Level Data Member Name
=>To Add the Class Level Data Members we use 2 approaches. They are
a) Inside of Class Definition
b) Inside of Class Level Method.
-----------------------------------------------------------------------------------------------------------
===========================================
Types of Methods in class of Python
===========================================
=>In a class of Python, we can define 3 types of Methods. They are
1. Instance Methods
2. Class Level Methods
3. Static Methods.
----------------------------------------------------------------------------------------------------------------------------
1. Instance Methods
----------------------------------------------------------------------------------------------------------------------------
=>Instance Methods are used for performing Specific Operation or Operation on Instance Data
Members of Object and these Metrhods are also called Object Level Methods.
=>Instance Methods always Takes "self" as a First Formal Parameter.
=>The Syntax for Instance Method
def InstanceMethodName(self,list of formal params if any)
-------------------------------------------
Specific Operations
Specify Instance Data Members
---------------------------------------------
=>All Instance Methods Must be accessed w.r.t Object Name or self
ObjectName.InstanceMethod Name()
(OR)
self.InstanceMethod Name()

=>What is "self"?
------------------------------
=>"self" is one of the First Formal Parameter in Instance Methods
=>"self" contains Reference / Address of Current Class Object
=>"self" can be used Inside of Corresponding Instance Method Body Only But not
Possible to access other part of Program
----------------------------------------------------------------------------------------------------------------------------
2. Class Level Methods
----------------------------------------------------------------------------------------------------------------------------
=>Class Level Methods are used for performing Common Operation on Class Level Data
Members.
=>In Order to define Class Level Methods, whose defeintion must be preceded with a
pre-defined decorator called @classmethod and takes "cls" as a First Formal Parameter.
=>The Syntax for Class Level Method is
@classmethod
def classlevelmethod(cls,list of formal params if any):
--------------------------------
Specify Class Level Data Memebrs
Common Operations
--------------------------------

=>All Class Level Methods can be accessed w.r.t Class Name or cls or object name or self

classname.classlevelmethod()
(OR)
cls.classlevelmethod()
(OR)
objname.classlevelmethod()
(OR)
self.classlevelmethod()
=>What is "cls"?
------------------------------
=>"cls" is one of the First Formal Parameter in Class Level Methods
=>"cls" contains Current Class name
=>"cls" can be used Inside of Corresponding Class Level Method Body Only But not
Possible to access other part of Program
----------------------------------------------------------------------------------------------------------------------------
3. Static Methods
----------------------------------------------------------------------------------------------------------------------------
=>Static Methods are used for performing Universal Operations or Utility Operations
=>Static Methods defeinition must be preceded with a predefined decorator called
@staticmethod and it never takes "cls" or "self" but always takes object of other classes.
=>The Syntax for Static Method is
@staticmethod
def staticmethodname(list of Formal Params):
-------------------------------------
Utility Operation / Universal Operations
------------------------------------

=>Static Methods can be accessed w.r.t Class Name or object name.

ClassName.static method name()


(OR)
ObjectName.static method name()
===================================x=======================================
===========================================
Types of Methods in class of Python
===========================================
=>In a class of Python, we can define 3 types of Methods. They are
1. Instance Methods
2. Class Level Methods
3. Static Methods.
----------------------------------------------------------------------------------------------------------------------------
1. Instance Methods
----------------------------------------------------------------------------------------------------------------------------
=>Instance Methods are used for performing Specific Operation or Operation on Instance Data
Members of Object and these Metrhods are also called Object Level Methods.
=>Instance Methods always Takes "self" as a First Formal Parameter.
=>The Syntax for Instance Method
def InstanceMethodName(self,list of formal params if any)
-------------------------------------------
Specific Operations
Specify Instance Data Members
---------------------------------------------
=>All Instance Methods Must be accessed w.r.t Object Name or self
ObjectName.InstanceMethod Name()
(OR)
self.InstanceMethod Name()

=>What is "self"?
------------------------------
=>"self" is one of the First Formal Parameter in Instance Methods
=>"self" contains Reference / Address of Current Class Object
=>"self" can be used Inside of Corresponding Instance Method Body Only But not
Possible to access other part of Program
----------------------------------------------------------------------------------------------------------------------------
2. Class Level Methods
----------------------------------------------------------------------------------------------------------------------------
=>Class Level Methods are used for performing Common Operation on Class Level Data
Members.
=>In Order to define Class Level Methods, whose defeintion must be preceded with a
pre-defined decorator called @classmethod and takes "cls" as a First Formal Parameter.
=>The Syntax for Class Level Method is
@classmethod
def classlevelmethod(cls,list of formal params if any):
--------------------------------
Specify Class Level Data Memebrs
Common Operations
--------------------------------

=>All Class Level Methods can be accessed w.r.t Class Name or cls or object name or self

classname.classlevelmethod()
(OR)
cls.classlevelmethod()
(OR)
objname.classlevelmethod()
(OR)
self.classlevelmethod()
=>What is "cls"?
------------------------------
=>"cls" is one of the First Formal Parameter in Class Level Methods
=>"cls" contains Current Class name
=>"cls" can be used Inside of Corresponding Class Level Method Body Only But not
Possible to access other part of Program
----------------------------------------------------------------------------------------------------------------------------
3. Static Methods
----------------------------------------------------------------------------------------------------------------------------
=>Static Methods are used for performing Universal Operations or Utility Operations
=>Static Methods defeinition must be preceded with a predefined decorator called
@staticmethod and it never takes "cls" or "self" but always takes object of other classes.
=>The Syntax for Static Method is
@staticmethod
def staticmethodname(list of Formal Params):
-------------------------------------
Utility Operation / Universal Operations
------------------------------------

=>Static Methods can be accessed w.r.t Class Name or object name.

ClassName.static method name()


(OR)
ObjectName.static method name()
(OR)
self.static method name()
===================================x=======================================
===========================================
Index of Constructors in Class of Python
===========================================
Index
------------
=>Purpose of Constructors
=>Definition of Constructors
=>Rules / Properties of Constructors
=>Types of Constructors
a) Default Constructors
b) Parameterized Constructors
=>Programming Examples
------------------------------------------------------------------------------------------------
==========================================
Constructors in Python
==========================================
=>The purpose of Constructors in Python is that "To Initlize the object ".
=>Initlizing the object is nothing but placing our own values in the object without leaving
an object empty.
-------------------------------------------------------------------------------------------------------------------------------------
=>Definition of Constructor:
-------------------------------------------------------------------------------------------------------------------------------------
=>A Constructor is a special Method which is automatically or implicitly called by PVM during object
creation and whose purpose is to initlize the object without leaving an object empty.
-------------------------------------------------------------------------------------------------------------------------------------
Syntax for Defining Constructor:
----------------------------------------------------
def __init__(self, list of formal params if any):
----------------------------------------
Block of Statements--Initlization
------------------------------------------

-------------------------------------------------------------------------------------------------------------------------------------
Rules or Properties of Constructor:
---------------------------------------------------------------------------------------------------------
1.The Name of the constructor is def __init__(self)
2. The Constructors automatically or implicitly called by PVM during object creation
3. Constructors should not return any value ( It can return only None value)
4. Constructors paricipates in Inheritance Process.
5. Constructors can be Overridden (can re-defined)
---------------------------------------------------------------------------------------------------------
==========================================
Types Constructors in Python
==========================================
=>In Python Programming, we have two types of Constructors. They are

1. Default or Paremeter-Less Constructor


2. Parameterized Constructor
---------------------------------------------------------------------------------------------------------------
1. Default or Paremeter-Less Constructor
---------------------------------------------------------------------------------------------------------------
=>A Constructor is said to be Default iff it never takes any argument(s ) or Formal Param(s)
=>The purpose of Default or Paremeter-Less Constructor is that "To Initlize multiple objects of same class
with same values".
=>Syntax:
def __init__(self):
--------------------------------------
Block of Stmts--Initlization
--------------------------------------

---------------------------
=>Examples
---------------------------
#DefConstEx1.py
class Test:
def __init__(self):
print("i am from Default Constructor:")
self.a=10
self.b=20
print("Value of a:{}".format(self.a))
print("Value of b:{}".format(self.b))

#main program
t1=Test()
t2=Test()
t3=Test()
---------------------------------------------------------------------------------------------------------------
2.Paremeterized Constructor
---------------------------------------------------------------------------------------------------------------
=>A Constructor is said to be Paremeterized iff it always takes any argument(s ) or Formal
Param(s)
=>The purpose of Paremeterized Constructor is that "To Initlize multiple objects of
same class with Different values".
=>Syntax:
def __init__(self, list of formal params):
--------------------------------------
Block of Stmts--Initlization
--------------------------------------

----------------------
Examples:
----------------------
#ParamConstEx1.py
class Test:
def __init__(self,a,b):
print("i am from Parameterized Constructor:")
self.a=a
self.b=b
print("Value of a:{}".format(self.a))
print("Value of b:{}".format(self.b))

#main progra m
t1=Test(10,20)
t2=Test(100,200)
t3=Test("RS","PYTHON")
-------------------------------------------------------------------------------------------------------------------------
Note:
----------
Note: In Class of Python, we can't define both default and Parameterized constructors bcoz PVM can
remember only latest constructor (due to its interpretation Process) . To full fill the need of both default
and parameterized constructors , we define single constructor with default parameter mechanism.
Examples:
-----------------
#DefultParamConstEx1.py
class Test:
def __init__(self,a=1,b=2):
print("i am from Default /Parameterized Constructor:")
self.a=a
self.b=b
print("Value of a:{}".format(self.a))
print("Value of b:{}".format(self.b))

#main progra m
t1=Test() # Object Creation calls Default Constructor
t2=Test(100,200) # Object Creation calls Parameterized Constructor
-------------------------------------------------------------------------------------------------------------
======================================
Destructors in Python
and
Garbage Collector
======================================
=>We know that Garbage Collector is one of the in-built program in python, which is running behind of
every python program and whose is role is to collect un-used memory space and it improves the
performnace of python based applications.
=>Every Garbage Collector Program is internally calling its Own Destructor Functions.
=>The destructor function name in python is def __del__(self).
=>By default ,The destructor always called by Garbage Collector when the program execution completed
for de-allocating the memory space of objects which are used in that program. Where as constructor called
By PVM implicitly when object is created for initlizing the object.

=>When the program execution is completed, GC calls its own destructor to de-allocate the memory space
of objects present in program and it is called automatic Garbage Collection.

=>Hence , We have THREE programming conditions for calling GC and to make the garbage collector to
call destructor Function.

a) By default (or) automatically GC calls destructor, when the program execution


completed.
b) Make the object reference as None for calling Forcefull Garbage Collection
Syntax : objname=None
c) delete the object by using del operator for calling Forcefull Garbage Collection
Syntax:- del objname

-----------------
=>Syntax:
-----------------
def __del__(self):
-----------------------
-----------------------
=>No Need to write destructor in class of Python bcoz GC contains its own Destructor
=======================================================================
Garbage Collector
---------------------------------------------------------------------------------------------------------------------------
=>Garbage Collector contains a pre-defined module called "gc"
=>Here gc contains the following Functions.

1) isenabled()
2) enable()
3) disable()
=>GC is not under control of Programmer but it always maintained and mangaged by OS
and PVM.
NOTE: Python Programmers need not to write destructor method / function and need not
to deal with Garbage Collection Process by using gc module bcoz PVM and OS takes care about
Automatic Garbage Collection Process.
==============================x============================================

===================================================
objects in Python
===================================================
=>When we define a class, memory space is not created for Data Members and Methods but whose
memory is created when we create an object w.r.t class name.
=>To Store the data and to do any Data Processing, It is mandatory to create an object.
=>To create an object, there must exists a class Definition otherwise we get NameError.

Definition of object:
-----------------------------------
=>Instance of a class is called object ( Instance is nothing but allocating sufficient memory space for the
Data Members and Methods of a class).
-------------------------------------------------
Syntax for creating an object
-------------------------------------------------
varname=classname()
(or)
varname=classname(Val1,Val2...val-n)

Examples: create an object of Student

so=Student()
Example:- create an object Employee

eo=Employee(10,"Rossum")
-----------------------------------------------------------------------------------------------
Differences Betwwen Classes and Objects
-----------------------------------------------------------------------
Class:
------------
1) A class is a collection of Data Members and Methods
2) When we define a class, memory space is not created for Data Members and Methods and it can be
treated as specification / model for real time application.
3) Definition of a perticular exists only once
4) When we develop any Program with OOPs principles, Class Definition Loaded First in main memory
only once.
---------------
Objects:
--------------
1) Instance of a class is called Object
2) When we create an object, we get the memory space for Data members and Methods of Class.
3)w.r.t One class Definition, we can create multiple objects.
4)we can crate an object after loading the class definition otherwise we get NameError
===============================X=================================

=================================================
Inheritance
=================================================
=>Inhenritance is one of distinct features of OOPs
=>The purpose of Inheritance is that " To build Re-usable Applications in Python Object Oriented
Programming".
-----------------------------------------
=>Definition of Inheritance:
-----------------------------------------
=>The Process obtaining Data members , Methods and Constructors (Features ) of one class into another
class is called Inheritance.
=>The class which is giving Data members , Methods and Constructors (Features ) is called Super or Base
or Parent Class.
=>The Class which is taking Data members , Methods and Constructors (Features ) is called Sub or Derived
or Child Class.
=>The Inheritance concept always follows Logical ( Virtual ) Memory Management. This Memory
Management says that " Neither we write Source Code nor Takes Physical Memory Space ".
-------------------------------------------------------------------------------------------------------------------------------------
Advatnages of Inheritance:
----------------------------------------------------------------------------------
=>When we develop any inheritance based application, we get the following advantages.
1. Application Development Time is Less
2. Application Memory Space is Less
3. Application Execution time is Fast / Less
4. Application Performance is enhanced (Improved )
5. Redundency (Duplication ) of the code is minimized.
-------------------------------------------------------------------------------------------------------------------------

==============================================
Types of Inheritances
==============================================
=>A Type of Inheritance is a model / Paradigm , which makes us to understand how the
features are In herited from Base Class into Derived Class.
=>In Python Programming, we have 5 types of Inheritances. They are

1. Single Inheritance
2. Multi Level Inheritance
3. Hierarchical Inheritance
4. Multiple Inheritance
5. Hybrid Inheritance

=============================================
Data Encapsulation and Data Abstraction
=============================================
Data Encapsulation:
--------------------------------
=>The Process of Hiding the confidential Information / Data / Methods from external Programmers / end
users is called Data Encapsulation.
=>The Purpose of Encapsulation concept is that "To Hide Confidental Information / Features of Class (Data
Members and Methods ) ".
=>Data Encapsulation can be applied in two levels. They are
a) At Data Members Level
b) At Methods Level

=>To implement Data Encapsulation in python programming, The Data Members , Methods must be
preceded with double under score ( _ _ )

Syntax1:- (Data member Lavel )

class <ClassName>:
def methodname(self):
self.__Data MemberName1=Value1
self.__Data MemberName2=Value2
--------------------------------------------------
self.__Data MemberName-n=Value-n

(OR)

Syntax1:- ( Data member Lavel )

class <ClassName>:
def __init__(self):
self.__Data MemberName1=Value1
self.__Data MemberName2=Value2
--------------------------------------------------
self.__Data MemberName-n=Value-n

Syntax2:- (Method Level)

class <ClassName>:
def __methodname(self):
self.Data MemberName1=Value1
self.Data MemberName2=Value2
--------------------------------------------------
self.Data MemberName-n=Value-n

Examples: Refer Acc1.py, Acc2.py, Acc3.py and Acc4.py Programs

==============================================================
Data Abstraction:
-------------------------------
=>The Process of retrieving / extracting Essential Details without considering Hidden Details is called Data
Abstraction.

Examples: Others1.py Others2.py


Others3.py Others4.py Programs
--------------------------------------------------------------------------------------------------------------

Note:- We can't apply Data Encapsulation on Constructors in Python but whose Initlized Data Memebrs can
be encapsulated.
=====================================================
Inheritaing the Features of Base Class Into Derived Class
=====================================================
Syntax:
-----------
class <clsname-1>:
----------------------
----------------------

class <clsname-2>:
----------------------
----------------------

-----------------------------

class <clsname-n>:
----------------------
----------------------

class <clsname-n+1>(<clsname-1>,<clsname-2>,.....<clsname-n>):
----------------------
----------------------

---------------------
Explanation:
---------------------
=>Here <clsname-1>,<clsname-2>.....<clsname-n> are called Base Classes / Super Classes
=>here <clsname-n+1> is called Derived Class.
=>Here The features of <clsname-1>,<clsname-2>.....<clsname-n> are Inherited into
<clsname-n+1> and these Features are available logically In <clsname-n+1> and we can access them w.r.t
Object Name (OR) Self (Instance ) /Class Name (Class level and Static ).
=>When we develop any Inheritance Application, we are always recommeding to create an object of
Bottom Most Derived Class bcoz It inherits the features of Intermediate Base Class(es) and Base class.
=>For Every Class in Python, There exist a pre-defined implicit super class called "object"
bcoz It provides Garbage Collection Facility to its sub classes.
==============================x=======================================
==============================================
Polymorphism in Python
==============================================
=>Polymorphism is one of the distinct features of OOPs
=>The purpose of Polymorphism is that "Efficient Utilization Memory Space (OR) Less Memory space is
achieved".
----------------------------------------
=>Def. of Polymorphism:
----------------------------------------
=>The Process of Representing "One Form in multiple Forms " is called Polymorphism.
=>The Polymorphism Principle is implemented(Bring into action) by Using "Method Overriding" feature of
all OO Programming Languages.
=>In The definition of polymorphism, "One Form" represents "Original Method" and multiple forms
represents Overridden Methods.
=>A "Form" is nothing but existence of a Method. if the method is existing in base class then it is called
"Original Method(one form)" and if the method existing in derived class(es) then it is called "Overridden
Method(multiple Forms)".
---------------------------------------------------X--------------------------------------------------------------

===========================================
Method Overriding in Python
===========================================
=>Method Overriding=Method Heading is same + Method Body is Different
(OR)
=>The process of re-defining the original method of base class into various derived classes for performing
different operations is called Method Overriding.
=>To use Method Overriding in python program we must apply Inheritance Principle.
=>Method Overriding used for implementing Polymorphism Principle.
( PLOYMORPHISM<----METHOD OVERRIDING<-----INHERITANCE<----CLASS AND OBJECTS )
-----------------------
Examples:
-----------------------
#methodoverex1.py
class Circle:
def draw(self): # original Method
print("Drawing Circle")

class Rect(Circle):
def draw(self): # overridden Method
print("Drawing Rect:")
super().draw()

class Square(Rect):
def draw(self): # overridden Method
print("Drawing Square:")
super().draw()

#main program
so=Square()
so.draw()
------------------------------------------------------------------------
#teacher.py
class Teacher:
def readsub(self):
print("Teacher advises to read 2 hours")

class LazyStudent(Teacher):
def readsub(self):
print("LazyStudent never read at all")
class PerfectStudent(Teacher):
def readsub(self):
print(" Perfect Student 2hrs reading and practicing")
ls=LazyStudent()
ls.readsub()
ps=PerfectStudent()
ps.readsub()
-----------------------------------------------------------------------------
===============================================
Number of approaches to call original methods / constructors from
Overridden methods / Constructors
===============================================
=>We have two approches to call original method / constructors of base class from overridden method /
constructors of derived class. They are

1) By using super()
2) By using Class Name
------------------------------------------------------------------------
1) By using super():
------------------------------------
=>super() is one of the pre-defined function, which is used for calling super class original method /
constructor from overridden method / constructors of derived class.

Syntax1:- super().methodname(list of values if any)

Syntax2:- super().__init__(list of values if any)

=>with super() we are able to call only immediate base class method but unable to call Specified method
of base Class . To do this we must use class name approach.
----------------------------------------------------------------
2) By using Class Name:
----------------------------------------------------------------
=>By using ClassName approach, we can call any base class method / constructor name from the context
of derived class method / constructor names.

Syntax1:- ClassName.methodname(self, list of values if any)


Syntax2:- ClassName.__init__(self, list of values if any)
-----------------------------------------------X----------------------------------------------------------------
==========================================
Pre-defined Functions in re module
==========================================
=>The 're' module contains the follwing essential Functions.
----------------------------------------------------------------------------------------------
1) finditer():
-------------------------------------------------------------------------------------------
Syntax:- varname=re.finditer("search-pattern","Given data")
=>here varname is an object of type <class,'Callable_Itetaror'>
=>This function is used for searching the "search pattern" in given data iteratively and it returns table of
entries which contains start index , end index and matched value based on the search pattern.
----------------------------------------------------------------------------------------------------------------------------
2) findall():
----------------------------------------------------------------------------------------------
Syntax:- varname=re.findall("search-pattern","Given data")
=>here varname is an object of <class,'list'>
=>This function is used for searching the search pattern in entire given data and find all occurences /
matches and it returns all the matched values in the form an object <class,'list'> but not returning Start
and End Index Values.
-------------------------------------------------------------------------------------------------------------------------------
3) search():
----------------------------------------------------------------------------------------------
Syntax:- varname=re.search("search-pattern","Given data")
=>here varname is an object of <class,'re.match'> or <class,'NoneType'>

=>This function is used for searching the search pattern in given data for first occuence / match only but
not for other occurences / matches.
=>if the search pattern found in given data then it returns an object of match class which contains
matched value and start and end index values and it indicates search is successful.
=>if the search pattern not found in given data then it returns None which is type <class, "NoneType"> and
it indicates search is un-successful
----------------------------------------------------------------------------------------------------------------
4) group():
----------------------------------------------------------------------------------------------
=>This function is used obtaining matched value by the object of match class
=>This function present in match class of re module
Syntax:- varname=matchtabobj.group()
----------------------------------------------------------------------------------------------
5) start():
----------------------------------------------------------------------------------------------
=>This function is used obtaining starting index of matched value
=>This function present in match class of re module
Syntax: varname=matchobj.start()
----------------------------------------------------------------------------------------------
6) end():
----------------------------------------------------------------------------------------------
=>This function is used obtaining end index+1 of matched value
=>This function present in match class of re module
Syntax: varname=matchobj.end()
----------------------------------------------------------------------------------------------
7) sub() Function
=> This function replaces the matches with the text of your choice:

import re
txt = "The rain in Spain"
x = re.sub("\s", "9", txt)
print(x)---------------------------------- The9rain9in9Spain
===================================================
Pre-Defined Character Classes in Reg Expr
===================================================
=>Pre-Defined Character Classes are those which are already available in Python software and they are
used for Preparing or Designing Search Pattern for searching in given data for obtaing Desired Result.
=>Syntax for Using Pre-Defined Character Classes
" \Search Pattern "
=>The Following are Pre-Defined Character Classes.
-------------------------------------------------------------------------------------------------------------------------------
1) \s----------->Searches for Space Character only
2) \S----------->Searches for all except Space Character

3) \d----------->Searches for Digits only OR [0-9]

4) \D----------->Searches for all except Digits OR [^0-9]

5) \w---------->Searches for Word Character OR [A-Za-z0-9]

6) \W---------->Searches for Special Symbols OR [^A-Za-z0-9]


====================================================
Quantifiers in Regular Expressions
====================================================
=>The purpose of Quantifiers in Regular Expressions is that "To Search for zero or one more Values in given
data".
=>Quantifiers are also used in Search Patterns to search in given data for obtaining desired result.
=>The essential Quantifiers in Regular Expressions are given bellow

1. k------------->Searches for Exactly one 'k'


2. k+------------>Searches for One k or More k's
3. k*------------>Searches for either zero k or 1 k or more k's
4. k?------------>Searches for either zero k or one k
5. . --------------->Searches for all

Imp Special Points


-----------------------------------------
1) \d+----->Searches one or more digits (OR) [0-9]+
2) \ddd----->Searches for 3 Digit Number OR \d{3} \d{10} (OR) [0-9]{3}
3) \d{n}----->Searches for N-Digit Number OR [0-9]{n}
4) \d{n}.\d{m}---->Searches N-Digit Integer and M-Digit floating point value(Ex 34.56 56.78..)
5) \w{n}----->Seraches n-length word OR [A-Za-z0-9]{n}
6) \w+------>Searches for either one word char or more word Characters.(OR) [A-Za-z0-9]+

7) \d{n,m }--->Searches for Min n-Digit Number and Maximum m-digit number
OR [0-9]{n,m}
--------------------------------------------------------------------------------------------------------------------
===================================================
Programmer-Defined Character Classes in Reg Expr
===================================================
=>Programmer-Defined Character Classes are those which defined by Programmers and they are for
Preparing or Designing Search Pattern for searching in given data for obtaing Desired Result.
=>Syntax for Using Programmer-Defined Character Classes
" [ Search Pattern ] "
=>The Following are Programmer-Defined Character Classes.
--------------------------------------------------------------------------------------------------------------
1. [abc]------->Searches for either a or b or c

2. [^abc]----->Searches for all except a or b or c

3. [a-z]-------->Searches for all Lower case alphabets only

4. [^a-z]------>Searches for all except Lower Case Alphabets


5. [A-Z]------->Searches for all Upper Case Alphabets

6.[^A-Z]------->Searches for all except Upper Case Alphabets

7. [0-9]------->Searches for all Digits only

8. [^0-9]----->Searches for all except Digits


9. [A-Za-z]---->Searches for all Alphabets (Lower and Upper) only

10. [^A-Za-z]---->Searches for all except Alphabets (Lower and Upper)

11. [A-Za-z0-9]--->Searches for all Alphabers and Digits(Alpha numberics--Word Character)

12. [^A-Za-z0-9]--->Searches for all Special Symbols ( ie Not Alphabets and Digits)

13. [a-z0-9]----->Searches for lower alphabets and digits

14. [^a-z0-9]----->Searches for all except lower alphabets and digits

15. [A-Z0-9]---->Sreaches for all Upper case Alphabets and Digits

16. [^A-Z0-9]---->Sreaches for all except Upper case Alphabets and Digits

--------------------------------------------------------------------------------------------------------------
=================================
generator in python
=================================
=>generator is one of the function
=>The generator function always contains yield keyword
=>If the function contains return statement then it is called Normal Function
=>If the function contains yield keyword then it is called generator
=>Syntax:
def function_name(start,stop,step):
----------------------------------------
----------------------------------------
yield value
----------------
=>The 'yield' key word is used for giving the value back to function call from function defintion and
continue the function execution until condition becomes false.
=>The advantage of generators over functions concept is that it save lot of memory space in the case large
sampling of data. In otherwords Functions gives all the result at once and it take more memory space
where as generators gives one value at a time when programmer requested and takes minimized memory
space.
========================X===================================
=============================================
Numpy Module---Data Scienece
=============================================
Index
----------
=>Purpose of Numpy
=>History of Numpy
=>Advantages of Numpy
=>Similarities and Differences Between List and Numpy
=>Importance of "ndarray"
=>Number of Approaches ro create an object of nd array
=>Attributes of ndarray
=>Types of Ndarrays ( 1-D, 2-D and n-Dimesional Arrays)
=>Basic Indexing and Slicing Operations on ndarray objects
=>Advanced Indexing and Slicing Operations on ndarray objects
=>Slecting or Filtering the values of ndarray objects
=>deleting,updating and adding the values of ndrray
=>Arithmetic or Matrix Operations on ndarray
=>Statistical Operations on ndarray
=>copy and view of ndarray
=>Sorting the values of ndarray
==========================x=====================================
==========================================
Numpy
==========================================
Introduction to Numpy:
-------------------------------------
=>Numpy stands for Numerical Python.
=>Numpy is one of the pre-defined third party module / Library and numpy module is not a pre-defined
module in Python Language.
=>Syntax for installing any module:

pip install module-name

=>Example: Install numpy module

pip install numpy

=>To use numpy as part of our program, we must import numpy module.
=>A Numpy module is a collection of Variables, Functions and Classes.
===============================================================
History of Numpy:
------------------------------
=>Numpy was developed by studying existing module called "Numeric Library"(origin for development of
numpy module)
=>The Numeric Library was developed by JIM HUNGUNIAN
=>The Numeric Library was not able to solve complex maths calculations.
=>Numpy module developed by TRAVIS OLIPHANT for solving complex maths
calculations and array oraganization.
=>Numpy Module developed in the year 2005
=>Numpy Module developed in C and PYTHON languages.
==============================================================
====================================================
Advantages of using NumPy
====================================================
-------------------------------------
Need of NumPy:
-------------------------------------
=>With the revolution of data science, data analysis libraries like NumPy, SciPy, Scikit, Pandas, etc. have
seen a lot of growth. With a much easier syntax than other programming languages, python is the first
choice language for the data scientist.
=>NumPy provides a convenient and efficient way to handle the vast amount of data. NumPy is also very
convenient with Matrix Operations and data reshaping. NumPy is fast which makes it reasonable to work
with a large set of data.
---------------------------------------------------------------------------
The advantages of Numpy Programming are:
---------------------------------------------------------------------------
1) With Numpy Programming, we can deal with Arrays such 1-D, 2-D and Multi Dimensional Arrays.
2) NumPy maintains minimal memory for large sets of data:
3) Numpy provides Fast in Performing Operations bcoz internally its data is available at
same address.
4) NumPy performs array-oriented computing.
5) It efficiently implements the multidimensional arrays.
6) It performs scientific computations.
7) It is capable of performing reshaping the data stored in multidimensional arrays.
8) NumPy provides Many in-built functions for Various Complex Mathematical Operations such as
statistical , financial, trigonometric Operations etc.
===================================================
Python Traditional List VS Numpy Module
===================================================
Similarities of python Traditional List VS Numpy Module:
-----------------------------------------------------------------------------------------
=>An object of list used to store multiple values of same type or different type and both types (unique
+duplicates) in single object.
=>In Numpy Programming, the data is organized in the object of "ndarray", which is one of the pre-defined
class in numpy module. Hence an object of ndarray can store same type or different type and both types
(unique +duplicates) in single object.
=>The objects of ndarray and list are mutable (changes can takes place)
----------------------------------------------------------------------------------------------------------------------
Differences between Python Traditional List and ndarray object of Numpy Module:
----------------------------------------------------------------------------------------------------------------------
=>An object of list contains both homogeneous and hetrogeneous values where as an object of ndarray of
numpy can store only similar type of values(even we store different values, internally they are treated as
similar type by treating all values of type "object" ).
=>On the object of list, we can't perform Vector Based Operations. where as on the object of ndarray, we
can perform Vector based operations.
=>In large sampling of data, List based applications takes more memory space where ndarray object takes
less memory space.
=>List based applications are not effiecient bcoz list object values takes more time to extract or retrive
( they are available at different Address) where as numpy based applications are efficient bcoz of ndarray
object values takes less to time to extract or retrive( they are available at same Address / clustered).
=>List object can't perform complex mathematical operations where as an object of ndarray can perform
complex mathematical operations.
==========================X==================================
=================================================
Number of approaches to create an object of ndarray
=================================================
=>"ndarray" is one of the pre-defined class of numpy module and whose object is used for storing the data
in numpy programming in the form of 1-D, 2-D and n-Dimensional Arrays.
=>In numpy programming, we have the following essential approaches to create an object of ndarray.
1. array()
2. arange()
3. zeros()
4. ones()
5. full()
6. identity()
7.hstack()
8.vstack()
-----------------------------------------------------------------------------------------------------
1) array():
----------------------------------
=>This Function is used for converting Traditional Python Objects into ndarray object.
=>Syntax:- varname=numpy.array( Object,dtype )
=>Here var name is an object of <class,ndarray>
=>here array() is pre-defined function of numpy module used for converting
Traditional Python Objects into ndrray object.
=>object represents any Traditional Python Objects
=>dtype represents any numpy data type such as int8,int16,int32,float16, float 32,
float64,....etc (Internal dfata types of C lang)

Examples:
------------------
>>> import numpy as np
>>> l1=[10,20,30,40,50,60]
>>> print(l1,type(l1))-----------------[10, 20, 30, 40, 50, 60] <class 'list'>
>>> a=np.array(l1)
>>> print(a,type(a))----------------[10 20 30 40 50 60] <class 'numpy.ndarray'>
>>> t=(10,20,30,40,50,60,70)
>>> print(t,type(t))--------------(10, 20, 30, 40, 50, 60, 70) <class 'tuple'>
>>> a=np.array(t)
>>> print(a,type(a))--------------[10 20 30 40 50 60 70] <class 'numpy.ndarray'>
>>> d1={10:1.2,20:4.5,30:6.7}
>>> a=np.array(d1)
>>> a----array({10: 1.2, 20: 4.5, 30: 6.7}, dtype=object)
---------------------------------------------------------------------------------------
>>> t=(10,20,30,40,50,60)
>>> a=np.array(t)
>>> a--------------array([10, 20, 30, 40, 50, 60])
>>> a.ndim------------1
>>> a.dtype----------dtype('int32')
>>> a.shape-------------(6,)
>>> b=a.reshape(3,2)
>>> c=a.reshape(2,3)
>>> b--------------
array([[10, 20],
[30, 40],
[50, 60]])
>>> c
array([[10, 20, 30],
[40, 50, 60]])
>>> print(b,type(b))
[[10 20]
[30 40]
[50 60]] <class 'numpy.ndarray'>
>>> print(c,type(c))
[[10 20 30]
[40 50 60]] <class 'numpy.ndarray'>
>>> b.ndim-------------2
>>> c.ndim------------2
>>> b.shape---------------(3, 2)
>>> c.shape-------------(2, 3)
>>> d=a.reshape(3,3)-------ValueError: cannot reshape array of size 6 into shape (3,3)
----------------------------------------------------------------------------------------------------------------------------
>>> t1=((10,20),(30,40))
>>> print(t1,type(t1))--------------((10, 20), (30, 40)) <class 'tuple'>
>>> a=np.array(t1)
>>> a
array([[10, 20],
[30, 40]])
>>> a.ndim----------2
>>> a.shape----------(2, 2)
------------------------------------------------------------------------------------------------------------
>>> t1=( ((10,20,15),(30,40,25)),( (50,60,18),(70,80,35) ))
>>> print(t1,type(t1))
(((10, 20, 15), (30, 40, 25)), ((50, 60, 18), (70, 80, 35))) <class 'tuple'>
>>> a=np.array(t1)
>>> a
array([[[10, 20, 15],
[30, 40, 25]],

[[50, 60, 18],


[70, 80, 35]]])
>>> print(a)
[[[10 20 15]
[30 40 25]]

[[50 60 18]
[70 80 35]]]
>>> a.ndim
3
>>> a.shape
(2, 2, 3)
>>> b=a.reshape(4,3)
>>> b
array([[10, 20, 15],
[30, 40, 25],
[50, 60, 18],
[70, 80, 35]])
>>> c=a.reshape(3,4)
>>> c
array([[10, 20, 15, 30],
[40, 25, 50, 60],
[18, 70, 80, 35]])
>>> d=a.reshape(3,2,2)
>>> d
array([[[10, 20],
[15, 30]],

[[40, 25],
[50, 60]],

[[18, 70],
[80, 35]]])
>>> d[0]
array([[10, 20],
[15, 30]])
>>> d[1]
array([[40, 25],
[50, 60]])
>>> d[2]
array([[18, 70],
[80, 35]])
>>>

------------------------------------------------------------------------------------------------------------------------------
2. arange():
------------------------------------------------------------------------------------
Syntax1:- varname=numpy.arange(Value)
Syntax2:- varname=numpy.arange(Start,Stop)
Syntax3:- varname=numpy.arange(Start,Stop,Step)
=>Here var name is an object of <class,ndarray>

=>Syntax-1 creates an object of ndarray with the values from 0 to value-1


=>Syntax-2 creates an object of ndarray with the values from Start to Stop-1
=>Syntax-3 creates an object of ndarray with the values from Start to Stop-1 with equal
Interval of Value-----step
=>arange() always create an object of ndarray in 1-D array only but not Possible to create directly 2-D and
Multi Dimesional Arrays.
=>To create 2-D and Multi Dimesional Arrays, we must use reshape() or shape attribute

Examples:
-----------------
>>> import numpy as np
>>> a=np.arange(10)
>>> a-----------array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a.ndim--------1
>>> a=np.arange(50,62)
>>> print(a,type(a))---[50 51 52 53 54 55 56 57 58 59 60 61] <class 'numpy.ndarray'>
>>> a.ndim------1
>>> a=np.arange(10,23,2)
>>> a-----array([10, 12, 14, 16, 18, 20, 22])
>>> a=np.arange(10,22,2)
>>> a--------array([10, 12, 14, 16, 18, 20])
>>> b=a.reshape(2,3)
>>> c=a.reshape(3,2)
>>> b-----
array([[10, 12, 14],
[16, 18, 20]])
>>> c
array([[10, 12],
[14, 16],
[18, 20]])
>>> b.ndim------ 2
>>> c.ndim------- 2
>>> b.shape-----(2, 3)
>>> c.shape-----(3, 2)
>>> l1=[ [[10,20],[30,40]], [[15,25],[35,45]] ]
>>> l1----------[[[10, 20], [30, 40]], [[15, 25], [35, 45]]]
>>> a=np.arange(l1)----------TypeError: unsupported operand type(s) for -: 'list' and 'int'
==================================================================
3. zeros():
------------------------
=>This Function is used for building ZERO matrix either with 1-D or 2-D or n-D
=>Syntax: varname=numpy.zeros(shape,dtype)

=>Here Shape can be 1-D(number of Zeros) or 2-D(Rows,Cols) or n-D( Number of Matrices,Number of


Rows, Number of Columns)
-----------------------
Examples:
--------------------
>>> import numpy as np
>>> a=np.zeros(12)
>>> a-----------array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
>>> a=np.zeros(12,dtype=int)
>>> a------------array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
>>> a.reshape(3,4)
array([[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]])
>>> a.reshape(4,3)
array([[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
>>> a.reshape(6,2)
array([[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]])
>>> a.reshape(2,6)
array([[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0]])
>>> a.reshape(2,3,2)
array([[[0, 0],
[0, 0],
[0, 0]],
[[0, 0],
[0, 0],
[0, 0]]])

>>> a.reshape(2,2,2,2)------ValueError: cannot reshape array of size 12 into shape (2,2,2,2)


>>> a.reshape(3,2,2)
array([[[0, 0],
[0, 0]],

[[0, 0],
[0, 0]],

[[0, 0],
[0, 0]]])
>>> a.reshape(2,3,2)
array([[[0, 0],
[0, 0],
[0, 0]],

[[0, 0],
[0, 0],
[0, 0]]])
>>> a.reshape(2,2,3)
array([[[0, 0, 0],
[0, 0, 0]],

[[0, 0, 0],
[0, 0, 0]]])
----------------------------------------------------------------------------
>>> import numpy as np
>>> a=np.zeros((3,3),dtype=int)
>>> a
array([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
>>> a=np.zeros((2,3))
>>> a
array([[0., 0., 0.],
[0., 0., 0.]])
>>> a=np.zeros((2,3),int)
>>> a
array([[0, 0, 0],
[0, 0, 0]])
>>> a=np.zeros((3,2,3),dtype=int)
>>> a
array([[[0, 0, 0],
[0, 0, 0]],

[[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0]]])
>>> print(a,type(a))
[[[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]]] <class 'numpy.ndarray'>
-------------------------------------------------------------------------------------------------------------------------------
4. ones()
---------------------------------------
=>This Function is used for building ONEs matrix either with 1-D or 2-D or n-D
=>Syntax: varname=numpy.ones(shape,dtype)

=>Here Shape can be 1-D(number of ones) or 2-D(Rows,Cols) or n-D( Number of Matrices,Number of


Rows, Number of Columns)

Examples:
-----------------------------
>>> import numpy as np
>>> a=np.ones(10)
>>> print(a,type(a))----------[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] <class 'numpy.ndarray'>
>>> a=np.ones(10,dtype=int)
>>> print(a,type(a))-------------[1 1 1 1 1 1 1 1 1 1] <class 'numpy.ndarray'>
>>> a.shape-----------(10,)
>>> a.shape=(5,2)
>>> a
array([[1, 1],
[1, 1],
[1, 1],
[1, 1],
[1, 1]])
>>> a.ndim-------------- 2
>>> a.shape------------ (5, 2)
>>> a.shape=(2,5)
>>> a
array([[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])
>>> a.shape----------------------(2, 5)
>>>
>>> a=np.ones((3,4),dtype=int)
>>> a
array([[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]])
>>> a=np.ones((4,3),dtype=int)
>>> print(a,type(a))
[[1 1 1]
[1 1 1]
[1 1 1]
[1 1 1]] <class 'numpy.ndarray'>
>>> a.shape----------(4, 3)
>>> a.shape=(3,2,2)
>>> a
array([[[1, 1],
[1, 1]],

[[1, 1],
[1, 1]],

[[1, 1],
[1, 1]]])
>>> a=np.ones((4,3,3),dtype=int)
>>> a
array([[[1, 1, 1],
[1, 1, 1],
[1, 1, 1]],

[[1, 1, 1],
[1, 1, 1],
[1, 1, 1]],

[[1, 1, 1],
[1, 1, 1],
[1, 1, 1]],

[[1, 1, 1],
[1, 1, 1],
[1, 1, 1]]])

================================================================
5) full()
-------------------------
=>This is function is used for building a matrix by specifying fill value either 1-D or 2-D or n-D
=>Syntax:-
varname=numpy.full(shape,fill_value,dtype)
=>varname is an obejct of <class, numpy.ndarray>
=>Here Shape can be 1-D(number of Fill_Value) or 2-D(Rows,Cols) or n-D( Number of Matrices,Number of
Rows, Number of Columns)
=>fill_value can be any number of programmer choice

Examples:
-------------------
>>> a=np.full(3,1)
>>> a---------array([1, 1, 1])
>>>print(type(a))--------<class,numpy.ndarray>
>>> a=np.full(3,9)
>>> a------------array([9, 9, 9])
>>> a=np.full(6,8)
>>> a-------------array([8, 8, 8, 8, 8, 8])
>>> a.shape=(3,2)
>>> a
array([[8, 8],
[8, 8],
[8, 8]])
>>> a=np.full(6,9)
>>> a----------array([9, 9, 9, 9, 9, 9])
>>> a.reshape(2,3)
array([[9, 9, 9],
[9, 9, 9]])
>>> a=np.full((3,3),9)
>>> a
array([[9, 9, 9],
[9, 9, 9],
[9, 9, 9]])
>>> a=np.full((2,3),6)
>>> a
array([[6, 6, 6],
[6, 6, 6]])
>>> a.reshape(3,2)
array([[6, 6],
[6, 6],
[6, 6]])
>>> a=np.full((3,3,3),7)
>>> a
array([[[7, 7, 7],
[7, 7, 7],
[7, 7, 7]],

[[7, 7, 7],
[7, 7, 7],
[7, 7, 7]],

[[7, 7, 7],
[7, 7, 7],
[7, 7, 7]]])
==================================================================
6) identity():
----------------------------------
=>This function always bulid Identity or unit matrix
=>Syntax:- varname=numpy.identity(N,dtype)
=>Here N represents Either we can take Rows or Columns and PVM takes as NXN Matrix (Square Matrix--
Unit or Identity)

Examples:
--------------------------
>>> import numpy as np
>>> a=np.identity(3,dtype=int)
>>> print(a,type(a))-------------
[[1 0 0]
[0 1 0]
[0 0 1]] <class 'numpy.ndarray'>
>>> a=np.identity(5,dtype=int)
>>> print(a,type(a))
[[1 0 0 0 0]
[0 1 0 0 0]
[0 0 1 0 0]
[0 0 0 1 0]
[0 0 0 0 1]] <class 'numpy.ndarray'>
===================================X====================================
=================================================
Numpy---Basic Indexing
=================================================
==>If we want to access Single element of 1D,2D and N-D arrays we must use the concept of Basic
Indexing.
--------------------------------------------------------------------
=>Accessing Single Element 1D-Array :
---------------------------------------------------------------------
=>Syntax:- ndarrayname [ Index ]

=>Here 'index' can be either either +ve or -ve indexing


----------------
Examples:
------------------
>>> a=np.array([10,20,30,40,50,60])
>>> a
array([10, 20, 30, 40, 50, 60])
>>> a[0]
10
>>> a[3]
40

-----------------------------------------------------------------------------------------------------------
=>Accessing single Element of 2D :
----------------------------------------------------------------------------------------------------------
=>Syntax:- ndarrayobj[ row index , column index ]

----------------
Examples:-
---------------
>>>import numpy as np
>>> a=np.array([10,20,30,40,50,60])
>>> b=a.reshape(2,3)
>>> b
array([[10, 20, 30],
[40, 50, 60]])
>>> b[0,0]
10
>>> b[0,1]
20
>>> b[1,2]
60

======================================================================
=>Accessing single Element of 3D :
----------------------------------------------------------------------------------------------------------------------------
Syntax:- ndarrayobj[ Index of matrix , row index , column index ]
-------------
Examples:
---------------
>>> a=np.array([10,20,30,40,50,60,70,80])
>>> b=a.reshape(2,2,2)
>>> b
array([[[10, 20],
[30, 40]],

[[50, 60],
[70, 80]]])

>>> b[0,0,0]-----------10
>>> b[-1,0,0]---------50
>>> b[-2,1,1]---------40
-------------------------------------------------------------------------------
=======================================================
Numpy---Indexing and Slicing Operations of 1D,2D and 3D array
=======================================================
------------------------------------
1D Arrays Slicing:
------------------------------------
Syntax:- 1dndrrayobj[begin:end:step]
-----------------------
Examples:
-----------------------
>>> a=np.array([10,20,30,40,50,60,70])
>>> a------------array([10, 20, 30, 40, 50, 60, 70])
>>> a[::-1]-----------array([70, 60, 50, 40, 30, 20, 10])
>>> a[::]-----------array([10, 20, 30, 40, 50, 60, 70])
------------------------------------
2D Arrays Slicing:
------------------------------------
Syntax:- ndrrayobj[ i , j ]
here 'i' represents Row Index
here 'j' represents Column Index
(OR)
Syntax:- 2dndrrayobj[Row Index, Column Index]

Syntax:- 2dndrrayobj[begin:end:step, begin:end:step]

--------------------------------------------------------------------
Examples:
--------------------------------------------------------------------
>>> a=np.array([[10,20,30],[40,50,60]])
>>> a
array([[10, 20, 30],
[40, 50, 60]])
>>> a[0,0]
10
>>> a[0:,0:1]
array([[10],
[40]])
>>> a[0:,1:2]
array([[20],
[50]])
>>> a[1:,:]
array([[40, 50, 60]])
===============================================================
3D Arrays Slicing
-----------------------------
Syntax:- 3dndrrayobj[i,j,k]

here 'i' represents Which 2D matrix ( Matrix Number-->0 1 2 3 4 5...... )


here 'j' represents which Rows in that 2D matrix
here 'k' represents which Columns in that 2D matrix
(OR)
Syntax:- 3dndrrayobj[ Matrix Index, Row Index, Column Index ]
(OR)
Syntax:- 3dndrrayobj[begin:end:step, begin:end:step, begin:end:step ]
----------------------
Examples:
----------------------
>>> lst=[ [ [1,2,3],[4,5,6],[7,8,9] ],[ [13,14,15],[16,17,18],[19,20,21] ] ]
>>> print(lst)
[[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[13, 14, 15], [16, 17, 18], [19, 20, 21]]]
>>> arr2=np.array(lst)
>>> print(arr2)
[[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]]

[[13 14 15]
[16 17 18]
[19 20 21]]]
>>> arr2.ndim
3
>>> arr2.shape
(2, 3, 3)
>>> arr2[:,:,0:1]
array([[[ 1],
[ 4],
[ 7]],

[[13],
[16],
[19]]])
>>> arr2[:,:,:1]
array([[[ 1],
[ 4],
[ 7]],
[[13],
[16],
[19]]])
>>> arr2[: , 0:2, 1:3]
array([[[ 2, 3],
[ 5, 6]],

[[14, 15],
[17, 18]]])
>>> arr2[: , :2, 1:]
array([[[ 2, 3],
[ 5, 6]],

[[14, 15],
[17, 18]]])
-------------------------------------------------------------------------------------
=================================================
Numpy---Advanced Indexing
=================================================
==>If we want to access multiple elements, which are not in order (arbitrary elements) of 1D,2D and N-D
arrays we must use the concept of Advanced Indexing.
=>If we want access the elements based on some condition then we can't use basic indexing and Basic
Slicing Operations. To fullfill such type of requirements we must use advanced Indexing.
--------------------------------------------------------------------
=>Accessing Multiple Arbitrary Elements ---1D :
---------------------------------------------------------------------
=>Syntax:- ndarrayname [ x ]

=>Here 'x' can be either ndarray or list which represents required indexes of arbitrary elements.
----------------
Examples:
------------------
>>> lst=[10,20,30,40,50,60,70,80,90]
>>> a=np.array(lst)
>>> print(a)----------------[10 20 30 40 50 60 70 80 90]
#access 10 30 and 80 elements
# here indexes of 10 30 and 80 are 0 2 7
>>>lst=[0,2,7] here [0,2,7] are indexes of 10 30 and 80
>>> indexes=np.array(lst) # here lst converted into ndarray object
>>> print(indexes)---------[0 2 7]
>>> print(a[indexes])--------------[10 30 80]
(OR)
>>> ind=[0,2,7] # prepare the list of indexes of arbitray elements(10,30,80) of ndarray and pass to ndarray
>>> print(a[ind]) -----------[10 30 80]
OR
>>> print(a[[0,2,7] ]) -----------[10 30 80]
Examples:
---------------------
Q1-->Access 20 30 80 10 10 30
>>> lst=[10,20,30,40,50,60,70,80,90]
>>> a=np.array(lst)
>>> print(a)----------------[10 20 30 40 50 60 70 80 90]
>>> ind=[1,2,7,0,0,2] # [1,2,7,0,0,2] are the indexes of 20 30 80 10 10 30
>>> print(a[ind])----------------[20 30 80 10 10 30]
-----------------------------------------------------------------------------------------------------------
=>Accessing Multiple Arbitrary Elements ---2D :
----------------------------------------------------------------------------------------------------------
=>Syntax:- ndarrayobj[ [row indexes],[column indexes] ]

Examples:-
---------------
>>>import numpy as np
>>>mat=np.array([ [1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16] ] )
>>> print(mat)
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]
[13 14 15 16]]

Q1) Access the principle diagnal elements 1 6 11 16

Ans:- mat[ [0,1,2,3],[0,1,2,3] ]


=>When the above statement is executed, The PVM takes internally as
mat[ (0,0), (1,1), (2,2),(3,3) ]-------- 1 6 11 16

>>> mat[ [0,1,2,3],[0,1,2,3] ]-----------array([ 1, 6, 11, 16])

Q2) Access the elements 6 14


Ans: mat[ [1,3] , [1,1] ]
=>When the above statement is executed, The PVM takes internally as
mat[ (1,1),(3,1) ]

>>> mat[[1,3],[1,1]]-----------array([ 6, 14])


======================================================================
=>Accessing Multiple Arbitrary Elements ---3D :
----------------------------------------------------------------------------------------------------------------------------
Syntax:- ndarray[ [Indexes of 2Dmatrix],[row indexes],[column indexes] ]
-------------

----------------
Examples:
---------------
>>>import numpy as np
>>>l1=[ [ [1,2,3,4],[5,6,7,8],[9,10,11,12] ],[ [13,14,15,16],[17,18,19,20],[21,22,23,24] ] ]
>>>mat3d=np.array(l1)
>>>print(mat3d)
>>> print(mat3d)
[[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]

[[13 14 15 16]
[17 18 19 20]
[21 22 23 24]]]
>>> mat3d.ndim
3
>>> mat3d.shape
(2, 3, 4)
----------------------------------------
Q1) Access the elements 1 14 24
Ans:- mat3d[ [0,1,1], [0,0,2], [0,1,3] ]

When the above statement is executed, Internally PVM takes as follows.


=>mat3d[ (0,0,0),(1,0,1),(1,2,3) ]-Gives-->1 14 24

Q1) Access the elements 10 16


>>> mat3d[[-2,-1],[-1,-3],[-3,-1]]----------array([10, 16])
====================================================
OR
========
>>> l1=[ [ [1,2,3,4],[5,6,7,8],[9,10,11,12] ],[ [13,14,15,16],[17,18,19,20],[21,22,23,24] ] ]
>>> a=np.array(l1)
>>> a
array([[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]],

[[13, 14, 15, 16],


[17, 18, 19, 20],
[21, 22, 23, 24]]])
>>> #ndarrayobj[ [MatrixIndex],[Row Index],[Col Index] ]---Syntax
>>> #ndarrayobj[ [MatrixIndex],[Row Index],[Col Index] ]
>>> #access 1,8,13,20
>>> matind=(0,0,1,1)
>>> rowind=(0,1,0,1)
>>> colind=(0,3,0,3)
>>> a[matind,rowind,colind]
array([ 1, 8, 13, 20])
>>> a[ [0,0,0,1,1,1],[0,1,2,0,1,2],[0,1,2,0,1,2] ]
array([ 1, 6, 11, 13, 18, 23])
===========================X==========================================
a=np.array([10,20,30,40,50,60,70,80,15,25,35,45,55,65,75,85])
print(a)

a.shape=(2,2,2,2)
print(a)
[[[[10 20]
[30 40]]

[[50 60]
[70 80]]]
[[[15 25]
[35 45]]

[[55 65]
[75 85]]]]

#access 10 from a---4-D


a[0][0][0][0]------------10
# access 10 and 40 from a---4D
a[[0,0],[0,0],[0,1],[0,1]]----array([10, 40])
# access 60,55 and 15 from a---4D
a[ [0,1,1],[1,1,0],[0,0,0],[1,0,0] ]----array([60, 55, 15])
===========================X===========================================
=========================================
Numpy--Arithmetic Operations (OR) Matrix Operations
=========================================
=>On the objects of ndarray, we can apply all types of Arithmetic Operators.
=>To perform Arithmetic Operations on the objects of ndarray in numpy programming, we use the
following functions.
a) add()
b) subtract()
c) multiply()
d) dot() or matmul()
e) divide()
f) floor_divide()
g) mod()
h) power()
=>All the arithmetic Functions can also be perfomed w.r.t Arithmetic Operators.
=>All these Arithmetic Operations are called Matrix Operations.
---------------
a) add():
--------------
Syntax:- varname=numpy.add(ndarrayobj1, ndarrayobj2)
=>This function is used for adding elements of ndarrayobj1, ndarrayobj2 and result can be displayed
Examples:
-----------------
>>> l1=[ [10,20],[30,40] ]
>>> l2=[[1,2],[3,4]]
>>> a=np.array(l1)
>>> b=np.array(l2)
>>> a
array([[10, 20],
[30, 40]])
>>> b
array([[1, 2],
[3, 4]])
>>> c=np.add(a,b)
>>> c
array([[11, 22],
[33, 44]])
--------------------------------------------------------------------------------
>>> l1=[[10,20],[30,40]]
>>> l2=[[1,2],[3,4]]
>>> a=np.array(l1)
>>> b=np.array(l2)
>>> a
array([[10, 20],
[30, 40]])
>>> b
array([[1, 2],
[3, 4]])
>>> c=a+b # we used operator + instead of add()
>>> c
array([[11, 22],
[33, 44]])
=================================
b) subtract()
------------------------------
Syntax:- varname=numpy.subtract(ndarrayobj1, ndarrayobj2)
=>This function is used for subtracting elements of ndarrayobj1, ndarrayobj2 and result can be displayed

Examples:
------------------
>>> l1=[[10,20],[30,40]]
>>> l2=[[1,2],[3,4]]
>>> a=np.array(l1)
>>> b=np.array(l2)
>>> a
array([[10, 20],
[30, 40]])
>>> b
array([[1, 2],
[3, 4]])
>>> c=np.subtract(a,b)
>>> c
array([[ 9, 18],
[27, 36]])
-----------------------------------
>>> d=a-b # we used operator - instead of subtract()
>>> d
array([[ 9, 18],
[27, 36]])
===================================
c) multiply():
-----------------------
Syntax:- varname=numpy.multiply(ndarrayobj1, ndarrayobj2)
=>This function is used for performing element-wise multiplication of ndarrayobj1, ndarrayobj2 and result
can be displayed

Examples:
>>> l1=[[1,2],[3,4]]
>>> l2=[[5,6],[4,3]]
>>> a=np.array(l1)
>>> b=np.array(l2)
>>> a
array([[1, 2],
[3, 4]])
>>> b
array([[5, 6],
[4, 3]])
>>> c=np.multiply(a,b)
>>> c
array([[ 5, 12],
[12, 12]])
-----------------------------------------------
>>> e=a*b # we used operator * instead of multiply()
>>> e
array([[ 5, 12],
[12, 12]])
------------------------------------------
d) dot() (or) matmul()
=>To perform Matrix Multiplication, we use dot(), matmul()

Syntax:- varname=numpy.dot(ndarrayobj1, ndarrayobj2)


Syntax:- varname=numpy.matmul(ndarrayobj1, ndarrayobj2)

=>These functions is used for performing actual matrix multiplication of ndarrayobj1, ndarrayobj2 and
result can be displayed
Examples:
-----------------
Examples:
>>> l1=[[1,2],[3,4]]
>>> l2=[[5,6],[4,3]]
>>> a=np.array(l1)
>>> b=np.array(l2)
>>> a
array([[1, 2],
[3, 4]])
>>> b
array([[5, 6],
[4, 3]])
>>> d=np.dot(a,b)
>>> d
array([[13, 12],
[31, 30]])
>>> e=np.matmul(a,b)
>>> e
array([[13, 12],
[31, 30]])

-----------------------------------------------------------------------------
e) divide()
-----------------------------------
Syntax:- varname=numpy.divide(ndarray1,ndarry2)
=>This function is used for performing element-wise division of ndarrayobj1, ndarrayobj2 and result can be
displayed
>>> l1=[[10,20],[30,40]]
>>> l2=[[1,2],[3,4]]
>>> a=np.array(l1)
>>> b=np.array(l2)
>>> a
array([[10, 20],
[30, 40]])
>>> b
array([[1, 2],
[3, 4]])
>>> c=np.divide(a,b)
>>> c
array([[10., 10.],
[10., 10.]])
---------------------------------------------------------------
>>> d=a/b # we used operator / instead of divide()
>>> d
array([[10., 10.],
[10., 10.]])
---------------------------------------------------------------------------------------------
f) floor_divide()
-----------------------------------
Syntax:- varname=numpy.floor_divide(ndarray1,ndarry2)
=>This function is used for performing element-wise floor division of ndarrayobj1, ndarrayobj2 and result
can be displayed
>>> l1=[[10,20],[30,40]]
>>> l2=[[1,2],[3,4]]
>>> a=np.array(l1)
>>> b=np.array(l2)
>>> a
array([[10, 20],
[30, 40]])
>>> b
array([[1, 2],
[3, 4]])
>>> c=np.floor_divide(a,b)
>>> c
array([[10, 10],
[10, 10]])
---------------------------------------------------------------
>>> d=a//b # we used operator // instead of floor_divide()
>>> d
array([[10, 10],
[10, 10]])
--------------------------------------------------------------------------------------------------------------------
g) mod()
-------------------------------
Syntax:- varname=numpy.mod(ndarray1,ndarry2)
=>This function is used for performing element-wise modulo division of ndarrayobj1, ndarrayobj2 and
result can be displayed
--------------------
Examples:
---------------------
>>> l1=[[10,20],[30,40]]
>>> l2=[[1,2],[3,4]]
>>> a=np.array(l1)
>>> b=np.array(l2)
>>> a
array([[10, 20],
[30, 40]])
>>> b
array([[1, 2],
[3, 4]])
>>> c=np.mod(a,b)
>>> c
array([[0., 0.],
[0., 0.]])
------------------------------------------------------------------------
=>We can also do with operator %
>>> e=a%b
>>> e
array([[0, 0],
[0, 0]], dtype=int32)
-----------------------------------------------------------------------------------------------------
h) power():
---------------------------------------
Syntax:- varname=numpy.power(ndarray1,ndarry2)
=>This function is used for performing element-wise exponential of ndarrayobj1, ndarrayobj2 and result
can be displayed

---------------------------------------

>>> l1=[[10,20],[30,40]]
>>> l2=[[1,2],[3,4]]
>>> a=np.array(l1)
>>> b=np.array(l2)
>>> a
array([[10, 20],
[30, 40]])
>>> b
array([[1, 2],
[3, 4]])
>>>c=np.power(a,b)
>>>print(c)
array([[ 10, 400],
[ 27000, 2560000]],
--------------------------------------------
>>> f=a**b # Instead of using power() we can use ** operator
>>> f
array([[ 10, 400],
[ 27000, 2560000]], dtype=int32)
==================================X=======================
===========================================
Numpy--Statistical Operations
===========================================
=>On the object of ndarray, we can the following Statistical Operations .
a) amax()
b) amin()
c) mean()
d) median()
e) var()
f) std()
=>These operation we can perform on the entire matrix and we can also peform on columnwise (axis=0)
and Rowwise (axis=1)
a) amax():
-------------------
=>This functions obtains maximum element of the entire matrix.
=>Syntax1:- varname=numpy.amax(ndarrayobject)

=>Syntax2:- varname=numpy.amax(ndarrayobject,axis=0)--->obtains max


elements on the basis of columns.

=>Syntax3:- varname=numpy.amax(ndarrayobject,axis=1)--->obtains max


elements on the basis of Rows.

Examples:
-------------------
>>> l1=[[1,2,3],[4,2,1],[3,4,2]]
>>> A=np.array(l1)
>>> print(A)
[[1 2 3]
[4 2 1]
[3 4 2]]
>>> max=np.amax(A)
>>> cmax=np.amax(A,axis=0)
>>> rmax=np.amax(A,axis=1)
>>> print("Max element=",max)-----------Max eleemnt= 4
>>> print("Column Max eleemnts=",cmax)---Column Max eleemnts= [4 4 3]
>>> print("Row Max eleemnts=",rmax)---Row Max eleemnts= [3 4 4]
-----------------------------------------------------------------------------------------------------
b) amin():
-------------------
=>This functions obtains minmum element of the entire matrix.
=>Syntax1:- varname=numpy.amin(ndarrayobject)

=>Syntax2:- varname=numpy.amin(ndarrayobject,axis=0)--->obtains min


elements on the basis of columns.

=>Syntax3:- varname=numpy.amin(ndarrayobject,axis=1)--->obtains min


elements on the basis of Rows.
Examples:
-------------------
>>> l1=[[1,2,3],[4,2,1],[3,4,2]]
>>> A=np.array(l1)
>>> print(A)
[[1 2 3]
[4 2 1]
[3 4 2]]
>>> min=np.amin(A)
>>> cmin=np.amin(A,axis=0)
>>> rmin=np.amin(A,axis=1)
>>> print("Min eleemnt=",min)---Min eleemnt= 1
>>> print("Column Min eleemnts=",cmin)---Column Min eleemnts= [1 2 1]
>>> print("Row Min eleemnts=",rmin)---Row Min eleemnts= [1 1 2]
---------------------------------------------------------------------------------------------------
c) mean():
-----------------
=>This is used for cal mean of the total matrix elements.
=>The formula for mean=(sum of all elements of matrix) / total number of elements.
Syntax1:- varname=numpy.mean(ndarrayobject)
Syntax2:- varname=numpy.mean(ndarrayobject,axis=0)--->Columnwise Mean
Syntax3:- varname=numpy.mean(ndarrayobject,axis=1)--->Rowwise Mean

Examples:
-----------------
>>> l1=[[1,2,3],[4,2,1],[3,4,2]]
>>> A=np.array(l1)
>>> print(A)
[[1 2 3]
[4 2 1]
[3 4 2]]
>>> m=np.mean(A)
>>> cm=np.mean(A,axis=0)
>>> rm=np.mean(A,axis=1)
>>> print("Mean=",m)-------Mean= 2.4444444444444446
>>> print("Column Mean=",cm)--Column Mean= [2.66666667 2.66666667 2. ]
>>> print("Row Mean=",rm)---Row Mean= [ 2. 2.33333333 3. ]
------------------------------------------------------------------------------------------------------
d) median()
---------------------
=>This is used for calculating / obtaining median of entire matrix elements.
=>Median is nothing but sorting the given data in ascending order and select middle element.
=>If the number of sorted elements are odd then center or middle element becomes median.
=>If the number sorted elements are even then select center or middle of two elements, add them and
divided by 2 and that result becomes median.

Syntax1:- varname=numpy.median(ndarrayobject)

Syntax2:- varname=numpy.median(ndarrayobject,axis=0)

Syntax3:- varname=numpy.median(ndarrayobject,axis=1)

Examples:
--------------------
>>> l1=[[1,2,3],[4,2,1],[3,4,2]]
>>> A=np.array(l1)
>>> print(A)
[[1 2 3]
[4 2 1]
[3 4 2]]
>>> md=np.median(A)
>>> cmd=np.median(A,axis=0)
>>> rmd=np.median(A,axis=1)
>>> print("Median=",md)----Median= 2.0
>>> print("Column Median=",cmd)---Column Median= [3. 2. 2.]
>>> print("Row Median=",rmd)------Row Median= [2. 2. 3.]
>>> l1=[[2,3],[4,1]]
>>> A=np.array(l1)
>>> print(A)
[[2 3]
[4 1]]
>>> md=np.median(A)
>>> cmd=np.median(A,axis=0)
>>> rmd=np.median(A,axis=1)
>>> print("Median=",md)---Median= 2.5
>>> print("Column Median=",cmd)---Column Median= [3. 2.]
>>> print("Row Median=",rmd)---Row Median= [2.5 2.5]
-----------------------------------------------------------------------------------------
e) var():
-------------
Variance= sqr(mean-xi) / total number of elements
here 'xi' represents each element of matrix.
------------------
Syntax1:- varname=numpy.var(ndarrayobject)

Syntax2:- varname=numpy.var(ndarrayobject,axis=0)

Syntax3:- varname=numpy.var(ndarrayobject,axis=1)
--------------------
Examples:
--------------------
>>> l1=[[1,2,3],[4,2,1],[3,4,2]]
>>> A=np.array(l1)
>>> print(A)
[[1 2 3]
[4 2 1]
[3 4 2]]
>>> vr=np.var(A)
>>> cvr=np.var(A,axis=0)
>>> rvr=np.var(A,axis=1)
>>> print("Variance=",vr)----Variance= 1.1358024691358024
>>> print("Column Variance=",cvr)---Column Variance= [1.55555556 0.88888889
0.66666667]
>>> print("Row Variance=",rvr)---Row Variance=[0.66666667 1.55555556 0.66666667]
--------------------------------------------------------------
f) std()
------------------
standard deviation=sqrt(var)
Syntax1:- varname=numpy.std(ndarrayobject)

Syntax2:- varname=numpy.std(ndarrayobject,axis=0)

Syntax3:- varname=numpy.std(ndarrayobject,axis=1)
-------------------------------
Examples:
----------------
>>> l1=[[1,2,3],[4,2,1],[3,4,2]]
>>> A=np.array(l1)
>>> print(A)
[[1 2 3]
[4 2 1]
[3 4 2]]
>>> vr=np.var(A)
>>> cvr=np.var(A,axis=0)
>>> rvr=np.var(A,axis=1)
>>> print("Variance=",vr)---Variance= 1.1358024691358024
>>> print("Column Variance=",cvr)---Column Variance= [1.55555556 0.88888889
0.66666667]
>>> print("Row Variance=",rvr)---Row Variance= [0.66666667 1.55555556 0.66666667]
--------------------------------------------------------------------------------------------------
>>> sd=np.std(A)
>>> csd=np.std(A,axis=0)
>>> rsd=np.std(A,axis=1)
>>> print("std=",sd)---std= 1.0657403385139377
>>> print(" column std=",csd)--- column std= [1.24721913 0.94280904 0.81649658]
>>> print("Row std=",rsd)--Row std= [0.81649658 1.24721913 0.81649658]
==========================X=====================================
Note: numpy module does not contain mode().
mode() present in statistics module of Python

mode() gives Highest Frequent Element in given object


Examples:
----------------
>>> import statistics as s
>>> l1=[10,20,30,10,20,40,10]
>>> s.mode(l1)-------------10
>>> l1=[10,20,30,10,20,40,10,20]
>>> s.mode(l1)-------------10
>>> l1=[20,10,30,10,20,40,10,20]
>>> s.mode(l1)------------------20
>>> s.multimode(l1)--------------[20, 10]
-------------------------------
>>> a=np.array(l1)
>>> s.mode(a)----------------20
>>> s.multimode(a)-----------[20, 10]
---------------------------------------------------------------
-------------------------------------------------
NumPy Sorting Arrays
--------------------------------------------------
=>Sorting is nothing arranging the elements in an ordered sequence.
=>Ordered sequence is any sequence that has an order corresponding to elements, like numeric or
alphabetical, ascending or descending.
=>The NumPy ndarray object has a function called sort(), that will sort a specified array.

Examples:
-------------------
import numpy as np
arr = np.array([3, 2, 0, 1])
print(np.sort(arr)) # [0 1 2 3]
----------------------------------------------------
import numpy as np
arr = np.array(['banana', 'cherry', 'apple'])
print(np.sort(arr)) # ['apple' 'banana' 'cherry']
-----------------------------------------------------
import numpy as np
arr = np.array([True, False, True])
print(np.sort(arr)) # [False True True]
-------------------------------------------------------
Sorting a 2-D Array
--------------------------------------------------------
If you use the sort() method on a 2-D array, both columns and Rows of nd array will be sorted.
-------------------
Examples:
-------------------
import numpy as np
arr = np.array([[3, 2, 4], [5, 0, 1]])
print(np.sort(arr))
#output
[[2 3 4]
[0 1 5]]
--------------------------------------------------------------------------------------------------
a=np.array([110, 20, -30, 40, 50, 160, 7, 8, 90])
print(a)

np.sort(a)-----------array([-30, 7, 8, 20, 40, 50, 90, 110, 160])


np.sort(a)[::-1]-----array([160, 110, 90, 50, 40, 20, 8, 7, -30])
a.shape=(3,3)
a-------------------------------array([[110, 20, -30],
[ 40, 50, 160],
[ 7, 8, 90]])

np.sort(a,axis=0) # ColumnWise
array([[ 7, 8, -30],
[ 40, 20, 90],
[110, 50, 160]])
-----------------------------------------------------------
print(a)
array([[110, 20, -30],
[ 40, 50, 160],
[ 7, 8, 90]])
np.sort(a,axis=1) # Row Wise
array([[-30, 20, 110],
[ 40, 50, 160],
[ 7, 8, 90]])
--------------------------------------------------------------------------------------------------
---------------------------
np.delete()
-------------------
Python’s Numpy library provides a method to delete elements from a numpy array based on index position
i.e.

numpy.delete(arr, obj, axis=None)


---------------------------------------------------------------
arr : Numpy ndarray from which elements needs to be deleted.
obj : Index position or list of index positions of items to be deleted from numpy ndarray arr.
axis : Axis along which we want to delete.
If 1 then delete columns.
If 0 then delete rows.

Examples:
--------------------
# Create a Numpy array from list of numbers
arr = np.array([4,5,6,7,8,9,10,11])
Now let’s delete an element at index position 2 in the above created numpy array,
# Delete element at index position 2
arr = np.delete(arr, 2)
print('Modified Numpy Array by deleting element at index position 2')
print(arr)
Output:----Modified Numpy Array by deleting element at index position 2
[ 4 5 7 8 9 10 11]
----------------------------------------------------
To delete multiple elements from a numpy array by index positions, pass the numpy array and list of index
positions to be deleted to np.delete() i.e.

# Create a Numpy array from list of numbers


arr = np.array([4, 5, 6, 7, 8, 9, 10, 11])
# Delete element at index positions 1,2 and 3
arr = np.delete(arr, [1,2,3])
print('Modified Numpy Array by deleting element at index position 1, 2 &amp; 3')
print(arr)
Output:---------Modified Numpy Array by deleting element at index position 1, 2 &amp; 3
[ 4 8 9 10 11]
----------------------------------------------------------------------------------------
Delete rows & columns from a 2D Numpy Array
----------------------------------------------------------------------------------------
Suppose we have a 2D numpy array i.e.

# Create a 2D numpy array from list of list


arr2D = np.array([[11 ,12, 13, 11],
[21, 22, 23, 24],
[31, 32, 33, 34]])
print(arr2D)
Output:
--------------
[[11 12 13 11]
[21 22 23 24]
[31 32 33 34]]
---------------------------------------------
=>Now let’s see how to delete rows and columns from it based on index positions.

=>Delete a column in 2D Numpy Array by column number


=>To delete a column from a 2D numpy array using np.delete() we need to pass the axis=1
along with numpy array and index of column i.e.

# Delete column at index 1


arr2D = np.delete(arr2D, 1, axis=1)
print('Modified 2D Numpy Array by removing columns at index 1')
print(arr2D)
Output:
-------------------
Modified 2D Numpy Array by removing columns at index 1
[[11 13 11]
[21 23 24]
[31 33 34]]
=>It will delete the column at index position 1 from the above created 2D numpy array.
=>Delete multiple columns in 2D Numpy Array by column number
=>Pass axis=1 and list of column numbers to be deleted along with numpy array to np.delete() i.e.

# Create a 2D numpy array from list of list


arr2D = np.array([[11 ,12, 13, 11],
[21, 22, 23, 24],
[31, 32, 33, 34]])
# Delete column at index 2 &amp; 3
arr2D = np.delete(arr2D, [2,3], axis=1)
print('Modified 2D Numpy Array by removing columns at index 2 &amp; 3')
print(arr2D)
Output:

Modified 2D Numpy Array by removing columns at index 2 &amp; 3


[[11 12]
[21 22]
[31 32]]
It deleted the columns at index positions 2 and 3 from the above created 2D numpy array.
----------------------------------------------------------------
Delete a row in 2D Numpy Array by row number
Our original 2D numpy array arr2D is,

[[11 12 13 11]
[21 22 23 24]
[31 32 33 34]]
To delete a row from a 2D numpy array using np.delete() we need to pass the axis=0 along with numpy
array and index of row i.e. row number,
--------------------------------------------------------------------
# Delete row at index 0 i.e. first row
arr2D = np.delete(arr2D, 0, axis=0)
print('Modified 2D Numpy Array by removing rows at index 0')
print(arr2D)
Output:

[[21 22 23 24]
[31 32 33 34]]
It will delete the row at index position 0 from the above created 2D numpy array.

Delete multiple rows in 2D Numpy Array by row number


Our original 2D numpy array arr2D is,

[[11 12 13 11]
[21 22 23 24]
[31 32 33 34]]
Pass axis=0 and list of row numbers to be deleted along with numpy array to np.delete() i.e.

# Delete rows at ro1 1 &amp; 2


arr2D = np.delete(arr2D, [1, 2], axis=0)
print('Modified 2D Numpy Array by removing rows at index 1 &amp; 2')
print(arr2D)
Output:

Modified 2D Numpy Array by removing rows at index 1 &amp; 2


[[11 12 13 11]]
It deleted the row at index position 1 and 2 from the above created 2D numpy array.
-----------------------------------------------------------------------------------------------------------
Delete specific elements in 2D Numpy Array by index position
-----------------------------------------------------------------------------------------------------------
Our original 2D numpy array arr2D is,

[[11 12 13 11]
[21 22 23 24]
[31 32 33 34]]
When we don’t pass axis argument to np.delete() then it’s default value is None, which means 2D numpy
array will be flattened for deleting elements at given index position. Let’s use np.delete() to delete
element at row number 0 and column 2 from our 2D numpy array,

# Delete element in row 0 and column 2 from 2D numpy array


modArr = np.delete(arr2D, 2)
print('Modified 2D Numpy Array by removing element at row 0 &amp; column 2')
print(modArr)
Output:
Modified 2D Numpy Array by removing element at row 0 &amp; column 2
[11 12 11 21 22 23 24 31 32 33 34]
-----------------------------------------------------------
======================================
Pandas
======================================
Introduction to Pandas:
----------------------------------
=>Pandas is an open source Python Library / Module providing high performance and data manipulation
and Analysis Tool.
=>The word PANDAs derived from PANel DAta
=>The pandas concept developed by WES MCKinney in the year 2008.
=>The Traditional Python Programming does not contain any Module for Data Analysis and Now Python
Programming uses Pandas as an anaysis tool.
=>Python Pandas can be used in wide range of fields like Finance Services, Statistics , retail maketing
sectors..etc
=>pandas module developed in C and Python Languages.
-----------------------------------------------
Instalation of Pandas:
-----------------------------------------------
=>The standard python software / Distribution(CPYTHON) does not contain any module for data analysis
and now we are using third party module called PANDAS and whose module name is pandas
=>Programatically to use pandas as part of our python program, we must install pandas module by using
pip tool.

Syntax:- pip install module name

Example:- pip install pandas


-----------------------------------------------------------------------------------------
Key Features of Pandas:-----> Series DataFrame
-----------------------------------------------------------------------------------------
1) Fast and Efficient Data Frame with default costomized indexing
2) Tools for loading the data in in-memory data objects( objects of Series, DataFrame as Panels)
3) We can access the data from pandas by using Labeled Based Slicing and indexing.
4) Columns from in-memory data objects( objects of Series, DataFrame as Panel) can be deleted and
inserted and updated
-----------------------------------------------------------------------------------------------------
=========================================
Data Structures used in Pandas
=========================================
=>In Pandas programming, we can store the data in 2 types of Data structures. They are.
a) Series
b) DataFrame

=>The best of way of thinking of these data structires is that The higher dimensional Data Structure is a
container of its lower dimensional data structure.
Examples:
--------------
=>Series is part of DataFrame.

-----------------------------------------------------------------------------------------------------------
====================================
Series
====================================
=>It is a One-Dimensional Labelled Array Capable of Storing / Holding Homogeneous data of any type
(Integer, String, float,.........Python objects etc).
=>The Axis Labels are collectively called Index.
=>Pandas Series is nothing but a column value in excel sheet.
=>Pandas Series Values are Mutable.
=>Pandas Series contains Homogeneous Data ( Internally even we store different types values , They are
treated as object type)
----------------------------------------------------------------------------------------------------
Creating a Series
-------------------------------------------------------------------------------------------------------
=>A Series object can be created by using the folowing Syntax:
Syntax:-
--------------
varname=pandas.Series(object, index, dtype)
-------------------
Explanation:-
-------------------
=>Here varname is an object of <class, pandas.core.series.Series >
=>pandas is one of the pre-defined third party module name
=>Series() is pre-defined Function in pandas module and it is used for creating an object of Series class.
=>'object' can either int, float, complex, bool, str, bytes, bytearray,range, list,ndarray,dict .....etc (But not
set type bcoz they are un-ordered)
=>'index' represents the position of values present Series object. The default value of Index starts from 0
to n-1, Here n represents number of values in Series object. Programatically we can give our own Index
Values.
=>'dtype' represents data type (Ex:- int32, ,int64, float32, float64...etc)
-------------------------------------------------------------------------------------------------------
Examples:- Create a series for 10 20 30 40 50 60

>>> import pandas as pd


>>> import numpy as np
>>> lst=[10,20,30,40,50,60]
>>> s=pd.Series(lst)
>>> print(s,type(s))
0 10
1 20
2 30
3 40
4 50
5 60
dtype: int64 <class 'pandas.core.series.Series'>
----------------------------
>>> lst=[10,20,30,40,50,60]
>>> s=pd.Series(lst,dtype=float)
>>> print(s,type(s))
0 10.0
1 20.0
2 30.0
3 40.0
4 50.0
5 60.0
dtype: float64 <class 'pandas.core.series.Series'>
------------------------------------------------------------------
>>> lst=["Rossum","Gosling","Travis","MCKinney"]
>>> a=np.array(lst)
>>> a ------array(['Rossum', 'Gosling', 'Travis', 'MCKinney'], dtype='<U8')
>>> print(a, type(a))--['Rossum' 'Gosling' 'Travis' 'MCKinney'] <class 'numpy.ndarray'>
>>> s=pd.Series(a)
>>> print(s,type(s))
0 Rossum
1 Gosling
2 Travis
3 MCKinney
dtype: object <class 'pandas.core.series.Series'>
----------------------------------------------------------------------
>>>lst=[10,"Rossum",34.56,"Author"]
>>> s=pd.Series(lst)
>>> print(s,type(s))
0 10
1 Rossum
2 34.56
3 Author
dtype: object <class 'pandas.core.series.Series'>
--------------------------------------------------------------------------------------------
Creating an Series object with Programmer-defined Index
--------------------------------------------------------------------------------------------
>>> lst=[10,"Rossum",34.56,"Author"]
>>> print(lst)--------[10, 'Rossum', 34.56, 'Author']
>>> s=pd.Series(lst,index=["Stno","Name","Marks","Desg"])
>>> print(s)
Stno 10
Name Rossum
Marks 34.56
Desg Author
dtype: object
>>> print(s["Stno"])-------10
------------------------------------------------------------------------------
>>> lst=["Rossum","Gosling","Travis","MCKinney"]
>>> s=pd.Series(lst,index=[100,200,300,400])
>>> print(s,type(s))
100 Rossum
200 Gosling
300 Travis
400 MCKinney
dtype: object <class 'pandas.core.series.Series'>
----------------------------------------------------------------------------------
Creating a Series object from dict
-----------------------------------------------------------------------------------
=>A dict object can be used for creating a series object
=>If we use dict object in Series() then keys can be taken as Indices (Or Indexes)
automatically and corresponding values of dict can be taken as Series data.
----------------
Examples:
---------------
>>> import pandas as pd
>>> d1={"sub1":"Python","sub2":"Java","sub3":"Data Science","sub4":"ML"}
>>> print(d1)--{'sub1': 'Python', 'sub2': 'Java', 'sub3': 'Data Science', 'sub4': 'ML'}
>>> s=pd.Series(d1)
>>> print(s)
sub1 Python
sub2 Java
sub3 Data Science
sub4 ML
dtype: object
>>> d2={"RS":2.3,"JG":1.2,"MCK":4.5,"TOLI":2.4}
>>> print(d2)---{'RS': 2.3, 'JG': 1.2, 'MCK': 4.5, 'TOLI': 2.4}
>>> s=pd.Series(d2)
>>> print(s)
RS 2.3
JG 1.2
MCK 4.5
TOLI 2.4
dtype: float64
===============================X==============================
===============================
Counter
===============================
Index
----------
=>What is Python Counter?
=>Why use Python Counter?
=>Counter with String
=>Counter with List
=>Counter with Dictionary
=>Counter with Tuple
=>Counter with Set
=>Accessing, Initializing and Updating Counters
=>Deleting an Element from Counter
=>Methods Available on Python Counter
=>Reassigning Counts in Python
=>Get and set the count of Elements using Counter
-----------------------------------------------
=>Python Counter is a container that will hold the count of each of the elements present in the container.
The counter is a sub-class available inside the dictionary class.
-------------------------------------------------
Uses Python Counter
--------------------------
=>The Counter holds the data in an unordered collection.
=>The elements here represent the keys and the count as values.
=>It allows you to count the items in an iterable list.
=>Arithmetic operations like addition, subtraction, intersection, and union can be easily performed on a
Counter.
=>A Counter can also count elements from another counter
----------------------------------------------------------
Syntax:
-------------
Varname=collections.counter(Iterable object)
=>Varname is an object of <class 'collections.Counter'>
=>Iterable object can be list, tuple, dictionary, string
---------------------------------------------------------
Example1:
from collections import Counter
list1 = ['x','y','z','x','x','x','y', 'z']
print(Counter(list1)) # Counter({'x': 4, 'y': 2, 'z': 2})
---------------------------------------------------------------------------------------
Example2:
from collections import Counter
dict1 = {'x': 4, 'y': 2, 'z': 2, 'z': 2}
print(Counter(dict1)) # Counter({'x': 4, 'y': 2, 'z': 2})
------------------------------------------------------------------------------
Example3
from collections import Counter
c=Counter("MIssisipi")
print(c) # Counter({'s': 3, 'i': 3, 'M': 1, 'I': 1, 'p': 1})
------------------------------------------------------------------------------
Example4:
from collections import Counter
tuple1 = ('x','y','z','x','x','x','y','z')
print(Counter(tuple1)) # Counter({'x': 4, 'y': 2, 'z': 2})
------------------------------------------------------------------------------
=>Methods Available on Python Counter
------------------------------------------
The methods available with Counter are:

1) elements() : This method will return you all the elements with count >0. Elements with 0 or -1 count will
not be returned.
Examples:
----------
d = Counter( a = 2, b = 3, c = 6, d = 1, e = 5)
for i in d.elements():
print ( i, end = " ") # a a b b b c c c c c c d e e e e e

2) most_common(value): This method will return you the most common elements from Counter list.
c=Counter({'x': 5, 'y': 12, 'z': -2, 'x1':0})
ce = c.most_common(2)
print(ce) # [('y', 12), ('x', 5)]
print(common_element)
3) subtract(): This method is used to deduct the elements from another Counter.
Examples:
from collections import Counter
c1 = Counter(A=4, B=3, C=10)
c2 = Counter(A=10, B=3, C=4)
c1.subtract(c2)
print(c1) # Counter({'c': 6, 'B': 0, 'A': -6})
4) update(): This method is used to update the elements from another Counter.
from collections import Counter
coun = Counter()
coun.update([1, 2, 3, 1, 2, 1, 1, 2])
print(coun) # Counter({1: 4, 2: 3, 3: 1})
coun.update([1, 2, 4])
print(coun) # Counter({1: 5, 2: 4, 3: 1, 4: 1})
5) total()---> This Function is used for adding all the occurences of Counter
Values.
Examples:
---------------------
s="MISSISSIPPI"
c=Counter(s)
print("content of c=",c) # content of c= Counter({'I': 4, 'S': 4, 'P': 2, 'M': 1})
t=c.total()
print("Total=",t) # Total=11
------------------------------------------------------------------------------------------------------------
==========================================
DataFrame in Pandas
==========================================
=>A DataFrame is 2-Dimensional Data Structure to organize the data .
=>In Otherwords a DataFrame Organizes the data in the Tabular Format, which is
nothing but Collection of Rows and Columns.
=>The Columns of DataFrame can be Different Data Types or Same Type
=>The Size of DataFrame can be mutable.
---------------------------------------------------------------------------------------------------------
================================================
Number of approaches to create DataFrame
================================================
=>To create an object of DataFrame, we use pre-defined DataFrame() which is present in pandas Module
and returns an object of DataFrame class.
=>We have 5 Ways to create an object of DataFrame. They are
a) By using list / tuple
b) By using dict
c) By using set type
d) By using Series
e) By using ndarray of numpy
f) By using CSV File (Comma Separated Values)
------------------------------------------------------------------------
=>Syntax for creating an object of DataFrame in pandas:
---------------------------------------------------------------------------
varname=pandas.DataFrame(object,index,columns,dtype)
----------------
Explanation:
----------------
=>'varname' is an object of <class,'pandas.core.dataframe.DataFrame'>
=>'pandas.DataFrame()' is a pre-defined function present in pandas module and it is used to create an
object of DataFrame for storing Data sets.
=>'object' represents list (or) tuple (or) dict (or) Series (or) ndarray (or) CSV file
=>'index' represents Row index and whose default indexing starts from 0,1,...n-1
where 'n' represents number of values in DataFrame object.
=>'columns' represents Column index whose default indexing starts from 0,1..n-1
where n number of columns.
=>'dtype' represents data type of values of Column Value.
=======================================================
Creating an object DataFrame by Using list / tuple
-----------------------------------------------------------------------------------
>>>import pandas as pd
>>>lst=[10,20,30,40]
>>>df=pd.DataFrame(lst)
>>>print(df)
0
0 10
1 20
2 30
3 40
------------------------------------
lst=[[10,20,30,40],["RS","JS","MCK","TRV"]]
df=pd.DataFrame(lst)
print(df)
0 1 2 3
0 10 20 30 40
1 RS JS MCK TRV
--------------------------------------------
lst=[[10,'RS'],[20,'JG'],[30,'MCK'],[40,'TRA']]
df=pd.DataFrame(lst)
print(df)
0 1
0 10 RS
1 20 JG
2 30 MCK
3 40 TRA
--------------------------------------------------
lst=[[10,'RS'],[20,'JG'],[30,'MCK'],[40,'TRA']]
df=pd.DataFrame(lst, index=[1,2,3,4],columns=['Rno','Name'])
print(df)

Rno Name
1 10 RS
2 20 JG
3 30 MCK
4 40 TRA
-------------------------------------------
tpl=( ("Rossum",75), ("Gosling",85), ("Travis",65), ("Ritche",95),("MCKinney",60) )
df=pd.DataFrame(tpl, index=[1,2,3,4,5],columns=['Name','Age'])
print(df)
Name Age
1 Rossum 75
2 Gosling 85
3 Travis 65
4 Ritche 95
5 MCKinney 60
-------------------------------------------------------------------------------------
Creating an object DataFrame by Using dict object
--------------------------------------------------------------------
=>When we create an object of DataFrame by using Dict , all the keys are taken as Column Names and
Values of Value are taken as Data.
-----------------
Examples:
-----------------
>>> import pandas as pd
>>> dictdata={"Names":["Rossum","Gosling","Ritche","McKinney"],"Subjects":
["Python","Java","C","Pandas"],"Ages":[65,80,85,55] }
>>> df=pd.DataFrame(dictdata)
>>> print(df)
Names Subjects Ages
0 Rossum Python 65
1 Gosling Java 80
2 Ritche C 85
3 McKinney Pandas 55
>>> df=pd.DataFrame(dictdata,index=[1,2,3,4])
>>> print(df)
Names Subjects Ages
1 Rossum Python 65
2 Gosling Java 80
3 Ritche C 85
4 McKinney Pandas 55
----------------------------------------------------------------------
Creating an object DataFrame by Using Series object
----------------------------------------------------------------------
>>> import pandas as pd
>>> sdata=pd.Series([10,20,30,40])
>>> df=pd.DataFrame(sdata)
>>> print(df)
0
0 10
1 20
2 30
3 40
>>> sdata=pd.Series({"IntMarks":[10,20,30,40],"ExtMarks":[80,75,65,50]})
>>> print(sdata)
IntMarks [10, 20, 30, 40]
ExtMarks [80, 75, 65, 50]
dtype: object

>>> df=pd.DataFrame(sdata)
>>> print(df)
0
IntMarks [10, 20, 30, 40]
ExtMarks [80, 75, 65, 50]
>>> ddata={"IntMarks":[10,20,30,40],"ExtMarks":[80,75,65,50]}
>>> df=pd.DataFrame(ddata)
>>> print(df)
IntMarks ExtMarks
0 10 80
1 20 75
2 30 65
3 40 50
-----------------------------------------------------------------------------------------------
Creating an object DataFrame by Using ndarray object
----------------------------------------------------------------------------------------------
>>> import numpy as np
>>> l1=[[10,60],[20,70],[40,50]]
>>> a=np.array(l1)
>>> df=pd.DataFrame(a)
>>> print(df)
0 1
0 10 60
1 20 70
2 40 50
>>> df=pd.DataFrame(a,columns=["IntMarks","ExtMarks"])
>>> print(df)
IntMarks ExtMarks
0 10 60
1 20 70
2 40 50
------------------------------------------------------------------------------------------
e) By using CSV File(Comma Separated Values)
-----------------------------------------------------------------
import pandas as pd1
df=pd1.read_csv("D:\KVR-JAVA\stud.csv")
print("type of df=",type(df)) #type of df= <class 'pandas.core.frame.DataFrame'>
print(df)
--------------------- OUTPUT--------------------
stno name marks
0 10 Rossum 45.67
1 20 Gosling 55.55
2 30 Ritche 66.66
3 40 Travis 77.77
4 50 KVR 11.11
------------------------------------------------------------------------------------------
=======================================================
Accesssing the Data of DataFrame
=======================================================
1) DataFrameobj.head(no.of rows)
2) DataFrameobj.tail(no.of rows)
3) DataFrameobj.describe()
4) DataFrameobj.shape
5) DataFrameobj [start:stop:step]
6) DataFrameobj["Col Name"]
7) DataFrameobj[ ["Col Name1","Col Name-2"...."Col Name-n"] ]
8) DataFrameobj[ ["Col Name1","Col Name-2"...."Col Name-n"]] [start:stop:step]
9) DataFrameobj.iterrows()
===================================================
Understabding loc() ----- here start and stop index Included and
Col Names can be used(but not column numbers]
--------------------------------------------------------------------------------------
1) DataFrameobj.loc[row_number]
2) DataFrameobj.loc[row_number,[Col Name,.........] ]
3) DataFrameobj.loc[start:stop:step]
4) DataFrameobj.loc[start:stop:step,["Col Name"] ]
5) DataFrameobj.loc[start:stop:step,["Col Name1", Col Name-2......."] ]
6) DataFrameobj.loc[start:stop:step,"Col Name1" : Col Name-n"]
------------------------------------------------------------------------------------------------------------

Understabding iloc() ----- here start index included and stop index excluded and
Col Numbers must be used(but not column names]
--------------------------------------------------------------------------------------
1) DataFrameobj.iloc[row_number]
2) DataFrameobj.iloc[row_number,Col Number.........]
3) DataFrameobj.iloc[row_number,[Col Number1,Col Number2............] ]
3) DataFrameobj.iloc[row start:row stop, Col Start: Col stop]
4) DataFrameobj.iloc[row start:row stop:step, Col Start: Col stop:step]
5) DataFrameobj.iloc[row start:row stop,Col Number ]
6) DataFrameobj.iloc[ [row number1, row number-2.....] ]
7) DataFrameobj.iloc[ row start: row stop , [Col Number1,Col Number2............] ]
8) DataFrameobj.iloc[ : , [Col Number1,Col Number2............] ]
===================================================================
Adding new Column Name to Data Frame
===================================================================
1) dataframeobj['new col name']=default value
2) dataframeobj['new col name']=expression
=======================================================================
Removing Column Name from Data Frame
=======================================================================
1)dataframe.drop(columns="col name")
2)dataframe.drop(columns="col name",inplace=True)
=======================================================================
sorting the dataframe data
=======================================================================
1) dataframeobj.sort_values(["colname"])
2) dataframeobj.sort_values(["colname"],ascending=False)
===================================================================
knowing duplicates in dataframe data
=======================================================================
1) dataframeobj.duplicated()---------------gives boolean result
===================================================================
Removing duplicates from dataframe data
===================================================================
1) dataframeobj.drop_duplicates()
2) dataframeobj.drop_duplicates(inplace=True)
===================================================================
Data Filtering and Conditional Change / updations
===================================================================
1) dataframeobj.loc[ simple condition]

Ex: df.loc[ df["maths"]>75 ]


df.loc[df["maths"]>90 ,["name","maths"]]

2) dataframeobj.loc[ compound condition ]


Ex: df.loc[ (df["maths"]>60) & (df["maths"]<85) ]
Ex: df.loc[ (df["maths"]>95) & (df["maths"]<=99),["name","maths"] ]
---------------------
MOST IMP
---------------------
3) dataframeobj.loc[ (compund condition), ["Col Name"] ]=Expression

Ex: df.loc[ (df["percent"]>=60) & (df["percent"]<=80),["grade"] ]="First" # cond updattion.


-----------------------------------------------------------------------------------------------------------------------
To Export the DataFrame object data to the csv file
df.to_csv("E:\KVR-PYTHON-7AM\PANDAS\studfinaldata.csv")
To Export the DataFrame object data to the txt file
df.to_csv("E:\KVR-PYTHON-7AM\PANDAS\class_10.txt")
(or)
df.to_csv("E:\KVR-PYTHON-7AM\PANDAS\class_10.txt",index=False)
(OR)
df.to_csv("E:\KVR-PYTHON-7AM\PANDAS\class_10.txt",index=False,sep="\t")
-----------------------------------------------------------------------------------------------------------------------
To read the data from EXCEL into dataframe object

dataframeobj=pandas.read_excel("Absolute path of excel file")


Examples:
df=pd.read_excel("D:\\KVR\\kvr.xlsx")
print(df)
--------------------------------------------------------------------------------------------------------------------------
==================================================
DataFrame--GroupBy
==================================================
=>The Group By mechanism in the Pandas provides a way to break a DataFrame into different groups or
chunks based on the values of single or multiple columns.
=>Let’s understand with some examples.
=>Assume we have a DataFrame,
----------------------------------------------------------------------------------------------------
ID Name Age City Experience
----------------------------------------------------------------------------------------------------
11 Jack 44 Sydney 19
12 Riti 41 Delhi 17
13 Aadi 46 Mumbai 11
14 Mohit 45 Delhi 15
15 Veena 43 Delhi 14
16 Shaunak 42 Mumbai 17
17 Manik 42 Sydney 14
18 Vikas 42 Delhi 11
19 Samir 42 Mumbai 15
20 Shobhit 40 Sydney 12
----------------------------------------------------------------------------------------------------
=>This DataFrame has a column ‘City’ which has three unique values like, “Delhi”, “Mumbai” and “Sydney”.
We want to create different groups out of this DataFrame based on the column “City” values.
=>As this column has only three unique values, so there will be three different groups.
=>Group 1 will contain all the rows for which column “City” has the value “Delhi” i.e.
----------------------------------------------------------------------------------------------------
ID Name Age City Experience
----------------------------------------------------------------------------------------------------
12 Riti 41 Delhi 17
14 Mohit 45 Delhi 15
15 Veena 43 Delhi 14
18 Vikas 42 Delhi 11
----------------------------------------------------------------------------------------------------
Group 2 will contain all the rows for which column “City” has the value “Mumbai” i.e.
----------------------------------------------------------------------------------------------------
ID Name Age City Experience
----------------------------------------------------------------------------------------------------
13 Aadi 46 Mumbai 11
16 Shaunak 42 Mumbai 17
19 Samir 42 Mumbai 15
----------------------------------------------------------------------------------------------------

Group 3 will contain all the rows for which column “City” has the value “Sydney” i.e.

ID Name Age City Experience


11 Jack 44 Sydney 19
17 Manik 42 Sydney 14
20 Shobhit 40 Sydney 12

-----------------------------------------------------------------------------------------------------------------
DataFrame.groupby() method
-----------------------------------------------------------------------------------------------------------------
DataFrame’s groupby() method accepts column names as arguments. Based on the column values, it
creates several groups and returns a DataFrameGroupBy object that contains information about these
groups.

For example, let’s create groups based on the column “City”,

# Create Groups based on values in column 'city'


groupObj = df.groupby('City')
print(groupObj)
-------------
Output
-------------
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000002895CA14048>

The groupby() function created three groups because column ‘City’ has three unique values. It returned a
DataFrameGroupBy object with information regarding all three groups.
-----------------------------------------------------------------------------------------------------------------------------
Iterate over all the DataFrame Groups
-----------------------------------------------------------------------------------------------------------------------------
DataFrame’s groupby() function returns a DataFrameGroupBy object, which contains the information of all
the groups. The DataFrameGroupBy is an iterable object. It means using a for loop, we can iterate over all
the created Groups,

# Iterate over all the groups


for grpName, rows in df.groupby('City'):

print("Group Name: ", grpName)


print('Group Content: ')
print(rows)
------------------------------
Output:
-------------------------------------------------
Group Name: Delhi
Group Content:
Name Age City Experience
ID
12 Riti 41 Delhi 17
14 Mohit 45 Delhi 15
15 Veena 43 Delhi 14
18 Vikas 42 Delhi 11
Group Name: Mumbai
Group Content:
Name Age City Experience
ID
13 Aadi 46 Mumbai 11
16 Shaunak 42 Mumbai 17
19 Samir 42 Mumbai 15
Group Name: Sydney
Group Content:
Name Age City Experience
ID
11 Jack 44 Sydney 19
17 Manik 42 Sydney 14
20 Shobhit 40 Sydney 12

-------------------------------------------------------------------------------------------------------------------
Get first row of each Group
------------------------------------------------------------------------------------------------------------------
=>DataFrame’s groupby() function returns a DataFrameGroupBy object, which contains the information of
all the groups. The DataFrameGroupBy object also provides a function first(), and it returns a DataFrame
containing the first row of each of the Group.
-------------------------------------------------------------------------------------------------------------------
Get nth row of each Group
------------------------------------------------------------------------------------------------------------------
=>The pandas.groupby().nth() function is used to get the value corresponding the nth row for each group.
To get the first value in a group, pass 0 as an argument to the nth() function.
-----------------------------
For example
-----------------------------
# Get first row of each group
firstRowDf = df.groupby('City').first()
print(firstRowDf)
---------------------------------
Output:
---------------------------------
Name Age Experience
City
Delhi Riti 41 17
Mumbai Aadi 46 11
Sydney Jack 44 19
There were three unique values in the column “City”, therefore 3 groups were created. The first() function
fetched the first row of each of the Group and returned a DataFrame populated with that. The returned
DataFrame has a row for each of the city and it is the first row from each of the city groups.
---------------------------------------------------------------------------------------------------------------------
Get the count of number of DataFrame Groups
------------------------------------------------------------------------------------------------------------------
The DataFrameGroupBy object also provides a function size(), and it returns the count of rows in each of
the groups created by the groupby() function. For example,
# Get the size of DataFrame groups
print(df.groupby('City').size())
----------------
Output:
----------------
Delhi 4
Mumbai 3
Sydney 3
dtype: int64
As there were three unique values in the column “City”, therefore 3 groups were created by groupby()
function. The size() function returned a Series containing the count of number of rows for each of the
group.
============================================================================
======================================
Decorators in Python
======================================
=>Decorator is one of the Function which will provides Additional Processing capability to the normal
Function value and returns the modified value.
=>A Decorator Function is always takes Normal Function as parameter
--------------
Syntax:-
-------------
def functionname1( functionname ): # Decorator
def innerfunctionname(): # Inner Function name
val=functionname()
--------------------------
#do the operation on ' val '
-------------------------
return resut # Inner Funtion must return modified value
return innerfunctionname # Decorator returns inner function name

=>here functionname1 is called Decorator function


=>here Functionname as a formal parameter . Every decorator function must take normal function as
parameter.
========================================
Multi Threading in Python
========================================
Index
----------
=>Purpose of Multi Threading
=>Types of Applications
a) Process Based Applications
b) Thread Based Application
=>Module Name for Developing Thread Based Applications ( threading)
=>Detailed Discussion of "threading module"
=>Number of approaches to develop Thread Based Applications.
a) By using Functional Approach
b) By Using Object Oriented Approach
=>Programming Examples
------------------------------------------------------------------------------
Dead Locks in Multi Threading.
=>Programming Examples.
-------------------------------------------------------------------------------

=========================================
Intruduction to Thread Based Applications
=========================================
=>The purpose of multi threading is that "To provide Concurrent / Simultaneous
execution / Paralllel Execution".
=>Concurrent Execution is nothing but executing the operations all at once.
=>The advantage of Concurrent execution is that to get less execution time.
=>If a Python Program contains multiple threads then it is called Multi Threading program.
--------------------------
=>Def. of thread:
--------------------------
=>A flow of Control is called thread.
=>The purpose of thread is that "To Perform certain operation whose logic
developed in Functions / Methods concurently."
-----------------------------------------------------------------------------------------------------
=>By default Every Python contains Single Thread and whose name is "MainThread" and It provides
Sequential Execution.
=>Programtically, In a Python Program we can create multiple sub / Child
threads and whose purpose is that "To execute operations whose logic is written in Functions / Methods
Concurrently ".
=>Hence Programatically a Python Program contains two types of Threads. They are
a) MainThread
b) Sub / Child Threads
=>MainThread is created / Initiated by PVM ,when program exeuction starts and the role of mainThread is
to execute main program statements and Monitor the exeuction status of Sub threads(if sub threads
present).
=>The Sub / Child Threads always executes operations whose logic is written in Functions / Methods
Concurrently ".
=====================================X=============================

======================================================
Number of approaches to develop thread based Applications
======================================================
=>In Python Programming, we have 2 approaches to develop thread based applications. They are
1) By Using Functional Approach
2) By using Object Oriended Approach
---------------------------------------------------------------------------------------------------------------------
1) By Using Functional Approach
---------------------------------------------------------------------------------------------------------------------
Steps:
-----------
1. import threading module
2. Define a Function, which is containing logic for Performing Operation by the sub thread.
3. Create a sub therad by using Thread class of threading module
4. Dispatch the sub thread for executing target function
Example: Refer NumberGenEx1.py
---------------------------------------------------------------------------------------------------------------------
2) By using Object Oriended Approach
---------------------------------------------------------------------------------------------------------------------
Steps:
-----------
1. import threading module
2. Define a Programmer-Defined Class
3. Define Instance Method in a Class
4. Create a an object Programmer-Defined Class
5. Create a sub therad by using Thread class of threading module
6. Dispatch the sub thread for executing target function
Example: Refer NumberGenEx3.py
---------------------------------------------------------------------------------------------------------------------
==============================================
Number of approaches for developing Thread Based Applications
==============================================
=>we can Develop thread based applications in 2 ways. They are
1. By using Functional Programming
2. By using Object Oriented Programming
-------------------------------------------------------------------------------------------------------
1. By using Functional Programming
-------------------------------------------------------------------------------------------------------
=>Steps:
1. Import threading Module and other modules if required
2. Define Programmer-Defined Function which contains logic to perform
the task.
3.create sub thread(s)
4. dispatch the sub thread(s) by using start()

Examples:
--------------------
Refer NumberGenEx1.py
-------------------------------------------------------------------------------------------------------
1. By using Object Oriented Programming
-------------------------------------------------------------------------------------------------------
=>Steps:
1. Import threading Module and other modules if required
2. Define Programmer-defined class name
3. Define Programmer-defined Method Name
4. Create Sub Thread(s)
5. Dispatch the sub threads by using start()

Examples: Refer NumberGenEx2.py


=========================x==============================
======================================================
Module Name used for Developing Thread Based Applications
======================================================
=>For Developing Thread Based Applications, we use a pre-defined module called
"threading".
================================================================
MODULE NAME : threading
================================================================
Functions Names in "threading" module
-----------------------------------------------------------------------------------------------------------
1) current_thread():- This Function is used for obtaining Name of the thread.
Syntax: varname=threading.current_thread()
-----------------
Examples:-
-----------------
tname=threading.current_thread()
print("Default Name of thread=",tname.name)

2) active_count(): This Function is used obtaining number of therads which are


running / active.
Syntax: varname=threading.active_count()
-----------------
Example
-----------------
noat=threading.active_count()
print("Number of active threads=",noat) # 1
-------------------
================================================================
Class Name in "threading" module : "Thread"
---------------------------------------------------------------------------------------------------------------
Methods in Thread Class
---------------------------------------------------------------------------------------------------------------
1) Thread(target,args)
-------------------------------------
Syntax:-
varname=threading.Thread(target=FunctionName,args=(list of values if any)
=>here varname is an object of Thread class and treated as sub thread / child
thread.
=>Examples: t1=threading.Thread(target=findsqauares,args=(lst,) )
t2=threading.Thread(traget=welcome)
Here t1 and t2 are called Sub Threads OR Child Threads.
---------------------------------------------
2) is_alive()
---------------------------------------------
=>This Function is used for checking wether the Sub thread is under execution or
not.
=>If the sub thread is under running Process then it returns True otherwise it
returns False.
=>Syntax: var name=threading.is_alive()
Examples: Refer ThreadEx2.py
--------------------------------------------------------
3. start()
--------------------------------------------------------
=>This Function is used for dispatching sub threads to the corresponding target
function.
=>Syntax: subthreadobj.start()
=>Examples Refer ThreadEx2.py
================================================================
4. setName(): It is used for setting the User-Freindly thread name for sub thread

syntax: subthreadobj.setName(" User-Freindly thread name")


----------
Here setName() deprecated on the name of "name" attribute
Syntax: subthreadobj.name=User-Freindly thread name
----------
Example: Refer ThreadEx3.py
---------------------------------------------
5. getName()
---------------------------------------------
=> It is used for getting the thread name
----------
syntax: varname=threadobj.getName(")
----------
Here getName() deprecated on the name of "name" attribute
-----------
Syntax: threadobj.name
----------
Example: Refer ThreadEx3.py
-----------------------------------------------------------------------------------------------------
6) join():
---------------------------------------------
=>This Function is used for making sub threads to join with main thread.
=>When subthreads object calls join() then main thread will wait until until sub threads complete their
execution.
=>Syntyax:- subthreadobj1.join()
subthreadobj2.join()
----------------------------
----------------------------
subthreadobj-n.join()

Examples: Refer NumberGenEx1.py


-----------------------------------------------------------------------------------------------------
================================================
Synchronization in Multi Threading
(OR)
Locking concept in Threading
================================================
=>When multiple threads are operating / working on the same resource(function / method) then by
default we get dead lock result / race condition / wrong result / non-thread safety result.
=>To overcome this dead lock problems, we must apply the concept of Synchronization
=>The advantage of synchronization concept is that to avoid dead lock result and provides Thread Safety
Result.
=>In Python Programming, we can obtain synchronization concept by using locking and un-locking concept.
--------------------------------------------------------------------------------------
=>Steps for implementing Synchronization Concept:
(OR)
Steps for avoiding dead lock
--------------------------------------------------------------------------------------
1) obtain / create an object of Lock class, which is present in threading module.
Syntax:-
----------------
lockobj=threading.Lock()
2) To obtain the lock on the sharable resource, we must use acquire()
Syntax:
--------------
lockobj.acquire()
Once current object acquire the lock, other thread objects are made wait until curent thread object
releases the lock.
3) To un-lock the sharable resource/current object, we must use release()
Syntax:
-------------
lockobj.release()

Once current object releases the lock, other objects are permitted into shrable resource. This
process of aquiring and releasing the lock will be continued until all the objects completed their execution.

========================================
random module
========================================
=>random one of pre-defined module present in python
=>The purpose of random is that "To generate random values in various contexts".
=>random module contains the follwoing essential functions.
a) randrange()
b) randint()
----------------------------------
c) random()
d) uniform()
----------------------------------
e) choice()
f) shuffle()
g) sample()
--------------------------------------
===============================================================
a) randrange()
-------------------------
=>This function is used for generating random integer values between specified limits.
Syntax1:- random.randrang(Value)
This syntax generates any random value between 0 to Value-1

Syntax-2: random.rangerange(start,stop)
This syntax generates any random value between start to stop-1

Examples:
---------------
>>> import random
>>> print(random.randrange(100,150))----133
>>> print(random.randrange(100,150))----121
>>> print(random.randrange(100,150))----139
>>> print(random.randrange(100,150))----143
>>> print(random.randrange(100,150))---106
>>> print(random.randrange(100,150))---133
>>> print(random.randrange(10))----5
>>> print(random.randrange(10))----9
-----------------------------------------------------
#randrangeex.py
import random
for i in range(1,6):
print(random.randrange(10))
print("---------------------------------------")
for i in range(1,6):
print(random.randrange(1000,1100))
print("---------------------------------------")
================================X============================
b) randint():
--------------------
=>Syntax:- random.radint(start,stop)
=>This syntax generates any random value between start to stop. Here start and stop are inclusive.
Examples:
----------------
>>> print(random.randint(10,15))------10
>>> print(random.randint(10,15))-----13
>>> print(random.randint(10,15))----14
>>> print(random.randint(10,15))----11
>>> print(random.randint(10,15))----15
----------------------------------------------------------
#randintex.py
import random
for i in range(1,6):
print(random.randint(10,20))
print("---------------------------------------")
==============================X================================
c) random()
-----------------------
=>Syntax:- random.random()
=>This syntax generates floating point random values between 0.0 and 1.0 (Exlusive))
Examples:
----------------
>>> import random
>>> print(random.random())----------0.1623906138450063
>>> print(random.random())--------0.15382209709271966
>>> print(random.random())-------0.09542283007844476
>>> print(random.random())-----0.6134301633766425
-------------------------
#randomex.py
import random
lst=[]
for i in range(1,6):
lst.append("%0.2f" %random.random())
print("---------------------------------------")
print("Content of lst={}".format(lst))
============================X=============================
d) uniform()
----------------------
Syntax:- random.uniform(start,stop)
=>This generates random floting point values from start to stop-1 values
=>The values of start and stop can both Integer or floating point values.
Examples:
----------------
>>> import random
>>> print(random.uniform(10,15))----------14.416746067678286
>>> print(random.uniform(10,15))----13.2420406264978
>>> print(random.uniform(10,15))-----11.716110933506432
>>> print(random.uniform(10,15))--------10.703499588966528
>>> print(random.uniform(10,15))-----11.306226559323017
>>> print(random.uniform(10.75,15.75))--------13.939787347170148
>>> print(random.uniform(10.75,15.75))----10.760428232717597
-------------------------------------------------------------------------------------------
#uniformex.py
import random
lst=[]
for i in range(1,6):
lst.append(float("%0.2f" %random.uniform(10,15.5)))
print("---------------------------------------")
print("Content of lst={}".format(lst))
===========================X================================
e) choice():
-------------------
Syntax:- random.choice(Iterable_object)
=>This function obtains random values from Iterable_object.
---------------------
EXAMPLES:
---------------------
>>> print(random.choice([10,20,30,40,50]),random.choice("PYTHON"),random.choice(range(10,15)))---40
T 11
>>>
print(random.choice([10,20,30,40,50]),random.choice("PYTHON"),random.choice(range(10,15)))----------30
P 12
>>>
print(random.choice([10,20,30,40,50]),random.choice("PYTHON"),random.choice(range(10,15)))-----------
40 N 12
-------------------------------------
#choiceex.py
import random
s="AaBRe#^%@8YuQLPau*&"
for i in range(1,6):
print(random.choice(s),random.choice(s),random.choice(s),random.choice(s))
===========================X================================
f) shuffle():
--------------------
=>This Function is used for re-organizing the elements of any mutable object but not on immutable object.

Syntax:- random.shuffle(list)
=>We can shuffle the data of list but not other objects of Data Types
Examples:
-------------------
>>> d={10:"cadburry",20:"kitkat",30:"malkybar", 40:"dairymilk"}
>>> print(d)---{10: 'cadburry', 20: 'kitkat', 30: 'malkybar', 40: 'dairymilk'}
>>> for k,v in d.items():
... print(k,"--",v)
...
10 -- cadburry
20 -- kitkat
30 -- malkybar
40 -- dairymilk
>>> import random
>>> print(random.shuffle(d))----Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\nareshit\AppData\Local\Programs\
Python\Python310\lib\random.py", line 394, in shuffle
x[i], x[j] = x[j], x[i]
KeyError: 3
>>> s={10,20,30,40,50}
>>> print(random.shuffle(s))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\nareshit\AppData\Local\Programs\Python\
Python310\lib\random.py", line 394, in shuffle
x[i], x[j] = x[j], x[i]
TypeError: 'set' object is not subscriptable

>>> t=(10,20,30,40,50)
>>> print(random.shuffle(t))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\nareshit\AppData\Local\Programs\Python\
Python310\lib\random.py", line 394, in shuffle
x[i], x[j] = x[j], x[i]
TypeError: 'tuple' object does not support item assignment
>>> l=[10,20,30,40,50]
>>> print(random.shuffle(l))-----None
>>> print(l)-------------[30, 40, 50, 10, 20]
>>> random.shuffle(l)
>>> print(l)------------[40, 30, 10, 20, 50]
>>> random.shuffle(l)
>>> print(l)---------[40, 10, 50, 20, 30]
>>> random.shuffle(l)
>>> print(l)------------[30, 50, 20, 40, 10]

#shuffleex.py
import random as r
l=[10,"Python","Rossum",34.56,True]
for i in range(1,6):
r.shuffle(l)
print("content of l=",l)
===================================X============================
g) sample()
------------------
=>This Function is used for selecting random samples from any Iterable object based on number of
samples(+ve)
Syntax:- random.sample(iterable_object, k)
=>Here 'k' can be number of samples.
Examples:
------------------
>>> import random
>>> s="ABCabcERTYUertyu$%^&*#@!%^&ghjkiyl"
>>> print(random.sample(s,5))----------['A', '*', '^', 'j', 't']
>>> print(random.sample(s,5))---------['%', 'l', 'b', 'C', 'y']
>>> print(random.sample(s,5))----------['%', 'e', 'Y', 'j', 'u']
>>> print(random.sample(s,5))------['y', 'E', '&', '$', '#']
>>> print(random.sample(s,5))----------['j', '*', 't', '$', 'u']
-----------------------------------------------------------------
#sampleex.py
import random
lst=[10,"Rossum","Python",34.56,True]
for i in range(1,6):
print(random.sample(lst,2))
================================X===========================
=======================================
Introduction to Network Programming
=======================================
=>The purpose of Network Programming is that "To share the data between multiple remote Machines
which are located across the world".
=>Def. of Network: A Network is a collection of Inter-connected Autonomous
--------------------------- Computers connected with Server
=>In Network Programming, we can develop two types of Propgrams. They are

1. Server Side Application / Program


2. Client Side Application / Program
-------------------------------------------------------------------------------------------------------
Server Side Application / Program
-------------------------------------------------------------------------------------------------------
=>A Server Side Application / Program is one, which always recevies request from client side program,
Process the request and gives response to client side Program.
-------------------------------------------------------------------------------
Client Side Application / Program
-------------------------------------------------------------------------------
=>A Client Side Application / Program is one which always makes a request to Server Side Program and
obtains Services / Response from Server Side Program.
-----------------------------------------------------------------------------------------------------------------
Definition of DNS (Domain Naming Service):
---------------------------------------------------------------------------------------------------------
=DNS is one of the Physical Machine where Server Side Program Resides.
=>The default DNS of every computer is "localhost"
---------------------------------------------------------------------------------------------------------
Definition of IP Address (Internet Protocol Address):
---------------------------------------------------------------------------------------------------------
=>IP Address is one of the Numerical value of the Physical Machine where Server
Side Program Resides.
=>The default IP Address of every computer is "127.0.0.1"(loop back address)
---------------------------------------------------------------------------------------------------------
Definition of Portno
---------------------------------------------------------------------------------------------------------
=>A Port Number is one of the Logical Numertical Id where server side program is running.
---------------------------------------------------------------------------------------------------------

===============================================
Developing Server and Client Side Applications
===============================================
-----------------------------------------------------------------------
Steps for Developing Server Side Applications:
-----------------------------------------------------------------------
1. import socket module
2. Every Server Side Program must BIND with DNS/ IP Address and Portno.
3. Every Server Side Program must be configured in such way that to how many
client side programs it can provide services.
4. Every Server Side Program must ACCEPT the request from Client Side Program.
5. Server Side Program must READ the requested data of Client Side Program.
6. Server Side Program must PROCESS the client side program request and gives
RESPONSE to Client Side Program.
7. Repeat step-(4)(5) and(6) until Client Side Propgram stops sending Requests.
-------------------------------------------------------------------------------------------------------------
Steps for Developing Client Side Applications
------------------------------------------------------------------------------------------------------------
1. import socket module
2. Every Client Side Program must CONNECT to Server Side Program by passing
(DNS / IP Address, portno)
3. Every Client Side Program must SEND Request to Server Side Program
4. Every Client Side Program must RECEIVE the response from Server Side
Program.
5. Client Side Program can repeat Step-(3) and (4) until Client Side Program
completed its number of requests.
-------------------------------------------------------------------------------------------------------------
=================================================
Module Name for Developing Networking Applications
=================================================
=>The Module Name for Developing Networking Applications is "socket".
=>In General, socket is one of the Bi-Directional Communication Entity Between
multiple Devices
---------------------------------------------------------------------------------------------------------------
1) socket()
---------------------------------------------------------------------------------------------------------------
=>Syntax: varname=socket.socket()
=>Here varname is an object of <class 'socket'>
=>This Function is used for creating an object socket class at both Server and
Client Side Programs.
=>Examples:- s=socket.socket()
---------------------------------------------------------------------------------------------------------------
2) bind()
---------------------------------------------------------------------------------------------------------------
=>Syntax: - serversocketobj.bind( ("DNS/IPAddr",portno ) )
=>This Function is used for making the Server Side Program and binding at
Certain machine (DNS / IP Addr) and at certain Port number.
=>Examples: s.bind( ("localhost",8888) )
(OR)
s.bind( ("127.0.0.1",8888) )
---------------------------------------------------------------------------------------------------------------
3) listen()
---------------------------------------------------------------------------------------------------------------
=>Syntax: serversocketobj.listen(number of clients)
=>This Function is used for configuring the server side program in such a way
that to how many clients The server side porogram can provide services.
=>Examples: s.listen(2)
---------------------------------------------------------------------------------------------------------------
4) accept()
---------------------------------------------------------------------------------------------------------------
=> Syntax:- clientsocket, clientaddr=serversockobj.accept()
=>This Function is used accepting and connecting by server Side Program to the
Client Side Program.
=>Example: - cs,ca=s.accept()
---------------------------------------------------------------------------------------------------------------
5) recv() with decode()
---------------------------------------------------------------------------------------------------------------
=>Syntax: strdata=clientsocketobj.recv(1024/2048/4096).decode()
=>The Function is used at Server Side for receving Client Request and it can also
be used at Client Side for receving Server Response.
=>Examples: strdata=cs.recv(1024).decode() # Server Side and Client Side
--------------------------------------------------------------------------------------------------------------
6) send() with encode()
---------------------------------------------------------------------------------------------------------------
=>Syntax: clientsocketobj.send("strdata".encode())
=>The Function is used at Server Side for Sending Response to Client Side Program and used at Client Side
for Sending Request to Server side program
=>Examples: strdata=cs.send("strdata".encode()) # # Server Side and Client Side
---------------------------------------------------------------------------------------------------------------
7) connect()
---------------------------------------------------------------------------------------------------------------
Syntax: clientsocketobj.connect(("DNS/IP Addr","Portno"))
=>This Function is used for obtaining connection Server Side Program by the client side Program
=>Examples: clientsocketobj.connect(("localhost",8888)
(OR)
clientsocketobj.connect(("127.0.0.1",8888)
============================x=====================================
===========================================
os module
===========================================
=>In Python, "os" is one pre-defined module.
=>The purpose of os module is that "To perform some os related oprations" much

1) Obtaining Current Working Folder( getcwd() ).


2) Creating Folder / Directory. (mkdir() )
3) Creating Folders Hierarchy. (makedirs() )
4) Removing Folder / Directory. (rmdir() )
5) Removing Folders Hierarchy. (removedirs() )
6) Removing File Name from Folder( remove() )
7) Renaming a Folder/File Name. (rename())
8) List the file names in folder ( listdir() )
--------------------------------------------------------------------------------------------
1) Obtaining Current Working Folder.
--------------------------------------------------------------------------------------------
=>For Obtaining Current Working Folder, we use a pre-defined function called getcwd()
present in os module,
=>Syntax: varname=os.getcwd()
--------------------------------------------------------------------------------------------
#Program for Obtaining Current Working Folder
#cwdex.py
import os
cwdname=os.getcwd()
print("Current Working Folder=",cwdname)
--------------------------------------------------------------------------------------------
2) Creating Folder / Directory
--------------------------------------------------------------------------------------------
=>For Creating a Folder / Directory, we use mkdir().
=>Syntax: os.mkdir("Folder Name")
=>if the folder name already exist then we get FileExistsError
=>mkdir() can create only one folder at a time and if we try to create folder hierarchy then
we get FileNotFioundError.
=>in mkdir(), if we specify any folder name with escape sequence ( \n \u \digits,\t..etc) then
we get OSError.

Examples:
----------------
#Program for Creating Folder / Directory
#mkdirex.py
import os
try:
os.mkdir("D:\suraj\python\7am")
print("Folder Created Successfully-verify")
except FileNotFoundError:
print("mkdir() can create only one folder at a time")
except FileExistsError:
print("The specified folder already exist")
except OSError:
print("Check ur path of folder names")
------------------------------------------------------------------------------------------------------------
3) Creating Folders Hierarchy.
-----------------------------------------------------------------------------------------------------------
=>For Creating Folders Hierarchy, we use makedirs().
=>Syntax: os.makedirs("Folders Hierarchy")
=>Here Folders Hierarchy represent Root Folder\sub folder\sub-sub folder so on...
=>if the folder name already exist then we get FileExistsError
=> if we specify any folder name with escape sequence ( \n \u \digits,\t..etc) then
we get OSError.

Examples:
---------------
#Program for Creating Folders Hierarchy
#makedirsex.py
import os
try:
os.makedirs("D:\\India\\Hyd\\ampt\\python\\python")
print("Folder Created Successfully-verify")
except FileExistsError:
print("The specified folder already exist")
except OSError:
print("Check ur path of folder names")
----------------------------------------------------------------------------------------------------------
4) Removing Folder / Directory.
----------------------------------------------------------------------------------------------------------
=>For Removing Folder / Directory, we use rmdir()
=>syntax: os.rmdir("folder name")
=>rmdir() can remove folder name provided folder name is empty.
=>if the folder name already exist then we get FileExistsError
=>if we specify any folder name with escape sequence ( \n \u \digits,\t..etc) then
we get OSError.
-------------------------------------------------------------------------------
#Program for Removing Folder / Directory
#rmdirex.py
import os
try:
os.rmdir("D:\KVR")
print("Folder removed Successfully-verify")
except FileNotFoundError:
print("folder name does not exist")
except OSError:
print("rmdir() can remove those foilder which are empty--check ur path")
----------------------------------------------------------------------------------------------------------
5) Removing Folders Hierarchy. (removedirs() )
----------------------------------------------------------------------------------------------------------
=>For Removing Removing Folders Hierarchy, we use removedirs()
=>Syntax: os.removedirs("Folders Hierarchy")
=>Here Folders Hierarchy represent Root Folder\sub folder\sub-sub folder so on...
=>if the folder name not exist then we get FileNotFoundError
=> if we specify any folder name with escape sequence ( \n \u \digits,\t..etc) then
we get OSError.
--------------------------
Examples
-------------------------
#Program for Removing Folders Hierarchy
#removedirsex.py
import os
try:
os.removedirs("D:\\India\\Hyd\\ampt\\python\\python")
print("Folders Hierarchy Removed Successfully-verify")
except FileNotFoundError:
print("The specified folders hierachy does exist")
except OSError:
print("remove those folder which are empty-Check ur path of folder names")
---------------------------------------------------------------------------------------------------
6) Removing File Name from Folder.
---------------------------------------------------------------------------------------------------
=>To remove the file name from folder, we use remove()
=>Syntax: os.remove("Absolute Path of File Name")
=>If the file name does not exist then we get FileNotFoundError
-----------------
Examples
-----------------
#Program for removing the file name from folder
#RemoveFileEx.py
import os
try:
os.remove("E:\KVR-PYTHON-7AM\MODULES\SE3.py")
print("File Name removed Sucessfully")
except FileNotFoundError:
print("File does not exist")

---------------------------------------------------------------------------------------------------
7) Renaming a Folder/File Name.
---------------------------------------------------------------------------------------------------
=>To rename a folder, we rename()
=>Syntax: os.rename("Old Folder Name","New Folde Name")
=>If the Old Folder Name does not exist then we get FileNotFoundError.
----------------
Examples
------------------
#Program for renaming a folder anme
#RenameFolderEx.py
import os
try:
os.rename("D:\KVR","D:\PYTHON")
print("Folder Name renamed")
except FileNotFoundError:
print("File does not exist")
---------------------------------------------------------------------------------------------------
8) List the file names in folder.
---------------------------------------------------------------------------------------------------
=>To list the file names in folder, we use listdir()
=>Syntax: os.listdir("Absolute Path of Folder Name")
=>If the Old Folder Name does not exist then we get FileNotFoundError.
------------------
Examples:
------------------
#Program for Listing files ijn folder
#ListFileFolderEx.py
import os
try:
FolderName=input("Enter Folder name to list files:")
fileslist=os.listdir(FolderName)
print("-"*50)
print("List of Files:")
print("-"*50)
for filename in fileslist:
print("\t{}".format(filename))
print("-"*50)
except FileNotFoundError:
print("Folder does not exist")
---------------------------------------------------------------------------------------------------
========================
Iterators in Python
========================
------------------------------------------------------
Why should WE use Iterators:
------------------------------------------------------
=>In modern days, we have a lot of data in our hands, and handling this huge amount of data creates
problems for everyone who wants to do some sort of analysis with that data.So, If you’ve ever struggled
with handling huge amounts of data, and your machine running out of memory, then WE use the concept
of Iterators in Python.
=>Therefore, Rather than putting all the data in the memory in one step, it would be better if we could
work with it in bits or some small chunks, dealing with only that data that is required at that moment. As a
result, this would reduce the load on our computer memory tremendously. And this is what exactly the
iterators do.
=>Therefore, you can use Iterators to save a ton of memory, as Iterators don’t compute their items when
they are generated, but only when they are called upon.
----------------------------------------------------------------------------------------------------------------------
=>Iterator in python is an object that is used to iterate over iterable objects like lists, tuples, dicts, and sets.
=>The iterator object is initialized using the iter() method. It uses the next() method for iteration.
=>Here iter() is used for converting Iterable object into Iterator object.
=>next() is used for obtaining next element of iterator object and if no next element then we get an
exception called StopIteration.
=>On the object of Iterator, we can't perform Indexing and Slicing Operations bcoz They supply the values
on demand .
--------------------------
Examples:
--------------------------
s = 'Python'
itobj = iter(s)
while True:
try:
item = next(s) # Iterate by calling next
print(item)
except StopIteration: # exception will happen when iteration will over
break
======================================================
mytuple = ("apple", "banana", "cherry")
myit = iter(mytuple)
print(next(myit))
print(next(myit))
print(next(myit))
=======================================================
================================
JSON file
================================
=>JSON (JavaScript Object Notation) is a popular data format used for representing structured data. It's
common to transmit and receive data between a server and Client web application development in the
form of JSON format.
=>In otherwords,JSON is a lightweight data format for data interchange which can be easily read and
written by humans, easily parsed and generated by machines.
=>It is a complete language-independent text format. To work with JSON data, Python has a built-in
module called json.
=================================================
Parse JSON (Convert from JSON to Python)
-------------------------------------------------------------------------------------
=>json.loads() method can parse a json string and converted into Python dictionary.
Syntax:
dictobj=json.loads(json_string)

Examples:
---------------------
# Python program to convert JSON to Python
import json
# JSON string
employee = ' {"id":"09", "name": "Rossum", "department":"IT"} '
# Convert JSON string to Python dict
employee_dict = json.loads(employee)
print(employee_dict)
--------------------------------------------------------------------------------------------------------------------------
Python--- read JSON file
--------------------------------------------------------------------------------------------------------------------------
=>json.load() method can read a file which contains a JSON object.
Consider a file named employee.json which contains a JSON object.
Syntax:
json.load(file_object)
------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------
Python--- write to JSON file
--------------------------------------------------------------------------------------------------------------------------
=>json.dump() method can write dict object data to a file.
Syntax:
json.dump(dict object, file_pointer)
------------------------------------------------------------------------------------------------------
==============================================
Namedtuple in Collections Module
==============================================
Index
-------------------------------------
=>What is tuple
=>Indexing in Tuple
=>Why we namedtuple()
=>Syntax for creating namedtuple
=>Arguments to namedtuple()
=>Converting namedtuple Instances Into Dictionaries
=>Converting Dictionaries into namedtuple Instances
=>Replacing Fields in Existing namedtuple Instances
=>Adding Additional namedtuple Attributes
=>Attributes of namedtuple
=>Displaying the Field Names and Field Values by using zip()
=>DataClasses(Mutable and immutable) VS namedtuple
=>Programming Examples
---------------------------------------------------------------------
=>Python’s collections module provides a factory function called namedtuple()
=>namedtuple() designed to make our code more Pythonic when you’re working with tuples.
=>With namedtuple(), we can create immutable sequence types that allow you to access their values
using descriptive field names and the dot notation instead of unclear integer indices.
=>Hence the advantage of namedtuple is that we can access their values using field names and the dot
notation.
----------------------------------------------------------
By using Normal tuple object
----------------------------------------------------------
>>> # Create a 2D point as a tuple
>>> point = (2, 4)
>>> point
(2, 4)

>>> # Access coordinate x


>>> point[0]
2
>>> # Access coordinate y
>>> point[1]
4

>>> # Try to update a coordinate value


>>> point[0] = 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
-----------------------------------------------------------
Here, you create an immutable two-dimensional point using a regular tuple. This code works: You have a
point with two coordinates, and you can’t modify any of those coordinates.
However, is this code readable? Can you tell up front what the 0 and 1 indices mean?
To prevent these ambiguities, you can use a namedtuple like this:
=========================================================================
Now Lets start how to use namedtuple
Syntax:- varname=namedtuple(typename, field_names)
we can't create an empty named tuple.
=========================================================================
>>> from collections import namedtuple

>>> # Create a namedtuple type, Point


>>> Point = namedtuple("Point", "x y")
>>> issubclass(Point, tuple)
True

>>> # Instantiate the new type


>>> point = Point(2, 4)
>>> point
Point(x=2, y=4)

>>> # Dot notation to access coordinates


>>> point.x
2
>>> point.y
4

>>> # Indexing to access coordinates


>>> point[0]
2
>>> point[1]
4

>>> # Named tuples are immutable


>>> point.x = 100---------AttributeError: can't set attribute
-------------------
Explanation
------------------
Now you have a point with two appropriately named fields, x and y. Your point provides a user-friendly and
descriptive string representation (Point(x=2, y=4)) by default. It allows you to access the coordinates using
the dot notation, which is convenient, readable, and explicit. You can also use indices to access the value of
each coordinate
=======================================================================================
===
Let starts Deep discussion about
------------------------------------------------------------------------------------------
Note: It’s important to note that, while tuples and named tuples are immutable, the values they store
don’t necessarily have to be immutable.
=>It’s totally legal to create a tuple or a named tuple that holds mutable values:
--------------------------------------------------------------------------------
>>> from collections import namedtuple
>>> Person = namedtuple("Person", "name children")
>>> john = Person("John Doe", ["Timmy", "Jimmy"])
>>> john
Person(name='John Doe', children=['Timmy', 'Jimmy'])
>>> id(john.children)------139695902374144
>>> john.children.append("Tina")
>>> john---Person(name='John Doe', children=['Timmy', 'Jimmy', 'Tina'])

=>You can create named tuples that contain mutable objects. You can modify the mutable objects in the
underlying tuple. However, this doesn’t mean that you’re modifying the tuple itself. The tuple will continue
holding the same memory references.
=================================================================================
Providing Required Arguments to namedtuple()
=================================================================================
=>As you learned before, namedtuple() is a factory function rather than a typical data structure. To create
a new namedtuple, you need to provide two positional arguments to the function:

Syntax:- varname=namedtuple(typename, field_names)

=>typename provides the class name for the namedtuple returned by namedtuple(). You need to pass a
string with a valid Python identifier to this argument.
=>field_names provides the field names that you’ll use to access the values in the tuple. You can provide
the field names using:
=>An iterable of strings, such as ["field1", "field2", ..., "fieldN"]
=>A string with each field name separated by whitespace, such as "field1 field2 ... fieldN"
=>A string with each field name separated by commas, such as "field1, field2, ..., fieldN"
=>To illustrate how to provide field_names, here are different ways to create points:
-------------------------------------------------------------------
>>> from collections import namedtuple
>>> # A list of strings for the field names
>>> Point = namedtuple("Point", ["x", "y"])
>>> Point
<class '__main__.Point'>
>>> Point(2, 4)
Point(x=2, y=4)
(OR)
>>> # A string with comma-separated field names
>>> Point = namedtuple("Point", "x, y")
>>> Point
<class '__main__.Point'>
>>> Point(4, 8)
Point(x=4, y=8)
OR
>>> # A generator expression for the field names
>>> Point = namedtuple("Point", (field for field in "xy")) # but not (field for field in "x,y")
>>> Point
<class '__main__.Point'>
>>> Point(8, 16)
Point(x=8, y=16)
In these examples, you first create Point using a list of field names. Then you use a string with comma-
separated field names. Finally, you use a generator expression. This last option might look like overkill in
this example. However, it’s intended to illustrate the flexibility of the process.
==============================================================================
Converting namedtuple Instances Into Dictionaries
-----------------------------------------------------
=>You can convert existing named tuple instances into dictionaries using ._asdict(). This method returns a
new dictionary that uses the field names as keys. The keys of the resulting dictionary are in the same order
as the fields in the original namedtuple:

>>> from collections import namedtuple

>>> Person = namedtuple("Person", "name age height")


>>> jane = Person("Jane", 25, 1.75)
>>> jane._asdict()
{'name': 'Jane', 'age': 25, 'height': 1.75}
----------------------------------------------------------------------------------
Replacing Fields in Existing namedtuple Instances
----------------------------------------------------------------------------------
The last method you’ll learn about is ._replace(). This method takes keyword arguments of the form
field=value and returns a new namedtuple instance updating the values of the selected fields:

>>> from collections import namedtuple

>>> Person = namedtuple("Person", "name age height")


>>> jane = Person("Jane", 25, 1.75)
>>> # After Jane's birthday
>>> jane = jane._replace(age=26)
>>> jane
Person(name='Jane', age=26, height=1.75)
----------------------------------------------------------------------------------------------
Exploring Additional namedtuple Attributes
----------------------------------------------------------------------------------------------
Named tuples also have one attribute: ._fields . This attribute holds a tuple of strings listing the field
names.
In the case of ._fields, you can use it to introspect(Examine) your namedtuple classes and instances. You
can also create new classes from existing ones:

>>> from collections import namedtuple


>>> Person = namedtuple("Person", "name age height")
>>> ExtendedPerson = namedtuple(
... "ExtendedPerson",
... [*Person._fields, "weight"]
... )
>>> jane = ExtendedPerson("Jane", 26, 1.75, 67)
>>> jane
ExtendedPerson(name='Jane', age=26, height=1.75, weight=67)
>>> jane.weight
67
-------------------------------------------------------------------------------------------
You can also use ._fields to iterate over the fields and the values in a given namedtuple instance using
Python’s zip():
------------------------------------------------------------------------------------------
>>> from collections import namedtuple
>>> Person = namedtuple("Person", "name age height weight")
>>> jane = Person("Jane", 26, 1.75, 67)
>>> for field, value in zip(jane._fields, jane):
... print(field, "->", value)
Output
------------
name -> Jane
age -> 26
height -> 1.75
weight -> 67
-------------------------------------------------------------------------------------------
To create a data class, you need to import the dataclass() decorator from dataclasses. Then you can define
your data classes using the regular class definition syntax:

>>> from dataclasses import dataclass


>>> @dataclass
... class Person:
... name: str
... age: int
... height: float
... weight: float
... country: str = "Canada"
...
>>> jane = Person("Jane", 25, 1.75, 67)
>>> jane
Person(name='Jane', age=25, height=1.75, weight=67, country='Canada')
>>> jane.name
'Jane'
>>> jane.name = "Jane Doe"
>>> jane.name
'Jane Doe'
========================================x==============================================
===
https://realpython.com/python-namedtuple/
In terms of readability, there are no significant differences between data classes and named tuples. They
provide similar string representations, and you can access their attributes using the dot notation.
-------------------------------------------------------------------------------------------
Mutability-wise, data classes are mutable by definition, so you can change the value of their attributes
when needed. However, they have an ace up their sleeve. You can set the dataclass() decorator’s frozen
argument to True and make them immutable:

>>> from dataclasses import dataclass

>>> @dataclass(frozen=True)
... class Person:
... name: str
... age: int
... height: float
... weight: float
... country: str = "Canada"
...

>>> jane = Person("Jane", 25, 1.75, 67)


>>> jane.name = "Jane Doe"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 4, in __setattr__
dataclasses.FrozenInstanceError: cannot assign to field 'name'
If you set frozen to True in the call to dataclass(), then you make the data class immutable. In this case,
when you try to update Jane’s name, you get a FrozenInstanceError.

Another subtle difference between named tuples and data classes is that the latter aren’t iterable by
default. Stick to the Jane example and try to iterate over her data:

>>> for field in jane:


... print(field)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'Person' object is not iterable
------------------------------------------------------------------------------

If you try to iterate over an object of data class, then you get a TypeError. This is common to regular
classes. Fortunately, there are ways to work around it. For example, you can add an .__iter__() special
method to Person like this:
>>> from dataclasses import astuple, dataclass

>>> @dataclass
... class Person:
... name: str
... age: int
... height: float
... weight: float
... country: str = "Canada"
... def __iter__(self):
... return iter(astuple(self))
...

>>> for field in Person("Jane", 25, 1.75, 67):


... print(field)
...
Jane
25
1.75
67
Canada
Here, you first import astuple() from dataclasses. This function converts the data class into a tuple. Then
you pass the resulting tuple to iter() so you can build and return an iterator from .__iter__(). With this
addition, you can start iterating over Jane’s data.
=======================================================================================
====
namedtuple vs typing.NamedTuple
-----------------------------------
Python 3.5 introduced a provisional module called typing to support function type annotations or type
hints. This module provides NamedTuple, which is a typed version of namedtuple. With NamedTuple, you
can create namedtuple classes with type hints. Following with the Person example, you can create an
equivalent typed named tuple like this:

>>> from typing import NamedTuple

>>> class Person(NamedTuple):


... name: str
... age: int
... height: float
... weight: float
... country: str = "Canada"
...

>>> issubclass(Person, tuple)


True
>>> jane = Person("Jane", 25, 1.75, 67)
>>> jane.name
'Jane'
>>> jane.name = "Jane Doe"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
With NamedTuple, you can create tuple subclasses that support type hints and attribute access through
the dot notation. Since the resulting class is a tuple subclass, it’s immutable as well.

A subtle detail to notice in the above example is that NamedTuple subclasses look even more similar to
data classes than named tuples.

You might also like