I want to know the best practices for extending the functionality of a sage class. For example, I would like to add the following method to the Partition class in sage:#\lambda^(i) from Carrell-Goulding paperdef i_part(self,i):if i==0:return selfelif i<0:return (self.conjugate().i_part(-i)).conjugate()zero_one_sequence = self.zero_one_sequence()num_ones = zero_one_sequence.count(1)if num_ones < i:zero_one_sequence += (i-num_ones)*[1]index_one_list = [index for index in range(len(zero_one_sequence)) if zero_one_sequence[index] == 1]zero_one_sequence[index_one_list[i-1]]=0return Partitions().from_zero_one(zero_one_sequence)My first inclination is to subclass Partition and add this as a method to the subclass. However, I am not able to make this work.
def add_method_to_class(klass):
r"""
Add a new method to a pre-existing class.
"""
def add_func(func):
setattr(klass,func.func_name,func)
return func
return add_func
@add_method_to_class(Partition)
def i_part(self,i):
if i==0:
return self
elif i<0:
return (self.conjugate().i_part(-i)).conjugate()
zero_one_sequence = self.zero_one_sequence()
num_ones = zero_one_sequence.count(1)
if num_ones < i:
zero_one_sequence += (i-num_ones)*[1]
index_one_list = [index for index in range(len(zero_one_sequence)) if zero_one_sequence[index] == 1]
zero_one_sequence[index_one_list[i-1]]=0
return Partitions().from_zero_one(zero_one_sequence)
sage: mu=Partition([4,3,1])
sage: mu.i_part(0)
[4, 3, 1]
sage: mu.i_part(1)
[3, 2]
sage: mu.i_part(2)
[3, 2, 1, 1]
sage: mu.i_part(3)
[3, 2, 2, 1]
sage: mu.i_part(-3)
[5, 4]
Partition.i_part = i_partThen if later I wrote:p = Partition([3,2,1])I can callp.i_part(2)
Ideally, I would like to define a subclass of Partition called MyPartition and include all my custom methods. I think this is a standard way to extend libraries, but for some reason this doesn't work at all. Is there a solution that is more in the spirit of subclassing?
Ideally, I would like to define a subclass of Partition called MyPartition and include all my custom methods. I think this is a standard way to extend libraries, but for some reason this doesn't work at all. Is there a solution that is more in the spirit of subclassing?
Ideally, I would like to define a subclass of Partition called MyPartition and include all my custom methods. I think this is a standard way to extend libraries, but for some reason this doesn't work at all. Is there a solution that is more in the spirit of subclassing?
from sage.structure.element import Element
from sage.structure.global_options import GlobalOptions
from sage.combinat.partition import PartitionOptions
class MyPartition(Partition):
@staticmethod
def __classcall_private__(cls, mu=None, **keyword):
return MyPartitions()(super(MyPartition,cls).__classcall_private__(cls,mu,**keyword))
def fred(self):
return "fred"
class MyPartitions(Partitions):
Element=MyPartition
global_options=PartitionOptions
Quite likely there will be more tweaks to get this to work fully, but it certainly gets things going:
%attach mypartiiton.py
sage: MyPartition([3,2])
[3, 2]
sage: mu=MyPartition([3,2]).cells()
sage: mu=MyPartition([3,2]).fred()
sage: MyPartition([3,2])
[3, 2]
sage: MyPartition([3,2]).cells()
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1)]
sage: MyPartition([3,2]).fred()
'fred'