Created
April 23, 2019 14:10
-
-
Save gorenje/57fbde5c9e76541228c064c6cb8730f4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23.Apr.19 14:07:19 AttributeOne set to 1 for topic one because increment to limit | |
23.Apr.19 14:07:19 AttributeOne set to 2 for topic one because increment to limit | |
23.Apr.19 14:07:19 AttributeOne set to 1 for topic one because decrement to limit | |
23.Apr.19 14:07:19 AttributeOne set to 0 for topic one because decrement to limit | |
23.Apr.19 14:07:19 AttributeTwo set to 5 for topic one because limited to max 5 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import types, math, sys, re, inspect, logging | |
from datetime import datetime | |
from collections import defaultdict | |
def tostderr(msg): | |
dstr = datetime.utcnow().strftime('%d.%b.%y %H:%M:%S') | |
for line in str(msg).splitlines(): | |
sys.stderr.write("%s %s\n" % (dstr, line)) | |
## Wrapper Class for handling method chaining and notify the wrapped | |
## object when it needs to modify its values. | |
class Scaler(object): | |
class Wrapper(object): | |
def __init__(self, name, parent): | |
self.name = name | |
self.parent = parent | |
def new_value(self, value, reason=None): | |
self.parent.set_cfg(self.name, value) | |
if reason != None: | |
tostderr("%s set to %s for %s because %s" % ( | |
self.name, value, self.parent, reason | |
)) | |
else: | |
tostderr("%s set to %s for %s" % ( | |
self.name, value, self.parent | |
)) | |
return value | |
@property | |
def current_value(self): | |
return int(self.parent.cfg[self.name]) | |
def __init__(self, parent, direction): | |
self.parent = parent | |
self.direction = direction | |
self.cv = parent.current_value | |
self.amount = None | |
self.lmt = None | |
self.reason = None | |
@classmethod | |
def new(self, cfgname, direction, parent): | |
return Scaler(Scaler.Wrapper(cfgname, parent), direction) | |
def by(self, value): | |
self.amount = value | |
return self | |
def limit(self, value): | |
self.lmt = value | |
return self | |
def cause(self, reason): | |
self.reason = reason | |
return self | |
@property | |
def doit(self): | |
nv = None | |
if self.direction == "inc": | |
nv = self.cv + self.amount | |
nv = min([nv, self.lmt]) or nv | |
elif self.direction == "dec": | |
nv = max([self.cv - self.amount, self.lmt]) | |
else: | |
return False | |
if self.cv == nv: | |
return False | |
return self.parent.new_value(nv, self.reason) | |
## Example of a class that represents configuration values. | |
class Topic(object): | |
def __init__(self, name): | |
self.cfg = defaultdict(lambda: 0, {}) | |
self.name = name | |
def inc(self, cfgname): | |
return Scaler.new(cfgname, "inc", self) | |
def dec(self, cfgname): | |
return Scaler.new(cfgname, "dec", self) | |
def __str__(self): | |
return self.name | |
def set_cfg(self, attrname, value): | |
## This is called when the attrname is changed and can | |
## be used to persist the value, for example, to a database. | |
self.cfg[attrname] = value | |
def main(): | |
# 'topic one' becomes the name of this object. | |
topic = Topic("topic one") | |
UpperLimit = 2 | |
LowerLimit = 0 | |
topic.inc("AttributeOne").by(1).limit(UpperLimit).cause( | |
"increment to limit").doit | |
topic.inc("AttributeOne").by(1).limit(UpperLimit).cause( | |
"increment to limit").doit | |
topic.inc("AttributeOne").by(1).limit(UpperLimit).cause( | |
"increment to limit").doit | |
topic.dec("AttributeOne").by(1).limit(LowerLimit).cause( | |
"decrement to limit").doit | |
topic.dec("AttributeOne").by(1).limit(LowerLimit).cause( | |
"decrement to limit").doit | |
topic.dec("AttributeOne").by(1).limit(LowerLimit).cause( | |
"decrement to limit").doit | |
topic.inc("AttributeTwo").by(10).limit(5).cause("limited to max 5").doit | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment