<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def spread(df, key, values, convert=False):
 """ Transforms a "long" DataFrame into a "wide" format using a key and value column. If you have a mixed datatype column in your long-format DataFrame then the default behavior is for the spread columns to be of type `object`, or string. If you want to try to convert dtypes when spreading, you can set the convert keyword argument in spread to True. Args: key (str, int, or symbolic):
 Label for the key column. values (str, int, or symbolic):
 Label for the values column. Kwargs: convert (bool):
 Boolean indicating whether or not to try and convert the spread columns to more appropriate data types. Example: widened = elongated >> spread(X.variable, X.value) widened >> head(5) _ID carat clarity color cut depth price table x y z 0 0 0.23 SI2 E Ideal 61.5 326 55 3.95 3.98 2.43 1 1 0.21 SI1 E Premium 59.8 326 61 3.89 3.84 2.31 2 10 0.3 SI1 J Good 64 339 55 4.25 4.28 2.73 3 100 0.75 SI1 D Very Good 63.2 2760 56 5.8 5.75 3.65 4 1000 0.75 SI1 D Ideal 62.3 2898 55 5.83 5.8 3.62 """


    # Taken mostly from dplython package
    columns = df.columns.tolist()
    id_cols = [col for col in columns if not col in [key, values]]

    temp_index = ['' for i in range(len(df))]
    for id_col in id_cols:
        temp_index += df[id_col].map(str)

    out_df = df.assign(temp_index=temp_index)
    out_df = out_df.set_index('temp_index')
    spread_data = out_df[[key, values]]

    if not all(spread_data.groupby([spread_data.index, key]).agg(
            'count').reset_index()[values] < 2):
        raise ValueError('Duplicate identifiers')

    spread_data = spread_data.pivot(columns=key, values=values)

    if convert and (out_df[values].dtype.kind in 'OSaU'):
        columns_to_convert = [col for col in spread_data if col not in columns]
        spread_data = convert_type(spread_data, columns_to_convert)

    out_df = out_df[id_cols].drop_duplicates()
    out_df = out_df.merge(spread_data, left_index=True, right_index=True).reset_index(drop=True)

    out_df = (out_df >> arrange(id_cols)).reset_index(drop=True)

    return out_df