def GetPlotOrders(self): """ Gets the curves to be displayed from the scenario and returns intantaneous values to be displayed on these curves """ PlotOrders = [] for Curve in self.Curves: if Curve == 'best': value = self.Statistics['Properties']['best'][1] elif Curve == 'average': value = self.Statistics['Properties']['average'][1] elif Curve in self.Scenario.get_gene_names(): # displaying average values of genes value = self.Statistics['Genomes']['average'][ self.Scenario.get_locus(Curve)] elif Curve in self.Scenario.phenemap(): # displaying average values of phenes value = self.Statistics['Phenomes']['average'][ self.Scenario.phenemap().index(Curve)] else: value = self.Scenario.local_display(Curve) if value is None: error(self.Name, ": unknown display instruction: " + Curve) value = 0 self.curve(Curve, int(value)) return Observer.GetPlotOrders(self)
def start_game(self, members): """ defines what is to be done at the group level each year before interactions occur - Used in 'life_game' """ if self.Parameter('Selectivity') == 0: error('Selection method should be "Selectivity"') self.census(members) for indiv in members: self.prepare(indiv)
def start_Curve(self, Curve_id, location): """ defines where a curve should start """ try: self.Curves[Curve_id].start(location) except IndexError: error("Curves: unknown Curve ID")
def lottery(self): " random selection of an individual by number in the population " winner = randint(0,self.popSize-1) for gr in self.groups: if gr.size > winner: return (gr,winner) else: winner -= gr.size error("Population: wrong population size", str(self.popSize))
def consistency(self): # if self.size() > self.sizeMax(): # error("Alliances", "too many gurus: %d" % self.friends.size()) # if self.followers.size() > self.followers.sizeMax(): # error("Alliances", "too many followers: %d" % self.followers.friends.size()) for F in self.followers: if self not in F: print('self: %s' % self) print("self's followers: %s" % list(map(str, self.followers.names()))) print('follower: %s' % F) print('its gurus: %s' % list(map(str, F.friends.names()))) error("Alliances: non following followers") if self == F: error("Alliances: Narcissism") ## print self.id, ' is in ', F.id, "'s guru list: ", [G.id for G in F.gurus.names()] for G in self: if self not in G.followers: print('\n\nself: %s' % self) print("self's gurus: %s" % list(map(str, self.friends.names()))) print('guru: %s' % G) print('its followers: %s' % list(map(str, G.followers.names()))) error("Alliances: unaware guru") if self == G: error("Alliances: narcissism") ## print self.id, ' is in ', G.id, "'s follower list: ", [F.id for F in G.followers.names()] ## print '\t', self.id, ' OK' if self.friends.size() > 0: if not self.friends.present( (self.friends.best(), self.friends.maximal())): error("Alliances: best guru is ghost") return ('%s consistent' % self.id)
def consistency(self): # if self.size() > self.sizeMax(): # error("Alliances", "too many gurus: %d" % self.friends.size()) # if self.followers.size() > self.followers.sizeMax(): # error("Alliances", "too many followers: %d" % self.followers.friends.size()) for F in self.followers.friends.names(): if self not in F.friends.names(): print('self: %s' % self) print("self's gurus: %s" % map(str, self.social_signature())) print('guru: %s' % G) print('its followers: %s' % map(str, G.followers.names())) error("Alliances: non following followers") if self == F: error("Alliances: Narcissism") ## print self.id, ' is in ', F.id, "'s guru list: ", [G.id for G in F.gurus.names()] for G in self.friends.names(): if self not in G.followers.friends.names(): print('\n\nself: %s' % self) print("self's gurus: %s" % map(str, self.social_signature())) print('guru: %s' % G) print('its followers: %s' % map(str, G.followers.names())) error("Alliances: unaware guru") if self == G: error("Alliances: narcissism") ## print self.id, ' is in ', G.id, "'s follower list: ", [F.id for F in G.followers.names()] ## print '\t', self.id, ' OK' if self.friends.size() > 0: if not self.friends.present((self.friends.best(), self.friends.maximal())): error("Alliances: best guru is ghost")
def detach(self): """ The individual quits its guru and its followers """ for G in self.gurus.names(): self.quit_(G) for F in self.followers.names(): F.quit_(self) if self.gurus.names() != []: error("Alliances: recalcitrant guru") if self.followers.names() != []: error("Alliances: sticky followers")
def create_graphic_agent(self, Position, Shape=None): " creates a graphic agent and returns the Q-reference " if Shape is None: Shape = self.DEFAULTSHAPE if Shape == 'ellipse': return self.addEllipse( 0, 0, Position.size, Position.size, QPen(QColor(EvolifeColourID(Position.colour)[1])), QBrush(QColor(EvolifeColourID(Position.colour)[1]), Qt.SolidPattern)) if Shape == 'rectangle': return self.addRect( 0, 0, Position.size, Position.size, QPen(QColor(EvolifeColourID(Position.colour)[1])), QBrush(QColor(EvolifeColourID(Position.colour)[1]), Qt.SolidPattern)) if Shape not in self.KnownShapes: if os.path.exists(Shape): # print('Existing shape: %s' % Shape) self.KnownShapes[Shape] = QPixmap(Shape) # loads the image if Shape in self.KnownShapes: agent = self.addPixmap(self.KnownShapes[Shape]) scale = float(Position.size) / agent.boundingRect().width() agent.scale(scale, scale) return agent error("Ground: unknown shape: %s" % Shape)
def init_genes(self, gene_list): " creates genes and puts them in a list " self.GeneMap = [] locus = 0 current_pos = 0 # for (g_name,g_length) in gene_list: for GeneDefinition in gene_list: # genes are assigned locus and future position on DNA g_length = self.Parameter('GeneLength') # default value g_coding = self.Parameter('GeneCoding') # default value if isinstance(GeneDefinition, tuple): if len(GeneDefinition) == 2: (g_name, g_length) = GeneDefinition elif len(GeneDefinition) == 3: (g_name, g_length, g_coding) = GeneDefinition else: error("Bad definition of gene map") else: g_name = GeneDefinition if g_length == 0: g_length = self.Parameter('GeneLength') # compatibility NewGene = Gene_def(g_name, g_length, locus, current_pos, g_coding) self.GeneMap.append(NewGene) locus += 1 current_pos = NewGene.end
def statistics(self): """ gathers data from the stored examiners and stores them as a dictionary of tuples (a tuple per slot) (number_of_instances, best_of_each_coordinate, average_of_each_coordinate, list_of_instances) """ # one takes the first examiner as representative for Slot in self.storage[0].storages: if len(list(set([Exam.storages[Slot].itemLength for Exam in self.storage]))) > 1: error('Observer: ',self.Name + ': Inconsistent item length accross examiners') # computing the best value of each coordinate best = map(lambda x: max(x), transpose([Exam.storages[Slot].best \ for Exam in self.storage])) # computing the total number of individual data cumulative_number = sum([Exam.storages[Slot].length for Exam in self.storage]) # computing global statistics by summing averages weighted by corresponding numbers totals = transpose([map(lambda x: x*Exam.storages[Slot].length, Exam.storages[Slot].average) for Exam in self.storage]) if cumulative_number: average = map(lambda x: sum(x)/cumulative_number, totals) else: average = map(lambda x: sum(x), totals) self.Statistics[Slot] = dict([('length',cumulative_number), ('best',best), ('average', average), ('data',reduce(lambda x,y: x+y, tuple(tuple(Exam.storages[Slot].storage for Exam in self.storage))))]) return self.Statistics
def jump(self, gazelle): " Strong gazelles perform a jump proportional to their signalling gene " if not self.gazelle(gazelle): error("Gazelle scenario:", "Signalling lion") if self.strongGazelle(gazelle): #return noise_add(gazelle.gene_relative_intensity('GazelleSignal'), self.Parameter('Noise')) return gazelle.gene_relative_intensity('GazelleSignal') return 0
def close_(self): if not self.open: error('Observer: ', self.Name+': closing while not open') if self.length < 0: self.length = len(self.storage) elif self.length != len(self.storage): error('Observer: ', self.Name+': Inconsistent lengths') self.statistics() # computes statistics self.open = False
def detach(self): """ The individual quits its guru and its followers """ for G in self.names(): self.G_quit_(G) # G is erased from self's guru list if self.names() != []: error("Alliances: recalcitrant guru") if self.followers is not None: for F in self.followers.names(): self.F_quit_(F) # self is erased from F's guru list if self.followers.names() != []: error("Alliances: sticky followers")
def F_quit_(self, Follower): """ the individual does not want its disciple any longer """ if self.followers is not None: self.followers.quit_(Follower) Follower.quit_(self) else: error('Alliances', 'No Follower whatsoever')
def close_(self): if not self.open: error('Observer: ', self.Name + ': closing while not open') if self.length < 0: self.length = len(self.storage) elif self.length != len(self.storage): error('Observer: ', self.Name + ': Inconsistent lengths') self.statistics() # computes statistics self.open = False
def get_friend(self, Offer, Partner, PartnerOffer): " Checks mutual acceptance before establishing friendship " if self.acquaintable(Offer, Partner, PartnerOffer): if not self.follow(Partner, PartnerOffer, Quit=self.end_friendship): error("Friend: self changed mind") if not Partner.follow(self, Offer, Quit=Partner.end_friendship): error("Friend: Partner changed mind") return True return False
def move(self, Curve_designation, newpoint): " introduces a discontinuity in a curve " # one is tolerant about the meaning of Curve_designation Curve_id = EvolifeColourID(Curve_designation)[0] try: ## self.drawTo(newpoint, Curve_id, Drawing=False) self.Curves[Curve_id].add(newpoint, Draw=False) except IndexError: error("Draw_Area: unknown Curve ID")
def plot(self, Curve_designation, newpoint, Width=3): " draws an additional segment on a curve " # one is tolerant about the meaning of Curve_designation Curve_id = EvolifeColourID(Curve_designation)[0] try: self.drawTo(newpoint, Width, Curve_id) # action on display self.Curves[Curve_id].add(newpoint) # memory except IndexError: error("Draw_Area: unknown Curve ID")
def get_friend(self, Offer, Partner, PartnerOffer): " Checks mutual acceptance before establishing friendship " if self.acquaintable(Offer, Partner, PartnerOffer): if not self.F_follow(Offer, Partner, PartnerOffer): error("Friend: self changed mind") if not Partner.F_follow(PartnerOffer, self, Offer): error("Friend: Partner changed mind") return True return False
def Parameter(self,ParamName, Silent=False, Optional=False): try: p = self.Params[ParamName] except KeyError: if Optional: return None error("Evolife_Parameters: Attempt to reach undefined parameter: ", ParamName) if not Silent: self.relevant.add(ParamName) return p
def accepts(self, performance): " signals that the new individual can be accepted into the club " if self.size() >= self.sizeMax and performance <= self.minimal(): return -1 # Note: priority given to former members # returning the rank that the candidate would be assigned # return sorted([performance] + self.performances(),reverse=True).index(performance) rank = self.size() - sorted([performance] + self.performances()).index(performance) if rank <= self.sizeMax: return rank error('Alliances', 'accept')
def append(self, Name='Curve', Color='red', Legend=''): if Color not in self.Colors: if not Legend: Legend = Name self.Curves[Name] = Curve(Name, Color, Legend) self.Colors.append(Color) self.Designations.append((Color, Name, Legend)) self.Legends.append((Color, Legend)) self.Values[Name] = None else: error('Observer', 'Two curves with same colour')
def move(self, Curve_designation, newpoint): " introduces a discontinuity in a curve " # one is tolerant about the meaning of Curve_designation Curve_id = EvolifeColourID(Curve_designation)[0] # print('moving to', Curve_designation, Curve_id, newpoint) try: ## self.drawTo(newpoint, Curve_id, Drawing=False) self.Curves[Curve_id].add(newpoint, Draw=False) except IndexError: error("Draw_Area: unknown Curve ID")
def record(self, Position, Window='Field', Reset=False): " stores current position changes " if isinstance(Position, list): Buffer = list(Position) elif isinstance(Position, tuple): Buffer = [Position] else: error(Observer, "Should be tuple or list: " + str(Position)) Keep = not Reset if Window == 'Field': self.Field_buffer = Keep * self.Field_buffer + Buffer elif Window == 'Trajectories': self.Trajectory_buffer = Keep * self.Trajectory_buffer + Buffer
def store(self, vector): if not self.open: error('Observer: ',self.Name+': not open') self.storage.append(vector) try: if self.itemLength > 0 and len(vector) != self.itemLength: error('Observer: ', self.Name + ': Inconsistent item length') self.itemLength = len(vector) except AttributeError, TypeError: self.itemLength = 1
def exits(self, oldMember): " a member goes out from the club " for (M,Perf) in self.__members[:]: # safe to copy the list as it is changed within the loop if M == oldMember: self.__members.remove((oldMember,Perf)) return True print 'members: ', [(str(F[0]),F[1]) for F in self.__members], print 'exiled: ', str(oldMember) error('Alliances: non-member attempting to quit a club') return False
def value(self, Value=-1, Levelling = False): if Value < 0: return self.__value if Value <= Phene.MaxPheneValue: self.__value = Value elif Levelling: self.__value = Phene.MaxPheneValue else: error("Phenotype: ", "Maximum value exceeded") return self.__value
def store(self, vector): if not self.open: error('Observer: ', self.Name + ': not open') self.storage.append(vector) try: if self.itemLength > 0 and len(vector) != self.itemLength: error('Observer: ', self.Name + ': Inconsistent item length') self.itemLength = len(vector) except (AttributeError, TypeError): self.itemLength = 1
def exits(self, oldMember): " a member goes out from the club " for ( M, Perf ) in self.__members[:]: # safe to copy the list as it is changed within the loop if M == oldMember: self.__members.remove((oldMember, Perf)) return True print('exiled: %s' % str(oldMember)) error('Alliances: non-member attempting to quit a club') return False
def enters(self, newMember, performance): if self.accepts(performance) >= 0: # First, check whether newMember is not already a member if newMember in self.names(): self.exits(newMember) # to prepare the come-back self.__members.append((newMember, performance)) if self.size() > self.sizeMax: return self.worst() # the redundant individual will be ejected return None error("Alliances: unchecked admittance") return None
def plot(self, Curve_designation, newpoint, Width=3): " draws an additional segment on a curve " # one is tolerant about the meaning of Curve_designation Curve_id = EvolifeColourID(Curve_designation)[0] # print('plotting to', Curve_designation, Curve_id, newpoint) try: self.drawTo(newpoint, Width, Curve_id) # action on display self.Curves[Curve_id].add(newpoint) # memory # if Width != self.Curves[Curve_id].thick: print('changing thickness to', Width) self.Curves[Curve_id].thick = Width # update thickness except IndexError: error("Draw_Area: unknown Curve ID")
def accepts(self, performance, conservative=True): " signals that the new individual can be accepted into the club " if self.size() >= self.sizeMax: if conservative and performance <= self.minimal(): return -1 # equality: priority given to former members elif performance < self.minimal(): return -1 # print 'acceptation de', performance, 'a la place de', self.minimal() # returning the rank that the candidate would be assigned # return sorted([performance] + self.performances(),reverse=True).index(performance) rank = self.size() - sorted([performance] + self.performances()).index(performance) if rank <= self.sizeMax: return rank error('Alliances', 'accept')
def ReturnFromThread(self, Best): """ The simulation thread returns the best current phenotype """ if Best == 'Buzy?': # this should never happen in batch mode error("Evolife_Batch","Inexistent buzy mode") self.BestResult = Best if self.Obs.Visible(): self.Process_graph_orders(Best) if self.Obs.Over(): return -1 # Stops the simulation thread else: return 0
def Parameter(self, ParamName, Silent=False, Default='dummy'): if Default != 'dummy': p = self.get(ParamName, Default) else: try: p = dict.__getitem__(self, ParamName) # parent getitem except KeyError: print(self.relevant) error( "Evolife_Parameters: Attempt to reach undefined parameter: ", ParamName) if not Silent and ParamName not in self.relevant and ParamName in self: self.relevant.add(ParamName) return p
def update(self, flagRanking = False, display=False): " updates groups and looks for empty groups " self.popSize = 0 # population size will be recomputed toBeRemoved = [] for gr in self.groups: gr.location = self.popSize # useful for separating groups when displaying them on an axis grsize = gr.update_(flagRanking, display=display) if grsize == 0: toBeRemoved.append(gr) self.popSize += grsize for gr in toBeRemoved: self.groups.remove(gr) if self.popSize == 0: error("Population is empty") self.best_score = max([gr.best_score for gr in self.groups]) return self.popSize
def ReturnFromThread(self, Best): """ The simulation thread returns the best current phenotype """ if Best == 'Buzy?': # this should never happen in batch mode error("Evolife_Batch", "Inexistent buzy mode") self.BestResult = Best if self.Obs.Visible(): self.Process_graph_orders(Best) if self.Obs.Over(): return -1 # Stops the simulation thread else: return 0
def locus_range(self, Locus): " returns the maximal amplitude of the gene at Locus " coding = self.get_gene(Locus).coding.lower() if coding in ['weighted', 'gray']: # Usual integer coding return (1 << self.get_gene(Locus).length ) - 1 elif coding == 'unweighted': # Genes are coded as the number of 1s on the DNA section return self.get_gene(Locus).length elif coding == 'nocoding': return 1 else: error("Genetic Map", 'unknown binary coding mode: %s' % str(coding))
def decision(self, Male, Female): """ The male decides which direction to take depending on the female's song """ AbsoluteDirection = self.direction(Male) try: # Relative position of the male (position are numbered by increasing Manhattan distance) Cell = self.Ground.Neighbourhood(Female.location[0:2]).index(Male.location[0:2]) except ValueError: print Male.location print Female.location error("Ghost male") return self.communication(Male, Female, Cell, AbsoluteDirection)
def enters(self, newMember, performance, conservative=True): if self.accepts(performance, conservative=conservative) >= 0: # First, check whether newMember is not already a member if newMember in self.names(): self.exits(newMember) # to prepare the come-back if self.size() >= self.sizeMax: worst = self.worst( ) # the redundant individual will be ejected else: worst = None self.__members.append((newMember, performance)) return worst error("Alliances: unchecked admittance") return None
def locus_range(self, Locus): " returns the maximal amplitude of the gene at Locus " coding = self.get_gene(Locus).coding.lower() if coding in ['weighted', 'gray']: # Usual integer coding return (1 << self.get_gene(Locus).length) - 1 elif coding == 'unweighted': # Genes are coded as the number of 1s on the DNA section return self.get_gene(Locus).length elif coding == 'nocoding': return 1 else: error("Genetic Map", 'unknown binary coding mode: %s' % str(coding))
def decision(self, Male, Female): """ The male decides which direction to take depending on the female's song """ AbsoluteDirection = self.direction(Male) try: # Relative position of the male (position are numbered by increasing Manhattan distance) Cell = self.Ground.Neighbourhood(Female.location[0:2]).index( Male.location[0:2]) except ValueError: print(Male.location) print(Female.location) error("Ghost male") return self.communication(Male, Female, Cell, AbsoluteDirection)
def Curvenames(self, Names): """ records names for Curves """ Str = '\nDisplay: \n\t' try: for (Curve_designation, Name) in Names: for P in self.Curves: CurveId = EvolifeColourID(Curve_designation, default=None)[0] if P.ID == CurveId: P.name(Name) Str += '\n\t%s:\t%s' % (P.ColName, P.name()) Str += '\n' except IndexError: error("Curves: unknown Curve ID") return Str
def __init__(self, gene_name, gene_length, locus, position, length_def): """ A gene knows its name, its length, its locus (order in the list of genes) and its start and end position on the DNA """ self.name = gene_name if gene_length: self.length = gene_length elif length_def: self.length = length_def else: error('Gene definition','Zero length with zero Default length') self.locus = locus self.start = position self.end = position + self.length
def __init__(self, gene_name, gene_length, locus, position, coding): """ A gene knows its name, its length, its locus (order in the list of genes) and its start and end position on the DNA """ self.name = gene_name self.length = gene_length if self.length == 0: error('Gene definition','Zero length with zero Default length') self.locus = locus # rank in the list of genes self.start = position # start location on DNA self.end = position + self.length # end location on DNA self.coding = coding if self.coding in range(-1,3): # old numeric designation of coding self.coding = ['Nocoding', 'Weighted', 'Unweighted', 'Gray'][self.coding+1]
def move_agent(self, Name, Coord): """ moves an agent's representative dot to some new location """ # Coord in analysed as a Position + an optional segment starting from that position, # and missing coordinates are completed (Position, Segment) = self.coordinates(Coord) if not self.Toric and self.reframe(Position.point()): # The window is reframed if necessary self.redraw() Location = self.convert(Position.point()) # Translation into physical coordinates if Name in self.positions: if self.positions[Name].colour != Position.colour: # Colour has changed, the agent is destroyed and reborn # print 'Changing colour' self.remove_agent(Name) if str(Position.colour).startswith('-'): # print 'destorying agent' return # negative colour means the agent is removed self.move_agent(Name, Coord) # false recursive call if self.positions[Name].Coord == Position.Coord and self.segments[Name].Coord == Segment.Coord: return # nothing to do #### moving an existing agent #### # print Name, Position.Coord, self.positions[Name].Coord self.positions[Name] = Position # recording the agent's new position AgentRef = self.GraphicAgents[Name][0] AgentRef.setPos(QPointF(Location[0],Location[1])) # performing actual move if self.segments[Name].Coord: # the segment is re-created self.remove_segment(Name) if Segment.Coord: SegmentRef = self.create_graphic_segment(Position, Segment) else: SegmentRef = None self.segments[Name] = Segment self.GraphicAgents[Name] = (AgentRef, SegmentRef) # New Q-reference to graphic objects are memorized else: #### creating the agent #### # print 'displaying', Name, 'in', Position.Coord try: if str(Position.colour).startswith('-'): # print 'Error negative colour in display -->\t\t', Position.Coord return AgentRef = self.create_graphic_agent(Position) AgentRef.setPos(QPointF(Location[0],Location[1])) if Segment.Coord: SegmentRef = self.create_graphic_segment(Position, Segment) else: SegmentRef = None self.positions[Name] = Position # recording the agent's new position self.segments[Name] = Segment self.GraphicAgents[Name] = (AgentRef, SegmentRef) # Q-reference to graphic objects are memorized except IndexError: error("Draw_Area: unknown colour ID")
def locus_range(self, Locus): " returns the maximal amplitude of the gene at Locus " coding = self.Parameter('GeneCoding') if coding in range(-1,3): # old numeric designation of coding coding = ['NoCoding', 'Weighted', 'Unweighted', 'Gray'][coding+1] if coding in ['Weighted', 'Gray']: # Usual integer coding return (1 << self.get_gene(Locus).length ) - 1 elif coding == 'Unweighted': # Genes are coded as the number of 1s on the DNA section return self.get_gene(Locus).length elif coding == 'NoCoding': return 1 else: error("Genetic Map", 'unknown binary coding mode: %d' % self.Parameter('GeneCoding'))
def __init__(self, gene_name, gene_length, locus, position, coding): """ A gene knows its name, its length, its locus (order in the list of genes) and its start and end position on the DNA """ self.name = gene_name self.length = gene_length if self.length == 0: error('Gene definition', 'Zero length with zero Default length') self.locus = locus # rank in the list of genes self.start = position # start location on DNA self.end = position + self.length # end location on DNA self.coding = coding if self.coding in range(-1, 3): # old numeric designation of coding self.coding = ['Nocoding', 'Weighted', 'Unweighted', 'Gray'][self.coding + 1]
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 individual's performance too """ # print '.', if self.F_affiliable(perf, G, G_perf, conservative=conservative): # the new guru is good enough and the individual is good enough for the guru # print '%s (%s) is about to follow %s (%s)' % (self, map(str, self.social_signature()), G, map(str, G.social_signature())) if not self.follow(G, G_perf, conservative=conservative, Quit=self.G_quit_): error("Alliances", "inconsistent guru") if G.followers is not None: if not G.followers.follow(self, perf, conservative=conservative, Quit=G.F_quit_): error('Alliances', "inconsistent self") # self.consistency() # G.consistency() return True else: return False
def Curvenames(self, Names): """ records names for Curves """ Str = '\nDisplay: \n\t' try: for Curve_description in Names: (Curve_designation, Name, Legend) = Curve_description + (0, '', '')[len(Curve_description):] for P in self.Curves: CurveId = EvolifeColourID(Curve_designation, default=None)[0] if P.ID == CurveId: P.name(Name) P.legend(Legend if Legend else Name) Str += '\n\t%s:\t%s' % (P.ColName, P.legend()) Str += '\n' except IndexError: error("Curves: unknown Curve ID") return Str
def statistics(self): """ gathers data from the stored examiners and stores them as a dictionary of tuples (a tuple per slot) (number_of_instances, best_of_each_coordinate, average_of_each_coordinate, list_of_instances) """ # one takes the first examiner as representative for Slot in self.storage[0].storages: if len( list( set([ Exam.storages[Slot].itemLength for Exam in self.storage ]))) > 1: error( 'Observer: ', self.Name + ': Inconsistent item length accross examiners') # computing the best value of each coordinate best = list(map(lambda x: max(x), transpose([Exam.storages[Slot].best \ for Exam in self.storage]))) # computing the total number of individual data cumulative_number = sum( [Exam.storages[Slot].length for Exam in self.storage]) # computing global statistics by summing averages weighted by corresponding numbers totals = transpose([ list( map(lambda x: x * Exam.storages[Slot].length, Exam.storages[Slot].average)) for Exam in self.storage ]) if cumulative_number: average = list( map(lambda x: sum(x) / cumulative_number, totals)) else: average = list(map(lambda x: sum(x), totals)) self.Statistics[Slot] = dict([ ('length', cumulative_number), ('best', best), ('average', average), ('data', functools.reduce( lambda x, y: x + y, tuple( tuple(Exam.storages[Slot].storage for Exam in self.storage)))) ]) return self.Statistics
def Curvenames(self, Names): """ records names for Curves """ Str = '\nDisplay: \n\t' try: for Curve_description in Names: (Curve_designation, Name, Legend) = Curve_description + (0, '', '')[len(Curve_description):] CurveId = EvolifeColourID(Curve_designation, default=None)[0] for P in self.Curves: if P.ID == CurveId: P.name(Name) P.legend(Legend if Legend else Name) Str += '\n\t%s:\t%s' % (P.ColName, P.legend()) break Str += '\n' except IndexError: error("Curves: unknown Curve ID") return Str
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 individual's performance too """ # print '.', if self.F_affiliable(perf, G, G_perf, conservative=conservative): # the new guru is good enough and the individual is good enough for the guru # print('%s (%s) is about to follow %s (%s)' % (self, list(map(str, self.social_signature())), G, list(map(str, G.social_signature())))) if not self.follow( G, G_perf, conservative=conservative, Quit=self.G_quit_): error("Alliances", "inconsistent guru") if G.followers is not None: if not G.followers.follow( self, perf, conservative=conservative, Quit=G.F_quit_): error('Alliances', "inconsistent self") # self.consistency() # G.consistency() return True else: return False
def one_year(self): " one year of life " if self.year < 0: # just to get a snapshot of the initial situation self.season() # annual resetting and time increment self.statistics() return True try: self.limit() # some individuals die to limit population size self.migration() # some individuals change group self.group_splitting() # big groups split and small groups are dissolved self.season() # annual resetting and time increment if self.Observer.Visible(): self.statistics(Complete=True, Display=True) # compute statistics before reproduction try: self.Observer.recordInfo('Best', self.groups[0].get_best()) except (IndexError, AttributeError): pass # no record of best individual return True except Exception as Msg: error("Population", str(Msg)) return False
def txt_to_cfg(self, CfgTxtFile): """ retrieves a configuration from a text file """ try: # reads lines with following syntax: # [<Prefix/>*]<NameOfParameter> <ParameterValue> [<comments>] # Numerical parameters Numerical = FileAnalysis( CfgTxtFile, r"^(?:[^#]\S*/)?(\w+)\s+(-?\d+(?:\.\d*)?)\s") # # # # Numerical = [(V[1], Num(V[2])) for V in Numerical] # NonNumerical parameters # Alphabcal = FileAnalysis(CfgTxtFile, "^([^#]\S*/)?(\w+)\s+([^-0-9/]\S*).*$") Alphabcal = FileAnalysis(CfgTxtFile, "^(?:[^#]\S*/)?(\w+)\s+([^#\n]+)\s*$") # # # # Alphabcal = [(V[1],Alph(V[2])) for V in Alphabcal if not set(V[2]) <= set('-0123456789.') ] #cfg = dict([(V[1],int(V[2])) for V in R]) cfg = dict(Numerical + Alphabcal) ## if len(cfg) < len(Numerical + Alphabcal): ## error("Evolife_Parameters: duplicated parameter", str([V for V in Numerical + Alphabcal if V not in cfg])) return cfg except IOError: error("Evolife_Parameters: Problem accessing configuration file", CfgTxtFile) return None