Prévia do material em texto
FACULDADE
ENGENHARIA DE SOFTWARE
ARQUITETURA CISC X RISC
o código de máquina (A linguagem de máquina é o conjunto de instruções (em binário)
que determinado processador consegue executar. Para ser executado, um programa
escrito em alto nível (em C, Python, ou Java, por exemplo deve ser convertido em
linguagem de máquina, formando o código de máquina: versão do programa
compreensível pelo processador. ) é mais simples de se gerar pelo compilador, pois,
geralmente, há relação direta entre uma linha de código em alto nível e uma instrução da
arquitetura, veja:
1 int a = 3
2 a = a + 5
Na linha 1, temos a declaração da variável a. Vamos assumir que ela está alocada na
memória principal em M[&a] (em que &a representa o endereço de a).
Na linha 2, desejamos realizar a soma entre os valores de a e 5 e guardar o resultado,
sobrescrevendo o valor da variável a para 8.
No caso de uma abordagem CISC, há uma instrução que realiza exatamente esse processo.
Como exemplo, na arquitetura do 386, temos a instrução ADDI, que realiza a adição de um
valor imediato. Veja a instrução em Assembly:
1 ADDI M[&a], 5
Segundo o manual do Processador 386, essa instrução leva 2 pulsos de clock ( Para operar
de forma organizada, o processador utiliza um relógio (Clock) que gera pulsos em
intervalos regulares. A cada vez que um pulso de clock é recebido, uma “etapa” é
executada, e todo o circuito avança um passo.Dessa forma, uma instrução que leve 2
pulsos (ciclos) de clock será executada após dois pulsos serem emitidos para o circuito ) (2
CLK) quando operada sobre um registrador e 7 CLK quando operada sobre um endereço
de memória. Essa diferença se dá pela necessidade de buscar o operando e escrever o
resultado na memória.
RISC
Convertendo o código
1 int a = 3
2 a = a + 5
Como podemos realizar essa operação no modelo RISC, onde não há operações que
façam adição de elementos diretamente da memória (terceira premissa de um processador
RISC)?
Para isso, precisaremos desmembrar a operação complexa em várias simples:
1
Buscar o valor da variavel a na memória (LOAD).
2
Realizar a adição imediata de 5.
3
Salvar o valor resultante em um registrador (ADDI).
4
Guardar o novo valor na variável a em memória (STORE).
Lembre-se de que na abordagem CISC esse código usava apenas uma instrução – “ADDI
M[&a], 5”.
Essa sequência de operações é exatamente a mesma do exemplo do pipeline dado
anteriormente:
A diferença é que essas operações de LOAD e STORE, que são custosas e atrasam o
pipeline, não são usadas tantas vezes assim. Com vários registradores, as variáveis são
carregadas nos registradores quando aparecem pela primeira vez e ficam sendo operadas
ali até que seja necessário usar esse registrador para outra função.
Para obtermos uma Unidade de Controle menor, sem microprograma, reduzimos o
conjunto de instruções.
Podemos perceber duas características comunsà abordagem RISC:
Tamanho fixo de instrução
Para simplificar a decodificação.
Operações com endereçamento
Registrador-Registrador.
LOAD Reg1, M[&a]1.
ADDI Reg1, Reg1, 52.
STORE Reg1, M[&a]3.
Analisaremos agora a rede de
hambúrgueres RISC.
O dono da empresa resolveu contratar apenas cinco funcionáriospara sua linha de
montagem:
Processador de pedidos no caixa
BI - Buscar Instrução.
Preparador
DI - Decodificar Instrução.
Montador
EXE - Execução.
Entregador
AM - Acesso à Memória.
Balconista
WB - WriteBack.
Os funcionários dessa loja devem saber montar pequenas partes de pedidos: montar um
hambúrguer, uma batata, um refrigerante etc.
Os pedidos completos são feitos em uma série de pedidos menores. Por exemplo:
Além disso, existe um pedido especial que tem a responsabilidade de buscar ingredientes
no mercado (LOAD) e um funcionário apenas para fazer entregas em domicílio (STORE).
Nesse caso, o conjunto de pedidos menores ficaria assim:
Podemos perceber que, se houvesse uma série de pedidos de 1 hambúrguer apenas,
teríamos uma sequência LOAD/hambúrguer/STORE. Isso seria muito ruim, pois as
operações normais levam um tempo menor e fixo (um pulso de CLK), que podemos definir
como 1 minuto na analogia. Já a busca de ingredientes e entrega em domicílio pode
demorar vários pulsos de CLK (por exemplo, 5 minutos).
Assim, o pedido de 1 hambúrguer para entrega demoraria 11 minutos, que é o tempo
próximo de um pedido similar na hamburgueria CISC (10 minutos). Todavia, se for possível
otimizaro conjunto de pedidos para buscar ingredientes uma única vez e fazer a entrega
apenas no final, montando 10 hambúrgueres de uma vez, teremos a entrega de 10
pedidos em 20 minutos – muito melhor que os 100 minutos da CISC.
assignment_ind
Comentário
Podemos perceber o fator determinante no sucesso ou no fracasso da abordagem RISC.
Como vimos, o ônus de otimizar as instruções a partir do código de alto nível é do
compilador, e, se for bem executado, as operações de acesso à memória serão reduzidas e
as operações em registradores, priorizadas, fazendo o pipeline do processador operar bem
perto do ideal (1 instrução por ciclo).
PYTHON
CLASSIFICAÇÃO POR GERAÇÕES
Outra forma de classificar as linguagens, amplamente difundida, é por gerações. Não há
um consenso sobre as gerações, alguns consideram 5, outros 6. A cada geração, novos
recursos facilitadores são embutidos nas respectivas linguagens.
LINGUAGENS DE 1ª GERAÇÃO
(LINGUAGEM DE MÁQUINA)
A 1ª geração de linguagens é representa pela linguagem de máquina, nativa dos
processadores.
LINGUAGENS DE 2ª GERAÇÃO
(LINGUAGEM DE MONTAGEM –
ASSEMBLY)
As linguagens de segunda geração são denominadas Assembly e são traduzidas para a
linguagem de máquina por um programa especial (montador), chamado Assembler. A
partir dessa geração, toda linguagem vai precisar de um processo de conversão do código
nela escrito, para o código em linguagem de máquina.
Acompanhe o exemplo abaixo para uma CPU abstrata. Considere a seguinte sequência de
3 instruções em linguagem Assembly:
Em linguagem de máquina, depois de traduzidas pelo Assembler, as instruções poderiam
ser representadas pelas seguintes sequências de palavras binárias:
Código em Assembly
O que faz cada linha de
código
Mov #8, A
Lê um valor da posição
de memória 8 para o
registrador A
Mov #9, B
Lê um valor da posição
de memória 9 para o
registrador B
ADD A,B
Soma os valores
armazenados nos
registradores A e B
Houve um aumento significativo no nível de abstração, mas parte da dificuldade
permanece, pois o programador, além de necessitar memorizar os mneumônicos, precisa
conhecer a arquitetura do computador como forma de endereçamento dos registradores e
memória, além de outros aspectos.
LINGUAGENS DE 3ª GERAÇÃO
(LINGUAGENS PROCEDURAIS)
São as, também, linguagens de alto nível, de aplicação geral, em que uma única instrução
em uma linguagem próxima a do homem pode corresponder a mais de uma instrução em
linguagem de máquina.
Caracterizam-se pelo suporte a variáveis do tipo simples (caractere, inteiro, real e lógico) e
estruturados (matrizes, vetores, registros), comandos condicionais, comando de iteração e
programação modular (funções e procedimentos), estando alinhadas à programação
estruturada.
O processo de conversão para a linguagem de máquina ficou mais complexo e ficaram a
cargo dos interpretadores e tradutores. As primeiras linguagens de 3ª geração que foram
apresentadas ao mercado são: Fortran, BASIC, COBOL, C, PASCAL, C, dentre outras.
Esta geração de linguagens apresenta as seguintes propriedades em comum:
Armazenar tipos de dados estaticamente: simples, estruturados e enumerados.•
Alocar memória dinamicamente, através de ponteiros, que são posições de memória
cujo conteúdo é outra posição de memória.
•
Disponibilizar: estruturas de controle sequencial, condicional, repetição e desvio
incondicional.
•
Permitir a programação modular, com uso de parâmetros.•
Operadores: relacionais, lógicos e aritméticos.•
Ênfase em simplicidade e eficiência.•
Código em Assembly
Código em linguagem
de máquina
Mov #8, A
01000011 11001000
01100001
Mov #9, B
01000011 11001001
01100010de uma quebra de linha.
9.
flag
Aponta a inserção de uma linha horizontal no documento. Normalmente, é utilizada
quando se pretende alterar a temática de um texto.
10.
Aplica o efeito de negrito em um texto.
1.
Aplica o efeito de negrito em um texto e o marca como importante.
2.
Aplica o efeito de itálico em um texto.
3.
Aplica o efeito de itálico e dá ênfase a um texto.
4.
A cada nova versão da HTML, novas tags são criadas, assim como antigas são
descontinuadas. As tags descontinuadas, chamadas de obsoletas, embora ainda possam
ter suporte em boa parte dos navegadores, devem ser evitadas pelos seguintes motivos:
Veja alguns exemplos de tags obsoletas!
Atualmente consideradas obsoletas, as tags e ainda são usadas em
muitas páginas HTML. Ambas se enquadram no conceito de que não é função da HTML
cuidar da apresentação. Logo, as duas foram substituídas por propriedades CSS.
Tags HTML complexas
Listas, tabelas e mídias em HTML
Você já deve conhecer as tags HTML básicas e ter criado páginas web simples usando
esses elementos. No HTML, existem diversas outras tags mais avançadas que podem ser
usadas para diferentes fins, como exibição de listas e tabelas ou/e inserção de vídeos e
áudios. E é justamente esse o tópico que trataremos a seguir.
Porque, provavelmente, foram substituídas por novas tags, com melhor semântica.•
Por causa do risco de desconfigurarem o conteúdo da página, uma vez que os
browsers podem deixar de suportá-las a qualquer momento.
•
filter_1
Identifica a inclusão de um applet Java.
1.
filter_2
Centraliza horizontalmente o conteúdo de um bloco.
2.
filter_3
Apresenta container para lista de diretórios ou arquivos.
3.
filter_4
Determina características relacionadas a fontes de um determinado elemento.
4.
filter_5
Apresenta relação ancestral com a tag , que era usada nas primeiras versões
HTML para a inserção de imagens.
5.
Listas na HTML
O HTML fornece suporte para a representação visual de três tipos de listas: as ordenadas,
as não ordenadas e as de definição. Vamos conhecer cada uma dessas listas a seguir.
Ordenadas
Usadas quando desejamos listar dados com a necessidade de representar a sua ordenação
de forma numérica ou alfabética.
Não ordenadas
Usadas quando não há necessidade de listar ordenadamente.
De definição
Usadas quando precisamos listar itens e atribuirmos uma descrição a eles.
Outra característica importante das listas se deve ao fato de que a sua marcação HTML é
composta por uma tag de container, ou tag “pai”, e por seus itens, ou “filhos”. Além disso,
a lista de definição possui ainda um terceiro item, que é justamente o utilizado para
descrevê-lo. Veja na tabela cada tipo de lista:
Ti
p
o
Ta
g
co
nt
ai
ne
r
Ta
g
it
e
m
Ta
g
de
sc
riç
ão
Or
de
na
da
s
--
N
ão
or
de
na
da
s
--
Lista ordenada
Lista não ordenada
Lista de definição
Cabe destacar, em relação às tags demonstradas anteriormente, que tanto o símbolo de
ordenação (a numeração 1,2,3) quanto o símbolo visual (o bullet) podem ser alterados
com a utilização de CSS.
report_problem
Atenção!
A HTML permite que sejam criadas listas dentro de listas – as chamadas listas aninhadas
(nested lists).
Tabelas na HTML
Quando precisamos lidar com dados tabulares em uma página web, utilizamos tabelas. As
tabelas usadas nesse documento são exemplos do tipo de dado e também da
apresentação obtida ao utilizarmos tais elementos na HTML.
Estrutura das tabelas
A marcação HTML relacionada às tabelas contém outras tags além da principal, a saber:
. A tag principal define o container geral.
De forma hierárquica, temos as tags para a definição de linhas e colunas . Com
essas três tags é possível representarmos uma tabela simples. Entretanto, há tags
adicionais que podem ser usadas e que ajudam a melhor organizar o conteúdo.
O esquema seguinte apresenta as tags de marcação, e suas respectivas funções,
relacionadas às tabelas:
filter_1
Representa container principal da tabela.
1.
filter_2
Representa as linhas, sendo composta pelas tags relacionadas às colunas.
2.
filter_3
Representa as colunas e precisa ser inserida dentro da tag de linha.
3.
filter_4
Representa colunas e é usada para exibir o título de uma coluna, possuindo, neste
sentido, função semântica. Assim como a tag , deve estar contida em uma tag de
linha. Esse elemento apresenta estilos próprios, sendo renderizado de forma diferente
das colunas comuns.
4.
filter_5
Armazena o cabeçalho da tabela, sendo composto por linhas e colunas. Esse
elemento, a exemplo do que vimos anteriormente, tem função semântica em termos
de estruturação de conteúdo.
5.
filter_6
Armazena o rodapé da tabela, tendo também função semântica em termos de
estruturação.
6.
As tabelas, normalmente, são organizadas de maneira uniforme: linhas sobre linhas,
colunas após colunas, célula ao lado de célula. Logo, as colunas costumam ter a mesma
largura, assim como as linhas a mesma altura. Entretanto, há situações nas quais é preciso
mudar um pouco essa organização. Por exemplo, pode ser necessário mesclar duas
colunas ou mesmo duas ou mais linhas.
Para isso, fazemos uso de alguns atributos, que têm função de destaque ao tratarmos das
tags relacionadas às tabelas. São eles:
filter_1
Rowspan
filter_2
Colspan
Esses atributos têm a função de expandir as linhas ou colunas. Sua declaração é
acompanhada de um número que indica a quantidade de células a serem utilizadas para
expansão da linha ou coluna. Ao final deste módulo, teremos a oportunidade de
praticarmos um pouco mais e vermos como esses atributos funcionam.
As tabelas e a semântica
Desde a criação do código HTML, as tabelas foram o elemento mais utilizado fora de sua
função semântica. Isso se deve ao fato de que a estrutura básica de uma página HTML
lembra muito a estrutura de uma tabela: cabeçalho, rodapé, seções (linhas) etc. Logo, foi
prática comum ao longo de muitos anos a codificação de páginas web completas fazendo-
se uso de tabelas. Além de ir de contra a semântica, tal uso traz consigo outros problemas,
como o peso das páginas e a redução da acessibilidade, entre outros.
Mídias na HTML: vídeo e áudio
O suporte à multimídia na HTML vem melhorando ao longo dos anos e versões. Com o
advento da HTML5, tornou-se possível, de forma muito simples, incorporar vídeo e áudio
em uma página web. Para isso, são usadas as tags e , veja:
HTMLcontent_copy
1
2
Como visto, os atributos também têm suma importância ao fazermos uso das tags de
vídeo e áudio. No exemplo acima, temos, inicialmente, o atributo “src” – que informa o
endereço, podendo ser de um site ou mesmo de um arquivo local – no seu computador
ou no servidor em que a página web fica hospedada.
http://www.youtube.com/watch?v=20SHvU@PKsM
Os atributos “controls”, “autoplay” e “loop”, que são específicos para esse tipo de mídia em
questão, fornecem suporte ao controle do conteúdo (vídeo ou áudio) incorporado pelo
navegador, além de definirem alguns comportamentos, como o “autoplay” e o “loop”, que
são autoexplicativos.
Os três atributos aqui descritos são apenas uma prévia, uma vez que há alguns outros
disponíveis. Outros componentes importantes, contidos na especificação do HTML5, são
os eventos que permitem o controle de mídia embutida com a utilização de Javascript. São
os chamados “Media Events”.
Formulário
Estrutura do formulário
A exemplo do que vimos com as tabelas, o formulário é composto por uma tag principal,
um container, e várias tags “filhas”. Fazem parte de sua estrutura tags como as de campos
de texto, de uma ou mais linhas, campos de seleção e botões.
Além disso, para maior clareza, também usamos tags para informar a função dos campos
do formulário. São as chamadas label. Veja agorauma lista as tags comumente usadas em
um formulário. Vamos lá?
filter_1
Container principal do formulário.
1.
filter_2
Campo do formulário. Como há diversos tipos de campos, fazemos uso do atributo
“type” para informar o tipo a ser utilizado – conforme veremos mais adiante.
2.
filter_3
Campo de texto de múltiplas linhas.
3.
filter_4
e
Campos de seleção, onde o container é definido pela tag e os itens pela tag
.
4.
Conhecendo melhor os elementos e atributos do
formulário
Na próxima imagem, temos o fragmento HTML correspondente a um formulário. É
possível observar as tags já mencionadas, assim como algumas tipificações nos campos e
novos atributos, que serão abordadas a seguir:
filter_5
Campo de botão. Permite que uma ação seja executada no formulário – enviar o
formulário; limpar os dados etc.
5.
filter_6
Campo usado para definir um título, uma legenda, que descreva para que serve cada
campo do formulário.
6.
É fácil identificar para o que serve cada campo do formulário anterior ao lermos o
conteúdo da tag . Além disso, a tag cria seções dentro do formulário,
ajudando a separar os campos no código e a visualizar a página no navegador.
Isso fica ainda mais claro quando vinculamos ao a tag .
Como vimos, é necessária uma atenção especial aos atributos quando tratamos de
formulários. Para melhor visualização e entendimento, todos os atributos contidos no
código mencionado são descritos a seguir:
filter_1
action
Define a URL (endereço) para a qual os dados do formulário serão enviados.
1.
filter_2
method
Define o método HTTP (POST ou GET) para envio dos dados.
2.
filter_3
for
Vincula a tag ao campo ao qual ela se refere. Esse vínculo faz com que seja
possível clicar na label para ativar o campo relacionado.
3.
filter_4
minlength, maxlength
Define a quantidade de caracteres mínima e máxima, respectivamente, permitida em
um campo.
4.
filter_5
,
type
Define o tipo do campo e, sobretudo, como ele se comporta.
5.
Atributos do formulário: o atributo type
Este atributo, dada a sua importância, precisa ser visto de forma aprofundada. Como já
dito, além de definir o tipo do campo, também determina como este se comporta. No
código apresentado na tabela, é utilizado apenas o tipo “text”, que, no caso da tag
, corresponde ao seu valor padrão.
Conheça outros tipos comuns:
Ao longo de vários anos, havia apenas esses tipos disponíveis na HTML. Com isso, algumas
necessidades − fossem de inserção de tipos de dados específicos fossem de validação de
valores − não podiam ser supridas apenas com a utilização de tags, sendo necessário
combinar códigos Javascript e CSS. Por exemplo: um campo para seleção de data.
Além disso, novos tipos de dados, com características específicas, ganharam importância
ao longo dos anos. Podemos citar, como exemplo, o e-mail. Embora seja um campo de
texto, ele possui um padrão de composição próprio, como o uso de @, entre outras
características.
Novos atributos e tipos
Pensando nas deficiências citadas, a HTML5 definiu novos tipos de entrada e também
novos atributos relacionados a formulários. Destacamos alguns desses novos atributos e
tipos, veja!
Atributos
filter_6
value
Define o valor do campo, e também pode ser utilizado na tag . No caso da
, os seus valores possíveis são previamente definidos quando a página é
codificada. Já na , embora também possa ser previamente definido,
normalmente é o usuário quem define o seu valor.
6.
“password”: mascara o texto com asteriscos.•
“hidden”: esconde o campo para não ser exibido no navegador.•
“checkbox”: usado para seleção de valor através de click/check.•
“radio”: usado para seleção exclusiva de valor – quando é apresentada mais de uma
opção, apenas uma poderá ser selecionada, ao contrário do tipo “checkbox”.
•
“submit”: associado à tag , dispara o evento que envia/submete o
formulário.
•
“reset”: associado à tag , dispara o evento que limpa os valores do
formulário.
•
“button”: uma tag pode ser do tipo “button” – exercendo, assim, a mesma
função da tag .
•
expand_more
Tipos
expand_more
Como funciona a validação?
A validação é um processo que pode e deve ocorrer tanto no lado cliente– no navegador
– quanto no lado servidor. Pensando no lado cliente, essa ação ocorre assim que o
formulário é submetido, antes que os dados sejam recebidos pelo servidor de destino.
Há pouco tempo, para validar um formulário, era necessário usar o Javascript. Entretanto,
na HTML5 é possível fazê-lo de forma nativa, sem o uso de linguagens de programação.
Tipos de validação
placeholder
Função: Exibir um texto no campo de input.
Comentário: Utilizado para dar uma dica ao usuário sobre o dado a ser inserido.
•
required
Função: Determinar se um campo é obrigatório.
Comentário: Utilizado na validação dos dados de um formulário.
•
autofocus
Função: Fixar o foco no campo.
Comentário: Utilizado quando desejamos que, ao carregar o formulário, um
determinado campo seja focado.
•
pattern
Função: Validar o valor de um campo com base em uma expressão regular.
(as RegEX – expressões regulares – podem ser consideradas um recurso de linguagem
de programação para a análise e manipulação de texto)
Comentário: O campo de tel. é um bom exemplo de utilização desse atributo. Com ele
podemos, por exemplo, determinar a quantidade de caracteres e o formato esperado
para um campo.
•
tel
Função: Inserir números de telefone.
Comentário: Para uma melhor usabilidade, deve ser usado em conjunto com o
atributo “pattern”.
•
datetime
Função: Inserir datas com o fuso horário em UTC a partir de um calendário.
•
date
Função: Inserir datas sem fuso horário a partir de um calendário.
•
number
Função: Inserir números.
Comentário: Cria um componente diferente do imput normal, em que, por meio de
setas, os números podem ser incrementados ou decrementados.
•
Na HTML5, há dois tipos possíveis de validação:
filter_1
Um tipo verifica se o dado inserido em um campo é consistente com o seu tipo e/ou
padrão (pattern).
filter_2
Outro tipo verifica se um campo obrigatório foi preenchido.
Vejamos o exemplo!
extension
Exemplo
Quanto à primeira validação, podemos citar novamente o elemento input do tipo “e-mail”.
Um endereço de e-mail é um dado que possui uma formatação predefinida: precisa ter o
“@”; precisa ter a extensão de domínio “.com / .com.br” etc.
Logo, declarar uma tag input com o type “e-mail” faz com que, naturalmente, seja validado
o seu conteúdo.
Algo semelhante acontece com a utilização do atributo “pattern”, sendo que, nesse caso, é
você quem define o que um campo precisa conter para ser considerado válido. Por
exemplo: determinar o formato desejado para um campo que receba um número de
telefone.
Você pode definir que ele contenha o DDD, com dois caracteres numéricos, seguido por
dois conjuntos de números – um contendo 5 e outro contendo 3 ou 4 caracteres – o que
geraria este código: pattern=“
[0-9]{5}-[0-9]{3,4}$”
Além da validação pelo tipo de dado, há também a validação de campos obrigatórios.
Logo, quando precisamos que determinado campo não fique em branco, usamos o
atributo “required”.
O comportamento padrão da HTML5 é validar os dados quando ocorre o envio do
formulário. Entretanto, é possível desativar essa funcionalidade. Para isso, deve ser
atribuído o atributo “novalidate” à tag .
JAVASCRIPT
Árvore DOM
O JavaScript é uma linguagem client side, ou seja, uma linguagem que roda no lado do
cliente, considerando o ambiente web. Nesse ambiente, além do JavaScript, temos ainda
duas outras principais tecnologias: a linguagem de marcação HTML e o CSS. No vídeo a
http://com.br/
seguir, você aprenderá a utilizar o JavaScript para interagir com páginas HTML por meio
da árvore DOM.
JavaScript
Esta linguagem faz parte da tríade de tecnologias que compõem o ambiente web. Veja aseguir:
code
HTML
Cuida da estrutura e do conteúdo das páginas.
color_lens
CSS
É responsável pela apresentação das páginas.
touch_app
JavaScript
Cuida do comportamento e da interatividade das páginas web.
Trata-se de uma linguagem de programação interpretada e multiparadigma, uma vez
que possui suporte à programação estruturada, orientada a objetos e funcional.
O JavaScript, conhecido como JS, foi criado inicialmente para o ambiente web, no lado
cliente. Entretanto, evoluiu a ponto de atualmente ser utilizado também no lado servidor,
além de ser uma das principais linguagens para o desenvolvimento de aplicativos mobile.
Embora possuam nomes parecidos, as linguagens de programação JavaScript e Java não
têm nenhuma relação.
Interface DOM
Iniciaremos nosso estudo de JavaScript entendendo o que é e como manipular a interface,
ou árvore, DOM. Isso auxiliará o entendimento de como essa linguagem se integra e
interage com a HTML.
A sigla DOM (document object model) significa modelo de objeto de documento. Trata-se
de uma interface que permite a manipulação, via programação, de documentos HTML (e
outros, como XML, por exemplo). Além de interface, é também chamado de árvore, por
fornecer uma representação estruturada do documento nesse formato.
A árvore DOM é composta por nós e objetos. Ambos possuem propriedades e métodos,
além de eventos. Por meio dessa estrutura, é possível acessar, por exemplo, o conteúdo
textual de um elemento − como a tag −, assim como recuperar e até mesmo alterar
seu valor.
report_problem
Atenção!
Embora sejam frequentemente associados, o DOM não faz parte do JavaScript, podendo
também ser manipulado por outras linguagens. Neste conteúdo, ficaremos restritos à
manipulação do DOM por meio do JavaScript.
Veja a seguir uma ilustração da árvore DOM e de seus elementos:
Árvore DOM.
Manipulando o DOM com JavaScript
Por meio do JavaScript, é possível:
domain_verification
Inserir dinamicamente, em tempo de execução, novos elementos à árvore DOM,
mesmo que eles não façam parte da estrutura inicial da página.
1.
domain_verification
Excluir e alterar elementos preexistentes ou dinamicamente criados.
2.
domain_verification
Manipular os estilos de um documento, de modo similar ao que é feito via CSS.
3.
Os elementos preexistentes ou dinamicamente criados, porém, existirão somente
enquanto durar a sessão atual do usuário, ou seja, trata-se de uma manipulação dinâmica
e dependente de estado, de ações e interações por parte do usuário, mas que se perderão
quando ele sair da página.
Sintaxe e conceitos
A linguagem JavaScript oferece uma série de recursos, além de possuir uma sintaxe
própria de utilização. Veremos, no vídeo a seguir, alguns desses recursos e como fazer
para incorporar código JS em páginas HTML.
Sintaxe JavaScript
Outros elementos
Ao longo do código apresentado anteriormente, foram utilizados outros elementos. Na
tabela a seguir, cada um deles será descrito:
Elemento
Para que serve
Linha do código
alert
Exibir uma caixa de
diálogo no navegador.
Existem outras funções
nativas de diálogo,
inclusive para receber
input de valores.
23
document.getElementByI
d
Referenciar um elemento
da árvore DOM por meio
do valor de seu atributo
“id”. Pesquise também
sobre
document.getElementBy
ClassName.
28
innerHTML
Propriedade DOM
relativa ao conteúdo de
um elemento. Permite
tanto a inclusão quanto a
exclusão e a modificação
do conteúdo do
elemento.
33
+=
Operador de atribuição
composta. A linha em
questão poderia ser
escrita de forma
simplificada com esse
operador, ou em sua
forma completa, como:
“divLocal.innerHTML =
divLocal.innerHTML +
resultadoMultiplicacao”.
33
Tabela: Lista de elementos utilizados no código de exemplo.
Alexandre de Oliveira Paixão.
O fluxo normal e o fluxo resultado da condicional podem ser vistos na imagem a seguir,
em que são apresentados os passos correspondentes ao nosso exercício, separando as
ações do programa e as do usuário.
open_in_full
function
Palavra reservada,
utilizada para indicar que
será declarada uma
função. É procedida pelo
nome da função e por
parênteses. Caso receba
parâmetros, eles devem
ser declarados dentro
dos parênteses._ipsum
36
return
Palavra reservada,
utilizada para indicar o
conteúdo a ser retornado
pela função. Nem todas
as funções retornam
valores. Logo, essa
instrução só deve ser
utilizada por funções que
retornem algum
resultado.
48
Fluxo normal e fluxo alternativo.
Repare que a verificação “é um nº inteiro positivo” permite apenas duas respostas: “sim” e
“não”. Essa condição, mediante a resposta fornecida, é responsável por seguir o fluxo
normal do código ou o alternativo.
O fluxograma de exemplo foi simplificado para fornecer mais detalhes. Logo, a respectiva
notação padrão não foi utilizada em sua confecção.
Nas linguagens de programação, utilizamos as instruções condicionais para implementar o
tipo de decisão apresentado no exemplo. Em JavaScript, estão disponíveis as instruções
"if/else" e "switch", como veremos a seguir.
push
Para compreender em que situações o método push pode ser útil, vamos voltar a nosso
vetor “alunos”. Imagine que, após ter sido declarado inicialmente com 3 valores, seja
necessário incluir novos valores a esse array, em tempo de execução. O método push nos
auxilia nessa tarefa. Sua sintaxe é:
nome_do_array.push(valor)
Usando nosso array de exemplo, poderíamos adicionar um novo elemento. Desse modo:
javascriptcontent_copy
1
alunos.push('Helena');
É possível, ainda, inserir múltiplos valores utilizando push:
javascriptcontent_copy
1
alunos.push('Helena', 'Maria');
Tamanho do array
Há outras maneiras de adicionar elementos a um array de forma dinâmica. A primeira
delas pode ser vista a seguir:
javascriptcontent_copy
1
alunos[alunos.length] = 'Maria';
Nesse caso, devemos utilizar o tamanho do array para informar que desejamos adicionar
um novo elemento. Isso pode ser feito informando o número, caso o saibamos, ou de
forma dinâmica, usando a propriedade length − que retorna justamente o tamanho do
array. Vamos entender melhor essa importante propriedade!
Propriedade length
Uma das necessidades mais comuns quando se trabalha com arrays é saber o seu
tamanho. Como vimos em alguns de nossos exemplos, em JavaScript, está disponível a
propriedade length, que retorna o tamanho ou número de elementos de um array. Sua
sintaxe é:
nome_do_array.length
splice
É um método multiuso em JavaScript que serve tanto para excluir elementos de um array,
como veremos a seguir, quanto para substituir e inserir. Sua sintaxe é:
Array.splice(posição,0,novo_elemento,novo_elemento,...)
Delete
Em JavaScript, a remoção de elementos de um array pode ser feita com a utilização do
método nativo delete. Veja como esse método funciona utilizando nosso array de
exemplo:
javascriptcontent_copy
1
delete frutas[0];
Observe que sua sintaxe é composta por:
Esse método possui uma particularidade: embora o valor seja excluído do array, este não é
“reorganizado”, permanecendo com o mesmo tamanho.
pop
Este método, que não recebe parâmetros, remove um elemento do final do array,
atualizando seu tamanho. Sua sintaxe é:
frutas.pop();
shift
Embora seja similar ao pop, este método remove um elemento do início do array. Após a
remoção, este é reindexado, ou seja, o elemento de índice 1 passa a ser o de índice 0, e
Nome do método (delete);•
Nome do array;•
Índice do elemento que queremos remover.•
assim sucessivamente. Além disso, o tamanho do array também é atualizado. Sua sintaxe
é:
frutas.shift();
Outras formas de remover elementos do
vetor
Existem outras maneiras para excluir elementos de um array. Uma forma simples é
determinar o tamanho do array utilizando a propriedade length. Isso fará com que ele
seja reduzido ao novo tamanho informado.
ENGEHARIA DE USABILIDADE
É um processo composto por seis atividades, segundo Hix e Hartson (1993):
Análise de tarefas, usuários e funções: fazemos o levantamentodas necessidades dos
usuários.
•
Especificação de requisitos: entendemos os problemas que precisamos resolver.•
Projeto conceitual e especificação do design: concebemos a solução.•
Prototipação: elaboramos as versões de interações possíveis.•
Implementação: desenvolvemos a solução escolhida.•
Nesse tipo de processo, o designer pode iniciar o trabalho pela atividade que preferir,
dependendo da necessidade do projeto. A única exigência é que, após concluir cada uma
delas, ele deve avaliar os resultados obtidos para verificar se está no caminho correto.
Como mostra a imagem a seguir, todas as atividades estão interligadas pela atividade de
avaliação, ou seja, o que quer que se faça, ao concluir uma atividade e antes de iniciar
outra, sempre é necessária uma avaliação.
Outro ciclo de vida para a engenharia de usabilidade foi proposto por Deborah Mayhew
(1999). Esse ciclo reúne e organiza diferentes atividades em IHC.
Veja como fica o esquema do ciclo de vida para a engenharia de usabilidade.
Avaliação: verificamos se os dados coletados na atividade de análise e os requisitos
especificados estão de acordo com as necessidades dos usuários e se não existem
erros de usabilidade no sistema.
•ADD A,B
01010100 01100001
01100010
LINGUAGENS DE 4ª GERAÇÃO
(LINGUAGENS APLICATIVAS)
São, também, linguagens de alto nível, com aplicação e objetivos bem específicos.
Enquanto as linguagens de 3ª geração são procedurais, ou seja, especifica-se passo a
passo a solução do problema, as de 4ª geração são não procedurais. O programador
especifica o que deseja fazer e não comodeve ser feito.
O melhor exemplo de linguagens de 4ª geração é a SQL (Structured Query Language),
utilizada para consulta à manipulação de banco de dados. PostScript e MATLAB são outros
dois exemplos de linguagens de 4ª geração.
LINGUAGENS DE 5ª GERAÇÃO (VOLTADAS
À INTELIGÊNCIA ARTIFICIAL)
São linguagens declarativas e não algorítmicas. Exemplos: Lisp e Prolog. As linguagens de
5ª geração são usadas para desenvolvimento de sistemas especialistas (área da IA), de
sistemas de reconhecimento de voz e machine learning.
ABSTRACAO:
refere-se ao processo de ocultar detalhes complexos de implementação e fornecer uma
interface simplificada para os usuários ou desenvolvedores. Isso permite que os usuários
se concentrem nos conceitos relevantes sem precisar entender todos os detalhes
subjacentes.
PROGRAMACÃO PROCEDURAL:
Programação procedural é um paradigma de programação que se concentra em descrever
os procedimentos ou ações que o programa deve executar para alcançar um determinado
resultado. Neste paradigma, um programa é dividido em pequenos blocos de código
chamados procedimentos ou funções, cada um dos quais executa uma tarefa específica.
PROGRAMACAO NÃO PROCEDURAL:
A programação não procedural, também conhecida como programação declarativa ou
orientada a declarações, é um paradigma de programação que se concentra em definir o
que deve ser alcançado, em vez de especificar como alcançá-lo. Neste paradigma, o
programador descreve o que deseja que o programa faça, e o sistema determina
automaticamente a melhor maneira de alcançar esse objetivo.
DOMÍNIOS DA PROGRAMAÇÃO
O computador tem sido usado para diversos fins, na ciência, nas forças armadas, nas
empresas públicas e privadas, pelos profissionais liberais, pelas pessoas em seus lazeres e
onde mais possa ser aplicado. Seu uso vai desde controlar robôs que fazem a montagem
de automóveis em suas linhas de montagem até jogos digitais. Em função desse uso
adverso, surgiram linguagens de programação com diferentes objetivos. A seguir,
discutiremos as principais áreas e as respectivas linguagens de programação em destaque.
Clique nas barras para ver as informações.
APLICAÇÕES CIENTÍFICAS (MÁQUINAS DE
CALCULAR COM ALTA PRECISÃO)
O primeiro computador, o ENIAC, foi desenvolvido por 3 anos e ficou pronto no ano de
1946. Sua principal finalidade eram cálculos balísticos. Os computadores seguintes, nas
décadas de 1940 e 1950, também focaram em cálculos científicos complexos.
As linguagens de programação nessa época eram a linguagem de máquina e Assembly.
Na década de 1960 surgem as primeiras linguagens de programação de alto nível, com
destaque para Fortran (iniciais de FORmula TRANslator) e posteriormente para ALGOL60.
As principais características dessas linguagens eram:
APLICAÇÕES COMERCIAIS
Estruturas de dados simples.•
Alto volume de cálculos com aritmética de ponto flutuante (precisão).•
Preocupação com a eficiência, pois sucederam a linguagem Assembly.•
A segunda onda de aplicativos foi para suprir as demandas das empresas a partir de
meados da década de 1950. Em 1960, surge a linguagem que seria o ícone das aplicações
comerciais de computadores de grande porte, naquele momento, o COBOL. As linguagens
de programação que apoiaram o crescimento das aplicações comerciais têm como
características:
Cabe destacar que as linguagens destinadas a aplicações comerciais ganham força com a
microcomputação a partir dos anos 1980, levando as aplicações comerciais aos médios e
pequenos empresários.
APLICAÇÕES COM INTELIGÊNCIA
ARTIFICIAL
As linguagens que sustentam o desenvolvimento de aplicações apoiadas na Inteligência
Artificial (IA) ganham força nos dias de hoje.
A grande ruptura no pensamento computacional é que as linguagens que apoiam a IA
usam a computação simbólica e não numérica, como a maioria das linguagens da época.
Em 1959, surge a linguagem Lisp, primeira linguagem projetada para apoio à computação
simbólica, primeira referência da computação funcional. Prolog, criada em 1977, foi a
primeira linguagem para apoio da computação lógica, essência dos sistemas especialistas
(sistemas que usam IA para simular o comportamento humano).
PROGRAMAÇÃO DE SISTEMAS
A programação de sistemas cabe a linguagens de programação que tenham comandos e
estruturas para acessar, diretamente, o hardware. Tais linguagens são usadas para
desenvolver softwares básicos, como sistemas operacionais, tradutores e interpretadores
de linguagens de programação. Antes de surgir a linguagem C, usada para desenvolver o
sistema operacional Linux, Assembly era a linguagem usada para esse fim. A linguagem
C++ também é usada com essa finalidade.
PROGRAMAÇÃO PARA WEB
Com o crescimento da internet e tecnologias adjacentes, o uso dos sistemas se desloca do
ambiente desktop (domínio dos anos 1980 e 1990) para o ambiente Web.
No contexto de programação para Web, temos 2 diferentes ambientes de
desenvolvimento: a camada de apresentação, que roda no navegador (lado cliente) e a
camada de lógica do negócio, que roda nos servidores web (lado servidor), juntamente
Facilidade para produzir relatórios, fundamentais nos controles das operações
contábeis, bancárias, estoque e financeiras (primeiros focos da época).
•
Precisão com números decimais e ponto flutuante, para representar as altas cifras das
grandes empresas, as primeiras a investirem nessas aplicações.
•
Capacidade de especificar operações aritméticas comerciais.•
com a camada de persistência, considerando o modelo de desenvolvimento em 3 camadas
(apresentação, lógica do negócio e persistência de dados).
Para a camada de apresentação, usa-se as linguagens HTML (linguagem de marcação) e
CSS (usada em conjunto com HTML para definir a apresentação da página web), além de
JavaScript (programação de scripts), no lado cliente (navegadores).
Para o desenvolvimento das camadas de lógica do negócio, as principais LP são: C#, PHP,
ASP, .NET, Java, Ruby e Python.
PROGRAMAÇÃO MOBILE
Considerando que hoje em dia, grande parte da população, no Brasil e no Mundo, tem
acesso à internet pelo celular, cresceu vertiginosamente a quantidade de apps (aplicativos)
para uso de aplicações via celular. Os apps, na verdade, são interfaces que rodam no lado
cliente.
As principais (não todas) linguagens que apoiam o desenvolvimento de apps para o
mundo mobile, oficialmente indicadas por seus fabricantes, são:
O desenvolvimento de APP para iOS é baseado numa IDE chamada Xcode que permite o
desenvolvimento de APP em várias linguagens, como: C, C++, Java e Python, mas
oficialmente orienta o Swift e Objective-C.
A Google, por sua vez, tem por base o Android SDK, orienta a usar as linguagens Kotlin,
Java e C++, mas as linguagens Python, Shell script, Basic4Android, LiveCode (para iOS e
Windows também), App Inventor (não necessita conhecer programação) e Unity (motor
para games) e GO, também são usadas para desenvolver app para Android.
No contexto de desenvolvimento de APP para Windows, foi lançado no Windows 8.1 e
atualizado para atender também ao Windows 10, o App Studio, que permite a qualquer
pessoa criar em poucos passos um app Windows e publicá-lo na loja.
Importante destacar que hoje existem plataformas de desenvolvimento mobile conectadas
a nuvem que fomentam o desenvolvimento de apps nativos para iOS, Android e Windows.
AVALIAÇÃO DE LINGUAGENS DE
PROGRAMAÇÃO
Segundo Sebesta (2018) são quatro grandes critérios para avaliação das linguagens de
programação, dentro de um mesmo domínio de programação. Cada critério é influenciado
por algumas características da linguagem.
Android: Java e Kotlin.•
iOS: Swift (oficial da Apple) e Objective-C (código nativo para iOS).•
Windows:C#, Visual Basic (VB), C++, HTML, CSS, JavaScript e Java.•
Legibilidade
Um dos critérios mais relevantes é a “facilidade com que os programas podem ser lidos e
entendidos” pelas pessoas que não necessariamente participaram do desenvolvimento.
Facilidade de escrita
O quão facilmente uma linguagem pode ser usada para desenvolver programas para o
domínio do problema escolhido.
Confiabilidade
Um programa é dito confiável se ele se comporta conforme a sua especificação, repetidas
vezes.
Custo
O custo final de uma linguagem de programação é em função de muitas de suas
propriedades e características.
TRADUÇÃO
Nesse processo de conversão, o programa escrito em uma linguagem de alto nível é
traduzido para uma versão equivalente em linguagens de máquina, antes de ser
executado. O processo de tradução pode ser executado em várias fases, que podem ser
combinadas e executadas em simultaneidade. O processo de tradução é erroneamente
chamado de compilação, que na verdade é uma de suas fases.
As fases que compõem o tradutor, ou seja, iniciando na leitura do programa-fonte
(linguagem de alto nível) e terminando com a geração do código executável (entendido
pela máquina), são: Compilação, Montagem, Carga e Ligação. A imagem abaixo ilustra o
processo de tradução.
Clique nas palavras.
Código-fonte
Compilador
Código Assembly
Montador
Ligador
Código-objeto relocável
Carregador
Código objeto
Código executável
Fases de tradução de um programa em linguagem de alto nível.Fonte: Autor.
Compilador
É o elemento central do processo de tradução, responsável pelo custo de compilação,
visto no modulo anterior. Em função dessa relevância, muitas vezes o processo como um
todo é erroneamente chamado de compilação, uma vez que o ambiente integrado das
linguagens atuais já integra todos os componentes (montador, compilador, carregador e
ligador) quando necessário.
O projeto da linguagem tem no compilador a sua figura central.
A imagem abaixo ilustra os componentes envolvidos na compilação de um programa
fonte:
Fonte: https://johnidm.gitbooks.io/compiladores-para-
humanos/content/part1/introduction-and-overview-about-compilers.html
Abaixo, vamos entender cada fase da compilação:
Clique nas barras para ver as informações.
ANÁLISE LÉXICA
Identifica os tokens (elementos da linguagem), desconsidera partes do código-fonte, como
espaços em branco e comentários e gera a Tabela de símbolos, com todos esses tokens,
que são identificadores de variáveis, de procedimentos, de funções, comandos, expressões
etc.
ANÁLISE SINTÁTICA
Verifica se os tokens são estruturas sintáticas (exemplos: expressões e comandos) válidas,
aplicando as regras gramaticais definidas no projeto da linguagem.
https://johnidm.gitbooks.io/compiladores-para-humanos/content/part1/introduction-and-overview-about-compilers.html
https://johnidm.gitbooks.io/compiladores-para-humanos/content/part1/introduction-and-overview-about-compilers.html
ANÁLISE SEMÂNTICA
Verifica se as estruturas sintáticas possuem sentido. Por exemplo, verifica se um
identificador de variável ou constante é usado adequadamente, se operandos e
operadores são compatíveis. Monta a árvore de derivação conforme ilustrado abaixo para
formação das expressões.
Árvore de derivação de uma expressão. Fonte: Autor
GERADOR DE CÓDIGO INTERMEDIÁRIO,
OTIMIZADOR DE CÓDIGO E GERADOR DE
CÓDIGO
Em distintas fases geram o programa-alvo ou programa-objeto.
Na imagem a seguir, o código intermediário está representado no último quadro – código
em Assembly:
Gerador de código intermediário, que contém toda a informação para gerar o
código-objeto.
1.
O otimizador tem por objetivo eliminar redundâncias do código intermediário e
tornar o objeto mais enxuto e eficiente.
1.
TRATADOR DE ERROS
Em todas as fases existem erros: léxicos, sintáticos e semânticos. Um bom compilador
apresenta uma boa tratativa de erros.
GERENCIADOR DA TABELA DE SÍMBOLOS
Mantém a tabela de símbolos atualizada a cada passo do compilador.
Atenção
As principais características dos compiladores são:
INTERPRETAÇÃO
A imagem abaixo ilustra o simples processo de Interpretação:
Gerar código-objeto mais otimizado.•
Execução mais rápida que o processo de interpretação.•
Traduz um mesmo comando apenas uma vez, mesmo que usado em várias partes do
programa – tanto iterações como repetição de código.
•
Processo de correção de erros e depuração é mais demorado.•
A programação final (código-objeto) é maior.•
O programa-objeto gerado é dependente de plataforma — processador + SO
(Sistema Operacional) — necessitando de um compilador diferente para cada família
de processadores/sistema operacional.
•
Na conversão por interpretação, cada comando do programa-fonte é traduzido e
executado (um a um) imediatamente. O interpretador traduz um comando de cada vez e
chama uma rotina para completar a sua execução.
O interpretador é um programa que executa repetidamente a seguinte sequência:
1
Obter a próxima instrução do código-fonte.
2
Interpretar a instrução (conversão para comandos em linguagem de máquina).
3
Executar a instrução.
Perceba que o procedimento, acima descrito, é bastante similar àquele executado por
computadores que implementam a máquina de Von Neumann, na execução de uma
instrução, conforme a seguir:
Clique na barra para ver as informações.
PRINCIPAIS CARACTERÍSTICAS DO
INTERPRETADOR
Dentre as principais características do interpretador, podemos citar:
Tradução x interpretação
Obter a próxima instrução.•
CI → endereço da próxima instrução. CI = contador de instruções.•
RI → instrução a ser executada. RI = registrador de instruções.•
Decodificar a instrução.•
Executar a instrução.•
Atua a cada vez que o programa precisa ser executado.•
Não produz programa-objeto persistente.•
Não traduz instruções que nunca são executadas.•
O resultado da conversão é instantâneo: resultado da execução do comando ou
exibição de erro – interpretador puro.
•
Útil ao processo de depuração de código devido a mensagens de erros em tempo de
execução (tanto análise sintática como semântica).
•
Execução mais lenta do que outros processos de tradução (compilação), pois toda vez
que o mesmo programa é executado, os mesmos passos de interpretação são
executados.
•
Consome menos memória.•
O Código-fonte é portátil.•
Não é gerado um código de máquina.◦
Pode executar o comando em alto nível diretamente ou gerar um código
intermediário, que neste caso é interpretado por uma máquina virtual (VM). –
Interpretador híbrido.
◦
Se a máquina virtual foi desenvolvida para diferentes plataformas, temos a
portabilidade do código-fonte. Este é o caso da linguagem Java.
◦
Fonte: http://codemastersufs.blogspot.com/2015/10/compiladores-versus-
interpretadores.html. Adaptado pelo autor.
SISTEMAS HÍBRIDOS
O processo híbrido de implementação de uma linguagem de programação combina a
execução rápida dos tradutores (compiladores) com a portabilidade dos interpretadores. O
segredo é a geração de um código intermediário mais facilmente interpretável, porém não
preso a uma plataforma (SO/Hardware).
Esse código intermediário não é específico para uma plataforma, possibilitando aos
programas já compilados para esse código serem portados em diferentes plataformas,
sem alterar e nem fazer nada. Para cada plataforma desejada devemos ter um
interpretador desse código.
Vantagens
Desvantagens
Tradutores
1. Execução mais rápida
2. Permite estruturas de
programas mais
complexas.
3. Permite a otimização
de código.
1. Várias etapas de
conversão.
2. Programação final é
maior, necessitando de
mais memória para sua
execução.
3. Processo de correção
de erros e depuração é
mais demorado.
Interpretadores
1. Depuração mais
simples.
2. Consome menos
memória.
3. Resultado imediato do
programa (ou parte dele).
1. Execução do programa
é mais lenta.
2. Estruturas de dados
demasiado simples.
3. Necessário fornecer o
código fonte ao
utilizador.
http://codemastersufs.blogspot.com/2015/10/compiladores-versus-interpretadores.html
http://codemastersufs.blogspot.com/2015/10/compiladores-versus-interpretadores.htmlDuas importantes linguagens implementaram essa solução, com diferentes formas usando
máquinas virtuais: Python e Java.
Sistema de implementação de Python
Python usa um sistema híbrido, uma combinação de interpretador e tradutor (compilador).
O compilador converte o código-fonte Python em um código intermediário, que roda
numa máquina virtual, a PVM (Python Virtual Machine).
Características gerais dos subprogramas
Definições básicas
As definições básicas, segundo Sebesta (2018), estabelecem que:
Um subprograma é definido quando o desenvolvedor descreve a interface e as ações da
abstração desse subprograma.
O subprograma é chamado quando uma instrução traz um pedido explícito para sua
execução.
O subprograma estará ativo após o início de sua execução, que se dá a partir da sua
chamada, e enquanto ele não for concluído.
float calculaIMC (int peso, float altura)
Em Python, as funções definidas pelo desenvolvedor devem ser precedidas pela palavra
reservada def. Não são especificados o tipo de retorno e os tipos dos parâmetros, como
no exemplo a seguir:
Cada subprograma tem um único ponto de entrada.1.
A unidade de programa chamadora é suspensa durante a execução do subprograma
chamado, o que significa que existe apenas um subprograma em execução em
determinado momento.
2.
Quando a execução do subprograma termina, o controle sempre retorna para o
chamador.
3.
def calculaIMC (peso, altura)
Em Python, as sentenças de função def são executáveis. Isso implica que a função só pode
ser chamada após a execução da sentença def.
Parâmetros, procedimentos e funções
Parâmetros
Usualmente, um subprograma executa cálculos e operações a partir de dados que ele deve
processar. Há duas maneiras de o subprograma obter esses dados: acessar variáveis não
locais, mas visíveis para o subprograma, ou pela passagem de parâmetros.
Quando o subprograma recebe os parâmetros adequados, ele pode ser executado com
quaisquer valores recebidos. Porém, quando ele manipula variáveis não locais, uma forma
de evitar alterações indevidas nessas variáveis é fazer cópias locais delas.
De acordo com Sebesta (2018), o acesso sistemático a variáveis não locais pode diminuir a
confiabilidade do programa. São denominados parâmetros formais aqueles do cabeçalho
do subprograma.
Quando o subprograma é chamado, é necessário escrever o nome dele e a lista de
parâmetros a serem vinculados a seus parâmetros formais, que são denominados
parâmetros reais ou argumentos.
Procedimentos e funções
Procedimentos
São aqueles que não retornam valores.
close
Funções
São aquelas que retornam valores.
Na maioria das linguagens que não explicita a diferença entre ambos, as funções podem
ser definidas sem retornar qualquer valor, tendo um comportamento de procedimento.
Esse é o caso de Python.
Veja o código a seguir (código 13 no arquivo disponibilizado na introdução deste texto):
-------------------------------------------
def func1(x):
x = 10
print(f'Função func1 - x = {x}')
def func2(x):
x = 20
print(f'Função func2 - x = {x}')
x = 0
func1(x)
func2(x)
print(f'Programa principal - x = {x}')
Ambientes de referenciamento local
Variáveis locais
Quando um subprograma define as próprias variáveis, ele estabelece ambientes de
referenciamento local. Essas variáveis são chamadas de variáveis locais, nas quais seu
escopo usualmente é o corpo do subprograma.
As variáveis locais podem ser:
Subprogramas aninhados
Métodos de passagens de parâmetros
Os métodos de passagem de parâmetros são as maneiras existentes para transmiti-los ou
recebê-los dos subprogramas chamados. Os parâmetros podem ser passados
principalmente por:
Valor
O parâmetro formal funciona como uma variável local do subprograma, sendo inicializado
com o valor do parâmetro real. Dessa maneira, não ocorre uma alteração na variável
externa ao subprograma caso ela seja passada como parâmetro.
Referência
Em vez de passar o valor do parâmetro real, é transmitido um caminho de acesso
(normalmente, um endereço) para o subprograma chamado. Isso fornece o caminho de
acesso para a célula que armazena o parâmetro real. Assim, o subprograma chamado
pode acessar esse parâmetro na unidade de programa chamadora.
Funções recursivas
Uma função recursiva é aquela que chama a si mesma. Veja o exemplo da função
regressiva() (código 16 do arquivo disponibilizado):
A função recursiva fatorial
A função matemática fatorial de um inteiro não negativo n é calculada por:
A sequência de Fibonacci
A sequência de Fibonacci é: 1, 1, 2, 3, 5, 8, 13, 21... Os dois primeiros termos são 1; a partir
do 3º termo, cada termo é a soma dos dois anteriores.
Documentação de funções – Docstrings
Docstrings
Em Python, é possível definir uma string que serve como documentação de funções
definidas pelo desenvolvedor. Ao chamar o utilitário help() passando como parâmetro a
função desejada, essa string é exibida.
Bibliotecas em
Python
import matplotlib.pyplot as plt / essa biblioteca gera um grafico de barras em pyhton
ex:
import matplotlib.pyplot as plt
# Dados para o gráfico de barras
categorias = ['A', 'B', 'C', 'D']
valores = [10, 20, 15, 2]
# Criar o gráfico de barras
plt.bar(categorias, valores)
# Adicionar título e rótulos aos eixos
plt.title('Gráfico de Barras')
plt.xlabel('Categorias')
http://plt.bar(categorias/
http://plt.bar(categorias/
plt.ylabel('Valores')
# Mostrar o gráfico
plt.show()
Importação de funções e módulos
Biblioteca padrão Python
A biblioteca padrão Python (Python standard library) consiste em milhares de funções,
métodos e classes relacionados a determinada finalidade e organizados em componentes
chamados de módulos. Há mais de 200 módulos que dão suporte, entre outras coisas, a:
Como usar uma função de módulo importado
Para usar as funções e os métodos de um módulo, são necessários dois passos:
Fazer a importação do módulo desejado com a instrução:
import nome_modulo
close
Chamar a função desejada, precedida do nome do módulo, com a instrução:
nome_modulo.nome_funcao(paramêtros)
math (dedicado a operações matemáticas) e calcular a raiz quadrada de 5 por meio da
função sqrt()
import math
x = math.sqrt(5)
print(x)
A partir desse ponto, serão apresentados os principais aspectos dos seguintes módulos:
math
Usado para operações matemáticas.
random
Usado para gerar números pseudoaleatórios.
smtplib
Operações matemáticas.1.
Interface gráfica com o usuário (GUI).2.
Funções matemáticas e geração de números pseudoaleatórios.3.
http://plt.show/
http://plt.show/
Usado para permitir envio de e-mails.
time
Usado para implementar contadores temporais.
tkinter
Usado para desenvolver interfaces gráficas.
Módulos nativos do Python
Módulo math
Esse módulo provê acesso a funções matemáticas de argumentos reais. As funções não
podem ser usadas com números complexos.
Listaremos agora algumas das funções do módulo math:
Módulo random
Esse módulo implementa geradores de números pseudoaleatórios para várias
distribuições.
Números inteiros
Função
Retorno
sqrt(x) Raiz quadrada de x
ceil(x)
Menor inteiro maior ou
igual a x
floor(x)
Maior inteiro menor ou
igual a x
cos(x) Cosseno de x
sin(x) Seno de x
log(x, b) Logaritmo de x na base b
pi Valor de Pi (3.141592...)
e Valor de e (2.718281...)
Para inteiros, existe:
- Uma seleção uniforme a partir de um intervalo.
Sequências
Para sequências, existem:
- Uma seleção uniforme de um elemento aleatório; - Uma função para gerar uma
permutação aleatória das posições na lista; - Uma função para escolher aleatoriamente
sem substituição.
Distribuições de valores reais
A tabela a seguir mostra algumas das principais funções disponíveis para distribuições de
valores reais no módulo random.
Funções para números inteiros
Veja algumas das principais funções disponíveis para inteiros no módulo random.
Função
Retorno
random()
Número de ponto
flutuante no intervalo
(00,0, 1,0)
uniform(a, b)
Número de ponto
flutuante N tal que a ≤ N
≤ b
gauss(mu, sigma)
Distribuição gaussiana.
mué a média e sigmaé o
desvio padrão.
normalvariate(mu,sigma)
Distribuição gaussiana.
mué a média e sigmaé o
desvio padrão.
Módulo SMTPLIB
Esse módulo define um objeto de sessão do cliente SMTP que pode ser usado a fim
de enviar e-mail para qualquer máquina da internet com um serviço de
processamento SMTP ou ESMTP. O exemplo a seguir vai permitir que você envie um e-
mail a partir do servidor SMTP do Gmail.
Como a Google não permite, por padrão, realizar o login com a utilização do smtplib por
considerar esse tipo de conexão mais arriscada, será necessário alterar uma configuração
de segurança. Para resolver isso, siga estas instruções:
Para fazer seu primeiro envio, crie um programa no seu projeto. O codigo a seguir mostra
as importações necessárias para o envio:
#import dos pacotes necessários
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
Acesse sua conta no Google.1.
Depois acesse Segurança.2.
Acesso a app menos seguro.3.
Atenção!Em algumas contas, os nomes estarão escritos no idioma inglês (Allow less
secure apps).
4.
Mude para "ativada" a opção de "Permitir aplicativos menos seguros".5.
Função
Retorno
randrange(stop)
Um elemento
selecionado aleatório de
range(start, stop, step),
mas sem construir um
objeto range.
randrange(start, stop,
[step])
randint(a, b)
Número inteiro N tal que
a ≤ N ≤ b
#criação de um objeto de mensagem
msg = MIMEMultipart()
texto = "Estou enviando um email com Python"
#parâmetros
senha = "SUA SENHA"
msg['From'] = "SEU E-MAIL"
msg['To'] = "E-MAIL DESTINO"
msg['Subject'] = "ASSUNTO"
#criação do corpo da mensagem
msg.attach(MIMEText(texto, 'plain'))
O próximo código mostra os passos necessários para o próprio envio:
#criação do servidor
server = smtplib.SMTP('smtp.gmail.com: 587')
server.starttls()
#Login na conta para envio
server.login(msg['From'], senha)
#envio da mensagem
server.sendmail(msg['From'], msg['To'], msg.as_string())
#encerramento do servidor
server.quit()
print('Mensagem enviada com sucesso')
O código referente ao programa para o envio de e-mail a partir do servidor SMTP do
Gmail encontra-se no arquivo disponibilizado neste conteúdo (código 28).
Módulo time
Esse módulo provê diversas funções relacionadas a tempo. Também pode ser útil conhecer
os módulos datetime e calendar.
Esta tabela aponta algumas das principais funções disponíveis no módulo time:
A linha 7 mostra a criação de um objeto de mensagem.1.
A linha 8 exibe o corpo da mensagem em uma string.2.
As linhas de 11 a 14 devem ser preenchidas com os valores adequados para que seu
programa seja executado com sucesso.
3.
A linha 17 anexa o corpo da mensagem (que estava em uma string) ao objeto msg.4.
As linhas 20 e 21 mostram a criação do servidor e a sua conexão no modo TLS.1.
A linha 24 mostra o login na conta de origem do e-mail.2.
A linha 27 representa o envio propriamente dito.3.
A linha 30 exibe o encerramento do servidor.4.
import time
x = time.time()
print(f'Local time: {time.ctime(x)}')
A variável x recebe o número de segundos desde 00:00:00 de 01/01/1970 pela função
time(). Ao executar ctime(x), o número de segundos armazenado em x é convertido em
uma string com o horário local.
A classe time.struct_time gera objetos sequenciais com valor de tempo retornado pelas
funções gmtime() e localtime(). São objetos com interface de tupla nomeada: os valores
podem ser acessados pelo índice e pelo nome do atributo.
Função
Retorno
time()
Número de segundos
passados desde o início
da contagem (epoch).
Por padrão, o início é
00:00:00 do dia 1 de
janeiro de 1970.
ctime(segundos)
Uma
stringrepresentando o
horário local, calculado a
partir do número de
segundos passado como
parâmetro.
gmtime(segundos)
Converte o número de
segundos em um objeto
struct_timedescrito a
seguir.
localtime(segundos)
Semelhante à gmtime(),
mas converte para o
horário local.
sleep(segundos)
A função suspende a
execução por
determinado número de
segundos.
Aparecem os seguintes valores :
Módulo tkinter
O pacote tkinter é a interface Python padrão para o Tk GUI (interface gráfica com o
usuário) toolkit. Na maioria dos casos, basta importar o próprio tkinter, mas diversos
outros módulos estão disponíveis no pacote. A biblioteca tkinter permite a criação de
janelas com elementos gráficos, como a entrada de dados e botões, por exemplo.
O exemplo a seguir vai permitir que você crie a primeira janela com alguns elementos.
Para isso, crie um programa novo no seu projeto. O código adiante mostra a criação da
sua primeira janela, ainda sem qualquer elemento gráfico.
from tkinter import *
janelaPrincipal = Tk()
janelaPrincipal.mainloop()
Índice
Atributo
Valores
0 tm_year Por exemplo, 2020
1 tm_mon range [1, 12]
2 tm_mday range [1, 31]
3 tm_hour range [0, 23]
4 tm_min range [0, 59]
5 tm_sec range [0, 61]
6 tm_wday
range [0, 6] Segunda-
feira é 0
7 tm_yday range [1, 366]
8 tm_isdst 0,1 ou -1
N/A tm_zone
Abreviação do nome da
timezone
from tkinter import *
janelaPrincipal = Tk()
texto = Label(master = janelaPrincipal, text = "Minha janela exibida")
texto.place(x = 50 y = 100)
janelaPrincipal.mainloop()
amos agora incrementar um pouco essa janela. Para isso, acrescentaremos uma imagem e
um botão. A imagem precisa estar na mesma pasta do seu arquivo .py.
from tkinter import *
def funcClicar():
print("Botão pressionado")
janelaPrincipal = Tk()
texto = Label(master = janelaPrincipal, text = "Minha janela exibida")
texto.pack()
pic = PhotoImage(file="logoEstacio.gif")
logo = Label(master = janelaPrincipal, image = pic)
logo.pack()
botao = Button(master = janelaPrincipal, text = 'Clique', command = funcClicar)
botao.pack()
janelaPrincipal.mainloop()
Verifique o resultado na imagem seguinte:
Abaixo você encontra uma lista com alguns dos pacotes externos mais comuns e utilizados
no mercado:
A linha 1 mostra a importação de todos os elementos disponíveis em tkinter. O objeto
janelaPrincipal é do tipo Tk. Um objeto Tk é um elemento que representa a janela
GUI. Para que essa janela apareça, é necessário chamar o método mainloop();
1.
Para exibir textos, vamos usar o elemento Label. O próximo código mostra as linhas 4
e 5, com a criação do elemento e o seu posicionamento. O tamanho padrão da janela
é 200 X 200 pixels, com o canto superior esquerdo de coordenadas (0,0) e o inferior
direito de coordenadas (200,200).
2.
No código anterior, há a inserção do elemento de imagem e o botão. Nas linhas 10,
11 e 12, é feita a criação do objeto Label para conter a imagem e seu posicionamento.
Observe que passamos a utilizar o método pack(), que coloca o elemento centralizado
e posicionado o mais perto possível do topo, depois dos elementos posicionados
anteriormente.
1.
O elemento botão é criado na linha 14 com os atributos text e command, os quais
são respectivamente o texto exibido no corpo do botão e a função a ser executada
quando o botão é clicado.
2.
Para o funcionamento correto do botão, é preciso definir a função funcClicar(), nas
linhas 3 e 4. Essa função serve apenas para imprimir na tela a string “Botão
pressionado”.
3.
Tratamento de exceções na linguagem
Python
Em Python, o tratamento de exceções é uma técnica usada para lidar com erros durante a
execução do programa de forma controlada, permitindo que o código continue a ser
executado mesmo após a ocorrência de um erro. Isso é feito utilizando as instruções try ,
except , else e finally .
try:
x = iny(input("Digite um numero ")
except ValueError:
print("Entre com Numeros " )
Neste código corrigido, o bloco try tenta converter a entrada do usuário para um
número inteiro usando a função int(input()) . Se o usuário digitar algo que não possa
ser convertido para um número inteiro, uma exceção do tipo ValueError será lançada, e
o código no bloco except será executado, imprimindo uma mensagem de erro.
Nome do módulo
Pra que serve?
numpy
Cálculos, operações
matemáticas e
simulações
pandas Manipulaçao de dados
scikit-learn
Modelos de aprendizado
de máquina
matplotlib Visualização de dados
requests
Biblioteca de comandos
de comunicaçãopelo
protocolo HTTP
flask
Construção de aplicações
web
Erros e exceções
Até agora consideramos que nossos programas tiveram seu fluxo de execução normal.
Neste módulo, vamos analisar o que acontece quando o fluxo de execução é interrompido
por uma exceção, além de controlar esse fluxo excepcional.
Dois tipos básicos de erros podem acontecer em um programa em Python. Os erros de
sintaxe são aqueles que ocorrem devido ao formato incorreto de uma instrução. Esses
erros são descobertos pelo componente do interpretador Python, que é chamado
analisador ou parser.
A tabela a seguir traz alguns tipos comuns de exceção:
Exceção
Explicação
KeyboardInterrupt
Levantado quando o
usuário pressiona
CTRL+C, a combinação
de interrupção.
OverflowError
Levantado quando uma
expressão de ponto
flutuante é avaliada
como um valor muito
grande.
ZeroDivisionError
Levantado quando se
tenta dividir por 0.
IOError
Levantado quando uma
operação de
entrada/saída falha por
um motivo relacionado a
isso.
IndexError
Levantado quando um
índice sequencial está
fora do intervalo de
índices válidos.
NameError
Levantado quando se
tenta avaliar um
identificador (nome) não
atribuído.
TypeError
Levantado quando uma
operação da função é
aplicada a um objeto do
tipo errado.
Em Python, as exceções são objetos. A classe Exception é derivada de BaseException,
classe base de todas as classes de exceção. BaseException fornece alguns serviços úteis
para todas as classes de exceção, mas normalmente não se torna uma subclasse
diretamente.
Tratamento de exceções e eventos
Captura e manipulação de exceções
Para evitar que os programas sejam interrompidos quando uma exceção é levantada, é
possível planejar um comportamento alternativo. Assim, o programa não será
interrompido e a exceção poderá ser tratada. Chamamos esse processo de captura da
exceção.
Vamos considerar um exemplo de programa que solicita ao usuário, com a função input(),
um número inteiro. Embora essa função trate a entrada do usuário como string, é possível
utilizá-la em conjunto com a função eval() para que os dados inseridos sejam avaliados
como números.
Bloco try
O bloco try é executado primeiramente. Devem ser inseridas nele as instruções do fluxo
normal do programa.
close
Bloco except
O bloco except só será executado se houver o levantamento de alguma exceção.
Orientação a objetos
PARA CRIA UMA CLASSE EM PYTHON BASTA FAZER O CODIGO A SEGUIR
Class Pessoa:
def _init_(self ,nome):
self.set(nome)
def set_nome(self , nome):
self.nome = nome
def get__nome(self)
return self.nome
agora para chamar a Class em algum objeto bastar fazer isso:
pessoa1 = Pessoa("Geraldo")
print(pessoa1.get_nome())
Conceitos e pilares de programação
orientada a objetos
Conceitos de programação orientada a objetos (POO)
A POO foi considerada uma revolução na programação, pois mudou completamente a
estruturação dos programas de computador. Essa mudança se estendeu inclusive para os
modelos de análise do mundo real e, em seguida, para a implementação dos respectivos
modelos nas linguagens de programação orientadas a objetos.
Conforme apresentam Rumbaugh e demais autores (1994):
“A tecnologia baseada em objetos é mais do que apenas uma forma de programar. Ela é
mais importante como um modo de pensar em um problema de forma abstrata, utilizando
conceitos do mundo real, e não ideias computacionais”.
(JAEGER, 1995)
Muitas vezes, analisamos um problema do mudo real pensando no projeto, que, por sua
vez, é influenciado por ideias sobre codificação. Tais ideias também são fortemente
influenciadas pelas linguagens de programação disponíveis.
A abordagem baseada em objetos permite que os mesmos conceitos e a mesma notação
sejam usados durante todo o processo de desenvolvimento de software, ou seja, não
existem conceitos de análise de projetos diferentes daqueles relativos à implementação
dos projetos.
Essa abordagem procura refletir os problemas do mundo real por meio da interação de
objetos modelados computacionalmente. Portanto, o desenvolvedor do software não
necessita realizar traduções para outra notação em cada etapa do desenvolvimento de um
projeto de software (COSTA, 2015).
O software é organizado como uma coleção de objetos separados que incorpora tanto a
estrutura quanto o comportamento dos dados. Isso contrasta com a programação
convencional, segundo a qual a estrutura e o comportamento dos dados têm pouca
vinculação entre si.
Os modelos baseados em objetos correspondem mais aproximadamente ao mundo real.
Em consequência disso, eles são mais adaptáveis às modificações e às evoluções dos
sistemas.
Pilares da orientação a objetos
Objetos
Um objeto é a representação computacional de um elemento ou processo do mundo real.
Cada objeto possui suas características (informações) e uma série de operações
(comportamento) que altera as suas características (estado do objeto).
Todo o processamento das linguagens de programação orientadas a objetos se baseia no
armazenamento e na manipulação das informações (estados). São exemplos de objetos do
mundo real e computacional: Aluno, Professor, Livro, Empréstimo e Locação (Costa, 2015).
Durante a etapa de levantamento dos objetos, deve-se analisar apenas os objetos
relevantes (abstrair) com as respectivas características mais importantes para o problema a
ser resolvido.
extension
Exemplo
As características de uma pessoa para um sistema acadêmico podem ser a formação ou o
nome do pai e o da mãe, enquanto as de um indivíduo, para o sistema de controle de uma
academia, são a altura e o peso.
Atributos
São propriedades do mundo real que descrevem um objeto. Cada objeto possui as
respectivas propriedades desse mundo, as quais, por sua vez, possuem valores. A
orientação a objetos define as propriedades como atributos. Já o conjunto de valores dos
atributos de um objeto define o seu estado naquele momento (RUMBAUGH, 1994).
Observe a seguir a diferença entre os atributos de duas mulheres:
Atributos de objetos da pessoa 1.
Atributos e valores armazenados
Nome - Maria
Idade - 35
Peso - 63kg
Altura - 1,70m
Atributos e valores armazenados
Nome - Joana
Idade - 30
Peso - 60kg
Altura - 1,65m
Atributos de objetos da pessoa 2.
Operações
Uma operação é uma função ou transformação que pode ser aplicada a objetos ou dados
pertencentes a um objeto. É importante dizer que todo objeto possui um conjunto de
operações, as quais, aliás, podem ser chamadas por outros objetos com o propósito de
colaborarem entre si.
Esse conjunto de operações é conhecido como interface.
A única forma de colaboração entre os objetos é por meio das suas respectivas interfaces
(FARINELLI, 2020). Utilizando o exemplo acima, podemos alterar o nome, a idade e o peso
da pessoa graças a um conjunto de operações. Desse modo, essas operações
normalmente alteram o estado do objeto.
Vejamos agora outros exemplos de operações:
extension
Exemplo
Classe empresa = Contratar_Funcionario, Despedir_Funcionario;
Classe janela = Abrir, fechar, ocultar.
O desenvolvimento de um sistema orientado a objetos consiste em realizar um
mapeamento conforme o apresentado na imagem a seguir.
Mapeamento de objetos do mundo real.
Basicamente, deve-se analisar o mundo real e identificar quais objetos precisam fazer
parte da solução do problema. Para cada objeto identificado, levantam-se os atributos,
que descrevem as propriedades dos objetos, e as operações, que podem ser executadas
sobre tais objetos.
O conceito de encapsulamento
Seu conceito consiste na separação dos aspectos externos (operações) de um objeto
acessíveis a outros objetos, além de seus detalhes internos de implementação, que ficam
ocultos dos demais objetos (RUMBAUGH, 1994). Algumas vezes, o encapsulamento é
conhecido como o princípio do ocultamento de informação, pois permite que uma classe
encapsule atributos e comportamentos, ocultando os detalhes da implementação.
Partindo desse princípio, a interface de comunicação de um objeto deve ser definida a fim
de revelar o menos possível sobre o seu funcionamentointerno.
extension
Exemplo
Foi desenvolvido um objeto ApresentaçãoMapa pertencente a um aplicativo de entrega
móvel, que possui a responsabilidade de apresentar um mapa com o menor caminho
entre dois pontos. No entanto, o objeto não “sabe” como calcular a distância entre os dois
pontos. Para resolver esse problema, ele precisa colaborar com um objeto Mapa que
“saiba” calcular e, portanto, possua essa responsabilidade.
O objeto Mapa implementa essa responsabilidade por meio da operação Calcula Melhor
Caminho, cujo resultado é a menor rota entre duas coordenadas geográficas. Utilizando o
encapsulamento, o objeto Mapa calcula e retorna o melhor caminho para o objeto
ApresentaçãoMapa de maneira transparente, escondendo a complexidade da execução
dessa tarefa.
Encapsulamento da classe Mapa.
Uma característica importante do encapsulamento é que pode surgir um modo diferente
de se calcular o melhor caminho entre dois pontos. Por conta disso, o objeto Mapa deverá
mudar o seu comportamento interno para implementar esse novo cálculo. Contudo, essa
mudança não afetará o objeto ApresentaçãoMapa, pois a implementação foi realizada
isoladamente (encapsulamento) no objeto Mapa sem causar impacto em outros objetos
no sistema.
text_snippet
Resumindo
Os objetos clientes têm conhecimento apenas das operações que podem ser requisitadas
e precisam estar cientes somente do que elas realizam, e não de como estão
implementadas.
Os mecanismos de herança e polimorfismo
Herança
Na orientação a objetos, a herança é um mecanismo por meio do qual classes
compartilham atributos e comportamentos, formando uma hierarquia. Uma classe herdeira
recebe as características de outra classe para reimplementá-las ou especializá-las de uma
maneira diferente da classe pai.
A herança permite capturar similaridades entre classes, dispondo-as em hierarquias. As
similaridades incluem atributos e operações sobre as classes (FARINELLI, 2020).
Essa estrutura reflete um mapeamento entre classes, e não entre objetos, conforme o
esquema a seguir:
Exemplo de herança.
No esquema anterior, as classes Carro, Moto, Caminhão e Ônibus herdam características
em comum da classe Veículo, como os atributos chassis, ano, cor e modelo.
Uma classe pode ser definida genericamente como uma superclasse e, em seguida,
especializada em classes mais específicas (subclasses). A herança permite a reutilização de
código em larga escala, pois possibilita que se herde todo o código já implementado na
classe pai e se adicione apenas o código específico para as novas funcionalidades
implementadas pela classe filha.
A evolução dos sistemas orientados a objetos também é facilitada, uma vez que, caso surja
uma classe nova com atributos e/ou operações comuns a outra, basta inseri-la na
hierarquia, acelerando a implementação.
Conheça a seguir os tipos de herança:
Herança simples
expand_more
Herança múltipla
expand_more
Polimorfismo
Agregação, classes e métodos estáticos
(parte 1)
Atributos públicos e privados
Para seguir o encapsulamento e proibir alterações indevidas dos atributos, deve-se definir
atributos privados para a classe. Por default, em Python, os atributos são definidos como
público, ou seja, podem ser acessados diretamente sem respeitar o encapsulamento -
acesso feito apenas por meio de métodos do objeto.
Para tornar um atributo privado, é preciso iniciá-lo com dois underscores (‘__’). E qual seria
o retorno do interpretador ao se acessar um atributo privado para classe Conta? Um erro
seria gerado.
Clique em Executar no emulador abaixo - no qual existe uma classe chamada Conta com
todos os atributos privados - e verifique:
Decorator @property
Uma estratégia importante disponibilizada pelo Python são as properties. Utilizando o
decorator property nos métodos, mantém-se os atributos como protegidos, os quais, por
sua vez, são acessados apenas por meio dos métodos “decorados” com property
(CAELUM, 2020).
No caso da classe Conta, não se pode acessar o atributo saldo (privado) para leitura. Com
o código, ele será acessado pelo método decorator @property:
@property
def saldo(self):
return self._saldo
Atributos de classe
Existem algumas situações em que os sistemas precisam controlar valores associados à
classe, e não aos objetos (instâncias) das classes. É o caso, por exemplo, ao se desenvolver
um aplicativo de desenho, como o Paint, que precisa contar o número de círculos criados
na tela.
Inicialmente, a classe Círculo vai ser criada:
class Circulo():
def__init__(self,pontox,pontoy,raio):
self.pontox = pontox
self.pontoy = pontoy
self.raio = raio
Métodos estáticos
São métodos que podem ser chamados sem haver uma referência para um objeto da
classe, ou seja, não existe a obrigatoriedade da instanciação de um objeto da classe. O
método pode ser chamado diretamente:
import math
class Math:
@staticmethod
def sqrt(x):
return math.sqrt(x)
Orientação a objetos como herança e polimorfismo
Herança e polimorfismo
As linguagens orientadas a objeto oferecem recursos que permitem o desenvolvimento de
sistemas de uma forma mais ágil e eficiente. Esses recursos são a herança, o polimorfismo
e o tratamento das exceções.
A herança permite uma redução da repetição de código, autorizando uma classe filho a
herdar métodos e atributos da classe pai; o polimorfismo, que, em determinadas situações,
os objetos possam ter comportamentos específicos. Caso haja algum problema durante a
execução do código, o tratamento de exceções facilita a manipulação do erro.
Introdução
No início do ano 2000, poucas pessoas tinham acesso a computadores com mais de um
processador. Além disso, os processadores dos desktops e notebooks daquela época
continham apenas um núcleo, ou seja, só podiam executar uma operação por vez.
Atualmente, é raro ter um computador, ou até mesmo um celular, com um processador de
apenas um núcleo. Com isso, é muito importante aprendermos alguns conceitos sobre
programação concorrentee paralela e como implementá-los, de forma a extrair o máximo
de performance dos nossos programas.
Na computação, temos dois conceitos relacionados à execução simultânea, concorrênciae
paralelismo, que serão apresentados no decorrer deste módulo.
A seguir, definiremos alguns conceitos relacionados à computação concorrente e paralela,
e, posteriormente, mostraremos como o Python implementa tais funcionalidades.
Conceitos de programa e processo
Programa é algo estático e permanente. Contém um conjunto de instruções e é percebido
pelo sistema operacional como passivo.
Em contrapartida, o processo é dinâmico e tem uma vida curta. Ao longo da sua execução,
tem seu estado alterado. Ele é composto por código, dados e contexto. Em suma, o
processo é um programa em execução.
O mesmo programa executado mais de uma vez gera processos diferentes, que contêm
dados e momento de execução (contexto) também diferentes.
Conceitos de concorrência e paralelismo
Em computação, o termo concorrente se refere a uma técnica para tornar os programas
mais usáveis. Ela pode ser alcançada mesmo em processadores de apenas um núcleo, pois
permite compartilhar o processador de forma a rodar vários processos. Os sistemas
operacionais multitarefas suportam concorrência.
Exemplo
É possível compactar um arquivo e continuar usando o processador de texto, mesmo em
um processador de um núcleo, pois o processador divide o tempo de uso entre os
processos dessas duas aplicações. Ou seja: essas duas aplicações executam de forma
concorrente.
Já o paralelismo é uma técnica para permitir que programas rodem mais rápido,
executando várias operações ao mesmo tempo. Ela requer várias máquinas ou um
processador com mais de um núcleo. Também é possível realizar o paralelismo nas placas
de vídeo.
Conceito de Threads
Threads e processos
Em um programa com múltiplos processos, cada um tem seu próprio espaço de memória
e cada um pode executar em um núcleo diferente, melhorando consideravelmente a
performance do programa.
Relembrando
O processo é uma instância de um programa em execução. Eleé composto pelo código
que está sendo executado, os dados utilizados pelo programa (exemplo: valores de
variável) e o estado ou contexto do processo.
Curiosidade
A thread pertence a um determinado processo. Múltiplas threads podem ser executadas
dentro de um mesmo processo. As de um mesmo processo compartilham a área de
memória e podem acessar os mesmos dados de forma transparente.
Desenvolvimento Web com Python
Curiosidade
O Python também pode ser utilizado para desenvolver aplicações Web?
Atualmente, existem diversos frameworks que facilitam a criação de aplicações Web em
Python.
Os frameworks podem ser divididos em, basicamente, dois tipos: full-stack e não full-stack.
Veja cada um deles a seguir:
Disponibilizam diversos recursos internamente, sem a necessidade de bibliotecas externas.
Dentre os recursos, podemos citar:
Respostas à requisição;
Mecanismos de armazenamento (acesso ao banco de dados);
Suporte a modelos (templates);
Manipulação de formulários;
Autenticação;
Testes;
Servidor para desenvolvimento, entre outros.
O principal framework Python full-stack é o Django.
Frameworksnão Full-stack
expand_more
Oferecem os recursos básicos para uma aplicação Web, como resposta à requisição e
suporte a modelos. Os principais frameworks dessa categoria são o Flask e o CherryPy.
Normalmente, para aplicações maiores, são utilizados os frameworks full-stack, que
também são um pouco mais complexos de se utilizar.
Para este módulo, usaremos o Flask.
Ciência de Dados em Python
Introdução
Desde o século XVII, as ciências experimentais e teóricas são reconhecidas pelos cientistas
como os paradigmas básicos de pesquisa para entender a natureza. De umas décadas para
cá, a simulação computacional de fenômenos complexos evoluiu, criando o terceiro
paradigma, a ciência computacional.
A ciência computacional fornece ferramentas necessárias para tornar possível a exploração
de domínios inacessíveis à teoria ou experimento.
Com o aumento das simulações e experimentos, mais dados são gerados e um quarto
paradigma emerge, que são as tecnologias e técnicas associadas à Ciência de Dados.
A Ciência de Dados é uma área de conhecimento que envolve a utilização de dados para
gerar impactos em uma instituição, seja uma universidade, uma empresa, um órgão
federal etc., de forma a resolver um problema real utilizando os dados.
Em 1996, Fayyad apresentou a definição clássica do processo de descoberta de
conhecimento em bases de dados, conhecido por KDD (Knowledge Discovery in
Databases):
2/SEMETRES (HTML)
Definição de tipos de documento (DTD)
O ponto inicial da estrutura de uma página web é o tipo de documento a ser utilizado.
Inicialmente, a HTML continha apenas tags para marcações simples, uma vez que ainda
não existia um dispositivo com interface gráfica no qual pudesse ser exibida.
Com isso, as primeiras tags eram relacionadas a elementos como títulos, parágrafos,
quebras de linha etc. Entretanto, com a sua rápida expansão e sobretudo pelo lançamento
do primeiro navegador, o Mosaic, surgiu a necessidade de criação de novas tags, para
marcações mais complexas.
Essa necessidade se tornou contínua, tendo como principais pilares os seguintes eventos: a
rápida expansão da web e a construção de novos navegadores.
O fato de que cada navegador implementava seus próprios padrões, incluindo tags que só
podiam ser interpretadas por eles mesmos, tornou necessária a adoção de padrões
reconhecidos por todos. Por isso, o W3C criou a definição de tipos de documentos (DTD)
ou document type definition, uma lista de elementos, atributos e requisitos relacionados a
determinada linguagem ou variação da linguagem.
Utilizando doctypes: document types
A importância dos document types na criação de páginas HTML diz respeito ao conjunto
de tags que podem ser usadas e que serão ou não renderizadasa partir do tipo utilizado.
Antes da HTML5, existia um conceito chamado concordância de documento.
Embora relevante apenas nas versões anteriores da HTML, é importante abordá-lo, uma
vez que muitas páginas web ainda não foram portadas para a HTML5. Isso significa que
cada página precisa ser concordante com a especificação W3C oficial para a qual foi
escrita.
A especificação da HTML 4, por exemplo, previa três tipos de doctypes: strict, transitional e
frameset. Vamos conhecer cada um desses tipos?
Na declaração, são definidas as seguintes informações sobre a página HTML:
Portanto, o doctype não é uma tag HTML, mas, sim, uma instrução. É uma declaração que
serve para informar ao navegador qual a versão da HTML usada em um arquivo HTML. A
partir da HTML5, quando a HTML deixou de ser baseada na SGML, a declaração do
doctype foi simplificada, como visto a seguir.
Tipo de Documento: HTML.•
Acesso à DTD: Public – logo, a DTD a que se refere está disponível para uso de forma
pública.
•
Onde se encontra o DTD: local em que foi criado e está hospedado no W3C.•
URL da especificação: o endereço http://www.w3.org/TR/html4/loose.dtd leva à
especificação em questão.
•
http://www.w3.org/TR/html4/loose.dtd
http://www.w3.org/TR/html4/loose.dtd
Comparando as declarações do doctype entre a HTML5 e a HTML4, notamos algumas
diferenças. A principal diferença é que a HTML5, ao contrário das versões anteriores, não
se baseia na SGML, portanto não requer referência a um DTD.
Estrutura de uma página web
Quando falamos de estrutura de uma página HTML, estamos nos referindo aos elementos
– ou tags – que irão compor o documento em questão. Entre esses elementos, alguns são
considerados obrigatórios para a correta renderização da página nos navegadores. Além
desses, há outros elementos que possuem papéis distintos e são usados para diferentes
fins, como criação de tabelas, listas, inserção de links etc. Esse conjunto de elementos,
obrigatórios e básicos, forma a estrutura de uma página web escrita com HTML.
Elementos obrigatórios
Como vimos, a estruturação de uma página web tem início na definição do doctype a ser
utilizado. Em seguida, é necessário inserir um conjunto de tags que, com o doctype,
formam a sua estrutura básica, apresentada a seguir.
Raiz
A tag inicial, após a declaração do doctype, é a . Esse elemento é a raiz do
documento. Logo, lembrando que o código HTML é composto por uma estrutura
hierárquica de tags, podemos dizer que a é a raiz da árvore do documento. Outra
característica importante é que uma tag deve ser aberta e fechada.
A declaração é a abertura, e o seu fechamento ocorre com a declaração .
Com isso, observando o código anterior, é possível perceber que as demais tags estão
contidas dentro da tag raiz, .
Comentário
Cabe destacar outro elemento importante referente à tag raiz: o atributo “lang”. Esse
atributo global (por ser declarado na tag raiz) deve ser utilizado para definir o idioma da
página – podendo também ser aplicado a outras tags, definindo o idioma delas. Veja
alguns exemplos de sua declaração:
•
•
Cabeçalho
A tag é chamada de cabeçalho do documento. Em uma analogia ao corpo
humano, devemos vê-la como a “cabeça”, uma vez que contém as tags que serão usadas
para manter todo o documento funcionando e em ordem.
Vejamos agora as tags que fazem parte do cabeçalho e entenderemos para que servem.
Vamos lá?
Corpo
Logo abaixo do cabeçalho, deve ser inserida a tag , responsável pela estruturação
do documento, sobretudo de seu conteúdo, e também pela apresentação. Apesar disso,
recomenda-se que a apresentação do documento seja feita por meio de folhas de estilo
(CSS).
Quando navegamos em um website, todo o conteúdo que vemos – textos, imagens e
demais elementos – está contido na tag .
Elementos básicos
•
É o título do documento, sendo visualizado na barra de título do navegador.
1.
Engloba uma série de informações– comumente chamadas de metainformações –
como a descrição da página, palavras-chave etc.
2.
É responsável pela inclusão e/ou definição de scripts relacionados ao documento.
3.
É responsável pela inclusão de folhas de estilo (externas) relacionadas ao documento.
Também possibilita a inclusão de favicons (pequenos ícones que aparecem na barra
de endereços do navegador).
4.
É responsável pelo vínculo de folhas de estilo ao documento − quando elas são
declaradas diretamente no documento.
5.
Embora as páginas web sejam diferentes umas das outras, elas tendem a compartilhar
uma mesma estrutura. Isso significa que, além da estrutura apresentada anteriormente,
uma página web também é composta por seções, sendo as mais comuns:
Funcionamento da HTML
Após concluído, o documento estruturado, composto por tags, deve ser salvo com a
extensão “html” ou “htm”. Assim, ele estará pronto para ser lido por um dispositivo, como
um navegador web – em um computador pessoal ou em um smartphone. Quando uma
página web é exibida no navegador, o que vemos é o seu conteúdo: texto, imagens etc., e
não o código ou as tags. Esse processo consiste no que chamamos de interpretação e
renderização.
Tags HTML básicas
Aprofundando o conceito de tags
Como já aprendemos, a HTML é uma linguagem de marcação que utiliza tags para
estruturar o seu conteúdo. Mas o que são tags?
Tags são palavras, escritas entre os caracteres de menor “” e que servem para
informar ao navegador a estrutura e o significado do conteúdo inserido em uma página
web.
Um dos exercícios propostos anteriormente consistia em inserir na estrutura básica de tags
da HTML − mais precisamente dentro da tag − um texto qualquer e, em seguida,
salvar e carregar essa página no navegador. Como pôde ser visto, o navegador exibiu o
texto, que provavelmente era curto.
Agora, tente imaginar o site de um portal de notícias com todo o conteúdo amontoado
dentro da tag . Embora exibido pelo navegador, tudo seria uma grande bagunça,
uma confusão! Agora, imagine que seja possível dizer ao navegador que determinado
conteúdo é o título de uma seção, sendo procedido de um parágrafo que diga respeito a
tal seção. Você ainda pode ir além, inserindo uma imagem e vários outros elementos. Para
isso servem as tags!
Como declarar tags
Antes de conhecermos mais a fundo as tags, a sua composição e os seus tipos, vamos
voltar à sua criação.
Primeiro, devemos ter em mente que existe um conjunto já definido de tags, padronizado
pelo W3C. Logo, não é possível criarmos as nossas próprias tags HTML. Outro ponto
importante é o modo como uma tag é escrita: como já sabemos, entre os sinais de menor
e maior. Lembre-se, a tag deve, obrigatoriamente, ser fechada! Para isso, repetimos a
declaração da tag e utilizamos uma barra “/” antes do seu nome.
Observe os exemplos:
filter_1
Título de uma seção
filter_2
Parágrafo contendo um texto
Com base no primeiro exemplo, dizemos que a tag foi iniciada ao inserirmos o e
fechada em .
Existem algumas tags que fogem a essa regra. Por exemplo, a tag de quebra de linha:
. Repare que, nesse caso, a tag é fechada com a utilização da “/” logo antes do sinal
de maior.
report_problem
Atenção!
A tag de quebra de linha tornou-se obsoleta a partir da HTML5.
Tipos e composição das tags
As tags podem ser divididas nos seguintes tipos de acordo com as suas funções:
estruturais, textuais e semânticas. Outra característica importante é o fato de que as tags
também podem ter atributos, a respeito dos quais falaremos a seguir.
Atributos
Servem para que algumas características sejam adicionadas a um elemento, a uma tag.
São compostos por um nome e por um valor.
Exemplo
expand_more
Há uma enorme variedade de atributos, assim como de relacionamentos entre esses
atributos e as tags. O site do W3C contém a lista completa de atributos e combinações.
Por ora, cabe destacar dois atributos de extrema importância no desenvolvimento web:
ID
Class
Utilizado para definir um identificador, que deve ser único, para uma tag em um
documento.
Com base nesses dois tipos de identificação, é possível, por exemplo, fazer referência a um
ou mais atributos para inserirmos estilização visual nas páginas, por meio de folhas de
estilo ou eventos e interação, usando o Javascript.
Tipos de tags: textuais e semânticas
Agora, vamos conhecer os tipos de tag textuais e semânticas.
Logo, voltando ao exemplo de seções básicas de uma página, nossa página ficaria da
seguinte maneira:
open_in_full
Tags estruturais básicas de uma página web.
Ao analisar a imagem, é possível perceber que existem tags específicas para cada seção do
conteúdo. Essa é uma característica importante da HTML, chamada de semântica, que,
nesse contexto, pode ser considerada a correta utilização de uma tag HTML de acordo
com o seu conteúdo ou a sua finalidade.
Em muitos casos, ao visualizarmos uma página no navegador, é indiferente o fato de as
tags serem utilizadas para guardar determinado conteúdo. Entretanto, recomenda-se usá-
las de acordo com sua função. Esse uso cria uma organização no documento que facilita
tanto para você, que o escreveu, quanto para outras pessoas que venham a editar o
mesmo documento. Além disso, muitos dispositivos fazem uso dessa marcação para uma
correta interpretação do conteúdo ali contido.
Vamos agora conhecer outras tags e suas respectivas funções!
Tags textuais: São responsáveis por organizar o conteúdo da página, ou seja, textos,
mídias e links, por exemplo. Algumas das principais tags textuais são: , ...
, e . Essas tags e suas funções serão descritas a seguir.
•
Tags semânticas: A partir da HTML5, foram inseridas tags com a função semântica de
organizar a estrutura de conteúdo de uma página.
•
flag
Inclui um bloco de conteúdo que deve ser usado quando se deseja inserir um artigo,
como um post de um blog, por exemplo.
1.
flag
Define uma seção no documento. É normalmente utilizado para agrupar seções. Por
exemplo: uma poderia conter vários .
2.
flag
, , , , e
Apresenta a inserção de títulos ao longo da página. É uma boa prática que cada seção
ou cada bloco de texto seja precedido por um título. Trata-se de uma tag hierárquica,
logo, no título mais importante, deve ser usada a tag ; no subtítulo seguinte,
, e assim por diante. Além disso, uma página poderá conter várias , ...
. A exceção aqui fica por conta da tag , uma vez que é recomendado
utilizar apenas uma em uma mesma página.
3.
flag
Aponta a inserção de parágrafos de texto.
4.
flag
Aponta a inserção de um texto pré-formatado.
5.
flag
Aponta o agrupamento de algum tipo de conteúdo que não tenha nenhuma
semântica específica ou que não se encaixe bem dentro de uma tag semântica,
embora não seja considerada semântica.
6.
flag
Apresenta semelhança com a . Entretanto, enquanto a é um elemento
não semântico no bloco (quando usada, quebra o conteúdo em uma seção), a
é embutida (não quebra o conteúdo, apenas o agrupa).
7.
Tags de formatação e vs e
A última versão HTML ainda dá suporte a algumas tags direcionadas à formatação visual
de conteúdo. Embora possam ser substituídas por CSS, quatro dessas tags merecem
atenção especial:
O destaque que tais elementos merecem diz respeito à função semântica que as tags
e exercem.
É interessante notar que ambas produzem o mesmo efeito visual das tags e ,
respectivamente, em um texto, ou seja, marcam em negritoe/ou itálico. Entretanto, há
uma diferença importante entre essas tags que vai além da visualização do texto no
navegador pela maioria dos usuários. A função semântica é perceptível em dispositivos
de leitura de tela, que transformam o texto em áudio, e normalmente são utilizados por
pessoas com deficiência visual.
Tags obsoletas
flag
Aponta a inserção de links.
8.
flag
Aponta a inserção