Python is popular due to its simple syntax, readability, and versatility. It's an interpreted, cross-platform language with a rich standard library and extensive third-party frameworks for web development, data analysis, and AI. It supports multiple paradigms (OOP, procedural, functional), features dynamic typing, and integrates well with other technologies. Its large community ensures abundant resources, making it ideal for beginners and experts alike.
Lists: Mutable, use [], suitable for modifiable data.
Tuples: Immutable, use (), ideal for fixed data.
Example:
List: shopping_list = ["apples", "bananas"] (can add/remove items).
Tuple: coordinates = (10.5, 20.3) (fixed values).
The __init__ method in Python is a special constructor method used to initialize an object's attributes when an instance of a class is created. Unlike other methods, it is automatically called and doesn't return any value explicitly (it always returns None).
def count_vowels(s):
return sum(1 for char in s.lower() if char in 'aeiou')
# Example usage
print(count_vowels("Hello World")) # Output: 3
Python's data types include int, float, str, list, tuple, dict, set, bool, and None. Examples: 5, 3.14, "hello", [1, 2], (1, 2), {'key': 'value'}, {1, 2}, True, and None.
A shallow copy creates a new object but copies references to the original elements, so changes to mutable objects affect both copies. A deep copy creates a completely independent copy, including copying nested objects, so changes don't affect the original.
Python handles memory management through automatic garbage collection and reference counting. When objects are no longer referenced, they are deallocated, and the memory is freed, typically using the garbage collector to handle cycles and unreferenced objects.
Python's built-in data structures are:
- List: Ordered, mutable collection (e.g., [1, 2, 3])
- Tuple: Ordered, immutable collection (e.g., (1, 2, 3))
- Dictionary: Key-value pairs (e.g., {'name': 'Alice', 'age': 25})
Set: Unordered collection of unique elements (e.g., {1, 2, 3})
In Python, == checks if the values of two objects are equal, while is checks if two objects refer to the same memory location (i.e., whether they are the same object).
Decorators in Python are functions that modify the behavior of other functions or methods. They are used to add functionality to existing code without changing the original function, typically applied using the @decorator_name syntax.
Python's comprehensions provide a concise way to create lists, sets, or dictionaries. Examples:
- List comprehension: [x**2 for x in range(5)] → [0, 1, 4, 9, 16]
- Set comprehension: {x**2 for x in range(5)} → {0, 1, 4, 9, 16}
- Dictionary comprehension: {x: x**2 for x in range(5)} → {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
Python's garbage collection uses reference counting to track the number of references to an object. When an object's reference count reaches zero, it is automatically deallocated. Additionally, Python uses a cyclic garbage collector to detect and clean up circular references that reference counting alone can't handle.
staticmethod: A method that doesn't take self or cls as its first argument and is not bound to an instance or class. It behaves like a regular function but belongs to the class.
classmethod: A method that takes cls as its first argument, allowing it to access or modify the class state, and is bound to the class, not an instance.
Exception handling in Python is implemented using try, except, else, and finally blocks. The try block contains code that may raise an exception, the except block handles the exception, the else block runs if no exception occurs, and the finally block executes regardless of an exception.
A Python generator is a function that uses yield to produce a sequence of values lazily, one at a time, instead of returning the entire sequence at once. Unlike a list, a generator does not store all values in memory, making it more memory-efficient for large datasets.
*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's lambda functions are anonymous, small functions defined using the lambda keyword. They can have any number of arguments but only one expression.
Example: python
Copy code
add = lambda x, y: x + y
print(add(2, 3)) # Output: 5
map(): Applies a function to all items in an iterable and returns a map object (e.g., [f(x) for x in iterable]).
filter(): Filters elements from an iterable based on a condition function, returning items that evaluate to True.
reduce(): Performs a cumulative operation on items of an iterable, reducing it to a single value (from the functools module).
copy() creates a shallow copy, copying only the references to objects within the original, not the nested objects.
deepcopy() creates a deep copy, recursively copying all objects and nested objects, ensuring complete independence from the original.
You can convert a Python string into a datetime object using the strptime() method from the datetime module.
Example:python
Copy code
from datetime import datetime
date_string = "2024-12-06"
date_object = datetime.strptime(date_string, "%Y-%m-%d")
In Python, files are handled using the open() function, which returns a file object. You can read, write, or append to the file with methods like .read(), .write(), and .close(). It's best practice to use the with statement to ensure files are properly closed.
Example:python
Copy code
with open('file.txt', 'r') as file:
content = file.read()
Python's with statement is used for resource management, ensuring that resources like files or network connections are properly acquired and released. It automatically handles setup and cleanup (e.g., closing files) when the block of code is executed, even if an exception occurs.
You can create a virtual environment in Python using the venv module.
Example:
bash
Copy code
python -m venv myenv
To activate:
- Windows: myenv\Scripts\activate
- Mac/Linux: source myenv/bin/activate
Deactivate with: deactivate
Iterable: An object that can return an iterator, such as a list, tuple, or string, and supports iteration (e.g., using a for loop).
Iterator: An object that represents a stream of data and can be iterated upon, using __next__() to fetch the next item until exhaustion.
Multithreading: Involves running multiple threads within the same process, sharing memory space. It's useful for I/O-bound tasks but may not be efficient for CPU-bound tasks due to Python's Global Interpreter Lock (GIL).
Multiprocessing: Involves running multiple processes, each with its own memory space. It's more effective for CPU-bound tasks as it bypasses the GIL and utilizes multiple cores.
Inheritance is implemented by defining a class that inherits from another class:
python
Copy code
class Animal:
def speak(self):
print("Animal speaks")
class Dog(Animal):
def speak(self):
print("Dog barks"
python
Copy code
def reverse_string(s):
if len(s) == 0:
return s
else:
return reverse_string(s[1:]) + s[0]
- Simple and readable syntax
- Dynamically typed
- Extensive standard library
- High-level, interpreted, and cross-platform
python
Copy code
def is_prime(n):
if n < 2:
return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False
return True
Python determines variable types at runtime, allowing variables to change types dynamically.
python
Copy code
def factorial(n):
if n == 0:
return 1
return n * factorial(n - 1)
- Mutable: Can be changed after creation (e.g., lists, dictionaries).
- Immutable: Cannot be changed after creation (e.g., strings, tuples).
Use libraries like pandas with methods like fillna(), dropna(), or interpolation to handle missing values.
Python's exceptions are organized in a hierarchy, with BaseException as the root. Common exceptions include Exception, ValueError, and IndexError.
Example:
python
Copy code
try:
x = int("hello")
except ValueError:
print("Invalid number!")
Use the update() method or dictionary unpacking (**):
python
Copy code
dict1 = {'a': 1}
dict2 = {'b': 2}
dict1.update(dict2) # Merges dict2 into dict1
# or
merged_dict = {**dict1, **dict2}
A Python module is a file containing Python code that defines functions, classes, or variables. Create a module by saving a .py file, and import it using import module_name.
python
Copy code
with open('file.txt', 'r') as file:
line_count = sum(1 for line in file)
print(line_count)
Python's dictionary is implemented using a hash table, providing average O(1) time complexity for lookups, insertions, and deletions.
yield turns a function into a generator, allowing it to return values one at a time without storing them in memory, making it memory efficient for large datasets.
python
Copy code
def find_duplicates(lst):
return [item for item in set(lst) if lst.count(item) > 1]
The Global Interpreter Lock (GIL) in CPython ensures that only one thread executes Python bytecode at a time, simplifying memory management but limiting multi-core performance.
Impact:
- Hinders parallelism in CPU-bound tasks, as threads cannot run concurrently.
- Works well for I/O-bound tasks, as threads can switch during I/O waits.
- Workarounds: Use multiprocessing for parallelism or offload heavy computations to GIL-independent libraries like NumPy.
Python manages memory using reference counting and a garbage collector:
- Reference Counting: Tracks the number of references to an object. When the count drops to zero, the object is deallocated.
- Garbage Collector: Handles cyclic references (objects referring to each other) that reference counting can't clean up.
- Memory Allocation: Objects are stored in a private heap managed by Python's memory manager.
Python’s garbage collection mechanisms:
- Reference Counting: Frees memory when an object's references drop to zero.
- Cycle Detection: Identifies and removes cyclic references (objects referencing each other).
- Generational Garbage Collection: Optimizes performance by categorizing objects into generations and collecting younger objects more frequently.
All managed automatically by Python, with manual control available via the gc module.
The difference between shallow copy and deep copy lies in how they duplicate objects:
- Shallow Copy:
- Creates a new object.
- Copies references of the original object's elements.
- Changes to mutable elements (e.g., lists, dictionaries) affect both copies.
- Deep Copy:
- Creates a new object.
- Recursively copies all elements, including nested objects.
- Changes to the copy do not affect the original.
Use the copy module in Python for both (copy.copy() for shallow, copy.deepcopy() for deep).
Metaclasses in Python are "classes of classes" used to define how classes behave. They control class creation and can modify or customize classes dynamically.
Uses of Metaclasses:
- Custom Class Behavior: Modify or validate class attributes and methods during creation.
- Code Automation: Automatically add or modify methods, properties, or attributes in classes.
- Enforcing Standards: Ensure all classes follow certain conventions or implement specific methods.
You define a metaclass by subclassing type and use it via the metaclass keyword in class definitions.
Python descriptors manage how attributes are accessed, set, or deleted in a class using special methods:
- __get__: Called on attribute access.
- __set__: Called on attribute assignment.
- __delete__: Called on attribute deletion.
Types:
- Data Descriptors: Implement __get__ and __set__.
- Non-Data Descriptors: Implement only __get__.
Uses:
- Control attribute behavior.
- Reuse code for attribute management.
- Common in Python features like properties and ORM fields.
Here's the difference between @staticmethod, @classmethod, and instance methods:
- @staticmethod:
- Does not take self or cls as the first argument.
- Can be called on the class or instance.
- Used for utility functions that don’t need access to instance or class data.
- @classmethod:
- Takes cls (class) as the first argument, not self.
- Can modify class state and be called on the class or instance.
- Instance methods:
- Takes self (instance) as the first argument.
- Operates on instance-specific data and can access both instance and class attributes.
In Python:
- is: Compares object identity (whether two variables refer to the same object in memory).
- ==: Compares values (whether the values of two objects are equal).
Example:
Python
a = [1, 2, 3]
b = a
c = [1, 2, 3]
print(a is b) # True (same object in memory)
print(a == c) # True (same values)
print(a is c) # False (different objects in memory)
Coroutines (defined with async def) are used for asynchronous programming, pausing with await and allowing other tasks to run.
Generators (defined with def and yield) are used for lazy iteration, pausing with yield and resuming on subsequent calls.
- Coroutines: Asynchronous tasks (e.g., I/O).
- Generators: Lazy value generation for iteration.
The __slots__ attribute in Python is used to limit the attributes that an object can have. By defining __slots__, you can prevent the creation of the default __dict__ (which stores object attributes), thus saving memory and improving performance.
Significance:
- Memory Efficiency: Reduces memory usage by preventing the dynamic creation of attributes.
- Performance: Faster attribute access due to fixed storage.
class MyClass:
__slots__ = ['attr1', 'attr2']
obj = MyClass()
obj.attr1 = 10 # Allowed
obj.attr3 = 20 # AttributeError: 'MyClass' object has no attribute 'attr3'
Python handles data serialization using modules like pickle, json, and marshal:
- pickle: Serializes Python objects into byte streams and deserializes them back. Supports complex Python data types.
- Example: pickle.dump(obj, file) to serialize, pickle.load(file) to deserialize.
- json: Serializes data into JSON format, primarily for interoperability with other languages and systems. Supports basic data types (strings, numbers, lists, dicts).
- Example: json.dump(obj, file) to serialize, json.load(file) to deserialize.
- marshal: Used internally by Python to serialize code objects (not typically for general-purpose data serialization).
Serialization enables storing and transmitting Python objects in a standardized format.
Python's abstract base classes (ABCs) are classes that define a common interface and cannot be instantiated directly. They use the abc module and @abstractmethod decorator to enforce that subclasses implement certain methods.
from abc import ABC, abstractmethod
class MyAbstract(ABC):
@abstractmethod
def my_method(self):
pass
Monkey patching in Python is the practice of modifying or extending existing classes or functions at runtime. It allows you to change behavior without altering the original code, commonly used for bug fixes or adding features.
class MyClass:
def greet(self):
print("Hello!")
# Monkey patching the greet method
MyClass.greet = lambda self: print("Hello, World!")
obj = MyClass()
obj.greet() # Output: Hello, World!
- repr(): Returns a string that represents the object, used for debugging.
- str(): Returns a user-friendly string representation of the object.
Context managers in Python manage resources like files or connections using setup and teardown actions. They are used with the with statement to ensure resources are properly handled.
How to implement:
- Using __enter__ and __exit__ methods.
- Using contextlib.contextmanager for simpler implementations.
from contextlib import contextmanager
@contextmanager
def my_context():
print("Entering context")
yield
print("Exiting context")
with my_context():
print("Inside context")
The __call__ method in Python allows an instance of a class to be called like a function. When an object with a __call__ method is called, it executes that method.
Key Points:
- Defines callable behavior for class instances.
- Can accept arguments just like a regular function.
The __call__ method in Python allows an instance of a class to be called like a function. When an object with a __call__ method is called, it executes that method.
class MyClass:
def __call__(self, x):
return x * 2
obj = MyClass()
print(obj(5)) # Output: 10
Here, obj is treated like a function due to the __call__ method.
Decorators in Python are functions that modify the behavior of other functions or methods. They take a function as input and return a new function that enhances or changes its behavior.
def decorator(func):
def wrapper():
print("Before")
func()
print("After")
return wrapper
@decorator
def greet():
print("Hello!")
greet()
The super() function in Python is used to call methods from a parent class in a subclass, enabling access to inherited methods without directly referencing the parent class.
Example:
class Parent:
def greet(self):
print("Hello from Parent")
class Child(Parent):
def greet(self):
super().greet() # Calls Parent's greet
print("Hello from Child")
child = Child()
child.greet()
Output:
Hello from Parent
Hello from Child
Python implements hashing using the __hash__ method, which returns an integer value used to uniquely identify objects in hash-based collections like sets and dictionaries.
Key Points:
- __hash__: Every object that needs to be hashable must implement this method, which returns a fixed-size integer.
- Immutability: Hashable objects must be immutable (e.g., tuples, strings) because their hash value should remain constant.
- Equality: If two objects are equal (__eq__), they must have the same hash value.
class MyClass:
def __hash__(self):
return hash((self.x, self.y))
obj = MyClass(1, 2)
print(hash(obj))
Python's built-in weakref objects allow you to reference objects without preventing them from being garbage collected. This is useful when you want to keep references to objects but don't want those references to affect their lifetime.
Key Points:
- weakref module: Provides tools to create weak references.
- Weak References: Do not increase the reference count of an object, allowing it to be collected by garbage collection when no strong references exist.
- Use Cases: Commonly used in caches, registries, or listeners where objects should be automatically removed when no longer needed.
import weakref
class MyClass:
pass
obj = MyClass()
weak_obj = weakref.ref(obj)
print(weak_obj()) # Accesses the object through the weak reference
Once obj is deleted, weak_obj() will return None.
Method Resolution Order (MRO) in Python determines the order in which classes are searched for methods and attributes, especially in multiple inheritance.
Key Points:
- Python uses the C3 Linearization algorithm.
- The mro() method or __mro__ attribute shows the MRO.
class D(B, C):
pass
print(D.mro()) # Prints MRO of D
Output
[<class 'D'>, <class 'B'>, <class 'C'>, <class 'A'>, <class 'object'>]
The difference between __getattr__ and __getattribute__:
- __getattribute__: Called for every attribute access, including missing ones.
- __getattr__: Called only when an attribute is missing.
class MyClass:
def __getattribute__(self, name):
return super().__getattribute__(name) # Called for all attributes
def __getattr__(self, name):
return "default" # Called for missing attributes
obj = MyClass()
Python manages multiple inheritance using the C3 Linearization algorithm to determine the Method Resolution Order (MRO). It ensures a consistent and predictable order for method and attribute lookup.
class D(B, C):
pass
print(D.mro()) # Shows the method resolution order
This avoids conflicts in method resolution when multiple parent classes are involved.
.pyc files are compiled bytecode versions of Python source files. They improve performance by allowing Python to skip recompiling the source code when the program is run.
- Stored in the __pycache__ folder.
- Automatically generated when a .py file is imported.
- Module: A single file containing Python code, such as functions, classes, or variables.
# math_module.py
def add(a, b):
return a + b
- Package: A collection of modules, typically in a directory, which can contain subdirectories (sub-packages) and an __init__.py file to define it as a package.
math_package/
__init__.py
add_module.py
subtract_module.py
__main__ allows a Python script to behave as both a reusable module and a standalone script.
Code inside the if __name__ == "__main__": block runs when the script is executed directly, but not when it's imported as a module.
def greet():
print("Hello!")
if __name__ == "__main__":
greet() # Runs only if the script is executed directly
async: Defines a function as asynchronous (coroutine), enabling non-blocking operations.
await: Pauses the coroutine execution until the awaited function completes, allowing other tasks to run during the wait.
import asyncio
async def say_hello():
await asyncio.sleep(1) # Simulate async operation
print("Hello!")
asyncio.run(say_hello())
The futures module provides a high-level interface for asynchronously executing tasks using threads or processes.
It enables concurrent execution of code by submitting tasks to be run asynchronously, simplifying multi-threading or multi-processing.
from concurrent.futures import ThreadPoolExecutor
def square(x):
return x * x
with ThreadPoolExecutor() as executor:
result = executor.submit(square, 5)
print(result.result()) # Output: 25
lru_cache is a decorator that caches the results of expensive function calls.
It stores results in a Least Recently Used (LRU) cache, automatically discarding the least recently used results when the cache exceeds a specified size, improving performance by avoiding redundant computations.
from functools import lru_cache
@lru_cache(maxsize=3)
def expensive_function(x):
print("Calculating...")
return x * x
print(expensive_function(5)) # Calculating... 25
print(expensive_function(5)) # Uses cached value: 25
Python 2: Uses except Exception, e: syntax.
Python 3: Uses except Exception as e: syntax.
Other Difference: In Python 3, exceptions are more consistently handled as objects, and BaseException is the base class for all exceptions.
Python 2:
try:
# code
except Exception, e:
print(e)
Python 3:
try:
# code
except Exception as e:
print(e)
Use dynamic programming to create a 2D table for storing subsequences and find the longest common one.
def lcs(X, Y):
dp = [[0] * (len(Y) + 1) for _ in range(len(X) + 1)]
for i in range(len(X)):
for j in range(len(Y)):
dp[i+1][j+1] = dp[i][j] + 1 if X[i] == Y[j] else max(dp[i+1][j], dp[i][j+1])
return dp[len(X)][len(Y)]
print(lcs("AGGTAB", "GXTXAYB"))
Use queue.Queue and create producer and consumer threads that interact through this queue.
import threading, queue, time
buffer = queue.Queue(5)
def producer():
for i in range(5): buffer.put(i); time.sleep(1)
def consumer():
for _ in range(5): print(buffer.get()); time.sleep(2)
threading.Thread(target=producer).start()
threading.Thread(target=consumer).start()
Use requests to fetch content and BeautifulSoup to parse HTML and extract data.
import requests
from bs4 import BeautifulSoup
soup = BeautifulSoup(requests.get("https://example.com").text, 'html.parser')
print(soup.title.text)
Implement the __enter__ and __exit__ methods in a class to manage resources.
class MyContextManager:
def __enter__(self): return self
def __exit__(self, exc_type, exc_val, exc_tb): pass
with MyContextManager(): print("Inside")
Define a metaclass that ensures only one instance of the class is created.
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class Singleton(metaclass=SingletonMeta): pass
print(Singleton() is Singleton())
Use file hashes (e.g., hashlib.md5) to compare file content and delete duplicates.
import os, hashlib
def find_duplicates(directory):
files = {}
for file in os.listdir(directory):
path = os.path.join(directory, file)
hash_val = hashlib.md5(open(path, 'rb').read()).hexdigest()
if hash_val in files: os.remove(path)
else: files[hash_val] = path
find_duplicates('/path')
Use itertools.permutations to generate all permutations.
import itertools
print(list(itertools.permutations([1, 2, 3])))
Create a DP table that stores the maximum value for each weight capacity and return the result.
def knapsack(w, v, c):
dp = [[0] * (c + 1) for _ in range(len(w) + 1)]
for i in range(1, len(w) + 1):
for j in range(c + 1):
dp[i][j] = max(dp[i-1][j], v[i-1] + dp[i-1][j-w[i-1]] if w[i-1] <= j else 0)
return dp[len(w)][c]
print(knapsack([1, 2, 3], [10, 20, 30], 5))
Use a generator function that yields rows from the CSV file one at a time.
import csv
def read_csv(filename):
with open(filename, 'r') as f:
for row in csv.reader(f): yield row
for row in read_csv('file.csv'): print(row)
Define a class with __iter__ and __next__ to return Fibonacci numbers.
class Fibonacci:
def __init__(self): self.a, self.b = 0, 1
def __iter__(self): return self
def __next__(self):
self.a, self.b = self.b, self.a + self.b
return self.a
for num in Fibonacci(): print(num)
Use zipfile.ZipFile to create a zip archive and add files to it.
import zipfile
def compress_files(file_list, zip_name):
with zipfile.ZipFile(zip_name, 'w') as zipf:
for file in file_list:
zipf.write(file)
compress_files(['file1.txt', 'file2.txt'], 'archive.zip')
Use OrderedDict to maintain the order of items and evict the least recently used one.
from collections import OrderedDict
class LRUCache:
def __init__(self, capacity):
self.cache = OrderedDict()
self.capacity = capacity
def get(self, key):
if key not in self.cache: return -1
self.cache.move_to_end(key)
return self.cache[key]
def put(self, key, value):
if key in self.cache: self.cache.move_to_end(key)
self.cache[key] = value
if len(self.cache) > self.capacity:
self.cache.popitem(last=False)
cache = LRUCache(2)
cache.put(1, 1)
cache.put(2, 2)
print(cache.get(1)) # Returns 1
cache.put(3, 3) # Removes key 2
Use time.time() to capture start and end times and compute the duration.
import time
def time_decorator(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
print(f'Execution time: {time.time() - start} seconds')
return result
return wrapper
@time_decorator
def example_function():
time.sleep(2)
example_function()
Compare the string with its reverse using slicing (string == string[::-1]).
def is_palindrome(s):
return s == s[::-1]
print(is_palindrome("madam")) # True
Use asyncio to manage connections, handle client communication asynchronously.
import asyncio
async def handle_client(reader, writer):
data = await reader.read(100)
message = data.decode()
addr = writer.get_extra_info('peername')
print(f"Received {message} from {addr}")
writer.write(data)
await writer.drain()
writer.close()
async def main():
server = await asyncio.start_server(handle_client, '127.0.0.1', 8888)
async with server:
await server.serve_forever()
asyncio.run(main())
Use sqlite3 to connect, create tables, insert, update, and delete records.
import sqlite3
def create_table():
conn = sqlite3.connect('example.db')
c = conn.cursor()
c.execute('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)')
conn.commit()
conn.close()
Define a Node class with methods for inserting and deleting nodes.
class Node:
def __init__(self, key):
self.left = self.right = None
self.value = key
Use requests.get() to fetch data and response.json() to parse JSON.
import requests
response = requests.get('https://jsonplaceholder.typicode.com/posts')
data = response.json()
print(data[0])
Use a priority queue to store the shortest paths and update distances iteratively.
import heapq
def dijkstra(graph, start):
heap = [(0, start)]
dist = {start: 0}
while heap:
(cost, node) = heapq.heappop(heap)
for neighbor, weight in graph[node]:
new_cost = cost + weight
if neighbor not in dist or new_cost < dist[neighbor]:
dist[neighbor] = new_cost
heapq.heappush(heap, (new_cost, neighbor))
return dist
Use watchdog to monitor file changes and trigger events.
import os import time
def monitor_directory(path):
before = dict([(f, None) for f in os.listdir(path)])
while True:
time.sleep(1)
after = dict([(f, None) for f in os.listdir(path)])
added = [f for f in after if f not in before]
removed = [f for f in before if f not in after]
if added: print(f"Added: {', '.join(added)}")
if removed: print(f"Removed: {', '.join(removed)}")
before = after
Use threading to create multiple threads for downloading files concurrently.
import threading
import requests
def download_file(url):
response = requests.get(url)
with open(url.split("/")[-1], 'wb') as f:
f.write(response.content)
urls = ['http://example.com/file1', 'http://example.com/file2']
threads = [threading.Thread(target=download_file, args=(url,)) for url in urls]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
Use a recursive function that tries different values and backtracks if a constraint is violated.
def is_valid(board, row, col, num):
# Checks rows, columns, and 3x3 grid for validity
return True
def solve_sudoku(board):
for row in range(9):
for col in range(9):
if board[row][col] == 0:
for num in range(1, 10):
if is_valid(board, row, col, num):
board[row][col] = num
if solve_sudoku(board): return True
board[row][col] = 0
return False
return True
Use pickle.dump() to serialize and pickle.load() to deserialize objects.
import pickle
def serialize(obj, filename):
with open(filename, 'wb') as f:
pickle.dump(obj, f)
def deserialize(filename):
with open(filename, 'rb') as f:
return pickle.load(f)
Define a Node class and a Stack class with methods like push and pop.
class Node:
def __init__(self, value):
self.value = value
self.next = None
class Stack:
def __init__(self):
self.top = None
def push(self, value):
node = Node(value)
node.next = self.top
self.top = node
def pop(self):
if self.top:
value = self.top.value
self.top = self.top.next
return value
return None
Use ftplib.FTP to connect and use storbinary to upload files.
from ftplib import FTP
def upload_file(ftp, filename):
with open(filename, 'rb') as f:
ftp.storbinary(f'STOR {filename}', f)
Use schedule or APScheduler to define and run recurring tasks at specific intervals.
from apscheduler.schedulers.background import BackgroundScheduler
import time
def job():
print("Job running!")
scheduler = BackgroundScheduler()
scheduler.add_job(job, 'interval', seconds=5)
scheduler.start()
try:
while True:
time.sleep(1)
except (KeyboardInterrupt, SystemExit):
scheduler.shutdown()
Use eval() or ast.literal_eval() for safe evaluation of mathematical expressions.
def eval_expr(expr):
return eval(expr)
print(eval_expr("3 + 5 * 2"))
Use pyflakes or pylint to check for syntax errors and output line numbers.
import ast
try:
with open('example.py', 'r') as file:
ast.parse(file.read())
print("No syntax errors found.")
except SyntaxError as e:
print(f"Syntax error: {e}")
Use pycryptodome to implement AES encryption and decryption.
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
cipher = AES.new(key, AES.MODE_CBC)
ciphertext = cipher.encrypt(pad(plaintext.encode(), AES.block_size))
decrypted = unpad(cipher.decrypt(ciphertext), AES.block_size).decode()
Use Flask to define endpoints for user registration, login, and CRUD operations on user data.
from flask import Flask, request, jsonify
app = Flask(__name__)
users = {}
@app.route('/users', methods=['POST']) # create, get, update, delete user
