Structuring code

Libs and snippets for structuring code properly

dataclasses

dataclasses for easy data classes with attributes which may be const

@dataclass(order=True, frozen=True)
class Command:
    command: str
    arguments: List[str]

def createComm(comm, *others) -> Command:
    return Command(comm, others)

def testFeatures():
    cmd1 = createComm(*"go fetch the ball".split())
    cmd2 = createComm(*"come get some food".split())
    print(cmd1, cmd2, sep="\t")
    print(cmd1>cmd2)
    
def testFreeze():
    cmd, *rest = "what does the fox say".split()
    test = Command(cmd, rest)
    test.command = "other"
    print(test.command, test.arguments)

#if __name__ == "__main__":
#    main()

Good clean printing description plus order=True allows for comparisson

testFeatures()
Command(command='go', arguments=('fetch', 'the', 'ball'))   Command(command='come', arguments=('get', 'some', 'food'))
True

Here we can see the frozen=True rises and error when we try to reset an attribute

try:
    testFreeze()
except FrozenInstanceError as e:
    print(e.__class__.__name__, ": ", e)
FrozenInstanceError :  cannot assign to field 'command'

back to top

typing

typing has to be called for type hintting on callables and lists.

  • Not on newer python, apparently
def uDictRandKey(frand: Callable[[List[str],int],List[int]]=np.random.choice,
                 base: str=letters, qty: int=1) -> List[str]:
    keys = []
    numChars = 1
    baseSize = len(set(base))
    while (qty//(baseSize**numChars)): numChars+=1
    
    return frand([*base], size=qty)
np.random.choice([*letters], size=10)
array(['a', 't', 'e', 'r', 'm', 'n', 'e', 'v', 'e', 'i'], dtype='<U1')
uDictRandKey(np.random.choice)
array(['d'], dtype='<U1')

back to top

Protocol

Protocol class implements interfaces in python. “Duck-typing”: if it has the right methods, it is the right type

class call(Protocol):
    def talk():
        ...
    def listen():
        ...
        
class msg(Protocol):
    def write():
        ...
    def read():
        ...
        
class extro:
    def __init__(self, name="Beeblebrot"):
        self.name = name
    def talk(self):
        print(f"{self.name} is talking..")
    def listen(self):
        print(f"{self.name} is not listening..")
    def read(self):
        print(f"{self.name} is not reading..")
    def write(self):
        print(f"{self.name} is writing..")
        
class intro:
    def __init__(self, name="Arthur"):
        self.name = name
    def talk(self):
        print(f"{self.name} is not talking..")
    def listen(self):
        print(f"{self.name} is listening..")
    def read(self):
        print(f"{self.name} is reading..")
    def write(self):
        print(f"{self.name} is not writing..")
        
def phonecall(person1: call, person2: call):
    person1.talk()
    person2.listen()
    person2.talk()
    person1.listen()
    
def textchat(person1: msg, person2: msg):
    person1.write()
    person2.read()
    person2.write()
    person1.read()
    
p1, p2 = extro(), intro()
phonecall(p1,p2)
textchat(p1,p2)
Beeblebrot is talking..
Arthur is listening..
Arthur is not talking..
Beeblebrot is not listening..
Beeblebrot is writing..
Arthur is reading..
Arthur is not writing..
Beeblebrot is not reading..

back to top

partial

partial decorator/class allows for parameter pre setting in functions

def myprint(toPrint,toPrint2):
    print(toPrint,toPrint2)

otherprint = partial(myprint, toPrint2="42")
otherprint("what is 6x8? ")
otherprint("what is 6x7? ")
what is 6x8?  42
what is 6x7?  42

back to top

ABC and abstractmethod

ABC class inheriting and abstractmethod decorator implements abstract classes in python

class absClass(ABC):
    @abstractmethod
    def aMethod(self):
        '''this method does this'''
    
    @abstractmethod
    def bMethod(self):
        '''this method does that'''
        
class concreteClass(absClass):
    
    def aMethod(self):
        print('this method does this')
        return self
        
    def bMethod(self):
        print('this method does that')
        return self
        
def testABC(obj: absClass):
    obj.aMethod().bMethod()
    
testABC(concreteClass())
this method does this
this method does that

back to top