Skip to content

Commit f239efc

Browse files
author
Bruce Eckel
committed
compare_output
1 parent ab8f05c commit f239efc

1 file changed

Lines changed: 204 additions & 6 deletions

File tree

tools/AttachResults.py

Lines changed: 204 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
"""
55
TODO = """
66
7+
- NUL bytes in some files:
8+
1. Show we can find them
9+
2. Replace with NUL or [NUL]
10+
711
- Display all files with less than 100% match (rather than putting percentage and "Sample" in)
812
Rely on visual inspection of non-matching file?
913
Have a list of files to exclude normally, and inspect ocasionally
@@ -23,6 +27,7 @@
2327
import textwrap
2428
import os, sys, re
2529
from itertools import chain
30+
from sortedcontainers import SortedSet
2631
from betools import CmdLine, visitDir, ruler, head
2732

2833
maxlinewidth = 59
@@ -32,10 +37,11 @@
3237
class JavaMain:
3338
max_output_length = 32 # lines beyond which we flag this
3439
maindef = re.compile("public\s+static\s+void\s+main")
35-
ellipses = ["[...]".center(maxlinewidth, '_')]
40+
leader = "_" * 8
41+
ellipses = [leader + leader.join(["..."] * 4) + leader]
42+
# ellipses = ["[...]".center(14, '_') * 4]
3643

3744
class JFile:
38-
"""Could just manipulate this, then write it at the end"""
3945
@staticmethod
4046
def with_main(javaFilePath):
4147
with javaFilePath.open() as doc:
@@ -96,7 +102,7 @@ def __init__(self, javaFilePath, j_file, outfile, errfile):
96102
out = "\n".join(lines[:self.first_and_last] + JavaMain.ellipses + lines[-self.first_and_last:])
97103
elif self.first_lines:
98104
lines = out.splitlines()
99-
out = "\n".join(lines[:self.first_lines] + JavaMain.ellipses)
105+
out = "\n".join(lines[:self.first_lines] + [" " * 18 + "..."])
100106
result += out + "\n"
101107
if errfile.exists(): # Always include all of errfile
102108
with errfile.open() as f:
@@ -127,6 +133,10 @@ def new_code(self):
127133

128134
@staticmethod
129135
def wrapOutput(output):
136+
"""
137+
Wrap to line limit and perform other fixups for display and comparison
138+
"""
139+
output = output.replace('\0', "NUL")
130140
lines = output.splitlines()
131141
result = []
132142
for line in lines:
@@ -180,7 +190,7 @@ def extractResults():
180190
results.write(j_main.result)
181191
os.system("subl AttachedResults.txt")
182192

183-
@CmdLine('n')
193+
#@CmdLine('n')
184194
def noOutputFixup():
185195
"""Attach "Output: (None)" lines to empty output files"""
186196
os.chdir(str(examplePath))
@@ -225,12 +235,62 @@ def viewAttachedFiles():
225235
os.system("subl {}".format(java))
226236
continue
227237

238+
239+
@CmdLine('x')
240+
def showNulBytesInOutput():
241+
"""Look for NUL bytes in output files`"""
242+
os.chdir(str(examplePath))
243+
for normal in Path(".").rglob("*-output.txt"):
244+
with normal.open() as codeFile:
245+
if "\0" in codeFile.read():
246+
print(normal)
247+
for errors in Path(".").rglob("*-erroroutput.txt"):
248+
with errors.open() as codeFile:
249+
if "\0" in codeFile.read():
250+
print(normal)
251+
252+
228253
@CmdLine('s')
229254
def showJavaFiles():
230255
"""Sublime edit all java files in this directory and below"""
231256
for java in Path(".").rglob("*.java"):
232257
os.system("subl {}".format(java))
233258

259+
260+
# @CmdLine('w')
261+
def boldWords():
262+
"""
263+
Create list of bolded words to be used as a Word dictionary
264+
"""
265+
from bs4 import BeautifulSoup
266+
import codecs
267+
import string
268+
clean = lambda dirty: ''.join(filter(string.printable.__contains__, dirty))
269+
def flense(word):
270+
word = clean(word)
271+
word = word.split('(')[0]
272+
word = word.split('[')[0]
273+
return word.strip()
274+
275+
os.chdir(str(examplePath / ".."))
276+
spelldict = SortedSet()
277+
with codecs.open(str(Path("TIJDirectorsCut.htm")),'r', encoding='utf-8', errors='ignore') as book:
278+
soup = BeautifulSoup(book.read())
279+
for b in soup.find_all("b"):
280+
text = (" ".join(b.text.split())).strip()
281+
if " " in text:
282+
continue
283+
text = flense(text)
284+
if text:
285+
spelldict.add(text)
286+
287+
with Path("BoldedWords.txt").open('w') as boldwords:
288+
for word in spelldict:
289+
if len(word):
290+
if word[0] in string.ascii_letters:
291+
boldwords.write(word + "\n")
292+
293+
234294
@CmdLine('b')
235295
def blankOutputFiles():
236296
"""Show java files with expected output where there is none"""
@@ -260,6 +320,144 @@ def unexpectedOutput():
260320
if errfile.stat().st_size:
261321
print("Unexpected error output: {}".format(java))
262322

323+
exclude_files = [
324+
r"concurrency\ActiveObjectDemo.java",
325+
r"concurrency\AtomicityTest.java",
326+
r"concurrency\CachedThreadPool.java",
327+
r"concurrency\CountDownLatchDemo.java",
328+
r"concurrency\DaemonFromFactory.java",
329+
r"concurrency\DeadlockingDiningPhilosophers.java",
330+
r"concurrency\FastSimulation.java",
331+
r"concurrency\FixedDiningPhilosophers.java",
332+
r"concurrency\FixedThreadPool.java",
333+
r"concurrency\MoreBasicThreads.java",
334+
r"concurrency\NIOInterruption.java",
335+
r"concurrency\SelfManaged.java",
336+
r"concurrency\SemaphoreDemo.java",
337+
r"concurrency\SimpleDaemons.java",
338+
r"concurrency\SleepingTask.java",
339+
r"concurrency\ThreadLocalVariableHolder.java",
340+
r"patterns\PaperScissorsRock.java",
341+
r"patterns\recyclea\RecycleA.java",
342+
r"patterns\visitor\BeeAndFlowers.java",
343+
r"concurrency\EvenGenerator.java",
344+
r"concurrency\GreenhouseScheduler.java",
345+
r"concurrency\OrnamentalGarden.java",
346+
r"concurrency\PipedIO.java",
347+
r"concurrency\SimplePriorities.java",
348+
r"concurrency\SimpleThread.java",
349+
r"concurrency\ThreadVariations.java",
350+
r"generics\DynamicProxyMixin.java",
351+
r"logging\LoggingLevelManipulation.java",
352+
r"logging\SimpleFilter.java",
353+
r"annotations\AtUnitExample4.java",
354+
r"concurrency\BankTellerSimulation.java",
355+
r"concurrency\CarBuilder.java",
356+
r"concurrency\ListComparisons.java",
357+
r"concurrency\MapComparisons.java",
358+
r"concurrency\ReaderWriterList.java",
359+
r"concurrency\restaurant2\RestaurantWithQueues.java",
360+
r"generics\Mixins.java",
361+
r"io\LockingMappedFiles.java",
362+
r"logging\ConfigureLogging.java",
363+
r"logging\LoggingLevels.java",
364+
r"operators\HelloDate.java",
365+
r"annotations\AtUnitComposition.java",
366+
r"annotations\AtUnitExample3.java",
367+
r"annotations\AtUnitExternalTest.java",
368+
r"annotations\HashSetTest.java",
369+
r"annotations\UseCaseTracker.java",
370+
r"concurrency\Interrupting.java",
371+
r"concurrency\SerialNumberChecker.java",
372+
r"concurrency\SimpleMicroBenchmark.java",
373+
r"concurrency\SynchronizationComparisons.java",
374+
r"concurrency\SyncObject.java",
375+
r"containers\ListPerformance.java",
376+
r"io\Logon.java",
377+
r"logging\CustomHandler.java",
378+
r"object\HelloDate.java",
379+
r"annotations\AtUnitExample1.java",
380+
r"annotations\AtUnitExample2.java",
381+
r"concurrency\ExchangerDemo.java",
382+
r"concurrency\ExplicitCriticalSection.java",
383+
r"concurrency\Restaurant.java",
384+
r"containers\MapPerformance.java",
385+
r"containers\SetPerformance.java",
386+
r"exceptions\LoggingExceptions.java",
387+
r"logging\InfoLogging.java",
388+
r"logging\InfoLogging2.java",
389+
r"logging\LogToFile.java",
390+
r"logging\LogToFile2.java",
391+
r"logging\MultipleHandlers.java",
392+
r"logging\MultipleHandlers2.java",
393+
r"annotations\AtUnitExample5.java",
394+
r"concurrency\Daemons.java",
395+
r"concurrency\HorseRace.java",
396+
r"concurrency\ToastOMatic.java",
397+
r"enums\ConstantSpecificMethod.java",
398+
r"exceptions\LoggingExceptions2.java",
399+
r"io\MakeDirectories.java",
400+
r"io\MappedIO.java",
401+
r"io\PreferencesDemo.java",
402+
r"logging\PrintableLogRecord.java",
403+
r"references\Compete.java",
404+
405+
# Keep an eye on:
406+
r"strings\JGrep.java",
407+
]
408+
409+
@CmdLine('c')
410+
def compare_output():
411+
"""Compare attached and newly-generated output"""
412+
TODO = """
413+
- Could also compare number of lines
414+
"""
415+
ratio_target = 1.0
416+
from difflib import SequenceMatcher
417+
os.chdir(str(examplePath))
418+
def generated_output(jfp):
419+
j_main = JavaMain.create(jfp)
420+
if not j_main:
421+
return None
422+
return j_main.result.strip()
423+
def embedded_output(jfp):
424+
find_output = re.compile(r"/\* (Output:.*)\*///:~", re.DOTALL)
425+
with jfp.open() as java:
426+
output = find_output.search(java.read())
427+
assert output, "No embedded output: in {}".format(jfp)
428+
return "\n".join(output.group(1).strip().splitlines()[1:])
429+
if Path("CompareExclusions.txt").is_file():
430+
Path("CompareExclusions.txt").unlink()
431+
with Path("OutputComparisons.txt").open('w') as comparisions:
432+
for jfp in Path(".").rglob("*.java"):
433+
if "gui" in jfp.parts or "swt" in jfp.parts:
434+
continue
435+
if str(jfp) in exclude_files:
436+
continue
437+
generated = generated_output(jfp)
438+
if generated is None:
439+
continue
440+
embedded = embedded_output(jfp)
441+
comp = SequenceMatcher(None, embedded, generated)
442+
ratio = comp.ratio()
443+
if ratio < ratio_target:
444+
print(jfp)
445+
print("ratio: {}\n".format(ratio))
446+
comparisions.write("\n" + ruler(jfp))
447+
comparisions.write("ratio: {}\n".format(ratio))
448+
comparisions.write(ruler("Attached"))
449+
comparisions.write(embedded)
450+
comparisions.write("\n" + ruler("Generated"))
451+
comparisions.write(generated)
452+
with Path("CompareExclusions.txt").open('a') as exclusions:
453+
exclusions.write('r"' + str(jfp) + "\",\n")
454+
if Path("CompareExclusions.txt").is_file():
455+
os.system("ed CompareExclusions.txt")
456+
if Path("OutputComparisons.txt").is_file():
457+
os.system("ed OutputComparisons.txt")
458+
459+
460+
263461
@CmdLine('a')
264462
def attachFiles():
265463
"""Attach standard and error output to all files"""
@@ -278,8 +476,8 @@ def attachFiles():
278476
if j_main.long_output:
279477
longOutput.write(ruler())
280478
longOutput.write(j_main.new_code())
281-
os.system("subl AllFilesWithOutput.txt")
282-
os.system("subl LongOutput.txt")
479+
# os.system("subl AllFilesWithOutput.txt")
480+
# os.system("subl LongOutput.txt")
283481

284482
if __name__ == '__main__': CmdLine.run()
285483

0 commit comments

Comments
 (0)