ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Thu, 23 Jan 2020 16:45:28 +0100Attempting to enrich quiver class yields "unexpected keyword argument" errorhttps://ask.sagemath.org/question/49636/attempting-to-enrich-quiver-class-yields-unexpected-keyword-argument-error/ I would like to do some computations with preprojective algebras, variations on the path algebra of a quiver in which every arrow has a partner going the other direction. I will want to construct representations of the "double quiver" in which I can conveniently compare the linear map associated to each arrow to that of its partner.
I figured I should create a class (something I haven't done in Python before) inheriting from DiGraph which has the extra data of a dictionary pairing the edges. My code to do this, with the constructor taking an arbitrary quiver and adding reversed copies of all the edges, is as follows:
class DoubleQuiver(sage.graphs.digraph.DiGraph):
def __init__(self, digraph):
edges = []
self._edgePairs = {}
for e in digraph.edges():
self._edgePairs[(e[0], e[1], e[2] + '0')] = (e[1], e[0], e[2] + '1')
self._edgePairs[(e[1], e[0], e[2] + '1')] = (e[0], e[1], e[2] + '0')
edges.append((e[0], e[1], e[2] + '0'))
edges.append((e[1], e[0], e[2] + '1'))
super(DoubleQuiver, self).__init__(edges, multiedges=True)
def flip(self, edge):
assert edge in self.edges()
return self._edgePairs[edge]
If I make a test digraph and run
DoubleQuiver(test)
it runs fine, and running methods like edges() or vertices() produces the results I expected. However, when I attempt to evaluate
DoubleQuiver(test).path_semigroup()
I get an error:
Error in lines 1-1
Traceback (most recent call last):
File "/cocalc/lib/python2.7/site-packages/smc_sagews/sage_server.py", line 1234, in execute
flags=compile_flags), namespace, locals)
File "", line 1, in <module>
File "/ext/sage/sage-8.9_1804/local/lib/python2.7/site-packages/sage/graphs/digraph.py", line 2511, in path_semigroup
return PathSemigroup(self)
File "sage/misc/classcall_metaclass.pyx", line 335, in sage.misc.classcall_metaclass.ClasscallMetaclass.__call__ (build/cythonized/sage/misc/classcall_metaclass.c:1741)
return cls.classcall(cls, *args, **kwds)
File "/ext/sage/sage-8.9_1804/local/lib/python2.7/site-packages/sage/quivers/path_semigroup.py", line 118, in __classcall__
Q = Q.copy(immutable=True, weighted=True)
File "/ext/sage/sage-8.9_1804/local/lib/python2.7/site-packages/sage/graphs/generic_graph.py", line 1206, in copy
data_structure=data_structure)
TypeError: __init__() got an unexpected keyword argument 'weighted'
How should I modify my class definition to avoid this error, or is there a better way of accomplishing what I'm trying to do? (Also, is it relevant that I'm trying this on CoCalc?)Wed, 22 Jan 2020 01:03:17 +0100https://ask.sagemath.org/question/49636/attempting-to-enrich-quiver-class-yields-unexpected-keyword-argument-error/Answer by eric_g for <p>I would like to do some computations with preprojective algebras, variations on the path algebra of a quiver in which every arrow has a partner going the other direction. I will want to construct representations of the "double quiver" in which I can conveniently compare the linear map associated to each arrow to that of its partner. </p>
<p>I figured I should create a class (something I haven't done in Python before) inheriting from DiGraph which has the extra data of a dictionary pairing the edges. My code to do this, with the constructor taking an arbitrary quiver and adding reversed copies of all the edges, is as follows:</p>
<pre><code>class DoubleQuiver(sage.graphs.digraph.DiGraph):
def __init__(self, digraph):
edges = []
self._edgePairs = {}
for e in digraph.edges():
self._edgePairs[(e[0], e[1], e[2] + '0')] = (e[1], e[0], e[2] + '1')
self._edgePairs[(e[1], e[0], e[2] + '1')] = (e[0], e[1], e[2] + '0')
edges.append((e[0], e[1], e[2] + '0'))
edges.append((e[1], e[0], e[2] + '1'))
super(DoubleQuiver, self).__init__(edges, multiedges=True)
def flip(self, edge):
assert edge in self.edges()
return self._edgePairs[edge]
</code></pre>
<p>If I make a test digraph and run</p>
<pre><code>DoubleQuiver(test)
</code></pre>
<p>it runs fine, and running methods like edges() or vertices() produces the results I expected. However, when I attempt to evaluate</p>
<pre><code>DoubleQuiver(test).path_semigroup()
</code></pre>
<p>I get an error:</p>
<pre><code>Error in lines 1-1
Traceback (most recent call last):
File "/cocalc/lib/python2.7/site-packages/smc_sagews/sage_server.py", line 1234, in execute
flags=compile_flags), namespace, locals)
File "", line 1, in <module>
File "/ext/sage/sage-8.9_1804/local/lib/python2.7/site-packages/sage/graphs/digraph.py", line 2511, in path_semigroup
return PathSemigroup(self)
File "sage/misc/classcall_metaclass.pyx", line 335, in sage.misc.classcall_metaclass.ClasscallMetaclass.__call__ (build/cythonized/sage/misc/classcall_metaclass.c:1741)
return cls.classcall(cls, *args, **kwds)
File "/ext/sage/sage-8.9_1804/local/lib/python2.7/site-packages/sage/quivers/path_semigroup.py", line 118, in __classcall__
Q = Q.copy(immutable=True, weighted=True)
File "/ext/sage/sage-8.9_1804/local/lib/python2.7/site-packages/sage/graphs/generic_graph.py", line 1206, in copy
data_structure=data_structure)
TypeError: __init__() got an unexpected keyword argument 'weighted'
</code></pre>
<p>How should I modify my class definition to avoid this error, or is there a better way of accomplishing what I'm trying to do? (Also, is it relevant that I'm trying this on CoCalc?)</p>
https://ask.sagemath.org/question/49636/attempting-to-enrich-quiver-class-yields-unexpected-keyword-argument-error/?answer=49653#post-id-49653If you look at the `__init__()` method of the class you are inheriting from, you will notice that it has a keyword argument `weighted`, as well as many other keyword arguments; simply type
DiGraph.__init__?
to see this. To have a description of these arguments, type
DiGraph?
So, I would say that the `__init__()` method of your class should have a keyword argument `weighted` (possibly with the default value `None`) and should pass it to `super(DoubleQuiver, self).__init__()` as follows:
super(DoubleQuiver, self).__init__(edges, multiedges=True, weighted=weighted)Wed, 22 Jan 2020 22:48:44 +0100https://ask.sagemath.org/question/49636/attempting-to-enrich-quiver-class-yields-unexpected-keyword-argument-error/?answer=49653#post-id-49653Answer by Will Dana for <p>I would like to do some computations with preprojective algebras, variations on the path algebra of a quiver in which every arrow has a partner going the other direction. I will want to construct representations of the "double quiver" in which I can conveniently compare the linear map associated to each arrow to that of its partner. </p>
<p>I figured I should create a class (something I haven't done in Python before) inheriting from DiGraph which has the extra data of a dictionary pairing the edges. My code to do this, with the constructor taking an arbitrary quiver and adding reversed copies of all the edges, is as follows:</p>
<pre><code>class DoubleQuiver(sage.graphs.digraph.DiGraph):
def __init__(self, digraph):
edges = []
self._edgePairs = {}
for e in digraph.edges():
self._edgePairs[(e[0], e[1], e[2] + '0')] = (e[1], e[0], e[2] + '1')
self._edgePairs[(e[1], e[0], e[2] + '1')] = (e[0], e[1], e[2] + '0')
edges.append((e[0], e[1], e[2] + '0'))
edges.append((e[1], e[0], e[2] + '1'))
super(DoubleQuiver, self).__init__(edges, multiedges=True)
def flip(self, edge):
assert edge in self.edges()
return self._edgePairs[edge]
</code></pre>
<p>If I make a test digraph and run</p>
<pre><code>DoubleQuiver(test)
</code></pre>
<p>it runs fine, and running methods like edges() or vertices() produces the results I expected. However, when I attempt to evaluate</p>
<pre><code>DoubleQuiver(test).path_semigroup()
</code></pre>
<p>I get an error:</p>
<pre><code>Error in lines 1-1
Traceback (most recent call last):
File "/cocalc/lib/python2.7/site-packages/smc_sagews/sage_server.py", line 1234, in execute
flags=compile_flags), namespace, locals)
File "", line 1, in <module>
File "/ext/sage/sage-8.9_1804/local/lib/python2.7/site-packages/sage/graphs/digraph.py", line 2511, in path_semigroup
return PathSemigroup(self)
File "sage/misc/classcall_metaclass.pyx", line 335, in sage.misc.classcall_metaclass.ClasscallMetaclass.__call__ (build/cythonized/sage/misc/classcall_metaclass.c:1741)
return cls.classcall(cls, *args, **kwds)
File "/ext/sage/sage-8.9_1804/local/lib/python2.7/site-packages/sage/quivers/path_semigroup.py", line 118, in __classcall__
Q = Q.copy(immutable=True, weighted=True)
File "/ext/sage/sage-8.9_1804/local/lib/python2.7/site-packages/sage/graphs/generic_graph.py", line 1206, in copy
data_structure=data_structure)
TypeError: __init__() got an unexpected keyword argument 'weighted'
</code></pre>
<p>How should I modify my class definition to avoid this error, or is there a better way of accomplishing what I'm trying to do? (Also, is it relevant that I'm trying this on CoCalc?)</p>
https://ask.sagemath.org/question/49636/attempting-to-enrich-quiver-class-yields-unexpected-keyword-argument-error/?answer=49654#post-id-49654I believe I've found the issue. The \__init__() referred to in the error message seems to be that of the class I'm defining. Presumably when I run the path_semigroup() method, it attempts to initialize a new DoubleQuiver for some reason, and includes an input for the "weighted" argument, something that the DiGraph constructor takes but the DoubleQuiver constructor, as written, does not.
Inserting **kwargs into the arguments of \__init__ and the call it makes to DiGraph's \__init__ appears to fix the problem by allowing for any missing arguments:
def __init__(self, digraph, multiedges=True, **kwargs):
edges = []
self._edgePairs = {}
for e in digraph.edges():
self._edgePairs[(e[0], e[1], e[2] + '0')] = (e[1], e[0], e[2] + '1')
self._edgePairs[(e[1], e[0], e[2] + '1')] = (e[0], e[1], e[2] + '0')
edges.append((e[0], e[1], e[2] + '0'))
edges.append((e[1], e[0], e[2] + '1'))
super(DoubleQuiver, self).__init__(edges, multiedges=True, **kwargs)
----------
An aside: Another problem that this revealed, which provides further evidence that path_semigroup() calls \__init__ again, is that the resulting path semigroup actually had all the arrows doubled again. I fixed this by checking whether the digraph input to \__init__ is already an instance of DoubleQuiver.Wed, 22 Jan 2020 22:54:46 +0100https://ask.sagemath.org/question/49636/attempting-to-enrich-quiver-class-yields-unexpected-keyword-argument-error/?answer=49654#post-id-49654Comment by Iguananaut for <p>I believe I've found the issue. The __init__() referred to in the error message seems to be that of the class I'm defining. Presumably when I run the path_semigroup() method, it attempts to initialize a new DoubleQuiver for some reason, and includes an input for the "weighted" argument, something that the DiGraph constructor takes but the DoubleQuiver constructor, as written, does not. </p>
<p>Inserting **kwargs into the arguments of __init__ and the call it makes to DiGraph's __init__ appears to fix the problem by allowing for any missing arguments:</p>
<pre><code>def __init__(self, digraph, multiedges=True, **kwargs):
edges = []
self._edgePairs = {}
for e in digraph.edges():
self._edgePairs[(e[0], e[1], e[2] + '0')] = (e[1], e[0], e[2] + '1')
self._edgePairs[(e[1], e[0], e[2] + '1')] = (e[0], e[1], e[2] + '0')
edges.append((e[0], e[1], e[2] + '0'))
edges.append((e[1], e[0], e[2] + '1'))
super(DoubleQuiver, self).__init__(edges, multiedges=True, **kwargs)
</code></pre>
<hr>
<p>An aside: Another problem that this revealed, which provides further evidence that path_semigroup() calls __init__ again, is that the resulting path semigroup actually had all the arrows doubled again. I fixed this by checking whether the digraph input to __init__ is already an instance of DoubleQuiver.</p>
https://ask.sagemath.org/question/49636/attempting-to-enrich-quiver-class-yields-unexpected-keyword-argument-error/?comment=49661#post-id-49661This is basically correct, and passing an arbitrary `**kwargs` to a subclass's constructor is a fairly common idiom. A couple (very minor) nitpicks where your code is non-idiomatic:
* Python has a style guide called PEP-8, which is also used by Sage (see [Sage Coding Conventions](https://doc.sagemath.org/html/en/developer/coding_basics.html#python-code-style). Most of your code is already PEP-8 except the `self._edgePairs`. camelCase is not used for local variables or attributes; instead you could call this `self._edge_pairs` (like I said, very minor)
* The line `assert edge in self.edges()` is unnecessary; if it isn't true the following line will raise a `KeyError`, which is more explicit than an `AssertionError` anyways.Thu, 23 Jan 2020 16:45:28 +0100https://ask.sagemath.org/question/49636/attempting-to-enrich-quiver-class-yields-unexpected-keyword-argument-error/?comment=49661#post-id-49661