Implement JSON parsing and HTTP integration tasks
Company: Stripe
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates proficiency in JSON parsing, file I/O, HTTP client integration, request/response handling, payload construction, mapping data between arrays (points to colors), and basic error handling.
Part 1: Parse and Return the First 10 Coordinate Strings
Constraints
- `0 <= len(json_text) <= 10^5`
- The JSON array may contain up to `10^4` items
- A valid point must be a JSON object with numeric `lat` and `lon` values
- Use standard Python numeric string conversion when formatting values
Examples
Input: '[{"lat": 37.7749, "lon": -122.4194}, {"lat": 37.7750, "lon": -122.4189}]'
Expected Output: ['37.7749,-122.4194', '37.775,-122.4189']
Explanation: Both points are valid, so both are returned. Note that `37.7750` becomes `37.775` after JSON parsing.
Input: '[{"lat":0,"lon":0},{"lat":1,"lon":-1},{"lat":2,"lon":-2},{"lat":3,"lon":-3},{"lat":4,"lon":-4},{"lat":5,"lon":-5},{"lat":6,"lon":-6},{"lat":7,"lon":-7},{"lat":8,"lon":-8},{"lat":9,"lon":-9},{"lat":10,"lon":-10},{"lat":11,"lon":-11}]'
Expected Output: ['0,0', '1,-1', '2,-2', '3,-3', '4,-4', '5,-5', '6,-6', '7,-7', '8,-8', '9,-9']
Explanation: There are 12 valid points, but only the first 10 should be returned.
Input: 'not json'
Expected Output: []
Explanation: Invalid JSON should be handled gracefully by returning an empty list.
Input: '[{"lat":1,"lon":2},{"lat":3},{"x":9},4,{"lat":5.5,"lon":6.5}]'
Expected Output: ['1,2', '5.5,6.5']
Explanation: Malformed entries are skipped; only valid points are formatted.
Input: '[]'
Expected Output: []
Explanation: An empty list produces an empty result.
Hints
- Use `json.loads` to turn the input text into Python objects.
- Collect valid points in order and stop once you have 10 of them.
Part 2: Simulate a POST Request Equivalent to cURL
Constraints
- `payload` is JSON-serializable
- `0 <= len(mock_responses) <= 10^4`
- Request matching must be exact
- Use canonical JSON with sorted keys and no extra spaces
Examples
Input: ('https://api.example.com/bikemap/render', 'TOKEN123', {'paths': [], 'mapStyle': 'light'}, {('POST', 'https://api.example.com/bikemap/render', 'Bearer TOKEN123', 'application/json', '{"mapStyle":"light","paths":[]}'): (200, '{"ok": true, "id": 7}')})
Expected Output: (200, {'ok': True, 'id': 7})
Explanation: The payload must be serialized canonically so it matches the mock request key.
Input: ('https://api.example.com/bikemap/render', 'BAD', {'mapStyle': 'dark', 'paths': []}, {('POST', 'https://api.example.com/bikemap/render', 'Bearer BAD', 'application/json', '{"mapStyle":"dark","paths":[]}'): (401, '{"error": "unauthorized"}')})
Expected Output: (401, {'error': 'unauthorized'})
Explanation: A non-2xx response is still returned because the response body is valid JSON.
Input: ('https://api.example.com/bikemap/render', 'MISSING', {'mapStyle': 'light', 'paths': []}, {})
Expected Output: (0, {'error': 'request failed'})
Explanation: If no exact request tuple exists in the mock server, the request is treated as failed.
Input: ('https://api.example.com/bikemap/render', 'TOKEN999', {'mapStyle': 'light', 'paths': []}, {('POST', 'https://api.example.com/bikemap/render', 'Bearer TOKEN999', 'application/json', '{"mapStyle":"light","paths":[]}'): (500, 'oops')})
Expected Output: (500, {'error': 'invalid json response'})
Explanation: The request matches, but the response body cannot be parsed as JSON.
Input: ('https://api.example.com/bikemap/render', 'E', {}, {('POST', 'https://api.example.com/bikemap/render', 'Bearer E', 'application/json', '{}'): (200, '{"received": true}')})
Expected Output: (200, {'received': True})
Explanation: An empty payload is serialized as `{}` and can still match successfully.
Hints
- Use `json.dumps(..., sort_keys=True, separators=(",", ":"))` so that request matching is deterministic.
- Even if the status code is 401 or 500, you should still return it if the response body parses as valid JSON.
Part 3: Add Colors to Points, Build a New Payload, and Re-send
Constraints
- `points_json` represents up to `10^4` point objects
- `colors[i]` corresponds to the point at index `i`
- `base_payload` is JSON-serializable
- Canonical JSON serialization must use sorted keys and no extra spaces
Examples
Input: ('https://api.example.com/bikemap/render', 'TOKEN123', {'mapStyle': 'light'}, '[{"lat": 37.7749, "lon": -122.4194}, {"lat": 37.7750, "lon": -122.4189}]', ['red', 'blue'], {('POST', 'https://api.example.com/bikemap/render', 'Bearer TOKEN123', 'application/json', '{"mapStyle":"light","paths":[{"color":"red","lat":37.7749,"lon":-122.4194},{"color":"blue","lat":37.775,"lon":-122.4189}]}'): (201, '{"saved": true, "count": 2}')})
Expected Output: (201, {'saved': True, 'count': 2})
Explanation: The points are parsed, colors are attached by index, and the final request matches the mock server.
Input: ('https://api.example.com/bikemap/render', 'T', {'mapStyle': 'light'}, '[{"lat":1,"lon":2},{"lat":3,"lon":4}]', ['red'], {})
Expected Output: (0, {'error': 'color count mismatch'})
Explanation: There are two points but only one color.
Input: ('https://api.example.com/bikemap/render', 'T', {'mapStyle': 'light'}, 'oops', ['red'], {})
Expected Output: (0, {'error': 'invalid points'})
Explanation: The points input is not valid JSON.
Input: ('https://api.example.com/bikemap/render', 'T', {'mapStyle': 'dark'}, '[{"lat":1,"lon":2}]', ['green'], {})
Expected Output: (0, {'error': 'request failed'})
Explanation: The colored payload is valid, but no matching request exists in the mock server.
Input: ('https://api.example.com/bikemap/render', 'EMPTY', {'mapStyle': 'light'}, '[]', [], {('POST', 'https://api.example.com/bikemap/render', 'Bearer EMPTY', 'application/json', '{"mapStyle":"light","paths":[]}'): (200, '{"saved": true, "count": 0}')})
Expected Output: (200, {'saved': True, 'count': 0})
Explanation: An empty list of points and colors is valid and results in an empty `paths` array.
Hints
- First parse all points and verify that the number of colors matches the number of points.
- Build a new payload by copying `base_payload`, then overwrite its `paths` field with the colored point list.