forked from season-lab/program-generator
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtimerange.py
More file actions
155 lines (120 loc) · 4.39 KB
/
timerange.py
File metadata and controls
155 lines (120 loc) · 4.39 KB
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
class TimeRange(object):
def __init__(self, conference):
self.conference = conference
self.sessions = []
self._start = None
self._end = None
self.additional_start_ticks = []
def add_session(self, session, update_start_end=True):
if update_start_end:
if self._start is None or session.start < self.start:
self._start = session.start
if self._end is None or session.end > self.end:
self._end = session.end
if session.start > self._start and session.start not in self.additional_start_ticks:
self.additional_start_ticks.append(session.start)
self.sessions.append(session)
def conflict(self, session):
if self._start is None and self._end is None:
return False
start_a = self._start
end_a = self._end
start_b = session.start
end_b = session.end
return (start_a >= start_b and end_a >= end_b) \
or (start_a >= start_b and end_a < end_b) \
or (start_b >= start_a and end_b < end_a) \
or (start_b >= start_a and start_b < start_a) \
or (start_a <= start_b and end_a > start_b)
@property
def start(self):
assert self._start is not None
return self._start
@start.setter
def start(self, v):
self._start = v
@property
def end(self):
assert self._end is not None
return self._end
@end.setter
def end(self, v):
self._end = v
def get_sessions_track(self, track):
sessions = []
for session in self.sessions:
if track is not None and session.track != track:
continue
placed = False
if len(sessions) == 0:
sessions.append([session])
else:
for subtrack in sessions:
for ses in subtrack:
if session.conflict(ses):
subtrack.append(session)
placed = True
break
if placed:
break
if not placed:
sessions.append([session])
return sessions
def width_track(self, track):
tracks = {}
for session in self.sessions:
if track is not None and session.track != track:
continue
placed = False
if session.track.name not in tracks:
tracks[session.track.name] = [[session]]
else:
for subtrack in tracks[session.track.name]:
for ses in subtrack:
if session.conflict(ses):
subtrack.append(session)
placed = True
break
if placed:
break
if not placed:
tracks[session.track.name].append([session])
width = 0
for track in tracks:
max_width = 0
for subtrack in tracks[track]:
max_width = len(subtrack) if len(subtrack) > max_width else max_width
width += max_width
return width
@property
def width(self):
return self.width_track(None)
@property
def tracks(self):
tracks = []
for session in self.sessions:
if session.track not in tracks:
tracks.append(session.track)
return tracks
def has_track(self, track_name, session_name=None):
for session in self.sessions:
if session.track.name == track_name:
if session_name is None:
return True
elif session.name != session_name:
return True
return False
def has_track_with_session(self, track_name, session_name=None):
for session in self.sessions:
if session.track.name == track_name:
if session_name is None:
return True
elif session.name == session_name:
return True
return False
def get_sessions_by_track(self, track_name):
sessions = []
for session in self.sessions:
if session.track.name == track_name:
sessions.append(session)
return sessions