Having Ruby fun with the comp.lang.fortran folks:
http://tinyurl.com/38o8ex
http://tinyurl.com/2pw22q
Please riff a better Ruby answer...
Regards,
···
--
Bil Kleb
http://fun3d.larc.nasa.gov
Having Ruby fun with the comp.lang.fortran folks:
http://tinyurl.com/38o8ex
http://tinyurl.com/2pw22q
Please riff a better Ruby answer...
Regards,
--
Bil Kleb
http://fun3d.larc.nasa.gov
Bil Kleb wrote:
Having Ruby fun with the comp.lang.fortran folks:
http://tinyurl.com/38o8ex
http://tinyurl.com/2pw22qPlease riff a better Ruby answer...
My current answer to the challenge...
require 'scanf'
require 'open-uri'
def write_uvs(u,v)
u = u[0...v.size] # limit U's size to V's
puts u, v # write Us & Vs
u.zip(v).each do |u_line,v_line| # zip Us & Vs together
u_value, v_value = u_line.scanf("%14c %f").last, v_line.scanf("%14c %f").last
printf "#{u_line[/.*=/].sub(/U/,'UV')} %7.3f\n", u_value*v_value # write UV
end
end
u, v = , # initialize U & V arrays
open 'http://home.earthlink.net/~dave_gemini/demo.in' do |iostream|
iostream.each_line do |line|
case line
when /^time/ then # found time delimiter
write_uvs(u,v) and u.clear and v.clear
puts "\n" + line.sub( /time\s*:/, 'for time' ) + "\n" # write time
when /^U/ then # add to U array
u << line
when /^V/ then # add to V array
v << line unless v.size == u.size # limit V's size to U's
end
end
end
write_uvs(u,v)
Later,
--
Bil Kleb
http://tufte-latex.googlecode.com
I'm confused as to why the data needs to be retained in memory..... But
here is a little something I put together. It does maintain the
datastructures in memory before calculating the results.
require 'open-uri'
class PhilCollins
attr_writer :time
alias :time :time=
def initialize(io)
@uv_by_t = Hash.new { |h,t| h[t] = Hash.new { |n,a| n[a] = } }
@time = 10
io.each_line do |line|
line.gsub!(/:\s*(\d+)[^\d]*$/, '(\1)')
line.gsub!(/([UV])\s*\(([^)]*)\)\s=\s(.*)$/, '\1[[\2]] << \3')
line.downcase!
begin; instance_eval(line); rescue Exception; end
end
end
def u; @uv_by_t[@time]; end
alias :v :u
def inspect
@uv_by_t.sort_by { |t,v| t }.map { |t,v|
"for time: #{t}\n" +
v.map { |args,vals|
"UV(#{args.join(',')}) = #{vals[0] * vals[1]}" if vals.length == 2
}.compact.join("\n")
}.join("\n\n")
end
end
p PhilCollins.new(open('http://home.earthlink.net/~dave_gemini/demo.in'\))
PS, don't try this script at home! It's very dangerous!
On Mon, Nov 12, 2007 at 10:30:06AM +0900, Bil Kleb wrote:
Having Ruby fun with the comp.lang.fortran folks:
http://tinyurl.com/38o8ex
http://tinyurl.com/2pw22qPlease riff a better Ruby answer...
--
Aaron Patterson
http://tenderlovemaking.com/
That little challenge made me wish for some Ruby 1.9 elements, like an ordered Hash.
James Edward Gray II
#!/usr/bin/env ruby -wKU
us, vs = Array.new, Array.new
DATA.each do |line|
if line =~ /^time\s*:\s*(.+?)\s*$/
[us, vs].each { |array| array.clear }
puts "for time #{$1}"
puts
elsif line =~ /^([UV])(\s*\([^)]+\))\s*=\s*([\d.]+)\s*$/
($1 == "U" ? us : vs) << [$2, $3.to_f]
puts line
end
if line =~ /^\s*$/ or DATA.eof?
next if us.empty? or vs.empty?
us.each do |sig, value|
next unless v = vs.assoc(sig)
puts "UV%s = %.2f" % [sig, value * v.last]
end
puts
end
end
__END__
On Nov 11, 2007, at 7:30 PM, Bil Kleb wrote:
Having Ruby fun with the comp.lang.fortran folks:
http://tinyurl.com/38o8ex
http://tinyurl.com/2pw22qPlease riff a better Ruby answer...
velocity U in m/s
U ( 1, 1, 1) = 12.34
U ( 1, 1, 2) = 10.00
U ( 1, 1, 3) = 11.01
U ( 1, 2, 1) = 10.05
U ( 1, 2, 2) = 12.40
U ( 1, 2, 3) = 11.20
U ( 1, 3, 1) = 12.80
U ( 1, 3, 2) = 10.30
U ( 1, 3, 3) = 11.25
velocity V in m/s
V ( 1, 1, 1) = 11.40
V ( 1, 1, 2) = 12.00
V ( 1, 1, 3) = 13.50
V ( 1, 2, 1) = 11.00
V ( 1, 2, 2) = 11.70
V ( 1, 2, 3) = 11.25
V ( 1, 3, 1) = 11.50
V ( 1, 3, 2) = 10.60
V ( 1, 3, 3) = 11.23
velocity U in m/s
U ( 1, 1, 1) = 13.30
U ( 1, 1, 2) = 11.00
U ( 1, 1, 3) = 11.30
U ( 1, 2, 1) = 10.00
U ( 1, 2, 2) = 12.30
U ( 1, 2, 3) = 10.10
U ( 1, 3, 1) = 10.90
U ( 1, 3, 2) = 11.40
U ( 1, 3, 3) = 11.75
velocity V in m/s
V ( 1, 1, 1) = 12.40
V ( 1, 1, 2) = 11.00
V ( 1, 1, 3) = 11.60
V ( 1, 2, 1) = 11.20
V ( 1, 2, 2) = 11.90
V ( 1, 2, 3) = 11.35
V ( 1, 3, 1) = 12.50
V ( 1, 3, 2) = 11.60
V ( 1, 3, 3) = 13.20
Bil Kleb wrote:
[snip]
Yeah ... it wasn't clear to me than anyone had set what the limits were. If the code only has to deal with little chunks of data like
velocity U in m/s
U ( 1, 1, 1) = 12.34
U ( 1, 1, 2) = 10.00
U ( 1, 1, 3) = 11.01
U ( 1, 2, 1) = 10.05
U ( 1, 2, 2) = 12.40
U ( 1, 2, 3) = 11.20
U ( 1, 3, 1) = 12.80
U ( 1, 3, 2) = 10.30
U ( 1, 3, 3) = 11.25
velocity V in m/s
V ( 1, 1, 1) = 11.40
V ( 1, 1, 2) = 12.00
V ( 1, 1, 3) = 13.50
V ( 1, 2, 1) = 11.00
V ( 1, 2, 2) = 11.70
V ( 1, 2, 3) = 11.25
V ( 1, 3, 1) = 11.50
V ( 1, 3, 2) = 10.60
V ( 1, 3, 3) = 11.23
"little" being defined as nine U values and nine V values per time step, I don't see why one would do this in awk or Ruby when Fortran could do it. It's been about 18 years since I read or wrote any Fortran, but I didn't know awk at the time and so, presented with a problem like this, would have coded it in Fortran. I think the real challenge here in any language is to scale this up to way more than nine U and V values per time step -- something where you'd actually need some kind of efficient data structure.
Oops. @time should be nil, but that shouldn't change the output....
On Mon, Nov 12, 2007 at 12:20:32PM +0900, Aaron Patterson wrote:
On Mon, Nov 12, 2007 at 10:30:06AM +0900, Bil Kleb wrote:
> Having Ruby fun with the comp.lang.fortran folks:
>
> http://tinyurl.com/38o8ex
> http://tinyurl.com/2pw22q
>
> Please riff a better Ruby answer...I'm confused as to why the data needs to be retained in memory..... But
here is a little something I put together. It does maintain the
datastructures in memory before calculating the results.require 'open-uri'
class PhilCollins
attr_writer :time
alias :time :time=
def initialize(io)
@uv_by_t = Hash.new { |h,t| h[t] = Hash.new { |n,a| n[a] = } }
@time = 10
--
Aaron Patterson
http://tenderlovemaking.com/
James Edward Gray II wrote:
That little challenge made me wish for some Ruby 1.9 elements, like an ordered Hash.
Nice; can it handle the
require 'open-uri'
open 'http://home.earthlink.net/~dave_gemini/demo.in'
data which has some unequal (u,v) sets? -- see the 19th
post in http://tinyurl.com/2pw22q
Later,
--
Bil
Aaron Patterson wrote:
I'm confused as to why the data needs to be retained in memory..... But
here is a little something I put together. It does maintain the
datastructures in memory before calculating the results.
No prize for Phil, he didn't tweak the time output line
or echo the U and V lines...
Later,
--
Bil Kleb
http://fun3d.larc.nasa.gov
Sure can. Try it out.
James Edward Gray II
On Nov 12, 2007, at 8:10 AM, Bil Kleb wrote:
James Edward Gray II wrote:
That little challenge made me wish for some Ruby 1.9 elements, like an ordered Hash.
Nice; can it handle the
require 'open-uri'
open 'http://home.earthlink.net/~dave_gemini/demo.in'data which has some unequal (u,v) sets?
James Edward Gray II wrote:
Nice; can it handle the data which has some unequal (u,v) sets?
Sure can. Try it out.
Sure enough. Why didn't you use a case? E.g.,
require 'open-uri'
us, vs = Array.new, Array.new
open 'http://home.earthlink.net/~dave_gemini/demo.in' do |ios|
ios.each_line do |line|
case line
when /time\s*:\s*(.*)/ then # output time
puts "for time #{$1}"
puts
when /(U|V)(.*?)\s*=\s*([\d.]+)/ then # capture and echo U & V lines
($1 == "U" ? us : vs) << [ $2, $3.to_f ]
puts line
when /^\s*$/, ios.eof? then # output UVs and reset U & V arrays
next if us.empty? or vs.empty?
us.each do |coordinates, u|
next unless v = vs.assoc(coordinates)
puts "UV%s = %7.3f" % [coordinates, u * v.last]
end
puts
[us, vs].each { |array| array.clear }
end
end
end
Later,
James Edward Gray II wrote:
Nice; can it handle the data which has some unequal (u,v) sets?
Sure can. Try it out.
Sure enough. Why didn't you use a case? E.g.,
Well, I don't think it's the same. Is it?
case line
when /^\s*$/, ios.eof? then # output UVs and reset U & V arrays
Won't that check if the contents of line match the Regexp or if the contents of line match the true/false returned by eof?(). That's not what we want.
James Edward Gray II
On Nov 12, 2007, at 7:11 PM, Bil Kleb wrote:
On Nov 12, 2007, at 8:10 AM, Bil Kleb wrote:
James Edward Gray II wrote:
Well, I don't think it's the same. Is it?
Seems to work at least according to the anti-pattern of
testing: guru scans output.
when /^\s*$/, ios.eof? then # output UVs and reset U & V arrays
Won't that check if the contents of line match the Regexp or if the contents of line match the true/false returned by eof?(). That's not what we want.
You're of course correct, but apparently the ios.eof? isn't
needed anyway... In fact, simply
else # output UVs and reset U & V arrays
is sufficient because of your
next if us.empty? or vs.empty?
Later,
--
Bil Kleb
http://fun3d.larc.nasa.gov
That's true only if the document contains a blank line after all of the data. My pasted content from the original email did not, so that didn't seem a safe assumption to make.
James Edward Gray II
On Nov 12, 2007, at 9:05 PM, Bil Kleb wrote:
James Edward Gray II wrote:
when /^\s*$/, ios.eof? then # output UVs and reset U & V arrays
Won't that check if the contents of line match the Regexp or if the contents of line match the true/false returned by eof?(). That's not what we want.
You're of course correct, but apparently the ios.eof? isn't
needed anyway... In fact, simplyelse # output UVs and reset U & V arrays
is sufficient because of your
next if us.empty? or vs.empty?
James Edward Gray II wrote:
That's true only if the document contains a blank line after all of the data. My pasted content from the original email did not, so that didn't seem a safe assumption to make.
Roger.
Later,
--
Bil Kleb
http://fun3d.larc.nasa.gov