条件の処理がうまくいかない

解決済

回答 5

投稿

  • 評価
  • クリップ 1
  • VIEW 476

KentaTsujino

score 7

前提・実現したいこと

はじめまして、Kentaと申します。
case,when のコマンドを練習するためにプログラムを組んでみたのですが、うまく処理されずに困っています。

発生している問題・エラーメッセージ

カウンターのようなものを作ってみました
プログラム自体は動作していて、エラーメッセージは出ていません。
条件文で、変数が他方の変数より小さいときの処理をつくっているのですが、この部分が処理されません。

該当のソースコード

Ruby

puts 'カウンター'
puts '何度数えますか?'
n = gets.to_i
a = 0
while true
case a 
when a<n ###この部分がスキップされてしまいます
puts'数える?(1)数えない?(0)'
input = gets.to_i
case input
when 0
puts '初めに戻ります'
when 1
puts '数えます'
sleep 1
a += 1
puts '現在'
print a
print '/'
puts n       
end
when a=n ###ここが常に出てきます。
sleep 1
puts '完了!'
exit
end
end

試したこと

いくつかの数字を代入してみましたが、どの場合も when a=n の処理だけ行われました。
初学者なりにコードを見直してみましたが、いまいちどこが悪かったのかわかりません。
お力をお貸ししていただけますと幸いです。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

+2

挙動は知りませんが、
case whenって比較演算子(<とか=とか)使えましたっけ?
case whenの仕様を見直してみましょう。

-追記------------------------------------------------------

a=5
case
 when a < 4
  p "4"
 when a < 7
  p "7" #=>7が表示される
 when a < 10
  p "10"
end


出来るんですね、勉強になりました。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/01 13:53

    簡潔な回答ありがとうございました、無事解決できそうです!

    キャンセル

checkベストアンサー

+1

whena < nのような一致でない条件判断を入れる場合、case aではなくcaseとだけしてください。caseだけの場合、whenの中で最初にtrue相当となったものが条件を満たします(るりま)。

もっとも、ふつうにif - elsif - elseなどを使ったほうがわかりやすいかもしれません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/01 13:56

    Caseの使い方に加えてほかのメソッドまで提案していただいてとても参考になりました。ありがとうございました!

    キャンセル

+1

case a 
when a<n ###この部分がスキップされてしまいます
  ...
end

ここはaa<nと同じであれば処理されます。((a < n) === a #=> false)
常にfalseが返ってくるので絶対に実行されません。
ちょっと言語化が難しいですが「aa < nである時」とは異なります。(a=0 < n=1 #=> true)

when a=n ###ここが常に出てきます。

また(a = n) === aは2回目以降は常にtrueです。

case文をあまり理解できていないように見受けられます。
今回の場合はcase文ではなくif文を使ったほうがいいでしょう。

puts 'カウンター'
puts '何度数えますか?'
n = gets.to_i
a = 0
while true
  if a < n
    puts'数える?(1)数えない?(0)'
    input = gets.to_i

    case input
    when 0
      puts '初めに戻ります'
    when 1
      puts '数えます'
      sleep 1
      a += 1
      puts "現在 #{a}/#{n}"
    end

  elsif a == n
    sleep 1
    puts '完了!'
    exit
  end
end

他にも 何度数えますか? でマイナスの値を入力すると無限ループしますし
数えるか数えないかの入力値が 0か1 以外だった場合の処理もないので
今後その辺りの処理も考えてみると良さそうです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/01 15:08

    詳しい解説ありがとうございました!
    現在の自分の知識ではいまいち理解が追いつきませんでしたが、これから理解できるように頑張ります。

    キャンセル

  • 2019/02/01 15:12

    a=n というのは、a==n の書き誤りでは?
    a=nは比較じゃなくて代入ですよ。

    キャンセル

  • 2019/02/01 15:18

    when a=n になっていた部分ですね。
    > when a=n ###ここが常に出てきます。

    混乱してましたがまとまりました。
    if (a = n) === a
    の比較になるので、やはり最初の比較でnの値がaに代入されて
    次回からは同じ値同士の比較になっています。

    キャンセル

+1

case a <=> n

とすると、 when 1, when 0, when -1 で処理分岐ができます。

それをつかって書いてみました。
想定外の入力があった場合 (a に負値や数字以外を指定するなど) にもある程度対応してみています。

puts 'カウンター'
puts '何度数えますか?'
n = gets.to_i

a = 0
while true
  case a <=> n
  when -1
    puts '数える?(1), 数えない?(0)'
    input = gets.to_i
    case input
    when 0
      puts '初めに戻ります'
    else
      puts '数えます'
      a += 1
    end
  when 0, 1
    puts '完了!'
    break
  end
  puts "現在 #{a}/#{n}"
end

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

case a で頑張りたいのなら、when a < n を when ->(x) { x < n } に書き換える方法も考えられます。まあ、今回の場合、お勧めではありませんが。

when 節に Proc オブジェクトを持ってくると、case 節にある a を引数にして Proc オブジェクトが実行されます。

上記のように書き換えた場合、実行されるのは ->(x) { x < n }.call(a) で、実質的には、a < n と同じです。

そして、true が返ると、お目当ての puts'数える?(1)数えない?(0)' が実行されて、目的達成となります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる