def test_dict_roundtrip(context, ignore_lattice): context = Context(context.objects, context.properties, context.bools) assert 'lattice' not in context.__dict__ d = context.todict(ignore_lattice=ignore_lattice) assert isinstance(d, dict) and d assert all(d[k] for k in ('objects', 'properties', 'context')) if ignore_lattice or ignore_lattice is None: assert 'lattice' not in context.__dict__ assert 'lattice' not in d else: assert 'lattice' in context.__dict__ assert d['lattice'] result = Context.fromdict(d) assert isinstance(result, Context) assert result == context if ignore_lattice or ignore_lattice is None: assert 'lattice' not in result.__dict__ else: assert 'lattice' in result.__dict__ assert result.lattice._eq(context.lattice)
def extract_concepts_in_order(objs, order:Order) -> [(set, set)]: var_idx = list(set(itertools.chain.from_iterable(variables for variables in objs.values()))) context_def = [ [var_idx.index(variable) for variable in variables] for (obj, variables) in objs.items() ] ctx = Context.fromdict({'objects': list(objs), 'properties': var_idx, 'context': context_def}) def linksof(c) -> set: "edges covered by the given concept" return set(itertools.product(c.extent, c.intent)) concepts_cover = {c: linksof(c) for c in iter(ctx.lattice)} treated = set() # set of edges already described def def_Random(concepts): return random.choice(tuple(concepts)) def def_LargestCoverFirst(concepts): return max(concepts.keys(), key=lambda c: len(linksof(c) - treated)) def def_LargestExtentFirst(concepts): return max(concepts.keys(), key=lambda c: len(c.extent)) def def_LargestIntentFirst(concepts): return max(concepts.keys(), key=lambda c: len(c.intent)) def def_LargestExtentOrIntentFirst(concepts): return max(concepts.keys(), key=lambda c: max(len(c.extent), len(c.intent))) while concepts_cover: best = locals()['def_' + order.name](concepts_cover) simplified_best = simplify_concept(best, treated) treated |= linksof(best) concepts_cover = {c: linksof(c) - treated for c in concepts_cover} concepts_cover = {c: links for c, links in concepts_cover.items() if len(links) > 0} if not simplified_best[0] or not simplified_best[1]: continue # ignore the extremums yield simplified_best
def test_fromdict_raw(context, lattice, d, raw): def shuffled(items): result = list(items) random.shuffle(result) return result _lattice = d.get('lattice') d = { 'objects': d['objects'], 'properties': d['properties'], 'context': [shuffled(intent) for intent in d['context']] } if _lattice is not None: pairs = shuffled(enumerate(_lattice)) index_map = {old: new for new, (old, _) in enumerate(pairs)} d['lattice'] = [(shuffled(ex), shuffled(in_), shuffled(index_map[i] for i in up), shuffled(index_map[i] for i in lo)) for _, (ex, in_, up, lo) in pairs] result = Context.fromdict(d, raw=raw) assert isinstance(result, Context) assert result == context if _lattice is not None: if raw: assert result.lattice._eq(lattice) else: # instance broken by shuffled(d['lattice']) assert not result.lattice._eq(lattice)
def test_fromdict(context, lattice, d, require_lattice, ignore_lattice, raw): if require_lattice and 'lattice' not in d: return result = Context.fromdict(d, require_lattice=require_lattice, ignore_lattice=ignore_lattice, raw=raw) assert result == context if ignore_lattice or 'lattice' not in d: assert 'lattice' not in result.__dict__ else: assert 'lattice' in result.__dict__ assert result.lattice._eq(lattice)
def test_fromdict_empty_lattice(d_invalid): d_invalid['lattice'] = [] with pytest.raises(ValueError, match='empty lattice'): Context.fromdict(d_invalid)
def test_fromdict_context_invalid_index(d_invalid): first = d_invalid['context'][0] d_invalid['context'][0] = (42, ) + first[1:] with pytest.raises(ValueError, match='invalid index'): Context.fromdict(d_invalid)
def test_fromdict_context_duplicates(d_invalid): first = d_invalid['context'][0] d_invalid['context'][0] = (first[0], first[0]) + first[2:] with pytest.raises(ValueError, match='duplicate'): Context.fromdict(d_invalid)
def test_fromdict_mismatch(d_invalid, short): d_invalid[short] = d_invalid[short][1:] lens = (5, 6) if short == 'objects' else (6, 5) match = r'mismatch: %d objects with %d context' % lens with pytest.raises(ValueError, match=match): Context.fromdict(d_invalid)
def test_fromdict_nonstring(d_invalid, nonstring): d_invalid[nonstring] = (42, ) + d_invalid[nonstring][1:] with pytest.raises(ValueError, match=r'non-string %s' % nonstring): Context.fromdict(d_invalid)
def test_fromdict_missing(d_invalid, missing): del d_invalid[missing] with pytest.raises(ValueError, match=r'missing .*%s' % missing): Context.fromdict(d_invalid, require_lattice=(missing == 'lattice'))