Browse Source

new class: MMGenRange()

    from mmgen.obj import MMGenRange
    r = MMGenRange('1-5') # initialize with string
    r2 = MMGenRange(1,5)  # or with integers
    assert r == r2
    assert r == (1,5)
    assert r.first == 1
    assert r.last == 5
    assert r.items == [1,2,3,4,5]

    r = MMGenRange('22') # initialize range of one item
    r2 = MMGenRange(22,22)
    assert r == r2

    r = MMGenRange('1-1000000') # memory-frugal iteration
    for n in r.iterate(): print(n)
MMGen 5 years ago
parent
commit
2f274cba2d
1 changed files with 44 additions and 0 deletions
  1. 44 0
      mmgen/obj.py

+ 44 - 0
mmgen/obj.py

@@ -317,6 +317,50 @@ class AddrIdxList(list,InitErrors,MMGenObject):
 			m = "{!r}: value cannot be converted to AddrIdxList ({})"
 			m = "{!r}: value cannot be converted to AddrIdxList ({})"
 			return type(self).init_fail(m.format(idx_list or fmt_str,e.args[0]),on_fail)
 			return type(self).init_fail(m.format(idx_list or fmt_str,e.args[0]),on_fail)
 
 
+class MMGenRange(tuple,InitErrors,MMGenObject):
+
+	min_idx = None
+	max_idx = None
+
+	def __new__(cls,*args,on_fail='die'):
+		cls.arg_chk(cls,on_fail)
+		try:
+			if len(args) == 1:
+				s = args[0]
+				if type(s) == cls: return s
+				assert issubclass(type(s),str),'not a string or string subclass'
+				ss = s.split('-',1)
+				first = int(ss[0])
+				last = int(ss.pop())
+			else:
+				s = repr(args) # needed if exception occurs
+				assert len(args) == 2,'one format string arg or two start,stop args required'
+				first,last = args
+			assert first <= last, 'start of range greater than end of range'
+			if cls.min_idx is not None:
+				assert first >= cls.min_idx, 'start of range < {:,}'.format(cls.min_idx)
+			if cls.max_idx is not None:
+				assert last <= cls.max_idx, 'end of range > {:,}'.format(cls.max_idx)
+			return tuple.__new__(cls,(first,last))
+		except Exception as e:
+			m = "{!r}: value cannot be converted to {} ({})"
+			return cls.init_fail(m.format(s,cls.__name__,e.args[0]),on_fail)
+
+	@property
+	def first(self):
+		return self[0]
+
+	@property
+	def last(self):
+		return self[1]
+
+	def iterate(self):
+		return range(self[0],self[1]+1)
+
+	@property
+	def items(self):
+		return list(self.iterate())
+
 class UnknownCoinAmt(Decimal): pass
 class UnknownCoinAmt(Decimal): pass
 
 
 class BTCAmt(Decimal,Hilite,InitErrors):
 class BTCAmt(Decimal,Hilite,InitErrors):