Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

001 sub adjust{ 002 my $self = shift; 003 my $instructions = shift; # $instructi

ID: 3537110 • Letter: 0

Question

001 sub adjust{

002 my $self = shift;

003 my $instructions = shift; # $instructions = [{mode => *mode*,lot_id => XXX, location_id => XXX,quant => XXX, nlocation_id = XXX }, ...]

004 my $cust_id = shift;

005

006

007 return $self->_error('no instructions arrayref specified') unless ref($instructions) eq 'ARRAY';

008

009 my @lotids;

010 foreach my $inst (@{$instructions}){

011 return $self->_error('mode must be specified') unless $inst->{mode};

012 return $self->_error('location_id must be specified') unless $inst->{location_id};

013 return $self->_error('quant must be specified') unless $inst->{quant};

014 if($inst->{mode} eq 'move'){

015 return $self->_error('nlocation_id must be specified') unless $inst->{nlocation_id};

016 }elsif($inst->{mode} eq 'adjust'){

017 return $self->_error('reason_code must be specified') unless $inst->{reason_code};

018 }elsif($inst->{mode} eq 'sale'){

019 #

020 }else{

021 return $self->_error("invalid mode $inst->{mode}");

022 }

023 push @lotids, $inst->{lot_id};

024 }

025

026 my $dbh = $self->{dbr}->connect('esrp_main') || return $self->_error('failed to connect to esrp_main');

027

028 return $self->_error('failed to select tracking') unless

029 my $transactions = $dbh->select(

030 -table => 'tracking',

031 -fields => [qw(row_id lot_id location_id quantity)],

032 -where => {

033 status => ['d',1], # 1 = active, 2 = retired

034 lot_id => ['in d',@lotids],

035 }

036 );

037

038 my %lottrack;

039 foreach my $transaction (@{$transactions}){

040 my $lotid = $transaction->{lot_id};

041 my $locid = $transaction->{location_id};

042

043 my $ref = $lottrack{ $lotid }->{ $locid } ||= {};

044

045 $ref->{quantity} += $transaction->{quantity};

046 push @{$ref->{row_ids} ||= []}, $transaction->{row_id};

047 }

048

049 my @retire;

050 my @newtrans;

051

052 #Now loop through the instructions and figure out how to execute them

053 foreach my $inst (@{$instructions}){

054 my $track = $lottrack{ $inst->{lot_id} }->{ $inst->{location_id} }; # pre existing quantity

055

056 my $changequant = $inst->{quant};

057

058 if ($inst->{mode} eq 'move') {

059 return $self->_error("no pre-existing quantity found for lot $inst->{lot_id} loc $inst->{location_id}") unless $track;

060

061 if ($changequant > $track->{quantity}) {

062 $changequant = $track->{quantity};

063 }

064 if ($changequant > 0) {

065 next if $inst->{nlocation_id} == $inst->{location_id}; #skip if its the same place

066 my $remainder = $track->{quantity} - $changequant;

067

068

069 my $status;

070 if($remainder == 0){

071 # none are left in the old location, they no longer need to be status 1

072 push @retire, @{$track->{row_ids}};

073 $status = 2;

074 }else{

075 $status = 1;

076 }

077

078 push @newtrans,{

079 quant => 0 - $changequant,

080 loc_id => $inst->{location_id},

081 lot_id => $inst->{lot_id},

082 action => 6, #moveout

083 status => $status, # might be live or retired

084 };

085

086

087 push @newtrans,{

088 quant => $changequant,

089 loc_id => $inst->{nlocation_id},

090 lot_id => $inst->{lot_id},

091 action => 3, #movein

092 status => 1, # live

093 };

094

095 }

096 } elsif ($inst->{mode} eq 'adjust') {

097 if ($changequant > 0) {

098 my $reason = $inst->{reason_code};

099

100

101 my $status;

102 if($reason =~ s/^A//i){

103 #Add

104 # no existing track is needed

105 $status = 1;

106 }elsif($reason =~ s/^S//i){ # subtract

107 return $self->_error("no quantity found for lot $inst->{lot_id} loc $inst->{location_id}") unless $track;

108

109 #chop requested quantity down so we don't go negative

110 $changequant = $track->{quantity} if $changequant > $track->{quantity};

111

112 my $remainder = $track->{quantity} - $changequant;

113 if ($remainder == 0) {

114 # none are left in the old location, they no longer need to be status 1

115 push @retire, @{$track->{row_ids}};

116 $status = 2;

117 } else {

118 $status = 1;

119 }

120

121 $changequant *= -1;

122 }else{

123 return $self->_error('no reason type specified');

124 }

125 $reason =~ s/D//g;

126

127 push @newtrans,{

128 quant => $changequant,

129 loc_id => $inst->{location_id},

130 lot_id => $inst->{lot_id},

131 action => 4, #adjust

132 reason => $reason,

133 status => $status,

134 };

135 }

136 }elsif ($inst->{mode} eq 'sale') {

137 if ($changequant > 0) {

138 return $self->_error("sale quantity exceeds available amount ($inst->{lot_id},$inst->{location_id},$changequant)") if

139 $changequant > $track->{quantity};

140

141 my $remainder = $track->{quantity} - $changequant;

142

143 my $status;

144 if($remainder == 0){

145 # none are left in the old location, they no longer need to be status 1

146 push @retire, @{$track->{row_ids}};

147 $status = 2;

148 }else{

149 $status = 1;

150 }

151

152 push @newtrans,{

153 quant => 0 - $changequant,

154 loc_id => $inst->{location_id},

155 lot_id => $inst->{lot_id},

156 action => 5 #sale

157 status => $status

158 };

159 }

160 }

161 }

162

163

164 $dbh->begin();

165

166 if (@retire) {

167

168 return $self->_error('failed to update tracking') unless

169 $dbh->update(

170 -table => 'tracking',

171 -fields => {status => ['d',2]},

172 -where => {

173 status => ['d',1], # 1 = active, 2 = retired

174 row_id => ['in d',@retire],

175 }

176 );

177 }

178

179 my $time = time();

180 foreach my $new (@newtrans){

181 return $self->_error('failed to insert tracking') unless

182 $dbh->insert(

183 -table => 'tracking',

184 -fields => {

185 lot_id => ['d',$new->{lot_id}],

186 date => ['d',$time],

187 status => ['d',$new->{status}],

188 location_id => ['d',$new->{loc_id}],

189 quantity => ['d',$new->{quant}],

190 action => ['d',$new->{action}],

191 reason => ['d',$new->{reason} || 0],

192 cust_id => ['d',$cust_id || 0],

193 },

194 );

195 }

196

197 $dbh->commit();

198

199

200 return 1;

201

202 }


1. What are your impressions of the style of this code?


2. What coding methodology is being used here?


3. What do you think the variable $self represents?


4. Describe the purpose of the code on lines 10-24


5. Describe what is happening on line 46


6. Describe what is happening on line 121


7. What is the purpose of prepending a letter to the reason_code parameter in a given instruction?


8. In your own words, Describe in detail the purpose of lines 39-47


9. Describe why $status is specified on line 83 but not on line 92, and the resulting effect.

10. Given the question #8, what do you think would be a more appropriate name for the %lottrack hash?


11. Are there any other variable names that you would change if you were to write this software? If so what would you change them to?


12. Can you spot any syntax or logical errors in the code? if so, please list them.


13. Describe any concepts in this code that you consider to be novel or interesting.


14. Please give your general impression of the sample code.


15. Are there any parts of this code you might have done differently? If so, how would you have done it?

Explanation / Answer

1. What are your impressions of the style of this code?

The style of code is procedural using a single sub-routine.


2. What coding methodology is being used here?

the coding methodology is CRUD - Create Read Update Delete, though in a procedural manner.


3. What do you think the variable $self represents?

It refers to the current running instance of the program.


4. Describe the purpose of the code on lines 10-24

Its a series of checks to validate the input 'instructions', and return proper error messages when required.

It's basically doing Input Validation.


5. Describe what is happening on line 46

Its inserting the row_id of the current transaction, into a list of already referred row_ids ( that is being pointed to by the ref variable).

Hence, its keeping track of all rows modified till now..


6. Describe what is happening on line 121

Its changing the sign of the quantity (i.e, either from negative to positive )


7. What is the purpose of prepending a letter to the reason_code parameter in a given instruction?

Its to keep track of whether the reason_code is validated or not.


8. In your own words, Describe in detail the purpose of lines 39-47

For each transaction, add the quantity in that transaction to specified lot & location (by lot_id, location_id).

Also keep track of the rows affected by keeping a list of referred row_ids.


9. Describe why $status is specified on line 83 but not on line 92, and the resulting effect.

Because it 82, we are oving out data, so we need to check the data status (whether its live or dead,i.e, whether its still useful or not)

This check is got by the variable $status.

In 92, we are moving in data, so we status is always live,i.e, status=1.

10. Given the question #8, what do you think would be a more appropriate name for the %lottrack hash?

lotList would be more proper.


11. Are there any other variable names that you would change if you were to write this software? If so what would you change them to?

NO


12. Can you spot any syntax or logical errors in the code? if so, please list them.

Not any currently.


13. Describe any concepts in this code that you consider to be novel or interesting.

I find the checking of status via live or dead novel, as its keeps the transactions, hence the database hash (lottrack) in a consistent state throughout.


14. Please give your general impression of the sample code.

The code is good, however should have been made more modular, by adding more proper subroutines.(not just the one in sub adjust).


15. Are there any parts of this code you might have done differently? If so, how would you have done it?

I would have added more subroutines to to separate the of Updating, Reading,Writing and Creating the database hash.