import random


def add_crime_types(df):
    """
    Generates a column of crime types  for all criminals.
    Each type has its own defined fraction of all criminals to ensure
    weapons sales has the most sales (in money units) and
    that other crime types profits look realistic.
    """

    crimes_dict = {'weapons sale': {'factor': 100.0, 'fraction': 0.05},
                   'drug sale': {'factor': 9.0, 'fraction': 0.08},
                   'robbery': {'factor': 0.2, 'fraction': 0.17},
                   'forgery': {'factor': 0.12, 'fraction': 0.10},
                   'theft': {'factor': 0.08, 'fraction': 0.4},
                   'pickpocketing': {'factor': 0.01, 'fraction': 0.2}
                   }

    full_crimes_list = []
    for k in list(crimes_dict.keys()):
        if k != list(crimes_dict.keys())[-1]:
            times = int(df.shape[0] * crimes_dict[k]['fraction'])
        else:
            times = df.shape[0] - len(full_crimes_list)
        crimes = [k for i in range(times)]
        full_crimes_list += crimes

    random.shuffle(full_crimes_list)

    df['crime_type'] = full_crimes_list

    def generate_criminal_profits(crime_type):
        """
        Adds profit information for each criminal.
        Factor from the dict is used to make crime types profits look realistic
        """
        return int(-(crimes_dict[crime_type]['factor'] * (-random.randrange(100, 5000, 10)) // 1))

    df['profit'] = df['crime_type'].apply(generate_criminal_profits)

    return df