%-------------------------------------------------------------------------------
% lecture13
clear
clc
echo on
%-------------------------------------------------------------------------------
% Beginnings of object oriented programming (oop)
% + want to model multiple and related info
% + Tedious way: use many variables

% ex) model people
      fn1 = 'gene';
      ln1 = 'demaitre';
      id1 = 1234;

      fn2 = 'ben';
      ln2 = 'stein';
      id2 = 4321;

      % assume even more people!
    
% + Notes:
%   - different types causes weird behavior:
%     A = [1 'aa'] 
%     outputs just $aa$ (weird)
%   - even if use all strings, strings diff lengths (each char = 1 col)
%     A = ['a' 'bb' ; 'ccc' 'd']
%     causes error message because row 1 needs 3 cols and row 2 needs 4 cols

% + Want to:
%   - reduce redundant code
%   - clearly model "multiple" constructs (many parts make whole)

% + But how? use
%   - cell arrays
%   - structure arrays
% + exploring these leads into OOP!
%-------------------------------------------------------------------------------
% STRUCTURE ARRAYS (SAs)
% ======================
% General:
% + special kind of array
% + holds arrays inside elements   
% + arrays may be different types!
% + addresses elements by names called FIELDS
%   (CAs address elements by numerical indicies)
% + SAs usually 1-D but can be multi-dim
%-------------------------------------------------------------------------------
% Creating SAs
% ============
% + Just make assignments
% + to store values use the $.$ operator
%   syntax: name.field=value

  A.fn = 'ben'; 
  A.ln = 'stein';
  A.id = 4321
  pause
% A = 
%    fn: 'ben'
%    ln: 'stein'
%    id: 4321
%
% Note:
% + ML will display a reference if the field is not 1-D
% + Try $A.x = [1:3;3:5]$ and then displaying $A$
    A.x = [1:3;3:5]
    pause
%-------------------------------------------------------------------------------
% Retrieve values
  A.fn
% ans =
% ben
%-------------------------------------------------------------------------------
% Fields can be any other data structure, including another SA

% Create a new SA
  B.tests = [99 88]
  B.projects = [10 10 10];
  B
  pause
% B = 
%       tests: [99 88]
%    projects: [10 10 10]

% Create new field of A called $scores$
% Assign scores in $B$ to $A$
  A.scores = B
% A = 
%        fn: 'ben'
%        ln: 'stein'
%        id: 4321
%         x: [2x3 double] % for 9:05am, this is supposed to be 2x3, not 2x2
%    scores: [1x1 struct] % this is indeed correct!
%
% Notes:
% + $scores$ and $x$ values NOT 1-D, so ML uses pointers
% + But, values are still there!
% + Access particular value
%   name.(substructure access) means name.name.field
    A.scores.tests
%   ans =
%   99    88
%-------------------------------------------------------------------------------
% Additional Things:
% help struct
% help rmfield
% help getfield
% help setfield

% Preallocation
  SA1 = struct('x',0,'y',1)
% SA1 = 
%
%    x: 0
%    y: 1

% Removing fields
% + ML's SAs have a feature not common to other languages
% + Entering $rmfield$ will remove the NAME and CONTENTS of a field
% A = rmfield(A,'x')
% pause
% A = 
%
%    fn: 'ben'
%    ln: 'stein'
%    id: 4321
%    scores: [1x1 struct]
%-------------------------------------------------------------------------------
% Array of Structures
% + can create an array of SAs by "adding" another SA
%   - start with initial SA and make another
%   - give 1 or more fields a value
%   - ML automatically creates a new SA
%   - empty fields represented as empty array $[]$

  A(2).fn = 'gene';
  A(2)
% ans = 
%
%        fn: 'gene'
%        ln: []
%        id: []
%         x: []
%    scores: []

% + What's an array of SAs???
  A
% A = 
%
% 1x2 struct array with fields:
%    fn
%    ln
%    id
%    x
%    scores

% + to get individual SAs, enter $A(1),A(2)$
  pause
%-------------------------------------------------------------------------------
% Cell Arrays and Structure Arrays
% + Store info with $struct$
    s = struct('colors',{'blue','red','yellow'})
%   s = 
%
%   1x3 struct array with fields:
%      colors

% + $struct2cell$ and $cell2struct$
% help cell2struct                               
% CELL2STRUCT Convert cell array to structure array.
%    S = CELL2STRUCT(C,FIELDS,DIM) converts the cell array C into
%    the structure S by folding the dimension DIM of C into fields of
%    S.  SIZE(C,DIM) must match the number of field names in FIELDS.
%    FIELDS can be a character array or a cell array of strings.
% Huh?
% -> the number of columns of C must match the number of elements of FIELDS
% -> FIELDS is going to be 1-D array

 CA = {'ben' 'stein' ; 4321 []};
 % use $reshape$ (takes elements from cols)
 SA = cell2struct(reshape(CA,1,4),{'fn','id','ln','blank'},2)

% SA = 
%       fn: 'ben'
%       id: 4321
%       ln: 'stein'
%    blank: []

% Get lost? Check type:
  class(SA) % struct
  class(CA) % cell
%-------------------------------------------------------------------------------
