def detect_white_band(self):
        # whitests columns (maximum of luminosity)
        whitest = self.brightness_levels[-1]
        white_cols = self.cols_of_brightness(whitest)

        # we want enough columns to increase sensibility
        # so we add the second whitest columns (unless it's too large or too dark)
        if len(white_cols) < 0.01 * self.DOWNSCALED_WIDTH and self.brightness_levels[-2] >= whitest - 1:
            next_group = self.cols_of_brightness(self.brightness_levels[-2])

            if len(next_group) < 0.02 * self.DOWNSCALED_WIDTH:
                white_cols = white_cols.append(next_group).sort_values()

        # First : try to detect a black binding inside the whitest columns range.
        # Use an extra margin because sometimes
        # the binding isn't preceeded or followed by a white col
        # so the binding could be just before or after the whitest cols
        first_idx, last_idx = white_cols.min(), white_cols.max()

        band = self.signal.loc[first_idx:last_idx]

        if band.min() > band.max() - 2:
            debug("Use band margin because original band min=%i, max=%i" % (band.min(), band.max()))
            margin = max(1, round(0.01 * self.DOWNSCALED_WIDTH))
            band = self.signal.loc[first_idx-margin:last_idx+margin]

        debug("White band has index range %d-%d" % (band.index[0], band.index[-1]))

        return band
    def binding_as_brightness_max(self):
        # mean of the whitest columns
        whitest = self.brightness_levels.max()
        binding_point = self.cols_of_brightness(whitest).median()
        debug("binding_point=%f (brightness max (default))" % binding_point)

        return binding_point
    def binding_as_dark_peak(self):
        darkest = self.brightness_levels[0]
        dark_cols = self.cols_of_brightness(darkest)

        if darkest == 0 and len(dark_cols) <= 0.01 * self.DOWNSCALED_WIDTH:
            binding_point = dark_cols.median()

            debug("binding_point=%f (dark peak)" % binding_point)

            return binding_point
    def binding_as_strong_white_band(self):
        whitest = self.brightness_levels.max()
        white_cols = self.cols_of_brightness(whitest)
        length = len(white_cols)

        first_idx, last_idx = white_cols.min(), white_cols.max()
        expected_length = len(np.arange(first_idx, last_idx)) + 1

        debug("whitest=%i, white_cols_length=%i, expected_length=%i" % (whitest, length, expected_length))

        if whitest == 10 and expected_length == length and length >= 0.02 * self.DOWNSCALED_WIDTH:
            binding_point = white_cols.median()
            debug("binding_point=%f (strong white band)")

            return binding_point
    def binding_as_dark_inside_white_band(self):
        white_band = self.detect_white_band()

        # local darkest inside white band
        darkest_local = white_band.min()
        debug("Darkest inside white band: %s" % darkest_local)

        if darkest_local <= self.brightness_levels.max() - 5:
            # dark band inside white columns: this is our binding
            # returns the median of these cols
            darkest_cols = white_band[white_band == darkest_local].reset_index()['index']

            binding_point = darkest_cols.median()

            debug("binding_point=%f (local dark inside white band)" % binding_point)

            return binding_point
def main():
    audio_player = ''
    playlist = []
    val = 0
    # command line inputs
    if len(sys.argv) >= 2:
        if sys.argv[1] == '-h':
            usage(0)

        elif sys.argv[1] == '-c':
            shutil.rmtree('econdata')

    # interactive prompt
    else:
        if sys.platform == 'darwin':
            audio_player = 'afplay'

        if not os.path.isdir("./econdata"):
            (zippath, zipbool) = unzip.scan()
        else:
            (zippath, zipbool) = ("./econdata", False)

        index = -1

        # unzip if it needs unzipping
        if zipbool:
            unzip.unzip(zippath)

        try:
            for items in os.walk("./econdata"):
                for track in items[2]:
                    playlist.append(track)

            playlist.sort()

        except OSError:
            print("Audio zip file not found. Please download the zip file")
            print("and put it in Downloads, Desktop, or this directory.")
            exit(1)

        if len(playlist) == 0:
            print("Playlist construction failed. Exiting")
            exit(1)

        # make catalogue of sections
        catalogue = utils.catalogue(playlist, LABELS)

        while index < 0 or index > len(playlist) - 1:
            index = int(input("Enter number of track you wish to play: ")) - 1

        # play each track starting at index while checking for user input
        while index < len(playlist):
            val = play.playfile(audio_player, zippath,
                                playlist[index], catalogue,
                                utils.last_call(val, playlist, index))

            # index check
            if index < 0:
                index = 0

            # user termination
            if val == ord('q'):
                break

            # skip to next track, increment index
            elif val == ord('n'):
                index += 1

            # restart this track; index doesn't change
            elif val == ord('z'):
                continue

            # go back to previous track; decrement index
            elif val == ord('p'):
                index -= 1

            # all other cases: assume it timed out, increment index
            else:
                index += 1

            if index >= len(playlist):
                utils.debug("Playlist fully traversed")
                break