最初の頃はあまりこの問題を認識していなかったのですが、データが整ってきていざ解析、となってくると、日々様々なグラフを作っては検討し、という繰り返しになってきます。この段階では、とりわけLive Scriptを使用するのが有利です。コードと共にグラフや数値出力を保存できるので、レポート用紙やノートブックのような感覚で使えます。
このようなスタイルで色々思いつく解析を試していくと似たような、しかし少しだけ違うLive Scriptファイルがたくさんできてきます。古い解析結果も、ノートブックのような感覚で残しておきたいが、中身がほぼ同じだったりするので新しいLive Scriptファイルとの間でどうやって名前を区別するかという**「名付け親」の苦しみ**が出てくるのです。苦しみというのは大袈裟かもしれませんが、本質的ではない部分で結構知恵を使わなければならず、煩わしいものです。
日付に基づいた接頭辞を用いてスクリプトを命名する
こちらの記事「解析において僕の考える最強のフォルダ構成」を参考にしましたが、これに対する単純明快な解決法はスクリプトファイルの名前を日付で始めるということです。実際には数字でファイル名を始めることが許されていませんから、アルファベットで始める必要があります。私の場合はscriptなので、接頭辞scrをつけて 以下のようにしています。
scr2017_02_15_115520_thisisagreatscript.mlx
つまり「年月日時分秒」を名前の頭に持ってくるのですが(正直「秒」は不要かもしれません)、こうすると何が嬉しいのでしょうか?
- ほとんど似たような内容のスクリプトでも気にせずに同じ名前で日付だけ変えて保存できるので身軽
- 見ただけでスクリプトだと分かる(関数やクラスではない)
- 見ただけでいつ頃の仕事だかイメージできる
- フォルダ内に日付順にスクリプトファイルが並ぶので仕事の進捗が見えやすい
ということに尽きるかもしれません。特に感じるのは、新しく解析を始めるときに抵抗感が少ないのです。
よく似た方法として、thisisagreatscript.mlx
, thisisagreatscript2.mlx
,
thisisagreatscript3.mlx`, ... と接尾辞で番号を付加して対応するやり方のほうがすぐに思いつくかもしれませんが、これの欠点は、
- 情報が少なくなる
- フォルダ内に類似した内容のファイルがまとまって表示され、仕事の進捗が見えにくい。(もちろんフォルダ表示の仕方を変えれば対応できますが)
- 一見してスクリプトなのか関数なのか判断できない
- 最初に名前をつける時は**「う~ん」と考えて**よい名前をつける必要がある
- だんだんヴァージョンが増えてきて内容が変わってきたときにどこから別の名前に切り替えようか悩む
これは内容毎にグループ化して捉えるか、日付でグループ化して捉えるかの違い、と言ってもよいと思います。野口悠紀雄の「超整理法」という本が昔流行りましたが、これは紙の書類を片付けるときに、内容毎に分類するのをやめて、押出しファイル形式と言って新しいものを本棚の左端に入れると決める、という提案でした。考え方としてはちょっと似ていると思います。
実感として、**私はscr20170215_120747_*.mlx
形式に切り替えてから、飛躍的にスクリプトの数が増えました。**身軽になった分、新しい解析に取り組む敷居が下がったのだと思っています。
関数 scriptname
以下のscriptnameという関数はさらにこれを身軽にするために考えたもので、コマンドウィンドウで
scriptname
と呼び出せば
scr20170215_120747_*.mlx
と出力され、ファイルの命名を助けてくれます。
scriptname hoge
と呼び出せば
scr20170215_120747_hoge.mlx
と、出来上がった形でのスクリプト名を返してくれます。
結論的なスクリプトは別のルールで
こちらの記事「解析において僕の考える最強のフォルダ構成」の執筆者も教えてくれましたが、こうやってたくさんスクリプトを貯めると、あとから見たときにどれが一番大事だったかパッと分かりにくいという問題が生じます。
私の場合はmain_
という接頭辞をつけることにしており、main_hoge.mlx
が最終版です。これは通常論文のための図などを意味します。
現在、私の作業フォルダには多数のscr*.mlx
ファイルが溢れており、小数のmain_*.mlx
ファイルが混じっています。
ぜひ一度お試しください。
function varargout = scriptname(varargin)
% scriptname prints something like 'scr2016_07_05_163045_thisscript.mlx' to
% Command Window.
%
% Including and beginning with automatically generated serial date-time
% string in the name of script releases you from the burden of thinking of
% unique name for each script. It is also easy to see the progress and
% shift of your work over time.
%
% scriptname()
% scriptname(datenumber)
% scriptname(datenumber,name)
% newname = scriptname(_____)
%
% INPUT ARGUMENTS
% datenumber Serial date number in double | now (default)
% (Optional)
%
% name char
% (Optional) Name of the new script. Illegal charcaters will be
% replaced with _. If you include '.m' or '.mlx' at the end of
% name, it will be maintained. Otherwise, '.mlx' will be added
% at the end of name.
%
% OUTPUT ARGUMENTS
% newname Name of the new script in char. It begins with 'scr',
% followed by date and time in the format '2016_07_01_121500_',
% and then by 'newscriptname.mlx' or 'newscriptname.m'
% eg. scr20160701_121500_newscriptname.mlx
%
%
% See also
% K_MATLAB_shortcuts, datename
%
% Written by Kouichi C. Nakamura Ph.D.
% MRC Brain Network Dynamics Unit
% University of Oxford
% kouichi.c.nakamura@gmail.com
% 11-Jul-2016 07:03:17
switch nargin
case 0
datenumber = now;
name = '*.mlx';
case 1
if isa(varargin{1},'double')
datenumber = varargin{1};
name ='*.mlx';
elseif ischar(varargin{1}) && isrow(varargin{1})
datenumber = now;
name = varargin{1};
else
error('The input argument is of wrong type')
end
case 2
datenumber = varargin{1};
name = varargin{2};
otherwise
error('too many input arguments')
end
if ~strcmp(name,'*.mlx')
ext = regexp(name,'\.m(lx|)$','match');
if isempty(ext)
ext = '.mlx';
else
ext = ext{1};
end
namestem = regexprep(name,'\.m(lx|)$','');
namestr = regexprep(namestem,'[^a-zA-Z0-9_]','_');
newnamestem = [namestr,ext];
else
newnamestem = name;
end
newname = sprintf('scr%s_%s',datename(datenumber),newnamestem);
if length(regexprep(newname,'\.[a-z]*$','')) > namelengthmax
warning('K:scriptname:toolong',...
'The length %d of the new name not including the file extention exceeds the max length %d allowed.',...
length(regexprep(newname,'\.[a-z]*$','')),namelengthmax)
end
if nargout > 0
varargout{1} = newname;
else
disp(newname) %#ok<DSPS>
clipboard('copy',newname);
end
end
%--------------------------------------------------------------------------
function s = datename(t)
% A wrapper of datestr for variable/file name
% s = datename(t)
%
% s = datestr(t,'YYYY_DD_MM_hhmmss')
%
% INPUT ARGUMENTS
% t a datetime value
%
%
% This utility funciton may be useful in preparing a data/time-based file
% names or variable nakmes.
%
% See also
% datestr,now
%
% Written by Kouichi C. Nakamura Ph.D.
% MRC Brain Network Dynamics Unit
% University of Oxford
% kouichi.c.nakamura@gmail.com
% 30-Jun-2016 15:21:00
s = datestr(t,'yyyymmdd_HHMMSS');
end