In which @Captain tries to extend a Python app to use MathJax
-
OK, this task "feels" like it is almost done. But the app is python based, and I am having a syntax error I don't understand. The line is:
return re.sub(jaxReg%("\\d","\\d"), "\\2" || "\\4", txt)
and Python complains about a "syntax error" at the second
\\d
. It is not more specific. It just says "Syntax error" and points to second\\d
(but not the first).The function I am writing (and monkey patching, ugh) is:
jaxReg = r"(\$+).*?\{\{c{s}::(.*?)\}\}[^\$]*(\$+)?|\{\{c{s}::(.*?)\}\}" def clozeJax(self, txt, ord, type): if not re.search(jaxReg%(ord, ord), txt): return "" def repl(m): # replace chosen cloze with type if type == "q": if m.group(1): return "\\text{[...]}" else: return "<span class='cloze'>[...]</span class='cloze'>" else: return "%s" % m.group(3) txt = re.sub(jaxReg%(ord, ord), repl, txt) # and display other clozes normally return re.sub(jaxReg%("\\d","\\d"), "\\2" || "\\4", txt) Template.clozeText = clozeJax
(so the problem is in the very last line of the
clozeJax
definition)Any ideas? Am I missing something dumb?
-
I get a syntax error on the
||
, which isn't a valid operator in Python. Did you mean+
for string concatentation?I don't know why you'd get a syntax error on the second
""\\d"
.
-
@Dragnslcr said in In which @Captain tries to extend a Python app to use MathJax:
I get a syntax error on the ||, which isn't a valid operator in Python. Did you mean + for string concatentation?
Aha, okay, that makes sense I guess. I definitely don't mean
+
, but I guess it would work. :-)What I "really" want is something that short circuit checks if
a
is defined and if not checks ifb
is defined ina ???? b
, where????
is some operator.I tried
+
, and it fixes the syntax error, but now it's complaining thata
isNone
at runtime. I guess I can sort it from here.
-
@Captain said in In which @Captain tries to extend a Python app to use MathJax:
What I "really" want is something that short circuit checks if a is defined and if not checks if b is defined in a ???? b, where ???? is some operator.
In that case, you should probably remember that this is not Haskell and that arguments are evaluated before invoking the function. So even if this operator existed, it wouldn't do what you want since it would be evaluated before the actual replacement happens. ;)
Fortunately for you, re.sub supports a function as the second argument. That's probably what you want.
-
I'm seeing some things here that I am really... ah, not very clear on, at the very least. let's go step by step on this, shall we?
First off, though: what version of Python are you using? While I don't see anything here that should be specific to 2.x or 3.x, it may be relevant. The main reason I ask is because you are using the
%
string interpolation operator a lot, and in 3.x the.format()
method is generally preferred over the interpolation operator.jaxReg = r"(\$+).*?\{\{c{s}::(.*?)\}\}[^\$]*(\$+)?|\{\{c{s}::(.*?)\}\}"
OK, this looks fine... except that later in the code, you apply string interpolations to it, and there aren't any interpolation specifiers (which always start with a percent sign
%
, and use a variant of the Csprintf()
formatting syntax). This means that you don't actually have anywhere to insert the interpolations to.def clozeJax(self, txt, ord, type):
Uhm, is this a method? While the identifier
self
isn't actually a keyword, it is conventional to use it only for the object reference of an instance method. You did say it was getting monkeypatched, so I don't know just how you are handling inserting it if it is part of a class, but it still seems odd here, especially since the function doesn't use it to reference any instance variables.if not re.search(jaxReg%(ord, ord), txt): return "" def repl(m):
You are defining an inner function here, but it doesn't seem to get used. No, wait, you're passing it as a closure to
re.sub()
later... huh? I don't think that will work - did you mean to call the function? checks language ref Oh, OK, that is valid, I guess.# replace chosen cloze with type if type == "q": if m.group(1): return "\\text{[...]}" else: return "<span class='cloze'>[...]</span class='cloze'>"
I am assuming that this is meant to be HTML, but I'm pretty sure attributes aren't legal in a closing tag.
else: return "%s" % m.group(3)
How is
"%s" % m.group(3)
different fromm.group(3)
, assuming thatm.group(3)
is in fact a string-convertable type? The only reason I can think for this would be to force a fail-fast situation (because the interpolation op would throw an error if it is eitherNone
or some type that doesn't implementstr()
), but wouldn't testing for the validity ofm.group(3)
and raising an error on failure make more sense?return re.sub(jaxReg%("\\d","\\d"), "\\2" || "\\4", txt)
The Perl-style short-circuit you are aiming for is invalid in Python, as already noted; not only is the operator for logical-or actually
or
, but also only applies to strict booleans.EDIT: corrected a dumbass attack re: the logical op.
-
@Captain said in In which @Captain tries to extend a Python app to use MathJax:
checks if a is defined and if not checks if b is defined in a ???? b
Maybe
or
?In [1]: a = None In [2]: b = "hello" In [5]: a or b Out[5]: 'hello'
-
@Adynathos OK, I didn't realize that would work. Crap, I fucked up there.
-
@ScholRLEA
Another useful structure is:a if cond else b
:In [9]: 1/0 if False else 0 Out[9]: 0
-
@ScholRLEA said in In which @Captain tries to extend a Python app to use MathJax:
I'm seeing some things here that I am really... ah, not very clear on, at the very least. let's go step by step on this, shall we?
First off, though: what version of Python are you using? While I don't see anything here that should be specific to 2.x or 3.x, it may be relevant. The main reason I ask is because you are using the
%
string interpolation operator a lot, and in 3.x the.format()
method is generally preferred over the interpolation operator.jaxReg = r"(\$+).*?\{\{c{s}::(.*?)\}\}[^\$]*(\$+)?|\{\{c{s}::(.*?)\}\}"
OK, this looks fine... except that later in the code, you apply string interpolations to it, and there aren't any interpolation specifiers (which always start with a percent sign
%
, and use a variant of the Csprintf()
formatting syntax). This means that you don't actually have anywhere to insert the interpolations to.Yup, that's my mistake. Those
{s}
were string interpolations like%s
until I tried to fix the syntax error and then I forgot to keep the code consistent.def clozeJax(self, txt, ord, type):
Uhm, is this a method? While the identifier
self
isn't actually a keyword, it is conventional to use it only for the object reference of an instance method. You did say it was getting monkeypatched, so I don't know just how you are handling inserting it if it is part of a class, but it still seems odd here, especially since the function doesn't use it to reference any instance variables.Yeah, the
clozeText
method is defined bydef clozeText(self, txt, ord, type): stuffLikeMineButDifferent
Per the monkey patching tutorial for the app, I'm just overwriting
clozeText
byclozeJax
.if not re.search(jaxReg%(ord, ord), txt): return "" def repl(m):
You are defining an inner function here, but it doesn't seem to get used. No, wait, you're passing it as a closure to
re.sub()
later... huh? I don't think that will work - did you mean to call the function? checks language ref Oh, OK, that is valid, I guess.Yeah, I didn't modify that part of the original
clozeText
function.# replace chosen cloze with type if type == "q": if m.group(1): return "\\text{[...]}" else: return "<span class='cloze'>[...]</span class='cloze'>"
I am assuming that this is meant to be HTML, but I'm pretty sure attributes aren't legal in a closing tag.
That's another issue in the original source, but I can clean it up easily. :-)
else: return "%s" % m.group(3)
How is
"%s" % m.group(3)
different fromm.group(3)
, assuming thatm.group(3)
is in fact a string-convertable type?More original source problems. Will fix too.
return re.sub(jaxReg%("\\d","\\d"), "\\2" || "\\4", txt)
The Perl-style short-circuit you are aiming for is invalid in Python, as already noted; not only is the operator for logical-or actually
or
, but also only applies to strict booleans.
-
@Captain As I noted in my reply to @Adynathos, I was wrong about the
or
only working on booleans - I tend not to rely on truthiness, and in any case I would have expected a boolean op that operates on truthy values to returnTrue
rather than the truthy value. Dunno why, every language that uses truthiness which I know of will do that, but it didn't occur to me.