Obtaining specific .csv data (one data at a time)

Im using the following code:

class Target <
  Struct.new(:question)
  #Struct.new(:action, :blank, :cost, :status, :due_date,
:responsibility)
  def print_csv_record
    # use the ternary operator to use one output format or the other
    question.length==0 ? printf(",") : printf("\"%s\",", question)
    printf("\n")
  end
end

CSV.open('ActionPlan.csv','rb').each do |row|
  t = Target.new
  t.question = row[1] if row[0].to_s.match(/1.[a-z]/)#maybe can use
each.line
  pp t.question #<---to test outputs
end

The outputs are as followed:

nil
nil
nil
"Maximise use of natural lighting"
"Turn-off unnecessary lights/equipment"
"Install energy efficient lighting"
"Turn-off unnecessary air conditioning"
"Repair or replace damaged oven/refrigerator seals"
"Install draught proofing"
"Consider energy efficiency labels when buying electrical items"
"Insulate hot water pipes"
......
......

For some reason, ruby returns the entire line of row[1]. If i only
require one result at a time (i.e only "Turn-off unnecessary
lights/equipment") and do not want ruby to return any 'nil' output, how
can i tell ruby to do so?

Attached is the .csv file use. Thanks for any help

Nizam

Attachments:
http://www.ruby-forum.com/attachment/5806/ActionPlan.csv

···

--
Posted via http://www.ruby-forum.com/.

Im using the following code:

class Target <
Struct.new(:question)
#Struct.new(:action, :blank, :cost, :status, :due_date,
:responsibility)
def print_csv_record
   # use the ternary operator to use one output format or the other
   question.length==0 ? printf(",") : printf("\"%s\",", question)
   printf("\n")
end
end

This bit here is a little cumbersome, it could probably be cleaned up like
this:

class Target < Struct.new(:question)
  def print_csv_record
    print %("#{question}") if question && !question.length.zero?
    puts ","
  end
end

Though, I think a better way to do this would be to return the string, and
let the calling code decide how it should be dealt with (ie sent to $stdout,
like puts does, or maybe saved to a file instead, or manipulated further,
elsewhere)

CSV.open('ActionPlan.csv','rb').each do |row|

t = Target.new
t.question = row[1] if row[0].to_s.match(/1.[a-z]/)#maybe can use
each.line
pp t.question #<---to test outputs
end

Here, you open the file, then iterate over it, but never close it. To
iterate over its rows, try using foreach instead, which handles the file
upkeep for you.

Also, you see the nils, because you create a target on every iteration,
regardless of whether you assign it a question. So if you create the target,
and it does not match the regex, then it will not have a question. So when
you say 'pp t.question', t.question will be nil, so that is the same as 'pp
nil', and you will see nil. It isn't clear to me what you were actually
wanting to happen, so here are two possibilities.

1, Assumes you meant to use print_csv_record, which will just output a comma
for empty records
CSV.foreach('ActionPlan.csv') do |row|
  t = Target.new
  t.question = row[1] if row[0] =~ /1.[a-z]/
  t.print_csv_record
end

2. Assumes you wanted to skip output for rows that don't match your regex
CSV.foreach('ActionPlan.csv') do |row|
  next unless row[0] =~ /1.[a-z]/
  t = Target.new row[1]
  t.print_csv_record
end

···

On Thu, Jan 27, 2011 at 6:30 PM, Kamarulnizam Rahim <niezam54@hotmail.com>wrote:

Hi Josh,

Thanks for the post. Problem solved. But i have one little question to
ask. In order to get the data from row[1], i use the following code:

next unless row[0] =~ /1.[a-z]/
t = Target.new row[1]

where '1.[a-z]' will take on any data with number '1'. The problem is,
my csv data on row[1] has data till number '11'. and when i used the
code above, it will take on data on number '1' and '11' as well. How do
i separate this?

Nizam

···

--
Posted via http://www.ruby-forum.com/.

THANKS!!

···

--
Posted via http://www.ruby-forum.com/.

Hi, I mistakenly look over my output.

I tried using the method above (/1\.[a-z]/)and it still give me the same
result which means it still take on data numbered '11'. Any idea to
solve this?

Nizam

···

--
Posted via http://www.ruby-forum.com/.

In regular expressions, the period will match any character. So you need to
escape the period to basically say "match a period" not "match any
character"
/1\.[a-z]/

···

On Mon, Jan 31, 2011 at 2:24 PM, Kamarulnizam Rahim <niezam54@hotmail.com>wrote:

Hi Josh,

Thanks for the post. Problem solved. But i have one little question to
ask. In order to get the data from row[1], i use the following code:

next unless row[0] =~ /1.[a-z]/
t = Target.new row[1]

where '1.[a-z]' will take on any data with number '1'. The problem is,
my csv data on row[1] has data till number '11'. and when i used the
code above, it will take on data on number '1' and '11' as well. How do
i separate this?

Nizam

--
Posted via http://www.ruby-forum.com/\.

You can easily experiment with your regular expression here:
    Rubular: 1\.[a-z]

There's a guide at the bottom with information on the syntax.

After you've experimented a bit, here's a "spoiler":
    Rubular: ^1\.[a-z]

···

On Wed, Feb 2, 2011 at 3:43 AM, Kamarulnizam Rahim <niezam54@hotmail.com> wrote:

I tried using the method above (/1\.[a-z]/)and it still give me the same
result which means it still take on data numbered '11'. Any idea to
solve this?