Hash

Discussion in 'Perl Misc' started by Pradeep Patra, Dec 23, 2011.

  1. Hi all,
    I have a questions of comparing two hashes.

    %hash1={a=>2,b=>3,c=>4,d=>5}
    %hash2={a=>7,b=>8,c=>9,d=>0)

    I have to ensure that from %hash2 the value is increased by 5(2->7 and
    3->8) for "a","b". I dont want to compare the all the values of
    hash2(for exp-d=0).I want to push this to a library(preferably a
    single method) so that I can reuse it. Is there a better way to do
    this?.

    Can anybody help me in this regard? Any source code will be of great
    help.


    Regards
    Pradeep
     
    Pradeep Patra, Dec 23, 2011
    #1
    1. Advertising

  2. Henry Law <> writes:

    [...]

    > I think you want to make sure that the values of hash2 for
    > keys 'a' and 'b' are 5 more than the corresponding values in hash1.
    > Here's some code that does that, but it's trivial, so I think there
    > must be more to it than that!
    >
    > #!/usr/bin/perl
    > use strict;
    > use warnings;
    >
    > my %hash1 = (a=>2,b=>3,c=>4,d=>5);
    > my %hash2 = (a=>7,b=>5,c=>9,d=>0);
    >
    > for ( qw(a b) ) {
    > print "$_: Not increased by 5\n" unless $hash2{$_} == $hash1{$_}+5;
    > }


    In case of exactly two comparisons known at compile time, using a
    logical operator usually makes more sense. Also, your variable names
    are by far not verbose enough. I suggest

    my %first_hash_table_using_modified_bernstein_hash;
    my %second_hash_table_also_using_modified_bernstein_hash;

    Remember, the more words (or letters) you need to express
    trivialities, the less likely it will be that your audience notices
    that (before falling asleep, that is ...)
     
    Rainer Weikusat, Dec 23, 2011
    #2
    1. Advertising

  3. On Dec 23, 7:49 pm, Henry Law <> wrote:
    > On 23/12/11 14:34, Rainer Weikusat wrote:
    >
    > > In case of exactly two comparisons known at compile time, using a
    > > logical operator usually makes more sense. Also, your variable names
    > > are by far not verbose enough. I suggest

    >
    > Are you trying to be funny?  You certainly don't seem to be trying to be
    > helpful to the OP.
    >
    > --
    >
    > Henry Law            Manchester, England


    Thanks Henry for you kind help. Sorry for the confusion.To be more
    clear:

    I have a %hash1 = { 'total' => '15',
    'success' => '15',
    'error' => '0',
    'percent' => '10%'
    };

    After some operations performed the %hash1 has values populated with
    new values for some of the keys(for exp: total,success,percent) and
    that result to %hash2.

    Lets say modified %hash2 is as follows.

    %hash2 = { 'total' => '20',
    'success' => '20',
    'error' => '0',
    'percent' => '15%'
    };


    Note: hash2 has modified values for (success,total and percent) was
    increased by 5.I want to ensure that the 'error' still 0(between hash1
    and hash2).

    I want to write a function for example:

    hash_compare(hash1,hash2)
    {
    if hash2's success counter is increased by 5 for
    total,success,percent return success;
    if hash2's error counter > 0 return fail;


    }

    It can be done 2 ways we need 2 foreach loops to loop through the
    "keys of hash1" and then "keys of hash2" and then match keys to
    retrieve values from hash1 and hash2 and then see that it increased by
    5. Is there a better way to do this? Code snippet to perform this will
    be useful.


    Regards
    Pradeep
     
    Pradeep Patra, Dec 23, 2011
    #3
  4. Henry Law <> writes:
    > On 23/12/11 14:34, Rainer Weikusat wrote:
    >> In case of exactly two comparisons known at compile time, using a
    >> logical operator usually makes more sense. Also, your variable names
    >> are by far not verbose enough. I suggest

    >
    > Are you trying to be funny? You certainly don't seem to be trying to
    > be helpful to the OP.


    In the sense that the code you posted was technically capable of
    solving the problem, this would be much better expressed as

    my %h0 = (a=>2,b=>3,c=>4,d=>5);
    my %h1 = (a=>6,b=>5,c=>9,d=>0);

    print "$_: Not increased by 5\n" if
    ($_ = 'a', $h0{a} + 5 != $h1{a})
    || ($_ = 'b', $h0{b} + 5 != $h1{b});

    instead of using a loop with a fixed number of iterations. Otherwise,
    this should be put into a subroutine which could work with any two
    hashes, instead of only hashes named %hash1 and %hash2 which happen to
    have keys named 'a' and 'b', but the problem specification of the OP
    is too incomplete for that (what should happen in case of non-isomorph
    hashes?).

    Also %hash1 is a singularly bad choice for a variable name in Perl
    since the fact that this is a hash is already communicated by the
    sigil and 'hash' doesn't communicate anything of interest about this
    hash and the only difference to simply naming it %h1 is that this lack
    of useful information is 'encoded' in a more verbose way.

    Coming to think of that, and even more efficient way to ensure thay
    any poor soul who might have to work with your code (not the fictional
    'maintenance programmer' who deserves to be tortured with any
    conceivable contortion but a *real* person) will curse your name till
    the end of times would be to use factually incorrect/ misleading
    verbose noise as variable names, ie,

    my %array1 = (a,2,b,3,c,4,d,5); # You can't catch me!

    BTW, this is a literary device which is known as 'parody' and it is
    supposed to draw attention to some shortcoming of something by
    exaggerating that into absurdity (a hyberbole). This even includes the
    Chuck Berry allusion.
     
    Rainer Weikusat, Dec 23, 2011
    #4
  5. Pradeep Patra <> writes:
    > I want to write a function for example:
    >
    > hash_compare(hash1,hash2)
    > {
    > if hash2's success counter is increased by 5 for
    > total,success,percent return success;
    > if hash2's error counter > 0 return fail;
    >
    >
    > }


    A working example of a possible interpretation of this description:

    --------------------
    my %h0 = (
    total => 15,
    success => 15,
    error => 0,
    percent => 10);

    my %h1 = (
    total => 20,
    success => 20,
    error => 0,
    percent => 15);

    sub verify_changes(\%\%$)
    {
    my ($h0, $h1, $pred) = @_;

    !exists($h1->{$_}) || $pred->($h0->{$_}, $h1->{$_}) || return
    for grep { $_ ne 'error'; } keys(%$h0);
    return 1;
    }

    printf("verified %s\n",
    !$h1{error} && verify_changes(%h0, %h1, sub { return $_[1] - $_[0] == 5; }) ?
    'ok' : 'not ok');
    ---------------------

    NB: The verify_changes subroutine takes three arguments, the 'source
    hash', the 'product hash' and a reference to a 'predicate' subroutine
    which is supposed to compare two values 'in some way', the
    example in the printf statement does your 'larger by 5' check. Testing
    $h1{error} is done separately before calling the verification routine.
     
    Rainer Weikusat, Dec 23, 2011
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Red Orchid
    Replies:
    3
    Views:
    1,048
  2. Pieter Claassen
    Replies:
    1
    Views:
    1,116
    CBFalconer
    Aug 4, 2004
  3. Bo Peng
    Replies:
    4
    Views:
    792
  4. rp
    Replies:
    1
    Views:
    539
    red floyd
    Nov 10, 2011
  5. Srijayanth Sridhar
    Replies:
    19
    Views:
    627
    David A. Black
    Jul 2, 2008
Loading...

Share This Page