-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathroute.py
129 lines (106 loc) · 3.33 KB
/
route.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
125
126
127
128
129
#!/usr/bin/env python
# Python coding challenge
# Takes vlans.csv and requests.csv as input and produces output.csv that
# specifies which requests reserved which VLAN_IDs on which port and device.
import csv, sqlite3, argparse
# Set default input files
parser = argparse.ArgumentParser()
parser.add_argument('requests', nargs='?', const=1, default='requests.csv')
parser.add_argument('vlans', nargs='?', const=1, default='vlans.csv')
args = parser.parse_args()
# Database connection
con = sqlite3.connect(":memory:")
con.row_factory = sqlite3.Row
cur = con.cursor()
# Create requests schema
cur.execute("""\
CREATE TABLE requests (
id INTEGER PRIMARY KEY NOT NULL ,
request_id int NOT NULL ,
redundant tinyint(1) NOT NULL
);
""")
cur.execute("""\
CREATE UNIQUE INDEX unique_requests
ON requests (request_id)
""")
# Create vlans schema
cur.execute("""\
CREATE TABLE vlans (
id INTEGER PRIMARY KEY NOT NULL ,
device_id int NOT NULL ,
primary_port tinyint(1) NOT NULL ,
vlan_id int NOT NULL ,
reserved tinyint(1) DEFAULT 0
);
""")
cur.execute("""\
CREATE UNIQUE INDEX unique_vlans
ON vlans (vlan_id, device_id, primary_port)
""")
con.commit()
# Load vlans.csv
with open(args.vlans, 'rb') as vlan_handle:
reader = csv.DictReader(vlan_handle)
all_rows = [(row['device_id'], row['primary_port'], row['vlan_id'])
for row in reader]
cur.executemany(
"INSERT INTO vlans (device_id, primary_port, vlan_id) VALUES (?, ?, ?);",
all_rows)
con.commit()
# Load requests.csv
with open(args.requests, 'rb') as request_handle:
reader = csv.DictReader(request_handle)
all_rows = [(row['request_id'], row['redundant']) for row in reader]
cur.executemany("INSERT INTO requests (request_id, redundant) VALUES (?, ?);",
all_rows)
con.commit()
# Create output file with header
writer = csv.writer(open("./output.csv", 'w'))
writer.writerow(['request_id', 'device_id', 'primary_port', 'vlan_id'])
# Request functions
def normal_request(request_id):
c = con.cursor()
c.execute("""
SELECT id, device_id, primary_port, vlan_id
FROM vlans
WHERE primary_port = 1
AND reserved = 0
ORDER BY vlan_id, device_id ASC
LIMIT 1
""")
row = c.fetchone()
c.execute("UPDATE vlans SET reserved=? WHERE id=?", (1, row['id']))
writer.writerow(
[request_id, row['device_id'], row['primary_port'], row['vlan_id']])
def redundant_request(request_id):
c = con.cursor()
c.execute("""
SELECT vlan_id, device_id
FROM vlans
WHERE reserved = 0
GROUP BY device_id, vlan_id
HAVING COUNT(primary_port) = 2
ORDER BY vlan_id ASC, device_id ASC
LIMIT 1
""")
row = c.fetchone()
c.execute("UPDATE vlans SET reserved=? WHERE vlan_id=? AND device_id=?",
(1, row['vlan_id'], row['device_id']))
for i in range(2):
writer.writerow([request_id, row['device_id'], i, row['vlan_id']])
# Route requests
cur.execute("""\
SELECT request_id, redundant
FROM requests
ORDER BY request_id ASC
""")
while True:
row = cur.fetchone()
if row == None:
break
elif row["redundant"]:
redundant_request(row['request_id'])
else:
normal_request(row['request_id'])
con.close()