Newbie questions on processing numerical data from text file


#1

Hi,

Hope you can help me get started with these trivial questions.
I’ve got a practical problem, and the Ruby cookbook to help me, but a
few combinations of the two haven’t produced any interesting results
yet. I’d need a simple useful example to start with and then make my
own variations.

Here is my practical problem:

  • I open a text file, locate a line according to some keyword or line
    number, and change a value
  • I run a fortran program
  • I read a text file (output of this program), extract several
    numerical values and export them in a two column text file

The way I’ve done that so far is using bash commands such as ‘awk’,
‘grep’, … but i need some loops and it’s getting too big for a
sensible bash script.

Could you help me get started in Ruby with the simpler example below?

Here is the content of “sampleTextFile.dat”:

other useless words …
I would like to read this data in some sort of array/hash, and export
the first column and the product of the last two columns to a new
file “results.dat”. This should be enough to understand the spirit I
guess, with the probably trivial problem to call the external program.

Any advice welcome.

Many thanks in advance!

baptiste


#2

How i create array under ruby?
for example need create a vector type array

2007/6/29, Axel E. removed_email_address@domain.invalid:


#3

How i create array under ruby?
for example need create a vector type array

Like this:

a=[]
a=Array.new
a=[1,2,3]
a=[1,“a”,9.0]

You can include elements from all sorts of
classes into an Array.

Best regards,

Axel


#4

Dear Baptiste,

welcome to Ruby!

Here is my practical problem:

  • I open a text file,

(… which already exists):

interesting_text=IO.readlines(file_name)

gives you an Array, with the lines as entries

locate a line according to some keyword

interesting_text.delete_if{|line| /(r|R)uby/.match==nil}

removes all lines that don’t contain the string Ruby or ruby,

or line number,

interesting_text[line_number] # (start counting at 0)

and change a value
old_value=1.2
new_value=2.4

interesting_text.sub!(value.to_s,new_value.to_s)

  • I run a fortran program

result=... where … is the system command you use to start
your fortran program,

  • I read a text file (output of this program), extract several
    numerical values

You can do the reading with IO.readlines, the extraction with a
Regexp,

and export them in a two column text file

and this via

f=File.new(“my_result_file.txt”,“w”)
f.puts formatted_text
f.close

Here is the content of “sampleTextFile.dat”:

this is a meaningless line
another one

maybe this line acts as a keyword for the following data

I don’t know how to interpret the values in brackets in the
following line:

1 3.1 (415, 19e-12)

If you read the file in via IO.readlines, it’s a String element
of an Array, say line=“1 3.1 (415, 19e-12)”
so you could do:

numbers=line.gsub(/[(,)]/,’’).split <= removes brackets an gives
a four element Array (of Strings), which you can turn ito numbers via
eval

number_array=line.gsub(/[(,)]/,’’).split.map{|x| eval(x)}

Some other approach might be to assign variable names to each element
in a line

vars_names=[‘a’,‘b’,‘c’,‘d’]
array_of_hashes=[]
lines.each{|line|
vals_line=line.gsub(/[(,)]/,’’).split.map{|x| eval(x)}
tmp={}
vars_names.each_with_index{|var_name,index|
tmp.store(var_name,vals_line[index])
}
array_of_hashes<<tmp
}

will give something like:

[{“a”=>1,“b”=>3.1,“c”=>415,“d”=>19e-12},…]

Best regards,

Axel


#5

On 29 Jun 2007, at 14:32, Axel E. wrote:

Dear Baptiste,

welcome to Ruby!

Thanks a lot!

I have a few problems though,

locate a line according to some keyword

interesting_text.delete_if{|line| /(r|R)uby/.match==nil}

removes all lines that don’t contain the string Ruby or ruby,

for some reason this doesn’t work for me. I get an error message:
ArgumentError: wrong number of arguments (0 for 1)

if i replace this argument with something based on line numbers
rather than regexp, it’s fine. Is the Regexp wrong?

and change a value
old_value=1.2
new_value=2.4

interesting_text.sub!(old_value.to_s,new_value.to_s)

I can’t get that to work either :
NoMethodError: private method `sub!’ called for #Array:0x7d180

Best regards,

Axel

The rest works fine, thanks again!

baptiste


#6

interesting_text.delete_if{|line| /(r|R)uby/.match==nil}

removes all lines that don’t contain the string Ruby or ruby,

for some reason this doesn’t work for me. I get an error message:
ArgumentError: wrong number of arguments (0 for 1)

if i replace this argument with something based on line numbers
rather than regexp, it’s fine. Is the Regexp wrong?

You’re right. The line should read:

interesting_text.delete_if{|line| /(r|R)uby/.match(line)==nil}

I can’t get that to work either :
NoMethodError: private method `sub!’ called for #Array:0x7d180

… and again … sub, gsub, sub!,gsub! are for Strings … so
either:

interesting_text=IO.readlines(file_name).to_s
interesting_text.sub!(old_value.to_s,new_value.to_s)

or , if, each line is to be processed separately,

interesting_text=IO.readlines(file_name)

new_text=interesting_text.each{|line|
line.sub(old_value.to_s,new_value.to_s)}

Sorry for the confusion.

Best regards,

Axel


#7

awesome, it works! It’s all starting to make some sense now.

Thanks!

baptiste