output of a method to file?

Z

Zoe Phoenix

Can anybody tell me how to take the output of a method and save it to a
file?

I have an array and I've created a method to take the strings I put into
the array and insert them into a place in a sentence. How do I execute
the method and save the output to a file? I just started with Ruby a
few days ago and I can have it save a file, but the file it saves is
empty.

Help, please?
 
P

Phillip Gawlowski

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Zoe Phoenix wrote:
| Can anybody tell me how to take the output of a method and save it to a
| file?
|
| I have an array and I've created a method to take the strings I put into
| the array and insert them into a place in a sentence. How do I execute
| the method and save the output to a file? I just started with Ruby a
| few days ago and I can have it save a file, but the file it saves is
| empty.
|
| Help, please?

Sure:
irb(main):003:0> to_file = [1,2,3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):004:0> File.open("a_file.txt","w") do |f|
irb(main):005:1* f.write to_file
irb(main):006:1> end
=> 5
irb(main):007:0> exit

C:\temp>cat a_file.txt
12345

Let's walk a bit through the code:
to_file is your average Array.

The File class allows you to interact with files (most commonly, reading
and writing).

Fil.open("a_file.txt","w") opens a file called "a_file.txt" in write
mode (the "w"). It's important to tell Ruby the mode you want to use.
"r" is the mode to read files, "a" is the mode to append to a file, and
Windows has the mode "b" to handle binary files.
You can find a quick reference for that here:
http://www.zenspider.com/Languages/Ruby/QuickRef.html#14

The |f| is a bloack variable. I use that in the next line, to actually
write to the file:
f.write to_file This writes the content of the Array to a file. Note
that the Array is dumped similar to Array#join "". You'll have to add
line breaks somehow, if you want lines.

Anyway: This step in the block writes to the file.

end closes the block, and with that, Ruby takes care of closing the
file, too, so that you don't have to.

I hope that helps. (I have to look it up myself, more often than I would
like).

- --
Phillip Gawlowski
Twitter: twitter.com/cynicalryan

~ YAAH! DEATH TO OATMEAL!
-- Calvin
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkf8BVcACgkQbtAgaoJTgL8HJACgjQcC3qMkIpm+VXUN0E/PdmUy
/dwAn3q5ECZNyH8bGwk9brT9sJmSZoOx
=z49y
-----END PGP SIGNATURE-----
 
Z

Zoe Phoenix

Maybe it would help if I posted the code, I'm not sure I understand...
For example..:


def cityList
c_list = ['Boston', 'Nashville', 'San Francisco', 'Houston', 'Portland',
'Atlanta', 'Chicago', 'Indianapolis', 'Charleston']

bar = '|| '


puts bar + c_list[0..2].join(' pets || ') + (' pets ||')

puts bar + c_list[3..5].join(' pets || ') + (' pets ||')

puts bar + c_list[6..8].join(' pets || ') + (' pets ||')

end

cityList


puts 'File completed. Save as..?'
save_as = gets.chomp



File::eek:pen('c:\rubyfiles\citylist-' + save_as + '.txt', 'w') do |f|


***********

I need it to take the output of that method that I created and write it
to a file... I'm not sure I understand how to do that with the example
you gave. Since I know the code that I had after "File::eek:pen", etc. was
wrong, I just left it out.

It would also be nice if I could have the method cycle through 3 items
in the array, then write 3 to a new line, the continue in increments of
3 until it reaches the end of the array. But, I'm not sure if I should
write another topic to ask that or if someone will answer that here.
Thanks for the help so far, though... I'm pretty new at this.
 
P

Phillip Gawlowski

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Zoe Phoenix wrote:
| Maybe it would help if I posted the code, I'm not sure I understand...
| For example..:
|
|
| def cityList
| c_list = ['Boston', 'Nashville', 'San Francisco', 'Houston', 'Portland',
| 'Atlanta', 'Chicago', 'Indianapolis', 'Charleston']
|
| bar = '|| '
|
|
| puts bar + c_list[0..2].join(' pets || ') + (' pets ||')
|
| puts bar + c_list[3..5].join(' pets || ') + (' pets ||')
|
| puts bar + c_list[6..8].join(' pets || ') + (' pets ||')
|
| end
|
| cityList
|
|
| puts 'File completed. Save as..?'
| save_as = gets.chomp
|
|
|
| File::eek:pen('c:\rubyfiles\citylist-' + save_as + '.txt', 'w') do |f|
|
|
| ***********
|
| I need it to take the output of that method that I created and write it
| to a file... I'm not sure I understand how to do that with the example
| you gave. Since I know the code that I had after "File::eek:pen", etc. was
| wrong, I just left it out.

If it is allowed, I'll add some Ruby idioms (you'll find these often,
and will find them useful, I hope).

I saved your file as "saving.rb", and it now produces the following:

File completed. Save as..?
temp #that's the name I saved the file as

C:\temp>less c:\rubyfiles\citylist-temp.txt # This is how the file looks.
|| Boston pets || Nashville pets || San Francisco pets ||
|| Houston pets || Portland pets || Atlanta pets ||
|| Chicago pets || Indianapolis pets || Charleston pets ||

This is the reworked script:

def cityList
~ c_list = [
~ 'Boston',
~ 'Nashville',
~ 'San Francisco',
~ 'Houston',
~ 'Portland',
~ 'Atlanta',
~ 'Chicago',
~ 'Indianapolis',
~ 'Charleston'
~ ] # I just changed that for readability.

~ bar = '|| ' # I left this, too.

~ temp_array = [] #This is a temporary array,
#I use to store the results.
~ temp_array.push bar + c_list[0..2].join(' pets || ') + (' pets ||') +
"\n" # This pushes the result of into the Array. It gets stored at the
first index of the Array. You could access it via temp_array[0].

~ temp_array.push bar + c_list[3..5].join(' pets || ') + (' pets ||') +
"\n" #This does something similar, except that it is stored at the next
Array index, temp_array[1]

~ temp_array.push bar + c_list[6..8].join(' pets || ') + (' pets ||') +
"\n" # See above, except this time it is temp_array[2]. Notice that I
added "\n" to your code. This adds a new line. Just delete it, if you
don't want the whole output on a new line, or just leave the last one,
if every iteration shall be on a new line.

end

puts 'File completed. Save as..?'
save_as = gets.chomp

File.open("c:/rubyfiles/citylist-#{save_as}.txt","w") do |f| # Here, I
used string-interpolation, which only works with the double quotes (").
~ f.write cityList #This is a bit complex. f.write takes the result of
cityList, and writes it to a file. In Ruby, every method returns its
last action, so to speak. In this case, it is the Array with all three
lines. Also notice, that you don't have to use File::eek:pen, but that
should work, too.
end #ending the block again, and closing the file.

I hope that helps (In case it's not really readable, just copy and paste
the code into your favorite editor).


| It would also be nice if I could have the method cycle through 3 items
| in the array, then write 3 to a new line, the continue in increments of
| 3 until it reaches the end of the array. But, I'm not sure if I should
| write another topic to ask that or if someone will answer that here.

Let me repeat, to see if I got that correctly:
You want to do cityList three times, and write all of these iterations
into 3 seperate files?

In that case, you could just wrap the File.open[..] part into a loop.
Like 3.times do
File.open[...]
end

| Thanks for the help so far, though... I'm pretty new at this.

We all were, at one time. :)

I hope I can help you out.

In case you haven't found it: Chris Pine's Learn to Program helped me a
lot: pine.fm/LearnToProgram/

And _why's Piognant Guide to Ruby is good, too (although a bit..
strange): http://poignantguide.net/ruby/

- --
Phillip Gawlowski
Twitter: twitter.com/cynicalryan

~ There's never enough time to do all the nothing you want.
-- Calvin
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkf8D6YACgkQbtAgaoJTgL8QbACdFn8p3d/haXRpq/lyh41TYEQl
s70AmgKb5gJaaLJSpsTkESefcjWUDXNb
=TrpN
-----END PGP SIGNATURE-----
 
Z

Zoe Phoenix

hm, let me re-phrase... I only have 9 items in that array, right? How
do I make the program continue through the array no matter how many
items are in it without having to go and edit the array that comes after
c_list?

~~temp_array.push c_list[0..2].join(' pets || ') + (' pets ||') +
"\n"

Like, say I added 3 more cities to the end of c_list, but I don't want
to have to add

~~temp_array.push c_list[9..11].join(' pets || ') + (' pets ||') +
"\n"


to the program. How can I make it cycle through the whole array without
having to edit c_list[number..number]? Is there a way to automate that,
so I only have to add cities to c_list without having to add more code?


And thanks, I've already found Mr. Pine's Learn To Program site and the
Poignant Guide.. :) They've been a big help. I've tried to learn other
programming languages, but Ruby's been the easiest for me to understand.
 
P

Phillip Gawlowski

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Zoe Phoenix wrote:
| hm, let me re-phrase... I only have 9 items in that array, right? How
| do I make the program continue through the array no matter how many
| items are in it without having to go and edit the array that comes after
| c_list?

Oh, indeed you can.Array provides the #each and #each_with_index methods:

irb(main):001:0> array = [1,2,3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):002:0> array.each{|a| puts a}
1
2
3
4
5
=> [1, 2, 3, 4, 5]

The above is Array#each. It allows you to operate on each element of
your array.


irb(main):003:0> array.each_with_index{|a,b| puts a;puts b}
1
0
2
1
3
2
4
3
5
4
=> [1, 2, 3, 4, 5]

Here, you get the current index, too (that is the second variable, I've
called b). This, of course, works with Strings also (like your city names).

Together with the % (modulo) operator, you can test if the index can be
divided by 3 without a remainder, so that you can add a new line after
the third element.

If that doesn't help you write your own code, I'll be happy to provide
an annotated example again.

- --
Phillip Gawlowski
Twitter: twitter.com/cynicalryan

~ - You know you've been hacking too long when...
...after days with YACC, you start to parse your conversations.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkf8GB4ACgkQbtAgaoJTgL9zyQCeKQLqgqQeD0RVWNqfSTMvezGs
7s8An1+IBecl8DQREtIvJ/A9+68F5cyT
=gdIk
-----END PGP SIGNATURE-----
 
Z

Zoe Phoenix

I think I understand what you're saying, but I'm not quite sure how to
apply it...
 
P

Phillip Gawlowski

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Zoe Phoenix wrote:
| I think I understand what you're saying, but I'm not quite sure how to
| apply it...

Let me show you an example:

irb(main):001:0> array = ["a","b","c","d","e"]
=> ["a", "b", "c", "d", "e"]
irb(main):002:0> array.each_with_index do |item, index|
irb(main):003:1* puts item if index % 3 == 0
irb(main):004:1> end
a
d
=> ["a", "b", "c", "d", "e"]

In this example, only the elements at an index that can be divided by 3
without a problem are printed. You can achieve a similar effect with a
counter, for example.

(My idea to use modulo was a bit off, sorry about that).

Translated to your problem:
saving.rb:

c_list = [
~ 'Boston',
~ 'Nashville',
~ 'San Francisco',
~ 'Houston',
~ 'Portland',
~ 'Atlanta',
~ 'Chicago',
~ 'Indianapolis',
~ 'Charleston'
~ ]

counter = 1
temp_array = []
c_list.each_with_index do |item,index|
~ temp_array.push "|| " if index % 3 == 0
~ temp_array.push "#{item} "
~ temp_array.push "pets ||"
~ temp_array.push "\n" if counter % 3 == 0
~ counter +=1
end
puts 'File completed. Save as..?'
save_as = gets.chomp


File.open("c:/rubyfiles/citylist-#{save_as}.txt","w") do |f|
~ f.write temp_array
end

What am I doing here (this is a very naive implementation, nothing
fancy, but it does what it is supposed to do)?

First, I create the array of cities (you can get fancy later on, and
read it from a file, too).

Then, I create a counter to help me later on, as well as an empty array.

After that, I iterate over the c_list array with the help of the
each_with_index method.

Now the fun starts:


temp_array.push "|| " if index % 3 == 0

This only gets done, in the case that I can divide the index by 3
without a remainder. This works with 0, so I get the "|| " part.


temp_array.push "#{item} "

This uses Ruby's String interpolation to create, for example, "Boston ".
String interpolation allows you to execute Ruby code within Strings,
roughly speaking. You can test that by doing puts "#{Time.now}" in irb,
for example.


temp_array.push "\n" if counter % 3 == 0

This pushes the newline character into the array for file output, in the
case that the counter variable I introduced earlier can be divided by 3
without a remainder.

This should give you at least a starting point, in case I missed what
you wanted.

File block you already know. :)

HTH,
- --
Phillip Gawlowski
Twitter: twitter.com/cynicalryan

~ - You know you've been hacking too long when...
...you begin to think in nested IF-THEN-ELSE clauses that would make a
bureaucrat get lost.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkf8Ku8ACgkQbtAgaoJTgL+wMwCdEFdqJL6WyzUsNvZWTBjjc8Hh
cqEAn2xcrv7D4uUwuMyc8GwvtptoYdbG
=c3il
-----END PGP SIGNATURE-----
 
Z

Zoe Phoenix

hmm, I see what you're doing there...

I still can't seem to get the file block to actually write the output of
the method to a file. The file it writes still comes up empty...
 
P

Phillip Gawlowski

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Zoe Phoenix wrote:
| hmm, I see what you're doing there...
|
| I still can't seem to get the file block to actually write the output of
| the method to a file. The file it writes still comes up empty...

Are you explicitly calling the #write method? puts doesn't work (I fall
for that trap 9 times out of 10), unfortunately.

And are you opening the file in write / append mode?

Are you getting any errors from Ruby?

- --
Phillip Gawlowski
Twitter: twitter.com/cynicalryan

Each module should do one thing well.
~ - The Elements of Programming Style (Kernighan & Plaugher)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkf8O/gACgkQbtAgaoJTgL+dYQCfenNkS+BvQW72NyRc+Ofkuwcj
GXMAnRjJFTwjBBihHeU+k/AhtSQZ7d2n
=Mmvh
-----END PGP SIGNATURE-----
 
Z

Zoe Phoenix

def cityList
c_list = [
'Boston',
'Nashville',
'San Francisco',
'Houston',
'Portland',
'Atlanta',
'Chicago',
'Indianapolis',
'Charleston'
]

bar = '|| '

temp_array = []

temp_array.push puts bar + c_list[0..2].join(' pets || ') + (' pets
||'+'/n')

temp_array.push puts bar + c_list[3..5].join(' pets || ') + (' pets
||'+'/n')

temp_array.push puts bar + c_list[6..8].join(' pets || ') + (' pets
||'+'/n')

end



puts 'File completed. Save as..?'
save_as = gets.chomp



File::eek:pen("c:\rubyfiles\citylist-#{save_as}.txt", 'w') do |f|
f.write cityList

end

********

This is the error it gives me...:

directory\rubyprograms\cities.rb:33:in 'initialize':
ubyfiles tylist-city1.txt (Errno::EINVAL)
from directory\rubyprograms\cities.rb:33:in
'open'
from directory\rubyprograms\cities.rb:33

********


There's something wrong with the code, I know, but I'm not sure what.
 
P

Phillip Gawlowski

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Zoe Phoenix wrote:

| directory\rubyprograms\cities.rb:33:in 'initialize':
| ubyfiles tylist-city1.txt (Errno::EINVAL)
| from directory\rubyprograms\cities.rb:33:in
| 'open'
| from directory\rubyprograms\cities.rb:33
|
| ********
|
|
| There's something wrong with the code, I know, but I'm not sure what.

Yes, but something simple, actually, and easy to fix:

Ruby, like other programming languages, uses the backslash "\" as an
escape character. That means (in simple terms), Ruby ignores the
character directly after the backslash. Usually, because that character
means something special. An example is the newline character "\n", which
produces a newline in a file or screen output, for example. (Like
pressing enter, just done by Ruby).

printf "This text has\na new line" #demonstrates the \n character.

You have two options: You can change your back slashes to forward
slashes (from \ to /), or add another backslash to escape your backslashes:

This happens when you try to open the file to write into it.

The possible solutions:
File::eek:pen("c:\\rubyfiles\\citylist-#{save_as}.txt", 'w') #Escaping the
backslashes
File::eek:pen("c:/rubyfiles/citylist-#{save_as}.txt", 'w') #Using forward
slashes

Both solutions are fine. Windows can handle forward slashes, too (at
least in Windows XP).

I hope that helps. :)

- --
Phillip Gawlowski
Twitter: twitter.com/cynicalryan

~ - You know you've been hacking too long when...
...after days with YACC, you start to parse your conversations.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkf8YhEACgkQbtAgaoJTgL9e7wCgjK7dGrSuohp0WJMBvUoIPfaw
7zYAnjKMnookgkBPjZygZDlnnslVtS0y
=wcVf
-----END PGP SIGNATURE-----
 
Z

Zoe Phoenix

Alright, I fixed the problem with the backslashes, but it's still
returning an empty file... it shows the output in the command line and
creates a file now, but it's still empty. :-/


I decided to go ahead and fix the file saving problem first before I
move on to the other part of it, so here's the original code. The output
is correct, but something's preventing it from being put into the file
it creates.



c_list = [
'Boston',
'Nashville',
'San Francisco',
'Houston',
'Portland',
'Atlanta',
'Chicago',
'Indianapolis',
'Charleston'
]

bar = '|| '

temp_array = []

temp_array.push puts bar + c_list[0..2].join(' pets || ') + (' pets
||'+ "\n")

temp_array.push puts bar + c_list[3..5].join(' pets || ') + (' pets
||'+"\n")

temp_array.push puts bar + c_list[6..8].join(' pets || ') + (' pets
||'+"\n")


puts 'File completed. Save as..?'
save_as = gets.chomp



File::eek:pen("c:\\rubyfiles\\citylist-#{save_as}.txt", 'w') do |f|
f.write temp_array

end


What am I doing wrong?? :-(
 
P

Peña, Botp

RnJvbTogWm9lIFBob2VuaXggW21haWx0bzpkYXJrX3NndHBob2VuaXhAaG90bWFpbC5jb21dIA0K
IyBXaGF0IGFtIEkgZG9pbmcgd3Jvbmc/PyA6LSgNCg0KbG9vayBhdCB0aGUgY29udGVudHMgb2Yg
dGVtcF9hcnJheS4NCg0KaGludDoNCg0KaXJiKG1haW4pOjAwNTowPiBwdXRzICJmb28iDQpmb28N
Cj0+IG5pbA0KDQppcmIobWFpbik6MDA2OjA+IFtdLnB1c2ggcHV0cygiZm9vIikNCmZvbw0KPT4g
W25pbF0NCg0Ka2luZCByZWdhcmRzIC1ib3RwDQo=
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top