【発展編】21-a 変な数?(1)

Q1. ☆問題☆

ミッション1でさいしょに作った次のプログラムは、「10cm以下になったら止まる」ものだったよね。
10cm以下なのに、whileのあとの条件は「ev3.measureUltrasonicCentimeters(on: .four) > 10」となっているのはなぜかな。説明としてもっともふさわしいものを選んでね。

repeat {
ev3.move(leftPort: .b, rightPort: .c, leftPower: 30, rightPower: 30)
} while ev3.measureUltrasonicCentimeters(on: .four) > 10
ev3.stopMove(leftPort: .b, rightPort: .c)

  • ワークブックがまちがっているので、正しくは「ev3.measureUltrasonicCentimeters(on: .four) < 10」としなければならないから
  • Swiftでは > が「〜以下」の意味になるから
  • whileのあとには「くり返す条件」を書くので、くり返すのは「10cm以下でない」とき、つまり「10より大きいとき」だから
  • Swiftでは、自動的に「大きい」「小さい」を判断してくれるので、実は > としても < としてもどちらの場合でも同じ結果になる
  • whileのあとには「絶対に起きない条件」を書くので、< でなくてもよい

正解

  • ワークブックがまちがっているので、正しくは「ev3.measureUltrasonicCentimeters(on: .four) < 10」としなければならないから
  • Swiftでは > が「〜以下」の意味になるから
  • whileのあとには「くり返す条件」を書くので、くり返すのは「10cm以下でない」とき、つまり「10より大きいとき」だから
  • Swiftでは、自動的に「大きい」「小さい」を判断してくれるので、実は > としても < としてもどちらの場合でも同じ結果になる
  • whileのあとには「絶対に起きない条件」を書くので、< でなくてもよい

解説

前回のおさらいだよ。whileはこれからも使うので、条件の書き方を覚えておいてね。

whileのあとに書く条件は「くり返す条件」だよ。だから、不等号の向きが逆になっているんだ。
それ以外の選択肢(せんたくし)はすべてまちがい。

EV3アプリとSwiftのちがいはいろいろあるから、少しずつちがいにもなれていってね。

Q2. ☆問題☆

次のうち、変数の作り方で正しくないものを選んでね。

  • var case:Float = 3
  • var hensu:String = “Hello”
  • var caseOfFalse:Float = 2
  • var zkai:String = “case”

正解

  • var case:Float = 3
  • var hensu:String = “Hello”
  • var caseOfFalse:Float = 2
  • var zkai:String = “case”

解説

ワークブックでは Float という「型」の変数しか作らなかったけど、IntやStringという型の変数を作ることもできるよ。
Intは整数(1とか2など、小数にならない数)、Stringは言葉(文字列というよ)を入れることができる型なんだ。
そして、実はStringという型に入れる値は ” ” でくくってあげないといけないんだ。

それでは、一見正しそうな「var case:Float = 3」は何がいけないんだろう?

あたりまえだけど、すでにある名前を別の名前として使うことはできないよ。
Vol.20で学んだように、「case」は switch – case – default という使い方をするものだったよね。
だから、そこで使われる case を変数の名前として使うことはできないんだ。
でも、caseOfFalse とすれば、ちがう名前として見てもらえるよ。また、「var zkai:String = “case”」が正しいのは、caseが名前ではなく、変数の値(変数の中身)として使われているからだ。

この講座では「変数の名前の付け方」は深くあつかわないけど、「このような名前をつけるとよい」というルールもあるんだ。興味があったら調べてみてね。

Q3. ☆問題☆

ミッション3でさいしょに作ったプログラムを次のように改造して、入力する文字をへらしてみたよ。このプログラムは、思ったとおりの動きをしてくれるかな?
ワークブックから改造したところは文字を太くしてあるから、ワークブックと見比べて考えてね。/p>

var kyori:Float = 100

kyori = ev3.measureUltrasonicCentimeters(on: .four)

repeat {
ev3.move(leftPort: .b, rightPort: .c, leftPower: 30, rightPower: 30)
} while kyori > 10
ev3.stopMove(leftPort: .b, rightPort: .c)

repeat {
ev3.move(leftPort: .b, rightPort: .c, leftPower: -30, rightPower: -30)
} while ev3.measureUltrasonicCentimeters(on: .four) < kyori
ev3.stopMove(leftPort: .b, rightPort: .c)

  • なんの問題もなく、思い通りに動く。
  • 思い通りに動くが、さいしょの「var kyori:Float = 100」を「var kyori:Float = 0」にしておくほうが正確に動く
  • 思い通りに動かない
  • 思い通りに動かないが、この場合は kyori < 10 とすれば正しく動く
  • 思い通りに動くときと動かないときがある

正解

  • なんの問題もなく、思い通りに動く。
  • 思い通りに動くが、さいしょの「var kyori:Float = 100」を「var kyori:Float = 0」にしておくほうが正確に動く
  • 思い通りに動かない
  • 思い通りに動かないが、この場合は kyori < 10 とすれば正しく動く
  • 思い通りに動くときと動かないときがある

解説

このプログラムでは kyori に超音波センサーの値を入れているし、ワークブックから変えた部分は「超音波センサーの値が10より大きい間は」の「超音波センサーの値が」だから、問題なさそうに思うかもしれないけど、正しく動かないよね。

だって、超音波センサーの値はスピードボットが動くと変わってしまう。
でも、kyoriの値は、最初に調べたものから変わらない。だから、このように変えてしまうと、スピードボットはずっと動き続けてしまうよ。