diff --git a/copycat.log b/copycat.log new file mode 100644 index 0000000..945ec05 --- /dev/null +++ b/copycat.log @@ -0,0 +1,63 @@ +object chosen = j from target string +destination: k +chosen bond facet: letterCategory +Source: j, destination: k +source descriptor: J +destination descriptor: K +proposing successor bond +urgency: 100.0, number: 1, bin: 7 +object chosen = j from target string +destination: i +chosen bond facet: letterCategory +Source: j, destination: i +source descriptor: J +destination descriptor: I +proposing predecessor bond +object chosen = successor bond between j and k from other string +bond strength = 48 for successor bond between j and k +object chosen = a from initial string +destination: b +chosen bond facet: letterCategory +Source: a, destination: b +source descriptor: A +destination descriptor: B +proposing successor bond +object chosen = successor bond between a and b from other string +bond strength = 48 for successor bond between a and b +succeeded: posting bond-builder +object chosen = successor bond between a and b from other string +number of incompatibleBonds: 0 +no incompatible bonds +no incompatible groups +building bond successor bond between a and b +object chosen = a from initial string +destination: b +chosen bond facet: letterCategory +Source: a, destination: b +source descriptor: A +destination descriptor: B +proposing successor bond +object chosen = a from initial string +destination: b +chosen bond facet: letterCategory +Source: a, destination: b +source descriptor: A +destination descriptor: B +proposing successor bond +Post top down: top-down-description-scout, with urgency: 5 +posting bottom up codelets +object chosen = a from initial string +object chosen = j from target string +destination: i +chosen bond facet: letterCategory +Source: j, destination: i +source descriptor: J +destination descriptor: I +proposing predecessor bond +object chosen = a from initial string +destination: b +chosen bond facet: letterCategory +Source: a, destination: b +source descriptor: A +destination descriptor: B +proposing successor bond diff --git a/copycat/__init__.py b/copycat/__init__.py index 7d25160..67e5cc9 100644 --- a/copycat/__init__.py +++ b/copycat/__init__.py @@ -1 +1 @@ -from copycat import Copycat, Reporter # noqa +from .copycat import Copycat, Reporter # noqa diff --git a/copycat/bond.py b/copycat/bond.py index d88e664..bf6e004 100644 --- a/copycat/bond.py +++ b/copycat/bond.py @@ -1,4 +1,4 @@ -from workspaceStructure import WorkspaceStructure +from .workspaceStructure import WorkspaceStructure class Bond(WorkspaceStructure): diff --git a/copycat/codeletMethods.py b/copycat/codeletMethods.py index 5cc09b1..dad3924 100644 --- a/copycat/codeletMethods.py +++ b/copycat/codeletMethods.py @@ -1,16 +1,16 @@ import inspect import logging -import formulas -from workspaceFormulas import chooseDirectedNeighbor -from workspaceFormulas import chooseNeighbor -from workspaceFormulas import chooseUnmodifiedObject -from workspaceObject import WorkspaceObject -from letter import Letter -from replacement import Replacement -from group import Group -from bond import Bond -from correspondence import Correspondence +from . import formulas +from .workspaceFormulas import chooseDirectedNeighbor +from .workspaceFormulas import chooseNeighbor +from .workspaceFormulas import chooseUnmodifiedObject +from .workspaceObject import WorkspaceObject +from .letter import Letter +from .replacement import Replacement +from .group import Group +from .bond import Bond +from .correspondence import Correspondence def codelet(name): @@ -804,7 +804,7 @@ def group_builder(ctx, codelet): incompatible.break_the_structure() # create new bonds group.bondList = [] - for i in xrange(1, len(group.objectList)): + for i in range(1, len(group.objectList)): object1 = group.objectList[i - 1] object2 = group.objectList[i] if not object1.rightBond: @@ -871,7 +871,7 @@ def rule_translator(ctx, codelet): bondDensity = numberOfBonds / nearlyTotalLength bondDensity = min(bondDensity, 1.0) weights = __getCutoffWeights(bondDensity) - cutoff = 10.0 * random.weighted_choice(range(1, 11), weights) + cutoff = 10.0 * random.weighted_choice(list(range(1, 11)), weights) if cutoff >= temperature.actual_value: result = workspace.rule.buildTranslatedRule() if result is not None: diff --git a/copycat/coderack.py b/copycat/coderack.py index cad5360..fb58e2a 100644 --- a/copycat/coderack.py +++ b/copycat/coderack.py @@ -1,13 +1,13 @@ import math import logging -import codeletMethods -from bond import Bond -from codelet import Codelet -from correspondence import Correspondence -from description import Description -from group import Group -from rule import Rule +from . import codeletMethods +from .bond import Bond +from .codelet import Codelet +from .correspondence import Correspondence +from .description import Description +from .group import Group +from .rule import Rule NUMBER_OF_BINS = 7 @@ -131,7 +131,7 @@ class Coderack(object): for codeletName in node.codelets: probability = self.probabilityOfPosting(codeletName) howMany = self.howManyToPost(codeletName) - for _ in xrange(howMany): + for _ in range(howMany): if not random.coinFlip(probability): continue urgency = getUrgencyBin( @@ -163,7 +163,7 @@ class Coderack(object): urgency = 1 if temperature.value() < 25.0 and 'translator' in codeletName: urgency = 5 - for _ in xrange(howMany): + for _ in range(howMany): if random.coinFlip(probability): codelet = Codelet(codeletName, urgency, [], self.codeletsRun) self.post(codelet) @@ -272,7 +272,7 @@ class Coderack(object): ('bottom-up-correspondence-scout', 2 * n), ] for name, count in codeletsToPost: - for _ in xrange(count): + for _ in range(count): codelet = Codelet(name, 1, [], self.codeletsRun) self.post(codelet) diff --git a/copycat/copycat.py b/copycat/copycat.py index aa96d47..fc400b8 100644 --- a/copycat/copycat.py +++ b/copycat/copycat.py @@ -1,8 +1,8 @@ -from coderack import Coderack -from randomness import Randomness -from slipnet import Slipnet -from temperature import Temperature -from workspace import Workspace +from .coderack import Coderack +from .randomness import Randomness +from .slipnet import Slipnet +from .temperature import Temperature +from .workspace import Workspace class Reporter(object): @@ -69,7 +69,7 @@ class Copycat(object): def run(self, initial, modified, target, iterations): self.workspace.resetWithStrings(initial, modified, target) answers = {} - for i in xrange(iterations): + for i in range(iterations): answer = self.runTrial() d = answers.setdefault(answer['answer'], { 'count': 0, @@ -80,7 +80,7 @@ class Copycat(object): d['sumtemp'] += answer['temp'] d['sumtime'] += answer['time'] - for answer, d in answers.iteritems(): + for answer, d in answers.items(): d['avgtemp'] = d.pop('sumtemp') / d['count'] d['avgtime'] = d.pop('sumtime') / d['count'] return answers diff --git a/copycat/correspondence.py b/copycat/correspondence.py index 8c6b422..0a3e2d2 100644 --- a/copycat/correspondence.py +++ b/copycat/correspondence.py @@ -1,8 +1,8 @@ -from conceptMapping import ConceptMapping -from group import Group -from letter import Letter -from workspaceStructure import WorkspaceStructure -import formulas +from .conceptMapping import ConceptMapping +from .group import Group +from .letter import Letter +from .workspaceStructure import WorkspaceStructure +from . import formulas class Correspondence(WorkspaceStructure): @@ -143,8 +143,8 @@ class Correspondence(WorkspaceStructure): def internallyCoherent(self): """Whether any pair of distinguishing mappings support each other""" mappings = self.relevantDistinguishingConceptMappings() - for i in xrange(len(mappings)): - for j in xrange(len(mappings)): + for i in range(len(mappings)): + for j in range(len(mappings)): if i != j: if mappings[i].supports(mappings[j]): return True diff --git a/copycat/curses_reporter.py b/copycat/curses_reporter.py index b2f7bf8..08f24db 100644 --- a/copycat/curses_reporter.py +++ b/copycat/curses_reporter.py @@ -1,13 +1,13 @@ import curses import time -from copycat import Reporter -from bond import Bond -from correspondence import Correspondence -from description import Description -from group import Group -from letter import Letter -from rule import Rule +from .copycat import Reporter +from .bond import Bond +from .correspondence import Correspondence +from .description import Description +from .group import Group +from .letter import Letter +from .rule import Rule class SafeSubwindow(object): @@ -122,7 +122,7 @@ class CursesReporter(Reporter): d['answer'], d['count'], d['avgtime'], d['avgtemp'], ) - answersToPrint = sorted(self.answers.itervalues(), key=fitness, reverse=True) + answersToPrint = sorted(iter(self.answers.values()), key=fitness, reverse=True) w = self.answersWindow pageWidth = w.getmaxyx()[1] @@ -175,7 +175,7 @@ class CursesReporter(Reporter): # Sort the most common and highest-urgency codelets to the top. entries = sorted( (count, key[0], key[1]) - for key, count in counts.iteritems() + for key, count in counts.items() ) # Figure out how we'd like to render each codelet's name. @@ -193,10 +193,10 @@ class CursesReporter(Reporter): w.erase() for u, string in printable_entries: # Find the highest point on the page where we could place this entry. - start_column = (u - 1) * columnWidth + start_column = int((u - 1) * columnWidth) end_column = start_column + len(string) for r in range(pageHeight): - if all(w.is_vacant(r, c) for c in xrange(start_column, end_column+20)): + if all(w.is_vacant(r, c) for c in range(start_column, end_column+20)): w.addstr(r, start_column, string) break w.refresh() @@ -308,7 +308,7 @@ class CursesReporter(Reporter): else: w.addstr(firstrow, column, '\\', curses.A_NORMAL) w.addstr(lastrow, column, '/', curses.A_NORMAL) - for r in xrange(firstrow + 1, lastrow): + for r in range(firstrow + 1, lastrow): w.addstr(r, column, '|', curses.A_NORMAL) def report_workspace(self, workspace): @@ -410,12 +410,12 @@ class CursesReporter(Reporter): end = endrow_for_group[group] # Place this group's graphical depiction. depiction_width = 3 + self.length_of_workspace_object_depiction(group, description_structures) - for firstcolumn in xrange(max_column, 1000): + for firstcolumn in range(max_column, 1000): lastcolumn = firstcolumn + depiction_width okay = all( w.is_vacant(r, c) - for c in xrange(firstcolumn, lastcolumn + 1) - for r in xrange(start, end + 1) + for c in range(firstcolumn, lastcolumn + 1) + for r in range(start, end + 1) ) if okay: self.depict_grouping_brace(w, start, end, firstcolumn + 1) diff --git a/copycat/description.py b/copycat/description.py index 1ee7365..ab81347 100644 --- a/copycat/description.py +++ b/copycat/description.py @@ -1,4 +1,4 @@ -from workspaceStructure import WorkspaceStructure +from .workspaceStructure import WorkspaceStructure class Description(WorkspaceStructure): diff --git a/copycat/formulas.py b/copycat/formulas.py index 8df8691..195cccc 100644 --- a/copycat/formulas.py +++ b/copycat/formulas.py @@ -1,4 +1,4 @@ -from conceptMapping import ConceptMapping +from .conceptMapping import ConceptMapping def weightedAverage(values): diff --git a/copycat/group.py b/copycat/group.py index 58659bb..015dae3 100644 --- a/copycat/group.py +++ b/copycat/group.py @@ -1,6 +1,6 @@ -from description import Description -from workspaceObject import WorkspaceObject -import formulas +from .description import Description +from .workspaceObject import WorkspaceObject +from . import formulas class Group(WorkspaceObject): diff --git a/copycat/letter.py b/copycat/letter.py index 624c222..36eaaf5 100644 --- a/copycat/letter.py +++ b/copycat/letter.py @@ -1,4 +1,4 @@ -from workspaceObject import WorkspaceObject +from .workspaceObject import WorkspaceObject class Letter(WorkspaceObject): diff --git a/copycat/replacement.py b/copycat/replacement.py index 690b131..0d4d094 100644 --- a/copycat/replacement.py +++ b/copycat/replacement.py @@ -1,4 +1,4 @@ -from workspaceStructure import WorkspaceStructure +from .workspaceStructure import WorkspaceStructure class Replacement(WorkspaceStructure): diff --git a/copycat/rule.py b/copycat/rule.py index bc8526a..b821528 100644 --- a/copycat/rule.py +++ b/copycat/rule.py @@ -1,8 +1,8 @@ import logging -from workspaceStructure import WorkspaceStructure -import formulas +from .workspaceStructure import WorkspaceStructure +from . import formulas class Rule(WorkspaceStructure): diff --git a/copycat/slipnet.py b/copycat/slipnet.py index bc7801c..db0b040 100644 --- a/copycat/slipnet.py +++ b/copycat/slipnet.py @@ -1,5 +1,5 @@ -from slipnode import Slipnode -from sliplink import Sliplink +from .slipnode import Slipnode +from .sliplink import Sliplink class Slipnet(object): diff --git a/copycat/tests.py b/copycat/tests.py index 731c2b6..7556f4a 100644 --- a/copycat/tests.py +++ b/copycat/tests.py @@ -1,6 +1,6 @@ import unittest -from copycat import Copycat +from .copycat import Copycat def pnormaldist(p): @@ -20,7 +20,7 @@ def pnormaldist(p): 0.99999999: 5.7307, 0.999999999: 6.1094, } - return max(v for k, v in table.iteritems() if k <= p) + return max(v for k, v in table.items() if k <= p) def lower_bound_on_probability(hits, attempts, confidence=0.95): @@ -44,11 +44,11 @@ class TestCopycat(unittest.TestCase): self.longMessage = True # new in Python 2.7 def assertProbabilitiesLookRoughlyLike(self, actual, expected): - actual_count = 0.0 + sum(d['count'] for d in actual.values()) - expected_count = 0.0 + sum(d['count'] for d in expected.values()) + actual_count = 0.0 + sum(d['count'] for d in list(actual.values())) + expected_count = 0.0 + sum(d['count'] for d in list(expected.values())) self.assertGreater(actual_count, 1) self.assertGreater(expected_count, 1) - for k in set(actual.keys() + expected.keys()): + for k in set(list(actual.keys()) + list(expected.keys())): if k not in expected: self.fail('Key %s was produced but not expected! %r != %r' % (k, actual, expected)) expected_probability = expected[k]['count'] / expected_count @@ -56,10 +56,10 @@ class TestCopycat(unittest.TestCase): actual_lo = lower_bound_on_probability(actual[k]['count'], actual_count) actual_hi = upper_bound_on_probability(actual[k]['count'], actual_count) if not (actual_lo <= expected_probability <= actual_hi): - print 'Failed (%s <= %s <= %s)' % (actual_lo, expected_probability, actual_hi) + print('Failed (%s <= %s <= %s)' % (actual_lo, expected_probability, actual_hi)) self.fail('Count ("obviousness" metric) seems way off! %r != %r' % (actual, expected)) if abs(actual[k]['avgtemp'] - expected[k]['avgtemp']) >= 10.0 + (10.0 / actual[k]['count']): - print 'Failed (%s - %s >= %s)' % (actual[k]['avgtemp'], expected[k]['avgtemp'], 10.0 + (10.0 / actual[k]['count'])) + print('Failed (%s - %s >= %s)' % (actual[k]['avgtemp'], expected[k]['avgtemp'], 10.0 + (10.0 / actual[k]['count']))) self.fail('Temperature ("elegance" metric) seems way off! %r != %r' % (actual, expected)) else: actual_hi = upper_bound_on_probability(0, actual_count) @@ -68,7 +68,7 @@ class TestCopycat(unittest.TestCase): def run_testcase(self, initial, modified, target, iterations, expected): actual = Copycat().run(initial, modified, target, iterations) - self.assertEqual(sum(a['count'] for a in actual.values()), iterations) + self.assertEqual(sum(a['count'] for a in list(actual.values())), iterations) self.assertProbabilitiesLookRoughlyLike(actual, expected) def test_simple_cases(self): diff --git a/copycat/workspace.py b/copycat/workspace.py index 024bb9b..3e5228a 100644 --- a/copycat/workspace.py +++ b/copycat/workspace.py @@ -1,8 +1,8 @@ -import formulas -from bond import Bond -from correspondence import Correspondence -from letter import Letter -from workspaceString import WorkspaceString +from . import formulas +from .bond import Bond +from .correspondence import Correspondence +from .letter import Letter +from .workspaceString import WorkspaceString def __adjustUnhappiness(values): diff --git a/copycat/workspaceObject.py b/copycat/workspaceObject.py index e0d0fdd..e641cea 100644 --- a/copycat/workspaceObject.py +++ b/copycat/workspaceObject.py @@ -1,6 +1,6 @@ -from description import Description -from formulas import weightedAverage -from workspaceStructure import WorkspaceStructure +from .description import Description +from .formulas import weightedAverage +from .workspaceStructure import WorkspaceStructure class WorkspaceObject(WorkspaceStructure): @@ -109,7 +109,7 @@ class WorkspaceObject(WorkspaceStructure): if d.descriptionType.fully_active()] def getPossibleDescriptions(self, descriptionType): - from group import Group # gross, TODO FIXME + from .group import Group # gross, TODO FIXME slipnet = self.ctx.slipnet descriptions = [] for link in descriptionType.instanceLinks: diff --git a/copycat/workspaceString.py b/copycat/workspaceString.py index 1893f7f..2d7a149 100644 --- a/copycat/workspaceString.py +++ b/copycat/workspaceString.py @@ -1,5 +1,5 @@ -from group import Group -from letter import Letter +from .group import Group +from .letter import Letter class WorkspaceString(object): diff --git a/copycat/workspaceStructure.py b/copycat/workspaceStructure.py index 5eda308..2832202 100644 --- a/copycat/workspaceStructure.py +++ b/copycat/workspaceStructure.py @@ -1,4 +1,4 @@ -import formulas +from . import formulas class WorkspaceStructure(object): diff --git a/copycat/curses_main.py b/curses_main.py old mode 100644 new mode 100755 similarity index 94% rename from copycat/curses_main.py rename to curses_main.py index 8a50d71..2779c32 --- a/copycat/curses_main.py +++ b/curses_main.py @@ -1,9 +1,10 @@ +#!/usr/bin/env python3 import argparse import curses import logging from copycat import Copycat -from curses_reporter import CursesReporter +from copycat.curses_reporter import CursesReporter if __name__ == '__main__': diff --git a/copycat/main.py b/main.py old mode 100644 new mode 100755 similarity index 76% rename from copycat/main.py rename to main.py index 27ab66c..8673d0d --- a/copycat/main.py +++ b/main.py @@ -1,17 +1,16 @@ +#!/usr/bin/env python3 import argparse import logging from copycat import Copycat, Reporter - class SimpleReporter(Reporter): def report_answer(self, answer): - print 'Answered %s (time %d, final temperature %.1f)' % ( + print('Answered %s (time %d, final temperature %.1f)' % ( answer['answer'], answer['time'], answer['temp'], - ) + )) - -if __name__ == '__main__': +def main(): logging.basicConfig(level=logging.INFO, format='%(message)s', filename='./copycat.log', filemode='w') parser = argparse.ArgumentParser() @@ -25,5 +24,8 @@ if __name__ == '__main__': copycat = Copycat(reporter=SimpleReporter(), rng_seed=options.seed) answers = copycat.run(options.initial, options.modified, options.target, options.iterations) - for answer, d in sorted(answers.iteritems(), key=lambda kv: kv[1]['avgtemp']): - print '%s: %d (avg time %.1f, avg temp %.1f)' % (answer, d['count'], d['avgtime'], d['avgtemp']) + for answer, d in sorted(iter(answers.items()), key=lambda kv: kv[1]['avgtemp']): + print('%s: %d (avg time %.1f, avg temp %.1f)' % (answer, d['count'], d['avgtime'], d['avgtemp'])) + +if __name__ == '__main__': + main()