たとえば以下のようなシラバスに基づく科目情報を考える。
表1: 履修科目データの例
| 科目名 | 基礎プログラミング |
|---|---|
| 科目コード | 154 |
| 担当教員 | 鳥海三輔 |
| 開講時期 | 前期 |
| 概要 | プログラミングを通じて問題解決能力を向上を図る。 本講ではRubyを用い,データ処理の構造と考え方の基礎を学ぶ。 |
| 科目名 | 応用プログラミング |
| 科目コード | 254 |
| 担当教員 | 飯森大和 |
| 開講時期 | 後期 |
| 概要 | 問題解決を通じてプログラミング能力向上を図る。 本講ではプログラミング言語Cを通じて,問題解決に最適なアルゴリズムを 適用する方策を学ぶ。 |
| 科目名 | 応用もっけ論 |
| 科目コード | 39 |
| 担当教員 | 酒田育造 |
| 開講時期 | 前期 |
| 概要 | 山形県庄内地方でよく使われる「もっけ」には様々な意味があり, 他の地域にもこのような多様性を持つ言葉がある。 その成立ちをふまえて正しくその地域の「もっけ」を理解し, 深い交流のきっかけとする。 |
以下同様の項目が多数続く…
このように,形式が同じものが多数あるようなデータを設計し, 検索できるデータベースを作成する過程を示す。
参照されることを前提とした情報は,整理した形で格納する必要がある。 表1のような科目情報がその一例で, 分類された項目に対する値が並んでいる。これを格納するには, ハッシュに情報を格納するときの キー(key)と値(value)の関係がふさわしい。
たとえば,上記の科目の1つは以下のようなハッシュで表現できる。
リスト1: 1科目分のハッシュ表現
kamoku0 = {
"科目名" => "基礎プログラミング",
"科目コード" => "154",
"担当教員" => "鳥海三輔",
"開講時期" => "前期",
"概要" => "プログラミングを通じて問題解決能力を向上を図る。
本講ではRubyを用い,データ処理の構造と考え方の基礎を学ぶ。"
}
この形式が複数集まったものがデータの集合となる。 つまり,キーと値の組み合わせが一定量集まったものがさらに「値」となり, その複合的な「値」を複数集める, という繰り返しによってデータベースができ上がる。
「キーと値」の組み合わせの集合が複合的な「値」となる
| (複合的な)値の集合 | |||||||||||||||||||||||||
|
1科目分の情報は1つのハッシュで表せる。そのハッシュ全体がさらに「値」 となり,それを複数集めることで科目データベースができ上がる。 ハッシュで表現した1科目分の「値」をどのように集めるかについて考察する。
リスト1のように書けば, 1科目分の情報が表現できる。しかし,これはRubyの表記であり, Rubyを知らない人には複雑だし,Rubyに慣れていたとしても入力に手間がかかる。 より入力の楽な書式で書かれたものをハッシュに変換するのが人間にとって 効率的なプログラムとなる。
ここでは,以下のような書式をキーと値に分解してハッシュ化するものを考える。
科目名: 基礎プログラミング 科目コード: 154 担当教員: 鳥海三輔 開講時期: 前期 概要: プログラミングを通じて問題解決能力を向上を図る。本講ではRubyを用い,データ処理の構造と考え方の基礎を学ぶ。
この例のように,行の先頭に「キー:」があり, 空白で区切った後にそれに対応する「値」が来るものとする。 また,一連の項目並びでは必ず「科目名:」が最初に来るものとする。 上記のようなテキストファイルを1行ずつ読み, 「科目名:」という行が来たら新規のハッシュを生成して以後のキーと値を 格納するプログラムは以下のようになる。
while line = gets
if /^科目名:\s*(.*)/ =~ line # 行頭「科目名:」空白(任意文字列)
data = Hash.new
data["科目名"] = $1
elsif /^(\S+):\s*(.*)/ =~ line # 行頭(非空白続き):空白(任意文字列)
data[$1] = $2
end
end
ただしこの例では,1科目分の科目情報のハッシュ化しか行なえない。
実際のデータファイルは以下のように複数科目をまとめたものになるであろう。
科目名: 基礎プログラミング 科目コード: 154 担当教員: 鳥海三輔 開講時期: 前期 概要: プログラミングを通じて問題解決能力を向上を図る。本講ではRubyを用い,データ処理の構造と考え方の基礎を学ぶ。 科目名: 応用プログラミング 科目コード: 254 担当教員: 飯森大和 開講時期: 後期 概要: 問題解決を通じてプログラミング能力向上を図る。 本講ではプログラミング言語Cを通じて,問題解決に最適なアルゴリズムを 適用する方策を学ぶ。
以下で,科目ごとのハッシュを複数集めてデータベースとする方法について 2つのやり方を示す。
複数の値を保持する目的には配列が使える。
| [0] | [1] | [2] | …………… | ||||||||||||||||||
|
|
|
……… |
syllabus.txt を読み取りつつ, 構築した科目ごとのハッシュを配列に追加していくプログラムは以下のようになる。
#!/usr/bin/env ruby
# coding: utf-8
db = []
count = -1 # 登録処理中の配列の要素番号
open("syllabus.txt", "r") do |df|
while line = df.gets
if /^科目名:\s*(.*)/ =~ line # 行頭「科目名:」空白(任意文字列)
count += 1
db[count] = Hash.new
db[count]["科目名"] = $1
elsif /^(\S+):\s*(.*)/ =~ line # 行頭(非空白続き):空白(任意文字列)
db[count][$1] = $2
end
end
end
p db # 結果確認用
上記の例はハッシュの集合という「値」を,配列に格納し データの個数を数えつつ整数の添字で管理した。次は科目ごとのデータを ハッシュで管理する。
ハッシュの場合は, 科目ごとのデータの「値」を結びつける「キー」が必要となる。 キーは,すべての科目で唯一に決まるものを必ず使用する。 一般的なデータベースでは一揃のデータに固有となるID番号を振って管理する。 今回の例では「科目コード」がそれに当たるが, 同一科目名がないことが保証できれば科目名を「キー」として利用してもよい。
科目名をキーとして科目ごとのデータをハッシュに格納する。 そのためのプログラムは以下のようになる。
#!/usr/bin/env ruby
# coding: utf-8
db = {}
open("syllabus.txt", "r") do |df|
while line = df.gets
if /^科目名:\s*(.*)/ =~ line # 行頭「科目名:」空白(任意文字列)
key = $1
db[key] = Hash.new
elsif /^(\S+):\s*(.*)/ =~ line # 行頭(非空白続き):空白(任意文字列)
db[key][$1] = $2
end
end
end
p db # 結果確認用
以上のように,
の2点を決めることで,実世界で利用する情報をプログラムで処理可能な形式に 取り込むことができる。上記の例では,1科目分の情報をハッシュとして格納し, さらにそれをまとめる形式として配列あるいはハッシュを利用する2つを示した。 どちらを用いるかはプログラムの作りやすさで判断してよい。
次項から続く処理の例では,後者の方法,つまり科目ごとの情報のハッシュを さらにハッシュで格納する方法を利用する。