数値とデータ
すべてのデータ点には三つの状態がある。手に入った、本当に何もなかった、分からない。後の二つは、グラフでは同じようにゼロとして描かれてしまうが、意味はまったく逆である。
検出の問いこれから表示しようとしている数値、あるいは信じようとしている「すべて問題なし」は、失敗したクエリ、空のテーブル、拒否された権限、あるいは全文を読まなかった出力(教訓 44 を参照)から来ていないか?
例と対処法
例
期限切れの権限のせいでクエリが失敗し、ダッシュボードには地域の「売上 0 件」と表示された。誰も疑わなかった。ゼロは、データに見えるからである。
どうするか
読み取りが失敗したら、ギャップやゼロではなく、エラーをそのカード自体に表示する。そして「問題 0 件」と表示するカウンターは、意図的に仕込んだ問題をまず見つけたことがある場合にのみ信頼できる。
数値とデータ
「アクティブな顧客」「日付」「上司」「しきい値」。同じ言葉が、二つの定義を隠していることが多い。二つのレポートが合わないとき、たいていこれが原因である。
検出の問いどちらか一方には真で、もう一方には偽であるルールはないか? また、二つの数字を一つの計算で組み合わせるとき、それらは同じ母集団、同じ尺度、同じ期間から来ているか?
危険信号「日付は同じだ」「ビューがもう絞り込んでいる」「どちらも『ペソ』だ」
例と対処法
例
「日付」は、イベントの日付、ロードの日付、パーティションの日付のどれでもありうる。「上司」も、その人の現在の上司か、測定対象の出来事が起きた時点の上司かで違う。
別の例
あるキャンペーンのテーブルには、会社全体の支出が入っていたが、収益は百件に一件の購入だけを抜き出したサンプルから来ていた。両方の列とも「ペソ」と書かれていたため、すべてのキャンペーンで収益率がマイナスになった。
どうするか
見た目が悪くても、それぞれの変形にコードと画面で別の名前を付ける。そして、別々のソースから来た二つの数字を割ったり引いたりする前に、それぞれがどこから来ているかを書き留める。結果がどの場合でも同じになる(全部赤字、全部黒字)なら、ビジネスを疑う前に、尺度を疑う。
数値とデータ
まだ終わっていない月は、終わった月より必ず悪く見える。それは傾向ではなく、暦である。
検出の問いこの計算は、まだ終わっていない期間を含んでいないか?
例と対処法
例
売上の曲線は最後の点で「下がる」。それは、まだ半分しか終わっていない月だからである。
どうするか
指標は最後に締められた期間で打ち切るか、未確定の期間を画面上で明示する。そして二つの時計を混ぜない。組織全体の数字は締められた月を使い、個人の数字は当日を使う。
数値とデータ
多くのシステムは、今日の値しか保存しない。その項目の上に「過去の」変数を作ると、現在を測りながら、それを過去として見せていることになる。
検出の問いこのフィールドは、値が変わったとき、以前の値を残すか、それとも置き換えるか?
例と対処法
例
システムは各人の現在の上司しか保存していない。退職した人の上司は、そのまま固定される。そのため「上司ごとのチームの離職率」は、結局「このチームはもう存在しない」を測ってしまう。
どうするか
過去を遡って見る前に、そのデータがスナップショットなのか履歴なのかを、ソースに確認する。
数値とデータ
一つの変数が、ほとんど誤りなしに、辞めた人と残った人を分けるなら、その変数の中に結果そのものが隠れている可能性が高い。
検出の問い品質の指標が上がっているのは、モデルが誰に起きたかではなく、いつ起きたかを推測しているからではないか?
危険信号「ほぼ完璧に出た!」「年で補正して先に進もう」
例と対処法
例
あるモデルが突然ずっと良くなった。調べると、ある変数は、辞めた人全員が 1、残った人全員が 0 になっていた。ソースが二つのグループを別々の方法で埋めていたからである。別のパターンでは、モデルは誰に起きたかではなく、いつ起きたかを学習していた。
どうするか
未来を使ってテストする。過去で学習させ、後の期間で評価する。そして、何かで補正する前に、その何かが、予測したい結果を決めているものかどうかを問う。
スクリプトとファイル
「アクティブとは何か」のルールがすべてのクエリで繰り返されていれば、そのコピーはずれていく。問題は、それがいつ起きるかであって、起きるかどうかではない。
検出の問いこの定義を変えたら、何個のファイルを直さなければならないか? 一つより多いなら、ルールは一か所にまとまっていない。
危険信号「ここにも置こう。一行だけだから」「その数字は変わらない」
例と対処法
例
あるバリデータは、参照項目の数を手で 43 と入力していた。文書が 47 に増えると、新しい四件を存在しないものとして弾いてしまった。今では、文書そのものの項目を数えている。
どうするか
定義を、すべてのクエリが通る一か所に置き、全員がそこから読むようにする。どこかの値をコピーした手入力の数字も、繰り返された定義である。
混同しないこと
学習用の教材で説明を意図的に繰り返すことは、定義のコピーではない。コピーしてはいけないのは、値を計算するルールのほうである。
スクリプトとファイル
プロセスは何をするつもりかを宣言するが、実際に行ったことを公開する。その二つは必ずしも一致しない。出力を使う側は、結果を読むべきである。
検出の問いこれはプロセスの設定から作られているか、それとも公開された結果から作られているか?
例と対処法
例
ある画面は、モデルが使うつもりだった変数のリストからコントロールを作っていた。学習の過程で一つの変数が落とされたが、何日もの間、何もしないコントロールが存在していた。
どうするか
公開された結果から導き出す。そして、導き出せないものは静かに消えるのではなく、はっきり失敗させる。
Git とプロセス
他の人が名前で読んでいるデータを変えるとき、それを読んでいる人の一覧を書き留めておかなければならない。記憶は必ず一つ漏らす。
検出の問いこの利用者の一覧は、どこから得たか? 検索か、それとも記憶か?
危険信号「使われている三か所はもうカバーした」「それはもう見てもらっている」「必要なものはすべて追加した」
例と対処法
例
あるモデルが変わった後、三つの画面のラベルを更新した。記憶になかった四つ目の画面は、前のモデルの選択肢を出し続けた。
別の例
章を書くとき、読者は前の章の三つの関数をすでに知っていると、記憶から書いた。検索すると、その章では一つしか教えていないことが分かった。また、新しいものとして扱った話題は、別の章ですでに説明されていた。
もう一つの例
変更は、記憶から書いたファイルの一覧とともに保存されたが、一つ漏れていた。新しいものを動かすために必要だったファイルである。後で確認した保留中の変更の一覧が、それを示した。
どうするか
変更の種類ごとに、影響の対応表を書き留めておく。それを最後まで見て、「変更する」か「〜のため該当しない」と言う。そして変更によって新しい利用先が生まれるなら、同じ変更の中で追加する。出典を引用する前には、その出典から、自分が主張している文をコピーする。誰かが別の人のしたこと、見たことを語るときも、確認が必要である。
Git とプロセス
保留中の項目を閉じるには、通常三か所が関わる。保留項目の一覧、それを監視するテスト、それを説明する文書である。一つだけ動かすと、残りは矛盾する。
検出の問いこの状態を主張している他の場所はどこか? 保存する前に名前を挙げる。
例と対処法
例
保留項目は一覧では閉じたことになっていたが、それを監視するテストは「失敗が想定される」のままで、文書にはまだ未解決と書かれていた。三か所、三つの版。
どうするか
作業の単位は、同じ変更の中で行う、完全な一式である。
インターフェースとデザイン
同じ画面の二つの版を、二種類のユーザー、二つの地域、二つの製品のために持っているなら、一方への改善は、もう一方への保留中の改善である。
検出の問い私が触っているものには、ユーザーが「同じモジュール」だと見なす双子がいるか?
例と対処法
例
デスクトップ版に日付フィルターが追加された。ユーザーが「同じ画面」だと思っているモバイル版には、一か月間それがなかった。
どうするか
双子を確認し、「同じ」か「〜のため該当しない」のどちらかを書くまで、変更を終えない。
執筆とドキュメント
データが信頼できなかったために何かを削除しても、同じ主張は別の文章に、別の言葉で残っていることが多い。
検出の問い今削除したものと同じことを言っている他の文章は、どこにあるか?
例と対処法
例
信頼できない図は取り下げられたが、「主な知見」のカードと行動計画には、その図が述べていたことがまだ推奨として残っていた。
別の例
章立て計画が 7 から 15 に振り直された。別の文書の二つのリストは、古い計画の「7.4」と「7.7」をまだ指していたが、それらは今や別の話題になっていた。計画を置き換えるとき、古い番号もまた主張である。
どうするか
識別子ではなく、トピックで検索する。言い回しを変えた同じ内容には、変数名のような目印がない。
12クエリが走ったからといって、数字が正しいとは限らない
数値とデータ
「エラーにならなかった」は「正しい」ではない。自分の計算とは独立した何かと照合する。
検出の問いこの結果を、自分のコードの外の何と照合するのか? そして、テキストがシステムの動作について述べていること(例、ルール、オプションの説明)はすべて、本物のエンジンで実行したか?
危険信号「自分のマシンでは動く」「エラーは出なかった」「そういう仕組みだ、今説明したばかりだ」
例と対処法
例
ある選択問題は、数値を引用符付きの文字列と比べるとエラーになると主張していた。他のエンジンではそうだが、実際に使われていたエンジンでは、クエリは走って行を返した。
別の例
あるテキストは、名前付きブロックが自分のクエリの中にしか存在しないと正しく説明していたが、その例では、三つの別々のクエリがそれを共有していると仮定していた。実行すると、二つ目のクエリはエラーになった。テーブルが存在しなかったのである。
もう一つの例
あるページのすべての例を実行したが、それでも三つの文が誤りだった。ページの最後に書かれたオプションの説明は、誰も実行していない行の動きを述べていた。エラーの読み方のルール(「こう言われたら、あれが不足している」)は、同じページの別の手順と矛盾していた。そして序文は、ある関数が「結果を返す」と書いていたが、実際には返さなかった。
どうするか
既知の数値、ソースシステム、前の期間と照合する。本番と同じ環境、同じ権限、同じライブラリ、実際に動くコードのコピーでテストする。システムの動作についてのあらゆる主張は、書き留める前に一度は実行する。例の中でさらりと出てきたもの、最後に書かれたものも含めて。主張が一般的なルール(「のみ」「常に」「決して」)なら、それを破るケースを見つけて、それも実行する。「整数に変換すると整数だけが読まれる」は、小数を含む文字列で確かめたところ、小数を含む数値では偽だった。割合を述べるとき(「六分の五」)は、何の全体の割合なのかを明示する。作り話のシナリオも確かめる。サイズ、差、p 値は、互いに矛盾しないこと。
13誤りを一度も見ていないチェッカーは、何も検証していない
テストとチェック
いつも通るテストは、壊れているかもしれない。それを知る唯一の方法は、本物の誤りに対して失敗するところを見ることである。
検出の問いこのチェックを、実際にエラーが現れる形で、そして正しいケースに対して、テストしたか?
危険信号「もう通っているから、正しく設定されている」
例と対処法
例
ある単語を禁止するテストは、小文字の形しか探していなかった。大文字やアクセント付きだと、テストは通ってしまった。
別の例
演習のために 37 件の重複レコードを仕込んだが、件数は 92 と返ってきた。データにはもともと自然に一致するものがあったのである。保存前に、仕込んだ数と比較するチェックがそれを捕まえた。
もう一つの例
インデントされたコードを検出するルールが、テキストで始まる行をフラグにした。通るべきケースは、そのような形をしていなかったのである。また、テキスト比較が動くことを確かめるテストは、比較が壊れていても通ってしまった。別のレビューが、先にエラーを弾いていたからである。
どうするか
二つのケースで較正する。一つは必ず何かを見つけなければならないケース、もう一つは何も見つけてはいけないケース。そして生まれた日に、本当に実行する。正しいケースは、誤りのケースと同じくらい大切である。正しいものを弾くチェッカーも壊れている。しかも、それは厳格に見えるため気づきにくい。正しいケースには、自分では書かなかった形も含めて、本当の形を含める。別の順序、別の名前。各チェックは自分自身を較正する。別のチェックが先に誤りを捕まえてしまったら、自分のチェックは一度もテストされていなかったのである。そして、すでに読んだものを繰り返すだけのレビュー(同じファイルを読み直す「二回目の実行」)は、決して失敗しない。そういうものは、何か間違っていれば失敗する照合に置き換える。
テストとチェック
チェックが、被害を起こした可能性のある同じパイプラインを通るなら、被害はチェックにも及び、物事が正しくても間違っていても同じ答えを返す。
検出の問い調べている変換は、自分のテストも変換してしまうか?
危険信号「同じようなクエリをもう一つ送って確かめる」
例と対処法
例
アクセントの問題を探すために、アクセント付きのクエリを、まさにその問題を起こしている経路で送っていた。
どうするか
被害が触れられない形でテストを組み立てる。
15自分で無効になるテストは、無効になったことを報告しない
テストとチェック
「データが見つからなければテストを飛ばす」という分岐は、まさに世界が変わったときに有効になり、誰も気づかないうちに監視をやめてしまう。
検出の問い私のテストには、正当な変更で有効になる、静かな抜け道があるか?
危険信号「アンカーが見つからなければ、テストを飛ばす」
例と対処法
例
テストはテーブルをそのタイトルで探し、見つからなければ飛ばしていた。タイトルが変わり、テストは何週間も、何も確認せずに通り続けた。
変形
最初に壊れたファイルで止まるチェックは、その後のすべてのファイルを監視しないままにする。クラッシュするバリデータは、「このページは読めない、12 行目」と報告する代わりに、レビュー全体を無効にしてしまう。
どうするか
欠けているのがツールなら、飛ばすのは正直である。欠けているのが監視対象のデータなら、テストは失敗しなければならない。そして、読めないファイルは、行番号付きの指摘であり、レビューの終わりではない。
16チェッカーのフィルターは、たいてい肝心なものを除外している
テストとチェック
どの自動レビューも「関係のある」ものだけを絞り込む。そのフィルターが、問題のある場所をまさに見えなくしていることがある。
検出の問い私のフィルターは何を除外しているか? 結果を信じる前に書き出す。
危険信号「四十八件の差分が見つかった。リストはもうある」「テストはすべてを回っている」
例と対処法
例
あるデザイン監査は、子要素を持たない要素だけをレビューしていた。レビューが必要なラベルの中には、ヘルプアイコンが入っていたので、監査は一度もそれを見なかった。
別の例
あるテストは、すべてのページを回り、常に最初の選択肢を選び、各クエリを順に実行していた。それは毎回通ったが、正しい答えが受け入れられることは一度も確認しなかった。
もう一つの例
あるテキストが変更されたかを判断するために、空白を無視していた。その結果、まさに空白と改行でそのテキストをどう整えるかを説明しているページが見落とされた。正規化もまた、フィルタリングである。
どうするか
フィルターが除外しているものを書き出し、除外された項目のサンプルを手で確認する。そして、フィルターに盲点があったと分かったら、自分が書いた他の似たフィルターを探す。すべての空白を消すレビューは、二つの単語を一つにつないでしまい、正しいコードを弾いていた。それは、同じ教訓を別の正規化から学んだ直後のことだった。
17コンパイルできるコードが、動くコードとは限らない
テストとチェック
構文チェッカーは、実行するとクラッシュするコードを通す。すべてが「緑」なのに画面が真っ白、というのは最悪の失敗である。
検出の問い私のテストは、コードを実行しているか、それとも読んでいるだけか?
危険信号「構文チェックは通った。コードは問題ない」
例と対処法
例
あるページは、構文チェックと型チェックを通った。しかし開くと真っ白だった。サーバー側にしか存在しない変数を使っていたのである。
どうするか
ページやプログラム全体を実際に動かすテストを、少なくとも一つは持つ。
18ソースを確認しても、届けられるものを確認したことにはならない
テストとチェック
X を確認し、ユーザーが受け取るのが X から派生した Y だとすれば、その間には誰も見ていないコードが存在している。
検出の問い誰かが、画面に届くものを確認しているか、それともソースから出てくるものだけを確認しているか?
危険信号「検証済みのデータから来ている」「ファイルは問題ない」
例と対処法
例
公開された各結果が正しいことは確認されていたが、そこから作られた版が画面に届いていた。その版は、欠損データに別のルールを使っていた。
別の例
あるレビューアーは、各ページのソースファイルを読んで承認した。モバイルではテーブルがカードに積み重なり、比較できなくなっていたが、それはページを実際に見て初めて分かった。
どうするか
人に届く地点で確認する。見られているままのページ、ダウンロードされるファイル、受け取るメッセージ(教訓 41 も参照)。
インターフェースとデザイン
「もう同じになっている」と言うには、見えるすべての性質を比べていなければならない。一つだけではだめである。
検出の問い一つの性質を比べたのか、それとも、ユーザーが見るすべての性質を比べたのか?
危険信号「サイズが合っているから、デザインは同じだ」
例と対処法
例
二つの画面のデザインを、四回のラウンドを経て揃えた。最初はサイズ、次は書体、次は色、最後はラベルの色。各納品で「完了した」と言われた。
別の例
ある資料のイラストは、内容とサイズはレビューされたが、コントラストはレビューされていなかった。その結果、二つの文字色が、四枚の画像で、最低限読めるレベルを下回っていた。
どうするか
最初の違いを直す前に、すべての違いを挙げる。そして、メモの動詞がそれを明かす。「直った」「〜になる」は意図であり、「〜と書いてある」「〜と表示される」は測定である。
スクリプトとファイル
「なければ挿入する」は重複を防ぐが、物事を凍結させる。すでにあるものは、二度と書き直されない。
検出の問いこのコードが挿入するものを変えたら、次の実行で更新されるか?
例と対処法
例
ある分類の範囲を示す凡例は、一度だけ挿入された。その後、範囲は変わったが、凡例は古い範囲を表示し続けた。
どうするか
置き換える。古いものを削除し、もう一度挿入し、残っているコピーが一つだけであることを確認する。
スクリプトとファイル
変更箇所をユーザーが読むテキスト(タイトルやラベル)で探すと、別の改善がその上に何かを貼り付けたとき、自分の変更は目印を見失う。
検出の問いアンカーに使うテキストは、別の理由で存在しうるか、あるいはその中に何かが増えうるか?
危険信号「タイトルをアンカーにしよう。一意だから」
例と対処法
例
いくつかのタイトルの横にヘルプアイコンが追加された。そのタイトルで自分の位置を見つけていた更新は、動かなくなった。
別の例
あるレビューは、数値に変換されているかを確かめるために「int(」を探したが、それは「print(」の中にも一致した。何かを表示するすべての行が合格しているように見えた。探す文字列は、別の単語の一部ではなく、単語全体でなければならない。
もう一つの例
あるレビューは、コードが最後に出力した行を答えとみなしていた。関数が中で数値を出力し、それを返さない場合、その行は別の理由で存在していた。答えは画面に現れたが、コードは決してそれを届けていなかったのである。
どうするか
ID やセクションコメントのような、自分だけの目印を使う。そして、変更が多くのブロックに同時に触れる場合は、最初のブロックだけでなく、すべてのブロックを確認する。
スクリプトとファイル
何も壊さずに繰り返される変更は、一回ではなく二回実行して確かめなければならない。
検出の問い変更をすでに適用されているものに対して実行したか? 私の後に、この同じテキストに触れている別のプロセスは何か?
例と対処法
例
スクリプトが二回目の実行で何も変えないことを確かめるために、同じ実行のチェックサムを二度比べた。その後、異なるファイルリストから取った二つのチェックサムを比べた。どちらの比較も「同じ」か「違う」かを言っただけで、何も証明しなかった。うまくいく比較は、チェックサムを取り、スクリプトを実行し、もう一度チェックサムを取る。同じファイルに対し、一つのコマンドの中で行うものである。
どうするか
同じ出発点から二回実行し、ファイルを比べる。二回目は何も変えてはならない。
スクリプトとファイル
「セル 9」の前に何かを挿入すると、セル 9 はもう別のセルになっている。
検出の問いこのツールは位置で物を指定しているか? そして、その前に何かを挿入したり削除したりしたか?
例と対処法
例
スクリプトは、ノートブックのセル 9 の前にタイトルのセルを挿入し、その後「セル 9」を編集した。結果、直前に挿入したセルを編集してしまった。
どうするか
挿入のたびに場所を探し直し、全体の構造をレビューして結果を確認する。
スクリプトとファイル
書き込みのためにファイルを開くと、即座に空になる。書き込みの途中で何かが失敗すると、空のファイルが残る。
検出の問いファイルを開いてから書き込みを終えるまでの間に、何かが失敗しうるか?
危険信号「単純な置き換えだから、直接書いてしまおう」
例と対処法
例
スクリプトは設定ファイルを書き直すために開いたが、値の一つを計算している途中で失敗し、ファイルは空のまま残った。サーバーは二度と起動しなかった。
どうするか
すべてをメモリ上で準備し、一時ファイルに書き、最後に一つの操作で元のファイルを置き換える。
スクリプトとファイル
「スケジュールタスクが有効になっている」は、「今月実行された」という意味ではない。そして、失敗したときにアラートが知らせてくれるのを待つことは、アラートが決して失敗しないと信じることである。
検出の問い何かが「勝手に起動する」ことを当てにしていないか?
危険信号「スケジュールされているから、動いている」
例と対処法
例
スケジュールタスクは「有効」と表示されていたが、期限切れの認証情報のせいで二か月間実行されていなかった。ダッシュボードは、最後のデータ点を、まるで今日のものであるかのように表示していた。
どうするか
データが最後に更新された日時を画面に表示する。どの期間が欠けているかを確認する。そして、行を重複させずに再実行しても安全なように、プロセスを作る。
テストとチェック
品質フィルターは、通常、新しいものをレビューする。すでに入っているものは放置され、その前提は誰も再び問わないまま古くなっていく。
検出の問い何か月も動き続けているこのものは、公開されてから、その前提が誰かに再検証されたか?
例と対処法
例
公開されたレポートは、ソースがもう埋めなくなった列で、まだ絞り込みを続けていた。結果はゼロを表示していたが、「すでに検証済み」だったので、誰も再び確認しなかった。
どうするか
使用中のものにも、新しい候補と同じテストを、すべてのレビューで課す。
コンソールとツール
数字が変わるべき時に変わらなかったり、見ている最中にちょうど変わったりしたら、次の順に疑う。キャッシュ、同じテーブルに書き込んでいる別のプロセス、見ているツール、そして最後の最後にシステムそのもの。
検出の問い私は今、システムを見ているのか、それとも、システムの古いスナップショットを保持していたり、途中で変えてしまったりするキャッシュ、コピー、ツールを見ているのか?
危険信号「もう直したのに、まだ同じだ」「今度こそ、ちゃんと打ち間違えずに入力した」
例と対処法
例
テーブルの列が「半分消えた」。数分後には完全になっていた。見ていたとき、別のプロセスがそれを再構築していたのである。
別の例
新しい画像がページで「読み込まれない」。ファイルは問題なかった。テストサーバーは、起動後に作られたフォルダを見ることができなかったのである。
もう一つの例
あるスクリプトが「テキストパターンを間違って計算した」。スクリプトは問題なかった。コードを渡すコンソールが、スクリプトが読む前に、すべての \n を実際の改行に変えていたのである。そして、セルが記憶を共有するノートブックでは、本来表示されるべきエラーが表示されなかった。変数が、以前のセルで保存されたまま残っていたからである。
どうするか
大惨事だと宣言する前に、数分後にもう一度スナップショットを取る。計器がすでに同じように失敗させたことがあるなら、それを見続けるのではなく取り替える。繰り返される失敗は運の悪さではなく、間違ったツールである。途中で \n や \\ を変えてしまうコンソールは、コードを渡すには向かない。コードはファイルに書き、それに触らないツールで書き、そこから実行する。そして機械的なもの(三回すでに失敗したコマンド)は、覚えておくのではなく、ガードでブロックする。
テストとチェック
同じ人が実行して確認するなら、実行の誤りは、それ自身を確認してしまう。
検出の問い実行した本人以外に、ユーザーが受け取る形で結果を確認した人はいるか?
例と対処法
例
各ページを書いた人が、レビュー用のスクリーンショットも撮っていた。しかも、危険だと思った手順のものだけだった。レビューアーはソースファイルを読んだ。スクリーンショットのない手順は、誰にも見られていなかった。
どうするか
一人が実行し、もう一人が結果を読んで確認する。「もうやった」は、今や検証できるという印であって、検証そのものではない。そして、検証する人は、実行した人と同じ経路で見てはいけない(教訓 14 を参照)。両方ともソースだけを読むなら、どちらも画面を見ていないことになる。
コンソールとツール
誰かの書いたコマンドを実行する人は、目隠しをして実行している。壊れたコマンドは、一つ壊れるたびに、次のコマンドに対する信頼を消費してしまう。
検出の問いこのコマンドの各名前を、今日、システムから読んだか、それとも記憶から打ち込んだか?
例と対処法
例
デプロイのコマンドには、ブランチ名が記憶から打ち込まれていた。ブランチは別の名前になっていた。実行した人は、質問する前に三十分を失った。
どうするか
人に渡す前に、自分で実行する。そして各名前(スクリプト、パス、ブランチ)は、記憶からではなく、システムからコピーする。
Git とプロセス
間違った方向に速く動くことは、前進ではない。
検出の問いこのブロックは大きいか、元に戻しにくいか、あるいは別の人がすでに決めたことを変えるか? そうなら、説明して待つ。そうでなければ、何をするかを言って進める。どのステップでも許可を求めることにも、コストがかかるからである。
危険信号「相手が何を望んでいるかは、もう分かっている」
例と対処法
例
プロジェクト全体のフォルダ構成が、知らせもなく再編された。その変更はそれ自体は正しかったが、完全に元に戻された。別の人が、コードには書かれていない理由で、その構成をすでに決めていたからである。
どうするか
作業の大きなブロックを始める前に、何をするか、なぜかを平易な言葉で説明し、確認を待つ。
31意思決定を変えないかぎり、画面に技術的なものは載せない
インターフェースとデザイン
業務画面のすべての要素は、何かを決める助けになるべきである。監査を助けるものはコードに入れる。決める助けになるものは、業務の言葉で画面に載せる。
検出の問いこの変更は、画面を使う人の決定を変えるか? 変えないなら、なぜここにあるのか?
例と対処法
例
販売画面は、最初の行に各注文の内部 ID と、最後に計算された時刻を表示していた。誰もそれで何かを決めていなかったが、本当に重要なデータのスペースを奪っていた。
どうするか
画面に何かを加える前に、それがどの決定を変えるかを書き出す。どれも変えないなら、画面ではなく、技術ログかコードに入れる。
32動いているのに見えないものは、壊れていると報告される
インターフェースとデザインwebapps
ボタンが、表示の外にあるものを変えるなら、ユーザーにとって、動いている場合と動いていない場合の見え方は同じである。
検出の問いコントロールを使った直後、その場所から動かずに、ユーザーは何が変わったかを見られるか?
危険信号「ちゃんと動いてはいる。ただ表示されないだけだ」
例と対処法
例
フィルターはテーブルを確かに絞り込んでいたが、テーブルは二画面分下にあった。人々はそれを「何もしない」と報告した。
変形
何かを隠すと、その中にあるものもすべて隠れる。それが無関係なものであっても。例えば、廃止されたコントロールの中にあった、役に立つリンクなど。
どうするか
すべてのコントロールは、何が変わったかを伝え、ユーザーをそこへ連れて行く。そして何かを隠す前に、その中にどんな要素があるかを確認する。
インターフェースとデザイン
小さな活字では、「÷」と「+」、「l」と「1」、「O」と「0」が混同される。二人が同じものを誤って読むなら、それは気が散っているからではなく、活字の大きさのせいである。
検出の問い読まれる大きさとフォントで、この記号は別のものと混同されうるか、それとも、入力できないものに見えるか?
例と対処法
例
二人の別々の人が、小さな活字のカードにある「98 ÷ 441」を「98 + 441」と読み、二人とも計算が間違っていると報告した。
別の例
教材のコードフォントは、>= を一つの記号 ⩾ につないでしまっていた。学習者は見たものをそのままコピーするが、その記号はキーボードにも言語にも存在しない。
どうするか
記号が混同されるなら、言葉に置き換える。「98 ÷ 441」の代わりに「98 割る 441」と書く。
テストとチェック
QA レポートは、たいてい症状については正しいが、提示する原因は仮説にすぎない。
検出の問い自分の測定で原因を再現できるか。それとも、もっともらしく聞こえるから受け入れているだけか?
例と対処法
例
あるレポートは、合計が合わないグラフを直すよう求めていた。しかしそのグラフは画面上に存在しなかった。データは、それを描くものが何もないまま流れていたのである。
どうするか
修正の前後で測る。症状を部分的にしか改善しない修正は、まだ完了していない。
Git とプロセス
別のことをしている最中に「後で」と書き留めたものは、もう存在しないかもしれないし、意図的な決定だったかもしれない。
検出の問いこの項目を今日確認したか、それとも、書かれているからといって取りかかろうとしているのか?
例と対処法
例
メモには「日付フィルターを削除する」とあった。ようやく取りかかったとき、そのフィルターはチームが書面で決めたことになっており、削除するとレポートが壊れた。
どうするか
保留中の項目に取りかかる前に、今日それを確認し、そのままにしたのが意図的だったと示す、書面の決定を探す。
数値とデータ
文書内のすべての数字は、日付と出典のある測定から来ている。記憶や、文書の以前の版から来ているのではない。
検出の問いこの数字、またはこの比較(「千を超える」「半分を超える」「ほぼすべて」)は、どのデータ、どの日付から来ているのか?
危険信号「それは以前から持っている数字だ」「だいたいその辺りになる」「全部通っているのが見える」
例と対処法
例
ある説明では、あるバグのせいで「ほぼ五件に一件」のチケットを失っていたとされていた。測り直すと、五件に一件よりも多かった。その文は、データではなく暗算から来ていた。
別の例
あるテキストは、あるコホートのグループが「50%を超えていた」と書いていたが、十二のうち五つは 50%を下回っていた。別の文書では、図が手計算を示していたが、その計算は合わなかった。割合に合計を掛けても、図に描かれた数にはならなかったのである。
どうするか
数字を書く前に、もう一度測り、その横に、どのデータ、どの日付から来たかを書き留める。数量を表す言葉(「ほぼ」「〜を超える」「大半」)も、姿を変えた数字である。同じように測る。図の中に計算があるなら、その図を描くのと同じスクリプトに計算させる。
37書きたいことではなく、実際にあることを文書にする
執筆とドキュメント
ドキュメントのレビューは文書を改善するものであって、システムを作り直すものではない。システムに制限があるなら、文書はそれを書く。隠したり、直すと約束したりしてはいけない。
検出の問いこれから書こうとしていることは、今どう動くかを述べているのか、それとも、どう動くべきかを述べているのか?
例と対処法
例
マニュアルには、データは自動で同期されると書かれていた。実際のシステムは、アプリを開いたときにしか同期しなかった。レビューは、制限をありのままに書く代わりに、「まもなく自動になる」と約束するように文書を「直して」しまった。
どうするか
文書についての指摘(「文章が下手だ」)と、システムについての指摘(「理想とは違う動きをする」)を分ける。後者は制限として明記する。
執筆とドキュメント
公式文書は、すべてを同じ権威で述べる。持ち主、予定、応答時間のような、作られた詳細は、本物の詳細と同じ重みで読まれてしまう。
検出の問いこの詳細は本当に知っているのか、それとも、もっともらしく聞こえるから仮定しているだけか?
例と対処法
例
ある手順には、誰も合意していない 24 時間の応答時間が書かれていた。もっともらしく聞こえたから書かれたが、公開された時点で約束になった。
どうするか
不足している部分は、赤字の「保留」のように目に見える形で印をつけ、詳しい人に確認する。偽りの言葉より、中立的な言葉のほうがよい。
混同しないこと
印は、決定する人のためのものであり、最終的な読者のためのものではない。公開された文章の中に「確認待ち」と書かれていれば、それもまた存在すべきでないデータである。確認される前に文書を出すなら、不足している内容を主張しない中立的な言葉を使い、保留の項目は報告書やプロジェクトの記録に残す。
執筆とドキュメント
変更のたびに、表紙に新しいバージョン番号を付け、履歴に一行を加える。日付、何を変えたか、誰が変えたかを書く。二つの版が出回っているとき、どちらが正しい版かを示すのは、バージョンだけである。
検出の問い先週のコピーを持っている人は、それがもう正しい版ではないと、どうやって分かるのか?
危険信号「小さな変更だから、バージョンはいらない」
例と対処法
例
マニュアルの二つの版がメールで出回っていた。古い版には、ツールは「ダブルクリックで開く」と書かれていたが、それはもう正しくなかった。しかし、どちらが正しい版なのか、誰にも分からなかった。
どうするか
文書を変更するのと同じ変更の中で、バージョン番号を上げ、履歴の行を書く。
40記録は、何が残り、なぜかを書く。失敗の年代記ではない
Git とプロセス
変更の履歴は、製品を理解するためのものであって、変更した人が解決済みの失敗を語るためのものではない。
検出の問いこの行は、製品を理解したり、同じ失敗を繰り返さないことを助けたりするか? それとも、ただ自分に起きたことを記録しているだけか?
例と対処法
例
履歴には「A は試して失敗、B は試して失敗、C を残した」とあった。数か月後にそれを読む人が必要としたのは C とその理由だけだったが、見つけるには三段落を読まなければならなかった。
どうするか
最終的な状態とその理由を書く。試して失敗したことは、同じ失敗を繰り返さないために誰かが必要とするものを教える場合にだけ書く。
インターフェースとデザインweb
テキストの中に単語があることを確かめても、それが表示されることは証明されない。テキストは文書の別の場所にあって、表示されるはずの形式が空のまま出てくることがある。
検出の問い読み手が見る通りに、その要素そのものを確認したか、それともソースの中で単語(またはコード)を見つけただけか?
例と対処法
例
番号付きの三つの手順が、空の箇条書きとして出てきた。その単語は文書の別の場所に存在していたため、自動チェックは通ってしまった。
別の例
「右にまだ列があります」という表示が追加され、コードがあるので完了とされた。しかし一度も表示されなかった。テーブルの一般的なスタイルが、それを有効にする条件を取り除いていたのである。別の人がスクリーンショットでそれに気づいた。
もう一つの例
ある回答の選択肢は、ファイルの中では「合計: {2 * 78}」だった。ページが描画されると、システムは中括弧の中身を計算し、「合計: 156」と表示した。二つの同じ選択肢になってしまった。画面を見た人だけがそれに気づいた。
変形
レビューする人が判断するスクリーンショットは、誰も到達しない画面を映すことがある。あるコースの撮影ツールは、コードの練習に対して、先へ進むための埋め草の行を返していたので、「実行後」のスクリーンショットには、その行と「期待される結果ではありません」というメッセージが映っていた。レビューする人は、正解した学習者が見るものを一度も見ていなかった。デスクトップでは、撮影にヘッダーとサイドメニューも入り、レッスンは読めない細い帯になった。レビュー用に撮影するときは、各ステップを成功したユーザーのように答えさせ、レビュー対象の部分だけを撮る。
どうするか
「これら三つの手順が、箇条書きとして」のように、正確な要素を確認する。そして、読み手が見る通りに、ページを少なくとも一度は見る。小さな修正も確認する。別のルールがそれを上書きすると、最も予想されていない場所だからだ。そして、ページで新しいリソース(コードブロック、固定ヘッダー)を初めて使うときは、モバイルでも見る。
執筆とドキュメント
古いコピーを対象にしたレビューは、すでに直したはずの誤りを再び持ち込む。
検出の問い今編集している版は、最新の版か、それとも自分が開いていた版か?
例と対処法
例
マニュアルの再編を、数週間前の版を使って行った。そこには、ツールは「ダブルクリックで開く」と、また書かれていたが、それはもう正しくなかった。
どうするか
レビューが提案する構成を取り、そこに最新の内容を流し込む。逆ではない。
執筆とドキュメント
部分的な修正を何度も重ねると、文書は自己矛盾を起こすことがある。どの修正も、その節の中では正しかったが、他の節を誰も読み直さなかった。
検出の問い誰かが全体を読んでから、この文書には何回修正が入ったか?
例と対処法
例
ある節には、接続がなければ何も保存されないと書かれていた。ところが FAQ には、まだ、取得したものは端末に保存されると書かれていた。
どうするか
各ラウンドが終わるたびに、修正した内容について文書が述べていることを、トピック別に検索する。
44出力から切り捨てたものが、判定であることがある
コンソールとツール
結果の最後の数行だけを見たり、別のコマンドに通したりすると、まさに「失敗した」と言っていた部分が捨てられてしまうことがある。失敗したテストの切り詰められた出力は、通ったテストの出力とまったく同じに見える。
検出の問い私は判定(何件通り、何件失敗し、どう終わったか)を読んでいるのか、それとも出力の一部だけを読んでいるのか?
危険信号「画面にエラーは出なかった」「最後の数行で十分だ」
例と対処法
例
あるページは、テストが「エラーなく終わった」ので、レビュー済みとされた。結果は末尾しか表示しないコマンドに通され、テストが失敗したという通知は途中で消えていた。
別の例
あるテストスイートは、失敗したテストを自動的に再試行していた。二回目で通ったテストは、失敗ではなく「不安定」として数えられ、原因は隠れたままだった。ステップが変わるたびに、サーバーにページを再度要求していたのである。再試行をやめると、失敗が現れ、測定できるようになった。
どうするか
ステータスを変える前に、判定の行を探す。コマンドをつなぐなら、最初のコマンドの失敗が最後まで届くようにする。出力に判定がなければ、それは「分からない」を意味し、「通った」ではない(教訓 1 を参照)。そして、出力全体をファイルに保存し、判定をそこで探す。そうすれば、どこまで読むかを事前に決めなくて済む。
インターフェースとデザインwebapps
すべてがうまくいくときに起きることだけをテストすると、間違える人が、その抜け穴を見つけてしまう。学習中には、間違えることこそが最も一般的なことである。
検出の問いユーザーが最もありそうな間違いをする(タイプミス、空の回答、二回のクリック)と、何が見えるか? そして、ユーザーは進み続けられるか?
例と対処法
例
クエリのセルは、クエリが実行されたときにしか試行回数を数えなかった。タイプミスがあると、次に進むボタンは有効にならず、人は立ち往生した。テストは通っていた。いつもエラーのない最初のクエリを実行していたからである。
どうするか
各コントロールについて三つの道をテストする。正しい道、最もよくある誤り、そして空の場合。三つとも、何が起きたかを伝え、ユーザーが進み続けられるようにする。
46すべてのリクエストで動くものは、コンテンツと一緒に大きくなってはならない
インターフェースとデザインweb
すべてのページで行うこと(すべてのコンテンツを読む、索引を再計算する)は、十ページなら少しの費用しかかからないが、百ページなら多くかかる。それは少しずつ大きくなり、「たまに」失敗し始めるまで誰も気づかない。
検出の問いこのすべてのリクエストで動くものは、すべてのコンテンツを通るか? それは今どれくらいかかり、二倍の量ならどれくらいか、そして多くのリクエストが同時に来たらどうか?
危険信号「ローカルでは速く読み込まれる」「たまにしか起きない失敗だ」
例と対処法
例
サイトのすべてのページが、目次を作るためにすべてのコンテンツを読んで解析していた。一ページだけなら 0.4 秒だった。しかしサイドバーは一度に約 40 件を要求していたので、合わせると 16 秒かかった。数か月後、ページを切り替えるとテストが失敗するようになり、その失敗はテストの問題に見えた。
どうするか
一ページだけではなく、コンパイルされたサーバーで、人々の使い方どおり、すべてのリクエストをまとめて測る。サーバーの稼働中に変わらないものはキャッシュする。そして、それを遅くした実際のケースで、その速さを測るテストを残す。
Git とプロセス
複数の人が同時に作業すると、各自は自分の部分をはっきり見ている。しかし、共有されるもの(テスト、データ、プロジェクト全体の文書)では、変更が合流してしまう。名前が衝突し、コピーが遅れ、他の人の未完成の作業を読むテストが生まれる。統合は、貼り付けではなく作業である。
検出の問い二つの部分が同時に触れているファイルはどれか。そして誰がそれを統合するのか? 私のテストは、他の人の未完成の作業を読んでいないか?
危険信号「それぞれ自分の部分はテストした」「失敗は別の部分にある」
例と対処法
例
四人がそれぞれ同時に一つの部分を書き、共有の部分を成果物として残していた。統合のとき、二つの成果物が、共有テストにすでにある名前を使っていたため、そのテストは走らなくなった。別のテストは、自分が確認するものの写しを持っていた。部分は変わったが、写しは変わらなかった。あるテストの実行は、別の人がまだ描いていた画像のせいで失敗した。そして最後には、各部分を単独で保存することができなくなった。共有ファイルには、すでに全員の変更が入っていたからである。
どうするか
共有されるものは一人が統合する。名前が衝突したら止まるステップを入れる。テストは写しではなく、元のものを読むようにする。全員が終わったら、あるいは変更中の部分を除いて、テストスイート全体を一度実行する。そして除外した部分を言う。同じファイルを共有する部分は一緒に保存し、保存されたそれぞれのバージョンが全体として動くようにする。
スクリプトとファイル
ファイルがスクリプトや他の部品から組み立てられるなら、そのファイルは元のものではなく出力である。直接修正した箇所は、次に生成されたとき、警告もなく失われる。
検出の問いこのファイルは、別の何か(スクリプト、テンプレート、部品の組み立て)によって書かれているか? 再生成したら、私の変更はまだ残っているか?
危険信号「ファイルを直接直した」「ちょっと再生成しただけだ」
例と対処法
例
あるメモは、各人が提出した節から組み立てられていた。三行をメモの中で直接修正したが、提出物から再生成したとき、古い三行が戻ってきた。別の案件では、レビューアーがテンプレートから作られたページの代替テキストを手で直したが、作成者がページを再生成すると、その修正は消えた。
どうするか
ファイルを直す前に、どこから来ているかを突き止める。生成元(テンプレート、スクリプト、提出物)を直し、再生成する。どうしても出力を直さなければならないなら、同じ手順で生成元も直す。生成された出力をレビューした人は、何が変わったかを言い、それがソースに移されるようにする。そして、ソースからファイルを再構築する前に、出てくるものと比べる。違いのあるものは、失われてしまう修正である。
49一般的なルールは、特定のルールを黙って打ち負かしてはならない
インターフェースとデザインweb
すべてに当てはまるルール(グローバルなスタイル、デフォルト値)は、各部品が自分で決めたことを、何の警告もなく上書きしうる。
検出の問いこの一般的なルールは、各部品が自分で決めている何かに触れるか? 両者が衝突したら、どちらが勝つか?
危険信号「繰り返さなくていいように、グローバルにした」
例と対処法
例
サイト全体のためのキーボードのフォーカススタイルには、独自の角丸が含まれていた。各コンポーネントのスタイルより優先されたため、ピル型のボタンは、キーボードでフォーカスすると形が変わった。マウスでは、フォーカスが現れないので、誰も気づかなかった。
どうするか
一般的なルールには、自分のものだけに触れさせる(フォーカスの輪郭は触るが、形は触らない)。意図的に勝たせたいなら、その横にそう書く。そして、一般的な部品ではなく、最も異なる部品でテストする。
50二つの説明が同じことを予測するなら、例はどちらも選べない
数値とデータ
例が説明を裏づけるのは、対立する説明だと違う結果になるときだけである。両方が同じことを予測するなら、例は先に思いついたほうを信じさせてしまう。
検出の問い同じ結果を生む、別の説明はないか。自分の例は、それを除外しているか?
例と対処法
例
あるレッスンでは、ファネルの最初のステップを五ポイント上げたときと、最後のステップを上げたときを比べた。最初のステップの改善が勝ち、本文には「訪問が多いところほど価値がある」と書かれた。しかし、最初のステップは転換率が最も低いステップでもあり、真の原因はそちらだった。最初のステップの転換率がよいファネルでは、訪問数が少なくても最後のステップのほうが勝つ。別のプロジェクトでは、あるページの読み込みが 2.7 秒かかるのはそのページのせいだとされた。ページを一つずつ要求するテストは、修正なしでも通った。本当の原因は、同時に四十件のリクエストが飛んでいたことだった。
どうするか
何かが起きる理由を教えたり報告したりする前に、対立する説明を書き出し、二つの説明が違う予測をする事例を作る。同じ大きさの部分を比べ、別の例の大きさも試し、一般的な主張は書く前に模擬データで測る。二つを切り分けられないなら、その例は両方と両立すると書く。
51自分には自明に見えることこそ、最初に教えるべきこと
執筆とドキュメント
既に知っている人は、考えずに行っている手順を見ない。そのため最初の例に新しいことが一度に現れ、初心者は一行目で置いていかれる。
検出の問い最初の例で、何も知らない人にとって新しいものはいくつあるか。私が求めるすべての記号、すべての語、すべてのボタン名、すべての操作は、これまでに教えられているか?
危険信号「誰でもわかる」「一行だけだ」「よくある言葉だ」
例と対処法
例
初心者向けのプログラミング講座は、一つのセルに新しいことが六つも同時に現れる例で始まっていた。カリキュラムでは、データ型が何かも、= が右から左へ値を保存して読むことも、一度も教えていなかった。講座の担当者は一文でこう指摘した。「あなたは学習者のことを前提にしすぎている。」その後、三つのレッスンで「数式をドラッグするのと同じように」と書かれていたが、ドラッグを教えたレッスンはなく、教えたのは「数式を下にコピーする」だけだった。
どうするか
書く前に、例が前提としていること(記号、語、クリック、学習者がすでに作っているはずのもの)を書き出し、それを先に教える。一度に一つの新しい考えだけを扱い、記号は最初に現れたときに必ず説明する。ボタン名と一致する語や、求める操作も、記号を探すのと同じように確かめる。可能なら、各例が使っているものと、すでに教えたものを比べる自動チェックを入れる。
52変化の速いツールは、記憶ではなく今日の実践から書く
執筆とドキュメント
数か月ごとに変わるツールについてのレッスンやガイドは、著者の記憶から書くと、書いている間に古くなる。最初の読者が読む前に、前提がすでに偽になっていることもある。
検出の問いこの文章の前提のうち、どれがツールの今の能力に依存しているか。それを最後に確かめたのはいつで、どの情報源に対してか?
危険信号「そういうふうに動くものだ」「みんなこうやっている」
例と対処法
例
「AI による分析」モジュールの計画は、「AI はあなたのデータを見られないので、表を貼り付けずに説明せよ」という一文で始まっていた。講座の担当者は、今やエージェントがデータベースに接続し、自分でクエリを実行し、数値を返すと指摘した。出典と日付を付けた調査で、それが確かめられた。二年前は、チャットからコードをコピーするのが普通のやり方だった。いくつかのレッスンは、今も通用するもの(問いを定めること、エージェントを監督すること、数値を確かめること)を中心に書き直された。
どうするか
変化の速いツールについて書く前に、今のやり方を出典と日付を付けて調べる。ツールが今何をするか、何が無料か、人々が実際に何を使っているか。次のバージョンを越えて残るスキル(枠組みを立てること、監督すること、検証すること)を中心に文章を組み立て、ツール固有の手順は、更新しやすい一か所にまとめる。確認できなかったことには印をつけ、公開する前に自分で一度試す。
53コードはシェルの文字列処理ではなく、エディタを通す
コンソールとツール
シェル自身の文字列ツールでソースファイルを書き直す(読み込み、置換、書き戻し)と、コードは別の目的のために作られた規則を通ってしまう。既定の文字コード、演算子の優先順位、引用符とエスケープである。変更はコマンドの中では正しく見えるが、ファイルは、コマンドが言っているように見えるものとは違う形で出来上がる。
検出の問いこのコードの変更は、エディタを通っているか。それとも、シェルの読み込み、置換、書き込みを通り、その文字コード、優先順位、引用符の規則を受けているか?
危険信号「ちょっと置換するだけだから、一つのコマンドでやってしまおう」「置換をまとめてやった方が速い」
例と対処法
例
一つのセッションでの二つの編集で、どちらも Windows PowerShell 5.1 でのものだった。スクリプトを読み込み、置換し、書き戻す処理(Get-Content、-replace、Set-Content -Encoding utf8)は、ファイルをシステムの ANSI コードページで読み、UTF-8 で書き戻した。そのため、中にあった ✓ と · はすべて ✓ と · に変わり、スクリプトの自己チェックは崩れた記号を表示した。次に、置換の一覧を `@('old', 'new' + "n" + 'more')` と書いたところ、行が抜け落ちた。PowerShell では、カンマが +` より強く結びつくため、各ペアが四つの要素になり、新しいテキストのうち最初の部分だけが書き込まれたのである。
どうするか
コードは、エディタ自身の編集と書き込みの機能で変える。変更をスクリプトで行う必要があるときは、スクリプトをファイルに書き、UTF-8 を読み書きし、文字列リテラルが素直なインタープリターで実行する(node fix.mjs、python -I fix.py)。そのうえで差分を見る。意図したより多くの行に触れた変更、あるいは触れるつもりのなかった文字が変わった変更は、シェルの仕業である。
EDU-1技能なしでも同じ答えになるなら、その課題はその技能を測っていない
テストとチェックeducation
課題が技能を測るのは、その技能を飛ばした人が違う結果を得るときだけである。出発点、例、近道ですでに正しい答えが出るなら、課題はすべての人を通してしまう。これは課題版の教訓 13 である。チェックに価値があるのは、誤りを退けるのを一度見たときだけだ。
検出の問い教えている技能を正確に飛ばした人、あるいは課題に手を付けずに提出した人は、どんな結果を得るか? それは正しい結果と違うか? 両方の計算がたまたま一致する場合(最初のグループ、最初のステップ、合計)を選んでいないか?
危険信号「正しい答えを出すなら、動いているということだ」
例と対処法
例
ある練習は、日付フィルタを使って夏の最大の購入額を求めるものだった。しかし、表全体の最大の購入もまた夏のものだったので、フィルタなしでも数値は同じになり、課題はそれを受け入れてしまった。別の練習では、コードに = を含めることが求められていた。しかし、結果を手で入力した total = 1945 でも通ってしまった。チェックが見ていたのは技能ではなく、文字だった。
どうするか
すべての課題を三通りに解く。手を付けずに、最も起こりやすい誤りを含めて、正しく。通ってよいのは三つ目だけである。その後、同じ近道の一覧を全課題に当てはめる。手で入力した数字、答えを末尾に足した開始コード、原因ではなく症状を手で直したもの、必須の語を空の状態で使うこと、前の試行の記憶が残ったままでの実行。許容誤差は、答えと最も起こりやすい誤りとの距離より小さく保つ。学習者が使うであろう正しい形を三つ書き、正しいものを拒否しないようにする。
EDU-2学習者が答える前に目にするものに、答えが含まれてはいけない
執筆とドキュメントeducation
答えがすでに見えてしまうと、問題は測定をやめる。画像、要点、別の課題の解説、ステップの見出し、前のレッスンのどこかに答えがあれば、正解した人は今しがた読んだだけかもしれない。
検出の問い学習者は、答える前にこの図、画像、語句を、ここでも前のレッスンでも見ているか? 正確な数字だけでなく、近似(「約 25」)、キャプションに書かれた結論、見出し、「今見たように…」、前の課題で最も多い誤答が画面に示していることも含めて。
危険信号「ただの文脈だ」「ただの見出しだ」「ただのキャプションだ」
例と対処法
例
練習問題の上に、求められている正しい数値を示した図が置かれていた。あるレッスンは「変数に新しい値を入れると何が起きるか」を問うが、そのステップの見出しは「もう一度入れると置き換わる」だった。最後の確認テストの下に置かれた要約は、答える前に読まれてしまっていた。最初の挑戦の後に表示されるフィードバックの枠は、たとえ失敗したときでも、答えの方向を示していた。
どうするか
各答えを、その問いより前に示されているすべてのものの中から探す。最初の失敗の後に出るもの、開始コードを実行したときに表示されるもの、ダウンロードできるファイル、図の中で数えられるものを含めて。ステップの見出しと学習目標は最後に書き、それぞれの予測の結果と並べて読む。自動チェックは正確な数字を見つけるが、近似や言い換えは、答えを念頭に置いて読む人にしか見つからない。
EDU-3正しいと弁護できる答えが二つある問題は、何も測らない
執筆とドキュメントeducation
問題文から見て別の選択肢も正当化できるなら、正当な理由で「誤った」ほうを選んだ人は不正解になり、正解した人は運がよかっただけかもしれない。問題が測っているのは、欠けている一文であって、考えではない。
検出の問い問題文とレッスンの内容から見て、別の選択肢も弁護できるか? それを除外するにはどんな事実が必要で、それは書かれているか?
危険信号「言うまでもない」「明らかに…という意味だ」
例と対処法
例
「その売上に割引がなかった」ときに、空の割引をどうするかを問う問題があった。レッスンは「事実として空白のものは空白のままにする」と教えていたので、「そのままにする」も正当化できた。想定された答え、つまり 0 で埋めることは、問題文が一度も言わなかったことに依存していた。目的が全売上の平均だという点である。別の問題では、「主要な指標は二か月目も支払う人の割合である」とあったが、「誰の」割合かは書かれていなかった。読み方によって、二つの答えは同じにも違いにもなった。
どうするか
誤りの選択肢ごとに、問題文とレッスンだけを根拠にして、誤りである理由を一行で書く。除外するために書かれていない事実が必要なら、問題文に加える。計算の目的、システムのルール、割合の分母、データについて分かっていることなどである。並べ替えの課題では、各項目を自分の分類だけでなく、すべての分類と照らし合わせて確かめる。
EDU-4正解を位置や長さで当てられるなら、そのクイズは当てずっぽうを測っている
テストとチェックeducation
問題一つひとつは問題なくても、問題集全体が答えを漏らすことがある。正解はいつも二番目、いつも最も長い、いつも中くらいの長さ、といった具合である。学習者は、作者よりも早くパターンに気づく。
検出の問い選択肢の位置と長さだけを見て、文章は読まないとしたら、三回に一回より多く正解を当てられるか?
例と対処法
例
あるモジュールの締めのクイズでは、七問のうち六問で正解が二番目の選択肢だった。講座全体では、正解が最も長い選択肢である問題が 55 % に上った。選択肢が三つなら偶然は三分の一である。長さを手作業で釣り合わせた後、正解が最も短くなったのはあるレッスンの七問のうち六問だった。また、三つの連続したレッスンでは、すべての問題で正解が中間の長さになった。
どうするか
選択肢は、正解がどこに書かれたかに由来しない順序で、表示時に並べ替える。ファイルごとに最長、最短、中間の長さを測り、少ない問題が傾向を隠さないよう、小さなファイルはモジュール単位でまとめる。数えた結果は、求めていたものと照らし合わせて読む。釣り合わせの作業は、漏れを消す代わりに場所を動かすことがあるからだ。
執筆とドキュメントeducation
ヒントは誤った試行の後に出る。ヒントが答えを教えたり、課題を解く一行を示したり、正解と最も多い誤りを分ける手順を示したりすると、二回目の試行は技能ではなく写しを測ってしまう。
検出の問いこのヒントを読んだ人は、技能がなくても次の試行を通せるか? ヒントは、答え、解く行、課題が測る手順、あるいは一致すべき前の数値を示していないか?
危険信号「ほんの少し促しただけだ」「もう一度は試したのだから」
例と対処法
例
講座の確認済みの練習 277 件を見直したところ、49 ファイルで 82 のヒントが書き換えられた。解く一行をそのまま示すヒントもあった(「二つ目のものは…」)。正解と、よくある誤りとを分ける順番をそのまま指示するヒントもあった。「前の結果と照らし合わせる」型の課題では、ヒントに「レッスン 2.2 で得た結果と一致するはずだ」と書かれていた。前の数値を覚えている人は、その手順を踏まずに数字を入力できた。
どうするか
ヒントは、よくある誤りの原因について書く(「位置は 1 からではなく 0 から始まる」)。そして、既に教えた内容だけを引用する。「前の数値と一致するはずだ」は、答えを示した後の解説のために残しておく。そこでは、二つの方法で同じ数値になることが検証なのだと教える。ヒントは単独ではなく、その課題で最も起こりやすい誤りと照らし合わせて見直す。
WEB-1壊れた保存先が、次のレコードまで道連れにしてはならない
スクリプトとファイルweb
サイトがレコードをどう保存していても、一度の壊れた書き込みは、その後に続くものまで道連れにしうる。レコードを行として追記していくと、途中で切れた行は次のレコードをくっつけてしまい、「壊れた行」を飛ばす読み込み側は、その両方を静かに失う。すべてのレコードを一つのファイルに入れ、読み込み、変更し、丸ごと書き戻す場合は、そのファイルが読めなくなった瞬間から、新しいレコードはすべて失敗する。それを知らせるのは、誰も見ていないコンソールだけである。これは教訓 24 の裏側である。そこではファイルが空になり、ここでは、その後に続くものが失われる。
検出の問い明日、保存先が壊れたら、次の訪問者のレコードはどうなり、そのことに誰が気づくか?
危険信号「壊れた行は飛ばされる」「末尾に追記するだけだから」「書き込みはアトミックだから、ファイルが壊れることはない」
例と対処法
例
最初の Web シミュレーションの両方の実行で、フォームは各メッセージを JSON の一行として保存し、管理画面は読めないものを飛ばしていた。ファイルの末尾で行が途中で切れると、次のメッセージは「ありがとうございます!」という返信を受け取って保存されたが、管理画面には一度も現れなかった。二つの版のうち一方には、「壊れた行: 飛ばす」というコメントがあった。
別の例
再実行の両方の実行では、すべてのメッセージが一つの JSON ファイルに入っており、一時ファイルに書いてから名前を変えていたので、書き込みの途中でクラッシュしても、もう被害はなかった。しかし、ファイルが別の形で壊れていた場合(手での編集、ディスクの空き容量不足、誤った復元など)、新しい訪問者は全員「Internal error」を受け取り、管理ページには何も表示されず、唯一の手がかりはサーバーのコンソールのスタックトレースだけだった。
どうするか
新しいレコードが古いレコードに依存しないようにする。ファイルが改行で終わっているなら末尾に追記し、そうでなければ、新しいレコードの先頭に改行を入れてから追記する。あるいは、すべてを入れた一つのファイルを書き直すのではなく、各レコードを別々のファイルに保存する。読み込むときは、読めなかったものの数を数え、その数を持ち主が見る場所に表示する。テストは、保存先を手で壊し(最後の行を途中で切る、ファイルを切り詰める)、その後にレコードを送って行う。
インターフェースとデザインweb
インターネットに開かれたフォームは、人だけが入力するわけではない。自動送信を止めるものがなく、メッセージを読む側がそれを掃除できなければ、最初の迷惑メールの波が本物の顧客を埋もれさせる。
検出の問い明日、千件の偽のメッセージが届いたら、持ち主はどうやって本物の一件を見つけ、残りをどうやって削除するのか?
危険信号「小さなサイトだから、誰も攻撃しない」「制限は後で追加する」
例と対処法
例
Web シミュレーションの両方の実行で、問い合わせフォームは、数秒のうちにスクリプトから 650 件のメッセージを受け付け、どれもが「ありがとう」と言っていた。管理者にはページも削除ボタンもなく、管理ページは高さが 100 万から 600 万ピクセルの間に膨らみ、モバイルでは、メッセージの本文が画面からはみ出した。どちらの場合も、構築者はそれを保留として記録していた。
どうするか
最初から、安価な歯止めを入れる。人が入力しない隠しフィールドと、アドレスごとの一分あたりの送信数の上限。そして、新しい順に並んだページを持つ管理画面と、削除または迷惑としてマークする手段。スクリプトで数百件のメッセージを送り、携帯電話で管理画面を開いてテストする。
WEB-3テストされていないフォールバックは、フォールバックではない
インターフェースとデザインweb
method と action を持つフォームは、JavaScript が失敗しても動くフォールバックを約束している。サーバーが JavaScript の期待する応答しか返さないなら、その約束は偽りで、人はコードを前に途方に暮れることになる。
検出の問いこの JavaScript ファイルが読み込まれなかったら、送信したとき人は何を見るのか?
危険信号「どうせみんな JavaScript を持っている」「念のため action は残しておこう」
例と対処法
例
Web シミュレーションの両方の実行で、フォームは JavaScript で送信され、method="post" が宣言されていた。JavaScript がない場合、一方の版では、サーバーが JSON の一行で送信を拒否し、メッセージは失われた。もう一方では、メッセージは保存されたが、空白のページに {"ok":true} だけが表示された。この二つ目の版の概要は、JavaScript なしでは送信しないと書いていた。
どうするか
二つのうち一つに決め、テストする。サーバーが通常の送信を受け付け、ページで応答する(またはお礼のページにリダイレクトする)か、あるいは、持っていないフォールバックを宣言しないか。JavaScript をオフにして、一度送信してみる。
WEB-4ボタンを無効にすると、フォーカスも一緒に消える
インターフェースとデザインweb
送信中にボタンを無効にすると二重送信は防げるが、ボタンはフォーカスを失い、ブラウザはフォーカスをドキュメントに移す。キーボードを使っている人は、通知の後、最初からやり直すことになる。
検出の問い送信のあと、成功しても失敗しても、フォーカスはどこに行き、次の Tab はどこへ進むか?
例と対処法
例
Web シミュレーションの両方の実行で、送信するとボタンが無効になった。サーバーが拒否したメールアドレスでは、通知がボタンの下に現れ、フォーカスはドキュメントに移り、次の Tab でページ上の最初のリンクに移動した。直すべきフィールドからは遠く離れていた。
どうするか
送信が終わったら、人が続けるために必要な場所にフォーカスを置く。エラーのあるフィールド(aria-invalid とその横のメッセージでマークする)か、成功の通知に。あるいは、無効にせずに二重送信を防ぐ。aria-disabled とフラグを使う。キーボードだけを使って、エラーの修正まで一通り操作してみる。
WEB-5試行回数の制限がないパスワードログインは、最も弱いパスワードと同じ強さしかない
インターフェースとデザインweb
間違ったパスワードに全速力で答えるログインは、誰でも毎分何千回も試せてしまう。強い初期パスワードは、持ち主が自分のパスワードを設定するまで問題を隠しておく。しかし、設定されたパスワードが短くても、それを止めるものは何もない。
検出の問いこのログインに対して、誰かが一分間に何回、間違ったパスワードを試せるか? そして、五回目の後に何が起きるか?
危険信号「初期パスワードは強い」「管理ページだけだから」
例と対処法
例
Web シミュレーションの再実行の両方の実行で、管理ページはパスワードを求めたが、失敗の回数を制限しなかった。間違ったパスワードを 200 回続けて送ると、一秒もかからず 200 回拒否されたが、どれもブロックされなかった。初期パスワードは長くてランダムだったが、構築した側の要約は持ち主に新しいパスワードの設定方法を教えており、それが長さを求める箇所はどこにもなかった。
どうするか
繰り返される失敗を遅くするか、ブロックする。アドレスごと、アカウントごとに、待ち時間を少しずつ増やしていく。持ち主がパスワードを設定するときは、最低限の長さを求める。テストは、間違ったパスワードを二十回続けて送り、最後の数回が拒否されることを確かめて行う。