algebra_with_sympy.preparser
1def algebra_with_sympy_preparser(lines): 2 """ 3 In IPython compatible environments (Jupyter, IPython, etc...) this supports 4 a special compact input method for equations. 5 6 The syntax supported is `equation_name =@ equation.lhs = equation.rhs`, 7 where `equation_name` is a valid Python name that can be used to refer to 8 the equation later. `equation.lhs` is the left-hand side of the equation 9 and `equation.rhs` is the right-hand side of the equation. Each side of the 10 equation must parse into a valid Sympy expression. 11 12 **Note**: This does not support line continuation. Long equations should be 13 built by combining expressions using names short enough to do this on one 14 line. The alternative is to use `equation_name = Eqn(long ... 15 expressions ... with ... multiple ... lines)`. 16 17 **Note**: If the `equation_name` is omitted the equation will be formed, 18 but it will not be assigned to a name that can be used to refer to it 19 later. You may be able to access it through one of the special IPython 20 underscore names. This is not recommended. 21 22 **THIS FUNCTION IS USED BY THE IPYTHON ENVIRONMENT TO PREPARSE THE INPUT 23 BEFORE IT IS PASSED TO THE PYTHON INTERPRETER. IT IS NOT MEANT TO BE USED 24 DIRECTLY BY A USER** 25 """ 26 new_lines = [] 27 if isinstance(lines,str): 28 lines = [lines] 29 for k in lines: 30 if '=@' in k: 31 drop_comments = k.split('#') 32 to_rephrase = '' 33 if len(drop_comments) > 2: 34 for i in range(len(drop_comments)-1): 35 to_rephrase += drop_comments[i] 36 else: 37 to_rephrase = drop_comments[0] 38 linesplit = to_rephrase.split('=@') 39 eqsplit = linesplit[1].split('=') 40 if len(eqsplit)!=2: 41 raise ValueError('The two sides of the equation must be' \ 42 ' separated by an \"=\" sign when using' \ 43 ' the \"=@\" special input method.') 44 templine ='' 45 if eqsplit[0]!='' and eqsplit[1]!='': 46 if eqsplit[1].endswith('\n'): 47 eqsplit[1] = eqsplit[1][:-1] 48 if linesplit[0]!='': 49 templine = str(linesplit[0])+'= Eqn('+str(eqsplit[0])+',' \ 50 ''+str(eqsplit[1])+')\n' 51 else: 52 templine = 'Eqn('+str(eqsplit[0])+','+str(eqsplit[1])+')\n' 53 new_lines.append(templine) 54 else: 55 new_lines.append(k) 56 return new_lines 57 58 59def integers_as_exact(lines): 60 """This preparser uses `sympy.interactive.session.int_to_Integer` to 61 convert numbers without decimal points into sympy integers so that math 62 on them will be exact rather than defaulting to floating point. **This 63 should not be called directly by the user. It is plugged into the 64 IPython preparsing sequence when the feature is requested.** The default for 65 Algebra_with_sympy is to use this preparser. This can be turned on and 66 off using the Algebra_with_sympy functions: 67 * `set_integers_as_exact()` 68 * `unset_integers_as_exact()` 69 """ 70 from sympy.interactive.session import int_to_Integer 71 string = '' 72 for k in lines: 73 string += k + '\n' 74 string = string[:-1] # remove the last '\n' 75 return int_to_Integer(string) 76 77from IPython import get_ipython 78if get_ipython(): 79 if hasattr(get_ipython(),'input_transformers_cleanup'): 80 get_ipython().input_transformers_post.\ 81 append(algebra_with_sympy_preparser) 82 else: 83 import warnings 84 warnings.warn('Compact equation input unavailable.\nYou will have ' \ 85 'to use the form "eq1 = Eqn(lhs,rhs)" instead of ' \ 86 '"eq1=@lhs=rhs".\nIt appears you are running an ' \ 87 'outdated version of IPython.\nTo fix, update IPython ' \ 88 'using "pip install -U IPython".')
2def algebra_with_sympy_preparser(lines): 3 """ 4 In IPython compatible environments (Jupyter, IPython, etc...) this supports 5 a special compact input method for equations. 6 7 The syntax supported is `equation_name =@ equation.lhs = equation.rhs`, 8 where `equation_name` is a valid Python name that can be used to refer to 9 the equation later. `equation.lhs` is the left-hand side of the equation 10 and `equation.rhs` is the right-hand side of the equation. Each side of the 11 equation must parse into a valid Sympy expression. 12 13 **Note**: This does not support line continuation. Long equations should be 14 built by combining expressions using names short enough to do this on one 15 line. The alternative is to use `equation_name = Eqn(long ... 16 expressions ... with ... multiple ... lines)`. 17 18 **Note**: If the `equation_name` is omitted the equation will be formed, 19 but it will not be assigned to a name that can be used to refer to it 20 later. You may be able to access it through one of the special IPython 21 underscore names. This is not recommended. 22 23 **THIS FUNCTION IS USED BY THE IPYTHON ENVIRONMENT TO PREPARSE THE INPUT 24 BEFORE IT IS PASSED TO THE PYTHON INTERPRETER. IT IS NOT MEANT TO BE USED 25 DIRECTLY BY A USER** 26 """ 27 new_lines = [] 28 if isinstance(lines,str): 29 lines = [lines] 30 for k in lines: 31 if '=@' in k: 32 drop_comments = k.split('#') 33 to_rephrase = '' 34 if len(drop_comments) > 2: 35 for i in range(len(drop_comments)-1): 36 to_rephrase += drop_comments[i] 37 else: 38 to_rephrase = drop_comments[0] 39 linesplit = to_rephrase.split('=@') 40 eqsplit = linesplit[1].split('=') 41 if len(eqsplit)!=2: 42 raise ValueError('The two sides of the equation must be' \ 43 ' separated by an \"=\" sign when using' \ 44 ' the \"=@\" special input method.') 45 templine ='' 46 if eqsplit[0]!='' and eqsplit[1]!='': 47 if eqsplit[1].endswith('\n'): 48 eqsplit[1] = eqsplit[1][:-1] 49 if linesplit[0]!='': 50 templine = str(linesplit[0])+'= Eqn('+str(eqsplit[0])+',' \ 51 ''+str(eqsplit[1])+')\n' 52 else: 53 templine = 'Eqn('+str(eqsplit[0])+','+str(eqsplit[1])+')\n' 54 new_lines.append(templine) 55 else: 56 new_lines.append(k) 57 return new_lines
In IPython compatible environments (Jupyter, IPython, etc...) this supports a special compact input method for equations.
The syntax supported is equation_name =@ equation.lhs = equation.rhs
,
where equation_name
is a valid Python name that can be used to refer to
the equation later. equation.lhs
is the left-hand side of the equation
and equation.rhs
is the right-hand side of the equation. Each side of the
equation must parse into a valid Sympy expression.
Note: This does not support line continuation. Long equations should be
built by combining expressions using names short enough to do this on one
line. The alternative is to use equation_name = Eqn(long ...
expressions ... with ... multiple ... lines)
.
Note: If the equation_name
is omitted the equation will be formed,
but it will not be assigned to a name that can be used to refer to it
later. You may be able to access it through one of the special IPython
underscore names. This is not recommended.
THIS FUNCTION IS USED BY THE IPYTHON ENVIRONMENT TO PREPARSE THE INPUT BEFORE IT IS PASSED TO THE PYTHON INTERPRETER. IT IS NOT MEANT TO BE USED DIRECTLY BY A USER
60def integers_as_exact(lines): 61 """This preparser uses `sympy.interactive.session.int_to_Integer` to 62 convert numbers without decimal points into sympy integers so that math 63 on them will be exact rather than defaulting to floating point. **This 64 should not be called directly by the user. It is plugged into the 65 IPython preparsing sequence when the feature is requested.** The default for 66 Algebra_with_sympy is to use this preparser. This can be turned on and 67 off using the Algebra_with_sympy functions: 68 * `set_integers_as_exact()` 69 * `unset_integers_as_exact()` 70 """ 71 from sympy.interactive.session import int_to_Integer 72 string = '' 73 for k in lines: 74 string += k + '\n' 75 string = string[:-1] # remove the last '\n' 76 return int_to_Integer(string)
This preparser uses sympy.interactive.session.int_to_Integer
to
convert numbers without decimal points into sympy integers so that math
on them will be exact rather than defaulting to floating point. This
should not be called directly by the user. It is plugged into the
IPython preparsing sequence when the feature is requested. The default for
Algebra_with_sympy is to use this preparser. This can be turned on and
off using the Algebra_with_sympy functions:
set_integers_as_exact()
unset_integers_as_exact()