def parse_scenario(scenario_data):
    """
    Takes a serialized scenario and turns it into a data structure suitable
    for feeding to run_scenario().

    :returns: scenario
    :raises: ValueError on invalid scenario
    """

    parsed_scenario = {}

    try:
        raw_scenario = json.loads(scenario_data)
    except ValueError as err:
        raise ValueError("Invalid JSON in scenario file: %s" % err)

    if not isinstance(raw_scenario, dict):
        raise ValueError("Scenario must be a JSON object, not array or string")

    if 'part_power' not in raw_scenario:
        raise ValueError("part_power missing")
    try:
        parsed_scenario['part_power'] = int(raw_scenario['part_power'])
    except ValueError as err:
        raise ValueError("part_power not an integer: %s" % err)
    if not 1 <= parsed_scenario['part_power'] <= 32:
        raise ValueError("part_power must be between 1 and 32, but was %d"
                         % raw_scenario['part_power'])

    if 'replicas' not in raw_scenario:
        raise ValueError("replicas missing")
    try:
        parsed_scenario['replicas'] = float(raw_scenario['replicas'])
    except ValueError as err:
        raise ValueError("replicas not a float: %s" % err)
    if 1 < parsed_scenario['replicas']:
        raise ValueError("replicas must be at least 1, but is %f"
                         % parsed_scenario['replicas'])

    if 'overload' not in raw_scenario:
        raise ValueError("overload missing")
    try:
        parsed_scenario['overload'] = float(raw_scenario['overload'])
    except ValueError as err:
        raise ValueError("overload not a float: %s" % err)
    if parsed_scenario['overload'] < 0:
        raise ValueError("overload must be non-negative, but is %f"
                         % parsed_scenario['overload'])

    if 'random_seed' not in raw_scenario:
        raise ValueError("random_seed missing")
    try:
        parsed_scenario['random_seed'] = int(raw_scenario['random_seed'])
    except ValueError as err:
        raise ValueError("replicas not an integer: %s" % err)

    if 'rounds' not in raw_scenario:
        raise ValueError("rounds missing")
    if not isinstance(raw_scenario['rounds'], list):
        raise ValueError("rounds must be an array")

    parser_for_command = {
        'add': _parse_add_command,
        'remove': _parse_remove_command,
        'set_weight': _parse_set_weight_command,
        'save': _parse_save_command,
    }

    parsed_scenario['rounds'] = []
    for round_index, raw_round in enumerate(raw_scenario['rounds']):
        if not isinstance(raw_round, list):
            raise ValueError("round %d not an array" % round_index)

        parsed_round = []
        for command_index, command in enumerate(raw_round):
            if command[0] not in parser_for_command:
                raise ValueError(
                    "Unknown command (round %d, command %d): "
                    "'%s' should be one of %s" %
                    (round_index, command_index, command[0],
                     parser_for_command.keys()))
            parsed_round.append(
                parser_for_command[command[0]](
                    round_index, command_index, command))
        parsed_scenario['rounds'].append(parsed_round)
    return parsed_scenario
dataset/ETHPy150Open openstack/swift/swift/cli/ring_builder_analyzer.py/parse_scenario/swapped operands of `<`