-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathena_map.py
124 lines (101 loc) · 5.27 KB
/
ena_map.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
from util import Selectors, Settings
import math
class ENAMap:
def __init__(self, squares_x, squares_y, meters_per_square):
self.squares_x = squares_x
self.squares_y = squares_y
self.meters_per_square = meters_per_square
self.squares = [[Square(y * meters_per_square, x * meters_per_square) for x in range(self.squares_y)] for y in range(self.squares_x)]
def __repr__(self):
return "\n".join(["|".join([str(sq) for sq in sqlist]) for sqlist in self.squares])
def set_square_coverage(self, x, y, coverage):
self.squares[x][y].coverage = coverage
def add_square_feature(self, x, y, feature):
self.squares[x][y].add_feature(feature)
def check_squares(self):
selectors = Selectors()
ap_squares = self.get_squares_with_APs()
for square in [square for sublist in self.squares for square in sublist]:
if square.coverage:
if selectors.get_by_repr(square.coverage).hasattr("check"):
square.check = ap_squares and selectors.get_by_repr(square.coverage).check > min([square.distance(ap) for ap in ap_squares])
else:
square.check = True
def get_uncovered_squares(self):
return [square for sublist in self.squares for square in sublist if not square.check]
def get_squares_with_APs(self):
return [square for sublist in self.squares for square in sublist if "A" in square.features]
def get_squares_with_uplinks(self):
return [square for sublist in self.squares for square in sublist if "U" in square.features]
def get_squares_with_cables(self):
return [square for sublist in self.squares for square in sublist if "C" in [feat[:1] for feat in square.features]]
def count_uncharted_squares(self):
return sum([1 for sublist in self.squares for square in sublist if not square.coverage])
def calculate_gear(self, format=False):
settings = Settings()
needed_slack = settings.getfloat("DISTANCES", "needed_slack")
possible_cables = [3, 5, 10, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100]
gear = {
"small switch" : 0,
"large switch" : 0,
"access point": 0,
"cables": {c:0 for c in possible_cables},
}
uplink_squares = self.get_squares_with_uplinks()
uplinks = [0 for _ in uplink_squares] # list of amount of connections per uplink
for ap in self.get_squares_with_APs(): # for all our Access Points
closest_up = -1
closet_dist = 99999999
for i, upsq in enumerate(uplink_squares): # find the closest uplink
dist = ap.manhattan_distance(upsq) + needed_slack
if dist < closet_dist:
closet_dist = dist
closest_up = i
uplinks[closest_up] += 1 # add 1 to connection counter of the closest uplink
gear['cables'][[c for c in possible_cables if c > closet_dist][0]] += 1 # add needed cable
gear['access point'] += 1 # add access point
for cab in self.get_squares_with_cables(): # for all cable squares
closest_up = -1
closet_dist = 99999999
for i, upsq in enumerate(uplink_squares): # find closest uplink
dist = ap.manhattan_distance(upsq) + needed_slack
if dist < closet_dist:
closet_dist = dist
closest_up = i
uplinks[closest_up] += 1 # add 1 to connection counter of the closest uplink
gear['cables'][[c for c in possible_cables if c > closet_dist][0]] += 1 # add needed cable
cables_needed_at_point = [int(feat[1:]) for feat in cab.features if feat[:1] == 'C'][0]
if cables_needed_at_point > 1:
gear['small switch'] += 1 # add small switch
gear['cables'][5] += cables_needed_at_point # add 5m cables
for i, connections in enumerate(uplinks):
if connections > 0:
gear['large switch'] += 1
gear['cables'][3] += 1
return self.format_gear(gear) if format else gear
def format_gear(self, gear):
string = ""
for gear_type, gear_amount in gear.items():
if type(gear_amount) == int:
string += f'{gear_type}: {gear_amount}\n'
elif type(gear_amount) == dict: # if amount is a sub dictionary
string += f'{gear_type}:\n'
for cable_length, cable_amount in gear_amount.items():
if cable_amount > 0:
string += f' {cable_length}m: {cable_amount}\n'
return string
class Square:
def __init__(self, pos_x, pos_y, coverage=None):
self.x = pos_x # real x position
self.y = pos_y # real y position
self.coverage = coverage
self.features = []
self.check = False
def __repr__(self):
return f'{self.x}, {self.y} {self.coverage} {"y" if self.check else "n"} {self.features}'
def add_feature(self, feature):
self.features.append(feature)
def distance(self, square):
return math.sqrt( (square.x - self.x)**2 + (square.y - self.y)**2)
def manhattan_distance(self, square):
return abs(square.x - self.x) + abs(square.y-self.y)