"A única maneira de aprender uma nova linguagem de programação é escrevendo programas nela." (Brian Kernighan e Dennis Ritchie, A Linguagem de Programação C)
O Capítulo 2 deu a você números inteiros e matemática suficientes por enquanto. Python é mais do que apenas uma calculadora. Como a criptografia é sobre lidar com valores de texto transformando texto simples em texto cifrado e vice-versa, você aprenderá como armazenar, combinar e exibir texto na tela neste capítulo. Você também fará seu primeiro programa, que cumprimenta o usuário com o texto "Olá, mundo!" e permite que o usuário insira seu nome.
Strings
Concatenação e replicação de string
Índices e fatiamento
A função print()
Em Python, trabalhamos com pequenos pedaços de texto chamados valores de string (ou simplesmente strings). Todos os nossos programas de cifra e hacking lidam com valores de string para transformar texto simples como 'Um se por terra, dois se por espaço' em texto cifrado como 'b1rJvsJo!Jyn1q,J702JvsJo!J63nprM'. O texto simples e o texto cifrado são representados em nosso programa como valores de string, e há muitas maneiras pelas quais o código Python pode manipular esses valores.
Você pode armazenar valores de string dentro de variáveis, assim como pode com valores inteiros e de ponto flutuante. Quando você digitar uma string, coloque-a entre duas aspas simples (') para mostrar onde a string começa e termina. Insira o seguinte na célula:
s = 'Olá'
s
As aspas simples não fazem parte do valor da string. O Python sabe que 'Olá' é uma string e s é uma variável porque strings são cercadas por aspas e nomes de variáveis não são. Se você digitar s na IDLE, verá o conteúdo da variável s (a string 'Olá').
Isso ocorre porque o Python avalia uma variável para o valor armazenado dentro dela: neste caso, a string 'Olá'. Strings podem ter quase qualquer caractere de teclado nelas. Estes são todos exemplos de strings:
'olá'
'GATINHOS'
'7 maçãs, 14 laranjas, 3 limões'
'O*&#wY%*&OcfsdYO*&gfC%YO*&%3yc8r2'
Observe que a string '' tem zero caracteres; não há nada entre aspas simples. Isso é conhecido como string em branco ou string vazia.
Você pode adicionar dois valores de string para criar uma nova string usando o operador +. Fazer isso é chamado de concatenação de string. Insira 'Olá,' + 'mundo!' no shell interativo:
'Olá,' + 'mundo!'
O Python concatena exatamente as strings que você diz para ele concatenar, então ele não colocará um espaço entre as strings quando você as concatena. Se você quiser um espaço na string resultante, deve haver um espaço em uma das duas strings originais. Para colocar um espaço entre 'Olá,' e 'mundo!', você pode colocar um espaço no final da string 'Olá,' e antes da segunda aspa simples, assim:
'Olá, ' + 'mundo!'
O operador + pode concatenar dois valores de string em um novo valor de string ('Olá, ' + 'mundo!' para 'Olá, mundo!'), assim como pode adicionar dois valores inteiros para resultar em um novo valor inteiro (2 + 2 para 4). Python sabe o que o operador + deve fazer por causa dos tipos de dados dos valores. Como você aprendeu no Capítulo 2, o tipo de dados de um valor nos diz (e ao computador) que tipo de dados o valor é.
Você pode usar o operador + em uma expressão com duas ou mais strings ou inteiros, desde que os tipos de dados correspondam. Se você tentar usar o operador com uma string e um inteiro, obterá um erro:
'Olá' + 10
'Olá' + '10'
A primeira linha de código causa um erro porque 'Olá' é uma string e 10 é um inteiro. Mas na segunda linha de código, '10' é uma string, então Python a concatena.
Você também pode usar o operador * em uma string e um inteiro para fazer replicação de string. Isso replica (isto é, repete) uma string por quantas vezes o valor inteiro for:
'Olá' * 3 # 1
s = 'Abcdef'
s = s * 3 # 2
s
Para replicar uma string, digite a string, depois o operador * e, em seguida, o número de vezes que você quer que a string se repita (1). Você também pode armazenar uma string, como fizemos com a variável s, e então replicar a variável em vez da string sozinha (2). Você pode até mesmo armazenar uma string replicada de volta na mesma variável ou em uma nova variável.
Como você viu no Capítulo 2, o operador * pode trabalhar com dois valores inteiros para multiplicá-los. Mas ele não pode trabalhar com dois valores de string, o que causaria um erro, como este:
'Olá' * 'mundo!'
A concatenação de strings e a replicação de strings mostram que operadores em Python podem fazer tarefas diferentes com base nos tipos de dados dos valores em que operam. O operador + pode fazer adição ou concatenação de strings. O operador * pode fazer multiplicação ou replicação de strings.
Seus programas de criptografia geralmente precisam obter um único caractere de uma string, o que você pode fazer por meio da indexação. Com a indexação, você adiciona colchetes [] ao final de um valor de string (ou uma variável contendo uma string) com um número entre eles para acessar um caractere. Esse número é chamado de índice e informa ao Python qual posição na string tem o caractere que você deseja. Os índices do Python começam em 0, então o índice do primeiro caractere em uma string é 0. O índice 1 é para o segundo caractere, o índice 2 é para o terceiro caractere e assim por diante:
s = 'Olá'
s[0]
s[1]
s[2]
Observe que a expressão s[0] é avaliada como o valor da string 'O', porque O é o primeiro caractere na string 'Olá' e os índices começam em 0, não em 1.
Você pode usar a indexação com uma variável contendo um valor de string, como fizemos no exemplo anterior, ou um valor de string por si só:
'Casa'[2]
Se você inserir um índice muito grande para a string, o Python exibirá uma mensagem de erro "index out of range", como você pode ver no código a seguir:
'Olá'[10]
Há três caracteres na string 'Olá', então se você tentar usar o índice 10, o Python exibirá um erro.
Índices negativos
Índices negativos começam no final de uma string e vão para trás. O índice negativo -1 é o índice do último caractere em uma string. O índice -2 é o índice do segundo ao último caractere, e assim por diante:
'Casa'[-1]
'Casa'[-2]
'Casa'[-3]
'Casa'[-4]
'Casa'[0]
Observe que -4 e 0 são os índices para o mesmo caractere. Na maioria das vezes, seu código usará índices positivos, mas às vezes é mais fácil usar os negativos.
Obtendo vários caracteres de strings usando fatias
Se você quiser obter mais de um caractere de uma string, você pode usar fatiamento em vez de indexação. Um slice (ou fatia) também usa os colchetes [], mas tem dois índices inteiros em vez de um. Os dois índices são separados por dois pontos (:) e informam ao Python o índice do primeiro e do último caractere no slice:
'Banana'[0:3]
A string que a fatia avalia começa no primeiro valor de índice e vai até, mas não inclui, o segundo valor de índice. O índice 0 do valor da string 'Banana' é B e o índice 3 é a. Como uma fatia vai até, mas não inclui o segundo índice, a fatia 'Banana'[0:3] avalia o valor da string 'Ban':
'Olá, mundo!'[0:5]
'Olá, mundo!'[7:13]
'Olá, mundo!'[-6: -1]
'Olá, mundo!'[7:13][2]
Observe que a expressão 'Olá, mundo!'[7:13] primeiro avalia a fatia da lista como 'mundo!'[2] e depois avalia como 'o'.
Diferentemente de índices, o fatiamento nunca dá erro se você der um índice muito grande para a string. Ele apenas retornará o maior fatiamento correspondente que puder:
'Olá'[0:999]
'Olá'[2:999]
'Olá'[1000:2000]
A expressão 'Olá'[1000:2000] retorna uma string em branco porque o índice 1000 está depois do fim da string, então não há caracteres possíveis que esse slice poderia incluir. Embora nossos exemplos não mostrem isso, você também pode fatiar strings armazenadas em variáveis.
Índices de fatias em branco
Se você omitir o primeiro índice de uma fatia, o Python usará automaticamente o índice 0 para o primeiro índice. As expressões 'Banana'[0:3] e ''Banana'[:3] são avaliadas como a mesma string. Se você omitir o segundo índice, o Python usará automaticamente o restante da string começando pelo primeiro índice.
Você pode usar índices em branco de muitas maneiras diferentes:
fruta = 'Banana é amarela'
fruta[-7:]
fruta[:8]
fruta[7:]
Como você pode ver, você pode até usar índices negativos com um índice em branco. Como -7 é o índice inicial no primeiro exemplo, o Python conta sete caracteres para trás a partir do final e usa isso como seu índice inicial. Então ele retorna tudo daquele índice até o final da string por causa do segundo índice em branco.
Vamos tentar outro tipo de instrução Python: uma chamada de função print():
print('Olá')
print(10)
Uma função (como print() neste exemplo) tem um código dentro dela que executa uma tarefa, como imprimir valores na tela. Muitas funções diferentes vêm com Python e podem executar tarefas úteis para você. Chamar uma função significa executar o código dentro da função.
As instruções neste exemplo passam um valor para print() entre parênteses, e a função print() imprime o valor na tela. Os valores que são passados quando uma função é chamada são argumentos. Quando você escreve programas, você usará print() para fazer o texto aparecer na tela.
Você pode passar uma expressão para print() em vez de um único valor. Isso ocorre porque o valor que é realmente passado para print() é o valor avaliado dessa expressão. Insira esta expressão de concatenação de string:
s = 'Gui'
print('Olá, ' + s)
A expressão 'Olá, ' + s é avaliada como 'Olá, ' + 'Gui', que então é avaliada como o valor da string 'Olá, Gui'. Esse valor da string é o que é passado para a chamada print().
Você pode querer usar um caractere em um valor de string que confundiria o Python. Por exemplo, você pode querer usar um caractere de aspas simples como parte de uma string. Mas você receberia uma mensagem de erro porque o Python pensa que aspas simples são as aspas que encerram o valor da string e o texto depois dela é um código Python ruim, em vez do resto da string:
print('Aquilo lá é 'muito' sério')
Para usar uma aspa simples em uma string, você precisa usar um caractere de escape. Um caractere de escape é um caractere de barra invertida seguido por outro caractere — por exemplo, \t, \n ou \'. A barra diz ao Python que o caractere após a barra tem um significado especial:
print('Aquilo lá é \'muito\' sério')
Agora o Python saberá que as aspas são caracteres no valor da string, não o código Python marcando o fim da string.
A barra invertida sempre precede um caractere de escape. Mesmo se você quiser apenas uma barra invertida na sua string, você não pode adicionar uma barra invertida sozinha porque o Python interpretará o próximo caractere como um caractere de escape. Por exemplo, esta linha de código não funcionaria corretamente:
print('Pegue o garfo\talher')
O 't' em 'talher' é identificado como um caractere de escape porque vem depois de uma barra invertida. O caractere de escape \t simula pressionar a tecla TAB no seu teclado. Em vez disso, insira este código:
print('Pegue o garfo\\talher')
Desta vez, a string será impressa conforme você pretendia, porque colocar uma segunda barra invertida na string faz com que a barra invertida seja o caractere de escape.
Strings nem sempre precisam estar entre duas aspas simples em Python. Você pode usar aspas duplas em vez disso. Essas duas linhas imprimem a mesma coisa:
print('Olá, mundo!')
print("Olá, mundo!")
Mas você não pode misturar aspas simples e duplas. Esta linha dá um erro:
print('Olá, mundo!")
Mas assim como você tem que usar o caractere de escape \' para ter uma aspa simples em uma string cercada por aspas simples, você precisa do caractere de escape \" para ter uma aspa dupla em uma string cercada por aspas duplas.
Exercício 01: Se você atribuir s = 'Gatos', o que as linhas a seguir imprimem:
s + s + s
s * 3
Exercício 02: O que as linhas a seguir imprimem?
print('Cara João,\nComo você vai?\nAtenciosamente,\nMaria')
print('Olá' + 'Olá')
Exercício 03: Se você atribuir s = 'Quatrocentos e sete anos são oitenta e sete anos.', o que cada uma das linhas a seguir imprimiria?
print(s[5])
print(s[-3])
print(s[0:4] + s[5])
print(s[-3:-1])
print(s[:10])
print(s[-5:])
print(s[:])
Escrever programas é apenas saber falar a linguagem do computador. Você aprendeu um pouco sobre como fazer isso no Capítulo 2, e agora você juntou várias instruções Python para fazer um programa completo.
Neste capítulo, você aprendeu várias técnicas novas para manipular strings, como usar o operador + para concatenar strings. Você também pode usar indexação e fatiamento para criar uma nova string a partir de parte de uma string diferente.
O restante dos programas neste livro será mais complexo e sofisticado, mas todos serão explicados linha por linha.
Em seguida, começaremos a escrever nosso primeiro programa de criptografia: a cifra reversa.