Lezione del 24/3/2014¶
Riassuntino `file`
File 5.1_intro_files.rb
1#!/usr/bin/env ruby
2#-------------------------------------------------------------------------#
3# Esercitazioni in Laboratorio per il Corso di #
4# Fondamenti di Informatica e Calcolo Numerico, AA 2013/2014 #
5# #
6# Autori: Enrico Bertolazzi e Carlos Maximiliano Giorgio Bort #
7# Dipartimento di Ingeneria Industriale, Universita` di Trento #
8# Sito web: http://www.ing.unitn.it/~bertolaz/ #
9# #
10# Contatti: enrico.bertolazzi@unitn.it, cm.giorgiobort@unitn.it #
11# #
12# Copyright (c) 2014 E.Bertolazzi e C.M. Giorgio Bort #
13#-------------------------------------------------------------------------#
14
15
16=begin
17Un File e` un'astrazione di qualsiasi oggetto file accessibile dal programma,
18ed e` associato con la classe IO File la quale include i metodi del modulo
19FileTest come metodi di classe, permettendo di scrivere (per esempio)
20File.exist?("foo")
21=end
22
23
24##########################################
25#### CREAZIONE DI UN FILE ################
26##########################################
27# Posso creare un file mediante il comando:
28nomefile = "testfile.txt"
29
30puts "Creazione e scrittura di file di testo"
31file = File.open( nomefile, "r+")
32# Nota: "w" e` usato per scrivere il file (eventualmente creandolo se non
33# esiste già)
34# "r" e` usato per leggere il file
35# "r+" sia per leggere che per leggere il file
36# "a" per aggiungere linee alla fine del file
37
38# Ci aggiungo stringhe in questo modo
39file.puts "Questa e` una prova"
40
41ary = [123456.654321, 22222.1111, -42421.123]
42file.puts "123.4\tciao\t#{ary}"
43
44
45# E alla fine devo sempre ricordarmi di chiudere il file!
46# Cosi` mi assicuro che tutti i dati bufferizzati sono scritti
47# e che rilascio tutte le risorse computazionali utilizzate.
48file.close
49
50
51##########################################
52#### LETTURA DA FILE #####################
53##########################################
54puts "\nPrimo metodo per leggere i file"
55# In alternativa, Ruby mi permette di fare tutto con un unico comando,
56# un unico BLOCCO. Questa funzione si chiama 'open', ed invece di restituirmi
57# un nuovo 'oggetto' File richiama il blocco definito, passandoci
58# come argomento il nuovo file aperto.
59File.open(nomefile, "r") do |file|
60 file.each do |line|
61 puts line
62 end
63end
64
65# Questa seconda opzione ha pro e contro:
66# pro: se sbaglio a programmare ed il mio codice da un errore mentre scrivo il file,
67# EVITO DI TENERE IL FILE APERTO (non ho bisogno di chiamare il '.close')
68# contro: e` una notazione meno flessibile e devo tenere le operazioni che
69# effettuo sul file in righe di codice tra loro vicine.
70
71puts "\nSecondo metodo per leggere i file"
72# In alternativa, per leggere il file posso usare:
73File.open(nomefile, "r") do |file|
74 while line = file.gets
75 puts line
76 end
77end
78
79
80puts "\nTerzo metodo per leggere i file"
81# Se combino l'idea dell'iteratore nel file,
82# con il secondo metodo di lettura dei file, posso usare 'IO.foreach':
83IO.foreach(nomefile){ |line| puts line }
File 5.2_file_dati.rb
1#-------------------------------------------------------------------------#
2# Esercitazioni in Laboratorio per il Corso di #
3# Fondamenti di Informatica e Calcolo Numerico, AA 2013/2014 #
4# #
5# Autori: Enrico Bertolazzi e Carlos Maximiliano Giorgio Bort #
6# Dipartimento di Ingeneria Industriale, Universita` di Trento #
7# Sito web: http://www.ing.unitn.it/~bertolaz/ #
8# #
9# Contatti: enrico.bertolazzi@unitn.it, cm.giorgiobort@unitn.it #
10# #
11# Copyright (c) 2014 E.Bertolazzi e C.M. Giorgio Bort #
12#-------------------------------------------------------------------------#
13
14#__________________________________________________________________________
15# 1. Leggere il file 'log.txt', e salvare ogni colonna in una hash dove la
16# corrispondente chiave e` ottenuta dall'intestazione del file.
17# Farsi restiuire le chiavi della hash 'dati' e la dimensione della
18# colonna con i dati sul tempo
19#__________________________________________________________________________
20file = 'log.txt'
21
22puts "Caricamento dei dati in #{file}"
23
24# verifico se il file esiste
25esiste = File.exists? file
26raise ArgumentError, "Il file #{file} non esiste" unless esiste
27
28str_frmt = " %.2f |"*9
29str_frmt.chop!
30str_frmt += "\n"
31
32dati = {}
33File.open(file, 'r') do |file|
34
35 intestazione = file.gets.split " "
36 intestazione.each_with_index do |s, i|
37 dati[s.to_sym] = []
38 dati[i] = dati[s.to_sym] # cosi` ho due modi per accedere allo stesso array:
39 # con una chiave o con un indice!
40 end # intestazione.each
41
42 file.each_line do |line|
43 parole = line.split " "
44
45 # stampo a video la stringa letta
46 print str_frmt % parole
47
48 # converto ogni parola nella linea in un Float (numero con la virgola)
49 parole.each_with_index{|s, i| dati[i] << s.to_f}
50 end # file.each...
51end # File.open...
52
53# Siccome non accedero` piu` a 'dati' mediante numeri ma soltanto con i simboli,
54# cancello tutte le coppie chiave-valore le cui chiavi siano interi
55dati.each_key{|k| dati.delete k if k.is_a? Integer}
56
57
58#__________________________________________________________________________
59# 2. Calcolare il valore medio e la deviazione standard di ogni colonna
60# nella hash 'dati'. Trascurare le chiavi della hash 'dati' che sono numeri interi.
61# Per una migliore rappresentazione arrotondare i numeri alla terza cifra significativa
62#__________________________________________________________________________
63puts "Calcolo media e varianza dei dati"
64
65def mean(ary)
66 is_array = ary.is_a? Array
67 is_number = ary.first.is_a? Numeric
68 msg = "Posso calcolare la media solo di un array di numeri"
69 raise ArgumentError, msg unless is_array && is_number
70
71 s = ary.inject(0){|sum, x| sum+x}
72 l = ary.size
73 return s/l
74end
75
76def std(ary)
77 m = mean(ary)
78 l = ary.size
79 sq = ary.inject(0){|sum, x| sum + (x-m)**2}
80 return Math::sqrt(sq/l)
81end
82
83puts "="*40
84dati.each{|k,v| puts "#{k}\t: media #{mean(v).round(3)}, std #{std(v).round(3)}" unless k.is_a? Integer}
85puts "="*40
86
87
88
89
90#__________________________________________________________________________
91# 3. Trasporre la matrice salvata in 'log.txt', salvandola in un file chiamato 'log.trasp.txt'
92#__________________________________________________________________________
93puts "Trasposizione dei dati"
94
95tr_file = File.new('log.trasp.txt', 'w')
96
97dati.each do |k, v|
98 str = k.to_s << " "
99 str << v.inject(){|sum, x| sum.to_s+" "+x.to_s}
100 tr_file.puts str
101end
102
103tr_file.close
File di Log
Problema N.1
Leggere un file ascii che contiene una prima riga di intestazione con i nomi delle colonne. Le successive righe contengono le colonne dei dati. Il file letto va memorizzato in una hash le cui chiavi sono i nomi dello colonne della intestazione.
Una volta letto e memorizzato il file calcolare media e deviazione standard di ogni colonna.
Problema N.2:
Una volta letto il file del problema N.1 trasporre i dati e salvarli su un’altro file. Cioè la prima colonna diventa la prima riga, la seconda colonna diventa la seconda riga e cosi via.
Problema N.3:
Leggere un file ascii, separare i vari paragrafi cioè i blocchi di parole in linee consecutive non contenenti linee vuote. Salvare ogni paragrafo in un vettore e farsi stampare sul terminale il numero di paragrafo il numero di parole che contiene. Compattare (giustificare) ogni paragrafo in modo che riempia al meglio 80 colonne. Salvare su un altro file il file giustificato.