情報基礎A 「Cプログラミング」総合演習

このページでは、プログラミングにとりかかる前のいくつかの準備と、ウォーミングアップを行う。

プログラミングのための準備

時系列データの入手

電力データ

東北電力のサイトの、過去実績データのダウンロードの中から、 各年度の「実績データ(CSV形式)」をダウンロードし、この課題用のディレクトリ(フォルダ)に保存する。 課題で用いるデータファイルは

とする(選択した課題によっては、使わないデータもある)。

「支援プログラム」の利用

支援プログラムのダウンロード

ダウンロードしたCSVデータをプログラムで読み取ったり、時間と日付の換算、等々、いくつかの面倒な処理を 簡単化するために、課題の作成を支援するための「支援プラグラム」を用意した。 ここを右クリックして「別名でリンク先を保存」すると、 tsa-helper.cというファイルがダウンロードできる。先ほどのCSVファイルと合わせ、作業用のディレクトリに

tsa-helper.c   juyo_2010_tohoku.csv   juyo_2011_tohoku.csv   juyo_2012_tohoku.csv

のファイルがあることを、まず確認しておく。

プログラムをコンパイルする際には
cc 何々.c -lm

なお、この「支援プログラム」の内部で数学関数(sqrt()など)を使用しているため、以下の予行演習や課題プログラム をコンパイルする際には、必ず-lmオプションを付けること。

予行練習1:時系列の表示
#include <stdio.h>
#include <math.h>
#include "tsa-helper.c"

main()
{
  int n,i ;
  float data[10000] ;

  n = read_csv("juyo_2010_tohoku.csv",data) ;
  for (i=0 ; i<n ; i=i+1) {
     printf("%d %f\n",i,data[i]) ;
  }
}

このプログラムは、CSVファイル"juyo_2010_tohoku.csv"を読み込んで、その中から各時刻の電力量 を自動的に切り出し、float型の配列(上の例ではdata)に1時間毎の電力量の値をセットする。 配列の添え字は、元旦深夜0時を起点とした経過時間に対応する。 次いで、この関数は、その配列データの内容を、画面に表示し、 読み込んだデータ点(時系列の長さ)を戻り値として返す。 つまり、この例では、変数nにデータ点の数(全部で何時間分のデータか)がセットされる。

read_csv("何々",data)の働きによって、配列の内容が、上の例では、data[0]が元旦0時〜1時、 data[1]が元旦1時〜2時まで、・・・、data[n-1]が大晦日23時〜24時までの電力量の値(万kWH)、 に設定される、というわけだ。

ここで、read_csv("ファイル名", 配列名)の箇所が、 「支援プログラム」によって提供された機能。 「支援プログラム」を使う場合には、プログラムの先頭部分に、必ず

#include "tsa-helper.c"

と書いておくこと。

予行演習2:時系列の表示(その2)
#include <stdio.h>
#include <math.h>
#include "tsa-helper.c"

main()
{
  int n,i ;
  float data[10000] ;

  n = read_csv("juyo_2010_tohoku.csv",data) ;
  for (i=0 ; i<n ; i=i+1) {
     print_date_plus_hour(2010,1,1,i) ; 
     printf(" %f\n",data[i]) ;
  }
}

動作は「予行演習1」のプログラムと同じだが、支援プログラムのprint_date_plus_hour()関数を使って、 元旦からの経過時間数の代わりに、「日時」で表示するようにした例。

予行演習3:電力の積算
#include <stdio.h>
#include <math.h>
#include "tsa-helper.c"

main()
{
  int n,i ;
  float data[10000],total ;
  total=0 ;
  n = read_csv("juyo_2010_tohoku.csv",data) ;
  for (i=0 ; i<n ; i=i+1) {
     total = total + data[i] ;
  }
  printf("年間総電力量= %f [万kWH]\n",total) ;
}

for文を使った「総和」計算によって、年間の(正確には、データ末尾までの)電力量を積算し、表示するプログラム。 シンプルなプログラムなので、動作の詳細について、説明の必要は無いだろう。

支援プログラムの機能や使い方については、こちらのページにまとめておいたので参照のこと。

時系列を可視化する

GNUPLOT関連情報:

gnuplot homepage
gnuplot tips
gnuplotの初歩

プログラムで処理した時系列データを、グラフを使って可視化する方法を知っておくと、プログラムの動作チェックや データの分析などに大変有用だ。そんな用途に使える定番ソフトのひとつとして、 無料で高機能なgnuplotが良く知られている。 ここでは、このgnuplotを使い方を簡単に紹介しておこう。

「予行演習1」のプログラムをコンパイルした後、実行する際に

a.out > tsdata.txt

Windowsのコマンドプロンプトでも同様の操作が可能

のようにすると、元々画面に出力される時系列のデータを、ファイルtsdata.txtに書き込むことができる。 このように ">ファイル名" によってデータの保存先(行き先)を切り替えることを「リダイレクト(redirect)する」と呼ぶ。 リダイレクトは、Linux環境でデータをファイルに保存する最も簡単な方法だ。

保存されたそのファイルの中身は、

0 1003.000000
1 998.000000
2 993.000000
3 985.000000
4 968.000000
5 949.000000
6 924.000000
...

といった具合に、経過時間と電力量がペアになって並んでいる。 ここで、経過時間を横軸、電力量を縦軸としたグラフをプロットするには、「端末」上で以下のようにgnuplotを起動し、操作をすれば良い:

[xxxxx] $ gnuplot <enter>
	G N U P L O T
	Version 4.X ....
	Build System: Darwin i386

	Copyright (C) 1986-1993, 1998, 2004, 2007-2012
	Thomas Williams, Colin Kelley and many others...
	
Terminal type set to 'x11'
gnuplot> plot "tsdata.txt" using 1:2 with lines <enter>

「端末」(コンソール)からgnuplotを起動するためのコマンドは

gnuplot <enter>

ファイルのデータをX-Yプロットするには、gnuplotのプロンプトが出ている状態で

gnuplot>  plot "ファイル名" using 1:2 with lines <enter>

とタイプする。using 1:2は、1カラム目をX座標、2カラム目をY座標に指定するための指示。 with linesは折れ線グラフ表示の指定。

gnuplotを終了するには

gnuplot>  quit <enter>

実際に2010年の電力量時系列をプロットした例を以下に示す:

elec-supply-2010

gnuplotの機能や詳しい使い方については、ウェブ上に沢山の情報源があるので、是非そちらも参考に。 Windows上で動作するgnuplotも簡単に入手できるので、これを機に、実験のレポート作成などに役立てるとよいだろう。