プログラミングにおいて、文字列はソートをできることを説明します。

ソートとは

データを一定の基準に従って並べること。同じデータをバラバラな順番にして、ソートした場合に必ず同じ順番になる。

プログラミングにおいては、配列から昇順または降順の配列を作ることを指すことが多いです。昇順のソートをした配列のN個目の値は、それより前の値より大きいまたは同じで、それよりあとの値より小さいまたは同じになっている。

ソートの操作をするためには、配列の比較できる値が入っている必要があります。

整数は比較できる

整数は、0より1が大きく、1より2が大きい。全ての整数は大小関係があり、比較ができます。

比較できる値の配列は比較できる

配列を比較するときは、それそれの配列の一つ目の値を取り出して比較して、異なる値であれば大小関係が決定し、同じ値であれば次の値取り出して比較します。この操作を繰り返して、値が取り出せない配列は小さいとします。

例えば、[0] < [1], [1, 1] < [1, 2], [1] < [1, 0]となります。

文字は数字として扱える

文字列ではなく、1つの文字についてです。

コンピュータは0と1のビット列しか扱うことができないので文字を表現するにも、各文字を1つの数字に割り当てることで表現しています。この割り当て表を文字コードと言います。アスキーコード(ASCII) や UTF-8がよく使われます。

アスキーコードでは、'A'を65、'a' を 97として扱います。

アスキーコードの文字列は比較できる

これらから、文字列を数字の配列であり、比較できます。

例えば、"a"→[97] < "b"→[96]となる。

アスキーコード以外の文字列は比較できるがプログラミング言語によって結果が異なる(たぶん)

アスキーコードは7bitで表現されており、それ以外の文字は複数バイトの文字として扱われる。プログラミング言語内部の文字列の扱いによって異なっている、そのため比較の結果も異なる。データベースでと、アプリケーションサーバー、Javascriptでソートした場合に結果が異なる場合がある。

アスキーコード以外意図しているソート順にはならないという前提で考えた方が良いので、ソート用の情報を別途持たせておくのが良いだろう。

意図した順番になるかはまた別の話

例えば"1", "2", "10"があった時に、大抵は"1", "10", "2"の順番に並んでしまう。意図したソート順に並べるのは一工夫必要です。

草津でワーケーションしてきた

妻「ちょっと一週間くらい実家帰ってきてくれない?」

話を聞くに、毎日一緒にいるのに飽きてきたらしい。確かに、うちの夫婦は2人ともリモートワークで、ほとんど出社もしない。習慣的に外に出るのも買い物か散歩程度で、1日23時間くらい同じ家の中で過ごしている。1日100歩程度のこともざらにある。私が出不精なため家にいるのは私の方になりがち。自分の家でゆっくりしたいらしい。

実家に行くのはなんとなく嫌だった。実家と仲が悪いというわけではないが、変わった理由で外に出るのだから、変わったことをしたいと思ったのだ。リモートワークをして、自分の家でないところから仕事をするのだから、どこで仕事をしても良いじゃないと考えた。そして、ちょうどいいサービスがあった(ステマではない)。

https://otell.app/otell-select-headerotell.app

Otellは長期宿泊できるホテルがまとまる。特にOtell Selectは最低限のWifiと机、いすがある。1週間どこかに行くのは便利そうということで予約することにした。Otellで予約する場合は、予約のリクエストという形で登録される。予約成立率があって、リクエストしたとしてもホテルが予約されたわけではない。失敗する場合があるようなにで注意が必要だ。

ワーケーションで5泊6日で予約したので荷物がかなり多い。仕事道具+6日分の旅行の荷物だからだ。できるだけ荷物を減らそうと思い、仕事道具は最低限にして、3日分の服を鞄に詰めてコインランドリーで一度洗うことにした。それでも重かったので準備が事前にできるのであれば、宅配で送るのをおすすめしたい。

草津の日々

夜のライトアップされた湯畑 毎日、朝起きて温泉に入り、仕事をして軽く町を散策しつつお昼を食べ、仕事を早めに切り上げて観光に行き、温泉に入る。朝起きて「とりあえず温泉に行こう」で始まり、熱々の温泉が常にあり、気が向いたら常に温泉に行ける。そんな日が4日も続く。東京はまだ35度を超えるような暑い日々が続いていたようだが、草津は肌寒い程度の気温だった。それもまた温泉を心地よくさせている。

ホテルは、町の端にある。シャトルバスは出ているが、歩きだとどこに行くにしても15分くらいかかる。坂も多い。それでも歩くほうが多かった。硫黄の香りが漂い、温泉の川が流れている町を散策していた。歩き疲れたら、休憩がてら足湯に入った。都会の喧騒とは違った、観光地を楽しむ人々の声が聞こえる。平日でも湯畑周辺では人が絶えない。

温泉が川になっている
西の河原
五重塔
草津熱帯圏
石灰をダバダバ入れているところ

些細な話

日曜日に明日から仕事のため、消耗品と軽く朝食を買おうと、買い出しをしに行った。

インスタントコーヒー等と、紅茶と信じられているクリープ

紅茶のつもりでクリープを買ったのだが、チャックが着いていないことに気がついて開けなかった。帰ってから写真を見ていた妻から「クリープ開けなかったんだね」と言われてやっと気がついた。しかも詰め替え用で詰め替え先は家にもない。

言ったら貸してくれたのかもしれないが、湯呑みでコーヒー飲んでいたので割れにくいタンブラーを持っていた方が良かった。

まとめ

  • 毎日温泉サイコー

C2カバレッジについて

カバレッジ基準のおもにC2カバレッジについて調べ直したのでまとめてみた。

カバレッジ基準とは

制御フローテストで着目する要素を「命令文」「分岐」「条件」のうち着目してカバレッジを計測する要素のことをカバレッジ基準と言います。

この要素で主なものは3つあります。

事実

 ステートメントカバレッジ

「命令文」に着目して全ての命令文を最低一度は通れるようにテストします。

ディシジョンカバレッジ

「分岐」に着目して全ての分岐を最低一度は通れるようにテストします。ステートメントカバレッジを包含しています。

コンディションカバレッジ

「条件」に着目して全ての条件を最低一度は通れるようにテストします。

単純条件カバレッジと複合条件カバレッジ

複数の条件を組み合わせた条件分岐がある場合に、個々の条件の真偽のみの組み合わせを網羅することを単純条件カバレッジという。ディシジョンカバレッジを包含していないし、ステートメントカバレッジも包含していません。

複数の条件を組み合わせた条件分岐がある場合に、そのすべての組み合わせを網羅することを複合条件カバレッジという。ディシジョンカバレッジを包含しています。

C2カバレッジが単純条件カバレッジと複合条件カバレッジのどちらのことを差しているかわからなかった。
同じような疑問を持った人がいたようだが、調べてみることにした。 コードカバレッジについて、また考える - その1 - ソフトウェアの品質を学びまくる2.0

Webサイトでの説明

C2を単純条件カバレッジとするWebサイトと複合条件カバレッジとするWebサイトがある。

書籍による説明

持っている書籍のみを一通り調べた。

(追記) * ソフトウェアテストと導入・移行 * 複合条件カバレッジが書かれており、単純条件カバレッジについての記載はない。 * プログラミング現場の単体テスト * 珍しく単体条件カバレッジのみが書かれている。単体条件カバレッジがディシジョンカバレッジことも書かれている * ソフトウェアテスト入門 押さえておきたい<<要点・重点>> * ディシジョンカバレッジまでは書いてあったがコンディションカバレッジについての記載は見つけられなかった * 知識ゼロから学ぶソフトウェアテスト * ディシジョンカバレッジまでは書いてあったがコンディションカバレッジについての記載は見つけられなかった * ソフトウェア品質を高める開発者テスト * C0、C1までは書いてあったがコンディションカバレッジについての記載は見つけられなかった

C2が何かが書かれていなかった。

Google ブックスによる検索

いくつかをピックアップした。全文読めないので若干何とも言い難い。

所感

C2カバレッジは、単純条件カバレッジと複合条件カバレッジのどちらかをはっきりさせることはできなかった(諦めた)。 単純条件カバレッジと複合条件カバレッジを計測できるツールを私は知らないし、計測するつもりもない。他の人も同様に計測する気はないのだろう。つまり、定義がどっちでもいいのだ。

まとめ

仕様を読む技術

走り書き。根拠はない。

まだ小さな開発チームなので社内のプルリクエストを流し読み程度に全て見るようにしている。コードの品質は人によってさまざまあるのは当然だが、仕様の理解度に差があるように感じている。それは人によって異なっていて、常に理解度の高い人と低い人がいる。

仕様を読むためには、主に3つの要素があるのではないかと考えた。

  • 前提知識
  • 環境要因
  • 完成の定義

前提知識

システム開発だと0から作ることは少なく、多くの場合は追加開発になる。要求は何か、既存のシステムがどうなっているか、技術的に何が使われて何を使えばいいのか、がわかっている必要がある。

例えば、「ルービックキューブに黒い面を追加する」という追加開発があったとする。要求は「他の6面と同様な7面目を追加する」ということになり、既存のシステムは「3x3マス、立方体の組み合わせ、回転できる」等である。技術的な部分は「回転機構、各パーツの形」等がある。この例の要求は明らかに矛盾していることに気がつく。しかし、システムを作るときはよくあり、矛盾があることに気がつかない人がいる。これは前提知識がないために起こるのではないかと思われる。

前提知識は単に時間をかけて知っていくしかないように思う。

環境要因

仕様のできや、忙しくて読む暇がない、期日が迫っている、疲労等で仕様を読む能力が減少する。

読む能力が低下する要素を減らすようにすべきだろう。

完成の定義

仕様に完成の定義が書いてあれば良いのかもしれないが、書いていない場合は完成の定義を考えられると仕様を読んだときの質が変わってくる。完成の定義が曖昧なまま書かれたコードは曖昧な部分が透けて見えることがたまにある。

完成の定義は「仕様を満たしていることがわかるテストを作成し問題なく通ること」と考えている。テストは自動でも手動でもかまわない。

最後に

「他にこんな要素があるのではないか?」とかがあればコメントしてほしい。

事例: プルリクを誰も見てくれない

エンジニアが数名という時に、Androidアプリをレビューする人がいないという事態が度々発生した。作ったプルリクエストは滞留してなかなかマージされない。取った解決策は、Githubにプルリクが作られアサインが行われたら該当の人に通知を行うというものだった。通知はメールやSlackに配信された。

結果としては、効果はなかった。その時にプルリクを見れる人は1人しかおらず、その人は会議に出ずっぱりだった。実質的に、リアルタイムにプルリクを見れる人は誰もいなかったのだ。通知を送ってもレビューがされないのも当然だった、誰も見れないので。

Androidのレビューできる人を増やすということで解決した。専門でない人にわかるような内容のプルリクにしたり、基礎知識を教育した。

現実を直視しないと何も解決しない。

TableHeaderViewのサイズをいい感じにする

UITableViewのtableHeaderView(セクションごとのヘッダーではない)は経験的にオートレイアウトが効かないので、状態によってTableHeaderViewの高さを変えたい厄介になります。この記事ではサイズをいい感じに調整する方法を紹介します。TableFooterViewも同様です。

やり方

TableHeaderViewには一つだけViewを置いてください。このVIewのことを便宜上BaseViewと呼ぶことにします。BaseViewはUIViewでもUIStackViewでも構いません。重要なことは1つだけにすることです。

BaseViewを上と左右に0でAutoLayoutを設定して、BaseViewの中身によってBaseViewの高さが決まるようにしてください。

ViewControllerに以下のコードを追加してください。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    if let headerView = tableView.tableHeaderView,
        headerView.subviews.count == 1,
        let baseView = headerView.subviews.first
    {
        headerView.frame.size.height = baseView.bounds.size.height
        tableView.tableHeaderView = headerView
    }
}

終わりです。

なぜいい感じになるのか

厳密には違うかもしれないが、viewDidLayoutSubviewsはオートレイアウトによって調整が行われるたびに呼び出されるメソッドです。BaseViewの高さがオートレイアウトによって変更されるたびに呼び出されてBaseViewの高さとTableHeaderViewの高さを同じにすることで、TableHeaderViewの高さを調整しています。

BaseViewの高さがTableHeaderViewに影響されないように、下にオートレイアウトをつけないのはそのためです。

ソースコードをお焚き上げしました

エンジニアは意外にも信心深いところがある。サーバーをお祓いしたり、デバッグ神社を建てたり、リリースするときにお祈りする。

iOSAndroidアプリを全面リニューアルと一部サービス終了があったので、今までのソースコードへの感謝の気持ちを込めてお焚き上げをすることにした。

今まで稼いだコードへの感謝

弊社では、アプリを全面リニューアルすることにした。

外注を行っていたのを内製化するにあたって、中途採用が行われチームができた。人を雇って改善を行っていこうと思うほど、重要なアプリになっていた旧アプリはそれだけの価値があったということになる。

内製化を行ったチームは、初めから内製化をし始めたわけではない。初めにやったことは内製化の価値を示すためにチームは新しいサービスを立ち上げた。サービスは今までには考えられないほどのスピードで開発されチームの価値が示された。ただ、そのサービスも期間限定で好評のうちに終了した。

私たちは、今まで稼いでくれていたが不要になったソースコードに感謝の念を示したいと考えた。検討した結果、お焚き上げをすることにした。

準備

ソースコードの持ち出しの許可をとる

即座にお焚き上げをするとはいえソースコードを無断で持ち出すのは問題がある。書類整理破棄を名目でCTOに持ち出しを打診したところ「お焚き上げをアンオフィシャルでやるならいいよ」と許可をもらった。お焚き上げは有志で行うことになった。

場所決め

IT系の神社といえば神田明神だが、ホームページにはお焚き上げに関する記載がなかったのと、 神札·御守·熊手·破魔矢等のみとのツイート があった。優先順位をつけて探すことにした。

  • 目の前でお焚き上げをしてもらえること
  • 場所(都内〜遠くても関東)
  • 予算(〜数万円程度)

同僚に探してもらったところ、つてで 戸越八幡神社 で行うことになった。ダンボール1箱程度で10,000円だった。割り勘で払うことにした。

印刷

前日に印刷を行った。その辺にあったMacbook Proの箱に詰めた。 そこまで多いソースコードだと思っていなかったが4pt2ページづつ両面印刷して、ほとんど米粒程度のフォントサイズにで印刷されてなんとか見える程度だった。しかしそれでも500枚程度になったので、もしやる機会がある人は気をつけてほしい。Macbook proの箱はちょうどいいサイズの段ボールでできているので、燃えるしどこの会社にもあるのでおすすめです。

当日

10時に戸越八幡神社に集合した。眠い。昇殿参拝を行って継往開来で祈祷をおこなってもらった。お清めされたドラム缶でお焚き上げをおこなった。 燃えていくソースコードを眺めていると「終わった」という気持ちに満たされていった。

お清めされたドラム缶
炎上してる

おわりに

リニューアルやサービスの終了時にお焚き上げするのをお勧めします。

最後に、感謝の念を込めながらGithubアーカイブのボタンを押して幕を閉じた。