def test_traverse(): """To test the traverse implementation we call gc.collect() while instances of all the C objects are still valid.""" acc = iteration_utilities.accumulate([]) app = iteration_utilities.applyfunc(lambda x: x, 1) cha = iteration_utilities.chained(int, float) cla = iteration_utilities.clamp([], 0, 1) com = iteration_utilities.complement(int) con = iteration_utilities.constant(1) dee = iteration_utilities.deepflatten([]) dup = iteration_utilities.duplicates([]) fli = iteration_utilities.flip(int) gro = iteration_utilities.grouper([], 2) ine = iteration_utilities.intersperse([], 1) iik = iteration_utilities.ItemIdxKey(10, 2) ite = iteration_utilities.iter_except(int, TypeError) mer = iteration_utilities.merge([]) nth = iteration_utilities.nth(1) pac = iteration_utilities.packed(int) par = iteration_utilities.partial(int, 10) rep = iteration_utilities.replicate([], 3) rou = iteration_utilities.roundrobin([]) see = iteration_utilities.Seen() sid = iteration_utilities.sideeffects([], lambda x: x) spl = iteration_utilities.split([], lambda x: True) sta = iteration_utilities.starfilter(lambda x: True, []) suc = iteration_utilities.successive([]) tab = iteration_utilities.tabulate(int) une = iteration_utilities.unique_everseen([]) unj = iteration_utilities.unique_justseen([]) gc.collect()
def part1(text, steps=100): def step(grid): neighbors = convolve2d(grid, np.ones((3, 3)), "same") - grid return (neighbors == 3) | (grid & (neighbors == 2)) grid = np.array(tuple(map(process, text.splitlines()))) return (nth(steps - 1)(applyfunc(step, grid)) if steps else grid).sum()
def part2(text, size=256): lengths = tuple(chain(map(ord, text.strip()), (17, 31, 73, 47, 23))) args = (tuple(range(size)), lengths, 0, 0) array, _, first, _ = nth(63)(applyfunc(process, args)) array = array[first % size:] + array[:first % size] return bytes(reduce(xor, group) for group in grouper(array, 16)).hex()
def part2(text, steps=100): def step(grid): neighbors = convolve2d(grid, np.ones((3, 3)), "same") - grid return (neighbors == 3) | (grid & (neighbors == 2)) | on grid = np.array(tuple(map(process, text.splitlines()))) on = np.zeros_like(grid) on[0, 0] = on[0, -1] = on[-1, 0] = on[-1, -1] = True grid |= on return (nth(steps - 1)(applyfunc(step, grid)) if steps else grid).sum()
def test_nth_pred4(): assert nth(1)([[T(0)], [T(1), T(2)]] * 2, pred=lambda x: len(x) > 1) == [T(1), T(2)]
def test_nth_pred3(): assert nth(0)([T(0)] * 100 + [T(1)], pred=bool) == T(1)
def test_nth_failures10(): # indexerror with generator with pytest.raises(IndexError): nth(1)((i for i in [T(0)]), pred=bool)
def getitem(iterable, idx=None, start=None, stop=None, step=None): """Get the item at `idx` or the items specified by `start`, `stop` and `step`. Parameters ---------- iterable : iterable The iterable from which to extract the items. idx : positive :py:class:`int`, -1, tuple/list thereof, or None, optional If not ``None``, get the item at `idx`. If it's a tuple or list get all the items specified in the tuple (they will be sorted so the specified indices are retrieved). Default is ``None``. .. note:: This parameter must not be ``None`` if also `start`, `stop` and `step` are ``None``. start : :py:class:`int` or None, optional If ``None`` then take all items before `stop`, otherwise take only the items starting by `start`. Default is ``None``. .. note:: This parameter is ignored if `idx` is not ``None``. stop : :py:class:`int` or None, optional If ``None`` then take all items starting by `start`, otherwise only take the items before `stop`. Default is ``None``. .. note:: This parameter is ignored if `idx` is not ``None``. step : positive :py:class:`int` or None, optional If ``None`` then take all items seperated by `step`, otherwise take successive items. Default is ``None``. .. note:: This parameter is ignored if `idx` is not ``None``. Returns ------- items : any type or generator If `idx` was not ``None`` then it returns the item, otherwise it returns the items specified by `start`, `stop` and `step`. Examples -------- The main bulk of examples is in :py:meth:`~iteration_utilities.Iterable.getitem` because that's where this function was originally implemented. """ if idx is None and start is None and stop is None and step is None: raise TypeError('one of "idx", "start" or "stop" must be given.') it = iter(iterable) if idx is not None: if not isinstance(idx, (tuple, list)): if idx < -1: raise ValueError('index must be -1 or bigger.') return nth(idx)(iterable) elif not idx: return [] else: # A list of indices, we sort it (insert -1 at the end because it's # the last one) and then extract all the values. idx = sorted(idx, key=lambda x: x if x != -1 else float('inf')) if idx[0] < -1: raise ValueError('index must be -1 or bigger.') current = 0 ret = [] for i in unique_justseen(idx): ret.append(nth(i - current)(it)) current = i + 1 return ret start_gt_0 = start is None or start > 0 step_gt_0 = step is None or step > 0 start_lt_0 = start is not None and start < 0 stop_lt_0 = stop is not None and stop < 0 step_lt_0 = step is not None and step < 0 # Several possibilities: # - start None, stop None, step None = self # if start is None and stop is None and step is None: # return iterable # - start None or > 0, stop None, step None or > 0 = islice if start_gt_0 and stop is None and step_gt_0: return islice(iterable, start, stop, step) # - start None or > 0, stop > 0, step None or > 0 = finite islice elif start_gt_0 and stop is not None and stop > 0 and step_gt_0: return islice(iterable, start, stop, step) # There could be valid cases with negative steps, for example if # reversed can be applied. But I won't go down that road! elif step_lt_0: raise ValueError('negative "step" is not possible.') # Any other combination requires the start to be not None and # negative. elif start_lt_0: # - start < 0, stop < 0, step None or > 0 = tail then islice. if stop_lt_0 and step_gt_0: it = tail(iterable, -start) it = islice(it, 0, stop - start, step) return it # - start < 0, stop None, step None = tail elif stop is None and step is None: it = tail(iterable, -start) return it # - start < 0, stop None, step > 0 = tail and islice elif stop is None and step > 0: it = tail(iterable, -start) it = islice(it, 0, None, step) return it else: raise ValueError('{0} cannot be subscripted with any ' 'combination of negative "start", "stop" or ' '"step". This combination wasn\'t allowed.')
def test_nth_predtruthyretpred7(): assert nth(2)([T(0), T(1), T(2), T(3)], pred=lambda x: x**T(2)) == T(3)
def test_nth_predtruthyretpred5(): assert nth(2)([T(0), T(1), T(2), T(3)], pred=bool) == T(3)
def test_nth_predtruthyretpred3(): assert nth(1)([T(0), T(2), T(3), T(0)], pred=lambda x: x**T(2), truthy=False) == T(0)
def test_nth_normal2(): assert nth(2)(map(T, range(10))) == T(2)
def test_nth_normal1(): assert nth(1)([T(1), T(2), T(3)]) == T(2)
def test_nth_pickle1(protocol): x = pickle.dumps(nth(2), protocol=protocol) assert pickle.loads(x)([T(1), T(2), T(3), T(4)]) == T(3)
def test_nth_failure15(): # Changing next method with pytest.raises(_hf.CacheNext.EXC_TYP, match=_hf.CacheNext.EXC_MSG): nth(2)(_hf.CacheNext(1))
def test_nth_failures14(): # evaluating as boolean fails with pytest.raises(_hf.FailBool.EXC_TYP, match=_hf.FailBool.EXC_MSG): nth(1)([T(0)], pred=lambda x: _hf.FailBool(), truthy=0)
def test_nth_attributes1(): assert iteration_utilities.first.n == 0 assert iteration_utilities.second.n == 1 assert iteration_utilities.third.n == 2 assert iteration_utilities.last.n == -1 assert nth(10).n == 10
def test_nth_predtruthyretpred1(): # pred with truthy/retpred assert nth(1)([T(0), T(2), T(3), T(0)], pred=bool, truthy=False) == T(0)
def test_nth_predtruthyretpred2(): assert not nth(1)( [T(0), T(1), T(2), T(3), T(0)], pred=bool, truthy=False, retpred=True)
def test_nth_nopred_retpred1(): assert nth(2)(toT(range(10)), retpred=1) == T(2)
def test_nth_predtruthyretpred4(): assert nth(1)(toT([0, 1, 2, 3, 0]), pred=lambda x: x**T(2), truthy=False, retpred=True) == T(0)
def test_nth_retidx1(): assert nth(2)(toT(range(10)), retidx=1) == 2
def test_nth_predtruthyretpred6(): assert nth(2)([T(0), T(1), T(2), T(3)], pred=bool, retpred=True)
def test_nth_retidx2(): assert nth(2)(toT(range(10)), pred=bool, retidx=1) == 3
def test_nth_failures8(): # too few arguments for __call__ with pytest.raises(TypeError): nth(1)()
def test_nth_failures6(): # Test that a failing iterator doesn't raise a SystemError with pytest.raises(_hf.FailNext.EXC_TYP, match=_hf.FailNext.EXC_MSG): nth(1)(_hf.FailNext())
def test_nth_pred1(): # With pred assert nth(1)([T(0), T(1), T(2)], pred=bool) == T(2)
def test_nth_failures9(): # too few arguments for __call__ with pytest.raises(ValueError, match='`retpred` or `retidx`'): nth(1)([T(0), T(1), T(2)], retpred=1, retidx=1)
def test_nth_pred2(): assert nth(1)([T(0), T(1), T(2)], pred=None) == T(2)
def test_nth_failures5(): # item not an integer with pytest.raises(TypeError): nth('a')