codelab@ime.usp.br
Grupo de extensão universitária que como objetivo estimular a inovação tecnológica na USP
Facebook:
Este trabalho do USPCodeLab está licenciado com uma Licença Creative Commons - Atribuição 4.0 Internacional
O USPCodeLab é um grupo de extensão que tem como objetivo estimular a inovação tecnológica na USP
São "subprogramas" que podem ser executados por código externo
Cidadãos de 1ª classe
Podem receber parâmetros de entrada e produzir uma saída
function jogaDado() {
const r = Math.random();
const dado = 1 + Math.floor(r*6);
return dado;
}
const meuDado = jogaDado();
let resultado;
if (meuDado >= 5)
resultado = "Ganhou!";
else
resultado = "Perdeu!";
console.log(resultado);
function jogaDado() {
const r = Math.random();
const dado = 1 + Math.floor(r*6);
return dado;
}
function resultado(umDado) {
let resultado;
if (umDado >= 5) resultado = "Ganhou!";
else resultado = "Perdeu!";
return resultado;
}
const meuDado = jogaDado();
const resposta = resultado(meuDado);
console.log(resposta);
function jogaDado() {
const r = Math.random();
const dado = 1 + Math.floor(r*6);
return dado;
}
function obtemResultado(umDado) {
let resultado;
if (umDado >= 5) resultado = "Ganhou!";
else resultado = "Perdeu!";
return resultado;
}
const resposta = obtemResultado(jogaDado());
console.log(resposta);
function jogaDado() {
const r = Math.random();
const dado = 1 + Math.floor(r*6);
return dado;
}
function obtemResultado(umDado) {
let resultado;
if (umDado >= 5) resultado = "Ganhou!";
else resultado = "Perdeu!";
return resultado;
}
console.log(obtemResultado(jogaDado()));
function sucessorDoPisoDoSextuploDeAleatorio() {
const r = Math.random();
const dado = 1 + Math.floor(r*6);
return dado;
}
function resultado(umDado) {
const resultado;
if (umDado >= 5) resultado = "Ganhou!";
else resultado = "Perdeu!";
return resultado;
}
const jogaDado = sucessorDoPisoDoSextuploDeAleatorio;
console.log(resultado(jogaDado()));
function soma(a, b) {
return a + b;
}
// versão alternativa
const soma = function (a, b) {
return a + b;
}
const soma = (a, b) => {
return a + b;
}
// versão simplificada
const soma = (a, b) => a + b;
console.log(soma(1, 2)); // 3
this é uma propriedade de um contexto de execução:
- contexto global: se refere a variável global (window)
- contexto de função: depende do tipo da função e de como ela foi chamada
function (a, b) {...}
const soma = (a, b) => {...}
- this pode ser um objeto novo ou pode ser copiado do contexto em que a função foi chamada
- não atribui nenhum valor a this: sempre pega o valor do contexto léxico (em que a função foi declarada)
Já que podemos armazenar funções em variáveis...
Funções "genéricas"...
... pedem callbacks "com conteúdo"
... por que não passar como argumento?
const disciplina = (p1, p2, p3, ep1, ep2, ep3, criterio) => {
const mp = ( p1 + p2 + p3) / 3,
mep = (ep1 + ep2 + ep3) / 3;
return criteiro(mp, mep);
}
const mediaSimples5 = (prova, ep) => {
return (prova + ep) / 2 >= 5.0;
}
const mediaSimples7 = (prova, ep) => {
return (prova + ep) / 2 >= 7.0;
}
const mediaPonderada5 = (prova, ep) => {
return (3 * prova + ep) / 4 >= 5.0;
}
let aprovado = disciplina(5.0, 6.5, 5.5, // true
9.0, 5.5, 7.0,
mediaSimples5);
aprovado = disciplina(5.0, 6.5, 5.5, // false
9.0, 5.5, 7.0,
mediaSimples7);
aprovado = disciplina(5.0, 6.5, 5.5, // true
9.0, 5.5, 7.0,
mediaPonderada5);
Um sistema que lida com compras
let compra1 = "manga",
compra2 = "leite",
compra3 = "paracetamol";
Mas e se eu quiser guardar todas em um mesmo lugar?
let compras = ["manga", "leite", "paracetamol"];
console.log(compras[0]); // manga
console.log(compras[1]); // leite
console.log(compras[2]); // paracetamol
E se eu quiser aumentar a lista?
manga
leite
paracetamol
açaí
push
manga
leite
paracetamol
açaí
compras =
let compras = ["manga", "leite","paracetamol"];
compras.push("açaí");
manga
leite
paracetamol
açaí
pop
manga
leite
paracetamol
compras =
let jogadoFora = compras.pop()
console.log(jogadoFora) // 'açai'
console.log(compras) //['manga', 'leite', 'paracetamol']
2
0
1
0
1
2
sort
compras.sort()
console.log(compras) //['leite', 'manga', 'paracetamol']
leite
paracetamol
compras =
manga
let meiaCompra = compras.slice(0, 2)
console.log(compras) //['leite', 'manga']
console.log(compras) //['leite', 'manga', 'paracetamol']
leite
paracetamol
manga
0
1
2
leite
manga
compras =
meiaCompra =
leite
paracetamol
compras =
manga
slice(0,2)
fechado
aberto
Como percorrer os dados?
Abordagem primária : laço "for"
Será a melhor solução?
Alternativas nativas da linguagem
- Função embutida de lista
- Use se quiser realizar uma operação para cada item da lista
- Recebe como argumento uma função callback
- Como funciona?
"Mota"
"Rodrigo"
"Guerreiro"
"Luiz"
- Mota
- Rodrigo
- Guerreiro
- Luiz
function itemiza (membro) {
console.log(`- ${membro}`);
}
const produção = ["Mota", "Rodrigo", "Guerreiro", "Luiz"];
produção.forEach(itemiza);
// "- Mota"
// "- Rodrigo"
// "- Guerreiro"
// "- Luiz"
forEach(itemiza)
- Útil quando você não tem uma lista
- Quando precisa acessar ou modificar outros itens, além do item atual da iteração
- Como funciona?
const produção = ["Mota", "Rodrigo", "Guerreiro", "Luiz"];
for (const membro of produção) {
console.log(`- ${membro}`)
}
// "- Mota"
// "- Rodrigo"
// "- Guerreiro"
// "- Luiz"
const produção = ["Mota", "Rodrigo", "Guerreiro", "Luiz"];
for (let i = 0; i < produção.length; i++) {
console.log(`- ${membro[i]}`)
}
// "- Mota"
// "- Rodrigo"
// "- Guerreiro"
// "- Luiz"
Seria melhor usar produção.forEach aqui
const aula = 'https://www.ime.usp.br/~jef/bd';
function downloadPDF(url) {
// função que baixa um pdf e salva no seu pc
}
for (let i; i < 11; i++) {
const url = `${aula}${i.padStart('2', '0')}.pdf`
downloadPDF(i)
}
- ForEach apenas itera
- E se eu quiser modificar o valor de uma lista?
- Retorna uma nova lista
- Modifica o valor de uma lista passando uma callback pra cada item
dobro = numeros.map(multiplicador)
numeros =
2
1
3
7
numeros =
2
1
3
7
dobro =
4
2
6
14
let numeros = [2,1,3,7]
const multiplicador = (n) => {
return n * 2;
}
let dobro = numeros.map(multiplicador)
console.log(numeros) //[2,1,3,7]
console.log(dobro) //[4,2,6,14]
- Usado pra filtrar apenas valores desejados na lista
- O critério para filtrar é especificado pela callback
membros =
presentes = membros.filter(PresentesHoje)
"Mota"
"Rodrigo"
"Guerreiro"
"Luiz"
presentes =
"Mota"
"Rodrigo"
membros =
"Mota"
"Rodrigo"
"Guerreiro"
"Luiz"
let numeros = [0,4,2,7];
const selecionaPequenos = (n) => {
return n < 3;
}
let pequenos = numeros.filter(selecionaPequenos);
console.log(numeros) // [0,4,2,7]
console.log(pequenos) // [0,2]
IMPORTANTE: a função de callback de filter deve retornar um booleano
true para o item passar no filtro
false para ele ser filtrado
- Reduz a lista inteira a um único valor (não necessariamente um número)
- O reduce recebe uma função callback e o valor inicial do acumulador
- A callback recebe como parâmetro um acumulador e o elemento atual
1
2
3
4
x = 10
x = numeros.reduce(soma, 0)
const soma = (acc, atual) => acc + atual;
let numeros = [1, 2, 3];
sum1 = numeros.reduce(soma, 0); // soma(0, 1) = 1
// soma(1, 2) = 3
// soma(3, 3) = 6
// sum1 vale 6
sum2 = numeros.reduce(soma, 10); // soma(10, 1) = 11
// soma(11, 2) = 13
// soma(13, 3) = 16
// sum2 vale 16
1
2
3
4
numeros =
- some()
- find()
- includes()
- join()
- sort()
- Podemos encadear métodos de lista?
Sim!
1
2
3
4
5
6
x = numeros.filter(menoresQueCinco)
.map(dobre)
.reduce(soma, 0)
x = 21
Vamos por partes
1
2
3
4
5
6
x = numeros.filter(menoresQueCinco)
1
2
3
4
1
2
3
4
.map(dobre)
2
4
6
8
x = numeros.filter(menoresQueCinco)
2
4
6
8
x = 21
.reduce(soma, 0)
.map(dobre)
x = numeros.filter(menoresQueCinco)
Instruções no Google Classroom
Obrigado pela presença! :)
By codelab@ime.usp.br
Grupo de extensão universitária que como objetivo estimular a inovação tecnológica na USP