情報科学(3) データと計算(1) 情報の表現 事始め - 名前をつける • 区別する,識別する – 人名: 姓と名による二名法 • 姓の種類数 ⇒ 単調減少 – 日本:29万,中国:3,000,韓国:200 日本の名前の決め方 • 自由,いい加減 – 2005年生れ,人気上位(明治生命) • 翔,大翔,拓海,翔太,颯太,翼,海斗,輝,太陽,大和 • 陽菜,さくら,美咲,葵,美羽,美優,凛,七海,美月, 結衣 – 人名漢字 • 常用漢字のほかに287字 • 法制審議会の578字追加案(2004年6月) – 意見募集の反応により一部削除 – 最終的に488字追加(2004年9月) – アルファベット,アラビア数字はダメ 人名用漢字案で一部削除へ 法制審部会が検 討 法相の諮問機関、法制審議会人名用漢字部会は8日、インターネット で公表した578文字の人名用漢字追加案について「人名にはふさわしく ない」などとして一部の漢字を削除する方向で検討を始めた。 先月11日に追加案を公表した直後から8日までに法務省に寄せられ た1000通以上の意見のうち、「糞」「屍」「癌」などの文字について「不適 切ではないか」との意見が半数を超えたため。人名用漢字部会は23日 の会合で、意見の集計結果とともに削除方針について審議する予定。2 けた程度の漢字の削除が決まる可能性が高いとみられる。 これを受け同部会は追加案を正式決定し、法相に諮問。法務省は戸籍 法施行規則(省令)を改正する。今秋にも新たな漢字が名前に使えるよう になる。 同部会は今回の追加検討の際、「常用性があり、平易であること」を原 則にJIS漢字表から選定。漢字自体が持つ意味が人名にふさわしいか どうかについては「意味を検討し始めると各委員の意見が異なり、収拾 がつかなくなる」(関係者)として検討しなかった結果、「糞」などの漢字が 含まれることになった。(共同通信) [2004年7月9日] 自由すぎるために制約を付加 • 字画姓名判断 • その他無意味な迷信 キリスト教,ユダヤ教,イスラム教 文化圏 • 名前は聖人の名前の集合から選ぶのが基本 – フランスでは最近まで約500の名前の中から選 ぶことが法律的に義務づけられていた 命名規則 • 競走馬の命名規則 – – – – カタカナで9文字以内 既登録馬や抹消後5年以内の馬名と不一致 過去の有名な馬名と同一のものは不許可 馬名としてふさわしくないものは不許可 生物の学名 • リンネ式階層分類 – 界,門,綱,目,科,属,種 • 動物界脊椎動物門哺乳綱サル目ヒト上科ヒト属ホモ・ サピエンス種 • 学名: ラテン語二名法 – 属名: 名詞(頭文字は大文字) – 種小名: 形容詞(小文字) 内包と外延 • 名前付けの2つの流儀 – 日本式: 制約条件を与える – フランス式: 集合を明示する • 集合の定義 – 内包的(intensional): 集合の要素が満たすべき条件を 与える.例:ジャイアンツの選手 – 外延的(extensional): 集合の要素を具体的に並べ挙げ る.例:上原,阿部,高橋,… 名前付け 対象物の空間 名前の空間 人 空間の性質: 「対象」も「人名」もそれぞれの要素に ついて「等しい」と「等しくない」という判別述語関数 が定義されている. 人名 関数としての性質 • 単射 – 同じ名前を持つ人はいない • 全射 – どの名前にもその名前を持つ人がいる • ありえねぇ Ruby 文字列の印刷と入力 • 挨拶プログラム puts "Hello, I am a Ruby program." • 会話プログラム puts "Hello, I am a Ruby program." puts "What is your name?" name = gets.chop # 1行読んで改行を取り去る puts "How are you, " + name + "?" # + は文字列の場合,文字列を連接する Ruby 文字列の「等しい」と「等しくない」 "David" == "David" "駒場太郎" == "駒場太郎" name = "David" name == "David" name == "DAVID" name != "DAVID" 電話番号は名前か? • 名前は文字という記号で表現 – 文字には文化的な意味が付与されている • 符号(code): 特定の意味と結びつかない記 号 – モールス信号 – 電話番号では数字を符号として使用,数値に意 味はない • 実は記号そのものに意味の中立性,代替可 能性がある 符号化 シニフィエ シニフィアン たとえば,n個の符号 m桁でnm個の対象を表現 近さの構造 対象空間の中の近さは記号列の近さに反映される f -1(a) 加入電話の電話番号 記号 列 f -1(b) f 加入電話 10桁の数字列 a g -1(a) b g-1(a) 10進数表現 g 10進10桁で表せる自然数 階層構造 類似の階層構造 • 年月日 – 日本流 YYMMDD (実はISOの標準) – ヨーロッパ流 DDMMYY – アメリカ流 MMDDYY なおいずれも,年は本来4桁で2桁は省略形 • 住所 – 日本流: 都道府県,市町村,丁目,番地,号 – 欧米流: 番地,通り,市,州/郡など Ruby 写像の表現 • 配列: 自然数 → データ eto = ["子","丑","寅","卯","辰","巳", "午","未","申","酉","戌","亥"] eto[0] eto[5] eto[11] • ハッシュ: 任意のデータ → データ directory = {"総長" => "21000", "学部長" => "46001", "守衛" => "46666"} directory["総長"] directory["守衛"] これは復習 Ruby 使ってみよう eto = ["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"] print “生まれた年は(西暦)? ” # printは最後に改行がない year = gets.to_i # 数として読み込む puts "あなたの干支は" + eto[(year-1900)%12] + "です." # putsは最後に改行がつく 構造的な表現 • 名前の替わりに性質を列挙して対象を表現 – イチロー 「マリナーズの選手で守備はライトで打順は1番」 – 性質: 属性名と値の対の集合 – 申込書: 名前,住所,電話番号,… Ruby クラス 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 データベース • 属性名と値の組で表されたデータを大量に集 めたもの • オペラ作品のデータベース – [作品名:椿姫;作曲者:ヴェルディ;初演1853; 言語:イタリア語;構成:3幕] • 属性にデータの型が対応 – 文字列,整数,… 表形式 • 属性が共通で順序を固定 作品名 作曲者 初演 言語 構成 椿姫 ヴェルディ 1853 イタリア語 3幕 カルメン ビゼー 1875 フランス語 4幕 オテロ ヴェルディ 1887 イタリア語 4幕 タンホイザー ワグナー 1845 ドイツ語 3幕 フィガロの結婚 モーツァルト 1786 イタリア語 4幕 フィデリオ ベートーヴェン 1805 ドイツ語 2幕 Ruby 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として,以下を実行する イテレータ px 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" Ruby Rubyのメソッドによる関数定義 ObjectというRuby世界の中の大親分に対するメソッド として定義するとどこでも使える関数となる def diagonals(n) (n-3)*n/2 end print "The number of diagonals of ", 8, "-polygon is ", diagnals(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“ # 関数の呼出し Ruby 論理計算 • n%2==0 – nが2で割り切れるときtrue,割り切れないとき false • (y%4 == 0) && (y%100 != 0) || (y%400 == 0) – yが4で割り切れかつ100で割り切れないか,yが 400で割り切れるときtrue,そうでなければfalse Ruby # チョーハン n = ARGV[0].to_i if n%2==0 puts "チョー" else puts "ハン" end 条件分岐 # 閏年 y = ARGV[0].to_i if (y%4 == 0) && (y%100 != 0) || (y%400 == 0) puts "Leap year." else puts "Common year." 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 分岐の複合 # 閏年 梯子型分岐 year = ARGV[0].to_i if year%400==0 puts "Leap year." elsif year%100==0 puts "Common year." elsif year%4==0 puts "Leap year." else puts "Common year." end Ruby if 梯子型 then else if then else if then else 森型 if if then then else if then if else then else else Ruby 梯子型の別の例 論語 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 Ruby # 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 Ruby 関数の関数 cube = lambda {|x| x**3} # 関数定義 def double(x,p) # 関数pを引数としてもらう関数 p.call(p.call(x)) end puts double(2,cube) #=> 512 関数の合成 f g Ruby 関数の合成の例 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 Ruby 関数を値として返してもよい 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 構造のあるデータにおける計算 • 有理数 – 約分,負数,逆数,四則演算,表示を定義 • 複素数 – 負数,逆数,四則演算,表示を定義 • その他書いてみた例 – 預金口座 – じゃんけん – トランプのカードの強さ 変数と代入 • 変数: 記憶域の場所を指す名前 x 3 y 5 name hanako • 代入: 変数の指す場所に値をしまう操作 – 形式 変数名=式 x=3 y = x+2 name = "hanako" 代入の意味 • 等号 = を使うが数学的等式ではない – 左辺(変数名)と右辺(式)は対称ではない – 左辺の変数は記憶場所を指し,右辺の式の中の 変数は記憶場所にしまわれた値を指す x = x+1 – 順序によって結果が変わる [A] x=2 x = x+1 y=x [B] x=2 y=x x = x+1 x 2 4 3 2 y 3 2 オブジェクト • オブジェクト: 意味的なまとまりのあるデータの単位 – 単純なもの: 整数,文字列など – 複雑なもの: 有理数,スタック,リストなど • メソッド: オブジェクトに対して可能な操作 – 整数に対する加算,文字列に対する置換 – スタックに対するpush, pop • クラス: 同じ種類のオブジェクトを総称したもの – クラスからここのオブジェクトが生成される – オブジェクトに適用可能なメソッドはクラスで定まる Ruby 変数とオブジェクト • あらゆるオブジェクトは変数に代入できる BaseballPlayer はクラス class BaseballPlayer attr_accessor :team, :position, :bat_order def initialize(t,p,bo) @team = t これ これも @position = p 変数 も変 数 @bat_order = bo オブジェクト end の生成 end ichiro = BaseballPlayer.new("Mariners", "right field", 1) ichiro は変数 変数の有効範囲 • 局所変数: 宣言された場所の含まれる範囲内での み有効 – 範囲: • 通常はメソッド定義の初めから終わり • より小さい単位はブロック • より大きい単位はクラス/モジュール定義の初めから終わり • インスタンス変数: 1つのオブジェクト内で有効 – Rubyでは変数名の語頭に@をおく規約 • クラス変数:1つのクラス内で有効 – Rubyでは変数名の語頭に@@をおく規約 • 大域変数: プログラム全体で有効 – Rubyでは変数名の語頭に$をおく規約 状態 • 変数にどんな値(オブジェクト)がしまわれているかは プログラム実行中に変化 • 変数と値の結びつき全体を状態という – 状態は時間で変化 • 状態のレベル – メソッドの状態: 局所変数が現在持つ値 – オブジェクトの状態: インスタンス変数が現在持つ値 – プログラムの状態: 大域変数が現在持つ値 より短い時間間隔ではオブジェクトの状態の総体 関数の世界と状態の世界 • 関数は入力と出力の数学的な関係を表す → 状態(時間変化)はない • 関数の計算をプログラムのメソッドとして実現する場 合,計算の途中に状態変化が起こりうる • また,計算の前後でオブジェクトの状態が一般に異 なることがある(副作用) • 逆にオブジェクトの状態変化は,一般に,変数に関 数の出力やそれを含む式を代入してもたらされる
© Copyright 2024 ExpyDoc