Jacques Wainer
2020
Neste curso vocês aprenderão como usar um computador para resolver problemas.
(a) Definiremos um problema a ser revolvido, (b) descreveremos uma solução imperativa e (c) implementaremos esta solução criando um programa.
Uma solução imperativa descreve uma sequencia de comandos e passos que devem ser executados para se resolver um problema.
Uma solução imperativa para um determinado problema é conhecida como algoritmo para se resolver o problema.
Suponha o problema de se encontrar a raiz quadrada de \(x\).
Abaixo temos uma solução imperativa (algoritmo) para encontrar \(\sqrt{x}\) de forma aproximada:
Comece com uma solução inicial \(i\) (exemplo \(x/2\))
Enquanto \(i^2\) não for próximo o suficiente de \(x\) faça
Este algoritmo usa o conhecido método de Newton e pode ser demonstrado matematicamente que converge para a raiz de \(x\).
Algoritmo:
Comece com uma solução inicial \(i\) (exemplo \(x/2\))
Enquanto \(i^2\) não for próximo o suficiente de \(x\) faça
Definimos que \(i^2\) está próximo de \(x\) quando \(|i^2 - x| < 0.1\).
Exemplo: raiz quadrada de \(9\):
\(i = 4.5\), mas \(i^2 = 20.25\) não está próximo de \(x\), então atualizamos \(i = (i + x/i)/2 = 3.25\)
\(i = 3.25\), mas \(i^2 = 10.56\) não está próximo de \(x\), então atualizamos \(i = (i + x/i)/2 = 3.0096\)
\(i = 3.0096\) e \(i^2 = 9.057\) estando próximo de \(x\), portanto finalizamos o processo.
Achamos a solução aproximada \(3.0096\).
Aprenderemos principalmente a criar algoritmos para resolver pequenos problemas. Mas nada que dependa tanto de conhecimento matemático quanto o problema de calcular a raiz quadrada usando o método de Newton.
Mas algum conhecimento de matemática talvez seja necessario em alguns problemas que veremos nesse curso. Mas de forma geral, programação não depende de nenhum conhecimento de matemática.
Um algoritmo pode ser descrito de várias formas, dentre elas, em português como vimos, ou em uma linguagem de programação.
Neste curso também aprenderemos a implementar um algoritmo em uma linguagem de programação específica que é a linguagem Python.
A vantagem de se implementar um algoritmo em uma linguagem de programação é que podemos a partir daí, criar um programa que usa o computador para resolver o problema.
Neste curso vocês aprenderão a criar algoritmos e programas para resolver problemas.
Criar algoritmos e programar é uma atividade básica de um cientista ou engenheiro da computação.
Eu não sou da computação !!!
Possíveis Respostas:
Porque é legal!
Posso ter algum retorno financeiro com isso!
Mais importante: conhecimento...
Eu sou das engenharias!
Alguns exemplos:
Como engenheiro você deverá ser capaz de automatizar algum processo.
Como engenheiro você deverá ser capaz de desenvolver novas ferramentas ou protótipos.
Você poderá enxergar situações onde uma solução computacional pode trazer benefícios.
Eu sou das áreas científicas! Matemática, Física, Química etc.
Alguns exemplos:
Como cientistas vocês devem propor uma hipótese e testá-la.
Você deverá resolver sistemas complexos de equações que não necessariamente podem ser resolvidos por softwares padrões (como MatLab).
Simulações.
Vocês aprenderão o básico para criar algoritmos e desenvolver programas.
Utilizaremos a linguagem Python para descrição dos algoritmos.
Vocês NÃO vão aprender a usar programas neste curso (como office, MacOs, Linux, AutoCad, etc).
Vocês VÃO ter porém, uma boa noção de como criar programas.
Você deverá ter acesso a um computador onde o Python 3 esteja instalado.
Pode-se instalar Python baixando a versão para o seu sistema operacional favorito em https://www.python.org/. Voce precisará também do pacote Numpy do python https://numpy.org/
Instale o python do miniconda https://docs.conda.io/en/latest/miniconda.html
Instale o numpy. No terminal:
conda install numpy
Instale o editor atom https://atom.io/
Ou o editor VS Code https://visualstudio.microsoft.com/
Mais sobre isso no lab.
Para ir bem neste curso:
Faça todos os laboratórios.
Faça e implemente as listas de exercícios.
E finalmente faça e implemente as listas de exercícios.
Um computador é uma máquina que, a partir de uma entrada, realiza um número muito grande de cálculos matemáticos e lógicos, gerando uma saída.
Os computadores fazem isto muito bem e muito rápido. Computadores modernos fazem centenas de milhares de cálculos por segundo.
Exemplo: Enquanto leio esta frase um computador típico executou mais de 1 Bilhão de instruções.
Usualmente chamamos de Hardware todos os dispositivos físicos que compõem um computador, como CPU, Disco Rígido, Memória, etc.
Estes dispositivos seguem uma organização básica como na figura (Arq. de Von Neumann).
Todo o hardware opera com sinais com apenas 2 valores (binário), que representamos como 0 e 1
A razão não é filosófica (“o computador só entende certo e errado”) mas eletrônica - é possível fazer circuitos que gastam muito pouca energia enquanto eles estão no estado 0 ou 1. Só gastam energia quando mudam de estado.
A representação binária também facilita a interface entre o analógico (sinais magnéticos, elétricos, de luz, de rádio) e o digital - é mais insensível a ruídos
Chamamos 1 desses sinais binários de bit
Chamamos de Byte um agrupamento de 8 bits.
Todas as informações armazenadas no computador são representadas por bits. Informações como letras, símbolos, imagens, programas são todas vários 0s e 1s.
Softwares são os programas que executam tarefas utilizando o hardware de um computador.
Os softwares são compostos por um conjunto de instruções que operam o hardware.
Temos abaixo, por exemplo, três instruções para um computador de 32 bits.
Um software é composto por milhares de instruções deste tipo.
0100 0010 0011 0101 0101 0100 0011 0110
0100 1110 1100 1100 1001 0110 0110 1000
0000 0101 1111 1110 1101 0011 0000 1100
Um ambiente computacional é organizado como uma pilha, onde cada item da pilha realiza tarefas bem específicas.
Items acima na pilha fazem uso de soluções propostas pelos items abaixo.
- programas
- compiladores/interpretadores
- sistema operacional
- hardware
Programas de Aplicação.
Como usuários, interagimos com os programas de aplicação.
Neste curso iremos descer nesta hierarquia, para construirmos novos programas de aplicação.
Para construir novos programas podemos escrever diretamente códigos digitais que serão executados por um computador.
Mas usaremos uma linguagem de programação específica e um interpretador para executar o nosso programa.
Compiladores/Interpretadores e Linguagens de Programação.
Uma linguagem de programação é um conjunto de comandos que são mais "próximos" da linguagem humana do que os sinais digitais.
Neste curso usaremos a linguagem de programação Python.
Compiladores/Interpretadores e Linguagens de Programação.
Podemos classificar as linguagens de programação em dois tipos: compiladas e interpretadas.
Uma linguagem compilada, como C, usa um compilador para transformar o código em C para um programa executável.
O compilador realiza esta tarefa juntamente com um assembler.
Somente depois de se compilar o programa e que pode-se executá-lo.
for(i=0; i< 10; i++) loop: add c, a, b 0100 0010 0011 0101 0101 0100 0011 0110
c = a+b; add i, i, 1 0110 0110 0111 0101 0101 0100 0011 0110
bnq i, 10, loop 1111 0000 0111 0101 0101 0100 0011 0110
Compiladores/Interpretadores e Linguagens de Programação.
Sistema Operacional.
Os programas possuem instruções que são executadas no hardware.
Mas o acesso ao hardware, como disco rígido, memória, processador, é controlado por um software especial conhecido como sistema operacional.
O sistema operacional é o responsável pelo controle do hardware, incluindo segurança, gerenciamento de memória, dentre outros.
Exemplos de sistema operacionais: Windows, OS X, Linux, Android, iOS.
Antes de criarmos um programa para resolver um determinado problema, devemos ser capazes de especificar um algoritmo para resolver o problema.
Algoritmo: Seqüência de passos, precisos e bem definidos, para a realização de uma tarefa ou resolução de um problema.
Algoritmos podem ser especificados de várias formas, inclusive em português.
Exemplo de algoritmo Como ordenar as cartas de um baralho?
Depois de criarmos um algoritmo, podemos especificar este em uma linguagem de programação.
Usaremos a linguagem Python para descrever os algoritmos.
O programa em python será executado diretamente invocando-se o interpretador python para executar o programa.
Os primeiros computadores eram do tipo programas-fixo. Isto significa que cada computador era desenvolvido para resolver um problema específico, como cálculos de projéteis durante a Segunda Guerra.
Desta forma, o programa era diretamente gravado como parte do hardware do computador e não podia ser alterado.
A arquitetura de Von Neumann foi um marco importante pois trouxe a idea de um computador com programa armazenado, ou seja, a ideia de que os computadores deveriam ter um conjunto pré-determinado de instruções que o operavam, e que os programas fossem construídos utilizando-se tais instruções. Haveria uma memória para armazenar tanto o programa quanto os dados necessários.
Com isso foi criado os computadores de uso geral, pois eles podem ser programados para resolver os mais diversos tipos de problemas.
Bem antes do surgimento dos primeiros computadores de uso geral, Alan Turing descreveu matematicamente um computador hipotético chamado Máquina de Turing, que serviu para formalizar os conceitos de algoritmos e o que é computável.
A tese de Church-Turing diz que se uma função é computável então existe uma Máquina de Turing que computa esta função
Você pode pensar simplificadamente que uma função ser computável significa um problema admitir um algoritmo que o resolva.
A partir da tese de Church-Turing temos que qualquer problema que possa ser resolvido por um algoritmo (por um computador) pode ser resolvido com uma máquina de Turing.
Apesar de computadores serem muito poderosos, Turing mostrou que existem problemas que não podem ser resolvidos por uma Máquina de Turing (e por consequência nenhum computador).
Um destes problemas é o conhecido problema da parada: dado um programa de computador, você deve criar um algoritmo que decide se o programa de computador encerra ou nunca para.
Turing mostrou ser impossível a criação de uma Máquina de Turing para este problema.
Os primórdios da programação: programação em código absoluto ou binário (apenas 0s e 1s).
Uma melhoria: A Linguagem Assembly.
Cria-se uma linguagem de baixo nível (Linguagem Assembly) para representar as instruções em código binário.
Um programa, chamado montador ou assembler, faz a transformação do assembly para a linguagem de maquina (0s e 1s)
LOOP: MOV A, 3
INC A
JMP LOOP
Uma brilhante idéia: Criação de linguagens de alto nível e compiladores/interpretadores para estas.
Mais distantes da máquina e mais próximas de linguagens naturais (inglês, português, etc.).
Mesmo mais compreensíveis, elas não são ambíguas.
Um compilador/interpretador as transforma em código executável.
Exemplos de linguagens:
C
C++
Python
Java
Javascript
Mathlab
R
Lua
Há/houve centenas de linguagens de programação https://github.com/stereobooster/programming-languages-genealogical-tree
Um programa em Python é um arquivo texto, contendo declarações e operações da linguagem. Isto é chamado de código fonte.
print("Ola turma de MC102!!")
Você pode salvar este arquivo como hello.py.
$ python hello.py
Ola turma de MC102!
Algoritmos.
Implementação em uma Linguagem de Programação.
Hardware e Software.
Pilha de um ambiente computacional: Programas de Aplicações, Compilador/Interpretador, Sistema Operacional, Hardware.
Código Binário, Assembly, Linguagem de Alto Nível.