% $Id: grades.m,v 1.7 2016/12/22 21:02:12 mike Exp $
AplusAB0=[0,65,75,85,95,100];

cellScores={
'Xxxxx,Xxxx'         '4+0'  '4+0'  '5+0'   '3+0'   '3+0L1' '4+8L4' '3+3L4' '3+0L10' '3+0L25'
};

% '5L75' is a way to directly input 25%

% vi commands to turn my grades to cell array
% make sure only student lines are in file and all grades are
% filled in.  Use vim, and:
%{
:%g/^ *$/d
:%s/^/'/
:%s/ *$/'/
:%s/\([a-z]\) /\1' /
:%s/ \([0-9]\)/ '\1/g
:%s/\([0-9]\) /\1' /g
1GyyP
:1s/^.*$/cellScores={/
Gyyp
:$s/^.*$/};/
%}

% or use sed script:
%{
1i cellScores={
$a };
/^ *$/d
s/^/'/
s/ *$/'/
s/\([a-z]\) /\1' /
s/ \([0-9]\)/ '\1/g
s/\([0-9]\) /\1' /g
%}

[nStudents,nLabs]=size(cellScores);

% make array of student names all of equal length
studentNames=char(cellScores{:,1});

% extract numeric values of scores from cellScores
numericScores=zeros(nStudents,nLabs);
extraCredit=zeros(nStudents,nLabs);
for student=1:nStudents
  for lab=2:nLabs
    t=cellScores{student,lab};
    if isempty(t)
      error(['empty string at student,lab=',num2str(student), ...
              ' ',num2str(lab)]);
    end
    v=str2num(t(1));
    v=max(v,0);
    numericScores(student,lab)=AplusAB0(v+1);
    if length(t)>1 && strcmp(t(2),'+')   % lazy evaluation
      extrastring=t(3:end);
      if isempty(extrastring)
        error(['+ w/o more info: "',t,'"']);
      end
      indexL=strfind(extrastring,'L');
      if ~isempty(indexL)
        if indexL > 1
          extraCredit(student,lab)=str2num(extrastring(1:indexL-1));
        end
      else
        extraCredit(student,lab)=str2num(extrastring);
      end
    end

        % subtract for late
    indexL=strfind(t,'L');
    if ~isempty(indexL)
      if isempty(t(indexL+1:end))
        error([' empty late string: "',t,'"'])
      end
      v=str2num(t(indexL+1:end));
      numericScores(student,lab)=numericScores(student,lab)-v;
    end
  end
end

% Do I really want extra credit to cancel late?
% maybe--objective is to get them to do extra credit
% maybe not--might end up with all labs to grade on last week

% some commented changes allow that carry-over extra credit points
% be valued at half
% currently allow full carry-over
% Might want to just not allow carry-over extra credit

% adjust for extra credit
adjustedScores=numericScores;
for student=1:nStudents
  extra=0;
  extraBank=0;  % bank contains half of previous unused extra points
  for lab=2:nLabs
    extra=extraCredit(student,lab);
    score=adjustedScores(student,lab);
    if score <= 100 & score>0  % only adjust labs that were turned in!
      need=100-score;
      if need>0
        if extra > need
          adjustedScores(student,lab)=score+need; % no score exceeds 100
          % extraBank=extraBank+round((extra-need)/2+.01);
          extraBank=extraBank+(extra-need); % carry full value forward
	else
	  if extraBank>(need-extra)
            adjustedScores(student,lab)=score+need; % no score exceeds 100
            extraBank=extraBank-(need-extra);
          else
            adjustedScores(student,lab)=score+extra+extraBank;
            extraBank=0;
          end
        end
      else
        %extraBank=extraBank+round(extra/2+.01);
        extraBank=extraBank+extra;
      end
    end
  end
end

sums=sum(adjustedScores,2);
aves=sums/(nLabs-1);

% create format for totals
fmt='%s\t';
for lab=2:nLabs
  fmt=[fmt,'%3d '];
end
fmt=[fmt,'%3d %3.0f\n'];

fid=0;
fid=fopen('grades.summary','w');
fprintf('\n\n\t\t Scores(plus extra credit) with adjusted sum and ave\n');
if fid~=0
  fprintf(fid,'\n\n\t\t Scores(plus extra credit) with adjusted sum and ave\n');
end

name='Student_Name';
for k=14:length(studentNames(1,:))
  name=[name,' '];
end
fprintf('%s\t',name);
for lab=2:nLabs
  fprintf(' Lab%2d ',lab-1);  % start with lab 1
end
fprintf(' sum ave\n');

if fid~=0
  fprintf(fid,'%s\t',name);
  for lab=2:nLabs
    fprintf(fid,' Lab%2d ',lab-1);
  end
  fprintf(fid,' sum ave\n');
end

for student=1:nStudents
  fprintf('%s\t',studentNames(student,:));
  for lab=2:nLabs
    fprintf('%3d(%1d) ',numericScores(student,lab), ...
	    extraCredit(student,lab));
  end
  fprintf('%4d %3.0f\n',sums(student),aves(student));
  if fid~=0
    fprintf(fid,'%s\t',studentNames(student,:));
    for lab=2:nLabs
      fprintf(fid,'%3d(%1d) ',numericScores(student,lab), ...
  	    extraCredit(student,lab));
    end
    fprintf(fid,'%4d %3.0f\n',sums(student),aves(student));
  end
end
if fid~=0
  fclose(fid);
end

