Having Ruby fun with the comp.lang.fortran folks:
http://tinyurl.com/38o8ex
http://tinyurl.com/2pw22q
Please riff a better Ruby answer…
Regards,
Having Ruby fun with the comp.lang.fortran folks:
http://tinyurl.com/38o8ex
http://tinyurl.com/2pw22q
Please riff a better Ruby answer…
Regards,
On Mon, Nov 12, 2007 at 10:30:06AM +0900, Bil K. wrote:
Having Ruby fun with the comp.lang.fortran folks:
http://tinyurl.com/38o8ex
http://tinyurl.com/2pw22qPlease 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
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 12:20:32PM +0900, Aaron P. wrote:
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
Oops. @time should be nil, but that shouldn’t change the output…
On Nov 11, 2007, at 7:30 PM, Bil K. wrote:
Having Ruby fun with the comp.lang.fortran folks:
http://tinyurl.com/38o8ex
http://tinyurl.com/2pw22qPlease riff a better Ruby answer…
That little challenge made me wish for some Ruby 1.9 elements, like
an ordered Hash.
James Edward G. 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
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 K. 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_valuev_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 K. 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.
James Edward G. 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,
On Nov 12, 2007, at 8:10 AM, Bil K. wrote:
James Edward G. 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?
Sure can. Try it out.
James Edward G. II
James Edward G. II wrote:
On Nov 12, 2007, at 8:10 AM, Bil K. 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,
Aaron P. 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,
On Nov 12, 2007, at 7:11 PM, Bil K. wrote:
James Edward G. II wrote:
On Nov 12, 2007, at 8:10 AM, Bil K. 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 G. II
James Edward G. 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,
James Edward G. 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,
On Nov 12, 2007, at 9:05 PM, Bil K. wrote:
is sufficient because of your
next if us.empty? or vs.empty?
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 G. II
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.
Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs