2""" @brief Individuals inherit this class which determines who is friend with whom.
5#============================================================================#
6# EVOLIFE http://evolife.telecom-paris.fr Jean-Louis Dessalles
21if __name__ ==
'__main__': sys.path.append(
'../..')
27 """ class club: list of individuals associated with their performance.
28 The performance is used to decide who gets acquainted
with whom.
31 def __init__(self, sizeMax = 0):
32 """ initializes club as an empty list of couples (individual,performance)
45 """ returns members' names (first elements of couples stored in members)
47 return [T[0]
for T
in self]
50 """ returns members' performances (second elements of couples stored in members)
52 return [T[1]
for T
in self]
55 """ returns True if the couple MemberPerf belongs to the club
57 return MemberPerf
in self
60 """ returns a list of members names (possibly ordered by decreasing performance)
63 return [T[0]
for T
in sorted(self.
__members, key =
lambda x: x[1], reverse=
True)]
64 return [T[0]
for T
in self]
67 """ returns the rank of Member in the list of decreasing performances
69 try:
return self.
ordered().index(Member)
70 except ValueError:
return -1
73 """ returns the performance of Member
76 except ValueError:
error(
'Alliances',
'Searching for non-member')
84 """ returns the minimal performance among members
86 if self.
size():
return min([T[1]
for T
in self])
90 """ returns the maximal performance among members
92 if self.
size():
return max([T[1]
for T
in self])
96 """ returns the member with the best performance
100 if self.
size():
return max(self, key=
lambda x: x[1])[0]
104 """ returns the member with the worst performance
109 def accepts(self, performance, conservative=True):
110 """ Checks whether an individual with 'performance' can be accepted into the club
111 Always true if club
is not full.
112 Returns admission rank.
115 if conservative
and performance <= self.
minimal():
117 elif performance < self.
minimal():
return -1
120 rank = self.
size() - sorted([performance] + self.
performances()).index(performance)
121 if rank <= self.
sizeMax:
return rank
122 error(
'Alliances',
'accept')
124 def enters(self, newMember, performance, conservative=True):
125 """ If newMember is accepted based on its performance, it enters the club.
126 If too many members in the club, the worst one
is ejected
and returned
128 if self.
accepts(performance, conservative=conservative) >= 0:
130 if newMember
in self.
names():
131 self.
exits(newMember)
135 self.
__members.append((newMember, performance))
137 error(
"Alliances: unchecked admittance")
141 """ a member goes out from the club
147 print(
'exiled: %s' % str(oldMember))
148 error(
'Alliances: non-member attempting to quit a club')
152 """ all performances are reduced (represents temporal erosion)
156 self.
__members.append((M, Perf * Factor))
164 return "[" +
'-'.join([str(T)
for T
in self.
names()]) +
"]"
167 """ class Friend: defines an individual's acqaintances
171 """ Defines Friend as a club
179 """ Checks whether an individual with 'performance' can be accepted as a friend.
180 Returns admission rank
185 """ Checks whether affiliation is possible
187 return self.
friends.
accepts(F_perf, conservative=conservative) >= 0
189 def follow(self, F, F_perf, conservative=True, Quit=None):
190 """ the individual wants to be F's disciple due to F's performance
193 if self.
affiliable(F_perf, conservative=conservative):
195 RF = self.
friends.enters(F, F_perf, conservative=conservative)
199 if Quit
is None: Quit = self.
quit_
205 """ checks whether Friend belongs to actual friends
207 return Friend
in self.
names()
212 """ the individual no longer follows its friend
214 if Friend
is None: Friend = self.
friends.worst()
215 if Friend
is not None:
224 """ returns a list of friend names (possibly ordered by decreasing performance)
226 return self.
friends.ordered(ordered=ordered)
229 """ returns the list of friends' names
231 return self.
friends.ordered(ordered=
False)
234 """ returns the rank of Friend in the list of decreasing performances
239 """ Number of friends
244 """ Number of friends
248 def sizeMax(self):
return self.friends.sizeMax
251 """ all performances are reduced (represents temporal erosion)
256 """ updates links by forgetting friends that are gone
259 if not membershipFunction(F): self.
quit_(F)
262 """ The individual quits all its friends
264 for F
in self: self.
quit_(F)
270 """ Checks that self and Partner would accept each other as friend, based on their performance
272 return self.
affiliable(PartnerOffer)
and Partner.affiliable(Offer)
275 """ Checks mutual acceptance and then establishes friendship
279 error(
"Friend: self changed mind")
280 if not Partner.follow(self, Offer, Quit=Partner.end_friendship):
281 error(
"Friend: Partner changed mind")
286 """ same as get_friend/3 with no performance
291 """ Partners remove each other from their address book
298 """ The individual quits its friends
307 """ returns the ordered list of friends
313 """ same as social_signature
321 """ Augmented version of Friends for asymmetrical links - replaces 'Alliances'.
322 'Follower' in addition knows about who
is following self
325 def __init__(self, MaxGurus, MaxFollowers=0):
326 """ calls the Friend constructor for followees.
327 creates another Friend object for followers
329 Friend.__init__(self, MaxGurus)
335 """ Checks whether affiliation is possible
336 by checking acceptance both in friends
and in followers
338 A = self.affiliable(G_perf, conservative=conservative)
340 A &= Guru.followers.affiliable(perf, conservative=conservative)
343 def F_follow(self, perf, G, G_perf, conservative=True):
344 """ the individual wants to be G's disciple because of some of G's performance
345 G may evaluate the individual's performance too
348 if self.
F_affiliable(perf, G, G_perf, conservative=conservative):
351 if not self.
follow(G, G_perf, conservative=conservative, Quit=self.
G_quit_):
352 error(
"Alliances",
"inconsistent guru")
353 if G.followers
is not None:
354 if not G.followers.follow(self, perf, conservative=conservative, Quit=G.F_quit_):
355 error(
'Alliances',
"inconsistent self")
362 """ the individual no longer follows its guru
367 if Guru.followers
is not None: Guru.followers.quit_(self)
370 """ the individual does not want its disciple any longer
375 else:
error(
'Alliances',
'No Follower whatsoever')
378 """ Checks mutual acceptance and then establishes friendship
381 if not self.
F_follow(Offer, Partner, PartnerOffer):
382 error(
"Friend: self changed mind")
383 if not Partner.F_follow(PartnerOffer, self, Offer):
384 error(
"Friend: Partner changed mind")
389 """ Partners remove each other from their address book
394 Partner.G_quit_(self)
399 """ Returns Friend's rank among self's followers
405 """ calls 'detach' for self's followers and then for self.
407 if self.
followers is None: Friend.forgetAll(self)
411 """ The individual quits its guru and quits its followers
414 if self.
names() != []:
error(
"Alliances: recalcitrant guru")
420 """ checks social links consistency (self belongs to the followers of its followees)
428 print(
'self: %s' % self)
429 print(
"self's followers: %s" % list(map(str, self.
followers.
names())))
430 print(
'follower: %s' % F)
431 print(
'its gurus: %s' % list(map(str, F.friends.names())))
432 error(
"Alliances: non following followers")
433 if self == F:
error(
"Alliances: Narcissism")
436 if self
not in G.followers:
437 print(
'\n\nself: %s' % self)
438 print(
"self's gurus: %s" % list(map(str, self.
friends.
names())))
439 print(
'guru: %s' % G)
440 print(
'its followers: %s' % list(map(str, G.followers.names())))
441 error(
"Alliances: unaware guru")
442 if self == G:
error(
"Alliances: narcissism")
447 error(
"Alliances: best guru is ghost")
448 return (
'%s consistent' % self.ID)
573if __name__ ==
"__main__":
574 print(__doc__ +
'\n')
575 print(Friend.__doc__ +
'\n\n')
576 raw_input(
'[Return]')
579__author__ =
'Dessalles'
Augmented version of Friends for asymmetrical links - replaces 'Alliances'.
def follower_rank(self, Friend)
Returns Friend's rank among self's followers.
def get_friend(self, Offer, Partner, PartnerOffer)
Checks mutual acceptance and then establishes friendship.
def end_friendship(self, Partner)
Partners remove each other from their address book.
def G_quit_(self, Guru)
the individual no longer follows its guru
def consistency(self)
checks social links consistency (self belongs to the followers of its followees)
def F_quit_(self, Follower)
the individual does not want its disciple any longer
def F_affiliable(self, perf, Guru, G_perf, conservative=True)
Checks whether affiliation is possible by checking acceptance both in friends and in followers.
def F_follow(self, perf, G, G_perf, conservative=True)
the individual wants to be G's disciple because of some of G's performance G may evaluate the individ...
def forgetAll(self)
calls 'detach' for self's followers and then for self.
def detach(self)
The individual quits its guru and quits its followers.
class Friend: defines an individual's acqaintances
def forgetAll(self)
The individual quits its friends
def get_friend(self, Offer, Partner, PartnerOffer)
Checks mutual acceptance and then establishes friendship.
def acquaintable(self, Offer, Partner, PartnerOffer)
symmetrical links #
def affiliable(self, F_perf, conservative=True)
Checks whether affiliation is possible.
def follows(self, Friend)
checks whether Friend belongs to actual friends
def __init__(self, MaxFriends=1)
Defines Friend as a club.
def quit_(self, Friend=None)
the individual no longer follows its friend
def lessening_friendship(self, Factor=0.9)
all performances are reduced (represents temporal erosion)
def accepts(self, F_perf)
asymmetrical links #
def nbFriends(self)
Number of friends.
def rank(self, Friend)
returns the rank of Friend in the list of decreasing performances
def signature(self)
same as social_signature
def names(self)
returns the list of friends' names
def detach(self)
The individual quits all its friends
def checkNetwork(self, membershipFunction=None)
updates links by forgetting friends that are gone
def end_friendship(self, Partner)
Partners remove each other from their address book.
def social_signature(self)
returns the ordered list of friends
def acquainted(self, Partner)
same as get_friend/3 with no performance
def Friends(self, ordered=True)
returns a list of friend names (possibly ordered by decreasing performance)
def size(self)
Number of friends.
def follow(self, F, F_perf, conservative=True, Quit=None)
the individual wants to be F's disciple due to F's performance
class club: list of individuals associated with their performance.
def best(self)
returns the member with the best performance
def exits(self, oldMember)
a member goes out from the club
def minimal(self)
returns the minimal performance among members
def present(self, MemberPerf)
returns True if the couple MemberPerf belongs to the club
def performances(self)
returns members' performances (second elements of couples stored in members)
def accepts(self, performance, conservative=True)
Checks whether an individual with 'performance' can be accepted into the club Always true if club is ...
def weakening(self, Factor=0.9)
all performances are reduced (represents temporal erosion)
def worst(self)
returns the member with the worst performance
def size(self)
size of the club
def rank(self, Member)
returns the rank of Member in the list of decreasing performances
def enters(self, newMember, performance, conservative=True)
If newMember is accepted based on its performance, it enters the club.
def names(self)
returns members' names (first elements of couples stored in members)
def performance(self, Member)
returns the performance of Member
def maximal(self)
returns the maximal performance among members
def ordered(self, ordered=True)
returns a list of members names (possibly ordered by decreasing performance)