              type=int,
              dest='num_bins',
              group=_("output"),
              default=5,
              help=_("Integer value. Number of folders that will be used to group by blur, "
                     "face-yaw and black-pixels. For blur folder 0 will be the least blurry, while "
                     "the last folder will be the blurriest. For face-yaw the number of bins is by "
                     "how much 180 degrees is divided. So if you use 18, then each folder will be "
                     "a 10 degree increment. Folder 0 will contain faces looking the most to the "
                     "left whereas the last folder will contain the faces looking the most to the "
                     "right. If the number of images doesn't divide evenly into the number of "
                     "bins, the remaining images get put in the last bin. For black-pixels it "
                     "represents the divider of the percentage of black pixels. For 10, first "
                     "folder will have the faces with 0 to 10%% black pixels, second 11 to 20%%, "
                     "etc. Default value: 5")))
          argument_list.append(dict(
              opts=('-l', '--log-changes'),
              action='store_true',
              group=_("settings"),
              default=False,
 
</s> remove "Integer value. Number of folders that will be used to group by blur, face-"
"yaw and black-pixels. For blur folder 0 will be the least blurry, while the "
"last folder will be the blurriest. For face-yaw the number of bins is by how "
"much 180 degrees is divided. So if you use 18, then each folder will be a 10 "
"degree increment. Folder 0 will contain faces looking the most to the left "
"whereas the last folder will contain the faces looking the most to the "
"right. If the number of images doesn't divide evenly into the number of "
"bins, the remaining images get put in the last bin. For black-pixels it "
"represents the divider of the percentage of black pixels. For 10, first "
"folder will have the faces with 0 to 10%% black pixels, second 11 to 20%%, "
"etc. Default value: 5"
 </s> add "R|Integer value. Used to control the number of bins created for grouping by: "
"any 'blur' methods, 'color' methods or 'face metric' methods ('distance', "
"'size') and 'orientation; methods ('yaw', 'pitch'). For any other grouping "
"methods see the '-t' ('--threshold') option.\n"
"L|For 'face metric' methods the bins are filled, according the the "
"distribution of faces between the minimum and maximum chosen metric.\n"
"L|For 'color' methods the number of bins represents the divider of the "
"percentage of colored pixels. Eg. For a bin number of '5': The first folder "
"will have the faces with 0%% to 20%% colored pixels, second 21%% to 40%%, "
"etc. Any empty bins will be deleted, so you may end up with fewer bins than "
"selected.\n"
"L|For 'blur' methods folder 0 will be the least blurry, while the last "
"folder will be the blurriest.\n"
"L|For 'orientation' methods the number of bins is dictated by how much 180 "
"degrees is divided. Eg. If 18 is selected, then each folder will be a 10 "
"degree increment. Folder 0 will contain faces looking the most to the left/"
"down whereas the last folder will contain the faces looking the most to the "
"right/up. NB: Some bins may be empty if faces do not fit the criteria.\n"
"Default value: 5" </s> remove             group=_("output"),
 </s> add             group=_("group settings"), </s> remove #: tools/sort/cli.py:150
 </s> add #: tools/sort/cli.py:191 </s> remove #: tools/sort/cli.py:164 tools/sort/cli.py:174
 </s> add #: tools/sort/cli.py:213 tools/sort/cli.py:223 </s> remove         logger.info("Sorting by percentage of black pixels...")
        img_list = [(filename, np.ndarray.all(image == [0, 0, 0], axis=2).sum()/image.size*100*3)
                    for filename, image, _ in tqdm(self._loader.load(),
                                                   desc="Calculating black pixels",
                                                   total=self._loader.count,
                                                   leave=False)]
        img_list_len = len(img_list)
        for i in tqdm(range(0, img_list_len - 1), desc="Comparing black pixels", file=sys.stdout):
            for j in range(0, img_list_len-i-1):
                if img_list[j][1] > img_list[j+1][1]:
                    temp = img_list[j]
                    img_list[j] = img_list[j+1]
                    img_list[j+1] = temp
        return img_list

    # Methods for grouping
    def group_blur(self, img_list):
        """ Group into bins by blur """
        # Starting the binning process
        num_bins = self._args.num_bins

        # The last bin will get all extra images if it's
        # not possible to distribute them evenly
        num_per_bin = len(img_list) // num_bins
        remainder = len(img_list) % num_bins

        logger.info("Grouping by blur...")
        bins = [[] for _ in range(num_bins)]
        idx = 0
        for i in range(num_bins):
            for _ in range(num_per_bin):
                bins[i].append(img_list[idx][0])
                idx += 1

        # If remainder is 0, nothing gets added to the last bin.
        for i in range(1, remainder + 1):
            bins[-1].append(img_list[-i][0])

        return bins

    def group_blur_fft(self, img_list):
        """ Group into bins by fft blur score"""
        # Starting the binning process
        num_bins = self._args.num_bins

        # The last bin will get all extra images if it's
        # not possible to distribute them evenly
        num_per_bin = len(img_list) // num_bins
        remainder = len(img_list) % num_bins

        logger.info("Grouping by fft blur score...")
        bins = [[] for _ in range(num_bins)]
        idx = 0
        for i in range(num_bins):
            for _ in range(num_per_bin):
                bins[i].append(img_list[idx][0])
                idx += 1

        # If remainder is 0, nothing gets added to the last bin.
        for i in range(1, remainder + 1):
            bins[-1].append(img_list[-i][0])

        return bins

    def group_face_cnn(self, img_list):
        """ Group into bins by CNN face similarity """
        logger.info("Grouping by face-cnn similarity...")

        # Groups are of the form: group_num -> reference faces
        reference_groups = {}

        # Bins array, where index is the group number and value is
        # an array containing the file paths to the images in that group.
        bins = []

        # Comparison threshold used to decide how similar
        # faces have to be to be grouped together.
        # It is multiplied by 1000 here to allow the cli option to use smaller
        # numbers.
        min_threshold = self._args.min_threshold * 1000

        img_list_len = len(img_list)
 </s> add         logger.debug("Cleaning arguments: %s", arguments)
        if arguments.sort_method == "none" and arguments.group_method == "none":
            logger.error("Both sort-by and group-by are 'None'. Nothing to do.")
            sys.exit(1)
            help=_("R|Integer value. Used to control the number of bins created for grouping by: "
                   "any 'blur' methods, 'color' methods or 'face metric' methods ('distance', "
                   "'size') and 'orientation; methods ('yaw', 'pitch'). For any other grouping "
                   "methods see the '-t' ('--threshold') option."
                   "\nL|For 'face metric' methods the bins are filled, according the the "
                   "distribution of faces between the minimum and maximum chosen metric."
                   "\nL|For 'color' methods the number of bins represents the divider of the "
                   "percentage of colored pixels. Eg. For a bin number of '5': The first folder "
                   "will have the faces with 0%% to 20%% colored pixels, second 21%% to 40%%, "
                   "etc. Any empty bins will be deleted, so you may end up with fewer bins than "
                   "selected."
                   "\nL|For 'blur' methods folder 0 will be the least blurry, while "
                   "the last folder will be the blurriest."
                   "\nL|For 'orientation' methods the number of bins is dictated by how much 180 "
                   "degrees is divided. Eg. If 18 is selected, then each folder will be a 10 "
                   "degree increment. Folder 0 will contain faces looking the most to the "
                   "left/down whereas the last folder will contain the faces looking the most to "
                   "the right/up. NB: Some bins may be empty if faces do not fit the criteria."
                   "\nDefault value: 5")))
              type=int,
              dest='num_bins',
              group=_("output"),
              default=5,
            help=_("R|Integer value. Used to control the number of bins created for grouping by: "
                   "any 'blur' methods, 'color' methods or 'face metric' methods ('distance', "
                   "'size') and 'orientation; methods ('yaw', 'pitch'). For any other grouping "
                   "methods see the '-t' ('--threshold') option."
                   "\nL|For 'face metric' methods the bins are filled, according the the "
                   "distribution of faces between the minimum and maximum chosen metric."
                   "\nL|For 'color' methods the number of bins represents the divider of the "
                   "percentage of colored pixels. Eg. For a bin number of '5': The first folder "
                   "will have the faces with 0%% to 20%% colored pixels, second 21%% to 40%%, "
                   "etc. Any empty bins will be deleted, so you may end up with fewer bins than "
                   "selected."
                   "\nL|For 'blur' methods folder 0 will be the least blurry, while "
                   "the last folder will be the blurriest."
                   "\nL|For 'orientation' methods the number of bins is dictated by how much 180 "
                   "degrees is divided. Eg. If 18 is selected, then each folder will be a 10 "
                   "degree increment. Folder 0 will contain faces looking the most to the "
                   "left/down whereas the last folder will contain the faces looking the most to "
                   "the right/up. NB: Some bins may be empty if faces do not fit the criteria."
                   "\nDefault value: 5")))
            help=_("R|Integer value. Used to control the number of bins created for grouping by: "
                   "any 'blur' methods, 'color' methods or 'face metric' methods ('distance', "
                   "'size') and 'orientation; methods ('yaw', 'pitch'). For any other grouping "
                   "methods see the '-t' ('--threshold') option."
                   "\nL|For 'face metric' methods the bins are filled, according the the "
                   "distribution of faces between the minimum and maximum chosen metric."
                   "\nL|For 'color' methods the number of bins represents the divider of the "
                   "percentage of colored pixels. Eg. For a bin number of '5': The first folder "
                   "will have the faces with 0%% to 20%% colored pixels, second 21%% to 40%%, "
                   "etc. Any empty bins will be deleted, so you may end up with fewer bins than "
                   "selected."
                   "\nL|For 'blur' methods folder 0 will be the least blurry, while "
                   "the last folder will be the blurriest."
                   "\nL|For 'orientation' methods the number of bins is dictated by how much 180 "
                   "degrees is divided. Eg. If 18 is selected, then each folder will be a 10 "
                   "degree increment. Folder 0 will contain faces looking the most to the "
                   "left/down whereas the last folder will contain the faces looking the most to "
                   "the right/up. NB: Some bins may be empty if faces do not fit the criteria."
                   "\nDefault value: 5")))
            help=_("R|Integer value. Used to control the number of bins created for grouping by: "
                   "any 'blur' methods, 'color' methods or 'face metric' methods ('distance', "
                   "'size') and 'orientation; methods ('yaw', 'pitch'). For any other grouping "
                   "methods see the '-t' ('--threshold') option."
                   "\nL|For 'face metric' methods the bins are filled, according the the "
                   "distribution of faces between the minimum and maximum chosen metric."
                   "\nL|For 'color' methods the number of bins represents the divider of the "
                   "percentage of colored pixels. Eg. For a bin number of '5': The first folder "
                   "will have the faces with 0%% to 20%% colored pixels, second 21%% to 40%%, "
                   "etc. Any empty bins will be deleted, so you may end up with fewer bins than "
                   "selected."
                   "\nL|For 'blur' methods folder 0 will be the least blurry, while "
                   "the last folder will be the blurriest."
                   "\nL|For 'orientation' methods the number of bins is dictated by how much 180 "
                   "degrees is divided. Eg. If 18 is selected, then each folder will be a 10 "
                   "degree increment. Folder 0 will contain faces looking the most to the "
                   "left/down whereas the last folder will contain the faces looking the most to "
                   "the right/up. NB: Some bins may be empty if faces do not fit the criteria."
                   "\nDefault value: 5")))
            help=_("R|Integer value. Used to control the number of bins created for grouping by: "
                   "any 'blur' methods, 'color' methods or 'face metric' methods ('distance', "
                   "'size') and 'orientation; methods ('yaw', 'pitch'). For any other grouping "
                   "methods see the '-t' ('--threshold') option."
                   "\nL|For 'face metric' methods the bins are filled, according the the "
                   "distribution of faces between the minimum and maximum chosen metric."
                   "\nL|For 'color' methods the number of bins represents the divider of the "
                   "percentage of colored pixels. Eg. For a bin number of '5': The first folder "
                   "will have the faces with 0%% to 20%% colored pixels, second 21%% to 40%%, "
                   "etc. Any empty bins will be deleted, so you may end up with fewer bins than "
                   "selected."
                   "\nL|For 'blur' methods folder 0 will be the least blurry, while "
                   "the last folder will be the blurriest."
                   "\nL|For 'orientation' methods the number of bins is dictated by how much 180 "
                   "degrees is divided. Eg. If 18 is selected, then each folder will be a 10 "
                   "degree increment. Folder 0 will contain faces looking the most to the "
                   "left/down whereas the last folder will contain the faces looking the most to "
                   "the right/up. NB: Some bins may be empty if faces do not fit the criteria."
                   "\nDefault value: 5")))
            help=_("R|Integer value. Used to control the number of bins created for grouping by: "
                   "any 'blur' methods, 'color' methods or 'face metric' methods ('distance', "
                   "'size') and 'orientation; methods ('yaw', 'pitch'). For any other grouping "
                   "methods see the '-t' ('--threshold') option."
                   "\nL|For 'face metric' methods the bins are filled, according the the "
                   "distribution of faces between the minimum and maximum chosen metric."
                   "\nL|For 'color' methods the number of bins represents the divider of the "
                   "percentage of colored pixels. Eg. For a bin number of '5': The first folder "
                   "will have the faces with 0%% to 20%% colored pixels, second 21%% to 40%%, "
                   "etc. Any empty bins will be deleted, so you may end up with fewer bins than "
                   "selected."
                   "\nL|For 'blur' methods folder 0 will be the least blurry, while "
                   "the last folder will be the blurriest."
                   "\nL|For 'orientation' methods the number of bins is dictated by how much 180 "
                   "degrees is divided. Eg. If 18 is selected, then each folder will be a 10 "
                   "degree increment. Folder 0 will contain faces looking the most to the "
                   "left/down whereas the last folder will contain the faces looking the most to "
                   "the right/up. NB: Some bins may be empty if faces do not fit the criteria."
                   "\nDefault value: 5")))
            help=_("R|Integer value. Used to control the number of bins created for grouping by: "
                   "any 'blur' methods, 'color' methods or 'face metric' methods ('distance', "
                   "'size') and 'orientation; methods ('yaw', 'pitch'). For any other grouping "
                   "methods see the '-t' ('--threshold') option."
                   "\nL|For 'face metric' methods the bins are filled, according the the "
                   "distribution of faces between the minimum and maximum chosen metric."
                   "\nL|For 'color' methods the number of bins represents the divider of the "
                   "percentage of colored pixels. Eg. For a bin number of '5': The first folder "
                   "will have the faces with 0%% to 20%% colored pixels, second 21%% to 40%%, "
                   "etc. Any empty bins will be deleted, so you may end up with fewer bins than "
                   "selected."
                   "\nL|For 'blur' methods folder 0 will be the least blurry, while "
                   "the last folder will be the blurriest."
                   "\nL|For 'orientation' methods the number of bins is dictated by how much 180 "
                   "degrees is divided. Eg. If 18 is selected, then each folder will be a 10 "
                   "degree increment. Folder 0 will contain faces looking the most to the "
                   "left/down whereas the last folder will contain the faces looking the most to "
                   "the right/up. NB: Some bins may be empty if faces do not fit the criteria."
                   "\nDefault value: 5")))
            help=_("R|Integer value. Used to control the number of bins created for grouping by: "
                   "any 'blur' methods, 'color' methods or 'face metric' methods ('distance', "
                   "'size') and 'orientation; methods ('yaw', 'pitch'). For any other grouping "
                   "methods see the '-t' ('--threshold') option."
                   "\nL|For 'face metric' methods the bins are filled, according the the "
                   "distribution of faces between the minimum and maximum chosen metric."
                   "\nL|For 'color' methods the number of bins represents the divider of the "
                   "percentage of colored pixels. Eg. For a bin number of '5': The first folder "
                   "will have the faces with 0%% to 20%% colored pixels, second 21%% to 40%%, "
                   "etc. Any empty bins will be deleted, so you may end up with fewer bins than "
                   "selected."
                   "\nL|For 'blur' methods folder 0 will be the least blurry, while "
                   "the last folder will be the blurriest."
                   "\nL|For 'orientation' methods the number of bins is dictated by how much 180 "
                   "degrees is divided. Eg. If 18 is selected, then each folder will be a 10 "
                   "degree increment. Folder 0 will contain faces looking the most to the "
                   "left/down whereas the last folder will contain the faces looking the most to "
                   "the right/up. NB: Some bins may be empty if faces do not fit the criteria."
                   "\nDefault value: 5")))
            help=_("R|Integer value. Used to control the number of bins created for grouping by: "
                   "any 'blur' methods, 'color' methods or 'face metric' methods ('distance', "
                   "'size') and 'orientation; methods ('yaw', 'pitch'). For any other grouping "
                   "methods see the '-t' ('--threshold') option."
                   "\nL|For 'face metric' methods the bins are filled, according the the "
                   "distribution of faces between the minimum and maximum chosen metric."
                   "\nL|For 'color' methods the number of bins represents the divider of the "
                   "percentage of colored pixels. Eg. For a bin number of '5': The first folder "
                   "will have the faces with 0%% to 20%% colored pixels, second 21%% to 40%%, "
                   "etc. Any empty bins will be deleted, so you may end up with fewer bins than "
                   "selected."
                   "\nL|For 'blur' methods folder 0 will be the least blurry, while "
                   "the last folder will be the blurriest."
                   "\nL|For 'orientation' methods the number of bins is dictated by how much 180 "
                   "degrees is divided. Eg. If 18 is selected, then each folder will be a 10 "
                   "degree increment. Folder 0 will contain faces looking the most to the "
                   "left/down whereas the last folder will contain the faces looking the most to "
                   "the right/up. NB: Some bins may be empty if faces do not fit the criteria."
                   "\nDefault value: 5")))
            help=_("R|Integer value. Used to control the number of bins created for grouping by: "
                   "any 'blur' methods, 'color' methods or 'face metric' methods ('distance', "
                   "'size') and 'orientation; methods ('yaw', 'pitch'). For any other grouping "
                   "methods see the '-t' ('--threshold') option."
                   "\nL|For 'face metric' methods the bins are filled, according the the "
                   "distribution of faces between the minimum and maximum chosen metric."
                   "\nL|For 'color' methods the number of bins represents the divider of the "
                   "percentage of colored pixels. Eg. For a bin number of '5': The first folder "
                   "will have the faces with 0%% to 20%% colored pixels, second 21%% to 40%%, "
                   "etc. Any empty bins will be deleted, so you may end up with fewer bins than "
                   "selected."
                   "\nL|For 'blur' methods folder 0 will be the least blurry, while "
                   "the last folder will be the blurriest."
                   "\nL|For 'orientation' methods the number of bins is dictated by how much 180 "
                   "degrees is divided. Eg. If 18 is selected, then each folder will be a 10 "
                   "degree increment. Folder 0 will contain faces looking the most to the "
                   "left/down whereas the last folder will contain the faces looking the most to "
                   "the right/up. NB: Some bins may be empty if faces do not fit the criteria."
                   "\nDefault value: 5")))
            help=_("R|Integer value. Used to control the number of bins created for grouping by: "
                   "any 'blur' methods, 'color' methods or 'face metric' methods ('distance', "
                   "'size') and 'orientation; methods ('yaw', 'pitch'). For any other grouping "
                   "methods see the '-t' ('--threshold') option."
                   "\nL|For 'face metric' methods the bins are filled, according the the "
                   "distribution of faces between the minimum and maximum chosen metric."
                   "\nL|For 'color' methods the number of bins represents the divider of the "
                   "percentage of colored pixels. Eg. For a bin number of '5': The first folder "
                   "will have the faces with 0%% to 20%% colored pixels, second 21%% to 40%%, "
                   "etc. Any empty bins will be deleted, so you may end up with fewer bins than "
                   "selected."
                   "\nL|For 'blur' methods folder 0 will be the least blurry, while "
                   "the last folder will be the blurriest."
                   "\nL|For 'orientation' methods the number of bins is dictated by how much 180 "
                   "degrees is divided. Eg. If 18 is selected, then each folder will be a 10 "
                   "degree increment. Folder 0 will contain faces looking the most to the "
                   "left/down whereas the last folder will contain the faces looking the most to "
                   "the right/up. NB: Some bins may be empty if faces do not fit the criteria."
                   "\nDefault value: 5")))
            help=_("R|Integer value. Used to control the number of bins created for grouping by: "
                   "any 'blur' methods, 'color' methods or 'face metric' methods ('distance', "
                   "'size') and 'orientation; methods ('yaw', 'pitch'). For any other grouping "
                   "methods see the '-t' ('--threshold') option."
                   "\nL|For 'face metric' methods the bins are filled, according the the "
                   "distribution of faces between the minimum and maximum chosen metric."
                   "\nL|For 'color' methods the number of bins represents the divider of the "
                   "percentage of colored pixels. Eg. For a bin number of '5': The first folder "
                   "will have the faces with 0%% to 20%% colored pixels, second 21%% to 40%%, "
                   "etc. Any empty bins will be deleted, so you may end up with fewer bins than "
                   "selected."
                   "\nL|For 'blur' methods folder 0 will be the least blurry, while "
                   "the last folder will be the blurriest."
                   "\nL|For 'orientation' methods the number of bins is dictated by how much 180 "
                   "degrees is divided. Eg. If 18 is selected, then each folder will be a 10 "
                   "degree increment. Folder 0 will contain faces looking the most to the "
                   "left/down whereas the last folder will contain the faces looking the most to "
                   "the right/up. NB: Some bins may be empty if faces do not fit the criteria."
                   "\nDefault value: 5")))
          argument_list.append(dict(
              opts=('-l', '--log-changes'),
              action='store_true',
              group=_("settings"),
              default=False,
keep keep keep keep replace replace replace replace replace replace replace replace replace replace replace keep keep keep keep keep
 Overhaul sort:
  - Standardize image data reading and writing
  - Optimize loading (just one pass required)
  - Make all sort groups binnable (to greater or lesser results)
  - Add sort by pitch
  - Deprecate multiple options
  - linting, docs + locales 
tools/sort/cli.py