10/25 データと計算(1)


前回までの補足

スライドに使われたプログラム

文字列の印刷と入力

puts "Hello, I am a Ruby program."
puts "What is your name?"
name = gets.chop # 1行読んで改行を取り去る
puts "How are you, " + name + "?" # + は文字列の場合,文字列を連接する

文字列の「等しい」と「等しくない」

"David" == "David"
"駒場太郎" == "駒場太郎"
name = "David"
name == "David"
name == "DAVID"
name != "DAVID"

写像の表現

eto = ["子","丑","寅","卯","辰","巳",
       "午","未","申","酉","戌","亥"]
eto[0]
eto[5]
eto[11]

directory = {"総長" => "21000", "学部長" => "46001", 
             "守衛" => "46666"}
directory["総長"]
directory["守衛"]

使ってみよう

eto = ["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
print "生まれた年は(西暦)?" # printは最後に改行がない
year = gets.to_i # 数として読み込む
puts "あなたの干支は" + eto[(year-1900)%12] + "です."
# putsは最後に改行がつく

クラス

class BaseballPlayer
  attr_accessor :team, :position, :bat_order
  # こうしておくと,いちいちteamとかpositionとかのメソッドを定義しなくていい
  def initialize(t,p,bo) 
    @team = t
    @position = p
    @bat_order = bo
  end
end

ichiro = BaseballPlayer.new("Mariners", "right field", 1)
puts "Ichiro's team is " + ichiro.team
puts "Ichiro's position is " + ichiro.position
puts "Ichiro's batting order is %d"%ichiro.bat_order

表形式

class Opera
   attr_accessor :title, :composer, :year, :language, :acts
   def initialize(*x)# *のついた(最後の)変数は残った引数の列を配列として受け取る
      @title, @composer, @year, @language, @acts = x #  便利な書き方ができる
   end
end
operas = Array.new(6)
operas[0] = Opera.new("椿姫", "ヴェルディ", 1853, "イタリア語", "3幕")
operas[1] = Opera.new("カルメン", "ビゼー", 1875, "フランス語", "4幕")
operas[2] = Opera.new("オテロ", "ヴェルディ", 1887, "イタリア語", "4幕")
operas[3] = Opera.new("タンホイザー", "ワグナー", 1845, "ドイツ語", "3幕")
operas[4] = Opera.new("フィガロの結婚", "モーツァルト", 1786, "イタリア語", "4幕")
operas[5] = Opera.new("フィデリオ", "ベートーヴェン", 1805, "ドイツ語", "2幕")
operas.each do |x| # operasのそれぞれをxとして,以下を実行する イテレータ
    p x
end
operas.each do |x| #  “\t”, “\n“ はそれぞれタブ,改行
    print x.title, "\t", x.composer, "\t", x.year, "\t",
            x.language, "\t", x.acts, "\n"
end

整数計算

ruby コマンド用
# n角形の対角線の数を求める
# 入力:n,出力:対角線の数 を与える関数
n = ARGV[0].to_i
  # ARGVはコマンドラインの引数の文字列の配列
  # to_iは文字列を数に変換する
d = (n-3)*n/2;
print "The number of diagonals of ", n,
        "-polygon is ", d, ".¥n"
irb コマンド用
# n角形の対角線の数を求める
# 入力:n,出力:対角線の数 を与える関数
n = gets.to_i
  # to_iは文字列を数に変換する
d = (n-3)*n/2;
print "The number of diagonals of ", n,
        "-polygon is ", d, ".¥n"

Rubyのメソッドによる関数定義

def diagonals(n)
    (n-3)*n/2
end
print "The number of diagonals of ", 8,
        "-polygon is ", diagonals(8), ".¥n"

実数計算

rubyコマンド用
# 摂氏温度を華氏に変換
tC = ARGV[0].to_f # 浮動小数点数へ変換
tF = 1.8*tC + 32.0
print "摂氏 ", tC, " 度は,華氏 ",  tF, " 度です.¥n"

# BMIの計算
def bmi(height, weight)               # 関数定義
    weight/height**2
end
puts "あなたの身長(m)は?"; h = gets.to_f 
puts "あなたの体重(kg)は?"; w = gets.to_f
print "あなたのBMIは", bmi(h,w), "です¥n"   # 関数の呼出し
irbコマンド用
# 摂氏温度を華氏に変換
tC = gets.to_f # 浮動小数点数へ変換
tF = 1.8*tC + 32.0
print "摂氏 ", tC, " 度は,華氏 ",  tF, " 度です.¥n"

# BMIの計算
def bmi(height, weight)               # 関数定義
    weight/height**2
end
puts "あなたの身長(m)は?"; h = gets.to_f 
puts "あなたの体重(kg)は?"; w = gets.to_f
print "あなたのBMIは", bmi(h,w), "です¥n"   # 関数の呼出し

条件分岐

rubyコマンド用
# チョーハン
n = ARGV[0].to_i
if n%2==0
  puts "チョー"
else
  puts "ハン"
end
irbコマンド用
# チョーハン
n = gets.to_i
if n%2==0
  puts "チョー"
else
  puts "ハン"
end

分岐の複合

rubyコマンド用
# 閏年 森型分岐
year = ARGV[0].to_i
if year%100==0
  if year%400==0
    puts "Leap year."
  else
    puts "Common year."
  end   
else
  if year%4==0
    puts "Leap year."
  else
    puts "Common year."
  end
end
irbコマンド用
# 閏年 森型分岐
year = gets.to_i
if year%100==0
  if year%400==0
    puts "Leap year."
  else
    puts "Common year."
  end   
else
  if year%4==0
    puts "Leap year."
  else
    puts "Common year."
  end
end

梯子型の別の例 論語

puts "何歳ですか?"
   age = gets.to_i
if age < 15
   puts "無"
elsif age < 30
   puts "志于學"
elsif age < 40
   puts "立"
elsif age < 50
   puts "不惑"
elsif age < 60
   puts "知天命"
elsif age < 70
   puts "耳順"
else
   puts "從心所欲、不踰矩"
end

応用

# BMI判定
puts "あなたの身長(m)は?"
height = gets.to_f
puts "あなたの体重(kg)は?"
weight = gets.to_f
bmi = weight/height**2
print "あなたのBMIは", bmi,
        "です.¥n"
if bmi >= 26.4
  puts "太りすぎです."
elsif bmi >= 24.0
  puts "太り気味です."
else
  puts "問題ありません."
end

# 星座
Zodiac = ["山羊座", "水瓶座", "魚座",
               "牡羊座", "牡牛座", "双子座",
               "蟹座", "獅子座", "乙女座",
               "天秤座", "蠍座", "射手座"]
StartDay = [21,19,21,21,22,22,23,23,24,24,23,22]
print "生まれた月は? "; month = gets.to_i
print "生まれた日は? "; day = gets.to_i
print "あなたの星座は"
if day < StartDay[month-1]
   print Zodiac[month-1], "です.\n"
else
   print Zodiac[month%12], "です.\n"
end

関数の関数

cube = lambda {|x| x**3}    # 関数定義
def double(x,p)  # 関数pを引数としてもらう関数
    p.call(p.call(x))
end
puts double(2,cube) #=> 512

関数の合成の例

def compose(x,f,g)
    g.call(f.call(x))
end
cube = lambda {|x| x**3}
down = lambda {|x| x-1}
puts compose(4,cube,down)   #=>63

関数を値として返してもよい

def compose(f,g)
    lambda {|x| g.call(f.call(x))}
end
cube = lambda {|x| x**3}
down = lambda {|x| x-1}
puts compose(cube,down).call(4)   #=>63

今日の課題