Aula 0

Bem-vindo

  • Quando David estava no primeiro ano, ele ficou muito intimidado para fazer qualquer curso de ciência da computação. Quando estava no segundo ano, ele encontrou coragem para fazer o equivalente ao CS50, mas apenas para passar/ser reprovado.
  • Na verdade, dois terços dos alunos do CS50 nunca fizeram um curso de ciência da computação antes.
  • E o mais importante também:

O que importa neste curso não é tanto onde você estará em relação aos seus colegas, mas onde você estará em relação a si mesmo quando começou.

O que é ciência da computação?

  • Ciência da computação é fundamentalmente resolução de problemas.
  • O processo de resolução de problemas é pegar uma entrada (detalhes sobre o problema) e gerar uma saída (a solução do problema). A "caixa preta" no meio é a ciência da computação. palavra "input", seta para a caixa, seta para fora da caixa, palavra "output"
  • Precisamos de uma maneira de representar entradas, de modo que possamos armazenar e trabalhar com informações de uma maneira padrão.

Binário

  • Um computador, no nível mais baixo, armazena dados em binário, um sistema numérico em que existem apenas dois dígitos, 0 e 1.
  • Quando aprendemos a contar, podemos ter usado um dedo para representar uma coisa. Esse sistema é chamado de unário. Quando aprendemos a escrever números com os dígitos de 0 a 9, aprendemos a usar o sistema decimal.
  • Por exemplo, sabemos que o seguinte representa cento e vinte e três:
1 2 3
  • O "3" está na coluna das unidades, o "2" está na coluna das dezenas e o "1" está na coluna das centenas.
  • Portanto, "123" é 100 × 1 + 10 × 2 + 1 × 3 = 100 + 20 + 3 = 123.
  • Cada lugar para um dígito representa uma potência de dez, pois há dez dígitos possíveis para cada lugar.

  • Em binário, com apenas dois dígitos, temos potências de dois para cada valor de lugar:

4 2 1
0 0 0
  • Isso ainda seria igual a 0.

  • Agora, se alterarmos o valor binário para, digamos, "0 1 1", o valor decimal será 3.

4 2 1
0 1 1
  • Se quiséssemos representar 8, precisaríamos de outro dígito:
8 4 2 1
1 0 0 0
  • E o binário faz sentido para computadores porque nós os alimentamos com eletricidade, que pode estar ligada ou desligada, então cada bit só precisa estar ligado ou desligado. Em um computador, há milhões ou bilhões de interruptores chamados transistores que podem armazenar eletricidade e representar um bit como "ligado" ou "desligado".
  • Com bits ou dígitos binários suficientes, os computadores podem contar até qualquer número.
  • 8 bits formam um byte.

Representações de dados

  • Para representar letras, tudo o que precisamos fazer é decidir como os números são mapeados para as letras. Alguns humanos, muitos anos atrás, decidiram coletivamente usar um mapeamento padrão chamado ASCII. A letra "A", por exemplo, é o número 65, e "B" é 66, e assim por diante. O mapeamento também inclui pontuação e outros símbolos. Outros caracteres, como letras com acentos e emojis, fazem parte de um padrão chamado Unicode que usa mais bits do que ASCII para acomodar todos esses caracteres.
    • Quando recebemos um emoji, nosso computador está na verdade apenas recebendo um número decimal como "128514" ("11111011000000010" em binário, se você puder ler isso mais facilmente) que ele então mapeia para a imagem do emoji.
  • Uma imagem também é composta de muitos pontos quadrados menores, ou pixels, cada um dos quais pode ser representado em binário com um sistema chamado RGB, com valores para luz vermelha, verde e azul em cada pixel. Ao misturar diferentes quantidades de cada cor, podemos representar milhões de cores: quadrado vermelho rotulado com 72, quadrado verde rotulado com 73, quadrado azul rotulado com 33
    • Os valores vermelho, verde e azul são combinados para obter uma cor amarelo claro: quadrado amarelo claro
  • Podemos ver isso em um emoji se aumentarmos o zoom o suficiente: emoji ampliado de lágrimas de alegria com quadrados de pixels distinguíveis
  • E os programas de computador sabem, com base no contexto de seu código, se os números binários devem ser interpretados como números, letras ou pixels.
  • E os vídeos são apenas muitas e muitas imagens exibidas uma após a outra, a um determinado número de quadros por segundo. A música também pode ser representada pelas notas que estão sendo tocadas, sua duração e seu volume.

Algoritmos

  • Então agora podemos representar entradas e saídas. A caixinha preta vista anteriormente conterá algoritmos, instruções passo a passo para solucionar um problema: caixa com a palavra "algoritmos"
  • Digamos que queremos encontrar um amigo, Mike Smith, em uma lista telefônica.
    • Podemos começar folheando o livro uma página de cada vez até encontrarmos Mike Smith ou chegarmos ao fim do livro.
    • Podemos também folhear duas páginas por vez, mas se formos longe demais, teremos de saber voltar uma página.
    • Mas uma forma ainda mais eficiente seria abrir a lista telefônica ao meio, decidir se Mike estará na metade esquerda ou direita do livro (já que o livro está em ordem alfabética) e descartar imediatamente metade do problema. Podemos repetir isso, dividindo o problema pela metade sempre. Com 1024 páginas para começar, precisaríamos de apenas 10 passos dividindo pela metade antes de sobrar apenas uma página para verificarmos.
  • Na verdade, podemos representar a eficiência de cada um desses algoritmos com um gráfico: gráfico com: "tamanho do problema" como eixo x; "tempo para resolver" como eixo y; linha reta íngreme vermelha da origem até o topo do gráfico rotulada como "n"; linha reta amarela menos íngreme da origem até o topo do gráfico rotulada como "n/2"; linha verde curva que se torna cada vez menos íngreme da origem até a direita do gráfico rotulada como "log n"
    • A nossa primeira solução, uma página por vez, é como a linha vermelha: nosso tempo para resolver aumenta linearmente conforme o tamanho do problema aumenta.
    • A segunda solução, duas páginas por vez, é como a linha amarela: a inclinação é menor, mas ainda linear.
    • Nossa solução final é como a linha verde: logarítmica, pois nosso tempo para resolver aumenta cada vez mais devagar conforme o tamanho do problema aumenta. Ou seja, se a lista telefônica passasse de 1000 para 2000 páginas, precisaríamos de mais um passo para encontrar Mike. Se o tamanho dobrasse novamente de 2000 para 4000 páginas, ainda precisaríamos de apenas mais um passo.

Pseudocódigo

  • Podemos escrever pseudocódigo, uma sintaxe informal que é apenas uma versão mais específica de inglês (ou outra língua humana) que representa nosso algoritmo:

       1  Pegue a lista telefônica
       2  Abra o meio da lista telefônica
       3  Olhe a página
       4  Se Smith estiver na página
       5      Ligue para Mike
       6  Senão se Smith estiver antes no livro
       7      Abra o meio da metade esquerda do livro
       8      Retorne à linha 3
       9  Senão se Smith estiver depois no livro
       10     Abra o meio da metade direita do livro
       11     Retorne à linha 3
       12 Senão
       13     Pare
    
  • Algumas dessas linhas começam com verbos ou ações. Passaremos a chamá-los de funções:

    1  Pegar a lista telefônica
    2  Abrir no meio da lista telefônica
    3  Olhar a página
    4  Se Smith estiver na página  
    5      Ligar para Mike
    6  Senão se Smith estiver antes no livro
    7      Abrir no meio da metade esquerda do livro
    8      Retornar à linha 3
    9  Senão se Smith estiver depois no livro
    10     Abrir no meio da metade direita do livro
    11     Retornar à linha 3
    12 Senão
    13     Parar
  • Também temos ramificações que levam a caminhos diferentes, como bifurcações na estrada, que chamaremos de condições:
    1  Pegar a lista telefônica
    2  Abrir no meio da lista telefônica
    3  Olhar a página
    4  Se Smith estiver na página
    5      Ligar para Mike
    6  Senão se Smith estiver antes no livro
    7      Abrir no meio da metade esquerda do livro
    8      Retornar à linha 3
    9  Senão se Smith estiver depois no livro
    10     Abrir no meio da metade direita do livro
    11     Retornar à linha 3
    12 Senão
    13     Parar
  • E as perguntas que decidem para onde vamos são chamadas de expressões booleanas, que eventualmente resultam em um valor verdadeiro ou falso:
    1  Pegar a lista telefônica
    2  Abrir no meio da lista telefônica
    3  Olhar a página
    4  Se Smith estiver na página
    5      Ligar para Mike
    6  Senão se Smith estiver antes no livro
    7      Abrir no meio da metade esquerda do livro
    8      Retornar à linha 3
    9  Senão se Smith estiver depois no livro
    10     Abrir no meio da metade direita do livro
    11     Retornar à linha 3
    12 Senão
    13     Parar
  • Finalmente, temos palavras que levam a ciclos, onde podemos repetir partes do nosso programa, chamadas de loops:
    1  Pegar a lista telefônica
    2  Abrir no meio da lista telefônica
    3  Olhar a página
    4  Se Smith estiver na página
    5      Ligar para Mike
    6  Senão se Smith estiver antes no livro
    7      Abrir no meio da metade esquerda do livro
    8      Retornar à linha 3
    9  Senão se Smith estiver depois no livro
    10     Abrir no meio da metade direita do livro
    11     Retornar à linha 3
    12 Senão
    13     Parar

Scratch

  • Podemos escrever programas com os blocos de construção que acabamos de descobrir:
    • funções
    • condições
    • expressões booleanas
    • laços
  • Usaremos uma linguagem de programação gráfica chamada Scratch, na qual arrastaremos e soltaremos blocos que contêm instruções.
  • Mais tarde em nosso curso, passaremos para linguagens de programação textuais como C, Python e JavaScript. Todas essas linguagens, incluindo o Scratch, têm recursos mais poderosos, como:
    • variáveis
      • a capacidade de armazenar valores e alterá-los
    • threads
      • a capacidade de nosso programa fazer várias coisas ao mesmo tempo
    • eventos
      • a capacidade de responder a mudanças em nosso programa ou entradas
  • O ambiente de programação do Scratch se parece com isto: captura de tela do Scratch
    • À esquerda, temos peças de quebra-cabeça que representam funções ou variáveis, ou outros conceitos, que podemos arrastar e soltar em nossa área de instruções no centro.
    • À direita, temos um palco que será exibido por nosso programa para um humano, onde podemos adicionar ou alterar planos de fundo, personagens (chamados sprites no Scratch) e muito mais.
  • Podemos arrastar alguns blocos para fazer o Scratch dizer “olá, mundo”:
    captura de tela de hello, world
    • O bloco “quando a bandeira verde clicada” é o início do nosso programa, e abaixo dele encaixamos um bloco “dizer” e digitamos “olá, mundo”.
  • Também podemos arrastar o bloco “perguntar e esperar”, com uma pergunta como “Qual é o seu nome?”, e combiná-lo com um bloco “dizer” para a resposta:
    captura de tela de pergunta e resposta
  • Mas não esperamos depois de dizer “Olá” com o primeiro bloco, então podemos usar o bloco “dizer () durante () segundos”:
    captura de tela de blocos com dizer por 2 segundos
  • Podemos usar o bloco “unir” para combinar duas frases para que o Scratch possa dizer “olá, David”:
    captura de tela de unir
    • Observe que podemos aninhar instruções e variáveis.
  • Na verdade, o próprio bloco “dizer” é como um algoritmo, onde fornecemos uma entrada de “olá, mundo” e ele produziu a saída do Scratch (o gato) “dizendo” essa frase:
    dizer como algoritmo com "olá, mundo" como entrada e gato como saída
  • O bloco “perguntar” também recebe uma entrada (a pergunta que queremos fazer) e produz a saída do bloco “resposta”:
    perguntar como algoritmo com "Qual é o seu nome?" como entrada e bloco de resposta como saída
  • Podemos então usar o bloco “resposta” junto com nosso próprio texto, “olá, “, como duas entradas para o algoritmo de junção …
    junção como algoritmo com "olá, " e "resposta" como entrada e "olá, David!" como saída
  • … que passamos como entrada novamente para o bloco “dizer”:
    dizer como algoritmo com "olá, David!" como entrada e gato como saída
  • Podemos tentar fazer o Scratch (o nome do gato) dizer miau:
    blocos rotulados "para sempre" com "reproduzir som Miau até fazer" aninhados dentro
    • Mas quando clicamos na bandeira verde, ouvimos o som do miado repetidamente e imediatamente. Nosso primeiro bug, ou erro! Podemos adicionar um bloco para esperar, para que os miados soem mais normais.
      blocos rotulados "para sempre" com "reproduzir som Miau até fazer" e "esperar 1 segundo" aninhados dentro
  • Podemos fazer o Scratch apontar para o mouse e mover-se em direção a ele:
    blocos rotulados "para sempre" com "apontar para o ponteiro do mouse" e "mover 10 passos" aninhados dentro
  • Veremos uma ovelha que pode contar:
    blocos rotulados "definir contador como 1" e "para sempre" com "dizer contador durante 1 segundo", "esperar 1 segundo" e "alterar contador em 1" aninhados dentro
    • Aqui, contador é uma variável, cujo valor podemos definir, usar e alterar.
  • Também podemos fazer o Scratch miar se tocarmos nele com o ponteiro do mouse:
    blocos rotulados "para sempre" com "se tocar no ponteiro do mouse? então" e "reproduzir som Miau até fazer" aninhados
  • Como alternativa, podemos fazer o Scratch rugir se o fizermos:
    blocos rotulados "para sempre" com "se tocar no ponteiro do mouse? então" e "reproduzir som rugido até fazer" aninhados, e "senão", "reproduzir som Miau até fazer", "esperar 1 segundo"
    • Aqui, temos dois ramos diferentes, ou condições, que se repetirão para sempre. Se o mouse estiver tocando, o Scratch “rugirá”, caso contrário, ele apenas miará.
  • Podemos fazer o Scratch se mover para frente e para trás na tela com mais alguns blocos que podemos descobrir olhando ao redor:
    blocos rotulados "definir estilo de rotação esquerda-direita" e "para sempre" com "mover 10 passos", "se tocar na borda? então" e "reproduzir som ai até fazer", "virar 180 graus"

    • Podemos até mesmo gravar nosso próprio som para tocar.
  • Com duas “vestimentas” ou imagens diferentes do Scratch com as pernas em posições diferentes, podemos até mesmo simular um movimento animado ao caminhar: blocos rotulados como “definir estilo de rotação esquerda-direita” e “para sempre” com “mover 10 passos”, “se tocou na borda? então” com “tocar som ai até fim”, “girar 180 graus” aninhado dentro e “próxima vestimenta”

  • Analisaremos outro programa, bark, no qual podemos usar a barra de espaço para silenciar um leão-marinho: blocos rotulados como “definir mudo para falso” e “para sempre” com se chave espaço pressionada? então” com “se mudo = verdadeiro então” e “definir mudo para falso” e “senão” e “definir mudo para verdadeiro” aninhados dentro e “aguarde 1 segundo”
    • Temos uma variável, muted, que é false por padrão. E o programa verificará constantemente se a barra de espaço é pressionada e definirá muted para false se for true ou true se não for. Dessa forma, podemos alternar a reprodução do som ou não, já que o outro conjunto de blocos do leão-marinho verifica a variável muted: blocos rotulados como “para sempre” com se muted = falso então” com “iniciar som SeaLion” e “pensar oi oi oi por 2 segundos” aninhados dentro e “aguarde 1 segundo”
  • Com vários sprites, ou personagens, podemos ter diferentes conjuntos de blocos para cada um deles: blocos rotulados como “para sempre” com se chave espaço pressionada? então” com “dizer Marco! por 2 segundos” e “transmissão de evento” aninhados dentro
    • Para um fantoche, temos esses blocos que dizem “Marco!” e, em seguida, um bloco de “transmissão de evento”. Esse “evento” é usado para que nossos dois sprites se comuniquem entre si, como o envio de uma mensagem secreta. Então, o outro fantoche pode apenas esperar que esse evento diga “Polo!”: blocos rotulados como “quando recebo evento”, “dizer Polo! por 2 segundos”
  • Agora que conhecemos alguns conceitos básicos, podemos pensar no design ou na qualidade de nossos programas. Por exemplo, podemos querer que o Scratch tussa três vezes repetindo alguns blocos: blocos rotulados como “dizer tosse por 1 segundo”, “aguarde 1 segundo”, “dizer tosse por 1 segundo”, “aguarde 1 segundo”, “dizer tosse por 1 segundo”, “aguarde 1 segundo”
  • Embora esteja correto, podemos evitar a repetição de blocos com um loop: blocos rotulados como “repetir 3” com “dizer tosse por 1 segundo”, “aguarde 1 segundo” aninhados dentro
  • A próxima etapa é abstrair parte do nosso código em uma função, ou torná-lo reutilizável de diferentes maneiras. Podemos criar um bloco chamado “tosse” e colocar alguns blocos dentro dele: dois conjuntos de blocos. o primeiro conjunto de blocos é: “definir tosse”, “dizer tosse por 1 segundo”, “aguarde 1 segundo”. o segundo conjunto é: “quando a bandeira verde é clicada”, “repetir 3”, “tosse”
    • Agora, todos os nossos sprites podem usar o mesmo bloco de “tosse”, em quantos lugares desejarmos.
  • Podemos até mesmo colocar um número de vezes em nossa função de tosse, portanto, precisamos apenas de um único bloco para tossir qualquer número de vezes: dois conjuntos de blocos. o primeiro conjunto de blocos é: “definir n vezes de tosse”, “repetir n”, dizer tosse por 1 segundo”, “aguarde 1 segundo”. o segundo conjunto é: “quando a bandeira verde é clicada”, “tosse 3 vezes”
  • Analisamos alguns exemplos e discutimos como podemos implementar componentes deles com diferentes sprites que seguem o cursor do mouse ou fazem com que algo mais aconteça no palco.
  • Bem-vindo a bordo!