Entradas, Saídas e Análise de DadosLeitura e Escrita de Ficheiros
Pedro BarahonaDI/FCT/UNL
Introdução aos Computadores e à Programação2º Semestre 2008/2009
24 Abril 2009 1Entradas, Saídas e Análise de Dados
24 Abril 2009 Entradas, Saídas e Análise de Dados 2
• Quando a quantidade de dados é grande, não é razoável ou mesmo possível
introduzi-los “manualmente” num programa.
• Tipicamente esses dados são armazenados em ficheiros que têm de ser lidos
pelos programas que os tratam (podendo esses ficheiros estar organizados em
bases de dados mais ou menos complexas)
• As funções básicas de manutenção de ficheiros (criação, alteração e destruição,
localização, acesso ao seu conteúdo, etc.) são definidas no sistema de ficheiros
(file system) , componente do sistema operativo (Operating System - Windows,
Linux, MacOS, ...).
• Todas as linguagens de programação têm acesso a essas funções básicas
(primitivas), implementadas através de chamadas ao sistema, mas que são
disponibilizadas ao nível da linguagem através de instruções próprias.
Armazenamento de Dados
24 Abril 2009 Entradas, Saídas e Análise de Dados 3
• Existe uma grande variedade de formas nessas instruções mas algumas
características são razoavelmente gerais:
• Antes de se escrever ou ler num ficheiro, este tem de ser aberto num modo
apropriado (leitura, escrita, leitura/escrita,...).
• Na abertura de um ficheiro, este é associado a um “canal” com um
identificador (tipicamente um número) único. Todos os acessos ao ficheiro
referem esse valor e não o nome com que o ficheiro é conhecido no
sistema de ficheiros.
• Os acessos de leitura e escrita de dados dos ficheiros dependem da forma
como os dados são codificados. Estes podem ser armazenados como texto
ou numa forma codificada que optimiza o espaço.
• Após todos os acessos pretendidos terem sido executados, um ficheiro
devem ser fechado.
• Como estas operações podem ser muito variadas, vamos centrar-nos nos
acessos a ficheiros texto em OCTAVE.
Armazenamento de Dados
24 Abril 2009 Entradas, Saídas e Análise de Dados 4
• Os ficheiros de entrada e saída, do tipo texto (extensão “.txt”) podem ser,
repectivamente produzidos e lidos em EXCEL, desde que se utilizem as opções
apropriadas no EXCEL quanto ao formato dos ficheiros.
• Tudo o que é necessário fazer é
– guardar o ficheiro em formato: Text (tab delimited) (*.txt)
– Ler o ficheiro em formato : Text files (*.prn; *.txt; *.csv) e usar as opções
• Delimited - Characters such as commas or tabs separate each field.
• Delimiters - Tabs
Ficheiros Texto em EXCEL
188 606.3940 161.35145 396.18...61 196.93139 357.33
data_in.txtA B C
1 188 606.392 40 161.353 145 396.18
29 61 196.9330 139 357.33
dat a_ i n. xl s
24 Abril 2009 Entradas, Saídas e Análise de Dados 5
• Outra opção para os ficheiros de entrada e saída consiste em separar os dados por
vírgulas (“Comma separated values”) em vez de tabs, trabalhando-se com ficheiros
do formato csv (extensão “.csv”)
• Nota: Neste caso há que garantir que o separador decimal é o ponto.
• Tudo o que é necessário fazer é
– guardar o ficheiro em formato: CSV (Comma delimited) (*.csv)
– Ler o ficheiro em formato : Text files (*.prn; *.txt; *.csv)
Ficheiros CSV em EXCEL
188,606.39,40,161.35,145,396.18,...158,421.8461,196.93
data_in.csvA B C
1 188 606.392 40 161.353 145 396.18
29 61 196.9330 139 357.33
dat a_ i n. xl s
24 Abril 2009 Entradas, Saídas e Análise de Dados 6
• Trabalhando-se com formatos de números decimal em que o separador decimal é uma
vírgula, tem de usar-se como separador um outro caracter (por exemplo o ponto-e-
vírgula) e trabalhar-se com ficheiros do formato txt (extensão “.txt”)
• Tudo o que é necessário fazer é
– guardar o ficheiro em formato: Text (tab delimited) (*.txt)
– Ler o ficheiro em formato : Text files (*.prn; *.txt; *.csv) e usar as opções
• Delimited - Characters such as commas or tabs separate each field.
• Delimiters - Semicolon
Ficheiros CSV em EXCEL
188;606,39;40;161,35;145;396,18;...158;421,84;61;196,93;
data_in.txtA B C
1 188 606.392 40 161.353 145 396.18
29 61 196.9330 139 357.33
dat a_ i n. xl s
24 Abril 2009 Entradas, Saídas e Análise de Dados 7
Regressão Linear : Um Exemplo
Exemplo
• Um dado produto é fabricado numa linha de produção por lotes. Os lotes são
encomendados pelos clientes e têm um número variável de exemplares do
produto, de acordo com a ordem do cliente.
• A empresa produtora está interessada em desenvolver um modelo de produção,
de forma a poder prever
– Qual o tempo que demora cada lote a ser produzido
– Quais os lotes que são produzidos em mais ou menos tempo que o esperado,
de forma a poderem ser analisados os factores que facilitam ou dificultam o
fabrico.
• Para fazer esse estudo a empresa detem um histórico da produção de vários lotes
no passado.
24 Abril 2009 Entradas, Saídas e Análise de Dados 8
Regressão Linear : Um Exemplo
• O modelo desenvolvido tem em conta que
– Antes de se começar a produzir o produto é necessário gastar um dado
tempo (t0: tempo de setup) para preparar um conjunto de recursos (por
exemplo, máquinas e instalações).
– Uma vez estabelecida essa preparação o número de peças produzidas é
basicamente proporcional ao tempo, demorando um tempo t1 a fabricar cada
peça.
• Assim parece apropriado um modelo do tipo, em que o tempo T que necessário
para se produzirem P peças é dado por
T = t1 P + t0
• O problema consiste pois em determinar os valores de t0 e t1 a partir dos dados
históricos.
24 Abril 2009 Entradas, Saídas e Análise de Dados 9
Análise de Dados – Regressão Linear
Exemplo
• Este problema é apenas um exemplo de aplicação da técnica de análise de
dados, denominada, regressão linear, que na sua forma geral se pode descrever
por
• Regressão Linear: Dado um conjunto de dados, xi e yi verificar se eles estão
numa relação linear
Y = m X +b
• O problema tem dois subproblemas:
– Determinar os valores de m e b mais apropriados aos valores dos vários
pares de valores xi – yi.
– Avaliar se é razoável assumir a relação linear acima, ou seja, se os pares de
valores <xi, yi> a “suportam” (ou ainda, se existe uma boa correlação linear
entre X e Y).
24 Abril 2009 Entradas, Saídas e Análise de Dados 10
Regressão Linear : Um Exemplo
• Podemos ilustrar esta técnica com dois exemplos gráficos. Os valores de
• m (inclinação da recta); e de
• b (intersecção da recta com o eixo Y)
são idênticos nos dois casos
x
y y
x
X e Y têm uma correlação linear forte
X e Y têm uma correlação linear fraca
24 Abril 2009 Entradas, Saídas e Análise de Dados 11
Determinação dos Parâmetros m e b
• O tratamento matemático para a determinação dos valores de m e b é relativamente
simples.
• Basicamente pretende determinar-se os valores de m e b que minimizem o erro
entre os resultados esperados e os resultados experimentais.
• Para cada ponto xi-yi o erro “experimental” é dado por
ei = yi – (m xi + b)
• O erro E que se pretende minimizar é o erro quadrático médio,
• Assim sendo o problema reduz-se a determinar os valores de m e b que minimizam
o erro E.
n
iieE
1
2
24 Abril 2009 Entradas, Saídas e Análise de Dados 12
Determinação dos Parâmetros m e b
• O mínimo de uma função em relação a uma variável ocorre quando a derivada
dessa função em ordem a essa variável é nula.
• Assim sendo, há que obter os zeros das derivadas (parciais) de E em relação às
incógnitas m e b.
– Nota 1: Assume-se uma função contínua e continuamente derivável, caso
contrário o mínimo pode não ocorrer no zero da derivada.
– Nota 2: A função E tem duas variáveis, m e b. A análise em Rn justifica que o
mínimo deve corresponder ao zero das duas derivadas.
– Nota 3: Como o mínimo de coincide com o mínimo de E, pode minimizar-
se a função F = E2 = ei2
• Assim o problema reduz-se a determinar os valores de m e b que minimizam o erro,
isto é, que garantem bem como
E
0b
F0
m
F
24 Abril 2009 Entradas, Saídas e Análise de Dados 13
Determinação dos Parâmetros m e b
0)(
0)(
0)(2
0)(
02
nbmxy
bmxy
bmxyb
bmxy
b
F
ii
ii
ii
ii
0)(
0)(2
0)(
0
2
2
iiii
iii
ii
bxmxyx
bmxyx
m
bmxy
m
F
• Ora
donde
• Por outro lado
nmxyb ii /)(
24 Abril 2009 Entradas, Saídas e Análise de Dados 14
Determinação dos Parâmetros m e b
nmxyb ii /)(
• Usando agora o valor de b anteriormente encontrado na fórmula anterior, obtemos
22
22
2
2
2
2
2
)(
))((
0
0)()(
0))((
0)/)((
0)(0
ii
iiii
iiiiii
iiiiiii
iiiiii
iiiiii
iiiiii
iiii
xxn
yxyxnmdonde
yxyxnxxnm
xxmyxxmnyxn
mxyxmnxynx
mxyxmnxynx
nmxyxmxyx
bxmxyxm
F
24 Abril 2009 Entradas, Saídas e Análise de Dados 15
• Assim, dados vectores X e Y, com n valores de xi e yi os valores de m e de b
podem ser obtidos através das fórmulas
• Em Octave, estas expressões podem ser calculadas facilmente. Começamos por
definir os vários somatórios envolvidos
Sx = sum(X);
Sy = sum(Y);
Sxx = sum(X.*X);
Syy = sum(Y.*Y);
Sxy = sum(X.*Y);
que são usados nas definições de b e de m
m = (n * Sxy – Sx*Sy) / (n*Sxx – Sx^2)
b = (Sy – m * Sx) / n
Parâmetros m e b em OCTAVE
nmxyb ii /)(
22 )( ii
iiii
xxn
yxyxnm
24 Abril 2009 Entradas, Saídas e Análise de Dados 16
• Para medir a qualidade da relação linear entre X e Y pode usar-se o coeficiente
de correlação r, definido como
• Este coeficiente (cuja derivação exige um maior conhecimento de estatística)
varia entre 1 (correlação perfeita) e 0 (correlação nula).
• O seu valor em OCTAVE pode ser obtido naturalmente através das definições
anteriores
r = (n*Sxy – Sx*Sy) / sqrt((n*Sxx – Sx^2)(n*Syy – Sy^2))
onde
Sx = sum(X); Sy = sum(Y);
Sxx = sum(X.*X); Syy = sum(Y.*Y);
Sxy = sum(X.*Y);
Correlação entre X e Y
2222 )()( iiii
iiii
yynxxn
yxyxnr
24 Abril 2009 Entradas, Saídas e Análise de Dados 17
• Assumamos pois um ficheiro em duas colunas, em que
– A primeira coluna representa o número de peças de cada lote (Pi)
– A segunda coluna, o número de horas necessárias para produzir esse lote (Ti)
Objectivos:
• Ler os dados do ficheiro de entrada;;
• Estabelecer uma relação linear T = t1 P + t0 ; e
• Escrever um ficheiro em 3 colunas em que:
• As duas primeiras colunas são como antes
• A 3ª coluna, representa a diferença entre o tempo estimado e o tempo gasto efectivamente
Entrada / Saída de Dados
188 606.3940 161.35145 396.18...61 196.93139 357.33
data_in.txt
188 606.39 19.51 40 161.35 19.55 145 396.18 -61.39 ... 61 196.93 -8.03 139 357.33 -82.19
data_out.txt
24 Abril 2009 Entradas, Saídas e Análise de Dados 18
• Após a abertura de um ficheiro texto, ele pode ser lido de duas formas básicas:
– Leitura caracter a caracter, sendo tarefa do programador interpretar as
sequências de caracteres como números, palavras, etc...
– Leitura de acordo com determinados padrões (templates) em que existem
primitivas da linguagem que interpretam directamente os caracteres para o tipo
de dados pretendido.
• Por exemplo, assumamos um ficheiro com a sequência “ 23 45.2 ”. Neste
caso podemos
– ler os 11 caracteres e tendo em atenção os espaços interpretar esses
caracteres como dois números (um inteiro e outro decimal).
– Indicar como padrão de leitura um inteiro seguido de um decimal que são
retornados em variáveis indicadas.
Entrada de Dados
24 Abril 2009 Entradas, Saídas e Análise de Dados 19
• O programa abaixo permite ler um ficheiro com duas colunas de dados, para dois
vectores X e Y.
• A instrução fopen abre o ficheiro com o nome “data_in.txt”, em modo de leitura
(argumento“r” - read), e atribui-lhe um ´número de canal ‘fid’, usado posteriormente.
• A instrução fclose fecha o canal com número ‘fid.
Leitura de Ficheiros
[fid,msg] = fopen(“data_in.txt", "r");i = 0; X = zeros(0,1); Y = zeros(0,1);[xi,yi,count] = fscanf(fid,"%i%f",”C”);while !feof(fid) i = i + 1; X(i) = xi; Y(i) = yi; [xi,yi,count] = fscanf(fid,"%i%f",”C”);endwhile;n=i; fclose(fid);
188 606.3940 161.35145 396.18...61 196.93139 357.33
data_in.txt
24 Abril 2009 Entradas, Saídas e Análise de Dados 20
• A instrução [xi,yi,count] = fscanf(fid,"%i%f",”C”) permite ler dados
– do canal de entrada (1º argumento - fid)
– de acordo com um padrão (template - ,"%i%f")
– como na linguagem C (3º argumento – “C”)
– os dados efectivamente lidos são colocados nas variáveis xi e yi
– o seu número é colocado na variável count.
• Neste caso, são lidos 2 números do canal de entrada. O primeiro é um inteiro ("%i") e
o segundo é decimal ("%f").
Leitura de Ficheiros
[xi,yi,count] = fscanf(fid,"%i%f",”C”);xi = 188yi = 606.39count = 2
188 606.3940 161.35145 396.18...61 196.93139 357.33
data_in.txt
24 Abril 2009 Entradas, Saídas e Análise de Dados 21
• Quando não há mais dados para ler, a instrução
[xi,yi,count] = fscanf(fid,"%i%f",”C”)
retorna xi e yi vazios (xi = yi = []) e count = 0.
• Normalmente existe uma função “end of file” para indicar se a última leitura já foi feita
após o fim do ficheiro. Em Octave essa função é expressa por feof(fid).
Leitura de Ficheiros
[xi,yi,count] = fscanf(fid,"%i%f",”C”), F = feof(fid).
count = 2, xi = 88, yi = 248.63, F = 0
[xi,yi,count] = fscanf(fid,"%i%f",2) F = feof(fid).
count = 0, xi = [], yi = [],
F = 1
188 606.3940 161.35145 396.18...61 196.93139 357.33
data_in.txt
24 Abril 2009 Entradas, Saídas e Análise de Dados 22
• Notas:
1. A chamada de fscanf é feita antes do ciclo.
2. A condição de entrada no ciclo é !feof
3. A variável n guarda o número de pontos X e Y lidos.
Leitura de Ficheiros
[fid,msg] = fopen("linear.txt", "r");i = 0; X = zeros(0,1); Y = zeros(0,1);[xi,yi,count] = fscanf(fid,"%i%f",”C”);while !feof(fid) i = i + 1; X(i) = xi; Y(i) = yi; [xi,yi,count] = fscanf(fid,"%i%f",”C”);endwhile;n=i; fclose(fid);
188 606.3940 161.35145 396.18...61 196.93139 357.33
data_in.txt
24 Abril 2009 Entradas, Saídas e Análise de Dados 23
• Uma vez obtidos os vectores X e Y com n pontos, os parâmetros m, b e r da regressão
linear podem ser recalculados.
• Os erros (entre os valores observados e os valores esperados), são guardados no
vector E.
Tratamento dos Dados
sx = sum(X); sy = sum(Y);sxy = sum(X.*Y);syy = sum(Y.*Y);sxx = sum(X.*X);
m = (n*sxy-sx*sy)/(n*sxx-sx^2);b = (sy-m*sx)/n;r = (n*sxy-sx*sy)/sqrt((n*sxx-sx^2)*(n*syy-sy^2));
E = zeros(1,n);for i = 1:n E(i) = Y(i) - (m * X(i) + b);endfor;
24 Abril 2009 Entradas, Saídas e Análise de Dados 24
• Ax e Ay , e portanto As, definem os limites dos eixos dos X e Y (na realidade P – nº de
peças e T – tempo de fabrico).
• Os vários plots destinam-se ao eixo X, os valores X e Y (na forma de pontos – formato
“@)”, a recta de regressão (Y2 tem os dois pontos limites) e finalmente os erros (na
forma de linhas de impulso – formato “^”).
Visualização dos Dados
Ax = [0, max(X)]; Ay = [min(E),max(Y)]; As = [Ax,Ay];Y2 = [m*min(Ax)+b, m*max(Ax)+b];clg; hold on; axis(As);plot(Ax,[0,0],'6');plot(X,Y,'@33');plot(Ax,Y2,'2');plot(X,E,'^1');
24 Abril 2009 Entradas, Saídas e Análise de Dados 25
• O armazenamento de dados num ficheiro segue passos semelhantes. A abertura de
um ficheiro em modo escrita, cria um ficheiro, que pode ser escrito de duas formas
básicas:
– Escrita caracter a caracter, sendo tarefa do programador criar as sequências
adequadas de caracteres para representar números, palavras, etc...
– Escrita de acordo com determinados padrões (templates) disponibilizados por
primitivas da linguagem.
• Por exemplo, para se escreverem os dados 23 e 45.2 ( “ 23 45.2 ”) num
ficheiro, pode-se
– escrever os 11 caracteres sequencialmente, isto é,
‘ ’,‘ ’,‘2’,’3’,‘ ’,‘ ’,‘4’,‘5’,‘.’,’2’,‘ ’
– indicar como padrão de escrita um inteiro (com 4 dígitos, seguido de um
espaço, seguido de um decimal com 5 casas, incluindo uma casa decimal,
seguido de um espaço.
Saída de Dados
24 Abril 2009 Entradas, Saídas e Análise de Dados 26
• As instruções fopen e fclose são semelhantes, mas com modo de escrita (“w” - write).
• A instrução fprintf escreve no canal de saída com identificador fid os 3 valores indicados com formatos
– Inteiro com 5 dígitos (1º dado – X(i))
– Decimal, com 7 casas, das quais duas decimais (2º/3º dado – Y(i) e E(i))
– Separados por espaços (no template) e com mudança de linha (“\n”)
Escrita de Ficheiros
[fid,msg] = fopen("linear_out.txt", "w");for i = 1:n fprintf(fid,"%5i %7.2f %7.2f\n", X(i),Y(i),E(i));endfor;fclose(fid);
188 606.39 19.51 40 161.35 19.55 145 396.18 -61.39 ... 61 196.93 -8.03 139 357.33 -82.19
data_out.txt
24 Abril 2009 Entradas, Saídas e Análise de Dados 27
• As instruções fopen e fclose são semelhantes, mas com modo de escrita (“w” - write).
• A instrução fprintf escreve no canal de saída com identificador fid os 3 valores
indicados, sem comprimento definido dos campos, mas simplesmente separados por
vírgulas.
Escrita de Ficheiros CSV
[fid,msg] = fopen("linear_out.csv", "w");for i = 1:n fprintf(fid,"%i,%f,%f,\n", X(i),Y(i),E(i));endfor;fclose(fid);
188,606.390000,19.512270,40,161.350000,19.547397,145,396.180000,-61.385362, ...61,196.930000,-8.025154,139,357.330000,-82.191776,
data_out.csv