Escolar Documentos
Profissional Documentos
Cultura Documentos
Lst = MUTÁVEL
Para mudar variável do tipo int:
>>> a = 3 >>> a = 6
>>> b = a
Videoaula 2 - Arquivos
Arquivos Sequência de bytes armazenada em memória secundária*.
Existem dois tipos de arquivos:
- Arquivos texto (.txt, .html, .py, etc.) (há codificação dos bytes em caracteres
que são legíveis pelos seres humanos)
- Arquivos binários (.exe, .mp3, .jpg, etc.) (não são codificados)
*Memória primária é a memória do computador (RAM), componente que a
memória usa para armazenar temporariamente os dados que serão
processados pelo processador
Memória secundária: componentes do computador que armazena dados que
não são voláteis (quando desligo o computador os dados não se apagam). Ex.
HD, Pen Drive, Nuvem, para armazenar dados nessas memórias, utilizamos os
arquivos.
Para escrever outros dados que não são string, devemos convertê-los ou usar
o método format():
>>> idade = 30
>>> outfile.write('Sua idade é '+str(idade)+' anos.\n') (posso transforma essa
variavel para o tipo string e então concatenamos na frase que desejamos ou
usamos a format, que transforma o dado em sua respectiva string e coloca no
lugar das {})
>>> outfile.write('Sua idade é {} anos.\n'.format(idade))
VIDEOAULA 3
Atributos: x e y
Métodos: setx(), sety(), get(), move()
Videoaula 4 - Programação Orientada a Objetos II
Sobrecarga de Operadores que são definidos diferentemente para múltiplas classes
operadores Exemplo: operador +
>>> 2 + 4
6
>>> [2, 3, 4] + [5]
[2, 3, 4, 5]
>>> 'abc' + 'de'
'abcde'
Como a linguagem Python é orientada a objetos, os operadores aritméticos são,
na essência, chamados a métodos definidos na respectiva classe do primeiro
operando
Assim, x+y é o equivalente a x.__add__(y), sendo que o método __add__() é
definido na classe de x
class Point():
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __repr__(self):
return '({},{})'.format(self.x, self.y)
Herança Técnica fundamental em POO, usada para criar e organizar classes reutilizáveis.
Serve para reutilizar ou alterar os métodos de classes já existentes, bem como
adicionar novos atributos e métodos a fim de adaptar as classes a novas
situações.
Exemplo: suponha que queremos definir uma classe Lista, que contenha um
método adicional: choice(), que irá retornar aleatoriamente um elemento
existente na lista
Poderíamos definir uma classe MyList contendo todos os métodos necessários:
import random
class MyList:
def __init__(self, initial = []):
self.lst = initial
def __len__(self):
return len(self.lst)
def append(self, item):
self.lst.append(self, item)
Seria necessário, entretanto, redefinir mais de 30 métodos da classe list, a fim
de usá-la da mesma forma que uma lista.
Ao invés, podemos fazer uma "extensão" da classe list, por meio de herança:
import random
class MyList(list):
def choice(self):
return random.choice(self)
Dizemos que MyList é uma subclasse da classe list, e list é uma superclasse de
MyList.
Exercício Considere uma entidade Funcionário, que possui nome, data de admissão e
salário. Implemente sua classe, definindo também alguns métodos para
manipulação dos atributos. Em seguida, considere a entidade Gerente, que
também é um funcionário. Além dos atributos de funcionário, um gerente
também contém um bônus, que é uma porcentagem adicional aplicada no seu
salário. Implemente a classe Gerente como uma extensão de Funcionário.
FAZER FAZER
Texto-base - Introdução a Computação Usando Python (Ler:
Capítulo 8 – Programação Orientada a Objetos) - Ljubomir
Perkovic
Classes Se forem projetadas especificamente para determinada aplicação tornarão o
programa de aplicação mais intuitivo e mais fácil de desenvolver, depurar, ler e
manter.
namespaces propriedade das classes que permite expõe ao usuário os métodos que podem ser
detalhados aplicados aos objetos da classe (ou seja, instâncias da classe), mas encapsula o
modo como os dados contidos nos objetos são armazenados e como os métodos da
classe são implementados.
Ex.a função setx() é uma função definida no namespace Ponto. Ela apanha não
apenas um, mas dois argumentos: o objeto Ponto que está invocando o método e uma
coordenada x
não apenas as classes, mas cada objeto Python tem seu próprio namespace separado
Ex. Instanciamos (Um objeto é uma instância de uma classe) um novo objeto
do tipo Ponto e lhe damos o nome ponto, como em
>>> ponto = Point()
Como um namespace é associado ao objeto ponto, podemos usá-lo para armazenar
valores:
>>> ponto.x = 3
POO paradigma de desenvolvimento de software que alcança modularidade e
portabilidade de código, organizando programas de aplicação em torno de
componentes que são classes e objetos.
Definindo uma Antes de implementarmos a classe Ponto (ponto refere-se a um objeto do tipo Ponto),
nova classe precisamos decidir como ela deverá se comportar, ou seja, quais métodos ela deverá
aceitar.
método setx(): Aqui, temos um lugar para a coordenada x de um objeto Ponto. Ela é
armazenada no namespace associado a ela. O método setx() seria implementado desta
maneira:
def setx(ponto, coordx):
ponto.x = coordx
* Como o método _ _init_ _() é chamado toda vez que um objeto é instanciado, o construtor
Ponto() agora deverá ser chamado com dois argumentos. Isso significa que a chamada do
construtor sem um argumento resultará em um erro:
Classe conteiner
Classe de fila
Operadores Ex. Operador +, seu método é __add__
sobrecarregado Ex. X.__add__(y) <==> x+y
Um operador sobrecarregado é um operador que foi definido para várias classes.
s
Para cada classe, a definição – e, portanto, o significado – do operador é diferente.
Assim, por exemplo, o operador + foi definido para as classes int, list e str. Ele
implementa adição de inteiros para a classe int, concatenação de lista para a classe
list e concatenação de strings para a classe str.
Se não sei qual o método do operador digito helo(int), help (str) ou hel(list)
Operado Método Número Lista e String
r
x+y x.__add__(y) Adição Concatenação
x-y x.__sub__(y) Subtração —
x*y x.__mul__(y) Multiplicação Autoconcatenação
x/y x.__truediv__(y) Divisão —
x // y x.__floordiv__(y) Divisão de —
inteiros
x%y x.__mod__(y) Módulos —
x == y x.__eq__(y) Igual a
x != y x.__ne__(y) Não igual a
x>y x.__gt__(y) Maior que
x >= y x.__ge__(y) Maior ou igual a
x<y x.__lt__(y) Menor que
x <= y x.__le__(y) Menor ou igual a
repr(x) x.__repr__() Representação de string canônica
str(x) x.__str__() Representação de string informal
len(x) x.__len__() — Tamanho da
coleção
<type>(x <type>.__init__(x) Construtor
)
__repr__ Representa string canônica
__eq__ Inplanta para que o operador == retorne True
Herança Uma classe também pode ser “estendida” em uma nova classe por meio da herança
de classe. Nesta seção, apresentaremos a segunda técnica.
Atividade
Avaliativa
Quando usar? Dependendo do problema, a recursão pode ser bem ou mal empregada.
Geralmente, se existe uma versão simples e não recursiva da função, ela deve
ser usada.
Usamos recursão quando o problema pode ser definido recursivamente de
forma natural.
Como usar? Necessário definir 3 pontos:
1) Definir o problema de forma recursiva, ou seja, em termos dele mesmo
Ex. • n! = n * (n – 1)! (n-1 é a chamada recursiva)
2) Definir a condição de término (ou condição básica)
•n=0
3) A cada chamada recursiva, deve-se tentar garantir que se está mais próximo
de satisfazer a condição de término
• A cada chamada, n é decrementado (diminuir o valor de um número)
Exemplo Implementar uma função recursiva em Python para calcular o fatorial de um
número inteiro positivo passado como parâmetro.
Exercício Implementar uma função recursiva para calcular o n-ésimo termo da sequência
de Fibonacci.
Considere os três pontos definidos para o problema:
1) f(0) = 0, f(1) = 1, f(n) = f(n-1) + f(n-2) p/ n>=2
2) n=0 ou n=1
3) n deve ser decrementado a cada chamada
def fib_rec(n):
if n < 2: (todos resultado < 2 é = a ele mesmo, por
isso retorna n)
return n
else: (se ele for >= 2, devo usar a função abaixo)
return fib_rec(n-1) + fib_rec(n-2)
Quiz da video
aula
No caso acima, embora a função interativa tenha muito mais linhas de código,
ela retornará o resultado mais rápido porque não há empilhamento e
desempilhamento como na função recursiva
Recursão vs. Problema: n-ésimo termo de Fibonacci
Iteração Quem é melhor?
Estimativa de tempo para Fibonacci
Memoização Técnica de otimização que armazena os resultados de chamadas de funções
custosas, e que retorna o valor armazenado quando a função é chamada
novamente.
Exemplo: fatorial:
Exercícios Dada uma lista l de n números, implemente uma função recursiva que retorna o
maior elemento do conjunto.
Dada uma lista l de n números, implemente uma função recursiva que retorna a
soma de todos os elementos do conjunto.
QUIZ
VIDEOAULA
QUIZ
Atividade
Avaliativa
Errei correto é b (I e III)
Semana 4: pilhas, filas e árvores
Video aula 7 Pilhas
Chamada de Qual o resultado da execução da função A?
funções Qual a dificuldade para se fazer esse cálculo?
Possíveis soluções?
Dificuldade:
- O que estava sendo executado quando uma função foi interrompida?
- Para onde voltar agora que se chegou ao fim de uma função?
Solução:
- A cada chamada da função, armazenar o endereço de retorno (e.g. função e
número da linha).
- Como armazenar o endereço de retorno de chamadas sucessivas?
Solução: pilha!
Pilha Definição: estrutura para armazenar um conjunto de elementos, da seguinte
forma:
- Novos elementos sempre entram no 'topo' da pilha
- O único elemento que se pode retirar da pilha em um dado momento é o
elemento do topo
Operações usuais:
- push(): empilha um elemento na pilha
- pop(): desempilha o elemento no topo da pilha
- top(): acessa o elemento do topo, sem desempilhá-lo
- empty(): verifica se a pilha está vazia
Texto base diferentemente da fila (FIFO), em uma pilha o último a entrar nela, é o primeiro a
sair (Last-In, First-Out — LIFO)
Onde as pilhas são usadas?
Talvez a mais famosa utilização de pilhas em computação esteja no gerenciamento
de chamadas de função de um programa. Uma pilha pode ser usada para manter
informações sobre as funções de um programa que estejam ativas, aguardando por
serem terminadas. Considere o seguinte exemplo:
1 def ola():
2 print "olá, "
3 mundo()
4
5 def mundo():
6 print "mundo!"
7
8 def olamundo():
9 ola()
10
11 olamundo()
A primeira função a ser chamada é a olamundo(), que por sua vez chama a função
ola(), então a função olamundo() é empilhada, pois seu término depende do
término da função ola(). Essa, por sua vez, chama a função mundo() e é
empilhada. Ao terminar a execução da função mundo(), a função ola() é
desempilhada e sua execução termina de onde havia parado (chamada à função
mundo()). Como não há mais nada a ser executado nessa função, sua execução
termina, e a função olamundo()é desempilhada e sua execução continua,
encerrando assim o programa.
Para adicionar um elemento no final de uma lista, basta usar
o método append(). E para remover o último elemento da lista?
.pop(tamanho_da_lista-1) é o que devemos fazer. E para obter o
tamanho da lista, podemos usar a função len(). Então:
1 def desempilha(self):
2 return self.dados.pop(len(dados)-1)
Ou então, podemos usar self.dados.pop(-1). O acesso ao índice -
1é a forma pythônica de se referir ao último elemento de uma
sequência.
1 def desempilha(self):
2 return self.dados.pop(-1)
Outra operação fundamental que deve estar disponível em uma
Pilha, é um método que retorne um booleano indicando se a
pilha está vazia. Um jeito bem simples seria usando a builtin
len() sobre a nossa lista interna self.dados e verificando se
ela retorna 0como resultado.
1 def vazia(self):
2 return len(self.dados) == 0
Pilha
1 class Pilha(object):
2 def __init__(self):
3 self.dados = []
4
5 def empilha(self, elemento):
6 self.dados.append(elemento)
7
8 def desempilha(self):
9 if not self.vazia():
10 return self.dados.pop(-1)
11
12 def vazia(self):
13 return len(self.dados) == 0
Exercício Implementar um programa em Python que realiza a conversão decimal para
binário usando pilha
Class Pilha():
def__init__(self):
self.data =[]
def pop(self):
if len(self, data) > 0:
return self.data.pop(-1)
def top(self):
if len(self.data) > 0:
return self.data[-1]
def empty(self):
return not len(self.data) > 0
p = Pilha()
num = 13
while num >0:
resto = num % 2
num = num // 2
p.push(resto)
Videoaula 8 Filas
Problema: fila Quais operações possíveis?
de banco - Entrar na fila: quem entra, entra onde?
- Sair da fila: quem sai, sai de onde?
- Avançar na fila
Fila Definição: estrutura para armazenar um conjunto de elementos, que funciona
da seguinte forma:
- Novos elementos sempre entram no fim da fila
- O único elemento que pode ser retirado da fila, em um determinado
momento, é seu primeiro elemento
Texto base Árvores são estruturas de dados muito versáteis que são utilizadas na solução de
uma enorme gama de problemas, como na otimização de consultas e na indexação
de bancos de dados, na geração de códigos para compressão de dados, na análise
sintática de código por compiladores, na representação da estrutura de diretórios
em um sistema de arquivos, etc.
Árvores Binárias
Uma árvores binária é um tipo especial de árvore, em que cada nó pode ter no
máximo 2 filhos, um à esquerda e um à direita do nó.
Implementação da busca
O código abaixo implementa o algoritmo de busca descrito acima para a classe
BSTNode, através do método get:
1 class BSTNode(object):
2 def __init__(self, key, value=None, left=None,
3 right=None):
4 self.key = key
5 self.value = value
6 self.left = left
7 self.right = right
8
9 def get(self, key):
10 if key < self.key:
11 return self.left.get(key) if self.left
else None
12
elif key > self.key:
13
return self.right.get(key) if self.right
14
else None
else:
return self
Observe que este é um método recursivo, o que é condizente com a estrutura da
árvore, que também é uma estrutura recursiva, com um nó sendo definido com
base nele próprio. A função tem como condição de parada o nó ser nulo (None).
Quando isso acontece, significa que chegamos ao fim de um galho da árvore sem
ter encontrado a chave, isto é, a chave não existe na árvore.
Para realizar uma busca pela chave 4, devemos fazer o seguinte (onde tree é uma
referência ao nó raiz da árvore):
1 tree = BSTNode(8)
2 ...
3 found = tree.get(4)
4 if found:
5 print(found)
O método get apresentado acima poderia ser refatorado, evitando a duplicação de
código:
1 def get(self, key):
2 """Retorna uma referência ao nó de chave key
3 """
4 if self.key == key:
5 return self
6 node = self.left if key < self.key else self.right
7 if node is not None:
8 return node.get(key)
Inserção em uma Árvore Binária de Busca
Uma inserção em uma árvore binária de busca deve respeitar a propriedade
fundamental dessa estrutura, mantendo menores à esquerda e maiores à direita.
Para que isso seja possível, é interessante que a interface de programação da nossa
árvore ofereça um método que faça a inserção de um elemento garantindo tal
propriedade.
O algoritmo para a inserção funciona de forma semelhante à busca. Vamos
descendo na árvore com o objetivo de encontrar o local certo onde o elemento
deve ser inserido, verificando sempre se devemos continuar o percurso na
subárvore à esquerda ou à direita do nó. Diferentemente da busca, na inserção
nossa travessia termina ao encontrarmos um nó folha, no qual o elemento a ser
inserido é adicionado como filho — à esquerda, se o elemento a ser adicionado for
menor que o nó, ou à direita, caso contrário.
Implementação da inserção
Assim como a busca, o método para inserção também pode ser implementado de
forma recursiva. Veja o código abaixo:
1 class BSTNode(object):
2 def __init__(self, key, value=None, left=None,
3 right=None):
4 self.key = key
5 self.value = value
6 self.left = left
7 self.right = right
8
9 def add(self, node):
10 if node.value < self.value:
11 if self.left is None:
self.left = node
12
else:
13
self.left.add(node)
14
15 else:
16 if self.right is None:
17 self.right = node
18 else:
self.right.add(node)
Como podemos ver no método add, a inserção percorre a árvore até encontrar
uma folha onde o novo nó pode ser inserido. Isso ocorre quando, no percurso da
árvore, encontramos um nó que não possui um filho do lado esquerdo (quando o
valor que estivermos inserindo for menor que o nó) ou do lado direito (quando o
valor do nó que estivermos inserindo for maior que o valor do nó).
Novamente, para eliminar um pouco a repetição de código, o método add poderia
ser refatorado para:
1 def add(self, key):
2 """Adiciona elemento à
3 subárvore
4 """
5 side = 'left' if key <
6 self.key else 'right'
7 node = getattr(self,
8 side)
9 if node is None:
setattr(self, side,
BSTNode(key))
else:
node.add(key)
Porém, nosso algoritmo de inserção um problema: ele pode deixar desbalanceada
a árvore após algumas inserções.
Balanceamento de árvore
Manter uma árvore bem organizadinha é um pouquinho mais complicado, pois é
necessário que mantenhamos o balanceamento da árvore. Para entendermos
melhor esse conceito, vamos ver um exemplo que ilustra o pior caso em uma
árvore binária de busca não balanceada, que ocorre quando os elementos são
inseridos de forma ordenada:
Para evitar situações como esta, existem algoritmos que são usados durante a
inserção de um elemento e que promovem uma reorganização dos nós da árvore
para que seu layout fique mais balanceado. Para compreender melhor o conceito
de balancemento de uma árvore, precisamos compreender antes o conceito de
altura de uma árvore, que é definido pela quantidade de arestas no caminho mais
longo entre a raiz e as folhas. A figura abaixo ilustra uma árvore de altura 3, que é a
quantidade de arestas entre a raiz e a folha mais distante dela (de valor 4).
Uma árvore balanceada é uma árvore na qual a altura de uma subárvore não pode
ser muito maior do que a altura da sua irmã. Para manter uma árvore balanceada,
após cada inserção, devemos verificar se a árvore permanece balanceada e, em
caso negativo, ela deve ser reorganizada, trocando os encadeamentos entre os
nós. Isso pode ser um pouco custoso, mas compensa no momento de fazer a busca
por algum elemento. Os tipos mais conhecidos de árvores binárias balanceadas
são: as Árvores AVL e as Árvores Rubro-Negras.
Remoção de A remoção de um elemento é um pouco mais complicada do que a inserção e
busca de um elemento. Existem 3 situações diferentes e que requerem diferentes
um abordagens para a remoção de um elemento:
elemento 1. o nó a ser removido é um nó folha
2. o nó a ser removido possui somente um filho
3. o nó a ser removido possui dois filhos
Remoção de um nó folha
Imagine que desejamos remover o nó 4 da árvore acima. Para isso, basta fazer com
que o campo left do nó 6 passe a apontar para None, e o coletor de lixo elimina o
nó da memória pra gente em algum momento.
Remoção de um nó que possui um filho
Agora, desejamos remover o nó 10. Para isso, temos que fazer com que o nó pai do
nó 10 (8) passe a apontar para o único filho de 10 (14).
Remoção de um nó que possui dois filhos
Este é o caso mais complicadinho. Imagine que queremos remover o nó 3, que
possui como filhos a subárvore que tem como raiz o nó 1 e a subárvore do nó 6.
Para remover o nó 3, é preciso que algum dos outros nós assuma o papel de raiz da
subárvore. O melhor candidato para assumir esse posto é o nó cuja chave é mais
próxima da chave do nó a ser removido.
Uma forma prática de encontramos tal valor é procurar o menor valor contido na
subárvore à direita do nó a ser removido, isto é, o nó mais à esquerda da
subárvore à direita. Na árvore do exemplo, esse nó é o nó de chave 4.
Implementação
O código abaixo implementa a remoção de um elemento. O método remove
primeiramente encontra o nó a ser removido — é isso que as chamadas recursivas
fazem — para depois fazer a remoção do elemento no código dentro do else. O
método _min retorna o nó que contém o menor elemento em uma subárvore, isto
é, o elemento mais à esquerda na subárvore em questão. Já o método
_remove_min retira da subárvore o menor elemento, sendo usado para remover de
sua posição o elemento que será utilizado como substituto ao elemento a ser
removido, no caso deste possuir dois filhos.
1 class BSTNode(object):
2
3 def __init__(self, key, value=None, left=None,
right=None):
4 self.key = key
5 self.value = value
6 self.left = left
7 self.right = right
8
9 def remove(self, key):
10 if key < self.key:
11 self.left = self.left.remove(key)
12 elif key > self.key:
13 self.right = self.right.remove(key)
14 else:
15 # encontramos o elemento, então vamos
removê-lo!
16
if self.right is None:
17
return self.left
18
if self.left is None:
19
return self.right
20 #ao invés de remover o nó, copiamos os
21 valores do nó substituto
22 tmp = self.right._min()
23 self.key, self.value = tmp.key, tmp.value
24 self.right._remove_min()
25 return self
26
27 def _min(self):
28 """Retorna o menor elemento da subárvore que
29 tem self como raiz.
30 """
31 if self.left is None:
32 return self
33 else:
34 return self.left._min()
35
36 def _remove_min(self):
37 """Remove o menor elemento da subárvore que
38 tem self como raiz.
39 """
40 if self.left is None: # encontrou o min, daí
pode rearranjar
return self.right
self.left = self.left._removeMin()
return self
Os dois primeiros ifs dentro do else (linhas 16 e 18) tratam o caso em que o nó a
ser removido não possui filhos ou possui somente um filho. Observe que se o nó
não possuir filho à direita, o filho à esquerda é retornado ao chamador, que é o
próprio método remove na linha 11 ou 13.
Da linha 21 em diante tratamos o caso em que o nó a ser removido possui os dois
filhos. A linha 21 obtém o elemento que irá substituir o elemento a ser removido. A
linha seguinte copia os valores do nó substituto para o nó a ser “removido” (repare
que acabamos não removendo o nó, mas sim copiando os valores do nó substituto
para o seu lugar). Depois disso, removemos o elemento substituto de sua posição
original, chamando o método _remove_min.
Texto de apoio Python 3 – conceitos e aplicações
Hashable: o Diz-se que um objeto é hashable quando ele tem um valor hash que não se
altera durante o ciclo de vida do objeto e que pode ser comparado ao hash de
que é isso? outros objetos.
Conjuntos Por definição, dentro do conjunto, só haverá uma ocorrência de cada elemento,
independentemente de quantas vezes se tente adicioná-lo.
Um conjunto pode ser criado de duas maneiras: utilizando dados entre chaves, { }
ou a função set. É possível existir um conjunto vazio. E apenas objetos hashable
podem ser membros de um conjunto.
existem dois tipos de conjunto: o set e o frozenset. Em praticamente tudo eles são
iguais, a única e fundamental diferença entre ambos é que o frozenset é imutável
e, uma vez criado, não pode ter seus membros alterados, incluídos ou removidos.
Implementação em Python
O for de fora itera os passos de 1 a n-1 e o for de dentro faz com que percorra
os elementos até a penúltima posição
If (se o v[j] for maior que o v[j+1], isto é o elemento da esquerda for maior que
o elemento da direita é feita a troca dos dois elementos (v[j], v[j+1] por v[j+1,
v[j])
Insertion sort: Ideia básica:
Ordenação por - Ordenar o conjunto inserindo os elementos em um subconjunto já ordenado.
inserção, - No i-ésimo passo, inserir o i-ésimo elemento na posição correta entre x[0], ...,
inserimos o o x[i-1], que já estão em ordem.
elemento em - Realocar elementos
um
subconjunto já
ordenado
1º comparo o segundo elemento com o primeiro, se o segundo for maior, não é
feito nada, assim segue a lista. Quando chega em um elemento que é menor que
o anterior, armazenamos o elemento (15) em uma variável auxiliar e deslocamos
os demais elementos anteriores até que o elemento (15) seja maior que o
elemento anterior
• X = (44 , 55 , 12 , 42 , 94 , 18 , 06 , 67)
• passo 1 (55) 44 55 12 42 94 18 06 67
• passo 2 (12) 12 44 55 42 94 18 06 67
• passo 3 (42) 12 42 44 55 94 18 06 67
• passo 4 (94) 12 42 44 55 94 18 06 67
• passo 5 (18) 12 18 42 44 55 94 06 67
• passo 6 (06) 06 12 18 42 44 55 94 67
• passo 7 (67) 06 12 18 42 44 55 67 94
For: é para percorrer o vetor da posição 1 até o tamanho da lista (for i in range
(1, len(v)); (como a lista começa com 1, o elemento na posição 0 fica parado,
como se estivesse já ordenado
Então o x recebe o 2º elemento e insere na lista;
J é para comparar com o x
Enquanto o j >= 0 e x< v[j], faço o descolamento.
Após o while terminar, é feita a inserção do x na sua posição correta
QUIZ
1º passo:
Escolha de um elemento pivô x, colocando-o em sua posição correta
2º Ordenar de forma que os elementos à esquerda do pivô são menores ou
iguais a ele e os elementos à direita são maiores ou iguais a ele
- Percorrer o vetor v da esquerda para direita até v[i] >= x; e da direita
para esquerda até que v[j] <= x.
- Trocar v[i] com v[j], incrementar i, decrementar j
- Quando i e j se cruzarem, a iteração finaliza, de forma que v[0]...v[j] são
menores ou iguais a x e v[i]...v[n-1] são maiores ou iguais a x
3º PASSo:
Ordenar subvetores à esquerda e à direita do elemento pivô.
Ex. 25 57 35 37 12 86 92 33
São colocados 2 ponteiros nas posições i = 0 e j = l + 1
Para encontrar o pivô, uso a fómula v=0+7)/2] = 3,5 = 4 – elemento da posição 4
= 37
Começo a incrementar i até que ele seja maior ou igual a 37, o mesmo o ocorre
o j, que deve ser <= 37. Quando são encontrados os elementos, eles são
trocados de posição entre si
Então incremento o i e p j para a posição seguinte.
Quando todos são feitos ficamos com os elementos d j na posição menor que o
pivô e i na posição maior que o pivô.
Feito isso, não é mais necessário trocar elementos dos vetores i com j.
Ficando 2 subvetores separados, nos quais deve ser feito o mesmo processo nos
subvetores separados
Exercício:
Fazer as ordenações dos subvetores, repetindo o processo 25 33 35 12 37 86 92
57
QUIZ
O heap pode ser representado por um vetor, colocamos o pai mais a esquerda e
vamos colocando os filhos em seguida
Pode ser feito por meio de vetores, com as regras citadas acima
A construção do heap envolve chamar o procedimento rearranjar heap de
forma ascendente para os n/2 – 1 (porque a partir do nó n/2 é folha) nós da
árvore (nós não folha).
Com isso, ao chamar pela última vez o procedimento para a raíz, teremos o
heap máximo construído.
Por fim faço o heap sort e troco as posições do 16 e do 1, e em seguida vou
fazendo o mesmo até reordenar
QUIZ
Def busca_binaria(l, x, inicio, fim) #os parâmetros são l (lista) , x (elemento que
procuro), inicio e fim que indicam o começo e o final da lista
If x ==l(mais):
Return meio
If x < l(meio):
Return busca binaria(l, x, inicio, meio –1)
If x > l(meio):
Return busca binaria(l, x , meio + 1, fim)
Python Console
>>> import random
>>> l = random.simple (range(10), 5)
>>>l
[2,1,6,8,9]
>>> l.sort() # ordena a lista
[1, 2, 6, 8, 9]
>>> busca_binaria (l, 2, 0, 4) #lista que procuro, posição que procuro, inicio e
final
QUIZ
QUIZ COM
OBJETIVO
EDUCACIONAL
ATIVIDADE
AVALIATIVA
ERREI, correto é e. Busca sequencial
Errei, o correto é d. Mergesort
ERREI, correto é Quicksort
ERREI, correto c. Busca binária
ERREI, correto é b. heapsort
HTTP
Http://www.univesp.br
Http = protocolo
www.univesp.br = hostname
Além do conteúdo em si, uma página Web contém elementos que definem o
layout, cabeçalhos, imagens, vídeos, hiperlinks, etc. Exemplo:
https://developer.mozilla.org/pt-BR/docs/Web/HTML/Element - ELEMENTOS
DO HTML
JSON JSON (JavaScript Object Notation) define um formato padrão para descrever,
em formato texto, objetos como dicionários, listas, números e strings. A maioria
das linguagens de programação possui bibliotecas para produzir e processar
dados no formato JSON.
As linguagem C++, java entendem as especificações do json e podem rodar elas.
O módulo json da biblioteca padrão contém funções para codificar objetos
Python em JSON e vice-versa.
Dumps:
quiz
No python:
1º importar biblioteca urlib.request
2º importar biblioteca urlopen
3º defino a função get source
4º defino a variável response
5º obtenho seu resultado por meio da response.read
6º Return html.decod (decodifica o conteudo encontrado e envia para fora da
função uma string quer contém os elementos html do recurso requisitado)
7º html == getsource http://univesp.org.br
Módulo O módulo html.parser, por meio da classe HTMLParser, permite processar
html.parser elementos HTML de uma página Web.
O método feed() da classe HTMLParser recebe como entrada uma página HTML
no formato string, e para cada 'token' lido (tags de início, tags de fim, texto,
etc.), executa um handler correspondente.
ATIVIDADE
AVALIATIVA
Nosso primeiro exemplo será uma janela simples, sem qualquer funcionalidade.
>>> from tkinter import Tk
>>> root = Tk()
>>> root.mainloop()
#WIDGET = FERRAMENTA
#WIDGET LABEL: USADO PARA EXIBIR TEXTO NA JANELA
#WIDGET ENTRY: é apropriado para a entrada (e exibição) de uma única linha de
texto. O usuário pode entrar com texto dentro do widget usando o teclado.
# WIDGET BUTTON: construtor Button.
o primeiro argumento do construtor Button deve se referir ao master do botão. Para
especificar o texto que será exibido no topo do botão, o argumento text é usado,
novamente assim como para um widget Label
A única diferença entre um botão e um label é que um botão é um widget interativo.
Toda vez que um botão é clicado, uma ação é realizada. Essa “ação” é, na realidade,
implementada como uma função, chamada toda vez que esse botão é acionado.
Podemos especificar o nome dessa função usando uma opção command no construtor
Button.
Quando o botão é clicado, a função clicked() será executada.
#WIDGET ROOT: CRIA A JANELA
#WIDGET CLICKED(): a função clicked() será executada. Agora, precisamos
implementar essa função. Quando chamada, a função deverá exibir a informação atual
de dia e hora.
Podemos adicionar um texto dentro da janela, para isso usamos o widget Label:
>>> from tkinter import Tk, Label
>>> root = Tk() # OBJETO ROOT SERÁ A JANELA CRIADA
>>> hello = Label(master = root, text = 'Ola classe') # PARAMETRO MASTER
INDICA EM QUAL JANELA IRÁ APARECER O TEXTO
>>> hello.pack() # MÉTODO PACK FAZ O EMPACOTAMENTO DE TODOS OS
COMPONENTES CRIADOS NA JANELA
>>> root.mainloop() # MÉTODO MAINLOOP FAZ A CHAMADA DA FUNÇÃO QUE
CRIA A JANELA.
Exemplo:
from tkinter import Tk, Label, PhotoImage, TOP, BOTTOM (PARTE DE BAIXO DA
JANELA) #TOP E BOTTOM SÃO DIRETIVAS QUE DETERMINAM O LOCAL QUE
CADA OBJETO DEVERÁ APARECER NA TELA
root = Tk()
photo = PhotoImage(file='computer.gif').subsample(5)
image = Label(master=root, image=photo)
image.pack(side=TOP)
text = Label(master=root, font=("Courier", 18),
text='Olá alunos da UNIVESP!')
text.pack(side=BOTTOM)
root.mainloop()
Uma outra opção para fornecer as diretivas ao geometry manager é por meio do
método grid().
Com ele, a janela é dividida em linhas e colunas, e cada célula pode armazenar
um widget.
Exemplo:
from tkinter import Tk, Label, RAISED
root = Tk()
Primeiro exemplo: janela com um botão que, quando clicado, exibe o dia e a hora
na tela.
def clicked():
time = strftime('Day: %d %b %Y\nTime: %H:%M:%S %p\n', localtime()) #\n -
PULA UMA LINHA, P É REFERENTE AO PERÍODO DA TARDE (AM OU PM)
showinfo(message=time) #A FUNÇÃO SHOWINFO É CHAMADA E PASSA A
MENSAGEM STRING TIME CRIADA
root = Tk()
button = Button(root, text='Clique', command=clicked) #ATRIBUTO COMMAND
DETERMINA O QUE ACONTECERÁ COM O OBJETO CRIADO
button.pack()
root.mainloop()
root = Tk()
label = Label(root, text='Digite uma data: ')
label.grid(row=0, column=0) #CRIA O LOCAL EM QUE APECERÁ A MENSAGEM NA
JANELA
entry = Entry(root)
entry.grid(row=0, column=1)
button = Button(root, text='Enter', command=compute)
button.grid(row=1, column=0, columnspan=2) #ATRIBURO COLUMSPAN
INFORMA QUE SERÁ MESCLADAS COLUNAS
root.mainloop()/
Exemplos:
• <Control-Button-1>:
Pressionar Ctrl e botão
esquerdo do mouse,
simultaneamente.
• <Button-1><Button-3>:
Pressionar botão
esquerdo e em seguida o
direito do mouse.
• <KeyPress-D><Return>:
Pressionar D e depois
Enter
def key_pressed(event):
print('char: {}'.format(event.keysym))
def mouse_clicked_left(event):
print('mouse left clicked')
def mouse_clicked_right(event):
print('mouse right clicked')
root = Tk()
text = Text(root, width=20, height='5')
text.bind('', key_pressed)
text.bind('', mouse_clicked_left)
text.bind('', mouse_clicked_right)
text.pack(expand=True, fill=BOTH)
root.mainloop()
EXECUTAR ESSE PROGRAMA EM PYTHON
QUIZ
QUIZ COM
OBETIVO
EDUCACIONAL
ATIVIDADE
AVALIATIVA
ERREI, CORRETO É D. APENAS III
ERREI, CORRETO É C (I, II,III)
ERREI, LETRA C – APENAS I E II, TAMBÉM NÃO É, NÃO É D (APENAS II) - ERREI