# Buggy code
def execute(cls, ctx, op):
    a = ctx[op.inputs[0].key]
    xdf = pd if isinstance(a, (pd.DataFrame, pd.Series)) else cudf

    if op.sort_type == "sort_values":
        ctx[op.outputs[0].key] = res = execute_sort_values(a, op)
    else:
        ctx[op.outputs[0].key] = res = execute_sort_index(a, op)

    by = op.by
    add_distinct_col = (
        bool(int(os.environ.get("PSRS_DISTINCT_COL", "0")))
        or getattr(ctx, "running_mode", None) == RunningMode.distributed
    )
    if (
        add_distinct_col
        and isinstance(a, xdf.DataFrame)
        and op.sort_type == "sort_values"
    ):
        # when running under distributed mode, we introduce an extra column
        # to make sure pivots are distinct
        chunk_idx = op.inputs[0].index[0]
        distinct_col = (
            _PSRS_DISTINCT_COL
            if a.columns.nlevels == 1
            else (_PSRS_DISTINCT_COL,) + ("",) * (a.columns.nlevels - 1)
        )
        res[distinct_col] = np.arange(
            chunk_idx << 32, (chunk_idx << 32) + len(a), dtype=np.int64
        )
        by = list(by) + [distinct_col]

    n = op.n_partition
    if op.sort_type == "sort_values" and a.shape[op.axis] < n:
        num = n // a.shape[op.axis] + 1
        res = execute_sort_values(xdf.concat([res] * num), op, by=by)

    w = res.shape[op.axis] * 1.0 / (n + 1)
    slc = np.linspace(
        max(w - 1, 0), res.shape[op.axis] - 1, num=n, endpoint=False
    ).astype(int)
    if op.axis == 1:
        slc = (slice(None), slc)
    if op.sort_type == "sort_values":
        # do regular sample
        if op.by is not None:
            ctx[op.outputs[-1].key] = res[by].iloc[slc]
        else:
            ctx[op.outputs[-1].key] = res.iloc[slc]
    else:
        # do regular sample
        ctx[op.outputs[-1].key] = res.iloc[slc]


# Traceback (ZeroDivisionError)
Traceback (most recent call last):
File "/Users/wenjun.swj/miniconda3/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3417, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-6-f86c22f8381d>", line 1, in <module>
mdf[mdf[0] != 0].sort_values(0).execute()
File "/Users/wenjun.swj/Code/mars/mars/core.py", line 646, in execute
return run()
File "/Users/wenjun.swj/Code/mars/mars/core.py", line 642, in run
self.data.execute(session, **kw)
File "/Users/wenjun.swj/Code/mars/mars/core.py", line 379, in execute
return run()
File "/Users/wenjun.swj/Code/mars/mars/core.py", line 374, in run
session.run(self, **kw)
File "/Users/wenjun.swj/Code/mars/mars/session.py", line 505, in run
result = self._sess.run(*tileables, **kw)
File "/Users/wenjun.swj/Code/mars/mars/session.py", line 111, in run
res = self._executor.execute_tileables(tileables, **kw)
File "/Users/wenjun.swj/Code/mars/mars/utils.py", line 457, in _inner
return func(*args, **kwargs)
File "/Users/wenjun.swj/Code/mars/mars/executor.py", line 883, in execute_tileables
self.execute_graph(chunk_graph, list(temp_result_keys),
File "/Users/wenjun.swj/Code/mars/mars/executor.py", line 698, in execute_graph
res = graph_execution.execute(retval)
File "/Users/wenjun.swj/Code/mars/mars/executor.py", line 579, in execute
future.result()
File "/Users/wenjun.swj/miniconda3/lib/python3.8/concurrent/futures/_base.py", line 432, in result
return self.__get_result()
File "/Users/wenjun.swj/miniconda3/lib/python3.8/concurrent/futures/_base.py", line 388, in __get_result
raise self._exception
File "/Users/wenjun.swj/miniconda3/lib/python3.8/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/Users/wenjun.swj/Code/mars/mars/utils.py", line 457, in _inner
return func(*args, **kwargs)
File "/Users/wenjun.swj/Code/mars/mars/executor.py", line 446, in _execute_operand
self.handle_op(first_op, results, self._mock)
File "/Users/wenjun.swj/Code/mars/mars/executor.py", line 378, in handle_op
return Executor.handle(*args, **kw)
File "/Users/wenjun.swj/Code/mars/mars/executor.py", line 649, in handle
return runner(results, op)
File "/Users/wenjun.swj/Code/mars/mars/dataframe/sort/psrs.py", line 355, in execute
num = n // a.shape[op.axis] + 1
ZeroDivisionError: integer division or modulo by zero

# Fixed code
def execute(cls, ctx, op):
    a = ctx[op.inputs[0].key]
    xdf = pd if isinstance(a, (pd.DataFrame, pd.Series)) else cudf

    if len(a) == 0:
        # when chunk is empty, return the empty chunk itself
        ctx[op.outputs[0].key] = ctx[op.outputs[-1].key] = a
        return

    if op.sort_type == "sort_values":
        ctx[op.outputs[0].key] = res = execute_sort_values(a, op)
    else:
        ctx[op.outputs[0].key] = res = execute_sort_index(a, op)

    by = op.by
    add_distinct_col = (
        bool(int(os.environ.get("PSRS_DISTINCT_COL", "0")))
        or getattr(ctx, "running_mode", None) == RunningMode.distributed
    )
    if (
        add_distinct_col
        and isinstance(a, xdf.DataFrame)
        and op.sort_type == "sort_values"
    ):
        # when running under distributed mode, we introduce an extra column
        # to make sure pivots are distinct
        chunk_idx = op.inputs[0].index[0]
        distinct_col = (
            _PSRS_DISTINCT_COL
            if a.columns.nlevels == 1
            else (_PSRS_DISTINCT_COL,) + ("",) * (a.columns.nlevels - 1)
        )
        res[distinct_col] = np.arange(
            chunk_idx << 32, (chunk_idx << 32) + len(a), dtype=np.int64
        )
        by = list(by) + [distinct_col]

    n = op.n_partition
    if op.sort_type == "sort_values" and a.shape[op.axis] < n:
        num = n // a.shape[op.axis] + 1
        res = execute_sort_values(xdf.concat([res] * num), op, by=by)

    w = res.shape[op.axis] * 1.0 / (n + 1)
    slc = np.linspace(
        max(w - 1, 0), res.shape[op.axis] - 1, num=n, endpoint=False
    ).astype(int)
    if op.axis == 1:
        slc = (slice(None), slc)
    if op.sort_type == "sort_values":
        # do regular sample
        if op.by is not None:
            ctx[op.outputs[-1].key] = res[by].iloc[slc]
        else:
            ctx[op.outputs[-1].key] = res.iloc[slc]
    else:
        # do regular sample
        ctx[op.outputs[-1].key] = res.iloc[slc]