# Buggy code
def default(self, obj):
    """
    Accept an object (of unknown type) and try to encode with priority:
    1. builtin:     user-defined objects
    2. sage:        sage math cloud
    3. pandas:      dataframes/series
    4. numpy:       ndarrays
    5. datetime:    time/datetime objects

    Each method throws a NotEncoded exception if it fails.

    The default method will only get hit if the object is not a type that
    is naturally encoded by json:

        Normal objects:
            dict                object
            list, tuple         array
            str, unicode        string
            int, long, float    number
            True                true
            False               false
            None                null

        Extended objects:
            float('nan')        'NaN'
            float('infinity')   'Infinity'
            float('-infinity')  '-Infinity'

    Therefore, we only anticipate either unknown iterables or values here.

    """
    # TODO: The ordering if these methods is *very* important. Is this OK?
    encoding_methods = (
        self.encode_as_plotly,
        self.encode_as_sage,
        self.encode_as_numpy,
        self.encode_as_pandas,
        self.encode_as_datetime,
        self.encode_as_date,
        self.encode_as_list,  # because some values have `tolist` do last.
    )
    for encoding_method in encoding_methods:
        try:
            return encoding_method(obj)
        except NotEncodable:
            pass
    return json.JSONEncoder.default(self, obj)


# Traceback (TypeError)
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/plotly/plotly/plotly.py", line 241, in plot
res = _send_to_plotly(figure, **plot_options)
File "/Library/Python/2.7/site-packages/plotly/plotly/plotly.py", line 1374, in _send_to_plotly
cls=utils.PlotlyJSONEncoder)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 250, in dumps
sort_keys=sort_keys, **kw).encode(obj)
File "/Library/Python/2.7/site-packages/plotly/utils.py", line 145, in encode
encoded_o = super(PlotlyJSONEncoder, self).encode(o)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/Library/Python/2.7/site-packages/plotly/utils.py", line 211, in default
return json.JSONEncoder.default(self, obj)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: Decimal('-94.6285553000') is not JSON serializable

# Fixed code
def default(self, obj):
    """
    Accept an object (of unknown type) and try to encode with priority:
    1. builtin:     user-defined objects
    2. sage:        sage math cloud
    3. pandas:      dataframes/series
    4. numpy:       ndarrays
    5. datetime:    time/datetime objects

    Each method throws a NotEncoded exception if it fails.

    The default method will only get hit if the object is not a type that
    is naturally encoded by json:

        Normal objects:
            dict                object
            list, tuple         array
            str, unicode        string
            int, long, float    number
            True                true
            False               false
            None                null

        Extended objects:
            float('nan')        'NaN'
            float('infinity')   'Infinity'
            float('-infinity')  '-Infinity'

    Therefore, we only anticipate either unknown iterables or values here.

    """
    # TODO: The ordering if these methods is *very* important. Is this OK?
    encoding_methods = (
        self.encode_as_plotly,
        self.encode_as_sage,
        self.encode_as_numpy,
        self.encode_as_pandas,
        self.encode_as_datetime,
        self.encode_as_date,
        self.encode_as_list,  # because some values have `tolist` do last.
        self.encode_as_decimal,
    )
    for encoding_method in encoding_methods:
        try:
            return encoding_method(obj)
        except NotEncodable:
            pass
    return json.JSONEncoder.default(self, obj)