AI Skill Report Card

Applying Software Principles

A-82·May 4, 2026·Source: Web

Quick Start

Python
# Before: Violates multiple principles class UserManager: def create_user(self, name, email): # Validation (should be separate) if not email or "@" not in email: print("Invalid email") # Breaks CQS return None # Database logic (should be separate) conn = sqlite3.connect("users.db") cursor = conn.cursor() cursor.execute("INSERT INTO users VALUES (?, ?)", (name, email)) conn.commit() conn.close() # Email logic (should be separate) smtp = smtplib.SMTP('localhost') smtp.send_message(f"Welcome {name}") smtp.quit() return True # After: Follows principles class UserValidator: def validate(self, email: str) -> bool: return email and "@" in email class UserRepository: def save(self, user: User) -> None: # Database implementation class EmailService: def send_welcome(self, user: User) -> None: # Email implementation class UserService: def __init__(self, validator: UserValidator, repo: UserRepository, email: EmailService): self._validator = validator self._repo = repo self._email = email def create_user(self, name: str, email: str) -> User: if not self._validator.validate(email): raise ValueError("Invalid email") user = User(name, email) self._repo.save(user) self._email.send_welcome(user) return user

Workflow

Progress:

  • Identify Violations: Scan for principle violations (long methods, mixed concerns, tight coupling)
  • Extract Responsibilities: Apply SRP - one reason to change per class
  • Define Interfaces: Use DIP - depend on abstractions, not concretions
  • Minimize Coupling: Apply Law of Demeter - avoid chaining calls
  • Separate Commands/Queries: CQS - methods either change state OR return data
  • Validate Substitution: Ensure LSP - derived classes work transparently
  • Refactor Incrementally: Boy Scout Rule - leave code cleaner

Examples

Example 1: DRY Violation Input:

Python
def calculate_tax_individual(income): return income * 0.2 if income > 50000 else income * 0.1 def calculate_tax_business(revenue): return revenue * 0.2 if revenue > 50000 else revenue * 0.1

Output:

Python
def calculate_tax(amount: float, threshold: float = 50000, high_rate: float = 0.2, low_rate: float = 0.1) -> float: return amount * high_rate if amount > threshold else amount * low_rate def calculate_tax_individual(income: float) -> float: return calculate_tax(income) def calculate_tax_business(revenue: float) -> float: return calculate_tax(revenue)

Example 2: SOLID Violation Input:

Python
class Report: def generate(self): data = self.fetch_data() # SRP violation formatted = self.format_data(data) # SRP violation self.save_to_file(formatted) # SRP violation self.email_report(formatted) # SRP violation

Output:

Python
class DataFetcher: def fetch(self) -> List[Dict]: pass class ReportFormatter: def format(self, data: List[Dict]) -> str: pass class FileStorage: def save(self, content: str, path: str) -> None: pass class EmailService: def send(self, content: str, recipient: str) -> None: pass class ReportGenerator: def __init__(self, fetcher: DataFetcher, formatter: ReportFormatter, storage: FileStorage, email: EmailService): self._fetcher = fetcher self._formatter = formatter self._storage = storage self._email = email def generate(self, save_path: str, email_to: str) -> None: data = self._fetcher.fetch() formatted = self._formatter.format(data) self._storage.save(formatted, save_path) self._email.send(formatted, email_to)

Best Practices

Design:

  • Start with interfaces/protocols before implementations
  • Favor composition over inheritance
  • Use dependency injection for testability
  • Keep public APIs minimal and stable

Implementation:

  • Methods should be 5-20 lines max
  • Classes should fit on one screen
  • Avoid deep nesting (max 3 levels)
  • Use meaningful names that explain intent

Refactoring:

  • Extract methods when you see duplication
  • Extract classes when methods don't belong together
  • Introduce interfaces when you see concrete dependencies
  • Use factory patterns for complex object creation

Common Pitfalls

Over-engineering:

  • Don't create abstractions until you need them (YAGNI)
  • Avoid "Enterprise FizzBuzz" - excessive patterns for simple problems

Coupling Issues:

  • Avoid God objects that know too much
  • Don't chain method calls (obj.getA().getB().getC())
  • Resist the urge to make everything public

Premature Optimization:

  • Profile before optimizing
  • Optimize algorithms, not micro-optimizations
  • Remember: "Make it work, make it right, make it fast"

Testing Anti-patterns:

  • Don't test implementation details
  • Avoid mocking what you don't own
  • Test behavior, not state
0
Grade A-AI Skill Framework
Scorecard
Criteria Breakdown
Quick Start
15/15
Workflow
12/15
Examples
18/20
Completeness
19/20
Format
15/15
Conciseness
13/15