Ruby」カテゴリーアーカイブ

paizaLvアップ問題と解答(標準出力3)Ruby

※スキルチェック問題ではありません。
規約により公式の解答コードそのままはよろしくないので、
オリジナルのコードにしています。

詳しくはコチラ

なるべくわかりやすい解説を付けました。

問題1 2 つの数値を出力 (paizaランク D 相当)

2 つの 1 を半角スペース区切りで出力してください。

入力される値
入力はありません。

入力値最終行の末尾に改行が1つ入ります。
文字列は標準入力から渡されます。

期待する出力
答えの数値を 1 行で出力してください。

1 1

末尾に改行を入れ、余計な文字、空行を含んではいけません。

条件
なし

解答 文字列+空白と文字列を足す

puts "1 " + "1"

または  配列を作成してから.joinで半角スペースを間に挟んでつなぎあわせる

puts [1,1].join(' ')

問題2 3 つの数値を出力 (paizaランク D 相当)

3 つの数値 8, 1, 3 を半角スペース区切りで出力してください。

入力される値
入力はありません。

入力値最終行の末尾に改行が1つ入ります。
文字列は標準入力から渡されます。

期待する出力
答えの数値を 1 行で出力してください。

8 1 3

末尾に改行を入れ、余計な文字、空行を含んではいけません。

条件
なし

解答

puts "8 " + "1 " + "3"

または

puts [8,1,3].join(' ')

または

print [8,1,3].join(' ')

問題3 10 個の数値を出力 (末尾に半角スペース有) (paizaランク D 相当)

1 から 10 までの数値をすべて、出力してください。
ただし、数値の後には必ず半角スペースを出力してください。

入力される値
入力はありません。

入力値最終行の末尾に改行が1つ入ります。
文字列は標準入力から渡されます。

期待する出力
答えの数値を 1 行で出力してください。

1 2 3 4 5 6 7 8 9 10

末尾に改行を入れ、余計な文字、空行を含んではいけません。

条件
なし

解答 %Wで配列を作成して半角スペースを間に挟んで結合して、出力する

puts %W[1 2 3 4 5 6 7 8 9 10 ].join(' ')

または 1から10までの配列を作成して、半角スペースを間に挟んで結合して、出力する

puts [*1..10 ].join(' ')

paizaLvアップ問題と解答(標準出力1)Ruby

※スキルチェック問題ではありません。
規約により公式の解答コードそのままはよろしくないので、
オリジナルのコードにしています。

詳しくはコチラ

なるべくわかりやすい解説を付けました。

問題1 1 行で整数 813 を出力してください。

入力される値
ありません。

入力値最終行の末尾に改行が1つ入ります。
文字列は標準入力から渡されます。

期待する出力
整数 813 を出力してください。また、出力の末尾には改行を入れてください。

813

 

条件
 なし

解答

puts 813

または

p 813

問題2 2 行の出力 (paizaランク D 相当)

整数 8 と 13 をこの順番で出力してください。
また、整数 8 を出力した後と 13 を出力した後に改行をしてください。

入力される値
ありません。

入力値最終行の末尾に改行が1つ入ります。
文字列は標準入力から渡されます。

期待する出力
答えの数値を 2 行で出力してください。また、出力の末尾には改行を入れてください。

8
13

 

条件
なし

解答

puts 8
puts 13

問題3 3 行の出力 (paizaランク D 相当)

整数 8, 1, 3 をこの順に改行区切りで出力してください。

入力される値

ありません。

入力値最終行の末尾に改行が1つ入ります。
文字列は標準入力から渡されます。

期待する出力
答えの数値を 3 行で出力してください。また、出力の末尾には改行を入れてください。

8
1
3

 

条件
なし

解答

puts 8
puts 1
puts 3

または  %wで文字列からなる配列を作成して、出力する

puts %w[8 1 3]

またはコチラ

puts %w(8 1 3)

paizaLvアップ問題と解答(標準入力3)Ruby

※スキルチェック問題ではありません。
規約により公式の解答コードそのままはよろしくないので、
オリジナルのコードにしています。

詳しくはコチラ

なるべくわかりやすい解説を付けました。

問題7   1行目で与えられる N 個の整数の入力 (large)

1 行目で、整数 N と、続けて N 個の整数 a_1, … , a_N が半角スペース区切りで与えられます。a_1, … , a_N を改行区切りで出力してください。

入力例1
5 8 1 3 1 3
出力例1
8
1
3
1
3

解答  .shiftで最初の配列を取り除いた後に出力

a = gets.split
a.shift
puts a

問題8 1 行目で与えられる N 個の実数の入力 (large)

1 行目で、整数 N と、続けて N 個の実数 a_1, … , a_N が半角スペース区切りで与えられます。a_1, … , a_N を改行区切りでそのまま出力してください。

入力例1
5 8.13 81.3 813 0.813 1.381
出力例1
8.13
81.3
813
0.813
1.381

解答 問題7とほぼ同じだが小数点なので.to_fで入力を受け取る。問題7と同じ答えでもOK

a = gets.split.map(&:to_f)
a.shift
puts a

問題9 行ごとに要素数の異なる整数列の入力

1 行目に整数 N が与えられます。
2 行目から (N + 1) 行目までの先頭に整数 M_i (1 ≦ i ≦ N) が与えられます。
それに続いて M_i 個の整数 a_1, …, a_{M_i} が与えられます。
上から i 番目、左から j 番目の整数は a_{i,j} です。
N 行の a_1, …, a_M をそのまま出力してください。

入力例1
3
1 8
2 8 1
3 8 1 3
出力例1
8
8 1
8 1 3

解答

  1. 入力Nを受け取る
  2. N回繰り返す
  3. 2行目,3行目,4行目の入力を受け取りaに代入
  4. 配列の最初の要素を出力したくないので、.shiftで0番目(初め)の配列を取り出す。
  5. .shiftは破壊的なので、配列の0番目が抜けた配列を.join(‘ ‘)でくっつける時に半角スペースを間に挿入する
n = gets.to_i

n.times do
  a = gets.split.map(&:to_i)
  m = a.shift
    puts a.join(' ')
end

Rubyまとめex(標準入力)

Rubyで標準入力から値を受け取る方法 2022年版

はじめに

この記事は、プログラミング問題などでよく見られる、標準入力から値を受け取る方法をまとめたものです。

前提

使用する言語はRubyです。

一行に1要素のとき(文字列)

標準入力

Ruby

標準入力を受け取るコード

string = gets

出力するコード

p string

出力結果

"Ruby"

一行に半角スペース刻みで要素があるとき(文字列)

標準入力

Ruby PHP Python

標準入力を受け取るコード

strings = gets.split

出力するコード

p strings

出力結果

["Ruby", "PHP", "Python"]

splitを使用することで、3つの要素をそれぞれ別のものとして配列に格納しています。

※splitの使い方
split(‘ ‘)としている記事などもありますが、
半角スペース刻みの入力値の場合は引数(‘ ‘)を指定しなくても問題ありません。

つまりsplit(‘ ‘) ≒ split (※半角スペース刻みの入力値のときのみです)

複数行に一つずつ要素が存在するとき(文字列)

標準入力

Ruby
PHP
Python

標準入力を受け取るコード

strings = readlines.map(&:chomp)
#またはこちら(パフォーマンス的に推奨)
strings = readlines(chomp: true)

出力するコード

p strings

出力結果

["Ruby", "PHP", "Python"]

複数行に半角スペース付きで要素が複数存在するとき(文字列)

標準入力

Ruby PHP Python
Java C# C++

標準入力を受け取るコード

strings = readlines.map{ |i| i.split.map(&:chomp)}
# またはこちら(推奨)
strings = readlines.map(&:split)

出力するコード

p strings

出力結果

[["Ruby", "PHP", "Python"], ["Java", "C#", "C++"]]

標準入力

Ruby PHP Python
Java C# C++

入力値が数値の場合

一行に数値がひとつのとき

標準入力

123

標準入力を受け取るコード

number = gets.to_i

出力するコード

p number

出力結果

123

一行に半角スペース刻みで数値があるとき

標準入力

1 2 3

標準入力を受け取るコード

numbers = gets.split.map(&:to_i)

出力するコード

p numbers

出力結果

[1, 2, 3]

複数行に一つずつ数値が存在するとき

標準入力

1
2
3

標準入力を受け取るコード

numbers = readlines.map(&:to_i)

出力するコード

p numbers

出力結果

[1, 2, 3]

複数行に半角スペース刻みで要素が存在するとき

標準入力

1 2 3
4 5 6

標準入力を受け取るコード

numbers = readlines.map{ |i| i.split.map(&:to_i) }

出力するコード

p numbers

出力結果

[[1, 2, 3], [4, 5, 6]]

FizzBuzz問題(Ruby)

FizzBuzz問題の復習をば

問題

整数 N が入力として与えられます。
1からNまでの整数を1から順に表示してください。
ただし、表示しようとしている数値が、
・3の倍数かつ5の倍数のときには、”Fizz Buzz”
・3の倍数のときには、”Fizz”
・5の倍数のときには、”Buzz”

を数値の代わりに表示してください。

入力例
18
出力例2
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
Fizz Buzz
16
17
Fizz

※ポイント

1.繰り返しを使う
2.繰り返しは基本0から始まってしまう
3.if文で各値を振り分けてあげる
4.0のとき判定がFizuBuzzと出力されてしまう
5.それをどうするか考える。

解答 範囲を使う場合(for inを使う)範囲オブジェクトの範囲分同じ処理を繰り返したり、配列の要素を順番に取得したい場合に使用するので

# Nを受け取る
n = gets.to_i
#範囲を作成する。(1から初めたいので)
m = (1..n)
for num in m do
  if num % 15 == 0
    puts "Fizz Buzz"
  elsif num % 3 == 0
    puts "Fizz"
  elsif num % 5 == 0
    puts "Buzz"
  else puts num
  end
end
puts

 

別解 uptoを使う場合(こっちのほうがいいかも)

# Nを受け取る
n = gets.to_i

1.upto(n) do |i|
  if (i % 15).zero?
    puts 'Fizz Buzz'
  elsif (i % 3).zero?
    puts 'Fizz'
  elsif (i % 5).zero?
    puts 'Buzz'
  else
    puts i
  end
end
puts

別解2 eachを使う場合

# Nを受け取る(例:18)
n = gets.to_i
#範囲を作成する。(1から初めたいので)(中身1..18)
m = (1..n)
#eachで1から18まで18回繰り返してもろて各値をif文で振り分ける
m.each do |m|
  if m % 15 == 0 
    puts "Fizz Buzz"
  elsif m % 3 == 0 
    puts "Fizz" 
  elsif m % 5 == 0 
    puts "Buzz" 
  else puts m 
  end
end

Rubyのまとめ6(プロテクテッドメソッド、モジュール、メソッドの公開範囲)

5から続く

プロテクテッドメソッド

class User

attr_reder :name 
  def initialize(name, deposit)
      @name = name
      @deposit = deposit
  end

  def bigger_than?(person)
      person.deposit < @deposit
  end
  protected

  def deposit
    @deposit
  end
end
  
suzutuki = User.new('suzutuki', 50000)
kunugi = User.new('kunugi', 30000)

suzutuki.bigger_than?(kunugi)
kunugi.bigger_than?(suzutuki) 
#.rbで出力すると
true
false

#クラスの外では呼び出せないよ
suzutuki.deposit
NoMethodError:

モジュール

クラスのようにメソッドや定数をまとめられるが
インスタンスが作れない、継承ができない
関連するメソッドや定数などをまとめてグループ化したいだけの時に、
手軽に使える。

module モジュール名
  #モジュールの定義 (メソッドや、定数など)
end
module Driver
  
  def self.run
    puts 'Run'
  end

  def self.stop
    puts 'Stop'
  end
end

Driver.run
Driver.stop
#.rbで出力すると
Run
Stop
# driver = Driver.new         #インスタンス生成できない
#   module TaxiDriver < Driver  #継承できない
# end
モジュールはインスタンス化できないのでself.でやる

 

module SampleNumber
  NUMBER = 300

  def number
    NUMBER
  end
end

puts SampleNumber::NUMBER
include SampleNumber
puts number
puts NUMBER

#.rbで出力すると
300
300
300

inncludeすることで定数をどちらでも呼び出せるようになる
module SampleModule

  def sum(a,b)
    a + b
  end

  module_function :sum
end

puts SampleModule.sum(4, 7)
ruby.module0.rbで出力
11
module SampleModule

  def sum(a,b)
    a + b
  end
end

class Port
  include SampleModule

  def call_sum(a, b)
    sum(a+ b)
  end
end

port = Port.new
puts port.sum(4, 7)
puts port.call_sum(8, 7)
#.rbで出力すると
11
15

include "モジュール名" でモジュールに定義されたメソッドを呼び出せる

例外と例外処理

puts '数値を入力してください'
i = gets.to_i
begin
#例外が起きうる処理
  puts 10 / i
  puts "begin's end"
  rescue => ex
#例外が発生した場合の処理
  puts 'error!'
  puts ex.message
  puts ex.class
  ensure
# 例外が発生しても、しなくても、最後に実行したい処理
  puts '終わり'
end
#.rbで出力すると
数値を入力してください
0
error!
divided by 0
ZeroDivisionError
終わり

puts “begin’s end”はエラー時は無視される
#実務ではよく使うので特に重要

例:2
[1] pry(main)> begin
[1] pry(main)* val = 10/ 0
[1] pry(main)* puts val
[1] pry(main)* rescue => e 
[1] pry(main)* p e.full_message
[1] pry(main)* p e.message
[1] pry(main)* p e.class
[1] pry(main)* end 

 1: from (pry):2:in `__pry__'\n(pry)
:2:in `/': \e[1mdivided by 0 (\e[4;1mZeroDivisionError\e[m\e[1m)\n\e[m""divided by 0"
ZeroDivisionError
=> ZeroDivisionError

メソッドの公開範囲

・public
誰からも見える
・protected
あまりつかわれない
・private
自分からしかみえない

class User

  def initialize(name)
    @name = name
  end

private
  def hello
    puts "Hello! I am #{@name}."
  end
end

suzutuki = User.new('suzutuki')
suzutuki.hello

#.rbで出力すると
Traceback (most recent call last):
access.rb:14:in `<main>': private method `hello' called for #<User:0x00000000010c4260 @name="suzutuki"> (NoMethodError)
suzutuki:~/environment/ruby_projects $ ruby access.rb

privateによってエラーが出る
privateをコメントアウトなどすると問題ない
Hello! I am suzutuki.
class User

  def initialize(name)
    @name = name
  end

  def say
     hello
  end

  private
    def hello
      puts "Hello! I am #{@name}."
    end
end

suzutuki = User.new('suzutuki')
suzutuki.say

def say hello endにより
#.rbで出力すると
Hello! I am suzutuki.
↑が出力されたので呼び出すことができた

バリデーションなどで使うので覚えておこう!

Rubyのまとめ5(クラスから継承まで)

4から続きます

クラス

オリジナルのクラスを作成する例:箱を定義するクラス
Boxクラス
メソッド hello ・・・ helloと出力する機能

class Box
  def hello
    puts 'hello'
  end
end

box = Box.new
box.hello

hello
class Box
  def initialize(name)
    puts 'initialize'
    @name = name 
  #インスタンス変数はインスタンス内であればどこでも使える
  #↑逆にこれは他では使えない
 end   

  def hello
    puts "Hello! I am #{@name}."
  end 
end

box = Box.new('Cardboard')
box.hello

wood = Box.new('wood')
wood.hello

#.rbで出力すると
initialize
Hello! I am wood.

更にインスタンスを追加することもできる

class Box
  def initialize(name)
    puts 'initialize'
  @name = name
end
  def hello
    puts "Hello! I am #{@name}."
  end
end

box = Box.new('Cardboard')
box.hello
wood = Box.new('wood')
wood.hello

#.rbで出力すると
initialize
Hello! I am Cardboard.
initialize
Hello! I am wood.

アクセサメソッド:インスタンス変数の値を読み書きするメソッドのこと

class Box
  def initialize(name)
    @name = name
  end
  def hello
    puts "Hello! I am #{@name}."
  end

  def name
    @name
  end
end

box = Box.new('Cardboard')
puts box.name

#.rbで出力すると
initialize
hello! I am Cardboard.
Cardboard

クラスの外からnameメソッドでインスタンス変数を呼び出した

インスタンス変数の@nameの値をクラスの外から書き換えたい

class Box
  def initialize(name)
    @name = name
  end
  def hello
    puts "Hello! I am #{@name}."
  end

  def name
   @name
  end
end
box = Box.new('Cardboard')
puts box.name
#.rbで出力すると
Cardboard
box.@name = 'suzutuki'
↑Syntax error インスタンス変数は外から書き換えられない

ではどうするか?書き込み用のメソッドを作る

class Box
  def initialize(name)
    # puts 'initialize'
  @name = name
  end
  def hello
    puts "Hello! I am #{@name}."
  end

#他の言語だとゲッターメソッド
  def name
    @name
  end
#他の言語だとセッターメソッド
  def name=(value) #←ここから
    @name = value
  end
end

box = Box.new('Cardboard')
# box.hello
puts box.name
box.name = 'suzutuki'
puts box.name

#.rbで出力すると
Cardboard
suzutuki

name=のように=で終わるメソッドを定義すると
変数に代入するような形でメソッドが呼び出される。
box.name = 'suzutuki'という書き方ができるようになる
メソッドを呼び出しているけれども
値('suzutuki')を代入するような書き方ができる。

インスタンス変数を読み書きするメソッドのことを
インスタンスメソッドと呼ぶ
設定を書き換えたいとき

アクセサメソッドattr_accessorメソッド
attrはattributeで属性のこと
インスタンスメソッドを開発者が書かなくて良くなる

class Box

attr_accessor :name
  def initialize(name)
    puts 'initialize'
    @name = name
  end
  def hello
    puts "Hello! I am #{@name}."
  end

# def name
#   @name
# end

# def name=(a)
#   @name = a
# end
end

box = Box.new('Cardboard')

puts box.name

box.name = 'suzutuki'
puts box.name

↓ruby accessor.rbで出力
Cardboard
suzutuki

class Box
  attr_accessor :name
end

box = Box.new
puts box.name
box.name = 'suzutuki'
puts box.name

#.rbで出力すると

suzutuki
※空欄はnilで初期引数を指定しないとなる

コメントアウトしているところを1行で書くことができる
定型文的なメソッドを毎回書かなくて良いので開発を効率化できる

読み込みのみしたいとき

class Box

attr_reader :name
  def initialize(name)
    @name = name
  end
  def hello
    puts "Hello! I am #{@name}."
  end

# def name
#   @name
# end

# def name=(a)
#   @name = a
# end
end

box = Box.new('Cardboard')
# box.hello
puts box.name
# box.name = 'suzutuki'書き込みをしようとするとエラーになる
puts box.name

↓ruby accessor.rb
Cardboard
Cardboard

↑書き込みがされてないので2回Cardboardが出力された
なお書き込もうとするとエラーが出る↓
accessor.rb:26:in `<main>': undefined method `name=' for #<Box:0x00000000021c7df0 @name="Cardboard"> (NoMethodError)
Did you mean? name

書き込みのみしたいとき

class Box

attr_writer :name
  def initialize(name)
    @name = name
  end
  def hello
    puts "Hello! I am #{@name}."
  end

# def name
#   @name
# end

# def name=(a)
#   @name = a
# end
end

box = Box.new('Cardboard')
# box.hello
# puts box.name
box.name = 'suzutuki'
# puts box.name

#.rbで出力すると
何も起きてないように見えるが書き込みはされている。表示はされない

クラス変数:クラス自体に値を保持できる変数

class Box

@@count = 0
  def initialize(name)
    @name = name
    @@count += 1
  end

  def hello
    puts "Hello! I am #{@name}. #{@@count} instance(s)."
  end
end

kit = Box.new('Cardboard')
kit.hello

wood = Box.new('wood')
wood.hello

suzutuki = Box.new('suzutuki')
suzutuki.hello

#.rbで出力すると
Hello! I am Cardboard. 1 instance(s).
Hello! I am wood. 2 instance(s).
Hello! I am suzutuki. 3 instance(s).

クラスメソッドinfoを定義、クラスメソッドinfoを実行すると
インスタンスの生成回数(@@count)を出力する

class Box

@@count = 0
  def initialize(name)
    @name = name
    @@count += 1
  end

  def hello
    puts "Hello! I am #{@name}. #{@@count} instance(s)."
  end

  def self.info
    puts "#{@@count} instance(s)."
  end
end

Box.info
#.rbで出力すると
0 instance(s).

↑インスタンスの生成が行われていないので0
class Box
  
@@count = 0
  def initialize(name)
    @name = name
    @@count += 1
  end
  
  def hello
    puts "Hello! I am #{@name}. #{@@count} instance(s)."
  end

  def self.info
    puts "#{@@count} instance(s)."
  end
end

kit = Box.new('Cardboard')
Box.info

wood = Box.new('wood')
Box.info

suzutuki = Box.new('suzutuki')
Box.info

#.rbで出力すると
1 instance(s)
2 instance(s)
3 instance(s)

一つのクラス変数@@countをそれぞれのインスタンスが共通して
利用していることがわかる

class FF
  def self.first_method
    puts '1'
  end

  class << self
    def second_method
     puts '2'
    end
    
    def third_method
      puts '3'
    end
   end
end

FF.first_method
FF.second_method
FF.third_method

#.rbで出力すると
'1'
'2'
'3'

FF.new.varだとエラー
オブジェクトからクラスメソッドを呼び出そうとしてもエラーになる

 

クラスと定数

class Box
REGION = 'USA'
@@count = 0
  def initialize(name)
    @name = name
    @@count += 1
  end

  def hello
    puts "Hello! I am #{@name}. #{@@count} instance(s)."
  end
  
  def self.info
    puts "#{@@count} instance(s). Region: #{REGION}"
  end
end

kit = Box.new('Cardboard')
Box.info

wood = Box.new('wood')
Box.info

suzutuki = Box.new('suzutuki')
Box.info

puts Box::REGION
クラスの外から呼び出せる

#.rbで出力すると
1 instance(s). Region: USA
2 instance(s). Region: USA
3 instance(s). Region: USA
↓putsがあるので4番目のUSAも出力されている。ないと3行まで
USA

クラスの継承

親クラスを作成することで親クラスの機能を引き継いで、
子クラスを作成することができる。
コードの再利用性や拡張性を高める仕組み

#親クラスのUserを作る
class User
  def initialize(name)
    @name = name
  end
  
  def hello
    puts "Hello! I am #{@name}"
  end
end

akina = User.new('akina')
akina.hello
#.rbで出力すると
Hello! I am akina
class AdminUser < User
#子クラスまたはサブクラスを作った
  def hello_admin
    puts "Hello! I am #{@name} from AdminUser."
  end
end
suzutuki = AdminUser.new('suzutuki')
suzutuki.hello
suzutuki.hello_admin

#.rbで出力すると
Hello! I am akina
Hello! I am suzutuki
Hello! I am suzutuki from AdminUser.

 

class User
  def initialize(name)
    @name = name
  end

  def hello
    puts "Hello! I am #{@name}"
  end
end

#子クラスまたはサブクラスを作った
class AdminUser < User
  def hello_admin
    puts "Hello! I am #{@name} from AdminUser."
  end
#↓helloメソッドをAdminUserの方でオーバーライドする
  def hello
    puts 'Admin!!'
  end
end

suzutuki = AdminUser.new('suzutuki')
suzutuki.hello
suzutuki.hello_admin

#.rbで出力すると
Admin!!
Hello! I am suzutuki from AdminUser.

親クラスから小クラスのメソッドは呼び出せないのに注意!

子クラスを編集することにより親クラスに変更を加えることなく
子クラスに機能を追加したり上書き(オーバーライド)することができる!

class User
 def initialize(name)
   @name = name
 end
 def hello
   puts "Hello! I am #{@name}"
 end
end

class AdminUser < User
 def hello_admin
   puts "Hello! I am #{@name} from AdminUser."
 end
 #↓helloメソッドをAdminUserの方でオーバーライドする
 def hello
   super
   puts 'Admin!!'
 end
end

suzutuki = AdminUser.new('suzutuki')
suzutuki.hello
akane = AdminUser.new('akane')
akane.hello

#.rbで出力すると

Hello! I am suzutuki
Admin!!
Hello! I am akane
Admin!!

親クラスのUserクラスのhelloも呼び出されている!

Integerの継承関係から継承関係を見ることができる

BasicObject
↑
Object
↑
Numeric
↑
Integer
#superclassで親クラスを知ることができる
Integer.superclass
=> Numeric
2.5.1 :002 > Numeric.superclass
=> Object
2.5.1 :003 > Object.superclass
=> BasicObject
2.5.1 :004 > BasicObject.superclass
=> nil

6に続く

Rubyのまとめ4(繰り返しからnext, whileまで)

3から続く

繰り返し処理 Each for

配列やハッシュ.each do |変数|
  #繰り返し実行したい処理
end

例1

#1:配列 numbersを作成(1,2,3,4,5)
numbers = [1, 2, 3, 4, 5]
#2:配列の要素を一つずつ取り出して実行
numbers.each do |number|
  puts number
end

別解1
numbers.each {|number|
  puts number
}
#一行でもかける
numbers.each {|number| puts number }

↑配列が入っている要素は複数形||の中の変数は
単数で書くことが多いらしい

配列 colors を作成
‘red’, ’green’ ’blue’

配列の要素を一つずつ取り出して出力

colors = ['red', 'green', 'blue']

colors.each do |color|
    puts color
end

red
green
blue
=> ["red", "green", "blue"]
#繰返処理 for構文

for 変数 in 配列やハッシュ do
 #繰り返し実行したい処理
end

1:配列 numbersを作成(1,2,3,4,5)
2:配列の要素を一つずつ取り出して実行

numbers = [1, 2, 3, 4, 5]

for number in numbers do
  puts number
end

forは原則使わないらしい

each (ハッシュ利用)

1:ハッシュで生徒ごとの点数scoresを用意
{luke: 100, ben: 90, alan: 70 }
配列の要素を一つずつ取り出して出力

scores = {luke: 100, ben: 90, alan: 70}

scores.each do |k, v|
  puts v
end

#出力されるもの
100
90
70

両方取り出したいとき↓

scores = {luke: 100, ben: 90, alan: 70}

scores.each do |k, v|
  puts "#{k}, #{v}"
end

#出力されるもの
luke, 100
ben, 90
alan, 70

80点以上を取り出したいとき↓ifをeachに追加

scores = {luke: 100, ben: 90, alan: 70}

scores.each do |k, v|
  if v >= 80
    puts "#{k}, #{v}"
  end
end

luke, 100
ben, 90

繰り返し処理 times

繰り返し回数.times do |i|
  繰り返し実行したい処理
end
|i|は省略可能
5.times do
  puts 'Hello'
end

Hello
Hello
Hello
Hello
Hello

ダブルクオートで囲んだとき

5.times do |i|
  puts "#{i}: Hello"
end

0: Hello
1: Hello
2: Hello
3: Hello
4: Hello

上も下も同じ意味
5.times { |i| puts "#{i}: Hello" }

繰り返し処理(while)

while 条件式 do
  繰り返し実行したい処理
end

数字を0から9まで、10個出力するプログラム。whileを使って書く

i = 0

while i < 10
  puts "#{i}:hello"
    i += 1 #i = i + 1
end
#出力されるもの
0:hello
1:hello
2:hello
3:hello
4:hello
5:hello
6:hello
7:hello
8:hello
9:hello

無限ループが起きることがあるので気をつけよう

uptoとdownto

開始値.upto(終了値){繰り返し実行したい処理}

10.upto(14) {|n| puts n }
14.downto(10) {|n| puts n }


10
11
12
13
14

14
13
12
11
10

繰り返し処理step

開始式.step(上限値,一度に増減する大きさ){}

1.step(10, 2) { |n| puts n }

1
3
5
7
9
減らすときはマイナスで
10.step(1, -2) { |n| puts n }

10
8
6
4
2

繰り返し処理(loop)

loop do
 繰り返し実行したい処理
end

loopメソッドを使って、変数の値を0から1ずつ増やして出力

i = 0

loop do
  puts i
  i += 1
 #breakがないと無限ループに突入するので注意!
  break if i == 10 
end
0
1
2
3
4
5
6
7
8
9

whileの場合

n = 0

while true
 puts ncf
 n += 1
end

応用)配列[1,2,3,4,5,]の値が、奇数の場合のみ、画面に出力する処理。

eachとnextを利用

numbers = [1, 2, 3, 4, 5]

numbers.each do |n|
 next if n % 2 == 0 
#もしnが偶数だったらループをスキップするという意味

#上と下は同じ意味だで
next if n.even?

#奇数の時はodd
next if n.odd? 
  puts n
end

#出力されるもの
1
3
5

5に続きます。

Rubyのまとめ3(配列からハッシュDate,Timeまで)

2から続く

配列(Array)

複数のデータをまとめて格納できるオブジェクトのこと

配列内のデータ(要素)は順番に並んでいて添字(インデックス)
を指定することでデータを取り出せる

配列の作成

空の配列を作る[]

3つの要素が格納された配列を作る
[要素1,要素2,要素3]

arr = []
=> []
arr
=> []

a = [1, 2, 3, 'aa', [1, 2, 3]]
=> [1, 2, 3, "aa", [1, 2, 3]]
2.5.1 :006 > a[0]
=> 1
2.5.1 :007 > a[1]
=> 2
2.5.1 :008 > puts a
1
2
3
aa
1
2
3
=> nil

小文字のwはシングルクォートとおなじで
%w(a b)
=> ["a", "b"]
大文字のWはダブルクォートとおなじで式展開できる
a = 1
=> 1
b = 2
=> 2

%W(あ#{a} い#{b})
=> ["あ1", "い2"]

シンボルに変換もできる
%i[ a b c ]
=> [:a, :b, :c]

繰り返し処理をする時
%w[a b c].each do |abc|
   puts abc
 end 
a
b
c
=> ["a", "b", "c"]

breakは指定したものまで繰り返す
%w[a b c].each do |abc|
   break if abc == 'c'
   puts abc
 end 
a
b
=> nil

nextは指定したものをスキップする
%w[a b c].each do |abc|
    next if abc == 'b' 
      puts abc 
    end 
a
c
=> ["a", "b", "c"]

mapを使って配列内に()を付加
%w[a b c].map { |abc| "(#{abc})" }
=> ["(a)", "(b)", "(c)"]

aは空か?(.empty)

a.empty?
=> false
2.5.1 :010 > b = []
=> []
2.5.1 :011 > b.empty?
=> true

変数aに’aa’はふくまれている?(.include)

2.5.1 :012 > a.include?('aa')
=> true
2.5.1 :013 > a.include?('b')
=> false
a = [[1, 2, 3], "aa", 3, 2, 1]
2.5.1 :014 > a.reverse
=> [[1, 2, 3], "aa", 3, 2, 1]
2.5.1 :015 > a
=> [1, 2, 3, "aa", [1, 2, 3]]
2.5.1 :016 > a.reverse!
=> [[1, 2, 3], "aa", 3, 2, 1]
2.5.1 :017 > a
=> [[1, 2, 3], "aa", 3, 2, 1]

配列をランダムにする(.shuffle)

2.5.1 :018 > a.shuffle
=> [3, 2, "aa", 1, [1, 2, 3]]

(0..25).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
2.5.1 :026 > (0..99).to_a.shuffle!
=> [96, 92, 23, 49, 27, 60, 20, 72, 8,
50, 70, 64, 41, 75, 88, 26, 82, 14, 6,
78, 10, 55, 74, 48, 17, 52, 24, 16, 95,
63, 36, 19, 91, 93, 57, 85, 56, 67, 2,
15, 89, 44, 31, 43, 98, 3, 38, 28, 12,
86, 35, 65, 83, 94, 47, 0, 81, 4, 62,
77, 84, 13, 90, 33, 45, 21, 99, 39, 22,
71, 46, 61, 66, 87, 25, 30, 29, 34, 51,
73, 68, 18, 69, 37, 80, 11, 7, 9, 58, 5,
53, 42, 1, 40, 79, 59, 32, 54, 76, 97]

配列に新しく入れる(.push)(<<)

z = (0..10).to_a

=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

2.5.1 :028 > z << 20

=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20]

2.5.1 :029 > z

=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20]

2.5.1 :030 > z.push(30)

=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30]

2.5.1 :031 > z

=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30]

配列の最後を取り出す(.pop)

2.5.1 :032 > z.pop
=> 30
2.5.1 :033 > z
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20]

最初の配列を取り出す(.shift)

z.shift
=> 0
z
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20]

2.5.1 :038 > z << 3

=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 3]

2.5.1 :039 > z << 6

=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 3, 6]

重複したものがなくなり一つにまとまる(.uniq)

2.5.1 :040 > z.uniq
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20]
2.5.1 :041 > z
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 3, 6]
2.5.1 :042 > z.uniq!
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20]
2.5.1 :043 > z
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20]

配列の文字列を結合する(.join)並び替える(.sort)

s = ['my' 'name' 'is' 'suzutuki']

s

=> ["my", "name", "is", "suzutuki"]

2.5.1 :048 > s.join

=> "mynameissuzutuki"

2.5.1 :049 > s.join(' ')

=> "my name is suzutuki"

2.5.1 :050 > s.join('_')

=> "my_name_is_suzutuki"

s.sort.reverse

=> ["suzutuki", "name", "my", "is"]

2.5.1 :053 > s.sort.reverse!

=> ["suzutuki", "name", "my", "is"]

2.5.1 :054 > s

=> ["my", "name", "is", "suzutuki"]
↓配列の数がわかる
s.size
=> 4

シンボル

ソースコード上では文字列のように見えるが内部では整数として扱われる。

シンボルを使った形の方が文字列をきれいに使う場合に比べて、ハッシュのアクセスは速いとされる

オブジェクトIDを確認すると、String オブジェクト で は 同じ 文字列であっても別のオブジェクトが生成されるのに対してシンボルでは同じシンボル名であれば同一のシンボルを指している。

ハッシュとは?

キー(key)と値(Value)の組み合わせでデータを管理するオブジェクト

連想配列、ディクショナリー、マップと言う場合も

ハッシュの作成

空のハッシュを作成{}(中かっこと読む)

キーと値の組み合わせを3つ格納するハッシュを作成

{キー1 => 値1, キー2 => 値2, キー3 => 値3 }

suzutuki = {'name' => 'suzutuki', 'birthplace' => 'Gihu'}

=> {"name"=>"suzutuki", "birthplace"=>"Gihu"}

2.5.1 :058 > puts suzutuki['name']

suzutuki
=> nil

2.5.1 :059 > puts suzutuki['birthplace']

Gihu
=> nil

2.5.1 :060 > suzutuki['age'] = 18
=> 18

2.5.1 :061 > puts suzutuki
{"name"=>"suzutuki", "birthplace"=>"Gihu", "age"=>18}
=> nil

↓ageを20に変更したいとき
suzutuki['age'] = 20
=> 20

2.5.1 :063 > puts suzutuki
{"name"=>"suzutuki", "birthplace"=>"Gihu", "age"=>20}
=> nil

suzutuki.delete('age')
=> 20

puts suzutuki
{"name"=>"suzutuki", "birthplace"=>"Gihu"}
=> nil
ota = {name: 'ota', birthplace: 'tokyo'}
=> {:name=>"ota", :birthplace=>"tokyo"}
2.5.1 :067 > puts ota[:name]
ota
=> nil
2.5.1 :068 > ota[:age] = 20
=> 20
2.5.1 :070 > ota[:age] = 21
=> 21
2.5.1 :072 > puts ota
{:name=>"ota", :birthplace=>"tokyo", :age=>21}
=> nil
2.5.1 :073 > ota.delete(:age)
=> 21
puts ota
{:name=>"ota", :birthplace=>"tokyo"}
=> nil

キーの確認.keys

ota.keys
=> [:name, :birthplace]

値の確認.values

2.5.1 :075 > ota.values
=> ["ota", "tokyo"]
2.5.1 :076 > ota.has_key?(:name)
=> true
2.5.1 :077 > ota.has_key?(:address)
=> false
2.5.1 :078 > ota.size
=> 2

Time,Dateオブジェクト

 Time.now
=> 2021-010-02 12:06:55 +0900
[6] pry(main)> Time.now.zone
=> "JST"
[7] pry(main)> datetime = Time.new(2021, 10, 2, 12, 45)
=> 2021-01-02 12:45:00 +0900
[8] pry(main)> datetime.strftime('%Y年 %m月 %d日 %H時 %M分')
=> "2021年 10月 02日 12時 45分"

いきなりDateクラスは使えない
[9] pry(main)> Date
NameError: uninitialized constant Date
Did you mean? Data
from (pry):12:in `__pry__'
requireをすることで使えるようになる
[10] pry(main)> require 'date'
=> true
[11] pry(main)> Date
=> Date
Date.today
=> #<Date: 2021-01-02 ((2459317j,0s,0n),+0s,2299161j)>
[15] pry(main)> Date.new(2021, 10, 2)
=> #<Date: 2021-01-02 ((2459217j,0s,0n),+0s,2299161j)>

[17] pry(main)> Date.new(2021, 10, 2).strftime('%Y年 %m月 %d日 %H時 %M分')
=> "2021年 10月 02日 00時 00分"

4に続く

Rubyのまとめ2(真偽値からFizzBuzzまで)

1から続く

真偽値と論理演算子(&&||)

真(true)となる例

trueそのもの すべての数値1,0,−1
すべての文字列’abc’ ’true’ ’false’

論理積(and)

・a && b
aとbがともに真の場合に真

論理和(or)

a||b
aかbの少なくとも1つが真の場合に真

and, or, not
↑↓似ているがand, or, notは、&&, ||, !,と比べて優先順位が低い
&&, ||, !

基本的には混在させない

t1 = true
=> true

t2 = true
=> true

fi = false
=> false

1 = false
=> false

f2 = false
=> false

t1 && t2
=> true

t1 and t2
=> true

t1 && f1
=> false

t1 and f2
=> false

t1 || t2
=> true

t1 or t2
=> true

t1 || f2
=> true

t1 or f2
=> true

f1 || f2
=> false

!t1
=> false

not(t1)
=> false

!f1
=> true

not(f1)
=> true

優先順位で変わってしまうため

!t1 || t1
=> true

↓ ||が先に処理されtrueだったものがnotで反転した
not t1 || t1
=> false

↓&&が先に処理されfalseになり||でtrueになった
t1 || t2 && f1
=> true

andは最後なのでfalse
t1 or t2 and f1
=> false

そんなときはカッコを使って明示的に優先順位を指定しよう!

(t1 || t2) && f1
=> false

条件分岐if

if 条件式1
条件式1が真の時に実行する処理
elsif 条件式2
条件式1が偽で条件式2が真の時に実行する処理
elsif 条件式3
条件式1及び条件式2が偽で条件式3が真の時に実行する処理
else
全ての条件式が偽の時に実行する処理
end

例1:テストの結果によって通知表の成績をコンソールに出力する

# 90点以上A
# 80点以上B
# 60点以上C
# 60点未満D

score = 90
  if score >= 90
    puts 'A'
  elsif score >= 80
    puts 'B'
  elsif score >= 60
    puts 'C'
  else
    puts 'D'
  end

Aが出力される

例2:商品の内容を出力

その他 : ‘Not found’

product = 'fish'
  if product == 'meat'
    puts 'meat'
  elsif product == 'fish'
    puts 'fish'
  elsif product == 'vegetable'
    puts 'vegetable'
  else
    puts 'Not found'
end

fishが出力される

==でないとエラーが生じる

応用) 入場料金の計算

大人18歳以上10,000円
中人6歳以上18歳未満5,000円
小人6歳未満1,000円

age = 19
  if age >= 18
    puts '10,000'
  elsif age >= 6
    puts '5000'
  else puts '1,000'
end

unless 条件式
条件式が偽(false)の時に実行する処理
end

例3: 変数nの値が0でなければ、”Not zero.”
と出力するプログラムをifをつかって記述
※ヒント:値が0か判定するには、zero?メソッドが使える

# n = 0
# if !n.zero?
# puts ‘Not zero.’
# end

# unlessを使おう

n = 0
  unless n.zero?
    puts 'Not zero.'
    puts 'This is zero'
end

This is zeroが出力される。
※無理にunlessを使う必要はない。読みやすいと思う場合はifでOK

Case文

case 対象オブジェクト
when 値1
値1と一致する場合に行う処理
when 値2
値2と一致する場合に行う処理
when 値3
値3と一致する場合に行う処理
else
どの値にも一致しない場合に行う処理
end

例4:商品の内容を出力

if文だと

product = 'fish'
  if product == 'meat'
    puts 'meat'
  elsif product == 'fish'
    puts 'fish'
  elsif product == 'vegetable'
    puts 'vegetable'
  else
    puts 'Not found'
end

#case文の場合

product = 'tuna' 
  case product
    when 'pork'
      puts 'meat'
    when 'tuna'
      puts 'fish'
    when 'tomato'
      puts 'vegetabale'
    else
    puts 'Not Found'
end

fishが出力される。

caseのほうがよりシンプルになるがifとの違いに注意!

メソッドとは?

複数の処理を1つにまとめて扱いやすくしたもの
・クラス内に定義する≒クラス内に定義する関数

def メソッド名(引数1, 引数2, …)
実行する処理
実行する処理
end

例4:Hello,World!と出力するメソッドを記述

メソッドを実行する。メソッド名は、hello_worldとする

def hello_world
  puts 'Hello,World!'
end

hello_world

‘Hello,World!’が出力される
続きを読む