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

log.txt

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.