use strict; use warnings; use Readonly; use Getopt::Long; use Scalar::Util::Numeric qw(isint); #age and avg_xp are calculated at the start of everyday. #The avg_xp=sum(XP)/#nodes in the past 7 days. #The program takes these two values in addition to #likes and #unlikes to dynamically compute reputation gains and losses. #Input for current reputation is prompted when it is time to update the reputation. my ($age, $avg_xp,$gained_rep, $lost_rep); my ($upvotes, $downvotes, $total_rep); my $current_rep; #variable to hold the current user reputation from the user page. my $vote; #a listener:either (u)pvote or (d)ownvote. Readonly::Scalar my $args =>4; #program accepts two args & two vals if(@ARGV != $args){die "syntax error: perl calculate_rep.pl --age n --avg_xp n\n";} GetOptions( "age=i"=>\$age, "avg_xp=i"=>\$avg_xp, )or die "syntax error: perl calculate_rep.pl --age n --avg_xp n\n"; print "enter u for upvote or d for downvote\n"; while($vote=<>){ chomp $vote; if($vote =~/^u$/i){ $upvotes++; analyze_upvotes($age, $upvotes); }elsif($vote=~/^d$/i){ $downvotes++; analyze_downvotes($age,$downvotes); }else{ print "ERROR: enter u for upvote or d for downvote\n"; } } sub analyze_upvotes{ my $node_age=shift; my $like_counter=shift; printf "you have %d likes\n",$like_counter; if($like_counter==1){#reward the first upvote $gained_rep=1; rep_update($gained_rep,"gain", $like_counter); $gained_rep=0; } if($age>2 && $like_counter>1){ #nodes older than two weeks get 1/5 rep increase $gained_rep+=1/5; if(isint $gained_rep){ #reputation is reported when gained reputation sums to a whole number rep_update($gained_rep,"gain", $like_counter); $gained_rep=0; } }elsif($age<=2 && $like_counter>1){ #rep for nodes < 2 weeks old is calculated with avg_xp perspective if($like_counter<=$avg_xp){ $gained_rep+=1/3; } elsif($like_counter>$avg_xp && $like_counter<=2*$avg_xp){ $gained_rep+=1/2; } elsif($like_counter>2*$avg_xp && $like_counter<=3*$avg_xp){ $gained_rep+=2/3; } elsif($like_counter>3*$avg_xp && $like_counter<=4*$avg_xp){ $gained_rep+=3/4; } elsif($like_counter>4*$avg_xp){$gained_rep+=1; $gained_rep=int $gained_rep; } if(isint $gained_rep){ if($current_rep-$gained_rep==0){ #for when cur_rep=1 and gained_rep=1; rep_update(1,"gain", $like_counter); }else{ rep_update($gained_rep, "gain", $like_counter); } $gained_rep=0; } } } sub analyze_downvotes{ my $node_age=shift; my $unlike_counter=shift; printf "you have %d unlikes\n", $unlike_counter; if($age<=2){ if($unlike_counter<= 3*$avg_xp){ $lost_rep+=1/3; } elsif($unlike_counter > 3*$avg_xp && $unlike_counter <= 4*$avg_xp){ $lost_rep+=1/4; } elsif($unlike_counter > 4*$avg_xp){ $lost_rep+=0; } if(isint $lost_rep){ rep_update($lost_rep, "loss", $unlike_counter); $lost_rep=0; } }elsif($age>2){ $lost_rep+=0;} } sub rep_update{ my $rep_gain_loss=shift; my $status=shift; my $like_unlike_counter=shift; print "what is the current user reputation?\n"; $current_rep=<>; chomp $current_rep; if($status eq "gain"){ my $total_gain=$current_rep + $rep_gain_loss; printf "you gained %d points\nyour reputation is %d\n", $rep_gain_loss, $total_gain; }elsif($status eq "loss"){ my $total_loss=$current_rep-$rep_gain_loss; printf "you lost %d reputation points\nyour reputation is %d\n", $rep_gain_loss,$total_loss; } }