4

I use a flashcard program called Anki, which is written in Python. I want to write my first add-on. I'm new to Python. I'm not a techie, but I have a few years experience of jumping around inside other people's code in Java, C++, C#, and so on.

The flash card shows a question, for example "Capital of France?". When the "Show Answer" button is pressed, Anki displays the answer "Paris".

I want to grab this text "Paris", before it's shown.

I've arrived at this point in the Anki code. At this instant, the card shows "Capital of France?". The answer is still blank. I think I want to be able to grab "val" (which I think is "Paris") and use it in my add-on.

def _getTypedAnswer(self):
    self.web.evalWithCallback("typeans ? typeans.value : null", self._onTypedAnswer)

def _onTypedAnswer(self, val):
    self.typedAnswer = val        
    self._showAnswer()

I've been googling to try to find the meaning of this:

("typeans ? typeans.value : null", self._onTypedAnswer)

I have access to all the code, and I can provide any code that might be useful to responders.

Thanks.


Added: after questions from responders.

Anki can be run on a computer or on the internet. All the results of studying cards are synced, so there's no difference between one method or the other as far as the end user is concerned.


From the "webview" class:

def evalWithCallback(self, js, cb):
    self.page().runJavaScript(js, cb)

The "reviewer" class shows the questions and answers. The reviewer window is "mw" (for "main window")

Here's the init statement for class "reviewer"

def __init__(self, mw):
    self.mw = mw
    self.web = mw.web
OldGrantonian
  • 597
  • 1
  • 8
  • 23
  • It's not Python syntax but it's called a "Ternary if" - See https://en.wikipedia.org/wiki/%3F: – Alastair McCormack Sep 15 '16 at 07:37
  • 1
    That appears to be calling out to some external language, possibly JavaScript (given the "web" in the method name). To Python, `"typeans ? typeans.value : null"` is just a string; whatever is using it as code is something outside of Python. What is `self.web`? Do you have the code of `evalWithCallback`? – BrenBarn Sep 15 '16 at 07:38
  • I think self._showAnswer() would be a better place to target your interception. TypedAnswer suggests that you are gathering... typed content. Which may not be the answer that appears when the button is clicked, hard to tell. – dodell Sep 15 '16 at 08:49

4 Answers4

1

typeans ? typeans.value : null is a C/C++/C# (and probably Java too, can't remember) code equivalent to (pseudo-code)

if typans:
   return typeans.value
else:
   return null

("typeans ? typeans.value : null", self._onTypedAnswer) is a tuple that contains this line of code as a string.

unwind
  • 391,730
  • 64
  • 469
  • 606
DeepSpace
  • 78,697
  • 11
  • 109
  • 154
0

Once you have found a place in the code that the variable you want is found, there are a number of ways of extracting this information to your own code.

If direct manipulation of the source is allowed then you could assign val as an attribute to a different object within the methods you have shown in the question.

For instance:

def _onTypedAnswer(self, val):
    self.typedAnswer = val
    myobj.answer = val
    # or call a method on myobj to break flow
    # myobj.method(val)
    self._showAnswer()
dodell
  • 470
  • 3
  • 7
0

BTW, the exact (and valid) python equivalent of typeans ? typeans.value : null is:

typeans and typeans.value or None
Andrei
  • 117
  • 8
0
self.web.evalWithCallback("typeans ? typeans.value : null", self._onTypedAnswer)

This just calls the evalWithCallback method with two arguments: the string "typeans ? typeans.value : null" and the method object self._onTypedAnswer. You can see what evalWithCallback does with this from your posted code:

def evalWithCallback(self, js, cb):
    self.page().runJavaScript(js, cb)

So evalWithCallback takes the string and runs it as JavaScript. It's not clear from this exactly how the callback is called (for instance, what arguments it will be called with), but the essence of what the code does is it executes the string typeans ? typeans.value : null as JavaScript and then calls the function self._onTypedAnswer. My guess would be that the val argument passed to _onTypedAnswer will be the result of the evaluating the JS expression.

Incidentally, judging from the name "typed answer", I would guess that val is not the correct answer to the question, but rather the user's guess (i.e., a value the user typed in).

BrenBarn
  • 242,874
  • 37
  • 412
  • 384