Superficially cleans data, i.e. changing simple things about formatting.
    Parameters:
    df - DataFrame
        DataFrame to clean
    error_rate - float {0 <= error_rate <= 1}, default 0
        Maximum amount of errors/inconsistencies caused explicitly by cleaning, expressed
        as a percentage of total dataframe rows (0 = 0%, .5 = 50%, etc.)
        Ex: na values from coercing a column of data to numeric

def clean(df,error_rate = 0):
    """ Superficially cleans data, i.e. changing simple things about formatting.
    Parameters:
    df - DataFrame
        DataFrame to clean
    error_rate - float {0 <= error_rate <= 1}, default 0
        Maximum amount of errors/inconsistencies caused explicitly by cleaning, expressed
        as a percentage of total dataframe rows (0 = 0%, .5 = 50%, etc.)
        Ex: na values from coercing a column of data to numeric
    """
    df = df.copy()
    
    # Change colnames
    basics.clean_colnames(df)
    # Eventually use a more advanced function to clean colnames
    print('Changed colnames to {}'.format(df.columns))
    
    # Remove extra whitespace
    obj_col_list = df.select_dtypes(include = 'object').columns
    for col_name in obj_col_list:
        df[col_name] = basics.col_strip(df,col_name)
        print("Stripped extra whitespace from '{}'".format(col_name))
    
    # Coerce columns if possible
    for col_name in obj_col_list:
        new_dtype = coerce_col(df,col_name,error_rate)
        if new_dtype is not None:
            print("Coerced '{}' to datatype '{}'".format(col_name, new_dtype))

    # Scrub columns
    obj_col_list = df.select_dtypes(include = 'object').columns
    for col_name in obj_col_list:
        scrubf, scrubb = smart_scrub(df,col_name,1-error_rate)
        if scrubf is not None or scrubb is not None:
            print("Scrubbed '{}' from the front and '{}' from the back of column '{}'" \
                  .format(scrubf,scrubb,col_name))
    
    # Coerice columns if possible
    for col_name in obj_col_list:
        new_dtype = coerce_col(df,col_name,error_rate)
        if new_dtype is not None:
            print("Coerced '{}' to datatype '{}'".format(col_name, new_dtype))  
    return df