1.4.12 · HinglishPython & Scientific Computing

Reading documentation and debugging

2,933 words13 min readRead in English

1.4.12 · AI-ML › Python & Scientific Computing

Overview

Documentation reading aur debugging wo meta-skills hain jo self-sufficient programmers ko un logon se alag karti hain jo stuck ho jaate hain. Tum nayi code likhne se zyada time docs padhne aur bugs fix karne mein lagaoge—in skills ko master karna tumhari productivity ko multiply kar deta hai.

Figure — Reading documentation and debugging

In skills ke bina, tum cooking seekhne ki jagah recipes yaad kar rahe ho.


Part 1: Documentation Ko Pro Ki Tarah Padhna

Maqsad memorize karna nahi hai—balki wo mental model extract karna hai jo library author ka tha.

The 80/20 Documentation Reading Strategy

Documentation ka 20% hissa wo 80% cheezein contain karta hai jo tumhe chahiye. Focus karo:

  1. Function signature line (name, params, return type)
  2. Pehla paragraph (ek-sentence purpose)
  3. Parameters section (har ek kya karta hai, types, defaults)
  4. Returns section (shape, type, edge cases)
  5. Examples section (usage patterns)

Step-by-step extraction:

  • Signature: 2 required args (start, stop), 4 optional
  • Purpose: "Return evenly spaced numbers over a specified interval" → Arithmetic sequence create karta hai, sirf range() nahi
  • Key params:
    • num=50: Kitne points chahiye (default 50)
    • endpoint=True: stop value include karo (vs. range() jo exclude karta hai)
    • retstep=False: Optionally spacing ∆x return karo
  • Returns: ndarray (agar retstep=False), ya tuple (array, step)
  • Mental model: range() ke unlike, ye endpoint include karta hai aur floats ke saath kaam karta hai

Ye step kyun? Signature + purpose tumhe batata hai is cheez ko kab use karo vs alternatives (range, arange, geomspace). Parameters control knobs for behavior dikhate hain.

Bura tarika: Google karo "python split keep delimiter" → Stack Overflow se copy karo → umeed karo kaam kare

Acha tarika:

  1. Broad shuru karo: Python string methods docs
  2. Method names scan karo: split, partition, rsplit, splitlines...
  3. partition check karo: "Pehli occurrence par split karo, 3-tuple return karo (before, sep, after)" → Delimiter rakhta hai! Lekin sirf pehli occurrence.
  4. re.split check karo: "Regex se split karo, maxsplit optional" → Parameter re.split(pattern, string, maxsplit=0, flags=0) → Lekin by default delimiters lose ho jaate hain...
  5. Aage padho: "Capturing groups in pattern bhi return hote hain" → re.split(r'(\d+)', 'a1b2c')['a', '1', 'b', '2', 'c']

Ye step kyun? Tum har variant ke liye ek decision tree banate ho, na ki sirf "split kaam karta hai".

Common Documentation Patterns

Ye formula kyun?

  • Purpose: Is tool ko kab use karein
  • Contracts: Tumhe kya provide karna hai, tumhe kya milega wapas
  • Edge cases: Kahan ye toot jaata hai ya surprising behavior karta hai
  • Alternatives: Similar functions ke bajaaye ye kyun

Kaise apply karo:

  1. Ek-line purpose padho → jawab do "Ye kaunsa problem solve karta hai?"
  2. Parameters check karo → jawab do "Main kya control karta hoon?"
  3. Returns check karo → jawab do "Mujhe kaisa shape/type milega wapas?"
  4. Examples padho → jawab do "Canonical usage kya hai?"
  5. 'See Also' scan karo → jawab do "Aur kya use kar sakta hoon instead?"

Mental model extraction:

  • Purpose: "DataFrame ko column(s) ke values se group karo, phir aggregate functions apply karo"
  • Contracts:
    • Input: Column name(s) ya function jo groups define kare
    • Output: DataFrameGroupBy object (lazy, .mean()/.sum()/etc. call karna zaroori hai)
  • Key parameter: as_index=True → group keys index ban jaate hain (vs column)
  • Edge case: Groups sirf un values ke liye banate hain jo data mein present hain—"empty" groups ka koi notion nahi. Lekin, dropna=True (default) ka matlab hai grouping key mein NaN wali rows completely exclude hoti hain; dropna=False set karo taaki wo apne alag group mein rahein. (Categorical grouping keys ke saath, observed parameter control karta hai ki unused categories dikhain ya nahi.)
  • Alternative: Crosstab-style aggregation ke liye pivot_table

Ye step kyun? Ab tum jaante ho groupby ek lazy object return karta hai (tumhe aggregate karna padega), ki as_index output structure control karta hai, aur ki dropna decide karta hai ki NaN keys survive hoti hain ya nahi—teen common confusion points.


Part 2: Systematic Debugging

Rookie ki galti: randomly code change karna aur ummeed karna kaam kare. Pro ka move: systematically search space narrow karna.

The Binary Search Debugging Strategy

First principles se derivation:

Agar tumhare program mein lines hain aur ek galat hai, to random search average mein checks leta hai. Lekin agar tum middle test karo, to aadha code eliminate ho jaata hai:

Kaise apply karo:

  1. Bad output location identify karo (line X galat value produce karta hai)
  2. Last good input identify karo (line Y par data sahi tha)
  3. Y aur X ke beech middle line Z check karo
  4. Agar Z galat hai → bug Y aur Z ke beech hai
  5. Agar Z sahi hai → bug Z aur X ke beech hai
  6. Recurse karo

Bug: Returns 0.0 for students = [{'name': 'Alice', 'score': 85}, ...]


**Symptom**: ~85 expected tha, mila 0.0

**Hypothesis 1**: Division by zero?
**Test**: `print(len(students))` → output 1, 0 nahi. Hypothesis refute hua.

**Hypothesis 2**: `total` 0 hai jab nahi hona chahiye?
**Test**: Division se pehle `print(total)` → output 0. Confirm! Bug accumulation mein hai.

**Hypothesis 3**: Loop kabhi chala hi nahi?
**Test**: Loop ke andar `print("Loop running")` → print hota hai. Loop chalta hai, lekin add nahi karta.

**Hypothesis 4**: `student['score']` exist nahi karta ya wrong type hai?
**Test**: `print(student, type(student['score']))` → `{'name': 'Alice', 'score': 85} <class 'int'>`. Data theek hai.

**AHA moment**: `total` initialization check karo... wo loop ke andar hai!
```python
for student in students:
    total = 0  # BUG: Har iteration mein 0 reset ho jaata hai!
    total += student['score']

Ye step kyun matter karta hai: Har test possibility space ka aadha eliminate karta hai. Systematic narrowing ke bina, tum random changes ke beech bhatkate rahoge.

The Stack Trace Reading Skill

Bottom-to-top padho:

  1. Exception type (last line): KeyError, TypeError, AttributeError, etc.
  2. Error message: Wo specific value/name jo fail hua
  3. Immediate location: File aur line jahan exception raise hua
  4. Call stack: Tum wahan kaise pahunche (function calls ka sequence)

Bottom-up analysis:

  • Exception: KeyError: 'price' → Dictionary mein 'price' key missing hai
  • Immediate cause: normalize() mein line 23 record['price'] try karta hai
  • Hum wahan kaise pahunche:
    • main.py:45 ne process_data(raw_data) call kiya
    • Jisne line 12 par clean_records(data) call kiya
    • Jisne line 67 par normalize(r) ko list-comprehend kiya
    • Jo ek specific record par crash hua

Hypothesis: raw_data mein koi ek record 'price' field nahi rakhta.

Ye step kyun? Stack trace tumhe exactly where (line 23) aur why (missing key), plus how (call chain) batata hai. Is free information ko ignore mat karo!

The Print-Driven Debugging Pattern

Kab use karo: Complex data transformations, unclear intermediate state

Kaise:

# BAD: Ek giant chain
result = df.groupby('category').apply(lambda x: x.sort_values('date').head(3)).reset_index(drop=True)
 
# GOOD: Steps mein todo, har ek print karo
step1 = df.groupby('category')
print("After groupby:", step1.groups.keys())
 
step2 = step1.apply(lambda x: x.sort_values('date').head(3))
print("After apply:\n", step2.head())
 
step3 = step2.reset_index(drop=True)
print("Final result:\n", step3)

Ye kyun kaam karta hai: Tum har stage par data transformation observe karte ho, pakad lo jahan wo expectation se alag ho jaata hai.

Goal: [1,2,3] ko ek 4x3 matrix ki har row mein add karo

matrix = np.array(10, 20, 30, [40, 50, 60], [70, 80, 90], [100, 110, 120]])

offset = np.array([1, 2, 3])

result = matrix + offset print(result)

Works! 11, 22, 33, [41, 52, 63], ...]

Ab [1, 2, 3, 4] ko har column mein add karo (alag offset per row)

offset_col = np.array([1, 2, 3, 4]) result2 = matrix + offset_col # ValueError: shape (4,3) + (4,) can't broadcast


**Debug process**:
1. **Shapes print karo**: `print(matrix.shape, offset_col.shape)` → `(4, 3)` aur `(4,)`
2. **Broadcasting rule samjho**: Dimensions right-to-left align hoti hain.
   - `(4, 3) + (3,)` kaam karta hai: last dims match hoti hain (3 == 3)
   - `(4, 3) + (4,)` fail hota hai: last dims match nahi hoti (3 ≠ 4)
3. **Fix**: Offset ko column vector `(4, 1)` mein reshape karo taaki wo columns ke across broadcast kare:
   ```python
   offset_col = offset_col.reshape(-1, 1)  # Ab (4, 1) hai
   result2 = matrix + offset_col  # Kaam karta hai! (4,3) + (4,1) → (4,3)

Ye step kyun? Shapes print karna geometric mismatch reveal karta hai, jo fix guide karta hai.


Common Mistakes & How to Fix Them

Kyun galat hai: Tum aisa behavior debug karne mein time waste karte ho jo documented hai. Example: list.sort() use karna aur expect karna ki sorted list return hogi, lekin ye None return karta hai (in-place sort). Docs ye immediately kehte hain.

Fix: Code likhne se pehle signature + parameters skim karo. Paanch minute ki reading ek ghante ki debugging bachati hai.

Kyun galat hai: Tum purane bugs dhundhne se zyada tezi se nayi bugs inject kar rahe ho. Tum track kho dete ho ki code kis state mein hai.

Fix: Ek cheez badlo aur test karo. Agar bug fix nahi hua, revert karo agle hypothesis try karne se pehle.

Kyun galat hai: Error message 80% time exactly bata deta hai kya galat hai. KeyError: 'price' matlab 'price' key exist nahi karti—ye precise hai!

Fix: Last line pehle padho (exception + message), phir trace karo upar kahan tumhare code mein. Agar unclear ho toh exception type + apna context Google karo.

Kyun galat hai: Assumptions hi wo jagah hai jahan bugs chhupte hain. Production data messy hoti hai, users creative hote hain, files move ho jaati hain.

Fix: Critical assumptions ke liye assert statements add karo:

def process_image(img_path):
    assert os.path.exists(img_path), f"Image not found: {img_path}"
    img = load_image(img_path)
    assert img.shape[2] == 3, f"Expected RGB, got shape {img.shape}"
    # ... baaki code

Active Recall Drills

Recall Feynman Explanation (12-Saal ke Bachche Ko Explain Karo)

Socho tumhe ek nayi video game mili hai lekin koi tutorial nahi hai. Tum:

  1. Random buttons mash kar sakte ho (guessing se debug karna)
  2. Manual padh sakte ho (documentation)
  3. Systematically try kar sakte ho: A press karo, dekho kya hota hai. B press karo, dekho kya hota hai. (Scientific debugging)

Documentation game manual ki tarah hai—ye batata hai har button kya karna chahiye. Debugging tab hoti hai jab tum A press karo aur kuch unexpected ho. Panic karne ki jagah:

  • Manual check karo: "Kya maine A button description galat padhi?"
  • Ek cheez test karo: "Kya A menu mein kaam karta hai? Battle mein? Sirf kabhi kabhi?"
  • Narrow karo: "Ye red item uthane ke baad break karta hai, toh bug item code mein hona chahiye."

Trick hai: ek cheez badlo aur test karo. Agar tum ek saath sab buttons mash karo, tumhe kabhi pata nahi chalega kaun sa button problem cause kiya!


Connections

  • 1.4.1-Python-basics-syntax-and-variables – Jahan tum pehli baar Python errors encounter karte ho
  • 1.4.5-File-IOand-CSV-handlingFileNotFoundError, PermissionError ka common source
  • 1.4.10-Introduction-to-matplotlib – Plotting parameters ke liye docs padhna
  • 1.7.2-Data-preprocessing-and-cleaning – Messy data pipelines debug karna
  • 2.3.4-Hyperparameter-tuning-grid-search-random-search – Model performance debug karna (kya ye bug hai ya bad hyperparameters?)

#flashcards/ai-ml

Documentation kaun si chaar key cheezein provide karti hai? :: API signature, Contracts (pre/postconditions), Edge cases, Examples

Documentation padhne ka 80/20 rule kya hai?
Focus karo: function signature, pehla paragraph, parameters section, returns section, aur examples par—inme 80% useful info hoti hai
Scientific debugging method ke 5 steps kya hain?
1. Symptom observe karo, 2. Hypothesis form karo, 3. Experiment design karo, 4. Experiment run karo, 5. Root cause milne tak repeat karo
Binary search debugging O(N) ki jagah O(log N) time kyun leta hai?
Har test remaining code ka aadha eliminate karta hai, isliye ek line tak narrow down karne ke liye log₂(N) tests chahiye
Python stack trace kaise padhna chahiye?
Bottom-top: 1. Exception type (last line), 2. Error message, 3. Immediate location (line number), 4. Call stack (tum wahan kaise pahunche)
Guessing se debug karne (random code changes) mein kya galat hai?
Tum purane bugs dhundhne se zyada tezi se nayi bugs inject karte ho, code state track kho dete ho, aur non-systematic exploration mein time waste hota hai
Bug fix karne ki koshish karne se pehle kya karna chahiye?
Error message completely padho (ye 80% time exactly bata deta hai kya galat hai), phir root cause ke baare mein hypothesis form karo
Print-driven debugging pattern kya hai?
Complex operations ko steps mein todo karo, har step ke baad intermediate state print karo, pakdo jahan data expectation se alag ho jaata hai
Documentation code likhne se pehle kyun padhni chahiye, break hone ke baad nahi?
Paanch minute ki reading ek ghante ki debugging bachati hai jo already documented behavior ki hoti (e.g., list.sort() None return karta hai)
pandas groupby mein dropna parameter kya control karta hai?
Kya grouping key mein NaN wali rows exclude hoti hain (dropna=True, default) ya apne alag group mein rakhi jaati hain (dropna=False). groupby sirf un values ke liye groups banata hai jo data mein actually present hain.
"Guessing se debug karne" ka fix kya hai?
Ek cheez badlo aur test karo. Agar kaam na kare, agle hypothesis try karne se pehle revert karo. Code state ka clear mental model maintain karo.

Concept Map

specifies

specifies

specifies

specifies

extract

focuses

finds right function in

guides

when reality differs

systematic method

prompts re-reading

connects

connects

connects

Read Documentation

Write Code

Debug

Mental Model

API Signature

Contracts

Edge Cases

Examples

80/20 Strategy

Search Strategy

Feedback Loop