Hash keys

Morning,

I am working on some code to gather accounts and their balances from a
text
file and have a question about adding that data to a hash. While
checking
to see if the account number is a key in the existing hash using
has_key?(key), can¹t I use the variable that has the account number in
it or
do I have to use the actual account number? When I run my code to check
it I
get undefined method `has_key?’ for nil:NilClass. I ran a test using
just
the account number in irb and it works but I would think you could use a
variable to iterate of my list of account numbers… Thanks in advance

class Info
attr_reader :acct, :money

def initialize(filename)
@acct = File.new(filename, “r”)
end
f = Info.new(“Balances20080415.txt”)
act = f.acct
act.each do |list|
#covert me to a string
futbal = list.to_s
#Pull accounts
office = futbal[21…23]
if office == “RPT”
next
else
acctnum = futbal[24…28]
lv = futbal[217…230]
lvind = futbal[215…215]
lvadd = lvind+lv
lvadd.to_f/100
end
#if Negitave vlaues
if lvind == “-”
lvnegfloat = lv.to_f/100
#print acctnum," “,lvind, lvnegfloat, “\n”
#puts lvadd
sktylist = Hash.new(”")
#if(sktylist.has_key?(23))
# sktylist = { acctnum => lvind,lvnegfloat }

          sktylist[acctnum] = lvind,lvnegfloat
          sktylist.each { |key, value| puts "#{key} equals #{value}" 

}
#else Positive Values

        elsif sktylist.has_key?('acctnum')
                puts "found #{key}second key"
            #lvposflt = lv.to_f/100

            #print acctnum, " ", lvposflt, "\n"
          end
        end

end

On Apr 24, 9:11 am, Tim W. [email protected] wrote:

    futbal = list.to_s
    end
          sktylist.each { |key, value| puts "#{key} equals #{value}" }

end
Your if clauses looked messed up. The no method error doesn’t have
anything to do with the key of has_key. You actually have no hash to
speak of.

T.

    futbal = list.to_s
    end
          sktylist.each { |key, value| puts "#{key} equals #{value}" }

end

Your if clauses looked messed up. The no method error doesn’t have
anything to do with the key of has_key. You actually have no hash to
speak of.

T.

The first if does return a hash with the keys and values so I know that
works. The first one is for any negative values as it is only indicated
by
a 0 or a - in position 215 of the string. The second if is for the
positive
values, so I’m guessing that when the script is processing the lines and
has
a positive value its not skipping the negative if and going to the elsif
to
process and store the info in the hash.

Basically what I’m trying to do here is gather the account balances and
account numbers and store them in a hash and if there are accounts with
the
same number to store their balances as an array in the hash value to add
them later when I iterate over the hash.

If there is a better way to do this that I’m not thinking of please
share
with me so I can better my ruby knowledge.

Thanks!
Tim

Tim W. wrote:

(…)
Basically what I’m trying to do here is gather the account balances and
account numbers and store them in a hash and if there are accounts with
the
same number to store their balances as an array in the hash value to add
them later when I iterate over the hash.

If there is a better way to do this that I’m not thinking of please
share
with me so I can better my ruby knowledge.

Thanks!
Tim

The following code does not store an array in a hash, it just stores a
running total:

DATA.gets
#DATA is the stuff below END
#you can treat it like a file.
#DATA.gets just gets the first line and ignores it.

totalled = Hash.new(0)
#Thanks to the (0) parameter, totalled will return 0 if a key is not
found.

DATA.each do |line|
ar_line = line.split(",")
account, balance = ar_line[0], ar_line[1].to_f
totalled[account] = totalled[account] + balance
#this line does the job. For the first line
#read in the loop, the key “101” is not found in the hash
#so it returns 0. Then the balance is added.
#The key and the new (running) balance are stored.
#A shorter way to write this is:
#totalled[account] += balance
end
p totalled

END
account,balance
101,100.00
102,500.00
101,-57.00
103,0.50
102,1

##end code

prints: {“101”=>43.0, “102”=>501.0, “103”=>0.5}

If you really need the hash with an array, replace the first line with:
totalled = Hash.new([])
(giving a ‘default value’ of an empty array); Also replace this line:
totalled[account] = totalled[account] + balance
with
totalled[account]=totalled[account]<<balance
HTH,

Siep

On Thu, Apr 24, 2008 at 9:40 AM, Tim W. [email protected] wrote:

them later when I iterate over the hash.

If there is a better way to do this that I’m not thinking of please share
with me so I can better my ruby knowledge.

Thanks!
Tim

Here are some ideas. You create the Hash using a block, this will
give you a default value for newly created hash pairs. You iterate
over the file line by line, you skip the lines that have an office
code of RPT. Otherwise, you pull out the account number and the
balance. You add the balance in to the hash pair for that account
number. If no values have been put in yet, you’ll add it to 0.
Otherwise, you’ll add it to the previous value. There is no need to
handle negative numbers in some special fashion, Ruby will know if
it’s a negative number when it sees the ‘-’ at the beginning of the
string.

I’m assuming you don’t want whatever is at position 216 to be part of
your balance, so you concatenate the character at 215 to the rest of
the balance in positions 217 to 230. You now have a string
representation of your balance, you call to_f on that and it will be a
positive or negative number.

act = File.new(“Balances20080415.txt”, ‘r’)

The default for a newly created value is 0

act.each do |list|

list already is a string, no need to

do this

futbal = list.to_s

#Pull accounts
office = list[21…23]
unless office == “RPT”
acctnum = list[24…28]
lvind = list[215,1]
lvnum = list[217…230]
lv = (lvind+lvnum).to_f/100
sktylist[acctnum] += lv
end
end

p sktylist