Help

hi Gurus,

Here my data structure

1234 => { 'open' => '1234-1',
               'analyzed' => '1234-2',
               'feedback' => '1234-3',
               'closed' => '1234-4'
             }
3455 => { 'open' => '3455-1',
               'analyzed' => '34552',
               'feedback' => '3455-3',
               'closed' => '3455-4'
             }

My task is to display numbers [like 1234 or 3455] if they have ('open'
OR 'analyzed') AND ('closed' OR 'feedback') keys. I tried following
code

puts numbers if $DATA[pr].has_key?( ( ('closed' || 'feedback')
                                                         && ('open' ||
'analyzed') ) )

I am not sure what is wrong with it but its not testing these
conditions and printing all numbers. Please help me understanding
has_key method and writing correct condition.

Thanks

The has_key? method receives a single key to be checked in the hash.
In your snippet, what you are passing to the has_key? method is the
result of evaluating this:

( ('closed' || 'feedback') && ('open' || 'analyzed') )

which is:

irb(main):002:0> ( ('closed' || 'feedback') && ('open' || 'analyzed') )
=> "open"

So you are testing only for the "open" key. I don't know what $DATA or
pr or numbers are in your snippet, but you are testing only for the
key "open".

Hope this helps,

Jesus.

···

On Thu, Jan 7, 2010 at 10:20 AM, Jagadeesh <mnjagadeesh@gmail.com> wrote:

hi Gurus,

Here my data structure

1234 => { 'open' => '1234-1',
'analyzed' => '1234-2',
'feedback' => '1234-3',
'closed' => '1234-4'
}
3455 => { 'open' => '3455-1',
'analyzed' => '34552',
'feedback' => '3455-3',
'closed' => '3455-4'
}

My task is to display numbers [like 1234 or 3455] if they have ('open'
OR 'analyzed') AND ('closed' OR 'feedback') keys. I tried following
code

puts numbers if $DATA[pr].has_key?( ( ('closed' || 'feedback')
&& ('open' ||
'analyzed') ) )

I am not sure what is wrong with it but its not testing these
conditions and printing all numbers. Please help me understanding
has_key method and writing correct condition.

Not tested, but I think the condition should be:

($DATA[pr].has_key?('closed') || $DATA[pr].has_key?('feedback')) &&
($DATA[pr].has_key?('open') || $DATA[pr].has_key?('analyzed'))

Your condition would always have translated to

if $DATA[pr].has_key?('open')

This happens because ruby first evaluates the argument to has_key? and because
of the way logical operators work. || returns the first operand which
evaluates to true (that is, the first operand which is not false or nil). This
means that:
'closed' || 'feedback' always gives 'closed'
'open' || 'analyzed' always gives 'open'

On the other hand, the && operator returns the last operand if both evaluate
to true and the value of the one which evaluates to false if one evaluates to
false (if both evaluate to false, it returns the first). In your case, you had
the expression

'closed' && 'open'

which evaluates to 'open'.

I hope this helps

Stefano

···

On Thursday 07 January 2010, Jagadeesh wrote:

>hi Gurus,
>
>Here my data structure
>
>1234 => { 'open' => '1234-1',
> 'analyzed' => '1234-2',
> 'feedback' => '1234-3',
> 'closed' => '1234-4'
> }
>3455 => { 'open' => '3455-1',
> 'analyzed' => '34552',
> 'feedback' => '3455-3',
> 'closed' => '3455-4'
> }
>
>My task is to display numbers [like 1234 or 3455] if they have ('open'
>OR 'analyzed') AND ('closed' OR 'feedback') keys. I tried following
>code
>
>puts numbers if $DATA[pr].has_key?( ( ('closed' || 'feedback')
> && ('open' ||
>'analyzed') ) )
>
>I am not sure what is wrong with it but its not testing these
>conditions and printing all numbers. Please help me understanding
>has_key method and writing correct condition.
>
>Thanks

Thank you so much for crystal clear explanation. Would you show me how
I can do it using array? I tried using grep but did not get good
result.

I want to print if I find (closed or feedback) and (open or analyzed)
keys.

Thanks

···

On Jan 7, 2:36 pm, Stefano Crocco <stefano.cro...@alice.it> wrote:

On Thursday 07 January 2010, Jagadeesh wrote:

> >hi Gurus,
> >
> >Here my data structure
> >
> >1234 => { 'open' => '1234-1',
> > 'analyzed' => '1234-2',
> > 'feedback' => '1234-3',
> > 'closed' => '1234-4'
> > }
> >3455 => { 'open' => '3455-1',
> > 'analyzed' => '34552',
> > 'feedback' => '3455-3',
> > 'closed' => '3455-4'
> > }
> >
> >My task is to display numbers [like 1234 or 3455] if they have ('open'
> >OR 'analyzed') AND ('closed' OR 'feedback') keys. I tried following
> >code
> >
> >puts numbers if $DATA[pr].has_key?( ( ('closed' || 'feedback')
> > && ('open' ||
> >'analyzed') ) )
> >
> >I am not sure what is wrong with it but its not testing these
> >conditions and printing all numbers. Please help me understanding
> >has_key method and writing correct condition.
> >
> >Thanks

Not tested, but I think the condition should be:

($DATA[pr].has_key?('closed') || $DATA[pr].has_key?('feedback')) &&
($DATA[pr].has_key?('open') || $DATA[pr].has_key?('analyzed'))

Your condition would always have translated to

if $DATA[pr].has_key?('open')

This happens because ruby first evaluates the argument to has_key? and because
of the way logical operators work. || returns the first operand which
evaluates to true (that is, the first operand which is not false or nil). This
means that:
'closed' || 'feedback' always gives 'closed'
'open' || 'analyzed' always gives 'open'

On the other hand, the && operator returns the last operand if both evaluate
to true and the value of the one which evaluates to false if one evaluates to
false (if both evaluate to false, it returns the first). In your case, you had
the expression

'closed' && 'open'

which evaluates to 'open'.

I hope this helps

Stefano

$DATA=>{'1234' => { 'open' => '1234-1',
               'analyzed' => '1234-2',
               'feedback' => '1234-3',
               'closed' => '1234-4'
             },
        '3455' => { 'open' => '3455-1',
               'analyzed' => '34552',
               'feedback' => '3455-3',
               'closed' => '3455-4'
              }
}

and am reading it in loop so pr will have 1234, 3455 etc.

Thanks for your help.

Thanks

···

On Jan 7, 2:33 pm, Jesús Gabriel y Galán <jgabrielyga...@gmail.com> wrote:

On Thu, Jan 7, 2010 at 10:20 AM, Jagadeesh <mnjagade...@gmail.com> wrote:
> hi Gurus,

> Here my data structure

> 1234 => { 'open' => '1234-1',
> 'analyzed' => '1234-2',
> 'feedback' => '1234-3',
> 'closed' => '1234-4'
> }
> 3455 => { 'open' => '3455-1',
> 'analyzed' => '34552',
> 'feedback' => '3455-3',
> 'closed' => '3455-4'
> }

> My task is to display numbers [like 1234 or 3455] if they have ('open'
> OR 'analyzed') AND ('closed' OR 'feedback') keys. I tried following
> code

> puts numbers if $DATA[pr].has_key?( ( ('closed' || 'feedback')
> && ('open' ||
> 'analyzed') ) )

> I am not sure what is wrong with it but its not testing these
> conditions and printing all numbers. Please help me understanding
> has_key method and writing correct condition.

The has_key? method receives a single key to be checked in the hash.
In your snippet, what you are passing to the has_key? method is the
result of evaluating this:

( ('closed' || 'feedback') && ('open' || 'analyzed') )

which is:

irb(main):002:0> ( ('closed' || 'feedback') && ('open' || 'analyzed') )
=> "open"

So you are testing only for the "open" key. I don't know what $DATA or
pr or numbers are in your snippet, but you are testing only for the
key "open".

Hope this helps,

Jesus.

Here is how I am trying to do with array

states = ['open', 'analyzed', 'feedback', 'closed']

unless ( ( states.grep('closed').empty? || states.grep
('feedback').empty? ) \
       && (states.grep('open').empty? ||states.grep
('analyzed').empty? ) )
          puts "hello"
   end

Thanks

As Stefano said:

irb(main):001:0> $DATA = {
irb(main):002:1* 1234 => { 'open' => '1234-1',
irb(main):003:2* 'analyzed' => '1234-2',
irb(main):004:2* 'feedback' => '1234-3',
irb(main):005:2* 'closed' => '1234-4'
irb(main):006:2> },
irb(main):007:1* 3455 => { 'open' => '3455-1',
irb(main):008:2* 'analyzed' => '34552',
irb(main):009:2* 'feedback' => '3455-3',
irb(main):010:2* 'closed' => '3455-4'
irb(main):011:2> }}
=> {3455=>{"open"=>"3455-1", "analyzed"=>"34552", "closed"=>"3455-4",
"feedback"=>"3455-3"}, 1234=>{"open"=>"1234-1", "analyzed"=>"1234-2",
"closed"=>"1234-4", "feedback"=>"1234-3"}}
irb(main):012:0> $DATA.each do |k,v|
irb(main):013:1* puts k if ( (v.has_key?('closed') ||
v.has_key?('feedback')) && ((v.has_key?('open') ||
v.has_key?('analyzed'))))
irb(main):014:1> end
3455
1234

Hope this helps,

Jesus.

···

On Thu, Jan 7, 2010 at 10:55 AM, Jagadeesh <mnjagadeesh@gmail.com> wrote:

On Jan 7, 2:33 pm, Jesús Gabriel y Galán <jgabrielyga...@gmail.com> > wrote:

On Thu, Jan 7, 2010 at 10:20 AM, Jagadeesh <mnjagade...@gmail.com> wrote:
> hi Gurus,

> Here my data structure

> 1234 => { 'open' => '1234-1',
> 'analyzed' => '1234-2',
> 'feedback' => '1234-3',
> 'closed' => '1234-4'
> }
> 3455 => { 'open' => '3455-1',
> 'analyzed' => '34552',
> 'feedback' => '3455-3',
> 'closed' => '3455-4'
> }

> My task is to display numbers [like 1234 or 3455] if they have ('open'
> OR 'analyzed') AND ('closed' OR 'feedback') keys. I tried following
> code

> puts numbers if $DATA[pr].has_key?( ( ('closed' || 'feedback')
> && ('open' ||
> 'analyzed') ) )

> I am not sure what is wrong with it but its not testing these
> conditions and printing all numbers. Please help me understanding
> has_key method and writing correct condition.

The has_key? method receives a single key to be checked in the hash.
In your snippet, what you are passing to the has_key? method is the
result of evaluating this:

( ('closed' || 'feedback') && ('open' || 'analyzed') )

which is:

irb(main):002:0> ( ('closed' || 'feedback') && ('open' || 'analyzed') )
=> "open"

So you are testing only for the "open" key. I don't know what $DATA or
pr or numbers are in your snippet, but you are testing only for the
key "open".

Hope this helps,

Jesus.

$DATA=>{'1234' => { 'open' => '1234-1',
'analyzed' => '1234-2',
'feedback' => '1234-3',
'closed' => '1234-4'
},
'3455' => { 'open' => '3455-1',
'analyzed' => '34552',
'feedback' => '3455-3',
'closed' => '3455-4'
}
}

and am reading it in loop so pr will have 1234, 3455 etc.

I'm not sure about what you mean by "using array?". Your code clearly uses a
hash, and Array has no keys and, obviously, no has_key? method. Looking at
your reply to Jesús, I'd say what you want is this:

$DATA.each_pair do |key, value|
  if (value.has_key?('closed') || value.has_key?('feedback')) &&
(value.has_key?('open') || value.has_key?('analyzed'))
    puts key
  end
end

Hash#each_pair calls the block for each key-value pair. The first argument of
the block will be set to the key; the second will be set to the value.

If you're sure the values associated with the 'closed', 'feedback', 'open' and
'analyzed' keys will never be nil or false, you can replace the condition with
this:

if (value['closed'] || value['feedback']) && (value['open'] ||
value['analyzed'])

This way, instead of checking whether the hash has a given key, you check
whether or not the associated value is nil. Since Hash returns nil if you ask
for a non existing key, you'll get a true value (in your case, a string) if
the key exists and nil if it doesn't. This means you get a true value when
has_key? would have returned true and a false value (nil) when has_key? would
have returned false. This, of course, breaks if a key can correspond to a
value which is false or nil.

Stefano

···

On Thursday 07 January 2010, Jagadeesh wrote:

>On Jan 7, 2:36 pm, Stefano Crocco <stefano.cro...@alice.it> wrote:
>> On Thursday 07 January 2010, Jagadeesh wrote:
>> > >hi Gurus,
>> > >
>> > >Here my data structure
>> > >
>> > >1234 => { 'open' => '1234-1',
>> > >
>> > > 'analyzed' => '1234-2',
>> > > 'feedback' => '1234-3',
>> > > 'closed' => '1234-4'
>> > > }
>> > >
>> > >3455 => { 'open' => '3455-1',
>> > >
>> > > 'analyzed' => '34552',
>> > > 'feedback' => '3455-3',
>> > > 'closed' => '3455-4'
>> > > }
>> > >
>> > >My task is to display numbers [like 1234 or 3455] if they have
>> > >('open' OR 'analyzed') AND ('closed' OR 'feedback') keys. I tried
>> > >following code
>> > >
>> > >puts numbers if $DATA[pr].has_key?( ( ('closed' || 'feedback')
>> > >
>> > > && ('open'
>> > > >>
>> > >
>> > >'analyzed') ) )
>> > >
>> > >I am not sure what is wrong with it but its not testing these
>> > >conditions and printing all numbers. Please help me understanding
>> > >has_key method and writing correct condition.
>> > >
>> > >Thanks
>>
>> Not tested, but I think the condition should be:
>>
>> ($DATA[pr].has_key?('closed') || $DATA[pr].has_key?('feedback')) &&
>> ($DATA[pr].has_key?('open') || $DATA[pr].has_key?('analyzed'))
>>
>> Your condition would always have translated to
>>
>> if $DATA[pr].has_key?('open')
>>
>> This happens because ruby first evaluates the argument to has_key? and
>> because of the way logical operators work. || returns the first operand
>> which evaluates to true (that is, the first operand which is not false
>> or nil). This means that:
>> 'closed' || 'feedback' always gives 'closed'
>> 'open' || 'analyzed' always gives 'open'
>>
>> On the other hand, the && operator returns the last operand if both
>> evaluate to true and the value of the one which evaluates to false if
>> one evaluates to false (if both evaluate to false, it returns the
>> first). In your case, you had the expression
>>
>> 'closed' && 'open'
>>
>> which evaluates to 'open'.
>>
>> I hope this helps
>>
>> Stefano
>
>Thank you so much for crystal clear explanation. Would you show me how
>I can do it using array? I tried using grep but did not get good
>result.
>
>I want to print if I find (closed or feedback) and (open or analyzed)
>keys.
>
>Thanks

Still I don't understand exactly what you're trying to do. states contains all
the four entries, so states.grep will never return an empty array and the puts
will always be executed.

Please, can you explain in detail what you're trying to do? This way we'll be
able to help you better.

Stefano

···

On Thursday 07 January 2010, Jagadeesh wrote:

>Here is how I am trying to do with array
>
>states = ['open', 'analyzed', 'feedback', 'closed']
>
> unless ( ( states.grep('closed').empty? || states.grep
>('feedback').empty? ) \
> && (states.grep('open').empty? ||states.grep
>('analyzed').empty? ) )
> puts "hello"
> end
>
>Thanks

You don't need to use grep to see whether an array contains an element. You
can use include?:

if (states.include?('closed') || states.include?('feedback')) &&
(states.include?('open') || states.include?('analyzed'))

Another aopproach is to use the Array & operator, which gives the intersection
between two arrays. You can do something like this:

first_group = ['open', 'analyzed']
second_group = ['closed', 'feedback']

if !(states & second_group).empty? && !(states & first_group).empty?

The reasoning is that, if states contains either the 'open' or the 'analyzed'
entries, then its intersection with first_group (states & first_group) won't
be empty. The same for the second group.

I hope this helps

Stefano

···

On Thursday 07 January 2010, Jagadeesh wrote:

>On Jan 7, 3:44 pm, Stefano Crocco <stefano.cro...@alice.it> wrote:
>> On Thursday 07 January 2010, Jagadeesh wrote:
>> > >Here is how I am trying to do with array
>> > >
>> > >states = ['open', 'analyzed', 'feedback', 'closed']
>> > >
>> > > unless ( ( states.grep('closed').empty? || states.grep
>> > >
>> > >('feedback').empty? ) \
>> > >
>> > > && (states.grep('open').empty? ||states.grep
>> > >
>> > >('analyzed').empty? ) )
>> > >
>> > > puts "hello"
>> > > end
>> > >
>> > >Thanks
>>
>> Still I don't understand exactly what you're trying to do. states
>> contains all the four entries, so states.grep will never return an
>> empty array and the puts will always be executed.
>>
>> Please, can you explain in detail what you're trying to do? This way
>> we'll be able to help you better.
>>
>> Stefano
>
>Actually there may be an arry without all those values. So I extracted
>keys into an array and was trying to grep in it.
>
>Thanks for your help.
>
>Thanks

Thank you so much. It is working now.

Thanks for all your help.

Thanks

···

On Jan 7, 3:08 pm, Jesús Gabriel y Galán <jgabrielyga...@gmail.com> wrote:

On Thu, Jan 7, 2010 at 10:55 AM, Jagadeesh <mnjagade...@gmail.com> wrote:
> On Jan 7, 2:33 pm, Jesús Gabriel y Galán <jgabrielyga...@gmail.com> > > wrote:
>> On Thu, Jan 7, 2010 at 10:20 AM, Jagadeesh <mnjagade...@gmail.com> wrote:
>> > hi Gurus,

>> > Here my data structure

>> > 1234 => { 'open' => '1234-1',
>> > 'analyzed' => '1234-2',
>> > 'feedback' => '1234-3',
>> > 'closed' => '1234-4'
>> > }
>> > 3455 => { 'open' => '3455-1',
>> > 'analyzed' => '34552',
>> > 'feedback' => '3455-3',
>> > 'closed' => '3455-4'
>> > }

>> > My task is to display numbers [like 1234 or 3455] if they have ('open'
>> > OR 'analyzed') AND ('closed' OR 'feedback') keys. I tried following
>> > code

>> > puts numbers if $DATA[pr].has_key?( ( ('closed' || 'feedback')
>> > && ('open' ||
>> > 'analyzed') ) )

>> > I am not sure what is wrong with it but its not testing these
>> > conditions and printing all numbers. Please help me understanding
>> > has_key method and writing correct condition.

>> The has_key? method receives a single key to be checked in the hash.
>> In your snippet, what you are passing to the has_key? method is the
>> result of evaluating this:

>> ( ('closed' || 'feedback') && ('open' || 'analyzed') )

>> which is:

>> irb(main):002:0> ( ('closed' || 'feedback') && ('open' || 'analyzed') )
>> => "open"

>> So you are testing only for the "open" key. I don't know what $DATA or
>> pr or numbers are in your snippet, but you are testing only for the
>> key "open".

>> Hope this helps,

>> Jesus.

> $DATA=>{'1234' => { 'open' => '1234-1',
> 'analyzed' => '1234-2',
> 'feedback' => '1234-3',
> 'closed' => '1234-4'
> },
> '3455' => { 'open' => '3455-1',
> 'analyzed' => '34552',
> 'feedback' => '3455-3',
> 'closed' => '3455-4'
> }
> }

> and am reading it in loop so pr will have 1234, 3455 etc.

As Stefano said:

irb(main):001:0> $DATA = {
irb(main):002:1* 1234 => { 'open' => '1234-1',
irb(main):003:2* 'analyzed' => '1234-2',
irb(main):004:2* 'feedback' => '1234-3',
irb(main):005:2* 'closed' => '1234-4'
irb(main):006:2> },
irb(main):007:1* 3455 => { 'open' => '3455-1',
irb(main):008:2* 'analyzed' => '34552',
irb(main):009:2* 'feedback' => '3455-3',
irb(main):010:2* 'closed' => '3455-4'
irb(main):011:2> }}
=> {3455=>{"open"=>"3455-1", "analyzed"=>"34552", "closed"=>"3455-4",
"feedback"=>"3455-3"}, 1234=>{"open"=>"1234-1", "analyzed"=>"1234-2",
"closed"=>"1234-4", "feedback"=>"1234-3"}}
irb(main):012:0> $DATA.each do |k,v|
irb(main):013:1* puts k if ( (v.has_key?('closed') ||
v.has_key?('feedback')) && ((v.has_key?('open') ||
v.has_key?('analyzed'))))
irb(main):014:1> end
3455
1234

Hope this helps,

Jesus.