Python 3 fixes

This commit is contained in:
cclauss
2018-10-17 01:48:46 +02:00
parent 1697ee1c43
commit 6a8e87e17b
13 changed files with 140 additions and 116 deletions

View File

@@ -38,13 +38,13 @@ differences between docex and doctest are:
writing "1+1==2 ==> True" and having it work in versions of Python writing "1+1==2 ==> True" and having it work in versions of Python
where True prints as "1" rather than as "True", and so on, where True prints as "1" rather than as "True", and so on,
but doctest has the edge if you want to compare against something but doctest has the edge if you want to compare against something
that doesn't have an eval-able output, or if you want to test that doesn't have an eval-able output, or if you want to test
printed output. printed output.
(4) Doctest has many more features, and is better supported. (4) Doctest has many more features, and is better supported.
I wrote docex before doctest was an official part of Python, but I wrote docex before doctest was an official part of Python, but
with the refactoring of doctest in Python 2.4, I decided to switch with the refactoring of doctest in Python 2.4, I decided to switch
my code over to doctest, even though I prefer the brevity of docex. my code over to doctest, even though I prefer the brevity of docex.
I still offer docex for those who want it. I still offer docex for those who want it.
From Python, when you want to test modules m1, m2, ... do: From Python, when you want to test modules m1, m2, ... do:
@@ -70,8 +70,9 @@ one of the following formats:
First y is evaled to yield an exception type, then x is execed. First y is evaled to yield an exception type, then x is execed.
If x doesn't raise the right exception, an error msg is printed. If x doesn't raise the right exception, an error msg is printed.
(5) Of the form 'statement'. Statement is execed for side effect. (5) Of the form 'statement'. Statement is execed for side effect.
(6) Of the form 'expression'. Expression is evaled for side effect. (6) Of the form 'expression'. Expression is evaled for side effect.
""" """
from __future__ import print_function
import re, sys, types import re, sys, types
@@ -96,9 +97,9 @@ class Docex:
if out: if out:
sys.stdout = sys.__stdout__ sys.stdout = sys.__stdout__
out.close() out.close()
def __repr__(self): def __repr__(self):
if self.failed: if self.failed:
return ('<Test: #### failed %d, passed %d>' return ('<Test: #### failed %d, passed %d>'
% (self.failed, self.passed)) % (self.failed, self.passed))
else: else:
@@ -141,8 +142,8 @@ class Docex:
match = search(s) match = search(s)
if match: self.run_string(s[match.end():]) if match: self.run_string(s[match.end():])
if hasattr(object, '_docex'): if hasattr(object, '_docex'):
self.run_string(object._docex) self.run_string(object._docex)
def run_string(self, teststr): def run_string(self, teststr):
"""Run a test string, printing inputs and results.""" """Run a test string, printing inputs and results."""
if not teststr: return if not teststr: return
@@ -163,7 +164,7 @@ class Docex:
try: try:
self.evaluate(teststr) self.evaluate(teststr)
except SyntaxError: except SyntaxError:
exec teststr in self.dictionary exec(teststr, self.dictionary)
def evaluate(self, teststr, resultstr=None): def evaluate(self, teststr, resultstr=None):
"Eval teststr and check if resultstr (if given) evals to the same." "Eval teststr and check if resultstr (if given) evals to the same."
@@ -172,18 +173,18 @@ class Docex:
self.dictionary['_'] = result self.dictionary['_'] = result
self.writeln(repr(result)) self.writeln(repr(result))
if resultstr == None: if resultstr == None:
return return
elif result == eval(resultstr, self.dictionary): elif result == eval(resultstr, self.dictionary):
self.passed += 1 self.passed += 1
else: else:
self.fail(teststr, resultstr) self.fail(teststr, resultstr)
def raises(self, teststr, exceptionstr): def raises(self, teststr, exceptionstr):
teststr = teststr.strip() teststr = teststr.strip()
self.writeln('>>> ' + teststr) self.writeln('>>> ' + teststr)
except_class = eval(exceptionstr, self.dictionary) except_class = eval(exceptionstr, self.dictionary)
try: try:
exec teststr in self.dictionary exec(teststr, self.dictionary)
except except_class: except except_class:
self.writeln('# raises %s as expected' % exceptionstr) self.writeln('# raises %s as expected' % exceptionstr)
self.passed += 1 self.passed += 1
@@ -191,7 +192,7 @@ class Docex:
self.fail(teststr, exceptionstr) self.fail(teststr, exceptionstr)
def fail(self, teststr, resultstr): def fail(self, teststr, resultstr):
self.writeln('###### ERROR, TEST FAILED: expected %s for %s' self.writeln('###### ERROR, TEST FAILED: expected %s for %s'
% (resultstr, teststr), % (resultstr, teststr),
'<font color=red><b>', '</b></font>') '<font color=red><b>', '</b></font>')
self.failed += 1 self.failed += 1
@@ -201,9 +202,9 @@ class Docex:
s = str(s) s = str(s)
if self.html: if self.html:
s = s.replace('&','&amp;').replace('<','&lt;').replace('>','&gt;') s = s.replace('&','&amp;').replace('<','&lt;').replace('>','&gt;')
print '%s%s%s' % (before, s, after) print('%s%s%s' % (before, s, after))
else: else:
print s print(s)
def seen(self, object): def seen(self, object):
"""Return true if this object has been seen before. """Return true if this object has been seen before.
@@ -213,7 +214,7 @@ class Docex:
return result return result
def main(args): def main(args):
"""Run Docex. args should be a list of python filenames. """Run Docex. args should be a list of python filenames.
If the first arg is a non-python filename, it is taken as the If the first arg is a non-python filename, it is taken as the
name of a log file to which output is written. If it ends in name of a log file to which output is written. If it ends in
".htm" or ".html", then the output is written as html. If the ".htm" or ".html", then the output is written as html. If the
@@ -230,9 +231,7 @@ def main(args):
for file in glob.glob(arg): for file in glob.glob(arg):
if file.endswith('.py'): if file.endswith('.py'):
modules.append(__import__(file[:-3])) modules.append(__import__(file[:-3]))
print Docex(modules, html=html, out=out) print(Docex(modules, html=html, out=out))
if __name__ == '__main__': if __name__ == '__main__':
main(sys.argv[1:]) main(sys.argv[1:])

View File

@@ -1,10 +1,11 @@
from __future__ import print_function
from collections import defaultdict from collections import defaultdict
def get_genomes(fname="byronbayseqs.fas.txt"): def get_genomes(fname="byronbayseqs.fas.txt"):
"Return a list of genomes, and a list of their corresponding names." "Return a list of genomes, and a list of their corresponding names."
import re import re
names, species, genomes = [], [], [] names, species, genomes = [], [], []
for name, g in re.findall('>(.*?)\r([^\r]*)\r*', file(fname).read()): for name, g in re.findall('>(.*?)\r([^\r]*)\r*', open(fname).read()):
names.append(name) names.append(name)
species.append(name.split('|')[-1]) species.append(name.split('|')[-1])
genomes.append(g) genomes.append(g)
@@ -14,7 +15,7 @@ def get_neighbors(fname="editdistances.txt"):
"Return dict: neighbors[i][j] = neighbors[j][i] = d means i,j are d apart." "Return dict: neighbors[i][j] = neighbors[j][i] = d means i,j are d apart."
## Read the data pre-computed from the Java program ## Read the data pre-computed from the Java program
neighbors = dict((i, {}) for i in range(n)) neighbors = dict((i, {}) for i in range(n))
for line in file(fname): for line in open(fname):
i,j,d = map(int, line.split()) i,j,d = map(int, line.split())
neighbors[i][j] = neighbors[j][i] = d neighbors[i][j] = neighbors[j][i] = d
return neighbors return neighbors
@@ -75,15 +76,15 @@ def showh(d):
return ' '.join('%s:%s' % i for i in sorted(d.items())) return ' '.join('%s:%s' % i for i in sorted(d.items()))
def greport(genomes): def greport(genomes):
print "Number of genomes: %d (%d distinct)" % (len(genomes), len(set(genomes))) print("Number of genomes: %d (%d distinct)" % (len(genomes), len(set(genomes))))
G = dict((g, set()) for g in genomes) G = dict((g, set()) for g in genomes)
for i in range(n): for i in range(n):
G[genomes[i]].add(species[i]) G[genomes[i]].add(species[i])
print "Multi-named genomes:", ( print("Multi-named genomes:", (
len([s for s in G.values() if len(s) > 1])) len([s for s in G.values() if len(s) > 1])))
lens = map(len, genomes) lens = map(len, genomes)
print "Genome lengths: min=%d, max=%d" % (min(lens), max(lens)) print("Genome lengths: min=%d, max=%d" % (min(lens), max(lens)))
print "Character counts: ", showh(c for g in genomes for c in g) print("Character counts: ", showh(c for g in genomes for c in g))
def nreport(neighbors): def nreport(neighbors):
NN, NumN = defaultdict(int), defaultdict(int) ## Nearest, Number of neighbors NN, NumN = defaultdict(int), defaultdict(int) ## Nearest, Number of neighbors
@@ -92,9 +93,9 @@ def nreport(neighbors):
NN[nn] += 1 NN[nn] += 1
for d2 in neighbors[n].values(): for d2 in neighbors[n].values():
NumN[d2] += 1 NumN[d2] += 1
print print()
print "Nearest neighbor counts:", showh(NN) print("Nearest neighbor counts:", showh(NN))
print "Number of neighbors at each distance:", showh(NumN) print("Number of neighbors at each distance:", showh(NumN))
def nspecies(c): return len(set(species[g] for g in c)) def nspecies(c): return len(set(species[g] for g in c))
@@ -104,34 +105,34 @@ def showc(c):
def creport(drange, dcrange): def creport(drange, dcrange):
def table(what, fn): def table(what, fn):
print "\n" + what print("\n" + what)
print ' '*8, ' '.join([' '+pct(dc, glen) for dc in dcrange]) print(' '*8, ' '.join([' '+pct(dc, glen) for dc in dcrange]))
for d in drange: for d in drange:
print '%s (%2d)' % (pct(d, glen), d), print('%s (%2d)' % (pct(d, glen), d), end=' ')
for dc in dcrange: for dc in dcrange:
print '%5s' % fn(cluster(neighbors, d, dc)), print('%5s' % fn(cluster(neighbors, d, dc)), end=' ')
print print()
print '\nNearest neighbor must be closer than this percentage (places). ' print('\nNearest neighbor must be closer than this percentage (places). ')
print 'Each column: all genomes in cluster within this percentage of each other.' print('Each column: all genomes in cluster within this percentage of each other.')
table("Number of clusters", len) table("Number of clusters", len)
cluster1 = cluster(neighbors, 8, 15) ## splits Cleora cluster1 = cluster(neighbors, 8, 15) ## splits Cleora
print '\nNumber of clusters of different sizes:', showh(len(c) for c in cluster1) print('\nNumber of clusters of different sizes:', showh(len(c) for c in cluster1))
M, T = defaultdict(int), defaultdict(int) M, T = defaultdict(int), defaultdict(int)
for c in cluster1: for c in cluster1:
M[margin(c)] += 1; T[margin(c)] += len(c) M[margin(c)] += 1; T[margin(c)] += len(c)
for x in M: print '%d\t%d\t%d'% (x,M[x],T[x]) for x in M: print('%d\t%d\t%d'% (x,M[x],T[x]))
print '\nMargins', showh(M) print('\nMargins', showh(M))
for c in cluster1: for c in cluster1:
if margin(c) <= 16: if margin(c) <= 16:
print showc(c) print(showc(c))
print '\nScatter plot of cluster diameter vs. margin.' print('\nScatter plot of cluster diameter vs. margin.')
for c in cluster1: for c in cluster1:
if diameter(c) > 0: if diameter(c) > 0:
pass pass
#print '%d\t%d' % (diameter(c), margin(c)) #print '%d\t%d' % (diameter(c), margin(c))
print '\nDifference from cluster(neighbors, 11, 14):' print('\nDifference from cluster(neighbors, 11, 14):')
#table(lambda cl: pct(len(cluster1)-compare(cluster1, cl),max(len(cluster1),len(cl)))) #table(lambda cl: pct(len(cluster1)-compare(cluster1, cl),max(len(cluster1),len(cl))))
print '\nNumber of clusters witth more than one species name:' print('\nNumber of clusters witth more than one species name:')
#table(lambda cl: sum(nspecies(c) > 1 for c in cl)) #table(lambda cl: sum(nspecies(c) > 1 for c in cl))
def pct_near_another(clusters, P=1.25): def pct_near_another(clusters, P=1.25):
total = 0 total = 0
@@ -143,21 +144,21 @@ def creport(drange, dcrange):
total += 1 total += 1
return pct(total, n) return pct(total, n)
def f(P): def f(P):
print '\nPercent of individuals within %.2f*diameter of another cluster.'%P print('\nPercent of individuals within %.2f*diameter of another cluster.'%P)
table(lambda cl: pct_near_another(cl, P)) table(lambda cl: pct_near_another(cl, P))
#map(f, [1.2, 1.33, 1.5]) #map(f, [1.2, 1.33, 1.5])
def sreport(species): def sreport(species):
SS = defaultdict(int) SS = defaultdict(int)
print print()
for s in set(species): for s in set(species):
c = [g for g in range(n) if species[g] == s] c = [g for g in range(n) if species[g] == s]
d = diameter(c) d = diameter(c)
if d > 14: if d > 14:
if d==glen: d = '>25' if d==glen: d = '>25'
print 'diameter %s for %s (%d elements)' % (d, s, len(c)) print('diameter %s for %s (%d elements)' % (d, s, len(c)))
SS[d] += 1 SS[d] += 1
print 'Diameters of %d labeled clusters: %s' % (len(set(species)), showh(SS)) print('Diameters of %d labeled clusters: %s' % (len(set(species)), showh(SS)))
def compare(cl1, cl2): def compare(cl1, cl2):
"Compare two lists of clusters" "Compare two lists of clusters"
@@ -174,7 +175,7 @@ def unit_tests():
assert diameter(set()) == 0 assert diameter(set()) == 0
assert diameter([17, 42]) == dist(17, 42) assert diameter([17, 42]) == dist(17, 42)
assert pct(1, 2) == '50.0%' assert pct(1, 2) == '50.0%'
print '\nAll tests pass.\n' print('\nAll tests pass.\n')

View File

@@ -23,6 +23,7 @@ an external file format that looks like this:
""" """
from __future__ import division from __future__ import division
from __future__ import print_function
from collections import Counter, defaultdict from collections import Counter, defaultdict
#### Read files in Books-Ngram format; convert to a dict #### Read files in Books-Ngram format; convert to a dict
@@ -31,7 +32,7 @@ def read_year_file(filename, dic=None):
"""Read a file of 'word year word_count book_count' lines and convert to a dict """Read a file of 'word year word_count book_count' lines and convert to a dict
{WORD: totalcount}. Uppercase all words, and only include all-alphabetic words.""" {WORD: totalcount}. Uppercase all words, and only include all-alphabetic words."""
if dic is None: dic = {} if dic is None: dic = {}
for line in file(filename): for line in open(filename):
word, year, c1, c2 = line.split('\t') word, year, c1, c2 = line.split('\t')
if '_' in word: if '_' in word:
word = word[:word.index('_')] word = word[:word.index('_')]
@@ -44,14 +45,14 @@ def read_year_file(filename, dic=None):
def write_dict(dic, filename): def write_dict(dic, filename):
"Write a {word:count} dict as 'word \t count' lines in filename." "Write a {word:count} dict as 'word \t count' lines in filename."
out = file(filename, 'w') out = open(filename, 'w')
for key in sorted(dic): for key in sorted(dic):
out.write('%s\t%s\n' % (key, dic[key])) out.write('%s\t%s\n' % (key, dic[key]))
return out.close() return out.close()
def read_dict(filename, sep='\t'): def read_dict(filename, sep='\t'):
"Read 'word \t count' lines from file and make them into a dict of {word:count}." "Read 'word \t count' lines from file and make them into a dict of {word:count}."
pairs = (line.split(sep) for line in file(filename)) pairs = (line.split(sep) for line in open(filename))
return {word: int(count) for (word, count) in pairs} return {word: int(count) for (word, count) in pairs}
#### Convert a bunch of year files into dict file format. #### Convert a bunch of year files into dict file format.
@@ -61,9 +62,9 @@ def convert_files(filenames, mincount=1e5):
import time import time
N = len(D) N = len(D)
W = sum(v for v in D.itervalues()) W = sum(v for v in D.itervalues())
print '%s: %s %s words (%s tokens) at %s' % ( print('%s: %s %s words (%s tokens) at %s' % (
filename, adj, format(W, ',d'), format(N, ',d'), filename, adj, format(W, ',d'), format(N, ',d'),
time.strftime("%H:%M:%S", time.gmtime())) time.strftime("%H:%M:%S", time.gmtime())))
for f in filenames: for f in filenames:
report(f, {}, 'starting') report(f, {}, 'starting')
D = read_year_file(f) D = read_year_file(f)
@@ -155,10 +156,10 @@ def getcount(counts, s, pos, length):
return counts[s, pos, length] return counts[s, pos, length]
print 'start' print('start')
#wc = word_counts('count_100K.txt') #wc = word_counts('count_100K.txt')
#counts = letter_counts(wc) #counts = letter_counts(wc)
print 'end' print('end')
@@ -172,18 +173,18 @@ def num(ch):
def stats(D, NS = (1, 2, 3, 4, 5, 6)): def stats(D, NS = (1, 2, 3, 4, 5, 6)):
counts = {n: Counter() for n in NS} counts = {n: Counter() for n in NS}
print 'words ' + ' '.join(' %d-grams ' % n for n in NS) print('words ' + ' '.join(' %d-grams ' % n for n in NS))
for (i, word) in enumerate(sortedby(D), 1): for (i, word) in enumerate(sortedby(D), 1):
for n in NS: for n in NS:
for ng in ngrams(word, n): for ng in ngrams(word, n):
counts[n][ng] += 1 counts[n][ng] += 1
if i % 5000 == 0 or i == len(D): if i % 5000 == 0 or i == len(D):
print "%4dK" % (i/1000), print("%4dK" % (i/1000), end=' ')
for n in NS: for n in NS:
c = len(counts[n]) c = len(counts[n])
field = "%5d (%d%%)" % (c, int(round(c*100/(26**n)))) field = "%5d (%d%%)" % (c, int(round(c*100/(26**n))))
print '%12s' % field, print('%12s' % field, end=' ')
print print()
letters = 'ETAOINSRHLDCUMFPGWYBVKXJQZ' letters = 'ETAOINSRHLDCUMFPGWYBVKXJQZ'
alphabet = ''.join(sorted(letters)) alphabet = ''.join(sorted(letters))
@@ -224,7 +225,7 @@ def substr(word, pos, length):
def lettercount(D, pos): def lettercount(D, pos):
LC = histogram((substr(w, pos, 1), D[w]) for w in D) LC = histogram((substr(w, pos, 1), D[w]) for w in D)
del LC[None] del LC[None]
print LC print(LC)
pos_name = (str(pos)+'+' if isinstance(pos, tuple) else pos_name = (str(pos)+'+' if isinstance(pos, tuple) else
pos if pos < 0 else pos if pos < 0 else
pos+1) pos+1)
@@ -293,7 +294,7 @@ def csvline(first, rest):
return '\t'.join([first] + map(str, rest)) return '\t'.join([first] + map(str, rest))
def makecsv(n, D=D): def makecsv(n, D=D):
out = file('ngrams%d.csv' % n, 'w') out = open('ngrams%d.csv' % n, 'w')
cols = columns(n) cols = columns(n)
Dng = defaultdict(lambda: defaultdict(int)) Dng = defaultdict(lambda: defaultdict(int))
for w in D: for w in D:
@@ -310,9 +311,9 @@ def makecsv(n, D=D):
if from_end <= 9: if from_end <= 9:
entry[ANY, -from_end, -from_end+n-1] += N entry[ANY, -from_end, -from_end+n-1] += N
# enumerate ngrams from word and increment counts for each one # enumerate ngrams from word and increment counts for each one
print >> out, csvline('%d-gram' % n, map(colname, cols)) print(csvline('%d-gram' % n, map(colname, cols)), file=out)
for ng in sorted(Dng, key=lambda ng: -Dng[ng][(ANY, ANY)]): for ng in sorted(Dng, key=lambda ng: -Dng[ng][(ANY, ANY)]):
print >> out, csvline(ng, [Dng[ng].get(col, 0) for col in cols]) print(csvline(ng, [Dng[ng].get(col, 0) for col in cols]), file=out)
out.close() out.close()
return Dng return Dng

View File

@@ -6,6 +6,11 @@ from __future__ import division
import math import math
import operator as op import operator as op
try:
raw_input # Python 2
except NameError:
raw_input = input # Python 3
################ Types ################ Types
Symbol = str # A Lisp Symbol is implemented as a Python str Symbol = str # A Lisp Symbol is implemented as a Python str
@@ -96,7 +101,7 @@ def repl(prompt='lis.py> '):
"A prompt-read-eval-print loop." "A prompt-read-eval-print loop."
while True: while True:
val = eval(parse(raw_input(prompt))) val = eval(parse(raw_input(prompt)))
if val is not None: if val is not None:
print(lispstr(val)) print(lispstr(val))
def lispstr(exp): def lispstr(exp):

View File

@@ -5,6 +5,7 @@
################ Symbol, Procedure, classes ################ Symbol, Procedure, classes
from __future__ import division from __future__ import division
from __future__ import print_function
import re, sys, StringIO import re, sys, StringIO
class Symbol(str): pass class Symbol(str): pass
@@ -114,9 +115,9 @@ def repl(prompt='lispy> ', inport=InPort(sys.stdin), out=sys.stdout):
x = parse(inport) x = parse(inport)
if x is eof_object: return if x is eof_object: return
val = eval(x) val = eval(x)
if val is not None and out: print >> out, to_string(val) if val is not None and out: print(to_string(val), file=out)
except Exception as e: except Exception as e:
print '%s: %s' % (type(e).__name__, e) print('%s: %s' % (type(e).__name__, e))
################ Environment class ################ Environment class
@@ -315,4 +316,3 @@ eval(parse("""(begin
if __name__ == '__main__': if __name__ == '__main__':
repl() repl()

View File

@@ -1,3 +1,4 @@
from __future__ import print_function
################ Tests for lis.py and lispy.py ################ Tests for lis.py and lispy.py
@@ -103,15 +104,15 @@ def test(tests, name=''):
for (x, expected) in tests: for (x, expected) in tests:
try: try:
result = eval(parse(x)) result = eval(parse(x))
print x, '=>', to_string(result) print(x, '=>', to_string(result))
ok = (result == expected) ok = (result == expected)
except Exception as e: except Exception as e:
print x, '=raises=>', type(e).__name__, e print(x, '=raises=>', type(e).__name__, e)
ok = issubclass(expected, Exception) and isinstance(e, expected) ok = issubclass(expected, Exception) and isinstance(e, expected)
if not ok: if not ok:
fails += 1 fails += 1
print 'FAIL!!! Expected', expected print('FAIL!!! Expected', expected)
print '%s %s: %d out of %d tests fail.' % ('*'*45, name, fails, len(tests)) print('%s %s: %d out of %d tests fail.' % ('*'*45, name, fails, len(tests)))
if __name__ == '__main__': if __name__ == '__main__':
from lis import * from lis import *

View File

@@ -8,6 +8,7 @@ Code copyright (c) 2008-2009 by Peter Norvig
You are free to use this code under the MIT licencse: You are free to use this code under the MIT licencse:
http://www.opensource.org/licenses/mit-license.php http://www.opensource.org/licenses/mit-license.php
""" """
from __future__ import print_function
import re, string, random, glob, operator, heapq import re, string, random, glob, operator, heapq
from collections import defaultdict from collections import defaultdict
@@ -27,7 +28,7 @@ def test(verbose=None):
"""Run some tests, taken from the chapter. """Run some tests, taken from the chapter.
Since the hillclimbing algorithm is randomized, some tests may fail.""" Since the hillclimbing algorithm is randomized, some tests may fail."""
import doctest import doctest
print 'Running tests...' print('Running tests...')
doctest.testfile('ngrams-test.txt', verbose=verbose) doctest.testfile('ngrams-test.txt', verbose=verbose)
################ Word Segmentation (p. 223) ################ Word Segmentation (p. 223)
@@ -97,9 +98,10 @@ def segment2(text, prev='<S>'):
for first,rem in splits(text)] for first,rem in splits(text)]
return max(candidates) return max(candidates)
def combine(Pfirst, first, (Prem, rem)): def combine(Pfirst, first, Prem__rem):
"Combine first and rem results into one (probability, words) pair." "Combine first and rem results into one (probability, words) pair."
return Pfirst+Prem, [first]+rem (Prem, rem) = Prem__rem
return Pfirst+Prem, [first]+rem
################ Secret Codes (p. 228-230) ################ Secret Codes (p. 228-230)
@@ -166,7 +168,7 @@ def hillclimb(x, f, neighbors, steps=10000):
if fx2 > fx: if fx2 > fx:
x, fx = x2, fx2 x, fx = x2, fx2
neighborhood = iter(neighbors(x)) neighborhood = iter(neighbors(x))
if debugging: print 'hillclimb:', x, int(fx) if debugging: print('hillclimb:', x, int(fx))
return x return x
debugging = False debugging = False

View File

@@ -1,3 +1,4 @@
from __future__ import print_function
import string, random, os, re, bisect import string, random, os, re, bisect
"""Produce Panama-ish Palindromes. Copyright (C) 2002, Peter Norvig. """Produce Panama-ish Palindromes. Copyright (C) 2002, Peter Norvig.
@@ -127,7 +128,7 @@ class Panama:
"Write current state to log file." "Write current state to log file."
if len(self) > self.best + 200: if len(self) > self.best + 200:
self.best = len(self) self.best = len(self)
print self.best print(self.best)
self.bestphrase = str(self) self.bestphrase = str(self)
assert is_panama(self.bestphrase) assert is_panama(self.bestphrase)
f = open('pallog%d.txt' % os.getpid(), 'w') f = open('pallog%d.txt' % os.getpid(), 'w')

View File

@@ -1,5 +1,11 @@
from __future__ import print_function
import random, re, bisect, time import random, re, bisect, time
try:
xrange # Python 2
except NameError:
xrange = range # Python 3
"""Produce Panama-ish Palindromes. Copyright (C) 2002-2008, Peter Norvig.""" """Produce Panama-ish Palindromes. Copyright (C) 2002-2008, Peter Norvig."""
################ Checking for Palindromes ################ Checking for Palindromes
@@ -107,10 +113,10 @@ def anpdictshort():
"Find the words that are valid when every phrase must start with 'a'" "Find the words that are valid when every phrase must start with 'a'"
def segment(word): return [s for s in word.split('a') if s] def segment(word): return [s for s in word.split('a') if s]
def valid(word): return all(reversestr(s) in segments for s in segment(word)) def valid(word): return all(reversestr(s) in segments for s in segment(word))
words = map(canonical, file('anpdict.txt')) words = map(canonical, open('anpdict.txt'))
segments = set(s for w in words for s in segment(canonical(w))) segments = set(s for w in words for s in segment(canonical(w)))
valid_words = [paldict.truename[w] for w in words if valid(w)] valid_words = [paldict.truename[w] for w in words if valid(w)]
file('anpdict-short.txt', 'w').write('\n'.join(valid_words)) open('anpdict-short.txt', 'w').write('\n'.join(valid_words))
################ Search for a palindrome ################ Search for a palindrome
@@ -185,14 +191,14 @@ class Panama:
def add_reversibles(self): def add_reversibles(self):
"Add in reversible words." "Add in reversible words."
print 'using reversibles ...' print('using reversibles ...')
for (word, rword) in self.dict.reversible_words().items(): for (word, rword) in self.dict.reversible_words().items():
if word not in self.seen and rword not in self.seen: if word not in self.seen and rword not in self.seen:
self.add('left', word) self.add('left', word)
self.add('right', rword) self.add('right', rword)
self.used_reversibles = True self.used_reversibles = True
self.stack = [] self.stack = []
print '...done' print('...done')
def report(self): def report(self):
"Report a new palindrome to log file (if it is sufficiently big)." "Report a new palindrome to log file (if it is sufficiently big)."
@@ -202,8 +208,8 @@ class Panama:
if N > self.best and (N > 12500 or N > self.best+500): if N > self.best and (N > 12500 or N > self.best+500):
self.best = len(self) self.best = len(self)
self.bestphrase = str(self) self.bestphrase = str(self)
print '%5d phrases (%5d words) in %3d seconds' % ( print('%5d phrases (%5d words) in %3d seconds' % (
self.best, self.bestphrase.count(' ')+1, time.clock() - self.starttime) self.best, self.bestphrase.count(' ')+1, time.clock() - self.starttime))
assert is_panama(self.bestphrase) assert is_panama(self.bestphrase)
f = open('pallog%d.txt' % (id(self) % 10000), 'w') f = open('pallog%d.txt' % (id(self) % 10000), 'w')
f.write(self.bestphrase + '\n') f.write(self.bestphrase + '\n')
@@ -254,7 +260,7 @@ def tests(p=Panama()):
d.tryharder = False d.tryharder = False
assert d.startswith('oklahoma') == ['oklahoma'] assert d.startswith('oklahoma') == ['oklahoma']
assert d.startswith('fsfdsfdsfds') == [] assert d.startswith('fsfdsfdsfds') == []
print 'all tests pass' print('all tests pass')
if __name__ == '__main__': if __name__ == '__main__':
p = Panama(); p = Panama();

View File

@@ -1,3 +1,4 @@
from __future__ import print_function
grammar = { grammar = {
'Noun': ['stench', 'wumpus'], 'Noun': ['stench', 'wumpus'],
'Verb': ['is', 'smell'], 'Verb': ['is', 'smell'],
@@ -9,16 +10,16 @@ grammar = {
'Preposition': ['to', 'in'], 'Preposition': ['to', 'in'],
'Conjunction': ['and', 'or'], 'Conjunction': ['and', 'or'],
'Digit': ['0', '1'], 'Digit': ['0', '1'],
'S': [['NP', 'VP'], ['S', 'Comjunction', 'S']], 'S': [['NP', 'VP'], ['S', 'Comjunction', 'S']],
'NP': ['Pronoun', 'Noun', ['Article', 'Noun'], ['Digit', 'Digit'], 'NP': ['Pronoun', 'Noun', ['Article', 'Noun'], ['Digit', 'Digit'],
['NP', 'PP'], ['NP', 'RelClause']], ['NP', 'PP'], ['NP', 'RelClause']],
'VP': ['Verb', ['VP', 'NP'], ['VP', 'Adjective'], ['VP', 'PP'], 'VP': ['Verb', ['VP', 'NP'], ['VP', 'Adjective'], ['VP', 'PP'],
['VP', 'Adverb']], ['VP', 'Adverb']],
'PP': [['Preposition', 'NP']], 'PP': [['Preposition', 'NP']],
'RelClause': [['that', 'VP']] 'RelClause': [['that', 'VP']]
} }
def parse(forest, grammar): def parse(forest, grammar):
if len(forest) == 1 and category(forest[0]) == 'S': if len(forest) == 1 and category(forest[0]) == 'S':
@@ -26,16 +27,16 @@ def parse(forest, grammar):
for i in range(len(forest)): for i in range(len(forest)):
for lhs in grammar.keys(): for lhs in grammar.keys():
for rhs in grammar[lhs]: for rhs in grammar[lhs]:
rhs = mklist(rhs) rhs = mklist(rhs)
n = len(rhs) n = len(rhs)
subsequence = forest[i:i+n] subsequence = forest[i:i+n]
if match(subsequence, rhs): if match(subsequence, rhs):
print subsequence, lhs, '=>', rhs print(subsequence, lhs, '=>', rhs)
forest2 = forest[:] forest2 = forest[:]
forest2[i:i+n] = [(lhs, subsequence)] forest2[i:i+n] = [(lhs, subsequence)]
result = parse(forest2, grammar) result = parse(forest2, grammar)
if result != None: if result != None:
return result return result
return None return None
def mklist(x): def mklist(x):

View File

@@ -7,6 +7,11 @@ From the shell, do:
import re, string, time, os import re, string, time, os
try:
cmp # Python 2
except NameError:
def cmp(x, y): # Python 3
return (x > y) - (x < y)
id = r'[a-zA-Z_][a-zA-Z_0-9]*' ## RE for a Python identifier id = r'[a-zA-Z_][a-zA-Z_0-9]*' ## RE for a Python identifier
g1, g2, g3, g4 = r'\1 \2 \3 \4'.split() ## groups for re.matches g1, g2, g3, g4 = r'\1 \2 \3 \4'.split() ## groups for re.matches

View File

@@ -1,4 +1,5 @@
from __future__ import division from __future__ import division
from __future__ import print_function
import re import re
from accum import * from accum import *
@@ -18,10 +19,10 @@ def expand_accumulations(program_text):
def test1(acc_display, expected): def test1(acc_display, expected):
"Eval an accumulation display and see if it gets the expected answer." "Eval an accumulation display and see if it gets the expected answer."
print acc_display print(acc_display)
result = eval(expand_accumulations(acc_display)) result = eval(expand_accumulations(acc_display))
assert result == expected, ('Got %s; expected %s' % (result, expected)) assert result == expected, ('Got %s; expected %s' % (result, expected))
print ' ==> %s' % result print(' ==> %s' % result)
#### Initialize some data #### Initialize some data
temp = [70, 70, 71, 74, 76, 76, 72, 76, 77, 77, 77, 78, temp = [70, 70, 71, 74, 76, 76, 72, 76, 77, 77, 77, 78,
@@ -33,11 +34,11 @@ candidates = votes.keys()
def test(): def test():
print 'temp = ', temp print('temp = ', temp)
print 'data = temp' print('data = temp')
print 'votes = ', votes print('votes = ', votes)
print 'candidates = ', candidates print('candidates = ', candidates)
print print()
#### Test some accumulation displays #### Test some accumulation displays
test1("[Max: temp[hour] for hour in range(24)]", test1("[Max: temp[hour] for hour in range(24)]",

View File

@@ -61,6 +61,7 @@ lines
Time for work. Time for work.
#] #]
""" """
from __future__ import print_function
import sys, re, os, os.path import sys, re, os, os.path
@@ -73,14 +74,14 @@ class Copier:
def repl(match, self=self): def repl(match, self=self):
"Replace the match with its value as a Python expression." "Replace the match with its value as a Python expression."
expr = self.preproc(match.group(1), 'eval') expr = self.preproc(match.group(1), 'eval')
if self.verbose: print '=== eval{%s}' % expr, if self.verbose: print('=== eval{%s}' % expr, end=' ')
try: try:
val = eval(expr, self.globals) val = eval(expr, self.globals)
except: except:
self.oops('eval', expr) self.oops('eval', expr)
if callable(val): val = val() if callable(val): val = val()
if val == None: val = '' if val == None: val = ''
if self.verbose: print '========>', val if self.verbose: print('========>', val)
return str(val) return str(val)
block = self.globals['_bl'] block = self.globals['_bl']
@@ -127,16 +128,16 @@ class Copier:
def execute(self, stmt): def execute(self, stmt):
stmt = self.preproc(stmt, 'exec') + '\n' stmt = self.preproc(stmt, 'exec') + '\n'
if self.verbose: if self.verbose:
print "******* executing {%s} in %s" % (stmt, self.globals.keys()) print("******* executing {%s} in %s" % (stmt, self.globals.keys()))
try: try:
exec stmt in self.globals exec(stmt, self.globals)
except: except:
self.oops('exec', stmt) self.oops('exec', stmt)
def oops(self, why, what): def oops(self, why, what):
print 'Something went wrong in %sing {%s}' % (why, what) print('Something went wrong in %sing {%s}' % (why, what))
print 'Globals:', self.globals.keys(), \ print('Globals:', self.globals.keys(), \
self.globals.get('SECTIONS', '???') self.globals.get('SECTIONS', '???'))
raise raise
def preproc(self, string, why, reg=re.compile(r"\s([<>&])\s"), def preproc(self, string, why, reg=re.compile(r"\s([<>&])\s"),
@@ -155,10 +156,10 @@ class Copier:
"Convert filename.* to filename.ext, where ext defaults to html." "Convert filename.* to filename.ext, where ext defaults to html."
global yaptu_filename global yaptu_filename
outname = re.sub('[.][a-zA-Z0-9]+?$', '', filename) + '.'+ext outname = re.sub('[.][a-zA-Z0-9]+?$', '', filename) + '.'+ext
print 'Transforming', filename, 'to', outname print('Transforming', filename, 'to', outname)
self.globals['_bl'] = file(filename).readlines() self.globals['_bl'] = open(filename).readlines()
yaptu_filename = filename yaptu_filename = filename
self.outf = file(outname, 'w') self.outf = open(outname, 'w')
self.copyblock() self.copyblock()
if __name__ == '__main__': if __name__ == '__main__':