Introdução à programação e aos algoritmos

João Araujo Ribeiro · Capítulo 81 de 103

Páginas do PDF

Introdução à programação e aos algoritmos

6.4 Arquivos

Escreva uma função que receba uma string como parâmetro e diga se se trata de

um palíndromo ou não. Na string devem ser ignorados os espaços em branco e as

letras maiúsculas e minúsculas não são diferenciadas. Por exemplo, a frase ‘Seco

de raiva coloco no colo caviar e doces’ deve ser considerada um palíndromo.

 

EXERCÍCIO 6.8

 

O Programa 6.10 só funciona bem com um nome composto de três partes.

Modi que o programa para que seja possível trabalhar com um número maior de

partes.

 

EXERCÍCIO 6.9

 

Prepare seu programa do exercício anterior para aceitar também nomes

compostos de apenas duas partes.

 

6.4 ARQUIVOS

Você já sabe o que é um arquivo. A maior parte dos arquivos de seu computador possui um formato especial. Sem conhecer os detalhes desse formato é impossível lê-los. Mas existe um tipo de arquivo que você sempre pode ler e até escrever: os arquivos de texto. Não estou falando aqui de arquivos que você usa em um editor de texto complexo, como o Word ou o LibreOffice. Falo de arquivos de texto puro, sem nenhuma formatação. Estes só contêm caracteres.

Com Python você pode processar qualquer tipo de arquivo,

basta conhecer os detalhes de seu formato, mas, precisamos nos concentrar nos textos por serem mais imediatos.

Abrir um arquivo em Python é muito simples:

arquivo = open(nome do arquivo,modo)

O nome do arquivo pode incluir seu caminho completo entre os diretórios. Isso é fonte de confusão muitas vezes, pois os sistemas operacionais usam formas diversas para indicar o caminho nos diretórios (“folders” ou pastas) do computador. Assim, dependendo de como você especificar esse caminho, o programa pode executar corretamente em um sistema operacional (Linux, Windows, MacOS) e apresentar erro em outro.

Os modos podem ser vistos na Tabela 6.2.

 

Tabela 6.2 Modos de abertura de um arquivo

 

Modo Arquivo existe Arquivo não existe

 

‘r’ Aberto para leitura (read) Erro de arquivo inexistente

 

‘w’ Apaga arquivo e abre novo (write) Cria novo arquivo aberto para

escrita

 

‘a’ Abre para acrescentar (append) Cria novo arquivo aberto para

escrita

 

Fato 6.1 – Nomes de arquivos.

O nome de um arquivo é composto de seu nome propriamente dito e de seu “caminho”,

isto é, sua localização dentro do sistema de arquivos. Essa localização não é uma coisa

física, mas é, antes de tudo, uma consequência da organização lógica implementada

pelo sistema operacional. São os sistemas operacionais que vão determinar como os

arquivos são organizados e acessados.

Se em um passado recente todos os arquivos eram armazenados em discos, hoje

em dia cada vez mais vemos dispositivos eletrônicos sendo usados para este m, como

os pen-drives e unidades SSD.

Atualmente, existem duas principais “famílias” de sistemas operacionais:

Windows e UNIX.

Na família Windows, a mais difundida entre os usuários domésticos, o sistema de

arquivos divide seus componentes em unidades lógicas. Assim, e você já deve estar

acostumado, seu disco é dividido em unidades lógicas designadas por letras como C:,

D:, E: e assim por diante. O nome completo do arquivo, que inclui seu caminho, é

determinado pelo nome da unidade lógica seguido pelos nomes de todas as “pastas”

(também chamadas de “folders” ou “diretórios”) separadas por uma barra (\). Por

exemplo, um arquivo de nome dados.txt poderia ter um nome completo como C:\usuario\documentos\dados.txt.

No Windows, outra característica é que os nomes de arquivos são insensíveis ao

uso de maiúsculas e minúsculas. Tanto faz chamar o arquivo dados.txt,

DADOS.TXT, Dados.txt ou qualquer combinação possível. Todos esses

nomes se referem ao mesmo arquivo. O mesmo vale para as letras que designam as

unidades lógicas: c: e C: referem-se à mesma unidade.

Na família UNIX, que inclui o Linux e MacOS, os arquivos são colocados em uma

árvore de diretórios, não havendo o conceito de unidades lógicas como no Windows. A

barra usada também é contrária à do Windows (/). Existe um diretório chamado de

“raiz” no qual serão “montados” todos os outros. Montar, no jargão de Unix, é colocar

uma unidade de armazenamento de arquivos na árvore de diretórios do sistema operacional. Um nome completo de arquivo seria por exemplo /home/araujo/dados.txt. Os nomes são sensíveis a maiúsculas e minúsculas. O arquivo dados.txt é diferente de Dados.txt.

Outra característica dos sistemas baseados no Unix é que as extensões de 3 letras

ao nal do nome não determinam o tipo de arquivo. Um arquivo pode ter nome

dados e ainda assim ser um arquivo de texto.

Se você lê ou escreve em um arquivo que esteja na mesma pasta de seu programa

Python, não terá de colocar seu caminho completo. Você também pode usar caminhos

relativos. Um arquivo que esteja na pasta textos que está dentro da pasta do seu programa pode ser acessado por textos/dados (Linux) ou textos\dados.txt (Windows).

Não dá para esgotar aqui tudo sobre as características dos sistemas de arquivos.

Mas o essencial está apresentado.

 

Sempre que abrir um arquivo, ao fim de sua utilização, lembre-se de fechá-lo. Normalmente as consequências do esquecimento de fechar um arquivo, especialmente aqueles abertos para leitura, não são graves, mas é bom fazê-lo sempre. Fechar um arquivo permite liberar a memória associada ao arquivo e garante que todos os dados sejam gravados, no caso de arquivos abertos para escrita (‘w’ e ‘a’). O comando para fechar um arquivo, que deve estar aberto para não ocasionar erro, é:

arquivo.close()

Para ler, usa-se o comando readlines() que lê um arquivo texto para dentro de uma lista. Cada elemento da lista é uma linha do arquivo. Um inconveniente é que cada linha virá com um caractere ‘\n’ (nova linha) ao final. Então, muitas vezes, é necessário livrar-se desse caractere extra.

Vamos trabalhar com um arquivo pequeno, nomes.txt. Este arquivo tem apenas 3 linhas. Para executar os programas desta seção, abra um editor de textos puro, não serve Word ou LibreOffice, e escreva alguns nomes, cada um em uma linha, e salve com o nome nomes.txt. No meu caso, o arquivo tem apenas 3 linhas, cada uma com o nome de um cientista da computação:

Niklaus Wirth

John von Neumann

Dennis Ritchie

No Programa 6.12 usamos readlines() para ler o arquivo para

uma lista chamada linhas e depois usamos a interação sobre a lista da maneira usual para imprimir cada linha lida.

arquivo = open(‘nomes.txt’, ‘r’)

linhas = arquivo.readlines()

arquivo.close()

for linha in linhas:

print(linha)

 

■ Programa 6.12: Programa que lê arquivo com readlines().

 

O resultado:

Niklaus Wirth

John von Neumann

Dennis Ritchie

Observe que as linhas impressas ficaram separadas por uma

linha vazia extra que não consta do arquivo original. Isso aconteceu porque não filtrei o caractere de nova linha ao fim de cada linha.

Para corrigir isso, podemos criar a lista por compreensão.

Lembra? (Seção 5.4). O que vamos fazer é criar uma lista a partir da lista criada por readlines(), porém filtrando o caractere ‘\n’ ao final de cada uma.

Para retirar esse caractere podemos usar a função rstrip().

Como vimos, strip() é uma função que devolve uma cópia de uma string retirando os caracteres de espaço. A função rstrip() é um parente próximo, mas só retira os caracteres de espaço que estejam no final da string (\n). Veja no Programa 6.13.

1 arquivo = open(‘nomes.txt’, ‘r’)

2 linhas = [linha.rstrip() for linha in arquivo.rea

dlines()]

3 arquivo.close()

4 for linha in linhas:

5 print (linha)

■ Programa 6.13: Programa que lê arquivo com readlines() e

rstrip().

 

O resultado é que cada linha perdeu seu caractere de nova linha e a impressão fica bem melhor:

Niklaus Wirth

John von Neumann

Dennis Ritchie

Uma terceira forma seria ler o arquivo inteiro para uma string. Isso é possível com a função read().

1 arquivo = open(‘nomes.txt’, ‘r’)

2 texto = arquivo.read()

3 arquivo.close()

4 print (‘Imprimindo linhas de texto’) 5 print(texto)

6 linhas = texto.split(‘\n’)

7 print (‘Imprimindo linhas (read com split)’) 8 for linha in linhas:

9 print (linha)

 

■ Programa 6.14: Programa que lê arquivo com read().

 

Neste exemplo, na linha 2 o arquivo é lido inteiro para uma string chamada texto. Veja como a impressão de nomes apresenta exatamente o texto do arquivo. Logo em seguida, na linha 6, usamos a função split() para dividir a string usando o caractere de nova linha ( \n) como delimitador. Essa função irá devolver uma lista em que cada elemento é uma linha, porém sem o caractere de nova linha.

O resultado da execução do programa é:

Imprimindo linhas de texto

Niklaus Wirth

John von Neumann

Dennis Ritchie

Imprimindo linhas (read com split)

Niklaus Wirth

John von Neumann

Dennis Ritchie

Uma última forma seria processar o arquivo diretamente,

percorrendo seu conteúdo e processando uma linha por vez, sem passar por uma lista de linhas. Obviamente, como a lista de linhas não está guardada, o programa só pode processar o arquivo uma vez sem precisar voltar ao início de tudo. O arquivo só deve ser fechado nesse caso depois de a última linha ter sido processada.

arquivo = open(‘nomes.txt’, ‘r’)

for linha in arquivo:

print (linha.rstrip())

arquivo.close()

 

■ Programa 6.15: Programa que lê arquivo e processa

imediatamente cada linha.

 

O uso de rstrip() serve para evitar linhas vazias entre cada

impressão.

 

EXERCÍCIO 6.10

 

Escreva um programa que converta todas as letras de um arquivo em maiúsculas e

escreva o resultado na tela.

 

EXERCÍCIO 6.11

 

Escreva um programa que converta todas as letras de um arquivo em minúsculas e

escreva o resultado na tela.

 

EXERCÍCIO 6.12