polycomb has asked for the wisdom of the Perl Monks concerning the following question:

Hi, all:

I have a simple work task: input from keyboard a name with two values(its concentration and volume) and then print out a table that shows list of names with their concentration, volume, total yield(con*vol), how much for 30ug/50ug(30/concentration).

I don't know how to create a hash with two values from STDIN, and here is the one I put those in the program.

#!/user/bin/perl # RNAi_cal.plx use warnings; #use strict; my $yield; my $thirty_ug; my $fifty_ug; #my %RNA; #print "Please enter RNAi name, concentration:\n"; my %RNA=( Ash2 =>"1.85", Ja2_1 =>"1.89", Ja2_2 =>"2.49", Set1_1 =>"1.55", Set1_2 =>"2.88"); my %vol=( Ash2 =>"150", Ja2_1 =>"150", Ja2_2 =>"100", Set1_1 =>"150", Set1_2 =>"100"); print "\t Con\.\t Volume\t Total yield (ug)\t 30ug\t 50ug\t \n"; for (keys %RNA){ $yield=$RNA{$_}*$vol{$_}; $thirty_ug=int(30/$RNA{$_}*100)/100; $fifty_ug=int(50/$RNA{$_}*100)/100; print "$_\t $RNA{$_}\t$vol{$_}\t $yield\t \t\t$thirty_ug\t $fifty_ +ug\t \n"; }
Many thanks.

Replies are listed 'Best First'.
Re: a simple work task
by SuicideJunkie (Vicar) on Jan 14, 2011 at 18:34 UTC

    Each value is a single value. However that single value is allowed to be a reference.

    Try something like:

    while (not $done) { my $name = 'Placebex'; my %info; $info{concentration} = 0; $info{volume} = 250; $recipe{name} = \%info; } foreach my $name (keys %recipe) { print "Take $recipe{$name}{volume} ml of $name,\n"; } print "and call me in the morning.\n"

Re: a simple work task
by johngg (Canon) on Jan 14, 2011 at 20:17 UTC

    You might want to use a hash of hashes (HoH) data structure to hold all of your data in one place. You can also use a while loop to read from STDIN until some end condition - here I use CTRL-D to signal eof as I'm on *nix. The Data::Dumper module is helpful when trying to visualise data and I think printf (and sprintf) will do your rounding for you.

    #!/usr/bin/perl # use strict; use warnings; use feature qw{ say }; use Data::Dumper; my $prompt = q{-> }; my $dePrompt = qq{\r} . q{ } x ( length( $prompt ) + 2 ) . qq{\r}; my %RNA; print qq{Please enter name, conc. and vol. (CTRL-D to finish):\n}; print $prompt; while ( 1 ) { do { print $dePrompt; last; } if eof STDIN; chomp( my $line = <STDIN> ); my( $name, $conc, $vol ) = split m{\s+}, $line; $RNA{ $name } = { conc => $conc, vol => $vol, }; print $prompt; } print Data::Dumper->Dumpxs( [ \ %RNA ], [ qw{ *RNA } ] ); say q{-} x 50; foreach my $name ( sort keys %RNA ) { printf qq{%10s%8.2f%6d%8.2f%8.2f%8.2f\n}, $name, $RNA{ $name }->{ conc }, $RNA{ $name }->{ vol }, $RNA{ $name }->{ conc } * $RNA{ $name }->{ vol }, 30 / $RNA{ $name }->{ conc }, 50 / $RNA{ $name }->{ conc }; }

    Here's a run of it.

    Please enter name, conc. and vol. (CTRL-D to finish): -> Ash2 1.85 150 -> Ja2_1 1.89 150 -> Ja2_2 2.49 100 -> Set1_1 1.55 150 -> Set1_2 2.88 100 %RNA = ( 'Set1_2' => { 'vol' => '100', 'conc' => '2.88' }, 'Ja2_1' => { 'vol' => '150', 'conc' => '1.89' }, 'Ash2' => { 'vol' => '150', 'conc' => '1.85' }, 'Set1_1' => { 'vol' => '150', 'conc' => '1.55' }, 'Ja2_2' => { 'vol' => '100', 'conc' => '2.49' } ); -------------------------------------------------- Ash2 1.85 150 277.50 16.22 27.03 Ja2_1 1.89 150 283.50 15.87 26.46 Ja2_2 2.49 100 249.00 12.05 20.08 Set1_1 1.55 150 232.50 19.35 32.26 Set1_2 2.88 100 288.00 10.42 17.36

    Note that my use of ^D and the $dePrompt string tidies away the last prompt. I hope this is helpful.

    Cheers,

    JohnGG

Re: a simple work task
by Anonymous Monk on Jan 14, 2011 at 18:37 UTC
    Read from STDIN.
    chomp( my $line = <STDIN> ); print "You typed '$line'.\n";
      three inputs is like: jar, 2, 200 or separate by tab

      how to store three inputs on same line into three scalar variable?

      and loop on several lines of inputs?
        how to store three inputs on same line into three scalar variable?
        split
        and loop on several lines of inputs?
        open a file, or...
        while (<>) { # do something }
        See also perlintro

        You may be looking for something like this:

        ... print "Please enter RNAi name, concentration, volume: (empty line to +continue)\n"; while ((my $line = <STDIN>) ne "\n") { chomp $line; my ($name, $conc, $vol) = split ' ', $line; # split by whitespace $RNA{$name} = $conc; $vol{$name} = $vol; } ...