Baixe o app para aproveitar ainda mais
Prévia do material em texto
1 2 Sumário UNIDADE I................................................................................................................................. 4 Introdução ............................................................................................................................ 4 Instalação ............................................................................................................................. 5 A Linguagem De Programação Python ................................................................................... 6 Sintaxe Para Programação Python ....................................................................................... 11 Conclusão ........................................................................................................................... 16 UNIDADE II .............................................................................................................................. 17 Introdução .......................................................................................................................... 17 Tipos e Estruturas De Dados ................................................................................................ 18 Manipulação De Strings....................................................................................................... 22 Conclusão ........................................................................................................................... 32 UNIDADE III ............................................................................................................................. 33 Introdução .......................................................................................................................... 33 Expressões e Operadores Aritméticos ................................................................................. 34 Operadores Relacionais ....................................................................................................... 36 Operadores Lógicos ............................................................................................................. 37 Operadores Compostos De Atribuição................................................................................. 39 Entrada e Saída ................................................................................................................... 42 Conclusão ........................................................................................................................... 47 UNIDADE IV ............................................................................................................................ 48 Introdução .......................................................................................................................... 48 Arquivos De Texto ............................................................................................................... 49 Estruturas De Controle De Fluxo De Execução ..................................................................... 52 Estrutura De Decisão ........................................................................................................... 52 Estrutura De Repetição ....................................................................................................... 56 Funções .............................................................................................................................. 60 Conclusão ........................................................................................................................... 65 UNIDADE V ............................................................................................................................. 66 Introdução .......................................................................................................................... 66 Orientação a Objetos .......................................................................................................... 67 Herança em Orientação a Objetos ....................................................................................... 69 Métodos Complementares .................................................................................................. 72 3 Módulos.............................................................................................................................. 75 Conclusão ........................................................................................................................... 82 4 UNIDADE I Introdução Python é uma linguagem de propósito geral capaz de atender a diversos tipos de demandas no desenvolvimento de software. É uma linguagem interpretada, ou seja, depende de um software instalado capaz de executar toda a sequência de código escrita após verificação da semântica e sintaxe dos códigos. Pode ser aplicada para desenvolvimento de aplicações web usando Django ou Bottle, por exemplo, programação matemática e computacional utilizando Orange, SymPy ou NumPy, por exemplo), aplicativos comuns para desktop usando PyQt ou PyWidgets, por exemplo, e jogos com Pygame e Panda3D, por exemplo. Por ser uma linguagem com licença do tipo open source (aberta), existe uma grande comunidade de desenvolvedores que auxiliam no desenvolvimento constante da linguagem, sua difusão e desenvolvimento de bibliotecas. A biblioteca padrão da linguagem possui centenas de módulos divididos em diversas categorias, podendo ser utilizada para o desenvolvimento de aplicações tanto comerciais como não comerciais. Além da biblioteca padrão, existem milhares de pacotes contidos no gerenciador de pacotes chamado “pip” para todas as áreas de desenvolvimento permitidas pela linguagem. Desenvolvida nos anos 1980, e publicada em 1991, foi desenvolvida por Guido van Rossum e se baseou num show de comediantes ingleses dos anos de 1970 (Monty Python’s Flying Circus) para batizar a linguagem criada. 5 Instalação A linguagem Python, como as demais linguagens em geral é gratuita, e existe uma IDE (interface integrada de desenvolvimento) própria e também gratuita que pode ser obtida gratuitamente na forma de simples download nas diferentes plataformas compatíveis como ilustrado na figura 1.1 a seguir. Figura 1.1: Versões para diferentes plataformas para instalação. Fonte: O autor Para instalar a IDE em cada plataforma, há um resumo dos procedimentos a serem efetuados em algumas plataformas disponíveis na figura 1.2. Windows Baixe e instale o bundle Anaconda (https://www.continuum.io/downloads, também disponível para outras plataformas). Ubuntu sudo apt install python3-scipy python3-matplotlib MacOS 6 Instale o Homebrew: https://brew.sh brew install python3 pip3 install numpy matplotlib Figura 1.2: Procedimentos para instalação da IDE Python. Fonte: https://docs.python.org/3/ Na página do site https://docs.python.org/3/ é possível obter documentação oficial complementar para os estudos desta versão da linguagem. A Linguagem De Programação Python Sendo uma linguagem de programação dita de “alto nível”, não há necessidade de manipulação direta de hardware, e assim, a programação em si se torna mais fácil por muitos pontos que necessitariam de atenção em uma linguagem de “baixo nível” em relação a uso e compatibilidades com hardware são dispensadas, pois são ajustadas automaticamente. Em função disto, programas criados em linguagens de alto nível necessitam etapas intermediárias entre a digitação de seu código e sua efetiva execução sobre o sistema operacional de um hardware. Este processo gera um tempo extra para que uma aplicação possa ser executada, o que pode representar um peso maior em algumas aplicações que em outras, mas o fato de o código poder ser escrito muito mais rapidamente e sem a necessidade de conhecimentoprofundo da arquitetura do hardware onde será executada a aplicação é muito importante. Outro fato é que um código escrito em linguagens de alto nível acaba tendo menores quantidades de linhas e sendo mais fáceis de interpretar, tornando estas, opções preferidas pela maioria dos desenvolvedores. 7 Outra característica da linguagem é sua capacidade de trabalhar com diferentes paradigmas de programação, ou seja, a estrutura dos códigos criados na linguagem podem ser implementados de diferentes formas, de forma a oferecer variadas formas de se desenvolver soluções computacionais. Um dos paradigmas que podem ser utilizados se chama imperativo, que é o mais comum e tradicional onde a execução do código segue um fluxo normal, mas que pode ser desviada sem problemas com estruturas de controle de fluxo. O objetivo principal deste paradigma é o processamento de dados através de instruções que mudam os estado das estruturas de dados que contém estes dados. Outro paradigma aceito pela linguagem se chama orientado a objetos que se baseia na definição de objetos que servem como abstrações de problemas reais a serem computacionalmente implementados e que possam ser modelados em classes com suas principais características divididas em atributos para os dados e métodos para processá-los. Outro paradigma aceito pela linguagem Python é o paradigma funcional que realiza o processamento computacional com base em funções dinâmicas que contrastam com as mudanças de estado da programação imperativa, tendo como base a construção de funções seguindo a lógica matemática na estruturação de códigos. Um último paradigma aceito pela linguagem é o procedural que se baseia no paradigma imperativo, mas que utiliza sub-rotinas para dividir o problema todo em partes menores que podem ser acionadas a qualquer instante e realizar processamentos sobre dados como nos demais paradigmas. Outro tipo de aspecto característico da linguagem Python é que a linguagem reduz redundâncias e busca a melhor ortogonalidade possível, ou seja, evita que comandos aceitem muitas exceções, tornando a codificação mais complexa como na linguagem C, por exemplo, mas isto a torna mais limitada em alguns aspectos. 8 A linguagem também possui código aberto (open-source), e com isto, foi adaptada para variadas plataformas como Windows, Android e MacOS, com seu uso permitido, tanto para uso educacional e científico, quanto comercial. Através de sua expansibilidade, aplicações podem ser desenvolvidas não apenas integralmente em Python, mas partes podem ser desenvolvidas em linguagens como C para melhoria de desempenho e interação com hardware que é mais completa na linguagem C. Possui uma grande biblioteca padrão com funcionalidades prontas para uso no desenvolvimento de interfaces gráficas, trabalho com bases de dados e redes, por exemplo, assim como bibliotecas desenvolvidas pela comunidade de desenvolvedores que também adicionam outra grande variedade de código pronto e livremente utilizável. Outra característica da linguagem é o fato de ser interpretada, ou seja, não gera software executável diretamente, e assim, diferencia-se neste aspecto de linguagens como C que geram aplicações compiladas para serem utilizadas em sistemas operacionais compatíveis com o compilador. Uma diferença importante neste caso é que um código compilado em linguagem C, por exemplo, que gere um software executável, pode ser levado a outro hardware contendo o mesmo sistema operacional e poderá ser executado sem que neste outro equipamento haja a necessidade de haver o compilador ou algum software para auxiliar na execução, a menos que este tenha sido projetado para funcionar em conjunto com outro software. Em Python, em função de ser interpretado, este não é compilado e um software executável não é gerado. Assim, o código, para ser executado, necessita que todos os outros equipamentos de hardware onde o mesmo deva ser executado tenham instalados, interpretadores Python compatíveis com o sistema operacional em uso. Isto aumenta a portabilidade do código, pois o interpretador é quem se adequa ao funcionamento do sistema operacional, mas linguagens compiladas também podem gerar código com alta portabilidade, necessitando apenas serem 9 compiladas em compiladores de cada sistema operacional onde devam ser executados. Assim, é perceptível que softwares gerados em linguagens compiladas tendem a ser mais rápidos em sua execução por funcionarem sozinhos depois de compilados, e códigos interpretados, tendem a ser mais lentos por terem sua execução dependente de interpretadores instalados e que para serem executados antes das aplicações, consomem recursos de hardware. Para que seja possível a geração de um executável, é preciso que seja instalado um complemento para a IDE Python chamado de Pyinstaller através do comando “pip install pyinstaller”. Este comando irá agregar a funcionalidade ao Python na máquina e assim, é possível gerar um executável a partir de um código usando o comando “pyinstaller código.py”. Pelo prompt do Windows ou terminal Linux, por exemplo, é só abrir o arquivo executável contido na subpasta dist criada na pasta onde foi gravado o arquivo contendo o código. Em Windows os arquivos executáveis levam uma extensão .EXE,mas em Linux, a sintaxe muda para “./” seguido do nome do software sem extensão. Para gerar um executável compilado em Python, basta chamar a ferramenta de compilação Python através do comando “pyinstaller” e depois o nome do arquivo .py que contém o código. Vantagens e desvantagens de ambos os tipos de formas de execução de códigos são perceptíveis, e cabe aos desenvolvedores, à escolha pela melhor opção em cada caso, avaliando custo e benefício, mas não apenas este aspecto é relevante, pois a ortogonalidade maior ou menor de cada linguagem, sua biblioteca de funções, recursos da linguagem como criação de aplicações web, interfaces gráficas, manipulação de hardware e gerenciamento de dados são aspectos também importantes e com pesos variados em cada tipo de aplicação a ser desenvolvida. Em relação à interpretação de código em Python, um aspecto muito importante é que seu funcionamento permite que seja interativo, e assim, o processo de interpretação de um código pode ser controlado em tempo real, ou ao invés de 10 um código todo ser fornecido de antemão, e através de um prompt de comandos fornecido por uma interface do tipo shell (>>>) pode-se ir inserindo um a um os comandos se desejado como mostrado na figura 1.3. Figura 1.3: Interface Shell para interpretação de código Python. Fonte: O autor. A linguagem permite a criação de aplicações web com ou sem interfaces gráficas, softwares matemáticos e estatísticos, software para gerenciamento de dados, aplicações matemáticas complexas e científicas, computação gráfica, etc. Graças a esta grande variedade, áreas como Big Data, inteligência artificial e aprendizado de máquina são altamente exploráveis e ajudaram a impulsionar o uso da linguagem no mercado de desenvolvimento de software. A linguagem já sofreu alterações para se adaptar às mudanças na área de desenvolvimento, como o surgimento e evolução da web, e como a linguagem conseguiu se desenvolver nas últimas décadas de forma conseguir ser vista como uma boa opção no mercado. Com as mudanças e evoluções diferentes versões e atualizações destas versões foram implementadas e puderam se manter ativas como a versões 2 e 3 e que certamente continuarão evoluindo por um tempo ainda. O fato de duas versões estarem ativas ainda é por causa de alguma incompatibilidade que pode ocorrer entre aplicações desenvolvidas na versão 2 11 para ser executada em um interpretador da versão 3, ou vice-versa, pois a sintaxe básica e adição ou exclusão de comandos pode ser ajustada por interpretadores próprios paratal função, mas as bibliotecas podem ou não terem sido ajustadas, e assim, há o risco do não funcionamento de algumas funções que poderiam inviabilizar a execução de aplicações. Existem interpretadores alternativos como Jython e PyPy implementados em Java e Python, mas a versão oficial CPython é a indicada por garantir maior compatibilidade com bibliotecas, mesmo não disponibilizando um interpretador JIT (Just in Time – em tempo real) que gera um código intermediário antes da primeira execução. Sintaxe Para Programação Python A programação em linguagem Python possui algumas particularidades em relação a sua sintaxe, assim como todas as demais linguagens de programação possuem, desde sua estruturação de código, símbolos utilizados, e até sua formatação de código em relação à endentação. Como não é exclusivamente procedural ou orientada a objetos, não possui uma função ou outro tipo de sub-rotina obrigatória para a inicialização de seus códigos, e trabalha em forma de scripts que dispensam ao interpretador a busca pelo código de um ponto específico para iniciar a interpretação e execução. Um aspecto fundamental para a construção de códigos em linguagem Python é que diferentemente da maioria das linguagens de programação tradicionais, a endentação é fundamental na sintaxe das instruções, e tem ligação direta com a semântica do código, pois é através deste espaçamento que são indicados blocos de instruções inclusas em outras instruções, por exemplo. Se um código não for endentado, não haverá a indicação de blocos de instruções e todas serão tratadas sequencialmente e estruturas de controle de fluxo da execução perdem seu sentido nos códigos. Com isto o escopo de cada instrução se baseia em níveis indicados pela endentação do código. Lembre-se que é 12 preferível o uso de espaços ao invés de tabulações, e o uso conjunto dos dois tipos de espaçamento num mesmo código pode gerar problemas. Outro detalhe relevante é que em ambientes Linux e MacOS, por exemplo, é comum que a primeira linha de um código seja uma shebang (#!/usr/bin/env python) que indica a estes sistemas operacionais o script possa ser executado sem que seja necessária uma prévia execução do interpretador. Códigos em linguagem Python, por recomendação, terminam sem caracteres especiais, como o ponto e vírgula, muito comum em diversas linguagens, mas pode ser utilizado. A recomendação é que o código seja baseado em quebras de linha para finalização linhas de comando. Mantendo linhas de código com até 79 caracteres por linha, um código se torna mais fácil de ser interpretado e editado, mas alguns comandos mais longos, ou que estejam com uma endentação muito a direita podem não caber e para dividir linhas de comando em mais de uma linha de texto, pode-se encerrar uma linha com o caractere “\” e continuando um comando na linha de baixo. Outro recurso é que expressões em parenteses, colchetes e chaves podem ser divididas em linhas sem o uso da barra invertida. Observe o exemplo da figura 1.4. Figura 1.4: Exemplo de quebra de linha de código em Python. Fonte: O autor. Palavras reservadas são comuns em todas as linguagens de programação e representam comandos que realizam ações específicas como controle de fluxo 13 ou entrada e saída de dados, por exemplo. A seguir, segue a lista de palavras reservadas da linguagem Python na figura 1.5. COMANDO DESCRIÇÃO and Operador lógico e. as Cria nome alternativo. assert Para depuração e validação de condições. break Interromper laço. class Definição de classe. continue Pular para próxima iteração de laço. def Declaração de função. del Exluir objeto. elif Alternativa complementar ao comando if else Alternativa complementar aos comandos if e elif. except Complemento do comando try e finally. False Valor lógico para falso. finally Complemento do comando try e except. for Laço de repetição condicional contado. from Importação de parte de um módulo. global Declara variável global. if Comando para estrutura condicional. import Importar módulo. in Verificação de presença de conteúdo em listas e dicionários. is Testa se duas variáveis são iguais. lambda Declarar função anônima. None Valor nulo. nonlocal Declarar variável não-local. not Operador lógico para não. or Operador lógico ou. pass Ignora erro de função vazia sem código, por exemplo. raise Tratamento pontual de exceção. return Retorno de uma função. 14 True Valor lógico para verdadeiro. try Para tratamento de exceções pelo código. while Laço de repetição condicional. with Fechamento de arquivos abertos. yield Semelhante a return, mas pode haver mais de um retorno. Figura 1.5: Palavras reservadas da linguagem Python. Fonte: O autor. É importante observar que como em outras linguagens, Python é considerada case sensitive, ou seja, letras maiúsculas e minúsculas são tratadas como diferentes e comandos devem ser escritos como é o padrão da linguagem, ou o interpretador as trata como identificadores de estruturas de dados, por exemplo. Os chamados identificadores são usados para nomear elementos definidos pelo desenvolvedor e abrangem nomes em geral para estruturas de dados e funções, por exemplo. Estes identificadores podem iniciar com caracteres maiúsculos e minúsculos ou com o sublinhado (_ ou underline), e depois, podem conter além destes caracteres, números no restante dos caracteres do identificador. Identificadores são nomes em geral utilizados para identificar elementos criados pelo desenvolvedor durante a implementação de um código para nomear estruturas de dados, funções e outros elementos que não sejam componentes padrões da própria linguagem como palavras reservadas, por exemplo. Assim, seguindo as regras padronizadas de nomenclatura da maioria das linguagens de programação e garantir maior portabilidade de código, os identificadores devem ser formados por letras ou pelo caractere “_” como primeiro caractere do identificador, lembrando que pela linguagem Python ser case sensitive, maiúsculas e minúsculas são considerados caracteres distintos. Nomes como: nome, Nome, DADO, Tipo1, valor2, tipo_de_dado e _1 são todos exemplos válidos de identificadores, mas #dado, 123dado, valor% e ?!@, por exemplo, são exemplos de identificadores inválidos para a linguagem Python. 15 É interessante seguir padrões de nomenclatura para facilitar a interpretação de scripts mais longos e manter código dentro de uma regra padrão de digitação de identificadores, palavras-chave, etc., mas estas regras podem variar quando se programa em um paradigma ou outro, pois há elementos que constam em um paradigma e não em outro. Nomes como “dado”, “Dado” e “DADO” são todos considerados diferentes como identificadores e podem ser todos os três utilizados num mesmo programa sem problemas, tirando o fato de poderem confundir o desenvolvedor pela semelhança. A partir do segundo caractere, a regra de ser case sensitive se mantém, podem ser usadas letras maiúsculas ou minúsculas, “_” e números a partir deste caractere, mas acentuação não é permitida nos caracteres e devem ser omitidos, mesmo em nomes que no idioma natural do desenvolvedor existam. Como já citado na linha especial chamada shebang, o sinal de # indica início para comentários em finais de linhas para facilitar a interpretação de linhas de comandos, instruções completas, blocos de instruções, etc. 16 Conclusão Nesta primeira unidade foi possível conhecer alguns aspectos básicos iniciais da linguagem Python como sua instalação de diferentes formas para preparação dos estudos. Também é estudada a forma como são executados os scripts gerados em Python e conceitos iniciais para compreensão da linguagem, paradigmas aceitos de programação e pontos de atenção em relação à forma como são estruturados códigos na linguagem.A sintaxe básica para implementação de código em linguagem Python também é comentada para permitir que o estudante possa ter uma noção básica antes de se aprofundar nos detalhes do desenvolvimento na linguagem. Foram apresentadas as palavras-chave da linguagem e uma breve descrição de suas funções, assim como conceitos sobre definição de identificadores a partir de regras para elaboração de nomes. Na próxima unidade, iniciam os estudos de detalhes mais técnicos como tipos de dados e sua manipulação, tendo certo destaque para a manipulação de dados do tipo texto. 17 UNIDADE II Introdução Nesta segunda unidade, conceitos ligados ao uso de dados simples como números inteiros e decimais, e como devem ser definidas estruturas mais complexas como listas compostas por dados simples. Também são diferenciadas as estruturas mais complexas citando tuplas, listas, conjuntos e dicionários que possuem todas formas mais adequadas de uso de acordo com o uso dos dados que podem ser contidos nestas. Um tipo especial de estrutura de dados que possui atenção especial nesta unidade é a string que representa texto em geral que pode ser manipulado e possui muitas aplicações em Python. 18 Tipos e Estruturas De Dados Os dados são tratados em todas as linguagens de programação, pois o processamento de dados é base da computação e praticamente todos os softwares são desenvolvidos com o intuito de lidar com dados. Os dados, ao longo do tempo, foram ganhando cada vez mais importância, devido ao que representavam para o mercado e para a sociedade. À medida que mais e mais dados foram sendo acumulados em sistemas e na Internet, sua relevância e consequentemente, sua importância foi crescendo rapidamente, ao ponto de hoje haverem estudos de como lidar com estes imensos volumes de dados acumulados e disponíveis. Até algum tempo, este acúmulo todo de dados era pouco explorado e tinha um caráter mais de registro histórico, mas com o passar do tempo, foi percebido o grau de informação que mesmo dados históricos poderiam trazer ao mercado, e complementar estratégias mercadológicas em geral. A chamada ciência de dados trata de como trabalhar dados de diferentes formas e volumes com o objetivo de extrair deles novas informações relevantes e que podem ser obtidas de forma simples ou complexa. Sistemas especialistas buscam dados em bases isoladas ou unificadas de forma a trazer, através de pesquisas mais profundas, resultados antes quase impossíveis em função da menor especialização dos mecanismos de tratamento de dados. Assim, cada linguagem trata dados de acordo com suas características e propósito, variando em quantidade e complexidade em cada linguagem, mas sempre tendo como básicos tipos capazes de lidar ao menos com caracteres em geral e números inteiros ou decimais. Em Python, existem os tipos mais simples como números inteiros, booleanos para verdadeiro e falso, decimais que aceitam casas decimais e números complexos. Os números booleanos são representados por 0 para falso e 1 para verdadeiro, não se utilizando de palavras reservadas, por exemplo nesta representação. 19 Os números inteiros aceitam quaisquer números sem casas decimais não tendo limitações pré-definidas, mas apenas o esgotamento dos recursos de hardware como limite, e assim, a linguagem pode lidar com números inteiros com muitos dígitos. Os números decimais ou de ponto flutuante permitem a inclusão de casas decimais nos números a serem utilizados, e que por aceitarem altos valores e muitas casas decimais, podem sofrer com algumas imprecisões nos cálculos devido ao método de cálculo realizado pelos computadores com base em bits. Os números complexos que são reconhecidos pela letra j ao final de cada número. Este tipo de número é usado em casos onde não seja possível uma representação de um valor em termos de números inteiros ou decimais. Um caso pode ocorrer, por exemplo, em equações do segundo grau do tipo Ax2 - Bx + C = 0 onde resultados podem terminar com uma parte representada pela raiz quadrada de -1, por exemplo, e isto não pode ser calculado, sendo então substituído pela letra “j” como uma representação imaginária do que poderia valer esta raiz, e considera-se a letra e esta nunca será substituída por valor alguma, a menos que numa operação, o significado da letra não seja mais relevante. Outro tipo de dado é chamado de coleção e engloba estruturas de dados que podem armazenar outras do mesmo tipo, ou de tipos diferentes como listas com elementos indicados entre colchetes, tuplas com elementos não alteráveis indicados por parênteses, conjuntos com elementos que podem ser alterados com operações de conjuntos e indicados por chaves. Finalmente, um tipo importante de coleção é o tipo dicionário que permite tipos mais complexos em forma de sequência não ordenada e com cada elemento podendo conter mais de um dado de tipos variados, por exemplo. A seguir, a figura 2.1 traz alguns exemplos de uso de coleções em Python. lista = ['A', 'B', 5, 6] lista = lista + [8, 9] 20 tupla = ( 1, 2, 3, 4) conjunto = {1, 2, 3, 4, 5} dicionário = {1:’A’, 2:’B’, 3:’C’} Figura 2.1: Exemplos de coleções de dados em Python. Fonte: O autor. O primeiro e segundo exemplos da figura 2.1 são complementares, e no primeiro, uma lista é criada com quatro elementos, e no segundo exemplo, a mesma é ampliada com o acréscimo de mais 2 elementos. Neste tipo de estrutura, a mesma pode ser ampliada, reduzida e ter seus elementos modificados. No terceiro exemplo, uma tupla é definida com quatro elementos, e estes não podem ser modificados e nem a estrutura da tupla pode ser modificada, sendo assim uma espécie de constante, que por este motivo possui desempenho mais rápido em operações de busca, por exemplo. No quarto exemplo, um conjunto é definido com cinco elementos e estes não podem ser repetidos, tendo também um acesso mais rápido em operações, além de permitir operações matemáticas de conjuntos como união, diferença e intersecção, por exemplo. Por fim, o quinto exemplo traz um dicionário contendo 3 pares de elementos, onde um elemento serve como chave para o outro de cada par de dados que representa uma unidade na estrutura. Assim, neste exemplo, 1 é chave para ‘A’, e assim por diante. As strings representam outro tipo importante de dado e são representadas por sequências de um ou mais caracteres que sempre devem ser indicadas com o uso de aspas simples ou duplas. Em Python as strings são consideradas constantes e por isto, não podem ser alteradas, mas podem ser ter seus caracteres acessados por meio de índices de 0 até o número de caracteres menos um. Assim, há diferentes formas de se trabalhar com o acesso de caracteres em strings. 21 Alguns caracteres especiais podem ser incluídos em strings para complementação e os principais estão indicados na figura 2.2. Marcador Caractere \\ Barra invertida \’ Aspas simples \” Aspas Duplas \n Nova Linha (Enter) \t Tabulação horizontal \v Tabulação vertical \b Retorno de carro \a Beep ou sinal sonoro padrão do hardware Figura 2.2: Caracteres especiais e sua representação em Python. Fonte: O autor. Em Python, assim como em outras linguagens, strings são sequências de caracteres simples que formam uma lista ou vetor com uma quantidade finita de elementos. A indicação básica de uma string nesta e em muitas outras linguagens é a indicação da mesma entre aspas. Em linguagem Python, ainda é possível o uso de aspas simples e aspas triplas para a manipulação de strings de diferentes formas. Um recurso útil que pode ser utilizado é a conversão forçada para dados (casting) que pode inclusive alterar dados e ajustá-los de acordo com alguma solicitação realizada. Para isto, basta utilizar um dos tipos padrão de dados simplespara forçar o dado em questão a ser adequado ao tipo definido como pode ser observado nos exemplos da figura 2.3. valor1 = int (10.5) 22 valor2 = int ("10") valor3 = 15.5 print (valor1 + valor2 + int (valor3)) 35 15.5 Figura 2.3: Exemplo de uso de conversão forçada de tipo. Fonte: O autor. Neste exemplo da figura 2.3, são utilizadas três variáveis, mas apenas duas têm seus dados convertidos para inteiros logo na sua inicialização. A terceira tem seu valor convertido apenas para utilização como um dos operadores passados como parâmetro para a expressão da função print(). Depois, em posterior exibição do valor da variável valor3 sem conversão, pode-se observar que seu valor original foi mantido. Manipulação De Strings As strings são consideradas dados, e por isto, necessitam de estruturas de dados para serem armazenadas para uso durante a execução de um código. O uso das aspas simples é o método mais simples e dentro do conteúdo das aspas não se podem utilizar aspas duplas para evitar confusão pelo compilador ao interpretar a linha de comando. As aspas duplas são as mais utilizadas e permitem o uso de aspas simples dentro de seu conteúdo para indicar termos destacados, por exemplo. As aspas triplas permitem o uso de aspas duplas e formatação com quebras de linhas no conteúdo da string, e assim, se torna uma opção mais completa em termos de utilização de strings, sendo esta, uma opção não presente na maioria das linguagens. 23 Observe o exemplo de código a seguir na figura 2.4 contendo formas de uso das aspas em funções de saída de dados e atribuições. texto = 'Teste' print ("\nString indicada por aspas simples: ") print (texto) texto = "Teste do uso de ‘aspas simples’" print ("\nString indicada por aspas duplas: ") print (texto) texto = '''Teste de uso de "aspas duplas"''' print ("\nString indicada por aspas triplas: ") print (texto) texto = '''Texto utilizando quebras de linha''' print ("\nString indicada por aspas simples: ") print (texto) Figura 2.4: Exemplos de uso das aspas em strings. Fonte: O autor. Estes exemplos da figura 2.4 servem para ilustrar diferentes usos das aspas simples, duplas e triplas indicando as possibilidades de uso de outros tipos de aspas dentro das strings a serem exibidas ou formatação diferenciada permitida com as aspas triplas. As strings funcionam como listas de caracteres, e por isto, seus elementos podem ser referenciados individualmente através da indicação da posição na lista com colchetes. Isso pode ser muito útil quando se realiza análise de conteúdo de strings para buscar ou alterar caracteres em algoritmos diversos. Observe o exemplo da figura 2.5 onde é exibido apenas o quarto caractere da palavra, lembrando que os índices de listas iniciam sua contagem em zero, e por isto o valor 3 é utilizado para este quarto caractere. 24 texto = "Teste" print ("\nQuarto caractere da string: ") print (texto[3]) print (texto[1:3]) texto[0] = "t" print (texto) del texto print (texto) Figura 2.5: Exemplos de uso das aspas em strings. Fonte: O autor. Uma variação na indicação de índices para uso de strings é que é possível indicar uma faixa de índices a serem trabalhados, onde o elemento inicial e final da sequência deve ser informado nos colchetes, separados por sinais de dois pontos como indicado no exemplo da figura 2.5 que exibe os caracteres “est” relativos à faixa de dados do índice 1 ao 3 da string. A atribuição pode ser utilizada tanto para se incluir dados em variáveis, por exemplo, e esta inclusão normalmente ocorre com dados que preenchem as variáveis, mas no caso das strings, como representam listas de dados, estas podem ter dados atribuídos de forma a preenche-las por completo como na linha texto = "Teste", ou parcialmente através do uso de índice como foi feito na linha texto[0] = "t" que ajustou apenas um caractere da string. Excluir caracteres de uma string é algo que pode ser feito, mas não de forma tão direta. Existe o comando del que apaga o conteúdo todo de uma string de uma vez apenas como mostrado na figura 2.5 pela linha del texto, mas a exclusão de um ou mais caracteres separadamente é algo que deve ser realizado por um processo que deve ser implementado através de uma varredura na string e posterior deslocamento dos caracteres seguintes para posições anteriores sucessivamente de forma a dar a impressão do caractere ter sido suprimido. 25 Uma string também pode ser composta por strings que unidas, formam uma nova cadeira de caracteres e pode ser um recurso bastante útil na manipulação de dados deste tipo. Casos como nomes de pessoas obtidos separadamente podem ser unidos, partes de um endereço, etc. A seguir seguem alguns exemplos de uso de strings compostas por partes nos exemplos da figura 2.6. texto = "{} {} {}".format ('Parte 1', 'Parte 2', 'Parte 3') print ("\nString completa na ordem natural das partes da string: ") print (texto) texto = "{1} {0} {2}".format ('Parte 1', 'Parte 2', 'Parte 3') print ("\nString completa na ordem indicada pelas chaves para as partes da string: ") print (texto) texto = "|{:<10}|{:^10}|{:>10}|".format ('Parte 1', 'Parte 2', 'Parte 3') print ("\nExemplos de alinhamento independente em partes da string: ") print (texto) texto = "{0:.2f}".format (1/3) print ("\nExemplo de formatação de casas decimais com arredondamento para : ") print (texto) Figura 2.6: Exemplos de uso das aspas em strings. Fonte: O autor. Nos exemplos trazidos na figura 2.6, o primeiro trecho utiliza as strings 'Parte 1', 'Parte 2', 'Parte 3' como elementos para compor uma nova string armazenada na variável texto. A exibição ocorre nesta ordem, pois as chaves que representam índices para cada parte, estão em branco, e assim, prevalece a ordem de inserção, mas no segundo trecho, a indicação "{1} {0} {2}" faz com que a ordem de exibição se altere e o elemento 'Parte 2' seja exibido antes do elemento 'Parte 1'. No terceiro trecho do código do exemplo da figura 2.6 é mostrado como se pode utilizar alinhamento na exibição através dos parâmetros "|{:<10}|{:^10}|{:>10}|" 26 que permitem a exibição dos elementos da string alinhados respectivamente a esquerda, centralizado e a direita. Na sequência, o último trecho de código traz um exemplo de número formatado com duas casas decimais através do parâmetro "{0:.2f}" utilizado juntamente com o método format para ajustar o resultado da divisão entre 1 e 3 que resulta em dízima periódica e é reduzida a 0,33. Complementarmente ao que foi citado até o momento sobre a manipulação de strings utilizando recursos próprios da linguagem Python, existem muitos métodos desenvolvidos para proporcionar funcionalidades adicionais importantes para a manipulação de strings. Alguns exemplos de métodos que podem ser utilizados com maior ou menor frequência aplicados em uma string qualquer indicada por “s” são descritas a seguir na tabela 2.1. s.capitalize() Manipula uma string de forma a transformar apenas seu primeiro caracteres em maiúscula se possível. s.center(width, char) Modifica uma string original adaptando-a a uma nova quantidade de caracteres centralizando a string original na quantidade de caracteres e preenchendo os caracteres excedentes com o caractere indicado como parâmetro. s.ljust(width, char) Modifica uma string original adaptando-a a uma nova quantidade de caracteres alinhando à esquerda a string original na quantidade de caracteres e preenchendo os caracteres excedentes com o caractere indicado como parâmetro. s.rjust(width, char) Modifica uma string original adaptando-a a uma nova quantidade de caracteres alinhando à direita a string original na quantidade de caracteres e preenchendo os caracteres excedentes com o caractere indicadocomo parâmetro. 27 s.count(t) Devolve a quantidade de ocorrências de um caractere especificado pelo parâmetro “t” na string. s.find(t, start, end) Retorna a posição para um caractere “t” encontrado na string. Se nada for encontrado retorna -1. s.isalnum() Devolve verdadeiro (True) se a string não estiver vazia e apenas com caracteres alfanuméricos. s.isalpha() Devolve verdadeiro (True) se a string não estiver vazia e apenas com letras. s.isdecimal() Devolve verdadeiro (True) se a string não estiver vazia e apenas com números no padrão Unicode. s.isdigit() Devolve verdadeiro (True) se a string não estiver vazia e apenas com números no padrão ASCII. s.islower() Retorna verdadeiro (True) se todos os caracteres de uma string são considerados minúsculos. s.isuper() Retorna verdadeiro (True) se todos os caracteres de uma string são considerados maiúsculos. s.join(t) Insere o caractere “t” entre cada caractere da string. s.lower() Converte e retorna todos os caracteres da string minúsculos. s.upper() Converte e retorna todos os caracteres da string maiusculas. s.partition(t) Retorna a string fracionada em três partes, sendo a parte antes do caracteres “t”, o próprio caractere e a parte posterior. s.split(t) Retorna uma série de strings fracionadas da string original utilizando o caractere “t” como separador, ou espaços em branco se não for indicado um caractere específico. s.swapcase() Retorna nova string invertendo caracteres maiúsculos e minúsculos. s.title() Devolve nova string onde todos os primeiros caracteres da string original são convertidos em maiúsculos. 28 s.zfill(n) Retorna nova string onde, caso a string seja menor que “n”, os caracteres mais a esquerda são preenchidos com zeros. Tabela 2.1: Exemplos de métodos para manipulação de strings. Fonte: O autor. Para testar estes métodos é interessante criar scripts com código contendo estes métodos para manipular e atuar em strings diversas aplicando estes métodos para compreender como podem ser utilizados, assim como é mostrado no exemplo de script da figura 2.7. texto = "Exemplo de string" letra = "e" print ("\n", texto) print ("A letra 'e' está inicialmente na posição: ", end="") print (texto.find( letra, 1)+1 ) print ("A letra 'e' está por último na posição: ", end="") print ( texto.rfind( letra, 1)+1 ) texto1 = texto.lower(); print ("Todos os caracteres em minúsculo: " + texto1) texto2 = texto.upper(); print ("Todos os caracteres em maiúsculo: " + texto2) texto3 = texto.swapcase(); print ("Inversão entre maiúsculas e minúsculas: " + texto3) texto4 = texto.title(); print ("Primeira letra maiúscula: " + texto4) print ("\nTamanho do texto: ", len(texto)); print ("O caractere 'e' aparece: ",end="x") 29 print (texto.count("e",0,15)) print ("Exemplo de alinhamento centralizado usando '-': ",end="") print ( texto.center(30,'-')) print ("Exemplo de alinhamento à esquerda: ",end="") print ( texto.ljust(30,'-')) print ("Exemplo de alinhamento à direita: ",end="") print ( texto.rjust(30,'-')) Figura 2.7: Exemplço de script para manipulação de string. Fonte: O autor. Nos exemplos do script da figura 2.7, inicialmente são declaradas duas variáveis texto e letra. Na sequência a string é exibida apenas para conferência do que está contido na variável texto. O trecho de código a seguir utiliza os métodos find e rfind para buscar o caractere “e” contido na variável texto e indicar sua posição na string. Um detalhe é que foi somado 1 ao resultado da busca, pois como a busca retorna um índice na string, é mais intuitivo a um usuário que a contagem seja iniciada em 1 ao invés de 0, padrão na linguagem. O trecho seguinte de código realiza conversões dos caracteres utilizando os métodos lower, upper, swapcase e title para que as variáveis texto1, texto2, texto3 e texto4 contenham a mesma string, mas com as string alteradas respectivamente, para todos os caracteres em minúsculos, maiúsculos, invertidos em relação à string original, e apenas com o primeiro maiúsculo. Na sequência, o trecho de código seguinte informa a quantidade de caracteres da string original contida na variável texto, e depois informa a quantidade de vezes que ocorrem o caractere “e” na string. Por fim, o último trecho de código exemplifica o posicionamento de texto com alinhamentos variados (esquerdo, centralizado e direito) inserindo a string em 30 uma sequência de 30 traços, de acordo com o alinhamento indicado em cada comando com os métodos center, ljust e rjust. O uso de texto em programação é bastante variado e útil, pois muitas aplicações desenvolvidas se baseiam em texto como base de dados a trabalhar, e este texto pode estar todo desestruturado em termos de estrutura de dados como num texto de um documento, por exemplo. Existem muitos recursos disponíveis em bibliotecas disponíveis que podem facilitar a manipulação destes textos e strings quaisquer. Bibliotecas como a re.py (regular expression) possui uma série de expressões para realização de buscas a partir da construção de expressões regulares elaboradas a partir de uma sintaxe própria que utiliza símbolos combinados a caracteres para definir alfabetos e strings que podem ser construídas com este alfabeto. Observe o exemplo da figura 2.8 que mostra como se pode extrair valores numéricos de uma string qualquer. import re def buscaNumeros (texto): resultado = re.findall (r'[0-9]+', texto) return resultado texto = "abc12def34fgh56ij78kl90" resultado = buscaNumeros (texto) print (*resultado) Figura 2.8: Exemplo de uso de expressões regulares. Fonte: O autor. Neste exemplo da figura 2.8 é possível observar alguns aspectos novos e relevantes como a adição do comando de importação da biblioteca para uso de expressões regulares import re.Em seguida, é implementada uma pequena função que utiliza o método findall () para realizar uma busca por valores entre 0 e 9 dentro da string contida em texto. Todos os valores encontrados são 31 armazenadas na variável resultado que é devolvida como retorno da função para o código principal. O código principal que vem na sequência contém a inicialização da variável texto com uma string de exemplo qualquer contendo letras e números. Em seguida, a variável resultado é inializada com a própria função para execução da busca a partir da regra da expressão regular aplicada na variável texto. Por fim, o resultado obtido apenas com valores numéricos é exibido ao usuário. Assim como existe a biblioteca re.py, há outras alternativas de bibliotecas, além de que o próprio desenvolvedor pode criar suas próprias bibliotecas .py e utilizá- las livremente em diversos scripts que vá desenvolver. 32 Conclusão Ao final dos estudos desta unidade, pode-se concluir que houve uma evolução no aprendizado e elementos mais técnicos da linguagem estão sendo tratados de forma a aumentar a compreensão da linguagem e suas particularidades. Os tipos de dados vistos são a base da programação Python e precisam ser conhecidos para que se possa desenvolver soluções computacionais partindo do correto uso de dados que representam a base do uso de software. Os dados podem ser organizados de forma simples, mas também podem ser agrupados em estruturas mais complexas como as que foram tratadas, mas uma delas teve um enfoque maior nesta unidade devido às suas muitas aplicações. As strings representam a base dos dados em Python e possuem muitos recursos de manipulação, sendo que várias foram trabalhadas nesta unidade. Na unidade seguinte, os operadores e seu uso, assim como funções de entrada e saída de dados serão tratados para a continuidade dos estudos. 33 UNIDADE III Introdução Após o estudo da base da linguagem Pythonem relação a sua sintaxe e posteriormente, as possibilidades de uso de dados simples ou em estruturas mais complexas, segue o avanço nos estudos. A seguir, os operadores que são muito utilizados em programação, são divididos em categorias para estudos e posterior aplicação na construção de expressões matemáticas e lógicas, por exemplo. Na sequência, são trabalhados os conceitos essenciais de entrada e saída de dados que são simples, mas essenciais para o desenvolvimento de software, pois além do processamento de dados, é preciso adquirir dados e exibir resultados a usuários normalmente. 34 Expressões e Operadores Aritméticos A matemática é a área que mais se adequa a linguagem Python devido a algumas particularidades da linguagem como variáveis numéricas que aceitam valores de qualquer tamanho e poderem assim, realizar cálculos muito precisos com estes valores, por exemplo. O interpretador da linguagem pode realizar cálculos diretamente sem que um script completo com funções e outros comandos seja desenvolvido, e assim, acaba se tornando uma ferramenta bastante versátil na sua funcionalidade. Existem detalhes que são perceptíveis durante o uso do prompt do shell de execução de comandos e scripts Python como a forma como valores atribuídos a variáveis são exibidos ao usuário e alguns exemplos simples são ilustrados na figura 3.1. >>> 2 + 2 4 >>> 1/3 0.3333333333333333 >>> 1//3 0 >>> 5 % 4 1 >>> 2 % 3 2 >>> 2*3 6 >>> 2**3 8 >>> 2 + (3 * 2) ** 2 38 >>> 2 + 3 * 2 ** 2 35 14 Figura 3.1: Exemplos de expressões e comandos no shell Python. Fonte: O autor. Observando os exemplos da figura 3.1, tem-se inicialmente uma simples soma com seu resultado exibido logo a seguir. Depois, é utilizada a barra de duas maneiras diferentes para mostrar a diferença entre dois operadores gerados com o mesmo caractere. Usando-se uma barra, é realizada uma divisão simples que gera um resultado exato com casas decimais se necessário, ao passo que usando barras duplas, a divisão é realizada também, mas apenas a parte inteira do resultado é exibida e a parte decimal excluída sem que seja feito qualquer arredondamento. Outro operador utilizado se baseia no símbolo % e realiza um cálculo chamado de módulo e complementa o cálculo realizado pelo operador //, pois enquanto este traz como resultado a parte inteira do resultado, o módulo traz o resto da divisão inteira que geraria na sequência dos cálculos, a parte decimal como mostrado no exemplo da figura 3.1 onde o módulo de 5 por 4 retorna 1, representando o resto da divisão inteira. Na sequência, a figura 3.1 traz o uso do operador asterisco simples e duplo para demonstrar as operações de multiplicação e exponenciação que são, respectivamente realizadas com estes operadores. Por fim, a figura 3.1 traz um exemplo de expressão usando diferentes operadores e estabelecendo precedência forçada em uma das operações com o uso de parênteses. Sem eles, o resultado da operação seria diferente, como mostrado também na figura 3.1, e assim os resultados variam entre 38 com parênteses que força a soma ser realizada primeiro, e 14, sem os parênteses. Os operadores possuem regras de uso e precedência de operadores, e estas precisam ser seguidas, pois erros de sintaxe serão identificados em expressões mal elaboradas. É preciso estar atento às regras e precedência de operadores, pois isto afeta diretamente resultados, e em usos matemáticos mais complexos, 36 um pequeno equívoco na elaboração de expressões pode não gerar erros de sintaxe, mas pode comprometer toda a validade do código implementado. Como regra geral da linguagem Python e várias outras, os parênteses são a maior prioridade, e depois vem o operador ** (exponenciação). Na sequência, os operadores * (multiplicação) e / (divisão) são os próximos em precedência. Por fim, os que são realizados por último, são os cálculos utilizando os operadores + (soma) e – (subtração). No caso de operadores de mesmo nível, vale a regra base de expressões serem calculadas da esquerda para a direita no caso de operadores de mesmo nível de precedência. Em strings podemos usar dois operadores normalmente usados com números o + de soma que em strings significa concatenação e o * de multiplicação que para string significa replicação. Isto já foi exemplificado anteriormente, e complementa o uso de operadores e expressões. Operadores Relacionais Além dos operadores aritméticos utilizados em expressões, existem os operadores relacionais que permitem validações em comparações entre dados que pode ser simplesmente informados ou estarem inclusos em estruturas de dados. Os operadores relacionais são == (igual), != (diferente), > (maior), < (menor), >= (maior ou igual), e <= (menor ou igual), e são utilizados com um operando a esquerda do operador e outro a direita como mostrado nos exemplos da figura 3.2. >>> 1 > 1 False >>> 1 >= 1 True >>> 2 == 2 37 True >>> 3 >= 2 True >>> print (5 < 6) True Figura 3.2: Exemplos de uso de operadores relacionais. Fonte: O autor. Nestes exemplos da figura 3.2, temos algumas comparações realizadas diretamente no prompt de interpretação de comandos onde são colocados alguns exemplos que resultam False (falso) ou True (verdadeiro) dependo dos operando utilizados com cada operador. No último exemplo é utilizada a função de saída de dados apenas para diferenciar o uso, mas resultando no mesmo tipo de saída para o usuário. Estes operadores são muito utilizados em comandos da linguagem que se baseiam em condições para realizar suas ações e serão reutilizados ao longo deste material em diversos exemplos para outros conceitos. Operadores Lógicos Muitas vezes são elaboradas expressões utilizando operadores relacionais para comparar valores, por exemplo. Estas comparações podem ser simples na maioria dos casos, mas às vezes é preciso realizar mais de uma comparação de uma única vez para avaliar condições compostas. Para elaborar estas composições, é preciso estar atento a regras para uso de operadores lógicos que são capazes de integrar condições simples, pois seu uso se baseia na teoria de tabelas-verdade e para analisar este funcionamento, observe os exemplos da figura 3.3. 38 >>> (3 > 4) and (5 >= 2) False >>> (3 < 4) and (5 >= 2) True >>> (3 > 4) or (5 >= 2) True >>> (3 < 4) or (5 >= 2) True >>> (3 > 4) or (5 <= 2) False Figura 3.3: Exemplos de uso de operadores lógicos e relacionais. Fonte: O autor. Nestes exemplo da figura 3.3 é possível avaliar o que ocorre com as combinações de situações colocadas de variação de operadores relacionais e lógicos “and” equivalente ao “e” da língua portuguesa, e “or” equivalente ao “ou” da língua portuguesa. Nos dois primeiros exemplos, o que acontece é que a primeira condição (3 > 4) é falsa, e por isto, o operador “and” automaticamente já retorna falso, pois para que este operador retorno verdadeiro, é preciso que todas as condições sejam verdadeiras, como ocorre no exemplo seguinte onde (3 < 4). Nos três exemplos finais, utiliza-se o operador “or” para avaliar combinações das condições utilizadas nos dois primeiros exemplos. No exemplo (3 > 4) or (5 >= 2), como pelo menos a segunda condição é verdadeira, a expressão toda já resulta verdadeiro. No exemplo (3 < 4) or (5 >= 2), como as duas condições são verdadeiras, basta a primeira ter sido verdadeira para que a expressão também retorne verdadeiro. Apenas na última expressão onde ambas as condições são falsas, o resultado foi também falso. Observe a tabela 3.1 a seguir contendo os resultados possíveis para os operadores “and” e “or”. 39 CONDIÇÃO 1 CONDIÇÃO 2 AND OR V V V V V F F V F V F V F F F F Tabela 3.1: Combinações de resultados para os operadores AND e OR. Fonte: Oautor. A partir desta tabela 3.1, é possível observar que para uma expressão “and” resultar verdadeiro, todas as condições precisam também ser verdadeiras, e no caso do operador “or”, apenas será falsa uma expressão onde todas as condições resultarem também falsas. Operadores Compostos De Atribuição Uma combinação que é possível na linguagem Python e representam simplificações de atribuições realizadas a partir de pequenas expressões se baseiam nos operadores +=, -=, *=, /=, %=, //=, **= e outros mais específicos . Observe os exemplos a seguir na figura 3.4 para compreender seu uso e finalidade. >>> x = 5 >>> x = x + 5 >>> x += 5 >>> print (x) 15 >>> x -= 3 >>> print (x) 40 12 >>> x *= 2 >>> print (x) 24 >>> x /= 3 >>> print (x) 8.0 >>> x %= 3 >>> print (x) 2.0 Figura 3.4: Exemplos de operadores compostos de atribuição. Fonte: O autor. Nestes exemplos da figura 3.4 são realizadas atribuições simples e compostas em sequência com exibição dos valores sendo atualizados da variável x para mostrar como agem estes operadores. Inicialmente, após a atribuição do valor 5 à variável, logo em seguida é realizada uma soma para aumentar o valor de x. Depois, é utilizado o operador += para que a mesma soma seja novamente realizada, mas com esta nova sintaxe, sendo então o valor das duas somas confirmado com a exibição do valor da variável atualizado para 15. Depois são realizadas sucessivas atribuições compostas para ir alterando o valor da variável utilizando os demais operadores de atribuição compostos para que o valor da variável seja alterado e seu valor exibido novamente como comprovação do cálculo e atribuição realizados em conjunto. Ao final, a última atribuição composta realiza uma operação de módulo de 8 com 3 que resulta em resto 2 que fica armazenado como novo valor para a variável x. Assim, conhecendo os operadores e podendo então estar apto a lidar com dados básicos em Python, é possível seguir adiante com os estudos. 41 Dois operadores importantes e não muito comuns em muitas linguagens são os operadores “is” e “in” que representam operações de comparação entre objetos e entre elementos e objetos. Observe o exemplo de uso dos operadores na figura 3.5. x = [1, 2] y = [1, 2] z = x print (x is z) print (x is y) print (x == y) print (2 in x) True False True True Figura 3.5: Exemplos de uso de operadores para objetos. Fonte: O autor. Neste exemplo da figura 3.5 de uso de operadores “is” e “in” são declarados dois objetos x e y contendo listas de dados numéricos. Depois é associado ao objeto z, o objeto x. A partir destas atribuições, as funções print() exibem diferentes resultados True ou False em função do uso dos operadores para objetos. A primeira função print() retorna True, pois como x foi atribuído a z, ambos são considerados o mesmo objeto pela atribuição feita, ao passo que a segunda função retorna False, pois mesmo tendo os mesmos elementos, não representam o mesmo objeto. 42 Depois, a terceira função retorna True, pois os dois objetos x e y possuem os mesmos objetos, e a última função retorna True também, pois o elemento 2 está contido nos dados do objeto x. Entrada e Saída Na linguagem Python, duas funções são disponibilizadas para realizar interação de entrada e saída padrão com usuários. A função input() é responsável pela entrada de dados e a função print() pela saída de dados. As duas funções podem utilizar parâmetros para que suas funcionalidades possam ser utilizadas, e no caso da função input(), o parâmetro é opcional que aceita a inclusão de uma string (cadeia de caracteres em forma de texto) que pode ser adicionada para melhorar a interface com o usuário exibindo a mensagem que possui o intuito de auxiliar no preenchimento do dado esperado. Já no caso da função de saída, além de strings que posem ser inseridas sequencialmente, separadas por vírgulas, também podem ser incluídos identificadores de variáveis para que seus conteúdos possam ser exibidos aos usuários. A função print() aceita uma maior variedade de parâmetros, e recursos adicionais podem ser aceitos como indicações de inserção de valores em partes de strings, por exemplo como exibido nos exemplos da figura 3.6 a seguir. print (' Texto Exemplo') print ("Primeira linha\nSegunda linha") print (r'Caractere \n anulado com o uso de r antes da string') print ('Exemplo', 'de String', 'Fracionada') Figura 3.6: Exemplo de código de saída de dados. Fonte: O autor. 43 No primeiro exemplo da figura 3.6, uma exibição simples da string ‘Texto Exemplo’ ao usuário, lembrando que as strings em Python são identificadas com aspas simples ou duplas, mas as simples são mais comumente usadas no desenvolvimento de software. Outro detalhe relevante é que na versão 2 da linguagem, não se utilizam parênteses na função print() para indicar seus parâmetros. No segundo exemplo, um detalhe importante é a possibilidade de uso de caracteres especiais para realizar ações com strings, como o uso do caractere especial “\n” que permite a inserção de quebras de linha dentro de strings para melhor formatação do texto. Um detalhe curioso exibido no terceiro exemplo da figura 3.6 é o uso da letra “r” como parâmetro logo à esquerda da string no comando para que o caractere especial “\n” seja tratado como texto simples a ser exibido, perdendo assim, naquele comando, a função de quebra de linha. Este recurso é utilizado quando se deseja que a própria representação do caractere seja exibida numa string. Por último, no quarto exemplo da figura 3.6, o uso da vírgula permite que mais de um parâmetro seja passado à função print() e todos sejam processados sequencialmente pela função, observando que não apenas strings podem ser utilizadas como parâmetros na função print(). A função input() permite a entrada de dados em Python e por ser uma função, necessita que um dado retornado seja armazenado em uma estrutura de dados para que este dado seja armazenado em memória temporária e esteja posteriormente disponível para processamento durante a execução do programa. A função input() em si é bastante simples e possui menor variação de uso em relação à função print(), facilitando seu aprendizado. Observe os exemplos da figura 3.7 para análise do seu uso. dado = input() 44 nome = input ('Digite seu nome: ') valor = float ( input ('Digite um valor: ')) Figura 3.7: Exemplos de entrada de dados. Fonte: O autor. No primeiro exemplo da figura 3.7, a forma básica da função onde a mesma é apenas atribuída a uma variável simples sem uso de parâmetro algum. Um detalhe é que como na linguagem não é necessária declaração tipada de estruturas de dados, a variável terá um tipo definido a partir do momento que algum dado for atribuído a ela. No segundo exemplo, um parâmetro é informado à função input() para que a mensagem indicada seja exibida ao usuário de forma a auxiliar na correta digitação de dados, pois como não foi definido um tipo, se não for indicado ao usuário um auxílio sobre o tipo de dado desejado, este pode não ter ideia do que é esperado pelo software e assim, fornecer entradas de dados inadequadas. No terceiro exemplo da figura 3.7, uma funcionalidade complementar é inserida, onde é especificado através da função float() que o dado retornado pela função input() deve ser convertido, se necessário em valor do tipo decimal antes de ser atribuído à variável “valor”. Isto permite uma validação da entrada de dados e melhora a robustez e funcionalidade do programa em execução. Existem muitas variações de uso de funções de saída de dados, e uma das particularidades da linguagem é a possibilidade do uso da elaboração de certo tipo de expressões como parâmetro combinando valores, operador e strings, por exemplo. Observe os exemplosda figura 3.8 para compreender a ideia de uso. >>> print (10 * 'É possível usar operadores em strings\n') É possível usar operadores em strings É possível usar operadores em strings É possível usar operadores em strings 45 É possível usar operadores em strings É possível usar operadores em strings É possível usar operadores em strings É possível usar operadores em strings É possível usar operadores em strings É possível usar operadores em strings É possível usar operadores em strings >>> print (3 * '#', 'Teste com String', 3 * '#') ### Teste com String ### >>> print (3 * '#', '5 + 5 = ', 5+5, 3 * '#') ### 5 + 5 = 10 ### Figura 3.8: Exemplos de constrção de função de saída com expressão. Fonte: O autor. Nos exemplos da figura 3.8, o primeiro contém uma multiplicação de uma string como parâmetro da função de saída que faz com que como resultado, a string seja repetida certo número de vezes, assim como no exemplo seguinte onde o símbolo “#” é multiplicado duas vezes para gerar um simples efeito de destaque em conjunto com o texto a ser exibido, e por fim, o último exemplo une os componentes variados que podem ser combinados como parâmetros. Além desse tipo de expressão, a função de saída de dados print() aceita parâmetros como quebras de linha representados pelo marcador \n já citado, e espaços em branco para separar cada parâmetro na função, por exemplo, mas além de parâmetros mais simples como estes, esta função permite que se manipule arquivos de texto usando a saída padrão como destino (monitor). Um detalhe importante é não confundir o símbolo “#” utilizado no exemplo com sua finalidade na elaboração de scripts em linguagem Python. Observe os exemplos da figura 3.9 de uso de comentários em linguagem Python para compreender este importante recurso de documentação de código. 46 # Exemplo de comentário de apenas uma linha ''' Comentários com mais de uma linha podem ser divididos em blocos utilizando-se o limitador ''' Figura 3.9: Exemplos de uso de comentários em linguagem Python. Fonte: O autor. Nos exemplos da figura 3.9, como o próprio texto do exemplo cita, o símbolo “#” é utilizado para comentários curtos de apenas uma linha no editor, e os comentários utilizando o delimitador de três aspas simples pode se dividir em várias linhas para que parágrafos inteiros possam ser utilizados como comentários. 47 Conclusão Após os estudos de como trabalhar com a grande quantidade de operadores disponíveis na linguagem Python e compreender como se pode aplicar estes operadores nos diferentes tipos de expressões que podem ser elaborados com estes operadores, desde cálculos matemáticos a condições que podem utilizar mesclas de operadores para compor avaliações lógicas que são a base de estruturas que serão trabalhadas na sequência dos estudos. Para completar os conceitos desta unidade, foram estudadas formas básicas de obtenção de dados junto a usuários para armazenamento em estruturas de dados. Também foram vistos conceitos de saída de dados envolvendo a construção de mensagens a serem exibidas a usuários mesclando elementos e utilizando caracteres especiais. Na sequência dos estudos, a próxima unidade trata da manipulação de arquivos de texto, e estruturas de controle de fluxo durante a execução de aplicações. 48 UNIDADE IV Introdução Após conhecer mais sobre a linguagem Python através do estudo de operadores e a construção de expressões, além do uso de recursos de entrada e saída de dados, é a hora de trabalhar mais forte com a parte lógica da linguagem. Primeiramente, para complementar os estudos sobre o uso de dados e implementação de estruturas de dados, é importante conhecer como se pode armazenar dados de forma permanente em disco e sempre que necessário, manipulá-los. Depois, são conhecidas as principais formas de organização lógica do processamento de dados e demais ações durante a execução de uma aplicação utilizando estruturas de controle que se dividem em estruturas de decisão e de repetição que necessitam de atenção a sua elaboração, pois utilizam de raciocínio lógico na elaboração de expressões lógicas e no controle de suas ações. 49 Arquivos De Texto Para se trabalhar com arquivos do tipo texto, mais comuns e que representam um tipo de dado bom para se complementar o uso da função print() de saída de dados. Esta manipulação de arquivos em Python não é complexa e se mostra um recurso bastante útil, pois permite que dados sejam gravados em disco e assim, uma aplicação possa ser executada em momentos distintos tendo como base os dados gravados na execução anterior, por exemplo. Basicamente, o processo de uso de arquivos se baseia na associação de um arquivo a um objeto instanciado como arquivo com file e aberto para leitura, gravação ou adição de dados com a função open(), usando uma string para indicação do nome do arquivo e um parâmetro adicional que define o modo de abertura do arquivo. Os modos básicos de abertura de arquivos para a função open() são r apenas para leitura, w para escrita, mas substituindo o conteúdo anterior, a para adicionar dados novos ao final do arquivo já existente, x para criar um novo arquivo vazio para escrita, b para arquivos binários (não texto), t para arquivos de texto (é o padrão em Python), e + para que possam ser atualizados os dados de um arquivo já existente. Um detalhe sobre arquivos de texto, é que este tipo de arquivo contém dois caracteres especiais que significam EOL que representa o final de cada linha de texto, e EOF que representa o final do arquivo em si. Para o final de linha, pode- se utilizar \n como em strings normais da função de saída de dados. Além da função open(), há métodos que são acionados com o objeto de arquivo instanciado para funcionalidades de manipulação do arquivo como write() para adicionar texto ao arquivo, seek() para posicionamento no arquivo, read() para leitura de dados, e close() para fechamento do arquivo de forma adequada, reduzindo a chance de se corromper o arquivo. 50 Observe o exemplo de script da figura 4.1 para compreender o processo de abertura de um arquivo de texto, a inserção de dados neste, a busca pelo texto inserido e sua exibição ao usuário. file = open ('arquivo.txt', 'w+t') file.write ('Linha 1\nLinha 2\nLinha 3'\nLinha 4'\nLinha 5') file.seek (0) print (file.read() ) file.close () Linha 1 Linha 2 Linha 3 Linha 4 Linha 5 Figura 4.1: Exemplo de abertura de dados Neste exemplo da figura 4.1, primeiramente, um objeto file é instanciado com o nome de arquivo “arquivo.txt” e seu modo de abertura é “w+t” que significa que o arquivo deve ser sobrescrito toda vez que for executado o script, seus dados possam ser atualizados e seu conteúdo seja do tipo texto. Se fosse utilizado apenas “w” também funcionaria, pois este modo já abre e sobrescreve um arquivo permitindo a inserção de dados, e como padrão, como não indicado, o arquivo seria do tipo texto, neste caso. Em seguida, o método write() associado ao objeto file realizará a inserção da string com quebras de linha no arquivo como se pode observar no resultado final da string onde a string é dividida em 5 linhas. Depois, o método seek(0) representa uma quantidade de avanço de caracteres no conteúdo do arquivo para sua manipulação. Depois, a função print() contém como parâmetro o método read() associado ao objeto file para leitura dos dados 51 do arquivo todo e posterior exibição destes. Por fim, o método close() associado ao objeto file fecha o arquivo. Pode-se, ao invés de efetuar a leitura de todo o arquivo de dados, ler apenas uma linha através do método readline() que lê caracteres até encontrar uma marcação de EOL que avise do término do conteúdo a ser lido nomomento. Este método pode ser utilizado seguidas vezes para que linhas vão sendo lidas em sequência ou até incluído em estruturas de repetição para esta finalidade. Um recurso adicional para a manipulação de arquivos é a exclusão de arquivos ou pastas baseando-se em uma biblioteca chamada “os” que representa acesso à funcionalidades do sistema operacional para gerenciamento de arquivos, por exemplo. Observe os exemplos da figura 4.2. import os os.remove("arquivo.txt") os.rmdir("Dados") Figura 4.2: Exemplos de uso de funcionalidades do sistema operacional. Fonte: O autor. Com este recurso de importação da biblioteca “os”, é possível utilizar métodos como remove() e rmdir() para excluir, respectivamente, arquivos e pastas, como é feito nas interfaces de modo texto nos sistemas operacionais geralmente. Na instrução que utiliza o método remove(), o parâmetro indica o nome do arquivo a ser excluído, se existir, pois o nome informado pode não se referir a um arquivo existente na pasta onde se está sendo executado o script, e o método rmdir() exclui a pasta indicada como parâmetro caso exista. 52 Estruturas De Controle De Fluxo De Execução Avançando nos estudos de programação Python, inicia-se uma nova etapa onde a lógica é utilizada para que se estruture scripts que possam tomar decisões de forma automática a partir de condições que são implementadas no desenvolvimento, mas que o fluxo de execução só é afetado durante a execução, a partir da variação de dados em tempo real geralmente. Estrutura De Decisão Neste tipo de estrutura que envolve condições, é comum a elaboração de expressões lógicas baseadas em dados simples, variáveis e operadores, por exemplo e uma série de recursos estudados são úteis a partir desta etapa. O comando if é a base deste tipo de estrutura e permite como parâmetros condições que permitem ao comando optar entre realizar um bloco de instruções (ou instrução simples), ou outro bloco de comandos (ou instruções simples). Observe o exemplo da figura 4.3. valor1 = input ('Digite um valor: ') valor2 = input ('Digite outro valor: ') if valor2 < valor1: print("Entre", valor1, "e", valor2, "O primeiro valor é maior.") elif valor2 == valor1: print("Os valores são iguais.") else: print("Entre", valor1, "e", valor2, "O segundo valor é maior.") Digite um valor: 5 Digite outro valor: 7 Entre 5 e 7 O segundo valor é maior. Figura 4.3: Exemplo de estrutura de decisão ou condicional. 53 Fonte: O autor. Neste exemplo da figura 4.3, os valores para duas variáveis são solicitados ao usuário para depois, estes valores serem analisados pela estrutura da decisão. Esta estrutura de decisão é composta por três etapas, onde cada etapa utiliza um comando diferente e age de forma diferente. Na primeira etapa, o comando if possui uma condição onde o dado contido em valor2 é avaliado se menor que o dado de valor1. Se for verdadeira a condição, executa a função print() que diz que o primeiro valor é maior, lembrando que as demais etapas da estrutura de decisão são ignoradas se a primeira resulta verdadeiro. Na segunda etapa que é acionada apenas se a primeira etapa resultar falso é verificado se os dois dados contidos nas duas variáveis são iguais. Para isto, utiliza-se outro comando chamado elif. Caso seja verdadeira a condição nesta etapa, a função print() exibirá a mensagem sobre os valores serem iguais. O comando elif é usado tantas vezes quantas forem necessárias, variando-se as condições em cada uso. Assim, se houverem 5 condições diferentes possíveis a serem avaliadas numa mesma estrutura de decisão, é preciso utilizar um comando if na primeira e mais quatro comandos elif nas demais. Caso as etapas anteriores a última tenham todas valores falso para as condições e nada seja executado até então, a última etapa utiliza o comando else para exibir a mensagem de que o segundo valor é maior que o primeiro, pois seria esta referente a qualquer situação não atendida pelas condições anteriores, e assim, nem necessita de uma condição para este comando. São possíveis variações de uso na elaboração de estruturas de decisão de forma a simplificar a sintaxe da estrutura, mas também é possível aumentar a avaliação lógica realizada pelos comandos através da criação de condições mais complexas envolvendo duas ou mais condições agregadas a operadores lógicos and ou or. Observe os exemplos da figura 4.4. 54 valor1 = input ('Digite um primeiro valor: ') valor2 = input ('Digite um segundo valor: ') valor3 = input ('Digite um terceiro valor: ') # Análise apenas se valor1 > valor2 print (valor1, "é maior que", valor2) if valor1 > valor2 else print(valor2, "é maior que", valor1) # Análise mais completa verifica quem é maior ou se são iguais entre valor1 e valor2. print (valor1, "é maior que", valor2) if valor1 > valor2 else print(valor1, "e", valor2, "iguais") if valor1 == valor2 else print(valor2, "é maior que", valor1) Digite um primeiro valor: 20 Digite um segundo valor: 10 Digite um terceiro valor: 30 20 é maior que 10 20 é maior que 10 Figura 4.4: Exemplos de variações com estruturas de decisão. Fonte: O autor. Observando os exemplos da figura 4.4, pode-se observar que são duas estruturas de decisão distintas, onde a primeira mostra uma simplificação da sintaxe da estrutura e realiza apenas uma verificação se o primeiro valor é maior que o segundo. O segundo exemplo mantém a estrutura simplificada, mas realiza uma análise mais adequada dos dois valores, pois além de verificar se um é maior que o outro, possui a alternativa de serem iguais. Uma outra forma de se utilizar estruturas de decisão é inserindo uma dentro da outra para que sejam realizadas análises complementares em sequência, mas é muito mais complexa a lógica na elaboração destas estruturas chamadas de “aninhadas”. 55 dado = int (input ('Digite um valor: ')) resto = dado % 2 if dado >= 0: print("Este valor é positivo...") if resto == 0: print("e é par.") else: print("e é ímpar.") else: print (“Este valor é negativo.”) Figura 4.5: Exemplo de estrutura de decisão aninhada. Fonte: O autor. Neste exemplo da figura 4.5 existem alguns pontos importantes a serem observados e que com o tempo, a prática e a experiência permitirão que estas situações que ocorrem no exemplo possam ser previstas pelo programador. Um primeiro ponto é que se não for utilizado o método int() para conversão da entrada de dados para a variável dado de forma a garantir o tipo desejado para a condição, o interpretador pode acusar erro. Outro ponto de atenção é que a operação que verifica se o valor contido na variável dado dividido por 2 gera valor exato ou sobra 1 é feita antes da avaliação na condição, pois a linguagem não aceita a operação na condição do comando if. Observados os detalhes, a parte lógica é simples e este exemplo simplesmente realiza duas avaliações e a primeira possui avaliações complementares. Se o valor contido na variável dado for maior ou igual à zero, uma mensagem informa que o valor é par, e em seguida, passa a uma nova avaliação que verifica se pelo valor contido na variável resto, o valor digitado é par ou ímpar em uma estrutura de decisão aninhada. Caso contrário, se o valor contido em dado for 56 menor que zero, apenas mostra ao usuário uma mensagem informando que o valor é negativo. Estrutura De Repetição Neste segundo tipo de controle de fluxo, uma instrução ou bloco de instruções pode ser executada repetidas vezes de acordo com condições determinadas na implementação do código, mas que são avaliadas e executadas em tempo real, como no caso das estruturas de decisão. Um comando que pode ser utilizado para este tipo de situação é while que aceita condições como parâmetros
Compartilhar