Skip to content

Commit 31dc911

Browse files
authored
Merge pull request #383 from bharatm29/main
add pydiff: A simple file diff python script
2 parents 4743938 + 61f1e16 commit 31dc911

File tree

4 files changed

+161
-0
lines changed

4 files changed

+161
-0
lines changed

OTHERS/PyDiff/README.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## PyDiff
2+
A simple python script to compare two files using *Dynamic Programming* based algorithm.
3+
4+
Usage:
5+
```sh
6+
py pydiff.py file1.txt file2.txt
7+
```
8+
9+
Output:
10+
```sh
11+
file1.txt | - 13 | mattis justo quis porta porttitor.
12+
file2.txt | + 13 | Aenean mattis justo quis porta porttitor.
13+
file1.txt | - 10 | Nullam elementum nunc in massa fringilla, sit amet iaculis elit blandit.
14+
file2.txt | + 10 | elementum nunc in massa fringilla, sit amet iaculis elit blandit.
15+
```

OTHERS/PyDiff/file1.txt

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
2+
Nulla volutpat mauris in magna posuere, in volutpat turpis pulvinar.
3+
Mauris semper ante non maximus vulputate.
4+
Fusce sollicitudin justo ut arcu blandit, id feugiat ex rhoncus.
5+
Suspendisse lacinia nisl sit amet vestibulum varius.
6+
Sed vestibulum erat in urna tempus mollis.
7+
Aliquam varius lectus eget dui consequat, sed aliquet diam ultricies.
8+
Sed a lectus a orci blandit accumsan.
9+
Etiam eu augue ac ipsum tempus lobortis at vitae nibh.
10+
Nullam elementum nunc in massa fringilla, sit amet iaculis elit blandit.
11+
Nam et nulla fermentum ligula laoreet malesuada sed nec risus.
12+
Pellentesque maximus velit non massa faucibus, vel aliquam ante pharetra.
13+
mattis justo quis porta porttitor.
14+
Donec dignissim ligula et pretium feugiat.

OTHERS/PyDiff/file2.txt

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
2+
Nulla volutpat mauris in magna posuere, in volutpat turpis pulvinar.
3+
Mauris semper ante non maximus vulputate.
4+
Fusce sollicitudin justo ut arcu blandit, id feugiat ex rhoncus.
5+
Suspendisse lacinia nisl sit amet vestibulum varius.
6+
Sed vestibulum erat in urna tempus mollis.
7+
Aliquam varius lectus eget dui consequat, sed aliquet diam ultricies.
8+
Sed a lectus a orci blandit accumsan.
9+
Etiam eu augue ac ipsum tempus lobortis at vitae nibh.
10+
elementum nunc in massa fringilla, sit amet iaculis elit blandit.
11+
Nam et nulla fermentum ligula laoreet malesuada sed nec risus.
12+
Pellentesque maximus velit non massa faucibus, vel aliquam ante pharetra.
13+
Aenean mattis justo quis porta porttitor.
14+
Donec dignissim ligula et pretium feugiat.

OTHERS/PyDiff/pydiff.py

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#!/usr/bin/env python3
2+
3+
import argparse
4+
5+
6+
class Colors:
7+
HEADER = '\033[95m'
8+
OKBLUE = '\033[94m'
9+
OKCYAN = '\033[96m'
10+
OKGREEN = '\033[92m'
11+
WARNING = '\033[93m'
12+
FAIL = '\033[91m'
13+
ENDC = '\033[0m'
14+
BOLD = '\033[1m'
15+
UNDERLINE = '\033[4m'
16+
17+
18+
ADD = "Add"
19+
REMOVE = "Remove"
20+
IGNORE = "Ignore"
21+
22+
def print_matrix(m1, m2):
23+
for i in range(len(m1) + 1):
24+
for j in range(len(m2) + 1):
25+
print(f"{m1[i][j]}({m2[i][j]})", end=", ")
26+
print()
27+
28+
29+
def main():
30+
parser = argparse.ArgumentParser()
31+
parser.add_argument("file1")
32+
parser.add_argument("file2")
33+
args = parser.parse_args()
34+
35+
file1 = args.file1
36+
file2 = args.file2
37+
38+
with open(file1, 'r') as f:
39+
file_content1 = f.read()
40+
41+
with open(file2, 'r') as f:
42+
file_content2 = f.read()
43+
44+
lines1 = file_content1.splitlines()
45+
lines2 = file_content2.splitlines()
46+
47+
n = len(lines1)
48+
m = len(lines2)
49+
50+
distances = [[0 for _ in range(m + 1)] for _ in range(n + 1)]
51+
action = [['0' for _ in range(m + 1)] for _ in range(n + 1)]
52+
53+
distances[0][0] = 0
54+
action[0][0] = IGNORE
55+
56+
for j in range(1, m + 1):
57+
i = 0
58+
distances[i][j] = j
59+
action[i][j] = ADD
60+
61+
for i in range(1, n + 1):
62+
j = 0
63+
distances[i][j] = i
64+
action[i][j] = REMOVE
65+
66+
for i in range(1, n + 1):
67+
for j in range(1, m + 1):
68+
if lines1[i - 1] == lines2[j - 1]:
69+
action[i][j] = IGNORE
70+
distances[i][j] = distances[i - 1][j - 1]
71+
continue
72+
73+
removeOps = distances[i - 1][j]
74+
addOps = distances[i][j - 1]
75+
76+
distances[i][j] = removeOps
77+
action[i][j] = REMOVE
78+
79+
if distances[i][j] > addOps:
80+
distances[i][j] = addOps
81+
action[i][j] = ADD
82+
83+
distances[i][j] += 1
84+
85+
i = n
86+
j = m
87+
res = []
88+
89+
while i > 0 and j > 0:
90+
_action = action[i][j]
91+
if _action == IGNORE:
92+
i -= 1
93+
j -= 1
94+
elif _action == ADD:
95+
j -= 1
96+
res.append((file2, ADD, j + 1, lines2[j]))
97+
elif _action == REMOVE:
98+
i -= 1
99+
res.append((file1, REMOVE, i + 1, lines1[i]))
100+
else:
101+
raise Exception("Unhandled action")
102+
103+
if not res:
104+
print(f"{Colors.HEADER}They are the same :){Colors.ENDC}")
105+
exit(0)
106+
107+
for (fname, ac, lineno, line) in res:
108+
if ac == ADD:
109+
print(fr"{Colors.HEADER}{fname}{Colors.ENDC} | {
110+
Colors.OKGREEN}+ {lineno} | {line}{Colors.ENDC}")
111+
112+
elif ac == REMOVE:
113+
print(fr"{Colors.HEADER}{fname}{Colors.ENDC} | {
114+
Colors.FAIL}- {lineno} | {line}{Colors.ENDC}")
115+
116+
117+
if __name__ == "__main__":
118+
main()

0 commit comments

Comments
 (0)