Compare commits
3 Commits
0e0eb64ce0
...
b251ae7e2e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b251ae7e2e | ||
|
|
e2711d6591 | ||
|
|
1b5d863dfa |
219
Docs/Basic/07-error-handeling.md
Normal file
219
Docs/Basic/07-error-handeling.md
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
# 06 – Error Handling, Linting, Formatting, and Testing in Python
|
||||||
|
|
||||||
|
This document explains how Python handles runtime errors, how to write safer code using `try / except`, and how to improve code quality using **linting**, **formatting**, and **unit testing** tools.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Error Handling with `try / except`
|
||||||
|
|
||||||
|
Python uses `try / except` blocks to handle runtime errors gracefully without crashing the program.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```python
|
||||||
|
def abbas(a, b):
|
||||||
|
try:
|
||||||
|
res = a / b
|
||||||
|
print(res)
|
||||||
|
except ZeroDivisionError:
|
||||||
|
print("Zero Number Detected")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error Detected {e}")
|
||||||
|
|
||||||
|
abbas(1, 0)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Explanation
|
||||||
|
|
||||||
|
* The code inside `try` is executed first.
|
||||||
|
* If no error occurs, the result is printed.
|
||||||
|
* If `b` is `0`, a `ZeroDivisionError` is raised.
|
||||||
|
* The specific `ZeroDivisionError` block runs first.
|
||||||
|
* Any other error is caught by the generic `Exception` block.
|
||||||
|
|
||||||
|
### Key Rule
|
||||||
|
|
||||||
|
* Always catch **specific exceptions first**.
|
||||||
|
* Use `Exception` only as a fallback.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Full `try / except` Structure
|
||||||
|
|
||||||
|
Python supports additional blocks for more control.
|
||||||
|
|
||||||
|
### Syntax
|
||||||
|
|
||||||
|
```python
|
||||||
|
try:
|
||||||
|
# code that may raise an error
|
||||||
|
except:
|
||||||
|
# runs if an error occurs
|
||||||
|
else:
|
||||||
|
# runs if no error occurs
|
||||||
|
finally:
|
||||||
|
# always runs
|
||||||
|
```
|
||||||
|
|
||||||
|
### Explanation
|
||||||
|
|
||||||
|
* `try`: code that may fail
|
||||||
|
* `except`: handles errors
|
||||||
|
* `else`: runs only if no exception occurred
|
||||||
|
* `finally`: runs no matter what (used for cleanup)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Linting with `pylint`
|
||||||
|
|
||||||
|
Linting analyzes code for:
|
||||||
|
|
||||||
|
* Syntax errors
|
||||||
|
* Style problems
|
||||||
|
* Bad practices
|
||||||
|
|
||||||
|
### Basic Command
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pylint main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### Detailed Report
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pylint --report y main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### Explanation
|
||||||
|
|
||||||
|
* `pylint` gives a score and suggestions.
|
||||||
|
* Helps maintain readable and maintainable code.
|
||||||
|
* Commonly used in professional Python projects.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Code Formatting with `black`
|
||||||
|
|
||||||
|
`black` is an automatic code formatter that enforces a consistent style.
|
||||||
|
|
||||||
|
### Command
|
||||||
|
|
||||||
|
```bash
|
||||||
|
black main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### Explanation
|
||||||
|
|
||||||
|
* Reformats code automatically.
|
||||||
|
* Removes style debates.
|
||||||
|
* Safe and widely used.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Unit Testing with `unittest`
|
||||||
|
|
||||||
|
Unit tests verify that individual parts of code behave as expected.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Application Code
|
||||||
|
|
||||||
|
#### `abbas.py`
|
||||||
|
|
||||||
|
```python
|
||||||
|
def bemola(a, b):
|
||||||
|
try:
|
||||||
|
res = a / b
|
||||||
|
print(res)
|
||||||
|
except ZeroDivisionError:
|
||||||
|
print("Zero Number Detected")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error Detected {e}")
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Test Code
|
||||||
|
|
||||||
|
#### `abbas_test.py`
|
||||||
|
|
||||||
|
```python
|
||||||
|
import unittest
|
||||||
|
from abbas import bemola
|
||||||
|
|
||||||
|
class TestAbbas(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_bemola(self):
|
||||||
|
a = 10
|
||||||
|
b = 2
|
||||||
|
self.assertEqual(bemola(a, b), 5)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Explanation
|
||||||
|
|
||||||
|
#### `unittest.TestCase`
|
||||||
|
|
||||||
|
* Base class for writing test cases.
|
||||||
|
|
||||||
|
#### Test Method
|
||||||
|
|
||||||
|
```python
|
||||||
|
def test_bemola(self):
|
||||||
|
```
|
||||||
|
|
||||||
|
* Test methods must start with `test_`.
|
||||||
|
|
||||||
|
#### Assertion
|
||||||
|
|
||||||
|
```python
|
||||||
|
self.assertEqual(bemola(a, b), 5)
|
||||||
|
```
|
||||||
|
|
||||||
|
* Checks if the function returns the expected result.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Important Note (Design Issue)
|
||||||
|
|
||||||
|
The function `bemola` **prints** the result but does not return it.
|
||||||
|
|
||||||
|
```python
|
||||||
|
print(res)
|
||||||
|
```
|
||||||
|
|
||||||
|
This causes the test to fail because the function returns `None`.
|
||||||
|
|
||||||
|
#### Correct Implementation
|
||||||
|
|
||||||
|
```python
|
||||||
|
def bemola(a, b):
|
||||||
|
try:
|
||||||
|
return a / b
|
||||||
|
except ZeroDivisionError:
|
||||||
|
return "Zero Number Detected"
|
||||||
|
except Exception as e:
|
||||||
|
return f"Error Detected {e}"
|
||||||
|
```
|
||||||
|
|
||||||
|
This version:
|
||||||
|
|
||||||
|
* Returns values instead of printing
|
||||||
|
* Is testable
|
||||||
|
* Follows best practices
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* `try / except` prevents program crashes
|
||||||
|
* `else` runs only when no error occurs
|
||||||
|
* `finally` always runs
|
||||||
|
* `pylint` improves code quality
|
||||||
|
* `black` enforces formatting
|
||||||
|
* `unittest` verifies correctness
|
||||||
|
* Functions should **return values**, not print them, when tested
|
||||||
182
Docs/Basic/08-decorators.md
Normal file
182
Docs/Basic/08-decorators.md
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
# 08 – Decorators in Python
|
||||||
|
|
||||||
|
This document explains **decorators**, how they work, and how they are used to extend function behavior without modifying the original function code.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. What Is a Decorator?
|
||||||
|
|
||||||
|
A **decorator** is a function that:
|
||||||
|
|
||||||
|
* Takes another function as input
|
||||||
|
* Adds extra behavior
|
||||||
|
* Returns a new function
|
||||||
|
|
||||||
|
Decorators are commonly used for:
|
||||||
|
|
||||||
|
* Input validation
|
||||||
|
* Logging
|
||||||
|
* Authentication
|
||||||
|
* Performance measurement
|
||||||
|
* Access control
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Basic Decorator Structure
|
||||||
|
|
||||||
|
A decorator has three layers:
|
||||||
|
|
||||||
|
1. The decorator function
|
||||||
|
2. The wrapper function
|
||||||
|
3. The original function
|
||||||
|
|
||||||
|
### General Pattern
|
||||||
|
|
||||||
|
```python
|
||||||
|
def decorator(func):
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
# extra behavior
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Example: Input Validation Decorator
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
```python
|
||||||
|
def check_number(func):
|
||||||
|
def wrapper(a, b):
|
||||||
|
if not (isinstance(a, (int, float)) and isinstance(b, (int, float))):
|
||||||
|
print("Input must be numbers")
|
||||||
|
return
|
||||||
|
return func(a, b)
|
||||||
|
return wrapper
|
||||||
|
```
|
||||||
|
|
||||||
|
### Explanation
|
||||||
|
|
||||||
|
* `check_number` is the decorator.
|
||||||
|
* `func` is the function being decorated.
|
||||||
|
* `wrapper` replaces the original function.
|
||||||
|
* `a` and `b` are the arguments passed to the original function.
|
||||||
|
* `isinstance(a, (int, float))` ensures inputs are numeric.
|
||||||
|
* If validation fails, execution stops.
|
||||||
|
* If validation passes, the original function is called.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Using the Decorator with `@` Syntax
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
```python
|
||||||
|
@check_number
|
||||||
|
def bemola(a, b):
|
||||||
|
try:
|
||||||
|
res = a / b
|
||||||
|
print(res)
|
||||||
|
except ZeroDivisionError:
|
||||||
|
print("Zero Number Detected")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error Detected {e}")
|
||||||
|
```
|
||||||
|
|
||||||
|
### What Happens Internally
|
||||||
|
|
||||||
|
This line:
|
||||||
|
|
||||||
|
```python
|
||||||
|
@check_number
|
||||||
|
```
|
||||||
|
|
||||||
|
Is equivalent to:
|
||||||
|
|
||||||
|
```python
|
||||||
|
bemola = check_number(bemola)
|
||||||
|
```
|
||||||
|
|
||||||
|
The function `bemola` is replaced by `wrapper`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Execution Flow
|
||||||
|
|
||||||
|
When calling:
|
||||||
|
|
||||||
|
```python
|
||||||
|
bemola(10, 2)
|
||||||
|
```
|
||||||
|
|
||||||
|
The flow is:
|
||||||
|
|
||||||
|
1. `wrapper(10, 2)` is called
|
||||||
|
2. Inputs are validated
|
||||||
|
3. `func(10, 2)` is executed
|
||||||
|
4. Result is printed
|
||||||
|
|
||||||
|
If calling:
|
||||||
|
|
||||||
|
```python
|
||||||
|
bemola(10, "a")
|
||||||
|
```
|
||||||
|
|
||||||
|
The output will be:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Input must be numbers
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Why Use Decorators?
|
||||||
|
|
||||||
|
Without decorators, input validation would need to be repeated in every function.
|
||||||
|
|
||||||
|
Decorators allow:
|
||||||
|
|
||||||
|
* Reusable logic
|
||||||
|
* Cleaner code
|
||||||
|
* Separation of concerns
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Limitations in This Example
|
||||||
|
|
||||||
|
* The decorator only works with exactly two arguments.
|
||||||
|
* It does not preserve the original function’s metadata (`__name__`, `__doc__`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Improved Version (Best Practice)
|
||||||
|
|
||||||
|
```python
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
def check_number(func):
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
if not all(isinstance(x, (int, float)) for x in args):
|
||||||
|
print("Input must be numbers")
|
||||||
|
return
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
```
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
* Supports any number of arguments
|
||||||
|
* Preserves function name and documentation
|
||||||
|
* More reusable and professional
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* Decorators modify function behavior without changing its code
|
||||||
|
* They wrap functions inside another function
|
||||||
|
* `@decorator` is syntactic sugar
|
||||||
|
* Commonly used for validation, logging, and access control
|
||||||
|
* Best practice is to use `*args`, `**kwargs`, and `functools.wraps`
|
||||||
266
Docs/Basic/09-standard-libs.md
Normal file
266
Docs/Basic/09-standard-libs.md
Normal file
@@ -0,0 +1,266 @@
|
|||||||
|
# 09 – Python Standard Library
|
||||||
|
|
||||||
|
This document introduces some of the most commonly used **Python standard library** modules:
|
||||||
|
|
||||||
|
* `datetime`
|
||||||
|
* `math`
|
||||||
|
* `random`
|
||||||
|
* `decimal`
|
||||||
|
|
||||||
|
These modules come bundled with Python and require no external installation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Date and Time with `datetime`
|
||||||
|
|
||||||
|
The `datetime` module provides classes for working with dates and times.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Working with Dates
|
||||||
|
|
||||||
|
#### Code
|
||||||
|
|
||||||
|
```python
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
date_1 = datetime.date(2026, 1, 1)
|
||||||
|
|
||||||
|
print(date_1.year)
|
||||||
|
print(date_1.month)
|
||||||
|
print(date_1.day)
|
||||||
|
|
||||||
|
print(date_1.weekday)
|
||||||
|
print(date_1.ctime)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Explanation
|
||||||
|
|
||||||
|
* `datetime.date(year, month, day)` creates a date object.
|
||||||
|
* `.year`, `.month`, `.day` access individual components.
|
||||||
|
|
||||||
|
#### Important Note
|
||||||
|
|
||||||
|
```python
|
||||||
|
date_1.weekday()
|
||||||
|
```
|
||||||
|
|
||||||
|
* Returns the day of the week as an integer:
|
||||||
|
|
||||||
|
* Monday = 0
|
||||||
|
* Sunday = 6
|
||||||
|
|
||||||
|
```python
|
||||||
|
date_1.ctime()
|
||||||
|
```
|
||||||
|
|
||||||
|
* Returns a human-readable string representation of the date.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Working with Time
|
||||||
|
|
||||||
|
#### Code
|
||||||
|
|
||||||
|
```python
|
||||||
|
time_1 = datetime.time(12, 12)
|
||||||
|
|
||||||
|
print(time_1.hour)
|
||||||
|
print(time_1.min)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Explanation
|
||||||
|
|
||||||
|
* `datetime.time(hour, minute)` creates a time object.
|
||||||
|
* `.hour` returns the hour.
|
||||||
|
* `.minute` returns the minute.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Working with Date and Time Together
|
||||||
|
|
||||||
|
#### Code
|
||||||
|
|
||||||
|
```python
|
||||||
|
abbas_birth = datetime.datetime(2026, 1, 1, 12, 12)
|
||||||
|
today = datetime.date.today()
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
|
||||||
|
diff_time = now - abbas_birth
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Explanation
|
||||||
|
|
||||||
|
* `datetime.datetime` includes both date and time.
|
||||||
|
* `date.today()` returns today’s date.
|
||||||
|
* `datetime.now()` returns the current date and time.
|
||||||
|
* Subtracting two `datetime` objects returns a `timedelta`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Mathematical Operations with `math`
|
||||||
|
|
||||||
|
The `math` module provides advanced mathematical functions and constants.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Mathematical Constants
|
||||||
|
|
||||||
|
```python
|
||||||
|
import math
|
||||||
|
|
||||||
|
print(math.pi)
|
||||||
|
print(math.e)
|
||||||
|
print(math.inf)
|
||||||
|
```
|
||||||
|
|
||||||
|
* `math.pi`: π constant
|
||||||
|
* `math.e`: Euler’s number
|
||||||
|
* `math.inf`: infinity
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Power and Rounding
|
||||||
|
|
||||||
|
```python
|
||||||
|
print(math.pow(2, 3))
|
||||||
|
|
||||||
|
print(round(4.2))
|
||||||
|
print(round(4.8))
|
||||||
|
```
|
||||||
|
|
||||||
|
* `math.pow(a, b)` returns `a` raised to the power of `b`.
|
||||||
|
* `round()` rounds to the nearest integer.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Floor and Ceil
|
||||||
|
|
||||||
|
```python
|
||||||
|
print(math.floor(4.2))
|
||||||
|
print(math.floor(4.9))
|
||||||
|
|
||||||
|
print(math.ceil(4.2))
|
||||||
|
print(math.ceil(4.9))
|
||||||
|
```
|
||||||
|
|
||||||
|
* `floor`: rounds down
|
||||||
|
* `ceil`: rounds up
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Logarithms
|
||||||
|
|
||||||
|
```python
|
||||||
|
print(math.log(100, 10))
|
||||||
|
```
|
||||||
|
|
||||||
|
* Returns the logarithm of 100 with base 10.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Random Values with `random`
|
||||||
|
|
||||||
|
The `random` module is used to generate pseudo-random values.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Random Numbers
|
||||||
|
|
||||||
|
```python
|
||||||
|
import random
|
||||||
|
|
||||||
|
print(random.randint(1, 6))
|
||||||
|
print(random.random())
|
||||||
|
```
|
||||||
|
|
||||||
|
* `randint(a, b)`: random integer between `a` and `b` (inclusive)
|
||||||
|
* `random()`: random float between `0` and `1`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Random Selection
|
||||||
|
|
||||||
|
```python
|
||||||
|
number_list = list(range(15))
|
||||||
|
print(random.choice(number_list))
|
||||||
|
|
||||||
|
char_list = ['a', 'm', 's']
|
||||||
|
print(random.choice(char_list))
|
||||||
|
```
|
||||||
|
|
||||||
|
* `choice()` selects a random element from a sequence.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Shuffling
|
||||||
|
|
||||||
|
```python
|
||||||
|
random.shuffle(number_list)
|
||||||
|
print(number_list)
|
||||||
|
```
|
||||||
|
|
||||||
|
* `shuffle()` randomly rearranges the list in place.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Decimal Precision with `decimal`
|
||||||
|
|
||||||
|
The `decimal` module provides precise decimal arithmetic, avoiding floating-point errors.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Decimal Context
|
||||||
|
|
||||||
|
```python
|
||||||
|
import decimal
|
||||||
|
|
||||||
|
print(decimal.getcontext())
|
||||||
|
```
|
||||||
|
|
||||||
|
* Shows current precision and rounding settings.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Float vs Decimal
|
||||||
|
|
||||||
|
```python
|
||||||
|
print(decimal.Decimal(0.1))
|
||||||
|
print(decimal.Decimal('0.1'))
|
||||||
|
```
|
||||||
|
|
||||||
|
* Passing a float carries floating-point error.
|
||||||
|
* Passing a string preserves exact value.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Precision Comparison
|
||||||
|
|
||||||
|
```python
|
||||||
|
print(0.1 + 0.2 == 0.3)
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns `False` due to floating-point precision issues.
|
||||||
|
|
||||||
|
```python
|
||||||
|
print(decimal.Decimal(0.1) + decimal.Decimal(0.2) == decimal.Decimal(0.3))
|
||||||
|
```
|
||||||
|
|
||||||
|
Still `False` because the floats are imprecise.
|
||||||
|
|
||||||
|
```python
|
||||||
|
print(decimal.Decimal('0.1') + decimal.Decimal('0.2') == decimal.Decimal('0.3'))
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns `True` because strings preserve precision.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* `datetime` handles dates and times
|
||||||
|
* `math` provides mathematical constants and functions
|
||||||
|
* `random` generates pseudo-random values
|
||||||
|
* `decimal` solves floating-point precision problems
|
||||||
|
* Always use strings when creating `Decimal` values
|
||||||
|
|
||||||
Reference in New Issue
Block a user