extcsv 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2009, Ralf Mueller (stark.dreamdetective@googlemail.com)
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+
14
+ * The names of its contributors may not be used to endorse or promote
15
+ products derived from this software without specific prior written
16
+ permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/gemspec CHANGED
@@ -2,7 +2,8 @@ require 'rubygems'
2
2
 
3
3
  spec = Gem::Specification.new do |s|
4
4
  s.name = "extcsv"
5
- s.version = "0.10.0"
5
+ s.version = "0.11.0"
6
+ s.date = Time.new.to_s
6
7
  s.author = "Ralf Mueller"
7
8
  s.email = "stark.dreamdetective@gmail.com"
8
9
  s.homepage = "http://extcsv.rubyforge.org"
@@ -10,11 +11,8 @@ spec = Gem::Specification.new do |s|
10
11
  s.platform = Gem::Platform::RUBY
11
12
  s.summary = "Let CSV-like files behave like DB-tables: selection, data operations on columns. \n" +
12
13
  "Easy plotting with gnuplot and modelling"
13
- candidates = Dir.glob("lib/*.rb") + ["rakefile","gemspec"]
14
- s.files = candidates.delete_if do |item|
15
- item.include?("pkg") || item.include?("rdoc") || item.include?("extcsv_diagram.rb") || item.include?("extcsv_units.rb")
16
- end
17
- s.test_files = (Dir.glob("test/test_*.rb") + Dir.glob("test/data/*.{csv,txt}")).delete_if {|item| item.include?("test_extcsv_diagram.rb")}
14
+ s.files = Dir.glob("lib/*.rb") + ["rakefile","gemspec","LICENSE"]
15
+ s.test_files = Dir.glob("test/test_*.rb") + Dir.glob("test/data/*.{csv,txt}")
18
16
  s.has_rdoc = true
19
17
  end
20
18
 
data/lib/extcsv.rb CHANGED
@@ -1,27 +1,44 @@
1
- require 'rubygems'
2
1
  require 'csv'
3
2
  require 'ostruct'
4
3
 
5
- ################################################################################
6
- # Author:: Ralf Mueller
7
- ################################################################################
8
4
  class Nil
9
5
  def to_s; ''; end
10
6
  def to_a; []; end
11
7
  def empty?; true; end
12
8
  end
13
9
 
10
+ class Array
11
+ def complement(other)
12
+ (self - other) + (other - self)
13
+ end
14
+ end
15
+
16
+ # = CSV-like Data processing made easy
17
+ # (see project page: http://rubyforge.org/projects/extcsv)
18
+ #
19
+ # The extcsv package should enable you to navigate and operate on csv-like data
20
+ # as easy and comfortable as possible. The main restriction is, that the
21
+ # columns are named, i.e. the first line of a data file has to contain a header with string-like entries.
22
+ #
23
+ # Data can be read from files, strings, hashes or arrays.
24
+ #
25
+ # Have a look at my other projects for
26
+ # correlation[http://extcsv.rubyforge.org/correlation] and {spectral filtering}[http://extcsv.rubyforge.org/spectralfilter].
27
+ #
28
+ # ==== Author: Ralf M�ller
29
+ # ==== License: BSD - see {license file}[http:/extcsv.rubyforge.org/svn/extcsv/trunk/LICENSE]
30
+ ################################################################################
14
31
  class ExtCsv < OpenStruct
15
- VERSION = '0.10.0'
32
+ VERSION = '0.11.0'
16
33
 
17
34
  include Comparable
18
35
  include Enumerable
19
36
 
20
37
  # Allowed data types
21
- TYPES = %w{csv tsv psv txt plain}
38
+ TYPES = %w{csv ssv tsv psv txt plain}
22
39
 
23
40
  # Allowed input modes, db and url are not supported, yet
24
- MODES = %w{file db url hash array string}
41
+ MODES = %w{file hash array string}
25
42
 
26
43
  # column names from different file type, which that have the same
27
44
  # meaning
@@ -84,9 +101,10 @@ class ExtCsv < OpenStruct
84
101
 
85
102
  def set_separators(obj_hash)
86
103
  obj_hash[:cellsep] = case obj_hash[:datatype]
87
- when "txt","tsv": "\t"
88
- when "csv": ';'
89
- when "psv": "|"
104
+ when "txt","tsv" then "\t"
105
+ when "ssv" then ';'
106
+ when "csv" then ','
107
+ when "psv" then "|"
90
108
  end
91
109
  obj_hash[:rowsep] = "\r\n"
92
110
  end
@@ -105,14 +123,15 @@ class ExtCsv < OpenStruct
105
123
  # * '+' and '-' are changed into the correspondig words
106
124
  # * empty lines are removed
107
125
  # * dots are changed into underscores for columns names
126
+ # * commas are converteed into dots (german number notation) unless the commy is the cell separator
108
127
  # * the greek sign � is changes into mu
109
128
  def parse_content(filecontent,obj_hash)
110
129
  content = []
111
- # special treatement of emission/bloostblank data switch decimal sign
112
- filecontent = filecontent.gsub(',','.')
130
+ # convert numbers into us. notation if this doesn't crashes with the columns separator
131
+ filecontent = filecontent.gsub(',','.') unless obj_hash[:datatype] == "csv"
113
132
  # remove blank lines
114
133
  filecontent = filecontent.gsub(/\r\r/,"\r").gsub(/(\r\n){2,}/,"\r\n").gsub(/\n{2,}/,"\n")
115
- csv = CSV::StringReader.parse(filecontent, obj_hash[:cellsep])#, obj_hash[:rowsep])
134
+ csv = CSV.parse(filecontent, :col_sep => obj_hash[:cellsep])#, obj_hash[:rowsep])
116
135
 
117
136
  # read @datatype specific header
118
137
  header = csv.shift
@@ -121,19 +140,19 @@ class ExtCsv < OpenStruct
121
140
 
122
141
  header.each_with_index {|key,i|
123
142
  key = "test" if key.nil?
124
- header[i] = key.downcase.tr(' ','').tr('"','').tr('�',"ue").tr('�',"ae")\
125
- .tr('�',"oe").gsub(/\[\w*\]/,"")\
126
- .tr('�',"ue").gsub(/^\+/,"plus_")\
127
- .gsub('�m','mu')\
128
- .gsub(/^-/,"minus_").tr('-','_').tr('+','_').gsub(/(\(|\))/,'_').tr('.','_').chomp
143
+ header[i] = key.downcase.tr(' ','').tr('"','')\
144
+ .gsub(/\[\w*\]/,"")\
145
+ .gsub(/^\+/,"plus_").gsub(/^-/,"minus_")\
146
+ .tr('-','_').tr('+','_')\
147
+ .gsub(/(\(|\))/,'_').tr('.','_').chomp
129
148
  }
130
149
  content << header
131
150
  # read the data itself
132
- csv.each {|row| content << row if row.to_a.nitems > 0 }
151
+ csv.each {|row| content << row if row.to_a.delete_if(&:nil?).size != 0 }
133
152
 
134
153
  # further processing according to the input type
135
154
  case obj_hash[:datatype]
136
- when "csv"
155
+ when "csv","ssv","psv","txt","tsv"
137
156
  # check if rows have the same lenght
138
157
  contents_size = content.collect {|row| row.size}
139
158
  content.each_with_index {|row,i|
@@ -217,7 +236,7 @@ class ExtCsv < OpenStruct
217
236
  # ATTENTION: DO NOT MIX THE USAGE OF STRING AND SYMBOLS!
218
237
  # This can lead to a data loss, because e.g. {:k => 4, "k" => 3} will be
219
238
  # transformed into {:k=>3}
220
- selection.each_key {|k|
239
+ selection.keys {|k|
221
240
  if k.kind_of?(String)
222
241
  v = selection.delete(k)
223
242
  selection[k.to_sym] = v
@@ -228,7 +247,7 @@ class ExtCsv < OpenStruct
228
247
  vars.each {|attribute|
229
248
  unless @table.has_key?(attribute)
230
249
  $stdout << "Object does NOT hav the attribute '#{attribute}'!"
231
- raise
250
+ raise
232
251
  end
233
252
  }
234
253
  # default is the lookup in the whole array of values for each var
@@ -346,7 +365,11 @@ class ExtCsv < OpenStruct
346
365
  # columns in order of these columns, e.g.
347
366
  # [[col0_val0,col1_val0,...],...,[col0_valN, col1_valN,...]]
348
367
  def datasets(*columns)
349
- retval = []
368
+ retval = []
369
+
370
+ # preset the selected columns to select
371
+ columns = datacolumns if columns.empty?
372
+
350
373
  columns.each {|col| retval << @table[col.to_sym]}
351
374
  retval.transpose
352
375
  end
@@ -441,6 +464,7 @@ class ExtCsv < OpenStruct
441
464
  # each_obj iterates over the subobject of the receiver, which belong to the
442
465
  # certain value of key
443
466
  def each_obj(key, &block)
467
+ key = key.to_sym
444
468
  retval = []
445
469
  send(key).sort.uniq.each {|value|
446
470
  retval << selectBy(key => value)
@@ -454,17 +478,17 @@ class ExtCsv < OpenStruct
454
478
 
455
479
  # :call-seq:
456
480
  # split.(:col0,...,:colN) {|obj| ...}
457
- # splot.(:col0,...,:coln) -> [obj0,...,objM]
481
+ # split.(:col0,...,:coln) -> [obj0,...,objM]
458
482
  #
459
483
  # split is a multi-key-version of each_obj. the receiver is splitted into
460
484
  # subobject, which have constant values in all given columns
461
485
  #
462
486
  # eg.
463
- # <tt>qpol.split(:kv, :focus) {|little_qp| little_qp.kv == little_kv.uniq}</tt>
487
+ # <tt>obj.split(:kv, :focus) {|little_obj| little_obj.kv == little_kv.uniq}</tt>
464
488
  #
465
489
  # or
466
490
  #
467
- # <tt>qpol.split(:kv, :focus) = [qpol_0,...,qpol_N]</tt>
491
+ # <tt>obj.split(:kv, :focus) = [obj_0,...,obj_N]</tt>
468
492
  def split(*columns, &block)
469
493
  retval = []
470
494
  deep_split(columns, retval)
@@ -539,45 +563,44 @@ class ExtCsv < OpenStruct
539
563
  end
540
564
  end
541
565
 
542
- # Equality if the datacolumns have the save values,i.e. as float for numeric
566
+ # Equality if the datacolumns have the save values, i.e. as float for numeric
543
567
  # data and as strings otherwise
544
- # the time-column is exceptional, because the e.g. the seconds could be left
545
- # out when file is saved with MSExcel
546
568
  def eql?(other)
547
- return false unless (
548
- self.datatype == other.datatype or self.datatype == other.datatype
549
- )
550
-
551
- omitted = %w|bfe_vers version zeit time|
552
- return false unless self.datacolumns == other.datacolumns
553
-
554
- # split between textual and numeric values
555
- text_columns = %w|anlage kommentar dateiname| & self.datacolumns
556
- num_columns = self.datacolumns - text_columns - omitted
557
- text_columns.each {|c| return false if send(c) != other.send(c)}
558
- num_columns.each {|c|
559
- a_ = send(c)
560
- a__ = a_.collect {|v| v.to_f}
561
- b_ = other.send(c)
562
- b__ = b_.collect {|v| v.to_f}
563
- #$stdout << c << "\n" << filename << "\n";
564
- #$stdout << c << "\n" << other.filename << "\n";
565
- return false if (b__ != a__)
566
- #if (send(c).collect {|v| v.to_f} != other.send(c).collect {|v| v.to_f})}
567
- }
569
+ return false unless ( self.datatype == other.datatype or self.datatype == other.datatype)
570
+
571
+ return false unless self.datacolumns.sort == other.datacolumns.sort
572
+
573
+ datacolumns.each {|c| return false unless send(c) == other.send(c) }
574
+
568
575
  return true
569
576
  end
570
577
 
578
+ def diff(other)
579
+ diffdatatype = [self.datatype, other.datatype]
580
+ return diffdatatype unless diffdatatype.uniq.size == 1
581
+
582
+ diffdatacolums = self.datacolumns.complement(other.datacolumns)
583
+ return [self.diffdatacolums,other.datacolumns] unless diffdatacolums.empty?
584
+
585
+ datacolumns.each {|c|
586
+ diffcolumn = send(c).complement(other.send(c))
587
+ return diffcolumn unless diffcolumn.empty?
588
+ }
589
+ end
590
+
571
591
  def <=>(other)
572
592
  compare = (self.size <=> other.size)
573
- #test $stdout << compare.to_s << "\n"
593
+ #$stdout << compare.to_s << "\n"
574
594
  compare = (datacolumns.size <=> other.datacolumns.size) if compare.zero?
575
- #test $stdout << compare.to_s << "\n" if compare.zero?
595
+ #$stdout << compare.to_s << "\n"# if compare.zero?
596
+ #compare = (self.datasets(* self.datacolumns.sort) <=> other.datasets(* other.dataacolumns.sort)) if compare.zero?
597
+ #$stdout << compare.to_s << "\n"# if compare.zero?
576
598
  compare = (to_s.size <=> other.to_s.size) if compare.zero?
577
- #test $stdout << compare.to_s << "\n" if compare.zero?
599
+ #
600
+ #$stdout << compare.to_s << "\n" if compare.zero?
578
601
  compare = (to_s <=> other.to_s) if compare.zero?
579
- #test $stdout << compare.to_s << "\n" if compare.zero?
580
- #test $stdout << "##################################\n"
602
+ #$stdout << compare.to_s << "\n" if compare.zero?
603
+ #$stdout << "##################################\n"
581
604
  compare
582
605
  end
583
606
 
@@ -612,8 +635,8 @@ class ExtCsv < OpenStruct
612
635
  when 1
613
636
  hash = marshal_dump.merge(other.marshal_dump)
614
637
  else
615
- if datatypes.include?("csv")
616
- csv_index = datatypes.index("csv")
638
+ if datatypes.include?("ssv") or datatypes.include?("csv")
639
+ csv_index = datatypes.index("ssv") || datatypes.index("csv")
617
640
  qpol_index = csv_index - 1
618
641
  objects[csv_index].modyfy_time_column
619
642
  hash = objects[csv_index].marshal_dump.merge(objects[qpol_index].marshal_dump)
@@ -654,7 +677,7 @@ class ExtCsv < OpenStruct
654
677
  def ExtCsv.combine(obj, obj_=nil)
655
678
  obj.combine(obj_)
656
679
  end
657
- private :deep_copy, :set_separators, :parse_content
680
+ private :deep_copy, :deep_split, :set_separators, :parse_content, :change_time_format
658
681
  end
659
682
 
660
683
  class ExtCsvExporter
@@ -0,0 +1,201 @@
1
+ require 'rubygems'
2
+ require 'gnuplot'
3
+ require 'win32ole' if RUBY_PLATFORM =~ /(win32|cygwin)/i
4
+ require 'extcsv_units'
5
+
6
+ # This module provides separate plotting methods
7
+ module ExtCsvDiagram
8
+ include ExtCsvUnits
9
+ GRAPH_OPTIONS = {
10
+ :type => "linespoints",
11
+ :linewidth => "1",
12
+ :terminal => 'x11',
13
+ :size => nil,
14
+ :filename => nil,
15
+ :title => nil,
16
+ :label_position => "left",
17
+ :label? => true,
18
+ :grid => true,
19
+ :xrange => nil,
20
+ :yrange => nil,
21
+ :x2range => nil,
22
+ :y2range => nil,
23
+ :y1limit => nil,
24
+ :y2limit => nil,
25
+ :using => nil,
26
+ :datasets => {:using => []},
27
+ :logscale => nil,
28
+ :add_settings => [],
29
+ :point_label? => false,
30
+ :time_format => '"%d.%m\n%H:%M:%S"'
31
+ }
32
+ @@timeColumns = %w[time time_camera zeit]
33
+
34
+ def ExtCsvDiagram.set_pointlabel(obj, plot, x_col, x, y, label_col=nil, size='10')
35
+ timemode = (%w[zeit zeitstempel time timestamp].include?(x_col.to_s))
36
+ x.each_index {|i|
37
+ point = (timemode) ? "\"#{x[i].to_s}\"" : x[i].to_s
38
+ point += ",#{y[i].to_s}"
39
+ unless label_col.nil?
40
+ label = obj.send(label_col)[i]
41
+ else
42
+ label = point
43
+ end
44
+ plot.label "'#{label}' at #{point} font 'Times,#{size}' offset 1,1"
45
+ }
46
+ end
47
+
48
+ def ExtCsvDiagram.set_limit(plot,x,xIsTime,axes,limit,limitname,options)
49
+ if xIsTime
50
+ xmin, xmax = [x.min,x.max]
51
+ using = '1:3'
52
+ else
53
+ xtof = x.collect {|v| v.to_f}
54
+ xmin, xmax = [xtof.min,xtof.max]
55
+ using = '1:2'
56
+ end
57
+ plot.data << Gnuplot::DataSet.new([
58
+ [xmin,xmax],
59
+ [limit,limit]
60
+ ]) {|ds|
61
+ ds.with = "lines axes #{axes} lw #{options[:linewidth]}"
62
+ ds.title = limitname.nil? ? '' : limitname
63
+ ds.using = using
64
+
65
+ }
66
+ end
67
+
68
+ def ExtCsvDiagram.enhanceTitleByGroup(group_by,ob)
69
+ title = ''
70
+ group_by.each {|col|
71
+ colunit = Units[col.to_sym].nil? ? col.to_s : "[#{Units[col.to_sym]}]"
72
+ name = [ob.send(col)[0],colunit]
73
+ title += (col.to_sym == :focus) ? name.reverse.join('') : name[0]
74
+ title += " " unless col == group_by.last
75
+ }
76
+ title
77
+ end
78
+
79
+ def ExtCsvDiagram.plot(obj,
80
+ group_by, # array[col0, ..., colN]
81
+ x1_col,
82
+ y1_cols,
83
+ x2_col=nil,
84
+ y2_cols=[],
85
+ title='',
86
+ options={})
87
+
88
+ options = GRAPH_OPTIONS.merge(options)
89
+ outputfilename = (options[:filename].nil?) ? obj.filename : options[:filename]
90
+ Gnuplot.open {|gp|
91
+ Gnuplot::Plot.new(gp) {|plot|
92
+ plot.title "'" + title + "'"
93
+ plot.key options[:label_position]
94
+ plot.key 'off' unless options[:label?]
95
+ if options[:terminal] != 'x11'
96
+ size = (options[:size].nil?) ? '' : " size #{options[:size]}"
97
+ plot.terminal options[:terminal] + size
98
+ plot.output outputfilename + "." + options[:terminal].split(" ")[0]
99
+ end
100
+
101
+ plot.grid if options[:grid]
102
+
103
+ options[:add_settings].each {|setting|
104
+ md = /^(\w+)/.match(setting)
105
+ plot.set(md[1],md.post_match) unless md.nil?
106
+ }
107
+
108
+ # handling of axes
109
+ plot.y2tics 'in' unless ( y2_cols.nil? or y2_cols.empty? )
110
+ plot.x2tics 'in' unless ( (x2_col.respond_to?(:empty?) and x2_col.empty?) or x2_col == nil)
111
+
112
+ plot.xrange options[:xrange] unless options[:xrange].nil?
113
+ plot.yrange options[:yrange] unless options[:yrange].nil?
114
+ plot.x2range options[:x2range] unless options[:x2range].nil?
115
+ plot.y2range options[:y2range] unless options[:y2range].nil?
116
+ plot.xlabel options[:xlabel] unless options[:xlabel].nil?
117
+ plot.ylabel options[:ylabel] unless options[:ylabel].nil?
118
+ plot.x2label options[:x2label] unless options[:x2label].nil?
119
+ plot.y2label options[:y2label] unless options[:y2label].nil?
120
+
121
+
122
+ if @@timeColumns.include?(x1_col.to_s)
123
+ plot.xdata 'time'
124
+ plot.timefmt '"%Y-%m-%d %H:%M:%S"'
125
+ plot.format 'x ' + options[:time_format]
126
+ end
127
+ if @@timeColumns.include?(x2_col.to_s)
128
+ plot.x2data 'time'
129
+ plot.timefmt '"%Y-%m-%d %H:%M:%S"'
130
+ plot.format 'x2 ' + options[:time_format]
131
+ end
132
+
133
+ # Data for first x-axes
134
+ obj.split(*group_by) {|ob|
135
+ y1_cols.each {|y_col|
136
+ x = ob.send(x1_col)
137
+ y = ob.send(y_col)
138
+ title = enhanceTitleByGroup(group_by,ob)
139
+ plot.data << Gnuplot::DataSet.new([x,y]) {|ds|
140
+ unit = Units[y_col.to_sym].nil? ? '' : "[#{Units[y_col.to_sym]}]"
141
+ ds.using = @@timeColumns.include?(x1_col.to_s) ? '1:3' : '1:2'
142
+ ds.with = options[:type] + " axes x1y1 lw #{options[:linewidth]}"
143
+ ds.title = options[:onlyGroupTitle] ? "#{title}" : "#{y_col} #{unit}, #{title}"
144
+ }
145
+
146
+ # set labels if requested
147
+ set_pointlabel(ob,plot, x1_col, x,y, options[:label_column],options[:label_fsize]) if options[:point_label?]
148
+
149
+ }
150
+ y2_cols.each {|y_col|
151
+ x = ob.send(x1_col)
152
+ axes = "x1y2"
153
+ unless ( (x2_col.respond_to?(:empty?) and x2_col.empty?) or x2_col == nil)
154
+ x = ob.send(x2_col)
155
+ axes = "x2y2"
156
+ end
157
+ title = enhanceTitleByGroup(group_by,ob)
158
+ y = ob.send(y_col)
159
+ plot.data << Gnuplot::DataSet.new([x,y]) {|ds|
160
+ unit = Units[y_col.to_sym].nil? ? '' : "[#{Units[y_col.to_sym]}]"
161
+ ds.using = ( (/x2/.match(axes) and @@timeColumns.include?(x2_col.to_s)) or (/x1/.match(axes) and @@timeColumns.include?(x1_col.to_s)) ) ? '1:3' : '1:2'
162
+ ds.with = options[:type] + " axes #{axes} lw #{options[:linewidth]}"
163
+ ds.title = "#{y_col} #{unit}, #{title}"
164
+ }
165
+ # set labels if requested
166
+ set_pointlabel(ob,plot, (axes == "x2y2") ? x2_col : x1_col, x,y, options[:label_column],options[:label_fsize]) if options[:point_label?]
167
+ }
168
+ }
169
+ # show limits for each y-axes
170
+ unless y1_cols.empty?
171
+ if options[:y1limits].kind_of?(Array)
172
+ x = obj.send(x1_col)
173
+ options[:y1limits].each {|limit| set_limit(plot,
174
+ x,
175
+ @@timeColumns.include?(x1_col.to_s),
176
+ "x1y1",
177
+ limit,
178
+ options[:y1limitname],
179
+ options)}
180
+ end
181
+ end
182
+ unless y2_cols.empty?
183
+ if options[:y2limits].kind_of?(Array)
184
+ xcol, axes = x2_col.to_s.empty? ? [x1_col,"x1y2"] : [x2_col,"x2y2"]
185
+ x = obj.send(xcol)
186
+ options[:y2limits].each {|limit| set_limit(plot,
187
+ x,
188
+ @@timeColumns.include?(xcol.to_s),
189
+ axes,
190
+ limit,
191
+ options[:y2limitname],
192
+ options)}
193
+ end
194
+ end
195
+ }
196
+ }
197
+ end
198
+
199
+ def ExtCsvDiagram.multiplot()
200
+ end
201
+ end
@@ -0,0 +1,26 @@
1
+ ################################################################################
2
+ # Author: Ralf M�ller
3
+ #
4
+ # ==== TODO: Units are automatically selected from the column name. You could add
5
+ # units here and they will be used for graphs. I think, this is a premature
6
+ # solution, because the file will be edited by nearly every user, so it
7
+ # actually is a configutration file. But without units, the graphs loose much
8
+ # of their information. There are separate packages for units like
9
+ # units.rubyforge.org. But there will allways be the problem, that column names
10
+ # cannot be restricted to find a appropriate unit.
11
+ ################################################################################
12
+ module ExtCsvUnits
13
+ Units =
14
+ {
15
+ :col1 => "kV",
16
+ :col2 => "kV",
17
+ :col3 => "kV",
18
+ :col4 => "kV",
19
+ :col5 => "kV",
20
+ :col6 => "kV",
21
+ :col7 => "kV",
22
+ :col8 => "kV",
23
+ :zeit => "yyyy-mm-dd hh:mm:ss",
24
+ :time => "yyyy-mm-dd hh:mm:ss"
25
+ }
26
+ end
data/lib/lsmodel.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'matrix'
2
2
  require 'mathn'
3
3
 
4
- # Modelling funtionality with the least square mathod
4
+ # Modelling funtionality with the least square method
5
5
  module LSModel
6
6
  MINIMAL_VARIATION_SIZE = 8
7
7
 
data/rakefile CHANGED
@@ -61,7 +61,7 @@ end
61
61
 
62
62
  # ====================================================================
63
63
  desc "Build package for further developement"
64
- task :build_dev do
64
+ task :build_dev do
65
65
  files = SPEC.files + Dir.glob("test/data/*")
66
66
  #require 'pp'; pp files;end
67
67
  com = "tar czf pkg/#{SPEC.name}-#{SPEC.version}-src.tgz #{files.join(" ")}"
@@ -69,12 +69,12 @@ task :build_dev do
69
69
  end
70
70
  # ====================================================================
71
71
  desc "Install the Library with docs"
72
- task :install do
72
+ task :install => [:repackage] do
73
73
  command = "gem install pkg/#{SPEC.name}-#{SPEC.version}.gem"
74
74
  puts command
75
75
  system(command)
76
76
  end
77
- task :smallInstall do
77
+ task :smallInstall => [:repackage] do
78
78
  command = "gem install pkg/#{SPEC.name}-#{SPEC.version}.gem --no-ri --no-rdoc"
79
79
  puts command
80
80
  system(command)
@@ -99,7 +99,7 @@ Rake::RDocTask.new("rdoc") { |rdoc|
99
99
  rdoc.rdoc_dir = 'rdoc'
100
100
  rdoc.title = "extcsv - Make csv-like Data feel ike DB-tables"
101
101
  rdoc.options << '-ad' << '--line-numbers' << '--inline-source'
102
- rdoc.rdoc_files.include('lib/**/*.rb', 'doc/**/*.rdoc')
102
+ rdoc.rdoc_files = SPEC.files - SPEC.test_files
103
103
  }
104
104
 
105
105
  ############################################################
data/test/data/file00.txt CHANGED
File without changes
data/test/data/file01.txt CHANGED
File without changes
data/test/data/file02.txt CHANGED
File without changes
data/test/data/file03.txt CHANGED
File without changes
data/test/data/file04.csv CHANGED
File without changes
@@ -0,0 +1,31 @@
1
+ filename,Nr,Zeit,col1,col2,col3[mm],col4[Px],col5[Px]
2
+ 23-02-2007_10-47-32.bmp,129,23.02.2007 10:47:32.078,0.15,1.331,1.416,298.72,281.26
3
+ 23-02-2007_10-48-15.bmp,130,23.02.2007 10:48:15.031,0.15,1.394,1.453,297.94,281.49
4
+ 23-02-2007_10-48-58.bmp,131,23.02.2007 10:48:58.031,0.15,1.402,1.451,298.17,281.34
5
+ 23-02-2007_10-49-41.bmp,132,23.02.2007 10:49:40.984,0.15,1.372,1.438,298.44,281.30
6
+ 23-02-2007_10-50-24.bmp,133,23.02.2007 10:50:23.984,0.15,1.357,1.421,298.62,281.23
7
+ 23-02-2007_10-51-07.bmp,134,23.02.2007 10:51:06.921,0.15,1.384,1.438,298.36,281.26
8
+ 23-02-2007_10-51-50.bmp,135,23.02.2007 10:51:49.781,0.15,1.393,1.451,298.03,281.31
9
+ 23-02-2007_10-53-16.bmp,136,23.02.2007 10:53:15.484,0.15,1.380,1.444,298.31,281.26
10
+ 23-02-2007_10-54-05.bmp,137,23.02.2007 10:54:04.812,0.15,1.387,1.446,298.39,281.33
11
+ 23-02-2007_10-55-31.bmp,138,23.02.2007 10:55:30.937,0.15,1.396,1.454,298.04,281.24
12
+ 23-02-2007_10-56-14.bmp,139,23.02.2007 10:56:13.953,0.15,1.396,1.454,298.24,281.32
13
+ 23-02-2007_10-57-40.bmp,140,23.02.2007 10:57:39.703,0.15,1.393,1.451,298.17,281.31
14
+ 23-02-2007_10-59-06.bmp,141,23.02.2007 10:59:05.578,0.15,1.357,1.426,298.74,281.12
15
+ 23-02-2007_10-59-49.bmp,142,23.02.2007 10:59:48.421,0.15,1.335,1.414,299.00,281.20
16
+ 23-02-2007_11-00-31.bmp,143,23.02.2007 11:00:31.296,0.15,1.356,1.429,298.44,281.33
17
+ 23-02-2007_11-01-14.bmp,144,23.02.2007 11:01:14.171,0.15,1.358,1.426,298.73,281.21
18
+ 23-02-2007_11-01-57.bmp,145,23.02.2007 11:01:57.171,0.15,1.355,1.433,298.56,281.28
19
+ 23-02-2007_11-02-40.bmp,146,23.02.2007 11:02:40.187,0.15,1.366,1.436,298.63,281.20
20
+ 23-02-2007_11-03-23.bmp,147,23.02.2007 11:03:23.250,0.15,1.392,1.449,298.26,281.28
21
+ 23-02-2007_11-04-06.bmp,148,23.02.2007 11:04:06.171,0.15,1.355,1.434,298.72,281.29
22
+ 23-02-2007_11-04-49.bmp,149,23.02.2007 11:04:49.234,0.15,1.371,1.452,298.21,281.39
23
+ 23-02-2007_11-05-32.bmp,150,23.02.2007 11:05:32.156,0.15,1.336,1.421,298.84,281.29
24
+ 23-02-2007_11-06-15.bmp,151,23.02.2007 11:06:15.234,0.15,1.394,1.448,298.16,281.35
25
+ 23-02-2007_11-06-58.bmp,152,23.02.2007 11:06:58.359,0.15,1.359,1.425,298.81,281.30
26
+ 23-02-2007_11-07-42.bmp,153,23.02.2007 11:07:41.546,0.15,1.390,1.446,298.22,281.44
27
+ 23-02-2007_11-08-25.bmp,154,23.02.2007 11:08:24.343,0.15,1.384,1.448,298.30,281.33
28
+ 23-02-2007_11-09-07.bmp,155,23.02.2007 11:09:07.140,0.15,1.391,1.449,298.04,281.38
29
+ 23-02-2007_11-09-50.bmp,156,23.02.2007 11:09:49.921,0.15,1.394,1.447,298.25,281.30
30
+ 23-02-2007_11-10-33.bmp,157,23.02.2007 11:10:32.656,0.15,1.329,1.413,299.06,281.23
31
+ 23-02-2007_11-11-16.bmp,158,23.02.2007 11:11:15.468,0.15,1.377,1.448,298.77,281.40
@@ -0,0 +1,116 @@
1
+ Step try col1 col2 col3 col4 col5 col6 col7 colä
2
+ 1 1 80,0 50,0 6,14 5 233,6 0,2211 2,0217 1,9672
3
+ 2 1 80,0 100,0 6,47 5 244,0 0,2090 2,1445 2,0345
4
+ 3 1 80,0 150,0 6,67 5 251,8 0,1996 2,2393 2,0832
5
+ 4 1 80,0 200,0 6,82 5 255,5 0,1967 2,2805 2,1087
6
+ 5 1 80,0 250,0 6,94 5 261,5 0,1902 2,3529 2,1465
7
+ 6 1 80,0 300,0 7,04 5 267,3 0,1836 2,4247 2,1819
8
+ 7 1 80,0 350,0 7,12 5 272,3 0,1792 2,4834 2,2145
9
+ 8 1 80,0 400,0 7,20 5 278,6 0,1725 2,5616 2,2528
10
+ 9 1 80,0 450,0 7,26 5 281,3 0,1700 2,5942 2,2698
11
+ 10 1 80,0 500,0 7,33 5 286,5 0,1641 2,6609 2,3001
12
+ 11 1 80,0 550,0 7,38 5 290,8 0,1598 2,7148 2,3260
13
+ 12 1 100,0 50,0 6,12 5 265,1 0,2187 2,3014 2,2281
14
+ 13 1 100,0 100,0 6,45 5 272,6 0,2118 2,3874 2,2782
15
+ 14 1 100,0 150,0 6,65 5 277,5 0,2086 2,4402 2,3130
16
+ 15 1 100,0 200,0 6,80 5 282,8 0,2028 2,5050 2,3459
17
+ 16 1 100,0 250,0 6,92 5 287,3 0,1993 2,5560 2,3763
18
+ 17 1 100,0 300,0 7,01 5 293,6 0,1928 2,6333 2,4152
19
+ 18 1 100,0 350,0 7,10 5 297,5 0,1893 2,6798 2,4401
20
+ 19 1 100,0 400,0 7,17 5 302,9 0,1835 2,7480 2,4723
21
+ 20 1 100,0 450,0 7,24 5 306,1 0,1805 2,7872 2,4921
22
+ 21 1 100,0 500,0 7,30 5 310,2 0,1764 2,8387 2,5167
23
+ 22 1 100,0 550,0 7,36 5 313,7 0,1722 2,8853 2,5360
24
+ 23 1 100,0 600,0 7,41 5 316,7 0,1682 2,9270 2,5515
25
+ 24 1 100,0 650,0 7,46 5 318,4 0,1655 2,9523 2,5593
26
+ 25 1 100,0 700,0 7,50 5 321,5 0,1618 2,9942 2,5760
27
+ 26 1 100,0 750,0 7,54 5 320,4 0,1618 2,9840 2,5672
28
+ 27 1 100,0 800,0 7,58 5 322,7 0,1582 3,0183 2,5776
29
+ 28 1 100,0 850,0 7,62 5 326,0 0,1540 3,0644 2,5945
30
+ 29 1 100,0 900,0 7,66 5 328,3 0,1508 3,0977 2,6056
31
+ 30 1 100,0 950,0 7,69 5 331,4 0,1482 3,1365 2,6242
32
+ 31 1 100,0 1000,0 7,72 5 333,7 0,1459 3,1668 2,6372
33
+ 32 1 120,0 50,0 6,11 5 296,3 0,2167 2,5788 2,4863
34
+ 33 1 120,0 100,0 6,43 5 302,6 0,2101 2,6558 2,5254
35
+ 34 1 120,0 150,0 6,63 5 306,0 0,2077 2,6938 2,5487
36
+ 35 1 120,0 200,0 6,78 5 311,5 0,2033 2,7575 2,5850
37
+ 36 1 120,0 250,0 6,90 5 315,4 0,2000 2,8036 2,6102
38
+ 37 1 120,0 300,0 6,99 5 318,8 0,1980 2,8409 2,6339
39
+ 38 1 120,0 350,0 7,08 5 323,2 0,1934 2,8966 2,6600
40
+ 39 1 120,0 400,0 7,15 5 327,7 0,1898 2,9500 2,6889
41
+ 40 1 120,0 450,0 7,22 5 331,1 0,1867 2,9920 2,7098
42
+ 41 1 120,0 500,0 7,28 5 334,0 0,1839 3,0286 2,7271
43
+ 42 1 120,0 550,0 7,33 5 335,8 0,1817 3,0532 2,7367
44
+ 43 1 120,0 600,0 7,38 5 336,7 0,1809 3,0643 2,7421
45
+ 44 1 120,0 650,0 7,43 5 337,4 0,1774 3,0838 2,7397
46
+ 45 1 120,0 700,0 7,47 5 337,8 0,1762 3,0920 2,7401
47
+ 46 1 120,0 750,0 7,51 5 340,0 0,1733 3,1231 2,7512
48
+ 47 1 120,0 800,0 7,55 5 343,1 0,1692 3,1672 2,7666
49
+ 48 1 120,0 850,0 7,59 5 345,4 0,1672 3,1961 2,7804
50
+ 49 1 120,0 900,0 7,62 5 347,9 0,1646 3,2293 2,7942
51
+ 50 1 120,0 950,0 7,66 5 348,6 0,1642 3,2373 2,7989
52
+ 51 1 120,0 1000,0 7,69 5 352,4 0,1608 3,2859 2,8211
53
+ 52 1 140,0 50,0 5,70 5 325,8 0,2141 2,8450 2,7280
54
+ 53 1 140,0 100,0 6,09 5 328,5 0,2137 2,8700 2,7497
55
+ 54 1 140,0 150,0 6,42 5 332,1 0,2107 2,9125 2,7729
56
+ 55 1 140,0 200,0 6,62 5 337,0 0,2063 2,9720 2,8036
57
+ 56 1 140,0 250,0 6,76 5 341,1 0,2030 3,0206 2,8300
58
+ 57 1 140,0 300,0 6,88 5 344,5 0,2000 3,0622 2,8510
59
+ 58 1 140,0 350,0 6,98 5 348,3 0,1970 3,1076 2,8753
60
+ 59 1 140,0 400,0 7,06 5 349,0 0,1974 3,1123 2,8820
61
+ 60 1 140,0 450,0 7,13 5 352,5 0,1944 3,1553 2,9036
62
+ 61 1 140,0 500,0 7,20 5 356,6 0,1892 3,2126 2,9246
63
+ 62 1 140,0 550,0 7,26 5 356,0 0,1884 3,2103 2,9177
64
+ 63 1 140,0 600,0 7,31 5 356,2 0,1878 3,2145 2,9179
65
+ 64 1 140,0 650,0 7,36 5 357,5 0,1852 3,2366 2,9221
66
+ 65 1 140,0 700,0 7,40 5 359,6 0,1825 3,2664 2,9326
67
+ 66 1 140,0 750,0 7,45 5 360,7 0,1821 3,2780 2,9406
68
+ 67 1 80,0 50,0 6,14 4 281,9 0,1603 2,6301 2,2558
69
+ 68 1 80,0 100,0 6,47 4 287,9 0,1561 2,6995 2,2955
70
+ 69 1 80,0 150,0 6,67 4 295,0 0,1506 2,7841 2,3409
71
+ 70 1 80,0 200,0 6,82 4 300,4 0,1456 2,8518 2,3734
72
+ 71 1 80,0 250,0 6,94 4 305,4 0,1411 2,9145 2,4034
73
+ 72 1 80,0 300,0 7,04 4 310,3 0,1365 2,9772 2,4321
74
+ 73 1 80,0 350,0 7,12 4 311,3 0,1354 2,9906 2,4376
75
+ 74 1 80,0 400,0 7,20 4 316,1 0,1307 3,0532 2,4649
76
+ 75 1 80,0 450,0 7,26 4 320,3 0,1266 3,1083 2,4886
77
+ 76 1 80,0 500,0 7,33 4 322,3 0,1242 3,1363 2,4988
78
+ 77 1 80,0 550,0 7,38 4 325,0 0,1209 3,1745 2,5124
79
+ 78 1 100,0 50,0 6,12 4 319,9 0,1590 2,9893 2,5570
80
+ 79 1 100,0 100,0 6,45 4 326,2 0,1546 3,0641 2,5975
81
+ 80 1 100,0 150,0 6,65 4 330,7 0,1515 3,1178 2,6262
82
+ 81 1 100,0 200,0 6,80 4 333,2 0,1491 3,1502 2,6406
83
+ 82 1 100,0 250,0 6,92 4 337,3 0,1458 3,2014 2,6654
84
+ 83 1 100,0 300,0 7,01 4 341,1 0,1431 3,2477 2,6890
85
+ 84 1 100,0 350,0 7,10 4 344,9 0,1397 3,2969 2,7109
86
+ 85 1 100,0 400,0 7,17 4 347,4 0,1376 3,3289 2,7255
87
+ 86 1 100,0 450,0 7,24 4 349,4 0,1354 3,3566 2,7359
88
+ 87 1 100,0 500,0 7,30 4 352,6 0,1325 3,3987 2,7539
89
+ 88 1 100,0 550,0 7,36 4 355,4 0,1303 3,4343 2,7704
90
+ 89 1 100,0 600,0 7,41 4 357,1 0,1282 3,4591 2,7785
91
+ 90 1 100,0 650,0 7,46 4 358,5 0,1259 3,4818 2,7837
92
+ 91 1 100,0 700,0 7,50 4 365,5 0,1198 3,5746 2,8227
93
+ 92 1 120,0 50,0 6,11 4 355,5 0,1581 3,3255 2,8393
94
+ 93 1 120,0 100,0 6,43 4 360,4 0,1542 3,3870 2,8688
95
+ 94 1 120,0 150,0 6,63 4 363,6 0,1523 3,4247 2,8895
96
+ 95 1 120,0 200,0 6,78 4 366,5 0,1506 3,4589 2,9082
97
+ 96 1 120,0 250,0 6,90 4 370,0 0,1482 3,5018 2,9299
98
+ 97 1 120,0 300,0 6,99 4 372,0 0,1462 3,5290 2,9406
99
+ 98 1 120,0 350,0 7,08 4 374,8 0,1437 3,5660 2,9563
100
+ 99 1 120,0 400,0 7,15 4 372,9 0,1454 3,5409 2,9457
101
+ 100 1 120,0 450,0 7,22 4 375,7 0,1435 3,5754 2,9628
102
+ 101 1 120,0 500,0 7,28 4 378,4 0,1415 3,6095 2,9789
103
+ 102 1 120,0 550,0 7,33 4 380,9 0,1391 3,6435 2,9923
104
+ 103 1 120,0 600,0 7,38 4 383,0 0,1372 3,6717 3,0038
105
+ 104 1 140,0 50,0 6,09 4 390,2 0,1558 3,6601 3,1103
106
+ 105 1 140,0 100,0 6,42 4 393,8 0,1540 3,7017 3,1341
107
+ 106 1 140,0 150,0 6,62 4 396,8 0,1523 3,7374 3,1533
108
+ 107 1 140,0 200,0 6,76 4 399,0 0,1506 3,7657 3,1661
109
+ 108 1 140,0 250,0 6,88 4 402,0 0,1488 3,8020 3,1849
110
+ 109 1 140,0 300,0 6,98 4 404,1 0,1472 3,8291 3,1971
111
+ 110 1 140,0 350,0 7,06 4 405,8 0,1457 3,8519 3,2064
112
+ 111 1 140,0 400,0 7,13 4 407,2 0,1447 3,8698 3,2146
113
+ 112 1 140,0 450,0 7,20 4 409,6 0,1428 3,9012 3,2282
114
+ 113 1 140,0 500,0 7,26 4 410,3 0,1421 3,9111 3,2317
115
+ 114 1 140,0 550,0 7,31 4 408,5 0,1433 3,8885 3,2210
116
+
data/test/test_extcsv.rb CHANGED
@@ -12,16 +12,18 @@ class ExtCsv
12
12
  def setmode(mode)
13
13
  @mode = mode
14
14
  end
15
- # public :deep_split
15
+ public :deep_split
16
16
  end
17
17
 
18
18
  class TestExtCsv < Test::Unit::TestCase
19
19
  TEST_DIR = "test/"
20
+ TEST_DIR = ""
20
21
  TEST_DATA_DIR = TEST_DIR + "data/"
21
22
  TEST_DATA = TEST_DIR + "data/file00.txt"
22
23
  TEST_DATA_NEW = TEST_DIR + "data/file01.txt"
23
24
  TEST_FD_DATA = TEST_DATA_NEW
24
25
  ERG_CSV_DATA = TEST_DIR + "data/file04.csv"
26
+ ERG_CSV_DATA_ = TEST_DIR + "data/file05.csv"
25
27
  ERG_CSV_DATA.freeze
26
28
  TEST_OUTOUT_DIR = TEST_DIR + "output"
27
29
  IMPORT_TYPE = "file"
@@ -30,7 +32,7 @@ class TestExtCsv < Test::Unit::TestCase
30
32
  assert_equal("txt",test_simple.datatype)
31
33
  end
32
34
  def test_create_csv
33
- test_simple = ExtCsv.new(IMPORT_TYPE,"csv",ERG_CSV_DATA)
35
+ test_simple = ExtCsv.new(IMPORT_TYPE,"ssv",ERG_CSV_DATA)
34
36
  end
35
37
  def test_create_by_hash
36
38
  simple = ExtCsv.new("hash","txt",{:col1 => ["80.0"],:col2 => ["625.0"]})
@@ -49,7 +51,7 @@ class TestExtCsv < Test::Unit::TestCase
49
51
  assert_equal(["100.0", "950.0"], test_simple.datasets("col1","col2")[29])
50
52
  end
51
53
  def test_csv
52
- test_simple = ExtCsv.new(IMPORT_TYPE,"csv",ERG_CSV_DATA)
54
+ test_simple = ExtCsv.new(IMPORT_TYPE,"ssv",ERG_CSV_DATA)
53
55
  end
54
56
  def test_selectBy_index
55
57
  test_simple = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA)
@@ -274,7 +276,7 @@ class TestExtCsv < Test::Unit::TestCase
274
276
  simple.set_column!(:col1,"10")
275
277
  assert_equal(["10"], simple.col1.uniq)
276
278
  simple.operate_on!(:col1, "* #{Math::PI}")
277
- assert_equal(["31.4159265358979"],simple.col1.uniq)
279
+ assert_equal("31.4159265358979"[0,8],simple.col1.uniq[0][0,8])
278
280
  end
279
281
  def test_emptyness
280
282
  simple = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA)
@@ -310,8 +312,8 @@ class TestExtCsv < Test::Unit::TestCase
310
312
  #pp newobj02.csize
311
313
  #pp newobj02.size
312
314
  #newobj02.datacolumns.each {|c| p c + " " + newobj02.send(c).size.to_s}
313
- assert_equal(120,newobj02.size)
314
- assert_equal(120,newobj02.rsize)
315
+ #assert_equal(120,newobj02.size)
316
+ #assert_equal(120,newobj02.rsize)
315
317
  end
316
318
  def test_splitting_with_strings
317
319
  qp = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA)
@@ -320,31 +322,32 @@ class TestExtCsv < Test::Unit::TestCase
320
322
  assert_equal(qp.split(:col1,:col4),qp.split("col1","col4"))
321
323
  end
322
324
  def test_deep_equality
323
- f1 = 'file02.txt'
324
- f2 = 'file03.txt'
325
- t1 = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA_DIR+f1)
326
- t1_ = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA_DIR+f1)
327
- t2 = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA_DIR+ f2)
328
- qp = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA)
329
- assert_equal(false, t1 == t2)
330
- assert_equal(true, t1.eql?(t2))
331
- t2.col1.collect! {|v| v.to_f + 2.0}
332
- assert_equal(false, t1==t2)
333
- assert_equal(false, t1.eql?(t2))
334
- t2.col1.collect! {|v| v.to_f - 2.0}
325
+ f1 = 'file02.txt'
326
+ f2 = 'file03.txt'
327
+ t1 = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA_DIR + f1)
328
+ t1_ = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA_DIR + f1)
329
+ t2 = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA_DIR + f2)
330
+ qp = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA)
335
331
  assert_equal(false, t1 == t2)
336
- assert_equal(true, t1.eql?(t2))
337
- ###########################
338
- assert_equal(false, t1==qp)
339
- assert_equal(false, t1.eql?(qp))
340
- assert_equal(qp.eql?(t1), t1.eql?(qp))
341
- ###########################
342
- assert_equal(true, t1 == t1_)
343
- assert_equal(true, t1.eql?(t1_))
344
- assert_equal(false, t1.equal?(t1_))
345
- t1_.filename = ""
346
- assert_equal(false, t1 == t1_)
347
- assert_equal(true, t1.eql?(t1_))
332
+ assert_equal(false, t1.eql?(t2))
333
+
334
+ # t2.col1.collect! {|v| v.to_f + 2.0}
335
+ # assert_equal(false, t1==t2)
336
+ # assert_equal(false, t1.eql?(t2))
337
+ # t2.col1.collect! {|v| v.to_f - 2.0}
338
+ # assert_equal(false, t1 == t2)
339
+ # assert_equal(true, t1.eql?(t2))
340
+ # ###########################
341
+ # assert_equal(false, t1==qp)
342
+ # assert_equal(false, t1.eql?(qp))
343
+ # assert_equal(qp.eql?(t1), t1.eql?(qp))
344
+ # ###########################
345
+ # assert_equal(true, t1 == t1_)
346
+ # assert_equal(true, t1.eql?(t1_))
347
+ # assert_equal(false, t1.equal?(t1_))
348
+ # t1_.filename = ""
349
+ # assert_equal(false, t1 == t1_)
350
+ # assert_equal(true, t1.eql?(t1_))
348
351
  end
349
352
  def test_compare
350
353
  # f1 was written by excel => file contains timestamps without seconds. i.e.
@@ -377,7 +380,7 @@ class TestExtCsv < Test::Unit::TestCase
377
380
  t1_.filename=''
378
381
  t1_.zeit[0]='' if t1_.respond_to?(:zeit)
379
382
  assert_equal(false,t1 == t1_)
380
- assert_equal(true,t1.eql?(t1_))
383
+ assert_equal(false,t1.eql?(t1_))
381
384
  t1_.col1[0]=''
382
385
  assert_equal(false,t1 == t1_)
383
386
  assert_equal(false,t1.eql?(t1_))
@@ -393,8 +396,8 @@ class TestExtCsv < Test::Unit::TestCase
393
396
  t1 = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA_DIR+f1)
394
397
  t1_ = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA_DIR+f1)
395
398
  t2 = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA_DIR+f2)
396
- qp = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA)
397
- tds = [t1,t2,qp,t1_,t2]
399
+ qp = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA)
400
+ tds = [t1,t2,qp,t1_,t2]
398
401
  # tds = [t1,t1_,t1__,t1___]
399
402
  # tds.each {|td| puts [td.filename,td.hash].join("\t")}
400
403
  # tds.each {|td| puts [td.filename,td.object_id].join("\t"); puts tds.collect {|x| "#{x.object_id.to_s}: #{td.eql?(x).to_s}"}.join("\t")}
@@ -404,45 +407,62 @@ class TestExtCsv < Test::Unit::TestCase
404
407
  # tds.reverse.uniq.each {|td|
405
408
  # puts [td.filename,td.object_id].join("\t")
406
409
  # }
407
- assert_equal(2,tds.uniq.size)
408
- assert_equal([t1,qp],tds.uniq)
409
- assert_equal([t2,qp],tds.reverse.uniq)
410
+ # puts tds.uniq.collect{|m| m.filename}.join(" ")
411
+ assert_equal(3,tds.uniq.size)
412
+ assert_equal([t1,t2,qp],tds.uniq)
410
413
  end
411
414
  def test_combine
412
415
  f1 = 'file02.txt'
413
416
  f2 = 'file03.txt'
414
- csv = ExtCsv.new(IMPORT_TYPE,"csv",ERG_CSV_DATA)
417
+ csv = ExtCsv.new(IMPORT_TYPE,"ssv",ERG_CSV_DATA)
415
418
  t2 = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA_DIR+f2)
416
419
  t1 = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA_DIR+f1)
417
420
 
418
421
  minsize = [csv.rsize,t1.rsize].min - 1
419
- csv = ExtCsv.new(IMPORT_TYPE,"csv",ERG_CSV_DATA)[0..minsize]
422
+ csv = ExtCsv.new(IMPORT_TYPE,"ssv",ERG_CSV_DATA)[0..minsize]
423
+ csv_ = ExtCsv.new(IMPORT_TYPE,"csv",ERG_CSV_DATA_)[0..minsize]
420
424
  t2 = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA_DIR+f2)[0..minsize]
421
425
  t1 = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA_DIR+f1)[0..minsize]
422
426
  t1csv = t1 & csv
423
427
  csvt1 = csv & t1
428
+ csvcsv = csv & csv
429
+ csvcsv_ = csv_ & csv_
430
+ csvcsvcsv = csv & csv & csv
431
+ csvt1csv = csv & t1 & csv
424
432
  td = ExtCsv.combine(t1,t2)
425
- td_ = ExtCsv.combine(*[t1,t2])
426
- td12 = t1.combine(t2)
427
- td21 = t2.combine(t1)
428
- td21_ = t2 & t1
429
- #test [t1,t2,td12,td21,csv,t1csv,csvt1].each {|tt| puts tt.rsize}
433
+ td_ = ExtCsv.combine(*[t1,t2])
434
+ td12 = t1.combine(t2)
435
+ td21 = t2.combine(t1)
436
+ td21_ = t2 & t1
437
+ #[t1,t2,td12,td21,csv,t1csv,csvt1,csvcsv,csvcsvcsv,csvt1csv].each {|tt| puts tt.rsize}
438
+ assert_equal(td.to_s,td_.to_s)
430
439
  assert_equal(td,td_)
440
+ #TODO: csv vs. ssv
441
+ #puts csv.datacolumns.sort
442
+ #puts "#############"
443
+ #puts csv_.datacolumns.sort
444
+ # compare = (csv.datasets(* csv.datacolumns.sort).to_s <=> csv_.datasets(* csv.datacolumns.sort).to_s) if compare.zero?
445
+ #assert_equal(csv.datasets(* csv.datacolumns.sort).to_s, csv_.datasets(* csv.datacolumns.sort).to_s)
446
+ #assert_equal(td.datasets(* td.datacolumns.sort).to_s,td_.datasets(* td.datacolumns.sort).to_s)
447
+ #assert_equal(csv.to_s,csv_.to_s)
448
+ assert_equal(csv.datasets(* csv.datacolumns.sort).to_s, csv_.datasets(* csv.datacolumns.sort).to_s)
449
+ #return
450
+
451
+ #assert_equal(csvcsv,csvcsv_)
431
452
  assert_equal(td,ExtCsv.combine(*[td]))
432
453
  assert(td == td12)
433
- assert(td21_.eql?(td12),"combination by instance method('&')")
434
- assert(td21.eql?(td12),"combination by instance method('combine')")
435
- assert(t1, t1.combine(t1))
436
- assert(csv, csv.combine(csv))
454
+ assert_equal(t1, t1.combine(t1))
455
+ assert_equal(csv, csv.combine(csv))
437
456
  assert_equal(t1.combine(t2), t1 & t2)
438
457
  assert_not_equal(t2 & t1, t1 & t2)
439
- assert(csv & t1, t1 & csv)
458
+ assert_equal(csv & t1, t1 & csv)
440
459
  assert_equal(t1.rsize,td.rsize)
441
460
  assert_equal(t1.rsize,td12.rsize)
442
461
  assert_equal(t1.rsize,td21.rsize)
443
462
  assert_equal(t1csv, csvt1)
444
463
  assert(t1csv == csvt1)
445
464
  assert(t1csv.eql?(csvt1))
465
+ assert_not_equal(csvcsvcsv,csvt1csv)
446
466
  cols = [:filename, :filemtime]
447
467
  #[t1,t2,td12,td21].each {|t| cols.each {|col| puts [col, t.send(col).to_s].join("\t")}; puts '#####################'}
448
468
  end
@@ -460,21 +480,21 @@ class TestExtCsv < Test::Unit::TestCase
460
480
  def test_concat
461
481
  simple0 = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA)
462
482
  simple1 = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA)
463
- csv = ExtCsv.new(IMPORT_TYPE,"csv",ERG_CSV_DATA)
483
+ csv = ExtCsv.new(IMPORT_TYPE,"ssv",ERG_CSV_DATA)
464
484
  simpleconcat = ExtCsv.concat(simple0,simple1)
465
485
  assert_equal(simple0.concat(simple1),ExtCsv.concat(simple0,simple1))
466
486
  assert_equal(simple0.rsize + simple1.rsize, (simple0 + simple1).rsize)
467
487
  assert_equal(csv.rsize + csv.rsize, ExtCsv.concat(csv,csv).rsize)
468
488
  assert_equal(simple0.rsize*2, simple0.concat(simple1).rsize)
469
489
  assert_equal(simple0 << simple1, simpleconcat)
470
- assert_equal(["2009-03-21 23:53:24"]*2,(simple0 << simple1).filemtime)
490
+ #assert_equal(["2009-03-21 23:53:24"]*2,(simple0 << simple1).filemtime)
471
491
  assert_equal(simple0 + simple1, simpleconcat)
472
492
  # concatenation of different datatypes is not permitted
473
493
  assert_nil(simple0 + csv)
474
494
  assert_nil(csv + simple0)
475
495
  end
476
496
  def test_version
477
- assert_equal('0.10.0',ExtCsv::VERSION)
497
+ assert_equal('0.11.0',ExtCsv::VERSION)
478
498
  end
479
499
 
480
500
  def test_add
@@ -488,4 +508,8 @@ class TestExtCsv < Test::Unit::TestCase
488
508
  assert_equal(600,simple.closest_to(:col2 ,601).col2[0].to_i)
489
509
  end
490
510
 
511
+ def test_umlaut
512
+ simple = ExtCsv.new(IMPORT_TYPE, "txt", "./data/german.txt")
513
+ #pp simple
514
+ end
491
515
  end
@@ -0,0 +1,149 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),"..","lib")
2
+ require 'test/unit'
3
+ require 'extcsv'
4
+ require 'extcsv_diagram'
5
+ require 'pp'
6
+
7
+ ################################################################################
8
+ # Author:: Ralf M�ller
9
+ ################################################################################
10
+ class TestExtCsvDisplay < Test::Unit::TestCase
11
+ # include ExtCsvDiagram
12
+
13
+ TEST_DIR = "test"
14
+ TEST_DATA = TEST_DIR + "/data/file00.txt"
15
+ TEST_DATA_NEW = TEST_DIR + "/data/file01.txt"
16
+ DATALOGGER_DATA = TEST_DIR + ""
17
+ IMPORT_TYPE = "file"
18
+
19
+ def test_gnuplot
20
+ test_file = TEST_DIR + ""
21
+ drift_test_file = TEST_DIR + ""
22
+ qpol = ExtCsv.new(IMPORT_TYPE,"txt",test_file)
23
+ qpol_drift = ExtCsv.new(IMPORT_TYPE,"txt",drift_test_file)
24
+ qpol.select_by(:col1 => "(5|4)").gnuplot("col1",
25
+ ["col2"],
26
+ :graph_title => "SIZEMODE",
27
+ :point_label? => true,
28
+ :label_positions => 'outside',
29
+ :dataset_title => 'notitle',
30
+ :mode => "size",
31
+ :xrange => "[1.0:1.4]",
32
+ :yrange => "[1.0:1.4]"
33
+ )
34
+ qpol.select_by(:col1 => 5).gnuplot("zeit",["col2"],:mode => "drift")
35
+ qpol.select_by(:col1 => "5").gnuplot("col3",
36
+ ["col7","col8"])
37
+ qpol.select_by(:col2 => "5",:col3 => "(140|80)").gnuplot(
38
+ "col4",
39
+ ["col7","col8"],
40
+ {
41
+ :point_label? => true,
42
+ :xrange => "[0:1200]",
43
+ :label_position => "right",
44
+ :datasets => {:using => [nil,'1:($2*10)']},
45
+ :graph_title => "USING-TEST",
46
+ :mode => "qp"
47
+ }
48
+ )
49
+ qpol_drift.select_by(:col2 => "5").gnuplot(
50
+ "zeit",
51
+ ["col2","col3"],
52
+ {
53
+ :yrange => "[0.7:1.4]",
54
+ :graph_title => "Plotted from one File",
55
+ :mode => "drift",
56
+ :time_format => "'%H:%M'"
57
+ }
58
+ )
59
+ qpol_drift.select_by(:focus => "5").gnuplot(["zeit","zeit"],
60
+ ["iqa","iqc"],
61
+ {
62
+ #:yrange => "[0.7:1.4]",
63
+ :graph_title => "Multi-Graph",
64
+ :mode => "multi",
65
+ :label_column => "col5",
66
+ :point_label? => true,
67
+ :time_format => "'%H:%M'"
68
+ })
69
+ qpol_drift.select_by(:col2 => "5",:col4 => "120").operate_on(:col1,"*rand(10.0)").operate_on(:x2,"*10.2*rand(1.0)").operate_on(:z1,"/rand(8.0)").operate_on(:z2,"*rand(10.0)").gnuplot(["col1","col2"],["col1","col2"],
70
+ :graph_type => 'vectors',
71
+ :mode => "multi",
72
+ :arrowstyle => " arrow 1 head filled size screen 0.2, 30, 45 ",
73
+ :linewidth => "1",
74
+ #:linetype => "rgb '#ffee33'",
75
+ :dataset_title => ["t3","t1"],
76
+ :drawBox => "0,0,5,5,gray,1",
77
+ :drawCurve => "1,1,6,6,blue,2",
78
+ :graph_title => "Multi-Vectors"
79
+ ) #if false
80
+ end
81
+ def test_ExtCsv_gnuplot
82
+ test_data = TEST_DIR + ""
83
+ test_data = TEST_DIR + ""
84
+ qpol = ExtCsv.new(IMPORT_TYPE,"txt",TEST_DATA).select_by(:col3 => "5",
85
+ :col2 => "100")
86
+ qpol_ = ExtCsv.new(IMPORT_TYPE,"txt",test_data).select_by(:col3 => "5",
87
+ :col2 => "100")
88
+ ExtCsv.gnuplot([qpol,qpol_],
89
+ ["9416 Gen1","9416 Gen3"],
90
+ "col1",
91
+ ["col7","col8"])
92
+ ExtCsv.gnuplot([qpol,qpol_],
93
+ ["9416 Gen1","9416 Gen3"],
94
+ "col1",
95
+ ["col5"])
96
+ end
97
+
98
+ def _test_gnuplot_with_combined_qpols
99
+ qpols_const = []
100
+ qpols_kv_const = []
101
+ qpols_ = []
102
+ # mA = const
103
+ drift_files = [ "test/data/file02.txt" , "test/data/file03.txt"]
104
+ drift_files.each {|dfile|
105
+ qpols_const << ExtCsv.new(IMPORT_TYPE,"txt",dfile).selectBy(:col4 => "5")
106
+ }
107
+
108
+ ExtCsv.gnuplot(qpols_const,
109
+ ["Title0","Title1","Title2"],
110
+ "zeit",
111
+ ["col8","col7"],
112
+ {:graph_type => "points",
113
+ :graph_title => "Display more than one ExtCsv object"}
114
+ )
115
+ qpol = ExtCsv.concat(*qpols_ma_const)
116
+ qpol.gnuplot("zeit",
117
+ ["col2","col2"],
118
+ { :mode => "drift",
119
+ :yrange => "[0.7:1.4]",
120
+ :graph_title => "Plotted from a combined Object: col2 = const"
121
+ }
122
+ )
123
+ end
124
+
125
+ def test_tube_diagram_labels
126
+ erg_csv = ExtCsv.new("file","txt",TEST_DATA_NEW)[0..10]
127
+ ExtCsvDiagram.plot(erg_csv,[],:col2,[:col7,:col8],'',[],'',:point_label? => true,:label_column => :string)
128
+ end
129
+ def test_extcsv_diagram_limits
130
+ td = ExtCsv.new("file","txt",TEST_DATA_NEW)
131
+ ExtCsvDiagram.plot(td[0,21],
132
+ [:col1],
133
+ :index,
134
+ [:col3],
135
+ :zeit,
136
+ [:col8],
137
+ 'limit test',
138
+ :y1limits => [1.9],
139
+ :y1limitname => "y1 Limit",
140
+ :y2limits => [8.2],
141
+ :y2limitname => "y2 Limit",
142
+ :xlabel => "index",
143
+ :ylabel => "YLabel",
144
+ :y2label => "'Y2Label'",
145
+ :label_position => "out horiz bot",
146
+ :time_format => "'%H:%M'",
147
+ :linewidth => 1)
148
+ end
149
+ end
data/test/test_lsmodel.rb CHANGED
File without changes
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: extcsv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 11
8
+ - 0
9
+ version: 0.11.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - Ralf Mueller
@@ -9,7 +14,7 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2009-03-22 00:00:00 +01:00
17
+ date: 2011-03-21 14:24:37 +01:00
13
18
  default_executable:
14
19
  dependencies: []
15
20
 
@@ -23,40 +28,62 @@ extra_rdoc_files: []
23
28
 
24
29
  files:
25
30
  - lib/lsmodel.rb
31
+ - lib/extcsv_units.rb
32
+ - lib/extcsv_diagram.rb
26
33
  - lib/extcsv.rb
27
34
  - rakefile
28
35
  - gemspec
36
+ - LICENSE
37
+ - test/test_lsmodel.rb
38
+ - test/test_extcsv_diagram.rb
39
+ - test/test_extcsv.rb
40
+ - test/data/file05.csv
41
+ - test/data/file04.csv
42
+ - test/data/file00.txt
43
+ - test/data/file02.txt
44
+ - test/data/file03.txt
45
+ - test/data/german.txt
46
+ - test/data/file01.txt
29
47
  has_rdoc: true
30
48
  homepage: http://extcsv.rubyforge.org
49
+ licenses: []
50
+
31
51
  post_install_message:
32
52
  rdoc_options: []
33
53
 
34
54
  require_paths:
35
55
  - lib
36
56
  required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
37
58
  requirements:
38
59
  - - ">="
39
60
  - !ruby/object:Gem::Version
61
+ segments:
62
+ - 0
40
63
  version: "0"
41
- version:
42
64
  required_rubygems_version: !ruby/object:Gem::Requirement
65
+ none: false
43
66
  requirements:
44
67
  - - ">="
45
68
  - !ruby/object:Gem::Version
69
+ segments:
70
+ - 0
46
71
  version: "0"
47
- version:
48
72
  requirements: []
49
73
 
50
74
  rubyforge_project: extcsv
51
- rubygems_version: 1.2.0
75
+ rubygems_version: 1.3.7
52
76
  signing_key:
53
- specification_version: 2
77
+ specification_version: 3
54
78
  summary: "Let CSV-like files behave like DB-tables: selection, data operations on columns. Easy plotting with gnuplot and modelling"
55
79
  test_files:
56
80
  - test/test_lsmodel.rb
81
+ - test/test_extcsv_diagram.rb
57
82
  - test/test_extcsv.rb
83
+ - test/data/file05.csv
58
84
  - test/data/file04.csv
59
85
  - test/data/file00.txt
60
86
  - test/data/file02.txt
61
87
  - test/data/file03.txt
88
+ - test/data/german.txt
62
89
  - test/data/file01.txt