From daeff3d9bf55c7e88bdb9457ffb057b92eaea024 Mon Sep 17 00:00:00 2001 From: J Alan Brogan Date: Mon, 22 Dec 2014 23:44:09 +0000 Subject: [PATCH] Pylint the code --- copycat/bond.py | 69 ++++++++----- copycat/codeletMethods.py | 186 ++++++++++++++++++++--------------- copycat/coderack.py | 35 +++---- copycat/coderackPressure.py | 98 +++++++++--------- copycat/conceptMapping.py | 5 +- copycat/correspondence.py | 2 + copycat/description.py | 2 +- copycat/formulas.py | 36 +++---- copycat/group.py | 53 ++++++---- copycat/rule.py | 7 +- copycat/slipnet.py | 93 +++++++++--------- copycat/slipnode.py | 23 ++--- copycat/workspaceFormulas.py | 52 +++++----- copycat/workspaceObject.py | 52 +++++----- 14 files changed, 388 insertions(+), 325 deletions(-) diff --git a/copycat/bond.py b/copycat/bond.py index e9b7df9..8dc9a15 100644 --- a/copycat/bond.py +++ b/copycat/bond.py @@ -4,6 +4,7 @@ from workspace import workspace class Bond(WorkspaceStructure): + # pylint: disable=too-many-arguments def __init__(self, source, destination, bondCategory, bondFacet, sourceDescriptor, destinationDescriptor): WorkspaceStructure.__init__(self) @@ -23,31 +24,30 @@ class Bond(WorkspaceStructure): self.category = bondCategory self.destinationIsOnRight = self.destination == self.rightObject - self.bidirectional = self.sourceDescriptor == self.destinationDescriptor + self.bidirectional = (self.sourceDescriptor == + self.destinationDescriptor) if self.bidirectional: self.directionCategory = None def flippedVersion(self): - """ - - """ return Bond( - self.destination, self.get_source(), self.category.getRelatedNode(slipnet.opposite), - self.facet, self.destinationDescriptor, self.sourceDescriptor - ) + self.destination, self.get_source(), + self.category.getRelatedNode(slipnet.opposite), + self.facet, self.destinationDescriptor, self.sourceDescriptor) def __repr__(self): return '' % self.__str__() def __str__(self): - return '%s bond between %s and %s' % (self.category.name, self.leftObject, self.rightObject) + return '%s bond between %s and %s' % ( + self.category.name, self.leftObject, self.rightObject) def buildBond(self): workspace.structures += [self] self.string.bonds += [self] self.category.buffer = 100.0 if self.directionCategory: - self.directionCategory.buffer = 100.0 + self.directionCategory.buffer = 100.0 self.leftObject.rightBond = self self.rightObject.leftBond = self self.leftObject.bonds += [self] @@ -79,7 +79,9 @@ class Bond(WorkspaceStructure): else: objekt = self.leftObject.correspondence.objectFromInitial if objekt.leftmost and objekt.rightBond: - if objekt.rightBond.directionCategory and objekt.rightBond.directionCategory != self.directionCategory: + if (objekt.rightBond.directionCategory and + objekt.rightBond.directionCategory != + self.directionCategory): incompatibles += [correspondence] if self.rightObject.rightmost and self.rightObject.correspondence: correspondence = self.rightObject.correspondence @@ -88,7 +90,9 @@ class Bond(WorkspaceStructure): else: objekt = self.rightObject.correspondence.objectFromInitial if objekt.rightmost and objekt.leftBond: - if objekt.leftBond.directionCategory and objekt.leftBond.directionCategory != self.directionCategory: + if (objekt.leftBond.directionCategory and + objekt.leftBond.directionCategory != + self.directionCategory): incompatibles += [correspondence] return incompatibles @@ -96,7 +100,8 @@ class Bond(WorkspaceStructure): # bonds between objects of same type(ie. letter or group) are # stronger than bonds between different types sourceGap = self.get_source().leftIndex != self.get_source().rightIndex - destinationGap = self.destination.leftIndex != self.destination.rightIndex + destinationGap = (self.destination.leftIndex != + self.destination.rightIndex) if sourceGap == destinationGap: memberCompatibility = 1.0 else: @@ -106,7 +111,8 @@ class Bond(WorkspaceStructure): facetFactor = 1.0 else: facetFactor = 0.7 - strength = min(100.0, memberCompatibility * facetFactor * self.category.bondDegreeOfAssociation()) + strength = min(100.0, memberCompatibility * facetFactor * + self.category.bondDegreeOfAssociation()) self.internalStrength = strength def updateExternalStrength(self): @@ -121,14 +127,16 @@ class Bond(WorkspaceStructure): self.externalStrength = strength def numberOfLocalSupportingBonds(self): - return len([b for b in self.string.bonds if b.string == self.get_source().string and - self.leftObject.letterDistance(b.leftObject) != 0 and - self.rightObject.letterDistance(b.rightObject) != 0 and - self.category == b.category and - self.directionCategory == b.directionCategory]) + return len([b for b in self.string.bonds if + b.string == self.get_source().string and + self.leftObject.letterDistance(b.leftObject) != 0 and + self.rightObject.letterDistance(b.rightObject) != 0 and + self.category == b.category and + self.directionCategory == b.directionCategory]) def sameCategories(self, other): - return self.category == other.category and self.directionCategory == other.directionCategory + return (self.category == other.category and + self.directionCategory == other.directionCategory) def myEnds(self, object1, object2): if self.get_source() == object1 and self.destination == object2: @@ -146,11 +154,14 @@ class Bond(WorkspaceStructure): if object1.beside(object2): slotSum += 1.0 for bond in self.string.bonds: - if bond != self and self.sameCategories(bond) and self.myEnds(object1, object2): - supportSum += 1.0 - if slotSum == 0.0: - return 0.0 - return 100.0 * supportSum / slotSum + if (bond != self and + self.sameCategories(bond) and + self.myEnds(object1, object2)): + supportSum += 1.0 + try: + return 100.0 * supportSum / slotSum + except ZeroDivisionError: + return 0.0 def sameNeighbours(self, other): if self.leftObject == other.leftObject: @@ -170,16 +181,20 @@ class Bond(WorkspaceStructure): def possibleGroupBonds(bondCategory, directionCategory, bondFacet, bonds): result = [] for bond in bonds: - if bond.category == bondCategory and bond.directionCategory == directionCategory: + if (bond.category == bondCategory and + bond.directionCategory == directionCategory): result += [bond] else: # a modified bond might be made if bondCategory == slipnet.sameness: return None # a different bond cannot be made here - if bond.category == bondCategory or bond.directionCategory == directionCategory: + if (bond.category == bondCategory or + bond.directionCategory == directionCategory): return None # a different bond cannot be made here if bond.category == slipnet.sameness: return None - bond = Bond(bond.destination, bond.get_source(), bondCategory, bondFacet, bond.destinationDescriptor, bond.sourceDescriptor) + bond = Bond(bond.destination, bond.get_source(), bondCategory, + bondFacet, bond.destinationDescriptor, + bond.sourceDescriptor) result += [bond] return result diff --git a/copycat/codeletMethods.py b/copycat/codeletMethods.py index b3ea53b..46d0c37 100644 --- a/copycat/codeletMethods.py +++ b/copycat/codeletMethods.py @@ -1,14 +1,25 @@ -import random + +import random +import logging + + +import slipnet +import temperature +import formulas +from workspaceFormulas import chooseDirectedNeighbor +from workspaceFormulas import chooseNeighbour from coderack import coderack from workspaceObject import WorkspaceObject from letter import Letter from replacement import Replacement -from formulas import * -from workspaceFormulas import * +from workspaceFormulas import workspace from group import Group -from bond import Bond, possibleGroupBonds +from bond import Bond +from bond import possibleGroupBonds from correspondence import Correspondence +from workspaceFormulas import chooseUnmodifiedObject +from workspaceFormulas import chooseBondFacet # some methods common to the codelets @@ -28,10 +39,10 @@ def __getScoutSource(slipnode, relevanceMethod, typeName): targetRelevance = relevanceMethod(workspace.target, slipnode) initialUnhappiness = workspace.initial.intraStringUnhappiness targetUnhappiness = workspace.target.intraStringUnhappiness - logging.info('initial : relevance = %d, unhappiness=%d' % ( - initialRelevance, int(initialUnhappiness))) - logging.info('target : relevance = %d, unhappiness=%d' % ( - targetRelevance, int(targetUnhappiness))) + logging.info('initial : relevance = %d, unhappiness=%d', + initialRelevance, int(initialUnhappiness)) + logging.info('target : relevance = %d, unhappiness=%d', + targetRelevance, int(targetUnhappiness)) string = workspace.initial relevances = initialRelevance + targetRelevance unhappinesses = initialUnhappiness + targetUnhappiness @@ -39,11 +50,11 @@ def __getScoutSource(slipnode, relevanceMethod, typeName): initials = initialRelevance + initialUnhappiness if randomized > initials: string = workspace.target - logging.info('target string selected: %s for %s' % ( - workspace.target, typeName)) + logging.info('target string selected: %s for %s', + workspace.target, typeName) else: - logging.info('initial string selected: %s for %s' % ( - workspace.initial, typeName)) + logging.info('initial string selected: %s for %s', + workspace.initial, typeName) source = chooseUnmodifiedObject('intraStringSalience', string.objects) return source @@ -68,12 +79,12 @@ def __allOppositeMappings(mappings): def __structureVsStructure(structure1, weight1, structure2, weight2): structure1.updateStrength() structure2.updateStrength() - weightedStrength1 = temperatureAdjustedValue( + weightedStrength1 = formulas.temperatureAdjustedValue( structure1.totalStrength * weight1) - weightedStrength2 = temperatureAdjustedValue( + weightedStrength2 = formulas.temperatureAdjustedValue( structure2.totalStrength * weight2) rhs = (weightedStrength1 + weightedStrength2) * random.random() - logging.info('%d > %d' % (weightedStrength1, rhs)) + logging.info('%d > %d', weightedStrength1, rhs) return weightedStrength1 > rhs @@ -83,9 +94,9 @@ def __fight(structure, structureWeight, incompatibles, incompatibleWeight): for incompatible in incompatibles: if not __structureVsStructure(structure, structureWeight, incompatible, incompatibleWeight): - logging.info('lost fight with %s' % incompatible) + logging.info('lost fight with %s', incompatible) return False - logging.info('won fight with %s' % incompatible) + logging.info('won fight with %s', incompatible) return True @@ -94,18 +105,19 @@ def __fightIncompatibles(incompatibles, structure, name, if len(incompatibles): if __fight(structure, structureWeight, incompatibles, incompatibleWeight): - logging.info('broke the %s' % name) + logging.info('broke the %s', name) return True - logging.info('failed to break %s: Fizzle' % name) + logging.info('failed to break %s: Fizzle', name) return False - logging.info('no incompatible %s' % name) + logging.info('no incompatible %s', name) return True def __slippability(conceptMappings): for mapping in conceptMappings: slippiness = mapping.slipability() / 100.0 - probabilityOfSlippage = temperatureAdjustedProbability(slippiness) + probabilityOfSlippage = formulas.temperatureAdjustedProbability( + slippiness) if formulas.coinFlip(probabilityOfSlippage): return True return False @@ -113,8 +125,8 @@ def __slippability(conceptMappings): # start the actual codelets def breaker(): - probabilityOfFizzle = (100.0 - Temperature) / 100.0 - assert not coinFlip(probabilityOfFizzle) + probabilityOfFizzle = (100.0 - formulas.Temperature) / 100.0 + assert not formulas.coinFlip(probabilityOfFizzle) # choose a structure at random structures = [s for s in workspace.structures if isinstance(s, (Group, Bond, Correspondence))] @@ -128,9 +140,9 @@ def breaker(): breakObjects += [structure.source.group] # try to break all objects for structure in breakObjects: - breakProbability = temperatureAdjustedProbability( + breakProbability = formulas.temperatureAdjustedProbability( structure.totalStrength / 100.0) - if coinFlip(breakProbability): + if formulas.coinFlip(breakProbability): return for structure in breakObjects: structure.break_the_structure() @@ -140,13 +152,13 @@ def bottom_up_description_scout(codelet): chosenObject = chooseUnmodifiedObject('totalSalience', workspace.objects) assert chosenObject __showWhichStringObjectIsFrom(chosenObject) - description = chooseRelevantDescriptionByActivation(chosenObject) + description = formulas.chooseRelevantDescriptionByActivation(chosenObject) assert description - sliplinks = similarPropertyLinks(description.descriptor) + sliplinks = formulas.similarPropertyLinks(description.descriptor) assert sliplinks and len(sliplinks) values = [sliplink.degreeOfAssociation() * sliplink.destination.activation for sliplink in sliplinks] - i = selectListPosition(values) + i = formulas.selectListPosition(values) chosen = sliplinks[i] chosenProperty = chosen.destination coderack.proposeDescription(chosenObject, chosenProperty.category(), @@ -161,7 +173,7 @@ def top_down_description_scout(codelet): descriptions = chosenObject.getPossibleDescriptions(descriptionType) assert descriptions and len(descriptions) values = [n.activation for n in descriptions] - i = selectListPosition(values) + i = formulas.selectListPosition(values) chosenProperty = descriptions[i] coderack.proposeDescription(chosenObject, chosenProperty.category(), chosenProperty, codelet) @@ -172,7 +184,7 @@ def description_strength_tester(codelet): description.descriptor.buffer = 100.0 description.updateStrength() strength = description.totalStrength - probability = temperatureAdjustedProbability(strength / 100.0) + probability = formulas.temperatureAdjustedProbability(strength / 100.0) assert formulas.coinFlip(probability) coderack.newCodelet('description-builder', codelet, strength) @@ -192,10 +204,10 @@ def bottom_up_bond_scout(codelet): __showWhichStringObjectIsFrom(source) destination = chooseNeighbour(source) assert destination - logging.info('destination: %s' % destination) + logging.info('destination: %s', destination) bondFacet = __getBondFacet(source, destination) - logging.info('chosen bond facet: %s' % bondFacet.get_name()) - logging.info('Source: %s, destination: %s' % (source, destination)) + logging.info('chosen bond facet: %s', bondFacet.get_name()) + logging.info('Source: %s, destination: %s', source, destination) bond_descriptors = __getDescriptors(bondFacet, source, destination) sourceDescriptor, destinationDescriptor = bond_descriptors logging.info("source descriptor: %s", sourceDescriptor.name.upper()) @@ -205,7 +217,7 @@ def bottom_up_bond_scout(codelet): assert category if category == slipnet.identity: category = slipnet.sameness - logging.info('proposing %s bond ' % category.name) + logging.info('proposing %s bond ', category.name) coderack.proposeBond(source, destination, category, bondFacet, sourceDescriptor, destinationDescriptor, codelet) @@ -243,16 +255,16 @@ def rule_scout(codelet): if targetObject.described(node): if targetObject.distinguishingDescriptor(node): newList += [node] - objectList = newList # XXX surely this should be += + objectList = newList # surely this should be += # "union of this and distinguishing descriptors" assert objectList and len(objectList) # use conceptual depth to choose a description valueList = [] for node in objectList: depth = node.conceptualDepth - value = temperatureAdjustedValue(depth) + value = formulas.temperatureAdjustedValue(depth) valueList += [value] - i = selectListPosition(valueList) + i = formulas.selectListPosition(valueList) descriptor = objectList[i] # choose the relation (change the letmost object to "successor" or "d" objectList = [] @@ -264,9 +276,9 @@ def rule_scout(codelet): valueList = [] for node in objectList: depth = node.conceptualDepth - value = temperatureAdjustedValue(depth) + value = formulas.temperatureAdjustedValue(depth) valueList += [value] - i = selectListPosition(valueList) + i = formulas.selectListPosition(valueList) relation = objectList[i] coderack.proposeRule(slipnet.letterCategory, descriptor, slipnet.letter, relation, codelet) @@ -275,7 +287,8 @@ def rule_scout(codelet): def rule_strength_tester(codelet): rule = codelet.arguments[0] rule.updateStrength() - probability = temperatureAdjustedProbability(rule.totalStrength / 100.0) + probability = formulas.temperatureAdjustedProbability( + rule.totalStrength / 100.0) assert random.random() <= probability coderack.newCodelet('rule-builder', codelet, rule.totalStrength, rule) @@ -305,7 +318,7 @@ def replacement_finder(): -1: slipnet.successor, 1: slipnet.predecessor} relation = relations[diff] - logging.info('Relation found: %s' % relation.name) + logging.info('Relation found: %s', relation.name) else: relation = None logging.info('no relation found') @@ -320,9 +333,10 @@ def replacement_finder(): def top_down_bond_scout__category(codelet): logging.info('top_down_bond_scout__category') category = codelet.arguments[0] - source = __getScoutSource(category, localBondCategoryRelevance, 'bond') + source = __getScoutSource(category, formulas.localBondCategoryRelevance, + 'bond') destination = chooseNeighbour(source) - logging.info('source: %s, destination: %s' % (source, destination)) + logging.info('source: %s, destination: %s', source, destination) assert destination bondFacet = __getBondFacet(source, destination) sourceDescriptor, destinationDescriptor = __getDescriptors( @@ -347,10 +361,10 @@ def top_down_bond_scout__category(codelet): def top_down_bond_scout__direction(codelet): direction = codelet.arguments[0] source = __getScoutSource( - direction, localDirectionCategoryRelevance, 'bond') + direction, formulas.localDirectionCategoryRelevance, 'bond') destination = chooseDirectedNeighbor(source, direction) assert destination - logging.info('to object: %s' % destination) + logging.info('to object: %s', destination) bondFacet = __getBondFacet(source, destination) sourceDescriptor, destinationDescriptor = __getDescriptors( bondFacet, source, destination) @@ -367,8 +381,8 @@ def bond_strength_tester(codelet): __showWhichStringObjectIsFrom(bond) bond.updateStrength() strength = bond.totalStrength - probability = temperatureAdjustedProbability(strength / 100.0) - logging.info('bond strength = %d for %s' % (strength, bond)) + probability = formulas.temperatureAdjustedProbability(strength / 100.0) + logging.info('bond strength = %d for %s', strength, bond) assert formulas.coinFlip(probability) bond.facet.buffer = 100.0 bond.sourceDescriptor.buffer = 100.0 @@ -391,9 +405,9 @@ def bond_builder(codelet): logging.info('already exists: activate descriptors & Fizzle') return incompatibleBonds = bond.getIncompatibleBonds() - logging.info('number of incompatibleBonds: %d' % len(incompatibleBonds)) + logging.info('number of incompatibleBonds: %d', len(incompatibleBonds)) if len(incompatibleBonds): - logging.info('%s' % incompatibleBonds[0]) + logging.info('%s', incompatibleBonds[0]) assert __fightIncompatibles(incompatibleBonds, bond, 'bonds', 1.0, 1.0) incompatibleGroups = bond.source.getCommonGroups(bond.destination) assert __fightIncompatibles(incompatibleGroups, bond, 'groups', 1.0, 1.0) @@ -413,15 +427,18 @@ def bond_builder(codelet): incompatible.break_the_structure() for incompatible in incompatibleCorrespondences: incompatible.break_the_structure() - logging.info('building bond %s' % bond) + logging.info('building bond %s', bond) bond.buildBond() +# pylint: disable=too-many-branches +# pylint: disable=too-many-statements def top_down_group_scout__category(codelet): groupCategory = codelet.arguments[0] category = groupCategory.getRelatedNode(slipnet.bondCategory) assert category - source = __getScoutSource(category, localBondCategoryRelevance, 'group') + source = __getScoutSource(category, formulas.localBondCategoryRelevance, + 'group') assert source and not source.spansString() if source.leftmost: direction = slipnet.right @@ -430,7 +447,7 @@ def top_down_group_scout__category(codelet): else: activations = [slipnet.left.activation] activations += [slipnet.right.activation] - if not selectListPosition(activations): + if not formulas.selectListPosition(activations): direction = slipnet.left else: direction = slipnet.right @@ -500,9 +517,10 @@ def top_down_group_scout__category(codelet): def top_down_group_scout__direction(codelet): direction = codelet.arguments[0] - source = __getScoutSource(direction, localDirectionCategoryRelevance, + source = __getScoutSource(direction, + formulas.localDirectionCategoryRelevance, 'direction') - logging.info('source chosen = %s' % source) + logging.info('source chosen = %s', source) assert not source.spansString() if source.leftmost: mydirection = slipnet.right @@ -511,7 +529,7 @@ def top_down_group_scout__direction(codelet): else: activations = [slipnet.left.activation] activations += [slipnet.right.activation] - if not selectListPosition(activations): + if not formulas.selectListPosition(activations): mydirection = slipnet.left else: mydirection = slipnet.right @@ -522,7 +540,7 @@ def top_down_group_scout__direction(codelet): if not firstBond: logging.info('no firstBond') else: - logging.info('firstBond: %s' % firstBond) + logging.info('firstBond: %s', firstBond) if firstBond and not firstBond.directionCategory: direction = None if not firstBond or firstBond.directionCategory != direction: @@ -533,15 +551,15 @@ def top_down_group_scout__direction(codelet): if not firstBond: logging.info('no firstBond2') else: - logging.info('firstBond2: %s' % firstBond) + logging.info('firstBond2: %s', firstBond) if firstBond and not firstBond.directionCategory: direction = None assert firstBond and firstBond.directionCategory == direction - logging.info('possible group: %s' % firstBond) + logging.info('possible group: %s', firstBond) category = firstBond.category assert category groupCategory = category.getRelatedNode(slipnet.groupCategory) - logging.info('trying from %s to %s' % (source, category.name)) + logging.info('trying from %s to %s', source, category.name) bondFacet = None # find leftmost object in group with these bonds search = True @@ -576,7 +594,7 @@ def top_down_group_scout__direction(codelet): destination = destination.rightBond.rightObject search = True assert destination != source - logging.info('proposing group from %s to %s' % (source, destination)) + logging.info('proposing group from %s to %s', source, destination) objects = [source] bonds = [] while source != destination: @@ -592,9 +610,9 @@ def group_scout__whole_string(codelet): string = workspace.initial if random.random() > 0.5: string = workspace.target - logging.info('target string selected: %s' % workspace.target) + logging.info('target string selected: %s', workspace.target) else: - logging.info('initial string selected: %s' % workspace.initial) + logging.info('initial string selected: %s', workspace.initial) # find leftmost object & the highest group to which it belongs leftmost = None for objekt in string.objects: @@ -634,7 +652,7 @@ def group_strength_tester(codelet): __showWhichStringObjectIsFrom(group) group.updateStrength() strength = group.totalStrength - probability = temperatureAdjustedProbability(strength / 100.0) + probability = formulas.temperatureAdjustedProbability(strength / 100.0) assert random.random() <= probability # it is strong enough - post builder & activate nodes group.groupCategory.getRelatedNode(slipnet.bondCategory).buffer = 100.0 @@ -671,16 +689,16 @@ def group_builder(codelet): continue incompatibleBonds += [leftBond] previous = objekt - next = group.objectList[-1] + next_object = group.objectList[-1] for objekt in reversed(group.objectList[:-1]): rightBond = objekt.rightBond if rightBond: - if rightBond.rightObject == next: + if rightBond.rightObject == next_object: continue if rightBond.directionCategory == group.directionCategory: continue incompatibleBonds += [rightBond] - next = objekt + next_object = objekt # if incompatible bonds exist - fight group.updateStrength() assert __fightIncompatibles(incompatibleBonds, group, 'bonds', 1.0, 1.0) @@ -778,9 +796,10 @@ def bottom_up_correspondence_scout(codelet): workspace.target.objects) assert objectFromInitial.spansString() == objectFromTarget.spansString() # get the posible concept mappings - conceptMappings = getMappings(objectFromInitial, objectFromTarget, - objectFromInitial.relevantDescriptions(), - objectFromTarget.relevantDescriptions()) + conceptMappings = formulas.getMappings( + objectFromInitial, objectFromTarget, + objectFromInitial.relevantDescriptions(), + objectFromTarget.relevantDescriptions()) assert conceptMappings and __slippability(conceptMappings) #find out if any are distinguishing distinguishingMappings = [m for m in conceptMappings if m.distinguishing()] @@ -795,12 +814,13 @@ def bottom_up_correspondence_scout(codelet): if (objectFromInitial.spansString() and objectFromTarget.spansString() and slipnet.directionCategory in initialDescriptionTypes - and __allOppositeMappings(oppositeMappings) + and __allOppositeMappings(formulas.oppositeMappings) and slipnet.opposite.activation != 100.0): objectFromTarget = objectFromTarget.flippedVersion() - conceptMappings = getMappings(objectFromInitial, objectFromTarget, - objectFromInitial.relevantDescriptions(), - objectFromTarget.relevantDescriptions()) + conceptMappings = formulas.getMappings( + objectFromInitial, objectFromTarget, + objectFromInitial.relevantDescriptions(), + objectFromTarget.relevantDescriptions()) flipTargetObject = True coderack.proposeCorrespondence(objectFromInitial, objectFromTarget, conceptMappings, flipTargetObject, codelet) @@ -810,7 +830,7 @@ def important_object_correspondence_scout(codelet): objectFromInitial = chooseUnmodifiedObject('relativeImportance', workspace.initial.objects) descriptors = objectFromInitial.relevantDistinguishingDescriptors() - slipnode = chooseSlipnodeByConceptualDepth(descriptors) + slipnode = formulas.chooseSlipnodeByConceptualDepth(descriptors) assert slipnode initialDescriptor = slipnode for mapping in workspace.slippages(): @@ -826,9 +846,10 @@ def important_object_correspondence_scout(codelet): targetCandidates) assert objectFromInitial.spansString() == objectFromTarget.spansString() # get the posible concept mappings - conceptMappings = getMappings(objectFromInitial, objectFromTarget, - objectFromInitial.relevantDescriptions(), - objectFromTarget.relevantDescriptions()) + conceptMappings = formulas.getMappings( + objectFromInitial, objectFromTarget, + objectFromInitial.relevantDescriptions(), + objectFromTarget.relevantDescriptions()) assert conceptMappings and __slippability(conceptMappings) #find out if any are distinguishing distinguishingMappings = [m for m in conceptMappings if m.distinguishing()] @@ -843,12 +864,13 @@ def important_object_correspondence_scout(codelet): if (objectFromInitial.spansString() and objectFromTarget.spansString() and slipnet.directionCategory in initialDescriptionTypes - and __allOppositeMappings(oppositeMappings) + and __allOppositeMappings(formulas.oppositeMappings) and slipnet.opposite.activation != 100.0): objectFromTarget = objectFromTarget.flippedVersion() - conceptMappings = getMappings(objectFromInitial, objectFromTarget, - objectFromInitial.relevantDescriptions(), - objectFromTarget.relevantDescriptions()) + conceptMappings = formulas.getMappings( + objectFromInitial, objectFromTarget, + objectFromInitial.relevantDescriptions(), + objectFromTarget.relevantDescriptions()) flipTargetObject = True coderack.proposeCorrespondence(objectFromInitial, objectFromTarget, conceptMappings, flipTargetObject, codelet) @@ -865,7 +887,7 @@ def correspondence_strength_tester(codelet): objectFromTarget.flipped_version()))) correspondence.updateStrength() strength = correspondence.totalStrength - probability = temperatureAdjustedProbability(strength / 100.0) + probability = formulas.temperatureAdjustedProbability(strength / 100.0) assert random.random() <= probability # activate some concepts for mapping in correspondence.conceptMappings: diff --git a/copycat/coderack.py b/copycat/coderack.py index 71d6f3d..0d32652 100644 --- a/copycat/coderack.py +++ b/copycat/coderack.py @@ -16,6 +16,13 @@ MAX_NUMBER_OF_CODELETS = 100 codeletsUsed = {} +def getUrgencyBin(urgency): + i = int(urgency) * NUMBER_OF_BINS / 100 + if i >= NUMBER_OF_BINS: + return NUMBER_OF_BINS + return i + 1 + + class CodeRack(object): def __init__(self): #logging.debug('coderack.__init__()') @@ -46,13 +53,6 @@ class CodeRack(object): self.postTopDownCodelets() self.postBottomUpCodelets() - def getUrgencyBin(self, urgency): - bin = int(urgency) * NUMBER_OF_BINS - bin /= 100 - if bin >= NUMBER_OF_BINS: - bin = NUMBER_OF_BINS - 1 - return bin + 1 - def post(self, codelet): self.postings[codelet.name] = self.postings.get(codelet.name, 0) + 1 self.pressures.addCodelet(codelet) @@ -71,10 +71,10 @@ class CodeRack(object): probability = workspaceFormulas.probabilityOfPosting( codeletName) howMany = workspaceFormulas.howManyToPost(codeletName) - for unused in range(0, howMany): + for _ in range(0, howMany): if random.random() >= probability: continue - urgency = self.getUrgencyBin( + urgency = getUrgencyBin( node.activation * node.conceptualDepth / 100.0) codelet = Codelet(codeletName, urgency, self.codeletsRun) codelet.arguments += [node] @@ -108,7 +108,7 @@ class CodeRack(object): urgency = 1 if formulas.Temperature < 25.0 and 'translator' in codeletName: urgency = 5 - for unused in range(0, howMany): + for _ in range(0, howMany): if random.random() < probability: codelet = Codelet(codeletName, urgency, self.codeletsRun) self.post(codelet) @@ -128,6 +128,7 @@ class CodeRack(object): newCodelet.pressure = oldCodelet.pressure self.tryRun(newCodelet) + # pylint: disable=too-many-arguments def proposeRule(self, facet, description, category, relation, oldCodelet): """Creates a proposed rule, and posts a rule-strength-tester codelet. @@ -162,9 +163,9 @@ class CodeRack(object): numberOfMappings = len(mappings) if urgency: urgency /= numberOfMappings - bin = self.getUrgencyBin(urgency) + binn = self.getUrgencyBin(urgency) logging.info('urgency: %s, number: %d, bin: %d', - urgency, numberOfMappings, bin) + urgency, numberOfMappings, binn) self.newCodelet('correspondence-strength-tester', oldCodelet, urgency, correspondence) @@ -226,7 +227,7 @@ class CodeRack(object): def postInitialCodelets(self): for name in self.initialCodeletNames: - for unused in range(0, workspaceFormulas.numberOfObjects()): + for _ in range(0, workspaceFormulas.numberOfObjects()): codelet = Codelet(name, 1, self.codeletsRun) self.post(codelet) codelet2 = Codelet(name, 1, self.codeletsRun) @@ -296,8 +297,8 @@ class CodeRack(object): threshold = r * urgsum chosen = None urgencySum = 0.0 - logging.info('temperature: %f' % formulas.Temperature) - logging.info('actualTemperature: %f' % formulas.actualTemperature) + logging.info('temperature: %f', formulas.Temperature) + logging.info('actualTemperature: %f', formulas.actualTemperature) logging.info('Slipnet:') for node in slipnet.slipnodes: logging.info("\tnode %s, activation: %d, buffer: %d, depth: %s", @@ -305,7 +306,7 @@ class CodeRack(object): node.conceptualDepth) logging.info('Coderack:') for codelet in self.codelets: - logging.info('\t%s, %d' % (codelet.name, codelet.urgency)) + logging.info('\t%s, %d', codelet.name, codelet.urgency) from workspace import workspace workspace.initial.log("Initial: ") @@ -344,7 +345,7 @@ class CodeRack(object): methodName) if not callable(method): raise RuntimeError('Cannot call %s()' % methodName) - args, varargs, varkw, defaults = inspect.getargspec(method) + args, _varargs, _varkw, _defaults = inspect.getargspec(method) #global codeletsUsed #codeletsUsed[methodName] = codeletsUsed.get(methodName,0) + 1 try: diff --git a/copycat/coderackPressure.py b/copycat/coderackPressure.py index fc2cc99..4c83519 100644 --- a/copycat/coderackPressure.py +++ b/copycat/coderackPressure.py @@ -13,6 +13,48 @@ class CoderackPressure(object): self.codelets = [] +def _codelet_index(codelet): + name_indices = { + 'bottom-up-bond-scout': 0, + 'top-down-bond-scout--category': { + slipnet.successor: 1, + slipnet.predecessor: 2, + None: 3 + }, + 'top-down-bond-scout--direction': { + slipnet.left: 4, + slipnet.right: 5, + None: 3, + }, + 'top-down-group-scout--category': { + slipnet.successorGroup: 6, + slipnet.predecessorGroup: 7, + None: 8, + }, + 'top-down-group-scout--direction': { + slipnet.left: 9, + slipnet.right: 10, + None: -1, + }, + 'group-scout--whole-string': 11, + 'replacement-finder': 12, + 'rule-scout': 13, + 'rule-translator': 14, + 'bottom-up-correspondence-scout': 15, + 'important-object-correspondence-scout': 16, + 'breaker': 17, + } + i = name_indices.get(codelet.name, -1) + try: + return int(i) + except ValueError: + try: + node = codelet.arguments[0] + return i[node] + except KeyError: + return i[None] + + class CoderackPressures(object): def __init__(self): #logging.debug('coderackPressures.__init__()') @@ -70,62 +112,16 @@ class CoderackPressures(object): def addCodelet(self, codelet): node = None - i = -1 - if codelet.name == 'bottom-up-bond-scout': - i = 0 - if codelet.name == 'top-down-bond-scout--category': - node = codelet.arguments[0] - if node == slipnet.successor: - i = 1 - elif node == slipnet.predecessor: - i = 2 - else: - i = 3 - if codelet.name == 'top-down-bond-scout--direction': - node = codelet.arguments[0] - if node == slipnet.left: - i = 4 - elif node == slipnet.right: - i = 5 - else: - i = 3 - if codelet.name == 'top-down-group-scout--category': - node = codelet.arguments[0] - if node == slipnet.successorGroup: - i = 6 - elif node == slipnet.predecessorGroup: - i = 7 - else: - i = 8 - if codelet.name == 'top-down-group-scout--direction': - node = codelet.arguments[0] - if node == slipnet.left: - i = 9 - elif node == slipnet.right: - i = 10 - if codelet.name == 'group-scout--whole-string': - i = 11 - if codelet.name == 'replacement-finder': - i = 12 - if codelet.name == 'rule-scout': - i = 13 - if codelet.name == 'rule-translator': - i = 14 - if codelet.name == 'bottom-up-correspondence-scout': - i = 15 - if codelet.name == 'important-object-correspondence-scout': - i = 16 - if codelet.name == 'breaker': - i = 17 + i = _codelet_index(codelet) if i >= 0: self.pressures[i].codelets += [codelet] if codelet.pressure: - codelet.pressure.codelets += [codelet] # XXX why do this + codelet.pressure.codelets += [codelet] if i >= 0: - codelet.pressure = self.pressures[i] # when this is next? - logging.info('Add %s: %d' % (codelet.name, i)) + codelet.pressure = self.pressures[i] + logging.info('Add %s: %d', codelet.name, i) if node: - logging.info('Node: %s' % node.name) + logging.info('Node: %s', node.name) def removeCodelet(self, codelet): self.removedCodelets += [codelet] diff --git a/copycat/conceptMapping.py b/copycat/conceptMapping.py index 71dc3a5..2a5ddbb 100644 --- a/copycat/conceptMapping.py +++ b/copycat/conceptMapping.py @@ -6,8 +6,9 @@ class ConceptMapping(object): def __init__(self, initialDescriptionType, targetDescriptionType, initialDescriptor, targetDescriptor, initialObject, targetObject): - logging.info('make a map: %s-%s' % (initialDescriptionType.get_name(), - targetDescriptionType.get_name())) + # pylint: disable=too-many-arguments + logging.info('make a map: %s-%s', initialDescriptionType.get_name(), + targetDescriptionType.get_name()) self.initialDescriptionType = initialDescriptionType self.targetDescriptionType = targetDescriptionType self.initialDescriptor = initialDescriptor diff --git a/copycat/correspondence.py b/copycat/correspondence.py index 92edc44..d7de5eb 100644 --- a/copycat/correspondence.py +++ b/copycat/correspondence.py @@ -1,3 +1,5 @@ + + from workspace import workspace from workspaceStructure import WorkspaceStructure from formulas import getMappings diff --git a/copycat/description.py b/copycat/description.py index fe95d50..f2a018f 100644 --- a/copycat/description.py +++ b/copycat/description.py @@ -47,7 +47,7 @@ class Description(WorkspaceStructure): self.descriptionType.buffer = 100.0 self.descriptor.buffer = 100.0 if not self.object.described(self.descriptor): - logging.info('Add %s to descriptions' % self) + logging.info('Add %s to descriptions', self) self.object.descriptions += [self] def breakDescription(self): diff --git a/copycat/formulas.py b/copycat/formulas.py index 9da8bdb..c1a4bc1 100644 --- a/copycat/formulas.py +++ b/copycat/formulas.py @@ -49,7 +49,7 @@ def temperatureAdjustedProbability(value): a = math.sqrt(coldness) b = 10.0 - a c = b / 100 - d = c * (1.0 - (1.0 - value)) # aka c * value, but we're following the java + d = c * (1.0 - (1.0 - value)) # as said the java e = (1.0 - value) + d f = 1.0 - e return max(f, 0.5) @@ -70,13 +70,14 @@ def chooseObjectFromList(objects, attribute): if not objects: return None probabilities = [] - for object in objects: - value = getattr(object, attribute) + for objekt in objects: + value = getattr(objekt, attribute) probability = temperatureAdjustedValue(value) - logging.info('Object: %s, value: %d, probability: %d' % (object, value, probability)) + logging.info('Object: %s, value: %d, probability: %d', + objekt, value, probability) probabilities += [probability] i = selectListPosition(probabilities) - logging.info("Selected: %d" % i) + logging.info('Selected: %d', i) return objects[i] @@ -84,7 +85,8 @@ def chooseRelevantDescriptionByActivation(workspaceObject): descriptions = workspaceObject.relevantDescriptions() if not descriptions: return None - activations = [description.descriptor.activation for description in descriptions] + activations = [description.descriptor.activation + for description in descriptions] i = selectListPosition(activations) return descriptions[i] @@ -119,13 +121,11 @@ def __localRelevance(string, slipnode, relevance): numberOfObjectsNotSpanning = numberOfMatches = 0.0 #logging.info("find relevance for a string: %s" % string); for objekt in string.objects: - #logging.info('object: %s' % objekt) if not objekt.spansString(): #logging.info('non spanner: %s' % objekt) numberOfObjectsNotSpanning += 1.0 if relevance(objekt, slipnode): numberOfMatches += 1.0 - #logging.info("matches: %d, not spanning: %d" % (numberOfMatches,numberOfObjectsNotSpanning)) if numberOfObjectsNotSpanning == 1: return 100.0 * numberOfMatches return 100.0 * numberOfMatches / (numberOfObjectsNotSpanning - 1.0) @@ -141,18 +141,20 @@ def localDirectionCategoryRelevance(string, direction): return __localRelevance(string, direction, __relevantDirection) -def getMappings(objectFromInitial, objectFromTarget, initialDescriptions, targetDescriptions): +def getMappings(objectFromInitial, objectFromTarget, + initialDescriptions, targetDescriptions): mappings = [] from conceptMapping import ConceptMapping - for initialDescription in initialDescriptions: - for targetDescription in targetDescriptions: - if initialDescription.descriptionType == targetDescription.descriptionType: - if initialDescription.descriptor == targetDescription.descriptor or initialDescription.descriptor.slipLinked(targetDescription.descriptor): + for initial in initialDescriptions: + for target in targetDescriptions: + if initial.descriptionType == target.descriptionType: + if (initial.descriptor == target.descriptor or + initial.descriptor.slipLinked(target.descriptor)): mapping = ConceptMapping( - initialDescription.descriptionType, - targetDescription.descriptionType, - initialDescription.descriptor, - targetDescription.descriptor, + initial.descriptionType, + target.descriptionType, + initial.descriptor, + target.descriptor, objectFromInitial, objectFromTarget ) diff --git a/copycat/group.py b/copycat/group.py index 6849521..fef8cd3 100644 --- a/copycat/group.py +++ b/copycat/group.py @@ -8,14 +8,18 @@ import formulas class Group(WorkspaceObject): - def __init__(self, string, groupCategory, directionCategory, facet, objectList, bondList): + # pylint: disable=too-many-instance-attributes + def __init__(self, string, groupCategory, directionCategory, facet, + objectList, bondList): + # pylint: disable=too-many-arguments WorkspaceObject.__init__(self, string) self.groupCategory = groupCategory self.directionCategory = directionCategory self.facet = facet self.objectList = objectList self.bondList = bondList - self.bondCategory = self.groupCategory.getRelatedNode(slipnet.bondCategory) + self.bondCategory = self.groupCategory.getRelatedNode( + slipnet.bondCategory) leftObject = objectList[0] rightObject = objectList[-1] @@ -41,8 +45,10 @@ class Group(WorkspaceObject): from description import Description if self.bondList and len(self.bondList): firstFacet = self.bondList[0].facet - self.addBondDescription(Description(self, slipnet.bondFacet, firstFacet)) - self.addBondDescription(Description(self, slipnet.bondCategory, self.bondCategory)) + self.addBondDescription( + Description(self, slipnet.bondFacet, firstFacet)) + self.addBondDescription( + Description(self, slipnet.bondCategory, self.bondCategory)) self.addDescription(slipnet.objectCategory, slipnet.group) self.addDescription(slipnet.groupCategory, self.groupCategory) @@ -51,22 +57,29 @@ class Group(WorkspaceObject): letter = self.objectList[0].getDescriptor(self.facet) self.addDescription(self.facet, letter) if self.directionCategory: - self.addDescription(slipnet.directionCategory, self.directionCategory) + self.addDescription(slipnet.directionCategory, + self.directionCategory) if self.spansString(): self.addDescription(slipnet.stringPositionCategory, slipnet.whole) elif self.leftIndex == 1: - self.addDescription(slipnet.stringPositionCategory, slipnet.leftmost) + self.addDescription( + slipnet.stringPositionCategory, slipnet.leftmost) elif self.rightIndex == self.string.length: - self.addDescription(slipnet.stringPositionCategory, slipnet.rightmost) + self.addDescription( + slipnet.stringPositionCategory, slipnet.rightmost) elif self.middleObject(): - self.addDescription(slipnet.stringPositionCategory, slipnet.middle) + self.addDescription( + slipnet.stringPositionCategory, slipnet.middle) + self.add_length_description_category() + def add_length_description_category(self): #check whether or not to add length description category probability = self.lengthDescriptionProbability() if random.random() < probability: length = len(self.objectList) if length < 6: - self.addDescription(slipnet.length, slipnet.numbers[length - 1]) + self.addDescription(slipnet.length, + slipnet.numbers[length - 1]) def __str__(self): s = self.string.__str__() @@ -103,8 +116,10 @@ class Group(WorkspaceObject): def flippedVersion(self): flippedBonds = [b.flippedversion() for b in self.bondList] flippedGroup = self.groupCategory.getRelatedNode(slipnet.flipped) - flippedDirection = self.directionCategory.getRelatedNode(slipnet.flipped) - return Group(self.string, flippedGroup, flippedDirection, self.facet, self.objectList, flippedBonds) + flippedDirection = self.directionCategory.getRelatedNode( + slipnet.flipped) + return Group(self.string, flippedGroup, flippedDirection, + self.facet, self.objectList, flippedBonds) def buildGroup(self): workspace.objects += [self] @@ -117,7 +132,7 @@ class Group(WorkspaceObject): def activateDescriptions(self): for description in self.descriptions: - logging.info('Activate: %s' % description) + logging.info('Activate: %s', description) description.descriptor.buffer = 100.0 def lengthDescriptionProbability(self): @@ -157,7 +172,8 @@ class Group(WorkspaceObject): self.rightBond.breakBond() def updateInternalStrength(self): - relatedBondAssociation = self.groupCategory.getRelatedNode(slipnet.bondCategory).degreeOfAssociation() + relatedBondAssociation = self.groupCategory.getRelatedNode( + slipnet.bondCategory).degreeOfAssociation() bondWeight = relatedBondAssociation ** 0.98 length = len(self.objectList) if length == 1: @@ -169,7 +185,8 @@ class Group(WorkspaceObject): else: lengthFactor = 90.0 lengthWeight = 100.0 - bondWeight - weightList = ((relatedBondAssociation, bondWeight), (lengthFactor, lengthWeight)) + weightList = ((relatedBondAssociation, bondWeight), + (lengthFactor, lengthWeight)) self.internalStrength = formulas.weightedAverage(weightList) def updateExternalStrength(self): @@ -190,8 +207,10 @@ class Group(WorkspaceObject): count = 0 for objekt in self.string.objects: if isinstance(objekt, Group): - if objekt.rightIndex < self.leftIndex or objekt.leftIndex > self.rightIndex: - if objekt.groupCategory == self.groupCategory and objekt.directionCategory == self.directionCategory: + if (objekt.rightIndex < self.leftIndex or + objekt.leftIndex > self.rightIndex): + if (objekt.groupCategory == self.groupCategory and + objekt.directionCategory == self.directionCategory): count += 1 return count @@ -223,7 +242,7 @@ class Group(WorkspaceObject): return result def distinguishingDescriptor(self, descriptor): - """Whether no other object of the same type (group) has the same descriptor""" + """Whether no other object of the same type has the same descriptor""" if not WorkspaceObject.distinguishingDescriptor(self, descriptor): return False for objekt in self.string.objects: diff --git a/copycat/rule.py b/copycat/rule.py index 4e792db..ba741ec 100644 --- a/copycat/rule.py +++ b/copycat/rule.py @@ -1,7 +1,10 @@ +import logging + + from slipnet import slipnet from workspace import workspace from workspaceStructure import WorkspaceStructure -from formulas import * +from formulas import weightedAverage class Rule(WorkspaceStructure): @@ -123,7 +126,7 @@ class Rule(WorkspaceStructure): o.described(self.descriptor) and o.described(self.category)] changed = changeds and changeds[0] or None - logging.debug('changed object = %s' % changed) + logging.debug('changed object = %s', changed) if changed: left = changed.leftIndex startString = '' diff --git a/copycat/slipnet.py b/copycat/slipnet.py index 6ace0c5..901888b 100644 --- a/copycat/slipnet.py +++ b/copycat/slipnet.py @@ -5,6 +5,7 @@ from sliplink import Sliplink class SlipNet(object): + # pylint: disable=too-many-instance-attributes def __init__(self): logging.debug("SlipNet.__init__()") self.initiallyClampedSlipnodes = [] @@ -21,8 +22,8 @@ class SlipNet(object): return '' def setConceptualDepths(self, depth): - logging.debug('slipnet set all depths to %f' % depth) - [node.setConceptualDepth(depth) for node in self.slipnodes] + logging.debug('slipnet set all depths to %f', depth) + _ = [node.setConceptualDepth(depth) for node in self.slipnodes] def reset(self): logging.debug('slipnet.reset()') @@ -36,8 +37,8 @@ class SlipNet(object): logging.debug('slipnet.update()') self.numberOfUpdates += 1 if self.numberOfUpdates == 50: - [node.unclamp() for node in self.initiallyClampedSlipnodes] - [node.update() for node in self.slipnodes] + _ = [node.unclamp() for node in self.initiallyClampedSlipnodes] + _ = [node.update() for node in self.slipnodes] for node in self.slipnodes: node.spread_activation() for node in self.slipnodes: @@ -46,6 +47,7 @@ class SlipNet(object): node.buffer = 0.0 def __addInitialNodes(self): + # pylint: disable=too-many-statements self.slipnodes = [] self.letters = [] for c in 'abcdefghijklmnopqrstuvwxyz': @@ -135,47 +137,49 @@ class SlipNet(object): self.__addCategoryLink(self.samenessGroup, self.letterCategory, 50.0) # lengths for number in self.numbers: - self.__addInstanceLink(self.length, number, 100.0) - self.__addNonSlipLink(self.predecessorGroup, self.length, length=95.0) - self.__addNonSlipLink(self.successorGroup, self.length, length=95.0) - self.__addNonSlipLink(self.samenessGroup, self.length, length=95.0) - # opposites - self.__addOppositeLink(self.first, self.last) - self.__addOppositeLink(self.leftmost, self.rightmost) - self.__addOppositeLink(self.left, self.right) - self.__addOppositeLink(self.successor, self.predecessor) - self.__addOppositeLink(self.successorGroup, self.predecessorGroup) + self.__addInstanceLink(self.length, number) + groups = [self.predecessorGroup, self.successorGroup, + self.samenessGroup] + for group in groups: + self.__addNonSlipLink(group, self.length, length=95.0) + opposites = [(self.first, self.last), (self.leftmost, self.rightmost), + (self.leftmost, self.rightmost), (self.left, self.right), + (self.successor, self.predecessor), + (self.successorGroup, self.predecessorGroup)] + for a, b in opposites: + self.__addOppositeLink(a, b) # properties self.__addPropertyLink(self.letters[0], self.first, 75.0) self.__addPropertyLink(self.letters[-1], self.last, 75.0) - # object categories - self.__addInstanceLink(self.objectCategory, self.letter, 100.0) - self.__addInstanceLink(self.objectCategory, self.group, 100.0) - # string positions - self.__addInstanceLink( - self.stringPositionCategory, self.leftmost, 100.0) - self.__addInstanceLink( - self.stringPositionCategory, self.rightmost, 100.0) - self.__addInstanceLink(self.stringPositionCategory, self.middle, 100.0) - self.__addInstanceLink(self.stringPositionCategory, self.single, 100.0) - self.__addInstanceLink(self.stringPositionCategory, self.whole, 100.0) - # alphabetic positions - self.__addInstanceLink( - self.alphabeticPositionCategory, self.first, 100.0) - self.__addInstanceLink( - self.alphabeticPositionCategory, self.last, 100.0) - # direction categories - self.__addInstanceLink(self.directionCategory, self.left, 100.0) - self.__addInstanceLink(self.directionCategory, self.right, 100.0) - # bond categories - self.__addInstanceLink(self.bondCategory, self.predecessor, 100.0) - self.__addInstanceLink(self.bondCategory, self.successor, 100.0) - self.__addInstanceLink(self.bondCategory, self.sameness, 100.0) - # group categories - self.__addInstanceLink( - self.groupCategory, self.predecessorGroup, 100.0) - self.__addInstanceLink(self.groupCategory, self.successorGroup, 100.0) - self.__addInstanceLink(self.groupCategory, self.samenessGroup, 100.0) + links = [ + # object categories + (self.objectCategory, self.letter), + (self.objectCategory, self.group), + # string positions, + (self.stringPositionCategory, self.leftmost), + (self.stringPositionCategory, self.rightmost), + (self.stringPositionCategory, self.middle), + (self.stringPositionCategory, self.single), + (self.stringPositionCategory, self.whole), + # alphabetic positions, + (self.alphabeticPositionCategory, self.first), + (self.alphabeticPositionCategory, self.last), + # direction categories, + (self.directionCategory, self.left), + (self.directionCategory, self.right), + # bond categories, + (self.bondCategory, self.predecessor), + (self.bondCategory, self.successor), + (self.bondCategory, self.sameness), + # group categories + (self.groupCategory, self.predecessorGroup), + (self.groupCategory, self.successorGroup), + (self.groupCategory, self.samenessGroup), + # bond facets + (self.bondFacet, self.letterCategory), + (self.bondFacet, self.length)] + for a, b in links: + self.__addInstanceLink(a, b) # link bonds to their groups self.__addNonSlipLink( self.sameness, self.samenessGroup, label=self.groupCategory, @@ -191,9 +195,6 @@ class SlipNet(object): label=self.bondCategory, length=90.0) self.__addNonSlipLink(self.predecessorGroup, self.predecessor, label=self.bondCategory, length=90.0) - # bond facets - self.__addInstanceLink(self.bondFacet, self.letterCategory, 100.0) - self.__addInstanceLink(self.bondFacet, self.length, 100.0) # letter category to length self.__addSlipLink(self.letterCategory, self.length, length=95.0) self.__addSlipLink(self.length, self.letterCategory, length=95.0) @@ -235,7 +236,7 @@ class SlipNet(object): link = self.__addLink(source, destination, None, length) source.categoryLinks += [link] - def __addInstanceLink(self, source, destination, length): + def __addInstanceLink(self, source, destination, length=100.0): categoryLength = source.conceptualDepth - destination.conceptualDepth self.__addCategoryLink(destination, source, categoryLength) #noinspection PyArgumentEqualDefault diff --git a/copycat/slipnode.py b/copycat/slipnode.py index a1ea6d3..e97cbf9 100644 --- a/copycat/slipnode.py +++ b/copycat/slipnode.py @@ -11,9 +11,14 @@ def jump_threshold(): return 55.0 +def points_at(links, other): + """Whether any of the links points at the other""" + return any([l.points_at(other) for l in links]) + + class Slipnode(object): + # pylint: disable=too-many-instance-attributes def __init__(self, name, depth, length=0.0): - # logging.info('depth to %s for %s' % (depth,name)) self.conceptualDepth = depth self.usualConceptualDepth = depth self.name = name @@ -52,7 +57,7 @@ class Slipnode(object): return not self.clamped def setConceptualDepth(self, depth): - logging.info('set depth to %s for %s' % (depth, self.name)) + logging.info('set depth to %s for %s', depth, self.name) self.conceptualDepth = depth def category(self): @@ -90,15 +95,11 @@ class Slipnode(object): def linked(self, other): """Whether the other is among the outgoing links""" - return self.points_at(self.outgoingLinks, other) + return points_at(self.outgoingLinks, other) def slipLinked(self, other): """Whether the other is among the lateral links""" - return self.points_at(self.lateralSlipLinks, other) - - def points_at(self, links, other): - """Whether any of the links points at the other""" - return any([l.points_at(other) for l in links]) + return points_at(self.lateralSlipLinks, other) def related(self, other): """Same or linked""" @@ -142,14 +143,14 @@ class Slipnode(object): result = link.label break if result: - logging.info('Got bond: %s' % result.name) + logging.info('Got bond: %s', result.name) else: logging.info('Got no bond') return result def spread_activation(self): if self.fully_active(): - [link.spread_activation() for link in self.outgoingLinks] + _ = [link.spread_activation() for link in self.outgoingLinks] def addBuffer(self): if self.unclamped(): @@ -157,7 +158,7 @@ class Slipnode(object): self.activation = min(self.activation, 100) self.activation = max(self.activation, 0) - def can_jump(): + def can_jump(self): if self.activation <= jump_threshold(): return False if self.clamped: diff --git a/copycat/workspaceFormulas.py b/copycat/workspaceFormulas.py index 799c7f1..74cd8b5 100644 --- a/copycat/workspaceFormulas.py +++ b/copycat/workspaceFormulas.py @@ -18,14 +18,16 @@ class WorkspaceFormulas(object): workspace.rule.updateStrength() ruleWeakness = 100.0 - workspace.rule.totalStrength values = ((workspace.totalUnhappiness, 0.8), (ruleWeakness, 0.2)) - slightly_above_actual_temperature = formulas.actualTemperature + 0.001 - logging.info('actualTemperature: %f' % slightly_above_actual_temperature) + above_actual_temperature = formulas.actualTemperature + 0.001 + logging.info('actualTemperature: %f', above_actual_temperature) formulas.actualTemperature = formulas.weightedAverage(values) - logging.info('unhappiness: %f, weakness: %f, actualTemperature: %f' % ( - workspace.totalUnhappiness + 0.001, ruleWeakness + 0.001, formulas.actualTemperature + 0.001)) + logging.info('unhappiness: %f, weakness: %f, actualTemperature: %f', + workspace.totalUnhappiness + 0.001, ruleWeakness + 0.001, + formulas.actualTemperature + 0.001) if temperature.clamped: formulas.actualTemperature = 100.0 - logging.info('actualTemperature: %f' % (formulas.actualTemperature + 0.001)) + logging.info('actualTemperature: %f', + formulas.actualTemperature + 0.001) temperature.update(formulas.actualTemperature) if not self.clampTemperature: formulas.Temperature = formulas.actualTemperature @@ -70,46 +72,49 @@ def __chooseLeftNeighbor(source): for o in workspace.objects: if o.string == source.string: if source.leftIndex == o.rightIndex + 1: - logging.info('%s is on left of %s' % (o, source)) + logging.info('%s is on left of %s', o, source) objects += [o] else: - logging.info('%s is not on left of %s' % (o, source)) - logging.info('Number of left objects: %s' % len(objects)) + logging.info('%s is not on left of %s', o, source) + logging.info('Number of left objects: %s', len(objects)) return formulas.chooseObjectFromList(objects, 'intraStringSalience') def __chooseRightNeighbor(source): - objects = [o for o in workspace.objects if - o.string == source.string and - o.leftIndex == source.rightIndex + 1 - ] + objects = [o for o in workspace.objects + if o.string == source.string + and o.leftIndex == source.rightIndex + 1] return formulas.chooseObjectFromList(objects, 'intraStringSalience') def chooseBondFacet(source, destination): - sourceFacets = [d.descriptionType for d in source.descriptions if d.descriptionType in slipnet.bondFacets] - bondFacets = [d.descriptionType for d in destination.descriptions if d.descriptionType in sourceFacets] + sourceFacets = [d.descriptionType for d in source.descriptions + if d.descriptionType in slipnet.bondFacets] + bondFacets = [d.descriptionType for d in destination.descriptions + if d.descriptionType in sourceFacets] if not bondFacets: return None - supports = [__supportForDescriptionType(f, source.string) for f in bondFacets] + supports = [__supportForDescriptionType(f, source.string) + for f in bondFacets] i = formulas.selectListPosition(supports) return bondFacets[i] def __supportForDescriptionType(descriptionType, string): - return (descriptionType.activation + __descriptionTypeSupport(descriptionType, string)) / 2 + string_support = __descriptionTypeSupport(descriptionType, string) + return (descriptionType.activation + string_support) / 2 def __descriptionTypeSupport(descriptionType, string): - """The proportion of objects in the string that have a description with this descriptionType""" - numberOfObjects = totalNumberOfObjects = 0.0 + """The proportion of objects in the string with this descriptionType""" + described_count = total = 0 for objekt in workspace.objects: if objekt.string == string: - totalNumberOfObjects += 1.0 + total += 1 for description in objekt.descriptions: if description.descriptionType == descriptionType: - numberOfObjects += 1.0 - return numberOfObjects / totalNumberOfObjects + described_count += 1 + return described_count / float(total) def probabilityOfPosting(codeletName): @@ -139,9 +144,7 @@ def probabilityOfPosting(codeletName): def howManyToPost(codeletName): - if codeletName == 'breaker': - return 1 - if 'description' in codeletName: + if codeletName == 'breaker' or 'description' in codeletName: return 1 if 'translator' in codeletName: if not workspace.rule: @@ -156,7 +159,6 @@ def howManyToPost(codeletName): number = 0 if 'bond' in codeletName: number = workspace.numberOfUnrelatedObjects() -# print 'post number of unrelated: %d, objects: %d' % (number,len(workspace.objects)) if 'group' in codeletName: number = workspace.numberOfUngroupedObjects() if 'replacement' in codeletName: diff --git a/copycat/workspaceObject.py b/copycat/workspaceObject.py index 59a1335..59a489f 100644 --- a/copycat/workspaceObject.py +++ b/copycat/workspaceObject.py @@ -5,7 +5,20 @@ from slipnet import slipnet from workspaceStructure import WorkspaceStructure +def distinguishingDescriptor(descriptor): + """Whether no other object of the same type has the same descriptor""" + if descriptor == slipnet.letter: + return False + if descriptor == slipnet.group: + return False + for number in slipnet.numbers: + if number == descriptor: + return False + return True + + class WorkspaceObject(WorkspaceStructure): + # pylint: disable=too-many-instance-attributes def __init__(self, workspaceString): WorkspaceStructure.__init__(self) self.string = workspaceString @@ -45,13 +58,13 @@ class WorkspaceObject(WorkspaceStructure): def addDescription(self, descriptionType, descriptor): description = Description(self, descriptionType, descriptor) - logging.info("Adding description: %s to %s" % (description, self)) + logging.info("Adding description: %s to %s", description, self) self.descriptions += [description] def addDescriptions(self, descriptions): copy = descriptions[:] # in case we add to our own descriptions for description in copy: - logging.info('might add: %s' % description) + logging.info('might add: %s', description) if not self.containsDescription(description): self.addDescription(description.descriptionType, description.descriptor) @@ -69,7 +82,7 @@ class WorkspaceObject(WorkspaceStructure): for bond in self.bonds: bondStrength += bond.totalStrength divisor = 6.0 - if self.spansString(): # XXX then we have already returned + if self.spansString(): # then we have already returned divisor = 3.0 return bondStrength / divisor @@ -98,7 +111,6 @@ class WorkspaceObject(WorkspaceStructure): if self.correspondence: interStringHappiness = self.correspondence.totalStrength self.interStringUnhappiness = 100.0 - interStringHappiness - #logging.info("Unhappy: %s"%self.interStringUnhappiness) averageHappiness = (intraStringHappiness + interStringHappiness) / 2 self.totalUnhappiness = 100.0 - averageHappiness @@ -116,9 +128,9 @@ class WorkspaceObject(WorkspaceStructure): (self.interStringUnhappiness, 0.2))) self.totalSalience = (self.intraStringSalience + self.interStringSalience) / 2.0 - logging.info('Set salience of %s to %f = (%f + %f)/2' % ( - self.__str__(), self.totalSalience, - self.intraStringSalience, self.interStringSalience)) + logging.info('Set salience of %s to %f = (%f + %f)/2', + self.__str__(), self.totalSalience, + self.intraStringSalience, self.interStringSalience) def isWithin(self, other): return (self.leftIndex >= other.leftIndex and @@ -128,11 +140,8 @@ class WorkspaceObject(WorkspaceStructure): return [d for d in self.descriptions if d.descriptionType.fully_active()] - def morePossibleDescriptions(self, node): - return [] - def getPossibleDescriptions(self, descriptionType): - logging.info('getting possible descriptions for %s' % self) + logging.info('getting possible descriptions for %s', self) descriptions = [] from group import Group for link in descriptionType.instanceLinks: @@ -168,7 +177,7 @@ class WorkspaceObject(WorkspaceStructure): return bool([d for d in self.descriptions if d.descriptor == slipnode]) def middleObject(self): - # XXX only works if string is 3 chars long + # only works if string is 3 chars long # as we have access to the string, why not just " == len / 2" ? objectOnMyRightIsRightmost = objectOnMyLeftIsLeftmost = False for objekt in self.string.objects: @@ -178,29 +187,18 @@ class WorkspaceObject(WorkspaceStructure): objectOnMyRightIsRightmost = True return objectOnMyRightIsRightmost and objectOnMyLeftIsLeftmost - def distinguishingDescriptor(self, descriptor): - """Whether no other object of the same type has the same descriptor""" - if descriptor == slipnet.letter: - return False - if descriptor == slipnet.group: - return False - for number in slipnet.numbers: - if number == descriptor: - return False - return True - def relevantDistinguishingDescriptors(self): return [d.descriptor for d in self.relevantDescriptions() - if self.distinguishingDescriptor(d.descriptor)] + if distinguishingDescriptor(d.descriptor)] def getDescriptor(self, descriptionType): """The description attached to this object of the description type.""" descriptor = None - logging.info("\nIn %s, trying for type: %s" % ( - self, descriptionType.get_name())) + logging.info("\nIn %s, trying for type: %s", + self, descriptionType.get_name()) for description in self.descriptions: - logging.info("Trying description: %s" % description) + logging.info("Trying description: %s", description) if description.descriptionType == descriptionType: return description.descriptor return descriptor