Preparing for refactor...

This commit is contained in:
2017-09-26 22:47:09 -03:00
parent 7ff0488861
commit 27bbc6118e
4 changed files with 44 additions and 10 deletions

View File

@ -83,7 +83,7 @@ class Coderack(object):
if 'correspondence' in codeletName: if 'correspondence' in codeletName:
return workspace.interStringUnhappiness / 100.0 return workspace.interStringUnhappiness / 100.0
if 'description' in codeletName: if 'description' in codeletName:
#TODO: use entropy # TODO: use entropy
return (temperature.value() / 100.0) ** 2 return (temperature.value() / 100.0) ** 2
return workspace.intraStringUnhappiness / 100.0 return workspace.intraStringUnhappiness / 100.0
@ -163,7 +163,7 @@ class Coderack(object):
if codeletName == 'breaker': if codeletName == 'breaker':
urgency = 1 urgency = 1
#TODO: use entropy # TODO: use entropy
if temperature.value() < 25.0 and 'translator' in codeletName: if temperature.value() < 25.0 and 'translator' in codeletName:
urgency = 5 urgency = 5
for _ in range(howMany): for _ in range(howMany):
@ -290,8 +290,8 @@ class Coderack(object):
random = self.ctx.random random = self.ctx.random
temperature = self.ctx.temperature temperature = self.ctx.temperature
assert self.codelets assert self.codelets
#TODO: use entropy # TODO: use entropy
scale = (100.0 - temperature.value() + 10.0) / 15.0 scale = (100.0 - temperature.value() + 10.0) / 15.0
chosen = random.weighted_choice(self.codelets, [codelet.urgency ** scale for codelet in self.codelets]) chosen = random.weighted_choice(self.codelets, [codelet.urgency ** scale for codelet in self.codelets])
self.removeCodelet(chosen) self.removeCodelet(chosen)

View File

@ -40,6 +40,16 @@ class Workspace(object):
self.modified = WorkspaceString(self.ctx, self.modifiedString) self.modified = WorkspaceString(self.ctx, self.modifiedString)
self.target = WorkspaceString(self.ctx, self.targetString) self.target = WorkspaceString(self.ctx, self.targetString)
'''
# TODO: Initial part of refactoring in this method
def getAssessedUnhappiness(self, unhappiness):
o.Unhappiness = __adjustUnhappiness(
o.relativeImportance * o.Unhappiness
for o in self.objects)
pass
'''
# TODO: Extract method?
def assessUnhappiness(self): def assessUnhappiness(self):
self.intraStringUnhappiness = __adjustUnhappiness( self.intraStringUnhappiness = __adjustUnhappiness(
o.relativeImportance * o.intraStringUnhappiness o.relativeImportance * o.intraStringUnhappiness
@ -51,6 +61,7 @@ class Workspace(object):
o.relativeImportance * o.totalUnhappiness o.relativeImportance * o.totalUnhappiness
for o in self.objects) for o in self.objects)
# TODO: these 3 methods seem to be the same... are they? If so, Extract method.
def calculateIntraStringUnhappiness(self): def calculateIntraStringUnhappiness(self):
value = sum( value = sum(
o.relativeImportance * o.intraStringUnhappiness o.relativeImportance * o.intraStringUnhappiness
@ -82,7 +93,7 @@ class Workspace(object):
self.initial.updateIntraStringUnhappiness() self.initial.updateIntraStringUnhappiness()
self.target.updateIntraStringUnhappiness() self.target.updateIntraStringUnhappiness()
#TODO: use entropy # TODO: use entropy
def getUpdatedTemperature(self): def getUpdatedTemperature(self):
self.calculateIntraStringUnhappiness() self.calculateIntraStringUnhappiness()
self.calculateInterStringUnhappiness() self.calculateInterStringUnhappiness()
@ -98,7 +109,7 @@ class Workspace(object):
)) ))
def numberOfUnrelatedObjects(self): def numberOfUnrelatedObjects(self):
"""A list of all objects in the workspace with >= 1 open bond slots""" """Computes the number of all objects in the workspace with >= 1 open bond slots."""
objects = [o for o in self.objects objects = [o for o in self.objects
if o.string == self.initial or o.string == self.target] if o.string == self.initial or o.string == self.target]
objects = [o for o in objects if not o.spansString()] objects = [o for o in objects if not o.spansString()]
@ -116,21 +127,21 @@ class Workspace(object):
return len(objects) return len(objects)
def numberOfUnreplacedObjects(self): def numberOfUnreplacedObjects(self):
"""A list of all unreplaced objects in the initial string""" """A list of all unreplaced objects in the initial string."""
objects = [o for o in self.objects objects = [o for o in self.objects
if o.string == self.initial and isinstance(o, Letter)] if o.string == self.initial and isinstance(o, Letter)]
objects = [o for o in objects if not o.replacement] objects = [o for o in objects if not o.replacement]
return len(objects) return len(objects)
def numberOfUncorrespondingObjects(self): def numberOfUncorrespondingObjects(self):
"""A list of all uncorresponded objects in the initial string""" """A list of all uncorresponded objects in the initial string."""
objects = [o for o in self.objects objects = [o for o in self.objects
if o.string == self.initial or o.string == self.target] if o.string == self.initial or o.string == self.target]
objects = [o for o in objects if not o.correspondence] objects = [o for o in objects if not o.correspondence]
return len(objects) return len(objects)
def numberOfBonds(self): def numberOfBonds(self):
"""The number of bonds in the workspace""" """The number of bonds in the workspace."""
return sum(1 for o in self.structures if isinstance(o, Bond)) return sum(1 for o in self.structures if isinstance(o, Bond))
def correspondences(self): def correspondences(self):

View File

@ -38,7 +38,7 @@ class WorkspaceString(object):
return self.string[i] return self.string[i]
def updateRelativeImportance(self): def updateRelativeImportance(self):
"""Update the normalised importance of all objects in the string""" """Update the normalised importance of all objects in the string."""
total = sum(o.rawImportance for o in self.objects) total = sum(o.rawImportance for o in self.objects)
if not total: if not total:
for o in self.objects: for o in self.objects:

23
main.py
View File

@ -1,4 +1,27 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""
Main Copycat program.
To run it, type at the terminal:
> python main.py abc abd ppqqrr --interations 10
The script takes three to five arguments. The first two are a pair of strings
with some change, for example "abc" and "abd". The third is a string which the
script should try to change analogously. The fourth (which defaults to "1") is
a number of iterations. One can also specify a defined seed falue for the
random number generator.
The above might produce output such as
ppqqss: 6 (avg time 869.0, avg temp 23.4)
ppqqrs: 4 (avg time 439.0, avg temp 37.3)
The first number indicates how many times Copycat chose that string as its
answer; higher means "more obvious". The last number indicates the average
final temperature of the workspace; lower means "more elegant".
"""
import argparse import argparse
import logging import logging