forked from hedgecrw/CS5260
-
Notifications
You must be signed in to change notification settings - Fork 0
/
read_files.py
117 lines (85 loc) · 3.52 KB
/
read_files.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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import annotations
import csv, os, re
# read_csv is a utility to read and parse the initial CSV files
# code by John Ford
def read_csv(file_path: str) -> dict[dict]:
entries = {}
with open(file_path, mode='r', encoding='utf-8-sig') as file:
csvFile = csv.DictReader(file)
for entry in csvFile:
entries[entry[list(entry.keys())[0]]] = entry
return entries
# init_state method takes the initial state file and returns a
# dictionary of dictionaries
def init_state(file_path: str) -> dict[dict]:
return read_csv(file_path)
def init_resources(file_path: str) -> dict[dict]:
return read_csv(file_path)
def init_transforms(folder_path: str) -> dict[dict]:
# read from folder file_path and loop through template files
# add each template file to the rules dict[dict]
transforms = {}
for x in os.listdir(folder_path):
if x.endswith(".tmpl"):
temp = parse(folder_path+"/"+x)
transforms[temp['name']] = temp
return transforms
# code by John Ford to read in template files
# modified to use dictionaries instead of the dataclass
def read_file(file_path: str) -> str:
file_contents = None
with open(file_path, mode='r') as file:
file_contents = file.read()
return file_contents
def validate_nonempty(template: str = "") -> bool:
return template != ""
def validate_enclosed(template: str = "") -> bool:
left_paren_count = template.count("(")
right_paren_count = template.count(")")
if left_paren_count != right_paren_count:
return False
return True
def validate_keywords(template: str = "") -> bool:
transform_keywords = ["TRANSFORM", "INPUTS", "OUTPUTS"]
for keyword in transform_keywords:
if not keyword in template:
return False
return True
def validate(template: str = ""):
if not validate_nonempty(template):
raise Exception("Empty template")
if not validate_enclosed(template):
raise Exception("Incorrect parentheses counts, verify all expressions are properly enclosed")
elif not validate_keywords(template):
raise Exception("Missing required keywords, verify transform is syntactically correct")
def build_resource_quantities(resource_quantities_block) -> [dict]:
quantities = []
regex = r"\(([A-Za-z]+) (\d)\)"
matches = re.finditer(regex, resource_quantities_block, re.MULTILINE)
for match in matches:
resource_name, resource_quantity = match.groups()
quantities.append({'name': resource_name,
'quantity': int(resource_quantity)})
return quantities
def build_transform_template(template_path: str, template: str) -> dict:
transform = {'name': '',
'inputs': [dict],
'outputs': [dict]
}
basename = os.path.basename(template_path)
transform_name = os.path.splitext(basename)[0]
transform['name'] = transform_name
inputs_start = template.index("INPUTS")
outputs_start = template.index("OUTPUTS")
inputs_string = template[inputs_start:outputs_start]
outputs_string = template[outputs_start:]
transform['inputs'] = build_resource_quantities(inputs_string)
transform['outputs'] = build_resource_quantities(outputs_string)
return transform
def parse(template_path: str) -> dict:
template = read_file(template_path)
validate(template)
transform_template = build_transform_template(template_path, template)
return transform_template