summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2024-04-13 22:19:52 -0400
committerRob Austein <sra@hactrn.net>2024-04-13 22:19:52 -0400
commitd2c08cfed1d0d545da42a80c6deaf85fcd844cc6 (patch)
tree00345f34e9caf59fa9d92e1159ec66aa282a4a9e
parent42e215baae5ba124cf4aa66a79bf68d4fe2e29c1 (diff)
doc
-rw-r--r--README.md30
-rwxr-xr-xrfc1982_serial_number.py35
2 files changed, 64 insertions, 1 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3537697
--- /dev/null
+++ b/README.md
@@ -0,0 +1,30 @@
+# Implementation of RFC 1982 Serial Number Arithmetic.
+
+Run as a program, this takes start and finish serial values and tells
+you what intermediate steps (if any) are needed to make the specified
+change.
+
+Used as a module, this implements the `Serial` class and an iterator
+which returns the intermediate steps (if any) needed between two
+`Serial` values.
+
+Per the RFC, only two operations are defined on `Serial` objects:
+addition and comparision, both within a restricted range specified
+by the RFC.
+
+The default modulus is `2**32`, you can change this by subclassing the
+`Serial` and overriding the class's `modulus` variable. The modulus
+must be a power of two.
+
+See RFC 1982 for discussion of the ways in which serial numbers do not
+work like normal integers. In particular, note that there's a corner
+case in which one can have a pair of serial numbers `I1` and `I2`
+where `I1` is neither equal to, less than, nor greater than `I2`.
+This is deliberate and is not a bug in the code. See the RFC.
+
+The `find_intermediate()` iterator takes two `Serial` values `start`
+and `finish` and yields the sequence of intermediate values (if any)
+needed to step from `start` to `finish`.
+
+There are also a couple of test programs that use `random.randint()`
+to generate test values. Maybe someday I'll recode with `unittest`.
diff --git a/rfc1982_serial_number.py b/rfc1982_serial_number.py
index e46974a..bb9988c 100755
--- a/rfc1982_serial_number.py
+++ b/rfc1982_serial_number.py
@@ -1,6 +1,34 @@
#!/usr/bin/env python3
+"""Implementation of RFC 1982 Serial Number Arithmetic.
+
+Run as a program, this takes start and finish serial values and tells
+you what intermediate steps (if any) are needed to make the specified
+change.
+
+Used as a module, this implements the Serial class and an iterator
+which returns the intermediate steps (if any) needed between two
+Serial values.
+"""
+
class Serial:
+ """Implementation of RFC 1982 Serial Number Arithmetic.
+
+ Per the RFC, only two operations are defined on Serial objects:
+ addition and comparision, both within a restricted range specified
+ by the RFC.
+
+ The default modulus is 2**32, you can change this by subclassing
+ the Serial class and overriding the class's modulus variable. The
+ modulus must be a power of two.
+
+ See RFC 1982 for discussion of the ways in which Serial numbers do
+ not work like normal integers. In particular, note that there's a
+ corner case in which one can have a pair of Serial numbers I1 and
+ I2 where I1 is neither equal to, less than, nor greater than I2.
+ This is deliberate and is not a bug in the code. See the RFC.
+
+ """
modulus = 2 ** 32
@@ -40,6 +68,11 @@ class Serial:
return f"{int(self):{len(str(self.modulus))}d}"
def find_intermediate(start, finish):
+ """
+ Find the sequence of intermediate values (if any) needed to step
+ from start to finish
+ """
+
while not (start < finish): # sic: serial numbers are not (quite) integers
start += ((Serial.modulus >> 1) - 1)
yield start
@@ -47,7 +80,7 @@ def find_intermediate(start, finish):
def main():
from argparse import ArgumentParser
- ap = ArgumentParser()
+ ap = ArgumentParser(description = __doc__)
ap.add_argument("start", type = Serial)
ap.add_argument("finish", type = Serial)
args = ap.parse_args()