The Schema Diff
A medium Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- medium
- Seniority
- L4
- Asked in
- Lowe's
Problem
A release tool compares two versions of a service's numeric config, the old release d1 and the new release d2, to report how the settings drifted. Return a summary with three keys: 'added' for settings only in d2, 'removed' for settings only in d1, and 'changed' for settings both releases carry but with differing values. Map each changed setting to its old value, its new value, and how far it moved (new minus old); settings the two releases share unchanged are left out.
Two versions of the same config - what changed between them?
Example 1
Input:
d1 = {"port":8080,"timeout":30}, d2 = {"port":8443,"retries":3}Output:
{"added":{"retries":3},"removed":{"timeout":30},"changed":{"port":[8080,8443,363]}}Example 2
Input:
d1 = {"pool_size":10}, d2 = {"pool_size":10}Output:
{"added":{},"removed":{},"changed":{}}Worked solution and explanation
What this really tests
Under the release-drift costume this is key categorization across two dicts: every key is added, removed, changed, or unchanged, and you decide which by testing membership in both directions, then subtracting the values only where the keys overlap. Walk only d1 and every key that lives solely in d2 is invisible, so each addition silently vanishes. The trap that separates candidates is the shared key whose value never moved: report it and your diff invents edits that never happened, complete with a bogus zero delta.
Break down the requirements
Step 1: Compute added keys
Keys in d2 but not in d1. Map each such key to its d2 value.
Step 2: Compute removed keys
Keys in d1 but not in d2. Map each such key to its d1 value.
Step 3: Compute changed keys and the delta
Keys in both dicts whose values differ. Map each to [old_value, new_value, new_value - old_value]: the old value, the new value, and the signed amount it moved.
The solution
def dict_diff_keys(d1: dict, d2: dict) -> dict:
added = {key: value for key, value in d2.items() if key not in d1}
removed = {key: value for key, value in d1.items() if key not in d2}
changed = {}
for key, old_value in d1.items():
if key in d2 and d2[key] != old_value:
new_value = d2[key]
changed[key] = [old_value, new_value, new_value - old_value]
return {
'added': added,
'removed': removed,
'changed': changed,
}Common follow-up questions
- What if the values in `d1` and `d2` were themselves nested dicts? (Tests a recursive diff for deep comparison.)
- How would you apply this diff to turn `d1` into `d2`? (Tests writing a patch function from the diff output.)
- What if a changed value were a string, where `new - old` has no meaning? (Tests guarding the delta on numeric types only.)
- How would you keep an audit log of these diffs over time? (Tests versioned diff storage.)