情報理学入門の講義案

情報理学入門(プログラミングを教える科目)のTAをしているのですが・・・

  • 進行が遅い!
    • 私がプログラミングの経験者という事を差し引いても遅い
    • for文に2時間もかけるな!
    • 学生みんなダレてる
  • 授業内容がまずい
    • ニュートン法など教えてもしょうがない
    • それより先にファイル出入力の方法を教えるべき
    • それよりさらに先に「インデントする」って事を教えるべき
  • C++を教えてはいけない
    • C++は難しすぎる
    • "Hello World"を書くだけで「おまじない」が幾つ必要なのか
    • ポインタで大部分が脱落する事必至


というわけで、TAで教官が話している隙に、
こういう授業をするべきじゃないか、という事を書いてみます。

  • 学生は理系だがコンピュータを研究対象としない学科を前提とする
  • ツールとしてのプログラミングを教える
  • 視覚的な要素を取り入れる(目に見える物を操作する方が、感覚が掴みやすい)
  • C++に比べ易しい、Pythonを使う
  • 第1回をHello World!で終わらせない
  • 「完璧な説明」はしない。細かい点は本を見ればよい

Pythonによる情報理学入門 第1回 gnuplotを使う

第1回はPythongnuplotを組み合わせてグラフを表示してみます。

は第0回に既にすんでいるとします.

gnuplotの紹介

gnuplot(ニュープロット)はグラフを描くためのソフトです。

Windowsの場合はwgnuplot.exeをダブルクリックして起動します。

キーボードからコマンドを入力してグラフを描きます。
plot sin(x)と入力してEnterキーを押してみてください。

ファイルからグラフを読み込む

理工系の学科の人は、実験データをグラフに表示する機会があると思います。
gnuplotにはそのための機能があります。

下のように, 数値を列挙したテキストファイルを作ります。
これをsample.txtという名前で保存します。

0 3
1 4
2 5
3 10
4 15
5 8
6 9
7 22
8 27
9 28

gnuplotcd "(sample.txtのフォルダのパス)"と入力してEnter、
plot "sample.txt"と入力しEnterを押します。


ここで、パスを「"」(半角ダブルコーテーション)で囲む事、
また、Windowsの場合は(sample.txtのフォルダのパス)の区切りの
"\"(円マーク・バックスラッシュ)を二重にして入力する事に注意してください。

2次関数x^2 + 2 * x + 1のグラフです。

Pythonでグラフを出力する

このようにテキストファイルさえ作れれば、好きな関数のグラフを、
gnuplotに内蔵されていない関数でも、描けると言う事です。

最初のPythonプログラムを書きましょう。テキストエディタで次の内容をgraph.pyというファイルに保存しましょう。

print(0, 0**2 + 2*0 + 1)
print(1, 1**2 + 2*1 + 1)
print(2, 2**2 + 2*2 + 1)
print(3, 3**2 + 2*3 + 1)
print(4, 4**2 + 2*4 + 1)
print(5, 5**2 + 2*5 + 1)
print(6, 6**2 + 2*6 + 1)
print(7, 7**2 + 2*7 + 1)
print(8, 8**2 + 2*8 + 1)
print(9, 9**2 + 2*9 + 1)

コンソールで, pythonコマンドにgraph.pyを渡すと, さっきsample.txtに書いたのと同じ内容が出力されます。

$> python graph.py
0 3
1 4
2 5
3 10
4 15
5 8
6 9
7 22
8 27
9 28

リダイレクトを使って, テキストファイルに出力すれば, sample.txtと同じようにgnuplotで表示できます。

$> python graph.py > graph.txt

解説

  • 足し算には「+」と書きます。算数と同じです。
  • 掛け算には「*」と書きます。キーボードには×の記号は無いので代わりに"*"を使います。
  • べき乗には「**」と書きます。
  • したがって, 「5**2 + 2*5 + 1」は算数の書き方をすれば, 5^2 + 2*5 + 1です。
  • printは何かを出力しろという命令です。
  • 「print(5, 5**2 + 2*5 + 1)」は, 「5と5^2 + 2*5 + 1(= 8)を出力しろ」という意味です。

for文で楽をする

しかし, print(x, x**2 + 2*x + 1)を10回も書くのは面倒なので、楽をしましょう。

graph.pyを以下のように書き換えると, さっきと同じ内容が出力されます。

for n in range(10):
    print(n, n**2 + 2*n + 1)

インデント

ここで注意ですが, 「print(n, n**2 + 2*n + 1)」の前には半角スペースを4個入れてください。
スペースが無かったり、全角スペースだと、エラーになります。

グラフの範囲を変える

for文を使った書き方をすると, グラフの範囲を変えるのも容易です。
「range(10)」の「10」を「100」に書き換えれば、0から99までのグラフになります。

for n in range(100):
    print(n, n**2 + 2*n + 1)

数式を変える

数式を変えたい場合も, 一箇所を変更すれば良いので非常に楽です。
(x - 1)^3 / 4のグラフを出力してみましょう。

  • "-"で引き算、"/"は割り算です。
  • カッコで囲むと、その部分が先に計算されます。
for n in range(100):
    print(n, (n - 1)**3 / 4)

グラフを細かくする

しかし、今のままでは整数目盛りのグラフしか出力できません。

それでは困るのでこうします。
y = x^2 + 2x + 1の, -1 から 1の間の, 0.1刻みのグラフを出力しましょう。

for n in range(21):
    print(-1 + n / 10, (-1 + n / 10)**2 + (-1 + n / 10)*2 + 1)

変数を使う

しかし, 「-1 + n / 10」が3箇所も出てきて、書くのが面倒ですし、
一見、どんなグラフか分かりません。

そこで, 変数xを導入します。

for n in range(21):
    x = -1 + n / 10
    print(x, x**2 + x*2 + 1)

x = -1 + n / 10と書くと, -1 + n / 10という値にxという名前を付ける事が出来ます。
これを, 「x に -1 + n / 10を代入する」と言います。

y = x^2 + 2x + 1のグラフである事を考えると, さらに変数yも導入しておきましょう。

for n in range(21):
    x = -1 + n / 10
    y = x**2 + x*2 + 1
    print(x, y)

場合分けのある関数のグラフ

世の中, 多項式のような簡単に書ける関数だけではありません。
y = \left{\begin{array} x & (x < 0)\\ x^2 & (\mbox{otherwise}) \\\end{array} \right.

のような、場合分けが必要な関数を出力するには、if文を使います。

for n in range(21):
    x = -1 + n / 10
    if x < 0:
        y = x
    else:
        y = x**2
    print(x, y)

if文

「if x < 0:」と書くと, x < 0が成り立つとき「y = x**3」が実行され,
成り立たないとき「y = x**2」が実行されます。

インデント

ここで「y = x**3」「y = x**2」は, if文の中にある要素なので,
半角スペースを4×2 = 8個入れます。

条件式

  • 算数と同じく, 「より小さい」「より大きい」には「<」は「>」を使います。
  • 「等しい」には「==」と2重に書きます。
  • 「以下」「以上」には「<=」「>=」と, 等号をくっ付けて書きます。

elif

3つ以上の場合分けが必要なら、「elif」を使います。elif は else if の略です。

y = \left{\begin{array}x^2 &(x < -0.5) \\   x & (-0.5 \leq x < 0) \\   -x & (0 \leq x \leq 0.5) \\   x^2 & (otherwise) \end{array}\right.

for n in range(21):
    x = -1 + n / 10
    if x < -0.5:
        y = x**2
    elif 0.5 <= x < 0:
        y = x
    elif 0 <= x <= 0.5:
        y = -x
    else:
        y = x**3
    print(x, y)

演習

関数 y = \left{\begin{array}|x| & (|x| < 1) \\ x^2 & (otherwise)\end{array}\right.
x \in [-2, 2]の範囲のグラフを出力する, Pythonのプログラムを書きなさい.