.. -*- coding: utf-8 -*- .. |Python| replace:: ``Python`` .. |spyder| replace:: ``spyder`` .. |IPython| replace:: ``IPython`` .. |PythonAnywhere| replace:: `PythonAnywhere `__ .. |RST| replace:: `reST `__ .. |Sphinx| replace:: `Sphinx `__ .. |HTML| replace:: ``HTML`` .. |Trinket| replace:: `Trinket `__ .. |Colab| replace:: `Google Colab `__ .. |Replit| replace:: `Replit `__ .. |Runestone| replace:: `Runestone `__ .. |cscircles| replace:: ``cscircles`` .. |fazsentido| replace:: Faz sentido? ``¯\_(ツ)_/¯`` .. |SURPRESO| replace:: ``(☉_☉)`` .. |TRISTE| replace:: ``(⊙︿⊙)`` .. |HEIN| replace:: ``¯\_(ツ)_/¯`` .. |HELP| replace:: ``(҂◡_◡)`` .. |VALEU| replace:: ``\(•◡•)/`` .. |CONFUSO| replace:: ``ఠ_ఠ`` .. |LOUCO| replace:: ``(⊙_◎)`` .. |TRISTE| replace:: ``(ಥ﹏ಥ)`` .. |ENTER| replace:: ``ENTER`` .. |Return| replace:: ``Return`` .. |Forward| replace:: ``Forward >`` .. |Last| replace:: ``Last >>`` .. |First| replace:: ``<< First`` .. |Back| replace:: ``< Back`` .. |Run| replace:: ``Run`` Introdução ========== .. index:: Resumo Esse texto eletrônico foi escrito para dar suporte às aulas presenciais da disciplina MAC0122 - Princípios de Desenvolvimento de Algoritmos. Nessa disciplina adotamos o método de sala de aula invertida. Basicamente, a idéia é que você se prepare **antes** da aula presencial lendo algum material e fazendo alguns exercícios. Durante as aulas, você vai participar de atividades práticas onde esse conhecimento será aplicado para resolver problemas e, assim, continuar de forma ativa a desenvolver seu `raciocínio aplicado na formulação e resolução de problemas computacionais `__. Tópicos ------- - Brevíssima revisão de |Python|. - Instale |Python| em seu computador usando o pacote `Anaconda `__. - Desenvolver programas usando o `Spyder `__. - Como usar esse texto. - Como estudar por esse texto. Antes de usar |Python| ---------------------- Caso você ainda não tenha programado com |Python|, não se preocupe. A sintaxe do |Python| é bem parecida com outras linguagens como C e Java, porém mais simples. De qualquer forma, nessas primeiras aulas vamos cobrir apenas alguns conceitos básicos para você ir se acostumando com a sintaxe do |Python| e consiga acompanhar esse texto desde o seu início. Nessa primeira aula, vamos relembrar um pouco de |Python| e, para isso, recomendamos que você instale |Python| em seu computador. Sugerimos que você instale o pacote da `Anaconda `__ pois este reúne várias ferramentas úteis para desenvolver programas científicos. Clique `nesse link `__ para ver mais instruções sobre a instalação de |Python|. Além do |Python|, o Anaconda instala o |spyder|, que é um IDE (*integrated development environment*) ou ambiente integrado de desenvolvimento que vamos usar para desenvolver os programas em |Python|. Clique `nesse link `__ para saber mais sobre o Spyder. Como usar esse texto? --------------------- Uma forte motivação nossa para escrever esse texto foi desenvolver um material de apoio interativo, onde você pode ler e, ao mesmo tempo, ver e aplicar os conceitos sendo apresentados. Por isso, muitos conceitos serão apresentados na forma de exercícios e programas. As soluções dos exercícios e programas apresentados nesse texto são baseados na versão 3.x do `Python `__ e a maioria deles pode ser editada e executada no seu próprio navegador, esse mesmo que você está usando para acessar e ler o texto. No entanto, durante as reuniões, recomendamos o uso do |spyder| para desenvolver suas soluções. Você pode usar o |spyder| também em seus estudos para resolver os exercícios recomendados ao final de cada capítulo. O |Python| é uma linguagem interpretada que permite a escrita e execução de scripts (programas muito curtos) como: .. code-block:: python print("Desenvolver algoritmos é muito bacana!") Para deixar o conteúdo desse texto mais divertido e interativo, vamos utilizar o `Trinket.io `__, que por sua vez é baseado no `Skulpt `__. O Trinket permitem que você desenvolva e execute os programas no próprio navegador, como ilustrado abaixo. Para executar o programa basta clicar no botão de ``Run`` ou ``Play`` (com o ícone de triângulo). .. raw:: html A janela do Trinket é dinâmica, ou seja, ele vai ajustar o conteúdo dependendo da largura da janela do seu navegador (inclusive facilita a leitura desse texto em um celular). Se a tela for larga o bastante, o resultado é mostrado em uma segunda coluna, como na :numref:`fig-a01-triket2col` abaixo. .. figure:: figuras/a01/trinket01.png :alt: janela do Trinket com 2 colunas :name: fig-a01-triket2col :width: 65.0% :align: center *Janela do Trinket com duas colunas. A coluna da esquerda corresponde ao editor do programa e a da direita contém o resultado da execução*. Caso contrário, o resultado é mostrado na mesma coluna, e o ícone da canetinha é incluído no menu, como ilustrado na :numref:`fig-a01-triket1col`. Clicando nesse ícone, você pode voltar a editar o programa no arquivo ``main.py``. .. figure:: figuras/a01/trinket02.png :alt: janela do Trinket com apenas 1 coluna :name: fig-a01-triket1col :width: 65.0% :align: center *Janela do Trinket com apenas 1 coluna. Quando a janela do navegador é estreita, o Thinket adapta a interface para mostrar apenas uma coluna. A imagem mostra o resultado da execução. Para editar o programa, basta clicar no ícone da canetinha*. Caso você esteja lendo esse texto em uma janela larga, experimente mudar o tamanho da janela do navegador para ver o que acontece |:smile:|. Agora, experimente usar o editor do Trinket. Copie o seguinte trecho de código no editor do Trinket acima, logo após o ``print("Desenvolver algoritmos é muito bacana!")`` e execute! .. code-block:: Python nome = input("Qual o seu nome? ") print(f"Olá {nome}!") .. admonition:: |:warning:| **Cuidado com os tabs** A linguagem |Python| usa tabs para delimitar blocos. Isso torna o código um pouco mais limpo pois não é necessário usar chaves como em C ou Java, e também força uma estrutura visual onde cada bloco mais interno aparece descolado de um tab. Dessa forma, o primeiro comando de um programa deve começar sempre na primeira coluna do texto. Uma boa prática também e colocar apenas um comando por linha. Vamos ver isso melhor na próxima seção, quando apresentamos o ``esqueleto de um programa em Python``. Isso significa por exemplo que o trecho: .. code:: python :number-lines: print("Desenvolver algoritmos é muito bacana!") nome = input("Qual o seu nome? ") print(f"Olá {nome}!") está sintaticamente incorreto em Python pois não deve haver tab nas linhas 2 e 3, ou seja, nesse script, todas as linhas devem começar na primeira coluna. Experimente incluir tabs extras no seu programa para ver o que acontece. Esqueleto de um programa em Python ---------------------------------- Nessa disciplina **sempre** utilize esse esqueleto em seus programas, que sempre deve conter uma função ``main()``. O esqueleto começa com a **definição da função** ``main()``, seguida da definição de outras funções e termina **chamando a função** ``main()``, para que o programa seja executado. A adoção desse esqueleto evita alguns possíveis problemas que podem ocorrer na correção automática dos exercícios que você deve entregar ao longo do semestre, além de deixar seu código bem estruturado. Vamos ilustrar esse esqueleto com um programa que lê um número inteiro e imprime o seu fatorial. Assim, além da função ``main()``, devemos implementar também a função ``fatorial()``. O programa completo está no Trinket a seguir. .. raw:: html Como mencionamos anteriormente, esse esqueleto permite ver que a tabulação dos comandos em Python é muito importante pois comandos com a mesma tabulação estão dentro do mesmo bloco. Portanto, o *corpo* da função ``main()`` precisa ficar deslocado de um tab. O texto entre apóstrofes triplos é chamado de *docstring* e pode conter múltiplas linhas. Recomendamos o uso de docstrings para documentar o seu programa. Os comentários simples são iniciados por um caractere ``#`` e terminam ao final da linha. A função ``input( msg )``, nativa do Python, recebe uma string ``msg`` e imprime ``msg`` como mensagem à pessoa que estiver usando o programa (a(o) usuária(o)), e espera o(a) usuário(a) digitar a resposta no teclado. Essa função sempre retorna uma string, que é então convertida para um objeto do tipo ``int`` (número inteiro) -- usando a função ``int()``, mas poderia também ser convertida para um número real (tipo ``float``) usando a função ``float()``. O comando ``if`` testa se o número é maior ou igual zero, e nesse caso calcula o fatorial (usando a função ``fatorial()`` definida no próprio programa, mais abaixo) e imprime o resultado usando a função ``print()``. Caso o número seja negativo, o bloco do ``else`` é executado. Essa sintaxe deve lhe ser familiar e muito parecida com a sintaxe da linguagem que você utilizou no curso introdutório. Observe que a função ``fatorial()`` é definida **fora** da função ``main()``, pois o comando ``def`` usado para definir cada função começa na primeira coluna do arquivo fonte. A última linha do esqueleto (observe que essa linha também não faz parte do corpo da função ``fatorial()``) chama a função ``main()`` para que o programa principal seja executado. A chamada da ``main()`` está dentro do comando ``if __name__ == "__main__":`` para que todos os nossos programas possam reusados mais tarde por outros programas por meio do comando ``import``, como veremos em aulas futuras. Em todos os seus programas escritos para essa disciplina, procure utilizar essa mesma estrutura: * defina a função ``main()`` primeiro; * defina as demais funções que você precisa utilizar, sem se preocupar com a ordem de definição dessas funções; * chame a função ``main()``. Clique no botão *Run* para executar o programa. Função ``potencia()`` --------------------- Vejamos se deu para entender. Como exercício |:running_woman:| |:man_running_tone4:| escreva uma função ``potencia()`` que **recebe** um número real ``base`` e um número inteiro ``expoente``, e **retorna** o valor da ``base`` elevada ao ``expoente``. .. raw:: html .. exercicio 2 ''' Complete o trecho abaixo com a sua função potencia() e use a função main() para testar a sua função. ''' def main(): base = float(input("Digite a base real: ")) exp = int(input("Digite o expoente inteiro: ")) pot = potencia(base, exp) print(f"potencia({base}, {exp}) = {pot} \n") def potencia(base, expoente): ''' (float, int) -> float retorna a base elevado ao expoente inteiro ''' # modifique o resto com o codigo da sua funcao print("Vixe, ainda nao fiz essa funcao") return 0 # chama a função main() main() Sugerimos que você também execute essa função no |spyder| ou outro IDE de sua preferência. Como estudar para MAC0122 usando esse texto -------------------------------------------- Se você é aluna ou aluno da disciplina de *MAC0122 Princípios de Desenvolvimento de Algoritmos*, essas leituras serão acompanhadas por atividades práticas realizadas em nossas reuniões presenciais. Para se preparar para essas atividades, estude e procure resolver os exercícios ao final de cada capítulo, **antes** de cada reunião. Para a nossa primeira reunião, procure resolver os exercícios a seguir. Exercícios ---------- 1. Escreva um programa que leia um inteiro ``n > 0`` e uma sequência de ``n`` números reais e imprime o valor do maior e do menor elemento da sequência. 2. Escreva um programa que leia dois inteiros positivos ``m`` e ``n`` e calcula a o número binomial .. math:: \left( \mathtt{\cfrac{m}{n}} \right) = \mathtt{\cfrac{m!}{n!(m-n)!}}. .. admonition:: |:thinking:| Podemos escrever uma função ``fatorial()`` e usá-la. 3. Escreva uma função ``mdc_fb()`` que recebe dois números inteiros ``m`` e ``n`` e devolve o mdc (máximo divisor comum) entre eles usando um algoritmo força-bruta. .. admonition:: O que é um algoritmo força-bruta? Um algoritmo força-bruta tipicamente testa todas as soluções possíveis. Nesse caso, podemos assumir que ``mdc = n``. Caso não seja, decrementamos o ``mdc`` até encontrar o valor correto. Observe que, apenas quando ``m`` e ``n`` são primos entre si, o valor do ``mdc`` será 1. 4. Escreva uma função ``mdc()`` que recebe dois números inteiros ``m`` e ``n`` e devolve o mdc (máximo divisor comum) entre eles usando o algoritmo de Euclides. .. admonition:: Qual é o algoritmo de Euclides? O algoritmo de Euclides é mais eficiente que o algoritmo força-bruta anterior pois não testa todas as possíbilidades. A ideia é a seguinte: 1. calcule o ``resto`` da divisão de ``m`` por ``n`` (você pode usar o operador ``%``). 2. se o ``resto`` for zero, o mdc é ``n``. 3. caso contrário, volte ao passo 1 considerando ``n`` e ``resto`` Simule esse processo, usando papel e lápis, com ``m=24`` e ``n=18``. Depois tende implementar o algoritmo em Python. Onde estamos e para onde vamos? ------------------------------- MAC0122 é uma disciplina intermediário de Ciência Computação que exige alguma experiência prévia com alguma linguagem de programação como C, Pascal, Java, etc. Nessa primeiro contato, apresentamos uma breve introdução a linguagem |Python|. Em sala de aula vamos usar o |spyder| para resolver alguns exercícios para você se acostumar com as ferramentas e com |Python|. Na próxima aula, vamos continuar essa introdução com exercícios usando listas em Python. Para saber mais --------------- Para saber mais sobre Python: * `Como Pensar como um Cientista da Computação - Aprendendo com Python: Edição interativa `__ . * `Estudo dirigido `__: aulas interativas do curso de Introdução à Computação em Python. .. aula presencial 01 * 30 minutos: apresentação da disciplina (vídeo?) * 20 minutos: conta no CEC - até 3 pessoas por computador? * 40 minutos: fazer um programa no Spider * 10 minutos: entregar o programa no eDisciplinas