Пример #1
0
def astar(stare_initiala, stare_finala, euristica, lista_chei):
    nod_initial = Nod(stare_initiala, None, None)
    deschise = SortedSet([nod_initial])
    scor_optim = SortedDict({tuple(stare_initiala): 0})

    # [1, 1, 1, 1, 1]
    # (1, 1, 1, 1, 1)

    while len(deschise) > 0:
        # extragem nodul cu f minim
        nod = deschise[0]
        deschise.pop(0)

        # daca am ajuns la starea finala, ne oprim
        if nod.stare == stare_finala:
            return nod

        # generam succesorii si facem verificari
        lista_succesori = genereaza_succesori(nod, lista_chei, euristica)
        for succesor in lista_succesori:
            if scor_optim.__contains__(tuple(succesor.stare)) == False:
                # daca starea succesorului nu a mai fost intalnita pana acum, o inseram
                scor_optim[tuple(succesor.stare)] = succesor.g
                deschise.add(succesor)
            elif succesor.g < scor_optim[tuple(succesor.stare)]:
                # introducem/editam starea curenta in setul "deschis", dupa caz
                succesor_fals = Nod(succesor.stare, None, None)
                succesor_fals.f = scor_optim[tuple(
                    succesor.stare)] + euristica(succesor.stare)

                if deschise.__contains__(succesor_fals) is True:
                    deschise.discard(succesor)
                deschise.add(succesor)
                # daca starea curenta este intalnita cu un cost mai mic, o reactualizam
                scor_optim[tuple(succesor.stare)] = succesor.g

    return None
Пример #2
0
class LeafSet(object):
    __slots__ = ('peers', 'capacity')
    __passthru = {'get', 'clear', 'pop', 'popitem', 'peekitem', 'key'}
    __iters = {'keys', 'values', 'items'}

    def __init__(self, my_key, iterable=(), capacity=8):
        try:
            iterable = iterable.items()  # view object
        except AttributeError:
            pass
        tuple_itemgetter = Peer.distance(my_key, itemgetter(0))
        key_itemgetter = Peer.distance(my_key)
        self.capacity = capacity
        self.peers = SortedDict(key_itemgetter)
        if iterable:
            l = sorted(iterable, key=tuple_itemgetter)
            self.peers.update(islice(l, capacity))

    def clear(self):
        self.peers.clear()

    def prune(self):
        extra = len(self) - self.capacity
        for i in range(extra):
            self.peers.popitem(last=True)

    def update(self, iterable):
        try:
            iterable = iterable.items()  # view object
        except AttributeError:
            pass
        iterable = iter(iterable)
        items = tuple(islice(iterable, 500))
        while items:
            self.peers.update(items)
            items = tuple(islice(iterable, 500))


    def setdefault(self, *args, **kwargs):
        self.peers.setdefault(*args, **kwargs)
        self.prune()

    def __setitem__(self, *args, **kwargs):
        self.peers.__setitem__(*args, **kwargs)
        self.prune()

    def __getitem__(self, *args, **kwargs):
        return self.peers.__getitem__(*args, **kwargs)

    def __delitem__(self, *args, **kwargs):
        return self.peers.__delitem__(*args, **kwargs)

    def __iter__(self, *args, **kwargs):
        return self.peers.__iter__(*args, **kwargs)

    def __reversed__(self, *args, **kwargs):
        return self.peers.__reversed__(*args, **kwargs)

    def __contains__(self, *args, **kwargs):
        return self.peers.__contains__(*args, **kwargs)

    def __len__(self, *args, **kwargs):
        return self.peers.__len__(*args, **kwargs)

    def __getattr__(self, key):
        if key in self.__class__.__passthru:
            return getattr(self.peers, key)
        elif key in self.__class__.__iters:
            return getattr(self.peers, 'iter' + key)
        else:
            return super().__getattr__(key)

    def __repr__(self):
        return '<%s keys=%r capacity=%d/%d>' % (
            self.__class__.__name__, list(self), len(self), self.capacity)
Пример #3
0
class MemberList:
    def __init__(self, manager):
        self.manager = manager
        self.member_map = {}
        self.name_map = SortedDict()
        self.phone_map = SortedDict()
        self.email_map = SortedDict()
        self.yob_map = SortedDict()
        self.id = 1

    def add_member(self, name, phone, email, yob):
        # if Member.name not in self.name_map:
        #     self.name_map[Member.name] = []
        #     self.name_map[Member.name].append(self.id)
        self.member_map[self.id] = Member(name, phone, email, yob)
        if not self.name_map.__contains__(name):
            self.name_map[name] = []
        self.name_map[name].append(self.id)

        if not self.phone_map.__contains__(phone):
            self.phone_map[phone] = []
        self.phone_map[phone].append(self.id)

        if not self.email_map.__contains__(email):
            self.email_map[email] = []
        self.email_map[email].append(self.id)

        if not self.yob_map.__contains__(yob):
            self.yob_map[yob] = []
        self.yob_map[yob].append(self.id)
        self.id += 1
        #ger herna lika undo_operation

    def add_sport_to_member(self, member, sport):
        member.sports.append(sport)

    def find_member_by_name(self, member):
        for name, id in self.name_map.items():
            if name == member:
                return self.member_map[id[0]]
        return False

    def remove_member(self, name):
        if name in self.name_map:
            member_id = self.name_map[name][0]
            member = self.member_map[member_id]
            del self.name_map[member.name][0]
            if not self.name_map[member.name]:
                del self.name_map[member.name]
            del self.member_map[member_id]
            del self.phone_map[member.phone][0]
            if not self.phone_map[member.phone]:
                del self.phone_map[member.phone]
            del self.yob_map[member.yob][0]
            if not self.yob_map[member.yob]:
                del self.yob_map[member.yob]
            del self.email_map[member.email][0]
            if not self.email_map[member.email]:
                del self.email_map[member.email]
            return True
        return False

        #geri svo herna undo_operation

    def get_members_ordered_by_name(self):
        ordered_list = []
        for _, value in self.name_map.items():
            for i in value:
                ordered_list.append(self.member_map[int(i)])
        return ordered_list

    def get_members_ordered_by_age(self):
        ordered_list = []
        for _, value in self.yob_map.items():
            for i in value:
                ordered_list.append(self.member_map[int(i)])
        return ordered_list

    def retrieve_by_name(self, member_name):
        member_list = []
        for member, member_id in self.name_map.items():
            if member == member_name:
                for i in member_id:
                    member_list.append(self.member_map[int(i)])
        return member_list

    def retrieve_by_phone(self, phone_nr):
        member_list = []
        for phone, phone_user_id in self.phone_map.items():
            if phone == phone_nr:
                for i in phone_user_id:
                    member_list.append(self.member_map[int(i)])
        return member_list

    def retrieve_by_yob(self, yob_nr):
        member_list = []
        for yob, yob_id in self.yob_map.items():
            if yob == yob_nr:
                for i in yob_id:
                    member_list.append(self.member_map[int(i)])
        return member_list

    def retrieve_by_email(self, email_nr):
        member_list = []
        for email, email_id in self.email_map.items():
            if email == email_nr:
                for i in email_id:
                    member_list.append(self.member_map[int(i)])
        return member_list
Пример #4
0
class Learner(Mozillian):
    def __init__(self, row):
        super().__init__(row)
        self.submitted_dt = row['Timestamp']
        self.time_availability_to_set(row['Time Availability'])
        self.interests_to_set(row['Interested in improving'])
        # if missing change_track value, set to unbias value of 3
        self.change_track = safe_cast(row['Interest in changing career track'],
                                      int, 3)
        assert self.change_track in [
            1, 2, 3, 4, 5
        ], self.get_id() + " has invalid change_track value " + str(
            self.change_track)
        # if missing outside_org value, set to unbias value of 2
        self.outside_org = safe_cast(
            row['Interest in mentoring or learning from someone outside your own organization?'],
            int, 2)
        assert self.outside_org in [
            1, 2, 3
        ], self.get_id() + " has invalid outside_org value " + str(
            self.outside_org)
        self.requests = row['Any particular requests?']
        self.identify_as = row['Do you identify yourself as']
        self.welcome_email_dt = row['Sent Wecome Email (date)']
        self.notify_manager_dt = row['Sent Manager Approval Email (date)']
        self.manager_approved_dt = row['Manager Approved (date)']

        #self.preferences = SortedDict(neg) #, enumerate('abc', start=1))
        #self.mentor_score = {}

    def time_availability_to_set(self, availability):
        """ Set times person is available in set form """
        self.availability_set = set(
            [x.strip() for x in availability.split(',')])
        #print(self.availability_set)

    def interests_to_set(self, interests):
        """ Set person's interest(s) in set form """
        self.interests_set = set([x.strip() for x in interests.split(',')])
        #print(self.interests_set)

    def get_submitted_dt(self) -> datetime:
        return self.submitted_dt

    def get_interests(self) -> set:
        return self.interests_set

    def get_times_available(self) -> set:
        return self.availability_set

    def get_outside_org_score(self, mentor) -> int:
        # outside org 1=prefer, 3=rather not
        assert mentor.org is not None, "Mentor " + mentor.get_id(
        ) + " has invalid org value " + mentor.track
        if self.outside_org == 1:
            if self.org == mentor.org:
                return 1
            else:
                return 3
        elif self.outside_org == 2:
            if self.org == mentor.org:
                return 2
            else:
                return 2
        elif self.outside_org == 3:
            if self.org == mentor.org:
                return 3
            else:
                return 1

    def get_change_track_score(self, mentor) -> int:
        # change career track 1=not interested, 5=very interested => give pref to mentors outside
        assert mentor.track is not None, "Mentor " + mentor.get_id(
        ) + " has invalid track value " + mentor.track
        if self.change_track == 1:
            if self.track != mentor.track:
                return 1
            else:
                return 5
        if self.change_track == 2:
            if self.track != mentor.track:
                return 2
            else:
                return 4
        if self.change_track == 3:
            if self.track != mentor.track:
                return 3
            else:
                return 3
        if self.change_track == 4:
            if self.track != mentor.track:
                return 4
            else:
                return 1
        if self.change_track == 5:
            if self.track != mentor.track:
                return 5
            else:
                return 1

    def calc_score(self, mentor, is_requested):
        # get count of overlapping times
        available_times = len(
            self.availability_set.intersection(mentor.get_times_available()))

        # If constraints are satisfied, calculate preference rankings for learners based on feature vector
        score = 0

        # add bias for requested mentor
        if is_requested:
            score = score + 50

        if available_times > 0:
            # match expertise to interest, max score of 7
            # need to account for "Other:" somehow
            score = score + len(
                self.interests_set.intersection(mentor.get_expertise()))

            score = score + self.get_outside_org_score(mentor)
            score = score + self.get_change_track_score(mentor)
        return score

    def set_preferences(self, mentors: dict, requested_mentor=""):
        self.preferences = SortedDict(neg)  #, enumerate('abc', start=1))
        self.mentor_score = {}

        for mentor_id, mentor in mentors.items():
            # Filter on constraints
            # cannot match to themselves
            if self.get_id() == mentor_id:
                continue
            # mentor-learner should not be in the same management reporting chain - will need ppl dataset info
            # for now just check that learner's manager = mentor or mentor's manager = learner
            if self.get_manager_email(
            ) == mentor_id or mentor.get_manager_email() == self.get_id():
                continue

            # unless manager says "no", manager approved column has no impact

            # get count of overlapping times
            available_times = len(
                self.availability_set.intersection(
                    mentor.get_times_available()))

            # If constraints are satisfied, calculate preference rankings for mentors based on feature vector
            score = 0

            # add bias for requested mentor
            if mentor_id == requested_mentor:
                score = score + 50

            if available_times > 0:

                # attribute, rank, weight
                # score will be learner's sum of weighted attributes

                # match interests to expertise, max score of 7
                # need to account for "Other:" somehow
                score = score + len(
                    self.interests_set.intersection(mentor.get_expertise()))
                #print("interests intersection score:" + str(score))

                score = score + self.get_outside_org_score(mentor)
                score = score + self.get_change_track_score(mentor)

                # so far learner ranks range is [2,18]

                # be careful matching those in relationship/married/dating/familial - How??

                # option to constrain mentor org level > learner org level? do levels translate across M/P?

                # if score is the same, order by date_submitted? no i think this is used in the apposite & global draw
                #print(mentor.get_id() + ": " + str(score))

                if score > 0:
                    if self.preferences.__contains__(score):
                        self.preferences[score].append(mentor)
                    else:
                        self.preferences[score] = [mentor]
                    #data_dict[regNumber].append(details) if self.preferences.__contains__(score) else self.preferences.update({score : [mentor]})
                    self.mentor_score[mentor_id] = score

    def get_preferences(self) -> SortedDict:
        return self.preferences

    def get_ranked_mentors(self) -> list:
        ranked_mentors = []
        # add weights to those scores that are the same?
        for value in self.preferences.values():
            ranked_mentors.extend([x.get_id() for x in value])
        return ranked_mentors

    def get_mentor_score(self) -> dict:
        return self.mentor_score

    def get_mentor_rank(self, mentor, is_requested) -> int:
        #scores = [score for subscribed_learner_id, score in self.learner_score.items() if subscribed_learner_id == learner.get_id()]
        return self.calc_score(mentor, is_requested)
Пример #5
0
class DotMap(MutableMapping):

    def __init__(self, *args, **kwargs):
        self._map = SortedDict()
        if args:
            d = args[0]
            if type(d) is dict:
                for k, v in self.__call_items(d):
                    if type(v) is dict:
                        v = DotMap(v)
                    self._map[k] = v
        if kwargs:
            for k, v in self.__call_items(kwargs):
                self._map[k] = v

    @staticmethod
    def __call_items(obj):
        if hasattr(obj, 'iteritems') and ismethod(getattr(obj, 'iteritems')):
            return obj.iteritems()
        else:
            return obj.items()

    def items(self):
        return self.iteritems()

    def iteritems(self):
        return self.__call_items(self._map)

    def __iter__(self):
        return self._map.__iter__()

    def __setitem__(self, k, v):
        self._map[k] = v

    def __getitem__(self, k):
        if k not in self._map:
            # automatically extend to new DotMap
            self[k] = DotMap()
        return self._map[k]

    def __setattr__(self, k, v):
        if k == '_map':
            super(DotMap, self).__setattr__(k, v)
        else:
            self[k] = v

    def __getattr__(self, k):
        if k == '_map':
            return self._map
        else:
            return self[k]

    def __delattr__(self, key):
        return self._map.__delitem__(key)

    def __contains__(self, k):
        return self._map.__contains__(k)

    def __str__(self):
        items = []
        for k, v in self.__call_items(self._map):
            items.append('{0}={1}'.format(k, repr(v)))
        out = 'DotMap({0})'.format(', '.join(items))
        return out

    def __repr__(self):
        return str(self)

    def to_dict(self):
        d = {}
        for k, v in self.items():
            if type(v) is DotMap:
                v = v.to_dict()
            d[k] = v
        return d

    def pprint(self):
        pprint(self.to_dict())

    # proper dict subclassing
    def values(self):
        return self._map.values()

    @staticmethod
    def parse_other(other):
        if type(other) is DotMap:
            return other._map
        else:
            return other

    def __cmp__(self, other):
        other = DotMap.parse_other(other)
        return self._map.__cmp__(other)

    def __eq__(self, other):
        other = DotMap.parse_other(other)
        if not isinstance(other, dict):
            return False
        return self._map.__eq__(other)

    def __ge__(self, other):
        other = DotMap.parse_other(other)
        return self._map.__ge__(other)

    def __gt__(self, other):
        other = DotMap.parse_other(other)
        return self._map.__gt__(other)

    def __le__(self, other):
        other = DotMap.parseOther(other)
        return self._map.__le__(other)

    def __lt__(self, other):
        other = DotMap.parse_other(other)
        return self._map.__lt__(other)

    def __ne__(self, other):
        other = DotMap.parse_other(other)
        return self._map.__ne__(other)

    def __delitem__(self, key):
        return self._map.__delitem__(key)

    def __len__(self):
        return self._map.__len__()

    def copy(self):
        return self

    def get(self, key, default=None):
        return self._map.get(key, default)

    def has_key(self, key):
        return key in self._map

    def iterkeys(self):
        return self._map.iterkeys()

    def itervalues(self):
        return self._map.itervalues()

    def keys(self):
        return self._map.keys()

    def pop(self, key, default=None):
        return self._map.pop(key, default)

    def setdefault(self, key, default=None):
        return self._map.setdefault(key, default)

    def viewitems(self):
        if version_info.major == 2 and version_info.minor >= 7:
            return self._map.viewitems()
        else:
            return self._map.items()

    def viewkeys(self):
        if version_info.major == 2 and version_info.minor >= 7:
            return self._map.viewkeys()
        else:
            return self._map.keys()

    def viewvalues(self):
        if version_info.major == 2 and version_info.minor >= 7:
            return self._map.viewvalues()
        else:
            return self._map.values()

    @classmethod
    def fromkeys(cls, seq, value=None):
        d = DotMap()
        d._map = SortedDict.fromkeys(seq, value)
        return d
Пример #6
0
class Mentor(Mozillian):
    def __init__(self, row):
        super().__init__(
            row
        )  #row['Email Address'], row['Organizational level (i.e. P3, M2, etc.)'], row['Organization'], row['Participant full name'], row['Manager email'])
        self.submitted_dt = row['Timestamp']
        self.time_availability_to_set(row['Time Availability'])
        self.expertise_to_set(row['Areas of expertise'])
        # if missing outside_org value, set to unbias value of 2
        self.outside_org = safe_cast(
            row['Interest in mentoring or learning from someone outside your own organization?'],
            int, 2)
        assert self.outside_org in [
            1, 2, 3
        ], self.get_id() + " has invalid outside_org value " + str(
            self.outside_org)
        self.requests = row['Any particular requests?']
        self.identify_as = row['Do you identify yourself as']
        self.welcome_email_dt = row['Sent Wecome Email (date)']
        self.notify_manager_dt = row['Sent Manager Approval Email (date)']
        self.manager_approved_dt = row['Manager Approved (date)']
        self.mentee_limit = safe_cast(
            row['Mentee Limit'], int,
            2)  # by default mentors have a max of two mentees

    def time_availability_to_set(self, availability):
        """ Set times person is available in set form """
        self.availability_set = set(
            [x.strip() for x in availability.split(',')])

    def expertise_to_set(self, expertise):
        """ Set person's  expertise in set form """
        self.expertise_set = set([x.strip() for x in expertise.split(',')])

    def get_submitted_dt(self) -> datetime:
        return self.submitted_dt

    def get_expertise(self) -> set:
        return self.expertise_set

    def get_times_available(self) -> set:
        return self.availability_set

    def get_mentee_limit(self) -> int:
        return self.mentee_limit

    def set_mentee_limit(self, mentee_limit: int):
        self.mentee_limit = mentee_limit

    def get_outside_org_score(self, learner) -> int:
        # outside org 1=prefer, 3=rather not
        assert learner.org is not None, "Learner " + learner.get_id(
        ) + " has invalid org value " + learner.track
        if self.outside_org == 1:
            if self.org == learner.org:
                return 1
            else:
                return 3
        elif self.outside_org == 2:
            if self.org == learner.org:
                return 2
            else:
                return 2
        elif self.outside_org == 3:
            if self.org == learner.org:
                return 3
            else:
                return 1

    def calc_score(self, learner, is_requested):
        # get count of overlapping times
        available_times = len(
            self.availability_set.intersection(learner.get_times_available()))

        # If constraints are satisfied, calculate preference rankings for learners based on feature vector
        score = 0

        # add bias for requested mentor
        if is_requested:
            score = score + 50

        if available_times > 0:
            # match expertise to interest, max score of 7
            # need to account for "Other:" somehow
            score = score + len(
                self.expertise_set.intersection(learner.get_interests()))

            score = score + self.get_outside_org_score(learner)

        return score

    def set_preferences(self, learners):
        self.preferences = SortedDict(neg)  #, enumerate('abc', start=1))

        for learner in learners:
            # Filter on constraints
            # cannot match to themselves
            if self.get_id() == learner.get_id():
                continue
            # mentor-learner should not be in the same management reporting chain - will need ppl dataset info
            # for now just check that learner's manager = mentor
            if self.get_manager_email() == learner.get_id():
                continue

            # unless manager says "no", manager approved column has no impact

            # get count of overlapping times
            available_times = len(
                self.availability_set.intersection(
                    learner.get_times_available()))

            # If constraints are satisfied, calculate preference rankings for learners based on feature vector
            score = 0
            if available_times > 0:

                # match expertise to interest, max score of 7
                # need to account for "Other:" somehow
                score = score + len(
                    self.expertise_set.intersection(learner.get_interests()))
                #print("interests intersection score:" + str(score))

                # outside org 1=prefer, 3=rather not
                # add 1 if prefer and orgs not the same
                if self.outside_org == 1 and self.org != learner.org:
                    #print("outside org add 1: " + mentor_org)
                    score = score + 1
                # add 1 if rather not and orgs are the same
                if self.outside_org == 3 and self.org == learner.org:
                    #print("outside org add 1: " + mentor_org)
                    score = score + 1

                # so far ranks range is [0,8]

                # be careful matching those in relationship/married/dating/familial - How??

                # option to constrain mentor org level > learner org level?

                # if score is the same, order by date_submitted? no i think this is used in the apposite & global draw
                #print(mentor.get_id() + ": " + str(score))

                if score > 0:
                    if self.preferences.__contains__(score):
                        self.preferences[score].append(learner)
                    else:
                        self.preferences[score] = [learner]

    def set_preferences_subscribed(self,
                                   subscribed_learners: dict,
                                   requested_learner=""):
        self.preferences = SortedDict(neg)  #, enumerate('abc', start=1))
        self.learner_score = {}

        for subscribed_learner_id, subscribed_learner in subscribed_learners.items(
        ):
            # Filter on constraints
            # cannot match to themselves
            if self.get_id() == subscribed_learner_id:
                continue
            # mentor-learner should not be in the same management reporting chain - will need ppl dataset info
            # for now just check that learner's manager = mentor
            if self.get_manager_email(
            ) == subscribed_learner_id or subscribed_learner.get_manager_email(
            ) == self.get_id():
                continue

            # unless manager says "no", manager approved column has no impact

            # get count of overlapping times
            available_times = len(
                self.availability_set.intersection(
                    subscribed_learner.get_times_available()))

            # If constraints are satisfied, calculate preference rankings for learners based on feature vector
            score = 0

            # add bias for requested mentor
            if subscribed_learner_id == requested_learner:
                print(self.get_id() + ' requested learner: ' +
                      requested_learner)
                score = score + 50

            if available_times > 0:

                # match expertise to interest, max score of 7
                # need to account for "Other:" somehow
                score = score + len(
                    self.expertise_set.intersection(
                        subscribed_learner.get_interests()))
                #print("interests intersection score:" + str(score))

                score = score + self.get_outside_org_score(subscribed_learner)

                # so far ranks range is [2,13]

                # be careful matching those in relationship/married/dating/familial - How??

                # option to constrain mentor org level > learner org level? do levels translate across M/P?

                # if score is the same, order by date_submitted? no i think this is used in the apposite & global draw
                #print(mentor.get_id() + ": " + str(score))

                #if score > 0:
            if self.preferences.__contains__(score):
                self.preferences[score].append(subscribed_learner)
            else:
                self.preferences[score] = [subscribed_learner]

            self.learner_score[subscribed_learner_id] = score

    def get_preferences(self) -> SortedDict:
        return self.preferences

    def get_ranked_learners(self) -> list:
        ranked_learners = []
        # add weights to those scores that are the same?
        for value in self.preferences.values():
            ranked_learners.extend([x.get_id() for x in value])

        #for score, learners_list in self.preferences.items():
        #  print("score: " + str(score) + ", learners: " + ','.join([x.get_id() for x in learners_list]))

        return ranked_learners

    def get_learner_score(self) -> dict:
        return self.learner_score

    def get_learner_rank(self, learner, is_requested) -> int:
        #scores = [score for subscribed_learner_id, score in self.learner_score.items() if subscribed_learner_id == learner.get_id()]
        return self.calc_score(learner, is_requested)