【発展編】22-b つかんで運ぼう(2)

Q1. ☆問題☆

次のうち、Swiftでの「!」の説明で正しくないものはどれかな。一つ選んでね。

  • 「!」は「〜でない」という意味だ
  • 「!」は条件の先頭につける
  • 「!」は何かの条件とセットで使う(これだけでは使えない)
  • 「!!」とすれば「『〜でない』でない」なので、「〜である」という意味になる
  • 「!=」とすれば「イコールでない」という意味になるので、「if a!= b」とすれば、「aとbが等しくないならば」という条件になる

正解

  • 「!」は「〜でない」という意味だ
  • 「!」は条件の先頭につける
  • 「!」は何かの条件とセットで使う(これだけでは使えない)
  • 「!!」とすれば「『〜でない』でない」なので、「〜である」という意味になる
  • 「!=」とすれば「イコールでない」という意味になるので、「if a!= b」とすれば、「aとbが等しくないならば」という条件になる

解説

「!」は「〜でない」という意味で、条件の先頭につけるよ。「〜でない」の意味だから、「〜」にあたる条件などとセットで使うものだ。
その上で、「!!」か「!=」のどちらかがまちがっているんだけど、さて、どちらだろう。

「『〜でない』ではない」は、「〜である」なのは正しい。
ただし、Swiftではこの言い方はできない。これがまちがい。

「!=」は、げんみつにいえば「!」の使い方とはちがうんだけど、「!=」で「イコールでない」という意味になることはまちがいないんだ。
だから、例えば次のようなプログラムを書くことができる。

if ev3.measureLightColor(on: .three) != .red{
ev3.playSound(file: .hello, atVolume: 100, withStyle: .waitForCompletion)
}

赤以外の色を感知したときには「ハロー」というプログラムだよ。

Q2. ☆問題☆

これは、実際に試しながら考えてもらいたい問題だよ。
Q1でも確認したとおり、「!」は「〜でない」という意味だったよね。
そして、これまでにも学んだように、「true」は「条件を満たす」という意味で、「false」は「条件を満たさない」という意味だったよね。
それでは、次のようなプログラムを作ったら、どのように動くかな。正しいものを1つ選んでね。

repeat {
ev3.playSound(note: .a4, forSeconds: 0.1, atVolume: 100)
} while !true

  • 「ラ」の音がなり続ける
  • 「ド」の音がなり続ける
  • 一度だけ音がなってプログラムが終わる
  • 音がならずにプログラムが終わってしまう
  • 実行する時間やタイミングによって動きが変わる

正解

  • 「ラ」の音がなり続ける
  • 「ド」の音がなり続ける
  • 一度だけ音がなってプログラムが終わる
  • 音がならずにプログラムが終わってしまう
  • 実行する時間やタイミングによって動きが変わる

解説

まず、「.a4」は「ラ」の音だよ。問題は、この音がなるのかならないのか、ということだ。

「実行する時間やタイミングによって動きが変わる」ことはない。このプログラムでは、そのようなことは起きない。

repeat – while があるから、一度は repeat の中身が実行されるよね。そして、くり返すかどうかを判断するところに「!true」がある。
問題文にも書いたけど、「true」は「条件を満たす」。だから、「!true」で「条件を満たさない」という意味になる。
つまり、この時点で、repeat – while からぬけるため、「一度だけ音がなってプログラムが終わる」が正解。

「こんなめんどうくさいことしなくても」と思ったかもしれない。でも実は、このような使い方をすることもあるんだ。
今は、そうなんだ、と思っておいてくれればいいよ。
(興味がある人は、保護者用ガイドに載っている『さいごのミッション』Q2のプログラム例を見てみよう。そこではowariという変数でこのような ! の使い方をしているよ)

Q3. ☆問題☆

アームを回転させるとき、モーターの回転角度からアームの回転角度を計算することができたよね。
でも、ぴったりその角度になることは少なかったはずだ。その理由としてふさわしくないものを、次の中から1つ選んでね。

  • その計算はいつも正しいものではなく、正しい結果になるかそうでないかは、運によって決まるから
  • ギアをとめてあるところがすべってしまい、モーターがまわった分だけギアがまわらなかったりすることがあるから
  • モーターの回転する部分がしっかりと止まっていないので、モーターが回転しても、ほんの少しの間、ギアが回らないことがあるから
  • Swiftが「どれだけモーターが回転したのか」を調べにいくタイミングによって、動くと決めた角度ピッタリで止まることができないから
  • モーターを止めても、これまで回っていたいきおいで、もう少し回り続けてしまうことがあるから

正解

  • その計算はいつも正しいものではなく、正しい結果になるかそうでないかは、運によって決まるから
  • ギアをとめてあるところがすべってしまい、モーターがまわった分だけギアがまわらなかったりすることがあるから
  • モーターの回転する部分がしっかりと止まっていないので、モーターが回転しても、ほんの少しの間、ギアが回らないことがあるから
  • Swiftが「どれだけモーターが回転したのか」を調べにいくタイミングによって、動くと決めた角度ピッタリで止まることができないから
  • モーターを止めても、これまで回っていたいきおいで、もう少し回り続けてしまうことがあるから

解説

「ギア比」の計算そのものは、いつだって正しいものなんだ。正しい結果になるかどうかは「運」だ、なんてことはないよ。
ただ、実際にはうまくいかないこともあるのは事実だ。その理由は、残り4つのものがどれも考えられる。

「ギアをとめてあるところがすべってしまい、モーターがまわった分だけギアがまわらなかったりすることがあるから」は、つな引きを想像してみるとわかりやすいかな。
力いっぱいつなを引いても、にぎっていた手がすべってしまい、つなを引けないことがあるよね。
同じようなことがここでも言えるかもしれない。

「モーターの回転する部分がしっかりと止まっていないので、モーターが回転しても、ほんの少しの間、ギアが回らないことがあるから」
これは、「あそび」という言葉で説明される。この「あそび」があることで、急にモーターが動いても、いきなり大きな力がかからなくてすむんだ。
ドライバーでネジを回したことがある人はわかると思うんだけど、ネジをいきなり大きな力で回そうとすると、ネジのあな(ネジ山)がつぶれてしまうことがあるよね。
モーターやそこに取り付けるパーツも同じことで、急に大きな力をかけると、部品がこわれてしまうことがある。そうならないようにしているんだよ。

「Swiftが『どれだけモーターが回転したのか』を調べにいくタイミングによって、動くと決めた角度ピッタリで止まることができないから」
これは仕方がない。Swift Playgroundsではこのタイミングを調整することはできなさそうだけど、プログラムを作るときには、このようなことも考えなければならないことがあるよ。

「モーターを止めても、これまで回っていたいきおいで、もう少し回り続けてしまうことがあるから」
これは、EV3アプリでも「ブレーキ方法」のところで考えたよね。急に「ピタ」っととまるのではなく、ブレーキがかかっても、少し進んでしまうことがあった。
それと同じことが言えるよ。