Programação para Advogados AUTORES: DANIEL CHADA E IVAR HARTMANN Apostila 1 GRADUAÇÃO 2015.1 Sumário Programação para Advogados Introdução ..................................................................................................................................................... 3 Módulo 0 - Boas Vindas ..................................................................................................................................... 4 Módulo 1 - Variáveis, Números, Strings (pte. 1) .................................................................................................. 5 Literais �������������.............................................................................................................................. 5 Variáveis ����������.............................................................................................................................. 7 Operadores ��������.............................................................................................................................. 9 Expressões ���������............................................................................................................................ 10 Statements (declarações) ................................................................................................................. 11 Strings ��������������............................................................................................................................ 11 O none ������������............................................................................................................................ 13 Funções úteis: dir(), type(), locals(), globals() ..................................................................... 13 Tipagem dinâmica .......................................................................................................................... 14 Módulo 2 - Tupla, Lista, Indexing e Slicing, Condicionais com if.......................................................................... 15 Estruturas de Dados ........................................................................................................................ 15 Lista e Tupla �����............................................................................................................................ 15 Indexação (indexing) e Recorte (slicing) ............................................................................................. 16 Condicionando a sequência do programa: if, elif, else ........................................................................... 19 Operadores Lógicos: not, or, and ........................................................................................................ 23 Módulo 3 - Funções (pte. 1) .............................................................................................................................. 25 Definindo (‘declarando’): ................................................................................................................. 25 Usando (‘chamando’): ...................................................................................................................... 25 O que é ‘escopo’? ........................................................................................................................... 27 Revendo operadores ......................................................................................................................... 28 A palavra reservada pass ................................................................................................................ 29 Mudando variáveis dentro de um escopo --Pass by Value, Pass by Reference, ** pass-by-object reference ** ....................................... 30 Retornando valores (ou não) ............................................................................................................. 31 Módulo 4 - Iteração com for, range(); a “Sua Amiga a Internet” ....................................................................... 34 Usando range() ........................................................................................................................... 35 Sua Amiga a Internet” ou “Olhe no Stack Overflow Antes!” .................................................................. 36 Módulo 5 - Importação de Módulos, Abrindo e Manipulando Arquivos, Dicionários ........................................... 38 Arquivos - abrindo, e manipulando, de dentro e de fora ....................................................................... 38 Dicionários �������............................................................................................................................ 41 Importando Módulos ....................................................................................................................... 44 Manipulando arquivos em si, não só seu conteúdo (o módulo os) ............................................................ 46 Módulo 6 - Funções (pte. 2); Built-ins: zip, map, reduce, filter; usando lambda; usando *args, **kwargs .............. 47 Valores default em funções ................................................................................................................ 49 Funções anônimas com lambda ........................................................................................................ 51 Parâmetros Variáveis com *args, **kwargs .......................................................................................... 54 Módulo 7 - Strings Avançados ......................................................................................................................... 57 Unicode strings ��............................................................................................................................ 57 Formatação �������............................................................................................................................ 61 Multi-line strings ............................................................................................................................ 63 Enfim ...O porque do “#coding: utf-8” no início dos arquivos! ........................................................ 64 Módulo 8 - Números Binários, Tabelas Verdade, OR, AND, XOR, NAND .................................................................... 65 Operadores Bitwise: not, or, xor, and, nand ........................................................................................ 65 Módulo 9 - Usando APIs Externas ..................................................................................................................... 67 Anexo A - Recursos Online¶.............................................................................................................................. 68 Referências¶.................................................................................................................................................. 69 Programação para Advogados Introdução Esta apostila visa prover resumos do conteúdo visto em sala durante as aulas teóricas da Atividade Complementar ‘Programação para Advogados’. Não se visa que esta seja uma referência completa nem aprofundada de nenhum dos temas abordados em seu texto, mas sim uma introdução amena a certos conceitos de utilidede a alunos de graduação de Direito ou de outros temas de ‘Humanas’. Almeja-se que os temas aqui abordados formem uma base conceitual para posterior aprofundamento tanto na teoria quanto na pratica do desenvolvimento de software. FGV DIREITO RIO 3 Programação para Advogados Módulo 0 - Boas Vindas Bem-vindos Advo* ...programadores! Esta apostila segue o material coberto nas aulas teóricas da ATC “Programação para Advogados”. Teremos exemplos práticos toda semana. O formato desta apostila tem dupla funcionalidade: i. de ser uma referência impressa para acompanhamento e ii. ser um repositório de exemplos de código a serem explorados e editados. Com este fim, escolhemos oferecer não só a versão impressa da apostila, mas também uma versão em iPython Notebook. iPython Notebook é um framework que permite a edição de texto, junto com a execução de código Python, em células auto-contidas. Desta forma é possível executar e editar, no seu próprio computador, os códigos dos exemplos expostos aqui. A homepage do Ipython Notebook contém instruções para instalação para Windows, OSX e Linux. Nosso desejo é que você, leitor e aluno da ATC, use esta funcionalidade para melhor entender o código provido a cada exemplo e tente explorar diferentes aspectos do Python. Boa Sorte! FGV DIREITO RIO 4 Programação para Advogados Módulo 1 - Variáveis, Números, Strings (pte. 1) #### Literais São as expressões e a notação usadas para gerar os valores de tipos built-in como números inteiros, longos (que ocupam mais espaço em memória, mas são maiores), decimais (também conhecidos como floating point ou float), números complexos e strings. Exemplos: 4, 3.2e212, 3.14159, 1+3j,’Ivar’. Estes são chamados literais pois os objetos são literalmente aquilo que representam: 3, “spam”, 7e4 Literais podem ser declarados, ou convertidos (dentro do possível) com operadores (que veremos abaixo) built-in do Python. isto é: In [1]: int(4.5) # gera um inteiro (que geralmente usa até 32 bits de memória) Out[1]: 4 In [2]: str(4.5) # gera uma string Out[2]: “4.5” In [3]: long(4.5e21) # gera um número longo, que tem precisão ilimitada (note o L ao final) FGV DIREITO RIO 5 Programação para Advogados Out[3]: 4500000000000000000000L In [4]: float(3) # gera um decimal, também chamado de ‘ponto flutuante’ (floating point) Out[4]: 3.0 In [5]: bool(4.5) # gera um booleano Out[5]: True In [6]: bool(0.000) # zero é sempre falso no Python Out[6]: False Python permite uma série de outros formatos literais muito úteis na computação e ciência, mas que não cabem no escopo desta apostila, como números complexos (a + b√-1) octais (0-7), hexadecimais (1-9,A-F) e binários (0,1). Veremos binários brevemente em uma das últimas unidades. In [7]: complex(1,3.14159) FGV DIREITO RIO 6 Programação para Advogados Out[7]: (1+3.14159j) In [8]: oct(500) # um zero sempre o precede Out[8]: “0764” In [9]: hex(500) # um ‘0x’ sempre o precede Out[9]: “0x1f4” In [10]: bin(500) # um ‘0b’ sempre o precede Out[10]: “0b111110100” Variáveis Variáveis são nomes que o programador dá a objetos no seu código. Podemos pensar em objetos como espaços de memória alocados no computador. Estes espaços têm diferentes tamanhos e são grandes o suficiente para representar o que quer que cada objeto seja. Um inteiro no Python, por exemplo, geralmente ocupa 32 bits de memória. Assim, uma variável referencia um objeto. Uma referência é um ponteiro, isto é, uma seta que aponta da variável (nome) ao objeto (lugar). Veja a figura 1.1: internamente, a variável aponta para o espaço de memória criado por se executar a expressão (veja o que é uma expressão abaixo) do operador 3. FGV DIREITO RIO 7 Programação para Advogados Variáveis são criadas no momento que você as atribue um valor (tecnicamente algumas são criadas antes disso, mas para nós basta esta definição). Atribuições subsequentes no código mudam o valor da variável (i.e. mudam para onde ela aponta). Variáveis nunca guardam em si nenhum tipo de informação, elas simplesmente se referem a um lugar onde algo fica. [1] Quando uma variável aparece em uma expressão, ela é imediatamente substituída pelo objeto para qual aponta: In [11]: x = 3 # crio o nome ‘x’ e mando ele apontar para o objeto ‘3’ gerado na memória print x # não imprimo ‘x’, e sim o valor para o qual ‘x’ aponta 3 In [12]: y = “Python para advogados é mole!” print y Python para advogados é mole! A nomenclatura de variáveis deve seguir algumas regras: i. o primeiro caractére da variável deve ser uma letra ou o _ (underscore); ii. nomes de variáveis são case-sensitive; iii. nomes de variáveis só podem conter caracréres alfanuméricos ou o underscore (a-z,A-Z,0-9,_) FGV DIREITO RIO 8 Programação para Advogados In [13]: _oi_1 = ‘0’; Oi = 1; oi = ‘2’ # exemplos de variáveis (dica: o ‘;’ funciona igual à quebra de linha: permite um novo comando) print _oi_1, Oi, oi 0 1 2 Operadores Operadores computam algum valor, quando executadas pelo Python. A tabela 1.1 lista todos os operadores do Python, em ordem de precedência. operador x descrição veremos? protocolo de envio de uma função geradora talvez geração de função anônima sim x if y else z seleção ternária talvez x or y ‘ou’ lógico sim x and y ‘e’ lógico sim negação lógica sim x in y; x not in y pertence (iteráveis, conjuntos) sim x is y; x is not y teste de identidade de objeto sim x >,>=,<,<= y compara magnitude, ou sub/super-conjunto sim x == y, x != y igualdade/desigualdade de valores sim x|y ‘ou’ bitwise, união de conjuntos sim x&y ‘e’ bitwise, interseção de conjuntos sim x^y xor bitwise sim x <<,>> y shiftar x, y bits para a esquerda/direita sim x+y adição, concatenação sim x-y subtração, deferença de conjuntos sim xy multiplicação, repetição sim x%y módulo (resto), formatação sim yield lambda not args: expressão x FGV DIREITO RIO 9 Programação para Advogados operador descrição veremos? x /,// y divisão: real e piso sim -x,+x negação, identidade sim ~x ‘não’ bitwise, inversão sim x ** y potênciação sim x[i] indexação (sequências, strings, etc) sim x[i:j:k] recorte (slicing) sim x(...) chamada (função, método, classe, ‘chamáveis’) sim x.attr referência a attr sim (...) tupla, expressão, expressão geradora sim [...] lista, list comprehension sim {...} dicionário sim fonte: tutorialspoint Expressões Expressões são combinações de objetos (literais ou outros) e operadores que computam algum valor, quando executadas pelo Python. Expressões compostas seguem as regras de precedência de operadores. Expressões compostas podem, porém, ser agrupadas por parênteses em subexpressões, ignorando as regras de prioridade normalmente aplicadas aos operadores (veja a Tabela 1.1 e o código abaixo). In [14]: x = 2 + 3 * 4 # o lado direito do igual é uma expressão y = (2 + 3) * 4 # aqui também print x, y 14 20 FGV DIREITO RIO 10 Programação para Advogados Statements (Declarações) Uma statement no Python é qualquer linha de código que o Python consiga interpretar e executar. Expressões podem ser declarações ou parte delas, mas nem toda expressão é uma statement. Essa distinção se tornará mais importante quando estudarmos funções anônimas com o operador lambda e as expressões geradas com ele. Strings Strings são cadeias de caracteres, delimitadas por aspas (simples ou duplas). Strings são literais de enorme utilidade na programação, e vamos usá-los constantemente neste curso. Esta ‘parte 1’ sobre strings expõe o básico do seu funcionamento, para que possamos começar a criá-los e manipulá-los. A primeira característica a mencionar é que strings, no Python, podem ser delimitados por aspas simples ('') ou duplas (""), desde que se mantenha a conformidade, isto é, se abrimos uma string com aspas simples, o Python só entenderá que a string se fechou ao ver a próxima aspa simples. Veja: In [15]: x = (“A”,’A’) # aspas e aspas duplas são a mesma coisa, isto é só uma conveniência print x (“A”, “A”) Strings comportam caracteres especiais e difíceis de digitar com sequências de escape. No Python, toda sequência de escape é iniciada pela ‘barra invertida’ (backslash): \ Sequências de escape são consideradas como um único caractere, apesar de, em geral, serem digitadas com dois (a barra invertida e mais um). As principais sequências de escape são (nova linha), (tab), ' (aspas simples, " (aspas duplas), \\ (a própria barra invertida). Então, se temos uma string definida com aspas duplas ...e precisamos inserir aspas duplas dentro da mesma string, podemos usar a sequencia de escape " que dirá ao Python que esta aspa dupla não deve ser interpretado como o fim da minha string. Uma lista das sequências de escape permitidas pelo Python está no tutorial de strings do site TutorialsPoint: FGV DIREITO RIO 11 Programação para Advogados In [16]: x = ‘o advogado’ y = ‘o advo\ngado’ # a função built-in len() dá o comprimento do objeto passado print x,’:’,len(x) print y,’:’,len(y) # a sequência de escape \” faz com que a aspa dupla # não seja interpretada como delimitador da string! x = “\ndisse\t\”oi\”” print x,’:’,len(x) o advogado : 10 o advo gado : 11 disse “oi” : 11 Strings são iteráveis (como veremos na seção sobre iteração) e implementam diferentes operadores, incluindo concatenação (via o mais, ‘+’), indexação e slicing (com ‘[]’) e repetição (via o operador de multiplicação, ‘*’: In [17]: x = “Dani” + “el” # concatenação com + print x x = ‘oi! ‘ * 3 # repetição com * print x x = “Oi, me chamo Daniel” # slicing com [] print x[0:13] + ‘Felipe’ Daniel oi! oi! oi! Oi, me chamo Felipe Veremos mais sobre estes operadores no módulo sobre listas. FGV DIREITO RIO 12 Programação para Advogados O None O None é uma palavra reservada do Python e uma constante built-in. None implica a ausência de valor. None pode ser usado quando queremos declarar uma variável, mas não lhe dar nenhum valor. Vale ressaltar que None sempre é avaliado como falso (veja o exemplo abaixo). Veremos mais sobre o None na seção sobre funções. In [18]: x = None print x print bool(x) x = 3 print x None False 3 Funções Úteis: dir(), type(), locals(), globals() Existem certas funcionalidades muito úteis no Python, que são disponibilizadas como funções do próprio Python, não atreladas a algum módulo ou objeto. Veremos muitas destas no decorrer desta apostila. Vamos começar explorando quatro: type(x): a função type retorna um objeto type que representa o tipo da variável x em questão (veja a seção tipagem dinâmica para exemplos). dir(x): retorna uma lista dos atributos (variáveis e funções) internos da variável x em questão locals(): retorna uma lista co os nomes de todas as variáveis no escopo local (veremos mais sobre escopo no módulo sobre funções) globals(): retorna uma lista co os nomes de todas as variáveis no escopo global (veremos mais sobre escopo no módulo sobre funções) print é um statement tão utilizado no Python, que os criadores da linguagem não requerem o uso de parênteses para sua chamada (isso mudou no Python 3). Vale notar que o print no Python 2.x não é um operador nem chamada de função. FGV DIREITO RIO 13 Programação para Advogados Tipagem Dinâmica O Python utiliza uma forma de designação de tipos chamada ‘tipagem dinâmica’ (em contraste à ‘tipagem estática’). Isto significa que toda a informação sobre o tipo de ma variável fica guardada com o objeto ao qual ela aponta, não com a própria variável. Veja: In [19]: x = 3 # x é um número print type(x) x = ‘e agora?’ # x é um string print type(x) x = None # x agora é o None! (única coisa no Python que tem o tipo NoneType) print type(x) x = len # x agora é a função len, logo seu tipo é ‘função built-in’ print type(x) x = type # finalmente, x agora é a própria função type, seu tipo então é ‘type’ print x <type “int”> <type “str”> <type “NoneType”> <type “builtin_function_or_method”> <type “type”> Encontramos uma lista dos tipos built-in do Python em python.org FGV DIREITO RIO 14 Programação para Advogados Módulo 2 - Tupla, Lista, Indexing e Slicing, Condicionais com if Estruturas de Dados Uma estrutura de dados é uma forma de se organizar os dados para utilização eficiente. Seja consulta, manipulação ou adição posterior de novos dados de forma rápida, ou até utilizações altamente específicas. Toda linguagem de computação se utiliza de estrutura de dados para alcançar seus fins. O Python (como toda outra linguagem) permite a criação de estruturas de dados por parte do programador. Mas o Python também provê uma série de estruturas genéricas e de forte utilidade. Já vimos uma destas: a string, que é uma forma de se organizar characteres individuais em sequência. Veremos agora duas outras estruturas que também organizam dados de forma sequencial: a lista e a tupla. #### Lista e Tupla A lista é uma das estruturas de dados mais utilizadas no Python, e se define por uma sequência de variáveis, separadas por vírgula e delimitadas por colchetes. Os itens de uma lista podem ser quaisquer variáveis ou objetos do Python, e uma lista não requer que seus elementos sejam uniformes. Veja o código abaixo: In [20]: lista1 = [‘lista’,’de’,’strings’] lista2 = [3.14, ‘heterogeneidade’, ‘de’, type(lista1), ‘valores’, lista1] A tupla é uma sequência imutável de objetos, separados por vírgula e delimitados por parênteses. Esta é a principal diferença entre a lista e a tupla: uma vez criada, seus membros não podem mais ser alterados. Veja o código abaixo: FGV DIREITO RIO 15 Programação para Advogados In [21]: tupla1 = (‘lista1’,lista1,’lista2’,lista2) tupla1[0] = ‘blah!’ # vai dar erro! --------------------------------------------------------TypeError Traceback (most recent call last) <ipython-input-21abd7796095f2> in <module>() 1 tupla1 = (“lista1”,lista1,”lista2”,lista2) ----> 2 tupla1[0] = “blah!” # vai dar erro! TypeError: “tuple” object does not support item assignment O erro indica que um item da tupla não pode ser designado, isto é, após a sua criação, seus itens não podem ser modificados! ...note que colocamos uma lista dentro de uma tupla ..este tipo de composição de objetos e estruturas de dados não só é permitido como pode ser muito útil! Indexação (indexing) e Recorte (slicing) Vimos que listas e tuplas no Python estruturas de dados que permitem guardar coleções de itens, sejam estes variáveis, literais, objetos, funções e até outras listas e tuplas! Estes itens ficam guardados em ordem, na lista ou tupla, e podemos acessá-los via seu índice, isto é sua posição na lista ou tupla. Este índice, por convenção dos criadores do Python (e seguindo a tradição de outras linguagens) sempre começa com o ZERO...vejamos: In [22]: # aqui, Daniel é o segundo item da tupla equipeSen = (‘Ivar’, ‘Daniel’, ‘Felipe’, ‘Pedro’, ‘Bianca’, ‘Luan’, ‘Mariana’) # como todas as coleções em Python começam com índice ZERO, acessamos o SEGUNDO item com o índice 1 print ‘oi!, meu nome é’, equipeSen[1] oi!, meu nome é Daniel FGV DIREITO RIO 16 Programação para Advogados Note que acessamos os itens contido na lista/tupla usando colchetes após o nome da variável que representa a lista/tupla. É assim que indexamos os valores guardados em listas e tuplas. Vale ressaltar que strings também funcionam da mesma forma (podemos pensar neles como listas de caracteres!) In [23]: cidade = ‘Rio de Janeiro’ print cidade[7] J Se quisermos acessar uma sublista dos valores guardados em uma lista ou tupla, podemos vazer um recorte dela: In [24]: lideresSen = equipeSen[0:2] # note que eu defino até o dois para pegar o índice 1, pois o python é indexado em ZERO print lideresSen (“Ivar”, “Daniel”) A indexação pode ser feita da esquerda para a direita, começando do zero, ou da direita para a esquerda, começando do -1. Assim, o último item do objeto iterável (lista, tupla ou string) pode ser acessado pelo seu valor positivo (que podemos pegar com len()) ou pelo número -1 ...vejamos um exemplo: In [25]: ultimoSen = equipeSen[-1] print ultimoSen penultimoSen = equipeSen[-2] print penultimoSen novosSen = equipeSen[-2:] print novosSen Mariana Luan (“Luan”, “Mariana”) FGV DIREITO RIO 17 Programação para Advogados Algumas das principais funções de listas são: In [26]: “””Easter Egg: os primeiros 4 que me mandarem um e-mail explicando corretamente o que estou fazendo na linha abaixo e porque, ganham um chocolate””” SeNList = list(equipeSen) # adiciona um objeto ao final da lista. CUIDADO: se adicionar uma lista, a própria lista, e não seus membros, será adicionada SeNList.append(‘Fabio’) print ‘adicionei mesmo:\n’,SeNList # extend extrai os MEMBROS de uma coleção, e os adiciona ...note que é uma TUPLA sendo passada SeNList.extend((‘Gabriel’, ‘Daniel’)) print ‘\nadicionei os membros da tupla:\n’,SeNList # podemos concatenar listas SeNList = SeNList + [‘Fred’,’Livia’] # podemos repetir seus membros print ‘\nmultiplicando:’,[‘Oi’,’SeN’] * 3 # remove retira o objeto SeNList.remove(‘Pedro’) print ‘\nremovi:\n’,SeNList # acho a posição de um objeto aSair = ‘Fabio’ print ‘\nQual a posição do membro ‘+aSair+’?’,SeNList. index(aSair) # insere o objeto passado na posição x (opcional, default 0) SeNList.insert(-1,’Pedro’) # podemos deletar um objeto de dentro da lista del(SeNList[SeNList.index(aSair)]) # podemos contar? print ‘\nquantos Danieis?’, SeNList.count(‘Daniel’) print ‘\npor fim:’, SeNList FGV DIREITO RIO 18 Programação para Advogados adicionei mesmo: [“Ivar”, “Daniel”, “Felipe”, “Pedro”, “Bianca”, “Luan”, “Mariana”, “Fabio”] adicionei os membros da tupla: [“Ivar”, “Daniel”, “Felipe”, “Pedro”, “Bianca”, “Luan”, “Mariana”, “Fabio”, “Gabriel”, “Daniel”] multiplicando: [“Oi”, “SeN”, “Oi”, “SeN”, “Oi”, “SeN”] removi: [“Ivar”, “Daniel”, “Felipe”, “Bianca”, “Luan”, “Mariana”, “Fabio”, “Gabriel”, “Daniel”, “Fred”, “Livia”] Qual a posição do membro Fabio? 6 quantos Danieis? 2 por fim: [“Ivar”, “Daniel”, “Felipe”, “Bianca”, “Luan”, “Mariana”, “Gabriel”, “Daniel”, “Fred”, “Pedro”, “Livia”] Condicionando a sequência do programa: if, elif, else Vamos mudar o foco agora de estruturas de dados para o fluxo dos nossos programas. Até agora, os nossos programas todos seguem uma sequência lógica única, isto é, executamos um comando por vez, um atrás do outro (A), contudo, podemos usar a estrutura condicional if para que nosso programa possa tomar caminhos alternativos (B) a sintaxe é: if [[condição a ser avaliada]] : <- note o ‘dois pontos’ [[instruções avaliadas...]] [[...se a condição for verdadeira...]] [[...ficam dentro de um novo escopo (com tab)]] ao terminar, retorna-se ao escopo normal, escrevendo instruções sem tab (ou com um tab a menos!) FGV DIREITO RIO 19 Programação para Advogados fig_1.svg Vejam o código abaixo: In [27]: minhalista = [‘Lucas’, 16, ‘RS’] if minhalista[1] < 18: # não esqueçam o ‘dois pontos’! minhalista.append(‘menor de idade’) # notem que uso a função append() para colocar uma nova informação na lista print minhalista [“Lucas”, 16, “RS”, “menor de idade”] Podemos adicionar mais condicionais, com elif e else. Com elif [[nova condicional]]:, podemos encadear condicionais de forma que se a condicional do primeiro if der falso, a condicional do primeiro elif será avaliada. Se esta der falso também, a segunda será avaliada, e assim por diante. Veja o código abaixo: In [28]: genteNaSala = [] # inicio uma lista vazia if ‘Ivar’ in genteNaSala: genteNaSala.extend([‘Luan’,’Gabriel’,’Livia’]) elif ‘Daniel’ in genteNaSala: genteNaSala.extend([‘Mariana’,’Fred’,’Bianca’]) print genteNaSala # como nem o Daniel nem o Ivar estão, a sala fica vazia! [] Aproveite para brincar com os valores iniciais da lista e com as condicionais do if e do elif. O else por sua vez, oferece uma última opção de instruções para o caso que nenhuma das condicionais de true. Seri o caso do senão ...passamos pelo if e quaisquer elifs dizendo “se isso acontecer, ou então se isso acontecer, FGV DIREITO RIO 20 Programação para Advogados ou então se isso acontecer” ...com o else, colocamos um senão ao final, caso nenhuma outra condicional seja preenchida. Vamos ver um exemplo: In [29]: genteNaSala = [] # inicio uma lista vazia if ‘Ivar’ in genteNaSala: # genteNaSala.extend([‘Luan’,’Gabriel’,’Livia’,’Feli pe’]) elif ‘Daniel’ in genteNaSala: genteNaSala.extend([‘Mariana’,’Fred’,’Bianca’,’Feli pe’]) else: genteNaSala.append(‘Felipe’) print genteNaSala # o Felipe está SEMPRE na sala. [“Felipe”] PERGUNTA: Qual a diferença entre usar if? Parece dar no mesmo!¶ elif e encadear condições Boa pergunta! vamos ver qual a diferença... Digamos que eu tenho uma lista dos professores que vão sair para almoçar. Como cada professor tem o seu apelido favorito para o professor Ivar, vamos reeditar a lista com ifs encadeados e com elifs, para ver qual será o apelido utilizado em um dado almoço para o prof. Ivar. FGV DIREITO RIO 21 Programação para Advogados In [30]: # notem que aqui uso uma lista, não uma tupla, pois vou alterar os seus valores! quemAlmoca = [‘Ivar’, ‘Daniel’, ‘Leandro’] if ‘Daniel’ in quemAlmoca: quemAlmoca[0] = ‘Ivair’ # note aqui uma mudança para escopo interno if ‘Leandro’ in quemAlmoca: quemAlmoca[0] = ‘Ivan’ # o else também if ‘Fernando’ in quemAlmoca: quemAlmoca[0] = ‘Ismar’ print quemAlmoca # qual será o nome do Ivar neste almoço?? [“Ivan”, “Daniel”, “Leandro”] ...se usarmos outra lista, vejam: In [31]: quemAlmoca = [‘Ivar’, ‘Daniel’, ‘Leandro’, ‘Fernando’] # mudei a lista! if ‘Daniel’ in quemAlmoca: quemAlmoca[0] = ‘Ivair’ elif ‘Leandro’ in quemAlmoca: # só mudei o if para elif aqui... quemAlmoca[0] = ‘Ivan’ elif ‘Fernando’ in quemAlmoca: # ...e aqui quemAlmoca[0] = ‘Ismar’ print quemAlmoca # qual será o nome do Ivar neste almoço?? [“Ivair”, “Daniel”, “Leandro”, “Fernando”] Os dois exemplos de código mostram a diferença entre usar elif ao invés de encadear ifs. FGV DIREITO RIO 22 Programação para Advogados Operadores Lógicos: not, or, and Os operadores lógicos nos permitem encadear avaliações lógicas. Já sabemos que True e False são literais essenciais à programação e que podemos modificar o curso do nosso programa com condicionais e avaliações lógicas. Com operadores lógicos podemos criar avaliações mais complexas, e de maior utilidade. vejamos: In [32]: idade = 79 sexo = ‘feminino’ hc = “” # posso fazer... if (idade > 65 and sexo == “feminino”): hc = hc + “a senhora, sendo de idade avançada...” elif(idade > 65 and sexo == “masculino”): hc = hc + “o senhor, sendo de idade avançada...” print hc a senhora, sendo de idade avançada... a ordem de avaliação de operadores é: not, and, or not: é usado para inverter a avaliação de uma proposição, se é True o not o tornará falso. and: retorna True somente se ambos os seus operandos forem verdadeiros. or: retorna True se qualquer um ou ambos os operandos foram verdadeiros. No caso do and as proposições são avaliadas da esquerda para a direita, sendo que a primeira que dê False interrompe a avaliação. O caso do or é similar mas oposto: avalia-se da esquerda para a direita, sendo que o primeiro True interrompe a avaliação. Podemos brincar um pouco com essas propriedades: In [33]: x = 25 y = None #lembrem que é igual a falso! z = x or y print z 25 FGV DIREITO RIO 23 Programação para Advogados In [34]: z = x and y print z None In [35]: l = [] s = “” n = None z = l and s and n print z z = l or s or n print z [] None Surerimos que vocês usem a funcionalidade do iPython Notebook para explorar as possibilidade de operadores lógicos, partindo dos exemplos acima. FGV DIREITO RIO 24 Programação para Advogados Módulo 3 - Funções (pte. 1) Funções são blocos de código reutilizável, organizado de forma a ser reutilizado e reduzir a repetição de código. Uma função pode ser vista como uma unidade de código que executa uma única tarefa. O Python disponibiliza uma série de funções ao programador (veja as built-in functions aqui), mas podemos também criar as nossas próprias funções, a fim de organizar, e poder reutilizar o nosso código. Já viemos trabalhando informalmente com funções desde o Módulo 1, porém agora vamos definir mais rigorosamente a sintaxe e funcionamento de uma função: Definindo (‘declarando’): Definimos uma função com a palavra reservada def, seguida do nome que queremos dar à função, depois colocamos quaisquer argumentos que queiramos passar à função entre parênteses (ou deixamos eles vazios). Por fim, usamos dois pontos para fechar a linha de definição e abrir o novo escopo (vide seção abaixo, para a definição de ‘escopo’). In [36]: def foo(): # def <nome da função> <parênteses vazios ou com parâmetros> <dois pontos> # <<instruções aqui>> # <<instruções aqui>> <- note o novo escopo! (veja abaixo) # <<instruções aqui>> pass # posso usar ‘pass’ como placeholder, vamos falar sobre o pass já já Usando (‘chamando’): Após declarar uma função, podemos utilizar o seu código simplesmente chamando a função por nome, e passando quaisquer argumentos que lhe sejam necessários: FGV DIREITO RIO 25 Programação para Advogados In [37]: def mostrar_frase(nome, sobrenome, idade): print ‘Oi, meu nome é’,nome, sobrenome, ‘e tenho’,idade,’anos’ mostrar_frase(‘Daniel’,’Chada’,’34’) mostrar_frase(‘Ivar’,’Hartmann’,’28’) mostrar_frase(‘Felipe’,’Silva’,’25’) Oi, meu nome é Daniel Chada e tenho 34 anos Oi, meu nome é Ivar Hartmann e tenho 28 anos Oi, meu nome é Felipe Silva e tenho 25 anos Aqui passamos os argumentos ‘nome’ e ‘idade’ a cada vez que chamamos a função mostrar_frase. Como mostrar_frase foi definida para receber dois parâmetros, que dentro dela são chamados pelos nomes nome e idade se a chamarmos sem passar os argumentos necessários, receberemos um erro! In [38]: mostrar_frase(‘Mari’) # uh oh! falta argumento! -------------------------------------------------------TypeError Traceback (most recent call last) <ipython-input-38a5ee942457ef> in <module>() ----> 1 mostrar_frase(“Mari”) # uh oh! falta argumento! TypeError: mostrar_frase() takes exactly 3 arguments (1 given) Além de passarmos os argumentos definidos utilizando a ordem (no caso de mostrar_frase ‘nome’ em primeiro, depois ‘idade’) também podemos passar argumentos ‘dando nome aos bois’. Isso se chamar usar keyword arguments ...vejamos FGV DIREITO RIO 26 Programação para Advogados In [39]: mostrar_frase(idade=’25’,nome=’Mari’, sobrenome=’Bedran’) Oi, meu nome é Mari Bedran e tenho 25 anos Mas cuidado, uma vez que começamos a nomear, não podemos voltar a utilizar a ordenação (até porque o Python não saberia poe onde recomeçar). In [40]: mostrar_frase(idade=’25’, ‘Mari’, ‘Bedran’) # po Mari, para de quebrar o Python! File “<ipython-input-40-164c6b628553>”, line 1 mostrar_frase(idade=”25”, “Mari”, “Bedran”) # po Mari, para de quebrar o Python! SyntaxError: non-keyword arg after keyword arg O que é ‘escopo’? Vimos anteriormente que variáveis são somente nomes dados a objetos, isto é, tags que damos a objetos e referenciam os objetos para nós. Porém, nem toda referência que fazemos fica válida por todo o decorrer do nosso programa. Uma definição intuitiva de escopo é a parte, ou subseção do nosso programa em que certas junções nome-->objeto se mantém válidas. Variáveis declaradas dentro de um determinado escopo em geral não se mantém válidas uma vez que o processamento daquele escopo termina. O Python tem regras muito bem definidas de escopo, que são fáceis de lembrar via o mnemonico: LEGB:* Local, Enclosing, Global, Built-in*. -Local: nomes de variável definidos dentro da função na qual estamos trabalhando -Enclosing: nomes de variável definidos na função que cerca o atual escopo local (no caso de aninhamento de funções, ou funções lambda que veremos -Global: o escopo global do arquivo .py em que estamos trabalhando -Built-in: nativas ao Python, acessíveis de qualquer programa Python FGV DIREITO RIO 27 Programação para Advogados In [41]: # CUIDADO COM O ESCOPO LOCAL! var = ‘foo’ def ex1(): var = ‘bar’ print ‘dentro temos’, var ex1() print ‘fora temos’, var dentro temos bar fora temos foo Este blog post: http://www.saltycrane.com/blog/2008/01/python-variable-scope-notes/ contém um ótimo tutorial sobre escopo no Python. Revendo operadores Agora que já conhecemos o suficiente sobre funções, podemos revelar a verdade! (TAM TAM TAAAAAM!) Os operadores no Python são o que chamamos de “açúcar sintático” (syntactic sugar) ...eles são atalhos: formas mais rápidas e fáceis de digitar coisas que na realidade, têm outro nome. o operador ‘+’ para números, na realidade pega o objeto referenciado pelo primeiro número e chama a sue função interna __add__(), passando o segundo número Já o operador ‘*’ chama a função __mul__(). ...veja: In [42]: x = 3 y = x.__add__(4) z = y.__mul__(x) print x, y print z 3 7 21 FGV DIREITO RIO 28 Programação para Advogados Listas, tuplas e strings, ao usar operadores, também usam syntactic sugar: In [43]: l = [‘syntactic’,’sugar’] print l.__getitem__(1) print l.__getitem__(1) == l[1] l.__setitem__(0,’salt’) print l sugar True [“salt”, “sugar”] Podemos dizer que quase tudo no Python se reverte a executar alguma função. A palavra reservada pass A palavra reservada pass no Python é uma operação nula (como multiplicar por 1). Ela é útil como preenchimento quando algum comando é necessário sintaticamente mas não temos código para executar naquele lugar. In [44]: def foo(): pass # não dá erro como daria se só continuassemos o código print ‘123’ 123 FGV DIREITO RIO 29 Programação para Advogados Mudando variáveis dentro de um escopo --- Pass by Value, Pass by Reference, ** pass-by-object reference ** Para literais, Python usa pass-by-value , enquanto para estruturas de dados, pass-by-reference ...vejamos as diferenç Em pass-by-value, passamos o valor, isto é, o lugar onde o objeto está guardado. Em pass-by-reference passamos, como o nome implica, a referência, isto é, o ponteiro que aonte para onde o objeto está. A diferença deve ficar mais clara nos exemplos abaixo In [45]: # pass-by-value def ex1(nome_interno): print ‘primeiro dentro temos’,nome_interno var = ‘bar’ print ‘depois temos’, nome_interno var = ‘foo’ ex1(var) print ‘fora temos’, var primeiro dentro temos foo depois temos foo fora temos foo FGV DIREITO RIO 30 Programação para Advogados In [46]: # exemplo de pass-by-reference def ex2(aqui_dentro_chamo_disso): print ‘aqui temos’,aqui_dentro_chamo_disso aqui_dentro_chamo_disso[1] = ‘ih, mudou?’ print ‘depois temos’, aqui_dentro_chamo_disso var = [‘foo’,’bar’] ex2(var) print ‘e aqui fora’,var aqui temos [“foo”, “bar”] depois temos [“foo”, “ih, mudou?”] e aqui fora [“foo”, “ih, mudou?”] Este comportamento do Python, na literatura, o define como nem pass-by-value nem pass-by-reference ..mas omo *pass-by-object-reference. No fundo não importa muito o que se chama, desde que os conceitos estejam sólidamente compreendidos. Este link pode ajudar, e este também Retornando valores (ou não) A palavra-chave return imediatamente finaliza a execução de código dentro de qualquer função e efetua a saída do escopo vigente. Isto é, o return termina e retorna ao escopo externo (de onde se chamou a função) o valor que o sucede. Um return sem nada em sua frente implica em retornar None. por default a finalização de qualquer função, sem o uso da palavra-chave return tem o mesmo efeito que return None vejamos exemplos: FGV DIREITO RIO 31 Programação para Advogados In [47]: def eh_string(input): if isinstance(input, str): # caso seja uma string, não preciso continuar com a função return True elif input: print ‘\t...not empty, not False, not None, but not a string!’ return False elif input is None: print ‘\t...recebi um None.’ return False print ‘\t...recebi algo, mas conta como falso.’ return False x = eh_string(None) y = eh_string(“oi!”) z = eh_string(21234) w = eh_string(()) # veremos mais sobre o que é False e o que é True em breve! print x,y,z,w ...recebi um None. ...not empty, not False, not None, but not a string! ...recebi algo, mas conta como falso. False True False False Veja que a execução pára quando se chega a um return. vejamos outro exemplo: FGV DIREITO RIO 32 Programação para Advogados In [48]: def find_x(input): for item in input: if item == ‘x’: return True print ‘cheguei ao fim e nada...nada de xiiiiiis!!!’ return False print find_x([123,’Daniel’,’x’,’Ivar’]) print ‘\nsegunda tentativa:’ print find_x([123,’Daniel’,’y’,’Ivar’]) True segunda tentativa: cheguei ao fim e nada...nada de xiiiiiis!!! False FGV DIREITO RIO 33 Programação para Advogados Módulo 4 - Iteração com for, range(); a “Sua Amiga a Internet” O loop for: O loop for nos permite iterar uma série de comandos e funções, sem precisar repeti-los seguidamente. Isto é uma ferramenta tremendamente útil em qualquer tarefa repetitiva, especialmente em tarefas que não sabemos quantas vezes teremos que repetir um dado grupo de comandos. O loop for introduz uma nova possibilidade no caminho do nosso programa, em que voltamos e repetimos um dado conjunto de comandos. Veja a fig_2. A sintaxe de um loop for é: for [[nome de uma ou mais variáveis que serão iteradas]] in [[coleção iterável]]: [[instruções em um novo escopo interno aqui]] [[instruções em um novo escopo interno aqui]] [[instruções em um novo escopo interno aqui]] [[instruções sem tab indicam a volta saída do escopo do for]] Vejamos na prática: In [49]: equipeSen = (‘Ivar’, ‘Daniel’, ‘Felipe’, ‘Pedro’, ‘Mariana’, ‘Bianca’, ‘Luan’, ‘Gabriel’, ‘Livia’) for y in equipeSen: print ‘oi, ‘+ y oi, Ivar oi, Daniel oi, Felipe oi, Pedro oi, Mariana oi, Bianca oi, Luan oi, Gabriel oi, Livia FGV DIREITO RIO 34 Programação para Advogados Usando range() a função range() é uma função built-in do Python (como a len(), locals() ou str()) que retorna uma lista de numeros, em sequência: In [50]: print range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] A função range() pode ser usada para listar números de um certo x a um certo y, ou até pular certos intervalos: In [51]: print range(3,15) # a função range cria uma lista de 3 a 14 e a retorna como entrada da função print. print range(3,15,3) # ‘imprima do 2 ao 15 (parando um antes), com intervalo de 3’ [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] [3, 6, 9, 12] O principal uso da função range() é em conjunto à iteração com um loop (e a função len()) for FGV DIREITO RIO 35 Programação para Advogados In [52]: SeNDev = [‘Daniel’, “Felipe”, “Mariana”] SeNJur = [‘Ivar’, ‘Livia’, ‘Gabriel’, ‘Bianca’, ‘Luan’] def digaOi(x): # posso usar o range() em conjunto com len() se não sei o tamanho for i in range(len(x)): # note que o for tem seu próprio escopo! print ‘oi, ‘ + x[i] +”!”, # para que serve este print? tente comentá’-lo! print ‘’ digaOi(SeNDev) digaOi(SeNJur) oi, Daniel! oi, Felipe! oi, Mariana! oi, Ivar! oi, Livia! oi, Gabriel! oi, Bianca! oi, Luan! Sua Amiga a Internet” ou “Olhe no Stack Overflow Antes!” Python é uma linguagem muito rica, com uma extensa comunidade de desenvolvedores do mundo todo que contribuem para o seu desenvolvimento. Enquanto alguns contribuem para o desenvolvimento do core da linguagem, outros contribuem escrevendo módulos e disponibilizando-os gratuitamente na internet. Assim, existe uma enorme quantidade de ferramentas prontas em python, na forma de módulos que podem ser baixados e instalados no seu python local. Quase nenhum projeto no Python precisa ser iniciado do zero. Com um pouco de pesquisa na internet, vocês provavelmetne encontrarão algum módulo ou pedaço de código que já resolve alguma parte do problema que você tem a reselver. Recomendamos que vocês utilizem o site http://stackoverflow.com e leiam a documentação oficial da linguagem python http://bit.ly/Pe9lfA. O Stack Overflow é um repositório de dúvidas e respostas sobre todas as linguagens e áreas da programação (não só Python!), mas tudo é identificado via tags, e todos os membros (tanto os que perguntam quanto os que responFGV DIREITO RIO 36 Programação para Advogados dem) prezam pela clareza e legibilidade, fazendo do site uma ótima primeira instância para pesquisa sobre qualquer dúvida. O site oficial do Python http://python.org e a documentação do Python http://python.org/doc são as referências oficiais sobre o core da linguagem. Finalmente, na data de escrita desta apostila - v1.0 (Set/2014) o site Tutorials Point http://www.tutorialspoint.com/python/ oferece bons e rápidos tutoriais sobre diferentes aspectos do Python. FGV DIREITO RIO 37 Programação para Advogados Módulo 5 - Importação de Módulos, Abrindo e Manipulando Arquivos, Dicionários Neste módulo vamos ver as duas últimas estruturas de dados do conjunto fundamental provido pelo python. Nós vimos números, strings, listas e tuplas ...hoje veremos arquivos e dicionários. Veremos também como importar módulos, para utilizar código criado por outros dentro de nossos programas Arquivos - abrindo, e manipulando, de dentro e de fora Arquivos são outra estrutura de dados importantíssima para o programador Python. Tudo que se manipula como usuário de computador toma a forma de um arquivo: imagens, PDFs, planilhas e até outros programas. De fato, todos os dados que ficam guardados em um computador de forma permanente (isto é, no disco e não na memória) tomam a forma de arquivos. Até os próprios sistemas operacionais (Windows, Linux, OSX, etc) são coleções de arquivos que ficam guardados no disco rígido (hard disk, HD) são carregados quando ocomputador se inicia. O Acesso e manipulação de arquivos permitem ao nossos programas interagir com bases de dados, imagens e outros até programas no computador. Em Python abrimos arquivos com a chamada open que retorna um objeto arquivo. meu_arq = open([[nome do arquivo]], [[modo]]) Outro modo de abertura de arquivo (ntem que inicializa um novo escopo!) é: with open([[nome do arquivo]], [[modo]]) as meu_arq: [[expressões em novo escopo]][[expressões em novo escopo]] [[expressões em novo escopo]] O parâmero modo lida com o que será feito com o arquivo, a tabela 5.1 lista os principais parâmetros que podem ser passados. Se nada for passado, o arquivo é aberto para leitura, isto é, o default é ‘r’: FGV DIREITO RIO 38 Programação para Advogados Modes Description r Opens a file for reading only. The file pointer is placed at the beginning of the file. This is the default mode. rb Opens a file for reading only in binary format. The file pointer is placed at the beginning of the file. This is the default mode. r+ Opens a file for both reading and writing. The file pointer will be at the beginning of the file. rb+ Opens a file for both reading and writing in binary format. The file pointer will be at the beginning of the file. w Opens a file for writing only. Overwrites the file if the file exists. If the file does not exist, creates a new file for writing. wb Opens a file for writing only in binary format. Overwrites the file if the file exists. If the file does not exist, creates a new file for writing. w+ Opens a file for both writing and reading. Overwrites the existing file if the file exists. If the file does not exist, creates a new file for reading and writing. wb+ Opens a file for both writing and reading in binary format. Overwrites the existing file if the file exists. If the file does not exist, creates a new file for reading and writing. a Opens a file for appending. The file pointer is at the end of the file if the file exists. That is, the file is in the append mode. If the file does not exist, it creates a new file for writing. ab Opens a file for appending in binary format. The file pointer is at the end of the file if the file exists. That is, the file is in the append mode. If the file does not exist, it creates a new file for writing. a+ Opens a file for both appending and reading. The file pointer is at the end of the file if the file exists. The file opens in the append mode. If the file does not exist, it creates a new file for reading and writing. ab+ Opens a file for both appending and reading in binary format. The file pointer is at the end of the file if the file exists. The file opens in the append mode. If the file does not exist, it creates a new file for reading and writing. fonte: http://www.tutorialspoint.com/python/python_files_io.htm In [53]: f = open(‘arq.csv’,’r+’) # neste exemplo, o arquivo deve estar na mesma pasta do programa sendo rodado # a função ‘open’ retorna um objeto tipo arquivo print f print type(f) FGV DIREITO RIO 39 Programação para Advogados <open file “arq.csv”, mode “r+” at 0x103e67930> <type “file”> Uma vez ‘abertos’, podemos usar as funções dos objetos arquivo para manipular o conteúdo dos arquivos, os exemplos abaixo mostram as principais funções para manipular o conteúdo de arquivos: In [54]: f = open(‘arq.csv’,’r’) # read() le e retorna o conteudo inteiro do arquivo ..se o arquivo for maior que a memória utilizável, corta a leitura # podemos também passar um número, que será o número de bytes a serem lidos do arquivo. x = f.read() print x f.close() Ivar,28,Harvard Daniel,34,PUC Felipe,24,FGV In [55]: f = open(‘novoarq.csv’,’w+’) x = ‘Mariana,25,UFF’ # write() (sobre)escreve o conteudo da variável passada para o arquivo. Não retorna nada. nada = f.write(x) print nada f.close() None FGV DIREITO RIO 40 Programação para Advogados Quando um arquivo é aberto para leiura, o Python aponta um ‘pointeiro de arquivo’ (eu chamo de ‘cursor’) para o conteúdo do arquivo. À medida que lemos ou editamos o conteúdo do arquivo, este ‘cursor’ é movido para a frente (ou para trás). Cada função de leitura ou escrita move o ‘cursor’ para frente, de forma que uma leitura (ou escrita) subsequente retornará outro resultado. Dependendo do modo utilizado ao abrir o arquivo, podemos já abri-lo com o cursor apontando para o final (modo ‘a’) Outras funções de escrita e leitura de arquivo são: readline() – retorna uma linha do arquivo, e passa o cursor para a próxima linha readlines() – devolve lista em que cada item é uma linha writelines() – recebe uma lista ou tupla ou iterável e cada item será inserido como se chamando writeline() f.tell() – retorna em que parte do arquivo o cursor parou f.seek(from, offset) – muda o cursor do from (0 pega do começo do arquivo, 1 usa a posição atual e 2 usa o final do arquivo como referência ..o default é 0) e avança tantos bytes quanto indicado no offset Encorajamos o leitor a explorar a manipulação dos dados de arquivos com estas funções, e buscar mais aprofundadamente sobre seu funcionamento na seção sobre arquivos da python.org Dicionários Dicionários trazem uma nova forma de guardar coleções de dados/objetos. Listas e tuplas nos dão uma forma ordinal de guardar dados, e podemos acessálos pela sua posição na ordem (i.e. nomes[3] retorna o segundo item da lista nomes). Já dicionários indexam seus valores de outra forma: por chaves. Ao invés de utilizar ordem, o dicionário usa uma função chamad função hash para decidir onde melhor colocar cada novo item que é adicionado. Isso torna o seu tempo de resposta muito mais rápido ao localizar um valor associado a uma chave. Há algumas restrições no que é passível de ser uma chave (quem quiser estudar mais as premissas, pode ler em https://wiki.python.org/moin/DictionaryKeys) mas aqui explicitamos que números, tuplas e strings podem ser chaves, enquanto listas não podem. Note que isso não implica o que pode ser guardado como valor, qualquer variável ou objeto pode ser guardado em um dicionário, até funções inteiras e módulos ...somente a chave tem restrições. Definimos dicionários com: {} e acessamos seus itens da mesma forma que listas: FGV DIREITO RIO 41 Programação para Advogados In [56]: x = { ‘Ivar’ : [27,’Nova Hamburgo’, ‘Inter’], ‘Daniel’ : [34, ‘Rio de Janeiro’, ‘Flamengo’] } # podemos adicionar valores aos dicionários, eles são *mutáveis* x[‘Felipe’] = [24, ‘Matrix’, ‘C’] print x[‘Felipe’] print x[‘Ivan’] # notem que dá erro, o Python nos diz que não existe a chave ‘Ivan’ [24, “Matrix”, “C”] --------------------------------------------------------KeyError Traceback (most recent call last) <ipython-input-56bc4cee0fac11> in <module>() 9 print x[“Felipe”] 10 ---> 11 print x[“Ivan”] # notem que dá erro, o Python nos diz que não existe a chave “Ivan” 12 KeyError: “Ivan” Como em todas as estruturas que guardam múltiplos dados, podemos guardar outros dicionários dentro de dicionários: FGV DIREITO RIO 42 Programação para Advogados In [57]: x = { ‘Ivar’ : {‘idade’:28,’cidade’:’Nova Hamburgo’, ‘time’:’Inter’, ‘lingua’:’Legagese’} , ‘Daniel’ : {‘idade’:float(‘Inf’), ‘cidade’:’Barad Dur’, ‘lingua’:’Black Speech’, ‘time’:’Mordor’} , ‘Felipe’ : {‘cidade’:’Xion’, ‘time’:’Morpheus’, ‘idade’:float(‘NaN’) , ‘lingua’:’CUDA’} } print x[‘Felipe’][‘time’] print x[‘Daniel’][‘idade’] # professores malvados são eternos! # PS: quem consegue explicar a minha idade e a do Felipe?? Morpheus inf Dicionários têm funções muito úteis, a saber: In [58]: # a função get() evita que o erro anterior aconteça, retornando None quando a chave não é encontrada print x.get(‘Ivar’) # para obter todas as chaves do dicionário, usamos keys(), que retorna uma lista print ‘\nKEYS:\t’,x.keys() # para obter os valores, a função values(), que retorna uma lista print ‘\nVALUES:\t’,x.values() # já a função items() retorna uma lista de tuplas na forma (chave,valor) print ‘\nITEMS:\t’,x.items() FGV DIREITO RIO 43 Programação para Advogados {“idade”: 28, “cidade”: “Nova Hamburgo”, “lingua”: “Legagese”, “time”: “Inter”} KEYS: [“Felipe”, “Daniel”, “Ivar”] VALUES: [{“idade”: nan, “cidade”: “Xion”, “lingua”: “CUDA”, “time”: “Morpheus”}, {“idade”: inf, “cidade”: “Barad Dur”, “lingua”: “Black Speech”, “time”: “Mordor”}, {“idade”: 28, “cidade”: “Nova Hamburgo”, “lingua”: “Legagese”, “time”: “Inter”}] ITEMS: [(“Felipe”, {“idade”: nan, “cidade”: “Xion”, “lingua”: “CUDA”, “time”: “Morpheus”}), (“Daniel”, {“idade”: inf, “cidade”: “Barad Dur”, “lingua”: “Black Speech”, “time”: “Mordor”}), (“Ivar”, {“idade”: 28, “cidade”: “Nova Hamburgo”, “lingua”: “Legagese”, “time”: “Inter”})] Vale notar que o print das chaves e valores não é nem alfabético, nem em função da ordem da adição dos registros, mas sim de acordo com a função hash mencionada. Estas listas retornadas pelas funções permitem iterar as chaves, os valores, ou AMBOS com loops. Os dicionários em si, porém, não são iteráveis (uma explicação básica seria que eles não têm ordenação intrínseca, como as listas e as tuplas). Importando Módulos Modulos são a forma de importar código de outros programas seus e de outros para dentro do seu programa. Nós importamos módulos para usar funcionalidades já programados (por nós mesmos ou outros) dentro do nosso código, sem re-escrever. o jeito de importar módulos é: In [59]: import sys # importando o módulo inteiro from glob import glob # importando uma função específica de um módulo from math import * # importando todas as funções do módulo para o escopo local FGV DIREITO RIO 44 Programação para Advogados FAQ: Qual é a diferença entre importar o módulo todo e importar todas as funções com o asterisco? Ao importar um módulo inteiro usando só o comando import, importa-se o módulo como um objeto, e as funções do módulo ficam acessíveis via este objeto: In [60]: # um detalhe: posso renomear o módulo ao importar, para facilitar a sua chamada! import os as o print o.getcwd() # getcwd() foi importada como função do objeto ‘os’! from math import sqrt, pi print sqrt(pi) # note que não preciso usar ‘math<ponto>’! /Users/cyg/Documents/work/code/atc_2014 1.77245385091 In [61]: # mas cuidado! from math import * # aqui eu redefino a variavel ‘pi’ importada antes do math, e perco a original! pi = ‘principal investigação’ print pi # já aqui, não corro este risco, pois fica como parte do módulo! import math print pi, math.pi principal investigação principal investigação 3.14159265359 FGV DIREITO RIO 45 Programação para Advogados Manipulando arquivos em si, não só seu conteúdo (o módulo os) Já vimos como manipular o conteúdo de arquivos, e como trazer código Python externo na forma de módulo para dentro do nosso próprio código. Agora usaremos um módulo do Python para manipular arquivos e diretórios (‘pastas’ para os que falam Windows®) Import os .mkdir() – make directory .chdir() – change directory .getcwd() – get current working directory .remove() .rename(a,b) .rmdir() – remove directory FGV DIREITO RIO 46 Programação para Advogados Módulo 6 - Funções (pte. 2); Built-ins: zip, map, reduce, filter; usando lambda; usando *args, **kwargs Outras Funcões Built-in Vamos agora continuar a ver funções built-in úteis no dia-a-dia da programação Python. Uma lista completa pode ser encontrada aqui. a função map recebe um objeto função e um objeto iterável (i.e. uma sequência...tupla, lista, string, etc) e aplica a função a cada membro do iterável, um de cada vez, coletando os resultados em uma lista. veja: In [62]: equipe = (‘Ivar’,’Felipe’, ‘Daniel’, ‘Mariana’, ‘Fred’, ‘Luan’) # passo a função len e a minha tupla tamanhos_de_cada = map(len, equipe) print tamanhos_de_cada [4, 6, 6, 7, 4, 4] A função zip retorna uma lista de tuplas, onde a n-ésima tupla contém os n-ésimos itens de cada iterável passado para ela: FGV DIREITO RIO 47 Programação para Advogados In [63]: idades = [28, float(‘NaN’), float(‘Inf’), 25, 22, 22] # passo dois iteráveis agrupados = zip(equipe,idades) print ‘agrupados:\t’, agrupados abc = ‘abcdefghijklmnopqrstuvwxyz’ # agora um terceiro, note o que acontece quando os tamanhos são # diferentes e quando os itens JÁ SÃO iteráveis em si agrup = zip(agrupados, abc) print ‘\nnovo agrup:\t’,agrup # posso DESAGRUPAR com o ‘*’: desagrup = zip(*agrupados) print ‘\ndesagrup:\t’,desagrup # assim... final = zip(zip(*agrupados)[0],zip(*agrupados)[1],abc) print ‘\nfinal:\t’,final # qual a diferença entre ‘final’ e ‘novo agrup’?? agrupados:[(“Ivar”, 28), (“Felipe”, nan), (“Daniel”, inf), (“Mariana”, 25), (“Fred”, 22), (“Luan”, 22)] novo agrup: [((“Ivar”, 28), “a”), ((“Felipe”, nan), “b”), ((“Daniel”, inf), “c”), ((“Mariana”, 25), “d”), ((“Fred”, 22), “e”), ((“Luan”, 22), “f”)] desagrup: [(“Ivar”, “Felipe”, “Daniel”, “Mariana”, “Fred”, “Luan”), (28, nan, inf, 25, 22, 22)] final: [(“Ivar”, 28, “a”), (“Felipe”, nan, “b”), (“Daniel”, inf, “c”), (“Mariana”, 25, “d”), (“Fred”, 22, “e”), (“Luan”, 22, “f”)] reduce aplica uma função que recebe dois valores e retorna um a um iterável, cada vez pegando o resultado da iteração anterior omo primeiro parâmetro: FGV DIREITO RIO 48 Programação para Advogados In [64]: def add(x,y): return x+y print reduce(add, [2,4,6,8]) 20 filter recebe uma função que retorna True ou False e um iterável. Constrói uma lista com os membros do iterável para os quais a função responde True In [65]: CUT_OFF = 5 def maior(x): return x >= CUT_OFF = filter(maior,tamanhos_de_cada) print y que(x): return x[0] >= CUT_OFF y def maior_ # agora posso fazer algo mais desafiador... o que estou fazendo aqui?? print zip(*filter(maior_que, zip(tamanhos_de_cada, equipe))) [1] #seja um dos 5 primeiros e um email explicando com o subject [explicação do filter] [6, 6, 7] (“Felipe”, “Daniel”, “Mariana”) Valores default em funções O Python permite que argumentos de funções tenham valores default, de forma que, se nada for passado naquele parametro, a função provê um valor pre-definido ao invés de dar erro. Em código: In [66]: def meu_time(nome, time=’Mordor’): torce por ‘ + time return nome + ‘ print meu_time(‘Ivar’,’Inter’) # na ausência do valor, vai o default print meu_time(‘Daniel’) Ivar torce por Inter Daniel torce por Mordor FGV DIREITO RIO 49 Programação para Advogados Cuidado que passar None ainda é passar alguma coisa: In [67]: print meu_time(‘Felipe’, None) # uh oh! --------------------------------------------------------TypeError Traceback (most recent call last) <ipython-input-67-387ca642fad3> in <module>() ----> 1 print meu_time(“Felipe”, None) # uh oh! <ipython-input-66-c198612e6fc7> in meu_time(nome, time) 1 def meu_time(nome, time=”Mordor”): ----> 2 return nome + “ torce por “ + time 3 4 print meu_time(“Ivar”,”Inter”) 5 # na ausência do valor, vai o default TypeError: cannot concatenate “str” and “NoneType” objects IMPORTANTE: É um erro comum utilizar um objeto mutável como valor default. Lembra, de pass-by-value, pass-by-reference? Vejamos um exemplo: In [68]: def bad_append(new_item, a_list=[]): a_list.append(new_item) return a_list print bad_append(‘one’) print bad_append(‘two’) [“one”] [“one”, “two”] FGV DIREITO RIO 50 Programação para Advogados Uh oh! Por que que o ‘one’ ainda está lá?! O problema é que o valor default, isto é, a lista vazia, é definida na declaração da função, e para sempre aponta para o mesmo objeto default, ou seja, o mesmo lugar na memória ...que é modificado! A forma correta de se criar uma lista (ou dicionário, ou qualquer objeto mutável) default é criá-lo durante a execução ...dentro de função. In [69]: def good_append(new_item, a_list=None): if a_list is None: a_list = [] a_list.append(new_item) return a_list print good_append(‘one’) print good_append(‘two’) [“one”] [“two”] Funções anônimas com lambda Há casos em que podemos querer aplicar uma expressão a uma coleção de objetos. Ou usar uma função simples apenas uma vez. Para estes casos, existe o operador lambda. Podemos usar o operador lambda para criar funções pequenas anônimas. Estas funções são chamadas anônimas pois não precisam de um def e um nome de chamada, isto é, não precisam ser declaradas na forma padrão. Expressões lambda podem aceitar qualquer quntidade de argumentos (como funções) mas devem conter apenas uma única expressão. Elas não podem aceitar statements ou múltiplas expressões. Aqui se torna importante que uma chamada print não se qualifica como uma expressão, e sim um statement mais abrangente; logo, chamadas print não são permitidas dentro de lambda. An anonymous function cannot be a direct call to print because lambda requires an expression. funções lambda têm seus próprios escopos internos, mas conseguem acessar variáveis da função ou escopo que a chama. FGV DIREITO RIO 51 Programação para Advogados Vamos ver um exemplo: In [70]: li = [‘Ivar’,’Daniel’,’Felipe’] # ao invés de definir uma função só para chamar dentro # do meu map ou fazer um for loop, uso uma função anônima quad = map(lambda inp: inp + ‘ ama Python’, li) quad Out[70]: [“Ivar ama Python”, “Daniel ama Python”, “Felipe ama Python”] IMPORTANTE: É necessário tomar cuidado ao usar lambda e def dentro de loops for. Este cuidado é necessário pois, se a função aninhada referencia algum valor que é modificado pelo loop, a regra de escopo dita que este será modificado e os ponteiros (isto é, as variáveis) criados acabarão por apontar ao valor final do loop. Vejamos: In [71]: def make(): items = [] for i in [‘Ivar’,’Daniel’,’Felipe’,’Mari’]: # cada item é um FUNÇÃO criada com lambda items.append(lambda x: i + x) return items # populei uma lista onde cada item é uma ***FUNÇÃO*** functions = make() # note... functions[0] # mas agora ao chamar as funções... FGV DIREITO RIO 52 Programação para Advogados Out[71]: <function __main__.<lambda>> In [72]: # esta deve me dar ‘Ivar ama python’ functions[0](‘ ama Python’) Out[72]: “Mari ama Python” In [73]: # esta deve me dar ‘Daniel ama C’ functions[1](‘ ama C’) Out[73]: “Mari ama C” In [74]: # esta deve me dar ‘Felipe ama LISP’ functions[2](‘ ama LISP’) Out[74]: “Mari ama LISP” Mas todas só se lembram do último i que foi criado no for, pois este fica no escopo externo e foi modificado lá. Para reslver este problema, podemos usar um valor default, como vimos acima: FGV DIREITO RIO 53 Programação para Advogados In [75]: def make(): items = [] for i in [‘Ivar’,’Daniel’,’Felipe’,’Mari’]: # cada item é um FUNÇÃO criada com lambda # # só que agora i é passado para dentro do # lambda como valor default, e existe lá dentro!! items.append(lambda x, i=i: i + x) return items # populei uma lista onde cada item é uma ***FUNÇÃO*** functions = make() # agora ao chamar as funções... functions[0](‘ ama Python’), functions[1](‘ ama C’), functions[2](‘ ama LISP’) Out[75]: (“Ivar ama Python”, “Daniel ama C”, “Felipe ama LISP”) FAQ: Mas se lambda só aceita uma expressão, qual a diferença entre ‘expression’ e ‘statement’? Volte e leia a parte sobre expressões e statements Parâmetros Variáveis com *args, **kwargs O Python nos permite a flexibilidade de montar funções que não precisam saber o números de argumentos que lhes serão passadas. Para isso usamos os operadores ‘*’ e ‘**’ ao declarar a função. O operador ‘*’ faz com que a variável que o segue (quase sempre chamada ‘args’ pela comunidade Python) seja interpretada como uma tupla contendo todos os argumentos da função passados dali em diante. Veja: FGV DIREITO RIO 54 Programação para Advogados In [76]: def foo(primeiroarg, *args): print ‘eis o primeiro:’,primeiroarg,’\n’ # todos os outros args são empacotados em uma tupla por cause do ‘*’! for i in args: # EASTER-EGG: quem me explica a vírgula aqui? # os primeiros 5 a mandar um email para daniel. chada<arroba>fgv<ponto>br # explicando (corretamente) ganham chocolate! print i, # note que estou passando 6 argumentos, mas a função só recebe dois! # ...não dá erro?? foo(3, ‘Daniel’,’é’, 10, ‘ou’, 3.14) eis o primeiro: 3 Daniel é 10 ou 3.14 Já o operador ‘**’ acolhe todos os valores nomeados, isto é, que recebem nome na chamada (não na declaração) em um dicionário (sempre nomeado ‘kwargs’ pela comunidade Python), com as chaves sendo os nomes das variáveis, e os valores seus valores. veja: In [77]: def bar(primeiroarg, **kwargs): print ‘eis o primeiro:’,primeiroarg,’\n’ for key,val in kwargs.items(): print ‘a chave:’,key,’...tem valor:’,val bar(‘1o’, trabalho=’diversão’, python=’legal’, Daniel=’melhor professor DO MUNDO!’, Ivar=’Ivan’) FGV DIREITO RIO 55 Programação para Advogados eis o primeiro: 1o a chave: python ...tem valor: legal a chave: Ivar ...tem valor: Ivan a chave: trabalho ...tem valor: diversão a chave: Daniel ...tem valor: melhor professor DO MUNDO! O site http://freepythontips.wordpress.com/2013/08/04/args-and-kwargs-in-python-explained/ contém uma boa explicação sobre o assunto. FGV DIREITO RIO 56 Programação para Advogados Módulo 7 - Strings Avançados Neste módulo veremos um pouco mais sobre strings, e as diferentes formas de interpretá-los. String é um subtipo de sequência, de fato, uma string é um sequência imutável, tal qual uma tupla. String não são apenas para guardar e procesar informação em texto. No Python, string podem servir para guardar e processar informação em qualquer formato binário, até imagens e outras mídias. Isso os torna fortemente flexíveis, mas um pouco mais difíceis de lidar quando saímos das interpretações triviais (isto é, 8 bits = um caractére). OBS: para referência, eis todos os tipos Python que são sequências: str, unicode, list, tuple, bytearray, buffer, xrange. Leia mais sobre eles em https:// docs.python.org/2/library/stdtypes.html#sequence-types-str-unicode-list-tuple-bytearray-buffer-xrange Unicode strings Python também nos permite utilizar caracteres fora do ‘básico’ provido pelo código ASCII (veja a lista ASCII completa em http://www.asciitable. com), permitindo quaisquer caracteres do Unicode (cuja espcificação fica em http://www.unicode.org). O site da Unicode explica: “Unicode provides a unique number for every character, no matter what the platform, no matter what the program, no matter what the language”. O Livro Referência [1], descreve: “non-Unicode strings are sequences of 8-bit bytes that print with ASCII characters when possible, and Unicode strings are sequences of Unicode code points - identifying numbers for characters, which do not necessarily map to single bytes when encoded to files or stored in memory. In fact, the notion of bytes doesn’t apply to Unicode”. Vejamos um exemplo um pouco mais concreto: FGV DIREITO RIO 57 Programação para Advogados In [78]: # o caractere em Unicode não é automaticamente lido no Python 2.x print ‘sp\xc4m’ # se colocarmos o ‘u’ na frente da string, o Python sabe que deve ler como # Unicode print u’sp\xc4m’ sp◊m spÄm As funções encode() e decode() funcionam para mapear strings para que sejam interpretados de certo jeito. Vejamos alguns outros exemplos de mapeamento: In [79]: ’\xc3\xa1’ # um string de um bando de caracteres Out[79]: “\xc3\xa1” In [80]: print ‘\xc3\xa1’ # a função print é esperta e interpreta o utf-8 >>> print ‘á’ á á In [81]: u’\xe1’ # um unicode sem muito sentido Out[81]: u”\xe1” FGV DIREITO RIO 58 Programação para Advogados In [82]: print u’\xe1’ # mas a função print já interpreta diferente á In [83]: u’\xe1’.encode(‘utf-8’) # mapeando Out[83]: “\xc3\xa1” In [84]: print u’\xe1’.encode(‘utf-8’) á In [85]: ’\xc3\xa1’.decode(‘utf-8’) # ...e de volta Out[85]: u”\xe1” In [86]: print ‘\xc3\xa1’.decode(‘utf-8’) á Para quem quiser ler um pouco mais sobre a função print, busque aqui: https://docs.python.org/2/library/functions.html#print FGV DIREITO RIO 59 Programação para Advogados In [87]: s = ‘ö’ >>> s.decode(‘utf-8’) # estou usando o ‘>>>’ para emular o terminal python que imprime as operações sem usar o print Out[87]: u”\xf6” In [88]: >>> ‘spam’.encode(‘utf-16’) # mapeie para utf-16 (16 bytes por caractere) Out[88]: “\xff\xfes\x00p\x00a\x00m\x00” In [89]: >>> print ‘sp\xc4m’ # uh oh, estou tentando considerar como string normal sp◊m In [90]: >>> print u’sp\xc4m’ # considere como um unicode spÄm In [91]: >>> u’sp\xc4\u00c4\U000000c4m’ # unicode hexadecimal, unicode ‘curto’ (16) e unicode ‘longo’ (32) Out[91]: u”sp\xc4\xc4\xc4m” FGV DIREITO RIO 60 Programação para Advogados In [92]: >>> print u’sp\xc4\u00c4\U000000c4m’ spÄÄÄm Há codecs (mapeamentos) que não tem nada à ver com texto, mas sim com como interpretar uma sequência de bytes (i.e. arquivos zip), veja https://docs. python.org/2/library/codecs.html#python-specific-encodings Uma lista dos codecs padrão que o Python lida como built-in existe aqui: https://docs.python.org/2/library/codecs.html#standard-encodings In [93]: >>> s.encode(‘zip’) Out[93]: “x\x9c;\xbc\r\x00\x02>\x01z” Formatação Python permite a formatação de strings via a função str.format(). O string sendo formatado (isto é, que chama a sua própria função format() poe conter texto literal (como sempre) ou campos de ‘substituição’, delimitados por chaves {}. Cada campo de substituição contém ou o índice numérico de um argumento posicional ou o nome de um argumento (veja o exemplo). A função retorna uma cópia da string onde cada campo de substituição é trocado pelo valor string (str()) do argumento correspondente. Vejamos: In [94]: x = ‘O melhor professor de Python é {} e o triste segundo é {}.’ print x y = x.format(‘Daniel’,’Ivar’) print y FGV DIREITO RIO 61 Programação para Advogados O melhor professor de Python é {} e o triste segundo é {}. O melhor professor de Python é Daniel e o triste segundo é Ivar. Vejamos colocando informação, junto ao delimitador: In [95]: print ‘O melhor professor de Python é {1}\ e o triste segundo é {0}.’.format(‘Daniel’, ‘Ivar’) O melhor professor de Python é Ivar e o triste segundo é Daniel. Também aceita-se valores nomeados, vejamos: In [96]: at1 = ‘fazer aluno sofrer’ at2 = ‘fazer aluno chorar’ s = “””olá, sou {nome} e tenho {idade} anos! \ Gosto muito de {ativ1} e {ativ2}!””” print s.format(nome=’Daniel’ , idade=’34’ , ativ1=at1 , ativ2=at2) olá, sou Daniel e tenho 34 anos! Gosto muito de fazer aluno sofrer e fazer aluno chorar! Também podemos usar híbridos de posicionamento e nomeação (lembrem da seção sobre *args e **kwargs) FGV DIREITO RIO 62 Programação para Advogados In [97]: s = “olá, sou {0} e tenho {1} ...gosto do {at1} e {at2}!” at1 = “programar” at2 = ‘dar zero a alunos’ print s.format(‘Daniel’,’34’, at1=at1, at2=at2) olá, sou Daniel e tenho 34 ...gosto do programar e dar zero a alunos! A documentação do Python contém varios exemplos de formatação ... aqui: (https://docs.python.org/2/library/string.html#format-examples) e aqui: (https://docs.python.org/2/tutorial/inputoutput.html#fancier-output-formatting) Multi-line strings String multi-linha são bastante simples no Python: usamos três aspas para defini-los: In [98]: >>> x = “””Ei! Eu sou uma string multi-linha!””” >>> x Out[98]: “Ei! Eu\n\nsou uma\n\nstring multi-linha!” FGV DIREITO RIO 63 Programação para Advogados In [99]: print x Ei! Eu sou uma string multi-linha! Enfim ...O porque do “#coding: utf-8” no início dos arquivos! O coding: utf-8 no início dos nossos arquivos .py indica que aquele código python deve ser interpretado como uma série de caracteres utf-8, não ASCII (que não permite acentos, e uma série de outros caracteres). a definição formal pela comunidade Python descreve: “The encoding information is then used by the Python parser to interpret the file using the given encoding. Most notably this enhances the interpretation of Unicode literals in the source code and makes it possible to write Unicode literals using e.g. UTF-8 directly in an Unicode aware editor”. Assim, o Python, ao ler nosso arquivo .py, consegue entender caracteres fora do ASCII. FGV DIREITO RIO 64 Programação para Advogados Módulo 8 - Números Binários, Tabelas Verdade, OR, AND, XOR, NAND A computação como um todo se baseia em números binários. Mas o que queremos dizer quando dizemos ‘binário’, ou ‘base dois’? Sabemos intuitivamente que, da mesma forma que a base decimal usa somente zero a nove {0,9}, a base binária se restringe a zeros e uns {0,1}. Na base decimal, quando chegamos ao final, adicionamos um à próxima casa ‘decimal’ e começamos de novo. Esta próxima casa implica uma outra potência de dez. por exemplo, 243 significa 2 4 3 10^2 10^1 10^0 243 é igual a 2*100 + 4*10 + 3*1 No binário, como só temos o 0 e o 1, fazemos a mesma coisa, mas muito mais vezes... ao chegar ao ‘final’ (o 1) adicionamos uma casa ‘binária’ e começamos de novo. Esta próxima casa implica outra potência de dois. Por exemplo 1011 significa: 1 2^3 0 2^2 1 2^1 1 2^0 Assim, 1011 é igual a 1*8 + 0*4 + 1*2 + 1*1 = 8+2+1 = 11 Mais informação e exemplos podem ser encontrados em: https://docs. python.org/2/library/stdtypes.html#truth-value-testing Operadores Bitwise: not, or, xor, and, nand Com binários, podemos utilizar operadores (iguais aos operadores lógicos que já vimos, mas que funcionam bit a bit), chamados bitwise. Vamos encontrar os mesmos operadores, mas vamos ver alguns outros importantes na computação também. O ou exclusivo (exclusive or) também chamado xor ...dadas duas proposições A e B, o xor funciona assim: A B A xor B 0 0 0 0 1 1 1 0 1 1 1 0 FGV DIREITO RIO 65 Programação para Advogados O xor é uma operação composta, que pode ser expressa como (A or B) and not(A and B) O and negado (negated and), também chamado nand ...dadas duas proposições A e B, o nand oferece os resultados opostos a um operador and assim: A B A nand B 0 0 1 0 1 1 1 0 1 1 1 0 In [100]: a = 0b1011 b = 0b1001 print bin(a | b) # operador ‘or’ bitwise print bin(a & b) # operador ‘and’ bitwise 0b1011 0b1001 FGV DIREITO RIO 66 Programação para Advogados Módulo 9 - Usando APIs Externas O Python package index é o principal repositório de módulos livremente disponíveis na internet. no momento da edição desta apostila, o site https://pypi.python.org/pypi descreve: “The Python Package Index is a repository of software for the Python programming language. There are currently 49551 packages here.” Como baixar e instalar? No Linux e OSX a ferramenta pip do terminal torna trivial a instalação de novos pacotes Python. No Windows, ela também pode ser usada, como descrito aqui. Muitos módulos disponibilizam instaladores específicos para o Windows, facilitando o processo. Podemos encontrar uma lista extra-oficial de módulos com instaladores para o Windows aqui. Em certos módulos do Python é necessário construir o módulo a partir do código-fonte original (isso se chama build from source). FGV DIREITO RIO 67 Programação para Advogados Anexo A - Recursos Online¶ StackOverflow.com Python.org Tutorialspoint.com FGV DIREITO RIO 68 Programação para Advogados Referências¶ [1] Lutz, M.; Learning Python 5th ed. In [100]: FGV DIREITO RIO 69 Programação para Advogados FICHA TÉCNICA Fundação Getulio Vargas Carlos Ivan Simonsen Leal PRESIDENTE FGV DIREITO RIO Joaquim Falcão DIRETOR Sérgio Guerra VICE-DIRETOR DE ENSINO, PESQUISA E PÓS-GRADUAÇÃO Rodrigo Vianna VICE-DIRETOR ADMINISTRATIVO Thiago Bottino do Amaral COORDENADOR DA GRADUAÇÃO André Pacheco Teixeira Mendes COORDENADOR DO NÚCLEO DE PRÁTICA JURÍDICA Cristina Nacif Alves COORDENADORA DE ENSINO Marília Araújo COORDENADORA EXECUTIVA DA GRADUAÇÃO FGV DIREITO RIO 70