Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
マトリクス構造解析 第11回
[go: Go Back, main page]

 

[Google] [情報統括センター] [WebClass] (構力I) (構力II) (構造メモ) (構造実験) (Fortran) (Ruby) (後藤資料)

マトリクス構造解析II 第3回

(マトリクス構造解析 第11回)

小さい字は補足説明なので、読み飛ばしてもいいです。

このページのオリジナルの作者は 後藤文彦です。
クリエイティブ・コモンズ・ライセンス
マトリクス構造解析オンライン授業用テキスト
第11回オンライン授業
YouTube授業動画リスト

目次

プログラム例題(リスト、for文、ファイルで入出力)

リスト、for文

クラスの一人一人の試験の点数を読み込んで、 平均点と不合格者(60点未満の人)の番号と点数を出力するプログラムを作ってみよう。 まずは、以下のプログラムに適当な名前(heikin.py)をつけて保存する。


# 点数を入れるリスト
tensuu = [0.0] * 100

# 人数の入力
ninzuu = int(input("人数を入力してください: "))

# データ入力
for i in range(1,ninzuu+1):
    tensuu[i] = float(input(f"{i}人目の点数を入力してください: "))

# 合計点の計算
goukei=0.0
for i in range(1,ninzuu+1):
   goukei=goukei+tensuu[i]

# 平均点の計算と表示
print("平均点は:", goukei/ninzuu)

# 不合格者の表示(60点未満)
for i in range(1,ninzuu+1):
    if tensuu[i] < 60.0:
        print("不合格者番号:", i, "点数:",tensuu[i])

まずはプログラムについて少々。

# 点数を入れるリスト

#を書いたところから改行までは コメントとみなされるので注釈とかを書ける。

tensuu = [0.0] * 100

tensuuという1次元のリストを宣言し、 その100個の成分(tensuu[0]からtensuu[99]まで)に 初期値として0.0を代入する。 リストというのは、 データを入れるベクトルやマトリクスのことで (他のプログラム言語では「配列」ということが多いかもしれない)、 例えば、 tensuu[1]=60.0, tensuu[2]=90.0, tensuu[3]=50.0, みたいな、 人数分の点数を入れる入れ物(ベクトル)をつくる。 tensuu[i]のiはインデックスと言い、ベクトルの添字に当たるが、 Pythonのインデックスはi=1からではなくi=0から始まるので、 そこに注意が必要である。 また、リストは空の状態では、

tensuu[1]=60.0

のような代入文で数値を代入することができないため、 このプログラムで扱いそうな人数ぶん(余裕を持って100人ぐらい)だけ、 初期値0.0を入れておく。

tensuu = [0.0] * 100

と書くと、 tensuu[0]からtensuu[99]までの100成分に0.0が代入される。 もし、*100のところを*200にすれば、 tensuu[0]からtensuu[199]までの200成分に0.0が代入される。

ninzuu = int(input("人数を入力してください: "))

人数をninzuuに代入して、人数の数だけ、同じ処理を繰り返したりする場合、 繰り返しの回数は整数でなければならないので、 回数を与えるための変数ninzuuは整数型でなければならない。 なので、今回は、input()で入力された数値をfloatではなくintで整数に変換している。

for i in range(1,ninzuu+1):
    tensuu[i] = float(input(f"{i}人目の点数を入力してください: "))

これは、for文というものだが、for文に慣れるために、 まずは簡単な以下のような2行を 適当な名前(i.pyとか)で保存して実行してみよう。

for i in range(5):
    print(i)

これは、iに0から4までを代入しながら、 for i in range(5):の下にインデントして書かれている行を5回繰り返して 実行する。range(n)と書かれていれば、i=0からi=n-1までのn回繰り返すことになる。 すると、print(i)が5回実行されて、

0
1
2
3
4

と表示される。 Pythonではリストのインデックスの初期値はi=0から始まるので、 こうなるが、添字がi=1から始まるベクトルやマトリクスなどの成分 (マトリクス構造解析の変位ベクトルや剛性マトリクスは正にそうだ)を プログラムの中でもインデックスがi=1から始まるように対応させたいことはある。 その場合、i=0を使わずにダミーとして、i=1から後だけを使うという方法がある。 次の2行を適当な名前(i1.pyとか)で保存して実行してみよう。

for i in range(1,5):
    print(i)

range(1,5)というのは、初期値i=1から(i=0のぶんも含めて)5回繰り返すという意味。 だから、i=1からi=nまでのn回を繰り返したければ、range(1,n+1)と書く必要がある。 i=2からnまでのn-1回を繰り返したければ、range(2,n+1)である。 つまり、for i in range(j,k):と書いた場合は、jは 繰り返し処理をする場合のiの初期値、kは(jにかかわらず)i=0を初期値として 数えた繰り返し回数ということになるだろうか。 上記を実行すると、

1
2
3
4

と表示されたと思う。 というわけで、heikin.pyのプログラムに戻る。

for i in range(1,ninzuu+1):
    tensuu[i] = float(input(f"{i}人目の点数を入力してください: "))

range(1,ninzuu+1)は、 i=1人目からi=ninzuu人目までの(i=0のぶんも含めて)ninnzuu+1回繰り返すという意味。 このfor文で繰り返す処理は、その下にインデントされて書かれている行になる。 input文の中に"f{i}人目...."みたいな表現があるが、 その説明のために、以下の2行を適当な名前(f.pyとか)で保存して実行してみよう。

for i in range(1,5):
    print(f"今は{i}回目です")

f"....{a}....."みたいな書き方は、 例えば、今a=3とかaに適当な数値が入っているときに、 print文やinput文で、 {a}の部分にその数値を入れて""の中のテキストを表示する。 上記を実行すると以下のようになる。

今は1回目です
今は2回目です
今は3回目です
今は4回目です

さて、heikin.pyの中身に戻る。

for i in range(1,ninzuu+1):
    tensuu[i] = float(input(f"{i}人目の点数を入力してください: "))

まず、range(1,ninzuu+1)となっているので、 初期値として i=1が代入されてインデントされている行

    tensuu[i] = float(input(f"{i}人目の点数を入力してください: "))

が実行されるが、 i=1のときに、「1人目の点数を入力してください:」と表示され tensuu[1]に1人目の点数が代入され、 i=2のときに、「2人目の点数を入力してください:」と表示され tensuu[2]に2人目の点数が代入され、、、 とi=ninzuu人目まで繰り返す。

次に合計点の計算。

goukei=0.0
for i in range(1,ninzuu+1):
   goukei=goukei+tensuu[i]

まず、for文に入る前に、 goukei=0.0としてgoukeiの値を0に初期化しておく。 i=1 のとき goukei=0.0+tensuu[1] つまり goukei=tensuu[1] となる。
i=2 のとき goukei=goukei+tensuu[2] つまり goukei=tensuu[1]+tensuu[2] となる。
これをi=3以降も 続けていって、
i=ninzuu のとき goukei=goukei+tensuu[ninzuu] つまり goukei=tensuu[1]+tensuu[2]+.....+tensuu[ninzuu] となる。 なお、 sum()関数というものを使って以下のように書けば、 for文を使わなくても リストに代入されている数値をすべて合計してくれる。

goukei = sum(tensuu)

平均点の計算と表示は特に問題ないだろう。

print("平均点は:", goukei/ninzuu)

プログラム言語においては、 割り算の分子と分母の整数型、実数型の組み合わせによって、 答えが整数型になるのか実数型になるのかといったことが問題になるが、 Pythonの場合は、a/bで計算した答えは、 aとbの整数型、実数型の組み合わせがどうなっていようと、 答えは実数型(浮動小数点数)になる。 なお、 a//bは、aをbで割った商の小数点以下を切り捨てた答えを表し、 a%bは、aをbで割ったあまりを表す。

 さて、このプログラムを実行すると、 最初に人数の入力を求められて、その後、 人数ぶんの点数の入力を求められるので、 3人とか、5人ぶんのデータで、予想通りに動作するか、ためしてほしい。 さて、 5人ぐらいだったら、手入力しても大したことはないかもしれないが、 数十人とかになったら、 これをいちいちキーボードから打ち込むのではめんどくさいし、 間違いが起きやすい。 そういう場合は、入力データをファイルにして入力する。 まず、エディターで

10
95.0
20.0
65.0
70.0
50.0
0.0
80.0
100.0
45.0
60.0

みたいな入力データを作って、 適当なファイル名(例えば、tensuu.dat)で 保存しよう。 拡張子の.datはなくてもいいが、 一応、データファイルだというのがわかりやすいように、つけておこう。 上の例は、1行目に人数の10人が、2行目から11行目までに 10人ぶんの点数が並んでいる。 この tensuu.dat を heikin.py に読み込んで実行するには、

$ python3 heikin.py < tensuu.dat

のように打ち込んでエンターを押す。 tensuu.datに書かれたデータが入力されて実行されると思う。 「<」は、tensuu.dat を heikin.py に入れるという左向き矢印の意味。 実行結果が画面に表示されただろうか。 この画面に表示された実行結果を、 ファイルに出力することもできる。 例えば、 tensuu.dat を heikin.py に読み込んで実行した 実行結果を kekka.out というファイルに出力 したい場合は、

$ python3 heikin.py < tensuu.dat > kekka.out

のように打ち込んでエンターを押す。 「>」は、kekka.outに入れるという右向きの矢印の意味。 lsコマンドで、kekka.outができているかどうか確認しよう。 kekka.outの中身を端末上で確認したければ、

$ cat kekka.out

と打てばいいし、エディターで確認したければ、geditで開けばいい。

先頭目次

プログラム課題3:

if文やfor文など、これまで出てきたコマンドを使って、 heikin.py を、 最高点の人の番号と点数も出力できるように 改造せよ。 これまでに使っていないコマンドや関数 (例えば、リストの最大値を求めるmax()関数など)は使わないこと。 最高点の人が2人以上いた場合に対応できるようにすることは求めない。 もちろん、対応できるようにして構わないし、 標準偏差も出すとか、他にも機能を加えても構わない。 最高点を出せても出せなくても、 WebClassの「プログラム課題3」から、 プログラム本体(例えば kadai3.py とか)と、 入力ファイル(例えば tensuu.dat とか)と 出力ファイル(例えば kekka.out とか)を それぞれアップロードし、 (仮にエラーが取れずにどうしても実行できなかった場合は、 エラーが出ている画面) をテキストエディター(gedit等)に貼り付けて保存したファイル(kekka.txtとか)を 提出する。








参考:append()メソッドを使う、for文のiを0から始める

以下は、あくまで参考資料です。 append()メソッドというものを使うと、 空のリストに代入することもできる。 その方法を使ってみる。 また、リストのインデックスの初期値i=0を使わないという方法は、 一般的には推奨されないようなので、 i=0を初期値として書き直してみる。 以下のプログラムの方が、冒頭のheikin.pyよりは Pythonらしいということになるのかもしれないが、 初学者にはちょっとわかりにくいかなと...

# 点数を入れるリスト
tensuu = []

# 人数の入力
ninzuu = int(input("人数を入力してください: "))

# データ入力
for i in range(ninzuu):
    a = float(input(f"{i+1}人目の点数を入力してください: "))
    tensuu.append(a)

# 合計点の計算
goukei=0.0
for i in range(ninzuu):
   goukei=goukei+tensuu[i]

# 平均点の計算と表示
print("平均点は:", goukei/ninzuu)

# 不合格者の表示(60点未満)
for i in range(ninzuu):
    if tensuu[i] < 60.0:
        print("不合格者番号:", i+1, "点数:",tensuu[i])

プログラムについて。

tensuu = []

tensuu[]という1次元のリストを空のまま定義している。

for i in range(ninzuu):
    a = float(input(f"{i+1}人目の点数を入力してください: "))
    tensuu.append(a)

まず、i=0が代入されて、

    a = float(input(f"{i+1}人目の点数を入力してください: "))

が実行されるが、 i=0のときに、「1人目の点数を入力してください:」と表示させたいので、 input(f"{i+1}人目....")として、i+1人目を表示させるようにしている。

今回は、tensuu[0]に1人目の点数、tensuu[1]に2人目の点数、、、という具合に 代入していきたいので、i=0のときに、

1人目の点数を入力してください: 

と表示されて1人目の点数をtensuu[0]に入力し、i=1のときに

2人目の点数を入力してください: 

と表示されて2人目の点数をtensuu[1]に入力し、、、というふうにやりたいのだが、 Pythonの場合、リストが空のときに、いきなり、

    tensuu[i] = float(input(f"{i+1}人目の点数を入力してください: "))

みたいにして、空のリストに数値を代入するということができないので、 一旦 適当な変数aにinputで入力された数値を代入しておいてから、 次にappend()メソッドというものを使って、

    tensuu.append(a)

と書くと、aに代入された数値が、 tensuu[i]に代入される。 Pythonなどの「動的配列」を持つプログラム言語 (JavaとかC#とか)では、こういう書式が一般的なようなのだが、 こういうところが、 FortranRubyと比べると なかなか難しいと私は感じる。 以下は、 イメージをつかむため、 a[i]にfor文の繰り返しで、i=0からi=4を代入し、それがその通り 代入されていることを確認するために出力するプログラム例。

a=[]
for i in range(5):
   a.append(i)
   print(f"a[{i}]=",a[i])

次にheikin.pyに戻って合計点の計算。

goukei=0.0
for i in range(ninzuu):
   goukei=goukei+tensuu[i]

まず、for文に入る前に、 goukei=0.0としてgoukeiの値を0に初期化しておく。 i=0 のとき goukei=0+tensuu[0] つまり goukei=tensuu[0] となる。
i=1 のとき goukei=goukei+tensuu[1] つまり goukei=tensuu[0]+tensuu[1] となる。
これをi=2以降も を続けていって、
i=ninzuu-1 のとき goukei=goukei+tensuu[ninzuu-1] つまり goukei=tensuu[0]+tensuu[1]+.....+tensuu[ninzuu-1] となる。 なお、 sum()関数というものを使えば、 for文を使わなくても リストに代入されている数値をすべて合計してくれる。