From: Gawnsoft Date: 2003-08-02T00:12:39+09:00 Subject: Re: A bundle of newbie queries On Fri, 1 Aug 2003 21:30:19 +0900, dblack@superlink.net wrote (more or less): >On Fri, 1 Aug 2003, Gawnsoft wrote: >>... >> aDictionary = Hash.new(0) >> >> aFile.each_line { | eachLine | aDictionary[ /[0-9.]+/ ] = >> aDictionary[ /[0-9.]+/ ] + 1 if >> eachLine.include?("plastic_1.1_lite-UMLtool-fw.exe") } >> > >Yes, you can use a regex as a key, but in your example, you're not >doing anything else with it :-) You'd get the same results with: > > dict[/blah/] = dict[/blah/] + 1 It was in IRB, so once I had the dictionary populated, I was also then able to aDictionary.each_value { | entry | puts entry } to see how often some people had downloaded the file and the like, so it wasn't entrirely wasted. >or even: > > dict[/blah/] = dict["hello!"] + 1 Hmmm - wouldn't this result in aDictionary having an entry with a key of "hello!" and so through my count of IP numbers off by one? (Another thing I did try was the line aFile.each_line { | eachLine | aDictionary[ /[0-9.]+/ ] if eachLine.include?("plastic") } to see if just mentioning an entry was enough to create it, after all, aFile.each_line { | eachLine | aDictionary[ /[0-9.]+/ ] = aDictionary[ /[0-9.]+/ ] + 1 if eachLine.include?("plastic") } was creating the entry with a value of 0, and then incrementing it to 1 for entries that had not previously existed. So why not just have it be created (albeit with a value of 0) >since dict["hello"] is just serving the purpose of evaluating to zero. Ah - so in actual fact, I could have used aFile.each_line { | eachLine | aDictionary[ /[0-9.]+/ ] += 1 if eachLine.include?("plastic") } and had the exact same effect? Of course! Bloody obvious now! Isn't hindsight a wonderful thing? Digressionary bit ---------------------VVV >If you just want the count of lines with plastic_1.1..., you could do: > > plastic_count = file.readlines.grep(/plastic_1.1.../).size Interestingly, my first reaction to your file.readlines.grep code snipplet was to write "I already had the number of lines which contained "plastic" (a count of occurrences in my text editor gave that). But often, the same IP number would have several downloads of the file. The reason I hashed it was to count the number of unique IP numbers associated with a line containing "plastic". For a file containing the lines 1.1.1.1 plastic 1.1.1.1 plastic 2.2.2.2 plastic 2.2.2.2 plastic 4.4.4.4 plastic 6.6.6.6 plastic I wanted a size of 4 returned, not a size of 6." But then I realised that grep must be doing something interesting, and possibly it was eliminating the count of replicated IP numbers. So I went to look it up in the book.. I think grep is one of those things that is /so/ well known to Unix and C programmers that it is taken for granted that every 'right-thinking' person must already know it. It's indirectly addressed in the book, so I had to spend a wee bit of time accessing the description. But it turns out that grep just selects if the pattern is present. Given your pattern was /plastic/ doesn't that mean your code would return 6 rather than 4? Ah yes, it would, and you even said so. >or, to save reading the whole file in at once: > > plastic_count = 0 > file.readlines.each do |line| > plastic_count += 1 if /plastic_1.1.../.match(line) > end End of Digressionary bit ---------------------^^^ >If you want to hash by IP address, you could do: > > regex = /([\d.]+).*plastic_1\. etc./ > dict = Hash.new(0) > > File.open("filename") do |fh| > fh.each_line do |line| > m = regex.match(line) > dict[m[1]] += 1 if m > end > end > >In this example, I'm using a MatchData object, m. m[1] contains the >results of the first capture (the ([\d.]+)). m will be nil if the line >doesn't match -- hence the "if m". > >(You could do the same thing using the special variable $1, but I'm >going for the full OO effect here :-) Interesting, but the entries of dict would be: 1.1.1.1 plastic rather than entries of 1.1.1.1 Thank you for the food for thought. Cheers, Euan Gawnsoft: http://www.gawnsoft.co.sr Symbian/Epoc wiki: http://html.dnsalias.net:1122 Smalltalk links (harvested from comp.lang.smalltalk) http://html.dnsalias.net/gawnsoft/smalltalk