JSON Serialization Challenge: Building a Custom Serializer
JSON (JavaScript Object Notation) is a ubiquitous data format used for data interchange. Python's built-in json module provides convenient tools for serializing Python objects into JSON strings and deserializing JSON strings back into Python objects. This challenge focuses on understanding the serialization process and building a simplified custom serializer for specific data types.
Problem Description
You are tasked with creating a function that serializes a Python dictionary containing various data types (strings, integers, floats, booleans, lists, and nested dictionaries) into a JSON string. However, you need to handle a specific custom data type: ComplexNumber. A ComplexNumber is represented as a tuple (real, imaginary). Your serializer should convert ComplexNumber objects into JSON-compatible dictionaries with keys "real" and "imaginary". The goal is to understand how Python's json module works and to implement a basic custom serialization strategy.
Key Requirements:
- The function must accept a Python dictionary as input.
- The dictionary may contain strings, integers, floats, booleans, lists, nested dictionaries, and
ComplexNumberobjects. ComplexNumberobjects must be serialized into dictionaries with "real" and "imaginary" keys.- All other data types should be serialized as they would be by the standard
json.dumps()function. - The function must return a JSON string representation of the input dictionary.
Expected Behavior:
The function should correctly serialize the input dictionary, handling all supported data types and converting ComplexNumber objects as specified. The output should be a valid JSON string.
Edge Cases to Consider:
- Empty dictionary as input.
- Dictionary containing only
ComplexNumberobjects. - Nested dictionaries and lists containing
ComplexNumberobjects. - Invalid input types (e.g., non-dictionary input). While the challenge doesn't require explicit error handling, the serializer should not crash.
Examples
Example 1:
Input: {"name": "Alice", "age": 30, "balance": 1234.56, "is_active": True, "complex": (5, -2)}
Output: {"name": "Alice", "age": 30, "balance": 1234.56, "is_active": true, "complex": {"real": 5, "imaginary": -2}}
Explanation: The input dictionary contains various data types, including a ComplexNumber. The ComplexNumber is correctly serialized into a dictionary with "real" and "imaginary" keys.
Example 2:
Input: {"data": [1, 2, ComplexNumber(3, 4), 5], "config": {"setting1": True, "setting2": ComplexNumber(0, 1)}}
Output: {"data": [1, 2, {"real": 3, "imaginary": 4}, 5], "config": {"setting1": true, "setting2": {"real": 0, "imaginary": 1}}}
Explanation: The input dictionary contains a list and a nested dictionary, both containing ComplexNumber objects. These are correctly serialized.
Example 3:
Input: {}
Output: {}
Explanation: An empty dictionary should be serialized to an empty JSON object.
Constraints
- The input dictionary will only contain strings, integers, floats, booleans, lists, nested dictionaries, and
ComplexNumberobjects. ComplexNumberobjects will always be represented as tuples of length 2.- The function must be able to handle dictionaries of reasonable size (up to 1000 key-value pairs).
- Performance is not a primary concern for this challenge; correctness is more important.
Notes
- You are allowed to use the standard
jsonmodule, but you must implement the custom serialization logic forComplexNumberobjects. - Consider using a custom encoder class with
json.dumps()to handle theComplexNumbertype. - Remember that JSON requires specific data type representations (e.g., Python
Truebecomes JSONtrue). - The
ComplexNumberclass is not provided; you can assume it exists and is represented as a tuple. For testing purposes, you can represent it as a tuple directly.