Forum: Ruby newbie questions on processing numerical data from text file

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
baptiste Auguié (Guest)
on 2007-06-29 15:49
(Received via mailing list)
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
Axel E. (Guest)
on 2007-06-29 17:33
(Received via mailing list)
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
Juan P. (Guest)
on 2007-06-29 17:58
(Received via mailing list)
How i create array under ruby?
for example need create a vector type array


2007/6/29, Axel E. <removed_email_address@domain.invalid>:
Axel E. (Guest)
on 2007-06-29 18:03
(Received via mailing list)
> 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
baptiste Auguié (Guest)
on 2007-06-29 21:47
(Received via mailing list)
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
Axel E. (Guest)
on 2007-06-29 23:00
(Received via mailing list)
> > 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
baptiste Auguié (Guest)
on 2007-06-30 00:34
(Received via mailing list)
awesome, it works! It's all starting to make some sense now.

Thanks!

baptiste
This topic is locked and can not be replied to.