-
Notifications
You must be signed in to change notification settings - Fork 52
/
output_validator.py
124 lines (103 loc) · 5.23 KB
/
output_validator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# Released to students
import sys
sys.path.append('..')
sys.path.append('../..')
import argparse
import utils
from student_utils import *
import input_validator
def validate_output(input_file, output_file, params=[]):
print('Processing', input_file)
input_data = utils.read_file(input_file)
output_data = utils.read_file(output_file)
input_message, input_error = input_validator.tests(input_file)
cost, message = tests(input_data, output_data, params=params)
message = 'Comments about input file:\n\n' + input_message + 'Comments about output file:\n\n' + message
print(message)
if input_error:
return input_error, 'infinite', input_message + 'Since this input is invalid, you will not receive a score for its output.\n'
return input_error, cost, message
def validate_all_outputs(input_directory, output_directory, params=[]):
input_files = utils.get_files_with_extension(input_directory, '.in')
output_files = utils.get_files_with_extension(output_directory, '.out')
all_results = []
for input_file in input_files:
output_file = utils.input_to_output(input_file, output_directory)
print(input_file, output_file)
if os.path.basename(output_file) not in output_files:
print(f'No corresponding .out file for {input_file}')
results = (None, None, f'No corresponding .out file for {input_file}')
else:
results = validate_output(input_file, output_file, params=params)
all_results.append((input_file, results))
return all_results
def tests(input_data, output_data, params=[]):
number_of_locations, number_of_houses, list_of_locations, list_of_houses, starting_location, adjacency_matrix = data_parser(input_data)
try:
G, message = adjacency_matrix_to_graph(adjacency_matrix)
except Exception:
return 'Your adjacency matrix is not well formed.\n', 'infinite'
message = ''
cost = -1
car_cycle = output_data[0]
num_dropoffs = int(output_data[1][0])
if len(output_data) - 2 != num_dropoffs:
message += f'Number of dropoffs in output ({len(output_data) - 2}) does not match number stated ({num_dropoffs}).\n'
cost = 'infinite'
return cost, message
targets = []
dropoffs = {}
for i in range(num_dropoffs):
dropoff = output_data[i + 2]
if dropoff[0] not in list_of_locations:
message += 'At least one dropoff location is not an actual location.\n'
cost = 'infinite'
if dropoff[0] not in car_cycle:
message += 'At least one dropoff location is not in the path of the car.\n'
cost = 'infinite'
dropoff_index = list_of_locations.index(dropoff[0])
if list_of_locations.index(dropoff[0]) in dropoffs.keys():
message += 'You have multiple dropoffs with the same location. Please compress them so that there is one dropoff'
cost = 'infinite'
dropoffs[dropoff_index] = convert_locations_to_indices(dropoff[1:], list_of_locations)
if len(dropoff) == 1:
message += 'One dropoff location has nobody getting off; it should not be included in the list of dropoffs.\n'
cost = 'infinite'
for target in dropoff[1:]:
if target not in list_of_houses:
message += 'One of the targets is not a house.\n'
cost = 'infinite'
if target in targets:
message += 'One of the targets got off at multiple dropoffs'
cost = 'infinite'
targets.append(target)
if any(target not in list_of_locations for target in targets):
message += 'At least one of the targets is not a valid location.\n'
cost = 'infinite'
if any(home not in targets for home in list_of_houses):
message += 'At least one student did not get home.\n'
cost = 'infinite'
if (car_cycle[0] != starting_location):
message += "Your car must start at the specified starting location.\n"
cost = 'infinite'
car_cycle = convert_locations_to_indices(car_cycle, list_of_locations)
if (car_cycle[0] != car_cycle[-1]):
message += "Your car must start and end at the same location.\n"
cost = 'infinite'
if cost != 'infinite':
cost, solution_message = cost_of_solution(G, car_cycle, dropoffs)
message += solution_message
return cost, message
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Parsing arguments')
parser.add_argument('--all', action='store_true', help='If specified, the output validator is run on all files in the output directory. Else, it is run on just the given output file')
parser.add_argument('input', type=str, help='The path to the input file or directory')
parser.add_argument('output', type=str, help='The path to the output file or directory')
parser.add_argument('params', nargs=argparse.REMAINDER, help='Extra arguments passed in')
args = parser.parse_args()
if args.all:
input_directory, output_directory = args.input, args.output
validate_all_outputs(input_directory, output_directory, params=args.params)
else:
input_file, output_file = args.input, args.output
validate_output(input_file, output_file, params=args.params)