1 | initial version |
This will not be a short answer, so let me better first address the shorter issues.
A possible IDE to use for debugging purposes is eclipse
, install also pydev as plugin inside. This worked for me a long time. Some post that shows how to combine sage devel in eclipse+pydev is here:
my sage+eclipse+pydev solution (posted as error)
For short: The IDE must (or should) be started from the terminal, e.g. eclipse &
, after setting via
`sage -sh`
in the "sage shell" all system variables to be used. Inside eclipse, each module should have the usual from sage.all import *
, and if sage is configured as python interpreter (instead python2.7
), than there may be also some change needed... (The problem in the above post.) Important note: There is no preparsing, so things may become delicate. E.g. the p = 2^8-1
is rejected in eclipse
, instead, the code should be written as p = 2**8-1
, which is accepted in both worlds, sage and python2. Also, the "intervall" [1..10]
does exist only after preparsing, and it is a list of ZZ
-numbers, not a list of python int
egers. A simple replacement of [1..10]
by the "naive" range(1,11)
may thus fail for "unexpected reasons" in eclipse, although sage may load the code without errors... So this was one of the short issues.
A deviation / derivative of eclipse is LiClipse, not free... Never tried it, but one may expect also support after paying for it!
An other IDE for python can be used, pycharm
. The same discussion as in the case of eclipse
applies for it. Here is my parallel answer for the pycharm
world:
the sage (iron python) interpreter is my best friend. Just copy+paste (using %cpaste
) short pieces of code, or load bigger chunks. (Or install even bigger ones as packages.) There is an automatic TAB-completion for methods, which makes it productive in a different way, compared with a good editor as emacs
, my choice. (I could not make emacs
consume the code. Yet.)
And the rest of the post goes to pytest
.
The following strategy worked for me, some pytest test sage code could be digested as follows.
First of all, i installed pytest
for the python2.7
interpreter. (Default is to use it for python3.) On this manjaro machine i installed the package python2-pytest
in version 3,3,2-1
from the community
manjaro repository. (This is thus an official manjaro package, and sage is also an official one in this distro! I'll stay with it...)
Then in a terminal: sage -sh
- same game as for eclipse and pycharm, this sets all related SAGE
paths and libraries. (Environment variables.) The prompter changes correspondingly.
With the new prompter i started:
(sage-sh) dan@k7:asksage$ python2.7 -m pytest pytest_sagetest.py
i.e. the command python2.7 -m pytest pytest_sagetest.py
from the folder asksage
where the file pytest_sagetest.py
with the following content lives in:
# content of pytest_sagetest.py
from sage.all import *
def test_HasseBoundTest():
""""Test the computations of the order of an elliptic curve
by testing if it stays in the Hasse interval.
"""
p = 127
F = GF(p)
for a in GF(p):
try:
E = EllipticCurve( F, [a,0] )
except Exception:
continue
ord = E.order()
# lower bound check
assert( ord >= p + 1 - 2*sqrt(p) )
assert( ord <= p + 1 + 2*sqrt(p) )
def test_LowerHasseBoundTaken():
p = next_prime(100)
F = GF(p)
orders = []
for a in F:
for b in F:
try:
E = EllipticCurve( F, [a,b] )
except Exception:
pass # discriminant is zero...
ord = E.order()
if ord not in orders:
orders.append( ord )
# lower bound check
assert( min(orders) == ceil(p + 1 - 2*sqrt(p)) )
assert( max(orders) == floor(p + 1 + 2*sqrt(p)) )
def test_AllOrdersTaken():
p = 71
F = GF(p)
orders = []
for a in F:
for b in F:
try:
E = EllipticCurve( F, [a,b] )
except Exception:
pass # discriminant is zero...
ord = E.order()
if ord not in orders:
orders.append( ord )
# lower bound check
orders.sort()
assert( orders == range( ceil (p + 1 - 2*sqrt(p)) ,
floor(p + 1 + 2*sqrt(p)) + 1 ) )
It was an intention to produce "errors". (Of course, some not so intentioned errors are also present... Since we want more errors, they remained in the landscape.) Then the pytest
digestive delivers the following information:
(sage-sh) dan@k7:asksage$ python2.7 -m pytest pytest_sagetest.py
================================ test session starts ================================
platform linux2 -- Python 2.7.14, pytest-3.3.2, py-1.5.0, pluggy-0.6.0
rootdir: /home/dan/asksage/asksage, inifile:
collected 3 items
pytest_sagetest.py .FF [100%]
===================================== FAILURES ======================================
_____________________________ test_LowerHasseBoundTaken _____________________________
def test_LowerHasseBoundTaken():
p = next_prime(100)
F = GF(p)
orders = []
for a in F:
for b in F:
try:
E = EllipticCurve( F, [a,b] )
except Exception:
pass # discriminant is zero...
ord = E.order()
if ord not in orders:
orders.append( ord )
# lower bound check
> assert( min(orders) == ceil(p + 1 - 2*sqrt(p)) )
E assert 83 == 82
E + where 83 = min([102, 105, 92, 114, 112, 87, ...])
E + and 82 = ceil(((101 + 1) - (2 * sqrt(101))))
E + where sqrt(101) = sqrt(101)
pytest_sagetest.py:37: AssertionError
________________________________ test_AllOrdersTaken ________________________________
def test_AllOrdersTaken():
p = 71
F = GF(p)
orders = []
for a in F:
for b in F:
try:
E = EllipticCurve( F, [a,b] )
except Exception:
pass # discriminant is zero...
ord = E.order()
if ord not in orders:
orders.append( ord )
# lower bound check
orders.sort()
> assert( orders == range( ceil (p + 1 - 2*sqrt(p)) ,
floor(p + 1 + 2*sqrt(p)) + 1 ) )
E assert [56, 57, 59, 60, 61, 62, ...] == [56, 57, 58, 59, 60, 61, ...]
E At index 2 diff: 59 != 58
E Right contains more items, first extra item: 85
E Use -v to get the full diff
pytest_sagetest.py:56: AssertionError
================================= warnings summary ==================================
pytest_sagetest.py::TestSuite
cannot collect test class 'TestSuite' because it has a __init__ constructor
-- Docs: http://doc.pytest.org/en/latest/warnings.html
================== 2 failed, 1 passed, 1 warnings in 7.43 seconds ===================
(sage-sh) dan@k7:asksage$
(And here there is a lot of colourful highlight gone. Just start in a proper termina...)
Note: pytest
is rather a "unit test" tool, it may be used in a "test driven devel" process. Personally, for my research this is too much (i.e. life is too short). But this is of huge importance while for devel+maintain of the packages. Sage has also a proper mechanism for doing this. In fact, after installing sage
one has already the chance to test it against the unit test code sage comes with...
2 | No.2 Revision |
This will not be a short answer, so let me better first address the shorter issues.
A possible IDE to use for debugging purposes is eclipse
, install also pydev as plugin inside. This worked for me a long time. Some post that shows how to combine sage devel in eclipse+pydev is here:
my sage+eclipse+pydev solution (posted as error)
For short: The IDE must (or should) be started from the terminal, e.g. eclipse &
, after setting via
`sage -sh`
in the "sage shell" all system variables to be used. Inside eclipse, each module should have the usual from sage.all import *
, and if sage is configured as python interpreter (instead python2.7
), than there may be also some change needed... (The problem in the above post.) Important note: There is no preparsing, so things may become delicate. E.g. the p = 2^8-1
is rejected in eclipse
, instead, the code should be written as p = 2**8-1
, which is accepted in both worlds, sage and python2. Also, the "intervall" [1..10]
does exist only after preparsing, and it is a list of ZZ
-numbers, not a list of python int
egers. A simple replacement of [1..10]
by the "naive" range(1,11)
may thus fail for "unexpected reasons" in eclipse, although sage may load the code without errors... So this was one of the short issues.
A deviation / derivative of eclipse is LiClipse, not free... Never tried it, but one may expect also support after paying for it!
An other IDE for python can be used, pycharm
. The same discussion as in the case of eclipse
applies for it. Here is my parallel answer for the pycharm
world:
the sage (iron python) interpreter is my best friend. Just copy+paste (using %cpaste
) short pieces of code, or load bigger chunks. (Or install even bigger ones as packages.) There is an automatic TAB-completion for methods, which makes it productive in a different way, compared with a good editor as emacs
, my choice. (I could not make emacs
consume the code. Yet.)
And the rest of the post goes to pytest
.
The following strategy worked for me, some pytest test sage code could be digested as follows.
First of all, i installed pytest
for the python2.7
interpreter. (Default is to use it for python3.) On this manjaro machine i installed the package python2-pytest
in version 3,3,2-1
from the community
manjaro repository. (This is thus an official manjaro package, and sage is also an official one in this distro! I'll stay with it...)
Then in a terminal: sage -sh
- same game as for eclipse and pycharm, this sets all related SAGE
paths and libraries. (Environment variables.) The prompter changes correspondingly.
With the new prompter i started:
(sage-sh) dan@k7:asksage$ python2.7 -m pytest pytest_sagetest.py
i.e. the command python2.7 -m pytest pytest_sagetest.py
from the folder asksage
where the file pytest_sagetest.py
with the following content lives in:
# content of pytest_sagetest.py
from sage.all import *
def test_HasseBoundTest():
""""Test """Test the computations of the order of an elliptic curve
by testing if it stays in the Hasse interval.
"""
p = 127
F = GF(p)
for a in GF(p):
try:
E = EllipticCurve( F, [a,0] )
except Exception:
continue
ord = E.order()
# lower bound check
assert( ord >= p + 1 - 2*sqrt(p) )
assert( ord <= p + 1 + 2*sqrt(p) )
def test_LowerHasseBoundTaken():
p = next_prime(100)
F = GF(p)
orders = []
for a in F:
for b in F:
try:
E = EllipticCurve( F, [a,b] )
except Exception:
pass # discriminant is zero...
ord = E.order()
if ord not in orders:
orders.append( ord )
# lower bound check
assert( min(orders) == ceil(p + 1 - 2*sqrt(p)) )
assert( max(orders) == floor(p + 1 + 2*sqrt(p)) )
def test_AllOrdersTaken():
p = 71
F = GF(p)
orders = []
for a in F:
for b in F:
try:
E = EllipticCurve( F, [a,b] )
except Exception:
pass # discriminant is zero...
ord = E.order()
if ord not in orders:
orders.append( ord )
# lower bound check
orders.sort()
assert( orders == range( ceil (p + 1 - 2*sqrt(p)) ,
floor(p + 1 + 2*sqrt(p)) + 1 ) )
It was an intention to produce "errors". (Of course, some not so intentioned errors are also present... Since we want more errors, they remained in the landscape.) Then the pytest
digestive delivers the following information:
(sage-sh) dan@k7:asksage$ python2.7 -m pytest pytest_sagetest.py
================================ test session starts ================================
platform linux2 -- Python 2.7.14, pytest-3.3.2, py-1.5.0, pluggy-0.6.0
rootdir: /home/dan/asksage/asksage, inifile:
collected 3 items
pytest_sagetest.py .FF [100%]
===================================== FAILURES ======================================
_____________________________ test_LowerHasseBoundTaken _____________________________
def test_LowerHasseBoundTaken():
p = next_prime(100)
F = GF(p)
orders = []
for a in F:
for b in F:
try:
E = EllipticCurve( F, [a,b] )
except Exception:
pass # discriminant is zero...
ord = E.order()
if ord not in orders:
orders.append( ord )
# lower bound check
> assert( min(orders) == ceil(p + 1 - 2*sqrt(p)) )
E assert 83 == 82
E + where 83 = min([102, 105, 92, 114, 112, 87, ...])
E + and 82 = ceil(((101 + 1) - (2 * sqrt(101))))
E + where sqrt(101) = sqrt(101)
pytest_sagetest.py:37: AssertionError
________________________________ test_AllOrdersTaken ________________________________
def test_AllOrdersTaken():
p = 71
F = GF(p)
orders = []
for a in F:
for b in F:
try:
E = EllipticCurve( F, [a,b] )
except Exception:
pass # discriminant is zero...
ord = E.order()
if ord not in orders:
orders.append( ord )
# lower bound check
orders.sort()
> assert( orders == range( ceil (p + 1 - 2*sqrt(p)) ,
floor(p + 1 + 2*sqrt(p)) + 1 ) )
E assert [56, 57, 59, 60, 61, 62, ...] == [56, 57, 58, 59, 60, 61, ...]
E At index 2 diff: 59 != 58
E Right contains more items, first extra item: 85
E Use -v to get the full diff
pytest_sagetest.py:56: AssertionError
================================= warnings summary ==================================
pytest_sagetest.py::TestSuite
cannot collect test class 'TestSuite' because it has a __init__ constructor
-- Docs: http://doc.pytest.org/en/latest/warnings.html
================== 2 failed, 1 passed, 1 warnings in 7.43 seconds ===================
(sage-sh) dan@k7:asksage$
(And here there is a lot of colourful highlight gone. Just start in a proper termina...)
Note: pytest
is rather a "unit test" tool, it may be used in a "test driven devel" process. Personally, for my research this is too much (i.e. life is too short). But this is of huge importance while for devel+maintain of the packages. Sage has also a proper mechanism for doing this. In fact, after installing sage
one has already the chance to test it against the unit test code sage comes with...
3 | No.3 Revision |
This will not be a short answer, so let me better first address the shorter issues.
A possible IDE to use for debugging purposes is eclipse
, install also pydev as plugin inside. This worked for me a long time. Some post that shows how to combine sage devel in eclipse+pydev is here:
my sage+eclipse+pydev solution (posted as error)
For short: The IDE must (or should) be started from the terminal, e.g. eclipse &
, after setting via
`sage -sh`
in the "sage shell" all system variables to be used. Inside eclipse, each module should have the usual from sage.all import *
, and if sage is configured as python interpreter (instead python2.7
), than there may be also some change needed... (The problem in the above post.) Important note: There is no preparsing, so things may become delicate. E.g. the p = 2^8-1
is rejected in eclipse
, instead, the code should be written as p = 2**8-1
, which is accepted in both worlds, sage and python2. Also, the "intervall" [1..10]
does exist only after preparsing, and it is a list of ZZ
-numbers, not a list of python int
egers. A simple replacement of [1..10]
by the "naive" range(1,11)
may thus fail for "unexpected reasons" in eclipse, although sage may load the code without errors... So this was one of the short issues.
A deviation / derivative of eclipse is LiClipse, not free... Never tried it, but one may expect also support after paying for it!
An other IDE for python can be used, pycharm
. The same discussion as in the case of eclipse
applies for it. Here is my parallel answer for the pycharm
world:
the sage (iron python) interpreter is my best friend. Just copy+paste (using %cpaste
) short pieces of code, or load bigger chunks. (Or install even bigger ones as packages.) There is an automatic TAB-completion for methods, which makes it productive in a different way, compared with a good editor as emacs
, my choice. (I could not make emacs
consume the code. Yet.)
And the rest of the post goes to pytest
.
The following strategy worked for me, some pytest test sage code could be digested as follows.
First of all, i installed pytest
for the python2.7
interpreter. (Default is to use it for python3.) On this manjaro machine i installed the package python2-pytest
in version 3,3,2-1
from the community
manjaro repository. (This is thus an official manjaro package, and sage is also an official one in this distro! I'll stay with it...)
Then in a terminal: sage -sh
- same game as for eclipse and pycharm, this sets all related SAGE
paths and libraries. (Environment variables.) The prompter changes correspondingly.
With the new prompter i started:
(sage-sh) dan@k7:asksage$ python2.7 -m pytest pytest_sagetest.py
i.e. the command python2.7 -m pytest pytest_sagetest.py
from the folder asksage
where the file pytest_sagetest.py
with the following content lives in:
# content of pytest_sagetest.py
from sage.all import *
def test_HasseBoundTest():
"""Test the computations of the order of an elliptic curve
by testing if it stays in the Hasse interval.
"""
p = 127
F = GF(p)
for a in GF(p):
try:
E = EllipticCurve( F, [a,0] )
except Exception:
continue
ord = E.order()
# lower bound check
assert( ord >= p + 1 - 2*sqrt(p) )
assert( ord <= p + 1 + 2*sqrt(p) )
def test_LowerHasseBoundTaken():
p = next_prime(100)
F = GF(p)
orders = []
for a in F:
for b in F:
try:
E = EllipticCurve( F, [a,b] )
except Exception:
pass # discriminant is zero...
ord = E.order()
if ord not in orders:
orders.append( ord )
# lower bound check
assert( min(orders) == ceil(p + 1 - 2*sqrt(p)) )
assert( max(orders) == floor(p + 1 + 2*sqrt(p)) )
def test_AllOrdersTaken():
p = 71
F = GF(p)
orders = []
for a in F:
for b in F:
try:
E = EllipticCurve( F, [a,b] )
except Exception:
pass # discriminant is zero...
ord = E.order()
if ord not in orders:
orders.append( ord )
# lower bound check
orders.sort()
assert( orders == range( ceil (p + 1 - 2*sqrt(p)) ,
floor(p + 1 + 2*sqrt(p)) + 1 ) )
It was an intention to produce "errors". (Of course, some not so intentioned errors are also present... Since we want more errors, they remained in the landscape.) Then the pytest
digestive delivers the following information:
(sage-sh) dan@k7:asksage$ python2.7 -m pytest pytest_sagetest.py
================================ test session starts ================================
platform linux2 -- Python 2.7.14, pytest-3.3.2, py-1.5.0, pluggy-0.6.0
rootdir: /home/dan/asksage/asksage, inifile:
collected 3 items
pytest_sagetest.py .FF [100%]
===================================== FAILURES ======================================
_____________________________ test_LowerHasseBoundTaken _____________________________
def test_LowerHasseBoundTaken():
p = next_prime(100)
F = GF(p)
orders = []
for a in F:
for b in F:
try:
E = EllipticCurve( F, [a,b] )
except Exception:
pass # discriminant is zero...
ord = E.order()
if ord not in orders:
orders.append( ord )
# lower bound check
> assert( min(orders) == ceil(p + 1 - 2*sqrt(p)) )
E assert 83 == 82
E + where 83 = min([102, 105, 92, 114, 112, 87, ...])
E + and 82 = ceil(((101 + 1) - (2 * sqrt(101))))
E + where sqrt(101) = sqrt(101)
pytest_sagetest.py:37: AssertionError
________________________________ test_AllOrdersTaken ________________________________
def test_AllOrdersTaken():
p = 71
F = GF(p)
orders = []
for a in F:
for b in F:
try:
E = EllipticCurve( F, [a,b] )
except Exception:
pass # discriminant is zero...
ord = E.order()
if ord not in orders:
orders.append( ord )
# lower bound check
orders.sort()
> assert( orders == range( ceil (p + 1 - 2*sqrt(p)) ,
floor(p + 1 + 2*sqrt(p)) + 1 ) )
E assert [56, 57, 59, 60, 61, 62, ...] == [56, 57, 58, 59, 60, 61, ...]
E At index 2 diff: 59 != 58
E Right contains more items, first extra item: 85
E Use -v to get the full diff
pytest_sagetest.py:56: AssertionError
================================= warnings summary ==================================
pytest_sagetest.py::TestSuite
cannot collect test class 'TestSuite' because it has a __init__ constructor
-- Docs: http://doc.pytest.org/en/latest/warnings.html
================== 2 failed, 1 passed, 1 warnings in 7.43 seconds ===================
(sage-sh) dan@k7:asksage$
(And here there is a lot of colourful highlight gone. Just start in a proper termina...)
Note: pytest
is rather a "unit test" tool, it may be used in a "test driven devel" process. Personally, for my research this is too much (i.e. life is too short). But this is of huge importance while for devel+maintain of the packages. Sage has also a proper mechanism for doing this. In fact, after installing sage
one has already the chance to test it against the unit test code sage comes with...
LATER EDIT :: import issues
Note that pytest
has a specific way to use a python path.
https://docs.pytest.org/en/latest/pythonpath.html
There is even a package pytest-pythonpath
that may make complicated things easier.
https://pypi.python.org/pypi/pytest-pythonpath
In our case, a simplistic situation as the following one could import a module (in the same directory).
Here is the situation:
[dan@k7 ~/asksage/asksage]$ ls tests
mycomputations.py test_sage.py
[dan@k7 ~/asksage/asksage]$ cat tests/mycomputations.py
# content of mycomputations.py
from sage.all import *
def PythonInteger(k):
return int(k)
def ZZInteger(k):
return ZZ(k)
[dan@k7 ~/asksage/asksage]$ cat tests/test_sage.py
# content of test_sage.py
from sage.all import *
import mycomputations
def test_type1():
a = mycomputations.PythonInteger(100)
assert type(a) == type(ZZ(0))
def test_type2():
a = mycomputations.ZZInteger(100)
assert type(a) == type(ZZ(0))
[dan@k7 ~/asksage/asksage]$
Then:
[dan@k7 ~/asksage/asksage]$ pytest2 tests
======================== test session starts =========================
platform linux2 -- Python 2.7.14, pytest-3.3.2, py-1.5.0, pluggy-0.6.0
rootdir: /home/dan/asksage/asksage, inifile:
collected 2 items
tests/test_sage.py F. [100%]
============================== FAILURES ==============================
_____________________________ test_type1 _____________________________
def test_type1():
a = mycomputations.PythonInteger(100)
> assert type(a) == type(ZZ(0))
E AssertionError: assert <type 'int'> == <type 'sage.rings.integer.Integer'>
E + where <type 'int'> = type(100)
E + and <type 'sage.rings.integer.Integer'> = type(0)
E + where 0 = ZZ(0)
tests/test_sage.py:7: AssertionError
========================== warnings summary ==========================
tests/test_sage.py::TestSuite
cannot collect test class 'TestSuite' because it has a __init__ constructor
-- Docs: http://doc.pytest.org/en/latest/warnings.html
=========== 1 failed, 1 passed, 1 warnings in 3.69 seconds ===========
[dan@k7 ~/asksage/asksage]$
More complicated unit test situations are covered by the pytest documentation / framework. If such issues remain, please consider using an IDE, eclipse and/or pycharm, both are comming with a supported unit test environment.
The post also mentions (asks for) debugging possibilities, same answer, eclipse+pydev and/or pycharm so far.
Personal note: People that have not used such IDEs (e.g. because having a pure mathematical formation and/or because using rather the notebook part of sage) will discover a new world with good productivity mechanisms.