카테고리
Package Drillpackage-drill
코드와 해설을 함께 읽는 학습 문서
Code Detail
Statistics + Control & Dynamics 중심의 Octave 학습 예제
ex-pkg/printff.m
코드를 복사해 Octave에서 바로 실행할 수 있습니다.
function printff(fmt_str)
99 lines
function printff(fmt_str)
[formatted_str, var_list] = fmt(fmt_str);
% 변수의 실제 값을 가져옴
values = cell(size(var_list));
for i = 1:length(var_list)
values{i} = resolve_variable(var_list{i});
end
printf(formatted_str, values{:});
end
function [formatted_str, var_list] = fmt(fmt_str)
% fmt 함수는 Python의 f-string과 유사한 문자열 포맷팅을 수행합니다.
% 입력:
% fmt_str - 포맷팅할 문자열 (예: 'Hello, {name}')
% 출력:
% formatted_str - printf에 전달할 포맷 문자열
% var_list - printf에 전달할 변수 이름 리스트 (문자열)
%
% 예시:
% [fmt_str, vars] = fmt('Hello, {name}')
% printf(fmt_str, vars{:})
% 중첩 표현도 포함하는 정규표현식 패턴
pattern = '\{((?:[^\{\}:]+|\{[^\}]+\})+)(?::([^}]+))?\}';
tokens = regexp(fmt_str, pattern, 'tokens');
var_list = {};
for i = 1:length(tokens)
raw_expr = tokens{i}{1};
format_spec = '';
if length(tokens{i}) > 1
format_spec = tokens{i}{2};
end
% 변수 리스트에 원본 표현을 그대로 추가 (예: "name" 또는 "my_set{idx}")
var_list{end+1} = raw_expr;
% 포맷 문자열을 printf 서식에 맞게 변환
if isempty(format_spec)
fmt_str = regexprep(fmt_str, ['\{' regexptranslate('escape', raw_expr) '\}'], '%%s', 'once');
else
fmt_str = regexprep(fmt_str, ['\{' regexptranslate('escape', raw_expr) ':[^}]+\}'], ['%%' format_spec], 'once');
end
end
formatted_str = fmt_str;
end
function value = resolve_variable(var_expr)
% resolve_variable: caller 또는 base 워크스페이스에서 변수 평가
% 만약 var_expr에 중첩 괄호가 있으면, 단일 레벨로 분리하여 처리.
if ~isempty(strfind(var_expr, '{'))
% 단순화된 패턴: base 변수와 인덱스 표현 (예: "my_set{idx}" 또는 "my_set{i,j}")
pattern = '^([^{}]+)\{([^{}]+)\}$';
tokens = regexp(var_expr, pattern, 'tokens');
if isempty(tokens)
error('Cannot parse nested expression: %s', var_expr);
end
base_var = strtrim(tokens{1}{1});
index_expr = strtrim(tokens{1}{2});
% 인덱스가 다중 인덱스(콤마 포함)인 경우 분리
idx_parts = strsplit(index_expr, ',');
idx_values = cell(size(idx_parts));
for k = 1:length(idx_parts)
part = strtrim(idx_parts{k});
try
idx_values{k} = evalin('caller', part);
catch
idx_values{k} = evalin('base', part);
end
end
% base 변수 평가 (caller 또는 base)
try
base_value = evalin('caller', base_var);
catch
base_value = evalin('base', base_var);
end
% base_value가 cell array인 경우, {} 인덱싱; 그렇지 않으면 () 인덱싱
if iscell(base_value)
if length(idx_values)==1
value = base_value{idx_values{1}};
else
value = base_value{idx_values{:}};
end
else
value = base_value(idx_values{:});
end
else
% 단순 변수인 경우
try
value = evalin('caller', var_expr);
catch
value = evalin ex-pkg/ex-cms.m
ex-pkg/ex-control.m
ex-pkg/ex-fmt.m
ex-pkg/ex-fstring.m
ex-pkg/ex-image.m
ex-pkg/ex-io.m
ex-pkg/ex-optim.m
ex-pkg/ex-signal.m