Introdução a Algoritmos, Computação Algébrica e à Linguagem de Programação Python Curso de Números Inteiros e Criptografia Prof. Luis Menasché Schechter Departamento de Ciência da Computação UFRJ Agosto de 2013
Noção Básica: Algoritmos Definição Informal: Um algoritmo é uma sequência finita de instruções que, ao serem executadas, permitem transformar um conjunto de objetos inicial (entrada) em um novo objeto (saída). Algoritmos não existem apenas em computação. Uma receita de bolo é um algoritmo. Uma receita de bolo descreve os passos necessários para transformar os ingredientes como ovos e farinha (os objetos iniciais) em um bolo (um novo objeto). Algumas tarefas simples que podem ser resolvidas por algoritmos executados em um computador: Dado um conjunto de 10 números naturais, informe qual é o menor. Dado um conjunto de 10 números naturais, ordene-os em ordem crescente.
Noção Básica: Linguagem de Programação Para que um computador possa executar um algoritmo, ele precisa ser codificado de uma forma que o computador entenda. Computadores e seres humanos entendem linguagens diferentes. Linguagens humanas (português, inglês) podem produzir ambiguidades. Linguagens computacionais precisam ser rígidas, formais e precisas. Algoritmos são escritos nas chamadas linguagens de programação. As instruções nestas linguagens são então processadas e executadas pelo computador. Pascal, C, C++, Java, Python... As linguagens oferecem os chamados tipos de dados. São utilizados para codificar os objetos manipulados pelo algoritmo (os objetos iniciais, o objeto final e outros que possam ser necessários em etapas intermediárias).
Noção Básica: Sistema de Computação Algébrica Nosso curso lida com a Teoria dos Números Inteiros. Desta forma, estes números serão objetos centrais nos algoritmos que estudaremos e implementaremos. Linguagens de Programação de uso geral, como C, por exemplo, possuem um limite superior para o tamanho dos números com os quais elas conseguem lidar. Em geral, estes números são armazenados em uma palavra de memória de 32 bits, o que limita sua magnitude a no máximo 2 32 1. Nos nossos algoritmos, precisamos lidar com números arbitrariamente grandes. O algoritmo de criptografia RSA, que estudaremos no curso, é utilizado na prática com números inteiros de 200 algarismos.
Noção Básica: Sistema de Computação Algébrica (2) Outro problema com as Linguagens de Programação de uso geral está na maneira como elas realizam cálculos com frações. Estas linguagens normalmente realizam implicitamente a divisão do numerador de uma fração pelo seu denominador e armazenam o resultado até um número limite de casas decimais. Desta forma, o resultado da divisão em alguns casos fica trucado ou aproximado. Muitos algoritmos matemáticos precisam responder com exatidão determinados problemas com frações. Ao utilizar uma linguagem de programação de uso geral, os resultados retornados seriam aproximados, o que é aceitável em alguns casos, mas não em outros.
Noção Básica: Sistema de Computação Algébrica (3) Sistemas de Computação Algébrica (ou Computação Simbólica), também chamados de CAS, implementam cálculos com números inteiros arbitrariamente grandes, com frações na forma numerador/denominador (sem calcular aproximações) e com polinômios em forma simbólica (cálculo simbólico de integrais, por exemplo). O consumo de memória de um CAS é mais elevado do que o de uma Linguagem de Programação de uso geral. Os cálculos simbólicos são, geralmente, mais lentos. Escolha de Eficiência X Exatidão. Exemplos de CAS: Maple, Mathematica, Matlab, Singular, Axiom, Scilab...
Python Python é o nome de uma linguagem de programação. Podemos descrever os algoritmos nesta linguagem de programação para que possam ser executados no computador. O interpretador Python é um programa de computador que lê e processa algoritmos descritos na linguagem de programação Python e os executa no computador. A linguagem Python não oferece todas as possibilidades discutidas anteriormente que são oferecidas por CAS. Entretanto, ela oferece uma delas, a mais importante para as nossas necessidades: a possibilidade de cálculos com números inteiros arbitrariamente grandes. A linguagem Python conta com uma grande quantidade de funções prontas em uma Biblioteca de Funções. Estas funções podem ser utilizadas nos algoritmos escritos em Python.
O Ambiente de Desenvolvimento IDLE IDLE é o nome de um ambiente de desenvolvimento para escrever algoritmos em Python e executá-los. O IDLE é instalado junto com o interpretador Python na instalação em Windows. O IDLE fornece uma interface para facilitar o trabalho do programador e pode chamar por baixo dos panos o interpretador Python para executar os algoritmos escritos, quando solicitado. Desta forma, todo o trabalho de programação e testes pode ser realizado no mesmo ambiente.
Componentes Básicos da Linguagem Python Dados Variáveis Uma variável é um nome para uma posição de memória que será usada para armazenar dados. Uma variável pode armazenar um dado atribuído a ela através de um Comando de Atribuição. Cada dado e cada variável possui um Tipo de Dados. Dados são tipados implicitamente. Uma variável é tipada em acordo com o tipo do dado que está armazenado nela no momento (dynamic typing).
Componentes Básicos da Linguagem Python (2) Comando de Atribuição. Comentários. Operadores Aritméticos e Lógicos. Comandos Condicionais. Comandos de Repetição. Subrotinas ou Funções. Biblioteca de Funções. Comandos para definição de funções adicionais.
Alguns Tipos de Dados da Linguagem Python Tipo Descrição Exemplos int Número Inteiro de 32 bits 5, 12, -4 long Número Inteiro de Tamanho Arbitrário 8347648723648 float Número Real 5.0, 7.2, -12.77 bool Valor Booleano True ou False list Lista [1,4,10] str String (Texto) ola, "casa"
Comandos Básicos e Comentários Comando de Atribuição: Var = Valor. Ex: a = 3. Conversão Expĺıcita de Tipo: NovoTipo(Valor). Ex: int(5.2) produz o valor 5. O tipo original de Valor e o tipo NovoTipo precisam ser compatíveis. Comentários: texto explicativo escrito pelo programador e descartado durante o processamento do programa. Qualquer linha iniciada por # em um algoritmo na linguagem Python é um comentário.
Operadores Aritméticos Operação Símbolo Usado em Python Adição + Subtração - Multiplicação * Divisão (Racional) / Quociente de Divisão Inteira // Resto de Divisão Inteira % Exponenciação ** O operador + também é utilizado para concatenar listas e concatenar strings. Não é possível usar o operador + com operandos de tipos incompatíveis entre si.
Operadores Lógicos Operação Símbolo Usado em Python Maior > Maior ou Igual >= Menor < Menor ou Igual <= Igual == Diferente!= Pertinência in Conjunção Lógica (E) and Disjunção Lógica (OU) or Negação Lógica (NÃO) not Expressões da forma e1 op e2, onde op é >, >=, <, <=, == ou!=, possuem sempre um valor do tipo bool (True ou False). Expressões da forma e1 and e2, e1 or e2 e not e1 exigem que e1 e e2 possuam um valor do tipo bool. Além disso, estas próprias expressões também possuem sempre um valor do tipo bool.
Comando Condicional: if/else Um comando condicional dentro de um algoritmo tem a função de selecionar trechos do algoritmo que serão ou não executados dependendo do resultado de um teste realizado. Em Python, existem duas maneiras de escrever um comando condicional. if (Condiç~ao): Bloco_de_Comandos if (Condiç~ao): Bloco_de_Comandos_1 else: Bloco_de_Comandos_2
Comando Condicional: if/else (2) Condiç~ao deve ser uma expressão que possua um valor do tipo bool. No primeiro caso do comando condicional, se o valor de Condiç~ao for True, o algoritmo prossegue com as instruções dentro de Bloco_de_Comandos. Caso Condiç~ao tenha valor False, estas instruções são puladas. No segundo caso do comando condicional, se o valor de Condiç~ao for True, o algoritmo prossegue com as instruções dentro de Bloco_de_Comandos_1 e se o valor for False, prossegue com Bloco_de_Comandos_2. Os comandos em Bloco_de_Comandos_1 e Bloco_de_ Comandos_2 devem estar endentados em relação aos comandos if e else, isto é, com recuo de espaçamento em relação a estes comandos. O ambiente IDLE realiza a endentação automaticamente ao detectar o caractere :.
Comando de Repetição: while Um comando de repetição dentro de um algoritmo tem a função de repetir as instruções em um certo trecho do algoritmo. Esta repetição é controlada da seguinte forma: O trecho é repetido enquanto uma condição se mantiver verdadeira; Em Python, o comando de repetição é escrito da seguinte forma: while (Condiç~ao): Bloco_de_Comandos Enquanto o valor de Condiç~ao for True, o algoritmo repete as instruções dentro de Bloco_de_Comandos. A expressão Condiç~ao é reavaliada após cada repetição.
Comando de Repetição: while (2) Python também possui um segundo comando de repetição: o comando for. Entretanto, sua construção é de entendimento mais complexo. Desta forma, não estudaremos este comando. Nos algoritmos que desenvolveremos no curso, utilizaremos sempre o comando while para repetições. As regras de endentação para o comando while são as mesmas dos comandos if e if/else. O IDLE realiza a endentação automaticamente da mesma forma descrita anteriormente.
Algumas Construções Úteis Se x é uma variável do tipo float, podemos obter a parte inteira do valor armazenado em x através da construção int(x). Se precisarmos calcular a raiz quadrada de um número, podemos utilizar a função sqrt da Biblioteca de Funções do Python. Para utilizar esta função, precisamos importá-la do setor de funções matemáticas da Biblioteca do Python (math) para dentro do nosso código, através do seguinte comando, colocado no topo do código: from math import sqrt Como exemplo, sqrt(25) retornará o valor 5.0. Para imprimir uma mensagem na tela, utilizamos o comando print seguido de um valor ou variável do tipo str. Ex: print "casa".
Definição de Funções Adicionais A linguagem Python também nos permite definir as nossas próprias funções. Definimos funções da seguinte forma: def Nome(Arg_1, Arg_2,...): Bloco_de_Comandos Bloco_de_Comandos deve estar endentado em relação ao cabeçalho da função da mesma maneira que vimos nos casos dos comandos condicionais e de repetição. O IDLE realiza esta endentação automaticamente a partir do caractere :. Para que a função retorne um valor, utilizamos o comando return Valor. Quando um comando return é executado, a execução da função é encerrada e o valor informado no comando é retornado para quem chamou a função (uma outra função ou o ambiente do IDLE).
Comandos e Funções para Manipulação de Listas Para representar uma lista em Python, utilizamos a forma [a 1, a 2,..., a n ]. Uma lista vazia é representada por []. Se L é uma lista, len(l) retorna o número de elementos em L. Os elementos de uma lista com n elementos são numerados de 0 a n 1. Logo, o k-ésimo elemento de uma lista L pode ser obtido com a notação L[k-1]. O primeiro elemento pode ser obtido com L[0] e o último com L[len(L)-1].
Comandos e Funções para Manipulação de Listas (2) Para concatenar duas listas L e M, podemos utilizar o operador +, escrevendo L + M. Para ordenar uma lista L, podemos escrever L.sort(). Para inverter os elementos de uma lista L, podemos escrever L.reverse(). Para testarmos se uma lista L está vazia, podemos testar se len(l) é igual a zero. Para testar se um valor armazenado em a ocorre dentro de uma lista L, podemos testar se o valor da expressão a in L é True.
Introdução a Algoritmos, Computação Algébrica e à Linguagem de Programação Python Curso de Números Inteiros e Criptografia Prof. Luis Menasché Schechter Departamento de Ciência da Computação UFRJ Agosto de 2013