http://qs1969.pair.com?node_id=1084640


in reply to Weighted Calculation

I don't understand why you make a case distinction for users with and without weight. Just assume that that users without one have weight 1.

Also I don't understand if there are any constraints related to how work can be redistributed. If not, simply add all the weights (and 1 for unweighted users), divide the total work units by that sum, and then you have the amount of work a "normal" user has to. Scale it by each users's weight to get the work she has to do.

#!/usr/bin/env perl use 5.010; use strict; use warnings; use List::Util qw/sum/; my %user_weight = (DREW => .5, TIM => 2,); my $total_work; while (<DATA>) { my @cols = split; $user_weight{$cols[0]} //= 1; $total_work += $cols[1]; } my $total_weights = sum values %user_weight; my $work_per_unit = $total_work / $total_weights; for my $u (sort keys %user_weight) { printf "%s: %.2f\n", $u, $work_per_unit * $user_weight{$u}; } __DATA__ TIM 150 JOE 124 JACK 111 KATE 145 DREW 177

Replies are listed 'Best First'.
Re^2: Weighted Calculation
by dirtdog (Monk) on May 01, 2014 at 16:35 UTC

    thanks for weighing in Moritz..pun intended..but i can't seem to get this to work. I know what you're doing with the following statement, but for some reason it's not working. Is the syntax correct?

     $user_weight{$cols[0]} //= 1;
      This a relatively new feature. Which version of Perl are you using?

      If your version is old, try this line instead:

      $user_weight{$cols[0]} = 1 unless defined $user_weight{$cols[0]} ;

      ..but for some reason it's not working. Is the syntax correct?

      If you are using perl version 5.10.0 and above, it should work. Of course the syntax is correct.
      However, this also work:     $user_weight{$cols[0]} ||= 1;

      The Defined-or operator was implemented in perl 5.10.0 check Defined-or-operator

      Update:

      Oops, I didn't see tye answer before posting mine, I had this post opened, then got distracted with some other things before submitting my post later. Only to refresh and see that mine post was in a way similar to his.
      +1 tye all the same.

      If you tell me, I'll forget.
      If you show me, I'll remember.
      if you involve me, I'll understand.
      --- Author unknown to me
        However, this also work:   $user_weight{$cols[0]} ||= 1;

        That will fail in the case in which the 'special' assigned weight for a worker is zero (maybe he or she is on vacation that week?): such a worker will be assigned a work-weight of 1.

        Update: Perl versions lacking  // might use exists:
            $user_weight{$cols[0]} = 1 unless exists $user_weight{$cols[0]};