From 54d6f7406af48e103c0d7e3ed33d5199a826e95a Mon Sep 17 00:00:00 2001
From: Jameson Graef Rollins <jrollins@finestructure.net>
Date: Wed, 29 Aug 2018 13:27:43 -0700
Subject: [PATCH] new Struct.diff() method to return list of differences with
 another struct

returns list of (param, value, other_value) tuples.

command line interface added as well.
---
 gwinc/__main__.py | 14 ++++++++++++++
 gwinc/struct.py   | 20 ++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/gwinc/__main__.py b/gwinc/__main__.py
index a98441ec..0d598ffb 100644
--- a/gwinc/__main__.py
+++ b/gwinc/__main__.py
@@ -78,6 +78,8 @@ group.add_argument('--yaml', '-y', action='store_true',
                    help="print IFO as yaml to stdout and exit")
 group.add_argument('--text', '-x', action='store_true',
                    help="print IFO as text table to stdout and exit")
+group.add_argument('--diff', '-d', metavar='IFO',
+                   help="show differences table between another IFO description")
 group.add_argument('--no-plot', '-np', action='store_false', dest='plot',
                    help="supress plotting")
 parser.add_argument('IFO', default=IFO,
@@ -109,6 +111,18 @@ def main():
     if args.text:
         print(ifo.to_txt(), end='')
         return
+    if args.diff:
+        fmt = '{:30} {:>20} {:>20}'
+        ifoo = load_ifo(args.diff)
+        diffs = ifo.diff(ifoo)
+        if diffs:
+            print(fmt.format('', args.IFO, args.diff))
+            for p in diffs:
+                k = str(p[0])
+                v = repr(p[1])
+                ov = repr(p[2])
+                print(fmt.format(k, v, ov))
+        return
     if args.plot:
         if args.save:
             # FIXME: this silliness seems to be the only way to have
diff --git a/gwinc/struct.py b/gwinc/struct.py
index c36418b8..568378e8 100644
--- a/gwinc/struct.py
+++ b/gwinc/struct.py
@@ -196,6 +196,26 @@ class Struct(object):
                 except (AttributeError, TypeError):
                     yield k, v
 
+
+    def diff(self, other):
+        """Return tuple of differences between target IFO.
+
+        Returns list of (key, value, other_value) tuples.  Value is
+        None if key not present.
+
+        """
+        diffs = []
+        for k, ov in other.walk():
+            v = self.get(k, None)
+            if ov != v and ov is not v:
+                diffs.append((k, v, ov))
+        for k, v in self.walk():
+            ov = other.get(k, None)
+            if ov is None:
+                diffs.append((k, v, ov))
+        return diffs
+
+
     def to_txt(self, path=None, fmt='0.6e', delimiter=': ', end=''):
         """Return text represenation of Struct, one element per line.
 
-- 
GitLab