diff --git a/book/06-estruturas-de-dados/01-strings.ipynb b/book/06-estruturas-de-dados/01-strings.ipynb index 55897d5..e0aeff5 100644 --- a/book/06-estruturas-de-dados/01-strings.ipynb +++ b/book/06-estruturas-de-dados/01-strings.ipynb @@ -36,7 +36,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -61,7 +61,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 8, "metadata": { "tags": [ "raises-exception" @@ -73,7 +73,7 @@ "evalue": "invalid syntax (1998578200.py, line 2)", "output_type": "error", "traceback": [ - "\u001b[1;36m Cell \u001b[1;32mIn[2], line 2\u001b[1;36m\u001b[0m\n\u001b[1;33m erro_de_sintaxe = \"Ela disse \"Olá mundo!\"\"\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n" + "\u001b[1;36m Cell \u001b[1;32mIn[8], line 2\u001b[1;36m\u001b[0m\n\u001b[1;33m erro_de_sintaxe = \"Ela disse \"Olá mundo!\"\"\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n" ] } ], @@ -99,7 +99,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -128,7 +128,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -171,7 +171,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -195,7 +195,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -242,7 +242,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -267,7 +267,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -299,7 +299,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -353,7 +353,7 @@ "\n", "Nesta altura, falamos muito sobre tipos de dados (`int`, `float`, `str`). No fundo, tipos de dados são objetos. Ao invés de falar tipo de dado `str`, podemos falar objeto do tipo `str`. Absolutamente tudo em Python é um objeto que tem um tipo! Mudar a forma de falar já está o colocando em outro patamar de entendimento sobre programação.\n", "\n", - "Vamos agora para definição de método. A dfinição que eu mais gosto é: métodos são funções que estão associadas a um determinado objeto e podem ser usadas para realizar operações nestes. Em termos simples, pense em métodos como ações que você pode realizar com um determinado objeto (`int`, `float`, `str`, etc.). \n", + "Vamos agora para definição de método. A definição que eu mais gosto é: métodos são funções que estão associadas a um determinado objeto e podem ser usadas para realizar operações nestes. Em termos simples, pense em métodos como ações que você pode realizar com um determinado objeto (`int`, `float`, `str`, etc.). \n", "\n", "A diferença principal entre métodos e funções é a seguinte:\n", "\n", @@ -366,7 +366,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -422,7 +422,7 @@ "\n", "Para fins puramente didáticos, vou separar os métodos em casos de uso, trazendo exemplos de uso de cada método.\n", "\n", - "1. Transformação de Case\n", + "1. Transformação de case\n", "- `str.upper()`: Converte todos os caracteres da string para maiúsculas.\n", "- `str.lower()`: Converte todos os caracteres da string para minúsculas.\n", "- `str.capitalize()`: Converte o primeiro caractere da string para maiúscula e o restante para minúscula.\n", @@ -431,17 +431,17 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "HENRIQUE BRANCO\n", - "henrique branco\n", - "Henrique branco\n", - "Henrique Branco\n" + "UM NOME QUALQUER\n", + "um nome qualquer\n", + "Um nome qualquer\n", + "Um Nome Qualquer\n" ] } ], @@ -457,7 +457,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "2. Remoção de Espaços\n", + "2. Remoção de espaços\n", "- `str.lstrip()`: Remove espaços em branco do início da string.\n", "- `str.rstrip()`: Remove espaços em branco do fim da string.\n", "- `str.strip()`: Remove espaços em branco do início e do fim da string.\n", @@ -471,16 +471,16 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Henrique Branco \n", - " Henrique Branco\n", - "Henrique Branco\n" + "Um texto qualquer com espaços em branco no começo e no final... \n", + " Um texto qualquer com espaços em branco no começo e no final...\n", + "Um texto qualquer com espaços em branco no começo e no final...\n" ] } ], @@ -503,7 +503,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -527,12 +527,259 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "```{admonition} Atenção\n", + "```{admonition} Atenção (espaços em branco)\n", ":class: warning\n", "\n", "O espaço em branco (deixado propositalmente) é super relevante na comparação de strings, por isso as strings `Python` (sem espaço em branco) e `Python ` (com espaço em branco no final) são diferentes, apesar de ser apenas por um único caracter em branco. Por esta razão tivemos `frase.endswith(\"Python\") = False`\n", "```" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "4. Verificação de caracteres\n", + "\n", + "Todos estes métodos abaixo verificam se a string contém apenas:\n", + "\n", + "- `str.islower()`: caracteres minúsculos.\n", + "- `str.isupper()`: caracteres maiúsculos\n", + "- `str.isalnum()`: caracteres alfanuméricos.\n", + "- `str.isalpha()`: caracteres alfabéticos.\n", + "- `str.isdigit()`: dígitos.\n", + "- `str.isspace()`: espaços em branco." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "olá é todo minúsculo? True\n", + "MUNDO é todo maiúsculo? True\n", + "olá123 é alfanumérico? True\n", + "ola, eu sou um texto puramente alfabético #sqn... é alfabético? False\n", + "12345 é dígito? True\n", + "' ' é espaço em branco? True\n" + ] + } + ], + "source": [ + "minusculo = \"olá\"\n", + "print(f\"{minusculo} é todo minúsculo? {minusculo.islower()}\")\n", + "\n", + "maiusculo = \"MUNDO\"\n", + "print(f\"{maiusculo} é todo maiúsculo? {maiusculo.isupper()}\")\n", + "\n", + "alfanumerico = \"olá123\"\n", + "print(f\"{alfanumerico} é alfanumérico? {alfanumerico.isalnum()}\")\n", + "\n", + "alfabetico = \"ola, eu sou um texto puramente alfabético #sqn...\"\n", + "print(f\"{alfabetico} é alfabético? {alfabetico.isalpha()}\")\n", + "\n", + "digitos = \"12345\"\n", + "print(f\"{digitos} é dígito? {digitos.isdigit()}\")\n", + "\n", + "espacos = \" \"\n", + "print(f\"'{espacos}' é espaço em branco? {espacos.isspace()}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```{admonition} Nota (caracteres alfabéticos)\n", + ":class: note\n", + "\n", + "O espaço em branco ` ` não é considerado um caracter alfabético, assim como `#`, `,` e `.`. Por outro lado, caracteres com acento, como `á`, são considerados alfabéticos.\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "5. Divisão e junção\n", + "\n", + "- `str.split()`: Divide a string em uma lista, utilizando um separador especificado.\n", + "- `str.join(lista)`: Junta uma lista de strings utilizando um separador especificado.\n", + "\n", + "```{admonition} Nota (listas)\n", + ":class: note\n", + "\n", + "Lista é uma outra estrutura de dados, que veremos em mais detalhes logo no capítulo seguinte.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['Lucas', 'Ferreira', 'de', 'Almeida', 'Gomes']\n", + "Lucas-Ferreira-de-Almeida-Gomes\n" + ] + } + ], + "source": [ + "nome_completo = \"Lucas Ferreira de Almeida Gomes\"\n", + "\n", + "lista_de_strings = nome_completo.split()\n", + "print(lista_de_strings)\n", + "\n", + "print(\"-\".join(lista_de_strings))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Por padrão, o `split()` usa um ou mais espaços em branco para separar a string, mas é possível passar outro caracter separador. Vejamos outros exemplos:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['123', '456', '789-10']\n", + "['123.456.789', '10']\n" + ] + } + ], + "source": [ + "cpf = \"123.456.789-10\"\n", + "\n", + "# Dividindo o CPF através do `.`\n", + "print(cpf.split(\".\"))\n", + "\n", + "#Dividindo o CPF através do `-`\n", + "print(cpf.split(\"-\"))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Reforço prático - métodos vs funções" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Anteriormente, abordamos a diferença entre métodos e funções de maneira teórica. Agora, vamos revisitar essa diferença com uma abordagem mais prática!\n", + "\n", + "Nós vimos vários métodos acima. E eu faço a seguinte pergunta agora: como calculamos o tamanho ou comprimento de uma string? Em outras palavras, quantos caracteres tem uma dada string?\n", + "\n", + "Bom, você pode se lembrar que não vimos todos os métodos disponíveis, e ir procurar na documentação oficial na [lista completa com todos os métodos de string](https://docs.python.org/3/library/stdtypes.html#string-methods). Lá, você vai encontrar algo com `len`, que vem de length (comprimento) do inglês. Ótimo! Este método `len` deve servir então! Vamos testar?" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "tags": [ + "raises-exception" + ] + }, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'str' object has no attribute 'len'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[24], line 4\u001b[0m\n\u001b[0;32m 1\u001b[0m nome_comprido \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mJoão Antônio da Silva Sauro de Souza Silva Santos\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;66;03m# Contando a quantidade de caracteres deste nome enorme\u001b[39;00m\n\u001b[1;32m----> 4\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mnome_comprido\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mlen\u001b[49m()) \u001b[38;5;66;03m# ... ops!\u001b[39;00m\n", + "\u001b[1;31mAttributeError\u001b[0m: 'str' object has no attribute 'len'" + ] + } + ], + "source": [ + "nome_comprido = \"João Antônio da Silva Sauro de Souza Silva Santos\"\n", + "\n", + "# Contando a quantidade de caracteres deste nome enorme\n", + "print(nome_comprido.len()) # ... ops!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Na verdade, de fato o `str.len()` não existe mesmo, pois ele não está na lista de métodos da documentação oficial.\n", + "\n", + "O que aconteceu afinal de contas? O erro é bem informativo: `AttributeError: 'str' object has no attribute 'len'`, ou seja, strings não possuem o `len`.\n", + "\n", + "Porém, para medirmos o comprimento de uma string, podemos fazer da seguinte forma:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "nome_comprido = \"João Antônio da Silva Sauro de Souza Silva Santos\"\n", + "\n", + "# Contando a quantidade de caracteres deste nome enorme\n", + "print(len(nome_comprido)) # ... agora sim!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "É aqui que começamos a entender a diferença entre métodos e funções. Quando estamos acessando `str.len()` estamos acessando **o método `len` de uma string**, que não existe. O que existe é a **função `len()` que recebe uma string**.\n", + "\n", + "Percebam que não existe `str.len()` na [lista de métodos de uma string](https://docs.python.org/3/library/stdtypes.html#string-methods), e existe a função `len()` na [lista de funções nativas do Python](https://docs.python.org/3/library/functions.html).\n", + "\n", + "Porque `len()` é uma função e não um método de string? De acordo com a definição que foi dada: *métodos são funções que estão associadas a um determinado objeto*. Notem agora que eu consigo medir o comprimento de outras coisas, como uma lista de itens, por exemplo." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8\n" + ] + } + ], + "source": [ + "lista_de_numeros = [10, 50, 40, 65, 90, 70, 30, 156]\n", + "print(len(lista_de_numeros))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ou seja, `len()` é uma função que mede o comprimento de uma dada sequencia qualquer. Como strings são sequencia de caracteres, eu consigo medir o comprimento de uma string unsando a função `len()`. Mas notem que **`len()` não é exclusivo de strings**. Métodos são exclusivos de um determinado tipo de objeto, como é o caso de `str.upper()` ou `str.lower()`.\n", + "\n", + "Conseguiram compreender agora porque usamos `len(string)` e não `string.len()`? Fez sentido?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] } ], "metadata": {