Ciclos contados
Até agora quando utilizamos ciclos , e em particular para percorrer tuplos, temos inicializado um contador e, no corpo do ciclo, fazemos avançar o contador. No caso dos tuplos, inicializamos um contador i=0 e avançamos o mesmo com i=i+1. Vamos agora ver como podemos utilizar ciclos contados para tingir o mesmo fim.
Num ciclo contado a execução é controlada por uma variável de controlo. Em geral, num ciclo contado especificamos o valor inicial da variável de controlo, a forma de actualizar a mesma, e a condição de paragem. Logo, um ciclo contado permite iterar sobre uma sequência de valores.
Em Python utilizamos a instrução for para definir ciclos contados e temos a seguinte sintaxe (em BNF):
<instrução for> ::= for <nome simples> in <expressão>: NEWLINE <bloco de instruções>
Neste caso o <nome simples> corresponde à variável de controlo e o valor <expressão> tem de ser uma sequência, e.g., um tuplo. Veremos adiante que existem várias entidades em Python que podem ser vistas como sequências, também designadas de iteráveis. O comportamento da instrução for consiste em executar o corpo do ciclo para cada elemento na sequência resultante de avaliar a <expressão>. Tal como na instrução while, na instrução for podemos utilizar a instrução break no corpo do ciclo (ou bloco de instruções) para interromper o mesmo independentemente do valor da variável de controlo.
Vejamos alguns exemplos.
def soma(t):
resultado = 0
for x in t:
resultado = resultado + x
return resultado
soma((1,2,3,4,5))Para gerar sequências em Python podemos utilizar a função pré-definida range. Em BNF,
range(<argumentos>) <argumentos> ::= <expressão> | <expressão>, <expressão> | <expressão, <expressão>, <expressão>
Em que os valores de cada <expressão> são do tipo inteiro e o resultado é uma sequência. O primeiro argumento define o início da sequência (inclusive), o segundo argumento define o fim da sequência (exclusive), e terceiro argumento define o passo ou incremento.
Exemplos:
>>> tuple(range(10)) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) >>> tuple(range(5,10)) (5, 6, 7, 8, 9) >>> tuple(range(-5,10)) (-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9) >>> tuple(range(-5,10,2)) (-5, -3, -1, 1, 3, 5, 7, 9) >>> tuple(range(-5,10,-2)) () >>> tuple(range(10,-5,-2)) (10, 8, 6, 4, 2, 0, -2, -4) >>> tuple(range(10,-5,-1)) (10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4) >>>
Exercício 1: Defina uma função que calcula a soma dos primeiros $n$ números naturais.
Exercício 2: Defina uma função que permite verificar se um tuplo com valores numéricos está ordenado. Nota: Será que podemos iterar simplesmente sobre os elementos do tuplo? Justifique.
Nota-se que a instrução while permite fazer tudo o que a instrução for pode fazer. Por outro lado existem casos em que não podemos utilizar a instrução for, com no caso da função alisa vista na última aula. Em geral o uso da instrução for é mais eficiente que a instrução while, nomeadamente quando utilizamos a função range, dado que o interpretador de Python tem um maior sucesso a optimizar esses casos. Portanto, a instrução for deverá ser sempre preferida em detrimento da instrução while quando possível.
Cadeias de caracteres
Anteriormente considerámos cadeias caracteres como constantes e vimos que são do tipo str em Python. Em geral uma cadeia de caracteres pode conter 0 ou mais caracteres. As cadeias de caracteres em Python são delimitadas por 's ou "s. A sequência de caracteres com 0 caracteres, ou vazia, é representada por '' ou "".
Nota-se que as "s em Python são também utilizadas para documentação, uma utilização completamente distinta da que acabámos de ver:
def soma(t):
"""
Recebe um tuplo de retorna a soma dos seus elementos.
"""
resultado = 0
for x in t:
resultado = resultado + x
return resultadoSe esta definição estiver carregada, podemos obter a seguinte interacção:
>>> help(soma)
Help on function soma in module __main__:
soma(t)
Recebe um tuplo de retorna a soma dos seus elementos.
>>>Tal como os tuplos, as cadeias de caracteres são imutáveis e podemos aceder aos caracteres por meio de índices. Exemplo:
>>> fp='Fundamentos da Programacao' >>> len(fp) 26 >>> fp[0] 'F' >>> fp[15:] 'Programacao' >>> fp[:11] 'Fundamentos' >>> fp[-3:] 'cao' >>>
Existem várias operações pré-definidas que podemos aplicar sobre cadeias de caracteres,
>>> fp1 = 'Fundamentos'
>>> f = 'Fundamentos'
>>> p = 'Programacao'
>>> f + ' de ' + p
'Fundamentos de Programacao'
>>> f*3
'FundamentosFundamentosFundamentos'
>>> 'c' in p
True
>>> 'c' in f
False
>>> len(p)
11
>>> str(9+8)
'17'
>>> str((9,8,20))
'(9, 8, 20)'
>>> eval('f + p')
'FundamentosProgramacao'
>>>Podemos também iterar sobre os caracteres. Vejamos o seguinte exemplo em que transformamos minúsculas em maiúsculas:
def toupper(s):
for i in range(len(s)):
if ord('a') <= ord(s[i]) <= ord('z'):
s = s[:i] + chr(ord(s[i]) - ord('a') + ord('A')) + s[i+1:]
return sNo exemplo anterior utilizámos também as funções pré-definidas char e ord que permitem obter o código de um caractere e obter um caractere para um dado código, respectivamente. Nota-se que os caracteres são representados por um código numérico, em que o código ASCII será o mais conhecido. O Python utiliza Unicode, que inclui o código ASCII.
Tendo por base esta representação numérica, podemos efetuar comparações entre caracteres e cadeias de caracteres:
>>> 'a' < 'z' True >>> 'a' < 'Z' False >>> 'a' > 'Z' True >>> 'Fundamentos' > 'Programacao' False >>> 'fundamentos' > 'Programacao' True >>> 'fundamentos' > 'fundao' False >>> 'fundamentos' < 'fundao' True >>>