裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

早期リターンではなくなっているぞ

2022年08月14日 | ブログラミング

以下の例を上げてきたが,これはもはや「早期リターンではない」

class Student:

  def __init__(self, student_id, name):
    self.student_id = student_id
    self.name = name

  def student_check(self):
    
    if self.student_id != "" or self.name != "":
      if len(self.student_id) > 12:
        flg = False
      else:
        flg = True
    else:
      flg = False
    return flg

student_exe = Student("101122222212","山田花子")
student_exe.student_check()

if のネストを避ける」というなら,以下のようにすればよい。これで「早期リターン」だ!!

  def student_check(self):
    
    if self.student_id != "" or self.name != "":
      return len(self.student_id) <= 12
    else:
      return False

蛇足だが,flg なんて変数名はダメダメ。flag にしよう。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

早期リターンとガード節

2022年08月14日 | ブログラミング

早期リターンとガード節

ガード節を使わないプログラムとして挙げられているのが prog1

if value === "hoge"
  result = "hoge"
else
  if value === "fuga"
    result = "fuga"
  else
    if value === "hogefuga"
      result = "hogefuga"
end

return result

ガード節を使うプログラムとして挙げられているのが prog2

if value === "hoge"
  return "hoge"
end

if value === "huga"
  return "fuga"
end

return "hogefuga"

この言語は何かわからないが,やっていることはわかる。

疑問は,「この言語は if-else しかないのか?if-elseif-else はないのか?」ということ

prog2 は,以下のように書くとわかりやすいのではないか? prog3

if value === "hoge"
  return "hoge"
else if value === "huga"
  return "fuga"
else
  return "hogefuga"
end

prog1 では,value が "hoge", "huga", "hogefuga" 以外の場合,未定義の result を返そうとする。言語によっては単に何も返さないと解釈されることもあるが,いずれにせよ,論理エラーである。

prog2, prog3  では,value が "hoge", "huga" 以外の場合,無条件に "hogefuga" を返す。これは論理エラーである。

prog3 はもう一段 else if があるべきだ。 prog4

これは prog1 を else if を使って,更に条件のチェック漏れを補完したプログラムだ。

if value === "hoge"
  return "hoge"
else if value === "huga"
  return "fuga"
else if value === "hogefuga"
  return "hogefuga"
else
  return "ERROR!!"
end

最後に,このバカバカしいプログラムに限ってだが,以下のように書くのがベストだ。prog5

if value === "hoge" || value === "huga" || value === "hogefuga"
  return value
else
  return "ERROR!!"
end

あるプログラミングスタイルを推奨する記事を書くとき,悪い例と良い例を提示するが,提示されたプログラムがクソだと,プログラミングスタイル自体がクソに見える。

早期リターンは必要なら使えばよい。

いずれにしても,プログラムをよく解析して,最良なアルゴリズムを適用することだ。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

ヒルベルト行列

2022年08月14日 | ブログラミング

Julia で書くと以下のようになる。

一行で書けるが決してこの書き方をすすめるわけではない。普通に2重ループで書くほうがよい。

演算子に // を使ったのは,分数型で答えを出力するためである。

julia> h(n) = [1 // (i + j - 1) for i in 1:n, j in 1:n]

h (generic function with 1 method)

julia> h(5)

5×5 Matrix{Rational{Int64}}:

 1//1  1//2  1//3  1//4  1//5

 1//2  1//3  1//4  1//5  1//6

 1//3  1//4  1//5  1//6  1//7

 1//4  1//5  1//6  1//7  1//8

 1//5  1//6  1//7  1//8  1//9

実数型に変換すると。

julia> float.(h(5))

5×5 Matrix{Float64}:

 1.0       0.5       0.333333  0.25      0.2

 0.5       0.333333  0.25      0.2       0.166667

 0.333333  0.25      0.2       0.166667  0.142857

 0.25      0.2       0.166667  0.142857  0.125

 0.2       0.166667  0.142857  0.125     0.111111

Python だと

>>> a = [[1/(i+j-1) for i in range(1, n+1)] for j in range(1, n+1)]

のようになるが,range(1, n+1) が鬱陶しい。

>>> a = [[1/(i+j+1) for i in range(n)] for j in range(n)]

とすればよい。

しかし,n = 5000 のとき,Julia で // を / にして直接実数型の結果を返す場合に比べて,Python は,ほぼ 24 倍遅い

追記:

Nemo パッケージに hilbert 関数があった。

 

julia> using Nemo

julia> M = MatrixSpace(QQ, 5, 5)

Matrix Space of 5 rows and 5 columns over Rational Field

 

julia> h = hilbert(M)

[   1   1//2   1//3   1//4   1//5]

[1//2   1//3   1//4   1//5   1//6]

[1//3   1//4   1//5   1//6   1//7]

[1//4   1//5   1//6   1//7   1//8]

[1//5   1//6   1//7   1//8   1//9]

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PVアクセスランキング にほんブログ村

PVアクセスランキング にほんブログ村