def calc_compensate_phases_t_extra_raw( v_cap: Optional[float], dsc_distances, capped_distances, class_phase_boundaries, ) -> pd.Series: """ Extra time each phase needs to run at `v_cap` to equalize `V_capped` distance with `V_dsc`. :param v_cap: Compensation applies only if `v_cap` > 0. :return: a series with the # of extra secs for each phase (which may be full of 0s) This functions checks zero/null `v_cap` condition. """ lengths = [ len(i) for i in (class_phase_boundaries, dsc_distances, capped_distances) ] assert itb.same( lengths ), f"# of phases missmatched phase-distances: {lengths}\n {locals()}" # What to return when decided not to compensate V-trace. no_compensation = pd.Series(0, index=capped_distances.index) if not v_cap or v_cap < 0: log.info("Skipped distance-compensation due to v_cap(%s)", v_cap) return no_compensation # Annex 1-9.2.1 simplified: # # - The 3.6 divisor cancels out with the t_diff formula below. # # - It also runs a 2-rolling-average window on the values, # which in effect affects only the 1st and last elements # which for phase-boundaries are both 0. phase_delta_s = dsc_distances["sum"] - capped_distances["sum"] if not phase_delta_s.any(): log.info("Distance-compensation is not needed.") return no_compensation assert (phase_delta_s >= 0).all(), f"Capped less than downscaled!?? {locals()}" # Annex 1-9.2.2 simplified: 3.6 factor canceled out, above. delta_t = phase_delta_s / v_cap return delta_t
def _run(*args, color=False): # We allow for nested iterables and None values as args for # convenience. We just need to flatten and filters them out. args = list(filter(None.__ne__, flatten(args))) if args: assert same(map(type, args), str) result = runner.invoke(mdedup, args, color=color) print_cli_output([CLI_NAME] + args, result.output) # Print some more debug info. print(result) if result.exception: print( ExceptionInfo.from_exc_info(*result.exc_info).get_formatted()) return result
def _make_box(box_type, mails=None): """Create a fake maildir and populate it with mails.""" # Check parameters. assert box_type in (Maildir, mbox) assert issubclass(box_type, Mailbox) if not mails: mails = [] assert same(map(type, mails), MailFactory) # Create the container under a random name and put all provided mails there. box = box_type(tmp_path.joinpath(uuid4().hex), create=True) box.lock() for fake_mail in mails: box.add(fake_mail.render()) box.close() return box._path, box_type
def check_box(box_path, box_type, content=None): """Check the content of a mail box (in any of maildir of mbox format). Does not use ``set()`` types internally to avoid silent deduplication. Translates all mails provided to ``mailbox.Message`` instances to provide fair comparison in a normalized space. """ # Check provided parameters. assert isinstance(box_path, str) assert box_type in (Maildir, mbox) assert not isinstance(content, set) if content is None: content = [] assert same(map(type, content), MailFactory) # Compares the content of the box. box = box_type(box_path, create=False) # TODO: use a COunter to count occurrences assert len(box) == len(content) mails_found = sorted([str(m) for m in box]) assert sorted([str(m.as_message()) for m in content]) == mails_found box.close()
def all_same(self): return iterutils.same(self) # to list def head(self, n=10): return KpaIterable(item for _,item in zip(range(n), self))