Python演習1

このドキュメントは、みなさんが実際に手を動かしながらPythonというプログラミング言語を学ぶためのものです。

Azureサーバにログインして、繰り返し練習してみてください。

Pythonとは?

プログラミング言語のひとつです。1991年と、比較的新しく開発された言語(C言語は1972年)です。理解しやすく書きやすく、パフォーマンスの良い書き方もできるなど、現代的な言語に求められる特性を多く備えており、科学技術計算のほか、Webや機械学習など、幅広い用途で使われています。

現在はPython 3系 が主流となっています。以前のPython 2系とは若干書き方が異なるため、書籍などを参考にする際にはバージョンを確認する必要があります。

C言語とは違うの?

違います。たとえば、[2, 4, 1, 5, 3]という数字の並びを小さい順に並び替えるプログラムを見てみます。

Cでの例は以下のようなものです(バブルソートという方法を使っています)。

#include <stdio.h>
int main(void)
{
    int i, j;
    int num[5] = {2, 4, 1, 5, 3};
    int tmp;
    for (i = 0; i < 5; i++)
    {
        for (j = i + 1; j < 5; j++)
        {
            if (num[i] > num[j])
            {
                tmp = num[i];
                num[i] = num[j];
                num[j] = tmp;
            }
        }
    }
    for (i=0 ; i < 5 ; i++)
    {
        printf("%d ", num[i]);
    }
    return 0;
}

対してPythonでは以下のようになります。

num = [2, 4, 1, 5, 3]
for i in range(len(num)):
    for j in range(i + 1, len(num)):
        if num[i] > num[j]:
            num[i], num[j] = num[j], num[i]
print(num)

明らかに記述の量が違いますね。Pythonのほうが見やすいし、プログラムも短いです。

C言語は余計な命令を書いているのでしょうか?いいえ。すべて必要な命令です。では、なぜこの違いが?

Pythonは、可読性(読みやすさ)や書きやすさに重点が置かれた言語です。難しい処理も簡潔に記述することを得意としています。

しかし、万能な言語ではありません。

たとえば、Pythonのプログラムにintが出現していないことに気付いたでしょうか。C言語では、変数を宣言するときは、必ずその変数に入るのが整数なのか、浮動小数点なのか、はたまた文字なのかを指定しなければいけません。

しかし、Pythonはそれを自動で行います。変数に値が代入されるときに、それが数字なのか、文字なのかを判断して、適切なを推論します。

これは一見嬉しいことのように思いますが、プログラムのバグを増やす要因になります。数字だと思って処理を書いたのに、実は文字列が入っていた、となると、プログラムは誤った動作をします。Pythonはこういったバグを生み出しやすいのです(もちろん、これを防ぐ方法もあります)。

Pythonの書きやすさには、文法の工夫に加えて、こうした「よしなにやってくれる仕組み」が貢献しています。この仕組は趣味の工作でPythonを使うには気が利いて便利ですが、たとえば銀行の勘定系システムを作るときには役に立ちません。

あいまいさを許容する言語は、書いたプログラムがCPU上でどのように実行されるのか?私たちにとってわかりにくくなります。厳密なプログラミングを行いたい場合、C言語のようにあいまいさが排除された言語を使った使ったほうがよいのです。

世の中には数百、数千、あるいはそれ以上のプログラミング言語がありますが、それぞれが利点と欠点を持っています。そのため、プログラマーはいくつもの言語を習得して、用途に応じて使い分けています。

Pythonはどのようなときに使いやすい?

では、Pythonにはどのような利点があるのでしょうか?

文法が書きやすく、読みやすい

上の例のように、Pythonでは余計なカッコなどで混乱することが少なく、人間にとって理解しやすく書けます。

オブジェクト指向言語

これはずっと後で説明しますが、現代的で人間が理解しやすいプログラミングの考え方を使えます。

世界中の多くの人が使っている

多くの人が使うため、言語を理解するための資料がたくさんあります。また、科学技術の計算などをさらに便利にするためのプログラム(モジュール)がオープンソースとして配布されており、自由に使うことができます。

Hello world!

では、実際にPythonを実行してみましょう。

まず、Azureサーバにログインしてください。

ログイン方法は前回のUNIXの実験を参照してください。

ログインできたら、python3と入力してEnterを押してください。

以下のような文言が出れば成功です。環境によって多少異なっているかもしれませんが、問題ありません。

2021EXX@elec-server:~$ python3
Python 3.6.9 (default, Jan 26 2021, 15:33:00)
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 

一番下の行の>>>は、「入力を受け付けています」というサインです。これが行の頭にあるとき、Pythonの命令を入力して実行できます。

まずは、以下のプログラムを入力してエンターを押しましょう。

print("Hello world!")

おめでとう!あなたはPythonを動かすことができました!

課題

print("好きな言葉")で、好きな言葉を表示してみましょう。好きな言葉の前後に"(ダブルクォート)を必ず入れてください。
この課題ができたら、、先生に確認してもらってください。次からの課題は、特に指示がなければ先生に見せずに進んでも良いです。

Tip

現在、Pythonはインタプリタとして動かしています。命令を入力するたびに、それを解釈して実行します。この他に、プログラムを一気に実行するコンパイラがあります。

変数

C言語と同様、Pythonにも変数があります。変数はなにか値を入れるための箱といえます。まずは使ってみましょう。下のプログラムを入力してください。

a = 1
print(a)

1が出力されましたか?変数aに値1代入されたため、変数aを表示(print)すると1が出力されます。

もうひとつやってみましょう。

b = 5
print(b)

次は、これらの変数を使って計算をします。

c = a * b
print(c)

*はかけ算を表しています。正しい結果が表示されたでしょうか。

他にも以下のような演算子が使えます。

演算子 意味
+ 足し算
- 引き算
* かけ算
/ わり算
// わり算の商
% わり算の余り
** べき乗
d = 3 + c * b
print(d)

意図した結果が出力されたでしょうか?

課題

答えが"42"になる数式を作り、printしましょう。

ここまで整数のみの計算をしましたが、変数には小数点のある数や文字列など、いろいろな値を格納することができます。

e = 3.14
print(e)
f = "hello"
print(f)

文字列を入力するときは、""で囲うことを忘れないでください。変数と文字列を区別するしるしです。

変数は何でも入って便利ですが、実は、コンピュータの内部では、それぞれの変数が整数を入れるための箱か、小数か、あるいは文字列を入れるための箱なのかを区別して記憶しています。これをといいます。

C言語では型を厳密に守らないとエラーが出ますが、Pythonでは自動的に型を推論してくれるため、いつも気にしなければいけないわけではありません。

では、それぞれの変数がどんな値を入れるための箱なのか?type(変数などのオブジェクト)で確認できます。下のプログラムは、type(変数などのオブジェクト)をprintで表示しています。

a = 1
print(type(a))
e = 3.14
print(type(e))
f = "hello"
print(type(f))

いろいろな型があります。type()に値を直接入れても結果が出ます。

print(type(3))

Tip

intはintegarつまり整数、floatはfloating numberつまり浮動小数点数、strはstringつまり文字列を意味します。浮動小数点数とは、ある程度の有効数字でとても大きな数やとても小さな数を表せる仕組みを使った数です。

課題

3.14"3.14"の型(type)を確認してみましょう。

いま使っている変数の型が何なのかを理解しながらプログラムを組まないと、型の違いによって処理が異なっておかしなことになる場合があります。

課題

3.14 + 3.14と、"3.14" + "3.14"をそれぞれprintして比べてみましょう。

エラー

以下のプログラムを実行しようとすると、

f = "hello"
print(f * 3.14)

結果の代わりに、なにやら英文が表示されました。

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'float'

これはエラーです。Pythonがうまくプログラムを実行できないときに発生します。この場合、"hello"という文字列に3.14をかけることはできないため、和訳すると「この型は浮動小数点数でかけることができません」と表示されています。

エラーのとき表示されるエラー文は、プログラムのどこでどのようにうまく動かなかったかを説明しています。プログラムを修正するときにはまず、エラー文が何を言っているのか理解する必要があります。

とはいえ、最初は難しいので、エラーが出たら先生に見てもらうと良いでしょう。

空白

ここまでのプログラムには、たくさんの半角スペースが入っていました。

たとえば、

e = 3.14
print(type(e))

これは、実はスペースがなくても動きます。

e=3.14
print(type(e))

逆にいっぱい入れても良いです。

e      =      3.14
print( type( e ) )

ただし、意味のあるまとまりの途中で半角スペースを入れるとエラーになります。

e = 3.14
pri nt(typ e(e))

このプログラムはエラーになります。

  File "<stdin>", line 1
    pri nt(typ e(e))
         ^
SyntaxError: invalid syntax

何のために半角スペースを入れるかと言うと、見やすさのためです。この演習を通じて、見やすい半角スペースの入れ方を考えてみてください。

Warning

全角スペースは絶対に使わないでください。エラーになります。

配列

Pythonで配列のような型はいくつかありますが、ここではリストを学習します。

リストとは、下のようにコンマで区切っていくつかの要素を入れることができる型です。リストは[]で囲みます。

g = [10, 20, 30, 40, 50]

リストの中のそれぞれの要素には要素番号が以下のようについています。0から始まることに注意してください。

要素番号を指定することで、要素を取り出すことができます。

print(g[2])

課題

リストgから、要素番号4の要素を取り出してみましょう。

ある範囲の要素をまとめて取り出すこともできます。たとえば

print(g[1:3])

[20, 30]となり、要素番号1から3の1つ前までの要素を取り出せました。

課題

リストgから、リストの2番めから4番目までの要素を抜き出してみましょう。

リストのリストを作ることもできます。

h = [[10, 20],
     [30, 40]]

ライブラリ

これまでprint()type()などの命令を使いました。このように文字の後ろにかっこ()がついていて、かっこの中身に処理するデータを入れる命令を関数といいます。

print()type()はPythonにあらかじめ用意されている組み込み関数です。

課題

数値の絶対値を求める組み込み関数はabs()です。かっこの中に数字を入れて動作を確認しましょう。

Tip

Pythonの組み込み関数一覧は、下のサイトでチェックできます。 https://docs.python.org/ja/3/library/functions.html

科学技術の計算をするときには、組み込み関数だけでなく、もっといろいろな関数を使いたい場合があります。例えば、sinやcosを計算できたら便利です。

そういったときに、色々な機能をまとめたライブラリを活用できます。まずは、標準ライブラリのmathを使ってみましょう。

ライブラリを使うときは、インポートを行います。

import math

これでmathライブラリが使えるようになりました。試しにsqrt()関数を使ってみましょう。引数の平方根をとる関数です。

k = math.sqrt(2.0)
print(k)

インポートしたライブラリの関数を使うには、頭にmath.をつけます。

課題

mathライブラリの関数fabs()は、引数の絶対値を返す関数です。-2の絶対値をとってみましょう。

次に、行列計算を高速に行えるNumPyというライブラリをインポートしましょう。Pythonでは、ライブラリに別名をつけることができます。

import numpy as np

これでNumPyにnpという別名をつけてインポートしました。同様に、グラフ描画のためのmatplotlibというライブラリをインポートします。

import matplotlib.pyplot as plt

これにはpltという別名をつけました。では、この2つのライブラリを使ってみましょう。

x = np.linspace(0, np.pi * 2, 100)
y = np.sin(x)
plt.plot(x,y)
plt.show()

sin波のグラフが出力されました。たった6行のプログラムでグラフが描けるのです!

このプログラムの中身は今は理解しなくても構いません。重要なのは、NumPyの関数を使うときはnp.sin()のように頭に別名.をつけていることです。matplotlibの関数についても、plt.plot()のようになっています。

課題

プログラムの一部を変更して、cos波を描いてみましょう。 この課題ができたら、先生に確認してもらってください

ここから先の課題は授業中の提出を求めません。

グラフの体裁(授業後の課題)

上で出力されたグラフは実験結果として不十分です。レポートに貼り付けるグラフとして体裁を整えます。

import なんちゃらでインポートしたライブラリはPythonインタプリタを閉じるまで使えます。上の課題の続きでやる場合は入力しなくても良いです。

一度Pythonインタプリタを閉じて、もう一度開いてプログラムを書く場合は、

import numpy as np
import matplotlib.pyplot as plt

を入力してください。

まずは、plt.show()の前までのプログラムを書きます。上ではsin(x)を描いたので、今度はsin(2x)を描いてみましょう。

x = np.linspace(0, np.pi * 2, 100)
y = np.sin(2 * x)
plt.plot(x,y)

まずはx軸とy軸がなにか説明しましょう。今回はx軸ラベルを"Time[ms]"とします。

plt.xlabel("Time[ms]")

y軸ラベルは"Voltage[V]"とします。

plt.ylabel("Voltage[V]")

このあとに

plt.show()

するとx軸とy軸のラベルが追加されました。

これらに加えて、このグラフがなんのグラフなのかを説明する凡例もつけます。今は1つの波形のみを表示していますが、複数の波形を同時に表示したときに役立ちます。

xyの値はすでに変数に入っているので、そのまま使います。

その後のplt.plot(x,y)に引数を追加し、以下のように記述します。これで凡例に"sin(x)"と表示されます。

plt.plot(x, y, label="sin(x)")

x, y軸のラベルもつけましょう。

plt.xlabel("Time[ms]")
plt.ylabel("Voltage[V]")

凡例をつけた場合、plt.show()の前に以下の命令を記述します。

plt.legend()

ここまで終わったら、

plt.show()

すると体裁の良くなったグラフができます。

これらに加えて、x, yの範囲を調整したり、プロットの種類を変えることでもっと良いグラフになります。

レポート課題

理論

Pythonとはどのようなプログラミング言語か説明せよ。

実験方法

sin(x)cos(5x)のグラフを作成する。

x軸ラベルは"Time[ms]"、y軸ラベルは"Voltage[V]"とする。凡例もつける。

軸ラベルと凡例についてはどうしても難しければなくても良いが、そのぶん減点する。

実験結果

上記プログラムの実行結果を記述する。

考察

このグラフがオシロスコープから得られた実験データだと仮定して、さらに体裁を整えるための工夫を考える。

たとえば、グラフを見ただけでこのグラフが何のグラフなのか?をわかるようにしたり、レポートに貼り付けても見やすい工夫を考える。