Programmer's Python Data - A Custom Data Class
Written by Mike James   
Monday, 15 January 2024
Article Index
Programmer's Python Data - A Custom Data Class
Node Numbering
Equality and Hash
The Complete Tree
from math import log2
import numbers
import collections.abc
class Tree(collections.abc.Sequence):
 
    class Node:
        def __init__(self,value):
            self.left=None
            self.right=None
            self.value=value 
    def __init__(self,value):
        self.root=Tree.Node(value)
        self.len=1 
    def appendBreathFirst(self,value):
        queue=[self.root]
        while len(queue)>0:
            node=queue.pop(0)
            if node.left is None:
                node.left=Tree.Node(value)
                self.len+=1 
                return node.left
            queue.append(node.left)
            if node.right is None:
                node.right=Tree.Node(value)
                self.len+=1 
                return node.right
            queue.append(node.right)
    def getNode(self,key):
        if key>=len(self) or key<0:
            raise IndexError('Index out of range') 
        if key==0:
            return self.root
        row=int(log2(key+1))
        currentNode=self.root
        for r in range(1,row+1):
            k=int((key+1)/2**(row-r)-1)
            if k%2 :
                currentNode=currentNode.left
            else:
                currentNode=currentNode.right
        return currentNode
    def setNode(self,key,node):
        row=int(log2(key+1))
        currentNode=self.root
        
        for r in range(1,row):
            f=2**(row-r)
            k=int((key+1- f)/f)
            
            if k%2 :
                currentNode=currentNode.left
            else:
                currentNode=currentNode.right
        if key%2 :
            currentNode.left=node
        else:
            currentNode.right=node
    
    def __len__(self):
        return self.len
    def __getitem__(self,key):
        if isinstance(key,slice):
            temp=[]
            for i in range(0,len(self))[key]:
                temp.append(self.getNode(i))
            return temp
        if isinstance(key,int): 
            return self.getNode(key)
        raise TypeError("invalid index")
                          
    def __setitem__(self,key,value):
        if isinstance(key,slice) and
isinstance(value,list): for i in range(0,len(self))[key]: self.getNode(i).value=value.pop(0) elif isinstance(key,int): self.getNode(key).value=value else: raise TypeError("invalid index or value") def __imul__(self,m): if isinstance(m,numbers.Number): for i in range(0,len(self)): self.getNode(i).value*= m return self def __eq__(self,otherTree): if not isinstance(otherTree,Tree): return NotImplemented if len(self)!=len(otherTree): return False for i in range(0,len(self)): if self.getNode(i).value!= otherTree.getNode(i).value: return False return True def __hash__(self): temp=[] for i in range(0,len(self)): temp.append(self.getNode(i).value) return hash(tuple(temp))

Summary

  • Adding indexing to custom data classes is a matter of defining the __getitem__ and __setitem__ methods.

  • Extending indexing to slicing is also easy, but actually handling a general slice object is tricky.

  • Python makes defining operators very easy as each operator has its own __operator__ function that you can redefine.

  • Two objects that test as equal should return the same hash value.

  • Making a data class hashable is much easier than you might expect using the supplied __hash__ function on its components.

  • Python is not strongly-typed and this is mostly good, but there are some drawbacks of the approach.

  • The idea of Abstract Base Classes (ABC) combined with multiple inheritance provides a facility that is more powerful and logical than abstract single inheritance and interfaces.

  • Using the abc module and its ability to register an arbitrary class as a subclass of another without involving inheritance is a powerful and useful ability.

  • The predefined ABC classes, numbers and collections, can help you implement your own data classes.

  • Although abstract classes provide a way of ensuring that a class has a particular attribute, sometimes it is useful to be able to dynamically add attributes to classes and instances and this is possible using getattr and setattr.

  • You can also use dynamic attributes to create extension methods, but this doesn’t work on built-in types.

Programmer's Python
Everything is Data

Is now available as a print book: Amazon

pythondata360Contents

  1. Python – A Lightning Tour
  2. The Basic Data Type – Numbers
       Extract: Bignum
  3. Truthy & Falsey
  4. Dates & Times
       Extract Naive Dates
  5. Sequences, Lists & Tuples
       Extract Sequences 
  6. Strings
       Extract Unicode Strings
  7. Regular Expressions
       Extract Simple Regular Expressions 
  8. The Dictionary
       Extract The Dictionary 
  9. Iterables, Sets & Generators
       Extract  Iterables 
  10. Comprehensions
       Extract  Comprehensions 
  11. Data Structures & Collections
       Extract Stacks, Queues and Deques
      
    Extract Named Tuples and Counters
  12. Bits & Bit Manipulation
       Extract Bits and BigNum 
       Extract Bit Masks
  13. Bytes
       Extract Bytes And Strings
       Extract Byte Manipulation 
  14. Binary Files
       Extract Files and Paths 
  15. Text Files
       Extract Text Files & CSV 
       Extract JSON ***NEW!!!
  16. Creating Custom Data Classes
        Extract A Custom Data Class 
  17. Python and Native Code
        Extract   Native Code
    Appendix I Python in Visual Studio Code
    Appendix II C Programming Using Visual Studio Code

<ASIN:1871962765>

<ASIN:1871962749>

<ASIN:1871962595>

<ASIN:B0CK71TQ17>

<ASIN:187196265X>

Related Articles

Creating The Python UI With Tkinter

Creating The Python UI With Tkinter - The Canvas Widget

The Python Dictionary

Arrays in Python

Advanced Python Arrays - Introducing NumPy

pico book

 

Comments




or email your comment to: comments@i-programmer.info

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

Banner



Last Updated ( Monday, 15 January 2024 )