MAC2166 - Introdução à Computação

12/05/2014 - Aula 12

Caracteres e uma (brevíssima) introdução sobre sua codificação

"Um caractere pode ser uma letra (maiúscula ou minúscula, um ponto final, ponto de interrogação, colchetes, enfim, símbolos que normalmente encontramos num teclado de um computador".

Em Python, um caractere é uma string de comprimento 1.

Como vimos na primeira aula deste curso, tudo o que computador armazena e processa são números. Por outro lado, durante este curso também já escrevemos programas que leem e manipulam textos (strings). Então, como será que o computador lida com os caracteres?
Para que possam ser processados pelo computador, precisamos representar os caracteres por meio de números.

Existem diferentes codificações (= representações numéricas) que podem ser usadas para caracteres. Algumas codificações são específicas para uma língua (como Chinês, Russo, etc.), enquanto outras podem ser usadas para múltiplas línguas. Um mesmo caracter pode aparecer em diferentes codificações; entretanto, duas codificações diferentes podem usar códigos numéricos diferentes para representar um mesmo caracter.

Uma das codificações mais conhecida (e antiga!) é a ASCII (American Standard Code for Information Interchange), que foi definida como um padrão em 1968. A ASCII foi criada para representar caracteres da língua inglesa e, para isso, usa os números entre 0 e 127. Como um código ASCII é um número entre 0 e 127, ele pode ser armazenado usando-se apenas 7 bits, ou seja, menos de 1 byte (= 8 bits). Você pode ver a tabela da codificação ASCII na Wikipédia.

A codificação ASCII define códigos apenas para caracteres não acentuados, portanto ela não representa completamente os caracteres de outras línguas que possuem o mesmo alfabeto do inglês, como o português, o francês e o espanhol. Para lidar com esse problema, nos anos 80 várias extensões do ASCII foram criadas usando os valores entre 128 e 255 como códigos para caracteres acentuados, resultando em códigos de 1 byte. Um exemplo de uma dessas extensões, usada para a língua portuguesa, é a codificação ISO-8859-1, também chamada de Latin1.

Problema das extensões do ASCII: 128 caracteres adicionais ainda não eram suficientes para representar ao mesmo tempo, por exemplo, os caracteres "especiais" existentes no português e no alfabeto russo.
A criação e uso de codificações específicas para um língua resolve uma parte desse problema. Um arquivo contendo um texto em português pode ter uma determinada codificação, enquanto um outro arquivo contendo um texto em russo pode ter uma codificação diferente. Mas o que fazer quando um texto em português precisava conter uma citação a um trecho em russo?

Para solucionar esse problema e prover uma representação unificada dos alfabetos de todas as línguas da humanidade (objetivo bastante ambicioso!), o padrão Unicode foi desenvolvido. Em sua proposta inicial, o Unicode usava códigos de até 16 bits (2 bytes), sendo capaz de codificar 2^16 = 65536 caracteres diferentes. Mas essa quantidade de caracteres logo mostrou-se insuficiente; atualmente, um código Uni0code pode ocupar até 4 bytes. O Unicode possui diferentes "implementações": UTF-8, UTF-16 e UTF-32. Para todos os caracteres que estão na tabela ASCII, o código Unicode (UTF-8) e o código ASCII são iguais.

O Python 3.x usa codificação UTF-8 como padrão. Já o Python 2.x usa a codificação ASCII como padrão.

As funções ord() e chr()

A função ord() devolve o código numérico do caractere passado como parâmetro. Veja os exemplos a seguir:

In [1]:
print(ord("8"))
print(ord("?"))
print(ord("A"))
print(ord("C"))
print(ord("^"))
print(ord("a"))
56
63
65
67
94
97

A função ord() gerará um erro se passarmos como parâmetro uma string contendo mais de um caracter:

In [2]:
ord("olá!")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-2e7b9727d71f> in <module>()
----> 1 ord("olá!")

TypeError: ord() expected a character, but string of length 4 found

A função chr() devolve o caracter corresponde ao código numérico passado como parâmetro. Veja os exemplos abaixo:

In [3]:
print(chr(43))
print(chr(54))
print(chr(65))
print(chr(472))
+
6
A
ǘ

Importante: Em todos os exercícios a seguir, por simplicidade, trabalharemos apenas com strings com codificação ASCII, ou seja, strings que não contêm caracteres com acentos.

Problema 23

Escreva um programa que imprima todos os caracteres ASCII de 32 a 127.

In [4]:
for i in range(32,128):
    print("Caracter '%s' tem código ASCII %d"%(chr(i), i))
Caracter ' ' tem código ASCII 32
Caracter '!' tem código ASCII 33
Caracter '"' tem código ASCII 34
Caracter '#' tem código ASCII 35
Caracter '$' tem código ASCII 36
Caracter '%' tem código ASCII 37
Caracter '&' tem código ASCII 38
Caracter ''' tem código ASCII 39
Caracter '(' tem código ASCII 40
Caracter ')' tem código ASCII 41
Caracter '*' tem código ASCII 42
Caracter '+' tem código ASCII 43
Caracter ',' tem código ASCII 44
Caracter '-' tem código ASCII 45
Caracter '.' tem código ASCII 46
Caracter '/' tem código ASCII 47
Caracter '0' tem código ASCII 48
Caracter '1' tem código ASCII 49
Caracter '2' tem código ASCII 50
Caracter '3' tem código ASCII 51
Caracter '4' tem código ASCII 52
Caracter '5' tem código ASCII 53
Caracter '6' tem código ASCII 54
Caracter '7' tem código ASCII 55
Caracter '8' tem código ASCII 56
Caracter '9' tem código ASCII 57
Caracter ':' tem código ASCII 58
Caracter ';' tem código ASCII 59
Caracter '<' tem código ASCII 60
Caracter '=' tem código ASCII 61
Caracter '>' tem código ASCII 62
Caracter '?' tem código ASCII 63
Caracter '@' tem código ASCII 64
Caracter 'A' tem código ASCII 65
Caracter 'B' tem código ASCII 66
Caracter 'C' tem código ASCII 67
Caracter 'D' tem código ASCII 68
Caracter 'E' tem código ASCII 69
Caracter 'F' tem código ASCII 70
Caracter 'G' tem código ASCII 71
Caracter 'H' tem código ASCII 72
Caracter 'I' tem código ASCII 73
Caracter 'J' tem código ASCII 74
Caracter 'K' tem código ASCII 75
Caracter 'L' tem código ASCII 76
Caracter 'M' tem código ASCII 77
Caracter 'N' tem código ASCII 78
Caracter 'O' tem código ASCII 79
Caracter 'P' tem código ASCII 80
Caracter 'Q' tem código ASCII 81
Caracter 'R' tem código ASCII 82
Caracter 'S' tem código ASCII 83
Caracter 'T' tem código ASCII 84
Caracter 'U' tem código ASCII 85
Caracter 'V' tem código ASCII 86
Caracter 'W' tem código ASCII 87
Caracter 'X' tem código ASCII 88
Caracter 'Y' tem código ASCII 89
Caracter 'Z' tem código ASCII 90
Caracter '[' tem código ASCII 91
Caracter '\' tem código ASCII 92
Caracter ']' tem código ASCII 93
Caracter '^' tem código ASCII 94
Caracter '_' tem código ASCII 95
Caracter '`' tem código ASCII 96
Caracter 'a' tem código ASCII 97
Caracter 'b' tem código ASCII 98
Caracter 'c' tem código ASCII 99
Caracter 'd' tem código ASCII 100
Caracter 'e' tem código ASCII 101
Caracter 'f' tem código ASCII 102
Caracter 'g' tem código ASCII 103
Caracter 'h' tem código ASCII 104
Caracter 'i' tem código ASCII 105
Caracter 'j' tem código ASCII 106
Caracter 'k' tem código ASCII 107
Caracter 'l' tem código ASCII 108
Caracter 'm' tem código ASCII 109
Caracter 'n' tem código ASCII 110
Caracter 'o' tem código ASCII 111
Caracter 'p' tem código ASCII 112
Caracter 'q' tem código ASCII 113
Caracter 'r' tem código ASCII 114
Caracter 's' tem código ASCII 115
Caracter 't' tem código ASCII 116
Caracter 'u' tem código ASCII 117
Caracter 'v' tem código ASCII 118
Caracter 'w' tem código ASCII 119
Caracter 'x' tem código ASCII 120
Caracter 'y' tem código ASCII 121
Caracter 'z' tem código ASCII 122
Caracter '{' tem código ASCII 123
Caracter '|' tem código ASCII 124
Caracter '}' tem código ASCII 125
Caracter '~' tem código ASCII 126
Caracter '' tem código ASCII 127

Problema 24

Dada uma sequência de caracteres representando um texto, determinar a frequência relativa de vogais no texto.

Por exemplo, no texto:

"Em terra de cego quem tem um olho e caolho"

essa frequência é 16/42.

In [5]:
texto = input("Digite um texto: ") # Suponha que o usuário digitou a frase do exemplo 

nv = 0
vogais = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']

for letra in texto:
    if letra in vogais:
        nv += 1

print("Frequência relativa = %d / %d"%(nv, len(texto)))    
    
Frequência relativa = 16 / 42

Problema 25

  1. Escreva uma função que recebe um caractere e, caso o caractere seja uma letra minúscula, retorna a letra maiúscula correspondente. Caso contrário, retorna o caractere.

  2. Escreva uma função que recebe um caractere e, caso o caractere seja uma letra maiúscula, retorna a letra minúscula correspondente. Caso contrário, retorna o caractere.

  3. Escreva um programa que leia uma frase e imprima:

In [6]:
def paraMaiuscula(c):
    if c >= 'a' and c <= 'z':
        return chr(ord('A') + ord(c) - ord('a'))
    else:
        return c
    
def paraMinuscula(c):
    if c >= 'A' and c <= 'Z':
        return chr(ord('a') + ord(c) - ord('A'))
    else:
        return c

# PROGRAMA PRINCIPAL
texto = input("digite um texto: ")  # Suponha que o usuário digitou "PeQuEno TesTE"

textoMaiusculo = ''
textoMinusculo = ''
for l in texto:
    textoMaiusculo += paraMaiuscula(l)
    textoMinusculo += paraMinuscula(l)

print("Em maiúsculas: ")
print (textoMaiusculo)

print("Em minúsculas: ")
print(textoMinusculo)
Em maiúsculas: 
PEQUENO TESTE
Em minúsculas: 
pequeno teste

Obs.: O tipo string em Python já possui funções para converter uma string para letras maiúsculas ou minúsculas - são as funções upper() e lower(). Veja um exemplo do uso delas a seguir:

In [7]:
texto = "PeQuEno TesTE"
textoMaiusculo = texto.upper()  # cria uma string com o texto em letras maiúsculas
textoMinusculo = texto.lower()  # cria uma string com o texto em letras minúsculas
print(textoMaiusculo)
print(textoMinusculo)
PEQUENO TESTE
pequeno teste

Problema Extra 1

Dada uma sequência de caracteres, determinar quantas letras minúsculas e maiúsculas aparecem na sequência. Considere apenas os caracteres ASCII.

Exemplo, para a frase: "Em terra de CEGO quem tem um olho e caolho"

Número de minúsculas: 28
Número de maiúsculas: 5
Total de caracteres no texto: 42

In [8]:
texto = "Em terra de CEGO quem tem um olho e caolho" # input("Digite um texto: ") # Suponha que o usuário digitou a frase do exemplo 
nmin = nmai = 0
for c in texto:
    if c >= 'a' and c<= 'z':
        nmin += 1
    elif c >= 'A' and c <= 'Z':
        nmai += 1

print("Número de minúsculas: %d"%(nmin))
print("Número de maiúsculas: %d"%(nmai))
print("Total de caracteres no texto: %d"%(len(texto)))
Número de minúsculas: 28
Número de maiúsculas: 5
Total de caracteres no texto: 42

Problema Extra 2

Dada uma string, contar o número de ocorrências de cada letra do alfabeto.

Exemplo, para a frase: "Em terra de CEGO quem tem um olho e caolho"

O número de ocorrências de 'A' é: 2
O número de ocorrências de 'B' é: 0
O número de ocorrências de 'C' é: 2
O número de ocorrências de 'D' é: 1
O número de ocorrências de 'E' é: 7
O número de ocorrências de 'F' é: 0
O número de ocorrências de 'G' é: 1
O número de ocorrências de 'H' é: 2
O número de ocorrências de 'I' é: 0
O número de ocorrências de 'J' é: 0
O número de ocorrências de 'K' é: 0
O número de ocorrências de 'L' é: 2
O número de ocorrências de 'M' é: 4
O número de ocorrências de 'N' é: 0
O número de ocorrências de 'O' é: 5
O número de ocorrências de 'P' é: 0
O número de ocorrências de 'Q' é: 1
O número de ocorrências de 'R' é: 2
O número de ocorrências de 'S' é: 0
O número de ocorrências de 'T' é: 2
O número de ocorrências de 'U' é: 2
O número de ocorrências de 'V' é: 0
O número de ocorrências de 'W' é: 0
O número de ocorrências de 'X' é: 0
O número de ocorrências de 'Y' é: 0
O número de ocorrências de 'Z' é: 0

In []:
texto = "Em terra de CEGO quem tem um olho e caolho" # input("Digite um texto: ") # Suponha que o usuário digitou a frase do exemplo 

ocorrencias = [0] * 26  # cria uma lista com 26 posições valendo 0; 
                        # a i-ésima posição corresponde ao número de ocorrências da i-ésima letra do alfabeto

ord_A = ord("A")
ord_a = ord("a")

for caracter in texto:
    # Verifica se é letra minúscula
    if caracter >= 'a' and caracter <= 'z':
        ocorrencias[ord(caracter) - ord_a] += 1
    elif caracter >= 'A' and caracter <= 'Z':
        ocorrencias[ord(caracter) - ord_A] += 1 

for i in range(26):
    caracter = chr(i + ord_A)
    print("O número de ocorrências de '%s' é: %d" %(caracter,ocorrencias[i]))

Tópicos vistos na aula 12

Referências e outros materiais para estudo