# Buggy code
def decide_series_chunk_size(shape, chunk_size, memory_usage):
    from ..config import options

    chunk_size = dictify_chunk_size(shape, chunk_size)
    average_memory_usage = memory_usage / shape[0] if shape[0] != 0 else memory_usage

    if len(chunk_size) == len(shape):
        return normalize_chunk_sizes(shape, chunk_size[0])

    max_chunk_size = options.chunk_store_limit
    series_chunk_size = max_chunk_size / average_memory_usage
    return normalize_chunk_sizes(shape, int(series_chunk_size))


# Traceback (ZeroDivisionError)
In [1]: import mars.dataframe as md

In [2]: import pandas as pd

In [4]: md.Series(pd.Series([], dtype=object)).execute()
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-4-665db81dbad7> in <module>
----> 1 md.Series(pd.Series([], dtype=object)).execute()

~/Workspace/mars/mars/core.py in execute(self, session, **kw)
641
642         if wait:
--> 643             return run()
644         else:
645             thread_executor = ThreadPoolExecutor(1)

~/Workspace/mars/mars/core.py in run()
637
638         def run():
--> 639             self.data.execute(session, **kw)
640             return self
641

~/Workspace/mars/mars/core.py in execute(self, session, **kw)
377
378         if wait:
--> 379             return run()
380         else:
381             # leverage ThreadPoolExecutor to submit task,

~/Workspace/mars/mars/core.py in run()
372         def run():
373             # no more fetch, thus just fire run
--> 374             session.run(self, **kw)
375             # return Tileable or ExecutableTuple itself
376             return self

~/Workspace/mars/mars/session.py in run(self, *tileables, **kw)
503         tileables = tuple(mt.tensor(t) if not isinstance(t, (Entity, Base)) else t
504                           for t in tileables)
--> 505         result = self._sess.run(*tileables, **kw)
506
507         for t in tileables:

~/Workspace/mars/mars/session.py in run(self, *tileables, **kw)
109             # set number of running cores
110             self.context.set_ncores(kw['n_parallel'])
--> 111             res = self._executor.execute_tileables(tileables, **kw)
112             return res
113

~/Workspace/mars/mars/utils.py in _inner(*args, **kwargs)
449         def _inner(*args, **kwargs):
450             with self:
--> 451                 return func(*args, **kwargs)
452
453         return _inner

~/Workspace/mars/mars/executor.py in execute_tileables(self, tileables, fetch, n_parallel, n_thread, print_progress, mock, compose, name)
859                 # build chunk graph, tile will be done during building
860                 chunk_graph = chunk_graph_builder.build(
--> 861                     tileables, tileable_graph=tileable_graph)
862                 tileable_graph = chunk_graph_builder.prev_tileable_graph
863                 temp_result_keys = set(result_keys)

~/Workspace/mars/mars/utils.py in _inner(*args, **kwargs)
449         def _inner(*args, **kwargs):
450             with self:
--> 451                 return func(*args, **kwargs)
452
453         return _inner

~/Workspace/mars/mars/tiles.py in build(self, tileables, tileable_graph)
346
347         chunk_graph = super().build(
--> 348             tileables, tileable_graph=tileable_graph)
349         self._iterative_chunk_graphs.append(chunk_graph)
350         if len(self._interrupted_ops) == 0:

~/Workspace/mars/mars/utils.py in _inner(*args, **kwargs)
449         def _inner(*args, **kwargs):
450             with self:
--> 451                 return func(*args, **kwargs)
452
453         return _inner

~/Workspace/mars/mars/tiles.py in build(self, tileables, tileable_graph)
260                     # for further execution
261                     partial_tiled_chunks = \
--> 262                         self._on_tile_failure(tileable_data.op, exc_info)
263                     if partial_tiled_chunks is not None and \
264                             len(partial_tiled_chunks) > 0:

~/Workspace/mars/mars/tiles.py in inner(op, exc_info)
299                     on_tile_failure(op, exc_info)
300                 else:
--> 301                     raise exc_info[1].with_traceback(exc_info[2]) from None
302         return inner
303

~/Workspace/mars/mars/tiles.py in build(self, tileables, tileable_graph)
240                 continue
241             try:
--> 242                 tiled = self._tile(tileable_data, tileable_graph)
243                 tiled_op.add(tileable_data.op)
244                 for t, td in zip(tileable_data.op.outputs, tiled):

~/Workspace/mars/mars/tiles.py in _tile(self, tileable_data, tileable_graph)
335         if any(inp.op in self._interrupted_ops for inp in tileable_data.inputs):
336             raise TilesError('Tile fail due to failure of inputs')
--> 337         return super()._tile(tileable_data, tileable_graph)
338
339     @enter_mode(build=True, kernel=True)

~/Workspace/mars/mars/tiles.py in _tile(self, tileable_data, tileable_graph)
199                 t._nsplits = o.nsplits
200         elif on_tile is None:
--> 201             tds[0]._inplace_tile()
202         else:
203             tds = on_tile(tileable_data.op.outputs, tds)

~/Workspace/mars/mars/core.py in _inplace_tile(self)
166
167     def _inplace_tile(self):
--> 168         return handler.inplace_tile(self)
169
170     def __getattr__(self, attr):

~/Workspace/mars/mars/tiles.py in inplace_tile(self, to_tile)
134         if not to_tile.is_coarse():
135             return to_tile
--> 136         dispatched = self.dispatch(to_tile.op)
137         self._assign_to([d.data for d in dispatched], to_tile.op.outputs)
138         return to_tile

~/Workspace/mars/mars/utils.py in _inner(*args, **kwargs)
449         def _inner(*args, **kwargs):
450             with self:
--> 451                 return func(*args, **kwargs)
452
453         return _inner

~/Workspace/mars/mars/tiles.py in dispatch(self, op)
117         else:
118             try:
--> 119                 tiled = op_cls.tile(op)
120             except NotImplementedError as ex:
121                 cause = ex

~/Workspace/mars/mars/dataframe/datasource/series.py in tile(cls, op)
60         memory_usage = raw_series.memory_usage(index=False, deep=True)
61         chunk_size = series.extra_params.raw_chunk_size or options.chunk_size
---> 62         chunk_size = decide_series_chunk_size(series.shape, chunk_size, memory_usage)
63         chunk_size_idxes = (range(len(size)) for size in chunk_size)
64

~/Workspace/mars/mars/dataframe/utils.py in decide_series_chunk_size(shape, chunk_size, memory_usage)
193
194     max_chunk_size = options.chunk_store_limit
--> 195     series_chunk_size = max_chunk_size / average_memory_usage
196     return normalize_chunk_sizes(shape, int(series_chunk_size))
197

ZeroDivisionError: division by zero

# Fixed code
def decide_series_chunk_size(shape, chunk_size, memory_usage):
    from ..config import options

    chunk_size = dictify_chunk_size(shape, chunk_size)
    average_memory_usage = memory_usage / shape[0] if shape[0] != 0 else memory_usage

    if len(chunk_size) == len(shape):
        return normalize_chunk_sizes(shape, chunk_size[0])

    if all(s == 0 for s in shape):
        # skip when shape is 0
        return tuple((s,) for s in shape)

    max_chunk_size = options.chunk_store_limit
    series_chunk_size = max_chunk_size / average_memory_usage
    return normalize_chunk_sizes(shape, int(series_chunk_size))