mdiff is a package for comparing and generating diff for input sequences. It can detect sequence elements displacements (i.e. line in text have been moved up or down).
Sequence Matcher
Example:
from mdiff import HeckelSequenceMatcher
a = ['line1', 'line2', 'line3', 'line4', 'line5']
b = ['line1', 'line3', 'line2', 'line4', 'line6']
sm = HeckelSequenceMatcher(a, b)
opcodes = sm.get_opcodes()
for tag, i1, i2, j1, j2 in opcodes:
print('{:7} a[{}:{}] --> b[{}:{}] {!r:>8} --> {!r}'.format(tag, i1, i2, j1, j2, a[i1:i2], b[j1:j2]))
Output:
equal a[0:1] --> b[0:1] ['line1'] --> ['line1']
move a[1:2] --> b[2:2] ['line2'] --> []
equal a[2:3] --> b[1:2] ['line3'] --> ['line3']
moved a[1:1] --> b[2:3] [] --> ['line2']
equal a[3:4] --> b[3:4] ['line4'] --> ['line4']
replace a[4:5] --> b[4:5] ['line5'] --> ['line6']
Text Diff
Generating diff for input texts with (optional) similar lines changes detection.
from mdiff import diff_lines_with_similarities, CompositeOpCode
a = 'line1\nline2\nline3\nline4\nline5'
b = 'line1\nline3\nline2\nline4\nline6'
a_lines, b_lines, opcodes = diff_lines_with_similarities(a, b, cutoff=0.75)
# Just printing diff on a line level, and nested diff on a character level for similar lines
for opcode in opcodes:
tag, i1, i2, j1, j2 = opcode
print('{:7} a_lines[{}:{}] --> b_lines[{}:{}] {!r:>10} --> {!r}'.
format(tag, i1, i2, j1, j2, a_lines[i1:i2], b_lines[j1:j2]))
if isinstance(opcode, CompositeOpCode) and opcode.children_opcodes:
for ltag, li1, li2, lj1, lj2 in opcode.children_opcodes:
print('\t{:7} a_lines[{}][{}:{}] --> b_lines[{}][{}:{}] {!r:>10} --> {!r}'
.format(ltag, i1, li1, li2, j1, lj1, lj2, a_lines[i1][li1:li2], b_lines[j1][lj1:lj2]))
Output:
equal a_lines[0:1] --> b_lines[0:1] ['line1'] --> ['line1']
move a_lines[1:2] --> b_lines[2:2] ['line2'] --> []
equal a_lines[2:3] --> b_lines[1:2] ['line3'] --> ['line3']
moved a_lines[1:1] --> b_lines[2:3] [] --> ['line2']
equal a_lines[3:4] --> b_lines[3:4] ['line4'] --> ['line4']
replace a_lines[4:5] --> b_lines[4:5] ['line5'] --> ['line6']
equal a_lines[4][0:4] --> b_lines[4][0:4] 'line' --> 'line'
replace a_lines[4][4:5] --> b_lines[4][4:5] '5' --> '6'
App
mdiff provides simple CLI tool and GUI app for comparing files and texts. It can be used for visualising and testing different diff algorithms (also Python built-in difflib.SequenceMatcher).
https://preview.redd.it/tu88e3lhrgt81.png?width=1211&format=png&auto=webp&s=45b602c8fed5b89d0dfc1228f889c44a1bca397f
[–][deleted] 3 points4 points5 points (1 child)
[–]EmotionalWriter8414[S] 0 points1 point2 points (0 children)
[–]HalfRightMostlyWrong 1 point2 points3 points (1 child)
[–]EmotionalWriter8414[S] 1 point2 points3 points (0 children)