extcsv 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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