[go: up one dir, main page]

0% found this document useful (0 votes)
2 views37 pages

20944254 Python Module 4

This document covers Object Oriented Programming (OOP) principles, focusing on class design, abstraction mechanisms, and the implementation of classes in Python. It discusses the structure of class definitions, methods, instance variables, and the importance of constructors, along with examples such as a Student class and a Rational number class. Additionally, it explores concepts like inheritance, polymorphism, and the use of class variables in the context of modeling real-world scenarios like banking and playing cards.

Uploaded by

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

20944254 Python Module 4

This document covers Object Oriented Programming (OOP) principles, focusing on class design, abstraction mechanisms, and the implementation of classes in Python. It discusses the structure of class definitions, methods, instance variables, and the importance of constructors, along with examples such as a Student class and a Rational number class. Additionally, it explores concepts like inheritance, polymorphism, and the use of class variables in the context of modeling real-world scenarios like banking and playing cards.

Uploaded by

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

MODULE IV - Object Oriented Programming

04/04/2023
Monday

Design with Classes

* Abstraction mechanisms are software tools in computational problem


solving for simplifying designs and controlling the complexity of
solutions.

- Abstraction mechanisms include functions, modules, objects, and classes.

* Whatever be the abstraction mechanism, it gives the user an external


view of a resource, showing what it does and how it can be used.

Eg: To use a function in the built-in math module, you import it, run help
to learn how to use the function correctly, and then include it appropriately
in your code.

(Other built-in data structures that provide abstraction include: strings and
lists, Turtle and Image classes)

- From a user’s perspective, he shouldn’t be concerned with how a


resource performs its task.

*The beauty and utility of an abstraction is that it frees you from the need
to be concerned with such details.

* Not all useful abstractions are built in.

- You will sometimes need to custom design an abstraction to suit the


needs of a specialized application or a suite of applications you are
developing.

- So we study how to design and implement new classes from scratch


* Programming languages that allow the programmer to define new classes
of objects are called object-oriented languages . These languages also
support a style of programming called object-oriented programming .

* Object oriented programming attempts to conceive and build entire


software systems from cooperating classes.

* A function packages an algorithm in a single operation that can be called


by name.

An object packages a set of data values-its state and a set of operations-its


methods in a single entity that can be referenced with a name.

Python Class

* Every data value in Python is an object . The types of objects are called
classes . Included in a class are the methods (or operations) that apply
to objects of that class. The set of methods of a given class of objects is
called its interface .

* The syntax of a simple class definition is the following:

* The class definition syntax has two parts: a class header and a set of
method definitions that follow the class header. The class header consists
of the class name and the parent class name.

* A class header contains the name of the class, conventionally capitalized


in Python, followed by a parenthesized list of one or more parent classes.

* The body of a class definition, nested one tab under the header, consists
of one or more method definitions, which may appear in any order.
* A method header looks very much like a function header, but a method
always has at least one parameter, in the first position, named self .

- At call time, the PVM automatically assigns to this parameter a reference


to the object on which the method is called; thus, you do not pass this
object as an explicit argument at call time.

- The parameter self is used within class and method definitions to call
other methods on the same object, or to access that object’s instance
variables or data

* Before you use some objects, you must create them. Ie, you must create
an instance of the object’s class.

The syntax for instantiating a class and assigning the resulting object to a
variable is the following:

<variable name> = <class name>(<any arguments>)

The expression on the right side of the assignment, also called a


constructor, resembles a function call.

The constructor can receive as arguments any initial values for the new
object’s attributes, or other information needed to create the object.

* All Python classes, including the built-in ones, are organized in a tree-
like class hierarchy .

- At the top, or root, of this tree is the most abstract class, named object ,
which is built in.

- Each class immediately below another class in the hierarchy is referred to


as a subclass, whereas the class immediately above it, if there is one, is
called its parent class . If the parenthesized parent class name is omitted
from the class definition, the new class is automatically made a subclass of
object .
* Illustration : The Student Class

Problem Description:
A course-management application needs to represent information about
students in a course. Each student has a name and a list of test scores. We
can use these as the attributes of a class named Student .

The Student class should allow the user to

1. View a student’s name,


2. View a test score at a given position (counting from 1),
3. Reset a test score at a given position,
4. View the highest test score,
5. View the average test score, and
6. Obtain a string representation of the student’s information.
When a Student object is created, the user supplies the student’s name and
the number of test scores. Each score is initially presumed to be 0.

Structure of Method Definitions

* All of the method definitions are indented below the class header.

* Each method definition must include a first parameter named self, even
if that method seems to expect no arguments when called.

When a method is called with an object, the interpreter binds the


parameter self to that object so that the method’s code can refer to the
object by name.

Ex: s.getScore(4)
It binds the parameter self in the method getScore to the
Student object referenced by the variable s .

The __init__ Method and Instance Variables

* Most classes include a special method named __ init __.


* __ init __ must begin and end with two consecutive underscores.

* This method is also called the class’s constructor , because it is run


automatically when a user instantiates the class.

* The purpose of the constructor is to initialize an individual object’s


attributes.

* Thus, when the code segment


s = Student("Juan", 5)
is run, Python automatically runs the constructor or __ init __
method of the Student class.

Here in this Student class, in addition to self , the Student constructor


expects two arguments that provide the initial values for these attributes
namely name and score.
Instance variables

* The attributes of an object are represented as instance variables . Each


individual object has its own set of instance variables.

* These variables serve as storage for its state. The scope of an instance
variable (including self ) is the entire class definition.

-Thus, all of the class’s methods are in a position to reference the instance
variables.

* The lifetime of an instance variable is the lifetime of the enclosing object

* Within the class definition, the names of instance variables must begin
with self.
The __str__ Method

* Many built-in Python classes usually include an __ str __ method. This


method builds and returns a string representation of an object’s state.

* When the str function is called with an object, that object’s __ str __
method is automatically invoked to obtain the string that str returns

Accessors and Mutators

* Methods that allow a user to observe but not change the state of an
object are called accessors

* Methods that allow a user to modify an object’s state are called


mutators .

- Here, the Student class has just one mutator method. It allows the user to
reset a test score at a given position. The remaining methods are accessors.

The Lifetime of Objects

* An object comes into existence, when its class is instantiated.

* An Object’s life ends, when the program that created it can no longer
refer to it.

Rules of Thumb for Defining a Simple Class

1. Before writing a line of code, think about the behavior and attributes of
the objects of the new class.

2. Choose an appropriate class name, and develop a short list of the


methods available to users.
3. Write a short script that appears to use the new class in an appropriate
way. The script should instantiate the class and run all of its methods.

4. Choose the appropriate data structures to represent the attributes of the


class.

5. Fill in the class template with a constructor (an __ init __ method) and
an __ str _ method.

6. Complete and test the remaining methods incrementally, working in a


bottom-up manner. If one method depends on another, complete the second
method first.

7. Include a docstring for the module, the class, and each method.

Problems
1. WAP to compute the area and perimeter of the circle using class

HW: WAP using Python Class to compute the area of a rectangular room
10/04/2023
Monday

Data-Modeling Examples

Objects and classes are useful for modeling objects in the real world.

Problem Scenario 1: Rational Numbers

A rational number consists of two integer parts, a numerator and a


denominator, and is written using the format numerator / denominator.
Examples are 1/2, 1/3, and so forth. Operations on rational numbers
include arithmetic and comparisons. Python has no built-in type for
rational numbers. So, develop a new class named Rational to support this
type of data.

* The interface of the Rational class includes

- a constructor for creating a rational number,


- an str function for obtaining a string representation, and
- accessors for the numerator and denominator

* Illustration of methods for usage of the new class


* Python allows the programmer to overload many of the built-in operators
foruse with new data types.
- So here we use the built-in operators + , == , and < with objects of the
new class, Rational

Step 1: Modeling the Internal representation of a rational number

* The constructor expects the numerator and denominator as arguments


and sets two instance variables to this information.

- This method then reduces the rational number to its lowest terms.

- To reduce a rational number to its lowest terms, you first compute the
greatest common divisor (GCD) of the numerator and the denominator,
using the Euclid’s algorithm

- Then divide the numerator and the denominator by this GCD

- These tasks are assigned to two other Rational methods, _reduce


and _gcd . Because these methods are not intended to be in the class’s
interface, their names begin with the _ symbol.
Step 2: Modeling Rational Number Arithmetic and Operator
Overloading

* Operator working in built-in data types

- For built-in types such as int or float , each arithmetic operator (+,-,*,
etc) corresponds to a special method name.

- The object on which the method is called corresponds to the left


operand, whereas the method’s second parameter corresponds to the right
operand.
Ie: The code x + y is actually shorthand for the code x.__add__(y) .

* Operator overloading in rational number system

- Here we add methods to perform arithmetic with rational numbers using


operator overloading.

- To overload an arithmetic operator, you just define a new method for that
operator.

- The code for each method corresponds to the arithmetic rules of the
rational number system.
* Illustration: Code for the addition operation implementation in rational
numbers

* The parameter self is viewed as the left operand of the operator, whereas
the parameter other is viewed as the right operand.

Comparison Methods

* Implementation of comparison methods with the built in integers and


floating-point types using the coperators == , ! = , < , > , <= , and >=

- When the Python interpreter encounters one of these operators, it uses a


corresponding method defined in the float or int class.
- Each of these methods expects two arguments. The first argument, self ,
represents the operand to the left of the operator, and the second argument
represents the other operand.
* Implementation of comparison operator for Rational object class

- To use the comparison operators with a new class of objects, such as


rational numbers, the class must include these methods with the
appropriate comparison logic

- The implementation of the __lt__ method (< operator) for rational


numbers is shown below:

- It compares the product of the extremes and the product of the


means. The extremes are the first numerator and the second denominator,
whereas the means are the second numerator and the first denominator.

Eg: To check 1/6 < 2/3, translate the expression to 1 * 3 < 2 * 6.

Equality and the __eq__ Method

* Python includes an implementation of this equality method for objects


like lists and dictionaries as well as the numeric types.

* Python needs an implementation of this method for the new Rational


class. The code for the method is given below:

- The implementation using is returns True only if the two operands refer
to the exact same object (object identity).

- If the two objects are distinct, the method then uses Python’s type
function to determine whether or not they are of the same type. If they are
not of the same type, they cannot be equal.
11/04/2023
Tuesday

Problem Scenario 2: Savings Accounts and Class Variables

Banking systems are easily modeled with classes. For example, a savings
account allows owners to make deposits and withdrawals. These accounts
also compute interest periodically. A simplified version of a savings
account includes an owner’s name, PIN, and balance as attributes.
A very simple bank allows a user to add new accounts, remove
accounts, get existing accounts, and compute interest on all accounts

* The interface for a SavingsAccount class is listed below:

* Class variable

- A class variable is a variable that is visible to all instances of a class and


does not vary from instance to instance.
It normally behaves like a constant, but in some situations a class
variable can be modified. When a change is made, the change takes effect
for the entire class.

- A class variable is placed between the class header and the first method
definition as an assignment statement that initializes it.

- Class variables are written in uppercase only.


Eg: RATE in the SavingsAccount class

- When you reference a class variable, you must prefix it with the class
name and a dot, as in SavingsAccount.RATE .

- Class variables are visible both inside a class definition and to exter-
nal users of the class.
-In general, you should use class variables only for symbolic constants or
to maintain data held in common by all objects of a class.

For data that are owned by individual objects, you must use instance
variables instead.

Putting the Accounts into a Bank

* Savings accounts most often make sense in the context of a bank. A very
simple bank allows a user to add new accounts, remove accounts, get
existing accounts, and compute interest on all accounts.

* A sample session that uses a Bank object and some SavingsAccount


objects is given below:
* To keep the design simple, the bank maintains the accounts in no
particular order.

Thus, you can choose a dictionary keyed by owners’ credentials to


represent the collection of accounts. Access and removal then depend on
an owner’s credentials.
HW : Problem Scenario 3: Playing Cards

Many games, such as poker, blackjack, and solitaire, use playing cards.
Modeling playing cards provides a nice illustration of the design of
cooperating classes.

A standard deck of cards has 52 cards. There are four suits: spades, hearts,
diamonds, and clubs. Each suit contains 13 cards. Each card also has a
rank, which is a number used to sort the cards and determine the count in a
hand. The literal numbers are 2 through 10. An Ace counts as the number 1
or some other number, depending on the game being played. The face
cards, Jack, Queen, and King, often count as 11, 12, and 13, respectively.
Structuring Classes with Inheritance and Polymorphism

* Object-based programming involves the use of objects, classes, and


methods to solve problems. It involves additional concepts like

1. Data encapsulation : Restricting the manipulation of an object’s state


by external users to a set of method calls.
2. Inheritance : Allowing a class to automatically reuse and extend the
code of similar but more general classes.
3. Polymorphism : Allowing several different classes to use the same
general method names.

* Python’s syntax does not enforce data encapsulation

* Inheritance and polymorphism are built into Python’s syntax

Inheritance Hierarchies and Modeling

* Objects in the natural world and objects in the world of artifacts can be
classified using inheritance hierarchies .
* At the top of a hierarchy is the most general class of objects. This class
defines features that are common to every object in the hierarchy.

* The path from a given class back up to the topmost one goes
through all of that given class’s ancestors.

* Each class below the topmost one inherits attributes and behaviors
from its ancestors and extends these with additional attributes and
behavior.

* An object-oriented software system models this pattern of inheritance


and extension in real-world systems by defining classes that extend other
classes.

- The advantage of inheritance in a software system is that each new


subclass acquires all of the instance variables and methods of its
ancestor classes for free.

- Inheritance avoids writing redundant code

* In Python, all classes automatically extend the built-in object class,


which is the most general class possible.

* It is possible to extend any existing class using the syntax

class <new class name>(<existing parent class name>):

Example 1: A Restricted Savings Account

* Suppose, banks provide customers with restricted savings accounts other


than normal accounts.

* Assume that a savings account has a name, a PIN, and a balance. You
can make deposits and withdrawals and access the account’s attributes.

* Assume, restricted savings accounts allow only a certain number of


deposits or withdrawals a month.
* Expected Interaction with Restricted savings account:

* A new method named resetCounter is called to enable withdrawals for


the next month.

* RestrictedSavingsAccount definition using inheritance

- If RestrictedSavingsAccount is defined as a subclass of SavingsAccount,


every method but withdraw can simply be inherited and used without
changes.

- The withdraw method is redefined in RestrictedSavingsAccount to return


an error message if the number of withdrawals has exceeded the
maximum.

- The maximum will be maintained in a new class variable


MAX_WITHDRAWALS , and the monthly count of withdrawals will be
tracked in a new instance variable.

- A new method, resetCounter, is included to reset the number of


withdrawals to 0

* Writing the constructor of subclass:


The rule of thumb to remember when writing the constructor for a
subclass is that each class is responsible for initializing its own instance
variables. Thus, the constructor of the parent class should always be called
to do this.

-Here, the RestrictedSavingsAccount constructor first calls the constructor


in the SavingsAccount class to initialize the instance variables for the
name, PIN, and balance defined there.

- The general form of the syntax for calling a method in the parent class
from within a method with the same name in a subclass follows:

<parent class name>.<method name>(self, <other arguments>)

- Continuing in RestrictedSavingsAccount ’s constructor, the new instance


variable counter is then set to 0.

* Extending an existing method


The withdraw method is redefined in RestrictedSavingsAccount to
override the definition of the same method in SavingsAccount .

- Here, we allow a withdrawal only when the counter’s value is less than
the maximum, and we increment the counter only after a withdrawal is
successful.

- Note that this version of the method calls the same method in the parent
or superclass to perform the actual withdrawal

* Adding a new method:


The new method resetCounter is included to allow the user to continue
withdrawals in the next month.
Polymorphic Methods

* A subclass usually adds something extra, such as a new method or a data


attribute, to the ensemble provided by its superclass

* In some cases, the two classes have the same interface, or set of methods
available to external users.

- In these cases, one or more methods in a subclass override the


definitions of the same methods in the superclass to provide specialized
versions of the abstract behavior.

- Python supports this capability with polymorphic methods . The term


polymorphic means “many bodies,” and it applies to two methods that
have the same header but have different definitions in different classes.

Eg: withdraw method in the bank account hierarchy

Exceptions

* Error in Python can be of two types i.e. Syntax errors and Exceptions.

- Syntax error is caused by the wrong syntax in the code. It leads to the
termination of the program

- Errors detected during execution are called exceptions. Exceptions are


raised when some internal events occur which changes the normal flow of
the program.
When these exceptions occur, the Python interpreter stops the
current process and passes it to the calling process until it is handled. If not
handled, the program will crash

Try and Except Statement – Catching Exceptions

*Python’s try-except statement allows an exception to be caught and the


program to recover
* Statements that can raise exceptions are kept inside the try clause and the
statements that handle the exception are written inside except clause.

* The syntax of a simple try-except statement is the following:

* When this statement is run, the statements within the try clause are
executed.

- If one of these statements raises an exception, control is immediately


transferred to the except clause.

- If the type of exception raised matches the type in this clause, its
statements are executed.

- Otherwise, control is transferred to the caller of the try-except


statement and further up the chain of calls, until the exception is
successfully handled or the program halts with an error message.

- If the statements in the try clause raise no exceptions, the except clause is
skipped, and control proceeds to the end of the try-except statement
Catching Specific Exception

* A try statement can have more than one except clause, to specify handlers for different
exceptions. At most one handler will be executed.
* A ZeroDivisionError is raised when you try to divide by 0. This is part
of the ArithmeticError Exception class.

* NameError is raised when the identifier being accessed is not defined in


the local or global scope.

You might also like