LOCカウンターを開発する機会があったので公開します
LOCカウンター(行数計測カウンター)を開発する機会があったので、その時に開発したカウンターをgithubに載せたことを報告しておきます。
自分でも思うのですが、おそらく使いどころはかなり限られると思いますし、関数ベースでプログラミングしているので設計にちょっと失敗しているかもしれない。
後で、暇でやる気になったときクラスベースで書き換えようと思います。
でもせっかく開発したので、オープンにしたいと思ってこの記事書いてます!!
なお、LOCというのは行数と同義です。
ダウンロードはこちらから(counter.exe)
開発経緯
PROBE法という見積もり法で見積もりを行う際に、クラスのLOCを計測する必要があったため開発しました。
これまで納期などを意識することなく趣味のようなものでプログラムやアプリ開発をしてきたのですが、クラウドソーシングなどで案件を受注したいと思い、そろそろしっかりプロジェクト管理について学ぼうと考えました。
そこで、プログラムの追加&修正規模から総開発時間を見積もるPROBE法というものを勉強していました。
PROBE法では、まず新規に開発するクラスや再利用するクラスなどのLOCを用いてプログラム全体の追加&修正規模を求めます。 そしてその追加&修正規模から総開発時間を見積もることになります。
そのため、クラスや関数のLOCを計測するカウンタープログラムを開発しました。
LOCカウンタープログラムで計測できるもの
- クラスのLOC
- 関数FunctionのLOC
- 1クラスのメソッド数
以下に実行例を記載しておきます。
LOCカウンターの仕様
- OS=Windows10
- 対象ファイル拡張子は .cpp または .h(それ以外だとプログラムが終了します)
- コマンドプロンプトなどで
counter.exe yourprogram_files
で引数のファイルのLOCをカウントできます(引数はいくつでも可) - 空行、コメントのみの行、{ または }のみの行はカウントしません
- LOCをカウントしたいクラスの定義箇所の先頭に
// class begin
を、末端に// class end
を付ける(以下に具体例を示します) - LOCをカウントしたい関数の定義箇所の先頭に
// function begin
を、末端に// function begin
を付ける(以下に具体例を示します) - クラス名、関数名の後ろに半角スペースを空けたあと引数を定義する(以下に具体例を示します)
- 1クラスのメソッドを数えたい場合は、メソッドの定義箇所の先頭に
// method
を付ける(以下に具体例を示します)
具体例
#include<iostream> #include<string> using std; class HelloWorldObj // class begin { private: string str; public : HelloWorldObj() { str = "Hello World!"; } HelloWorldObj(string name) { str = "Hello World! " + name; } void add_name(string name) // method { str += name; } void print() // method { cout << str << endl; } } // class end int main (void) // function begin { HelloWorldObj hwo1 = new HelloWorldObj(); HelloWorldObj hwo2 = new HelloWorldObj("taro"); hwo1.print(); hwo2.print(); hwo2.add_name("ziro"); hwo2.print(); return 0; } // function end
上記の内容のファイルmain.cppがあるとしたら
コマンドプロンプトでcounter.exe main.cppで実行したら
ファイル名 | クラス・関数名 | メソッド数 | LOC | 合計LOC |
---|---|---|---|---|
main.cpp | ||||
main | 0 | 7 | ||
HelloWorldObj | 2 | 11 | ||
23 |
となります。(これは手で数えてますので、間違ってたらごめんなさい)
実行ファイルはGithubにあります
興味ある方はこちらから
【Git】個人開発でよく使うGitコマンド
個人的によく使うGitコマンドをまとめてみました。
git init
ディレクトリをGit管理下に置くコマンドです。
これで、git関連ファイルが作成され、Gitを使ってディレクトリのバージョン管理ができるようになります。
git status
git管理下にあるディレクトリの変更箇所を一覧で見ることできます。
ステージング前のファイルでの変更箇所を見たい場合は、git diff
ステージング後のファイルでの変更箇所を見たい場合は、git diff -cached
git log
ローカルリポジトリのコミット履歴を表示する。これでコミットID、日時、コメント、変更箇所などが見れる。
基本的にはこれでいいと思う。
1行で簡易表示させたい場合は、git log --oneline
変更箇所と変更行数を表示したい場合は、git log -p
git add -A
git add ○
で指定したファイルをaddできます。○=ファイルパス
git add -A
で、管理下にあるディレクトリで変更分のみ、addできます。
変更したかどうかに関わらず、git管理下にあるすべてのファイルをaddしたい場合は、git add .
で出来ます。
git commit
git commit
でaddして保存された内容にコメントを付けて、コミットできます。
git管理下にあるディレクトリの変更箇所のみをローカルリポジトリに保存できます。
オプションなし(= git commit
)に実行することそのままエディターが開き、そこでコメントが打てます。
簡単なコメントを添えてコミットしたい場合は
git commit -m "your comment "
でコミットできます。
addとcommitを合わせて実行したい場合は、git commit -amend
git push
リモートリポジトリ(githubなど)にローカルリポジトリの内容を反映できます。
マスターブランチのものを反映したい場合は、git push origin master
となります。
サブブランチのものを反映したい場合は、git push subbranch_name
で出来ます。
git pull
リモートリポジトリをローカルリポジトリに反映したい場合は、git pull origin master
で出来ます。
個人開発では2台のPCを使って開発を進めたいときなどに使えると思います。
git checkout -- filename
ステージング前の変更を取り消す。
つまり、追加・修正など変更を加えていたものすべてを最新のステージング後の状態に戻す。
git commit --amend
直前のコミットの内容を変更する。
直前のコミットを取り消す場合は、git revert HEAD
。
git revert HEAD^
で、2つ前のコミットを取り消すこともできる。
これらはpushしてしまったコミットには、使えません。
git reset --hard HEAD
1つ前のコミットの状態に戻ることができる。
2つ前のコミットの状態に戻るには、git reset --hard HEAD^
git mv filename, git rm filename
git管理下にあるファイルを移動する。(git mv filename)
git管理下にあるファイルを削除する。(git rm filename)
git管理下にあるファイルの場合、通常のLinuxコマンドmv filename
, rm filename
では移動・削除はできない。
git config --global alias.〇 △
○=エイリアス名(短縮名)、△=コマンド名(add, commit, statusなど)
命令(add, commit, statusなど)にエイリアス(短縮名)を付けて実行できるようにする。
例)git config --global alias.ci commit
することで、git ci
でコミットできるようになる。
設定したエイリアスを確認するには、git config -l
ここからは補足です。興味ある方は見てみて下さい。
add, commit, pushは具体的に何してるのか
まずはGitの仕組みについて簡単に説明するよ
Gitには現在作業をしているGit管理下のディレクトリ「ワーキングツリー」
バージョンを管理したいファイルを置いておく「インデックス」(ステージングエリア)
過去の変更履歴を管理したりリモートリポジトリに送る変更履歴がある「ローカルリポジトリ」
複数人で変更履歴を共有できる「リモートリポジトリ」の4つのエリアがあります。
上記でも少し出てきたブランチというものもありますが、今回は割愛します。
add
git addではワーキングツリーからインデックスに管理したいファイルやフォルダを追加すること(ステージング)を行っています。
ファイルはインデックスに追加すればバージョン管理できますので、変更したファイルはインデックスに追加しておきましょう。
ただし、パスワードなど外部に漏れたら困る情報が記載されたファイルはステージングしないようにしましょう。(特定のファイルを無視するには.gitignoreファイルを使えば無視できます。)
commit
git commitではインデックスのファイルの変更内容をコメントを付けてローカルリポジトリに記録することを行っています。
push
git pushではローカルリポジトリからリモートリポジトリにアップすることを行っています。
これでローカルリポジトリの変更履歴をリモートリポジトリに反映させることができます。
イメージとしてこんな感じ
分かりやすい図があったので、引用してます。
引用元:【Git入門】初めに知るべき仕組み・基本知識 全まとめ【これだけでOK】 | 初心者向け完全無料プログラミング入門
Git管理ファイル作成からpushまでの流れ(Github利用)
作業用ディレクトの最上位に移動
↓
git init
↓
git remote add origin repository_URL
↓
git add -A
↓
git commit
↓
git push
参考サイト
Gitの仕組み kray.jp oldbigbuddha.dev
Git管理ファイル作成からpushまでの流れ(Github利用) techacademy.jp
オブジェクト指向と単体・結合テスト
最近テストについてちゃんと考え理解しはじめたので、現時点での自分の理解を整理しておこうと思います。
私は最初はテストって言うと、ただ単にビルド・コンパイルが上手くいって、そして入力データに対する正しいデータが出力されればいいと思っていました。
条件網羅とかも一応知ってはいたのですが、それがどう関係してくるのか、いまいちピンと来なかったんです。
また、テストコードについても知りませんでした。最近はようやくこのテストの重要性に気づきはじめた次第です。
以下に書くことは、あくまで個人的な見解ですので参考までにしていただけるとありがたいです。
前置きはこのくらいにして、少しずつ本題に入って行こうと思います。
オブジェクト指向とテスト
一応誤解を生まないために言っておきますが、オブジェクト指向とはオブジェクト指向プログラミングのことです。
ここでは、オブジェクト指向プログラミングについては割愛します。
気になる方は、個人的に分かりやすいサイトへのリンクを貼り付けているので、そちらを参照下さい。
一応、「オブジェクト」と「クラス」の違いまで読んでいただければ良いです。
少し話がそれました。
設計レベルまでのテストだと、単体テストと結合テストというものがあります。 以下の図をご覧ください。
単体テストは詳細設計(内部設計)に対応するテストです。
そして、結合テストは基本設計(外部設計)に対応するテストです。
この説明で理解できる人は、この記事を読まなくていいです。
ここからは私の見解です。間違っていたらごめんなさい。
まずは設計から
「とある1つの配列の平均、分散、標準偏差を求め画面上に表示するプログラム」を例に挙げて考えてみましょう。
オブジェクト指向の考え方に則って、プログラム設計を考えると、
- 計算機能を担当するCalcクラス
- 計算結果の表示を担当するShowクラス
に分けられます。(人によって分け方は様々ですが)
画像が大きすぎて、申し訳ないです。
Calcクラスには、平均を計算するメソッド、分散を計算するメソッド、標準偏差を求めるメソッドがあります。
Showクラスには、計算結果を箇条書き形式で表示するメソッドがあります。(箇条書き形式でなく表形式とかでも構いません)
イメージとしてはこんな感じ。
さてではこの例で、テストについて考えていきましょう。
単体テスト
単体テストの概念をのせておきます。
単体テスト(ユニットテストと呼ばれることもあります)は、プログラムを構成する比較的小さな単位(ユニット)が個々の機能を正しく果たしているかどうかを検証するテストです。 通常、関数やメソッドが単体テストの単位(ユニット)となります。 プログラムが全体として正しく動作しているかを検証する 結合テストは、開発の比較的後の段階でQAチームなどによって行なわれることが多いのとは対照的に、単体テストは、コード作 成時などの早い段階で開発者によって実施されることが多いのが特徴です。
ここで言う、単位(ユニット)とはクラス(またはメソッド)です。
つまり、Calcクラス、Showクラスそれぞれが持つ機能を満たしているのかを確認するのが単体テストとなります。
具体的には、Calcクラスは平均、分散、標準偏差を正しく計算できるか?
Showクラスは与えられた値を箇条書き形式で表示できているか?、ということを確認することです。
結合テスト
単体テストと同じ要領で説明していきます。
結合テストの概念をのせておきます。
結合テストとは、システム開発におけるプログラムの検証作業の中でも、手続きや関数といった個々の機能を結合させて、うまく連携・動作しているかを確認するテストのことである。 結合テストでは、個々の機能を果たすためのプログラム部品(プログラムモジュール)を組み合わせて、データの受け渡しがうまく行われているか、コードの記述様式は揃っているか、データを授受するタイミングはずれていないか、といった点が確認され る。結合テストで不備が発見された際には、再度コーディングが行われる。
つまり、CalcクラスとShowクラスを繋げてみて、平均・分散・標準偏差を正しい値で表示できるかを確認するテストです。
学びはじめて間もないと、オブジェクト指向プログラミングとかテストとかあまりイメージしにくいと思いますが、参考になれば嬉しいです。