Python(1)
Python とは
- いわゆるスクリプト言語のひとつ。
- 他にも
ruby
とかperl
とかあります。
- 他にも
- C 言語よりも簡単な記述が可能。
- 使いやすい「型」、豊富なライブラリがある。
- オブジェクト指向言語である。
ROS
のプログラムを書く上では必須。- C 言語か
python
しか使えない。
- C 言語か
- python でプログラムを書けるようになろう
プログラムの書き方と実行方法
- テキストエディタでプログラムを書く。
emacs
を使いましょう。- 拡張子は伝統的に
.py
。 - 1 行目には、
#!/usr/bin/python
を書く。
- 実行権限を与えて実行する。
$ chmod u+x filename.py
$ ./filename.py
python
コマンドの引数にファイル名を与えて実行することも可能。
$ python filename.py
プログラムの中身
- 基本的には C 言語等と同じ。
- 上から下へと実行される。
- 関数定義についてはファイルの分割も可能。
- 関数を別ファイルで定義しておくなど。
- 当然文法は違う。
- C 言語と同じ動作を違う文法で書くことになる。
- 対応を考えながら覚えるとよい。
- C 言語との違いを中心に解説
変数の型
- 宣言が不要。
- いきなり使用してよい。
- 代入した値の型になる。
- 型がないわけではない。
Python | C 言語 |
---|---|
a = "hoe" |
char a[] = "hoe"; |
a = 3 |
int a=3; |
a = 3.1415 |
float a=3.1415; |
a = [2, 3, 5] |
int a[3] = {2, 3, 5}; |
配列の中身
- 配列の中には何でも入れられる。
- 複数の型の混在も可能。
- 配列の中に配列を入れてもよい。
- いわゆる多次元配列が作れる。
a = [ 3, "hoe", 3.14 ]
b = [ 1, [ 2.1, "a", 0 ] "hoge" ]
c = [ [ 1, 2, 3, 4], [ 5, 6, 7, 8 ], [ 9, 10, 11, 12 ]]
配列の要素数
- 要素の数は自由に伸ばせる。
- 宣言のときに指定する必要なし。
Python
a =[] # 要素数 0の配列
b = [2, 3, 5] # 初期化(要素数3)
b[10] = 8 # これは範囲外でエラー
b.append(-2) # 最後に要素を追加 b = [2, 3, 5, -2] になる
c = len(b) # 要素数を返す関数
C 言語
int a[3];
a[5] = 8; /* 範囲外でエラー */
オブジェクト指向
- Python においてすべての変数の型はクラスである。
クラスとは
- データとそれを扱う関数のセットが定義された型。
- データにアクセスするにはセットになっている関数を使う必要がある。
- イメージはデータを管理する市役所の窓口。
- 実際のデータは「インスタンス」「オブジェクト」などと呼ばれる。
クラスのイメージ
- 配列のクラス(本当は「リスト」クラス)。
- クラス名「リスト」は窓口の課名。
- 変数名
a
は担当者の名前。 - データの出し入れは担当者に依頼。
a =[5, "hoe"] # 「リスト」課の a さんにデータ 5,"hoe" の管理をお願いする。
a.append(-2) # a さん、最後に「-2」を追加して。
a[0] = 3 # a さん、0 番目を「3」に変更して
c = len(a) # a さん、今、何個のデータを持っている?
なぜそんな構造にするのか
- データそのものを隠蔽化。
- 勝手に変更できないように。
- 使いまわしが楽。
- 内部の実装を知らなくてよい。
- 担当者が窓口の内側で何をやっているのか知らなくてよい。
- 誰もそのようなことは知りたくない。
- 窓口の内側でのやり方が変わってもこちらはいつもと同じようなやり方で頼める。
- インターフェイスさえ知っていればよい。
リストクラスの便利な使い方
- 要素番号の指定方法
a[-1]
は最後の 1 個。a[-2]
は最後から 2 番目。a[2:5]
はa[2]
~a[4]
までの部分リスト。
- リスト同志の加算
[1,2] + [1,2,4] → [1,2,1,2,4]
- 要素の挿入
a.append(x)
:x
を最後に追加a.insert(i, x)
:x
をi
番目に挿入
- 要素の削除
del a[2]
: 2 番目の要素を削除b = a.pop()
: 最後の要素を削除しb
に代入a.remove(x)
: 値がx
である最初の要素を削除
- 値の検索
x in a
:x
がリスト中にあればTrue
a.index(x)
: 値がx
である要素番号
- 並べ替え
a.sort()
: 要素を小さい順に並べ替えa.reverse()
: 逆順に並べかえ
配列(や辞書)を使う時の注意点
- 複数の名前が同じ変数につけられる。
- コピーではなく、同じものにふたつの名前がついている。
- C 言語でいうところのポインタでの変数指定に似ている。
- コピーしたい場合は明示的に指定する必要がある。
a = [2, 3, 5]
b = a
b[1] = 0
print(a)
print(b) # <-出力を確認
import copy
c = copy.copy(a)
c[2] = 1
print(a) # <-出力を確認
print(c)
実習(1)
- 適当なプログラムを作り挙動を調べる。
- 変数、配列、メソッドなど。
- とりあえずテストしたいときは「プログラムを組んで実行」ではなく、インタラクティブモードでの実行が便利。
インタラクティブモード
- ターミナルソフトで
python
と打ってEnter
キーを押す。 >>>
に対して Python のプログラムを入力する。- 変数名だけを入力すると中身を表示できる。
- 終了したいときは
quit()
と打ってEnter
キーを押す。
実習(1)手順
- インタラクティブモードにする。
- いろんな変数を作ってみる。
- 整数、実数、文字列、配列・・・
- 計算させて結果を見る。
- リストクラスを使ってみる。
- いろんなメソッドを試す。
- 中身を表示させどう変化するか観察する。
リストより便利なクラス
- 「辞書」クラスでは配列の添え字に数字以外を使うことができる。
ruby
なら「ハッシュ」、perl
なら「連想配列」に相当する。- 自由な添え字(キー)と値(バリュー)の組を定義して使う。
- 「順番」は存在しない。
a = {} # 初期化の記号
a[2] = 3.14
a["hoe"] = 0 # 文字列の添え字
a[8.7] = "hoge"
b = a[2] + a["hoe"]
# 初期化の方法
a ={ 2:3.14, "hoe":0, 8.7:"hoge" } # キー : 値
辞書クラスの便利なメソッド
- 要素(キーと値のセット)の追加
a["hoe"] = 3
- 要素の削除
del a["hoe"]
b = a.pop("hoe")
# pop は下記と等価
# b = a["hoe"]
# del a["hoe"]
- キーの検索
x in a # キーに x があれば True
a.has_key(x) # キーに x があれば True
b = a.keys() # キーのリストの取得
b = a.values() # 値のリストの取得
実習(2)
- 辞書についても実習してみましょう。
- インタラクティブモードにして辞書クラスを使ってみる。
- いろんなメソッドを試す。
- 中身を表示させ、どう変化するか確認する。
- 辞書クラスは非常に便利。
文字列クラス
- 文字列を扱うクラス。
- C 言語と比較して非常に便利。
文字列クラスでよく使うメソッド
s = "hoe" + "hoge" # s には "hoehoge" が入る
s = "hoe" * 3 # s には "hoehoehoe" が入る
len(s) # 文字列の長さ
s[2] # 一部を取り出す
s[1:3] # 一部を取り出す
a = s.rstrip() # 最後の改行と空白文字を削除
a = s.split(",") # 指定された文字で分割しリストに
s = "-".join(a) # リストの要素を指定文字で連結
C 言語 VS Python その他の違い
printf
文
print("hoe %d hoge" % a)
- 型の変換
# 文字列 → 数字
int("12")
float("3.14")
# 数字 → 文字列
str(3.12)
-
True
とFalse
- C 言語の場合 「偽」が 0,「真」 はその他の数
-
None
- 「何もない」という特別な値
実習(3)
- インタラクティブモードにして文字列クラスを使ってみる。
- いろんなメソッドを試す。
- メソッド一覧は Web 検索で見つけてください。
- 中身を表示させ、どう変化するか確認する。
- いろんなメソッドを試す。
- 今までの知識とあわせいろいろやってみる。
- 正しく使いこなせるように。
ブロックの範囲指定
- ブロックの範囲はインデントで指定する。
if a == 1 :
print("hoe")
else:
print("Error: not hoe")
exit()
- C 言語だと括弧(
{
、}
)
if (a == 1 ){
printf("hoe\n");
} else {
printf("Error: not hoe\n");
exit();
}
多重ブロック
- インデントの深さで表現する。
- 段差がずれないように注意すること。
a = 0
while a < 10:
a = a + 1
print("hoe")
if a == 5:
print("hoge")
print("end")
- C 言語
a = 0;
while (a < 10){
a++;
printf("hoe\n");
if (a == 5 ){
printf("hoge\n");
}
}
printf("end\n");
条件分岐
- いわゆる
if
文。 - 考え方は C 言語と同じ。
- 条件に書ける演算子
==, !=, >, <, >=, <=, is
and, or, not
if ~ else if ~
のかわりにelif
も使える。- インデントが深くならなくて良い。
if a == "hoe":
print("hoe")
b = b + 1
else:
if c > 0 and d < 10:
print("hoge")
else:
print("error")
switch ~ case
文は存在しない。
==
とis
との違い
==
は「値が同じか?」をチェック。is
は「同じオブジェクトか?」をチェック。- 普通は
==
で良い。
a = "abc"
b = "abc"
if a == b:
print("same value")
if a is b:
print("same object")
else:
print("different object")
繰り返し
while
文
- 条件が満たされている間繰り返す。
- コード例
# while 文
a = 0
while a < 10:
a = a + 1
print("hoe")
print("hoge")
for
文
- コード例
- 与えられたリストの中身を順に加算する。
a = 0
for i in [2, 5, 8]:
a = a + i
print("hoe")
print("hoge")
- コード例
- 与えられた文字列の文字を 1 文字づつ参照する。
# 文字列で
for i in "hoe":
print("--%s--" % i)
print("hoge")
for
文の使い方
- 0 ~ 9 までのループ
[0, 1, 2, ..., 9]
というリストを作ってfor
文にrange()
関数を利用
- 辞書の中身を順に呼び出す
- キーだけのリストを作り
for
文にa.keys()
を利用
- キーだけのリストを作り
# range 文
for i in range(0,10): # これで i は 0~9 まで変化する
print("hoe")
# リストの中身
a = [3, 4, "hoe"]
for i in a:
print i
# 辞書の中身
a = { 1: "a", "hoe": 5}
k = a.keys()
for i in k:
print a[i]
実習(4)
- 今度はインタラクティブモードではなく、プログラムを
emacs
で書いて実行する。
実習(4-1)
- 以下のようなプログラムを作成して実行する。
- 10 個の整数を要素とするリストを定義する。
- 値は何でもよい。
- 小さい順にソートし、値を表示する。
- 10 個の整数を要素とするリストを定義する。
実習(4-2)
- 以下のようなプログラムを作成して実行する。
- 英文が書かれたファイルを準備する。
- 使用されている単語の個数を調べ、上位 5 個の単語を表示する。
- input.txt
ファイルの読み書き
- 基本は C 言語と同じ。
- ファイルをオープンし、それに対して読み書きする。
- ファイルのオープン・クローズ
f = open("filename", "r") # "w" なら書き込み
f.close()
# ファイルからの読み出し
s = f.readline()
# ファイルへの書き込み
f.write("hoe")
- 順に読むなら、
for
文を使う。
ファイル入出力の例
ifn = "input.txt"
ofn = "output.txt"
ifp = open(ifn, "r") # ファイルをオープン
ofp = open(ofn, "w") # ファイルをオープン
s = ifp.readline() # 1行読み込み
print s.rstrip()
for s in ifp: # 各行を順に読み込み
a = s.split(",")
ofp.write(a[0] + "\n") # ファイルに書き込み
ifp.close() # ファイルをクローズ
ofp.close() # ファイルをクローズ