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 ***NEW!!!
  5. Sequences, Lists & Tuples
       Extract Sequences 
  6. Strings
       Extract Unicode Strings
  7. 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 
  13. Bytes
       Extract Bytes And Strings
       Extract Byte Manipulation 
  14. Binary Files
  15. Text Files
  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

espbook

 

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 )