Ask Your Question
2

How to break up function definitions across several lines?

asked 2019-04-26 15:35:32 +0200

stockh0lm gravatar image

updated 2019-04-28 12:20:13 +0200

slelievre gravatar image

if i write a function definition and i break it up across several lines, the sage prepocessor complains:

phi(epsilon, Q, r) = 1/(4*pi*
                        epsilon
)*Q/r

show(phi(1,2,3))

the sage prepocessor complains:

sage demo.sage
  File "demo.sage.py", line 6
    __tmp__=var("epsilon,Q,r"); phi = symbolic_expression(_sage_const_1 /(_sage_const_4 *pi*).function(epsilon,Q,r)
                                                                                            ^
SyntaxError: invalid syntax

While this is a very short function that is easily kept on one line, I do have rather long and intricate ones which I would like to break up (and potentially comment) over several lines.

Linebreaks with backslash as the last char of the line don't work:

cat demo.sage
phi(epsilon, Q, r) = 1/(4*pi*\
                        epsilon\
)*Q/r

show(phi(1,2,3))

% sage demo.sage
  File "demo.sage.py", line 6
    __tmp__=var("epsilon,Q,r"); phi = symbolic_expression(_sage_const_1 /(_sage_const_4 *pi* * BackslashOperator() * ).function(epsilon,Q,r)
                                                                                             ^
SyntaxError: invalid syntax

How do I do that?

edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
1

answered 2019-04-26 19:58:12 +0200

dsejas gravatar image

updated 2019-04-27 20:37:00 +0200

Hello, @stockh0lm. This seems to be a problem with the preprocessor, since it is assuming all \ to be a matrix operation (i.e., the Matlab-style operator for solving systems of linear equations).

As a workaround you could use consistent indentation and wrap the code with parenthesis, so that Sage's preparser understands the complete extension of your code. The following worked for me:

phi(epsilon, Q, r) = (1 / (4 * pi 
                     * epsilon)
                     * Q / r)

show(phi(1,2,3))

Notice all lines defining phi are equally indented, and I started and finished its definition with parenthesis. The preparser seems to assume the code defining the function ends on the line with the last parenthesis, so we are forcing it to consider our complete definition.

Also, I am using the PEP 8 convention of breaking a line BEFORE an operator, i.e., the asterisk doesn't end a line, but it starts one. (This last convention has nothing to do with the working of the code; it's just a convention.)

edit flag offensive delete link more

Comments

how weird, this does not work for me, either:

% sage demo.sage
  File "demo.sage.py", line 8
    * Q/r
    ^
IndentationError: unexpected indent

% cat demo.sage
phi(epsilon, Q, r) = 1/(4*pi
                     * epsilon)
                     * Q/r

show(phi(1,2,3))
stockh0lm gravatar imagestockh0lm ( 2019-04-27 00:45:42 +0200 )edit

Yes, sorry. You're right! This is weird, but Sage's preparser thinks the expression extends until the line that closes the last parenthesis (in your code until the end of the second line). Thus, the third line is not considered to be part of the definition, and Sage doesn't know why you indented.

I was lucky! Notice I closed the parenthesis on the last line (I think this is not good style), so in my case, it worked. Funny result!

Try wrapping all the expression in parenthesis, like:

phi(epsilon, Q, r) = (1/(4*pi
    * epsilon)
    * Q/r)

show(phi(1,2,3))
dsejas gravatar imagedsejas ( 2019-04-27 01:42:10 +0200 )edit

this works! Thank you! - can you please put it in a proper answer, instead of a comment, so i can upvote and accept it?

stockh0lm gravatar imagestockh0lm ( 2019-04-27 16:40:29 +0200 )edit

Hello, @stockh0lm. I think this webpage doesn't allow multiple answers from the same user, so I have edited my original answer to include my comment that gave you the correct answer. Therefore, you can mark that as an answer. Thank you!

dsejas gravatar imagedsejas ( 2019-04-27 20:39:39 +0200 )edit

This does also work without indentation

phi(epsilon, Q, r) = (1 / (4 * pi 
* epsilon)
* Q / r)
vdelecroix gravatar imagevdelecroix ( 2019-04-27 22:02:52 +0200 )edit
2

answered 2019-04-27 22:24:56 +0200

vdelecroix gravatar image

This is indeed a bug of the preparse function. Your syntax is perfectly valid in Python

>>> A = 1 + (3*
... 4
... ) * 2
25

However Sage preparser function is not smart in matching the start and end of an instruction.

sage: s = """phi(epsilon, Q, r) = 1/(4*pi*
....:                         epsilon
....: )*Q/r"""
sage: print(s)
phi(epsilon, Q, r) = 1/(4*pi*
                        epsilon
)*Q/r
sage: print(preparse(s))
__tmp__=var("epsilon,Q,r"); phi = symbolic_expression(Integer(1)/(Integer(4)*pi*).function(epsilon,Q,r)
                        epsilon
)*Q/r

Somehow, only the first line went transformed into a function. If you call directly preparse_calculus (which is the part that perform the preparsing of the instruction defining the function) it works

sage: from sage.repl.preparse import preparse_calculus
sage: print(preparse_calculus(";" + s + ";"))
;__tmp__=var("epsilon,Q,r"); phi = symbolic_expression(1/(4*pi*
                        epsilon
)*Q/r).function(epsilon,Q,r);

(Don't ask me why, but the function preparse_calculus needs a ";" at the begining and the end of the instruction). This can then be executed manually

sage: exec(preparse_calculus(";" + s + ";")[1:-1])
sage: phi
(epsilon, Q, r) |--> 1/4*Q/(pi*epsilon*r)

Note that this problem has been reported 8 years ago in trac ticket #11621.

edit flag offensive delete link more
0

answered 2019-04-26 16:31:53 +0200

god.one gravatar image

Hi,

you can use line breaks line breaks

phi(epsilon, Q, r) = 1/(4*pi* \
                    epsilon \
)*Q/r

show(phi(1,2,3))

Worked for me in the sage command line v8.2

edit flag offensive delete link more

Comments

No.

File "demo.sage.py", line 6
            __tmp__=var("epsilon,Q,r"); phi = symbolic_expression(_sage_const_1 /(_sage_const_4 *pi* * BackslashOperator() * ).function(epsilon,Q,r)
                                                                                                     ^
SyntaxError: invalid syntax

actually i had tried that, and i cant. see error above.

stockh0lm gravatar imagestockh0lm ( 2019-04-26 17:06:58 +0200 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2019-04-26 15:35:32 +0200

Seen: 1,904 times

Last updated: Apr 28 '19