Buscar

Python para Desenvolvedores

Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original

ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceA/ApendiceA.ipynb
{
 "metadata": {
 "name": ""
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
 {
 "cells": [
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "[Python para Desenvolvedores](http://ricardoduarte.github.io/python-para-desenvolvedores/#conteudo)\n",
 "===================================\n",
 "2ª edi\u00e7\u00e3o, revisada e ampliada\n",
 "-----------------------------------\n",
 "\n",
 "Ap\u00eandice A: Integra\u00e7\u00e3o com aplicativos\n",
 "=============================\n",
 "_____________________________\n",
 "Python pode ser usado como linguagem *script* em v\u00e1rios aplicativos para automatizar tarefas e adicionar novas funcionalidades, ou para oferecer seus recursos para outro programa, atrav\u00e9s de uma API ou protocolo. Muitos desses pacotes de software s\u00e3o *Open Source*, como o BrOffice.org e o Blender, por exemplo.\n",
 "\n",
 "Muitas vezes isso \u00e9 poss\u00edvel porque esses programas adotaram uma arquitetura de *plugins*, na qual existe uma infraestrutura gen\u00e9rica que permite que componentes externos sejam ligados aos aplicativos.\n",
 "\n",
 "Na maioria dos casos, isso \u00e9 viabilizado mediante o uso de uma API que \u00e9 disponibilizada pelo software, que \u00e9 vista pelo Python como um m\u00f3dulo ou um pacote, que apenas precisa estar no PYTHONPATH para que possa ser utilizado. Com isso, o programa pode fazer chamadas as rotinas do aplicativo, para utilizar seus recursos e se comunicar.\n",
 "\n",
 "Em outros casos, como o Inkscape, o programa em Python funciona como um filtro, recebendo e enviando informa\u00e7\u00f5es para o aplicativo atrav\u00e9s de entrada (*stdin*) e sa\u00edda (*stdout*) padr\u00f5es."
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [],
 "language": "python",
 "metadata": {},
 "outputs": [
 {
 "html": [
 "<style>\n",
 " @font-face {\n",
 " font-family: \"Computer Modern\";\n",
 " src: url('http://mirrors.ctan.org/fonts/cm-unicode/fonts/otf/cmunss.otf');\n",
 " }\n",
 " div.cell{\n",
 " width:800px;\n",
 " margin-left:16% !important;\n",
 " margin-right:auto;\n",
 " }\n",
 " h1 {\n",
 " font-family: Helvetica, serif;\n",
 " }\n",
 " h4{\n",
 " margin-top:12px;\n",
 " margin-bottom: 3px;\n",
 " }\n",
 " div.text_cell_render{\n",
 " font-family: Computer Modern, \"Helvetica Neue\", Arial, Helvetica, Geneva, sans-serif;\n",
 " line-height: 145%;\n",
 " font-size: 130%;\n",
 " width:800px;\n",
 " margin-left:auto;\n",
 " margin-right:auto;\n",
 " }\n",
 " .CodeMirror{\n",
 " font-family: \"Source Code Pro\", source-code-pro,Consolas, monospace;\n",
 " }\n",
 " .note{\n",
 " border-bottom: 1px black dotted;\n",
 " }\n",
 " .prompt{\n",
 " display: None;\n",
 " }\n",
 " .text_cell_render h5 {\n",
 " font-weight: 300;\n",
 " font-size: 16pt;\n",
 " color: #4057A1;\n",
 " font-style: italic;\n",
 " margin-bottom: .5em;\n",
 " margin-top: 0.5em;\n",
 " display: block;\n",
 " }\n",
 " \n",
 " .warning{\n",
 " color: rgb( 240, 20, 20 )\n",
 " } \n",
 "</style>\n",
 "<script>\n",
 " MathJax.Hub.Config({\n",
 " TeX: {\n",
 " extensions: [\"AMSmath.js\"]\n",
 " },\n",
 " tex2jax: {\n",
 " inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\n",
 " displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ]\n",
 " },\n",
 " displayAlign: 'center', // Change this to 'center' to center equations.\n",
 " \"HTML-CSS\": {\n",
 " styles: {'.MathJax_Display': {\"margin\": 4}}\n",
 " }\n",
 " });\n",
 "</script>"
 ],
 "output_type": "pyout",
 "prompt_number": 1,
 "text": [
 "<IPython.core.display.HTML at 0x50f8f98>"
 ]
 }
 ],
 "prompt_number": 1
 }
 ],
 "metadata": {}
 }
 ]
}
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceB/ApendiceB.ipynb
{
 "metadata": {
 "name": ""
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
 {
 "cells": [
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "[Python para Desenvolvedores](http://ricardoduarte.github.io/python-para-desenvolvedores/#conteudo)\n",
 "===================================\n",
 "2&ordf; edi\u00e7\u00e3o, revisada e ampliada\n",
 "-----------------------------------\n",
 "\n",
 "Ap\u00eandice B: Blender\n",
 "=============================\n",
 "_____________________________\n",
 "[Blender](http://www.blender.org/) \u00e9 um software de modelagem 3D de c\u00f3digo aberto, capaz de gerar anima\u00e7\u00f5es e tamb\u00e9m funciona como *Game Engine* (infraestrutura especializada para cria\u00e7\u00e3o de jogos para computador). Al\u00e9m disso, o software possui um renderizador interno e pode ser integrado a renderizadores externos, como os projetos, tamb\u00e9m de c\u00f3digo aberto, [Yafaray](http://www.yafaray.org/) e [LuxRender](http://www.luxrender.net/).\n",
 "\n",
 "![Tela do Blender](files/blender1.png)\n",
 "\n",
 "No Blender, uma cena \u00e9 composta por objetos, que precisam ser fixados em posi\u00e7\u00f5es e conectados a cena. Se o objeto n\u00e3o estiver conectado a cena, ele ser\u00e1 eliminado ao fim do processamento. Para cada s\u00f3lido, \u00e9 poss\u00edvel configurar v\u00e1rios materiais, que podem ter zero ou mais texturas.\n",
 "\n",
 "A cena padr\u00e3o do Blender \u00e9 composta por tr\u00eas objetos: uma c\u00e2mera, uma l\u00e2mpada e um cubo (representado como *mesh*). A escala no Blender \u00e9 medida em BUs (*Blender Units*).\n",
 "\n",
 "Com Python \u00e9 poss\u00edvel acessar todas essas estruturas do Blender atrav\u00e9s de m\u00f3dulos, incluindo:\n",
 "\n",
 "+ *Blender*: permite abrir arquivos, salvar e outras fun\u00e7\u00f5es correlatas.\n",
 "+ *Object*: opera\u00e7\u00f5es com objetos 3D.\n",
 "+ *Materials*: manipula\u00e7\u00e3o de materiais.\n",
 "+ *Textures*: manipula\u00e7\u00e3o de texturas.\n",
 "+ *World*: manipula\u00e7\u00e3o do ambiente da cena.\n",
 "+ *Draw*: rotinas de interface com o usu\u00e1rio.\n",
 "+ *Nmesh*: manipula\u00e7\u00e3o de malhas.\n",
 "+ *BGL*: acesso direto as fun\u00e7\u00f5es do OpenGL.\n",
 "\n",
 "A API do Blender oferece v\u00e1rias texturas procedurais e uma cole\u00e7\u00e3o de s\u00f3lidos primitivos prontos, que podem ser criados e alterados atrav\u00e9s de c\u00f3digo.\n",
 "\n",
 "Exemplo de c\u00f3digo para a cria\u00e7\u00e3o de uma cena:"
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [
 "import math\n",
 "import Blender\n",
 "\n",
 "# Pega a cena atual\n",
 "cena = Blender.Scene.GetCurrent()\n",
 "\n",
 "# Elementos da cena \"default\"\n",
 "camera = Blender.Object.Get()[0]\n",
 "cubo
= Blender.Object.Get()[1]\n",
 "lamp = Blender.Object.Get()[2]\n",
 "\n",
 "# Move a c\u00e2mera\n",
 "camera.setLocation(8., -8., 4.)\n",
 "camera.setEuler(math.radians(70), 0.,\n",
 " math.radians(45))\n",
 "\n",
 "# Muda a lente\n",
 "camera.data.lens = 30\n",
 "\n",
 "# Remove da cena o objeto \"default\"\n",
 "cena.objects.unlink(cubo)\n",
 "\n",
 "# Altera a intensidade da luz\n",
 "lamp.data.energy = 1.2\n",
 "\n",
 "# Muda o tipo para \"Sun\"\n",
 "lamp.data.type = 1\n",
 "\n",
 "# Aumenta o n\u00famero de samples\n",
 "lamp.data.raySamplesX = 16\n",
 "lamp.data.raySamplesY = 16\n",
 "\n",
 "# E a cor\n",
 "lamp.data.col = 1., .9, .8\n",
 "\n",
 "# Cria outra fonte de luz\n",
 "lamp1 = Blender.Lamp.New('Lamp')\n",
 "lamp1.energy = 0.5\n",
 "lamp1.col = .9, 1., 1.\n",
 "_lamp1 = Blender.Object.New('Lamp')\n",
 "\n",
 "# Muda o lugar da fonte (default = 0.0, 0.0, 0.0)\n",
 "_lamp1.setLocation(6., -6., 6.)\n",
 "\n",
 "# \"Prende\" a fonte de luz na cena\n",
 "_lamp1.link(lamp1)\n",
 "cena.objects.link(_lamp1)\n",
 "\n",
 "# Cria um material\n",
 "material1 = Blender.Material.New('newMat1')\n",
 "material1.rgbCol = [.38, .33, .28]\n",
 "material1.setAlpha(1.)\n",
 "\n",
 "# Cria uma textura\n",
 "textura1 = Blender.Texture.Get()[0]\n",
 "textura1.setType('Clouds')\n",
 "textura1.noiseType = 'soft'\n",
 "textura1.noiseBasis = Blender.Texture.Noise['VORONOICRACKLE']\n",
 "\n",
 "# Coloca no material\n",
 "material1.setTexture(0, textura1)\n",
 "mtex1 = material1.getTextures()[0]\n",
 "mtex1.col = .26, .22, .18\n",
 "mtex1.mtNor = 1\n",
 "mtex1.neg = True\n",
 "mtex1.texco = Blender.Texture.TexCo['GLOB']\n",
 "material1.mode += Blender.Material.Modes['RAYMIRROR']\n",
 "material1.rayMirr = 0.2\n",
 "material1.glossMir = 0.8\n",
 "\n",
 "# Cria o piso\n",
 "mesh = Blender.Mesh.Primitives.Plane(40.)\n",
 "piso = cena.objects.new(mesh,'Mesh')\n",
 "piso.setLocation(0., 0., .05)\n",
 "# Rotaciona o piso\n",
 "piso.setEuler(0., 0., math.radians(45))\n",
 "\n",
 "# Coloca o material no piso\n",
 "piso.setMaterials([material1])\n",
 "piso.colbits = 1\n",
 "\n",
 "# Cria outro material\n",
 "material2 = Blender.Material.New('newMat2')\n",
 "material2.rgbCol = [.77, .78, .79]\n",
 "material2.setAlpha(1.)\n",
 "material2.mode += Blender.Material.Modes['RAYMIRROR']\n",
 "material2.rayMirr = 0.6\n",
 "material2.glossMir = 0.4\n",
 "\n",
 "# Coloca textura no outro material\n",
 "material2.setTexture(0, textura1)\n",
 "mtex2 = material2.getTextures()[0]\n",
 "mtex2.col = .3, .3, .4\n",
 "mtex2.mtNor = 1\n",
 "mtex2.neg = True\n",
 "mtex2.texco = Blender.Texture.TexCo['GLOB']\n",
 "\n",
 "mat = [material2]\n",
 "\n",
 "# Cria objetos na cena\n",
 "def objeto(local, tam, mat, prim=Blender.Mesh.Primitives.Cube):\n",
 "\n",
 " mesh = prim()\n",
 " obj = cena.objects.new(mesh, 'Mesh')\n",
 " obj.setLocation(*local)\n",
 " obj.size = tam\n",
 " obj.setMaterials(mat)\n",
 " obj.colbits = 1\n",
 " return obj\n",
 "\n",
 "def coluna(x=0., y=0., z=0., mat=mat):\n",
 "\n",
 " # Cilindro\n",
 " prim = Blender.Mesh.Primitives.Cylinder\n",
 "\n",
 " # Topo\n",
 " local = x, y, 2.5 + z\n",
 " tam = .25, .25, .1\n",
 " objeto(local, tam, mat)\n",
 "\n",
 " # Base\n",
 " local = x, y, 0. + z\n",
 " objeto(local, tam, mat)\n",
 "\n",
 " # Corpo\n",
 " for k in xrange(10):\n",
 " local = x, y, .25 * k + z\n",
 " tam = .2 - k / 200., .2 - k / 200., .25\n",
 " objeto(local, tam, mat, prim)\n",
 "\n",
 "# Cria colunas no fundo\n",
 "for i in xrange(16):\n",
 "\n",
 " # Primeira fileira\n",
 " coluna(i - 8., 8)\n",
 "\n",
 " # Segunda fileira\n",
 " coluna(-8., i - 8.)\n",
 "\n",
 " # Aqueduto\n",
 " local = -8., i - 8., 3.\n",
 " tam = .5, .5, .5\n",
 " objeto(local, tam, mat)\n",
 "\n",
 " local = i - 8., 8., 3.\n",
 " objeto(local, tam, mat)\n",
 "\n",
 "z = .25\n",
 "\n",
 "# Cria colunas em cima do piso\n",
 "for i in (-3, 3):\n",
 " for j in range(-2, 3):\n",
 "\n",
 " # Fileiras X\n",
 " coluna(i, j, z)\n",
 "\n",
 " # Fileiras Y\n",
 " coluna(j, i, z)\n",
 "\n",
 " # Cantos\n",
 " for j in (-3, 3):\n",
 " coluna(i, j, z)\n",
 "\n",
 "# Cria escada\n",
 "for i in xrange(8):\n",
 " local = 0., 0., i / 32. - .25\n",
 " tam = 3.3 + (8. - i) / 8., 3.3 + (8. - i) / 8., .25\n",
 " objeto(local, tam, mat)\n",
 "\n",
 "# Cria teto\n",
 "for i in xrange(35):\n",
 " local = 0., 0., 2.9 + i / 60.\n",
 " tam = 3.5 - i / 200., 3.5 * ( 1. - i / 35.), .1\n",
 " objeto(local, tam, mat)\n",
 "\n",
 "# Pega o \"mundo\"\n",
 "world = Blender.World.Get()[0]\n",
 "\n",
 "# Modo \"blend\" no fundo\n",
 "world.skytype = 1\n",
 "\n",
 "# Atualiza a cena\n",
 "cena.update()"
 ],
 "language": "python",
 "metadata": {},
 "outputs": []
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Sa\u00edda renderizada:\n",
 "\n",
 "![Blender](files/blender2.png)\n",
 "\n",
 "Exemplo com interface:"
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [
 "from math import *\n",
 "from Blender.Draw import *\n",
 "from Blender import BGL, Window, Mesh, Scene\n",
 "\n",
 "\n",
 "class Buttons:\n",
 " \"\"\"\n",
 " Classe com para armazenar os bot\u00f5es para que\n",
 " os valores possam ser usados por outras rotinas\n",
 " sem usar vari\u00e1veis globais\n",
 " \"\"\"\n",
 " # Equa\u00e7\u00e3o\n",
 " formula = Create('cos(x) - sin(3*x)')\n",
 " # Varia\u00e7\u00e3o\n",
 " delta = Create(.1)\n",
 "\n",
 "\n",
 "def interface():\n",
 " \"\"\"\n",
 " Fun\u00e7\u00e3o que desenha a interface\n",
 " \"\"\"\n",
 " # Pega o tamanho da janela\n",
 " x, y = Window.GetAreaSize()\n",
 "\n",
 " # Desenha caixa de texto\n",
 " # Par\u00e2metros: r\u00f3tulo, evento, x, y, largura, altura, valor inicial,\n",
 " # tamanho m\u00e1ximo do texto, tooltip\n",
 " Buttons.formula = String('F\u00f3rmula: ', 0, 10, y - 30, 300, 20,\n",
 " Buttons.formula.val, 300, 'Entre com uma express\u00e3o Python')\n",
 " # Desenha caixa de n\u00famero\n",
 " # Par\u00e2metros: r\u00f3tulo, evento, x, y, largura, altura, valor inicial,\n",
 " # m\u00ednimo, m\u00e1ximo, tooltip\n",
 " Buttons.delta = Number('Delta: ', 0, 10, y - 60, 300, 20,\n",
 " Buttons.delta.val, .01, 1., 'Entre com a varia\u00e7\u00e3o')\n",
 " # Desenha os bot\u00f5es\n",
 " # Par\u00e2metros: texto do bot\u00e3o, evento, x, y, largura, altura, tooltip\n",
 " PushButton('Ok', 1, 10, y - 90, 100, 20, 'Aplica as mudan\u00e7as')\n",
 " PushButton('Fim', 2, 10, y - 120, 100, 20, 'Termina o programa')\n",
"\n",
 " # Comandos OpenGL atrav\u00e9s da BGL\n",
 " BGL.glClearColor(.7, .7, .6, 1)\n",
 " BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)\n",
 "\n",
 "def events(evt, val):\n",
 " \"\"\"\n",
 " Fun\u00e7\u00e3o que responde a eventos diversos,\n",
 " menos os gerados por bot\u00f5es\n",
 " \"\"\"\n",
 "\n",
 " # Os eventos das teclas est\u00e3o definidas em Draw\n",
 " if evt == ESCKEY:\n",
 " # Termina o programa\n",
 " Exit()\n",
 "\n",
 "def buttons(evt):\n",
 " \"\"\"\n",
 " Fun\u00e7\u00e3o que responde a eventos dos bot\u00f5es\n",
 " \"\"\"\n",
 "\n",
 " if evt == 2:\n",
 " Exit()\n",
 "\n",
 " elif evt == 1:\n",
 " gen3d()\n",
 "\n",
 "def gen3d():\n",
 "\n",
 " # Cena 3D\n",
 " cena = Scene.GetCurrent()\n",
 " x = y = z = 0\n",
 "\n",
 " while x < 2 * pi:\n",
 "\n",
 " # Calcula os valores de z\n",
 " z = eval(Buttons.formula.val)\n",
 "\n",
 " # Cria uma esfera de 16 segmentos, 16 an\u00e9is e 0.1 BU de raio\n",
 " s = Mesh.Primitives.UVsphere(16, 16, .1)\n",
 " esfera = cena.objects.new(s, 'Mesh')\n",
 " \n",
 " # Transfere a esfera para o local calculado\n",
 " esfera.setLocation(x, y, z)\n",
 "\n",
 " # Pr\u00f3ximo x\n",
 " x += Buttons.delta.val\n",
 " \n",
 " # Atualiza a cena\n",
 " cena.update()\n",
 "\n",
 "if __name__ == '__main__':\n",
 "\n",
 " # Registra as fun\u00e7\u00f5es callback\n",
 " Register(interface, events, buttons)"
 ],
 "language": "python",
 "metadata": {},
 "outputs": []
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Interface:\n",
 "\n",
 "![Blender](files/blender3.png)\n",
 "\n",
 "Sa\u00edda:\n",
 "\n",
 "![Blender](files/blender4.png)\n",
 "\n",
 "Exemplo de cria\u00e7\u00e3o de malha:"
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [
 "from Blender import NMesh, Redraw\n",
 "\n",
 "# Cria uma nova malha\n",
 "mesh = NMesh.New()\n",
 "\n",
 "# Um dicion\u00e1rio para armazenar os v\u00e9rtices\n",
 "# conforme a posi\u00e7\u00e3o\n",
 "vertices = {}\n",
 "\n",
 "for X in xrange(3):\n",
 " for Y in range(3):\n",
 " # Uma face \u00e9 determinada pelos v\u00e9rtices que fazem parte dela\n",
 " face = []\n",
 " coords = [(X + 0, Y + 0), (X + 0, Y + 1),\n",
 " (X + 1, Y+ 1), (X + 1, Y + 0)]\n",
 "\n",
 " # V\u00e9rtices da face\n",
 " for x, y in coords:\n",
 " vertices[(x, y)] = vertices.get((x, y), NMesh.Vert(x, y, 0))\n",
 " face.append(vertices[(x, y)])\n",
 "\n",
 " # Adiciona um objeto \"face\" na lista de faces da malha\n",
 " mesh.faces.append(NMesh.Face(face))\n",
 "\n",
 "# Adiciona os v\u00e9rtices na malha\n",
 "for vertice in vertices.values():\n",
 " mesh.verts.append(vertice)\n",
 "\n",
 "# Carrega a malha na cena\n",
 "NMesh.PutRaw(mesh, 'chess', True)\n",
 "Redraw()"
 ],
 "language": "python",
 "metadata": {},
 "outputs": []
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Sa\u00edda:\n",
 "\n",
 "![Malha no Blender](files/blender5.png)\n",
 "\n",
 "Para executar c\u00f3digo em Python no ambiente do Blender, basta carregar o programa na janela de editor de texto do Blender e usar a op\u00e7\u00e3o de execu\u00e7\u00e3o no menu.\n",
 "\n",
 "Game engine\n",
 "-----------\n",
 "*Game engine* \u00e9 um software que facilita a cria\u00e7\u00e3o de jogos, simulando determinados aspectos da realidade, de forma a possibilitar a intera\u00e7\u00e3o com objetos em tempo real. Para isso, ele deve implementar v\u00e1rias funcionalidades que s\u00e3o comuns em jogos, como por exemplo a capacidade de simula\u00e7\u00e3o f\u00edsica. O objetivo principal do uso de *game engines* \u00e9 centrar o foco da cria\u00e7\u00e3o do jogo no conte\u00fado, ou seja, mapas (n\u00edveis), personagens, objetos, di\u00e1logos, trilha sonora e cenas. \u00c9 comum que v\u00e1rios jogos usem o mesmo engine, reduzindo assim, o esfor\u00e7o de desenvolvimento.\n",
 "\n",
 "Um dos principais recursos fornecidos por *game engines* \u00e9 a capacidade de renderizar cenas em 2D ou 3D em tempo real, geralmente usando uma biblioteca gr\u00e1fica, como o OpenGL, permitindo anima\u00e7\u00f5es e efeitos especiais. O componente especializado para esta fun\u00e7\u00e3o \u00e9 conhecido como *render engine*.\n",
 "\n",
 "Al\u00e9m disso, a simula\u00e7\u00e3o f\u00edsica tamb\u00e9m \u00e9 essencial para um jogo, para representar de forma adequada os movimentos dos personagens sendo influenciados pela gravidade, in\u00e9rcia, atrito, detec\u00e7\u00e3o de colis\u00f5es e outros. O componente que realiza esses c\u00e1lculos \u00e9 chamado *Physics Engine*.\n",
 "\n",
 "Outra funcionalidade importante \u00e9 a l\u00f3gica, que \u00e9 como o jogo determina o comportamento do ambiente e dos personagens. Em muitos casos, o *game engine* suporta uma ou mais linguagens para descrev\u00ea-la.\n",
 "\n",
 "Os *game engines* podem incluir outros recursos importantes para determinados tipos de jogos, como conectividade. No caso de MMOG (*Massively Multiplayer Online Games*), que s\u00e3o muito complexos, a infraestrutura de software \u00e9 mais conhecida como *middleware*.\n",
 "\n",
 "A populariza\u00e7\u00e3o dos *game engines* aconteceu durante a d\u00e9cada de 90, gra\u00e7as a Id Software, que desenvolveu os jogos que definiram o g\u00eanero chamado FPS (*First Person Shooter*), jogos de a\u00e7\u00e3o em primeira pessoa. Esses t\u00edtulos tiveram seus *engines* licenciados para outras empresas, que criaram outros jogos desenvolvendo o conte\u00fado do jogo. Em paralelo, os processadores de v\u00eddeo foram incorporando suporte as fun\u00e7\u00f5es gr\u00e1ficas cada vez mais sofisticadas, o que facilitou a evolu\u00e7\u00e3o dos *engines*. A Id tamb\u00e9m liberou os game engines das s\u00e9ries DOOM e Quake em GPL.\n",
 "\n",
 "Al\u00e9m de entretenimento, outras \u00e1reas podem se beneficiar desses engines. Chamadas genericamente de serious games, aplica\u00e7\u00f5es nas \u00e1reas de treinamento, arquitetura, engenharia, medicina e marketing est\u00e3o se popularizando aos poucos.\n",
 "\n",
 "O Blender inclui um *game engine* gen\u00e9rico, que permite a cria\u00e7\u00e3o de jogos 3D, usando o pr\u00f3prio aplicativo para cria\u00e7\u00e3o de conte\u00fado e Python para as partes com l\u00f3gica mais complexa.\n",
 "\n",
 "O Blender Game Engine (BGE) usa como *physics engine* o projeto, tamb\u00e9m *Open Source*, chamado [Bullet](http://www.bulletphysics.org/). Com ele, \u00e9 poss\u00edvel simular o comportamento de corpos r\u00edgidos (como pe\u00e7as de maquinaria), macios (como tecidos), est\u00e1ticos (fixos) e intang\u00edveis (que n\u00e3o s\u00e3o afetados por colis\u00f5es).\n",
 "\n",
 "![Blender Bullet](files/blender6.png)\n",
 "\n",
 "O *render engine* do Blender suporta GLSL (*OpenGL Shading Language*), o que permite que ele utilize recursos avan\u00e7ados dispon\u00edveis nos processadores de v\u00eddeo mais recentes.\n",
 "\n",
 "J\u00e1 a l\u00f3gica \u00e9
definida no BGE atrav\u00e9s de *Logic Bricks*, que segue um modelo baseado em eventos. Eventos s\u00e3o associados a um objeto da cena e podem ser gerados por perif\u00e9ricos de entrada (como teclado e mouse), pelo sistema (tempo), pelo pr\u00f3prio BGE (colis\u00f5es, por exemplo) ou por mensagens enviadas por outros objetos. Quando um ou mais eventos s\u00e3o detectados, o BGE toma uma decis\u00e3o e reage de acordo.\n",
 "\n",
 "Existem tr\u00eas tipos de *bricks*:\n",
 "\n",
 "+ Sensores (*sensors*), que detectam os eventos.\n",
 "+ Controladores (*controllers*), que relacionam os sensores com os ativadores adequados.\n",
 "+ Ativadores (*actuators*), que ativam as rea\u00e7\u00f5es.\n",
 "\n",
 "No painel *Logic*, as associa\u00e7\u00f5es entre os *bricks* pode ser definida de forma interativa. O BGE tem diversos ativadores prontos, para realizar tarefas como encerrar a execu\u00e7\u00e3o ou mudar a velocidade do objeto.\n",
 "\n",
 "O BGE pode evocar c\u00f3digo em Python para responder aos eventos, atrav\u00e9s do controlador \u201cPython\u201d. Quando uma fun\u00e7\u00e3o em Python \u00e9 executada, ela recebe como argumento o controlador que realizou a chamada, com isso \u00e9 poss\u00edvel identificar e modificar o objeto (*owner*) que possui o controlador.\n",
 "\n",
 "Exemplo (m\u00f3dulo com fun\u00e7\u00e3o para teleporte):"
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [
 "# M\u00f3dulo de interface com o Game Engine\n",
 "import GameLogic\n",
 "\n",
 "def teleport(cont):\n",
 "\n",
 " # obt\u00eam o dono do controller\n",
 " own = cont.owner\n",
 "\n",
 " # obt\u00eam a cena\n",
 " scene = GameLogic.getCurrentScene()\n",
 " \n",
 " # obt\u00eam o destino\n",
 " dest = scene.getObjectList()['OBr_portal']\n",
 " \n",
 " # obt\u00eam as coordenadas do destino\n",
 " x, y, z = dest.getPosition()\n",
 " \n",
 " # move a c\u00e2mera para 1 BU acima do destino\n",
 " own.setPosition([x, y, z + 1])"
 ],
 "language": "python",
 "metadata": {},
 "outputs": []
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Essa fun\u00e7\u00e3o muda a posi\u00e7\u00e3o do objeto, para um BU a cima do objeto chamado \u201cr_portal\u201d, independente do lugar na cena em que estiver localizado."
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [],
 "language": "python",
 "metadata": {},
 "outputs": [
 {
 "html": [
 "<style>\n",
 " @font-face {\n",
 " font-family: \"Computer Modern\";\n",
 " src: url('http://mirrors.ctan.org/fonts/cm-unicode/fonts/otf/cmunss.otf');\n",
 " }\n",
 " div.cell{\n",
 " width:800px;\n",
 " margin-left:16% !important;\n",
 " margin-right:auto;\n",
 " }\n",
 " h1 {\n",
 " font-family: Helvetica, serif;\n",
 " }\n",
 " h4{\n",
 " margin-top:12px;\n",
 " margin-bottom: 3px;\n",
 " }\n",
 " div.text_cell_render{\n",
 " font-family: Computer Modern, \"Helvetica Neue\", Arial, Helvetica, Geneva, sans-serif;\n",
 " line-height: 145%;\n",
 " font-size: 130%;\n",
 " width:800px;\n",
 " margin-left:auto;\n",
 " margin-right:auto;\n",
 " }\n",
 " .CodeMirror{\n",
 " font-family: \"Source Code Pro\", source-code-pro,Consolas, monospace;\n",
 " }\n",
 " .note{\n",
 " border-bottom: 1px black dotted;\n",
 " }\n",
 " .prompt{\n",
 " display: None;\n",
 " }\n",
 " .text_cell_render h5 {\n",
 " font-weight: 300;\n",
 " font-size: 16pt;\n",
 " color: #4057A1;\n",
 " font-style: italic;\n",
 " margin-bottom: .5em;\n",
 " margin-top: 0.5em;\n",
 " display: block;\n",
 " }\n",
 " \n",
 " .warning{\n",
 " color: rgb( 240, 20, 20 )\n",
 " } \n",
 "</style>\n",
 "<script>\n",
 " MathJax.Hub.Config({\n",
 " TeX: {\n",
 " extensions: [\"AMSmath.js\"]\n",
 " },\n",
 " tex2jax: {\n",
 " inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\n",
 " displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ]\n",
 " },\n",
 " displayAlign: 'center', // Change this to 'center' to center equations.\n",
 " \"HTML-CSS\": {\n",
 " styles: {'.MathJax_Display': {\"margin\": 4}}\n",
 " }\n",
 " });\n",
 "</script>"
 ],
 "output_type": "pyout",
 "prompt_number": 1,
 "text": [
 "<IPython.core.display.HTML at 0x50f8f98>"
 ]
 }
 ],
 "prompt_number": 1
 }
 ],
 "metadata": {}
 }
 ]
}
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceB/blender1.png
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceB/blender2.png
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceB/blender3.png
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceB/blender4.png
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceB/blender5.png
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceB/blender6.png
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceC/ApendiceC.ipynb
{
 "metadata": {
 "name": ""
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
 {
 "cells": [
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "[Python para Desenvolvedores](http://ricardoduarte.github.io/python-para-desenvolvedores/#conteudo)\n",
 "===================================\n",
 "2&ordf; edi\u00e7\u00e3o, revisada e ampliada\n",
 "-----------------------------------\n",
 "\n",
 "Ap\u00eandice C: GIMP\n",
 "=============================\n",
 "_____________________________\n",
 "[GIMP](http://www.gimp.org/) (GNU Image Manipulation Program) \u00e9 um software de c\u00f3digo aberto bastante conhecido, que implementa v\u00e1rias ferramentas para processamento e edi\u00e7\u00e3o de imagens *raster* (com alguns recursos vetoriais, para lidar com texto, por exemplo), al\u00e9m de algoritmos de convers\u00e3o para diversos formatos. Permite a manipula\u00e7\u00e3o de imagens compostas de m\u00faltiplas camadas e possui uma arquitetura baseada em *plugins* que permite implementar novas funcionalidades.\n",
 "\n",
 "Originalmente, os *plugins* eram criados na linguagem funcional Scheme, por\u00e9m hoje \u00e9 poss\u00edvel usar Python tamb\u00e9m, atrav\u00e9s de uma extens\u00e3o chamada [Gimp-Python](http://www.gimp.org/docs/python/index.html).\n",
 "\n",
 "Um *plugin* feito em Python deve seguir os seguintes passos:\n",
 "\n",
 "+ Importar *gimpfu*: o m\u00f3dulo *gimpfu* define as fun\u00e7\u00f5es e tipos necess\u00e1rios para o Python + possa se comunicar com o GIMP.\n",
 "+ Definir fun\u00e7\u00e3o de processamento: a fun\u00e7\u00e3o que ser\u00e1 utilizada para processar a imagem, usando a API do GIMP.\n",
 "+ Registrar a fun\u00e7\u00e3o: a fun\u00e7\u00e3o `register()` cadastra a fun\u00e7\u00e3o de processamento na *Procedural Database*
(PDB), permitindo que o GIMP conhe\u00e7a as informa\u00e7\u00f5es necess\u00e1rias para executar o *plugin*.\n",
 "+ Executar `main()`: rotina principal da API.\n",
 "\n",
 "A fun\u00e7\u00e3o de processamento ter\u00e1 realizar alguns passos para poder interagir corretamente com o GIMP:\n",
 "\n",
 "+ Receber vari\u00e1veis: a fun\u00e7\u00e3o recebe como argumentos a imagem (*image*), a camada corrente em edi\u00e7\u00e3o (*drawable*) e outros que forem definidos no registro da fun\u00e7\u00e3o. Os outros par\u00e2metros ser\u00e3o obtidos atrav\u00e9s de uma caixa de dialogo apresentada ao usu\u00e1rio antes da execu\u00e7\u00e3o.\n",
 "+ Iniciar transa\u00e7\u00e3o: inicio da transa\u00e7\u00e3o atrav\u00e9s da fun\u00e7\u00e3o `pdb.gimp_image_undo_group_start()`. A transa\u00e7\u00e3o pode ser desfeita posteriormente atrav\u00e9s de *undo*.\n",
 "+ Processar imagem: altera a imagem ou a camada atrav\u00e9s das fun\u00e7\u00f5es definidas na API.\n",
 "+ Terminar transa\u00e7\u00e3o: encerra a transa\u00e7\u00e3o atrav\u00e9s da fun\u00e7\u00e3o `pdb.gimp_image_undo_group_end()`.\n",
 "\n",
 "Com isso, o processamento realizado pelo *plugin* ter\u00e1 um comportamento conforme com outras funcionalidades presentes no software, incluindo a capacidade de ter a opera\u00e7\u00e3o desfeita (*undo*).\n",
 "\n",
 "Exemplo:"
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [
 "# Importa a interface para o GIMP\n",
 "from gimpfu import *\n",
 "\n",
 "def stonify(img, drawable, fracture=135, picture=135):\n",
 " \"\"\"\"\"\"\n",
 " # Inicia a transa\u00e7\u00e3o para UNDO\n",
 " pdb.gimp_image_undo_group_start(img)\n",
 " \n",
 " # Cria uma camada de lava\n",
 " pdb.script_fu_lava(img, drawable, 10, 10, 7,\n",
 " 'German flag smooth', 1, 1, 0)\n",
 " lava = img.layers[0]\n",
 " w, h = img.width, img.height\n",
 " \n",
 " # Cria uma camada de ru\u00eddo\n",
 " rock = gimp.Layer(img, 'Rock', w, h, RGB_IMAGE,\n",
 " 100, MULTIPLY_MODE)\n",
 " pdb.gimp_image_add_layer(img, rock, 0)\n",
 " pdb.plug_in_solid_noise(img, rock, 0, 0, 0, 1, 4, 4)\n",
 " \n",
 " # Aplica relevo nas camadas\n",
 " pdb.plug_in_bump_map(img, rock, lava,\n",
 " fracture, 45, 15, 0, 0, 0, 0, 1, 0, 0)\n",
 " pdb.plug_in_bump_map(img, rock, drawable,\n",
 " picture, 45, 30, 0, 0, 0, 0, 1, 0, 0)\n",
 " lava.visible = 0\n",
 " \n",
 " # Combina as camadas da imagem em uma s\u00f3\n",
 " img.flatten()\n",
 " pdb.gimp_brightness_contrast (img.layers[0], 30, 10)\n",
 " \n",
 " # Termina a transa\u00e7\u00e3o\n",
 " pdb.gimp_image_undo_group_end(img)\n",
 "\n",
 "# Registra a fun\u00e7\u00e3o na PDB\n",
 "register(\n",
 " # Identifica\u00e7\u00e3o\n",
 " 'Stonify',\n",
 " '\"Stonify\" the image...',\n",
 " '\"Stonify\" the image with some noise',\n",
 " 'Luiz Eduardo Borges',\n",
 " 'Luiz Eduardo Borges',\n",
 " '2008-2010',\n",
 " # Localiza\u00e7\u00e3o no menu\n",
 " '<Image>/Filters/Render/Stonify...',\n",
 " # Modos suportados (todos) \n",
 " '*',\n",
 " # Par\u00e2metros\n",
 " [\n",
 " (PF_INT, 'fracture', 'Fracture power', 135),\n",
 " (PF_INT, 'picture', 'Picture power', 135)\n",
 " ],\n",
 " # Resultados\n",
 " [],\n",
 " stonify)\n",
 "\n",
 "# Executa o plugin\n",
 "main()"
 ],
 "language": "python",
 "metadata": {},
 "outputs": []
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Janela de op\u00e7\u00f5es:\n",
 "\n",
 "![Gimp](files/gimp1.png)\n",
 "\n",
 "Exemplo dos passos para a gera\u00e7\u00e3o da imagem:\n",
 "\n",
 "![Diagrama Gimp](files/bpypd_diags38.png)\n",
 "\n",
 "O GIMP tamb\u00e9m permite que os plugins sejam executados atrav\u00e9s de linha de comando, usando os par\u00e2metros `--no-interface --batch`.\n",
 "\n",
 "O *script* precisa estar numa pasta em que o GIMP possa encontr\u00e1-lo. Para o GIMP 2.6, a pasta de *plugins* do usu\u00e1rio fica em `.gimp-2.6/plug-ins` abaixo do diret\u00f3rio `home` do usu\u00e1rio. Al\u00e9m disso, a extens\u00e3o requer que PyGTK e suas depend\u00eancias estejam instaladas."
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [],
 "language": "python",
 "metadata": {},
 "outputs": [
 {
 "html": [
 "<style>\n",
 " @font-face {\n",
 " font-family: \"Computer Modern\";\n",
 " src: url('http://mirrors.ctan.org/fonts/cm-unicode/fonts/otf/cmunss.otf');\n",
 " }\n",
 " div.cell{\n",
 " width:800px;\n",
 " margin-left:16% !important;\n",
 " margin-right:auto;\n",
 " }\n",
 " h1 {\n",
 " font-family: Helvetica, serif;\n",
 " }\n",
 " h4{\n",
 " margin-top:12px;\n",
 " margin-bottom: 3px;\n",
 " }\n",
 " div.text_cell_render{\n",
 " font-family: Computer Modern, \"Helvetica Neue\", Arial, Helvetica, Geneva, sans-serif;\n",
 " line-height: 145%;\n",
 " font-size: 130%;\n",
 " width:800px;\n",
 " margin-left:auto;\n",
 " margin-right:auto;\n",
 " }\n",
 " .CodeMirror{\n",
 " font-family: \"Source Code Pro\", source-code-pro,Consolas, monospace;\n",
 " }\n",
 " .note{\n",
 " border-bottom: 1px black dotted;\n",
 " }\n",
 " .prompt{\n",
 " display: None;\n",
 " }\n",
 " .text_cell_render h5 {\n",
 " font-weight: 300;\n",
 " font-size: 16pt;\n",
 " color: #4057A1;\n",
 " font-style: italic;\n",
 " margin-bottom: .5em;\n",
 " margin-top: 0.5em;\n",
 " display: block;\n",
 " }\n",
 " \n",
 " .warning{\n",
 " color: rgb( 240, 20, 20 )\n",
 " } \n",
 "</style>\n",
 "<script>\n",
 " MathJax.Hub.Config({\n",
 " TeX: {\n",
 " extensions: [\"AMSmath.js\"]\n",
 " },\n",
 " tex2jax: {\n",
 " inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\n",
 " displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ]\n",
 " },\n",
 " displayAlign: 'center', // Change this to 'center' to center equations.\n",
 " \"HTML-CSS\": {\n",
 " styles: {'.MathJax_Display': {\"margin\": 4}}\n",
 " }\n",
 " });\n",
 "</script>"
 ],
 "output_type": "pyout",
 "prompt_number": 1,
 "text": [
 "<IPython.core.display.HTML at 0x50f8f98>"
 ]
 }
 ],
 "prompt_number": 1
 }
 ],
 "metadata": {}
 }
 ]
}
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceC/bpypd_diags38.png
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceC/gimp1.png
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceD/ApendiceD.ipynb
{
 "metadata": {
 "name": ""
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets":
[
 {
 "cells": [
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "[Python para Desenvolvedores](http://ricardoduarte.github.io/python-para-desenvolvedores/#conteudo)\n",
 "===================================\n",
 "2&ordf; edi\u00e7\u00e3o, revisada e ampliada\n",
 "-----------------------------------\n",
 "\n",
 "Ap\u00eandice D: Inkscape\n",
 "=============================\n",
 "_____________________________\n",
 "O editor de imagens vetoriais [Inkscape](http://www.inkscape.org/) permite o uso do Python como linguagem *script*, para a cria\u00e7\u00e3o de extens\u00f5es. O aplicativo utiliza o SVG como formato nativo e implementa v\u00e1rios recursos previstos no padr\u00e3o.\n",
 "\n",
 "As extens\u00f5es para o Inkscape servem principalmente para a implementa\u00e7\u00e3o de filtros e efeitos. Enquanto outros aplicativos (como o Blender) apresentam uma API na forma de m\u00f3dulos para o interpretador, o Inkscape passa argumentos pela linha de comando e transfere informa\u00e7\u00f5es pela entrada e sa\u00edda padr\u00e3o do sistema operacional, de forma similar aos utilit\u00e1rios de tratamento de texto encontrados em sistemas UNIX. Com isso, a extens\u00e3o tem acesso apenas aos elementos que fazem parte do documento, e n\u00e3o a interface gr\u00e1fica do aplicativo. Qualquer intera\u00e7\u00e3o com o usu\u00e1rio durante a execu\u00e7\u00e3o fica por conta da extens\u00e3o.\n",
 "\n",
 "A cria\u00e7\u00e3o e manipula\u00e7\u00e3o das estruturas de dados \u00e9 feita usando XML, como prev\u00ea a especifica\u00e7\u00e3o do formato SVG, permitindo com isso o uso de m\u00f3dulos como o *ElementTree*.\n",
 "\n",
 "Para simplificar o processo, o Inkscape prov\u00ea o m\u00f3dulo chamado *inkex*, que define estruturas b\u00e1sicas para extens\u00f5es. Com esse m\u00f3dulo, novas extens\u00f5es podem ser criadas por heran\u00e7a a partir de uma classe chamada *Effect*.\n",
 "\n",
 "Exemplo (randomtext.py):"
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [
 "import random\n",
 "import inkex\n",
 "import simplestyle\n",
 "\n",
 "\n",
 "class RandomText(inkex.Effect):\n",
 " \"\"\"\n",
 " Repete um texto aleatoriamente dentro de uma \u00e1rea.\n",
 " \"\"\"\n",
 " def __init__(self):\n",
 "\n",
 " # Evoca a inicializa\u00e7\u00e3o da superclasse\n",
 " inkex.Effect.__init__(self)\n",
 "\n",
 " # Adiciona um par\u00e2metro para ser recebido do Inkscape\n",
 " self.OptionParser.add_option('-t', '--texto',\n",
 " action = 'store', type = 'string',\n",
 " dest = 'texto', default = 'Python',\n",
 " help = 'Texto para ser randomizado')\n",
 "\n",
 " self.OptionParser.add_option('-q', '--quantidade',\n",
 " action='store', type='int',\n",
 " dest='quantidade', default=20,\n",
 " help='Quantidade de vezes que o texto ir\u00e1 aparecer')\n",
 "\n",
 " self.OptionParser.add_option('-l', '--largura',\n",
 " action='store', type='int',\n",
 " dest='largura', default=1000,\n",
 " help='Largura da \u00e1rea')\n",
 "\n",
 " self.OptionParser.add_option('-c', '--altura',\n",
 " action='store', type='int',\n",
 " dest='altura', default=1000,\n",
 " help='Altura da \u00e1rea')\n",
 "\n",
 " def effect(self):\n",
 "\n",
 " # Pega as vari\u00e1veis que foram passadas como\n",
 " # op\u00e7\u00f5es de linha de comando pelo Inkscape\n",
 " texto = self.options.texto\n",
 " quantidade = self.options.quantidade\n",
 " largura = self.options.largura\n",
 " altura = self.options.altura\n",
 "\n",
 " # Raiz do SVG\n",
 " svg = self.document.getroot()\n",
 "\n",
 " # Altura e largura do documento\n",
 " doc_largura = inkex.unittouu(svg.attrib['width'])\n",
 " doc_altura = inkex.unittouu(svg.attrib['height'])\n",
 "\n",
 " # Cria uma camada no documento\n",
 " camada = inkex.etree.SubElement(svg, 'g')\n",
 " camada.set(inkex.addNS('label', 'inkscape'), 'randomtext')\n",
 " camada.set(inkex.addNS('groupmode', 'inkscape'), 'camada')\n",
 "\n",
 " for i in xrange(quantidade):\n",
 "\n",
 " # Cria um elemento para o texto\n",
 " xmltexto = inkex.etree.Element(inkex.addNS('text','svg'))\n",
 " xmltexto.text = texto\n",
 "\n",
 " # Posiciona o elemento no documento\n",
 " x = random.randint(0, largura) + (doc_largura - largura) / 2\n",
 " xmltexto.set('x', str(x))\n",
 " y = random.randint(0, altura) + (doc_altura - altura) / 2\n",
 " xmltexto.set('y', str(y))\n",
 "\n",
 " # Centraliza na vertical e na horizontal\n",
 " # e muda a cor de preenchimento usando CSS\n",
 " c = random.randint(100, 255)\n",
 " style = {'text-align' : 'center',\n",
 " 'text-anchor': 'middle',\n",
 " 'fill': '#%02x%02x%02x' % (c, c - 30, c - 60)}\n",
 " xmltexto.set('style', simplestyle.formatStyle(style))\n",
 "\n",
 " # Coloca o texto na camada\n",
 " camada.append(xmltexto)\n",
 "\n",
 "\n",
 "if __name__ == '__main__':\n",
 " rt = RandomText()\n",
 " rt.affect()"
 ],
 "language": "python",
 "metadata": {},
 "outputs": []
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Para que o Inkscape reconhe\u00e7a a nova extens\u00e3o, \u00e9 necess\u00e1rio criar um arquivo XML com a configura\u00e7\u00e3o, que informa ao aplicativo os m\u00f3dulos e os par\u00e2metros usados pela extens\u00e3o, incluindo os tipos, limites e valores padr\u00e3o desses par\u00e2metros, para que ele possa interagir com o usu\u00e1rio atrav\u00e9s de uma caixa de dialogo antes da execu\u00e7\u00e3o para obter os valores desejados. Os par\u00e2metros s\u00e3o passados como argumentos na linha de comando quando o *script* \u00e9 executado.\n",
 "\n",
 "Arquivo de configura\u00e7\u00e3o (randomtext.inx):"
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [
 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
 "<inkscape-extension xmlns=\"http://www.inkscape.org/namespace/inkscape/extension\">\n",
 " <_name>RandomText</_name>\n",
 " <id>org.ekips.filter.randomtext</id>\n",
 " <dependency type=\"executable\" location=\"extensions\">randomtext.py</dependency>\n",
 " <dependency type=\"executable\" location=\"extensions\">inkex.py</dependency>\n",
 " <param name=\"texto\" type=\"string\" _gui-text=\"Texto\">Python</param>\n",
 " <param name=\"quantidade\" type=\"int\" min=\"1\" max=\"500\" _gui-text=\"Quantidade\">20</param>\n",
 " <param name=\"largura\" type=\"int\" min=\"1\" max=\"10000\" _gui-text=\"Largura\">1000</param>\n",
 " <param name=\"altura\" type=\"int\" min=\"1\" max=\"10000\" _gui-text=\"Altura\">1000</param>\n",
 " <effect>\n",
 " <object-type>all</object-type>\n",
 " <effects-menu>\n",
 " <submenu _name=\"Render\"/>\n",
 " </effects-menu>\n",
 " </effect>\n",
 " <script>\n",
 " <command reldir=\"extensions\" interpreter=\"python\">randomtext.py</command>\n",
" </script>\n",
 "</inkscape-extension>"
 ],
 "language": "python",
 "metadata": {},
 "outputs": []
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Janela com os par\u00e2metros da extens\u00e3o:\n",
 "\n",
 "![Inkscape](files/inkscape1.png)\n",
 "\n",
 "Exemplo de sa\u00edda (quantidade igual a 100, largura igual a 600 e altura igual a 200):\n",
 "\n",
 "![Inkscape](files/inkscape2.png)\n",
 "\n",
 "Tanto o programa quanto o arquivo de configura\u00e7\u00e3o precisam ficar na pasta de extens\u00f5es (`share\\extensions`, dentro da pasta de instala\u00e7\u00e3o, para a vers\u00e3o Windows) para que sejam encontrados pelo aplicativo e o nome do arquivo de configura\u00e7\u00e3o precisa ter extens\u00e3o `.inx`."
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [],
 "language": "python",
 "metadata": {},
 "outputs": [
 {
 "html": [
 "<style>\n",
 " @font-face {\n",
 " font-family: \"Computer Modern\";\n",
 " src: url('http://mirrors.ctan.org/fonts/cm-unicode/fonts/otf/cmunss.otf');\n",
 " }\n",
 " div.cell{\n",
 " width:800px;\n",
 " margin-left:16% !important;\n",
 " margin-right:auto;\n",
 " }\n",
 " h1 {\n",
 " font-family: Helvetica, serif;\n",
 " }\n",
 " h4{\n",
 " margin-top:12px;\n",
 " margin-bottom: 3px;\n",
 " }\n",
 " div.text_cell_render{\n",
 " font-family: Computer Modern, \"Helvetica Neue\", Arial, Helvetica, Geneva, sans-serif;\n",
 " line-height: 145%;\n",
 " font-size: 130%;\n",
 " width:800px;\n",
 " margin-left:auto;\n",
 " margin-right:auto;\n",
 " }\n",
 " .CodeMirror{\n",
 " font-family: \"Source Code Pro\", source-code-pro,Consolas, monospace;\n",
 " }\n",
 " .note{\n",
 " border-bottom: 1px black dotted;\n",
 " }\n",
 " .prompt{\n",
 " display: None;\n",
 " }\n",
 " .text_cell_render h5 {\n",
 " font-weight: 300;\n",
 " font-size: 16pt;\n",
 " color: #4057A1;\n",
 " font-style: italic;\n",
 " margin-bottom: .5em;\n",
 " margin-top: 0.5em;\n",
 " display: block;\n",
 " }\n",
 " \n",
 " .warning{\n",
 " color: rgb( 240, 20, 20 )\n",
 " } \n",
 "</style>\n",
 "<script>\n",
 " MathJax.Hub.Config({\n",
 " TeX: {\n",
 " extensions: [\"AMSmath.js\"]\n",
 " },\n",
 " tex2jax: {\n",
 " inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\n",
 " displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ]\n",
 " },\n",
 " displayAlign: 'center', // Change this to 'center' to center equations.\n",
 " \"HTML-CSS\": {\n",
 " styles: {'.MathJax_Display': {\"margin\": 4}}\n",
 " }\n",
 " });\n",
 "</script>"
 ],
 "output_type": "pyout",
 "prompt_number": 1,
 "text": [
 "<IPython.core.display.HTML at 0x50f8f98>"
 ]
 }
 ],
 "prompt_number": 1
 }
 ],
 "metadata": {}
 }
 ]
}
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceD/inkscape1.png
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceD/inkscape2.png
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceE/ApendiceE.ipynb
{
 "metadata": {
 "name": ""
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
 {
 "cells": [
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "[Python para Desenvolvedores](http://ricardoduarte.github.io/python-para-desenvolvedores/#conteudo)\n",
 "===================================\n",
 "2&ordf; edi\u00e7\u00e3o, revisada e ampliada\n",
 "-----------------------------------\n",
 "\n",
 "Ap\u00eandice E: BrOffice.org\n",
 "=============================\n",
 "_____________________________\n",
 "[BrOffice.org](http://www.broffice.org/) \u00e9 um conhecido pacote de automa\u00e7\u00e3o de escrit\u00f3rios de c\u00f3digo aberto, que inclui editor de textos, planilha e outros aplicativos. Al\u00e9m disso, o BrOffice.org tamb\u00e9m suporta Python (entre outras linguagens):\n",
 "\n",
 "+ Como linguagem de macro, permitindo a automatiza\u00e7\u00e3o de tarefas.\n",
 "+ Para a constru\u00e7\u00e3o de extens\u00f5es (*add ons*).\n",
 "+ Em um servi\u00e7o para atender conex\u00f5es, atrav\u00e9s de uma API chamada UNO (*Universal Network Objects*).\n",
 "\n",
 "Exemplo de macro:"
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [
 "# A macro deve ser executada a partir do\n",
 "# BrOffice.org Calc\n",
 "\n",
 "def plan():\n",
 " \"\"\"\n",
 " Preenche uma planilha\n",
 " \"\"\"\n",
 "\n",
 " # Obt\u00eam o documento para o contexto de script\n",
 " doc = XSCRIPTCONTEXT.getDocument()\n",
 "\n",
 " # A primeira planilha do documento\n",
 " sheet = doc.getSheets().getByIndex(0)\n",
 "\n",
 " col = lin = 0\n",
 " a = ord('A')\n",
 "\n",
 " # Cria uma linha com os t\u00edtulos para as colunas\n",
 " for titulo in ('Jan', 'Fev', 'Mar', 'Total'):\n",
 "\n",
 " col += 1\n",
 " sheet.getCellByPosition(col, lin).setString(titulo)\n",
 "\n",
 " # E coloca uma f\u00f3rmula com somat\u00f3rio na \u00faltima linha\n",
 " coluna = chr(a + col)\n",
 " formula = '=SUM(%s2:%s6)' % (coluna, coluna)\n",
 " sheet.getCellByPosition(col, lin + 6).setFormula(formula)\n",
 "\n",
 " for lin in xrange(1, 6):\n",
 "\n",
 " # Numera as linhas\n",
 " sheet.getCellByPosition(0, lin).setValue(lin)\n",
 "\n",
 " # Coloca somat\u00f3rios no fim de cada linha\n",
 " formula = '=SUM(B%d:D%d)' % (lin + 1, lin + 1)\n",
 " sheet.getCellByPosition(4, lin).setFormula(formula)\n",
 " \n",
 " # Preenche os dados\n",
 " for col in (1, 2, 3):\n",
 " sheet.getCellByPosition(col, lin).setFormula('=10*RAND()')\n",
 "\n",
 " # Substitui a f\u00f3rmula pelo valor\n",
 " val = sheet.getCellByPosition(col, lin).getValue()\n",
 " sheet.getCellByPosition(col, lin).setValue(val)\n",
 "\n",
 " return None"
 ],
 "language": "python",
 "metadata": {},
 "outputs": []
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Sa\u00edda:\n",
 "\n",
 "![BrOffice.org](files/broffice.png)\n",
 "\n",
 "Para que o BrOffice.org possa identificar o *script* escrito em Python como um arquivo de macro, ele precisa estar na pasta para *scripts* em Python, que no Windows fica em `Basis\\share\\Scripts\\python`, dentro da pasta de instala\u00e7\u00e3o do BrOffice.org.\n",
 "\n",
 "Exemplo de gera\u00e7\u00e3o de relat\u00f3rio em PDF atrav\u00e9s do editor de texto (Writer), atrav\u00e9s da Python UNO Bridge:"
 ]
 },
 {
"cell_type": "code",
 "collapsed": false,
 "input": [
 "# Para iniciar o BrOffice.org como servidor:\n",
 "# swriter.exe -headless\n",
 "# \"-accept=pipe,name=py;urp;StarOffice.ServiceManager\"\n",
 "\n",
 "import os\n",
 "import uno\n",
 "from com.sun.star.beans import PropertyValue\n",
 "\n",
 "# Dados...\n",
 "mus = [('Artista', 'Faixa'),\n",
 " ('King Crimson', 'Starless'), ('Yes', 'Siberian Khatru'),\n",
 " ('Led Zeppellin', 'No Quarter'), ('Genesis', 'Supper\\'s Ready')]\n",
 "\n",
 "# Obt\u00eam o n\u00famero e o tamanho dos registros\n",
 "rows = len(mus)\n",
 "cols = len(mus[0])\n",
 "\n",
 "# Inicio do \"Boiler Plate\"...\n",
 "\n",
 "# Contexto de componente local\n",
 "loc = uno.getComponentContext()\n",
 "\n",
 "# Para resolver URLs\n",
 "res = loc.ServiceManager.createInstanceWithContext(\n",
 " 'com.sun.star.bridge.UnoUrlResolver', loc)\n",
 "\n",
 "# Contexto para a URL\n",
 "con = res.resolve('uno:pipe,name=py;urp;StarOffice.ComponentContext')\n",
 "\n",
 "# Documento corrente\n",
 "desktop = con.ServiceManager.createInstanceWithContext(\n",
 " 'com.sun.star.frame.Desktop', con)\n",
 "\n",
 "# Fim do \"Boiler Plate\"...\n",
 "\n",
 "# Cria um documento novo no Writer\n",
 "doc = desktop.loadComponentFromURL('private:factory/swriter',\n",
 " '_blank', 0, ())\n",
 "\n",
 "# Cursor de texto\n",
 "cursor = doc.Text.createTextCursor()\n",
 "\n",
 "# Muda as propriedades do texto\n",
 "cursor.setPropertyValue('CharFontName', 'Verdana')\n",
 "cursor.setPropertyValue('CharHeight', 20)\n",
 "cursor.setPropertyValue('CharWeight', 180)\n",
 "\n",
 "# Insere o texto no documento\n",
 "doc.Text.insertString(cursor, 'M\u00fasicas favoritas\\n', 0)\n",
 "\n",
 "# Cria tabela\n",
 "tab = doc.createInstance('com.sun.star.text.TextTable')\n",
 "tab.initialize(rows, cols)\n",
 "doc.Text.insertTextContent(cursor, tab, 0)\n",
 "\n",
 "# Preenche a tabela\n",
 "for row in xrange(rows):\n",
 " for col in xrange(cols):\n",
 " cel = chr(ord('A') + col) + str(row + 1)\n",
 " tab.getCellByName(cel).setString(mus[row][col])\n",
 "\n",
 "# Propriedades para exportar o documento\n",
 "props = []\n",
 "p = PropertyValue()\n",
 "p.Name = 'Overwrite'\n",
 "p.Value = True # Sobrescreve o documento anterior\n",
 "props.append(p)\n",
 "\n",
 "p = PropertyValue()\n",
 "p.Name = 'FilterName'\n",
 "p.Value = 'writer_pdf_Export' # Writer para PDF\n",
 "props.append(p)\n",
 "\n",
 "# URL de destino, no qual o arquivo PDF ser\u00e1 salvo\n",
 "url = uno.systemPathToFileUrl(os.path.abspath('musicas.pdf'))\n",
 "\n",
 "# Salva o documento como PDF\n",
 "doc.storeToURL(url, tuple(props))\n",
 "\n",
 "# Fecha o documento\n",
 "doc.close(True)"
 ],
 "language": "python",
 "metadata": {},
 "outputs": []
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Sa\u00edda (arquivo PDF):\n",
 "\n",
 "![BrOffice.org](files/broffice2.png)\n",
 "\n",
 "A API do BrOffice.org \u00e9 bastante completa e simplifica v\u00e1rias atividades que s\u00e3o lugar comum em programas para ambiente desktop."
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [],
 "language": "python",
 "metadata": {},
 "outputs": [
 {
 "html": [
 "<style>\n",
 " @font-face {\n",
 " font-family: \"Computer Modern\";\n",
 " src: url('http://mirrors.ctan.org/fonts/cm-unicode/fonts/otf/cmunss.otf');\n",
 " }\n",
 " div.cell{\n",
 " width:800px;\n",
 " margin-left:16% !important;\n",
 " margin-right:auto;\n",
 " }\n",
 " h1 {\n",
 " font-family: Helvetica, serif;\n",
 " }\n",
 " h4{\n",
 " margin-top:12px;\n",
 " margin-bottom: 3px;\n",
 " }\n",
 " div.text_cell_render{\n",
 " font-family: Computer Modern, \"Helvetica Neue\", Arial, Helvetica, Geneva, sans-serif;\n",
 " line-height: 145%;\n",
 " font-size: 130%;\n",
 " width:800px;\n",
 " margin-left:auto;\n",
 " margin-right:auto;\n",
 " }\n",
 " .CodeMirror{\n",
 " font-family: \"Source Code Pro\", source-code-pro,Consolas, monospace;\n",
 " }\n",
 " .note{\n",
 " border-bottom: 1px black dotted;\n",
 " }\n",
 " .prompt{\n",
 " display: None;\n",
 " }\n",
 " .text_cell_render h5 {\n",
 " font-weight: 300;\n",
 " font-size: 16pt;\n",
 " color: #4057A1;\n",
 " font-style: italic;\n",
 " margin-bottom: .5em;\n",
 " margin-top: 0.5em;\n",
 " display: block;\n",
 " }\n",
 " \n",
 " .warning{\n",
 " color: rgb( 240, 20, 20 )\n",
 " } \n",
 "</style>\n",
 "<script>\n",
 " MathJax.Hub.Config({\n",
 " TeX: {\n",
 " extensions: [\"AMSmath.js\"]\n",
 " },\n",
 " tex2jax: {\n",
 " inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\n",
 " displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ]\n",
 " },\n",
 " displayAlign: 'center', // Change this to 'center' to center equations.\n",
 " \"HTML-CSS\": {\n",
 " styles: {'.MathJax_Display': {\"margin\": 4}}\n",
 " }\n",
 " });\n",
 "</script>"
 ],
 "output_type": "pyout",
 "prompt_number": 1,
 "text": [
 "<IPython.core.display.HTML at 0x50f8f98>"
 ]
 }
 ],
 "prompt_number": 1
 }
 ],
 "metadata": {}
 }
 ]
}
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceE/broffice.png
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceE/broffice2.png
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceF/ApendiceF.ipynb
{
 "metadata": {
 "name": ""
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
 {
 "cells": [
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "[Python para Desenvolvedores](http://ricardoduarte.github.io/python-para-desenvolvedores/#conteudo)\n",
 "===================================\n",
 "2&ordf; edi\u00e7\u00e3o, revisada e ampliada\n",
 "-----------------------------------\n",
 "\n",
 "Ap\u00eandice F: Integra\u00e7\u00e3o com outras linguagens\n",
 "=============================\n",
 "_____________________________\n",
 "Existe hoje muito c\u00f3digo legado desenvolvido em diversas linguagens que pode ser aproveitado pelo Python, atrav\u00e9s de v\u00e1rias formas de integra\u00e7\u00e3o.\n",
 "\n",
 "Uma forma gen\u00e9rica de fazer isso \u00e9 gerar uma biblioteca compartilhada (*shared library*) atrav\u00e9s do compilador da outra linguagem e fazer chamadas a fun\u00e7\u00f5es que est\u00e3o definidas na biblioteca.\n",
 "\n",
 "Como a implementa\u00e7\u00e3o original do Python \u00e9 usando Linguagem C, \u00e9 poss\u00edvel
integrar Python e C nos dois sentidos:\n",
 "\n",
 "+ Python -> C (Python faz chamadas a um m\u00f3dulo compilado em C).\n",
 "+ C -> Python (C evoca o interpretador Python em modo *embedded*).\n",
 "\n",
 "Tamb\u00e9m \u00e9 poss\u00edvel integrar o Python com Fortran usando o utilit\u00e1rio f2py, que faz parte do projeto NumPy.\n",
 "\n",
 "Bibliotecas compartilhadas\n",
 "--------------------------\n",
 "A partir da vers\u00e3o 2.5, o Python incorporou o m\u00f3dulo *ctypes*, que implementa tipos compat\u00edveis com os tipos usados pela linguagem C e permite evocar fun\u00e7\u00f5es de bibliotecas compartilhadas.\n",
 "\n",
 "O m\u00f3dulo prov\u00ea v\u00e1rias formas de evocar fun\u00e7\u00f5es. Fun\u00e7\u00f5es que seguem a conven\u00e7\u00e3o de chamada *stdcall*, como a API do Windows, podem ser acessadas atrav\u00e9s da classe *windll*. *Dynamic-link library* (DLL) \u00e9 a implementa\u00e7\u00e3o de bibliotecas compartilhadas que s\u00e3o usadas no Windows.\n",
 "\n",
 "Exemplo com *windll*:"
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [
 "import ctypes\n",
 "\n",
 "# Evocando a caixa de mensagens do Windows\n",
 "# Os argumentos s\u00e3o: janela pai, mensagem,\n",
 "# t\u00edtulo da janela e o tipo da janela.\n",
 "# A fun\u00e7\u00e3o retorna um inteiro, que\n",
 "# corresponde a que bot\u00e3o foi pressionado\n",
 "i = ctypes.windll.user32.MessageBoxA(None,\n",
 " 'Teste de DLL!', 'Mensagem', 0)\n",
 "\n",
 "# O resultado indica qual bot\u00e3o foi clicado\n",
 "print i"
 ],
 "language": "python",
 "metadata": {},
 "outputs": []
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Para fun\u00e7\u00f5es que seguem a conven\u00e7\u00e3o de chamada *cdecl*, usada pela maioria dos compiladores C, existe a classe *cdll*. Para as passagens de argumentos por refer\u00eancia \u00e9 preciso criar uma vari\u00e1vel que funciona como um *buffer* para receber os resultados. Isso \u00e9 necess\u00e1rio para receber *strings*, por exemplo.\n",
 "\n",
 "Exemplo com *cdll* e *buffer*:"
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [
 "import ctypes\n",
 "\n",
 "# msvcrt \u00e9 a biblioteca com a maioria das fun\u00e7\u00f5es\n",
 "# padr\u00f5es da linguagens C no Windows\n",
 "# O Windows coloca automaticamente\n",
 "# a extens\u00e3o do arquivo\n",
 "clib = ctypes.cdll.msvcrt\n",
 "\n",
 "# Cria um buffer para receber o resultado\n",
 "# a refer\u00eancia para o buffer ser\u00e1 passada para\n",
 "# a fun\u00e7\u00e3o, que preenche o buffer com o resultado\n",
 "s = ctypes.c_buffer('\\000', 40)\n",
 "\n",
 "# sscanf() \u00e9 uma fun\u00e7\u00e3o que extrai valores\n",
 "# de uma string conforme uma mascara\n",
 "clib.sscanf('Testando sscanf!\\n',\n",
 " 'Testando %s!\\n', s)\n",
 "\n",
 "# Mostra o resultado\n",
 "print s.value"
 ],
 "language": "python",
 "metadata": {},
 "outputs": []
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "\u00c9 poss\u00edvel tamb\u00e9m evocar fun\u00e7\u00f5es de bibliotecas compartilhadas no Linux:"
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [
 "import ctypes\n",
 "\n",
 "# Carrega a biblioteca padr\u00e3o C no Linux\n",
 "# A extens\u00e3o do arquivo precisa passada\n",
 "# para a fun\u00e7\u00e3o LoadLibrary()\n",
 "clib = ctypes.cdll.LoadLibrary(\"libc.so.6\")\n",
 "\n",
 "# Cria um buffer para receber o resultado\n",
 "s = ctypes.c_buffer('\\000', 40)\n",
 "\n",
 "# Evoca a fun\u00e7\u00e3o sprintf\n",
 "clib.sprintf(s, 'Testando %s\\n', 'sprintf!')\n",
 "\n",
 "# Mostra o resultado\n",
 "print s.value"
 ],
 "language": "python",
 "metadata": {},
 "outputs": []
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Atrav\u00e9s de bibliotecas compartilhadas \u00e9 poss\u00edvel usar c\u00f3digo desenvolvido em outras linguagens de uma maneira simples.\n",
 "\n",
 "Python -> C\n",
 "-----------\n",
 "O m\u00f3dulo escrito em C deve utilizar as estruturas do Python (que est\u00e3o definidas na API de interface) para se comunicar com o interpretador Python.\n",
 "\n",
 "Exemplo:"
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [
 "// Arquivo: mymodule.c\n",
 "\n",
 "// Python.h define as estruturas do Python em C\n",
 "#include <Python.h>\n",
 "\n",
 "// No Python, mesmo os erros sao objetos\n",
 "static PyObject *MyModuleError;\n",
 "\n",
 "// Chamando a funcao \"system\" em C\n",
 "static PyObject *\n",
 "mymodule_system(PyObject *self, PyObject *args)\n",
 "{\n",
 " const char *command;\n",
 " int sts;\n",
 "\n",
 " // \"PyArg_ParseTuple\" desempacota a tupla de parametros\n",
 " // \"s\" significa que ele deve identificar uma string\n",
 " if (!PyArg_ParseTuple(args, \"s\", &command))\n",
 " // retornando NULL gera uma excessao\n",
 " // caso falte parametros\n",
 " return NULL;\n",
 "\n",
 " // chamando \"system\":\n",
 " sts = system(command);\n",
 "\n",
 " // \"Py_BuildValue\" gera objetos que o Python conhece\n",
 " // \"i\" significa inteiro\n",
 " return Py_BuildValue(\"i\", sts);\n",
 "}\n",
 "\n",
 "// Tabela que o Python consulta para resolver\n",
 "// os metodos do modulo e pode ser usado\n",
 "// tambem para gerar a documentacao\n",
 "// por instrospeccao: dir(), help(),...\n",
 "static PyMethodDef MyModuleMethods[] = {\n",
 " {\"system\", mymodule_system, METH_VARARGS,\n",
 " \"Executa comandos externos.\"},\n",
 " // Fim da tabela:\n",
 " {NULL, NULL, 0, NULL}\n",
 "};\n",
 "\n",
 "// inicializacao do modulo:\n",
 "PyMODINIT_FUNC\n",
 "initmymodule(void)\n",
 "{\n",
 " // O modulo tambem e' um objeto\n",
 " PyObject *m;\n",
 "\n",
 " // \"Py_InitModule\" precisa do nome do modulo e da\n",
 " // tabela de metodos\n",
 " m = Py_InitModule(\"mymodule\", MyModuleMethods);\n",
 "\n",
 " // Erros...\n",
 " MyModuleError = PyErr_NewException(\"mymodule.error\",\n",
 " NULL, NULL);\n",
 "\n",
 " // \"Py_INCREF\" incrementa o numero de referencias do objeto\n",
 " Py_INCREF(MyModuleError);\n",
 "\n",
 " // \"PyModule_AddObject\" adiciona um objeto ao modulo\n",
 " PyModule_AddObject(m, \"error\", MyModuleError);\n",
 "}"
 ],
 "language": "python",
 "metadata": {},
 "outputs": []
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Ao inv\u00e9s de compilar o m\u00f3dulo manualmente, use o Python para automatizar o processo. Primeiro, crie o *script*:"
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [
 "# Arquivo: setup.py\n",
 "\n",
 "from distutils.core import setup, Extension\n",
 "\n",
 "mymodule = Extension('mymodule', sources = ['mymodule.c'])\n",
 "setup(name = 'MyPackage', version = '1.0',\n",
 " description = 'My Package',\n",
 " ext_modules = [mymodule])"
 ],
 "language": "python",
 "metadata": {},
 "outputs": []
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
"E para compilar:\n",
 "\n",
 " python setup.py build\n",
 " \n",
 "O bin\u00e1rio compilado ser\u00e1 gerado dentro da pasta \u201cbuild\u201d. O m\u00f3dulo pode ser usado como qualquer outro m\u00f3dulo no Python (atrav\u00e9s de *import*).\n",
 "\n",
 "C -> Python\n",
 "-----------\n",
 "O inverso tamb\u00e9m \u00e9 poss\u00edvel. Um programa escrito em C pode evocar o interpretador Python seguindo tr\u00eas passos:\n",
 "\n",
 "+ Inicializar o interpretador.\n",
 "+ Interagir (que pode ser feito de diversas formas).\n",
 "+ Finalizar o interpretador.\n",
 "\n",
 "Exemplo:"
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [
 "// Arquivo: py_call.c\n",
 "\n",
 "// Python.h com as definicoes para\n",
 "// interagir com o interpretador\n",
 "#include <Python.h>\n",
 "\n",
 "int main()\n",
 "{\n",
 " // Inicializa interpretador Python\n",
 " Py_Initialize();\n",
 "\n",
 " // Executando codigo Python\n",
 " PyRun_SimpleString(\"import os\\n\"\n",
 " \"for f in os.listdir('.'):\\n\"\n",
 " \" if os.path.isfile(f):\\n\"\n",
 " \" print f, ':', os.path.getsize(f)\\n\");\n",
 "\n",
 " // Finaliza interpretador Python\n",
 " Py_Finalize();\n",
 " return 0;\n",
 "}"
 ],
 "language": "python",
 "metadata": {},
 "outputs": []
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Para compilar, \u00e9 preciso passar a localiza\u00e7\u00e3o das headers e libraries do Python para o compilador C:\n",
 "\n",
 " gcc -I/usr/include/python2.5 \\\n",
 " -L/usr/lib/python2.5/config \\\n",
 " -lpython2.5 -opy_call py_call.c\n",
 "\n",
 "Observa\u00e7\u00f5es:\n",
 "\n",
 "+ Esta API faz parte do CPython (porte do Python escrito em C).\n",
 "+ Existem ferramentas para automatizar o processo para gerar interfaces para sistemas maiores: SWIG, Boost.Python e SIP."
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [],
 "language": "python",
 "metadata": {},
 "outputs": [
 {
 "html": [
 "<style>\n",
 " @font-face {\n",
 " font-family: \"Computer Modern\";\n",
 " src: url('http://mirrors.ctan.org/fonts/cm-unicode/fonts/otf/cmunss.otf');\n",
 " }\n",
 " div.cell{\n",
 " width:800px;\n",
 " margin-left:16% !important;\n",
 " margin-right:auto;\n",
 " }\n",
 " h1 {\n",
 " font-family: Helvetica, serif;\n",
 " }\n",
 " h4{\n",
 " margin-top:12px;\n",
 " margin-bottom: 3px;\n",
 " }\n",
 " div.text_cell_render{\n",
 " font-family: Computer Modern, \"Helvetica Neue\", Arial, Helvetica, Geneva, sans-serif;\n",
 " line-height: 145%;\n",
 " font-size: 130%;\n",
 " width:800px;\n",
 " margin-left:auto;\n",
 " margin-right:auto;\n",
 " }\n",
 " .CodeMirror{\n",
 " font-family: \"Source Code Pro\", source-code-pro,Consolas, monospace;\n",
 " }\n",
 " .note{\n",
 " border-bottom: 1px black dotted;\n",
 " }\n",
 " .prompt{\n",
 " display: None;\n",
 " }\n",
 " .text_cell_render h5 {\n",
 " font-weight: 300;\n",
 " font-size: 16pt;\n",
 " color: #4057A1;\n",
 " font-style: italic;\n",
 " margin-bottom: .5em;\n",
 " margin-top: 0.5em;\n",
 " display: block;\n",
 " }\n",
 " \n",
 " .warning{\n",
 " color: rgb( 240, 20, 20 )\n",
 " } \n",
 "</style>\n",
 "<script>\n",
 " MathJax.Hub.Config({\n",
 " TeX: {\n",
 " extensions: [\"AMSmath.js\"]\n",
 " },\n",
 " tex2jax: {\n",
 " inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\n",
 " displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ]\n",
 " },\n",
 " displayAlign: 'center', // Change this to 'center' to center equations.\n",
 " \"HTML-CSS\": {\n",
 " styles: {'.MathJax_Display': {\"margin\": 4}}\n",
 " }\n",
 " });\n",
 "</script>"
 ],
 "output_type": "pyout",
 "prompt_number": 1,
 "text": [
 "<IPython.core.display.HTML at 0x50f8f98>"
 ]
 }
 ],
 "prompt_number": 1
 }
 ],
 "metadata": {}
 }
 ]
}
ricardoduarte-python-para-desenvolvedores-787fb53/ApendiceG/ApendiceG.ipynb
{
 "metadata": {
 "name": ""
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
 {
 "cells": [
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "[Python para Desenvolvedores](http://ricardoduarte.github.io/python-para-desenvolvedores/#conteudo)\n",
 "===================================\n",
 "2&ordf; edi\u00e7\u00e3o, revisada e ampliada\n",
 "-----------------------------------\n",
 "\n",
 "Ap\u00eandice G: Integra\u00e7\u00e3o com .NET\n",
 "=============================\n",
 "_____________________________\n",
 "[IronPython](http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython) \u00e9 a implementa\u00e7\u00e3o do interpretador Python na linguagem C#. Embora o projeto tenha como objetivo a compatibilidade com CPython, existem algumas diferen\u00e7as entre elas. A principal vantagem do IronPython em rela\u00e7\u00e3o ao CPython \u00e9 a integra\u00e7\u00e3o com componentes baseados no *framework* .NET.\n",
 "\n",
 "![.NET](files/bpypd_diags36.png)\n",
 "\n",
 "O .NET \u00e9 uma infra-estrutura de software criada pela Microsoft para a cria\u00e7\u00e3o e execu\u00e7\u00e3o de aplica\u00e7\u00f5es. A parte principal do .NET \u00e9 o *Common Language Runtime* (CLR), que prov\u00ea uma s\u00e9rie recursos aos programas, como gerenciamento de mem\u00f3ria para as aplica\u00e7\u00f5es. Al\u00e9m disso, h\u00e1 um vasto conjunto de bibliotecas de componentes prontos para uso. As instru\u00e7\u00f5es das linguagens de programa\u00e7\u00e3o s\u00e3o traduzidas para *intermediate language* (IL) reconhecida pelo CLR, permitindo que v\u00e1rias linguagens sejam usadas.\n",
 "\n",
 "Dentro dos recursos dispon\u00edveis no *framework*, existe o *Dynamic Language Runtime* (DLR), que implementa os servi\u00e7os necess\u00e1rios para linguagens din\u00e2micas. O IronPython faz uso desses servi\u00e7os.\n",
 "\n",
 "Para evocar o modo interativo do IronPython:\n",
 "\n",
 " ipy\n",
 "\n",
 "Para executar um programa:\n",
 "\n",
 " ipy prog.py\n",
 "\n",
 "As bibliotecas do CPython podem ser usadas dentro do IronPython, desde que as vers\u00f5es sejam compat\u00edveis.\n",
 "\n",
 "Exemplo:"
 ]
 },
 {
 "cell_type": "code",
 "collapsed": false,
 "input": [
 "import sys\n",
 "\n",
 "# Acrescenta o caminho no PYTHONPATH\n",
 "sys.path.append(r'c:\\python25\\lib')\n",
 "import os\n",
 "print os.listdir('.')"
 ],
 "language": "python",
 "metadata": {},
 "outputs": []
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source":

Teste o Premium para desbloquear

Aproveite todos os benefícios por 3 dias sem pagar! 😉
Já tem cadastro?

Outros materiais