Last active
June 25, 2025 11:58
-
-
Save paulbrodner/b7e8e095b702c6ba1fb9ddfa4fcfda33 to your computer and use it in GitHub Desktop.
Revisions
-
paulbrodner revised this gist
Jun 12, 2025 . 1 changed file with 202 additions and 204 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,273 +1,271 @@ # 🚀 Refined "Delete First, Code Last" Rules - Practical Edition > **Core Philosophy: Question every line of code. Prefer simplicity over cleverness, but don't sacrifice clarity for brevity.** ## 🎯 **The Golden Question** Before writing any code: **"What's the simplest way to solve this that I can still understand in 6 months?"** --- ## 🏆 **6 Practical Principles** (Guidelines, Not Laws) ### 1. **🔍 Question Abstractions - But Don't Avoid Them** **Guideline:** Create abstractions when they genuinely simplify understanding or prevent errors. ```python # ❌ Pointless wrapper class StringHelper: @staticmethod def get_length(s): return len(s) # ❌ Missing useful abstraction def process_order(order_data): # 50 lines of validation, calculation, and formatting # Should be broken down into conceptual chunks # ✅ Meaningful abstraction def process_order(order_data): validated_order = validate_order_data(order_data) calculated_totals = calculate_order_totals(validated_order) return format_order_response(calculated_totals) ``` **Test:** Does this abstraction represent a meaningful concept that could be explained to a domain expert? --- ### 2. **🧹 Eliminate True Duplication** **Guideline:** Consolidate identical logic, but similar-looking code isn't always duplication. ```python # ❌ True duplication - same logic, same purpose def validate_user_email(email): if not email or "@" not in email: raise ValueError("Invalid email") return email.lower().strip() def validate_admin_email(email): if not email or "@" not in email: raise ValueError("Invalid email") return email.lower().strip() # ✅ Consolidated def validate_email(email): if not email or "@" not in email: raise ValueError("Invalid email") return email.lower().strip() # ✅ Similar but NOT duplication - different purposes def format_display_name(name): return name.title().strip() def format_database_key(name): return name.lower().strip() ``` **Test:** Is the logic identical AND serving the same purpose? Only then consolidate. --- ### 3. **📁 Functions vs Classes - Context Matters** **Guideline:** Use functions for transformations, classes for stateful behavior and related operations. ```python # ❌ Class for simple data holding class UserSettings: def __init__(self, theme, language): self.theme = theme self.language = language # ✅ Simple data structure @dataclass(frozen=True) class UserSettings: theme: str language: str # ✅ Class justified - manages state and related operations class DatabaseConnection: def __init__(self, connection_string): self._connection = None self._connection_string = connection_string def connect(self): if not self._connection: self._connection = create_connection(self._connection_string) def execute(self, query): self.connect() return self._connection.execute(query) def close(self): if self._connection: self._connection.close() ``` **Test:** Does this need to maintain state between operations? If yes, consider a class. If no, use functions. --- ### 4. **⚡ Fail Fast - But Handle Gracefully** **Guideline:** Let exceptions bubble up for programmer errors, handle expected failures gracefully. ```python # ✅ Let programming errors bubble up def calculate_average(numbers): return sum(numbers) / len(numbers) # ZeroDivisionError is appropriate # ✅ Handle expected business failures def process_payment(amount, card_token): try: return payment_service.charge(amount, card_token) except PaymentDeclinedError as e: return PaymentResult(success=False, error=str(e)) # Let unexpected errors (network, auth) bubble up ``` **Test:** Is this an expected business scenario or a programming error? Handle business scenarios, let programming errors fail fast. --- ### 5. **🎯 Prefer Pure Functions - When Practical** **Guideline:** Use pure functions where possible, but don't contort your code to avoid necessary state. ```python # ✅ Pure function - easy to test and reason about def calculate_tax(amount, rate): return amount * rate # ✅ Necessary state - don't force this into pure functions class OrderProcessor: def __init__(self, tax_calculator, payment_service): self.tax_calculator = tax_calculator self.payment_service = payment_service def process_order(self, order): # Coordinates multiple services - state is justified tax = self.tax_calculator.calculate(order.amount) payment_result = self.payment_service.charge(order.amount + tax) return OrderResult(order, tax, payment_result) ``` **Test:** Can this logic work without external dependencies or state? If yes, make it pure. --- ### 6. **🗑️ The Contextual Delete Test** **Guideline:** Delete code that doesn't serve a clear purpose, but consider the full context. **Safe to Delete:** - Dead code (unreachable) - Obvious comments (`x = x + 1 # increment x`) - Trivial wrappers that don't add meaning - Unused imports (verified by tools) **Consider Context Before Deleting:** - Single-use functions (may represent important concepts) - Seemingly redundant checks (may prevent edge case bugs) - Comments explaining non-obvious business logic - Error handling that seems excessive **Delete Process:** 1. **Understand why it exists** - check git history, ask teammates 2. **Verify it's truly unused** - search codebase, check tests 3. **Comment it out first** - don't delete immediately 4. **Run full test suite** - including integration tests 5. **Monitor in production** - some code prevents rare edge cases --- ## 🎯 **Practical Implementation** ### **The 30-Second Rule:** Before writing code, spend 30 seconds considering: 1. **Does this already exist?** (standard library, existing function) 2. **Is this the simplest approach?** (not necessarily shortest) 3. **Will this be clear to future maintainers?** (including yourself) 4. **What could go wrong?** (edge cases, failure modes) ### **Balanced Metrics:** - ✅ **Cyclomatic complexity <15** per function (10 is ideal, but context matters) - ✅ **File length <500 lines** (split if much larger, but related code can stay together) - ✅ **Function parameters <7** (use objects for more, but don't force awkward groupings) - ✅ **Clear naming** (slightly longer names are fine if they're clearer) - ✅ **Good test coverage** (focus on critical paths, not 100% line coverage) ### **Code Smells (Investigate, Don't Auto-Delete):** - 🔍 Functions >50 lines - may need breakdown - 🔍 Classes with >10 methods - may have too many responsibilities - 🔍 Files importing >15 modules - may be doing too much - 🔍 Functions with >5 parameters - consider grouping - 🔍 Deeply nested conditions - consider early returns or extraction --- ## 🌟 **Practical Mantras** 1. **"Clear is better than clever"** 2. **"Simple is better than easy"** 3. **"Explicit is better than implicit"** 4. **"Readable code is maintainable code"** 5. **"Optimize for the reader, not the writer"** 6. **"Perfect is the enemy of good"** 7. **"Delete with purpose, not prejudice"** --- ## 🧪 **Weekly Code Review** **Every week, pick one area and ask:** 1. **What's confusing?** - simplify or document 2. **What's duplicated?** - consider consolidation 3. **What's unused?** - delete safely 4. **What's overly complex?** - break down or simplify 5. **What's missing?** - add needed abstractions 6. **What's fragile?** - add error handling or tests --- ## 🔄 **Balanced Before/After Template** ``` 📊 CHANGE ANALYSIS: ❌ BEFORE: [brief description of issue] ✅ AFTER: [brief description of solution] 📈 METRICS: - Lines: X → Y (Z% change) - Complexity: A → B - Test coverage: C → D 🎯 TRADE-OFFS: - Gained: [specific benefits] - Lost: [what was sacrificed, if anything] - Risk: [potential issues to monitor] 🔧 TECHNIQUE: [specific method used] ``` --- ## 🎪 **The Context Game** When tempted to apply a rule rigidly, ask: 1. **What's the goal?** (performance, maintainability, clarity) 2. **Who's the audience?** (junior devs, domain experts, future you) 3. **What's the risk?** (production failure, maintenance burden, confusion) 4. **What's the timeline?** (prototype, long-term system, migration) 5. **What are the constraints?** (team size, expertise, deadlines) **Remember: Rules are tools, not laws. Use judgment, not dogma.** --- ## 🎯 **The Ultimate Test** **Would you rather:** - Maintain 100 lines of crystal-clear code? - Maintain 50 lines of clever, terse code? - Maintain 150 lines of obvious, redundant code? **The answer depends on your team, timeline, and domain. Choose consciously.** -
paulbrodner created this gist
Jun 12, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,273 @@ # 🚀 Enhanced "Delete First, Code Last" Rules > **For AI: Always prioritize the Top 6 rules below. Before suggesting any code, ask "Can I delete something instead?" Apply the Delete Test to every function/class/file.** ## 🎯 **Golden Rule: "Can I delete this and still accomplish the goal?"** If YES → Delete it. If NO → Keep it. No exceptions. --- ## 🏆 **Top 6 Universal Principles** ### 1. **🔍 Question Every Abstraction** **Rule:** Don't create layers that just wrap simpler things. ```python # ❌ Unnecessary wrapper class DatabaseManager: def __init__(self, connection): self.connection = connection def execute(self, query): return self.connection.execute(query) # ✅ Direct and simple def execute_query(query: str, connection): return connection.execute(query) ``` **Test:** If your class has <3 methods or just stores data → use functions/primitives instead. --- ### 2. **🧹 Delete Redundant Code Immediately** **Rule:** Same logic in multiple places = consolidate to ONE place. ```python # ❌ Duplicate setup everywhere def process_users(): db = connect_db() setup_logging() create_directories() def process_orders(): db = connect_db() setup_logging() create_directories() # ✅ One setup function, used everywhere def setup_environment(): return connect_db(), setup_logging(), create_directories() ``` **Test:** Can you find identical/similar logic blocks? → Extract to utility function. --- ### 3. **📁 Functions Over Classes** **Rule:** Only use classes when they provide actual stateful behavior, not just data storage. ```python # ❌ Class that just holds data class UserData: def __init__(self, name, email): self.name = name self.email = email # ✅ Use simple data structures from dataclasses import dataclass @dataclass(frozen=True) # Immutable, simple class User: name: str email: str # Or even simpler def process_user(name: str, email: str): # Work directly with the data ``` **Test:** Does your class only store data and have getters/setters? → Use dataclass/struct/record instead. --- ### 4. **⚡ Exceptions Over Validation** **Rule:** Let language features handle errors instead of custom validation systems. ```python # ❌ Custom validation system def validate_file_exists(path): if os.path.exists(path): return True return False def read_file(path): if validate_file_exists(path): return open(path).read() return None # ✅ Let exceptions do the work def read_file(path): return Path(path).read_text() # Raises FileNotFoundError if missing ``` **Test:** Are you returning None/False and checking later? → Use exceptions instead. --- ### 5. **🎯 Data Transformation Over State Management** **Rule:** Pass data through pure functions instead of managing mutable state. ```python # ❌ Stateful, complex class OrderProcessor: def __init__(self): self.orders = [] self.processed = [] def add_order(self, order): self.orders.append(order) def process_all(self): for order in self.orders: processed = self.validate_and_process(order) self.processed.append(processed) # ✅ Pure functions, data flow def process_orders(orders: list) -> list: return [validate_and_process(order) for order in orders] def validate_and_process(order: dict) -> dict: # Transform and return new data return {**order, "status": "processed", "timestamp": time.now()} ``` **Test:** Can you eliminate mutable state and just transform data? → Use pure functions. --- ### 6. **🗑️ The Delete Test (Systematic Approach)** **Rule:** Before committing ANY code, try deleting each function/class/file systematically. **MANDATORY Process (prevents broken dependencies):** 1. **Dependency Audit:** Search codebase for ALL references to what you want to delete 2. **Comment out the code** (don't delete yet) 3. **Run tests/application** immediately 4. If nothing breaks → DELETE IT PERMANENTLY 5. If something breaks → Either fix the dependency OR restore the code **🚨 CRITICAL: Never delete data structures without checking ALL consumers** **Safe Delete Targets (low risk):** - Comments that explain obvious code - Unused imports (verified by IDE) - Functions used ≤1 times → inline them - Debug/logging statements - Redundant variable assignments **Risky Delete Targets (check dependencies first):** - Data fields in objects/dicts → verify no consumers - Function parameters → check all call sites - Return values → check all receivers - Classes with only `__init__` and getters → verify no external usage **Delete Order (safest first):** 1. Comments and documentation 2. Unused imports 3. Dead code (unreachable) 4. Single-use variables (inline) 5. Single-use functions (inline) 6. Data structure simplifications (AFTER dependency check) --- ## 🎯 **Implementation Guidelines** ### **The 5-Second Rule:** Before writing ANY code, spend 5 seconds asking: 1. **Built-in exists?** (standard library, language feature) 2. **Already exists?** (existing function, library) 3. **Used 3+ times?** (if not, inline it) 4. **Simplest way?** (avoid abstractions) 5. **Can delete instead?** (remove existing code) ### **Success Metrics:** - ✅ **Cyclomatic complexity <10** per function - ✅ **File length <200 lines** (split if larger) - ✅ **Function parameters <5** (use objects if more) - ✅ **Dependency count decreasing** over time - ✅ **Test-to-code ratio >1:1** (more test code than implementation) ### **Warning Signs (Delete Immediately):** - 🚨 Functions with >20 lines - break them down - 🚨 Classes with single responsibility violations - split or eliminate - 🚨 Files that import >10 modules - too many responsibilities - 🚨 Functions with >3 levels of nesting - flatten with early returns - 🚨 Variables that store computed values used once - inline the computation ### **⚠️ Danger Signs (Check Dependencies First):** - 🔥 Modifying data structure fields - audit ALL consumers - 🔥 Removing function parameters - verify ALL call sites - 🔥 Changing return types - check ALL receivers - 🔥 Deleting shared utilities - grep for ALL usage - 🔥 Simplifying APIs - ensure backward compatibility --- ## 🌟 **Universal Mantras** 1. **"The best code is no code"** 2. **"Transform data, don't manage state"** 3. **"Fail fast, fail explicit"** 4. **"Compose functions, don't inherit classes"** 5. **"Standard library over dependencies"** 6. **"Readable code over clever code"** 7. **"Early return over nested conditions"** --- ## 🧪 **The Daily Delete Challenge** **Every day, before writing new code:** 1. **Delete** one function (inline it) 2. **Eliminate** one class (use functions/data structures) 3. **Merge** one file (combine similar functionality) 4. **Remove** one dependency (use standard library) 5. **Flatten** one nested condition (use early returns) 6. **Inline** one intermediate variable 7. **Extract** one repeated code block --- ## 🎖️ **Achievement System** Track your progress: - 🗑️ **Deletionist**: Removed 100+ lines in one session - 🔥 **Simplifier**: Converted 3+ classes to functions - ⚡ **Inliner**: Eliminated 5+ single-use utility functions - 📦 **Minimalist**: Removed 3+ unnecessary dependencies - 🎯 **Consolidator**: Merged duplicate code from 3+ places - 🧹 **Flattener**: Eliminated 5+ levels of nested conditions - 💎 **Purist**: Converted stateful code to pure functions --- ## 🔄 **Mandatory Before/After Template** When making ANY change, always show: ``` ❌ BEFORE (X lines, Y complexity): [old complex code] ✅ AFTER (A lines, B complexity): [simplified code] 💡 IMPROVEMENT: - Removed Z lines (P% reduction) - Reduced complexity by Q points - Technique: [specific method used] - Benefits: [performance, maintainability, readability gains] ``` --- ## 🎲 **Random Deletion** Pick one daily: 1. **File Roulette**: Randomly pick a file, delete 10% of it 2. **Function Funeral**: Delete the longest function in your codebase 3. **Class Cremation**: Convert your most complex class to functions 4. **Dependency Detox**: Remove one external dependency 5. **Variable Vacation**: Inline 5 intermediate variables 6. **Comment Cemetery**: Delete comments that don't add value **The goal: Same functionality, significantly less code, higher quality.**