structure updates
This commit is contained in:
533
tech_docs/python/Python_programming.md
Normal file
533
tech_docs/python/Python_programming.md
Normal file
@@ -0,0 +1,533 @@
|
||||
# Python Functions: A Comprehensive Guide
|
||||
|
||||
Python functions are the building blocks of Python programming, enabling code reusability, organization, and modularity. This guide explores Python functions, their syntax, and how to use them effectively.
|
||||
|
||||
## Introduction to Python Functions
|
||||
|
||||
A function is a block of code that runs when it's called. It can accept input, produce output, and perform a specific task. Here's a basic example:
|
||||
|
||||
```python
|
||||
# Defining a function
|
||||
def greet(name):
|
||||
return f"Hello, {name}!"
|
||||
|
||||
# Calling the function
|
||||
print(greet("Alice"))
|
||||
```
|
||||
|
||||
- **Defining Functions**: Use the `def` keyword followed by the function name and parentheses.
|
||||
- **Arguments**: Functions can take arguments, which are specified within the parentheses.
|
||||
- **Returning Values**: Use the `return` statement to send back an output.
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### Parameters vs. Arguments
|
||||
|
||||
- **Parameters** are the variables listed inside the parentheses in the function definition.
|
||||
- **Arguments** are the values passed to the function when it is called.
|
||||
|
||||
### Default Parameters
|
||||
|
||||
You can assign default values to parameters, making them optional during a function call:
|
||||
|
||||
```python
|
||||
def greet(name, greeting="Hello"):
|
||||
return f"{greeting}, {name}!"
|
||||
|
||||
print(greet("Alice")) # Uses default greeting
|
||||
print(greet("Alice", "Goodbye")) # Overrides default greeting
|
||||
```
|
||||
|
||||
### Keyword Arguments
|
||||
|
||||
Keyword arguments allow you to specify arguments by their names, making your function calls more readable:
|
||||
|
||||
```python
|
||||
def describe_pet(animal_type, pet_name):
|
||||
print(f"I have a {animal_type} named {pet_name}.")
|
||||
|
||||
describe_pet(animal_type="hamster", pet_name="Harry")
|
||||
```
|
||||
|
||||
### Arbitrary Arguments
|
||||
|
||||
Sometimes you might not know how many arguments will be passed into your function. Use `*args` for arbitrary number of positional arguments and `**kwargs` for arbitrary number of keyword arguments:
|
||||
|
||||
```python
|
||||
def make_pizza(*toppings):
|
||||
print("Making a pizza with the following toppings:")
|
||||
for topping in toppings:
|
||||
print(f"- {topping}")
|
||||
|
||||
make_pizza('pepperoni', 'mushrooms', 'green peppers')
|
||||
```
|
||||
|
||||
## Advanced Function Features
|
||||
|
||||
### Lambda Functions
|
||||
|
||||
Lambda functions are small, anonymous functions defined with the `lambda` keyword. They can have any number of arguments but only one expression:
|
||||
|
||||
```python
|
||||
multiply = lambda x, y: x * y
|
||||
print(multiply(2, 3))
|
||||
```
|
||||
|
||||
### Function Annotations
|
||||
|
||||
Function annotations provide a way of associating metadata with function parameters and return values:
|
||||
|
||||
```python
|
||||
def greet(name: str) -> str:
|
||||
return f"Hello, {name}!"
|
||||
```
|
||||
|
||||
### Generators
|
||||
|
||||
Functions can also be generators, which yield a sequence of values lazily, meaning they generate each value only when needed:
|
||||
|
||||
```python
|
||||
def countdown(num):
|
||||
while num > 0:
|
||||
yield num
|
||||
num -= 1
|
||||
|
||||
for i in countdown(5):
|
||||
print(i)
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- **Descriptive Names**: Choose function names that clearly describe their purpose.
|
||||
- **Small and Focused**: Functions should do one thing and do it well.
|
||||
- **Documentation Strings**: Use docstrings to describe what your function does, its parameters, and its return value.
|
||||
|
||||
## Conclusion
|
||||
|
||||
Python functions are a fundamental aspect of writing clean, efficient, and reusable code. By understanding and applying the concepts in this guide, you'll be able to create more complex and modular Python applications with ease.
|
||||
|
||||
This guide should provide you with a solid understanding of Python functions, covering their definition, usage, and some advanced features to enhance your programming skills.
|
||||
|
||||
---
|
||||
|
||||
# Understanding Objects in Python: A Technical Guide
|
||||
|
||||
Python is an object-oriented programming language at its core, which means everything in Python is an object. This guide delves into the technical aspects of Python objects, including their creation, manipulation, and the principles that govern their interactions.
|
||||
|
||||
## Basics of Python Objects
|
||||
|
||||
In Python, objects are instances of classes, which can contain data (attributes) and functions (methods) that operate on the data. Here’s how you can define a class and create an object:
|
||||
|
||||
```python
|
||||
class MyClass:
|
||||
def __init__(self, value):
|
||||
self.attribute = value
|
||||
|
||||
def method(self):
|
||||
return f"Attribute value: {self.attribute}"
|
||||
|
||||
# Creating an object
|
||||
my_object = MyClass(10)
|
||||
print(my_object.method())
|
||||
```
|
||||
|
||||
- **Class Definition**: Use the `class` keyword followed by the class name and a colon.
|
||||
- **The `__init__` Method**: Known as the constructor, it initializes the object’s state.
|
||||
- **Attributes and Methods**: Attributes store the object's state, and methods define its behavior.
|
||||
|
||||
## Object Attributes and Methods
|
||||
|
||||
### Instance Attributes vs. Class Attributes
|
||||
|
||||
- **Instance Attributes**: Defined within methods and prefixed with `self`, unique to each object.
|
||||
- **Class Attributes**: Defined outside of methods and are shared across all instances of the class.
|
||||
|
||||
### Instance Methods, Class Methods, and Static Methods
|
||||
|
||||
- **Instance Methods**: Operate on an instance of the class and have access to `self`.
|
||||
- **Class Methods**: Operate on the class itself, rather than instance, and take `cls` as the first parameter. Use the `@classmethod` decorator.
|
||||
- **Static Methods**: Do not access the class or its instances and are defined using the `@staticmethod` decorator.
|
||||
|
||||
```python
|
||||
class MyClass:
|
||||
class_attribute = "Shared"
|
||||
|
||||
def __init__(self, value):
|
||||
self.instance_attribute = value
|
||||
|
||||
def instance_method(self):
|
||||
return self.instance_attribute
|
||||
|
||||
@classmethod
|
||||
def class_method(cls):
|
||||
return cls.class_attribute
|
||||
|
||||
@staticmethod
|
||||
def static_method():
|
||||
return 'Static method called'
|
||||
```
|
||||
|
||||
## Inheritance and Polymorphism
|
||||
|
||||
Inheritance allows one class to inherit the attributes and methods of another, enabling code reuse and the creation of complex object hierarchies.
|
||||
|
||||
```python
|
||||
class BaseClass:
|
||||
pass
|
||||
|
||||
class DerivedClass(BaseClass):
|
||||
pass
|
||||
```
|
||||
|
||||
Polymorphism allows objects of different classes to be treated as objects of a common superclass, particularly when they share a method name but implement it differently.
|
||||
|
||||
```python
|
||||
def common_interface(obj):
|
||||
obj.method_name()
|
||||
```
|
||||
|
||||
## Magic Methods
|
||||
|
||||
Magic methods (or dunder methods) are special methods with double underscores at the beginning and end of their names. They enable operator overloading and custom behavior for built-in operations.
|
||||
|
||||
```python
|
||||
class MyClass:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def __str__(self):
|
||||
return f"MyClass with value: {self.value}"
|
||||
```
|
||||
|
||||
## Encapsulation and Abstraction
|
||||
|
||||
- **Encapsulation**: The bundling of data with the methods that operate on that data.
|
||||
- **Abstraction**: Hiding the internal implementation details of a class and exposing only the necessary parts.
|
||||
|
||||
## Conclusion
|
||||
|
||||
Understanding the technical aspects of Python objects is crucial for mastering object-oriented programming in Python. By grasping concepts like inheritance, polymorphism, and magic methods, you can design robust and reusable code structures.
|
||||
|
||||
---
|
||||
|
||||
# Mastering List Comprehensions in Python
|
||||
|
||||
List comprehensions in Python provide a concise way to create lists. They consist of brackets containing an expression followed by a `for` clause, then zero or more `for` or `if` clauses. This guide will explore the syntax and capabilities of list comprehensions, helping you write more Pythonic code.
|
||||
|
||||
## Basic Syntax
|
||||
|
||||
The basic syntax of a list comprehension is:
|
||||
|
||||
```python
|
||||
[expression for item in iterable]
|
||||
```
|
||||
|
||||
- **expression**: An expression producing a value to be included in the new list.
|
||||
- **item**: The variable representing each element in the iterable.
|
||||
- **iterable**: A sequence (list, tuple, string, etc.) or collection (set, dictionary, etc.) that can be iterated over.
|
||||
|
||||
### Example: Squaring Numbers
|
||||
|
||||
```python
|
||||
squares = [x**2 for x in range(10)]
|
||||
print(squares)
|
||||
```
|
||||
|
||||
This creates a list of the squares of numbers 0 through 9.
|
||||
|
||||
## Adding Conditionals
|
||||
|
||||
List comprehensions can also include conditional statements to filter items from the input iterable.
|
||||
|
||||
### Filtering Items
|
||||
|
||||
```python
|
||||
even_squares = [x**2 for x in range(10) if x % 2 == 0]
|
||||
print(even_squares)
|
||||
```
|
||||
|
||||
This generates a list of squares for even numbers only.
|
||||
|
||||
### Conditional Expressions
|
||||
|
||||
You can also use conditional expressions within the expression part of the list comprehension:
|
||||
|
||||
```python
|
||||
values = [x if x > 0 else -x for x in range(-5, 5)]
|
||||
print(values)
|
||||
```
|
||||
|
||||
This creates a list where negative numbers are made positive.
|
||||
|
||||
## Nested List Comprehensions
|
||||
|
||||
List comprehensions can be nested to create complex lists:
|
||||
|
||||
```python
|
||||
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
|
||||
flattened = [elem for row in matrix for elem in row]
|
||||
print(flattened)
|
||||
```
|
||||
|
||||
This flattens a list of lists into a single list.
|
||||
|
||||
## Using List Comprehensions with Other Data Types
|
||||
|
||||
While they're called list comprehensions, this syntax can be used to create sets and dictionaries as well.
|
||||
|
||||
### Set Comprehensions
|
||||
|
||||
```python
|
||||
square_set = {x**2 for x in range(-5, 5)}
|
||||
print(square_set)
|
||||
```
|
||||
|
||||
This creates a set of squared numbers, removing duplicates.
|
||||
|
||||
### Dictionary Comprehensions
|
||||
|
||||
```python
|
||||
square_dict = {x: x**2 for x in range(5)}
|
||||
print(square_dict)
|
||||
```
|
||||
|
||||
This creates a dictionary with numbers as keys and their squares as values.
|
||||
|
||||
## Best Practices
|
||||
|
||||
- **Readability**: Use list comprehensions for simple expressions and operations. For complex logic, consider using regular loops.
|
||||
- **Performance**: List comprehensions can be faster than equivalent `for` loops, but readability should not be sacrificed for slight performance gains.
|
||||
- **Avoid Side Effects**: Do not use list comprehensions for operations that have side effects, such as file I/O or modifying external variables.
|
||||
|
||||
## Conclusion
|
||||
|
||||
List comprehensions are a powerful feature of Python that allow for clean, readable, and efficient code. By understanding and applying the concepts outlined in this guide, you can leverage list comprehensions to simplify your code while maintaining or even improving its performance.
|
||||
|
||||
---
|
||||
|
||||
# Python Dictionaries: A Guide for API Calls
|
||||
|
||||
Python dictionaries are essential for handling data in Python, especially when working with API calls. This guide provides a concise overview of dictionaries and their use in constructing API payloads.
|
||||
|
||||
## Introduction to Python Dictionaries
|
||||
|
||||
Dictionaries in Python are collections of key-value pairs, allowing you to store and manage data dynamically. Here's a quick rundown:
|
||||
|
||||
```python
|
||||
# Example of a Python dictionary
|
||||
my_dict = {
|
||||
"key1": "value1",
|
||||
"key2": "value2",
|
||||
"key3": "value3",
|
||||
}
|
||||
```
|
||||
|
||||
- **Key Characteristics**:
|
||||
- **Unordered**: The items do not have a defined order.
|
||||
- **Changeable**: You can add, remove, or modify items.
|
||||
- **Indexed**: Accessed by keys, which must be unique and immutable.
|
||||
|
||||
## Basic Operations
|
||||
|
||||
- **Accessing Items**: `value = my_dict["key1"]`
|
||||
- **Adding Items**: `my_dict["newKey"] = "newValue"`
|
||||
- **Removing Items**: `my_dict.pop("key1")`, `del my_dict["key2"]`
|
||||
- **Looping Through**: `for key in my_dict: print(key, my_dict[key])`
|
||||
|
||||
## Using Dictionaries for API Calls
|
||||
|
||||
When making API calls, dictionaries are often used to construct payloads or parameters:
|
||||
|
||||
```python
|
||||
# API payload as a dictionary
|
||||
payload = {
|
||||
"username": "user",
|
||||
"password": "pass",
|
||||
"email": "email@example.com"
|
||||
}
|
||||
|
||||
# Using requests library for API call
|
||||
import requests
|
||||
response = requests.post("https://api.example.com/users", json=payload)
|
||||
```
|
||||
|
||||
- Dictionaries are converted to JSON or other formats suitable for web transmission.
|
||||
- This method simplifies sending structured data over HTTP requests.
|
||||
|
||||
## Best Practices
|
||||
|
||||
- **Key Management**: Ensure keys are descriptive and consistent.
|
||||
- **Data Validation**: Validate and sanitize data before adding it to a dictionary, especially when received from user input.
|
||||
- **Dynamic Construction**: Leverage dictionary comprehensions and dynamic insertion for creating complex payloads.
|
||||
|
||||
## Conclusion
|
||||
|
||||
Understanding Python dictionaries is fundamental for API interactions, providing a structured and flexible way to handle data. Their key-value nature makes them ideal for constructing API payloads, facilitating efficient data transmission over networks.
|
||||
|
||||
Remember to follow best practices for key management and data validation to ensure secure and effective API communication.
|
||||
|
||||
|
||||
This guide encapsulates the essentials of Python dictionaries, focusing on their application in API calls, which should be quite handy for your learning and development tasks.
|
||||
|
||||
---
|
||||
|
||||
# Advanced Python Concepts and Best Practices
|
||||
|
||||
## Advanced OOP Features
|
||||
|
||||
### Polymorphism and Duck Typing
|
||||
Python is known for its "duck typing" philosophy, encapsulating the idea of polymorphism. It means that an object's suitability for a task is determined by the presence of certain methods and properties, rather than the object's type itself.
|
||||
|
||||
```python
|
||||
def quack_and_fly(thing):
|
||||
thing.quack()
|
||||
thing.fly()
|
||||
# If it looks like a duck and quacks like a duck, it's a duck.
|
||||
```
|
||||
|
||||
### Abstract Base Classes (ABCs)
|
||||
Abstract Base Classes are a form of interface checking more strict than duck typing. ABCs allow for the definition of methods that must be created within any child classes implemented from the abstract base.
|
||||
|
||||
```python
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
class Bird(ABC):
|
||||
@abstractmethod
|
||||
def fly(self):
|
||||
pass
|
||||
|
||||
class Duck(Bird):
|
||||
def fly(self):
|
||||
print("Duck flying")
|
||||
```
|
||||
|
||||
## Decorators
|
||||
Decorators allow you to modify or enhance functions without changing their definitions. They are a powerful tool for logging, enforcing access control, instrumentation, and more.
|
||||
|
||||
```python
|
||||
def my_decorator(func):
|
||||
def wrapper():
|
||||
print("Something is happening before the function is called.")
|
||||
func()
|
||||
print("Something is happening after the function is called.")
|
||||
return wrapper
|
||||
|
||||
@my_decorator
|
||||
def say_hello():
|
||||
print("Hello!")
|
||||
```
|
||||
|
||||
## Generators and Iterators
|
||||
Generators provide a way to create iterators in a more straightforward manner, using the `yield` statement. They are used to iterate through sequences efficiently without requiring the entire sequence to be stored in memory.
|
||||
|
||||
```python
|
||||
def my_generator():
|
||||
yield 1
|
||||
yield 2
|
||||
yield 3
|
||||
|
||||
for value in my_generator():
|
||||
print(value)
|
||||
```
|
||||
|
||||
## Context Managers
|
||||
Context managers allow setup and teardown operations to be executed around a block of code. The `with` statement simplifies the management of resources such as file streams.
|
||||
|
||||
```python
|
||||
with open('file.txt', 'w') as opened_file:
|
||||
opened_file.write('Hello, world!')
|
||||
```
|
||||
|
||||
## Exception Handling
|
||||
Proper exception handling is crucial for creating reliable and resilient applications. Python provides try-except-else-finally blocks for catching and handling exceptions.
|
||||
|
||||
```python
|
||||
try:
|
||||
# Code block where exceptions can occur
|
||||
pass
|
||||
except ExceptionType1:
|
||||
# Handle specific exception
|
||||
pass
|
||||
except ExceptionType2 as e:
|
||||
# Handle specific exception and access its information
|
||||
pass
|
||||
else:
|
||||
# Execute if no exceptions
|
||||
pass
|
||||
finally:
|
||||
# Execute no matter what
|
||||
pass
|
||||
```
|
||||
|
||||
## Testing
|
||||
Testing is critical for ensuring code reliability and functionality. Python's `unittest` and `pytest` frameworks facilitate the creation and management of tests.
|
||||
|
||||
```python
|
||||
# Example using pytest
|
||||
def add(a, b):
|
||||
return a + b
|
||||
|
||||
def test_add():
|
||||
assert add(2, 3) == 5
|
||||
```
|
||||
|
||||
This guide presents a deeper dive into essential Python concepts beyond classes and data classes. Mastery of these topics will significantly enhance your Python programming skills and your ability to develop robust, efficient, and maintainable Python applications.
|
||||
|
||||
|
||||
Each of these topics represents a core aspect of Python programming that, when understood and applied, can greatly improve the quality and efficiency of your code. As with any skill, practice and continuous learning are key to mastery.
|
||||
---
|
||||
|
||||
# Python Classes and Data Classes Reference Guide
|
||||
|
||||
## Python Classes
|
||||
|
||||
### Basic Structure
|
||||
```python
|
||||
class MyClass:
|
||||
def __init__(self, attribute1, attribute2):
|
||||
self.attribute1 = attribute1
|
||||
self.attribute2 = attribute2
|
||||
|
||||
def method1(self):
|
||||
# Method implementation
|
||||
pass
|
||||
```
|
||||
|
||||
### Key Concepts
|
||||
- **Encapsulation**: Grouping data and methods that act on the data within a single unit.
|
||||
- **Inheritance**: Creating a new class that inherits attributes and methods from an existing class.
|
||||
```python
|
||||
class DerivedClass(BaseClass):
|
||||
pass
|
||||
```
|
||||
- **Polymorphism**: Allowing methods to do different things based on the object it is acting upon.
|
||||
- **Abstraction**: Hiding complex implementation details and showing only the necessary features of an object.
|
||||
|
||||
## Data Classes (Python 3.7+)
|
||||
|
||||
### Basic Usage
|
||||
```python
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass
|
||||
class MyDataClass:
|
||||
attribute1: int
|
||||
attribute2: float = 0.0
|
||||
```
|
||||
|
||||
### Key Features
|
||||
- **Automatic Method Generation**: `__init__`, `__repr__`, `__eq__`, and more.
|
||||
- **Type Hints**: Mandatory for each field, improving code readability.
|
||||
- **Default Values**: Easily set defaults for fields.
|
||||
- **Immutability**: Optionally, make instances immutable by using `@dataclass(frozen=True)`.
|
||||
|
||||
### Comparison with Standard Classes
|
||||
- Use **data classes** for simpler, data-centric models to reduce boilerplate.
|
||||
- Use **standard classes** for more complex behaviors, custom method implementations, and when OOP features like inheritance and polymorphism are needed.
|
||||
|
||||
## Practical Tips
|
||||
- Leverage **inheritance** in standard classes to create a logical, hierarchical structure.
|
||||
- Use **data classes** for data models in applications like data processing and analysis for cleaner, more maintainable code.
|
||||
- Remember to use type hints with data classes for better static analysis and error checking.
|
||||
|
||||
This reference guide should serve as a quick lookup for the core concepts and usage patterns of Python classes and data classes. Adjust and expand based on specific project needs and complexity.
|
||||
Reference in New Issue
Block a user