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

Unit-3 Python Basics_fiot

This document provides an introduction to Python programming, covering data types, control flow, functions, and modules. It explains how to define and call functions, use parameters and return values, and manage code organization through modules and packages. Key concepts include the use of built-in functions, variable scope, and the importance of modularity in programming.

Uploaded by

moonswings04
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)
6 views65 pages

Unit-3 Python Basics_fiot

This document provides an introduction to Python programming, covering data types, control flow, functions, and modules. It explains how to define and call functions, use parameters and return values, and manage code organization through modules and packages. Key concepts include the use of built-in functions, variable scope, and the importance of modularity in programming.

Uploaded by

moonswings04
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/ 65

nhoduction tD


Inroductionto’
Imglemntation
UNIT-IL

of fython
ToT

with
Introduction to

pata typesg Aumtene


Jata atucurea abing
Tple
Oitionaie,

(ontol
while
fBo
ange
’ break lonlu
Pas
igthon funtiey
’ Modles

Pakags

Aate Time.eprations
clans
-> Ijthon a
gennal pupoe high leael PgUp

preg language'
the main iar acteniaica of tathon
ython ae;
PgDr
VO Multi paradigm progreming
longag
Sam Sntor active Jonguage
Jew tay -to arn, read and Maintain,
and proadure otunted

(VD Salable
ata Tupu B Data saucts
(0 Numbr
Numbor data type 4 used. to store
Values muni
SNunbens a
Simutabe data tpeu,
mumtr data type eyule in a
ney alloratid oljct

typeca)
'int's

#Aoaing
b=25
peint
>> type Cb)
<type 'oat>

ye 2+5J

a tut o chanactuu

there are no lini to the


charaters Can hae im
charactoy
Ex:
+ Create shing

<type 'str,

Samle fooquam"

'Hello warld ! Thie is Sampk frgram'


6et the lngth of a ring
>>ylenCs)

+ conveYt opper |tower case

'HELO wORLD!'

helle world)'
# Accsing'sud ninge

'World !'

orld
ans) 'onion, 'Caot', l'potato, Vegetdes »
Combining #
'borona,
"pa 'nang' ('aple.
'orang, mango,
(t'mange) rnt >tuits.
'banana,'pear lst a to an
lt raom iler
pear'] 'mango'hanara, 'orange, ['apee,
appende'pea)
to lem an
list
ango] 'banana, 'orange, l'aple,Hhui)ts ty(pe >»>
txaunplfruyt-a
anme the mot med itam At ’
haut all
walus. cther Toqether
type,
nd
bo dattomeound
a
>>> eatabde

C'apple bmango, 'orange', 'bananas 'poar


'potato, amt, onion',beani|
# List Can be nuted

(I'apple', 'angd, lorauge, 'hanand, 'pean.


petate; tarot', 'onioo , 'bean]|
(vs Tuplesr
’ A tupk, is c Seaenedota type nita
that is Aimilar to
coub ot a mumber of valuey
tuple
amd encloed
Keporatid commcs

eith im pareintheiu,
Unlike ist, the element of tupla
Cannet be changd,
e tuples Can e

thouglt
eramply
uiti : (" pple', "orange', "hanana')

3
edement

('appe', buange')
Combining tqla
Cpotalo ,'onúcn) )

('apple 'oxang, 'hund, otato,'ornio)


5 Jctienariei
a wnpping dal typu
kind o had table that maps Rey to
Valu.
ean be

data type , mundos and atin


com, monby wed for keg
data ype
a
dictionay
oljct
COn' be

ctudent 'name': 'Mang, 'id':'ys',


*major' : 'es'?
>» type(udnt)
'dict
+length o a
>lonc sludent)
3
+Get ale of a kuy
kuy
demt ['name']
Get all itim diitionanies

lCmajor jcs) , (name,'Mavr'),cid ys))


Get oall uys
stdt keyst) dichionary
('major 'name,: 1
# Gl al vales a
S> wtudnt vaes()
key
['cs, 'many, 'us]
+ check a didionang has a key
>> Atudant . has. uylnamd')
Tue

Convesiens;r

t convnt to ting
onat to leng
>> b:2015
>>> longco)
t onvet to oat 2013L
b 2013
HoatCb)
2013·O
# Convent to lit
>>> 6= "aeiou"
S Lst (s)
Contol Flou

alaliment in
dhe
athe i atatment in

a> to 000
Pint Mor"
el:
Prit ey"

More
>>7s-'Hlo wd

int s

hybion teratey
whica
fyamples:
hellotng "Hello tootd"
'banand, 'mango'
tudut: namd': 'Ha, i'us',
thjoy';rs'
Ven charatu in a
iotbing :
poäntc
Atm n a lit

for ttem in tek:


print "fuit :.d: .s" %Ci, tanm)
ves kys in
sudenti ditionay
phint s:
wile
Jhe while statemint ii gthon tauty
ho dtaltements
Ait ithin ths wilo lovp
leng

i2
print i
dhe
Range stalement in
nmmbeys
gnerate
ari thmetie

SSSYange C1o)
3,4t15i6, j8,9]
To, t, 2
S) Yange Ct0, 10, 10)
Llo, 2o, 30, 0, 50,, 60, 0, 8o, 90, too)

5) Brak Continyç'
the oreak statemnk breakout ef the
the Certne
torlotile Lovp whwuay the t
statennt continies wttu tle
iavation.

in rang Cuj256,);
y>512:
break

32
384
tit: 'apple', 'orange','hanand,' Man
'hanand :
Centnue
else
riht itam

fipple
ovange
Mango

6) Pas stalmnt
e pas stalemnt in python i
mull oevation: when a
pas statinent is ued
’ The
vequived syntacially
Atatent s dont lwant g ommand
but ye to eecte
r code

lopple','banana']
itom baunana

pas
pint dem

banana
Functions in Python
In Python, functions are reusable blocks of code that perform a specific task.
They help you organize your code, make it more readable, and allow you to
avoid repetition. Here's a breakdown of how functions work in Python:
1. Defining a Function
You define a function using the `def` keyword, followed by the function name
and parentheses `()`. If the function takes inputs (called parameters), you list
them inside the parentheses. The code block inside the function is indented.

```python
def greet():
print("Hello, world!")
```

2. Calling a Function
To execute the function, you "call" it by writing its name followed by
parentheses.

```python
greet() # Output: Hello, world!
```

3. Parameters and Arguments


Functions can accept inputs, known as parameters, which you define in the
parentheses. When you call the function, you pass arguments to those
parameters.

```python
def greet(name):
print(f"Hello, {name}!")

greet("Alice") # Output: Hello, Alice!


greet("Bob") # Output: Hello, Bob!
```

You can also define multiple parameters:

```python
def add(a, b):
result = a + b
print(f"The sum is {result}")

add(3, 5) # Output: The sum is 8


```

4. Return Statement
Functions can return values using the `return` keyword. Once `return` is
executed, the function stops running and sends the value back to the caller.

```python
def multiply(a, b):
return a * b

result = multiply(4, 6)
print(result) # Output: 24
```
If no `return` is specified, the function returns `None` by default.

5. Default Parameters
You can give parameters default values, making them optional when calling the
function.

```python
def greet(name="stranger"):
print(f"Hello, {name}!")

greet() # Output: Hello, stranger!


greet("Emma") # Output: Hello, Emma!
```

6. Keyword Arguments
When calling a function, you can specify arguments by parameter name, which
allows you to pass them in any order.

```python
def describe_person(name, age):
print(f"{name} is {age} years old.")

describe_person(age=25, name="John") # Output: John is 25 years old.


```
7. Variable Number of Arguments
- `*args`: Allows a function to accept any number of positional arguments as a
tuple.
- ` kwargs`: Allows a function to accept any number of keyword arguments as a
dictionary.
```python
def print_args(*args):
for arg in args:
print(arg)

print_args(1, 2, 3, "four") # Output: 1, 2, 3, four

def print_kwargs( kwargs):


for key, value in kwargs.items():
print(f"{key}: {value}")

print_kwargs(name="Alice", age=30) # Output: name: Alice, age: 30


```
8. Lambda Functions
A `lambda` function is a small, anonymous function defined in a single line
using the `lambda` keyword. It’s often used for short, throwaway functions.

```python
add = lambda x, y: x + y
print(add(2, 3)) # Output: 5
```
9. Scope
Variables defined inside a function are local to that function and can’t be
accessed outside unless returned. Variables outside are global, but to modify
them inside a function, you need the `global` keyword.

```python
x = 10
def modify():
global x
x = 20

modify()
print(x) # Output: 20
```

Key Points
- Functions make code modular and reusable.
- They can take inputs, process them, and return outputs.
- Python treats functions as "first-class citizens," meaning you can pass them as
arguments, return them from other functions, or assign them to variables.
Modules in Python
In Python, “modules” are files containing Python code (functions, classes,
variables, etc.) that you can import and use in other Python programs. They
allow you to organize your code into reusable, manageable pieces, promote
modularity, and avoid cluttering a single file with too much code. Here's a
detailed explanation of modules in Python:

1. What is a Module?
A module is simply a `.py` file that contains Python definitions and statements.
For example, if you create a file called `math_utils.py` with some functions, that
file becomes a module you can import elsewhere.

```python
# math_utils.py
def add(a, b):
return a + b

def subtract(a, b):


return a - b
```

2. Importing a Module
To use the code from a module in another file, you use the `import` keyword.

```python
# main.py
import math_utils

result = math_utils.add(3, 5)
print(result) # Output: 8
```

- The `import` statement loads the entire module, and you access its contents
using the dot notation (`module_name.item`).
3. Importing Specific Items
If you only need specific functions or variables from a module, you can import
them directly using `from ... import ...`.

```python
from math_utils import add

result = add(3, 5) # No need for "math_utils." prefix


print(result) # Output: 8
```
You can also import everything from a module using `*` (though this is
generally discouraged to avoid namespace pollution):

```python
from math_utils import *

print(add(3, 5)) # Output: 8


print(subtract(10, 4)) # Output: 6
```
4. Aliasing Modules
You can give a module or its items a shorter name (alias) using `as` for
convenience.

```python
import math_utils as mu

result = mu.add(3, 5)
print(result) # Output: 8
```
5. Built-in Modules
Python comes with a rich standard library of built-in modules that you can
import without creating files yourself. Examples include:
- `math`: Mathematical functions.
- `random`: Random number generation.
- `datetime`: Date and time handling.

```python
import math

print(math.sqrt(16)) # Output: 4.0


```
6. The `__name__` Variable
Every module has a built-in variable called `__name__`. When you run a file
directly, `__name__` is set to `"__main__"`. When the file is imported as a
module, `__name__` is set to the module's name. This is useful for running code
only when the file is executed directly, not when imported.

```python
# math_utils.py
def add(a, b):
return a + b

if __name__ == "__main__":
print("This runs only if math_utils.py is executed directly.")
print(add(2, 3))
```

- If you run `python math_utils.py`, you'll see the output.


- If you import it into another file, the `if` block won’t execute.
7. Creating Your Own Modules
Any `.py` file can be a module. To use it, just place it in the same directory as
your script (or in a directory listed in Python’s module search path, `sys.path`).

For example:
- Create `my_module.py`:
```python
# my_module.py
greeting = "Hello from my_module!"

def say_hi():
print(greeting)
```

- Use it in another file:


```python
import my_module
my_module.say_hi() # Output: Hello from my_module!
```
8. Packages
A package is a collection of modules organized in a directory with a special
`__init__.py` file (which can be empty). This allows you to group related
modules together.

For example:
```
my_package/
__init__.py
module1.py
module2.py
```

You can import from the package like this:


```python
from my_package import module1
```
9. How Python Finds Modules
When you import a module, Python looks in:
1. The current directory.
2. Directories listed in the `PYTHONPATH` environment variable (if set).
3. Default directories defined in `sys.path` (includes standard library locations).

You can check or modify `sys.path` programmatically:


```python
import sys
print(sys.path) # List of paths where Python looks for modules
```
Key Benefits of Modules
-Reusability: Write code once and use it across multiple projects.
- Organization: Keep related code together and separate concerns.
- Namespace: Avoid naming conflicts by scoping variables and functions to
their module.
-Maintainability: Easier to debug and update smaller, focused files.

Example: Putting It Together


Imagine you’re building a small program:
- `calculations.py`:
```python
def multiply(a, b):
return a * b

def divide(a, b):


return a / b if b != 0 else "Error: Division by zero"
```

- `main.py`:
```python
from calculations import multiply, divide
print(multiply(4, 5)) # Output: 20
print(divide(10, 2)) # Output: 5.0
print(divide(10, 0)) # Output: Error: Division by zero
```
PACKAGES
In Python, packages are a way to organize and structure multiple related
modules into a single directory hierarchy. They allow you to group modules
together, making your code more modular, scalable, and easier to manage.
Essentially, a package is a directory that contains Python modules (`.py` files)
and a special `__init__.py` file, which tells Python that the directory should be
treated as a package.

Here’s a detailed explanation of packages in Python:

---

1. What is a Package?
A package is a folder that:
- Contains one or more `.py` files (modules).
- Includes an `__init__.py` file (can be empty), which marks the folder as a
package.
- Can contain sub-packages (subdirectories with their own `__init__.py` files).

For example:
```
my_package/
__init__.py
module1.py
module2.py
```

- `my_package` is the package.


- `module1.py` and `module2.py` are modules within the package.
2. The `__init__.py` File
The `__init__.py` file is required to make a directory a package. It can:
- Be empty (most common for simple packages).
- Contain initialization code that runs when the package is imported.
- Define what’s available when someone imports the package with `*`.

Example with an empty `__init__.py`:


```
my_package/
__init__.py # Empty file
module1.py
```
Example with initialization code:
```python
# my_package/__init__.py
print("Initializing my_package")
version = "1.0"
```
3. Importing from a Package
You can import a package, its modules, or specific items from its modules using
dot notation (`.`).

# Import the Entire Package


```python
import my_package

# Access module contents with dot notation


my_package.module1.some_function()
```
# Import a Specific Module
```python
import my_package.module1

my_package.module1.some_function()
```
# Import Specific Items
```python
from my_package.module1 import some_function

some_function() # No prefix needed


```

# Import with `*` (via `__init__.py`)


If `__init__.py` defines `__all__`, you can control what’s imported with `*`:
```python
# my_package/__init__.py
__all__ = ["module1"] # Only module1 will be imported with *

# main.py
from my_package import *
module1.some_function() # Works
module2.some_function() # Fails (not in __all__)
```

4. Example of a Package
Let’s create a simple package called `math_tools`.

Directory structure:
```
math_tools/
__init__.py
basic.py
advanced.py
```

- `basic.py`:
```python
def add(a, b):
return a + b

def subtract(a, b):


return a - b
```

- `advanced.py`:
```python
def multiply(a, b):
return a * b

def divide(a, b):


return a / b if b != 0 else "Error: Division by zero"
```
- `__init__.py` (empty for now).

Using the package:


```python
# main.py (in the parent directory of math_tools)
from math_tools.basic import add
from math_tools.advanced import multiply

print(add(3, 4)) # Output: 7


print(multiply(5, 2)) # Output: 10
```
5. Sub-Packages
Packages can contain other packages (subdirectories with their own
`__init__.py` files).

Updated structure:
```
math_tools/
__init__.py
basic/
__init__.py
operations.py
advanced/
__init__.py
operations.py
```
- `math_tools/basic/operations.py`:
```python
def add(a, b):
return a + b
```

- `math_tools/advanced/operations.py`:
```python
def multiply(a, b):
return a * b
```

Usage:
```python
from math_tools.basic.operations import add
from math_tools.advanced.operations import multiply

print(add(3, 4)) # Output: 7


print(multiply(5, 2)) # Output: 10
```
6. Why Use Packages?
- Organization : Group related modules together (e.g., all math-related tools in
`math_tools`).
- Namespace Management : Avoid naming conflicts by scoping modules
within a package.
- Scalability : Easily add more modules or sub-packages as your project
grows.
- Reusability : Share the package across projects or with others.
7. Installing Packages
Beyond creating your own, Python has a vast ecosystem of third-party packages
available via PyPI (Python Package Index). You install them using `pip`:
```bash
pip install requests
```

Then use them:


```python
import requests

response = requests.get("https://api.example.com")
print(response.status_code)
```
8. How Python Locates Packages
Python searches for packages in:
1. The current directory.
2. Directories in `sys.path` (includes standard library and site-packages for
installed third-party packages).

Check `sys.path`:
```python
import sys
print(sys.path)
```

---
9. Practical Example
Imagine a `game` package:
```
game/
__init__.py
characters.py
utils/
__init__.py
helpers.py
```

- `characters.py`:
```python
def create_player(name):
return f"Player: {name}"
```

- `utils/helpers.py`:
```python
def roll_dice():
import random
return random.randint(1, 6)
```

- `main.py`:
```python
from game.characters import create_player
from game.utils.helpers import roll_dice

player = create_player("Alice")
score = roll_dice()
print(player) # Output: Player: Alice
print(score) # Output: (random number 1-6)
```
Key Points
- A package is a directory with an `__init__.py` file and modules/sub-packages.
- Use dot notation to navigate the package structure.
- Packages make large projects manageable and reusable.
FILE HANDLING IN PYTHON
File handling in Python refers to the process of working with files—reading
from them, writing to them, appending data, or managing them in other ways.
Python provides built-in functions and methods to perform these operations
easily and efficiently. Here's a detailed explanation of file handling in Python:
1. Basics of File Handling
Files are stored on a computer's disk, and Python allows you to interact with
them using the `open()` function, which is the primary tool for file handling.
Once a file is opened, you can read its contents, write new data, or modify it,
and then close it to free up system resources.
2. The `open()` Function
The `open()` function is used to open a file and returns a file object. It takes two
main arguments:
- File path : The name or path of the file (e.g., `"example.txt"` or
`"folder/example.txt"`).
- Mode : Specifies the purpose of opening the file (e.g., reading, writing).

Syntax:
```python
file_object = open("filename", "mode")
```
Common File Modes
| Mode | Description |
| `"r"` | Read (default). Opens file for reading; error if file doesn’t exist. |
| `"w"` | Write. Creates a new file or overwrites an existing one. |
| `"a"` | Append. Adds data to the end of the file; creates file if it doesn’t exist. |
| `"r+"`| Read and write. File must exist. |
| `"b"` | Binary mode (e.g., `"rb"`, `"wb"`). Used for non-text files like images. |
3. Opening and Closing a File
Files should always be closed after use to avoid resource leaks. You can
manually close a file with `close()`, but the best practice is to use a `with`
statement, which automatically closes the file when done.

#### Manual Way


```python
file = open("example.txt", "r")
print(file.read())
file.close() # Explicitly close the file
```

#### Using `with` Statement (Recommended)


```python
with open("example.txt", "r") as file:
print(file.read())
# File is automatically closed after the block
```
4. Reading from a File
Python provides several methods to read file contents:
`read()` - Read Entire File
Reads the entire file as a single string.
```python
with open("example.txt", "r") as file:
content = file.read()
print(content)
```
`readline()` - Read One Line
Reads the file line by line.
```python
with open("example.txt", "r") as file:
line = file.readline()
print(line) # Prints the first line
```
`readlines()` - Read All Lines as a List
Returns a list where each element is a line from the file.
```python
with open("example.txt", "r") as file:
lines = file.readlines()
print(lines) # Prints a list of lines
```
Looping Over Lines
A simple way to read a file line by line:
```python
with open("example.txt", "r") as file:
for line in file:
print(line.strip()) # strip() removes trailing newlines
```
5. Writing to a File
You can write to a file using the `"w"` (overwrite) or `"a"` (append) modes.
Writing with `"w"` (Overwrites)
```python
with open("example.txt", "w") as file:
file.write("Hello, world!\n")
file.write("This is a new line.")
```
- If `example.txt` already exists, it will be overwritten.
- If it doesn’t exist, a new file will be created.

Appending with `"a"`


```python
with open("example.txt", "a") as file:
file.write("\nAdding this to the end.")
```
- Adds content to the end of the file without overwriting existing data.
Writing a List with `writelines()`
```python
lines = ["Line 1\n", "Line 2\n", "Line 3\n"]
with open("example.txt", "w") as file:
file.writelines(lines)
```
6. Working with Binary Files
For non-text files (e.g., images, audio), use binary mode (`"rb"`, `"wb"`, etc.).
```python
# Copy an image file
with open("image.jpg", "rb") as source:
with open("image_copy.jpg", "wb") as target:
target.write(source.read())
```
7. File Position and Seeking
When reading or writing, Python keeps track of the current position in the file.
You can move this position using `seek()` and check it with `tell()`.
```python
with open("example.txt", "r") as file:
print(file.read(5)) # Reads first 5 characters
print(file.tell()) # Current position (5)
file.seek(0) # Move back to start
print(file.read()) # Read entire file again
```
8. Checking if a File Exists
You can use the `os` module to check if a file exists before performing
operations.
```python
import os

if os.path.exists("example.txt"):
print("File exists!")
else:
print("File not found.")
```
9. Deleting or Renaming Files
The `os` module also provides file management functions:
- Delete a file:
```python
import os
os.remove("example.txt")
```

- Rename a file:
```python
import os
os.rename("old_name.txt", "new_name.txt")
```
10. Example: Putting It Together
Here’s a practical example combining reading and writing:
```python
# Write some data
with open("data.txt", "w") as file:
file.write("Name: Alice\nAge: 25\n")
# Append more data
with open("data.txt", "a") as file:
file.write("Name: Bob\nAge: 30\n")

# Read and print the file


with open("data.txt", "r") as file:
for line in file:
print(line.strip())
```
Output:
```
Name: Alice
Age: 25
Name: Bob
Age: 30
```
Key Points
- Use `open()` with the appropriate mode (`"r"`, `"w"`, `"a"`, etc.).
- The `with` statement is the safest way to handle files (auto-closes).
- Use text mode for text files and binary mode for images, videos, etc.
- Always handle exceptions (e.g., `FileNotFoundError`) in production code for
robustness.

#### Exception Handling Example


```python
try:
with open("non_existent.txt", "r") as file:
print(file.read())
except FileNotFoundError:
print("File not found!")
```
DATE & TIME OPERATIONS
In Python, date and time operations are primarily handled using the built-in
`datetime` module, which provides classes and methods to work with dates,
times, and time intervals. This module is versatile and allows you to perform tasks
like getting the current date/time, formatting dates, performing arithmetic with
dates, and handling time zones (with additional modules like `pytz`). Here's a
detailed explanation of date and time operations in Python:
1. The `datetime` Module
The `datetime` module includes several key classes:
- `datetime.date`: Represents a date (year, month, day).
- `datetime.time`: Represents a time (hour, minute, second, microsecond).
- `datetime.datetime`: Combines date and time.
- `datetime.timedelta`: Represents a duration or difference between two
dates/times.
To use it, import the module:
```python
import datetime
```
2. Getting the Current Date and Time
#### Current Date and Time (`datetime.datetime.now()`)
```python
from datetime import datetime
now = datetime.now()
print(now) # Output: 2025-03-25 12:34:56.789012 (example)
```
#### Current Date Only (`datetime.date.today()`)
```python
from datetime import date
today = date.today()
print(today) # Output: 2025-03-25
```

#### Current Time Only


```python
from datetime import datetime

current_time = datetime.now().time()
print(current_time) # Output: 12:34:56.789012
```
3. Creating Date and Time Objects
You can manually create date, time, or datetime objects by specifying values.
#### Date Object
```python
from datetime import date

my_date = date(2023, 12, 15) # Year, Month, Day


print(my_date) # Output: 2023-12-15
```

#### Time Object


```python
from datetime import time

my_time = time(14, 30, 45) # Hour, Minute, Second


print(my_time) # Output: 14:30:45
```

#### Datetime Object


```python
from datetime import datetime

my_datetime = datetime(2023, 12, 15, 14, 30, 45)


print(my_datetime) # Output: 2023-12-15 14:30:45
```
4. Formatting Dates and Times
The `strftime()` method converts a datetime object into a formatted string.
#### Common Format Codes
| Code | Meaning | Example |
|------|---------------------|---------------|
| `%Y` | Year (4 digits) | 2025 |
| `%m` | Month (01-12) | 03 |
| `%d` | Day (01-31) | 25 |
| `%H` | Hour (00-23) | 14 |
| `%M` | Minute (00-59) | 30 |
| `%S` | Second (00-59) | 45 |
| `%A` | Weekday name | Tuesday |
| `%B` | Month name | March |

Example:
```python
from datetime import datetime
now = datetime.now()
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
print(formatted) # Output: 2025-03-25 12:34:56

print(now.strftime("%A, %B %d, %Y")) # Output: Tuesday, March 25, 2025


```
5. Parsing Strings to Datetime
The `strptime()` method converts a string into a datetime object, given a specific
format.
```python
from datetime import datetime

date_string = "2023-12-15 14:30:45"


dt = datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S")
print(dt) # Output: 2023-12-15 14:30:45
```
6. Date and Time Arithmetic with `timedelta`
The `timedelta` class is used to add or subtract time intervals.

#### Adding Days


```python
from datetime import datetime, timedelta

now = datetime.now()
future_date = now + timedelta(days=10)
print(future_date) # Adds 10 days to current date/time
```
#### Subtracting Time
```python
past_date = now - timedelta(hours=5, minutes=30)
print(past_date) # Subtracts 5 hours and 30 minutes
```

#### Difference Between Dates


```python
date1 = datetime(2023, 1, 1)
date2 = datetime(2023, 12, 31)
difference = date2 - date1
print(difference) # Output: 364 days, 0:00:00
print(difference.days) # Output: 364
```
7. Accessing Components
You can extract specific parts of a `datetime` object:
```python
from datetime import datetime

now = datetime.now()
print(now.year) # Output: 2025
print(now.month) # Output: 3
print(now.day) # Output: 25
print(now.hour) # Output: 12
print(now.minute) # Output: 34
print(now.second) # Output: 56
```
8. Working with Time Zones
The `datetime` module has basic timezone support with `timezone`, but for
more robust handling, use the third-party `pytz` library.
#### Using `timezone` (Built-in)
```python
from datetime import datetime, timezone

# UTC time
utc_now = datetime.now(timezone.utc)
print(utc_now) # Output: 2025-03-25 10:34:56.789012+00:00
```

#### Using `pytz` (Install with `pip install pytz`)


```python
from datetime import datetime
import pytz

# Get timezone
tz = pytz.timezone("America/New_York")
ny_time = datetime.now(tz)
print(ny_time) # Output: 2025-03-25 06:34:56.789012-04:00 (example)

# Convert between timezones


utc_time = ny_time.astimezone(pytz.utc)
print(utc_time) # Output: 2025-03-25 10:34:56.789012+00:00
```
9. Comparing Dates and Times
You can compare `datetime` objects using standard comparison operators (`<`,
`>`, `==`, etc.).
```python
from datetime import datetime

dt1 = datetime(2023, 1, 1)
dt2 = datetime(2023, 12, 31)

print(dt1 < dt2) # Output: True


print(dt1 == dt2) # Output: False
```
10. Practical Example
Here’s a script combining several operations:
```python
from datetime import datetime, timedelta

# Current date and time


now = datetime.now()
print(f"Now: {now.strftime('%Y-%m-%d %H:%M:%S')}")

# Add 7 days
future = now + timedelta(days=7)
print(f"7 days from now: {future.strftime('%Y-%m-%d %H:%M:%S')}")

# Parse a date string


event = datetime.strptime("2025-04-01 09:00:00", "%Y-%m-%d %H:%M:%S")
print(f"Event date: {event}")
# Time until event
time_left = event - now
print(f"Days until event: {time_left.days}")
```

Output (example):
```
Now: 2025-03-25 12:34:56
7 days from now: 2025-04-01 12:34:56
Event date: 2025-04-01 09:00:00
Days until event: 6
```
Key Points
- Use `datetime` for most date/time tasks.
- `strftime()` formats dates as strings; `strptime()` parses strings into dates.
- `timedelta` handles arithmetic with time intervals.
- For time zones, `pytz` is highly recommended.
- Always consider edge cases (e.g., leap years, daylight saving time) in
production code.
CLASSES IN PYTHON
In Python, classes are a fundamental part of object-oriented programming
(OOP). They allow you to define a blueprint for creating objects, which are
instances of the class. Classes encapsulate data (attributes) and behavior
(methods) into a single unit, promoting code reusability, modularity, and
organization. Here's a detailed explanation of classes in Python:
1. What is a Class?
A class is a template or blueprint that defines the properties (attributes) and
actions (methods) that objects created from the class will have. Think of a class
as a "cookie cutter" and objects as the "cookies" made from it.
2. Defining a Class
You define a class using the `class` keyword followed by the class name
(typically capitalized by convention). The body of the class contains attributes
and methods.
#### Basic Syntax
```python
class ClassName:
# Class body
pass
```

#### Simple Example


```python
class Dog:
def bark(self):
print("Woof!")
```
3. Creating Objects (Instances)
Once a class is defined, you can create objects (instances) of that class by
calling the class name like a function.
```python
class Dog:
def bark(self):
print("Woof!")

# Create objects
dog1 = Dog()
dog2 = Dog()

# Call method
dog1.bark() # Output: Woof!
dog2.bark() # Output: Woof!
```
4. The `self` Parameter
In Python, every method in a class must include `self` as its first parameter.
`self` refers to the instance calling the method, allowing access to its attributes
and other methods.

```python
class Dog:
def bark(self):
print("Woof!")

def wag_tail(self):
print("Tail wagging...")

dog = Dog()
dog.bark() # Output: Woof!
dog.wag_tail() # Output: Tail wagging...
```
5. Adding Attributes
Attributes are variables that belong to an object. They are typically initialized in
a special method called `__init__`, which is the constructor.

#### Using `__init__`


```python
class Dog:
def __init__(self, name, age):
self.name = name # Instance attribute
self.age = age # Instance attribute

def bark(self):
print(f"{self.name} says Woof!")

# Create objects with attributes


dog1 = Dog("Buddy", 3)
dog2 = Dog("Max", 5)

print(dog1.name) # Output: Buddy


print(dog2.age) # Output: 5
dog1.bark() # Output: Buddy says Woof!
```

- `__init__` is automatically called when a new object is created.


- `self.name` and `self.age` are instance attributes unique to each object.
6. Class Attributes vs. Instance Attributes
- Class Attributes : Shared across all instances of the class.
- Instance Attributes : Unique to each object.

```python
class Dog:
species = "Canis familiaris" # Class attribute

def __init__(self, name):


self.name = name # Instance attribute

def describe(self):
print(f"{self.name} is a {self.species}")

dog1 = Dog("Buddy")
dog2 = Dog("Max")

dog1.describe() # Output: Buddy is a Canis familiaris


dog2.describe() # Output: Max is a Canis familiaris
print(Dog.species) # Output: Canis familiaris
```
7. Methods
Methods are functions defined inside a class that operate on its objects.
#### Instance Methods
Use `self` to access instance attributes/methods.
```python
class Dog:
def __init__(self, name):
self.name = name

def bark(self):
print(f"{self.name} barks!")

def rename(self, new_name):


self.name = new_name

dog = Dog("Buddy")
dog.bark() # Output: Buddy barks!
dog.rename("Rex")
dog.bark() # Output: Rex barks!
```

#### Class Methods


Use the `@classmethod` decorator and `cls` instead of `self` to work with class
attributes.
```python
class Dog:
species = "Canis familiaris"

@classmethod
def get_species(cls):
return cls.species

print(Dog.get_species()) # Output: Canis familiaris


```
#### Static Methods
Use the `@staticmethod` decorator; they don’t take `self` or `cls` and behave
like regular functions but belong to the class.
```python
class Dog:
@staticmethod
def bark_sound():
return "Woof!"

print(Dog.bark_sound()) # Output: Woof!


```
8. Inheritance
Classes can inherit from other classes, allowing you to reuse and extend
functionality.

#### Example
```python
class Animal:
def __init__(self, name):
self.name = name

def speak(self):
print("Generic animal sound")

class Dog(Animal): # Dog inherits from Animal


def speak(self): # Override the parent method
print(f"{self.name} says Woof!")
dog = Dog("Buddy")
dog.speak() # Output: Buddy says Woof!
```

#### Calling Parent Methods


Use `super()` to access the parent class:
```python
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # Call parent's __init__
self.breed = breed

def speak(self):
print(f"{self.name} the {self.breed} says Woof!")

dog = Dog("Buddy", "Golden Retriever")


dog.speak() # Output: Buddy the Golden Retriever says Woof!
```
9. Encapsulation
Encapsulation hides internal details and exposes only what’s necessary. Python
uses naming conventions for this:
- `_attribute`: Protected (convention, not enforced).
- `__attribute`: Private (name mangling).

```python
class Dog:
def __init__(self, name):
self.__secret = "I’m a good boy" # Private attribute
self.name = name

def reveal_secret(self):
print(self.__secret)

dog = Dog("Buddy")
dog.reveal_secret() # Output: I’m a good boy
# print(dog.__secret) # Raises AttributeError
```
10. Properties (Getters and Setters)
The `@property` decorator allows controlled access to attributes.

```python
class Dog:
def __init__(self, name):
self._name = name

@property
def name(self):
return self._name

@name.setter
def name(self, value):
if isinstance(value, str):
self._name = value
else:
raise ValueError("Name must be a string")

dog = Dog("Buddy")
print(dog.name) # Output: Buddy
dog.name = "Max"
print(dog.name) # Output: Max
# dog.name = 123 # Raises ValueError
```
11. Practical Example
Here’s a complete example:
```python
class Car:
total_cars = 0 # Class attribute

def __init__(self, make, model):


self.make = make
self.model = model
self._mileage = 0
Car.total_cars += 1

def drive(self, miles):


self._mileage += miles
print(f"Drove {miles} miles. Total mileage: {self._mileage}")

@classmethod
def get_total_cars(cls):
return cls.total_cars
# Create instances
car1 = Car("Toyota", "Camry")
car2 = Car("Honda", "Civic")

car1.drive(50) # Output: Drove 50 miles. Total mileage: 50


print(Car.get_total_cars()) # Output: 2
```
Key Points
- Classes define blueprints for objects.
- Use `self` for instance-specific data/methods.
- Inheritance allows code reuse; encapsulation protects data.
- Class/static methods and properties add flexibility.
Python Packages of Interest in IOT
1. `json`
- Purpose : Provides tools to encode (serialize) and decode (deserialize) data
in JSON (JavaScript Object Notation) format, a lightweight and widely-used
data interchange format.
- Use Case : In IoT, JSON is often used to structure sensor data for
transmission to servers or cloud platforms (e.g., via MQTT or HTTP). It’s
human-readable and machine-parseable.
- Key Functions :
- `json.dumps()`: Converts a Python object (e.g., dict) to a JSON string.
- `json.loads()`: Parses a JSON string into a Python object.
- `json.dump()`: Writes a Python object as JSON to a file.
- `json.load()`: Reads JSON from a file into a Python object.
- Example :
```python
import json

# IoT sensor data


sensor_data = {"temperature": 25.5, "humidity": 60}
json_string = json.dumps(sensor_data) # Serialize to JSON
print(json_string) # Output: {"temperature": 25.5, "humidity": 60}

# Parse back
parsed_data = json.loads(json_string)
print(parsed_data["temperature"]) # Output: 25.5
```
- IoT Relevance : JSON is a standard format for sending structured data from
IoT devices to APIs or databases (e.g., AWS IoT, ThingSpeak).
2. `xml` (xml.etree.ElementTree)
- Purpose : Part of the `xml` package, `xml.etree.ElementTree` is a
lightweight module for parsing and creating XML (Extensible Markup
Language) data, a more verbose alternative to JSON.
- Use Case : Less common in IoT than JSON due to its verbosity, but useful
when interfacing with legacy systems or protocols (e.g., SOAP-based services)
that require XML.
- Key Features :
- Parse XML documents into a tree structure.
- Create or modify XML programmatically.
- Example :
```python
import xml.etree.ElementTree as ET

# XML data (e.g., from an IoT device config)


xml_data =
'''<device><name>Sensor1</name><value>23.5</value></device>'''
tree = ET.fromstring(xml_data)
print(tree.find("name").text) # Output: Sensor1
print(tree.find("value").text) # Output: 23.5

# Create XML
root = ET.Element("device")
ET.SubElement(root, "name").text = "Sensor2"
print(ET.tostring(root, encoding="unicode"))
```
- IoT Relevance : Useful for IoT systems integrating with enterprise software
or older protocols, though JSON is more common in modern setups.
3. `http.client` (formerly `httplib`)
- Purpose : A low-level module for making HTTP requests and handling
responses. It’s part of Python’s standard library and provides fine-grained
control over HTTP communication.
- Use Case : In IoT, it can be used to send data from devices to web servers or
APIs directly, though higher-level libraries like `requests` are often preferred
for simplicity.
- Key Features :
- Supports GET, POST, and other HTTP methods.
- Handles headers, status codes, and response data.
- Example :
```python
import http.client

conn = http.client.HTTPSConnection("api.example.com")
conn.request("GET", "/data")
response = conn.getresponse()
print(response.status) # Output: 200 (if successful)
print(response.read().decode()) # Output: Response body
conn.close()
```
- IoT Relevance : Useful for lightweight IoT devices needing to communicate
with RESTful APIs without extra dependencies (e.g., on MicroPython), though
it’s less intuitive than `requests`.
4. `urllib` (urllib.request, urllib.parse, etc.)
- Purpose : A collection of modules for working with URLs, including
fetching data (`urllib.request`), parsing URLs (`urllib.parse`), and handling URL
encoding. It’s a higher-level alternative to `http.client`.
- Use Case : In IoT, it’s handy for fetching data from web services (e.g.,
weather APIs) or posting sensor data to a server.
- Key Components :
- `urllib.request`: For opening and reading URLs.
- `urllib.parse`: For breaking down or constructing URLs.
- Example :
```python
import urllib.request

# Fetch data from a web server


with urllib.request.urlopen("http://api.example.com/data") as response:
data = response.read().decode()
print(data)

# POST request with data


import urllib.parse
data = urllib.parse.urlencode({"temp": 25}).encode()
req = urllib.request.Request("http://example.com", data=data,
method="POST")
with urllib.request.urlopen(req) as response:
print(response.read().decode())
```
- IoT Relevance : Useful for IoT devices to interact with web-based services
or APIs, especially in environments where `requests` isn’t available (e.g.,
MicroPython).
5. `SMTPLIB`
- Purpose : Implements the Simple Mail Transfer Protocol (SMTP) for
sending emails from Python. It’s part of the standard library.
- Use Case : In IoT, it can send alerts or notifications (e.g., "Temperature
exceeded threshold!") from a device to a user’s email.
- Key Features :
- Connects to SMTP servers (e.g., Gmail, Outlook).
- Supports plain text and HTML emails with authentication.
- Example :
```python
import smtplib
from email.mime.text import MIMEText

# Email details
sender = "[email protected]"
receiver = "[email protected]"
msg = MIMEText("Temperature alert: 35°C!")
msg["Subject"] = "IoT Alert"
msg["From"] = sender
msg["To"] = receiver

# Connect to SMTP server (e.g., Gmail)


with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls() # Enable TLS
server.login(sender, "your_app_password") # Use app-specific password
server.send_message(msg)
print("Email sent!")
```
- IoT Relevance : Critical for IoT systems requiring notifications (e.g., smart
home alerts, industrial monitoring), though it needs an SMTP server and
credentials.
How These Fit into IoT
- `json` : Structures sensor data for transmission (e.g., over MQTT or HTTP)
or storage in databases.
- `xml` : Less common, but useful for IoT systems interfacing with legacy
XML-based protocols.
- `http.client` & `urllib` : Enable IoT devices to communicate with web
servers or APIs (e.g., sending data to a cloud dashboard like ThingSpeak).
- `smtplib` : Adds notification capabilities, enhancing IoT systems with real-
time user alerts.
Comparison to Third-Party Alternatives
- `json` vs. Third-Party : Rarely replaced, as it’s lightweight and sufficient.
- `xml` vs. `lxml` : `lxml` is faster and more feature-rich for complex XML
tasks.
- `http.client`/`urllib` vs. `requests` : `requests` is more user-friendly and
widely adopted, but the standard modules are dependency-free.
- `smtplib` vs. `yagmail` : `yagmail` simplifies email sending but requires
installation.
Practical IoT Example
Combining these for an IoT temperature monitor:
```python
import json
import urllib.request
import smtplib
from email.mime.text import MIMEText

# Simulated sensor data


temp_data = {"device": "Sensor1", "temperature": 35}
json_data = json.dumps(temp_data)

# Send to a server
req = urllib.request.Request("http://example.com/api", data=json_data.encode(),
headers={"Content-Type": "application/json"})
with urllib.request.urlopen(req) as response:
print(response.read().decode())

# Send email alert if temperature is high


if temp_data["temperature"] > 30:
msg = MIMEText(f"High temperature detected:
{temp_data['temperature']}°C")
msg["Subject"] = "Temperature Alert"
msg["From"] = "[email protected]"
msg["To"] = "[email protected]"
with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls()
server.login("[email protected]", "app_password")
server.send_message(msg)
print("Alert sent!")
```
These standard library modules are powerful for IoT and general programming,
requiring no external dependencies, which is a plus for resource-constrained
devices.

You might also like