<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Программирование — Sage Tutorial in Russian v5.9</title> <link rel="stylesheet" href="_static/sage.css" type="text/css" /> <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '', VERSION: '5.9', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> <script type="text/javascript" src="_static/translations.js"></script> <link rel="shortcut icon" href="_static/favicon.ico"/> <link rel="top" title="Sage Tutorial in Russian v5.9" href="index.html" /> <link rel="next" title="Использование SageTeX" href="sagetex.html" /> <link rel="prev" title="Интерфейсы" href="interfaces.html" /> <link rel="icon" href="_static/sageicon.png" type="image/x-icon" /> </head> <body> <div class="related"> <h3>Просмотр</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="genindex.html" title="Словарь-указатель" accesskey="I">словарь</a></li> <li class="right" > <a href="py-modindex.html" title="Python Module Index" >модули</a> |</li> <li class="right" > <a href="sagetex.html" title="Использование SageTeX" accesskey="N">следующий</a> |</li> <li class="right" > <a href="interfaces.html" title="Интерфейсы" accesskey="P">предыдущий</a> |</li> <a href="../index.html"><img src="_static/sagelogo.png" style="vertical-align: middle" title="Sage Logo"></a> <li><a href="index.html">Sage Tutorial in Russian v5.9</a> »</li> </ul> </div> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body"> <div class="section" id="id1"> <h1>Программирование<a class="headerlink" href="#id1" title="Ссылка на этот заголовок">¶</a></h1> <div class="section" id="sage"> <span id="section-loadattach"></span><h2>Загрузка и прикрепление файлов Sage<a class="headerlink" href="#sage" title="Ссылка на этот заголовок">¶</a></h2> <p>Следующее показывает, как подгружать программы в Sage, записанные в отдельный файл. Создайте файл <tt class="docutils literal"><span class="pre">example.sage</span></tt> со следующим содержанием:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">print</span> <span class="s">"Hello World"</span> <span class="k">print</span> <span class="mi">2</span><span class="o">^</span><span class="mi">3</span> </pre></div> </div> <p>Вы можете прочитать и выполнить <tt class="docutils literal"><span class="pre">example.sage</span></tt> с помощью команды <tt class="docutils literal"><span class="pre">load</span></tt>.</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: load "example.sage"</span> <span class="go">Hello World</span> <span class="go">8</span> </pre></div> </div> <p>Вы также можете прикрепить файл Sage к запущенной сессии в помощью команды <tt class="docutils literal"><span class="pre">attach</span></tt>:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: attach "example.sage"</span> <span class="go">Hello World</span> <span class="go">8</span> </pre></div> </div> <p>Теперь если вы измените файл <tt class="docutils literal"><span class="pre">example.sage</span></tt> и введете пустую строку в Sage (т.е. нажмите <tt class="docutils literal"><span class="pre">return</span></tt>), то содержимое <tt class="docutils literal"><span class="pre">example.sage</span></tt> будет автоматически перегружено в Sage.</p> <p>В частности, <tt class="docutils literal"><span class="pre">attach</span></tt> автоматически перегружает файл, как только он изменен, что очень удобно при поиске ошибок в коде, тогда как <tt class="docutils literal"><span class="pre">load</span></tt> загружает файл лишь единожды.</p> <p>Когда <tt class="docutils literal"><span class="pre">example.sage</span></tt> загружается в Sage, он переводится в Python, а затем выполняется с помощью интерпретатора Python. Затраты на данную операцию минимальны; в основном, это включает в себя перевод целых констант в <tt class="docutils literal"><span class="pre">Integer()</span></tt>, дробных констант в <tt class="docutils literal"><span class="pre">RealNumber()</span></tt>, замену <tt class="docutils literal"><span class="pre">^</span></tt> на <tt class="docutils literal"><span class="pre">**</span></tt> и, например, <tt class="docutils literal"><span class="pre">R.2</span></tt> на <tt class="docutils literal"><span class="pre">R.gen(2)</span></tt>. Переведенная версия <tt class="docutils literal"><span class="pre">example.sage</span></tt> будет содержаться в той же директории, что <tt class="docutils literal"><span class="pre">example.sage</span></tt>, под названием <tt class="docutils literal"><span class="pre">example.sage.py</span></tt>. Данный файл будет содержать следующий код:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">print</span> <span class="s">"Hello World"</span> <span class="k">print</span> <span class="n">Integer</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span><span class="o">**</span><span class="n">Integer</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span> </pre></div> </div> <p>Целые контстанты переведены и <tt class="docutils literal"><span class="pre">^</span></tt> заменено на <tt class="docutils literal"><span class="pre">**</span></tt>. (В Python <tt class="docutils literal"><span class="pre">^</span></tt> означает “исключающее ИЛИ” и <tt class="docutils literal"><span class="pre">**</span></tt> означает “возведение в степень”.)</p> <p>Данные операции выполняются в <tt class="docutils literal"><span class="pre">sage/misc/interpreter.py</span></tt>.)</p> <p>Вы имеете возможность вставлять многострочный код с отступами в Sage до тех пор, пока есть новые строки для новых блоков (это необязательно для файлов). Однако, лучшим способом для вставки такого кода является сохранение в файл и использование <tt class="docutils literal"><span class="pre">attach</span></tt>, как описано выше.</p> </div> <div class="section" id="section-compile"> <span id="id2"></span><h2>Создание компилированного кода<a class="headerlink" href="#section-compile" title="Ссылка на этот заголовок">¶</a></h2> <p>Скорость — важная составляющая в математических вычислениях. Хотя Python является высокоуровневым языком программирования, некоторые вычисления могут быть выполнены на несколько порядков быстрее в Python при использовании статических типов данных при компилировании. Некоторые компоненты Sage были бы слишком медленными, будь он написан целиком на Python. Для этого Sage поддерживает компилированную “версию” Python, которая называется Cython (<a class="reference internal" href="bibliography.html#cyt">[Cyt]</a> и <a class="reference internal" href="bibliography.html#pyr">[Pyr]</a>). Cython одновременно похож и на Python, и на C. Большинство конструкций Python, включая представление списков, условные выражения, код наподобие <tt class="docutils literal"><span class="pre">+=</span></tt>, разрешены; вы также можете импортировать код, написанный в других модулях Python. Кроме того, вы можете объявлять произвольные переменные C и напрямую обращаться к библиотекам C. Конечный код будет сконвертирован в C и обработан компилятором C.</p> <p>Для того, чтобы создать компилируемый код в Sage, объявите файл с расширением <tt class="docutils literal"><span class="pre">.spyx</span></tt> (вместо <tt class="docutils literal"><span class="pre">.sage</span></tt>). Если вы работаете с интерфейсом коммандной строки, вы можете прикреплять и загружать компилируемый код точно так же, как и интерпретируемый (на данный момент, прикрепление и загрузка кода на Cython не поддерживается в интерфейсе Notebook). Само компилирование происходит “за кулисами”, не требуя каких-либо действий с вашей стороны. Просмотреть пример компилированного исполнения функции факториал, которое напрямую использует библиотеки GMP на C, можно в <tt class="docutils literal"><span class="pre">$SAGE_ROOT/examples/programming/sagex/factorial.spyx</span></tt>. Для того, чтобы опробовать это самому, перейдите в <tt class="docutils literal"><span class="pre">$SAGE_ROOT/examples/programming/sagex/</span></tt> с помощью cd, а затем выполниет следующее:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: load "factorial.spyx"</span> <span class="go">***************************************************</span> <span class="go"> Recompiling factorial.spyx</span> <span class="go">***************************************************</span> <span class="go">sage: factorial(50)</span> <span class="go">30414093201713378043612608166064768844377641568960512000000000000L</span> <span class="go">sage: time n = factorial(10000)</span> <span class="go">CPU times: user 0.03 s, sys: 0.00 s, total: 0.03 s</span> <span class="go">Wall time: 0.03</span> </pre></div> </div> <p>В данном примере L в конце означает Python long integer (см. <a class="reference internal" href="afterword.html#section-mathannoy"><em>Пре-парсер: Различия между Sage и Python</em></a>).</p> <p>Заметьте, что Sage перекомпилирует <tt class="docutils literal"><span class="pre">factorial.spyx</span></tt> в том случае, если вы выйдете и перезапустите Sage. Компилированная библиотека общих объектов содержится в <tt class="docutils literal"><span class="pre">$HOME/.sage/temp/hostname/pid/spyx</span></tt>. Эти файлы будут удалены при выходе из Sage.</p> <p>Пре-парсировка не применяется к spyx файлам. Например <tt class="docutils literal"><span class="pre">1/3</span></tt> превратится в 0 в spyx файле вместо рационального числа <img class="math" src="_images/math/217aedbdc339bacc8ba075a2ec16902b098194e3.png" alt="1/3"/>. Допустим, <tt class="docutils literal"><span class="pre">foo</span></tt> - это функция в библиотеке Sage. Для того, чтобы использовать ее из spyx-файла, импортируйте <tt class="docutils literal"><span class="pre">sage.all</span></tt> и примените <tt class="docutils literal"><span class="pre">sage.all.foo</span></tt>.</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">sage.all</span> <span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">n</span><span class="p">):</span> <span class="k">return</span> <span class="n">sage</span><span class="o">.</span><span class="n">all</span><span class="o">.</span><span class="n">factorial</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> </pre></div> </div> <div class="section" id="id5"> <h3>Доступ к функциям С из внешних файлов<a class="headerlink" href="#id5" title="Ссылка на этот заголовок">¶</a></h3> <p>Доступ к функциям C из внешних <tt class="docutils literal"><span class="pre">*.c</span></tt> файлов осуществляется довольно просто. Создайте файлы <tt class="docutils literal"><span class="pre">test.c</span></tt> и <tt class="docutils literal"><span class="pre">test.spyx</span></tt> в одной директории со следующим содержанием:</p> <p>Код на языке С: <tt class="docutils literal"><span class="pre">test.c</span></tt></p> <div class="highlight-python"><pre>int add_one(int n) { return n + 1; }</pre> </div> <p>Код на языке Cython: <tt class="docutils literal"><span class="pre">test.spyx</span></tt>:</p> <div class="highlight-python"><pre>cdef extern from "test.c": int add_one(int n) def test(n): return add_one(n)</pre> </div> <p>Выполните:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: attach "test.spyx"</span> <span class="go">Compiling (...)/test.spyx...</span> <span class="go">sage: test(10)</span> <span class="go">11</span> </pre></div> </div> <p>В том случае, если понадобится дополнительная библиотека <tt class="docutils literal"><span class="pre">foo</span></tt> для того, чтобы скомпилировать код на C, полученный из файла Cython, добавьте <tt class="docutils literal"><span class="pre">clib</span> <span class="pre">foo</span></tt> в источник Cython кода. Аналогично, дополнительный С файл <tt class="docutils literal"><span class="pre">bar</span></tt> может быть добавлен в компиляцию с объявлением <tt class="docutils literal"><span class="pre">cfile</span> <span class="pre">bar</span></tt>.</p> </div> </div> <div class="section" id="python-sage"> <span id="section-standalone"></span><h2>Самостоятельные скрипты Python/Sage<a class="headerlink" href="#python-sage" title="Ссылка на этот заголовок">¶</a></h2> <p>Данный самостоятельный скрипт Sage раскладывает на множители целые числа, полиномы и т.д.:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/env sage -python</span> <span class="kn">import</span> <span class="nn">sys</span> <span class="kn">from</span> <span class="nn">sage.all</span> <span class="kn">import</span> <span class="o">*</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span> <span class="k">print</span> <span class="s">"Usage: </span><span class="si">%s</span><span class="s"> <n>"</span><span class="o">%</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">print</span> <span class="s">"Outputs the prime factorization of n."</span> <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">print</span> <span class="n">factor</span><span class="p">(</span><span class="n">sage_eval</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]))</span> </pre></div> </div> <p>Для того, чтобы использовать этот скрипт, <tt class="docutils literal"><span class="pre">SAGE_ROOT</span></tt> должен быть в PATH. Если вышеописанный скрипт называется <tt class="docutils literal"><span class="pre">factor</span></tt>, следующее показывает, как его выполнить:</p> <div class="highlight-python"><pre>bash $ ./factor 2006 2 * 17 * 59 bash $ ./factor "32*x^5-1" (2*x - 1) * (16*x^4 + 8*x^3 + 4*x^2 + 2*x + 1)</pre> </div> </div> <div class="section" id="id6"> <h2>Типы данных<a class="headerlink" href="#id6" title="Ссылка на этот заголовок">¶</a></h2> <p>Каждый объект в Sage имеет определенный тип. Python включает в себя большой спектр встроенных типов тогда, как библиотеки Sage добавляют еще больше. Встроенные типы данных Python включают в себя символьные строки, списки, кортежи, целые и дробные числа:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: s = "sage"; type(s)</span> <span class="go"><type 'str'></span> <span class="go">sage: s = 'sage'; type(s) # Вы можете использовать двойные или одинарные кавычки</span> <span class="go"><type 'str'></span> <span class="go">sage: s = [1,2,3,4]; type(s)</span> <span class="go"><type 'list'></span> <span class="go">sage: s = (1,2,3,4); type(s)</span> <span class="go"><type 'tuple'></span> <span class="go">sage: s = int(2006); type(s)</span> <span class="go"><type 'int'></span> <span class="go">sage: s = float(2006); type(s)</span> <span class="go"><type 'float'></span> </pre></div> </div> <p>В свою очередь Sage добавляет много других типов данных, например, векторное поле:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: V = VectorSpace(QQ, 1000000); V</span> <span class="go">Vector space of dimension 1000000 over Rational Field</span> <span class="go">sage: type(V)</span> <span class="go"><class 'sage.modules.free_module.FreeModule_ambient_field_with_category'></span> </pre></div> </div> <p>Только определенные функции могут быть применены к <tt class="docutils literal"><span class="pre">V</span></tt>. В других математических программах функции вызывались бы в “функциональном” виде: <tt class="docutils literal"><span class="pre">foo(V,...)</span></tt>. В Sage определенные функции прикреплены к типу (или классу) <tt class="docutils literal"><span class="pre">V</span></tt> и вызываются с помощью объектно-ориентированного синтаксиса, как в Java или C++, например, <tt class="docutils literal"><span class="pre">V.foo(...)</span></tt>. Это способствует тому, что именная область видимости не захламляется десятками тысяч функций, и означает, что многие функции с разным содержанием могут быть названы “foo” без проверки типов аргументов. Также, если Вы используете имя функции повторно, эта функция все равно доступна (например, если Вы вызываете что-то наподобие <tt class="docutils literal"><span class="pre">zeta</span></tt>, а затем хотите вычислить значение функции Riemann-Zeta при 0.5, Вы можете напечатать <tt class="docutils literal"><span class="pre">s=.5;</span> <span class="pre">s.zeta()</span></tt>).</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: zeta = -1</span> <span class="go">sage: s=.5; s.zeta()</span> <span class="go">-1.46035450880959</span> </pre></div> </div> <p>В некоторых часто встречающихся случаях, обычное функциональное обозначение также способствует удобству из-за того, что математические выражения могут выглядеть запутанно при исаользовании объектно-ориентированного обозначения. Например:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: n = 2; n.sqrt()</span> <span class="go">sqrt(2)</span> <span class="go">sage: sqrt(2)</span> <span class="go">sqrt(2)</span> <span class="go">sage: V = VectorSpace(QQ,2)</span> <span class="go">sage: V.basis()</span> <span class="go"> [</span> <span class="go"> (1, 0),</span> <span class="go"> (0, 1)</span> <span class="go"> ]</span> <span class="go">sage: basis(V)</span> <span class="go"> [</span> <span class="go"> (1, 0),</span> <span class="go"> (0, 1)</span> <span class="go"> ]</span> <span class="go">sage: M = MatrixSpace(GF(7), 2); M</span> <span class="go">Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7</span> <span class="go">sage: A = M([1,2,3,4]); A</span> <span class="go">[1 2]</span> <span class="go">[3 4]</span> <span class="go">sage: A.charpoly('x')</span> <span class="go">x^2 + 2*x + 5</span> <span class="go">sage: charpoly(A, 'x')</span> <span class="go">x^2 + 2*x + 5</span> </pre></div> </div> <p>Для того, чтобы перечислить все члены-функции для <img class="math" src="_images/math/019e9892786e493964e145e7c5cf7b700314e53b.png" alt="A"/>, напечатайте <tt class="docutils literal"><span class="pre">A.</span></tt>, а затем нажмите кнопку <tt class="docutils literal"><span class="pre">[tab]</span></tt> на Вашей клавиатуре, как описано в разделе <a class="reference internal" href="interactive_shell.html#section-tabcompletion"><em>Обратный поиск и автодополнение</em></a></p> </div> <div class="section" id="id7"> <h2>Списки, кортежи и последовательности<a class="headerlink" href="#id7" title="Ссылка на этот заголовок">¶</a></h2> <p>Тип данных список может хранить в себе элементы разных типов данных. Как в C, C++ и т.д., но в отличие от других алгебраических систем, элементы списка начинаются с индекса <img class="math" src="_images/math/bc1f9d9bf8a1b606a4188b5ce9a2af1809e27a89.png" alt="0"/>:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: v = [2, 3, 5, 'x', SymmetricGroup(3)]; v</span> <span class="go">[2, 3, 5, 'x', Symmetric group of order 3! as a permutation group]</span> <span class="go">sage: type(v)</span> <span class="go"><type 'list'></span> <span class="go">sage: v[0]</span> <span class="go">2</span> <span class="go">sage: v[2]</span> <span class="go">5</span> </pre></div> </div> <p>При индексировании списка, применение индексов, не являющихся целым числом Python, сработает нормально.</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: v = [1,2,3]</span> <span class="go">sage: v[2]</span> <span class="go">3</span> <span class="go">sage: n = 2 # целое число Sage</span> <span class="go">sage: v[n] # работает правильно</span> <span class="go">3</span> <span class="go">sage: v[int(n)] # тоже работает правильно</span> <span class="go">3</span> </pre></div> </div> <p>Функция <tt class="docutils literal"><span class="pre">range</span></tt> создает список целых чисел, используемых Python(не Sage):</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: range(1, 15)</span> <span class="go">[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]</span> </pre></div> </div> <p>Это удобно, когда для создания списков используется вид списка:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: L = [factor(n) for n in range(1, 15)]</span> <span class="go">sage: print L</span> <span class="go">[1, 2, 3, 2^2, 5, 2 * 3, 7, 2^3, 3^2, 2 * 5, 11, 2^2 * 3, 13, 2 * 7]</span> <span class="go">sage: L[12]</span> <span class="go">13</span> <span class="go">sage: type(L[12])</span> <span class="go"><class 'sage.structure.factorization_integer.IntegerFactorization'></span> <span class="go">sage: [factor(n) for n in range(1, 15) if is_odd(n)]</span> <span class="go">[1, 3, 5, 7, 3^2, 11, 13]</span> </pre></div> </div> <p>Для большего понимания списков см. <a class="reference internal" href="bibliography.html#pyt">[PyT]</a>.</p> <p>Расщепление списков - это очень удобный инструмент. Допустим <tt class="docutils literal"><span class="pre">L</span></tt> - это список, тогда <tt class="docutils literal"><span class="pre">L[m:n]</span></tt> вернет под-список L, полученный, начиная с элемента на позиции <img class="math" src="_images/math/f5047d1e0cbb50ec208923a22cd517c55100fa7b.png" alt="m"/> и заканчивая элементом на позиции <img class="math" src="_images/math/7955459cf8b75c3ac12c23c393024177d7d56412.png" alt="(n-1)"/>, как показано ниже.</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: L = [factor(n) for n in range(1, 20)]</span> <span class="go">sage: L[4:9]</span> <span class="go">[5, 2 * 3, 7, 2^3, 3^2]</span> <span class="go">sage: print L[:4]</span> <span class="go">[1, 2, 3, 2^2]</span> <span class="go">sage: L[14:4]</span> <span class="go">[]</span> <span class="go">sage: L[14:]</span> <span class="go">[3 * 5, 2^4, 17, 2 * 3^2, 19]</span> </pre></div> </div> <p>Кортежи имеют сходство со списками, однако они неизменяемы с момента создания.</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: v = (1,2,3,4); v</span> <span class="go">(1, 2, 3, 4)</span> <span class="go">sage: type(v)</span> <span class="go"><type 'tuple'></span> <span class="go">sage: v[1] = 5</span> <span class="gt">Traceback (most recent call last):</span> <span class="c">...</span> <span class="gr">TypeError</span>: <span class="n">'tuple' object does not support item assignment</span> </pre></div> </div> <p>Последовательности - это тип данных, схожий по свойствам со списком. Последовательности как тип данных не встроены в Python в отличие от списков и кортежей. По умолчанию, последовательность является изменяемой, однако используя метод <tt class="docutils literal"><span class="pre">set_immutable</span></tt> из класса <tt class="docutils literal"><span class="pre">Sequence</span></tt>, она может быть сделана неизменяемой, как показано в следующем примере. Все элементы последовательности имеют общего родителя, именуемого универсумом последовательости.</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: v = Sequence([1,2,3,4/5])</span> <span class="go">sage: v</span> <span class="go">[1, 2, 3, 4/5]</span> <span class="go">sage: type(v)</span> <span class="go"><class 'sage.structure.sequence.Sequence_generic'></span> <span class="go">sage: type(v[1])</span> <span class="go"><type 'sage.rings.rational.Rational'></span> <span class="go">sage: v.universe()</span> <span class="go">Rational Field</span> <span class="go">sage: v.is_immutable()</span> <span class="go">False</span> <span class="go">sage: v.set_immutable()</span> <span class="go">sage: v[0] = 3</span> <span class="gt">Traceback (most recent call last):</span> <span class="c">...</span> <span class="gr">ValueError</span>: <span class="n">object is immutable; please change a copy instead.</span> </pre></div> </div> <p>Последовательности могут быть использованы везде, где могут быть использованы списки:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: v = Sequence([1,2,3,4/5])</span> <span class="go">sage: isinstance(v, list)</span> <span class="go">True</span> <span class="go">sage: list(v)</span> <span class="go">[1, 2, 3, 4/5]</span> <span class="go">sage: type(list(v))</span> <span class="go"><type 'list'></span> </pre></div> </div> <p>Базис для векторного поля является неизменяемой последовательностью, так как очень важно не изменять их. Это показано в следующем примере:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: V = QQ^3; B = V.basis(); B</span> <span class="go">[</span> <span class="go">(1, 0, 0),</span> <span class="go">(0, 1, 0),</span> <span class="go">(0, 0, 1)</span> <span class="go">]</span> <span class="go">sage: type(B)</span> <span class="go"><class 'sage.structure.sequence.Sequence_generic'></span> <span class="go">sage: B[0] = B[1]</span> <span class="gt">Traceback (most recent call last):</span> <span class="c">...</span> <span class="gr">ValueError</span>: <span class="n">object is immutable; please change a copy instead.</span> <span class="go">sage: B.universe()</span> <span class="go">Vector space of dimension 3 over Rational Field</span> </pre></div> </div> </div> <div class="section" id="id9"> <h2>Словари<a class="headerlink" href="#id9" title="Ссылка на этот заголовок">¶</a></h2> <p>Словарь (также именуемый ассоциативным массивом) - это сопоставление ‘хэшируемых’ объектов (как строки, числа и кортежи из них; см. документацию Python: <a class="reference external" href="http://docs.python.org/tut/node7.html">http://docs.python.org/tut/node7.html</a> и <a class="reference external" href="http://docs.python.org/lib/typesmapping.html">http://docs.python.org/lib/typesmapping.html</a>) произвольным объектам.</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: d = {1:5, 'sage':17, ZZ:GF(7)}</span> <span class="go">sage: type(d)</span> <span class="go"><type 'dict'></span> <span class="go">sage: d.keys()</span> <span class="go"> [1, 'sage', Integer Ring]</span> <span class="go">sage: d['sage']</span> <span class="go">17</span> <span class="go">sage: d[ZZ]</span> <span class="go">Finite Field of size 7</span> <span class="go">sage: d[1]</span> <span class="go">5</span> </pre></div> </div> <p>Третий ключ показывает, что индексы словаря могу быть сложными, как, например, кольцо целых чисел.</p> <p>Можно превратить вышеописанный словарь в список с тем же содержимым:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: d.items()</span> <span class="go">[(1, 5), ('sage', 17), (Integer Ring, Finite Field of size 7)]</span> </pre></div> </div> <p>Часто используемой практикой является произведение итераций по парам в словаре:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: d = {2:4, 3:9, 4:16}</span> <span class="go">sage: [a*b for a, b in d.iteritems()]</span> <span class="go">[8, 27, 64]</span> </pre></div> </div> <p>Как показывает последний пример, словарь не упорядочен.</p> </div> <div class="section" id="id10"> <h2>Множества<a class="headerlink" href="#id10" title="Ссылка на этот заголовок">¶</a></h2> <p>В Python есть встроенный тип множество. Главным преимуществом этого типа является быстрый просмотр, проверка того, принадлежит ли элемент множеству, а также обычные операции из теории множеств.</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: X = set([1,19,'a']); Y = set([1,1,1, 2/3])</span> <span class="go">sage: X</span> <span class="go">set(['a', 1, 19])</span> <span class="go">sage: Y</span> <span class="go">set([1, 2/3])</span> <span class="go">sage: 'a' in X</span> <span class="go">True</span> <span class="go">sage: 'a' in Y</span> <span class="go">False</span> <span class="go">sage: X.intersection(Y)</span> <span class="go">set([1])</span> </pre></div> </div> <p>В Sage также имеется свой тип данных множество, который (в некоторых случаях) осуществлен с использованием встроенного типа множество Python, но включает в себя функциональность, связанную с Sage. Создайте множество Sage с помощью <tt class="docutils literal"><span class="pre">Set(...)</span></tt>. Например,</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: X = Set([1,19,'a']); Y = Set([1,1,1, 2/3])</span> <span class="go">sage: X</span> <span class="go">{'a', 1, 19}</span> <span class="go">sage: Y</span> <span class="go">{1, 2/3}</span> <span class="go">sage: X.intersection(Y)</span> <span class="go">{1}</span> <span class="go">sage: print latex(Y)</span> <span class="go">\left\{1, \frac{2}{3}\right\}</span> <span class="go">sage: Set(ZZ)</span> <span class="go">Set of elements of Integer Ring</span> </pre></div> </div> </div> <div class="section" id="id11"> <h2>Итераторы<a class="headerlink" href="#id11" title="Ссылка на этот заголовок">¶</a></h2> <p>Итераторы - это сравнительно недавнее добавление в Python, которое является очень полезным в математических приложениях. Несколько примеров использования итераторов приведены ниже; подробнее см. <a class="reference internal" href="bibliography.html#pyt">[PyT]</a>. Здесь создается итератор для квадратов неотрицательных чисел до <img class="math" src="_images/math/c4b7944fa276d9ec5b24da0d60c54d903a67dae4.png" alt="10000000"/>.</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: v = (n^2 for n in xrange(10000000))</span> <span class="go">sage: v.next()</span> <span class="go">0</span> <span class="go">sage: v.next()</span> <span class="go">1</span> <span class="go">sage: v.next()</span> <span class="go">4</span> </pre></div> </div> <p>Следующий пример - создание итераторов из простых чисел вида <img class="math" src="_images/math/2a1db6fdf22b67fce46356a3e76964125408175b.png" alt="4p+1"/> с простым <img class="math" src="_images/math/36f73fc1312ee0349b3f3a0f3bd9eb5504339011.png" alt="p"/> и просмотр нескольких первых значений:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: w = (4*p + 1 for p in Primes() if is_prime(4*p+1))</span> <span class="go">sage: w # random output на следующей строке 0xb0853d6c может быть другим шестнадцатиричным числом</span> <span class="go"><generator object at 0xb0853d6c></span> <span class="go">sage: w.next()</span> <span class="go">13</span> <span class="go">sage: w.next()</span> <span class="go">29</span> <span class="go">sage: w.next()</span> <span class="go">53</span> </pre></div> </div> <p>Определенные кольца, как и конечные поля и целые числа, имеют итераторы:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: [x for x in GF(7)]</span> <span class="go">[0, 1, 2, 3, 4, 5, 6]</span> <span class="go">sage: W = ((x,y) for x in ZZ for y in ZZ)</span> <span class="go">sage: W.next()</span> <span class="go">(0, 0)</span> <span class="go">sage: W.next()</span> <span class="go">(0, 1)</span> <span class="go">sage: W.next()</span> <span class="go">(0, -1)</span> </pre></div> </div> </div> <div class="section" id="id13"> <h2>Циклы, функции, управляющие конструкции и сравнения<a class="headerlink" href="#id13" title="Ссылка на этот заголовок">¶</a></h2> <p>Мы уже видели несколько примеров с использованием циклов <tt class="docutils literal"><span class="pre">for</span></tt>. В Python цикл <tt class="docutils literal"><span class="pre">for</span></tt> имеет табулированную структуру:</p> <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">5</span><span class="p">):</span> <span class="gp">... </span> <span class="k">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="gp">...</span> <span class="go">0</span> <span class="go">1</span> <span class="go">2</span> <span class="go">3</span> <span class="go">4</span> </pre></div> </div> <p>Заметьте двоеточие на конце выражения(“do” или “od”, как GAP или Maple, не используются), а отступы перед “телом” цикла, в частности, перед <tt class="docutils literal"><span class="pre">print(i)</span></tt>. Эти отступы важны. В Sage отступы ставятся автоматически при нажатии <tt class="docutils literal"><span class="pre">enter</span></tt> после ”:”, как показано ниже.</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: for i in range(5):</span> <span class="go">....: print(i) # нажмите Enter дважды</span> <span class="go">....:</span> <span class="go">0</span> <span class="go">1</span> <span class="go">2</span> <span class="go">3</span> <span class="go">4</span> </pre></div> </div> <p>Символ <tt class="docutils literal"><span class="pre">=</span></tt> используется для присваивания. Символ <tt class="docutils literal"><span class="pre">==</span></tt> используется для проверки равенства:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: for i in range(15):</span> <span class="gp">... </span> <span class="k">if</span> <span class="n">gcd</span><span class="p">(</span><span class="n">i</span><span class="p">,</span><span class="mi">15</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span> <span class="gp">... </span> <span class="k">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="go">1</span> <span class="go">2</span> <span class="go">4</span> <span class="go">7</span> <span class="go">8</span> <span class="go">11</span> <span class="go">13</span> <span class="go">14</span> </pre></div> </div> <p>Имейте в виду, как табуляция определяет структуру блоков для операторов <tt class="docutils literal"><span class="pre">if</span></tt>, <tt class="docutils literal"><span class="pre">for</span></tt> и <tt class="docutils literal"><span class="pre">while</span></tt>:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: def legendre(a,p):</span> <span class="gp">... </span> <span class="n">is_sqr_modp</span><span class="o">=-</span><span class="mi">1</span> <span class="gp">... </span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">p</span><span class="p">):</span> <span class="gp">... </span> <span class="k">if</span> <span class="n">a</span> <span class="o">%</span> <span class="n">p</span> <span class="o">==</span> <span class="n">i</span><span class="o">^</span><span class="mi">2</span> <span class="o">%</span> <span class="n">p</span><span class="p">:</span> <span class="gp">... </span> <span class="n">is_sqr_modp</span><span class="o">=</span><span class="mi">1</span> <span class="gp">... </span> <span class="k">return</span> <span class="n">is_sqr_modp</span> <span class="go">sage: legendre(2,7)</span> <span class="go">1</span> <span class="go">sage: legendre(3,7)</span> <span class="go">-1</span> </pre></div> </div> <p>Конечно, это не эффективная реализация символа Лежандра! Данный пример служит лишь иллюстрацией разных аспектов программирования в Python/Sage. Функция {kronecker}, встроенная в Sage, подсчитывает символ Лежандра эффективно с использованием библиотек C, в частности, с использованием PARI.</p> <p>Сравнения <tt class="docutils literal"><span class="pre">==</span></tt>, <tt class="docutils literal"><span class="pre">!=</span></tt>, <tt class="docutils literal"><span class="pre"><=</span></tt>, <tt class="docutils literal"><span class="pre">>=</span></tt>, <tt class="docutils literal"><span class="pre">></span></tt>, <tt class="docutils literal"><span class="pre"><</span></tt> между числами автоматически переводят оба члена в одинаковый тип:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: 2 < 3.1; 3.1 <= 1</span> <span class="go">True</span> <span class="go">False</span> <span class="go">sage: 2/3 < 3/2; 3/2 < 3/1</span> <span class="go">True</span> <span class="go">True</span> </pre></div> </div> <p>Практически любые два объекта могут быть сравнены.</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: 2 < CC(3.1,1)</span> <span class="go">True</span> <span class="go">sage: 5 < VectorSpace(QQ,3) # random output</span> <span class="go">True</span> </pre></div> </div> <p>Используйте переменные bool для символьных неравенств:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: x < x + 1</span> <span class="go">x < x + 1</span> <span class="go">sage: bool(x < x + 1)</span> <span class="go">True</span> </pre></div> </div> <p>При сравнении объектов разного типа в большинстве случаев Sage попытается найти каноническое приведение обоих к общему родителю. При успехе, сравнение выполняется между приведёнными объектами; если нет, то объекты будут расценены как неравные. Для проверки равенства двух переменных используйте <tt class="docutils literal"><span class="pre">is</span></tt>. Например:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: 1 is 2/2</span> <span class="go">False</span> <span class="go">sage: 1 is 1</span> <span class="go">False</span> <span class="go">sage: 1 == 2/2</span> <span class="go">True</span> </pre></div> </div> <p>В следующих двух строках первое неравенство дает <tt class="docutils literal"><span class="pre">False</span></tt>, так как нет канонического морфизма <img class="math" src="_images/math/b748dc67ed08d23e72eaecdcdc706c48c3fe2334.png" alt="\QQ\to \GF{5}"/>, поэтому не существует канонического сравнения между <img class="math" src="_images/math/dce34f4dfb2406144304ad0d6106c5382ddd1446.png" alt="1"/> в <img class="math" src="_images/math/a0c8a3534da46e2c30e5fb267dd7afec808bd531.png" alt="\GF{5}"/> и <img class="math" src="_images/math/ba8e101dc0e5943893e54746db6f32b4629d4615.png" alt="1 \in \QQ"/>. Однако, существует каноническое приведение <img class="math" src="_images/math/b64f4251e07b91d5be522e16faf6c07a69a0af63.png" alt="\ZZ \to \GF{5}"/>, поэтому второе выражение дает <tt class="docutils literal"><span class="pre">True</span></tt>. Заметьте, порядок не имеет значения.</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: GF(5)(1) == QQ(1); QQ(1) == GF(5)(1)</span> <span class="go">False</span> <span class="go">False</span> <span class="go">sage: GF(5)(1) == ZZ(1); ZZ(1) == GF(5)(1)</span> <span class="go">True</span> <span class="go">True</span> <span class="go">sage: ZZ(1) == QQ(1)</span> <span class="go">True</span> </pre></div> </div> <p>ВНИМАНИЕ: Сравнение в Sage проводится более жёстко, чем в Magma, которая объявляет <img class="math" src="_images/math/08ce2169a2f6b9619e29d0023d29e9b0a9a52083.png" alt="1 \in \GF{5}"/> равным <img class="math" src="_images/math/ba8e101dc0e5943893e54746db6f32b4629d4615.png" alt="1 \in \QQ"/>.</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: magma('GF(5)!1 eq Rationals()!1') # optional - magma</span> <span class="go">true</span> </pre></div> </div> </div> <div class="section" id="id14"> <h2>Профилирование<a class="headerlink" href="#id14" title="Ссылка на этот заголовок">¶</a></h2> <p>Автор раздела: Martin Albrecht (<a class="reference external" href="mailto:malb%40informatik.uni-bremen.de">malb<span>@</span>informatik<span>.</span>uni-bremen<span>.</span>de</a>)</p> <blockquote> <div>“Преждевременная оптимизация - это корень всего зла.” - Дональд Кнут</div></blockquote> <p>Часто очень полезно проверять код на слабые места, понимать, какие части отнимают наибольшее время на вычисления; таким образом можно узнать, какие части кода надо оптимизировать. Python и Sage предоставляет несколько возможностей для профилирования (так называется этот процесс).</p> <p>Самый легкий путь - это использование команды <tt class="docutils literal"><span class="pre">prun</span></tt>. Она возвращает краткую информацию о том, какое время отнимает каждая функция. Далее следует пример умножения матриц из конечных полей:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: k,a = GF(2**8, 'a').objgen()</span> <span class="go">sage: A = Matrix(k,10,10,[k.random_element() for _ in range(10*10)])</span> </pre></div> </div> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: %prun B = A*A</span> <span class="go"> 32893 function calls in 1.100 CPU seconds</span> <span class="go">Ordered by: internal time</span> <span class="go">ncalls tottime percall cumtime percall filename:lineno(function)</span> <span class="go"> 12127 0.160 0.000 0.160 0.000 :0(isinstance)</span> <span class="go"> 2000 0.150 0.000 0.280 0.000 matrix.py:2235(__getitem__)</span> <span class="go"> 1000 0.120 0.000 0.370 0.000 finite_field_element.py:392(__mul__)</span> <span class="go"> 1903 0.120 0.000 0.200 0.000 finite_field_element.py:47(__init__)</span> <span class="go"> 1900 0.090 0.000 0.220 0.000 finite_field_element.py:376(__compat)</span> <span class="go"> 900 0.080 0.000 0.260 0.000 finite_field_element.py:380(__add__)</span> <span class="go"> 1 0.070 0.070 1.100 1.100 matrix.py:864(__mul__)</span> <span class="go"> 2105 0.070 0.000 0.070 0.000 matrix.py:282(ncols)</span> <span class="go"> ...</span> </pre></div> </div> <p>В данном примере <tt class="docutils literal"><span class="pre">ncalls</span></tt> - это количество вызовов, <tt class="docutils literal"><span class="pre">tottime</span></tt> - это общее время, затраченное на определенную функцию (за исключением времени вызовов суб-функций), <tt class="docutils literal"><span class="pre">percall</span></tt> - это отношение <tt class="docutils literal"><span class="pre">tottime</span></tt> к <tt class="docutils literal"><span class="pre">ncalls</span></tt>. <tt class="docutils literal"><span class="pre">cumtime</span></tt> - это общее время, потраченное в этой и всех суб-функциях, <tt class="docutils literal"><span class="pre">percall</span></tt> - это отношение <tt class="docutils literal"><span class="pre">cumtime</span></tt> к числу примитивных вызовов, <tt class="docutils literal"><span class="pre">filename:lineno(function)</span></tt> предоставляет информацию о каждой функции. Чем выше функция находится в этом списке, тем больше времени она отнимает.</p> <p><tt class="docutils literal"><span class="pre">prun?</span></tt> покажет детали о том, как использовать команду профилирования и понимать результат ее использования.</p> <p>Профилирующая информация может быть вписана в объект для более подробного изучения:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: %prun -r A*A</span> <span class="go">sage: stats = _</span> <span class="go">sage: stats?</span> </pre></div> </div> <p>Заметка: ввод <tt class="docutils literal"><span class="pre">stats</span> <span class="pre">=</span> <span class="pre">prun</span> <span class="pre">-r</span> <span class="pre">A\*A</span></tt> отобразит синтаксическую ошибку, так как <tt class="docutils literal"><span class="pre">prun</span></tt> - это команда оболочки IPython, а не обычная функция.</p> <p>Для графического отображения профилирующей информации, Вы можете использовать hotshot - небольшой скрипт, названный hotshot2cachetree и программу <tt class="docutils literal"><span class="pre">kcachegrind</span></tt> (только в Unix). Tот же пример с использованием hotshot:</p> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: k,a = GF(2**8, 'a').objgen()</span> <span class="go">sage: A = Matrix(k,10,10,[k.random_element() for _ in range(10*10)])</span> <span class="go">sage: import hotshot</span> <span class="go">sage: filename = "pythongrind.prof"</span> <span class="go">sage: prof = hotshot.Profile(filename, lineevents=1)</span> </pre></div> </div> <div class="highlight-python"><div class="highlight"><pre><span class="go">sage: prof.run("A*A")</span> <span class="go"><hotshot.Profile instance at 0x414c11ec></span> <span class="go">sage: prof.close()</span> </pre></div> </div> <p>Результат будет помещен в файл <tt class="docutils literal"><span class="pre">pythongrind.prof</span></tt> в текущей рабочей директории. Для визуализации эта информация может быть переведена в формат cachegrind.</p> <p>В системной оболочке введите</p> <div class="highlight-python"><pre>hotshot2calltree -o cachegrind.out.42 pythongrind.prof</pre> </div> <p>Выходной файл <tt class="docutils literal"><span class="pre">cachegrind.out.42</span></tt> теперь может быть проанализирован с помощью <tt class="docutils literal"><span class="pre">kcachegrind</span></tt>. Заметьте, что обозначение <tt class="docutils literal"><span class="pre">cachegrind.out.XX</span></tt> должно быть соблюдено.</p> </div> </div> </div> </div> </div> <div class="sphinxsidebar"> <div class="sphinxsidebarwrapper"> <h3><a href="index.html">Содержание</a></h3> <ul> <li><a class="reference internal" href="#">Программирование</a><ul> <li><a class="reference internal" href="#sage">Загрузка и прикрепление файлов Sage</a></li> <li><a class="reference internal" href="#section-compile">Создание компилированного кода</a><ul> <li><a class="reference internal" href="#id5">Доступ к функциям С из внешних файлов</a></li> </ul> </li> <li><a class="reference internal" href="#python-sage">Самостоятельные скрипты Python/Sage</a></li> <li><a class="reference internal" href="#id6">Типы данных</a></li> <li><a class="reference internal" href="#id7">Списки, кортежи и последовательности</a></li> <li><a class="reference internal" href="#id9">Словари</a></li> <li><a class="reference internal" href="#id10">Множества</a></li> <li><a class="reference internal" href="#id11">Итераторы</a></li> <li><a class="reference internal" href="#id13">Циклы, функции, управляющие конструкции и сравнения</a></li> <li><a class="reference internal" href="#id14">Профилирование</a></li> </ul> </li> </ul> <h4>Предыдущий раздел</h4> <p class="topless"><a href="interfaces.html" title="предыдущая глава">Интерфейсы</a></p> <h4>Следующий раздел</h4> <p class="topless"><a href="sagetex.html" title="следующая глава">Использование SageTeX</a></p> <h3>На этой странице</h3> <ul class="this-page-menu"> <li><a href="_sources/programming.txt" rel="nofollow">Показать исходный текст</a></li> </ul> <div id="searchbox" style="display: none"> <h3>Быстрый поиск</h3> <form class="search" action="search.html" method="get"> <input type="text" name="q" size="18" /> <!-- The shading of the "Go" button should be consistent --> <!-- with the colour of the header and footer. See the file --> <!-- doc/common/themes/sage/theme.conf for colours used by --> <!-- the Sage theme. --> <input type="submit" style="background-color: #B8B9F6" value="Искать" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> Введите слова для поиска или имя модуля, класса или функции. </p> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <div class="clearer"></div> </div> <div class="related"> <h3>Просмотр</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="genindex.html" title="Словарь-указатель" >словарь</a></li> <li class="right" > <a href="py-modindex.html" title="Python Module Index" >модули</a> |</li> <li class="right" > <a href="sagetex.html" title="Использование SageTeX" >следующий</a> |</li> <li class="right" > <a href="interfaces.html" title="Интерфейсы" >предыдущий</a> |</li> <a href="../index.html"><img src="_static/sagelogo.png" style="vertical-align: middle" title="Sage Logo"></a> <li><a href="index.html">Sage Tutorial in Russian v5.9</a> »</li> </ul> </div> <div class="footer"> © Copyright 2005--2011, The Sage Development Team. При создании использован <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3. </div> <script type="text/javascript"> /*global jQuery, window */ /* Sphinx sidebar toggle. Putting this code at the end of the body * enables the toggle for the live, static, and offline docs. Note: * sage.misc.html.math_parse() eats jQuery's dollar-sign shortcut. */ var jq = jQuery; jq(document).ready(function () { var bar, bod, bg, fg, key, tog, wid_old, wid_new, resize, get_state, set_state; bod = jq('div.bodywrapper'); bar = jq('div.sphinxsidebar'); tog = jq('<div class="sphinxsidebartoggle"></div>'); /* Delayed resize helper. Not perfect but good enough. */ resize = function () { setTimeout(function () { tog.height(bod.height()); }, 100); }; jq(window).resize(function () { resize(); }); /* Setup and add the toggle. See Sphinx v0.5.1 default.css. */ fg = jq('div.sphinxsidebar p a').css('color') || 'rgb(152, 219, 204)'; bg = jq('div.document').css('background-color') || 'rgb(28, 78, 99)'; wid_old = '230px'; wid_new = '5px'; tog.css('background-color', bg) .css('border-width', '0px') .css('border-right', wid_new + ' ridge ' + bg) .css('cursor', 'pointer') .css('position', 'absolute') .css('left', '-' + wid_new) .css('top', '0px') .css('width', wid_new); bod.css('position', 'relative'); bod.prepend(tog); resize(); /* Cookie helpers. */ key = 'sphinxsidebar='; set_state = function (s) { var date = new Date(); /* Expiry in 7 days. */ date.setTime(date.getTime() + (7 * 24 * 3600 * 1000)); document.cookie = key + encodeURIComponent(s) + '; expires=' + date.toUTCString() + '; path=/'; }; get_state = function () { var i, c, crumbs = document.cookie.split(';'); for (i = 0; i < crumbs.length; i += 1) { c = crumbs[i].replace(/^\s+/, ''); if (c.indexOf(key) === 0) { return decodeURIComponent(c.substring(key.length, c.length)); } } return null; }; /* Event handlers. */ tog.mouseover(function (ev) { tog.css('border-right-color', fg); }).mouseout(function (ev) { tog.css('border-right-color', bg); }).click(function (ev) { if (bod.hasClass('wide')) { bod.removeClass('wide'); bod.css('margin-left', wid_old); bar.css('width', wid_old); bar.show(); set_state('visible'); } else { set_state('hidden'); bar.hide(); bar.css('width', '0px'); bod.css('margin-left', wid_new); bod.addClass('wide'); } resize(); }); /* Hide the normally visible sidebar? */ if (get_state() === 'hidden') { tog.trigger('click'); } else { set_state('visible'); } }); </script> </body> </html>