Ojasa Mirai

Ojasa Mirai

Python

Loading...

Learning Level

🟢 BeginneršŸ”µ Advanced
What are Variables?Numbers — Integers and FloatsNumber OperationsStrings — Creating and Using TextString FormattingBooleans and NoneType ConversionGetting User InputBest Practices
Python/Variables Data Types/Best Practices

šŸŽ“ Best Practices — Professional Variables & Type Handling

Professional Python code balances flexibility with clarity. Using type hints, following PEP 8, validating inputs, handling errors gracefully, and documenting types creates maintainable, debuggable applications. These practices become increasingly important in team environments and long-lived codebases.


šŸ“ Type Hints and Documentation

Type hints serve as executable documentation, enabling static type checking and IDE support.

from typing import Optional, Union, List, Dict, Callable

# Document parameter and return types
def process_user(
    user_id: int,
    include_details: bool = False
) -> Dict[str, Union[int, str, bool]]:
    """
    Process user and return user data.

    Args:
        user_id: User ID (must be positive)
        include_details: Include detailed information

    Returns:
        Dictionary with user data

    Raises:
        ValueError: If user_id <= 0
        UserNotFoundError: If user doesn't exist
    """
    if user_id <= 0:
        raise ValueError("user_id must be positive")
    # Implementation...

# Optional types (can be None)
def find_user(email: str) -> Optional[Dict]:
    # Could return dict or None
    pass

# Union types (multiple possibilities)
def convert_to_number(value: Union[str, int, float]) -> float:
    return float(value)

# Callable types
def apply_to_list(items: List[int], func: Callable[[int], int]) -> List[int]:
    return [func(item) for item in items]

# Use mypy for type checking
# pip install mypy
# mypy your_file.py

āœ… Input Validation and Error Handling

Always validate data at system boundaries (user input, external APIs, file I/O).

class ValidationError(Exception):
    """Raised when validation fails."""
    pass

def create_user(name: str, age: int, email: str) -> Dict:
    """Create user with validation."""
    # Type validation
    if not isinstance(name, str):
        raise TypeError("name must be string")
    if not isinstance(age, int):
        raise TypeError("age must be int")

    # Value validation
    if not name or len(name) < 2:
        raise ValidationError("name must be 2+ characters")
    if age < 0 or age > 150:
        raise ValidationError("age must be 0-150")
    if '@' not in email:
        raise ValidationError("invalid email")

    return {"name": name, "age": age, "email": email}

# Safe conversion with defaults
def safe_int(value, default=0) -> int:
    """Convert to int with fallback."""
    try:
        return int(value)
    except (ValueError, TypeError):
        return default

# Graceful error handling
try:
    user_data = create_user("Alice", "25", "alice@example.com")
except (TypeError, ValidationError) as e:
    print(f"Invalid user data: {e}")
    user_data = None

šŸ—ļø Advanced Patterns

# Dataclass for structured data (Python 3.7+)
from dataclasses import dataclass

@dataclass
class User:
    name: str
    age: int
    email: str

    def __post_init__(self):
        """Validate after initialization."""
        if len(self.name) < 2:
            raise ValueError("name must be 2+ characters")

# Use constants for magic values
class Config:
    MAX_RETRIES = 3
    TIMEOUT_SECONDS = 30
    DEFAULT_ENCODING = 'utf-8'

def api_call(url: str, retries: int = Config.MAX_RETRIES):
    """Make API call with retry logic."""
    pass

# Context manager for resource management
from contextlib import contextmanager

@contextmanager
def timer():
    """Context manager for timing code."""
    import time
    start = time.time()
    try:
        yield
    finally:
        elapsed = time.time() - start
        print(f"Elapsed: {elapsed:.2f}s")

with timer():
    # Code is timed
    pass

# Property for computed attributes
class Rectangle:
    def __init__(self, width: float, height: float):
        self.width = width
        self.height = height

    @property
    def area(self) -> float:
        """Compute area on demand."""
        return self.width * self.height

    @property
    def perimeter(self) -> float:
        """Compute perimeter on demand."""
        return 2 * (self.width + self.height)

šŸš€ Performance Considerations

# Use appropriate data structures
# Bad: searching list repeatedly
items = [1, 2, 3, 4, 5]
if 3 in items:  # O(n) operation
    pass

# Good: use set for membership testing
items_set = {1, 2, 3, 4, 5}
if 3 in items_set:  # O(1) operation
    pass

# String concatenation
# Bad: creates new strings repeatedly
result = ""
for item in items:
    result += str(item)

# Good: use join (single operation)
result = "".join(str(item) for item in items)

# Generator expressions for large datasets
# Bad: creates full list in memory
squares = [x**2 for x in range(1000000)]

# Good: generator (lazy evaluation)
squares_gen = (x**2 for x in range(1000000))

# Use __slots__ for memory efficiency
class Point:
    __slots__ = ['x', 'y']  # Fixed attributes
    def __init__(self, x, y):
        self.x = x
        self.y = y

šŸ“Š Testing and Verification

# Unit test for type handling
import unittest

class TestUserCreation(unittest.TestCase):
    def test_valid_user(self):
        user = create_user("Alice", 25, "alice@example.com")
        self.assertEqual(user['name'], "Alice")

    def test_invalid_age(self):
        with self.assertRaises(ValidationError):
            create_user("Alice", 200, "alice@example.com")

    def test_invalid_email(self):
        with self.assertRaises(ValidationError):
            create_user("Alice", 25, "invalid-email")

# Property-based testing
from hypothesis import given, strategies as st

@given(st.integers(min_value=0, max_value=150))
def test_age_validation(age):
    """Test age validation with random values."""
    user = create_user("Alice", age, "alice@example.com")
    assert user['age'] == age

āœ… Professional Checklist

āœ… Use type hints for all public functions
āœ… Follow PEP 8 style guide
āœ… Validate inputs at system boundaries
āœ… Handle errors gracefully
āœ… Document expected types and exceptions
āœ… Use appropriate data structures
āœ… Avoid mutable default arguments
āœ… Use constants for magic values
āœ… Test with various inputs
āœ… Use immutable objects when possible
āœ… Profile before optimizing
āœ… Document assumptions

šŸŽ“ You've Completed the Advanced Path!

Congratulations! You now understand:

  • āœ… Professional variable naming and conventions
  • āœ… Deep numeric types and operations
  • āœ… Advanced string operations and formatting
  • āœ… Boolean logic and short-circuit evaluation
  • āœ… Type checking and safe conversion
  • āœ… Duck typing and flexibility
  • āœ… Memory management and references
  • āœ… Professional best practices and patterns

You're now a Variables & Data Types expert! šŸš€


šŸ“š Next Steps

  • Explore **Functions** for advanced patterns
  • Study **Data Structures** for complex types
  • Learn **Testing** for quality assurance
  • Master **Design Patterns** for architecture

Ready to apply your knowledge? Try advanced challenges or take the quiz


Resources

Python Docs

Ojasa Mirai

Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.

Learn Deep • Build Real • Verify Skills • Launch Forward

Courses

PythonFastapiReactJSCloud

Ā© 2026 Ojasa Mirai. All rights reserved.

TwitterGitHubLinkedIn