Ask Your Question
1

Some code gives error in sagemath 9 but OK in 8.9

asked 2020-03-09 21:52:26 +0200

Nasser gravatar image

After I upgraded to sagemath 9.0 some of the code that used to work now gives error. The code was used to obtain an estimate of size of expression.

>sage --version
SageMath version 9.0, Release Date: 2020-01-01
>which sage
/bin/sage

It looks like sagemath 9 now uses python 3.0 while 8.9 used python 2 (since I had to change all my print statements to use () to make them work.

Here is an example of function that now gives an error. This is in file, say bug_sage.py

#!/usr/bin/env sage

from sage.all import *

def tree(expr):     
    if expr.operator() is None: 
        return expr 
    else: 
        return [expr.operator()]+map(tree, expr.operands()) 

var('x')
tree(x*e**((x*log(x) + 1)/log(x)))

Now from command line at Linux, I type sage ./bug_sage.py and it gives the error

Traceback (most recent call last):
  File "./bug_sage.py", line 12, in <module>
    print (tree(x*e**((x*log(x) + 1)/log(x))))
  File "./bug_sage.py", line 9, in tree
    return [expr.operator()]+map(tree, expr.operands()) 
TypeError: can only concatenate list (not "map") to list

In 8.9, no error is generated.

It looks like this is due to change in Python itself? This function is meant to generate list of all operands in expression in order to estimate the size of the expression. It is later used as follows

   len(flatten(tree(anti)))

Any idea how to fix it? Or do you suggest better way to obtain size of expression (called leaf count in other CAS systems).

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2020-03-09 22:02:39 +0200

rburing gravatar image

updated 2020-03-09 22:06:13 +0200

Yes, you are right: map no longer returns a list but rather an iterator. So you can do e.g.:

def tree(expr):     
    if expr.operator() is None: 
        return expr 
    else: 
        return [expr.operator()]+list(map(tree, expr.operands()))

You can also avoid map and write a list comprehension instead:

def tree(expr):     
    if expr.operator() is None: 
        return expr 
    else: 
        return [expr.operator()]+[tree(op) for op in expr.operands()]
edit flag offensive delete link more

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: 2020-03-09 21:52:26 +0200

Seen: 210 times

Last updated: Mar 09 '20