Aula 6
Noções básicas de Python
- Hoje aprenderemos uma nova linguagem de programação chamada Python. Lembre-se de que um dos objetivos gerais do curso não é aprender nenhuma linguagem específica, mas sim como programar em geral.
-
O código-fonte em Python parece muito mais simples do que em C, mas é capaz de resolver problemas em campos como ciência de dados. Na verdade, para imprimir "hello, world", tudo o que precisamos escrever é:
print("hello, world")
- Observe que, ao contrário do C, não precisamos importar uma biblioteca padrão, declarar uma função
main
, especificar uma nova linha na funçãoprint
ou usar ponto e vírgula.
- Observe que, ao contrário do C, não precisamos importar uma biblioteca padrão, declarar uma função
-
Python é uma linguagem interpretada, o que significa que, na verdade, executamos outro programa (um interpretador) que lê nosso código-fonte e o executa de cima para baixo. Por exemplo, podemos salvar o código acima como
hello.py
e executar o comandopython hello.py
para executar nosso código, sem precisar compilá-lo. -
Podemos obter strings de um usuário:
answer = get_string("Qual é o seu nome?\n") print("hello, " + answer)
- Criamos uma variável chamada
answer
, sem especificar o tipo (o interpretador determina isso a partir do contexto para nós), e podemos facilmente combinar duas strings com o operador+
antes de passá-la paraprint
. - Também podemos passar vários argumentos para
print
, comprint("hello,", answer)
, e ele unirá automaticamente essas strings com espaços para nós também. print
também aceita strings de formato comof"hello, {answer}"
, que substitui variáveis dentro de chaves por uma string.
- Criamos uma variável chamada
-
Podemos criar variáveis com apenas
counter = 0
. Para incrementar uma variável, podemos usarcounter = counter + 1
oucounter += 1
. -
As condições se parecem com:
if x < y: print("x é menor que y") elif x > y: print("x é maior que y") else: print("x é igual a y")
- Ao contrário do C e do JavaScript (em que as chaves
{
}
são usadas para indicar blocos de código), a indentação exata de cada linha é o que determina o nível de aninhamento em Python. - E em vez de
else if
, basta dizermoselif
.
- Ao contrário do C e do JavaScript (em que as chaves
-
As expressões booleanas também são um pouco diferentes:
while True: print("hello, world")
-
Podemos escrever um loop com uma variável:
i = 3 while i > 0: print("cough") i -= 1
-
Também podemos usar um loop
for
, no qual podemos fazer algo para cada elemento de uma lista:for i in [0, 1, 2]: print("cough")
- As listas em Python são como matrizes em C, mas podem crescer e diminuir facilmente com o interpretador gerenciando a implementação e a memória para nós.
- Este loop
for
definirá a variáveli
para o primeiro elemento,0
, será executado e, em seguida, para o segundo elemento,1
, será executado novamente e assim por diante. - E podemos usar uma função especial,
range
, para obter alguns valores numéricos, como emfor i in range(3)
. Isso nos dará0
,1
e2
, para um total de três valores.
-
No Python, há muitos tipos de dados:
bool
,True
ouFalse
float
, números reaisint
, números inteirosstr
, stringsrange
, sequência de númeroslist
, sequência de valores mutáveis, que podemos alterar, adicionar ou removertuple
, sequência de valores imutáveis, que não podemos alterardict
, coleção de pares chave/valor, como uma tabela hashset
, coleção de valores únicos
- docs.python.org é a fonte oficial de documentação, mas o Google e o StackOverflow também têm recursos úteis quando precisamos descobrir como fazer algo em Python. Na verdade, os programadores no mundo real raramente sabem tudo que está na documentação, mas sabem como encontrar o que precisam quando precisam.
Exemplos
-
Podemos borrifar uma imagem com:
from PIL import Image, ImageFilter before = Image.open("bridge.bmp") after = before.filter(ImageFilter.BLUR) after.save("out.bmp")
- Em Python, incluímos outras bibliotecas com
import
, e aqui nós vamos importar os nomesImage
eImageFilter
da bibliotecaPIL
. - Acontece que se olharmos a documentação para a biblioteca
PIL
, podemos usar as próximas três linhas de código para abrir uma imagem chamadabridge.bmp
, executar um filtro de borramento nela, e salvá-la em um arquivo chamadoout.bmp
. - E podemos executar isso com
python blur.py
depois de salvar em um arquivo chamadoblur.py
.
- Em Python, incluímos outras bibliotecas com
-
Podemos implementar um dicionário com:
words = set() def check(word): if word.lower() in words: return True else: return False def load(dictionary): file = open(dictionary, "r") for line in file: words.add(line.rstrip("\n")) file.close() return True def size(): return len(words) def unload(): return True
- Primeiro, criamos um novo conjunto chamado
words
. Então, paracheck
, nós só precisamos perguntarif word.lower() in words
. Paraload
, nós abrimos o arquivo e usamoswords.add
para adicionar cada linha ao nosso conjunto. Parasize
, nós podemos usarlen
para contar o número de elementos em nosso conjunto, e finalmente, paraunload
, nós não precisamos fazer nada!
- Primeiro, criamos um novo conjunto chamado
-
Acontece que, mesmo que implementar um programa em Python seja mais simples para nós, o tempo de execução de nosso programa em Python é mais lento do que nosso programa em C, pois nosso interpretador tem mais trabalho a fazer para nós. Então, dependendo de nossos objetivos, também teremos que considerar a compensação do tempo humano para escrever um programa que seja mais eficiente, em relação ao tempo de execução do programa.
-
Em Python, também podemos incluir a biblioteca CS50, mas nossa sintaxe será:
from cs50 import get_string
- Observe que especificamos as funções que queremos usar.
-
Agora podemos obter strings de um usuário:
from cs50 import get_string s = get_string("Qual é o seu nome?:\n") print("olá, " + s)
-
Também podemos substituir expressões em nossas strings de formato:
from cs50 import get_int age = get_int("Qual é a sua idade?\n") print(f"Você tem pelo menos {age * 365} dias de idade.")
-
E podemos demonstrar condições:
from cs50 import get_int x = get_int("x: ") y = get_int("y: ") if x < y: print("x é menor que y") elif x > y: print("x é maior que y") else: print("x é igual a y")
-
Para verificar condições, podemos dizer:
from cs50 import get_string s = get_string("Você concorda?\n") if s == "Y" ou s == "y": print("Concordo.") elif s == "N" ou s == "n": print("Não concordo.")
- Python não tem caracteres, então as podemos verificar como strings diretamente.
- Podemos também dizer
if s in ["Y", "y"]:
, ouif s.lower() in ["y"]:
. Acontece que as strings em Python são como structs em C, em que não temos apenas variáveis, mas funções que podemos chamar. Por exemplo, dada uma strings
, podemos chamar sua funçãolower
coms.lower()
para obter a versão em minúsculas da string.
-
Também podemos melhorar as versões de
cough
:print("cough") print("cough") print("cough")
- Não precisamos declarar uma função
main
, então simplesmente escrevemos a mesma linha de código três vezes.
- Não precisamos declarar uma função
-
Mas podemos fazer melhor:
for i in range(3): cough() def cough(): print("cough")
- Perceba que não precisamos especificar o tipo de retorno de uma nova função, que pode ser definida com
def
. -
Mas isso causa um erro quando tentamos executá-la:
NameError: name 'cough' is not defined
(Erro de nome: o nome 'cough' não está definido). Acontece que precisamos definir nossa função antes de usá-la, então podemos mover nossa definição decough
para o topo ou criar uma funçãomain
:def main(): for i in range(3): cough() def cough(): print("cough") main()
-
Agora, no momento em que chamarmos nossa função
main
, a funçãocough
terá sido lida pelo nosso interpretador.
- Perceba que não precisamos especificar o tipo de retorno de uma nova função, que pode ser definida com
-
Nossas funções também podem receber entradas:
def main(): cough(3) def cough(n): for i in range(n): print("cough") main()
-
Podemos definir uma função para obter um inteiro positivo:
from cs50 import get_int def main(): i = get_positive_int() print(i) def get_positive_int(): while True: n = get_int("Inteiro Positivo: ") if n > 0: break return n main()
- Como não há um laço do-while em Python como em C, temos um laço
while
que continuará infinitamente, mas usamosbreak
para finalizar o laço assim quen > 0
. Então, nossa função simplesmentereturn n
. - Observe que as variáveis em Python têm escopo de função por padrão, o que significa que
n
pode ser inicializado dentro de um laço, mas ainda pode ser acessado posteriormente na função.
- Como não há um laço do-while em Python como em C, temos um laço
-
Podemos imprimir uma linha de pontos de interrogação na tela:
for i in range(4): print("?", end="") print()
- Quando imprimimos cada bloco, não queremos a nova linha automática, então podemos passar um parâmetro, ou argumento nomeado, para a função
print
. Aqui, dizemosend=""
para especificar que nada deve ser impresso no final de nossa string. Então, depois de imprimir nossa linha, podemos chamarprint
para obter uma nova linha.
- Quando imprimimos cada bloco, não queremos a nova linha automática, então podemos passar um parâmetro, ou argumento nomeado, para a função
-
Também podemos “multiplicar” uma string e imprimi-la diretamente com:
print("?" * 4)
. -
Podemos imprimir uma coluna com um loop:
for i in range(3): print("#")
-
E sem um loop:
print("#\n" * 3, end="")
. -
Podemos implementar loops aninhados:
for i in range(3): for j in range(3): print("#", end="") print()
-
Não precisamos usar a função
get_string
da biblioteca CS50, pois podemos usar a funçãoinput
embutida no Python para obter uma string do usuário. Mas se quisermos outro tipo de dado, como um inteiro, do usuário, precisaremos convertê-lo comint()
. - Mas nosso programa travará se a string não puder ser convertida em um inteiro, por isso podemos usar
get_string
, que simplesmente perguntará novamente. -
No Python, tentar obter um estouro de inteiro na verdade não funcionará:
from time import sleep i = 1 while True: print(i) sleep(1) i *= 2
- Chamamos a função
sleep
para pausar nosso programa por um segundo entre cada iteração. - Isso continuará até que o inteiro não caiba mais na memória do seu computador.
- Chamamos a função
-
A imprecisão de ponto flutuante também pode ser evitada por bibliotecas que podem representar números decimais com quantos bits forem necessários.
-
Podemos fazer uma lista:
scores = [] scores.append(72) scores.append(73) scores.append(33) print(f"Média: {sum(scores) / len(scores)}")
- Com
append
, podemos adicionar itens à nossa lista, usando-a como uma lista vinculada. - Também podemos declarar uma lista com alguns valores como
scores = [72, 73, 33]
.
- Com
-
Podemos iterar sobre cada caractere em uma string:
from cs50 import get_string s = get_string("Entrada: ") print("Saída: ", end="") for c in s: print(c, end="") print()
- Python obterá cada caractere na string para nós.
-
Para deixar uma string em maiúsculas também, podemos simplesmente chamar
s.upper()
para obter a versão em maiúsculas da string inteira, sem ter que iterar sobre cada caractere nós mesmos.
Mais recursos
-
Podemos receber argumentos de linha de comando com:
from sys import argv for i in range(len(argv)): print(argv[i])
- Como
argv
é uma lista de strings, podemos usarlen()
para obter seu tamanho, erange()
para uma faixa de valores que podemos usar como índice para cada elemento da lista.
- Como
-
Mas também podemos deixar o Python iterar sobre a lista:
from sys import argv for arg in argv: print(arg)
-
Também podemos retornar códigos de saída quando nosso programa sai:
from sys import argv, exit if len(argv) != 2: print("argumento de linha de comando ausente") exit(1) print(f"olá, {argv[1]}") exit(0)
- Importamos a função
exit
e a chamamos com o código que queremos que nosso programa saia.
- Importamos a função
-
Podemos implementar a busca linear apenas verificando cada elemento em uma lista:
import sys names = ["EMMA", "RODRIGO", "BRIAN", "DAVID"] if "EMMA" in names: print("Encontrado") sys.exit(0) print("Não encontrado") sys.exit(1)
-
Se tivermos um dicionário, um conjunto de pares chave:valor, também podemos verificar cada chave:
import sys people = { "EMMA": "617-555-0100", "RODRIGO": "617-555-0101", "BRIAN": "617-555-0102", "DAVID": "617-555-0103" } if "EMMA" in people: print(f"Encontrado {people['EMMA']}") sys.exit(0) print("Não encontrado") sys.exit(1)
- Observe que podemos obter o valor de uma chave em particular em um dicionário com
people['EMMA']
. Aqui, usamos aspas simples (apóstrofos e aspas duplas são permitidas, desde que correspondam a uma string) para diferenciar a string interna da string externa. - E declaramos dicionários com chaves,
{}
, e listas com colchetes[]
.
- Observe que podemos obter o valor de uma chave em particular em um dicionário com
-
Em Python, podemos comparar strings diretamente com apenas
==
:from cs50 import get_string s = get_string("s: ") t = get_string("t: ") if s == t: print("Igual") else: print("Diferente")
-
Copiar strings também funciona sem nenhum trabalho extra nosso:
from cs50 import get_string s = get_string("s: ") t = s t = t.capitalize() print(f"s: {s}") print(f"t: {t}")
-
A troca de duas variáveis também pode ser feita atribuindo ambos os valores ao mesmo tempo:
x = 1 y = 2 print(f"x é {x}, y é {y}") x, y = y, x print(f"x é {x}, y é {y}")
Arquivos
-
Vamos abrir um arquivo CSV:
import csv from cs50 import get_string file = open("phonebook.csv", "a") name = get_string("Nome: ") number = get_string("Número: ") writer = csv.writer(file) writer.writerow((name, number)) file.close()
- Acontece que o Python também tem um pacote
csv
(biblioteca) que nos ajuda a trabalhar com arquivos CSV, então depois que abrirmos o arquivo para acrescentar, podemos chamarcsv.writer
para criar umwriter
do arquivo e depoiswriter.writerow
para escrever uma linha. Com os parênteses internos, estamos criando uma tupla com os valores que queremos escrever, então estamos realmente passando um único argumento que tem todos os valores para nossa linha.
- Acontece que o Python também tem um pacote
-
Podemos usar a palavra-chave
with
, que nos ajudará a fechar o arquivo:... with open("phonebook.csv", "a") as file: writer = csv.writer(file) writer.writerow((name, number))
Novos recursos
- Um recurso do Python que o C não tem são as expressões regulares, ou padrões contra os quais podemos combinar strings. Por exemplo, sua sintaxe inclui:
.
, para qualquer caractere.*
, para 0 ou mais caracteres.+
, para 1 ou mais caracteres?
, para algo opcional^
, para início da entrada$
, para fim da entrada
-
Por exemplo, podemos combinar strings com:
import re from cs50 import get_string s = get_string("Você concorda?\n") if re.search("^y(es)?$", s, re.IGNORECASE): print("Concordo.") elif re.search("^no?$", s, re.IGNORECASE): print("Não concordo.")
- Primeiro, precisamos do pacote
re
, ou biblioteca, para expressões regulares. - Então, para
y
ouyes
, temos a expressão regular^y(es)?$
. Queremos ter certeza de que a string começa comy
e, opcionalmente, temes
imediatamente após oy
, e então termina. - Da mesma forma, para
n
eno
, queremos que nossa string comece, tenha a letran
e, opcionalmente, a letrao
depois, e então termine. A expressão regular para isso seria^no?$
. - Passamos outro argumento,
re.IGNORECASE
, para ignorar a caixa das letras na string. - Se nenhuma das expressões regulares corresponder, não imprimiremos nada.
- Primeiro, precisamos do pacote
-
Em nosso próprio Mac ou PC, podemos abrir um terminal após instalar o Python e usar o microfone para converter nossa fala em texto:
import speech_recognition recognizer = speech_recognition.Recognizer() with speech_recognition.Microphone() as source: print("Diga algo!") audio = recognizer.listen(source) print("O Google Speech Recognition acha que você disse:") print(recognizer.recognize_google(audio))
-
Acontece que há outra biblioteca que podemos baixar, chamada
speech_recognition
, que pode ouvir áudio e convertê-lo em uma string. -
E agora, podemos combinar com o áudio para imprimir algo diferente:
... words = recognizer.recognize_google(audio) # Responda a fala if "hello" in words: print("Olá, para você também!") elif "how are you" in words: print("Estou bem, obrigado!") elif "goodbye" in words: print("Adeus para você também!") else: print("Hã?")
-
Podemos até usar expressões regulares, para combinar com parte de uma string:
... words = recognizer.recognize_google(audio) matches = re.search("my name is (.*)", words) if matches: print(f"Olá, {matches[1]}.") else: print("Olá, você.")
-
Aqui, podemos obter todos os caracteres após
my name is
com.*
e imprimi-los. -
Executamos detect.py e faces.py, que encontra cada rosto (ou até mesmo um rosto específico) em uma foto.
- qr.py também gerará um código QR para um determinado URL.
-