# Path: bioframe/ops.py
# def sort_bedframe(
#     df,
#     view_df=None,
#     reset_index=True,
#     df_view_col=None,
#     view_name_col="name",
#     cols=None,
#     cols_view=None,
# ):
#     """
#     Sorts a bedframe 'df'.
# 
#     If 'view_df' is not provided, sorts by ``cols`` (e.g. "chrom", "start", "end").
#     If 'view_df' is provided and 'df_view_col' is not provided, uses
#     :func:`bioframe.ops.assign_view` with ``df_view_col='view_region'``
#     to assign intervals to the view regions with the largest overlap and then sorts.
#     If 'view_df' and 'df_view_col' are both provided, checks if the latter
#     are cataloged in 'view_name_col', and then sorts.
# 
#     df : pandas.DataFrame
#         Valid bedframe.
# 
#     view_df : pandas.DataFrame | dict-like
#         Valid input to make a viewframe. When it is dict-like
#         :func:'bioframe.make_viewframe' will be used to convert
#         to viewframe. If view_df is not provided df is sorted by chrom and start.
# 
#     reset_index : bool
#         Default True.
# 
#     df_view_col: None | str
#         Column from 'df' used to associate intervals with view regions.
#         The associated region in 'view_df' is then used for sorting.
#         If None, :func:'bioframe.assign_view' will be used to assign view regions.
#         Default None.
# 
#     view_name_col: str
#         Column from view_df with names of regions.
#         Default `name`.
# 
#     cols : (str, str, str) or None
#         The names of columns containing the chromosome, start and end of the
#         genomic intervals. The default values are 'chrom', 'start', 'end'.
# 
#     cols_view : (str, str, str) or None
#         The names of columns containing the chromosome, start and end of the
#         genomic intervals in the view. The default values are 'chrom', 'start', 'end'.
# 
#     Returns
#     -------
#     out_df : sorted bedframe
# 
#     Notes
#     -------
#         df_view_col is currently returned as an ordered categorical
# 
#     """
#     ck1, sk1, ek1 = _get_default_colnames() if cols is None else cols
# 
#     if not checks.is_bedframe(df, cols=cols):
#         raise ValueError("not a valid bedframe, cannot sort")
# 
#     out_df = df.copy()
#     if view_df is None:
#         out_df.sort_values([ck1, sk1, ek1], inplace=True)
# 
#     else:
#         ckv, skv, ekv = _get_default_colnames() if cols_view is None else cols_view
#         view_df = construction.make_viewframe(
#             view_df, view_name_col=view_name_col, cols=[ckv, skv, ekv]
#         ).rename(columns=dict(zip([ckv, skv, ekv], [ck1, sk1, ek1])))
# 
#         if df_view_col is None:
#             if _verify_columns(out_df, ["view_region"], return_as_bool=True):
#                 raise ValueError("column view_region already exists in input df")
#             df_view_col = "view_region"
#             out_df = assign_view(
#                 out_df,
#                 view_df,
#                 df_view_col=df_view_col,
#                 view_name_col=view_name_col,
#                 cols=cols,
#                 cols_view=cols,
#             )
# 
#         else:
#             if not _verify_columns(out_df, [df_view_col], return_as_bool=True):
#                 raise ValueError(
#                     "column 'df_view_col' not in input df, cannot sort by view"
#                 )
#             if not checks.is_cataloged(
#                 out_df[pd.isna(out_df[df_view_col].values) == False],
#                 view_df,
#                 df_view_col=df_view_col,
#                 view_name_col=view_name_col,
#             ):
#                 raise ValueError(
#                     "intervals in df not cataloged in view_df, cannot sort by view"
#                 )
# 
#         view_cat = pd.CategoricalDtype(
#             categories=view_df[view_name_col].values, ordered=True
#         )
#         out_df[df_view_col] = out_df[df_view_col].astype({df_view_col: view_cat})
#         out_df.sort_values([df_view_col, ck1, sk1, ek1], inplace=True)
# 
#     # make sure no columns get appended and dtypes are preserved
#     out_df = out_df[df.columns].astype(df.dtypes)
# 
#     if reset_index:
#         out_df.reset_index(inplace=True, drop=True)
# 
#     return out_df


from io import StringIO
from bioframe.core.checks import *
from bioframe.ops import sort_bedframe
import pandas as pd
import numpy as np
import pytest

    view_df = pd.DataFrame(
        [
            ["chrX", 1, 8, "oranges"],
            ["chrX", 8, 20, "grapefruit"],
            ["chr1", 0, 10, "apples"],
        ],
        columns=["chrom", "start", "end", "fruit"],
    )
    df_view_cat = pd.CategoricalDtype(
        categories=["oranges", "grapefruit", "apples"], ordered=True
    )
    view_df = view_df.astype({"fruit": df_view_cat})

    assert is_sorted(
        view_df, view_df=view_df, view_name_col="fruit", df_view_col="fruit"
    )

    df = pd.DataFrame(
        [
            ["chr1", 0, 10, "+"],
            ["chrX", 5, 10, "+"],
            ["chrX", 0, 5, "+"],
            ["chr2", 5, 10, "+"],
        ],
        columns=["chrom", "start", "end", "strand"],
    )

    assert not is_sorted(df)


# Path: bioframe/ops.py
# def sort_bedframe(
#     df,
#     view_df=None,
#     reset_index=True,
#     df_view_col=None,
#     view_name_col="name",
#     cols=None,
#     cols_view=None,
# ):
#     """
#     Sorts a bedframe 'df'.
# 
#     If 'view_df' is not provided, sorts by ``cols`` (e.g. "chrom", "start", "end").
#     If 'view_df' is provided and 'df_view_col' is not provided, uses
#     :func:`bioframe.ops.assign_view` with ``df_view_col='view_region'``
#     to assign intervals to the view regions with the largest overlap and then sorts.
#     If 'view_df' and 'df_view_col' are both provided, checks if the latter
#     are cataloged in 'view_name_col', and then sorts.
# 
#     df : pandas.DataFrame
#         Valid bedframe.
# 
#     view_df : pandas.DataFrame | dict-like
#         Valid input to make a viewframe. When it is dict-like
#         :func:'bioframe.make_viewframe' will be used to convert
#         to viewframe. If view_df is not provided df is sorted by chrom and start.
# 
#     reset_index : bool
#         Default True.
# 
#     df_view_col: None | str
#         Column from 'df' used to associate intervals with view regions.
#         The associated region in 'view_df' is then used for sorting.
#         If None, :func:'bioframe.assign_view' will be used to assign view regions.
#         Default None.
# 
#     view_name_col: str
#         Column from view_df with names of regions.
#         Default `name`.
# 
#     cols : (str, str, str) or None
#         The names of columns containing the chromosome, start and end of the
#         genomic intervals. The default values are 'chrom', 'start', 'end'.
# 
#     cols_view : (str, str, str) or None
#         The names of columns containing the chromosome, start and end of the
#         genomic intervals in the view. The default values are 'chrom', 'start', 'end'.
# 
#     Returns
#     -------
#     out_df : sorted bedframe
# 
#     Notes
#     -------
#         df_view_col is currently returned as an ordered categorical
# 
#     """
#     ck1, sk1, ek1 = _get_default_colnames() if cols is None else cols
# 
#     if not checks.is_bedframe(df, cols=cols):
#         raise ValueError("not a valid bedframe, cannot sort")
# 
#     out_df = df.copy()
#     if view_df is None:
#         out_df.sort_values([ck1, sk1, ek1], inplace=True)
# 
#     else:
#         ckv, skv, ekv = _get_default_colnames() if cols_view is None else cols_view
#         view_df = construction.make_viewframe(
#             view_df, view_name_col=view_name_col, cols=[ckv, skv, ekv]
#         ).rename(columns=dict(zip([ckv, skv, ekv], [ck1, sk1, ek1])))
# 
#         if df_view_col is None:
#             if _verify_columns(out_df, ["view_region"], return_as_bool=True):
#                 raise ValueError("column view_region already exists in input df")
#             df_view_col = "view_region"
#             out_df = assign_view(
#                 out_df,
#                 view_df,
#                 df_view_col=df_view_col,
#                 view_name_col=view_name_col,
#                 cols=cols,
#                 cols_view=cols,
#             )
# 
#         else:
#             if not _verify_columns(out_df, [df_view_col], return_as_bool=True):
#                 raise ValueError(
#                     "column 'df_view_col' not in input df, cannot sort by view"
#                 )
#             if not checks.is_cataloged(
#                 out_df[pd.isna(out_df[df_view_col].values) == False],
#                 view_df,
#                 df_view_col=df_view_col,
#                 view_name_col=view_name_col,
#             ):
#                 raise ValueError(
#                     "intervals in df not cataloged in view_df, cannot sort by view"
#                 )
# 
#         view_cat = pd.CategoricalDtype(
#             categories=view_df[view_name_col].values, ordered=True
#         )
#         out_df[df_view_col] = out_df[df_view_col].astype({df_view_col: view_cat})
#         out_df.sort_values([df_view_col, ck1, sk1, ek1], inplace=True)
# 
#     # make sure no columns get appended and dtypes are preserved
#     out_df = out_df[df.columns].astype(df.dtypes)
# 
#     if reset_index:
#         out_df.reset_index(inplace=True, drop=True)
# 
#     return out_df


# Path: tests/test_core_checks.py
from io import StringIO
from bioframe.core.checks import *
from bioframe.ops import sort_bedframe
import pandas as pd
import numpy as np
import pytest


    view_df = pd.DataFrame(
        [
            ["chrX", 1, 8, "oranges"],
            ["chrX", 8, 20, "grapefruit"],
            ["chr1", 0, 10, "apples"],
        ],
        columns=["chrom", "start", "end", "fruit"],
    )
    df_view_cat = pd.CategoricalDtype(
        categories=["oranges", "grapefruit", "apples"], ordered=True
    )
    view_df = view_df.astype({"fruit": df_view_cat})

    assert is_sorted(
        view_df, view_df=view_df, view_name_col="fruit", df_view_col="fruit"
    )

    df = pd.DataFrame(
        [
            ["chr1", 0, 10, "+"],
            ["chrX", 5, 10, "+"],
            ["chrX", 0, 5, "+"],
            ["chr2", 5, 10, "+"],
        ],
        columns=["chrom", "start", "end", "strand"],
    )

    assert not is_sorted(df)


    bfs = sort_bedframe(df, view_df=view_df, view_name_col="fruit")