PyGObject, hex color to Gdk.RGBA - pygobject

i found this code
gdk_rgba_parse ()
which should allow me to do something like
Gdk.RGBA.parse(#7F7F7F)
Error:
TypeError: unbound method parse() must be called with RGBA instance as first argument (got str instance instead)
using the RGBA color ( in percent, from 0 to 1 )
Docs:
https://developer.gnome.org/gdk3/stable/gdk3-RGBA-Colors.html#gdk-rgba-parse
http://www.crategus.com/books/cl-cffi-gtk/pages/gdk_fun_gdk-rgba-parse.html
But I'm kinda lost, i struggle to translate from C to PyGOBject and understanding the arguments of the function.. any help would be appreciated!
Since i didn't find the right solution, i made this converter:
def hex_to_rgba(value):
value = value.lstrip('#')
if len(value) == 3:
value = ''.join([v*2 for v in list(value)])
(r1,g1,b1,a1)=tuple(int(value[i:i+2], 16) for i in range(0, 6, 2))+(1,)
(r1,g1,b1,a1)=(r1/255.00000,g1/255.00000,b1/255.00000,a1)
return (r1,g1,b1,a1)
It works..

The function requires an instance of a GdkRGBA struct:
gboolean
gdk_rgba_parse (GdkRGBA *rgba,
const gchar *spec);
This translates to Python as a method on a Gdk.RGBA instance which mutates the structs contents:
color = Gdk.RGBA()
color.parse('#7F7F7F')
color.to_string() # 'rgb(127,127,127)'
It's not a very nice API for Python but every once in a while you have to deal with these kind of things with introspection based bindings. lazka's docs should be more helpful than the C ones:
http://lazka.github.io/pgi-docs/#Gdk-3.0/structs/RGBA.html#Gdk.RGBA.parse

Related

How do I take a reference to new?

Suppose I have the following code:
my constant #suits = <Clubs Hearts Spades Diamonds>;
my constant #values = 2..14;
class Card {
has $.suit;
has $.value;
# order is mnemonic of "$value of $suit", i.e. "3 of Clubs"
multi method new($value, $suit) {
return self.bless(:$suit, :$value);
}
}
It defines some suits and some values and what it means to be a card.
Now, to build a deck, I essentially need to take the cross product of the suits and the values and apply that to the constructor.
The naiive approach to do this, would of course be to just iterate with a loop:
my #deck = gather for #values X #suits -> ($v, $c) {
take Card.new($v, $c);
}
But this is Raku, we have a cross function that can take a function as an optional argument!, so of course I'm gonna do that!
my #deck = cross(#values, #suits, :with(Card.new));
# Unexpected named argument 'with' passed
# in block <unit> at .\example.raku line 36
... wait no.
What about this?
my #deck = cross(#values, #suits):with(Card.new);
# Unexpected named argument 'with' passed
# in block <unit> at .\example.raku line 36
Still nothing. Reference maybe?
my #deck = cross(#values, #suits):with(&Card.new);
# ===SORRY!=== Error while compiling D:\Code\Raku/.\example.raku
# Illegally post-declared type:
# Card used at line 36
I read somewhere I can turn a function into an infix operator with []
my #deck = cross(#values, #suits):with([Card.new]);
# Unexpected named argument 'with' passed
# in block <unit> at .\example.raku line 36
That also doesn't work.
If classes are supposed to just be modules, shouldn't I then be able to pass a function reference?
Also why is it saying 'with' is that's unexpected? If I'm intuiting this right, what it's actually complaining about is the type of the input, rather than the named argument.
The error message is indeed confusing.
The :with parameter expects a Callable. Card.new is not a Callable. If you write it as :with( { Card.new($^number, $^suit) } ), it appears to work.
Note that I did not use $^value, $^suit, because they order differently alphabetically, so would produce the values in the wrong order. See The ^ twigil for more information on that syntax.
The error is LTA, this makes it a little bit better.
To get back to your question: you can find the code object that corresponds to Card.new with ^find_method. However, that will not work, as Card.new actually expects 3 arguments: the invocant (aka self), $value and $suit. Whereas the cross function will only pass the value and the suit.
The title of your question is “How do I take a reference to new?”, but that is not really what you want to do.
Raku being Raku, you can actually get a reference to new.
my $ref = Card.^lookup('new');
You can't use it like you want to though.
$ref(2,'Clubs'); # ERROR
The problem is that methods take a class or instance as the first argument.
$ref(Card, 2,'Clubs');
You could use .assuming to add it in.
$ref .= assuming(Card);
$ref(2,'Clubs');
But that isn't really any better than creating a block lambda
$ref = { Card.new( |#_ ) }
$ref(2,'Clubs');
All of these work:
cross( #values, #suits ) :with({Card.new(|#_)}) # adverb outside
cross( #values, #suits, :with({Card.new(|#_)}) ) # inside at end
cross( :with({Card.new(|#_)}), #values, #suits ) # inside at beginning
#values X[&( {Card.new(|#_)} )] #suits # cross meta-op with fake infix op
do {
sub new-card ($value,$suit) { Card.new(:$value,:$suit) }
#values X[&new-card] #suits
}
do {
sub with ($value,$suit) { Card.new(:$value,:$suit) }
cross(#values,#suits):&with
}

Is it possible to init a variable in the while condition body for Kotlin?

In the code below:
var verticesCount: Int // to read a vertices count for graph
// Reading until we get a valid vertices count.
while (!Assertions.checkEnoughVertices(
verticesCount = consoleReader.readInt(null, Localization.getLocStr("type_int_vertices_count"))))
// The case when we don't have enough vertices.
println(String.format(Localization.getLocStr("no_enough_vertices_in_graph"),
Assertions.CONFIG_MIN_VERTICES_COUNT))
val resultGraph = Graph(verticesCount)
we are getting next error on the last line:
Error:(31, 33) Kotlin: Variable 'verticesCount' must be initialized
Assertions.checkEnoughVertices accepts a safe type variable as an argument (verticesCount: Int), so it's impossible for verticesCount to be uninitialized or null here (and we're getting no corresponding errors on those lines).
What's going on on the last line when already initialized variable becomes uninitialized again?
The syntax you've used denotes a function call with named arguments, not the assignment of a local variable. So verticesCount = is just an explanation to the reader that the value which is being passed here to checkEnoughVertices corresponds to the parameter of that function named verticesCount. It has nothing to do with the local variable named verticesCount declared just above, so the compiler thinks you've still to initialize that variable.
In Kotlin, the assignment to a variable (a = b) is not an expression, so it cannot be used as a value in other expressions. You have to split the assignment and the while-loop condition to achieve what you want. I'd do this with an infinite loop + a condition inside:
var verticesCount: Int
while (true) {
verticesCount = consoleReader.readInt(...)
if (Assertions.checkEnoughVertices(verticesCount)) break
...
}
val resultGraph = Graph(verticesCount)
Well, technically it is possible to assign values to variables in the while condition - and anything else you might want to do there, too.
The magic comes from the also function:
Try this: (excuse the completely useless thing this is doing...)
var i = 10
var doubleI: Int
while ((i * 2).also { doubleI = it } > 0) {
i--
println(doubleI)
}
Any expression can be "extended" with "something to do" by calling also which takes the expression it is called upon as the it parameter and executes the given block. The value also returns is identical to its caller value.
Here's a very good article to explain this and much more: https://medium.com/#elye.project/mastering-kotlin-standard-functions-run-with-let-also-and-apply-9cd334b0ef84

Can a map be used in the 'def __init__' ? And how to read errors

I've created a class for a Counter that I'm wanting to build, and I want this object to figure out player scores. I'm expecting to see 3 when I test it, however what I get is the following error:
TypeError: unsupported operand type(s) for += 'method' and 'int' I'm not sure what that means, so I'm not sure if the issue is the map, my object itself, or my syntax. Any and all advice is welcome!
class Counter:
def __init__(self):
self.pointValue = {'Item_1': 3,
'Item_2': 5,
'Item_3': -3
}
def playerScore(self, itemFound ):
self.playerScore += (self.pointValue[itemFound])
return self.playerScore
gameCounter = Counter()
x = 'Item_1'
print (gameCounter.playerScore(x))
You can absolutely use a map (in Python it's called a dict) in __init__; it is not that part of the code that is throwing the error.
The message unsupported operand type(s) for += 'method' and 'int' refers to the line
self.playerScore += (self.pointValue[itemFound])
where self.playerScore is the method you are currently calling; it makes no sense to add an integer to a method, so an error is raised.
I think you actually want something like:
class ScoreCounter:
POINT_VALUE = {'Item_1': 3,
'Item_2': 5,
'Item_3': -3}
def __init__(self):
self.score = 0
def find_item(self, item):
self.score += self.POINT_VALUE.get(item, 0)
return self.score
Which you could use like:
>>> c = ScoreCounter()
>>> c.find_item("Item_1")
3
Note that the POINT_VALUE is a class attribute, shared by all ScoreCounter instances, whereas the score is an instance attribute, separate for each one. Also note that score is a different name to find_item, so you don't end up trying to assign to the method, and I have avoided the name Counter as it's used elsewhere. Finally, I have adopted naming conventions from the Python style guide.

Why can't I use builtin for classes that overload subsref?

I would like to overload only one type of subsref calls (the '()' type) for a particular class and leave any other calls to Matlab's built in subsref -- specifically, I want Matlab to handle property/method access via the '.' type. But, it seems like Matlab's 'builtin' function doesn't work when subsref is overloaded in a class.
Consider this class:
classdef TestBuiltIn
properties
testprop = 'This is the built in method';
end
methods
function v = subsref(this, s)
disp('This is the overloaded method');
end
end
end
To use the overloaded subsref method, I do this:
t = TestBuiltIn;
t.testprop
>> This is the overloaded method
That's as expected. But now I want to call Matlab's built in subsref method. To make sure I'm doing things right, first I try out a similar call on a struct:
x.testprop = 'Accessed correctly';
s.type = '.';
s.subs = 'testprop';
builtin('subsref', x, s)
>> Accessed correctly
That's as expected as well. But, when I try the same method on TestBuiltIn:
builtin('subsref', t, s)
>> This is the overloaded method
...Matlab calls the overloaded method rather than the built in method. Why does Matlab call the overloaded method when I requested that it call the builtin method?
UPDATE:
In response to #Andrew Janke's answer, that solution almost works but doesn't quite. Consider this class:
classdef TestIndexing
properties
prop1
child
end
methods
function this = TestIndexing(n)
if nargin==0
n = 1;
end
this.prop1 = n;
if n<2
this.child = TestIndexing(n+1);
else
this.child = ['child on instance ' num2str(n)];
end
end
function v = subsref(this, s)
if strcmp(s(1).type, '()')
v = 'overloaded method';
else
v = builtin('subsref', this, s);
end
end
end
end
All of this works:
t = TestIndexing;
t(1)
>> overloaded method
t.prop1
>> 1
t.child
>> [TestIndexing instance]
t.child.prop1
>> 2
But this doesn't work; it uses the built in subsref for the child rather than the overloaded subsref:
t.child(1)
>> [TestIndexing instance]
Note that the above behavior is inconsistent with both of these behaviors (which are as expected):
tc = t.child;
tc(1)
>> overloaded method
x.child = t.child;
x.child(1)
>> overloaded method
It's possible, IIRC. To change () but not {} and '.', write your subsref method to pass those other cases along to the builtin subsref from within your overloaded subsref, instead of trying to explicitly call the builtin from outside.
function B = subsref(A, S)
% Handle the first indexing on your obj itself
switch S(1).type
case '()'
B = % ... do your custom "()" behavior ...
otherwise
% Enable normal "." and "{}" behavior
B = builtin('subsref', A, S(1))
end
end
% Handle "chaining" (not sure this part is fully correct; it is tricky)
orig_B = B; % hold on to a copy for debugging purposes
if numel(S) > 1
B = subsref(B, S(2:end)); % regular call, not "builtin", to support overrides
end
end
(And if that builtin call doesn't work, you can just put in cases that use . and {} directly, because the subsref overload is ignored inside the class definition.)
To make it fully functional, you may need to change B to a varargout, and add chaining behavior in to the "()" case.
To expand on the explanation given on the Mathworks board, builtin only works from within an overloaded method to access the pre-existing (built in) method.
Overloading a method in Matlab effectively shadows the built in implementation from everything except the method doing the shadowing, and the method doing the shadowing must use builtin to access the built in implementation instead of recursing into itself.
In general. You should use builtin(m,s) inside the function that is been overloaded. This is specified clearly in MATLAB documentation.
http://www.mathworks.com/help/matlab/ref/builtin.html
builtin(function,x1,...,xn) executes the built-in function with the
input arguments x1 through xn. Use builtin to execute the original
built-in from within a method that overloads the function. To work
properly, you must never overload builtin.
Consider this code:
classdef TestBuiltIn
properties
testprop = 'This is the built in method';
testprop2 = 'This is the derived subsref ';
end
methods
function v = subsref(m, s)
disp('enter subsref no matter how!');
v = builtin('subsref',m, s);
end
end
end
and test command
clear;
t = TestBuiltIn;
builtin('subsref', t, s)
s.type = '.';
s.subs = 'testprop';
s2 = s;
s2.subs = 'testprop2';
>> builtin('subsref', t, s1)
enter subsref no matter how!
ans =
This is the derived subsref
>> builtin('subsref', t, s)
enter subsref no matter how!
ans =
This is the built in method
In your updated version of this problem, when you call t.child(1), the subsref function will receive argument s with s(1).type='.', s(1).subs='child' and s(2).type='()', s(2).subs='1'. The evaluation of this expression is not in a step-by-step manner, as Andrew Janke mentioned in his answer. As a result, when overriding subsref, you should handle this operation chain, by first processing the '.' operator. Here is a incomplete example for your case,
function v = subsref(this, s)
switch s(1).type
case '.'
member = s(1).subs;
if ismethod(this, member)
% invoke builtin function to access method member
% there is issue about the number of output arguments
v = builtin('subsref',this,s);
elseif isprop(this, member) % property
if length(s) == 1
% invoke builtin function to access method member
v = builtin('subsref', this, s);
elseif length(s) == 2 && strcmp(s(2).type,'()')
% this is where you evaluate 'tc.child(1)'
else
% add other cases when you need, otherwise calling builtin
end
else
% handling error.
end
case '()'
% this is where you evaluate 't(1)'
% you may need to handle something like 't(1).prop1', like the '.' case
otherwise
% by default, calling the builtin.
end
end
You can also find a detailed code sample and instruction at Code Patterns for subsref and subsasgn Methods.
One more thing you may need to know, is that method members in this class will also be invoked through subsref with '.' operation. Look at this subject subsref on classes: how to dispatch methods?, you will find that the builtin function has no return value (since the invoked method has no return value). However, the return value of builtin is assigned to v(even though v is replaced by varargout), which is an obvious error. The author also gives a temporary solution by using try ... catch to resolve this error.

Does MATLAB support "callable" (i.e. function-like) classes?

Is it possible to define a MATLAB class such that the objects from this class can be called like any other function?
IOW, I'm asking whether one can write in MATLAB the equivalent of something like the following Python class:
# define the class FxnClass
class FxnClass(object):
def __init__(self, template):
self.template = template
def __call__(self, x, y, z):
print self.template % locals()
# create an instance of FxnClass
f = FxnClass('x is %(x)r; y is %(y)r; z is %(z)r')
# call the instance of FxnClass
f(3, 'two', False)
...
[OUTPUT]
x is 3; y is 'two'; z is False
Thanks!
I do not know, whether MATLAB directly supports what you want, but MATLAB does support first-class functions; closures might therefore provide a useable substitute, for instance:
function f = count_call(msg)
calls = 0;
function current_count()
disp(strcat(msg, num2str(calls)));
calls = calls + 1;
end
f = #current_count;
end
In this case, current_count closes over calls (and msg). That way you can express functions that depend on some internal state. You would use it this way:
g = count_call('number of calls: ') % returns a new function ("__init__")
g() % "__call__"
I will be interested to see if this is possible without simply creating a java method in Matlab. I know you can do the following
classdef ExampleObject
properties
test;
end
methods
function exampleObject = ExampleObject(inputTest)
exampleObject.test=inputTest;
end
function f(exampleObject,funcInput)
disp(funcInput+exampleObject.test);
end
end
end
>> e=ExampleObject(5);
>> f(e,10)
15
But as far as my knowledge goes, if you tried to override the call function you'd run into a conflict with Matlab's parenthetical subscript reference subsref. You can find a reference here showing how to overwrite that, and you might be able to get it to do what you want...but it doesn't seem like good form to do so. Not sure how Matlab would handle a call to an object (as opposed to a function) without it getting confused with this.
One way is to override the feval function for your class:
classdef FxnClass < handle
properties
template
end
methods
function obj = FxnClass(t)
obj.template = t;
end
function out = feval(obj, varargin)
out = sprintf(obj.template, varargin{:});
end
end
end
This would be used as:
>> f = FxnClass('x = %f, y = %s, z = %d');
>> feval(f, 3,'two',false)
ans =
x = 3.000000, y = two, z = 0
Now if you want to provide additional syntactic sugar, you could redefine the subsref function for your class as #Salain suggested. Add the following to the previous class definition:
classdef FxnClass < handle
...
methods
function out = subsref(obj, S)
switch S(1).type
case '.'
% call builtin subsref, so we dont break the dot notation
out = builtin('subsref', obj, S);
case '()'
out = feval(obj, S.subs{:});
case '{}'
error('Not a supported subscripted reference');
end
end
end
end
Now you could simply write:
>> f = FxnClass('x = %f, y = %s, z = %d');
>> f(3,'two',false)
ans =
x = 3.000000, y = two, z = 0
Personally I don't particularly like overriding the subsref or subsasgn functions. They are used for too many cases, and its sometimes hard to get them write. For example all the following will eventually call the subsref method with different input:
f(..)
f.template
f.template(..)
f(..).template
f(..).template(..)
There is also the case of the end keyword which could appear in indexing, so you might have to also override it as well in some cases. Not to mention that objects can also be concatenated into arrays, which makes things even more complicated:
>> ff = [f,f];
>> ff(1) % not what you expect!
That said, I think #Frank's suggestion to use nested functions with closures is more elegant in this case:
function f = FxnClass(t)
f = #call;
function out = call(varargin)
out = sprintf(t, varargin{:});
end
end
which is called as before:
>> f = FxnClass('x = %f, y = %s, z = %d');
>> f(3, 'two', false)
If you mean that you want a class to hold a method which you use like a normal function (eg. defined in an m-file), then yes, Matlab does support static methods.
A static method runs independently of any instances of that class, in fact, you don't even need to instantiate a class to use its static methods.
Matlab does not support static fields, however, so you would have to instantiate such a class first, and then set its fields before using the functions (which presumably make use of these fields, since you are asking this question).
Given the limitation with static members, you might be better off with closures, as described by Frank.