File: ef230-2023-08/www/examples/gpa2.m Download
%! GPA calculator example
%! reads and writes text data files

function gpa2(name)
clc;
% use one of the two lines below, depending upon how you want to store data
file_type = 'txt';  % store data in text format
% file_type = 'mat';  % store data in matlab format

% get data set name
if nargin==0
    v=inputdlg('Enter Name','File name',1,{'lazydog'});
    if isempty(v), return, end
    name = v{1};
end
filename = ['gpa_' name '.' file_type];

% load data - use default set of classes if file not found
data = gpa2_readdata(filename);

while 1 % loop to show current data and process changes
    % build display text for classes and grades
    clear names;
    for i=1:length(data);
        names{i}=sprintf('%1.0f   %2s   %s',data(i).hrs,data(i).grade,data(i).name);
    end
    names{length(data)+1} = '...add a class';

    % show main list
    prompt{1}=sprintf('File: %s',filename);
    prompt{2}=sprintf('GPA=%3.2f',gpa2_calc_gpa(data));
    prompt{3}='Select course(s) to update';
    firstblank = find(strcmp({data(:).grade},''),1);
    todo = listdlg('ListString',names,...
        'name','Nuclear Engineering',...
        'initialvalue',firstblank,...
        'listsize',[200 500],...
        'PromptString',prompt);

    % process requested changes
    if isempty(todo)
        break; % done
    else
        % update class data for each selected class
        for t=todo
            if (t>length(data))  % add new class choice
                data(t).name='New class';
                data(t).hrs=3;
                data(t).grade='';
            end
            data(t) = gpa2_update_class(data(t));
        end

        % remove 0 hr classes
        for i=length(data):-1:1  %start at end and work backwards
            if data(i).hrs==0
                data(i)=[];
            end
        end
    end

end

% done, save changes if desired
yn = questdlg('Save Data','GPA Calculator','Yes','No','Yes');
if strcmp(yn,'Yes')
    if file_type=='mat'
        save(filename,'data');  % save data
    else
        gpa2_save(filename,data);
    end
end
return

function c=gpa2_update_class(c)
% display data for a class and allow changes
p = {'Name','Hrs (set to 0 to delete class)','Grade'};
d{1}=c.name;
d{2}=num2str(c.hrs);
d{3}=c.grade;
nd = inputdlg(p,'Class info',1,d);
if ~isempty(nd)
    c.name=nd{1};
    c.hrs=str2num(nd{2});
    c.grade=upper(strtrim(nd{3}));
end
return

function gpa = gpa2_calc_gpa(data)
% calculate gpa
qpts = 0;
hrs = 0;
for i=1:length(data)
    if length(data(i).grade)>0
        qpts = qpts + data(i).hrs*gpa2_grade_value(data(i).grade);
        hrs = hrs + data(i).hrs;
    end
end
if hrs==0
    gpa=0;
else
    gpa=qpts./hrs;
end
return

function v=gpa2_grade_value(g)
% compute a letter grade value

% nothing
if length(g)==0
    v=0;
    return;
end

% main grade
if g(1)=='A'
    v=4;
elseif g(1)=='B'
    v=3;
elseif g(1)=='C'
    v=2;
elseif g(1)=='D'
    v=1;
else
    v=0;
end

if length(g)==1
    return
end

% +/- adjust
if g(2)=='+'
    v=v+.3;
elseif g(2)=='-'
    v=v-.3;
else
end
return

function data = gpa2_readdata(filename)
% read data from a file,use default data if file not present
if exist(filename,'file')
    len = length(filename);
    file_type = filename(len-2:len);
    if file_type=='mat'
        load(filename);
    else
        data = gpa2_load(filename);
    end
else
    default_names = {
        'Chem 120',4
        'Chem 130',4
        'EF105',1
        'EF 151',4
        'EF 152',4
        'Eng 101',3
        'Eng 102',3
        'Math 141',4
        'Math 142',4
        'Econ 201',4
        'ECE 301',3
        'ME 202',2
        'Math 231',3
        'Math 241',4
        'EF 230',2
        'ME 331',3
        'Phys 231',3
        'Phys 232',4
        'Math 403',4
        'NE 342',3
        'NE 351',3
        'NE 360',3
        'NE 401',3
        'NE 433',3
        'NE 470',4
        'EF 402',1
        'ME 321',3
        'MSE 201',3
        'NE 402',3
        'NE 406',3
        'NE 472',4
        'Philosophy Elective',3
        'Elective 1',3
        'Elective 2',3
        'Elective 3',3
        'Technical 1',3
        'Technical 2',3
        };

    % build an array of structures based on existing data
    for i=1:length(default_names)
        data(i).name=default_names{i,1};
        data(i).hrs=default_names{i,2};
        data(i).grade=''; % not taken
    end
end
return

function data = gpa2_load(filename)
% load text file containing grade data
% text file must be formatted like this
% Column  Data
% 1       course hours
% 3-4     course grade
% 6...    course name
% blank lines are skipped
% lines beginning with % are skipped
fid=fopen(filename,'rt');
n=0;
disp(['Reading ' filename]);
while 1
    line = fgetl(fid); % get next line from file
    if line==-1  % end of file
        break;
    end
    line = strtrim(line);
    if length(line)==0, continue, end; % skip blank lines
    if line(1)=='%', disp(line), continue, end; % skip comment lines
    n=n+1;
    data(n).hrs = str2num(line(1));
    data(n).grade = strtrim(line(3:4));
    data(n).name = line(6:end);
end
fclose(fid);
return

function gpa2_save(filename,data)
% save data in a text file (see above for format)
fid=fopen(filename,'wt');
fprintf(fid,'%% GPA data file written %s\n',datestr(now));
for i=1:length(data)
    fprintf(fid,'%1.0f %-2s %s\n',data(i).hrs,data(i).grade,data(i).name);
end
fclose(fid);
return