# 交互式Shell¶

## 你的Sage会议¶

_:  previous input (interactive shell and notebook)
__: next previous input (interactive shell only)
_oh : list of all inputs (interactive shell only)


sage: factor(100)
_1 = 2^2 * 5^2
sage: kronecker_symbol(3,5)
_2 = -1
sage: %hist   #This only works from the interactive shell, not the notebook.
1: factor(100)
2: kronecker_symbol(3,5)
3: %hist
sage: _oh
_4 = {1: 2^2 * 5^2, 2: -1}
sage: _i1
_5 = 'factor(ZZ(100))\n'
sage: eval(_i1)
_6 = 2^2 * 5^2
sage: %hist
1: factor(100)
2: kronecker_symbol(3,5)
3: %hist
4: _oh
5: _i1
6: eval(_i1)
7: %hist


sage: E = EllipticCurve([1,2,3,4,5])
sage: M = ModularSymbols(37)
sage: %hist
1: E = EllipticCurve([1,2,3,4,5])
2: M = ModularSymbols(37)
3: %hist
sage: %macro em 1-2
Macro em created. To execute, type its name (without quotes).

sage: E
Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over
Rational Field
sage: E = 5
sage: M = None
sage: em
Executing Macro...
sage: E
Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over
Rational Field


sage: !ls
auto  example.sage glossary.tex  t  tmp  tut.log  tut.tex


sage: !gp

GP/PARI CALCULATOR Version 2.2.11 (alpha)
i686 running linux (ix86/GMP-4.1.4 kernel) 32-bit version
...
sage: !singular
SINGULAR                             /  Development
A Computer Algebra System for Polynomial Computations   /   version 3-0-1
0<
by: G.-M. Greuel, G. Pfister, H. Schoenemann        \   October 2005
FB Mathematik der Universitaet, D-67653 Kaiserslautern    \


## 记录输入和输出¶

was@form:~$sage ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ │ Using Python 3.7.3. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: logstart setup Activating auto-logging. Current session state plus future input saved. Filename : setup Mode : backup Output logging : False Timestamping : False State : active sage: E = EllipticCurve([1,2,3,4,5]).minimal_model() sage: F = QQ^3 sage: x,y = QQ['x,y'].gens() sage: G = E.gens() sage: Exiting SAGE (CPU time 0m0.61s, Wall time 0m50.39s). was@form:~$ sage
┌────────────────────────────────────────────────────────────────────┐
│ SageMath version 9.0, Release Date: 2020-01-01                     │
│ Using Python 3.7.3. Type "help()" for help.                        │
└────────────────────────────────────────────────────────────────────┘

Finished replaying log file <setup>
sage: E
Elliptic Curve defined by y^2 + x*y  = x^3 - x^2 + 4*x + 3 over Rational
Field
sage: x*y
x*y
sage: G
[(2 : 3 : 1)]


## 粘贴忽略提示¶

sage: 2^10
1024
sage: sage: sage: 2^10
1024
sage: >>> 2^10
1024


## 定时命令¶

sage: %time a = int(1938)^int(99484)
CPU times: user 0.66 s, sys: 0.00 s, total: 0.66 s
Wall time: 0.66


sage: timeit("int(1938)^int(99484)")
5 loops, best of 3: 44.8 ms per loop


sage: %time a = 1938^99484
CPU times: user 0.04 s, sys: 0.00 s, total: 0.04 s
Wall time: 0.04


sage: %time a = pari(1938)^pari(99484)
CPU times: user 0.05 s, sys: 0.00 s, total: 0.05 s
Wall time: 0.05


GMP更好，但只是稍微好一点（正如预期的那样，因为为Sage构建的PARI版本使用GMP进行整数运算）。

sage: t = cputime()
sage: a = int(1938)^int(99484)
sage: b = 1938^99484
sage: c = pari(1938)^pari(99484)
sage: cputime(t)                       # somewhat random output
0.64

sage: cputime?
...
Return the time in CPU second since SAGE started, or with optional
argument t, return the time since time t.
INPUT:
t -- (optional) float, time in CPU seconds
OUTPUT:
float -- time in CPU seconds


sage: time 1938^99484;
CPU times: user 0.01 s, sys: 0.00 s, total: 0.01 s
Wall time: 0.01
sage: gp(0)
0
sage: time g = gp('1938^99484')
CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
Wall time: 0.04
sage: maxima(0)
0
sage: time g = maxima('1938^99484')
CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
Wall time: 0.30
sage: kash(0)
0
sage: time g = kash('1938^99484')
CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
Wall time: 0.04
sage: mathematica(0)
0
sage: time g = mathematica('1938^99484')
CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
Wall time: 0.03
sage: maple(0)
0
sage: time g = maple('1938^99484')
CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
Wall time: 0.11
sage: gap(0)
0
sage: time g = gap.eval('1938^99484;;')
CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
Wall time: 1.02


## 其他IPython技巧¶

• 你可以使用 %bg 在后台运行命令，然后使用 jobs 访问结果，如下所示。（评论 not tested 在这里是因为 %bg 语法不能很好地与Sage的自动测试工具配合使用。如果你自己输入这个，它应该能正常工作。当然，这对于需要一段时间才能完成的命令非常有用。）

sage: def quick(m): return 2*m
sage: %bg quick(20)  # not tested
Starting job # 0 in a separate thread.
sage: jobs.status()  # not tested
Completed jobs:
0 : quick(20)
sage: jobs[0].result  # the actual answer, not tested
40


请注意，在后台运行的作业不使用Sage preparser—请参阅 预解析器：Sage和Python的区别 了解更多信息。解决这个问题的一个（也许很尴尬）方法是跑步：

sage: %bg eval(preparse('quick(20)')) # not tested


不过，它更安全更容易使用 %bg 不需要preparser的命令。

• 你可以使用 %edit （或） %eded )打开一个编辑器，如果你想输入一些复杂的代码。在开始使用Sage之前，请确保 EDITOR 环境变量设置为您最喜欢的编辑器（通过 export EDITOR=/usr/bin/emacsexport EDITOR=/usr/bin/vim 或者类似的东西在适当的地方，比如 .profile 文件）。从Sage提示符，执行 %edit 将打开命名编辑器。然后可以在编辑器中定义函数：

def some_function(n):
return n**2 + 3*n + 2


保存并退出编辑器。在剩下的Sage会话中，您可以使用 some_function . 如果要修改它，请键入 %edit some_function 从明智的提示。

• 如果您有一个计算，并且要修改其输出以供其他用途，请执行计算和类型 %rep ：这将把上一个命令的输出放在Sage提示符下，供您编辑。:

sage: f(x) = cos(x)
sage: f(x).derivative(x)
-sin(x)


此时，如果您键入 %rep 在Sage提示符下，您将得到一个新的Sage提示符，后面跟着 -sin(x) ，光标位于行尾。

## 错误和异常¶

sage: 3_2
------------------------------------------------------------
File "<console>", line 1
ZZ(3)_2
^
SyntaxError: invalid syntax

sage: EllipticCurve([0,infinity])
------------------------------------------------------------
Traceback (most recent call last):
...
TypeError: Unable to coerce Infinity (<class 'sage...Infinity'>) to Rational


sage: %pdb
Automatic pdb calling has been turned ON
sage: EllipticCurve([1,infinity])
---------------------------------------------------------------------------
<type 'exceptions.TypeError'>             Traceback (most recent call last)
...

ipdb>


For a list of commands in the debugger, type ? at the ipdb> prompt:

ipdb> ?

Documented commands (type help <topic>):
========================================
EOF    break  commands   debug    h       l     pdef   quit    tbreak
a      bt     condition  disable  help    list  pdoc   r       u
alias  c      cont       down     ignore  n     pinfo  return  unalias
args   cl     continue   enable   j       next  pp     s       up
b      clear  d          exit     jump    p     q      step    w
whatis where

Miscellaneous help topics:
==========================
exec  pdb

Undocumented commands:
======================
retval  rv


## 反向搜索和制表符完成¶

sage: V = VectorSpace(QQ,3)
sage: V
Vector space of dimension 3 over Rational Field


sage: V = QQ^3


sage: V.[tab key]
V._VectorSpace_generic__base_field
...
V.ambient_space
V.base_field
V.base_ring
V.basis
V.coordinates
...
V.zero_vector


sage: V.i[tab key]
V.is_ambient  V.is_dense    V.is_full     V.is_sparse


## 集成帮助系统¶

Sage具有集成的帮助功能。键入函数名，后跟？用于该功能的文档。

sage: V = QQ^3
sage: V.coordinates?
Type:           instancemethod
Base Class:     <type 'instancemethod'>
String Form:    <bound method FreeModule_ambient_field.coordinates of Vector
space of dimension 3 over Rational Field>
Namespace:      Interactive
File:           /home/was/s/local/lib/python2.4/site-packages/sage/modules/f
ree_module.py
Definition:     V.coordinates(self, v)
Docstring:
Write v in terms of the basis for self.

Returns a list c such that if B is the basis for self, then

sum c_i B_i = v.

If v is not in self, raises an ArithmeticError exception.

EXAMPLES:
sage: M = FreeModule(IntegerRing(), 2); M0,M1=M.gens()
sage: W = M.submodule([M0 + M1, M0 - 2*M1])
sage: W.coordinates(2*M0-M1)
[2, -1]


sage: V = QQ^3
sage: V.coordinates??
Type:           instancemethod
...
Source:
def coordinates(self, v):
"""
Write $v$ in terms of the basis for self.
...
"""
return self.coordinate_vector(v).list()


sage: V = QQ^3
sage: V.coordinate_vector??
...
def coordinate_vector(self, v):
...
return self.ambient_vector_space()(v)


sage: V = QQ^3; W = V.span_of_basis([V.0, V.1])
sage: W.coordinate_vector??
...
def coordinate_vector(self, v):
"""
...
"""
# First find the coordinates of v wrt echelon basis.
w = self.echelon_coordinate_vector(v)
# Next use transformation matrix from echelon basis to
# user basis.
T = self.echelon_to_user_matrix()
return T.linear_combination_of_rows(w)


（如果您认为实现效率低下，请注册帮助优化线性代数。）

sage: help(VectorSpace)
Help on class VectorSpace ...

class VectorSpace(__builtin__.object)
|  Create a Vector Space.
|
|  To create an ambient space over a field with given dimension
|  using the calling syntax ...
:
:


## 保存和加载单个对象¶

1. 保存游戏： 只支持保存和加载完整的会话（例如GAP、Magma）。

2. Unified Input/Output: 使每个对象以可读回（GP/PARI）的方式打印。

3. Eval ：易于在解释器中计算任意代码（例如，单数、PARI）。

sage: A = MatrixSpace(QQ,3)(range(9))^2
sage: A
[ 15  18  21]
[ 42  54  66]
[ 69  90 111]
sage: save(A, 'A')


sage: A = load('A')
sage: A
[ 15  18  21]
[ 42  54  66]
[ 69  90 111]


sage: E = EllipticCurve('11a')
sage: v = E.anlist(100000)              # takes a while
sage: save(E, 'E')
sage: quit


~/tmp$ls -l E.sobj -rw-r--r-- 1 was was 153500 2006-01-28 19:23 E.sobj ~/tmp$ sage [...]
sage: v = E.anlist(100000)              # instant!


（在Python中，保存和加载是使用 cPickle 模块。尤其是Sage的东西 x 可以通过 cPickle.dumps(x, 2) . 注意 2 ！）

Sage无法保存和加载在其他计算机代数系统中创建的单个对象，例如GAP、Singular、Maxima等。它们在标记为“无效”的状态下重新加载。在GAP中，虽然许多物体以一种可以重建的形式打印出来，但许多物体没有，所以故意不允许从它们的打印表示中重建。

sage: a = gap(2)
sage: a.save('a')
Traceback (most recent call last):
...
ValueError: The session in which this object was defined is no longer
running.


GP/PARI对象可以保存和加载，因为它们的打印表示足以重建它们。

sage: a = gp(2)
sage: a.save('a')
2


### 另存为文本¶

sage: R.<x,y> = PolynomialRing(QQ,2)
sage: f = (x+y)^7
sage: o = open('file.txt','w')
sage: o.write(str(f))
sage: o.close()


## 保存和加载完整会话¶

Sage对保存和加载完整的会话有非常灵活的支持。

sage: E = EllipticCurve('11a')
sage: M = ModularSymbols(37)
sage: a = 389
sage: t = M.T(2003).matrix(); t.charpoly().factor()
_4 = (x - 2004) * (x - 12)^2 * (x + 54)^2


sage: save_session('misc')
Saving a
Saving M
Saving t
Saving E
sage: quit
was@form:~/tmp$ls -l misc.sobj -rw-r--r-- 1 was was 2979 2006-01-28 19:47 misc.sobj  最后，我们重新启动Sage，定义一个额外的变量，并加载保存的会话。 sage: b = 19 sage: load_session('misc') Loading a Loading M Loading E Loading t  每个保存的变量都将再次可用。此外，变量 b 未被覆盖。 sage: M Full Modular Symbols space for Gamma_0(37) of weight 2 with sign 0 and dimension 5 over Rational Field sage: E Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: b 19 sage: a 389  ## 旧式笔记本界面¶ 本节指的是传统的Sage笔记本或“sagenb”。 SageMath正在过渡到使用 Jupyter notebook 作为默认值，它具有不同的结构。对于用户来说，最重要的区别是Jupyter中的单个工作表与其他文件一样保存在本地系统上，而Sage笔记本的主要访问点是通过服务器在下面描述的文件中。 ### 传统SageNB笔记本¶ Sage笔记本是在启动Sage之后选择它来运行的 -n 选项。这将启动Sage笔记本并打开默认的web浏览器来查看它。服务器的状态文件存储在 $HOME/.sage/sage\_notebook.sagenb .

conf.pickle
openid.pickle
twistedconf.tac
sagenb.pid
users.pickle
home/guest/ (a directory for guests)
home/pub/ (a directory for published worksheets)


“笔记本”是用户帐户的集合，每个帐户可以有任意数量的工作表。创建新工作表时，定义该工作表的数据存储在 home/username/number 目录。在每个这样的目录中都有一个纯文本文件 worksheet.html -如果您的工作表、Sage或其他任何东西发生任何情况，那么这个人类可读的文件包含了重建工作表所需的所有内容。每个工作表还至少包含以下文件/文件夹：

cells/
worksheet.html
data/
worksheet_conf.pickle


----------------------
|                    |
|                    |
|   firefox/safari   |
|                    |
|     javascript     |
|      program       |
|                    |
|                    |
----------------------
|      ^
| AJAX |
V      |
----------------------
|                    |
|       sage         |                SAGE process 1
|       web          | ------------>  SAGE process 2    (Python processes)
|      server        |   pexpect      SAGE process 3
|                    |                    .
|                    |                    .
----------------------                    .