-
-
Notifications
You must be signed in to change notification settings - Fork 6
7 Advanced Coding Standards
- Introduction
- Language Preference
- File Naming and Organization
- Coding Style
- Functions and Modularity
- Log Handling
- Version Control
- Documentation
- Compatibility
- Security Considerations
- Code Review Process
- Version control
- Dependency Management
- Conclusion
Logicytics Coding Standards are designed to ensure consistency, readability, and maintainability throughout our codebase. These standards are crucial for collaborative development and long-term maintenance of Logicytics projects. Adhering to these practices ensures that our codebase remains clean, efficient, and easy to understand for all contributors.
Prefer Python, Batch, or PowerShell scripts for new additions:
- Python: Ideal for complex logic and integrations
- Batch: Suitable for simple Windows-specific tasks
- PowerShell: Good for advanced Windows automation
If using other languages:
- Ensure thorough documentation
- Translate to EXE for compatibility
Follow these guidelines:
- Place files in appropriate directories based on functionality
- Example structure:
Logicytics/
└── CODE/
| └── # Normal CODE #
└── MODS/
└── # CODE for MODS #
- Use
lowercase_with_underscores
naming convention (e.g.,my_script.py
)- If the file should be ignored by the script running, start the file with an underscore (e.g.,
_my_script.py
) - If the file is a library, start the file with
__lib_
(e.g.,__lib_class.py
)
- If the file should be ignored by the script running, start the file with an underscore (e.g.,
- Indentation: Use 4 spaces for each level of nesting
- Naming conventions:
- Variables:
lowercase_with_underscores
- Functions/Methods:
lowercase_with_underscores
- Classes:
CapitalizedWords
- Variables:
- Line length: Limit lines to 79 characters (maximum 150)
- Imports: Group imports alphabetically, separate standard library imports from project-specific ones
- Avoid unnecessary comments and print statements - Use
log.debug()
andlog.info()
instead ofprint()
Example:
import os
from typing import Dict, Any
import psutil
import json
def collect_system_info() -> Dict[str, Any]:
"""Collects system information."""
# Main logic
info = {
'os': os.name,
'cpu_count': os.cpu_count(),
'memory': psutil.virtual_memory().total / (1024 * 1024),
'disk_space': psutil.disk_usage('/').total / (1024 * 1024)
}
return info
if __name__ == "__main__":
system_info = collect_system_info()
print(json.dumps(system_info, indent=2))
- Use triple quotes for docstrings
- Explain function/class purpose, parameters, and return values
- Use inline comments sparingly to explain complex logic or non-obvious decisions
Example:
from typing import Dict, Any, List
from logicytics import Log, DEBUG
if __name__ == "__main__":
log = Log({"log_level": DEBUG})
def process_log_file(file_path: str) -> Dict[str, Any]:
"""
Processes a log file and extracts relevant information.
Args:
file_path (str): Path to the log file
Returns:
Dict[str, Any]: Extracted log information
Raises:
IOError: If the file cannot be read
ValueError: If the file content is invalid
"""
# We're using a try-except block here because file operations can raise exceptions
try:
with open(file_path, 'r') as file:
file.read()
# Complex parsing logic here...
parsed_log_info = parse_log_content()
return {"file_path": file_path, "content": parsed_log_info}
except IOError as e:
log.error(f"Error reading file: {e}")
raise
except ValueError as e:
log.warning(f"Invalid file content: {e}")
return {}
def parse_log_content() -> List[Dict[str, str]]:
"""Parses log content and returns structured data."""
# Implementation details...
pass
- Use built-in types like
str
,int
,dict
,list
- For complex types, use
typing
module (e.g.,List
,Dict
,Optional
) - You can also use
from __future__ import annotations
to use the|
operator for Union types
Example:
from __future__ import annotations
from typing import Dict, Optional, Any, Tuple
def analyze_process(process_id: int) -> Optional[Tuple[int, Dict[str, float]]] | None:
"""Analyzes a process and returns its details."""
process_details = get_process_details(process_id)
if not process_details:
return None
cpu_usage, memory_usage = calculate_resource_usage(process_details)
return process_id, {'cpu': cpu_usage, 'memory': memory_usage}
def get_process_details(process_id: int) -> Optional[Dict[str, Any]]:
"""Retrieves process details."""
# Implementation details...
return {'Process ID': process_id}
def calculate_resource_usage(details: Dict[str, Any]) -> Tuple[float, float]:
"""Calculates CPU and memory usage based on process details."""
# Implementation details...
return details['cpu_usage'], details['memory_usage']
- Keep functions focused on a single responsibility
- Use descriptive names for functions and variables
- Group related functionality into modules
- Aim for a maximum of 20-30 lines per function
- Use meaningful parameter names and avoid excessive parameters (>4)
Example:
import os
from datetime import datetime
import zipfile
def create_backup(Source_dir: str, backup_dir: str) -> str:
"""Creates a backup of the source directory."""
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
Backup_name = f"{os.path.basename(Source_dir)}_{timestamp}.zip"
backup_path = os.path.join(backup_dir, Backup_name)
zip_files(Source_dir, Backup_path)
return backup_path
def zip_files(source: str, destination: str) -> None:
"""Zips files from source to destination."""
with zipfile.ZipFile(destination, 'w', compression=zipfile.ZIP_DEFLATED) as zipf:
for root, _, files in os.walk(source):
for file in files:
file_path = os.path.join(root, file)
rel_path = os.path.relpath(file_path, source)
zipf.write(file_path, rel_path)
def verify_backup(backup_path: str) -> bool:
"""Verifies the integrity of a backup file."""
try:
with zipfile.ZipFile(backup_path, 'r') as zip_ref:
zip_ref.testzip()
return True
except zipfile.BadZipFile:
return False
# Usage
source_dir = "/path/to/source"
Backup_dir = "/path/to/backups"
Backup_path = create_backup(source_dir, Backup_dir)
if verify_backup(Backup_path):
print(f"Backup created successfully: {Backup_path}")
else:
print("Backup verification failed.")
- Use specific exception types where possible
- Provide meaningful error messages
- Handle potential exceptions gracefully
- Don't use
print()
- Uselog.error()
,log.warning()
andlog.critical()
instead - To raise exceptions, use
log.exception()
with your message and Exception class type, likelog.exception("Error Message", FileNotFoundError)
- Don't use
- Attempt to only import needed items from the
logicytics
module, don't use wildcard imports! Example:
import socket
from typing import Dict, Any
from logicytics import Log, DEBUG
if __name__ == "__main__":
log = Log({"log_level": DEBUG})
def collect_network_stats():
try:
# Network operations here
network_stats = {"network": "stats"} # Example
log.info("Network stats collected successfully.")
return network_stats
except socket.timeout:
log.error("Network timeout occurred. Retrying...")
return collect_network_stats()
except PermissionError:
log.error("Insufficient permissions to access network information.")
return None
except Exception as e:
log.critical(f"Unexpected error occurred: {e}")
raise
def process_user_input(input_data: str) -> Dict[str, Any]:
"""Processes user input and returns structured data."""
try:
parsed_input = parse_input(input_data)
validated_data = validate_input(parsed_input)
processed_result = process_validated_data(validated_data)
log.debug(f"Processed input: {input_data}")
return {"status": "success", "result": processed_result}
except ValueError as e:
log.warning(f"Invalid input: {e}")
return {"status": "error", "message": str(e)}
except Exception as e:
log.exception(f"Unexpected error during input processing: {e}", Exception)
raise
def parse_input(input_data: str) -> Dict[str, Any]:
"""Parses raw input into structured data."""
# Implementation details...
return {"parsed_data": input_data}
def validate_input(parsed_data: Dict[str, Any]) -> Dict[str, Any]:
"""Validates parsed input data."""
# Implementation details...
return {"validated_data": parsed_data}
def process_validated_data(validated_data: Dict[str, Any]) -> Dict[str, Any]:
"""Processes validated input data."""
# Implementation details...
return {"processed_data": validated_data}
-
Python Users: Utilize in-built class
__lib_class.py
for colored output and structured logging. Avoid usingprint()
; for newline characters, uselog.newline()
instead. -
Other Languages: Start messages with appropriate keywords (
INFO:
,WARNING:
,ERROR:
,CRITICAL:
) followed by the message. For example,"INFO: Your Message"
.
- Use Git for tracking changes
- Create feature branches for new features or bug fixes
- Use descriptive commit messages following the Conventional Commits format
- Include relevant issue numbers in commit messages when applicable
Example commit message:
feat: add support for multi-threaded processing
- Implement ThreadPoolExecutor for parallel task execution
- Add configuration option for thread count
- Update documentation with usage examples
Closes #123
- Maintain an up-to-date
README.md
file in the project root - Include information about:
- Project overview
- Installation instructions
- Usage examples
- Contributing guidelines
- License information
Example README.md
structure:
# Logicytics Project
A comprehensive toolkit for system analysis and automation.
## Table of Contents
- [Installation](#installation)
- [Usage](#usage)
- [Contributing](#contributing)
- [License](#license)
## Installation
To install Logicytics, follow these steps:
`git clone https://github.com/DefinetlyNotAI/Logicytics.git`
`pip install -r requirements.txt`
## Usage
Basic usage example:
"""
from logicytics import SystemAnalyzer
analyzer = SystemAnalyzer()
report = analyzer.generate_report()
print(report.summary())
"""
## Contributing
See our [CONTRIBUTING.md](CONTRIBUTING.md) file for details on how to contribute.
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
- Use docstrings for all modules, classes, functions, and methods
- Follow the Google Python Style Guide for docstring formatting
- Include information about parameters, return values, exceptions raised, and any side effects
Example module documentation:
"""
Module for handling network-related operations.
Classes:
NetworkInterface: Represents a network interface.
PacketSniffer: Sniffs packets on a given interface.
Functions:
get_network_interfaces(): Returns a list of available network interfaces.
ping_host(host: str): Pings a host and returns the result.
"""
from typing import List
class NetworkInterface:
"""Represents a network interface."""
def __init__(self, name: str):
"""
Initializes a NetworkInterface object.
Args:
name (str): Name of the network interface.
"""
self.name = name
def get_ip_address(self) -> str:
"""
Gets the IP address associated with this interface.
Returns:
str: The IP address of the interface.
Raises:
ValueError: If the interface doesn't have an IP address assigned.
"""
# Implementation details...
def get_network_interfaces() -> List[NetworkInterface]:
"""
Retrieves a list of available network interfaces.
Returns:
List[NetworkInterface]: A list of NetworkInterface objects representing available interfaces.
"""
# Implementation details...
def ping_host() -> bool:
"""
Pings a host and returns the result.
Returns:
bool: True if the host responds, False otherwise.
Raises:
socket.error: If there's a problem with the network connection.
"""
# Implementation details...
- Use inline comments sparingly to explain complex logic or non-obvious decisions
- Keep comments concise and relevant
- Update comments when modifying code to ensure they remain accurate
Example:
import zlib
from typing import Dict, Any
import json
def calculate_checksum(data: bytes) -> int:
"""
Calculates the checksum of the given data using CRC32 algorithm.
Args:
data (bytes): Data to calculate checksum for.
Returns:
int: The calculated checksum.
"""
# We're using zlib.crc32 here because it provides a fast and reliable CRC32 implementation
return zlib.crc32(data) & 0xffffffff
def parse_config(config_str: str) -> Dict[str, Any]:
"""
Parses a configuration string into a dictionary.
Args:
config_str (str): Configuration string in JSON format.
Returns:
Dict[str, Any]: Parsed configuration dictionary.
Raises:
json.JSONDecodeError: If the input string is not valid JSON.
"""
# We're using json.loads instead of eval for security reasons
# It safely parses JSON strings without executing arbitrary code
return json.loads(config_str)
- Ensure new additions don't break existing features
- Use version control tags to mark major releases
- Implement backwards compatibility for at least one minor version
- Document any breaking changes in release notes
Example of documenting breaking changes:
- Removed deprecated
old_function()
method. Usenew_method()
instead. - Changed default behavior of
process_data()
. Now requires explicitverbose=False
parameter for silent operation.
- Added support for parallel processing in
analyze_system()
- Introduced new
config_manager
class for centralized configuration management
- Fixed issue with incorrect timestamp parsing in
parse_log_file()
- Resolved memory leak in
continuous_monitoring()
function
- Always validate and sanitize user inputs
- Use whitelisting approach for allowed inputs
- Implement proper error handling for invalid inputs
Example:
import re
import bcrypt
def validate_username(username: str) -> bool:
"""
Validates a username against security criteria.
Args:
username (str): Username to validate.
Returns:
bool: True if the username is valid, False otherwise.
"""
pattern = r'^[a-zA-Z0-9_]{3,16}$'
return bool(re.match(pattern, username))
def create_user(username: str, password: str) -> dict:
"""
Creates a new user account.
Args:
username (str): Desired username.
password (str): Password for the new account.
Returns:
User: Created user object if successful, None otherwise.
Raises:
ValueError: If the username or password is invalid.
"""
if not validate_username(username):
raise ValueError("Invalid username")
if len(password) < 8:
raise ValueError("Password must be at least 8 characters long")
# Hash password before storing
hashed_password = hash_password(password)
return {username: hashed_password}
def hash_password(password: str) -> str:
"""
Hashes a password using bcrypt.
Args:
password (str): Password to hash.
Returns:
str: Hashed password string.
"""
salt = bcrypt.gensalt()
return str(bcrypt.hashpw(password.encode(), salt))
- Use secure methods for data encryption and decryption
- Implement proper key management practices
- Avoid hardcoding sensitive information in source code
Example:
from cryptography.fernet import Fernet
class SecureDataHandler:
def __init__(self, key: str):
self.key = key.encode()
def encrypt_data(self, data: str) -> str:
"""
Encrypts the given data using Fernet symmetric encryption.
Args:
data (str): Data to encrypt.
Returns:
str: Encrypted data as a URL-safe base64-encoded string.
"""
cipher_suite = Fernet(self.key)
cipher_text = cipher_suite.encrypt(data.encode())
return cipher_text.decode()
def decrypt_data(self, encrypted_data: str) -> str:
"""
Decrypts the given encrypted data.
Args:
encrypted_data (str): Encrypted data to decrypt.
Returns:
str: Decrypted data.
Raises:
ValueError: If the decryption fails.
"""
try:
cipher_suite = Fernet(self.key)
plain_text = cipher_suite.decrypt(encrypted_data.encode())
return plain_text.decode()
except Exception as e:
raise ValueError(f"Decryption failed: {e}")
# Usage example
handler = SecureDataHandler(str(Fernet.generate_key()))
secret_message = "This is a secret message"
encrypted_message = handler.encrypt_data(secret_message)
decrypted_message = handler.decrypt_data(encrypted_message)
assert secret_message == decrypted_message
Before submitting code for review:
- Run linters and formatters (
black .
) - Perform manual testing of new functionality
- Update documentation
- Ensure code adheres to coding standards
During code review:
- Focus on code quality, readability, and maintainability
- Check for adherence to coding standards
- Evaluate performance implications
- Assess security aspects
- Look for opportunities for refactoring or optimization
Example code review checklist:
# Code Review Checklist
## General
- Does the code follow Logicytics Coding Standards?
- Are all functions/classes properly documented?
## Performance
- Are there any obvious performance bottlenecks?
- Is memory usage optimized?
## Security
- Are inputs properly validated and sanitized?
- Are sensitive data handled securely?
## Testing
- Are appropriate unit tests included?
- Do tests cover edge cases?
## Architecture
- Does the code fit well with the overall project architecture?
- Are dependencies properly managed?
## Readability
- Is the code easy to understand?
- Are variable/function names descriptive?
## Comments
- Are comments clear and concise?
- Are complex logic parts commented?
## Error Handling
- Are exceptions handled appropriately?
- Are error messages informative?
## Documentation
- Is the README updated if necessary?
- Are any new APIs or interfaces documented?
## Best Practices
- Are design patterns used appropriately?
- Is the code DRY (Don't Repeat Yourself)?
## Suggestions
- Any suggestions for improvement or refactoring?
Use semantic versioning for Logicytics packages:
- MAJOR.MINOR.PATCH format
- Increment MAJOR for breaking changes
- Increment MINOR for new features
- Increment PATCH for bug fixes
Implement dependency security checks:
- Use tools like
pip-compile
orpoetry
for dependency management - Regularly update dependencies
- Scan for known vulnerabilities
The Logicytics Coding Standards document provides a comprehensive guide for developing high-quality, maintainable, and secure software. By following these guidelines, developers can ensure consistency across projects, improve code readability, and reduce potential bugs and security vulnerabilities.
Remember to regularly review and update these standards to reflect best practices and new technologies. Encourage team members to contribute to the evolution of these standards through continuous feedback and discussion.
By adhering to these coding standards, Logicytics aims to deliver exceptional software solutions while fostering a culture of excellence in software engineering.
This concludes the Logicytics Coding Standards document. Remember to adapt and expand these standards as needed for your specific projects and organizational requirements.
Wiki Last Updated on version 3.0.0
of Logicytics on day 07-12-2024
.
Basic update on version 3.1.0
on day 11-12-2024