Working with Someone Else's Code

This document covers strategies for understanding and fixing problems in code written by others, including reading comments and tests, navigating large codebases, and practicing with open-source projects. Essential skills for maintaining unfamiliar code.

This document provides strategies for understanding and fixing problems in code written by others, covering techniques for reading unfamiliar code, leveraging comments and tests, navigating large codebases, and building skills through practice with open-source projects.


Introduction

In IT roles, fixing problems in code written by others is a common task. Whether working with open-source software or internal company projects, understanding unfamiliar code requires specific strategies and approaches. Developing these skills enables effective troubleshooting and maintenance of codebases regardless of original authorship.


Starting Points for Understanding Code

Reading Comments and Documentation

Well-documented code with clear comments provides the best starting point for understanding functionality. Comments explain the intent behind code decisions, document assumptions, and clarify complex logic.

Value of Good Comments

BenefitDescription
ContextExplains why code exists and what problem it solves
IntentClarifies what the code is trying to accomplish
AssumptionsDocuments preconditions and expected states
WarningsHighlights edge cases or potential issues

Improving Undocumented Code

When code lacks sufficient comments, adding them while reading serves dual purposes:

  • Solidifies understanding through articulation
  • Creates documentation for future reference
  • Benefits other developers who encounter the code later

Contributing comments back to original developers improves overall code quality and helps the broader community.


Learning from Tests

Understanding Function Expectations

Well-written tests serve as executable documentation showing:

  • Expected inputs and outputs
  • Valid use cases
  • Edge cases that should be handled
  • Error conditions and expected behavior

Test Analysis Strategy

1# Example: Understanding function behavior from tests
2def test_parse_config():
3    """Test reveals parse_config expects dict with 'host' and 'port' keys."""
4    config = parse_config('config.ini')
5    assert isinstance(config, dict)
6    assert 'host' in config
7    assert 'port' in config
8    assert isinstance(config['port'], int)

From this test, learn that:

  • Function returns dictionary
  • Dictionary must contain ‘host’ and ‘port’ keys
  • Port value must be integer

Writing Tests to Understand Code

ActionBenefit
Write missing testsForces understanding of expected behavior
Test edge casesReveals handling of unusual inputs
Add regression testsEnsures modifications don’t break functionality
Document with testsCreates living documentation

Reading Code Effectively

Small Projects Approach

For projects with hundreds of lines of code:

  • Read through entire codebase systematically
  • Follow execution flow from entry point
  • Note key functions and data structures
  • Identify architectural patterns

Large Projects Strategy

For codebases with thousands or tens of thousands of lines:

  • Focus on specific functions or modules related to the problem
  • Start with the function where error occurred
  • Trace backward through calling functions
  • Build understanding of relevant context only

Tracing Execution Flow

1Error Location (Starting Point)
23Calling Function
45Higher-Level Function
67Entry Point / Main Function

Working backward from the error helps understand the chain of events leading to the problem.


Code Navigation Techniques

Step-by-Step Approach

StepActionPurpose
1Identify error locationFind where problem manifests
2Read function containing errorUnderstand immediate context
3Find calling functionsTrace how function is invoked
4Examine data flowTrack how data reaches error point
5Understand dependenciesIdentify required modules and libraries
6Review configurationCheck settings affecting behavior

Tools for Code Navigation

 1# Grep for function calls
 2grep -r "function_name" .
 3
 4# Find function definitions
 5grep -rn "^def function_name" .
 6grep -rn "^function function_name" .  # For shell scripts
 7
 8# Find class definitions
 9grep -rn "^class ClassName" .
10
11# Use ctags for code navigation
12ctags -R .

Working Across Programming Languages

Language Familiarity Not Required

Fixing bugs in unfamiliar languages is possible when:

  • The logic error is identified through debugging
  • The problem and solution are well understood
  • Code patterns are recognizable
  • Syntax differences are minimal for the specific fix

Universal Programming Concepts

ConceptApplies Across Languages
VariablesStoring and manipulating data
FunctionsCode organization and reuse
ConditionalsBranching logic
LoopsIteration over data
Error handlingManaging exceptional conditions

Building Code Reading Skills

Practice Before Emergencies

Developing code reading skills proactively reduces stress when urgent fixes are needed.

Practical Exercises

ExerciseLearning Outcome
Trace web server configuration parsingUnderstand configuration file formats and validation
Analyze library data processingLearn API design and data transformation patterns
Study Python module internalsSee implementation details of familiar tools
Review open-source project structureUnderstand large-scale code organization

Example: Understanding Python Requests Module

1# Clone the repository
2git clone https://github.com/psf/requests.git
3cd requests
4
5# Find how response data is processed
6grep -rn "def json" requests/
7
8# Read the implementation
9less +/"def json" requests/models.py

Contributing to Open-Source Projects

Benefits of Open-Source Contribution

Participating in open-source projects provides:

  • Real-world practice reading unfamiliar code
  • Experience with collaborative development
  • Exposure to different coding styles and patterns
  • Portfolio of contributions demonstrating skills

Getting Started with Open-Source

StepAction
1Choose project actively used
2Review issue tracker for beginner-friendly issues
3Read contributing guidelines
4Set up development environment
5Fix simple issue
6Submit pull request
7Respond to feedback

Finding Beginner-Friendly Issues

Look for labels like:

  • good first issue
  • beginner-friendly
  • easy
  • starter
  • help wanted

Code Reading Workflow

Systematic Approach

 11. Read error message and traceback
 2 32. Locate error in source code
 4 53. Read function containing error
 6 74. Check function documentation and comments
 8 95. Review associated tests
10116. Trace backward through calling functions
12137. Examine data flow and transformations
14158. Identify root cause
16179. Implement fix
181910. Add or update tests

Practical Example

 1# Error: IndexError: list index out of range in process_items()
 2
 3def process_items(items):
 4    """Process list of items."""
 5    # Reading this function alone may not reveal the issue
 6    result = items[0]  # Line causing error
 7    return result
 8
 9# Need to trace backward to understand why empty list was passed
10def main():
11    items = load_items_from_file('data.txt')  # This function might return empty list
12    process_items(items)  # Called with empty list

Fix requires understanding both functions:

1def process_items(items):
2    """Process list of items."""
3    if not items:
4        raise ValueError("Items list cannot be empty")
5    result = items[0]
6    return result

Best Practices

When Reading Code

  • Take notes on key functions and their purposes
  • Draw diagrams of module relationships
  • Create simplified examples to test understanding
  • Add comments explaining non-obvious logic
  • Document assumptions discovered during reading

When Modifying Code

  • Run existing tests before making changes
  • Make small, incremental modifications
  • Test after each change
  • Add tests for new functionality
  • Update documentation to reflect changes
  • Preserve original coding style

Conclusion

Understanding and fixing code written by others is an essential skill in software development. Effective strategies include reading comments and documentation, analyzing tests, systematically tracing execution flow, and practicing with open-source projects. These skills improve with practice, making it valuable to proactively develop them before urgent fixes are required. Contributing improvements back to the original codebase benefits the broader community and enhances overall code quality.


FAQ