From 6a8e87e17b9df8b5468cdc457e8a901679611198 Mon Sep 17 00:00:00 2001 From: cclauss Date: Wed, 17 Oct 2018 01:48:46 +0200 Subject: [PATCH] Python 3 fixes --- py/docex.py | 39 +++++++++++++++---------------- py/ibol.py | 59 ++++++++++++++++++++++++----------------------- py/lettercount.py | 31 +++++++++++++------------ py/lis.py | 7 +++++- py/lispy.py | 6 ++--- py/lispytest.py | 9 ++++---- py/ngrams.py | 12 ++++++---- py/pal.py | 3 ++- py/pal2.py | 20 ++++++++++------ py/parse.py | 29 ++++++++++++----------- py/py2html.py | 5 ++++ py/testaccum.py | 15 ++++++------ py/yaptu.py | 21 +++++++++-------- 13 files changed, 140 insertions(+), 116 deletions(-) diff --git a/py/docex.py b/py/docex.py index cbffe2a..ab3b8b7 100644 --- a/py/docex.py +++ b/py/docex.py @@ -38,13 +38,13 @@ differences between docex and doctest are: 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, 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. (4) Doctest has many more features, and is better supported. 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 - 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. 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. If x doesn't raise the right exception, an error msg is printed. (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 @@ -96,9 +97,9 @@ class Docex: if out: sys.stdout = sys.__stdout__ out.close() - + def __repr__(self): - if self.failed: + if self.failed: return ('' % (self.failed, self.passed)) else: @@ -141,8 +142,8 @@ class Docex: match = search(s) if match: self.run_string(s[match.end():]) if hasattr(object, '_docex'): - self.run_string(object._docex) - + self.run_string(object._docex) + def run_string(self, teststr): """Run a test string, printing inputs and results.""" if not teststr: return @@ -163,7 +164,7 @@ class Docex: try: self.evaluate(teststr) except SyntaxError: - exec teststr in self.dictionary + exec(teststr, self.dictionary) def evaluate(self, teststr, resultstr=None): "Eval teststr and check if resultstr (if given) evals to the same." @@ -172,18 +173,18 @@ class Docex: self.dictionary['_'] = result self.writeln(repr(result)) if resultstr == None: - return + return elif result == eval(resultstr, self.dictionary): - self.passed += 1 + self.passed += 1 else: - self.fail(teststr, resultstr) - + self.fail(teststr, resultstr) + def raises(self, teststr, exceptionstr): teststr = teststr.strip() self.writeln('>>> ' + teststr) except_class = eval(exceptionstr, self.dictionary) try: - exec teststr in self.dictionary + exec(teststr, self.dictionary) except except_class: self.writeln('# raises %s as expected' % exceptionstr) self.passed += 1 @@ -191,7 +192,7 @@ class Docex: self.fail(teststr, exceptionstr) 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), '', '') self.failed += 1 @@ -201,9 +202,9 @@ class Docex: s = str(s) if self.html: s = s.replace('&','&').replace('<','<').replace('>','>') - print '%s%s%s' % (before, s, after) + print('%s%s%s' % (before, s, after)) else: - print s + print(s) def seen(self, object): """Return true if this object has been seen before. @@ -213,7 +214,7 @@ class Docex: return result 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 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 @@ -230,9 +231,7 @@ def main(args): for file in glob.glob(arg): if file.endswith('.py'): modules.append(__import__(file[:-3])) - print Docex(modules, html=html, out=out) + print(Docex(modules, html=html, out=out)) if __name__ == '__main__': main(sys.argv[1:]) - - diff --git a/py/ibol.py b/py/ibol.py index d2490a6..c3b878d 100644 --- a/py/ibol.py +++ b/py/ibol.py @@ -1,10 +1,11 @@ +from __future__ import print_function from collections import defaultdict def get_genomes(fname="byronbayseqs.fas.txt"): "Return a list of genomes, and a list of their corresponding names." import re 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) species.append(name.split('|')[-1]) 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." ## Read the data pre-computed from the Java program 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()) neighbors[i][j] = neighbors[j][i] = d return neighbors @@ -75,15 +76,15 @@ def showh(d): return ' '.join('%s:%s' % i for i in sorted(d.items())) 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) for i in range(n): G[genomes[i]].add(species[i]) - print "Multi-named genomes:", ( - len([s for s in G.values() if len(s) > 1])) + print("Multi-named genomes:", ( + len([s for s in G.values() if len(s) > 1]))) lens = map(len, genomes) - 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("Genome lengths: min=%d, max=%d" % (min(lens), max(lens))) + print("Character counts: ", showh(c for g in genomes for c in g)) def nreport(neighbors): NN, NumN = defaultdict(int), defaultdict(int) ## Nearest, Number of neighbors @@ -92,9 +93,9 @@ def nreport(neighbors): NN[nn] += 1 for d2 in neighbors[n].values(): NumN[d2] += 1 - print - print "Nearest neighbor counts:", showh(NN) - print "Number of neighbors at each distance:", showh(NumN) + print() + print("Nearest neighbor counts:", showh(NN)) + print("Number of neighbors at each distance:", showh(NumN)) def nspecies(c): return len(set(species[g] for g in c)) @@ -104,34 +105,34 @@ def showc(c): def creport(drange, dcrange): def table(what, fn): - print "\n" + what - print ' '*8, ' '.join([' '+pct(dc, glen) for dc in dcrange]) + print("\n" + what) + print(' '*8, ' '.join([' '+pct(dc, glen) for dc in dcrange])) for d in drange: - print '%s (%2d)' % (pct(d, glen), d), + print('%s (%2d)' % (pct(d, glen), d), end=' ') for dc in dcrange: - print '%5s' % fn(cluster(neighbors, d, dc)), - print - print '\nNearest neighbor must be closer than this percentage (places). ' - print 'Each column: all genomes in cluster within this percentage of each other.' + print('%5s' % fn(cluster(neighbors, d, dc)), end=' ') + print() + print('\nNearest neighbor must be closer than this percentage (places). ') + print('Each column: all genomes in cluster within this percentage of each other.') table("Number of clusters", len) 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) for c in cluster1: M[margin(c)] += 1; T[margin(c)] += len(c) - for x in M: print '%d\t%d\t%d'% (x,M[x],T[x]) - print '\nMargins', showh(M) + for x in M: print('%d\t%d\t%d'% (x,M[x],T[x])) + print('\nMargins', showh(M)) for c in cluster1: if margin(c) <= 16: - print showc(c) - print '\nScatter plot of cluster diameter vs. margin.' + print(showc(c)) + print('\nScatter plot of cluster diameter vs. margin.') for c in cluster1: if diameter(c) > 0: pass #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)))) - 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)) def pct_near_another(clusters, P=1.25): total = 0 @@ -143,21 +144,21 @@ def creport(drange, dcrange): total += 1 return pct(total, n) 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)) #map(f, [1.2, 1.33, 1.5]) def sreport(species): SS = defaultdict(int) - print + print() for s in set(species): c = [g for g in range(n) if species[g] == s] d = diameter(c) if d > 14: 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 - 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): "Compare two lists of clusters" @@ -174,7 +175,7 @@ def unit_tests(): assert diameter(set()) == 0 assert diameter([17, 42]) == dist(17, 42) assert pct(1, 2) == '50.0%' - print '\nAll tests pass.\n' + print('\nAll tests pass.\n') diff --git a/py/lettercount.py b/py/lettercount.py index 3c6db88..ab78a8e 100644 --- a/py/lettercount.py +++ b/py/lettercount.py @@ -23,6 +23,7 @@ an external file format that looks like this: """ from __future__ import division +from __future__ import print_function from collections import Counter, defaultdict #### 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 {WORD: totalcount}. Uppercase all words, and only include all-alphabetic words.""" if dic is None: dic = {} - for line in file(filename): + for line in open(filename): word, year, c1, c2 = line.split('\t') if '_' in word: word = word[:word.index('_')] @@ -44,14 +45,14 @@ def read_year_file(filename, dic=None): def write_dict(dic, 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): out.write('%s\t%s\n' % (key, dic[key])) return out.close() def read_dict(filename, sep='\t'): "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} #### Convert a bunch of year files into dict file format. @@ -61,9 +62,9 @@ def convert_files(filenames, mincount=1e5): import time N = len(D) 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'), - time.strftime("%H:%M:%S", time.gmtime())) + time.strftime("%H:%M:%S", time.gmtime()))) for f in filenames: report(f, {}, 'starting') D = read_year_file(f) @@ -155,10 +156,10 @@ def getcount(counts, s, pos, length): return counts[s, pos, length] -print 'start' +print('start') #wc = word_counts('count_100K.txt') #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)): 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 n in NS: for ng in ngrams(word, n): counts[n][ng] += 1 if i % 5000 == 0 or i == len(D): - print "%4dK" % (i/1000), + print("%4dK" % (i/1000), end=' ') for n in NS: c = len(counts[n]) field = "%5d (%d%%)" % (c, int(round(c*100/(26**n)))) - print '%12s' % field, - print + print('%12s' % field, end=' ') + print() letters = 'ETAOINSRHLDCUMFPGWYBVKXJQZ' alphabet = ''.join(sorted(letters)) @@ -224,7 +225,7 @@ def substr(word, pos, length): def lettercount(D, pos): LC = histogram((substr(w, pos, 1), D[w]) for w in D) del LC[None] - print LC + print(LC) pos_name = (str(pos)+'+' if isinstance(pos, tuple) else pos if pos < 0 else pos+1) @@ -293,7 +294,7 @@ def csvline(first, rest): return '\t'.join([first] + map(str, rest)) def makecsv(n, D=D): - out = file('ngrams%d.csv' % n, 'w') + out = open('ngrams%d.csv' % n, 'w') cols = columns(n) Dng = defaultdict(lambda: defaultdict(int)) for w in D: @@ -310,9 +311,9 @@ def makecsv(n, D=D): if from_end <= 9: entry[ANY, -from_end, -from_end+n-1] += N # 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)]): - 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() return Dng diff --git a/py/lis.py b/py/lis.py index 525f982..065eab4 100644 --- a/py/lis.py +++ b/py/lis.py @@ -6,6 +6,11 @@ from __future__ import division import math import operator as op +try: + raw_input # Python 2 +except NameError: + raw_input = input # Python 3 + ################ Types 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." while True: val = eval(parse(raw_input(prompt))) - if val is not None: + if val is not None: print(lispstr(val)) def lispstr(exp): diff --git a/py/lispy.py b/py/lispy.py index 08923c1..1d8af76 100644 --- a/py/lispy.py +++ b/py/lispy.py @@ -5,6 +5,7 @@ ################ Symbol, Procedure, classes from __future__ import division +from __future__ import print_function import re, sys, StringIO class Symbol(str): pass @@ -114,9 +115,9 @@ def repl(prompt='lispy> ', inport=InPort(sys.stdin), out=sys.stdout): x = parse(inport) if x is eof_object: return 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: - print '%s: %s' % (type(e).__name__, e) + print('%s: %s' % (type(e).__name__, e)) ################ Environment class @@ -315,4 +316,3 @@ eval(parse("""(begin if __name__ == '__main__': repl() - diff --git a/py/lispytest.py b/py/lispytest.py index bed5307..a69fd7c 100644 --- a/py/lispytest.py +++ b/py/lispytest.py @@ -1,3 +1,4 @@ +from __future__ import print_function ################ Tests for lis.py and lispy.py @@ -103,15 +104,15 @@ def test(tests, name=''): for (x, expected) in tests: try: result = eval(parse(x)) - print x, '=>', to_string(result) + print(x, '=>', to_string(result)) ok = (result == expected) 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) if not ok: fails += 1 - print 'FAIL!!! Expected', expected - print '%s %s: %d out of %d tests fail.' % ('*'*45, name, fails, len(tests)) + print('FAIL!!! Expected', expected) + print('%s %s: %d out of %d tests fail.' % ('*'*45, name, fails, len(tests))) if __name__ == '__main__': from lis import * diff --git a/py/ngrams.py b/py/ngrams.py index 6b04c29..6275943 100644 --- a/py/ngrams.py +++ b/py/ngrams.py @@ -8,6 +8,7 @@ Code copyright (c) 2008-2009 by Peter Norvig You are free to use this code under the MIT licencse: http://www.opensource.org/licenses/mit-license.php """ +from __future__ import print_function import re, string, random, glob, operator, heapq from collections import defaultdict @@ -27,7 +28,7 @@ def test(verbose=None): """Run some tests, taken from the chapter. Since the hillclimbing algorithm is randomized, some tests may fail.""" import doctest - print 'Running tests...' + print('Running tests...') doctest.testfile('ngrams-test.txt', verbose=verbose) ################ Word Segmentation (p. 223) @@ -97,9 +98,10 @@ def segment2(text, prev=''): for first,rem in splits(text)] return max(candidates) -def combine(Pfirst, first, (Prem, rem)): - "Combine first and rem results into one (probability, words) pair." - return Pfirst+Prem, [first]+rem +def combine(Pfirst, first, Prem__rem): + "Combine first and rem results into one (probability, words) pair." + (Prem, rem) = Prem__rem + return Pfirst+Prem, [first]+rem ################ Secret Codes (p. 228-230) @@ -166,7 +168,7 @@ def hillclimb(x, f, neighbors, steps=10000): if fx2 > fx: x, fx = x2, fx2 neighborhood = iter(neighbors(x)) - if debugging: print 'hillclimb:', x, int(fx) + if debugging: print('hillclimb:', x, int(fx)) return x debugging = False diff --git a/py/pal.py b/py/pal.py index db8f509..135e482 100644 --- a/py/pal.py +++ b/py/pal.py @@ -1,3 +1,4 @@ +from __future__ import print_function import string, random, os, re, bisect """Produce Panama-ish Palindromes. Copyright (C) 2002, Peter Norvig. @@ -127,7 +128,7 @@ class Panama: "Write current state to log file." if len(self) > self.best + 200: self.best = len(self) - print self.best + print(self.best) self.bestphrase = str(self) assert is_panama(self.bestphrase) f = open('pallog%d.txt' % os.getpid(), 'w') diff --git a/py/pal2.py b/py/pal2.py index 9436ead..4faecb4 100644 --- a/py/pal2.py +++ b/py/pal2.py @@ -1,5 +1,11 @@ +from __future__ import print_function 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.""" ################ Checking for Palindromes @@ -107,10 +113,10 @@ def anpdictshort(): "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 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))) 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 @@ -185,14 +191,14 @@ class Panama: def add_reversibles(self): "Add in reversible words." - print 'using reversibles ...' + print('using reversibles ...') for (word, rword) in self.dict.reversible_words().items(): if word not in self.seen and rword not in self.seen: self.add('left', word) self.add('right', rword) self.used_reversibles = True self.stack = [] - print '...done' + print('...done') def report(self): "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): self.best = len(self) self.bestphrase = str(self) - print '%5d phrases (%5d words) in %3d seconds' % ( - self.best, self.bestphrase.count(' ')+1, time.clock() - self.starttime) + print('%5d phrases (%5d words) in %3d seconds' % ( + self.best, self.bestphrase.count(' ')+1, time.clock() - self.starttime)) assert is_panama(self.bestphrase) f = open('pallog%d.txt' % (id(self) % 10000), 'w') f.write(self.bestphrase + '\n') @@ -254,7 +260,7 @@ def tests(p=Panama()): d.tryharder = False assert d.startswith('oklahoma') == ['oklahoma'] assert d.startswith('fsfdsfdsfds') == [] - print 'all tests pass' + print('all tests pass') if __name__ == '__main__': p = Panama(); diff --git a/py/parse.py b/py/parse.py index 8c7e4ea..4580dac 100644 --- a/py/parse.py +++ b/py/parse.py @@ -1,3 +1,4 @@ +from __future__ import print_function grammar = { 'Noun': ['stench', 'wumpus'], 'Verb': ['is', 'smell'], @@ -9,16 +10,16 @@ grammar = { 'Preposition': ['to', 'in'], 'Conjunction': ['and', 'or'], 'Digit': ['0', '1'], - + 'S': [['NP', 'VP'], ['S', 'Comjunction', 'S']], - 'NP': ['Pronoun', 'Noun', ['Article', 'Noun'], ['Digit', 'Digit'], + 'NP': ['Pronoun', 'Noun', ['Article', 'Noun'], ['Digit', 'Digit'], ['NP', 'PP'], ['NP', 'RelClause']], - 'VP': ['Verb', ['VP', 'NP'], ['VP', 'Adjective'], ['VP', 'PP'], + 'VP': ['Verb', ['VP', 'NP'], ['VP', 'Adjective'], ['VP', 'PP'], ['VP', 'Adverb']], 'PP': [['Preposition', 'NP']], 'RelClause': [['that', 'VP']] } - + def parse(forest, grammar): if len(forest) == 1 and category(forest[0]) == 'S': @@ -26,16 +27,16 @@ def parse(forest, grammar): for i in range(len(forest)): for lhs in grammar.keys(): for rhs in grammar[lhs]: - rhs = mklist(rhs) - n = len(rhs) - subsequence = forest[i:i+n] - if match(subsequence, rhs): - print subsequence, lhs, '=>', rhs - forest2 = forest[:] - forest2[i:i+n] = [(lhs, subsequence)] - result = parse(forest2, grammar) - if result != None: - return result + rhs = mklist(rhs) + n = len(rhs) + subsequence = forest[i:i+n] + if match(subsequence, rhs): + print(subsequence, lhs, '=>', rhs) + forest2 = forest[:] + forest2[i:i+n] = [(lhs, subsequence)] + result = parse(forest2, grammar) + if result != None: + return result return None def mklist(x): diff --git a/py/py2html.py b/py/py2html.py index 896d0de..bf29818 100644 --- a/py/py2html.py +++ b/py/py2html.py @@ -7,6 +7,11 @@ From the shell, do: 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 g1, g2, g3, g4 = r'\1 \2 \3 \4'.split() ## groups for re.matches diff --git a/py/testaccum.py b/py/testaccum.py index d8e18c1..484e9d2 100644 --- a/py/testaccum.py +++ b/py/testaccum.py @@ -1,4 +1,5 @@ from __future__ import division +from __future__ import print_function import re from accum import * @@ -18,10 +19,10 @@ def expand_accumulations(program_text): def test1(acc_display, expected): "Eval an accumulation display and see if it gets the expected answer." - print acc_display + print(acc_display) result = eval(expand_accumulations(acc_display)) assert result == expected, ('Got %s; expected %s' % (result, expected)) - print ' ==> %s' % result + print(' ==> %s' % result) #### Initialize some data temp = [70, 70, 71, 74, 76, 76, 72, 76, 77, 77, 77, 78, @@ -33,11 +34,11 @@ candidates = votes.keys() def test(): - print 'temp = ', temp - print 'data = temp' - print 'votes = ', votes - print 'candidates = ', candidates - print + print('temp = ', temp) + print('data = temp') + print('votes = ', votes) + print('candidates = ', candidates) + print() #### Test some accumulation displays test1("[Max: temp[hour] for hour in range(24)]", diff --git a/py/yaptu.py b/py/yaptu.py index e08bd26..10981d2 100644 --- a/py/yaptu.py +++ b/py/yaptu.py @@ -61,6 +61,7 @@ lines Time for work. #] """ +from __future__ import print_function import sys, re, os, os.path @@ -73,14 +74,14 @@ class Copier: def repl(match, self=self): "Replace the match with its value as a Python expression." expr = self.preproc(match.group(1), 'eval') - if self.verbose: print '=== eval{%s}' % expr, + if self.verbose: print('=== eval{%s}' % expr, end=' ') try: val = eval(expr, self.globals) except: self.oops('eval', expr) if callable(val): val = val() if val == None: val = '' - if self.verbose: print '========>', val + if self.verbose: print('========>', val) return str(val) block = self.globals['_bl'] @@ -127,16 +128,16 @@ class Copier: def execute(self, stmt): stmt = self.preproc(stmt, 'exec') + '\n' if self.verbose: - print "******* executing {%s} in %s" % (stmt, self.globals.keys()) + print("******* executing {%s} in %s" % (stmt, self.globals.keys())) try: - exec stmt in self.globals + exec(stmt, self.globals) except: self.oops('exec', stmt) def oops(self, why, what): - print 'Something went wrong in %sing {%s}' % (why, what) - print 'Globals:', self.globals.keys(), \ - self.globals.get('SECTIONS', '???') + print('Something went wrong in %sing {%s}' % (why, what)) + print('Globals:', self.globals.keys(), \ + self.globals.get('SECTIONS', '???')) raise 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." global yaptu_filename outname = re.sub('[.][a-zA-Z0-9]+?$', '', filename) + '.'+ext - print 'Transforming', filename, 'to', outname - self.globals['_bl'] = file(filename).readlines() + print('Transforming', filename, 'to', outname) + self.globals['_bl'] = open(filename).readlines() yaptu_filename = filename - self.outf = file(outname, 'w') + self.outf = open(outname, 'w') self.copyblock() if __name__ == '__main__':