Programação I / Introdução à Programaçãojpp/Prog1920/teorica-09_strings.pdf · Programação...

Post on 15-Nov-2019

24 views 0 download

Transcript of Programação I / Introdução à Programaçãojpp/Prog1920/teorica-09_strings.pdf · Programação...

Programação I / Introdução à ProgramaçãoCapítulo 5, "Data types" (cadeias de caracteres, "strings")

João Pedro Pedroso

2019/2020

Última aula:I Funções

Hoje:I Notas sobre aulas anterioresI Typos de dados: Strings

Números pseudo-aleatórios

I Necessários em muitas situações:I num jogo, para lançar um dado/moeda ao ar;I baralhar um conjunto de cartas;I escolher um exercício para examinar um aluno;I simular o tempo de espera por um autocarro;I codificar informação numa consulta à conta bancária;I . . .

I módulo random tem funcionalidades para isto, e.g.:random.random() → float no intervalo [0, 1[random.choice(xs) → um valor (aleatório) da lista xs

I xs não pode ser vaziarandom.randrange(a,b[,step]) → inteiro aleatório entre a

e b, com distribuição uniformeI limite superior não é incluído (tal como range)

random.randint(a, b) → inteiro N aleatório, a ≤ N ≤ bI alias para randrange(a, b+1)

I os geradores de números pseudo-aleatórios são baseados numalgoritmo determinístico

I são inicializados com uma semente (seed)I inicialização “manual”: e.g., seed(1) → comportamento

sempre igualI inicialização “por omissão”: em geral será diferente; por isso, o

comportamento, na prática, é aleatório

1 import random2 # random.seed(1) # uncomment this line for having always the same numbers generated3 prob = random.random()4 print(prob)5 diceThrow = random.randint(1,6)6 print(diceThrow)

output:0.40794106360008856

Dicas, truques, erros comuns

I código errado para determinar se uma lista tem números pares:

1 numbers = [10, 5, 24, 8, 6]2 for number in numbers:3 if number % 2 == 1:4 print("list has odd numbers")5 break6 else:7 print("list has NO odd numbers")8 break

onde está o erro?

1 numbers = [10, 5, 24, 8, 6]2 has_odd = False3 for number in numbers:4 if number % 2 == 1:5 has_odd = True6 break7 if has_odd:8 print("list has odd numbers")9 else:

10 print("list has NO odd numbers")

Dicas, truques, erros comuns

I código errado para determinar se uma lista tem números pares:

1 numbers = [10, 5, 24, 8, 6]2 for number in numbers:3 if number % 2 == 1:4 print("list has odd numbers")5 break6 else:7 print("list has NO odd numbers")8 break

onde está o erro?

1 numbers = [10, 5, 24, 8, 6]2 has_odd = False3 for number in numbers:4 if number % 2 == 1:5 has_odd = True6 break7 if has_odd:8 print("list has odd numbers")9 else:

10 print("list has NO odd numbers")

Mais Pythonic:

1 numbers = [10, 5, 24, 8, 6]2 for number in numbers:3 if number % 2 == 1:4 print("list has odd numbers")5 break6 else: # no break7 print("list has NO odd numbers")

I módulo math: funções e constantes matemáticassin, cos, pi, . . .

I números complexos: módulo cmath

>>> import cmath>>> a = cmath.sqrt(-1)>>> a1j

Onde está o gato?

1 def any_odd(xs): # Buggy version2 """ Return True if there is an odd number in xs, a list of integers. """3 for v in xs:4 if v % 2 == 1:5 return True6 else:7 return False

1 def any_odd(xs):2 """ Return True if there is an odd number in xs, a list of integers. """3 for v in xs:4 if v % 2 == 1:5 return True6 return False

Onde está o gato?

1 def any_odd(xs): # Buggy version2 """ Return True if there is an odd number in xs, a list of integers. """3 for v in xs:4 if v % 2 == 1:5 return True6 else:7 return False

1 def any_odd(xs):2 """ Return True if there is an odd number in xs, a list of integers. """3 for v in xs:4 if v % 2 == 1:5 return True6 return False

Recomendações

I Escrever um programa não resolve o problema!I apenas automatiza os passos necessáriosI → usar papel e lápis antes de começar a programar

I Não utilizar print e input dentro de funçõesI exceções:

I quando o papel dessa função é input/outputI quando se está a fazer debugging → remover print’s depois de

o código estar corrigido

Tipos de dados compostos

I Vimos já alguns tipos de dados do PythonI int, float, bool, strI vimos também listas e tuplos

I Strings, listas e tuplos são diferentes dos outros:I são constituidos por elementos mais pequenosI strings (cadeias de carateres):

I cada um desses elementos mais pequenos é uma string comum carater

I são chamados tipos de dados compostosI por vezes interessa-nos vê-los como um todo, outras vezes

queremos aceder a cada uma das partes

Strings como objetos singularesI Tal como vimos com as tartarugas, strings são objetos com

atributos e métodos

>>> our_string = "Hello, World!">>> all_caps = our_string.upper()>>> all_caps'HELLO, WORLD!'>>> our_string'Hello, World!'

I Outros métodos: lower, capitalize, swapcase, ...Podemos consultar o manual,

listá-los com help(str), ou:

Strings como objetos compostos

I Podemos aceder a cada uma das partes de uma string com ooperador de indexação, []

1 >>> fruit = "banana"2 >>> letter = fruit[1] # 1 -> index3 >>> print(letter)

a

fruit " b a n na a "0 1 2 3 4 5 6index

Strings: indexação

I Primeiro elemento ("b") → índice zeroI Índice → qualquer expressão com valor inteiroI Podemos visualizar os índices com enumerate:

>>> fruit = "banana">>> list(enumerate(fruit))[(0, 'b'), (1, 'a'), (2, 'n'), (3, 'a'), (4, 'n'), (5, 'a')]

I Indexação de strings e de listas é semelhante

Strings: indexação com valores negativos

>>> word = "banana">>> size = len(word)>>> word[size]Traceback (most recent call last):

File "<stdin>", line 1, in <module>IndexError: string index out of range

Último elemento de uma string s:I índice len(s) - 1

I word[size-1] → "a"I índice -1 → primeiro elemento a contar do fim:

I word[-1] → "a"

>>> word[-2]

n

Fatias

Permitem obter substrings

>>> phrase = "Pirates of the Caribbean">>> print(phrase[0:5])Pirat>>> friends = ["Joe", "Zoe", "Brad", "Angelina", "Zuki", "Thandi", "Paris"]>>> friends[2:4]['Brad', 'Angelina']

txt[i:j] substring entre indices i e j-1 inclusivetxt[i:] substring desde o índice i até ao finaltxt[:j] substring desde o ínicio até ao índice j-1 inclusive

Nota: o valor de j pode ser superior ao tamanho da string, noacesso a uma fatia isso não dá erro (resulta na string desde i até aofinal)

Percorrer strings

I Semelhante ao idioma que vimos para percorrer listas:

1 word="Banana"2 for letter in word:3 print(letter)

Banana

Outros idiomasI Básico:

1 word="Banana"2 for letter in word:3 print(letter)

I Com indexação

1 for i in range(len(word)):2 print(i, word[i])

I Com indexação e ciclo while (pouco recomendado)

1 i = 02 while i < len(word):3 letter = word[i]4 print(i, letter)5 i += 1

I Com enumerate e tuploI usado quando precisamos do índice e do valor e cada elemento

1 for i,letter in enumerate(word):2 print(i, letter)

Comparação de strings

I Operadores de comparação funcionam com strings:

>>> word = "banana">>> word == "apple"False>>> word == "banana"True>>> word == "Banana"False

I É usada uma ordem lexicográfica; ordenação não é alfabética!

1 word = "Zebra"2 if word < "banana":3 print("Your word, " + word + ", comes before banana.")4 elif word > "banana":5 print("Your word, " + word + ", comes after banana.")6 else:7 print("Well, we have no bananas...")

Your word, Zebra, comes before banana.

Códigos ascii

I Códigos numéricos associados aos carateresI Estabelecem a ordem lexicográfica

32 33 ! 34 " 35 # 36 $ 37 %38 & 39 ' 40 ( 41 ) 42 * 43 +44 , 45 - 46 . 47 / 48 0 49 150 2 51 3 52 4 53 5 54 6 55 756 8 57 9 58 : 59 ; 60 < 61 =62 > 63 ? 64 @ 65 A 66 B 67 C68 D 69 E 70 F 71 G 72 H 73 I74 J 75 K 76 L 77 M 78 N 79 O80 P 81 Q 82 R 83 S 84 T 85 U86 V 87 W 88 X 89 Y 90 Z 91 [92 \ 93 ] 94 ^ 95 _ 96 ` 97 a98 b 99 c 100 d 101 e 102 f 103 g104 h 105 i 106 j 107 k 108 l 109 m110 n 111 o 112 p 113 q 114 r 115 s116 t 117 u 118 v 119 w 120 x 121 y122 z 123 { 124 | 125 } 126 ~

Strings e mutabilidade

I As strings são imutáveis: não as podemos alterar

>>> greeting = "Jello, world!">>> greeting[0] = 'H'TypeError: 'str' object does not support item assignment

I mas podemos criar novas strings:

>>> new_greeting = "H" + greeting[1:]>>> new_greeting'Hello, world!'

Testar ocorrência

txt1 in txt2 → testa ocorrência de txt1 dentro de txt2

>>> 'ana' in 'Banana'True>>> 'mana' in 'Banana'False>>> 'mana' not in 'Banana'True>>> 'Banana' in 'Banana'True>>> '' in 'Banana'True

1 def remove_vowels(phrase):2 vowels = "aeiou"3 string_sans_vowels = ""4 for letter in phrase:5 if letter.lower() not in vowels:6 string_sans_vowels += letter7 return string_sans_vowels

>>> remove_vowels("Programacao I")'Prgrmc '

1 def remove_vowels(phrase):2 vowels = "aeiou"3 string_sans_vowels = ""4 for letter in phrase:5 if letter.lower() not in vowels:6 string_sans_vowels += letter7 return string_sans_vowels

>>> remove_vowels("Programacao I")'Prgrmc '

Procurar dentro de uma string

1 def my_find(haystack, needle):2 for index, letter in enumerate(haystack):3 if letter == needle:4 return index5 return -1

I find → inverso da indexaçãoI quando não se encontra o que se procura: retorna -1I este idioma: "short-circuit evaluation"

I logo que se encontra o que se procura, para-se a pesquisa

>>> haystack = "Bananarama!">>> print(haystack.find('a'))1>>> print(my_find(haystack,'a'))1

Parâmetros opcionais

I Podemos modificar a função my_find para utilizar o índiceonde deve começar a procurar:

1 def my_find(haystack, needle, start=0):2 for index, letter in enumerate(haystack[start:]):3 if letter == needle:4 return index + start5 return -1

I Podemos dar um valor "por omissão"I na definição de uma função start=0I se chamarmos my_find com dois argumentos, o valor de

start será zeroI na implementação do método find de strings, há dois

parâmetros opcionais:start onde se começa a procurarend onde se termina a procura

Mais métodos úteis sobre strings

find índice da primeira ocorrênciareplace substituir ocorrênciasupper substituir letras minúsculas por maiúsculaslower substituir letras maiúsculas por minúsculassplit divite uma string com várias palavras numa lista de

palavras

>>> phrase = "Well I never did said Alice">>> words = phrase.split()>>> words['Well', 'I', 'never', 'did', 'said', 'Alice']

"Limpeza" de stringsI Muitas vezes, é útil remover todos os carateres que não são

letras:

1 punctuation = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"2 def remove_punctuation(phrase):3 phrase_sans_punct = ""4 for letter in phrase:5 if letter not in punctuation:6 phrase_sans_punct += letter7 return phrase_sans_punct

I Em vez de definirmos punctuation, podemos usar umadefinição do módulo string:

1 import string2 def remove_punctuation(phrase):3 phrase_sans_punct = ""4 for letter in phrase:5 if letter not in string.punctuation:6 phrase_sans_punct += letter7 return phrase_sans_punct

Ver mais atributos na documentação do Python:https://docs.python.org/3/library/string.html

Formatação de strings

Guia através de exemplos:

1 print("{:<5}{:<5}{:^7}{:^7}{:>15}{:>15}{:>15}"\2 .format("i", "i**2", "i**3", "i**5", "i**10", "i**10", "i**10"))3 print("{:<5}{:<5}{:^7}{:^7}{:>15}{:>15}{:>15}"\4 .format("---", "---", "---", "---", "---", "---", "---",))5 for i in range(1, 11):6 print(f"{i:<5}{(i**2):<5}{(i**3):^7}{(i**5):^7}\7 {(i**10):>15}{(i**10):>15e}{(i**10):>15.2f}")

i i**2 i**3 i**5 i**10 i**10 i**10--- --- --- --- --- --- ---1 1 1 1 1 1.000000e+00 1.002 4 8 32 1024 1.024000e+03 1024.003 9 27 243 59049 5.904900e+04 59049.004 16 64 1024 1048576 1.048576e+06 1048576.005 25 125 3125 9765625 9.765625e+06 9765625.006 36 216 7776 60466176 6.046618e+07 60466176.007 49 343 16807 282475249 2.824752e+08 282475249.008 64 512 32768 1073741824 1.073742e+09 1073741824.009 81 729 59049 3486784401 3.486784e+09 3486784401.0010 100 1000 100000 10000000000 1.000000e+10 10000000000.00

format, f"string"

"Hello {}, how are you?".format("John") → resulta em"Hello John, how are you?"

"{:<5}".format(i) string com valor i alinhado à esquerda em 5"espaços"

"{:^5}".format(i) . . . alinhado ao centro"{:>5}".format(i) . . . alinhado à direita

f"{i}" o mesmo que "{}".format(i)

1 alunos = [(123, "Jose", 14.5),2 (13, "Maria", 17.5),3 (32, "Manuela", 16.7)]4

5 for (numero, nome, nota) in alunos:6 print(f"{nome} teve {nota} valores no exame.")

Jose teve 14.5 valores no exame.Maria teve 17.5 valores no exame.Manuela teve 16.7 valores no exame.

Noções estudadas

indexing []length function lenfor loop traversal forslicing [:]string comparison >, <, >=, <=, ==, !=membership operators in and not in

Próxima aulaI Tipos de dados do Python: strings (conclusão)