{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Инфраструктура Python. Богатый вывод" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "todo Для удобства использования IPython стоит установить расширения" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```\n", "pip install jupyter_contrib_nbextensions\n", "pip install jupyter_nbextensions_configurator\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "todo Темы IPython, полезные расширения, настройка реестра для запуска IPython, тоталоплагин?\n", "\n", "tikz/asymptote, geogebra?\n", "\n", "todo как заставить IPython не тормозить при объемном выводе и зацикливании?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Богатый вывод в IPython" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Упоминаются библиотеки `colorama`, `IPython`, `ipy_table`, `tabulate`, `qgrid`, `tqdm`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Библиотека `hexdump` позволяет удобно отображать бинарные строки, как в hex-редакторах и проводить обратные преобразования, например, над копипастой." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "00000000: D8 C2 6B 42 82 67 C8 4D 7A 95 E8 81 48 C1 9E 40 ..kB.g.Mz...H..@\n", "00000010: E8 FB CF E6 4F BA E6 AF 78 19 6F 9C E9 F7 7A DD ....O...x.o...z.\n", "00000020: 42 CE 8C 03 B8 66 D3 AB 00 7E DE 3E 53 DE 30 91 B....f...~.>S.0.\n", "00000030: 3D F7 =.\n" ] } ], "source": [ "import hexdump, random\n", "random.seed(0)\n", "hexdump.hexdump(''.join([chr(random.randint(0, 255)) for i in range(50)]))" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'\\xd8\\xc2kB\\x82g\\xc8Mz\\x95\\xe8\\x81H\\xc1\\x9e@\\xe8\\xfb\\xcf\\xe6O\\xba\\xe6\\xafx\\x19o\\x9c\\xe9\\xf7z\\xddB\\xce\\x8c\\x03\\xb8f\\xd3\\xab\\x00~\\xde>S\\xde0\\x91=\\xf7'" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "hexdump.restore('''\n", "00000000: D8 C2 6B 42 82 67 C8 4D 7A 95 E8 81 48 C1 9E 40 ..kB.g.Mz...H..@\n", "00000010: E8 FB CF E6 4F BA E6 AF 78 19 6F 9C E9 F7 7A DD ....O...x.o...z.\n", "00000020: 42 CE 8C 03 B8 66 D3 AB 00 7E DE 3E 53 DE 30 91 B....f...~.>S.0.\n", "00000030: 3D F7 =.\n", "''')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Linux поддерживает раскраску символов в консоли выводом специальных escape-последовательностей вида `\\033[31m` (синтаксис: `\\033` `[` список кодов через `;` `m`) 3x — цвет текста, 4x — фона, 0 — сброс). Библиотека `colorama` упрощает генерацию этих escape-последовательностей и реализует схожее поведение на Windows. IPython с грехом пополам копирует цвет символов в свои выходные ячейки." ] }, { "cell_type": "code", "execution_count": 98, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[43;35m magenta on yellow \u001b[0m\n" ] } ], "source": [ "print(\"\\033[43;35m magenta on yellow \\033[0m\")" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[31mred text\u001b[30m\u001b[0m\u001b[0m\n", "\u001b[43myellow background\u001b[0m\u001b[49m\n", "\u001b[45m\u001b[37mwhite on green\u001b[0m\u001b[49m\n", "\u001b[30mback to normal now\n" ] } ], "source": [ "from colorama import Fore, Back, Style\n", "print Fore.RED + 'red text' + Fore.BLACK + Style.RESET_ALL + Style.RESET_ALL\n", "print Back.YELLOW + 'yellow background' + Style.RESET_ALL + Back.RESET\n", "print Back.MAGENTA + Fore.WHITE + 'white on green' + Style.RESET_ALL + Back.RESET\n", "print Fore.BLACK + 'back to normal now'" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from colorama import Back, init\n", "init()" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Alert!!!\n" ] } ], "source": [ "print Fore.YELLOW + Style.BRIGHT + Back.MAGENTA + 'Alert!!!'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "todo Понять, что за ерунда, проверить в линухе, \"реализует схожее поведение на Windows\" - ??? powershell? cmder?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Сам IPython способен отображать довольно много видов объектов: размеченный markdown текст, HTML, формулы, картинки, SVG, таблицы" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import IPython\n", "import pandas\n", "from time import sleep\n", "import sys" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/markdown": [ "~~hello~~ $x^2$ *world* of `markdown`" ], "text/plain": [ "" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "IPython.display.Markdown('~~hello~~ $x^2$ *world* of `markdown`')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "todo Почему при рестарте пропадает маркдаун, SVG, стили у HTML-вывода show_diff, кастомные визуализаторы `<__main__.MyCircle instance at 0x00000000198FB3C8>`?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Содержимое объектов вроде `IPython.display.Markdown` просматривается в выходных ячейках как результат исполнения последней строки. Если нужно вывести IPython-объект не в последней строке, можно явно позвать функцию `IPython.display.display`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "todo Примеры разнообразнее" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/markdown": [ "~~hello~~ $\\sqrt{x^2}$ *world* **of** `markdown`" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "usual text\n" ] } ], "source": [ "IPython.display.display(IPython.display.Markdown('~~hello~~ $\\sqrt{x^2}$ *world* **of** `markdown`'))\n", "print 'usual text'" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "hello $\\sqrt{x^2}$ world of HTML" ], "text/plain": [ "" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "IPython.display.HTML('hello $\\sqrt{x^2}$ world of HTML')" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "hello $\\sqrt{x^2}$ world of HTML" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "hello $\\sqrt{x^2}$ world of HTML" ] }, { "cell_type": "code", "execution_count": 429, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$x_{1,2} = \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}$" ], "text/plain": [ "" ] }, "execution_count": 429, "metadata": {}, "output_type": "execute_result" } ], "source": [ "IPython.display.Latex(r'$x_{1,2} = \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}$')" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$x_{1,2} = \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%latex\n", "$x_{1,2} = \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}$" ] }, { "cell_type": "code", "execution_count": 432, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "execution_count": 432, "metadata": {}, "output_type": "execute_result" } ], "source": [ "IPython.display.Image('https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png')" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/svg+xml": [ "\n", " \n", " \n", " \n", " \n", " \n", " \n", "" ], "text/plain": [ "" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "IPython.display.SVG('''\n", " \n", " \n", " \n", " \n", " \n", " \n", "''')" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/svg+xml": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%svg\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Для IPython существует несколько способов отображать табличные данные" ] }, { "cell_type": "code", "execution_count": 94, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
AB
1$x^2$
" ], "text/plain": [ "" ] }, "execution_count": 94, "metadata": {}, "output_type": "execute_result" } ], "source": [ "IPython.display.HTML('
AB
1$x^2$
')" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": true }, "outputs": [], "source": [ "data = [[1,2,3], ['hi', 'hello', 'greetings']]" ] }, { "cell_type": "code", "execution_count": 417, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
123
hihellogreetings
" ], "text/plain": [ "" ] }, "execution_count": 417, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import ipy_table\n", "ipy_table.make_table(data)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": true }, "outputs": [], "source": [ "data = [[1,2,3], ['hi', 'hello', 'greetings'], [u'один', u'два', u'три']]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```\n", "pip install tabulate\n", "```" ] }, { "cell_type": "code", "execution_count": 420, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "one two three\n", "----- ----- ---------\n", "1 2 3\n", "hi hello greetings\n", "один два три\n" ] } ], "source": [ "import tabulate\n", "print tabulate.tabulate(data, headers=['one', 'two', 'three'])" ] }, { "cell_type": "code", "execution_count": 421, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
one two three
1 2 3
hi hellogreetings
один два три
" ], "text/plain": [ "" ] }, "execution_count": 421, "metadata": {}, "output_type": "execute_result" } ], "source": [ "html = tabulate.tabulate(data, headers=['one', 'two', 'three'], tablefmt='html')\n", "IPython.display.HTML(html)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```\n", "pip install qgrid\n", "```" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import qgrid\n", "qgrid.show_grid(pandas.DataFrame(data))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "todo чтобы сортируемый грид не пропадал" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Для подсветки кода можно использовать `pygments`, который поддерживает более 400 языков." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiAAAABoCAMAAAD/w7sGAAADAFBMVEX////9/f36+vr5+fn39/f1\n9fX09PTy8vLw8PDv7+/u7u7u7t3u7tzs7Ozr6+vq6urt7dvr69np6eno6Nvn5+fm5ubi4t/e3svc\n3Nzc3Mfa2trY2NjZ2cXU1NTS0tLU1L7Pz8/Ozs7Q0LrLy8vNzbfJycnLy7THx8fGxsbDw8PFxa7B\nwcG/v7+7u7i3t7G2tpyxsbGxsZWrq5Onp6empqakpKSlpYejo6OhoYKcnJybm5udnX6Tk5OSkpKR\nkZGPj2+NjY2Li4uJiYmNjWyLi2qKimiJiWiIiIiIiGYAhtL7ZgqDg4OCgoKBgYGAgIB+fn59fX18\nfHx6enp4eHhvb29tbW1sbGxqamppaWkFZ54DcK0DbqsEa6YAg84Ag80BgswBgcoBgckBgMcBfsUB\nfsQCfMEBfMIBe8ACeb0Cd7kCdbb3ZAr2ZAryYwvuYQrrYAroXwrnXwrmXwvmXgrlXgvkXgvgXQve\nXAvbWgvZWgzQVgvFUwy/UAtgYGBfX19dXV1bW1tZWVmvSwygRQ2MPg1yNA5kLw9hLg5eLQ5cLA9R\nUVFNTU1ISEhDQ0NAQEA9PT08PDw7Ozs5OTk2NjYuLi4rKysqKiooKChJJg9AIhAtGxApGRAnJycm\nJiYnGRAlJSUkJCQjIyMlGBEjGBEFZJoFYJQGX5EGWooHVYIHVH8HU34IUXoIT3gITnYJSW0JR2sJ\nRGYKPlwLOFILOFEMN08LN1AMNEsMMkcNMEQNLUAOKDcOJjQOJDEhISEgICAeHh4cHBwPHygPHSUP\nHCMbGxsaGhoZGRkYGBgXFxcWFhYQGyAQGiAQGR8QGR4QGB0QFxwQFhoQFhkaFBAWExEVFRUTExMS\nEhIRFRcRFBYRFBURExQREhMQFRgQFBcUERERERH/AAf2AQjqAgjVAwnOBArKBAnDBAm2BQqqBguk\nBwuYCAx7Cg1nCw1VDA5EDQ85Dg80DxAvDxAkEBAdEBAZEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAidFscAAALLUlEQVR4nO2diWMVxR3H10BAjEJCCFdEDgElmoYrgAQIFdC8V0Qr\nYkGgcljACIVqLT3QcFiryKVBUYqttVrRoMQaK1awVkATW61FpIlQ5hESMJCEK39Ad2f3t8fszLwz\n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\n", "text/plain": [ "" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pygments, pygments.lexers, pygments.formatters\n", "import PIL\n", "from io import BytesIO\n", "\n", "code = ''''''\n", "\n", "lexer = pygments.lexers.get_lexer_by_name('PHP')\n", "\n", "formatter = pygments.formatters.GifImageFormatter(linenos=True, style='fruity')\n", "gif = pygments.highlight(code, lexer, formatter)\n", "PIL.Image.open(BytesIO(gif))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Встроенные в pygments стили достаточно невзрачны, но популярную пару стилей Solarized можно поставить из библиотеки `pygments-style-solarized`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```\n", "pip install pygments-style-solarized\n", "```" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
<?\n",
       "var_dump($_FILES);\n",
       "if (isset($_FILES['up'])) {\n",
       "    move_uploaded_file($_FILES['up']['tmp_name'], "uploaded");\n",
       "}\n",
       "?>\n",
       "
\n" ], "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "formatter = pygments.formatters.HtmlFormatter(style='solarizedlight', noclasses=True)\n", "#css = ''\n", "html = pygments.highlight(code, lexer, formatter)\n", "IPython.display.HTML(html)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "manni igor lovelace xcode vim autumn vs rrt native perldoc borland tango emacs friendly monokai paraiso-dark colorful murphy bw pastie algol_nu paraiso-light trac default algol fruity solarizeddark solarizedlight\n" ] } ], "source": [ "print ' '.join(list(pygments.styles.get_all_styles()))" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "404" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(list(pygments.lexers.get_all_lexers()))" ] }, { "cell_type": "code", "execution_count": 127, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ABAP | ABNF | ADL | ANTLR | ANTLR With ActionScript Target | ANTLR With C# Target | ANTLR With CPP Target | ANTLR With Java Target | ANTLR With ObjectiveC Target | ANTLR With Perl Target | ANTLR With Python Target | ANTLR With Ruby Target | APL | ActionScript | ActionScript 3 | Ada | Agda | Alloy | AmbientTalk | ApacheConf | AppleScript | Arduino | AspectJ | Asymptote | AutoIt | Awk | BBCode | BC | BNF | BUGS | Base Makefile | Bash | Bash Session | Batchfile | Befunge | BlitzBasic | BlitzMax | Boo | Boogie | Brainfuck | Bro | C | C# | C++ | CAmkES | CBM BASIC V2 | CFEngine3 | CMake | COBOL | COBOLFree | CPSA | CSS | CSS+Django/Jinja | CSS+Genshi Text | CSS+Lasso | CSS+Mako | CSS+Mako | CSS+Myghty | CSS+PHP | CSS+Ruby | CSS+Smarty | CSS+mozpreproc | CUDA | Ceylon | ChaiScript | Chapel | Cheetah | Cirru | Clay | Clojure | ClojureScript | CoffeeScript | Coldfusion CFC | Coldfusion HTML | Common Lisp | Component Pascal | Coq | Crmsh | Croc | Cryptol | Csound Document | Csound Orchestra | Csound Score | Cypher | Cython | D | DTD | Darcs Patch | Dart | Debian Control file | Debian Sourcelist | Delphi | Diff | Django/Jinja | Docker | Duel | Dylan | Dylan session | DylanLID | EBNF | ECL | ERB | Earl Grey | Easytrieve | Eiffel | Elixir | Elixir iex session | Elm | EmacsLisp | Embedded Ragel | Erlang | Erlang erl session | Evoque | Ezhil | FSharp | Factor | Fancy | Fantom | Felix | Fish | Fortran | FortranFixed | FoxPro | GAP | GAS | GLSL | Genshi | Genshi Text | Gettext Catalog | Gherkin | Gnuplot | Go | Golo | GoodData-CL | Gosu | Gosu Template | Groff | Groovy | HTML | HTML+Cheetah | HTML+Django/Jinja | HTML+Evoque | HTML+Genshi | HTML+Handlebars | HTML+Lasso | HTML+Mako | HTML+Mako | HTML+Myghty | HTML+PHP | HTML+Smarty | HTML+Twig | HTML+Velocity | HTTP | Haml | Handlebars | Haskell | Haxe | Hexdump | Hxml | Hy | Hybris | IDL | INI | IRC logs | Idris | Igor | Inform 6 | Inform 6 template | Inform 7 | Io | Ioke | Isabelle | J | JAGS | JCL | JSON | JSON-LD | Jade | Jasmin | Java | Java Server Page | JavaScript | JavaScript+Cheetah | JavaScript+Django/Jinja | JavaScript+Genshi Text | JavaScript+Lasso | JavaScript+Mako | JavaScript+Mako | JavaScript+Myghty | JavaScript+PHP | JavaScript+Ruby | JavaScript+Smarty | Javascript+mozpreproc | Julia | Julia console | Kal | Kconfig | Koka | Kotlin | LLVM | LSL | Lasso | Lean | LessCss | Lighttpd configuration file | Limbo | Literate Agda | Literate Cryptol | Literate Haskell | Literate Idris | LiveScript | Logos | Logtalk | Lua | MAQL | MOOCode | MQL | MSDOS Session | MXML | Makefile | Mako | Mako | Mask | Mason | Mathematica | Matlab | Matlab session | MiniD | Modelica | Modula-2 | MoinMoin/Trac Wiki markup | Monkey | MoonScript | Mscgen | MuPAD | MySQL | Myghty | NASM | NSIS | Nemerle | NewLisp | Newspeak | Nginx configuration file | Nimrod | Nit | Nix | NumPy | OCaml | ODIN | Objective-C | Objective-C++ | Objective-J | Octave | Ooc | Opa | OpenEdge ABL | PHP | PL/pgSQL | POVRay | PacmanConf | Pan | ParaSail | Pawn | Perl | Perl6 | Pig | Pike | PkgConfig | PostScript | PostgreSQL SQL dialect | PostgreSQL console (psql) | PowerShell | PowerShell Session | Praat | Prolog | Properties | Protocol Buffer | Puppet | PyPy Log | Python | Python 3 | Python 3.0 Traceback | Python Traceback | Python console session | QBasic | QML | QVTO | RConsole | REBOL | RHTML | RPMSpec | RQL | RSL | Racket | Ragel | Ragel in C Host | Ragel in CPP Host | Ragel in D Host | Ragel in Java Host | Ragel in Objective C Host | Ragel in Ruby Host | Raw token data | Rd | Red | Redcode | ResourceBundle | Rexx | Roboconf Graph | Roboconf Instances | RobotFramework | Ruby | Ruby irb session | Rust | S | SCSS | SPARQL | SQL | SWIG | Sass | Scala | Scalate Server Page | Scaml | Scheme | Scilab | Shen | Slim | Smali | Smalltalk | Smarty | Snobol | SourcePawn | SquidConf | Stan | Standard ML | SuperCollider | Swift | TADS 3 | TAP | Tcl | Tcsh | Tcsh Session | TeX | Tea | Termcap | Terminfo | Terraform | Text only | Thrift | Todotxt | TrafficScript | Treetop | Turtle | Twig | TypeScript | UrbiScript | VB.net | VCTreeStatus | VGL | Vala | Velocity | VimL | X10 | XML | XML+Cheetah | XML+Django/Jinja | XML+Evoque | XML+Lasso | XML+Mako | XML+Mako | XML+Myghty | XML+PHP | XML+Ruby | XML+Smarty | XML+Velocity | XQuery | XSLT | XUL+mozpreproc | Xtend | YAML | YAML+Jinja | Zephir | aspx-cs | aspx-vb | autohotkey | c-objdump | cADL | ca65 assembler | cfstatement | cpp-objdump | d-objdump | dg | eC | liquid | mozhashpreproc | mozpercentpreproc | nesC | objdump | objdump-nasm | reStructuredText | reg | sqlite3con | systemverilog | verilog | vhdl\n" ] } ], "source": [ "print ' | '.join(sorted([item[0] for item in pygments.lexers.get_all_lexers()]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Для объекта любого класса можно зарегистрировать функцию, преобразующую его в вид, который IPython умеет отображать." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class MyCircle:\n", " def __init__(self, n):\n", " self.n = n\n", " def show_as_svg(self):\n", " return '''\n", "\n", " \n", " %d\n", "''' % self.n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [], "source": [ "get_ipython().display_formatter.formatters['image/svg+xml'].for_type(MyCircle, MyCircle.show_as_svg)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", " \n", " 42\n", "" ], "text/plain": [ "<__main__.MyCircle instance at 0x0000000017556788>" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "MyCircle(42)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", " \n", " 53\n", "" ], "text/plain": [ "<__main__.MyCircle instance at 0x0000000017556E88>" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "MyCircle(53)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "todo нипахает `_repr_as_svg_`" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class MyFont:\n", " def __init__(self, name):\n", " self.name = name\n", " def _repr_as_svg_(self):\n", " return u'''\n", " Съешь еще этих мягких французских булок да выпей чаю\n", "''' % self.name" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [], "source": [ "get_ipython().display_formatter.formatters['image/svg+xml'].for_type(MyFont, MyFont._repr_as_svg_)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/svg+xml": [ "\n", " Съешь еще этих мягких французских булок да выпей чаю\n", "" ], "text/plain": [ "<__main__.MyFont instance at 0x0000000017587588>" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "MyFont('PT Sans')" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/svg+xml": [ "\n", " Съешь еще этих мягких французских булок да выпей чаю\n", "" ], "text/plain": [ "<__main__.MyFont instance at 0x000000001757AF88>" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "MyFont('Georgia')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Можно заменять выводимые в выходную ячейку данные, не только добавлять. В случае чистого текста можно использовать возврат каретки `\\r`, в случае более богатого содержимого `IPython.display.clear_output`" ] }, { "cell_type": "code", "execution_count": 442, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "9\n" ] } ], "source": [ "for i in range(10):\n", " IPython.display.clear_output(wait=True)\n", " print i\n", " sleep(0.5)" ] }, { "cell_type": "code", "execution_count": 565, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1 2 3 4 5 6 7 8 9\n" ] } ], "source": [ "for i in range(10):\n", " print i,; sys.stdout.flush()\n", " sleep(0.5)" ] }, { "cell_type": "code", "execution_count": 566, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "9\n" ] } ], "source": [ "for i in range(10):\n", " print '\\r', i,; sys.stdout.flush()\n", " sleep(0.5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Длительный процесс можно визуализировать прогрессбаром, построенным по этому методу" ] }, { "cell_type": "code", "execution_count": 100, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
10000000 / 10000000  100.00% Current i is 10000000
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Wall time: 8.65 s\n" ] } ], "source": [ "%%time\n", "import time\n", "from IPython.display import clear_output, HTML, display\n", "\n", "prev_call = 0\n", "def progress(a, b, msg=''):\n", " global prev_call\n", " now = time.time()\n", " if now - prev_call >= 0.05 or a == b:\n", " prev_call = now\n", " p = 100.0 * a / b\n", " clear_output(wait=True)\n", " display(HTML(\n", " '
%*d / %d' % (len(str(b)), a, b) + \\\n",
    "            '  %5.2f%%' % (p, p) + \\\n",
    "            (\" \" + msg if msg != '' else '') + '
'\n", " ))\n", "\n", "for i in range(10000001):\n", " progress(i, 10000000, 'Current i is %d' % i)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [] }, { "name": "stdout", "output_type": "stream", "text": [ "0\n" ] }, { "name": "stderr", "output_type": "stream", "text": [] }, { "name": "stdout", "output_type": "stream", "text": [ "40\n" ] }, { "name": "stderr", "output_type": "stream", "text": [] }, { "name": "stdout", "output_type": "stream", "text": [ "80\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|████████████████████████████████████████| 100/100 [00:10<00:00, 9.97it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "from tqdm import tqdm, tqdm_notebook\n", "\n", "for i in tqdm(range(100)):\n", " if i % 40 == 0:\n", " tqdm.write(str(i))\n", " sleep(0.1)\n", "\n", "for i in tqdm_notebook(range(100), desc='2nd loop'):\n", " sleep(0.1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "IPython поддерживает вывод интерактивных виджетов, изменение которых приводит к повторным вызовам функции. Тип значения определяет тип виджета и его значение (для слайдера и дропдауна множество значений, а само значение дефолтным значением параметра в самой функции). Виджеты не сохраняются, для их появления нужно переисполнить ячейку." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "todo Заменено на from ipywidgets import interact, interactive; умеют частично сохранять виджеты при экспорте" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5.89 motor True 1\n" ] } ], "source": [ "from IPython.html.widgets import interact\n", "@interact(slider=(5., 10., 0.01), text=\"moto\", checkbox=True, dropdown={'a': 1, 'b': 2})\n", "def ps(text, checkbox, slider=6.28, dropdown=2):\n", " print slider, text, checkbox, dropdown" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.12" } }, "nbformat": 4, "nbformat_minor": 2 }