Use file's contents in Ruby - ruby

My "information" file includes following hash.
student_balances = {"Jane Doe"=>1000, "Jim Doe"=>6200, "John Newman"=>73282, "Leonard Smith"=>3992, "Loe Newton"=>5643, "Eric"=>34234}
I want to import this "information" file into my main program and use its contents right away.
file_location = "Ruby/account.rb"
f = File.open(file_location, "r+")
student_balances.each do |key, value|
puts "#{key} : #{value}"
end
I can't figure out how.

I would suggest to store the data in another format like YAML. It is more readable and easier to write:
# in balances.yml
"Jane Doe": 1000
"Jim Doe": 6200
"John Newman": 73282
"Leonard Smith": 3992
"Loe Newton": 5643
"Eric": 34234
Read the file with:
require 'yaml'
balances = YAML.load_file('balances.yml')

When the input files contains the following string and you will like
to import the string in a ruby variable you first have to evaluate the
string. Then you can use the variables as an array
student_balances = nil
DATA.readline.each do | line |
eval line
puts student_balances
end
__END__
student_balances = {"Jane Doe"=>1000, "Jim Doe"=>6200, "John Newman"=>73282, "Leonard Smith"=>3992, "Loe Newton"=>5643, "Eric"=>34234}

Related

removing escape characters when parsing a string from file

I'm trying to read from a file a string that interpolates variables which are defined in the code, and substitutes the string value of those variables.
The text file:
my name is #{name}
the code:
file = File.open("tesst.txt", "r")
arr = []
name = "CDJ"
file.each_line.with_index { |line, index|
puts line
}
file.close
Desired output:
My name is CDJ
Actual output:
My name is #{name}
When output is line.inspect:
"My name is \#{name}"
Can anyone help me format this string correctly so it reads #{name} as a variable instead of a string with the inserted escape character?
file= 'tesst.txt'
name = 'CDJ'
File.readlines(file).each do |line|
eval("puts \"#{line}\"")
end
Consider this:
class Template
def initialize(source: DATA)
#text = source.read.chomp.split("\n")
end
def render(locals: {})
locals.each do |key, value|
instance_variable_set("##{key}", value)
self.class.send(:attr_reader, key)
end
#text
.map { |line| eval("\"#{line}\"") }
.join("\n")
end
end
puts Template
.new(source: File.open('./tesst.txt', 'r'))
.render(locals: {name: 'George', age: 29})
__END__
my name is #{name}
I am #{age} years old
Notes:
Variables can be provided through the hash.
File can be switched with DATA to read contents from bottom of file after __END__

How can I remove escape characters from string? UTF issue?

I've read in a XML file that has lines such as
<Song name="Caught Up In You" id='162' duration='276610'/>
I'm reading in the file with
f=File.open(file)
f.each_with_index do |line,index|
if line.match('Song name="')
#songs << line
puts line if (index % 1000) == 0
end
end
However when I try and use entries I find that get text with escaped characters such as:
"\t\t<Song name=\"Veinte Anos\" id='3118' duration='212009'/>\n"
How can I eliminate the escape characters either in the initial store or in the later selection
#songs[rand(#songs.size)]
ruby 2.0
Your text does not have 'escape' characters. The .inspect version of the string shows these. Observe:
> s = gets
Hello "Michael"
#=> "Hello \"Michael\"\n"
> puts s
Hello "Michael"
> p s # The same as `puts s.inspect`
"Hello \"Michael\"\n"
However, the real answer is to process this XML file as XML. For example:
require 'nokogiri' # gem install nokogiri
doc = Nokogiri.XML( IO.read( 'mysonglist.xml' ) ) # Read and parse the XML file
songs = doc.css( 'Song' ) # Gives you a NodeList of song els
puts songs.map{ |s| s['name'] } # Print the name of all songs
puts songs.map{ |s| s['duration'] } # Print the durations (as strings)
mins_and_seconds = songs.map{ |s| (s['duration'].to_i/1000.0).divmod(60) }
#=> [ [ 4, 36.6 ], … ]

Ruby retrieve data from file after specific label

How can I get specific data from a file in ruby? I want to get some 10. ip addresses from a file set up like this...
Whatever: xathun
ip_address: 10.2.232.6
etc: aouoeu
more: snthuh
I want to push the ip addresses into an array.
I can pull 10. addresses out of text. I was hoping for a more accurate way to do it as in only the data after the 'ip_address:' label in case there is unwanted matching data.
s_text = File.open("test.txt",'r').read
ip_addresses = s_text.scan(/\d+.\d+.\d+.\d+/)
puts ip_addresses.inspect #=> ["10.2.232.6"]
Here's a simple enough solution.
open('<textfile path>') { |f| puts f.grep(/10\./) }
If the file is setup like that throughout you can do:
arr = []
File.open("text").each_line do |line|
parts = line.split(":")
arr << parts[1].strip if parts[0] == "ip_address"
end
adding to array as you go through once, one line at a time:
ip_data.txt
Whatever: xathun
ip_address: 10.2.232.6
etc: aouoeu
more: snthuh
Whatever: badone
ip_address: 66.8.103.3
etc: huh
more: noooo
Whatever: blah
ip_address: 10.9.244.13
etc: hello
more: goodbye
code
found_tens = []
File.open('ip_data.txt') {|f|
f.each {|line|
line = line.chomp
next if line.empty?
found_tens << $1 if line =~ /^ip_address:\s+(10\.\d+\.\d+\.\d+)/
}
}
p found_tens #["10.2.232.6", "10.9.244.13"]

Taking multiple lines from a file and creating hash

I'm taking a file and reading in it's contents and creating a hash based on newlines. I've been able to make a hash based on the contents of each line, but how can I create a hash based on the content of everything before the next blank newline? Below is what I have so far.
Input:
Title 49th parallel
URL http://artsweb.bham.ac.uk/
Domain artsweb.bham.ac.uk
Title ABAA booknet
URL http://abaa.org/
Domain abaa.org
Code:
File.readlines('A.cfg').each do |line|
unless line.strip.empty?
hash = Hash[*line.strip.split("\t")]
puts hash
end
puts "\n" if line.strip.empty?
end
Outputs:
{"Title"=>"49th parallel"}
{"URL"=>"http://artsweb.bham.ac.uk/"}
{"Domain"=>"artsweb.bham.ac.uk"}
{"Title"=>"ABAA booknet"}
{"URL"=>"http://abaa.org/"}
{"Domain"=>"abaa.org"}
Desired Output:
{"Title"=>"49th parallel", "URL"=>"http://artsweb.bham.ac.uk/", "Domain"=>"artsweb.bham.ac.uk"}
{"Title"=>"ABAA booknet", "URL"=>"http://abaa.org/", "Domain"=>"abaa.org"}
Modifying your existing code, this does what you want:
hash = {}
File.readlines('A.cfg').each do |line|
if line.strip.empty?
puts hash if not hash.empty?
hash = {}
puts "\n"
else
hash.merge!(Hash[*line.strip.split("\t")])
end
end
puts hash
You can likely simplify that depending on what you're actually doing with the data.
open('A.cfg', &:read)
.strip.split(/#$/{2,}/)
.map{|s| Hash[s.scan(/^(\S+)\s+(\S+)/)]}
gives
[
{
"Title" => "49th",
"URL" => "http://artsweb.bham.ac.uk/",
"Domain" => "artsweb.bham.ac.uk"
},
{
"Title" => "ABAA",
"URL" => "http://abaa.org/",
"Domain" => "abaa.org"
}
]
read the whole content of the file using read:
contents = ""
File.open('A.cfg').do |file|
contents = file.read
end
And then split the contents on two newline characters:
contents.split("\n\n")
And lastly, create a function pretty similar to what you already have to parse those chunks.
Please note that if you are working on windows it may happen that you need to split on a different sequence because of the carriage return character.

Can't correctly use external text file the way I used a literal list

I move a comparison of a list of words to a text file which I now try to bring in using IO.gets on each line. This has completely altered my results.
Basically I'm using a Trie to figure out if a prefix is inside a word - now my output is only showing the prefixes which means none of them are "matching" correctly and defaulting to returning all of the prefixes.
Is this an encoding issue or what's going on?
Here's the specific code I'm speaking of - so as opposed to:
sources = ['Bash', 'cplusplus', 'java', 'javascript', 'php', 'python', 'ruby']
prefixes = ['ab', 'ba', 'bu', 'Jav', 'ph', 'ru', 'ze']
I do this now:
def fileList(dir, array)
file = File.new(dir, "r")
while (line = file.gets)
array << line
end
end
sources = Array.new
prefixes = Array.new
fileList("../lists/sources.list", sources)
fileList("../lists/prefixes.list", prefixes)
With each element having its own line in the text file
https://github.com/jphenow/merge_prefix/tree/master/ruby
Thanks a ton for any help!
It's not real clear what you are trying to accomplish, but here's how to read the lines of files and append them to an array, which is a common-enough task:
The source files look like:
sources.list:
Bash
cplusplus
java
javascript
php
python
ruby
and
prefixes.list:
ab
ba
bu
Jav
ph
ru
ze
The code looks like:
require 'pp'
def fileList(dir, array)
array += File.readlines(dir).map(&:chomp)
end
sources = Array.new
prefixes = Array.new
pp fileList("sources.list", sources)
pp fileList("prefixes.list", prefixes)
=> ["Bash", "cplusplus", "java", "javascript", "php", "python", "ruby"]
=> ["ab", "ba", "bu", "Jav", "ph", "ru", "ze"]
Try this:
def file_list(dir, array)
Dir.chdir dir
Dir.glob("*").each{|file| array << file}
end
It's unusual for a method to change a variable's value but it will happen because of a quirk of array#<<. It's more common for the method to return the value:
def file_list(dir, array)
Dir.chdir dir
array + Dir.glob("*")
end
sources = fileList("./somedir", sources)

Resources