Python Training , study and exam guide
1 Introduction to Python
1.1 What is Python?
1.2 History of Python
1.3 Features of Python
1.4 Python Applications
1.5 Setting up the Python Environment
1.6 Running Your First Python Program
2 Python Basics
2.1 Python Syntax and Indentation
2.2 Variables and Data Types
2.2 1 Numbers
2.2 2 Strings
2.2 3 Lists
2.2 4 Tuples
2.2 5 Sets
2.2 6 Dictionaries
2.3 Operators
2.3 1 Arithmetic Operators
2.3 2 Comparison Operators
2.3 3 Logical Operators
2.3 4 Assignment Operators
2.3 5 Membership Operators
2.3 6 Identity Operators
2.4 Input and Output
2.4 1 Input Function
2.4 2 Output Function
2.5 Comments
2.5 1 Single-line Comments
2.5 2 Multi-line Comments
3 Control Flow
3.1 Conditional Statements
3.1 1 If Statement
3.1 2 If-Else Statement
3.1 3 Elif Statement
3.1 4 Nested If Statements
3.2 Loops
3.2 1 For Loop
3.2 2 While Loop
3.2 3 Nested Loops
3.3 Loop Control Statements
3.3 1 Break Statement
3.3 2 Continue Statement
3.3 3 Pass Statement
4 Functions
4.1 Defining Functions
4.2 Function Arguments
4.2 1 Positional Arguments
4.2 2 Keyword Arguments
4.2 3 Default Arguments
4.2 4 Variable-length Arguments
4.3 Return Statement
4.4 Lambda Functions
4.5 Scope of Variables
4.5 1 Local Variables
4.5 2 Global Variables
4.6 Recursion
5 Data Structures
5.1 Lists
5.1 1 List Operations
5.1 2 List Methods
5.1 3 List Comprehensions
5.2 Tuples
5.2 1 Tuple Operations
5.2 2 Tuple Methods
5.3 Sets
5.3 1 Set Operations
5.3 2 Set Methods
5.4 Dictionaries
5.4 1 Dictionary Operations
5.4 2 Dictionary Methods
5.5 Advanced Data Structures
5.5 1 Stacks
5.5 2 Queues
5.5 3 Linked Lists
6 Modules and Packages
6.1 Importing Modules
6.2 Creating Modules
6.3 Standard Library Modules
6.3 1 Math Module
6.3 2 Random Module
6.3 3 DateTime Module
6.4 Creating Packages
6.5 Installing External Packages
7 File Handling
7.1 Opening and Closing Files
7.2 Reading from Files
7.2 1 read()
7.2 2 readline()
7.2 3 readlines()
7.3 Writing to Files
7.3 1 write()
7.3 2 writelines()
7.4 File Modes
7.5 Working with CSV Files
7.6 Working with JSON Files
8 Exception Handling
8.1 Try and Except Blocks
8.2 Handling Multiple Exceptions
8.3 Finally Block
8.4 Raising Exceptions
8.5 Custom Exceptions
9 Object-Oriented Programming (OOP)
9.1 Classes and Objects
9.2 Attributes and Methods
9.3 Constructors and Destructors
9.4 Inheritance
9.4 1 Single Inheritance
9.4 2 Multiple Inheritance
9.4 3 Multilevel Inheritance
9.5 Polymorphism
9.6 Encapsulation
9.7 Abstraction
10 Working with Libraries
10.1 NumPy
10.1 1 Introduction to NumPy
10.1 2 Creating NumPy Arrays
10.1 3 Array Operations
10.2 Pandas
10.2 1 Introduction to Pandas
10.2 2 DataFrames and Series
10.2 3 Data Manipulation
10.3 Matplotlib
10.3 1 Introduction to Matplotlib
10.3 2 Plotting Graphs
10.3 3 Customizing Plots
10.4 Scikit-learn
10.4 1 Introduction to Scikit-learn
10.4 2 Machine Learning Basics
10.4 3 Model Training and Evaluation
11 Web Development with Python
11.1 Introduction to Web Development
11.2 Flask Framework
11.2 1 Setting Up Flask
11.2 2 Routing
11.2 3 Templates
11.2 4 Forms and Validation
11.3 Django Framework
11.3 1 Setting Up Django
11.3 2 Models and Databases
11.3 3 Views and Templates
11.3 4 Forms and Authentication
12 Final Exam Preparation
12.1 Review of Key Concepts
12.2 Practice Questions
12.3 Mock Exams
12.4 Exam Tips and Strategies
9 6 Encapsulation Explained

9 6 Encapsulation Explained

Key Concepts

Encapsulation in Python involves several key concepts:

1. Data Hiding

Data hiding is the practice of restricting access to certain attributes or methods of a class. This prevents direct modification of the internal state of an object.

Example:

class BankAccount:
    def __init__(self, balance):
        self.__balance = balance

    def deposit(self, amount):
        self.__balance += amount

    def withdraw(self, amount):
        if amount <= self.__balance:
            self.__balance -= amount
        else:
            print("Insufficient funds")

account = BankAccount(1000)
account.deposit(500)
account.withdraw(200)
    

Analogy: Think of data hiding as a vault that stores valuable items, accessible only through specific methods.

2. Access Modifiers

Access modifiers control the visibility of attributes and methods. In Python, there are no strict access modifiers like in some other languages, but conventions like using single or double underscores are used to indicate private or protected members.

Example:

class Car:
    def __init__(self, make, model):
        self.__make = make  # Private attribute
        self.__model = model  # Private attribute

    def get_make(self):
        return self.__make

    def get_model(self):
        return self.__model

car = Car("Toyota", "Camry")
print(car.get_make())  # Output: Toyota
print(car.get_model())  # Output: Camry
    

Analogy: Think of access modifiers as security levels that determine who can access certain information.

3. Getter and Setter Methods

Getter and setter methods are used to access and modify private attributes. They provide a controlled way to interact with the internal state of an object.

Example:

class Person:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def get_name(self):
        return self.__name

    def set_name(self, name):
        self.__name = name

    def get_age(self):
        return self.__age

    def set_age(self, age):
        if age > 0:
            self.__age = age
        else:
            print("Age must be a positive number")

person = Person("Alice", 30)
print(person.get_name())  # Output: Alice
person.set_age(35)
print(person.get_age())  # Output: 35
    

Analogy: Think of getter and setter methods as controlled access points to a safe, where only authorized personnel can retrieve or deposit items.

4. Practical Applications

Encapsulation is crucial for maintaining the integrity of an object's state and ensuring that it behaves predictably. It is commonly used in scenarios involving data validation, security, and maintaining invariants.

Example:

class Employee:
    def __init__(self, name, salary):
        self.__name = name
        self.__salary = salary

    def get_name(self):
        return self.__name

    def get_salary(self):
        return self.__salary

    def set_salary(self, salary):
        if salary > 0:
            self.__salary = salary
        else:
            print("Salary must be a positive number")

employee = Employee("Bob", 50000)
print(employee.get_name())  # Output: Bob
employee.set_salary(55000)
print(employee.get_salary())  # Output: 55000
    

Analogy: Think of encapsulation as a protective shield around an object, ensuring that its internal workings are safe from external interference.

Putting It All Together

By understanding and using encapsulation effectively, you can create robust and maintainable code that protects the integrity of your objects.

Example:

class Product:
    def __init__(self, name, price):
        self.__name = name
        self.__price = price

    def get_name(self):
        return self.__name

    def get_price(self):
        return self.__price

    def set_price(self, price):
        if price > 0:
            self.__price = price
        else:
            print("Price must be a positive number")

product = Product("Laptop", 1000)
print(product.get_name())  # Output: Laptop
product.set_price(1200)
print(product.get_price())  # Output: 1200