-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathvs
executable file
·141 lines (113 loc) · 4.51 KB
/
vs
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env python3
import argparse
import os
import json
import csv
from termcolor import colored as c
import re
class VS:
"""Manage data operations independent of user input."""
QUOTES = re.compile('[“”]')
def dump(self, data):
"""
Output list of match data into data.json file.
:param data: List (or, in theory, other data) to dump.
"""
with open('data.json', 'w') as f:
f.write(json.dumps(data))
def load(self, filename):
"""
Load JSON data from file.
:param file: Name of file to load data from.
"""
try:
with open(filename) as f:
# Need to account for JSON data occasionally containing nonstandard quotes
return json.loads(re.sub(self.QUOTES, '"', f.read()))
except OSError:
return []
def consolidate(self, directory):
"""
Load all JSON files in a directory and consolidate them into one file.
:param directory: Directory to find JSON files in.
"""
# TODO: Unbundle all file I/O from this method.
files = [f for f in os.listdir(directory) if f.endswith('.json')]
if len(files) > 1 or not files[0].endswith('data.json'):
matches = []
for f in files:
print('Parsing %s...' % f)
try:
matches += self.load(f)
except json.decoder.JSONDecodeError:
files.remove(f)
print(c('File \'%s\' has parsing errors. Resolve and run again.' % f.split('/')[-1], 'red'))
for f in files:
os.remove(f)
matches.sort(key=lambda match: (match['team'], match['match']))
return matches
else:
return []
def conflict(self, data):
"""
Handle conflicting and duplicate match data.
:param data: Scouting data to search for duplicates and conflicts.
"""
remove = []
if len(data) > 1:
for i in range(1, len(data)):
pre = data[i]
cur = data[i-1]
if pre == cur:
remove.append(i-1)
elif pre['match'] == cur['match'] and pre['team'] == cur['team']:
print(c('Team #%s was scouted differently twice in match #%s. Here are the two data:' % (pre['team'], cur['match']), 'red'))
print(('%s: ' % (i-1)) + str(pre))
print(('%s: ' % i) + str(cur))
choice = int(input(c('Please select the data you want to remove by typing 1 or 2: ', 'blue')))
remove.append(i + (choice - 2))
for index in reversed(remove):
print('Removing duplicate data point %s...' % index)
del data[index]
print(c('All conflicts and duplication eliminated.' if len(remove) else 'No duplicate or conflicting data found.', 'green'))
return data
def csv(self, data, csvfile):
"""
Convert JSON scouting data into a CSV spreadsheet.
:param data: Scouting data to convert.
:param csvfile: Name of file to output CSV content to.
"""
try:
os.remove('%s.csv' % csvfile)
except OSError:
pass
dest = csv.writer(open('data.csv', 'w+', newline=''))
# Write header
dest.writerow([k for k in data[0].keys()])
for match in data:
dest.writerow([match[i] for i in match])
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Process FRC scouting data.')
parser.add_argument('command', type=str, help='What you want to do.')
args = parser.parse_args()
vs = VS()
try:
data = vs.load('data.json')
except json.decoder.JSONDecodeError:
data = []
if args.command.startswith('cons'):
consolidated = vs.consolidate(os.getcwd())
if consolidated == []:
print(c('No unconsolidated scouting JSON in current directory.', 'blue'))
else:
print(c('Data successfully consolidated.', 'green'))
vs.dump(consolidated)
elif args.command.startswith('conf'):
vs.dump(vs.conflict(data))
elif args.command == 'csv' or args.command == 'ss' or args.command == 'spreadsheet':
if os.path.exists('data.json'):
vs.csv(data, 'data')
else:
print('Error: No valid scouting JSON in the current directory.')
else:
print('Unknown command %s.' % args.command)