def all_to_str(self):
        """
        In all columns, turn all floats/ints into strings.
        If a float ends with .0, strip off '.0' from the resulting string.
        """
        def stringify(x):
            # float --> string,
            # truncating floats like 3.0 --> 3
            if isinstance(x, float):
                if x.is_integer():
                    #print('{} --> {}'.format(x, str(x).rstrip('0').rstrip('.')))
                    return str(x).rstrip('0').rstrip('.')
                return(str(x))
            # keep strings as they are,
            # unless it is a string like "3.0",
            # in which case truncate that too
            if isinstance(x, str):
                try:
                    float(x)
                    if x.endswith('0'):
                        if x.rstrip('0').endswith('.'):
                            #print('{} --> {}'.format(x, x.rstrip('0').rstrip('.')))
                            return x.rstrip('0').rstrip('.')
                except (ValueError, TypeError):
                    pass
            # integer --> string
            if isinstance(x, int):
                return str(x)
            # if it is not int/str/float, just return as is
            return x

        def remove_extra_digits(x, prog):
            """
            Remove extra digits
            x is a string,
            prog is always the following '_sre.SRE_Pattern':
            prog = re.compile("\d*[.]\d*([0]{5,100}|[9]{5,100})\d*\Z").
            However, it is compiled outside of this sub-function
            for performance reasons.
            """
            if not isinstance(x, str):
                return x
            result = prog.match(x)
            if result:
                decimals = result.string.split('.')[1]
                result = result.string
                if decimals[-3] == '0':
                    result = x[:-2].rstrip('0')
                if decimals[-3] == '9':
                    result = x[:-2].rstrip('9')
                    try:
                        last_digit = int(result[-1])
                        result = result[:-1] + str(last_digit + 1)
                    except ValueError:
                        result = float(result[:-1]) + 1
                #if result != x:
                #    print('changing {} to {}'.format(x, result))
                return result
            return x

        for col in self.df.columns:
            self.df[col] = self.df[col].apply(stringify)

        prog = re.compile("\d*[.]\d*([0]{5,100}|[9]{5,100})\d*\Z")
        for col in self.df.columns:
            self.df[col] = self.df[col].apply(lambda x: remove_extra_digits(x, prog))
In all columns, turn all floats/ints into strings.
        If a float ends with .0, strip off '.0' from the resulting string.