Rob Austein преди 7 месеца
родител
ревизия
35224a5803
променени са 1 файла, в които са добавени 27 реда и са изтрити 20 реда
  1. 27 20
      rfc1982_serial_number.py

+ 27 - 20
rfc1982_serial_number.py

@@ -2,21 +2,27 @@
 
 class Serial:
 
-    _modulus = 2 ** 32
-    _bitmask = _modulus - 1
-    _signbit = _modulus >> 1
+    modulus = 2 ** 32
+
+    @property
+    def bitmask(self):
+        return self.modulus - 1
+
+    @property
+    def signbit(self):
+        return self.modulus >> 1
 
     def __init__(self, val):
-        self._val = int(val) & self._bitmask
+        self._val = int(val) & self.bitmask
 
     def __add__(self, val):
-        return self.__class__(self._val + int(val))
+        return type(self)(self._val + int(val))
 
     def __le__(self, other):
-        return (self._modulus - int(self) + int(other)) & self._signbit == 0
+        return (self.modulus - int(self) + int(other)) & self.signbit == 0
 
     def __ge__(self, other):
-        return (self._modulus + int(self) - int(other)) & self._signbit == 0
+        return (self.modulus + int(self) - int(other)) & self.signbit == 0
 
     def __eq__(self, other):
         return int(self) == int(other)
@@ -34,25 +40,26 @@ class Serial:
         return self._val
 
     def __str__(self):
-        return str(int(self))
+        return f"{int(self):{len(str(self.modulus))}d}"
+
+def step(start, finish):
+    if start < finish:
+        return start, finish
+    else:
+        midpoint = start + ((Serial.modulus >> 1) - 2)
+        assert start < midpoint and midpoint < finish
+        return start, midpoint, finish
 
 if __name__ == "__main__":
     from random import randint
 
     for test in range(100):
-        i1 = Serial(randint(0, 2**32-1))
-        i2 = Serial(randint(0, 2**32-1))
+        i1 = Serial(randint(0, Serial.modulus - 1))
+        i2 = Serial(randint(0, Serial.modulus - 1))
 
         assert i1 == i2 or \
             (i1 < i2 and not (i1 > i2)) or \
             (i1 > i2 and not (i1 < i2)) or \
-            int(i1) & int(i2) == 0x80000000
-
-        if i1 == i2:
-            print(f"{int(i1):10d} == {int(i2):10d}, how did that happen?")
-        elif i1 < i2:
-            print(f"{int(i1):10d} => {int(i2):10d}, can do it in one jump")
-        else:
-            i3 = i1 + (2**31 - 2)
-            print(f"{int(i1):10d} => {int(i2):10d}, need to wrap, i3 value {i3}")
-            assert i1 < i3 and i3 < i2
+            int(i1) & int(i2) == Serial.modulus >> 1
+
+        print(f"{i1} => {i2}: {', '.join(str(s) for s in step(i1, i2))}")