Skip to content

Instantly share code, notes, and snippets.

@achilleas-k
Created April 25, 2022 19:07
Show Gist options
  • Save achilleas-k/2802e529a4e31cfdfe9a7454e466b92a to your computer and use it in GitHub Desktop.
Save achilleas-k/2802e529a4e31cfdfe9a7454e466b92a to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import argparse
import json
def loadjson(fname: str):
with open(fname, mode="r", encoding="utf-8") as jsonfile:
return json.load(jsonfile)
def difflist(alist, blist):
acopy = list(alist)
for bv in blist:
try:
acopy.remove(bv)
except ValueError:
pass
bcopy = list(blist)
for av in alist:
try:
bcopy.remove(av)
except ValueError:
pass
diff = {}
if acopy:
diff["a"] = acopy
if bcopy:
diff["b"] = bcopy
return diff
def calcdiff(adata, bdata):
diff = {}
if adata == bdata:
return diff
if isinstance(adata, dict) and isinstance(bdata, dict):
only_in_a = []
for ak, av in adata.items():
bv = bdata.get(ak)
if bv is None:
only_in_a.append({ak: av})
kdiff = calcdiff(av, bv)
if kdiff:
diff[ak] = kdiff
if only_in_a:
diff["only-in-a"] = only_in_a
# find keys that are only in b
only_in_b = []
for bk in bdata.keys():
if adata.get(bk) is None:
only_in_b.append({bk: bv})
if only_in_b:
diff["only-in-b"] = only_in_b
elif isinstance(adata, list) and isinstance(bdata, list):
diff.update(difflist(adata, bdata))
else:
diff["a"] = adata
diff["b"] = bdata
return diff
def describe(diff):
# TODO: simplify and make it readable
print(json.dumps(diff, indent=2))
def main():
parser = argparse.ArgumentParser()
parser.add_argument("a")
parser.add_argument("b")
args = parser.parse_args()
a = args.a
b = args.b
adata = loadjson(a)
bdata = loadjson(b)
diff_data = calcdiff(adata, bdata)
describe(diff_data)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment