PyQt: QAxBase.dynamicCall overloaded with list as arguments - pyqt

calling QAxBase.dynamicCall like this works:
my_comp.dynamicCall("MyMethod(const QString&, int, bool)", "test", 2, False)
however, using the overloaded call (http://qt-project.org/doc/qt-4.8/qaxbase.html#dynamicCall-2) doesn't:
my_comp.dynamicCall("MyMethod(const QString&, int, bool)", ["test", 2, False])
It gives an Error: ... Non-optional parameter missing
The overloaded call expects a QList<QVariant> in Qt. Is the list I've provided mapped automatically to a QList<QVariant> by SIP? Can I create it manually?
As I've got 18 args I need to use the overloaded call.
EDIT: I've also converted the args explicitly to a QVariant like this, but the same issue.
args = ["test", 2, False]
q_var_args = [QVariant(arg) for arg in args]
my_comp.dynamicCall("MyMethod(const QString&, int, bool)", ["test", 2, False])
Cheers,
Jan

You can have a fixed parameter followed by an unpacked list of parameters:
params = ["test", 2, False]
my_comp.dynamicCall("MyMethod(QString, int, bool)", *params)

Related

What kind of comprehension is this?

One of my students found that, for ell (a list of string) and estr (a string), the following expression is True iff a member of ell is contained in estr:
any(t in estr for t in ell)
Can anyone explain why this is syntactically legal, and if so what does the comprehension generate?
This is a generator expression.
func_that_takes_any_iterable(i for i in iterable)
It's like a list comprehension, but a generator, meaning it only produces one element at a time:
>>> a = [i for i in range(10)]
>>> b = (i for i in range(10))
>>> print(a)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print(b)
<generator object <genexpr> at 0x7fb9113fae40>
>>> print(list(b))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print(list(b))
[]
When using a generator expression in isolation, the parentheses are required for syntax reasons. When creating one as an argument to a function, the syntax allows for the extra parentheses to be absent.
Most functions don't care what type of iterable they're given - list, tuple, dict, generator, etc - and generators are perfectly valid. They're also marginally more memory-efficient than list comprehensions, since they don't generate the entire thing up front. For all() and any(), this is especially good, since those methods short-circuit as soon as they would return False and True respectively.
As of python 3.8, the syntactic restrictions for the walrus operator := are similar - in isolation, it must be used inside its own set of parentheses, but inside another expression it can generally be used without them.
This is syntactically legal because it's not a list. Anything of the form (x for x in array) is a generator. Think of it like lazy list, which will generate answer only when you ask.
Now generator are also an iterable so it's perfectly fine for it to be inside an any() function.
willBeTrue = any(True for i in range(20))
So this will basically generate 20 Trues and any function looks for any true value; thus will return True.
Now coming to your expression:
ans = any(t in estr for t in ell)
This {t in estr} returns a boolean value. Now generator makes len(ell) amount of those boolean value and any thinks good.. since atleast one is true I return True.

What is the Groovy 'it'?

I have a collection which I process with removeIf {} in Groovy. Inside the block, I have access to some it identifier. What is this and where is it documented?
it is an implicit variable that is provided in closures. It's available when the closure doesn't have an explicitly declared parameter.
When the closure is used with collection methods, such as removeIf, it will point to the current iteration item.
It's like you declared this:
List<Integer> integers = [1, 2, 3]
for(Integer it: integers) {print(it)}
When you use each, instead (and that's an example), you can get it implicitly provided:
integers.each{print(it)} //it is given by default
Or
integers.removeIf{it % 2 == 0} //it is the argument to Predicate.test()
it will successively take the values 1, 2, and 3 as iterations go.
You can, of course, rename the variable by declaring the parameter in the closure:
integers.each{myInteger -> print(myInteger)}
In this case, Groovy doesn't supply the implicit it variable. The documentation has more details
If you create a closure without an explicit argument list, it defaults to having a single argument named it. Here's an example that can be run in the Groovy console
Closure incrementBy4 = { it + 4 }
// test it
assert incrementBy4(6) == 10
In the example above the closure is identical to
Closure incrementBy4 = { it -> it + 4 }
Here's another example that uses removeIf
Closure remove2 = { it == 2 }
def numbers = [1, 2, 3]
numbers.removeIf(remove2)
// verify that it worked as expected
assert numbers == [1, 2]

using Int or number in Elm dictionary

I defined my model to be Model = Dict Int String however in compile time, I get number instead of Int so it is wrong:
The 2nd argument to function `get` is causing a mismatch.
71| Dict.get 3 model
^^^^^
Function `get` is expecting the 2nd argument to be:
Dict number v
But it is:
Model
and unfortunately Elm repl does the same thing returning Dict number instead of Dict Int.
> Dict.fromList [ (1, {a= 1} )]
Dict.fromList [(1,{ a = 1 })] : Dict.Dict number { a : number1 }
Certain languages such as Haskell expose Int as as well as Integer as well as number How can I coerce it to be integer?
Would you be able to provide the relevant code?
The following compiles and works fine for me:
import Dict exposing (Dict, fromList, get)
type alias Model = Dict Int String
model : Model
model = fromList [(1, "apple"), (2, "banana"), (42, "giraffe")]
test : Maybe String
test = get 2 model

Is there a way to refer to an operator as a two-argument closure?

Sometimes I need to pass an operator as a closure, like this:
do.some.thing() { x,y -> x+y }
I'm wondering if there is any shorthand "operator pointer" syntax, analogous to the "method pointer" syntax, that would give me the operator already wrapped into a two-argument closure.
I see that most arithmetic operators are available as methods on Number and related classes:
public Number plus(Number right)
Add two numbers and return the result.
but they are instance methods and I can't figure out if I can use the method pointer operator .& to turn them into a two-argument closure.
You can do this sort of thing as well...
Not sure uncurry is the right term, but it's almost right ;-)
import org.codehaus.groovy.runtime.MethodClosure
def uncurry(MethodClosure c) {
{a, ...b -> a."$c.method"(*b) }
}
Then, to make a 2 arg closure from Number.plus, you can do:
def plus = uncurry(Number.&plus)
And then:
assert plus(1, 2) == 3
Which also works with other method handles as well:
def collate = uncurry(List.&collate)
assert collate([1, 2, 3, 4, 5], 2, true) == [[1, 2], [3, 4], [5]]
No, there's no such operator.
The method pointer operator won't work because the MethodClosure it creates basically has an object, in this case the Number class, and a method name. So if you do...
def c = Number.&plus
Then calling c will attempt to call plus() on the Number class, which of course won't work.
The only shortcut I can think of is to declare your operator closures once and simply reuse them as needed.

Does Swift init(count:, repeatedValue:) work?

Tested this from the reference: https://developer.apple.com/documentation/swift
var string = String(count: 5, repeatedValue: "a")
// string is "aaaaa"
I got this error:
Playground execution failed: error: :5:14: error: could not find an overload for 'init' that accepts the supplied arguments
var string = String(count: 5, repeatedValue: "a")
Does this actually work?
It seems that you have to explicitly pass in a Character type to it to function. This works for me.
let char = Character("a")
let string = String(count: 5, repeatedValue: char)
Although, there may be bug mixed in with all this as well. I believe the way you were doing this should have worked on its own. And I can't seem to get code completion on this initializer at all.
Edit: I'm going with bug. The following compiles just fine.
let array = Array(count: 5, repeatedValue: "a")
For the benefit of future searchers: as of Swift 3, use init(repeating:count:).
let sososo = String(repeating: "so", count: 3)
This works just fine :
var str9 = String(count: 5,repeatedValue: Character("c"))
For anyone in swift 3.x its now something like this this will work like a charm.
var string = String(repeating: "a", count: 5)
I know this is an old question and already has an answer. However I think I know why String(count: 5, repeatedValue: "a") does not work.
The thing is String has two similar looking initialisers:
init(count: Int, repeatedValue: Character)
init(count: Int, repeatedValue: UnicodeScalar)
So in this case compiler can't tell whether a literal is a Character or UnicodeScalar, hence compile time error if you don't pass explicit Character. To confirm that "a" can be interpreted as UnicodeScalar you can check that this line compiles:
let a: UnicodeScalar = "a"
Swift 3:
var array = Array(repeating: 0, count: 5)
Output: [0, 0, 0, 0, 0]

Resources