Octave Atelier

코드와 해설을 함께 읽는 학습 문서

Code Detail

printff

Statistics + Control & Dynamics 중심의 Octave 학습 예제

ex-pkg/printff.m

목록으로

코드를 복사해 Octave에서 바로 실행할 수 있습니다.

카테고리

Package Drill

package-drill

코드 길이

99

lines

작성자

-

날짜 정보 없음

패키지

none

pkg load

함수 시그니처

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

코드 해설

목적

  • Statistics + Control & Dynamics 중심의 Octave 학습 예제

입력

  • 파라미터: fmt_str

출력

  • 콘솔 텍스트 출력

실행 흐름

  1. 입력
  2. 출력

핵심 함수

  • evalin
  • length
  • fmt
  • isempty
  • strtrim
  • cell
  • printf
  • regexp

실습 과제

  • 같은 연산을 내장 함수와 사용자 함수 두 방식으로 계산해 오차를 비교해보세요.
  • 질량/감쇠/강성 또는 전달함수 계수를 바꿔 응답 변화를 확인해보세요.
  • 핵심 함수 evalin의 인자를 한 가지 바꿔 결과 변화를 기록해보세요.

같은 카테고리 코드

이전 코드 fmtf 다음 코드 demo_loop_speed