|
<Task>
テキストファイル tab2.5.csv (内容はここ)
の2行目以降にコンマ区切りで実験データ
(xi, yi, zi)が記入してあるから yiを読み込んでベクトル
(y0,y1,・・・,yndata-1) を作りなさい。そしてベクトルの成分を a 倍(スケーリング)しなさい。
ただし、ファイルの読み込みは別モジュールとします。
<Excel を使えば>
このファイルをクリックすれば Excel が自動的に立ち上がると思います。2行目からは A, B, C列にデータが入っており、それがずーっと下まで続いています。
a の値は D1 セルに入っているものとします。スケーリング結果をD列に作りたければまず D2セルに「=B2*$D$1」を入力します。次に下方に drag すれば完了です。
この作業をPhthonとModula-2でやってみましょうというのが今回のテーマです。
<補足情報>
ベクトルの成分数 ndata はファイルを読んで判断しますが、一応1000以下とします(Python にとっては不要な情報です)。各行の成分数は3まで(A, B, C まで)とします。
|
| <Python (Object Oriented Programming)>
[Module] fileRead.py
class readtest:
def __init__(self,fname):
w = []
file = open(fname, 'r')
nline = 0
while (True):
line = file.readline()
print(line, end="")
if len(line)==0:
break
nline += 1
if nline == 1:
self.header = line
else:
result = line.split(',')
w.append(float(result[1]))
file.close()
nline -= 1
self.ndata = nline
self.w = w
[Main] mytest.py
def scaling(x, a):
n = len(x)
out = x.copy()
for i in range(n):
out[i] = a*out[i]
return out
f = fileRead.readtest('tab2.5.csv')
ndata = f.ndata
y = f.w
yy = scaling(y, 2.)
print(y,', ',yy)
|
<Modula-2 (Structured Programming)>
DEFINITION MODULE fileRead.DEF
VAR header: ARRAY[0..79] OF CHAR;
PROCEDURE readtest(fname: ARRAY OF CHAR;
VAR ndata: INTEGER;
VAR y: ARRAY OF LONGREAL);
IMPLEMENTATION MODULE fileRead.MOD
PROCEDURE readtest(fname: ARRAY OF CHAR;
VAR ndata: INTEGER; VAR y: ARRAY OF LONGREAL);
VAR
f : FIO.File;
line, s: ARRAY[0..79] OF CHAR;
nline,i: INTEGER;
OK : BOOLEAN;
BEGIN
IF NOT FIO.Exists(fname) THEN RETURN END;
f := FIO.Open(fname);
nline := 0; ndata := 0;
LOOP
FIO.RdStr(f,line);
WrStr(line); WrLn;
IF Str.Length(line)=0 THEN EXIT END;
INC(nline);
IF nline=1 THEN Str.Copy(header,line);
ELSE
Str.Item(s, line, Str.CHARSET{','}, 1);
y[ndata]:= Str.StrToReal(s,OK);
INC(ndata);
END;
END;
FIO.Close(f);
END readtest;
[Main] mytest.MOD
IMPORT fileRead;
IMPORT WrStr, WrLn, WrLngReal, WrInt;
PROCEDURE scaling(VAR yout: ARRAY OF LONGREAL;
yin: ARRAY OF LONGREAL;
n: INTEGER;
a: LONGREAL);
VAR
i: INTEGER;
BEGIN
FOR i:=0 TO n-1 DO
yout[i]:= a*yin[i];
END;
END scaling;
VAR
ndata: INTEGER;
y,yy : ARRAY[0..999] OF LONGREAL;
BEGIN
fileRead.readtest('tab2.5.csv', ndata, y);
scaling(yy, y, ndata, 3.0);
WrStr('ndata='); WrInt(ndata,1); WrLn;
FOR i:=0 TO ndata-1 DO
WrLngReal(y[i],5,10); WrStr(', ');
WrLngReal(yy[i],5,10); WrLn;
END;
|
初心者がいうのもなんですが・・・
- (time,conc,error) の全要素を得るには time = f.x 等とすると共にソースコードの手直しをする。
- 少ない行数で実現できるということは、生産性が高いとみてよさそう。
- class の中で attribute と method をどう設定するかで多彩な論理展開が可能になりそうである。
- object は便利なアイデアであるが、油断は禁物。例えば上の out = x.copy() をout = x とすれば y の値が変わった。プログラムが走ればそれで安心とはいかない。
|
- (time,conc,error) の全要素を得るには readtest の引数を増やすと共にソースコードの手直しをする。
- 変数の受け渡し (value or address) が明確なので安心してプログラムが書ける。
- 入出力も含め、すべてをモジュールから import せねばばらないのは確かに煩わしいが、グローバル変数のモジュールを最下層に持ってくる(exportだけのモジュールをを作る)
など、階層構造をうまく作れば生産性が上げられるが、大きなプログラムでないとペイしないかもしれない。
- ベクトルの要素数 ndata を明示せねばならないことが特に不便とは思えない。
|