HomePage RecentChanges

Lesson07

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 resultado

Se 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 s

No 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
>>>