[Tutor] review of beginner's code requested

James Cunningham jameshcunningham at gmail.com
Tue Nov 14 18:47:08 CET 2006


Hello.


I'm new to Python; for a project to get to know the language I wrote up an
api for representing finite topologies, and for subsets of topologies for
which the orbit (the number of ways to use closure, interior, and complement
operators to get separate sets) is fourteen.


It can be used like this:


some_set = [[1, 2, 3], [1, 2], [2, 3], [1, 3], [1], [2], [3], []]

a = FiniteTopology(some_set, [1, 2, 3])


...


With all attendant methods. The constructor will take a list of lists or a
set of sets.


orbits_of_fourteen(8)


will generate all topologies on subsets of [1, 2, 3, 4, 5, 6, 7, 8], and
look for subsets of those topologies whose orbits are of length fourteen.
(It will also never end. I wouldn't recommend trying that; I put it in as an
exercise.)


One thing I'm not sure of: if the user tries to create a FiniteTopology with
a collection of sets that's not a topology, I throw a NotATopologyError in
the constructor. But it looks like the FiniteTopology instance is still
created. Is there any way to keep the instance from being created at all?


I'm also interested in tips about documentation and style.


Thanks a lot!


Best,

James



#!/usr/bin/env python


class NotATopologyError(Exception):

    pass


class FiniteTopology(object):

    """This represents a finite topology on a set of elements that can be

    represented by Python's builtin set class. Its representation is of a
set

    of frozensets, but its constructor will take a list of lists; let it be

    stressed that the elements on which the topology is defined must be

    immutable."""


    def __init__(self, topology, main_set):

        """Creates an instance of FiniteTopology, checking first to make
sure

        that it *is* a topology. If it isn't, we raise a NotATopology

        exception."""


        self.topology = set([frozenset(element) for element in topology])

        self.main_set = set(main_set)


        if not self._is_a_topology():

            raise NotATopologyError()


    def get_topology(self):

        return self.topology


    def _is_a_topology(self):

        """Checks if self.topology is a topology."""


        check_one = self._check_contains_empty_main()

        check_two = self._check_unions()

        check_three = self._check_intersections()


        return check_one and check_two and check_three


    def _check_contains_empty_main(self):

        """A topology contains its set and the empty set."""


        return self.main_set in self.topology and set([]) in self.topology


    def _check_unions(self):

        """A topology contains all unions of open sets."""

        for i in xrange(1, len(self.topology) + 1):

            for subset in combinations(self.as_list(), i):

                current_union = set()

                for one_set in subset:

                    current_union = current_union.union(one_set)

                if not current_union in self.topology:

                    return False

        return True


    def _check_intersections(self):

        """A topology contains all pairwise intersections of open sets."""

        for item in self.topology:

            for next_item in self.topology:

                intersect = set(item).intersection(next_item)

                if not intersect in self.topology:

                    return False

        return True


    def as_list(self):

        """Returns a list representation of the topology."""

        return [[i for i in j] for j in self.topology]


    def orbit(self, subset):

        """Calculates the maximum number of ways we can use take
complements,

        interiors, and closures of a set to make unique sets. There are at

        most 14 ways to do this, and usually less."""

        orbit = set()


        complement = self.complement

        closure = self.closure

        interior = self.interior


        orbit.add(frozenset(subset))

        orbit.add(frozenset(complement(subset)))

        orbit.add(frozenset(complement(interior(subset))))

        orbit.add(frozenset(complement(interior(complement(subset)))))

        orbit.add
(frozenset(complement(interior(complement(closure(subset))))))

        orbit.add(frozenset(interior(subset)))

        orbit.add(frozenset(interior(closure(subset))))

        orbit.add(frozenset(interior(complement(subset))))

        orbit.add(frozenset(interior(complement(interior(subset)))))

        orbit.add(frozenset(interior(closure(interior(subset)))))

        orbit.add
(frozenset(interior(closure(interior(complement(subset))))))

        orbit.add(frozenset(closure(subset)))

        orbit.add(frozenset(closure(interior(subset))))

        orbit.add(frozenset(closure(interior(complement(subset)))))


        return orbit


    def closure(self, subset):

        """A limit point p of a set X is such that all open sets containing
p

        contain another point of X not equal to p. The closure of a set is
the

        set plus all of its limit points.


        This finds all of the limit points of the subset and adds them."""


        subset = set(subset)

        set_of_lps = set()


        for maybe_lp in self.main_set:

            is_lp = True

            for open_set in self.topology:

                if maybe_lp in open_set:

                    p = [i for i in open_set if i != maybe_lp and i in
subset]

                    if not len(p):

                        is_lp = False

            if is_lp:

                set_of_lps.add(maybe_lp)


        return subset.union(set_of_lps)


    def interior(self, subset):

        """The interior of a subset X is the union of all open subsets of
X."""


        subsets = set()

        for one_set in self.topology:

            if set(one_set).issubset(subset):

                subsets = subsets.union(one_set)

        return subsets


    def complement(self, subset):

        """Returns the complement of a subset."""

        return set(self.main_set) - set(subset)


def combinations(sequence, n):

    """Generates all unique n-combinations of a sequence."""


    if n == 0:

        yield []

    else:

        for i in xrange(len(sequence) - (n - 1)):

            for smaller_comb in combinations(sequence[i + 1:], n - 1):

                yield [sequence[i]] + smaller_comb


def power_set(some_set, return_as_sets=False):

    """This returns the power set (set of all subsets) of some set, as a
list

    of lists or a set of sets."""


    # set_list = [[i for i in j] for j in some_set]


    power_set = [[]]


    for i in xrange(1, len(some_set) + 1):

        for j in combinations(some_set, i):

            power_set.extend([j])


    if return_as_sets:

        power_set = set([frozenset(subset) for subset in power_set])


    return power_set


def all_collections(some_set):

    """This returns all collections of subsets of a particular set, as a
list

    of lists. Takes a list."""


    the_power_set = power_set(some_set)

    collections = []


    for i in xrange(1, len(the_power_set) + 1):

        for j in combinations(the_power_set, i):

            collections.append(j)


    return collections


def all_topologies_on_set_of_ints(upper_index):

    """This will find all topologies on a set like [1, 2, ..., upper_index].

    They'll be returned as a list."""


    all_topologies = []

    coll = all_collections(range(1, upper_index + 1))


    for some_set in coll:

        try:

            curr_top = FiniteTopology(some_set, some_set[len(some_set) - 1])

        except:

            pass

        else:

            all_topologies.append(some_set)


    return all_topologies


def orbits_of_fourteen(upper_index):

    """Prints topologies and subsets for which the orbit of that subset in
the

    topology is fourteen."""


    all_t = all_topologies_on_set_of_ints(upper_index)


    for i in all_t:

    for j in xrange(1, len(i[len(i) - 1]) + 1):

    for comb in combinations(i[len(i) - 1], j):

    orb_len = len(FiniteTopology(i, i[len(i) - 1]).orbit(comb))

    if orb_len == 14:

    print str(comb) + " " + str(all_t)


def main():

    possible_topology = [[1, 2, 3], [1, 2], [1, 3], [2, 3], [1], [2], [3],
[]]

    FiniteTopology(possible_topology, [1, 2, 3])


if __name__ == '__main__':

    main()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/tutor/attachments/20061114/8d804e15/attachment-0001.html 


More information about the Tutor mailing list