0% found this document useful (0 votes)
1 views21 pages

Python unit 5 notes

PYTHON NOTES
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)
1 views21 pages

Python unit 5 notes

PYTHON NOTES
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

UNIT-V

SOFTWARE DEVELOPMENT PRACTICES IN PYTHON

Unit Testing with unittest and pytest - Documentation with docstrings and Sphinx - Version Control
with Git - Packaging Python Projects ([Link], pip installable) - Case Study: Build and Deploy a
Mini Web App (To-do List or Expense Tracker)

Unit Testing with Unittest :


A class in Python is a user-defined template for creating [Link] we create a new class, we
define a new type of object. We can then create multiple instances of this object [Link] is an
object oriented programming language.A Class is like an object constructor, or a "blueprint" for creating
[Link] are created using class keyword. Attributes are variables defined inside the class and
represent the properties of the class. Attributes can be accessed using the dot . operator (e.g.,
MyClass.my_attribute).
Create a Class :
To create a class, use the keyword class:
# define a class
class MyClass:
x = 5 # class attribute
Output :
5

Create Object :
● An Object is an instance of a Class. It represents a specific implementation of the class
and holds its own data.
● we can use the class named MyClass to create objects.
Example :
Create an object named p1, and print the value of x:
class MyClass:
x = 5# class attribute
# Create an object from the class
p1 = MyClass()
# Access the class attribute
print(p1.x)

The __init__() Function :


● In Python, class has __init__() function. It automatically initializes object attributes when an object is
created.
● All classes have a function called __init__(), which is always executed when the class is being initiated.
● Use the __init__() function to assign values to object properties, or other operations that are necessary
to do when the object is being created.
Example
Create a class named Person, use the __init__() function to assign values for name and age:
class Person:
def __init__(self, name, age):
[Link] = name #class attribute
[Link] = age #class attribute
# Create an object from the class
p1 = Person("John", 36)
# Access the class attribute
print([Link])
print([Link])
Output :
John
36

● The __init__() function is called automatically every time the class is being used to create a new
object.

Explanation:

● p1 = Person("John", 36): Creates an object of the Person class with name as "John" and
age as 36.

● [Link]: Accesses the instance attribute name of the p1 object.

● [Link]: Accesses the class attribute age of the p1 object.

Self Parameter :
self parameter is a reference to the current instance of the class. It allows us to access the
attributes and methods of the object.

Example:

class Dog:
def __init__(self, name, age):
[Link] = name
[Link] = age

def bark(self):
print([Link],"is barking!")

# Creating an instance of Dog


dog1 = Dog("Buddy", 3)
[Link]()

Output :

Buddy is barking!
Explanation:

● Inside bark(), [Link] accesses the specific dog's name and prints it.

● When we call [Link](), Python automatically passes dog1 as self, allowing access to its
attributes.

The __str__() Function :

● The __str__() function controls what should be returned when the class object is represented as a string.
● If the __str__() function is not set, the string representation of the object is returned. By default, when
we print an object or convert it to a string using str(), Python uses the default implementation, which
returns a string like <__main__.ClassName object at 0x00000123>.

Example:

The string representation of an object WITHOUT the __str__() function:

class Person:

def __init__(self, name, age):

[Link] = name

[Link] = age

p1 = Person("John", 36)

print(p1)

Output :

<__main__.Person object at 0x783ea18c1be0>

Example:

The string representation of an object WITH the __str__() function:

class Person:
def __init__(self, name, age):
[Link] = name
[Link] = age

def __str__(self):
# The return statement sends back a string when this method is called
return f"{[Link]}({[Link]})"

p1 = Person("John", 36)
print(p1)

Output:

John(36)

● the return statement gives back the result of __Str__() which we print.

Hint return:

1. return is used inside functions or methods to send back values.

2. Without return, functions return None by default.

3. In special methods like __str__, return defines how objects behave when converted to
strings (e.g., using print).

[ Hint : The f"{...}" you see in the return statement is called an f-string (short for formatted string literal) in
Python. It is used to embed expressions inside string literals, allowing you to create dynamic strings easily.

Explanation of f"{...}":

● The letter f before the string tells Python that this is a formatted string.
● Anything inside { } is treated as a Python expression and is evaluated.

Example: return f"{[Link]}({[Link]})"

Here:

● [Link] replaces {[Link]} with the actual value ("John" in your example).

● [Link] replaces {[Link]} with the value (36 in your example).

Result:
"John(36)"

Without f-string (Old style formatting for comparison):

1. return [Link] + "(" + str([Link]) + ")"

Example :

class Person:
def __init__(self, name, age):
[Link] = name
[Link] = age
def __str__(self):
# Using string concatenation instead of f-string
return [Link] + "(" + str([Link]) + ")"

p1 = Person("John", 36)

print(p1)

Output : John (36)

2. return "{}({})".format([Link], [Link])

Example :

class Person:
def __init__(self, name, age):
[Link] = name
[Link] = age

def __str__(self):
# Using .format() instead of f-string
return "{}({})".format([Link], [Link])

p1 = Person("John", 36)

print(p1)

Output : John (36) ]

Exercise :

1. When the class object is represented as a string, there is a function that controls what should be
returned, which one?

a) __init__()
b) __str__()
c) __return__()

Answer : Option B) __str__()

Inheritance :

● Inheritance allows us to define a class that inherits all the methods and properties from another
class.
● Parent class is the class being inherited from, also called base class or superclass.
● Child class is the class that inherits from another class, also called derived class or subclass.
Inheritance Syntax:

#define a superclass

class super_class:

# attributes and method definition

# inheritance

class sub_class(super_class):

# attributes and method of super_class


# attributes and method of sub_class

Explanation of Python Inheritance Syntax

1. Parent Class:

● This is the base class or super_class from which other classes inherit.

● It contains attributes and methods that the child class can reuse.

2. Child Class:

● This is the derived class that inherits from the parent class.

● The syntax for inheritance is class ChildClass(ParentClass)or sub_class(super_class).

● The child class automatically gets all attributes and methods of the parent class unless
overridden.
Creating a Parent Class
● Any class can be a parent class, so the syntax is the same as creating any other class:

Example :

Create a class named Person, with firstname and lastname properties, and a printname
method:

class Person:
def __init__(self, fname, lname):
[Link] = fname
[Link] = lname

def printname(self):
print([Link], [Link])

#Use the Person class to create an object, and then execute the printname method:

x = Person("John", "Doe")
[Link]()
Output:
John Doe

Creating a Child Class :

A child class (also known as a subclass) is a class that inherits properties and methods from its parent class.
The child class can also introduce additional attributes and methods, or even override the ones inherited from
the parent.

Documentation with Docstrings and Sphinx Example

Generating comprehensive documentation for Python projects often involves using docstrings within the code
and then processing them with a tool like Sphinx to create formatted output (e.g., HTML).

1. Python Code with Docstrings

First, write your Python code and include docstrings for modules, classes, and functions/methods, following a
standard format like reStructuredText (used by Sphinx's autodoc extension) or NumPy/Google style.

# my_module.py

"""

A simple module demonstrating docstrings and Sphinx integration.

"""

def add_numbers(a: int, b: int) -> int:

"""

Adds two integer numbers and returns their sum.


:param a: The first integer.

:type a: int

:param b: The second integer.

:type b: int

:return: The sum of `a` and `b`.

:rtype: int

:Example:

>>> add_numbers(5, 3)

>>> add_numbers(-1, 1)

"""

return a + b

class Calculator:

"""

A simple calculator class.

"""
def __init__(self, initial_value: int = 0):

"""

Initializes the Calculator with an optional initial value.

:param initial_value: The starting value for calculations. Defaults to 0.

:type initial_value: int, optional

"""

[Link] = initial_value

def multiply(self, factor: int) -> int:

"""

Multiplies the current value by a given factor.

:param factor: The number to multiply by.

:type factor: int

:return: The new value after multiplication.

:rtype: int

"""

[Link] *= factor

return [Link]

Sphinx Setup

Install Sphinx.
Code

Initialize Sphinx.

Navigate to your project's root directory and create a docs folder. Then, run sphinx-quickstart inside
the docs folder and follow the prompts, accepting most defaults.

Code

mkdir docs
cd docs
sphinx-quickstart

Configure [Link].

Edit docs/[Link] to enable autodoc and napoleon (if using Google/NumPy style docstrings) extensions, and
set the path to your source code.

Python

# [Link] (inside docs folder)

import os
import sys
[Link](0, [Link]('..')) # Path to your project root

# ... other configurations ...

extensions = [
'[Link]',
'[Link]', # If using Google or NumPy style docstrings
'[Link]',
'[Link]',
]

# ... other configurations ...

# Set the theme (e.g., Read the Docs theme)


html_theme = 'sphinx_rtd_theme'

Generate .rst files with sphinx-apidoc.

From your project's root directory (one level above docs), run sphinx-apidoc to generate reStructuredText
files from your Python code.

sphinx-apidoc -o docs my_project_folder # Replace 'my_project_folder' with your actual code directory

Include generated .rst in [Link].

Edit docs/[Link] to include the generated module documentation.

.. toctree::

:maxdepth: 2

:caption: Contents:

Modules

Build Documentation

Finally, build the HTML documentation from within the docs folder:

Code

make html

This will create an _build/html directory containing your generated documentation, which you can then open
in a web browser.

In software development, tracking changes, managing code versions, and collaborating smoothly are
essential, and Version Control Systems (VCS) make this possible. Git is the most widely used VCS, helping
developers work efficiently on personal projects or large team-based codebases.

 Tracks every change made to your project.

 Maintains multiple versions without manual file copies.

 Enables smooth collaboration across individuals and teams.


Version Control

Before starting to discuss Git, it is important to understand the concept of version control. In simple terms,
version control is a system that tracks changes made to files over time. It allows developers to:

 Save and track changes: Every modification made to the codebase is recorded.

 Revert to previous versions: If something breaks or a feature doesn’t work as expected, you can
revert to a stable version.

 Collaborate: Multiple developers can work on the same project without overwriting each other’s
work.

 Branching and Merging: Developers can create branches for different features, work on them
independently, and merge them back to the main codebase when ready.

Introduction to Git

Git is a distributed version control system, meaning that it allows developers to work on their own local
copies of a project, while still enabling them to push changes to a shared repository. Created by Linus
Torvalds in 2005, Git has since become the standard for version control in the software development industry.

 Git manages and tracks code changes in a decentralized way.

 Every developer has a full copy of the project’s complete history.

 This design makes Git fast, scalable, and resilient to server failures.

Capabilities of Git

The following are the key features of Git:

 Version Tracking: Git follows all adjustments done in one record, letting you revert to old releases
without trouble.

 Collaboration: Different programmers can work on a similar task at the same time without clash.

 Branching: You have the option to create distinct branches for new attributes, bug repairs or tests.

 Distributed System: Every programmer has an entire version of the project implying that it is
decentralized software.
 Log of Commits: With this feature, Git maintains an account of all commit actions (changes), which
makes understanding how a project has evolved over time much easier.

Benefits of Using Git

In collaborative development, Git is a widely trusted tool that helps developers manage code changes
smoothly. Since it is a distributed system, every contributor has a full copy of the project’s history, enabling
flexible work, even offline.

The Benefits of Git and a Distributed Version Control System:

 Distributed Nature: Each developer has the complete project history, allowing independent work
without relying on a central server and enabling offline development.

 Smooth Collaboration: Branching and merging allow multiple developers to work on the same
codebase without conflicts.

 Clear Version History: Every change is stored in an organized log, making it easy to track progress
and troubleshoot issues.

 Easy Branching & Merging: Lightweight branches allow experimentation with new features before
merging them into the main code.

 High Performance: Git handles large projects efficiently with fast operations and minimal storage
overhead.

Various Approaches to Use Git for Version Control

Approach 1: Git via Command Line

This is the most common method where developers use terminal commands to interact with Git. By utilizing
git through command prompt, one has exhaustive authority over git functions.

Step 1: Install Git.

1. Download and install Git from the official website : Git Downloads.

2. After Installation, verify Git by running the following command in your terminal.

git --version

Step 2: Initialize a Git Repository


1. Navigate to your project folder in the terminal.

2. Initialize Git in the project folder by running:

git init

This creates a hidden .git folder that tracks your project.

Step 3: Staging Changes

To start tracking files, you need to stage them. This moves the files into a "staging area" before committing
them:

git add <file-name>

or to add all files:

git add .

Step 4: Committing Changes

After staging, commit your changes with a message describing what you have done:

git commit -m "Initial commit"

Step 5: Viewing Commit History

You can view the history of commits using:

git log

Step 6: Creating and working with Branches

Create a new branch for a feature or experiment:

git checkout -b <branch-name>

Switch back to the main branch:

git checkout main

Step 7: Pushing to a Remote Repository

To collaborate with others, push your changes to a remote repository like GitHub:
git remote add origin <repository-URL>
git push -u origin main

Packaging Python Projects ([Link], pip installable)

Packaging Python projects to be pip installable involves structuring your project and providing
metadata. While [Link] was traditionally used, [Link] is now the recommended standard.

1. Project Structure:

A common and recommended structure includes a top-level project directory, a src directory containing your
actual Python package, and a [Link] file at the root.

your_project_name/

├── src/

│ └── your_package_name/

│ ├── __init__.py

│ └── your_module.py

├── [Link]

└── [Link]

[Link]:

This file contains metadata about your project and its dependencies.

# [Link]

[project]

name = "your_package_name"

version = "0.1.0"

description = "A short description of your project"

authors = [
{name = "Your Name", email = "[Link]@[Link]"},

license = {file = "LICENSE"}

readme = "[Link]"

requires-python = ">=3.8"

dependencies = [

"some-dependency",

"another-dependency>=1.0",

[build-system]

requires = ["setuptools", "wheel"]

build-backend = "setuptools.build_meta"

[[Link]]

where = ["src"]

Key elements in [Link]:

 [project]: Defines project-level metadata like name, version, description, authors, license, and Python
version compatibility.

 dependencies: Lists the packages your project depends on.

 [build-system]: Specifies the build backend (e.g., setuptools) and its requirements.

 [[Link]]: (If using setuptools) Tells setuptools where to find your packages
(e.g., in the src directory).

3. Installing Your Package:

 Local Installation (for development): Navigate to your project's root directory and run:
pip install .

For editable installs (changes reflected without reinstallation):

pip install -e .

Building Distributions (for sharing/PyPI).

python -m build

This will create sdist (source distribution) and wheel (built distribution) files in a dist/ directory.

 Uploading to PyPI: Use twine to upload your built distributions.

pip install twine

twine upload dist/*

Flask is a lightweight and popular choice for small applications due to its simplicity. Django is more feature-
rich for larger projects. For this example, Flask is recommended.

Set Up Your Project:

Create a new directory for your project and Create a virtual environment.

python -m venv venv

source venv/bin/activate # On Windows: venv\Scripts\activate

Install Flask

pip install Flask

Develop the Application (Example: To-do List with Flask):

from flask_wtf import FlaskForm

from wtforms import StringField, BooleanField, SubmitField

from [Link] import DataRequired, Length


class TodoForm(FlaskForm):

title = StringField('Title', validators=[DataRequired(), Length(max=200)])

submit = SubmitField('Add')

[Link] (Main Application File).

from flask import Flask, render_template, request, redirect, url_for

app = Flask(__name__)

# Simple in-memory list for demonstration

todos = []

@[Link]('/')

def index():

return render_template('[Link]', todos=todos)

@[Link]('/add', methods=['POST'])

def add_todo():

todo_item = [Link]('todo_item')

if todo_item:

[Link](todo_item)

return redirect(url_for('index'))
@[Link]('/delete/<int:item_id>')

def delete_todo(item_id):

if 0 <= item_id < len(todos):

[Link](item_id)

return redirect(url_for('index'))

if __name__ == '__main__':

[Link](debug=True)

<!doctype html>

<html>

<head>

<meta charset="utf-8">

<title>My To-Do App</title>

<link rel="stylesheet" href="{{ url_for('static', filename='[Link]') }}">

</head>

<body>

<header><h1>To-Do List</h1></header>

<main>

{% with messages = get_flashed_messages(with_categories=true) %}

{% if messages %}

<ul class="flashes">

{% for cat, msg in messages %}


<li class="{{ cat }}">{{ msg }}</li>

{% endfor %}

</ul>

{% endif %}

{% endwith %}

{% block content %}{% endblock %}

</main>

</body>

</html>

You might also like