2018年03月04日(日) [長年日記]
■ [hard][life] ケータイ電話を買い替えた
親が使っているドコモのガラケーが壊れてしまい、新しいケータイを買ったのでメモ。
もうFOMAの携帯電話は売っていない。買ったのは、Xi端末だが見た目はガラケーのAQUOS ケータイ SH-01J。OSはAndroidらしいが使い勝手はガラケーと同じだった。
ドコモオンラインショップで33696円もする。ただし、2年間は毎月料金から1404円が割引かれるので2年使えば元が取れる(実質負担金0円というやつ)。
FOMAからXiへの乗り換えなので、料金プランも変えなければならない。今までは
- タイプSSバリュー(ファミ割MAX50) 934円
- パケ・ホーダイ ダブル 372円
- iモード 300円
で合計1606円だったのが、
- カケホーダイライトプラン(ケータイ) 1200円
- ケータイパック 300円
- spモード 300円
の合計1800円に微増した。ただし、Android化したことでデータ通信量が増えるのではないかという心配がある。
2018年03月14日(水) [長年日記]
■ [howto][dev] GNU Makeでエラー時に成果物を削除する
makeはコマンドが失敗してもターゲットファイルを削除しない。
$ cat Makefile out: $(COMMAND) > $@ $ COMMAND=gagaga make gagaga > out /bin/sh: 1: gagaga: not found Makefile:2: ターゲット 'out' のレシピで失敗しました make: *** [out] エラー 127 $ ls -l out -rw-rw-rw- 1 kenichi kenichi 0 3月 14 15:52 out
GNU Makeなら、.DELETE_ON_ERROR というターゲットを作っておくとエラー時にターゲットファイルを削除してくれるみたい。
$ cat Makefile .DELETE_ON_ERROR: out: $(COMMAND) > $@ $ \rm out $ COMMAND=gagaga make gagaga > out /bin/sh: 1: gagaga: not found Makefile:4: ターゲット 'out' のレシピで失敗しました make: *** [out] エラー 127 make: *** ファイル 'out' を削除します $ ls -l out ls: 'out' にアクセスできません: そのようなファイルやディレクトリはありません
2018年03月15日(木) [長年日記]
■ [c++] Boost.Testのデータドリブンテストケース
Boost.Testのdata-driven test casesを使ってみたのでメモ。Boost 1.65.1 と g++ 6.3 を使用。
ドキュメントの辿り方が分かりにくいのだけれど、上でリンクしたページの先頭にある次のリンクの先に詳しい説明がある。
- Datasets
- Declaring and registering test cases with datasets
- Operations on dataset
- Datasets generators
簡単なサンプル
#define BOOST_TEST_MODULE data driven test #include <boost/test/included/unit_test.hpp> #include <cmath> #include <boost/test/data/test_case.hpp> namespace bu = boost::unit_test; BOOST_AUTO_TEST_SUITE(suite, * bu::tolerance(1e-16)) BOOST_DATA_TEST_CASE( sqrt_test, bu::data::xrange(0.0, 1.0, 0.1), a) { const auto root = std::sqrt(a); BOOST_TEST(root * root == a); } BOOST_AUTO_TEST_SUITE_END()
- std::sqrt(a)の2乗がaに等しくなるかをテストしている。
- BOOST_DATA_TEST_CASE()の2番目の引数に「dataset」を与える。上ではxrange()を使って0.0~0.9までの10個の小数からなるdatasetを与えている。これにより、このテストケースは10回呼び出されることになる。
- datasetの各要素の値はBOOST_DATA_TEST_CASE()の3番目の引数に代入される。
上のプログラムを実行すると次のように出力される。
Running 10 test cases... data_test.cpp(17): error: in "suite/sqrt_test/_2": check root * root == a has failed [0.44721359549995793 * 0.44721359549995793 != 0.20000000000000001]. Relative difference exceeds tolerance [1.38778e-16 > 1e-16] Failure occurred in a following context: a = 0.20000000000000001; data_test.cpp(17): error: in "suite/sqrt_test/_3": check root * root == a has failed [0.54772255750516619 * 0.54772255750516619 != 0.30000000000000004]. Relative difference exceeds tolerance [1.85037e-16 > 1e-16] Failure occurred in a following context: a = 0.30000000000000004; data_test.cpp(17): error: in "suite/sqrt_test/_5": check root * root == a has failed [0.70710678118654757 * 0.70710678118654757 != 0.5]. Relative difference exceeds tolerance [2.22045e-16 > 1e-16] Failure occurred in a following context: a = 0.5; data_test.cpp(17): error: in "suite/sqrt_test/_6": check root * root == a has failed [0.7745966692414834 * 0.7745966692414834 != 0.59999999999999998]. Relative difference exceeds tolerance [1.85037e-16 > 1e-16] Failure occurred in a following context: a = 0.59999999999999998; data_test.cpp(17): error: in "suite/sqrt_test/_7": check root * root == a has failed [0.83666002653407556 * 0.83666002653407556 != 0.69999999999999996]. Relative difference exceeds tolerance [1.58603e-16 > 1e-16] Failure occurred in a following context: a = 0.69999999999999996; *** 5 failures are detected in the test module "data driven test"
誤差が生じるのでいくつかのテストは失敗している。
datasetを組み合わせる
datasetの組に対してjoinとzipとgridという操作をして新しいdatasetを生成できるようになっている。zipを使ったサンプルを示す。
#define BOOST_TEST_MODULE data driven test #include <boost/test/included/unit_test.hpp> #include <cmath> #include <boost/test/data/test_case.hpp> namespace bu = boost::unit_test; BOOST_AUTO_TEST_SUITE(suite, * bu::tolerance(1e-16)) BOOST_DATA_TEST_CASE( sqrt_test2, bu::data::xrange(0.0, 1.0, 0.1) ^ bu::data::make(2), a, b) { const auto root = std::sqrt(a); BOOST_TEST((root + b) * (root - b) == a - 4); } BOOST_AUTO_TEST_SUITE_END()
- BOOST_DATA_TEST_CASE()の2番目の引数で使っている演算子「^」がzip操作を表す。これにより { {0.0, 2}, {0.1, 2}, {0.2, 2}, ..., {0.9, 2} } というdatasetが作られる。
- datasetの各要素の1番目と2番目の値はそれぞれBOOST_DATA_TEST_CASE()の3番目と4番目の引数(aとb)に代入される。
datasetの組み合わせの組み合わせ
datasetに対する操作はネストさせることができるのだと思うけれど、少なくともzipした結果同士をjoinすると正しく動かないようで、チケットがあがっている。
手元の環境でチケットにあるコードを試すとsegmentation faultが発生してしまう。このチケットは現状で2か月放置されている。