def load_user_incident_intervals(all_oncall, participation_matchers): assert all_oncall != I.empty() since = arrow.get(all_oncall.lower) until = arrow.get(all_oncall.upper) incident_intervals = I.empty() for incident in pypd.Incident.find(since=since, until=until): # Make sure that the start time of the incident is in a waiting window incident_start = __pd_parse_time(incident['created_at']).timestamp if all_oncall.contains(incident_start): # Add this incident interval to the list of incident work times participation_start = __user_participated_at_timestamp( incident, participation_matchers, ) incident_end = __pd_parse_time( incident['last_status_change_at']).timestamp participation_ival = I.closed(participation_start, incident_end) incident_intervals = incident_intervals.union(participation_ival) if participation_start < I.inf: logger.debug('User participated in incident %s from %s - %s', incident['id'], participation_start, incident_end) return incident_intervals
def read_memory_fast(s, module_list): module_list = sorted(module_list) # Get list of available address ranges for LSASS pslist = s.plugins.pslist(proc_regex='lsass.exe') task = next(pslist.filter_processes()) addr_space = task.get_process_address_space() max_memory = s.GetParameter("highest_usermode_address") mem_list = sorted([(run.start, run.end) for run in addr_space.get_address_ranges(end=max_memory) ]) # Enumerate modules, find "holes" that need zero filling filling = I.empty() for a, mod_start, size in module_list: d = I.IntervalDict() mod = I.closedopen(mod_start, mod_start + size) d[mod] = 'fill' # What parts of the module are available? for start, end in mem_list: mem = I.closedopen(start, end) if mem & mod != I.empty(): d[mem] = 'mem' if start > mod_start + size: break filling |= d.find('fill') # What to read, what to zero fill operations = [] for x in list(filling): operations.append((x.lower, x.upper, 'pad')) for start, end in mem_list: operations.append((start, end, 'mem')) # Read & fill memoryinfo_list = [] memory64_list = [] for start, end, op in sorted(operations): size = end - start mi = dict(BaseAddress=start, AllocationBase=0, AllocationProtect=0, RegionSize=size, Protect=0) mi['State'] = 0 mi['Type'] = 0 memoryinfo_list.append(mi) if op == 'fill': #data = b'\x00'*size # Attempt to read these anyway. Rekall will fill with zeros if the read fails data = addr_space.read(start, size) else: data = addr_space.read(start, size) memory64_list.append((start, size, data)) return memoryinfo_list, memory64_list
def test_overlaps(): # Overlaps should reject non supported types with pytest.raises(TypeError): I.closed(0, 1).to_atomic().overlaps(1) with pytest.raises(TypeError): I.closed(0, 1).overlaps(1) assert I.closed(0, 1).overlaps(I.closed(0, 1)) assert I.closed(0, 1).overlaps(I.open(0, 1)) assert I.open(0, 1).overlaps(I.closed(0, 1)) assert I.closed(0, 1).overlaps(I.openclosed(0, 1)) assert I.closed(0, 1).overlaps(I.closedopen(0, 1)) assert I.closed(1, 2).overlaps(I.closed(2, 3)) assert I.closed(1, 2).overlaps(I.closedopen(2, 3)) assert I.openclosed(1, 2).overlaps(I.closed(2, 3)) assert I.openclosed(1, 2).overlaps(I.closedopen(2, 3)) assert not I.closed(0, 1).overlaps(I.closed(3, 4)) assert not I.closed(3, 4).overlaps(I.closed(0, 1)) assert not I.closed(0, 1).overlaps(I.open(1, 2)) assert not I.closed(0, 1).overlaps(I.openclosed(1, 2)) assert not I.closedopen(0, 1).overlaps(I.closed(1, 2)) assert not I.closedopen(0, 1).overlaps(I.closedopen(1, 2)) assert not I.closedopen(0, 1).overlaps(I.openclosed(1, 2)) assert not I.closedopen(0, 1).overlaps(I.open(1, 2)) assert not I.open(0, 1).overlaps(I.open(1, 2)) assert not I.empty().overlaps(I.open(-I.inf, I.inf)) assert not I.open(-I.inf, I.inf).overlaps(I.empty())
def test_creation(): assert I.closed(0, 1) == I.AtomicInterval(I.CLOSED, 0, 1, I.CLOSED) assert I.open(0, 1) == I.AtomicInterval(I.OPEN, 0, 1, I.OPEN) assert I.openclosed(0, 1) == I.AtomicInterval(I.OPEN, 0, 1, I.CLOSED) assert I.closedopen(0, 1) == I.AtomicInterval(I.CLOSED, 0, 1, I.OPEN) assert I.closed(-I.inf, I.inf) == I.open(-I.inf, I.inf) assert I.singleton(2) == I.closed(2, 2) assert I.Interval() == I.open(0, 0) assert I.empty() == I.Interval() assert I.closed(3, -3) == I.empty() assert I.openclosed(3, 3) == I.empty() # I.empty() is a singleton assert I.empty() is I.empty() assert I.Interval(I.closed(0, 1).to_atomic()) == I.closed(0, 1) assert I.Interval(I.closed(0, 1)) == I.closed(0, 1) assert I.Interval(I.closed(0, 1).to_atomic(), I.closed(2, 3)) == I.closed(0, 1) | I.closed(2, 3) assert I.Interval(I.closed(0, 1) | I.closed(2, 3)) == I.closed(0, 1) | I.closed(2, 3) with pytest.raises(TypeError): I.Interval(1)
def test_overlaps_permissive(): assert I.closed(0, 1).overlaps(I.closed(0, 1), permissive=True) assert I.closed(0, 1).overlaps(I.open(0, 1), permissive=True) assert I.open(0, 1).overlaps(I.closed(0, 1), permissive=True) assert I.closed(0, 1).overlaps(I.openclosed(0, 1), permissive=True) assert I.closed(0, 1).overlaps(I.closedopen(0, 1), permissive=True) assert I.closed(1, 2).overlaps(I.closed(2, 3), permissive=True) assert I.closed(1, 2).overlaps(I.closedopen(2, 3), permissive=True) assert I.openclosed(1, 2).overlaps(I.closed(2, 3), permissive=True) assert I.openclosed(1, 2).overlaps(I.closedopen(2, 3), permissive=True) assert not I.closed(0, 1).overlaps(I.closed(3, 4), permissive=True) assert not I.closed(3, 4).overlaps(I.closed(0, 1), permissive=True) assert I.closed(0, 1).overlaps(I.open(1, 2), permissive=True) assert I.closed(0, 1).overlaps(I.openclosed(1, 2), permissive=True) assert I.closedopen(0, 1).overlaps(I.closed(1, 2), permissive=True) assert I.closedopen(0, 1).overlaps(I.closedopen(1, 2), permissive=True) assert not I.closedopen(0, 1).overlaps(I.openclosed(1, 2), permissive=True) assert not I.closedopen(0, 1).overlaps(I.open(1, 2), permissive=True) assert not I.open(0, 1).overlaps(I.open(1, 2), permissive=True) assert not I.empty().overlaps(I.open(-I.inf, I.inf), permissive=True) assert not I.open(-I.inf, I.inf).overlaps(I.empty(), permissive=True)
def load_user_incident_intervals(all_oncall, participation_matchers): assert all_oncall != I.empty() since = arrow.get(all_oncall.lower) until = arrow.get(all_oncall.upper) incident_intervals = I.empty() for incident in pypd.Incident.find(since=since, until=until): # Make sure that the start time of the incident is in a waiting window incident_start = __pd_parse_time(incident['created_at']).timestamp if all_oncall.contains(incident_start): # Add this incident interval to the list of incident work times participation_start = __user_participated_at_timestamp( incident, participation_matchers, ) incident_end = __pd_parse_time( incident['last_status_change_at'] ).timestamp participation_ival = I.closed(participation_start, incident_end) incident_intervals = incident_intervals.union(participation_ival) if participation_start < I.inf: logger.debug( 'User participated in incident %s from %s - %s', incident['id'], participation_start, incident_end ) return incident_intervals
def test_intersection(): assert I.closed(0, 1) & I.closed(0, 1) == I.closed(0, 1) assert I.closed(0, 1) & I.closed(0, 1).to_atomic() == I.closed(0, 1) assert I.closed(0, 1) & I.open(0, 1) == I.open(0, 1) assert I.openclosed(0, 1) & I.closedopen(0, 1) == I.open(0, 1) assert (I.closed(0, 1) & I.closed(2, 3)).is_empty() assert I.closed(0, 1) & I.empty() == I.empty()
def sousinter(K, k, V): if V == I.empty() or K == I.empty() or k == I.empty(): return (I.empty()) offset = V.lower - K.lower v = I.empty() for i in list(k): v |= ico(i.lower + offset, i.upper + offset) return (v)
def test_replace(): i = I.open(-I.inf, I.inf) assert i.replace(lower=lambda v: 1, upper=lambda v: 1) == I.open(-I.inf, I.inf) assert i.replace(lower=lambda v: 1, upper=lambda v: 2, ignore_inf=False) == I.open(1, 2) assert I.empty().replace(left=I.CLOSED, right=I.CLOSED) == I.empty() assert I.empty().replace(lower=1, upper=2) == I.open(1, 2) assert I.empty().replace(lower=lambda v: 1, upper=lambda v: 2) == I.empty() assert I.empty().replace(lower=lambda v: 1, upper=lambda v: 2, ignore_inf=False) == I.open(1, 2) i = I.closed(0, 1) | I.open(2, 3) assert i.replace() == i assert i.replace(I.OPEN, -1, 4, I.OPEN) == I.openclosed(-1, 1) | I.open(2, 4) assert i.replace(lower=2) == I.closedopen(2, 3) assert i.replace(upper=1) == I.closedopen(0, 1) assert i.replace(lower=5) == I.empty() assert i.replace(upper=-5) == I.empty() assert i.replace( left=lambda v: not v, lower=lambda v: v - 1, upper=lambda v: v + 1, right=lambda v: not v) == I.openclosed(-1, 1) | I.openclosed(2, 4) assert I.empty().replace(lower=2, upper=4) == I.open(2, 4)
def add_vote(compte, sender, receiver, nxtlvl): vs, rb = lc[sender].trans, (receiver, nxtlvl) vs[rb] = vs.get(rb, I.empty()) lc[receiver].recu = True if nxtlvl - 1 <= lc[compte].niveau <= nxtlvl: vs[rb] |= lc[compte].piece & actifs.get(max(0, nxtlvl - 3), I.empty()) if lc[sender].piece != I.empty() and lc[receiver].piece == I.empty()\ and nxtlvl <= maxlvl + 1 and\ sizeunion(vs[rb]) >= seuil * sizeunion(actifs.get(max(0,nxtlvl - 3), I.empty())) : activate(sender, receiver, nxtlvl) else: lc[compte].defense.add((sender, receiver, nxtlvl))
def test_difference(): assert I.closed(1, 4) - I.closed(1, 3) == I.openclosed(3, 4) assert I.closed(1, 4) - I.closed(1, 3).to_atomic() == I.openclosed(3, 4) assert I.closed(1, 4).to_atomic() - I.closed(1, 3).to_atomic() == I.openclosed(3, 4) assert (I.closed(1, 4) - I.closed(1, 4)).is_empty() assert I.closed(0, 1) - I.closed(2, 3) == I.closed(0, 1) assert I.closed(0, 4) - I.closed(2, 3) == I.closedopen(0, 2) | I.openclosed(3, 4) assert I.closed(0, 4) - I.closed(2, 3) == I.closed(0, 4).to_atomic() - I.closed(2, 3) assert I.closed(0, 4) - I.closed(2, 3) == I.closed(0, 4).to_atomic() - I.closed(2, 3).to_atomic() assert I.closed(0, 4) - I.closed(2, 3) == I.closed(0, 4) - I.closed(2, 3).to_atomic() assert I.closed(0, 4) - I.empty() == I.closed(0, 4) assert I.empty() - I.closed(0, 4) == I.empty()
def activate(sender, receiver, nxtlvl) : global vivants, morts print("vote validant", receiver, "actifs", actifs, maxlvl) vivants = (vivants | receiver) - sender morts |= sender actifs[nxtlvl] = actifs.get(nxtlvl, I.empty()) | lc[sender].piece maj_lvl() lc[receiver].niveau = nxtlvl lc[receiver].piece = lc[sender].piece lc[receiver].density = lc[sender].density * [0.9,0.8][nxtlvl >= lc[sender].niveau + 2] print("new density", lc[receiver].density) for (s2, r2, n2) in lc[receiver].defense : decoupe(receiver, s2, r2, n2) for (r2, n2) in lc[receiver].trans : decoupe(I.empty(), receiver, r2, n2)
def test_containment_for_intervals(): # Intervals assert I.closed(1, 2) in I.closed(0, 3) assert I.closed(1, 2) in I.closed(1, 2) assert I.open(1, 2) in I.closed(1, 2) assert I.closed(1, 2) not in I.open(1, 2) assert I.closed(0, 1) not in I.closed(1, 2) assert I.closed(0, 2) not in I.closed(1, 3) assert I.closed(-I.inf, I.inf) in I.closed(-I.inf, I.inf) assert I.closed(0, 1) in I.closed(-I.inf, I.inf) assert I.closed(-I.inf, I.inf) not in I.closed(0, 1) assert I.empty() in I.closed(0, 3) assert I.empty() in I.empty() assert I.closed(0, 0) not in I.empty()
def recep(compte, sender, receiver, nxtlvl): [newsenderl, newreceiverl] = map(list, decoupe(compte, sender, receiver, nxtlvl)) if newsenderl != [I.empty()]: for (i, senderk) in enumerate(newsenderl): output(monint, senderk.lower, senderk.upper, newreceiverl[i].lower, nxtlvl)
def createIntervals(s, e): x = I.empty() s = [int(i) for i in s.split(',')] e = [int(i) for i in e.split(',')] for i in range(len(s)): x = x | I.closed(s[i], e[i]) return (x)
def independence_list(self, signature): il = [] v = self.values.get(signature) for key in self.values.keys(): if ((self.values[key] & v) == I.empty()): il.append(key) return il
def test_union(): assert I.closed(1, 2).to_atomic() | I.closed(1, 2).to_atomic() == I.closed(1, 2).to_atomic() assert I.closed(1, 4).to_atomic() | I.closed(2, 3).to_atomic() == I.closed(1, 4).to_atomic() assert I.closed(1, 2).to_atomic() | I.closed(2, 3).to_atomic() == I.closed(2, 3).to_atomic() | I.closed(1, 2).to_atomic() assert I.closed(1, 2).to_atomic() | I.closed(3, 4).to_atomic() == I.closed(1, 2) | I.closed(3, 4) assert I.closed(1, 2) | I.closed(1, 2) == I.closed(1, 2) assert I.closed(1, 4) | I.closed(2, 3) == I.closed(2, 3) | I.closed(1, 4) assert I.closed(1, 4) | I.closed(2, 3) == I.closed(1, 4) assert I.closed(1, 4) | I.closed(2, 3).to_atomic() == I.closed(1, 4) assert I.closed(1, 4) | I.closed(2, 3).to_atomic() == I.closed(2, 3).to_atomic() | I.closed(1, 4) assert I.closed(1, 2) | I.open(2, 3) == I.closedopen(1, 3) assert I.closed(1, 3) | I.closed(2, 4) == I.closed(1, 4) assert I.closed(1, 2) | I.closed(2, 3) == I.closed(2, 3) | I.closed(1, 2) assert I.closedopen(1, 2) | I.closed(2, 3) == I.closed(1, 3) assert I.open(1, 2) | I.closed(2, 4) == I.openclosed(1, 4) assert I.closed(1, 2) | I.closed(3, 4) != I.closed(1, 4) assert (I.closed(1, 2) | I.closed(3, 4) | I.closed(2, 3)).is_atomic() assert I.closed(1, 2) | I.closed(3, 4) | I.closed(2, 3) == I.closed(1, 4) assert I.closed(1, 2) | I.closed(0, 4) == I.closed(0, 4) assert (I.closed(0, 1) | I.closed(2, 3) | I.closed(1, 2)).is_atomic() assert I.closed(0, 1) | I.closed(2, 3) | I.closed(1, 2) == I.closed(0, 3) assert I.closed(0, 1) | I.empty() == I.closed(0, 1)
def test_apply(): i = I.closed(0, 1) assert i.apply(lambda s: s) == i assert i.apply(lambda s: (False, -1, 2, False)) == I.open(-1, 2) assert i.apply(lambda s: I.AtomicInterval(False, -1, 2, False)) == I.open( -1, 2) assert i.apply(lambda s: I.open(-1, 2)) == I.open(-1, 2) i = I.closed(0, 1) | I.closed(2, 3) assert i.apply(lambda s: s) == i assert i.apply(lambda s: (False, -1, 2, False)) == I.open(-1, 2) assert i.apply(lambda s: (not s.left, s.lower - 1, s.upper - 1, not s.right )) == I.open(-1, 0) | I.open(1, 2) assert i.apply(lambda s: I.AtomicInterval(False, -1, 2, False)) == I.open( -1, 2) assert i.apply(lambda s: I.open(-1, 2)) == I.open(-1, 2) assert i.apply(lambda s: (s.left, s.lower, s.upper * 2, s.right)) == I.closed(0, 6) assert I.empty().apply(lambda s: (I.CLOSED, 1, 2, I.CLOSED)) == I.closed( 1, 2) with pytest.raises(TypeError): i.apply(lambda s: None) with pytest.raises(TypeError): i.apply(lambda s: 'unsupported')
def load_oncall(since, until, schedule_id_list, user_id): oncall = I.empty() for schedule_id in schedule_id_list: schedule = pypd.Schedule.fetch( id=schedule_id, since=since, until=until, time_zone='UTC', ) entries = schedule['final_schedule']['rendered_schedule_entries'] for rendered_entry in entries: rendered_user_id = rendered_entry['user']['id'] if rendered_user_id != user_id: logger.debug('Skipping user id: %s', rendered_user_id) continue oncall_start = __pd_parse_time(rendered_entry['start']) oncall_end = __pd_parse_time(rendered_entry['end']) logger.debug('Found oncall: %s - %s', oncall_start, oncall_end) oncall = oncall.union(__times_to_interval(oncall_start, oncall_end)) return oncall
def parse_input(input_lines): RULE_PATTERN = re.compile("(?P<start>[0-9]+)-(?P<end>[0-9]+)") rules = {} my_ticket = [] other_tickets = [] is_done_rules, is_done_my_ticket = False, False for input_line in input_lines: if (len(input_line) == 0) or ('ticket' in input_line): is_done_rules = True continue if not is_done_rules: field, valid_ranges_raw = input_line.split(':') rules[field] = intervals.empty() for start_range, end_range in RULE_PATTERN.findall( valid_ranges_raw): valid_interval = intervals.closed(int(start_range), int(end_range)) rules[field] = rules[field].union(valid_interval) elif not is_done_my_ticket: my_ticket = [int(value) for value in input_line.split(',')] is_done_my_ticket = True else: other_ticket = [int(value) for value in input_line.split(',')] other_tickets.append(other_ticket) return rules, my_ticket, other_tickets
def sizeunion(union): if union == I.empty(): return 0 s = 0 for i in list(union): s += i.upper - i.lower return s
def test_from_string_customized(): i1, i2, i3, i4 = '<"0"-"1">', '<!"0"-"1">', '<"0"-"1"!>', '<!"0"-"1"!>' params = { 'conv': lambda s: int(s[1:-1]), 'disj': ' or ', 'sep': '-', 'left_open': '<!', 'left_closed': '<', 'right_open': '!>', 'right_closed': '>', 'pinf': r'\+oo', 'ninf': '-oo', } assert I.from_string(i1, **params) == I.closed(0, 1) assert I.from_string(i2, **params) == I.openclosed(0, 1) assert I.from_string(i3, **params) == I.closedopen(0, 1) assert I.from_string(i4, **params) == I.open(0, 1) assert I.from_string('<!!>', **params) == I.empty() assert I.from_string('<"1">', **params) == I.singleton(1) assert I.from_string('<!-oo-"1">', **params) == I.openclosed(-I.inf, 1) assert I.from_string('<"1"-+oo!>', **params) == I.closedopen(1, I.inf) assert I.from_string('<"0"-"1"> or <"2"-"3">', **params) == I.closed(0, 1) | I.closed(2, 3)
def test_to_string_customized(): i1, i2, i3, i4 = I.closed(0, 1), I.openclosed(0, 1), I.closedopen(0, 1), I.open(0, 1) params = { 'disj': ' or ', 'sep': '-', 'left_open': '<!', 'left_closed': '<', 'right_open': '!>', 'right_closed': '>', 'conv': lambda s: '"{}"'.format(s), 'pinf': '+oo', 'ninf': '-oo', } assert I.to_string(i1, **params) == '<"0"-"1">' assert I.to_string(i2, **params) == '<!"0"-"1">' assert I.to_string(i3, **params) == '<"0"-"1"!>' assert I.to_string(i4, **params) == '<!"0"-"1"!>' assert I.to_string(I.empty(), **params) == '<!!>' assert I.to_string(I.singleton(1), **params) == '<"1">' assert I.to_string(I.openclosed(-I.inf, 1), **params) == '<!-oo-"1">' assert I.to_string(I.closedopen(1, I.inf), **params) == '<"1"-+oo!>' assert I.to_string(I.closed(0, 1) | I.closed(2, 3), **params) == '<"0"-"1"> or <"2"-"3">'
def test_emptiness(): assert I.openclosed(1, 1).is_empty() assert I.closedopen(1, 1).is_empty() assert I.open(1, 1).is_empty() assert not I.closed(1, 1).is_empty() assert I.Interval().is_empty() assert I.empty().is_empty()
def parse_or_empty(parser, text, verbose=False): try: return parser.parse(text) except Exception as e: if verbose: print('E:', text) return I.empty()
def generate_activity_intervals(since, until, engineer, load_incidents): all_oncall = report.load_oncall( since, until, engineer.oncall_schedules, engineer.pagerduty_id, ) logger.debug('Entire oncall range: %s', all_oncall) if all_oncall == I.empty(): logger.debug('Engineer was not oncall during range!') sys.exit(0) work_schedule = report.generate_work_schedule( since, until, engineer.workday_schedule, engineer.day_start_time, engineer.day_length_hours, ) logger.debug('Entire work schedule: %s', work_schedule) waiting_times = all_oncall.difference(work_schedule) logger.debug('Oncall waiting times: %s', waiting_times) incident_intervals = I.empty() if load_incidents: participation_matchers = [ report.LogParticipationMatcher('id', engineer.pagerduty_id), ] if engineer.slack_username is not None: participation_matchers.append( report.LogParticipationMatcher('name', engineer.slack_username)) incident_intervals = report.load_user_incident_intervals( all_oncall, participation_matchers, ) logger.debug('Incident intervals: %s', incident_intervals) waiting_pay = waiting_times.difference(incident_intervals) incident_pay = incident_intervals.difference(work_schedule) return [ report.ActivityInterval('waiting', waiting_pay), report.ActivityInterval('incident', incident_pay), ]
def test_union(): assert I.closed(1, 2).to_atomic() | I.closed(1, 2).to_atomic() == I.closed(1, 2).to_atomic() assert I.closed(1, 4).to_atomic() | I.closed(2, 3).to_atomic() == I.closed(1, 4).to_atomic() assert I.closed(1, 2).to_atomic() | I.closed(2, 3).to_atomic() == I.closed(2, 3).to_atomic() | I.closed(1, 2).to_atomic() assert I.closed(1, 2).to_atomic() | I.closed(3, 4).to_atomic() == I.closed(1, 2) | I.closed(3, 4) assert I.closed(1, 2) | I.closed(1, 2) == I.closed(1, 2) assert I.closed(1, 4) | I.closed(2, 3) == I.closed(2, 3) | I.closed(1, 4) assert I.closed(1, 4) | I.closed(2, 3) == I.closed(1, 4) assert I.closed(1, 4) | I.closed(2, 3).to_atomic() == I.closed(1, 4) assert I.closed(1, 4) | I.closed(2, 3).to_atomic() == I.closed(2, 3).to_atomic() | I.closed(1, 4) assert I.closed(1, 2) | I.open(2, 3) == I.closedopen(1, 3) assert I.closed(1, 3) | I.closed(2, 4) == I.closed(1, 4) assert I.closed(1, 2) | I.closed(2, 3) == I.closed(2, 3) | I.closed(1, 2) assert I.closedopen(1, 2) | I.closed(2, 3) == I.closed(1, 3) assert I.open(1, 2) | I.closed(2, 4) == I.openclosed(1, 4) assert I.closed(1, 2) | I.closed(3, 4) != I.closed(1, 4) assert (I.closed(1, 2) | I.closed(3, 4) | I.closed(2, 3)).is_atomic() assert I.closed(1, 2) | I.closed(3, 4) | I.closed(2, 3) == I.closed(1, 4) assert I.closed(1, 2) | I.closed(0, 4) == I.closed(0, 4) assert (I.closed(0, 1) | I.closed(2, 3) | I.closed(1, 2)).is_atomic() assert I.closed(0, 1) | I.closed(2, 3) | I.closed(1, 2) == I.closed(0, 3) assert I.closed(0, 1) | I.empty() == I.closed(0, 1) # https://github.com/AlexandreDecan/python-intervals/issues/12 assert I.open(0, 2) | I.closed(0, 2) == I.closed(0, 2) assert I.open(0, 2) | I.closed(1, 2) == I.openclosed(0, 2) assert I.open(0, 2) | I.closed(0, 1) == I.closedopen(0, 2) assert I.closed(0, 2) | I.open(0, 2) == I.closed(0, 2) assert I.closed(1, 2) | I.open(0, 2) == I.openclosed(0, 2) assert I.closed(0, 1) | I.open(0, 2) == I.closedopen(0, 2) assert I.closed(0, 2) | I.singleton(2) == I.closed(0, 2) assert I.closedopen(0, 2) | I.singleton(2) == I.closed(0, 2) assert I.openclosed(0, 2) | I.singleton(2) == I.openclosed(0, 2) assert I.openclosed(0, 2) | I.singleton(0) == I.closed(0, 2) assert I.singleton(2) | I.closed(0, 2) == I.closed(0, 2) assert I.singleton(2) | I.closedopen(0, 2) == I.closed(0, 2) assert I.singleton(2) | I.openclosed(0, 2) == I.openclosed(0, 2) assert I.singleton(0) | I.openclosed(0, 2) == I.closed(0, 2) # https://github.com/AlexandreDecan/python-intervals/issues/13 assert I.closed(1, 1) | I.openclosed(1, 2) == I.closed(1, 2) assert I.openclosed(1, 2) | I.closed(1, 1) == I.closed(1, 2) assert I.closed(0, 1) | I.openclosed(1, 2) == I.closed(0, 2) assert I.openclosed(1, 2) | I.closed(0, 1) == I.closed(0, 2) assert I.openclosed(1, 2) | I.closed(1, 1) == I.closed(1, 2) assert I.closed(1, 1) | I.openclosed(1, 2) == I.closed(1, 2) assert I.openclosed(1, 2) | I.closed(0, 1) == I.closed(0, 2) assert I.closed(0, 1) | I.openclosed(1, 2) == I.closed(0, 2)
async def reset_me(ctx): name = ctx.author.name time_intervals[name] = I.empty() await ctx.send(f'Emptied the timetable for {name}.') await send_state_in_discord(f'reset_me ({name})')
def monfric(compte): envie = compte & vivants somme = 0. for itv in lc: mapart = itv & envie if mapart != I.empty(): somme += sizeunion(mapart) * lc[itv].density return somme
def check(k, v): if k == I.empty() or (k in lc and v in lc): return for (cle, compte) in lc.items(): kcommun = cle & k if kcommun != I.empty(): vcommun = sousinter(k, kcommun, v) k -= kcommun v -= vcommun if kcommun != cle: adapte_coupe(cle, kcommun, compte) adapte_coupe(cle, cle - kcommun, compte) lc.pop(cle) check(vcommun, kcommun) check(k, v) break check(v, k)
def recep_aux(l): [compte, sender, receiver, nxtlvl] = l (vs, rb) = (lc[sender].trans, (receiver, nxtlvl)) if rb not in vs: lc[compte].defense.add((sender, receiver, nxtlvl)) vs[rb] = vs.get(rb, I.empty()) | compte if lc[sender].piece: update(sender, (rb, vs[rb]))
def split_into_days(activity_intervals, tz): start = I.inf end = -I.inf for _, intervals in activity_intervals: start = min(start, intervals.lower) end = max(end, intervals.upper) midnights = I.empty() day_span_range = arrow.Arrow.span_range( 'day', arrow.get(start), arrow.get(end), tz=tz, ) for midnight, _ in day_span_range: midnights = midnights.union( I.closed(midnight.timestamp, midnight.timestamp) ) logger.debug('Midnights: %s', midnights) hours_per_day = defaultdict(lambda: defaultdict(int)) for report_name, intervals in activity_intervals: if intervals == I.empty(): continue pay_interval_by_day = intervals.difference(midnights) for day_interval in pay_interval_by_day: logger.debug( 'Day interval[%s]: %s - %s', report_name, day_interval.lower, day_interval.upper, ) total_seconds = day_interval.upper - day_interval.lower interval_date = datetime.fromtimestamp(day_interval.lower).date() hours_per_day[interval_date][report_name] += total_seconds/3600 return hours_per_day
def generate_activity_intervals(since, until, engineer): all_oncall = report.load_oncall( since, until, engineer.oncall_schedules, engineer.pagerduty_id, ) logger.debug('Entire oncall range: %s', all_oncall) if all_oncall == I.empty(): logger.debug('Engineer was not oncall during range!') sys.exit(0) work_schedule = report.generate_work_schedule( since, until, engineer.workday_schedule, engineer.day_start_time, engineer.day_length_hours, ) logger.debug('Entire work schedule: %s', work_schedule) waiting_times = all_oncall.difference(work_schedule) logger.debug('Oncall waiting times: %s', waiting_times) participation_matchers = [ report.LogParticipationMatcher('id', engineer.pagerduty_id), ] if engineer.slack_username is not None: participation_matchers.append( report.LogParticipationMatcher('name', engineer.slack_username) ) incident_intervals = report.load_user_incident_intervals( all_oncall, participation_matchers, ) logger.debug('Incident intervals: %s', incident_intervals) waiting_pay = waiting_times.difference(incident_intervals) incident_pay = incident_intervals.difference(work_schedule) return [ report.ActivityInterval('waiting', waiting_pay), report.ActivityInterval('incident', incident_pay), ]
def generate_work_schedule(since, until, workdays, workday_start_time, hours_per_day): work_schedule = I.empty() for day_start, day_end in arrow.Arrow.span_range('day', since, until): if workdays.contains(day_start.weekday()): logger.debug('%s is a workday', day_start) workday_start = arrow.Arrow.fromdatetime( datetime.combine( day_start.datetime.date(), workday_start_time, ), day_start.tzinfo, ) workday_end = workday_start.shift(hours=hours_per_day) logger.debug('Workday times: %s - %s', workday_start, workday_end) workday_interval = __times_to_interval(workday_start, workday_end) work_schedule = work_schedule.union(workday_interval) return work_schedule