はじめに
前回、こちらのブログ記事にて、Sturtevantの構造複雑度を使用したメトリクスの活用という題目のもと、VFI・VFO(Visibility Fun-in/out)を使った閾値分けについて紹介しました。[第2回記事はこちらから]
今回はこのシリーズの最後としまして、閾値分けを行ったVFI・VFOに対して、分析しやすいように、グラフにプロットすることご紹介します。
プロット関数の定義
まず、グラフとしてプロットするために、必要なプロット関数の定義を以下のように行います。
今回はプロット関数を2種類用意し、グラフにプロットしていきます。
構造複雑度別に各ファイルをプロットする関数
def plot_xy(x_metrics,y_metrics,df,title=""):
if title == "":
title = str(x_metrics)+"-"+str(y_metrics)+"のグラフ(構造複雑度別)"
x_metrics = x_metrics
y_metrics = y_metrics
x = df[x_metrics]
y = df[y_metrics]
group = df["group"]
import plotly.express as px
symbols =["circle","square","star","x","cross"]
data = [
go.Scatter(
x=x[group==i], y=y[group==i],
name=groupname[i],
mode = 'markers',
marker = dict(color=px.colors.qualitative.Plotly[i],
size=6,
symbol='star'
),
text = df["サブシステム"][group==i]
)
for i in range(len(groupname))
]
fig = go.Figure(data=data)
fig.update_xaxes(title_text=x_metrics)
fig.update_yaxes(title_text=y_metrics, hoverformat=".3f")
fig.update_layout(title=dict(text='<b>'+title,
font=dict(size=26,
color='black'),
xref='paper', # container or paper
x=0.5,
y=0.9,
xanchor='center'
))
plotly.offline.iplot(fig)
return fig
クロス集計した結果をプロットする関数
def plot_xy_cross(x_metrics,y_metrics,df,title=""):
if title == "":
title = str(x_metrics)+"-"+str(y_metrics)+"のグラフ(クロス集計)"
x_metrics = x_metrics
y_metrics = y_metrics
x = df[x_metrics]
y = df[y_metrics]
group = df["group"]
cyc_group = df["cyc_group"]
symbols =["circle","square","star","x","cross"]
data = [
go.Scatter(
x=x[cyc_group==i][group==j], y=y[cyc_group==i][group==j],
name=cyc_groupname[i]+" & "+groupname[j],
mode = 'markers',
marker = dict(color=px.colors.qualitative.Plotly[i],
size=4,
symbol=symbols[j]
),
text = df["サブシステム"][group==j][cyc_group==i]
)
for i in range(len(cyc_groupname)) for j in range(len(groupname))
]
fig = go.Figure(data=data)
fig.update_xaxes(title_text=x_metrics)
fig.update_yaxes(title_text=y_metrics, hoverformat=".3f")
fig.update_layout(title=dict(text='<b>'+title,
font=dict(size=26,
color='black'),
xref='paper', # container or paper
x=0.5,
y=0.9,
xanchor='center'
))
plotly.offline.iplot(fig)
return fig
VFI-VFOグラフの描画
ここからは上記で定義したプロット関数を使って、VFI-VFOグラフを描画していきます。
VFI-VFOグラフの描画
fig = plot_xy("VFI","VFO",df_ltx_file,"VFIとVFOの各ファイル分布(構造複雑度別)")
fig.write_html("VFIとVFOの各ファイル分布(構造複雑度別).html")
今回出力するVFI-VFOグラフはplotlyで触れるインタラクティブなグラフを生成しているため、(jupyterから出力されたhtmlでもインタラクティブ性が維持される)以下のようなこともグラフに対して操作できます。
- 各データ点をマウスオーバーすることでファイル名のポップアップ
- 凡例毎に表示/非表示の操作
- グラフ内をドラッグすることで範囲を限定して表示(グラフをダブルクリックで全体表示に戻る)
- x軸、y軸のスクロールの操作
出力すると以下のようなグラフを表示することができます。
fig = plot_xy_cross("VFI","VFO",df_ltx_file,"VFIとVFOの各ファイル分布(クロス集計)") fig.write_html("VFIとVFOの各ファイル分布(クロス集計).html")
このグラフから、ファイルがどこの閾値のグループに属しているのかを視覚的に確認することができます。
また、影響が大きいファイルを事前に把握することで、属するグループ毎に、重点的にレビューやテストを行うなどの対応策を事前に打ち出すことができます。その結果、ソースコードの修正の効率化、不具合混入のリスクを下げるなどの効果を期待できます。
まとめ
今回、計3回に渡って、Sturtevantの構造複雑度の分析スクリプトをご紹介しました。
Understand・Lattixでメトリクスを計測することはできていても、なかなかどのように活用すればよいか分からない、効率的にソースコードの保守を行うにはどうすればよいのか分からない、といった、課題について、解決策のひとつとして参考いただけると幸いです。
また、今後もこのような分析を手助けするようなTipsもご紹介できればと思います。
最後までご覧いただきありがとうございました。