how remove puts inside method?

C

Carlos Delmar

I have a method (process_transaction) that uses puts to output a result.
Now I wanted to remove puts, so I could further process the result of
the method before printing it. But I can't get it to work ...

# method checks what key matches with string
# and adds additional info to each string def process_transaction
(line_of_file)

if get_money(line_of_file) < 0

Ausgabekonten.any? { |key, konto|
if key =~ line_of_file
kontonummer = extract_four_digit(konto)
puts line_of_file.chomp + " \"" + key.to_s + "\" " +
kontonummer.to_s + " 1200" + " AUSGABE"
break true
end
} or warn line_of_file.chomp + " (no key) \"\" \"\" \"\"
AUSGABE_NO_KEY"

else

Einnahmekonten.any? { |key, konto|
if key =~ line_of_file
kontonummer = extract_four_digit(konto)
puts line_of_file.chomp + " \"" + key.to_s + "\"" + " 1200 " +
kontonummer.to_s + " EINNAHME"
break true
end
} or warn line_of_file.chomp + " (no key) \"\" \"\" \"\"
EINNAHME_NO_KEY"

end

end

# apply process_transaction to each line of the transactions array

transactions.each do |member|
process_transaction(member)
end
 
C

Carlos Delmar

For example I would like to remove puts from the process_transaction
method and the do this:

transactions.each do |member|
puts process_transaction(member)
end

(sorry for the messy line breaks!)
 
R

Robert Klemme

Carlos said:
For example I would like to remove puts from the process_transaction
method and the do this:

transactions.each do |member|
puts process_transaction(member)
end

(sorry for the messy line breaks!)

I'm not really sure what you're up to. Can you elaborate? The only thing
that comes to mind is that you probably want to use #each instead of #any?
because the latter is merely for identifying something and it does short
circuit (i.e. stop once the first block returns true).

Kind regards

robert
 
K

Kevin Olbrich

You could just mash the output into one long string...

output = ""
...
output << line_of_file.....
...
return output

Then return the string at the end of the function.
You may need to tack on some linefeeds at the end of each line.
 
A

ara.t.howard

For example I would like to remove puts from the process_transaction
method and the do this:

transactions.each do |member|
puts process_transaction(member)
end

(sorry for the messy line breaks!)

it's not puts that you need to mess with - it's stdout that needs capturing:

harp:~ > cat a.rb
require "yaml"
require "stringio"

def buffering_stdout
stdout, sio = $stdout, StringIO::new
begin
$stdout = sio
yield
sio.rewind
sio.read
ensure
$stdout = stdout
end
end

stdout =
buffering_stdout do
puts 42
p 42
printf "%d\n", 42
end

y "stdout" => stdout



harp:~ > ruby a.rb
stdout: |
42
42
42


regards.

-a
--
===============================================================================
| ara [dot] t [dot] howard [at] noaa [dot] gov
| all happiness comes from the desire for others to be happy. all misery
| comes from the desire for oneself to be happy.
| -- bodhicaryavatara
===============================================================================
 
C

Carlos Delmar

I'm not really sure what you're up to. Can you elaborate?

I'd like the output of process_transaction as a long string. But I don't
completely understand the post from Kevin:
output = ""
...
output << line_of_file.....
...
return output

where does this go?

If the method works I would like to apply it to each line of
transactions array and output the result to a new file.

here's the latest version of the script:
http://rafb.net/paste/results/D632e199.html
 
R

Robert Klemme

Carlos said:
I'd like the output of process_transaction as a long string. But I
don't completely understand the post from Kevin:


where does this go?

If the method works I would like to apply it to each line of
transactions array and output the result to a new file.

here's the latest version of the script:
http://rafb.net/paste/results/D632e199.html

The parts after "or" will never be called because each returns the
Enumerable. You have several options; one of is replacing "puts" by
"return" and remobing "or". In the calling block you can then process the
string return value as needed. For example you can do

puts transactions.map do |member|
process_transaction(member)
end

This will print each result on a single line. Or you can do

puts transactions.map do |member|
process_transaction(member)
end.join

to get a single long string.

There are lots of alternatives...

Kind regards

robert
 
C

Carlos Delmar

thanks Robert ... but it did not work out ...
The parts after "or" will never be called because each returns the Enumerable.

that was right, i replaced 'puts' after 'or' with 'warn' (which I had
removed by mistake)

Fnd a working script with some data here:

http://rafb.net/paste/results/2yJH7J28.html

BUT: I still would like to remove 'puts' and 'warn' in the
process_transaction method and would much prefer to 'puts' a resulting
string later in the transactions.each statement (or write that to a
file).
 
L

Lyndon Samson

------=_Part_62661_23650148.1136550646416
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
BUT: I still would like to remove 'puts' and 'warn' in the
process_transaction method and would much prefer to 'puts' a resulting
string later in the transactions.each statement (or write that to a
file).


A simple solution is you can allways stuff your output in an array.

out =3D []

out << "Message #{msg}"

out.each { |line| puts line }

You know you can return multiple values from a method right?

return out, retCode, a,b,c

------=_Part_62661_23650148.1136550646416--
 
K

Kevin Olbrich

Carlos said:
I'd like the output of process_transaction as a long string. But I don't
completely understand the post from Kevin:


where does this go?

If the method works I would like to apply it to each line of
transactions array and output the result to a new file.

here's the latest version of the script:
http://rafb.net/paste/results/D632e199.html

Just put this type of structure in whichever function you are trying to
capture the output of.

first line creates a string object, then you use the '<<' to append
output to that string, then you do something with the string when you
are done.
 
R

Robert Klemme

Carlos said:
thanks Robert ... but it did not work out ...


that was right, i replaced 'puts' after 'or' with 'warn' (which I had
removed by mistake)

Fnd a working script with some data here:

http://rafb.net/paste/results/2yJH7J28.html

BUT: I still would like to remove 'puts' and 'warn' in the
process_transaction method and would much prefer to 'puts' a resulting
string later in the transactions.each statement (or write that to a
file).

Somehow I find your design a bit contrived: you store your meta data in
strings and then have to extract what you need. It would be much cleaner
and simpler to directly store it, for example in arrays stored in hashes:


#!/usr/bin/ruby

# script should check if one of the keys in Ausgabekonten or
Einnahmekonten hash
# can be found in each line of the transactions array.
# If it does, it should print the matching key and value of the
Ausgabekonten hash.
# If it does not, it should print a warning.

Ausgabekonten = {
/BIO COMPANY / => ["1805", "Bio Company", "Lebensmittel"],
/KAISERS / => ["1805", "Bio Company", "Lebensmittel"],
/VINOTRIA / => ["1805", "Bio Company", "Lebensmittel"],
}

Einnahmekonten = {
/CLIENT_ONE/ => ["8300", "Client 1", "Erlöse 7% Ust"],
/CLIENT_TWO/ => ["8300", "Client 2", "Erlöse 7% Ust"],
}

transactions = [
'"30.12.2005" "30.12.2005" "VINOTRIA ITALIAN VINE STORE" "-20,00"
"EUR" "*"',
'"30.12.2005" "30.12.2005" "KAISERS FOOD" "-140,00" "EUR" "*"',
'"30.12.2005" "30.12.2005" "SOMETHING NEW" "900,00" "EUR" "*"',
'"30.12.2005" "30.12.2005" "CLIENT_ONE Job XY" "2.000,00" "EUR" "*"',
'"30.12.2005" "30.12.2005" "I DONT REMEMBER" "-300,00" "EUR" "*"',
'"30.12.2005" "30.12.2005" "CLIENT_TWO Job XY" "1.500,00" "EUR" "*"'
]

# method finds money snippet in string and converts it into a string
def find_money_string (string)

string.scan(/\"-?[0123456789]{0,3}.[0123456789]{0,3},[0-9][0-9]\"/).to_s.c
hop[1..-1]
end

# method changes string from german format (,.) to float (.)
def format_number(string)
string.tr(".", ";").tr(",", ".").tr(";", "").to_f
end

# extracts the 4 digit number from a string
def extract_four_digit(string)
string.to_s.scan(/[0-9][0-9][0-9][0-9]/)
end

# method extracts money of string
def get_money (string)
x = find_money_string(string)
format_number(x)
end

def parse(line)
line.scan(/"([^"]*)"/).map {|m| m[0]}
end

# method checks what key matches with string and adds additional info to
each string
def process_transaction (line_of_file)
date1, date2, text, amount, currency, rest = parse line_of_file
amount = amount.tr('.,', '_.').to_f

if amount < 0

key, info = Ausgabekonten.find { |key, konto| key =~ line_of_file }

if info
print line_of_file.chomp, " \"", info[1], "\" \"", info[0], "1200\n"
else
warn line_of_file.chomp + " (no
-- -- --"
end

else

key, info = Einnahmekonten.find { |key, konto| key =~ line_of_file }

if info
print line_of_file.chomp, " \"", info[1], "\" \"1200\" ", info[0],
"\n"
else
warn line_of_file.chomp + " (no
-- -- --"
end
end

end

# apply process_transaction to each line of the transactions array
transactions.each do |member|
process_transaction(member)
end

HTH

robert
 
C

Carlos Delmar

Thanks Robert! This works beautifull!

I have one question though. What exactly does the m[0]? Why zero?

def parse(line)
line.scan(/"([^"]*)"/).map {|m| m[0]}
end
 

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

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,160
Latest member
CollinStri
Top