# Where the Line Breaks

> Every batch has a last piece. Mark it right.

Canonical URL: <https://datadriven.io/problems/where_the_line_breaks>

Domain: Python · Difficulty: easy · Seniority: L3

## Problem

Log entries stream in for a downstream consumer that accepts at most `n` at a time. Split the entries into ordered batches of `n`, tagging each batch with its position and whether it is the final one.

## Worked solution and explanation

### What this problem is really testing

On its face this is textbook chunking: slice the list every n elements. The real work is the `is_last` flag, and this is where careful candidates get burned. The tempting move is to mark a chunk last when it comes up short (`len(batch) < n`). That reads fine until the record count divides evenly by n: now every chunk is full, the size test never fires, and NOTHING gets flagged as last. The flag has to come from position (`i + n >= total`), not from size. Get it wrong and a downstream consumer waiting on `is_last` to flush never fires on a clean multiple, and the final batch quietly disappears.

---

### Break down the requirements

#### Step 1: Chunk the list into batches of size n

Use range with step n and list slicing, the standard chunking pattern. Slicing past the end is safe in Python, so the final short chunk needs no special case.

#### Step 2: Wrap each batch with its index and is_last flag

Track the batch index as you iterate, and compute is_last from position: the last batch is the one where `i + n` reaches or exceeds the total length. Do NOT infer it from the chunk's length.

#### Step 3: Handle empty input

An empty records list should return an empty list of batches, not a single empty batch. The range-with-step loop gives this for free: it never enters the loop body.

---

### The solution

**Chunking with index and terminal flag**

```python
def batch_with_metadata(records, n):
    result = []
    total = len(records)
    batch_index = 0
    for i in range(0, total, n):
        batch = records[i:i + n]
        is_last = (i + n) >= total
        result.append({
            'batch_index': batch_index,
            'records': batch,
            'is_last': is_last,
        })
        batch_index += 1
    return result
```

> **Time and Space Complexity**
>
> **Time:** O(len(records)). Each element is copied once during slicing.
> 
> **Space:** O(len(records)) for the output, since every record appears in exactly one batch wrapper.

**Size-based flag (wrong)**

is_last = len(batch) < n. On records=[1,2,3,4], n=2 both chunks are full, so is_last is False everywhere. No chunk is ever marked last.

**Position-based flag (correct)**

is_last = (i + n) >= total. On the same input the second chunk starts at i=2, and 2 + 2 >= 4, so it is correctly flagged last.

> **Common Pitfall**
>
> Deriving is_last from the chunk length instead of its position. It passes the ragged cases you eyeball first (5 records, n=2) and fails silently on exact multiples, which is exactly the case a hurried candidate does not test.

> **Interviewers Watch For**
>
> Clean separation between the chunking logic and the metadata wrapping. Candidates who conflate these into one tangled loop, or who reach for len(batch) to decide is_last, are harder to trust with production batching code.

---

## Common follow-up questions

- What if the caller also needs a total_batches count in each wrapper? _(Tests whether you can pre-compute the count using ceiling division before iterating.)_
- How would you stream batches to an API with retry logic? _(Tests knowledge of generator-based batching with error handling per batch.)_
- What if records arrive as a stream rather than a list? _(Tests iterator-based approaches where you cannot call len() upfront, so is_last can only be known by lookahead.)_

## Related

- [All practice problems](https://datadriven.io/problems)
- [Mock interview mode](https://datadriven.io/interview/where_the_line_breaks)
- [Python Interview Questions](https://datadriven.io/python-interview-questions)
- [Data Engineering Interview Prep Guide](https://datadriven.io/data-engineer-interview-prep)
- [Daily Challenge](https://datadriven.io/daily)

---

Source: DataDriven (https://datadriven.io). DataDriven is the data engineering interview community. Live code execution in SQL, Python, and Spark sandboxes. Every feature is open to every member.