20210510のPythonに関する記事は30件です。

Pythonで簡単にデータベースを扱う(SQLite3) その2

1.はじめに 以前下記のような記事を書きましたが、この記事がLGTM数はさておき私の想定より閲覧数があった為、第2弾として私がSQLite3に関して知ってることを備忘録兼ねて追加で書くことにしました。 動作環境 OS : Windows10 pro Python : 3.8.3// Miniconda 4.9.1 sqlite3:2.6.0 jupyter notebook DB Browser for SQLite(管理ツール) 2.今回説明に使うDB,テーブル作成 まずは本記事で使用するサンプルDB作成、サンプルテーブルを2個作成するまでの流れです。 前回と少し変えて書いてますが、コードの中に解説入れてますのでご参考ください。 ※前回の記事でSQL命令にクオテーションを3つ使っていたが、あれは行をまたぐ命令を書く場合のやり方で基本的には文字列同様にクオテーション1個でいい。本記事では1個で行きます。 2-1.今回説明に使うDB,テーブル作成、確認 import sqlite3 import pandas as pd dbname1 = ('test2.db')#データベース名.db拡張子で設定 con = sqlite3.connect(dbname1, isolation_level=None)#データベースを作成、自動コミット cur = con.cursor() #データベースに接続する # テーブルの作成 """ 今回はカラムに型を定義 PRIMARY KEY:主キー制約をかける(重複したデータを入れることが出来なくなる。今回は同じID番号を登録できなくしている) NOT NULL:対象カラムにnullを入れることをできなくする """ #テーブル1作成 cur.execute("create table if not exists test1(id integer PRIMARY KEY, name text NOT NULL, date text)") #テーブル2作成 cur.execute("create table if not exists test2(id integer PRIMARY KEY, sex text, height real)") ここでテーブルがきちんと作成できたかを確認するが、前回記事と調べ方を変える。 本記事ではSELECT命令に関しては基本的にこのread_sql_queryを使用して表示させていく。 #テーブルが作成されたかを確認 """ jupyterでSQL命令のSELECT命令を確認をする際にはpandasの「read_sql_query」を使う。 本記事では前回の記事では使わなかったこの関数を基本的に活用していく """ pd.read_sql_query('SELECT name FROM sqlite_master WHERE TYPE="table"', con) name 0 test1 1 test2 2-2.レコード挿入 まずはカラム作成時に制約をかけたNOT NULLの機能を確認してみる data = [ (0, None, 19980108), #nameカラムにnullを設定してみる ] cur.executemany('INSERT INTO test1 VALUES(?,?,?)', data) 実行結果 IntegrityError: NOT NULL constraint failed: test1.name 次にカラム作成時に制約をかけたPRIMARY KEYの機能を確認してみる data = [ (0, "Bob", 19980108), (0, "Bobby", 19980109), #あえて同じidで登録させようとしてみる ] cur.executemany('INSERT INTO test1 VALUES(?,?,?)', data) 実行結果 IntegrityError: UNIQUE constraint failed: test1.id 制約の確認はできたので、test1テーブルで使用するその他レコードを挿入する #test1テーブルへ値挿入 data = [ (1, "Taro", 19800810), (2, "Rena", 19921015), (3, "Masa", 20050505), (4, "Jiro", 19910510), (5, "Satoshi", 19880117) ] cur.executemany('INSERT INTO test1 VALUES(?,?,?)', data) pd.read_sql_query('SELECT * FROM test1', con).head(2) #長いので先頭の2行だけ表示 id name date 0 0 Bob 19980108 1 1 Taro 19980810 同様にtest2テーブルで使用するレコードを挿入する ※test2は最後の結合にしか使用しませんので出番は当分先ですが。。 #test2テーブルへ値挿入 data = [ (0, "Man", 179.5), (1, "Man", 191.1), (2, "Woman", 161.2), (3, "Man", 171.7), (4, "Man", 156.9), (5, "Woman", 188), ] cur.executemany('INSERT INTO test2 VALUES(?,?,?)', data) pd.read_sql_query('SELECT * FROM test2', con).head(2) id sex height 0 0 Man 179.5 1 1 Man 191.1 3.様々なテーブル単体操作 前回の記事で紹介しなかった操作を色々記述していく。 なお、いちいちdf.head()で個別表示するのはシンドイので、ここからは基本的にIPython.displayモジュール(jupyterの表示に特化)を活用していく。 3-0.LIMIT句で抜粋 LIMITを使用するとレコードの抜粋場所を指定できる from IPython.display import display, display_markdown display_markdown('LIMIT句:先頭から2レコード抜粋', raw=True) display(pd.read_sql_query('SELECT * FROM test1 LIMIT 2', con)) display_markdown('OFFSET句:先頭を2レコードずらしてから2レコード抜粋', raw=True) display(pd.read_sql_query('SELECT * FROM test1 LIMIT 2 OFFSET 2', con)) ※以下出力結果 LIMIT句:先頭から2レコード抜粋 id name date 0 0 Bob 19980108 1 1 Taro 19980810 OFFSET句:先頭を2レコードずらしてから2レコード抜粋 id name date 0 2 Rena 19921015 1 3 Masa 20050505 3-1.WHEREで条件を付けて検索する WHEREの後に抽出する条件を入れてクエリーをかけるサンプル。 GLOB句は正規表現的なやつです。 from IPython.display import display, display_markdown display_markdown('WHERE句:id4以上のみ抜粋', raw=True) display(pd.read_sql_query('SELECT * FROM test1 WHERE id > 3', con)) display_markdown('BETWEEN句:idが2~4を抽出', raw=True) display(pd.read_sql_query('SELECT * FROM test1 WHERE id BETWEEN 2 and 4', con)) display_markdown('IN句:nameカラムでMasaなのをピンポイント抽出', raw=True) display(pd.read_sql_query('SELECT * FROM test1 WHERE name IN("Masa")', con)) display_markdown('GLOB句:nameカラムで「Ma」とつくものを抽出', raw=True) display(pd.read_sql_query('SELECT * FROM test1 WHERE name GLOB("Ma*")', con)) WHERE句:id4以上のみ抜粋 id name date 0 4 Jiro 19910510 1 5 Maki 19880117 BETWEEN句:idが2~4を抽出 id name data 0 2 Rena 19921015 1 3 Masa 20050505 1 4 Jiro 19910510 IN句:nameカラムでMasaなのをピンポイント抽出 id name date 0 3 Masa 20050505 GLOB句:nameカラムで「Ma」とつくものを抽出 id name date 0 3 Masa 20050505 1 5 Maki 19880117 3-2.ORDER BYでソート 昇順(ASC)と降順(DESC)で選択可能 display_markdown('idカラム昇順', raw=True) display(pd.read_sql_query('SELECT * FROM test1 ORDER BY id ASC', con).head(2)) display_markdown('idカラム降順', raw=True) display(pd.read_sql_query('SELECT * FROM test1 ORDER BY id DESC', con).head(2)) idカラム昇順 id name date 0 0 Bob 19980108 1 1 Taro 19980810 idカラム降順 id name date 5 5 Maki 19880117 4 4 Jiro 19910510 3-3.UPDATEで値を更新する id=0のBobを最初に失敗したBobbyのデータにidはそのままで置き換える。 ※名前と生年月日を入れ替える。 #SELECTでないので、カーソルオブジェクト使用。 cur.execute('UPDATE test1 SET name="Bobby", date="19880116" WHERE id=0') #確認はread_sql_queryで display(pd.read_sql_query('SELECT * FROM test1', con).head(2)) id name date 0 0 Bobby 19980116 1 1 Taro 19980810 3-4.ALTER TABLEでカラムを追加する 新しく「age」カラムを追加する。 初期値は何も指定しないとNoneになる。(None以外にも指定できるが同じ値しか入れられない) なお、各箇所に値を入れる方法は私はこれしか知らないが、もっといい方法あったらぜひ教えてください! #新しくageカラムを追加 display_markdown('ageカラム挿入後初期状態', raw=True) cur.execute('ALTER TABLE test1 ADD age integer') display(pd.read_sql_query('SELECT * FROM test1', con).head(2)) #追加したageカラムにUPDATEを使用してデータを更新 data = [33, 41, 29, 16, 30, 33] for i,row in enumerate(data): cur.execute('UPDATE test1 SET age = (?) WHERE id=(?)', [row, i]) display_markdown('ageカラムに値を代入後', raw=True) display(pd.read_sql_query('SELECT * FROM test1', con).head(2)) ageカラム挿入後初期状態 id name date age 0 0 Bobby 19980116 None 1 1 Taro 19980810 None ageカラムに値を代入後 id name date age 0 0 Bobby 19980116 33 1 1 Taro 19980810 41 3-5.カラムの削除 これはめんどくさい方法をしないとSQLiteの場合はなぜかできない。 よって今一番簡単だと考えている方法を書いておく。 まずはサンプルカラムを追加する(後で消す) #新しくage2カラムを追加 cur.execute('ALTER TABLE test1 ADD age2 integer') pd.read_sql_query('SELECT * FROM test1', con).head(2) id name date age age2 0 0 Bobby 19980116 33 None 1 1 Taro 19980810 41 None このage2カラムを削除するのに簡単なのは「DB Browser for SQLite」を使用する方法である。 下図のようにテーブルの変更からage2を選んで削除すれば消すことが出来る。 #age2カラムが消えたか確認 ※削除作業後 pd.read_sql_query('SELECT * FROM test1', con).head(2) 確かに消えていることがわかる。これが一番簡単だと思います。 id name date age 0 0 Bobby 19980116 33 1 1 Taro 19980810 41 3-6.GROUPBYでグループ化 いわゆるグループ化をやってみる。 今回は追加したageカラムをグループ分けする。33歳の人が2名いることが注目? display_markdown('GROUPBY句でage別に表示', raw=True) display(pd.read_sql_query('SELECT age, COUNT(*) AS Count FROM test1 GROUP BY age', con)) display_markdown('HAVING句でさらにGROUPBY後にカウント2以上を抜粋', raw=True) display(pd.read_sql_query('SELECT age, COUNT(*) AS Count FROM test1 GROUP BY age HAVING COUNT(*) = 2', con)) GROUPBY句でage別に表示 age Count 0 16 1 1 29 1 2 30 1 3 33 2 4 41 1 HAVING句でさらにGROUPBY後にカウント2以上を抜粋 age Count 0 33 2 3-7.JOINでテーブルの結合 テーブル同士の結合を行う。 今回はtest1とtest2テーブルで共通のidを使用して横に結合させる。 結合のやり方はいくつかあるが、今回は2個だけ紹介する。 まずは結合前のテーブルを今一度確認しておく display_markdown('test1テーブルを表示', raw=True) display(pd.read_sql_query('SELECT * FROM test1', con)) display_markdown('test2テーブル', raw=True) display(pd.read_sql_query('SELECT * FROM test2', con)) test1テーブルを表示 id name date age 0 0 Bobby 19980116 33 1 1 Taro 19980810 41 2 2 Rena 19921015 29 3 3 Masa 20050505 16 4 4 Jiro 19910510 30 5 5 Maki 19880117 33 test2テーブルを表示 id sex height 0 0 Man 179.5 1 1 Man 191.1 2 2 Woman 161.2 3 3 Man 171.7 4 4 Man 156.9 5 5 Woman 188.0 確認が終わったので結合をしていく。 自然結合の場合、同じカラム名を自動抽出してくれる+結合後にidがダブってないのでおすすめです。 長いので再び2行だけの表示です #結合 display_markdown('INNER JOIN結合', raw=True) display(pd.read_sql_query('SELECT * FROM test1 INNER JOIN test2 ON test1.id = test2.id', con).head(2)) display_markdown('自然結合', raw=True) display(pd.read_sql_query('SELECT * FROM test1 NATURAL INNER JOIN test2', con).head(2)) INNER JOIN結合 id name date age id sex height 0 0 Bobby 19980116 33 0 Man 179.5 1 1 Taro 19980810 41 1 Man 191.1 自然結合 id name date age sex height 0 0 Bobby 19980116 33 Man 179.5 1 1 Taro 19980810 41 Man 191.1 4.Jupyterで直接SQL命令を扱う 今までとは違って、jupyterで直接SQL命令を書く方法も記載しておく。 ただしpip install ipython-sqlでまずはインストールが必要。(jupyterでやるなら先頭に!つける) # !pip install ipython-sql %load_ext sql #jupyterでSQL使えるようにするコマンド %sql sqlite:///test2.db #.dbのあるpathを指定する。今回はjupyterと同じ階層のケース これで何も出力されなければDBが読み出せている。 後はマジックコマンド%%sqlに続けてSQL命令を書くときちんと表示されていることがわかる。 #test1テーブルを表示 %%sql SELECT * FROM test1 sqlite:///test2.db Done. id name date age 0 Bobby 19980116 33 1 Taro 19980810 41 2 Rena 19921015 29 3 Masa 20050505 16 4 Jiro 19910510 30 5 Maki 19880117 33 #test1テーブルとtest2テーブルの自然結合を表示 %%sql SELECT * FROM test1 NATURAL INNER JOIN test2 sqlite:///test2.db Done. id name date age sex height 0 Bobby 19980116 33 Man 179.5 1 Taro 19980810 41 Man 191.1 2 Rena 19921015 29 Woman 161.2 3 Masa 20050505 16 Man 171.7 4 Jiro 19910510 30 Woman 156.9 5 Maki 19880117 33 Woman 188.0 5.さいごに 自分の備忘録も兼ねるためにちょっと長くなったが、いかがだっただろうか? 前回の記事と合わせれば基本的な箇所は抑えられていると思う。 参考になったと思ったらLGTM、ストックをモチベ維持の為にもぜひお願いします。 それでは今回はここで終わります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SQLAlchemyで既存のDBからモデルを作る方法

Djangoならこちらの方法があるんですが https://docs.djangoproject.com/ja/3.1/howto/legacy-databases/ それ以外の場合に少し困ったのでこちらに備忘録として書いておきます。 sqlacodegen インストール pip install sqlacodegen 使用例 sqlacodegenの後にSQLAlchemyで使用するDatabaseURLを記載します。 下記はpostgresqlの例です。 sqlacodegen postgresql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}/{DB_NAME} > models.py
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ポリゴン加工における刃の挙動

概要 ポリゴン加工 工作機械で行う旋削加工の一つに、ポリゴン加工という方法があります。 刃物とワーク(加工対象物)の回転比を2:1にして削るとワークを多角形に加工できるというもので、多角形の加工を非常に効率的に行える加工です。 イメージはこちらなどがわかりやすいです。 http://www.nittopolygon.com/01polygon.html 刃をn枚配置すると2n角形ができます。 やりたい事 この加工を知った時は回転だけで綺麗な多角形が削れることに感動したのですが、 なぜ回転運動だけで直線が加工できるのか。そもそも本当に直線なのか。 回転比2:1という値に数学的な意味があるのか 奇数角形はできないのか など疑問が湧いてきたので刃の挙動を描画してみることにしました。 刃の挙動を求める式 元になる情報 こちらの方がすでに同じ事をされているので基本的にこれを見ればいいのですが、自分の理解のため少し順を追って説明します。またMathmaticaを使っているようなので、Pythonで再実装してみます。 https://fyang2.stanford.edu/hardware/polygon-turning.html 式 刃がワークに対してどう動くかを考えたいので、ワークの座標を固定し、その場合の工具の刃の挙動を考えます。 ワークの回転中心と工具の回転中心の距離 : R 工具の半径 : Rt ワークの回転角度 : θ 工具の刃の回転角度 : θt 回転比 : k(k=2の時、刃物とワークの回転比が2:1) とします。 その場合、工具の回転中心の座標は単純に Xtc = R * cosθ Ytc = R * sinθ です。これは簡単。 次は刃の位置ですが、工具の回転中心からの座標は以下となります。 Xt = Rt * cosθt Yt = Rt * sinθt したがって刃の軌跡はXtc+Xt, Ytc+Ytとなり、以下で表せます。 X = R * cosθ + Rt * cosθt Y = R * sinθ + Rt * sinθt ここでθtをθで表す必要があります。結論から言うとθt = -(k-1)θとなりますが、これについて説明します。 まずマイナスが付くのは、ポリゴン加工時のワークと工具の回転方向が逆になるためです。 k-1についてですが、 回転比が同じ場合(k=1の場合)、ワークを中心に考えると工具側は自転していない様に見えます。なので常に0*θ=0となります。k=2の時に初めて1回転している様に見えます。(= -θ)。同様に3,4,5...と増えていくと、-2*θ、-3* θ、-4* θ...という風に増えていくことになります。 もう少しちゃんとした説明があると思いますが、ひとまずその様な理屈でθt=-(k-1)θとなります。 したがって、刃の軌跡は以下となります。 X = R * cosθ + Rt * cos(-(k-1)θ) Y = R * sinθ + Rt * sin(-(k-1)θ) 刃先が複数の場合 工具には等間隔に刃先を複数枚つけられます。それも考慮に入れます。 刃先の数をnとするとi番目の刃先の位置は 2π*i/n分だけ位相がずれるので、 Xi = R * cosθ + Rt * cos(-(k-1)θ + 2π*i/n) Yi = R * sinθ + Yt = Rt * sin(-(k-1)θ+ 2π*i/n) となります。 実装 これらを元にpython(jupyter notebook)で実装してみます。 まず必要なモジュールのインポート notebook %matplotlib inline import matplotlib.pyplot as plt import numpy as np グラフを書く処理を一部関数化します。 notebook def create_ax(xlim, ylim): """ matplotlibのfig,axを作成して返す。figsizeは固定。 """ fig = plt.figure(figsize=(6,6)) ax = fig.add_subplot(111) ax.grid() ax.set_title("Polygon orbit") ax.set_xlim(xlim[0],xlim[1]) ax.set_ylim(ylim[0],ylim[1]) return fig, ax def draw_data(ax,x,y, color="blue"): """ 与えられたx,yをaxに描画。ついでに原点も描画。 """ ax.set_xlabel("x", fontsize=16) ax.set_ylabel("y", fontsize=16) ax.plot(x,y,color=color) ax.scatter(0,0,color="black") 主役の刃の軌跡を返す関数。前段で導出した式を使います。ついでに円の軌跡を返す関数も追加。 notebook def circle_data(R, theta): """ θが与えられた場合の、円のx,y座標を返す。 """ x = R * np.cos(theta) y = R * np.sin(theta) return x, y def poly_data(R,Rt, k, theta, n=1,i=0): """ θが与えられた場合の、刃の軌跡のx,y座標を返す。 """ d = 2 * np.pi * i / n # 位相の算出 x = R* np.cos(theta) + Rt * np.cos(-(k-1)*theta +d) y = R* np.sin(theta) + Rt * np.sin(-(k-1)*theta +d) return x, y 上記の関数を使ってグラフを描画する関数 notebook def plot_orbit(R, Rt, k, n): """ 工具中心の軌道と、刃の軌道を描画 """ d=4 #描画範囲 c=129 # データ数。適当で良い。 _, ax = create_ax((d,-d),(d,-d)) # ax生成 # ワーク一周分のデータを作成。 theta = np.linspace(0, 2*np.pi, c) # c個のデータを、0-2πまで均等に生成 x,y = circle_data(R, theta) #工具中心の軌道(円)。 draw_data(ax,x,y) # 描画 # 刃数nの分だけ軌跡を描画 for i in range(n): x,y = poly_data(R, Rt, k, theta, n, i) draw_data(ax, x, y , color="red") あとはパラメーターを設定して呼び出すだけ。 notebook params ={ "R":2, # ワークと工具中心の距離 "Rt":1.5, # 工具の半径 "k": 2, # 回転比 "n":3, # 刃の数 } plot_orbit(**params) 結果 パラメータを変化させた結果を確認します。 赤が刃の軌跡、青が工具中心の軌跡です。 k=2の場合 回転比2:1で固定して刃の数を増やして行った場合です。 k=2, n=1の場合: k=2, n=2の場合: k=2, n=3の場合: 赤が刃の軌跡なのでこの最内で切り取られた部分が切削面になります。 これらを見ると軌道は直線ということは無く、楕円(に似た)形のより平坦な箇所が切削面になっている様です。 その他 k=3, n=1とすると三角形もできそうです。これは凹型になります。 またR,Rtを変えても形が色々と変わります。 考察 刃の軌跡について これをみると、刃は直線を描いているわけではなく、楕円(に似た)形の長辺部分が切削面となっています。厳密には直線ではないけど、用途によっては許される範囲の精度で加工ができる、ということの様です。 工具の半径が大きいとより直線に近づきます。 回転比kについて 上とも重複しますがk=2(回転比2:1)だと直線になる、と行った特別な意味は無い様です。 経験的に2:1が良いとされているのか、またはこの値が一番フラットに近くなるという結果が出ているのか、そこまでは調べきれていません。 奇数角形について x角形を作るには x = k * n となる様にすると良いので、特にk=2に固定しなければ、奇数角形もできます。 三角形の場合は (k, n ) = (3,1), (1.5, 2)などの組み合わせが考えられます。 実用になるかは、この曲線が加工精度として許せるかどうかという事になるでしょうか。 まとめと雑感 グラフで描画することにより、ポリゴン加工の動作がより直感的に理解できた気がします。 回転比2:1というのは、数学上の特別な値ではなく、加工において効率と精度をバランスよく実現するために採用された値だという理解です。 理屈上、k, n, R, Rtがわかれば、切削面が直線に対してどれくらい乖離するかを計算でき、加工する前に精度を計算可能だと思うのですが、現状そこまでは手が出せてません。 おまけ より軌道を理解するため、アニメーション版も作ってみました。 が、微妙に動作しなかったりします。 notebook %matplotlib nbagg from matplotlib import animation R=2 Rt=1.5 k=2 n=4 d=4 #描画範囲 c=129 # データ数 fig, ax = create_ax((d,-d),(d,-d)) x, y = [],[] x_p = [[] for _ in range(n)] y_p = [[] for _ in range(n)] def _update(frame): ax.grid() x1,y1 = circle_data(R, frame) x.append(x1) y.append(y1) ax.plot(x, y, color="blue") for i in range(n): x1,y1 = poly_data(R,Rt,k,frame, n,i) x_p[i].append(x1) y_p[i].append(y1) ax.plot(x_p[i], y_p[i], color="red") params= { "fig": fig, "func": _update, "interval": 20, "frames": np.linspace(0, 2*np.pi, c), "repeat":False, } anime = animation.FuncAnimation(**params)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Python3 エンジニア認定基礎試験に合格した話

自己紹介 みなさん、はじめまして。 Web開発エンジニアを目指している、インフラエンジニア歴7年目の者です。 初投稿なので、備忘録として資格合格した話を書いていこうと思います。 技術的な深い話はなく、かつ拙い文章になるかと思いますので、ご覧いただいた方は暖かい目で見てください。。 概要 今回受験した資格試験は、冒頭の通り「Python3 エンジニア認定基礎試験」になります。 Pythonを扱う、またはこれからPythonを使って仕事をしていきたいという方々が目指す初心者向けの資格になるかと思います。 試験の詳細についてはこちらを参照してください。 結論から申しあげると、当方は知識ゼロから合格するまでに1か月程度あれば合格できるレベルでした。 公式のチュートリアルやWeb模擬問題集などの試験対策がすべて無料で活用できるため、経済的にも受験しやすい資格です(ただし受験料だけが11,000円(税込)と微妙に高い。。。)。 そんなかんじで、資格取得したい方は受験料に目を瞑って勉強頑張っていきましょう。 試験当日までの手続き 資格試験の受験するための前準備として、以下のステップが必要になります。 ①試験会場の申し込み  ・・・お近くの試験会場を探して申し込みをするだけなのですが、試験会場によって空いている日時が違ったりするので、早めに試験スケジュールを確認することを推奨します。 ②Odyssey IDの登録  ・・・試験日までに登録が必要となり、試験当日に「Odyssey ID」と「パスワード」が必要になるので忘れないようにしましょう。 ③試験当日の持ち物  ・・・「写真付き身分証明書」と「受験票」を忘れないように持っていきます。     中には「受験票」が発行されない試験会場もあるので、電話等で確認してみましょう。     (当方は発行されない試験会場でした) 詳しくは概要欄で書いた試験の詳細の参照先にある「受験の流れ」を確認してください。 試験当日までの勉強方法 それでは、勉強方法について書いていきます。 使用教材 使用する教材(教科書)については一つだけ、以下を読み込みましょう。 Python ver3.5 チュートリアル ※2021/5/10時点ではver3.5が試験範囲となっていますが、今後変更する可能性はあるため注意してください。 このチュートリアルは試験範囲そのものなので、出題率の高い章から重点的に勉強していきましょう。 出題率は、概要欄で書いた試験の詳細の参照先にある「試験科目」>「Python 3 エンジニア認定基礎試験」>「出題範囲」から確認してください。 ただし、読み込むだけで頭に入らない方は実際に同バージョンのPythonをPCにインストールして、テキストの内容を検証していくと理解しやすくなるのでおすすめです。 Pythonインストール方法は、以下を参考にしてください。 Python環境構築ガイド 使用模擬問題 使用する模擬問題については二つ、以下を周回しましょう。 DIVE INTO EXAM PRIME STUDY 基礎と応用の問題がうまく散りばめられているので、最初は1問ずつ丁寧に解いていくと良いかと思います。 慣れてきたら、実際の試験時間に合わせて問題を解いていくことでより合格に近づけるはずです。 あとがき ここまで「Python 3 エンジニア認定基礎試験」の備忘録を書いてみました。 決して難しくない資格なので、やる気と受験料さえ出せれば問題なく合格できるはずです。 少しでも合格を目指している方のお力になれれば幸いです。 当方もまだまだプログラミングに足を踏み入れたばかりなので、Web開発エンジニアを目指している方々と一緒に頑張りたいと思います。 というわけで、拙い文章でしたがご覧いただきありがとうございました。 明日はなんの勉強しよっかな。。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

駆け出しpythonエンジニアのまとめ デザインパターンまとめ5(singleton)

趣旨 駆け出しエンジニアの備忘録の垂れ流し。  ※ 出典漏れがあればご指摘ください 出典: https://yamakatsusan.web.fc2.com/ https://dackdive.hateblo.jp/ https://www.oreilly.co.jp/books/9784873117393/ singletonパターン概要 生成に関するデザインパターンの1つ。 あるクラスのインスタンスが1つしか生成されないように制限する、あるいは1つしか生成されないことを保証する。 DB connectionなどに利用するケースが多い. 実装方針 Singletonクラスをスーパクラスとして実装。インスタンスを取得するメソッド(get_instance)を実装。 get_instanceの記載はほぼテンプレ化しているっぽいのでいずれかの方法で利用 Singletonサブクラスでは実処理(やりたいこと)を記載。 補足 pythonではインスタンス生成の際、__new__メソッドが呼ばれる。引数として、第一引数に生成するクラスと、以降に適切な引数を定義して、__init__メソッドに渡される。 ただし、__new__メソッドがインスタンスを返さない場合、__init__メソッドは呼び出されない。 __init__メソッドから非None値を返してはいけない、 __init__は__new__で生成されたインスタンスをカスタマイズするようなふるまいのため、非Noneが変えるとTypeErrorになる。 また、サブクラスが__init__メソッドを持つ場合、インスタンスの基底クラス部分が適切に初期化されること保証する必要があるため、super().__init__([args...])のような記載が必要なる、らしい。 super() は 親クラスを参照する場合に利用する。第一引数にはクラス、第二引数にはインスタンスを指定することができる。 実装例 # https://yamakatsusan.web.fc2.com/pythonpattern05.htmlより引用 # 書き方1 class Singleton: def __new__(cls, *args, **kwargs): # args,kwargsとしておけば使い回せるのでこうしているが、明確に書くなら避けるべき if not hasattr(cls, "__instance"): cls.__instance = \ super(Singleton, cls).__new__(cls, *args, **kwargs) return cls.__instance # 書き方2 class Singleton: @classmethod def get_instance(cls, *args, **kwargs): if not hasattr(cls, "_instance"): cls._instance = cls(*args, **kwargs) return cls._instance # 書き方3 class Singleton: _instance = None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs) return cls._instance # 書き方4 class Singleton(object): _instances = dict() def __new__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] = object.__new__(cls, *args, **kwargs) return cls._instances[cls] # サブクラス class DBConnection(Singleton):   def __init__(self): self.connection = get_connection() def get_connection_state(self): hoge() # client側 def main(): connection = DBConnection() or connection = DBConnection.get_instance() signletonはアンチパターンらしい 問題点 グローバル変数と同義のため 複数インスタンス化出来た方が良い事が分かった際の影響が絶大 依存関係を見えにくくし、コードが読みづらくなる。 singletonクラスを利用するコードのユニットテストが難しくなる。(外部から渡せないオブジェクトはモックにする事が難しい。) 解決策 状態を初期化できるようにする⇛singletonクラスのテストを楽にする 依存性の注入 (Dependency Injection) の利用⇛singletonクラスを利用するコードのテストを楽にする 本当にあるクラスのインスタンスが1つしか生成されないように制限する、あるいは1つしか生成されないことを保証するのか、再度設計を見直す(Singletonを採用しない) 引用元:https://qiita.com/mo12ino/items/abf2e31e34278ebea42c 実装例2 class Singleton: def __new__(cls, *args, **kwargs):    # args,kwargsとしておけば使い回せるのでこうしているが、明確に書くなら避けるべき if not hasattr(cls, "__instance"): cls.__instance = \ super(Singleton, cls).__new__(cls, *args, **kwargs) return cls.__instance # サブクラス class DBConnection(Singleton):   def __init__(self): self.connection = get_connection() def refresh(self): self.connection = None def get_connection_state(self): hoge() # client側 def main(connection: DBConnection): connection.get_connection_state() # test1: main側のテスト def test_main() with patch('DBConnection', spec=DummyConnection) as dc: assert main(dc) # test2: DBconnectionクラスのメソッドのテスト def test_db_connection1(): connect = DBConnection() assert connect def test_db_connection2(): connect = DBConnection() connect.refresh() assert not connect メリットと使い所 あるクラスのインスタンスが1つしか生成されないように制限する、あるいは1つしか生成されないことを保証する。 そんな状況を実装する場合に使う
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

S3ファイルの大量コピーは、AthenaのINSERT INTOでやると高速(1案として)

s3で、大量のファイル(10万とか)をコピーしたい時、どうされていますか? *ディレクトリ名をちょっと変えたいとかで、大量のディレクトリとファイルがある場合 boto3でプログラム組んで、コピーしようとしたら、ゾッとする遅さでした。 管理コンソール上で数秒で終わるコピーが、何分もかかるとは、思わなかった・・・ 今回の方法は、やや制約(gzipになる、HIVE形式でディレクトリ出力される)は発生しますが、同じ溝にはまった人はご参考までに。 s3で大量コピー:boto3(python)の場合 boto3 pythonで実行したところ、100ファイルごとに30秒前後かかっていて、震えました。。。 目の前の25万ファイルを目にして。 30秒×25万ファイル=2083時間 = 87日 もかかる・・・ Athenaでやってみた どうしようか、、、と考えて、思いついた方法 「AthenaのINSERT INTOを使おう!」 という話です。 [手順] (1) COPY元のテーブルを作成   (ディレクトリをパーティションに指定) * コツ: テーブルカラムはstringに統一した方が面倒がないかも (2) COPY元のパーティションを追加してください。 MSCK REPAIR TABLEは超遅いから、 ALTER TABLEでやりましょう。 例えば、日付("dt", YYYYMMDD形式)をパーティションキーにする場合のコードを載せておきます。 from datetime import datetime , timedelta start_day = datetime.strptime('2020-10-15','%Y-%m-%d') #例えば2020/10/15 ~ last_day = datetime.strptime('2021-05-10','%Y-%m-%d') # 2021/5/10までのデータをコピーする時 q = 'ALTER TABLE old_table ADD IF NOT EXISTS' # q に ALTER TABLEが入る part = " PARTITION (dt='{dt}') LOCATION 's3://bucket/path/to/{dt}/'" dts = [] # ここには、100パーティションの "dt in ({parttion})" に指定するリストが入る key = [] ctr = 0 while start_day.timestamp() <= last_day.timestamp(): ctr +=1 d = start_day.strftime('%Y%m%d') q += part.format(dt=d) key.append("'{}'".format(d)) start_day += timedelta(days=1) if ctr >=100: dts.append(",".join(key)) key = [] ctr = 0 if ctr >0: dts.append(",".join(key)) (3) COPY先のテーブルを作成   (ディレクトリをパーティションに指定)  * [制約]HIVE形式( /dt=xxxx/ になる)  * [制約]出力はgzip形式になる    (4) パーティション数が100以上になる場合は、100単位で分割 Athenaは一気に100パーティション以上扱えないらしい。  だから、パーティション100個分ずつ、実行する必要がある。 (5) INSERT INTOを実行 ・一応重複がないように、ファイル名が一致したら取り込まないようにする [追記/訂正] こちら、new."$path"としてますが、ファイル名変わるのでカラムとして取り込まないとダメでした。すいません。 INSERT INTO new_table (select old.* from old_table as old left join new_table as new on egexp_extract(old."\$path", '[^/]+$') = regexp_extract(new."\$path", '[^/]+$') where new."$path" is null and dt in ('20201015','20201016' ) [結果] -> ざっくりですが、250ディレクトリ、 25万件ほどのファイルコピーが実行3回(合計、15分くらい)で終わった。 よかった。。。 Athenaって便利ですね。 他にも方法があるのかもしれませんが。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

li = li.reverse()は間違いです (今日のPython Day10)

0. はじめに  今日は思いつかなかったので省略。早速問題を解きましょう! 1. 問題  太郎くんは、リストli = [1, 2, 3, 4, 5]を逆順にするために次のようなコードを書いた。しかし実行結果は逆順にならず「None」と出力されてしまった。太郎くんに代わってコードを直そう。 太郎くんのコード li = [1, 2, 3, 4, 5] li = li.reverse() print(li) # -> None 2. 解答例 li = [1, 2, 3, 4, 5] li.reverse() print(li) 3. 解説  li.reverse()単体にします。li = li.reverse()としてはいけません。これはappend()など割と初期に習うメソッドも同様です (全てのメソッドがこうとは限らない)。reverse()の戻り値はNoneなので太郎くんのように書いてしまうと左辺のliに逆順した結果ではなくreverse()の戻り値が代入されてしまうのだと思います (違っていたらごめんなさい)。 4. まとめ ・li.reverse()単体でOK。 5. おまけトーク  毎日YouTubeに動画を投稿する人ってすごいですよね。毎日投稿してネタがつきないなんて。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【BacklogAPIレート制限対応】ユーザーごとのAPIレートの監視をする仕組みを作った

背景 2021年7月末からBacklog APIに対するレート制限が実装される。 レート制限に関するブログ : https://backlog.com/ja/blog/backlog-api-rate-limit-announcement/ このレート制限は、APIの種類ごと・ユーザー単位・分単位での制限となる。 この対応のために、まずBacklog APIを利用している各サービスでのAPI利用状況を把握し影響箇所を調査する必要がある。 方法 「レート制限情報の取得」APIが用意されている。このAPIを利用することで、その時点のAPI利用状況が把握できる。 https://developer.nulab.com/ja/docs/backlog/api/2/get-rate-limit/# ただし、得られる情報はAPIのリクエストを送った時点の情報のみであり、特定期間内における利用状況を把握するためには、その期間中に定期的にこのAPIを実行し情報を取得する必要がある。 そのために、以下の簡易な監視システムを構築した。 監視システム リポジトリ 作成したものは以下のリポジトリに格納。 ソースコード等はこのリポジトリを参照 仕様・注意事項 調査したいBacklogユーザーのAPIキーを使い、レート制限情報の取得APIを定期実行して利用状況を把握する https://developer.nulab.com/ja/docs/backlog/api/2/get-rate-limit/# 取得した情報はCloudWatchメトリクスにカスタムメトリクスとして値を格納し、ダッシュボードでグラフを参照できるようにする。 上記構成図の通り、バッチ処理はLambda + Eventbridgeで構成。 取得頻度は 約5秒 Lambdaは1分毎に実行される。コード内で5秒置きに取得するように実装。 値の精度 Lambdaの重複実行に対する冪等な実装はしていない。 レート制限情報を取得する時間とメトリクスを作成する時間同じになるよう実装していないため、ms単位での誤差がある。 以上のように 完全に正確な値であるとは保証されないが、利用状況の傾向や大幅なリクエスト増加を見る前提で、この精度で十分であると判断する。 このレート情報取得自体にreadが使われるため、readの値にはその分が上乗せされたで状態で集計される メトリクス仕様 Namespace : BacklogApiRate メトリクス名 説明 Limit 制限数 Remaining 制限残数 (残り利用可能なリクエスト数) Usage 利用数。Limit - Remaining ディメンション 説明 ApiKey 対象のAPIキーの先頭5文字 ApiType 対象のAPI種別。read = 読み込み , update = 更新 , search = 検索 , icon = アイコン。 詳細 ダッシュボードを別途作成 収集したメトリクスをダッシュボード化して可視化。ダッシュボードは上記デプロイ後、別途作成。 作成例 まとめ 簡易ではあるが、傾向を把握するのには十分な精度で利用状況を可視化することができた。これを元に影響箇所を調査し対応することとした。 ただし、複数のワークロードにまたがって1つのユーザーをAPIに利用されていることもあるため、できればAPIキー単位でレート情報を取得できれば嬉しかった。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【保留】Power Automate Desktopがなんとなく使える講座 番外編 Pythonのライブラリを調べる

(執筆 2021/5/10)  Power Automate DesktopでPythonが使えるようになっていますが、どのような環境なのか確認します。 Python環境 Pythonのバージョン Pythnスクリプトの実行 import sys print(sys.version) 出力 2.7.9 (IronPython 2.7.9 (2.7.9.0) on .NET 4.0.30319.42000 (64-bit)) Pythonスクリプトの実行 import sys print(sys.platform) 出力 cli  IronPython2.7.9は2018年10月9日にリリースされました。Python2のサポートは終了しており、IronPython3.4が2021年4月20日にリリースされているので、近々メジャーバージョンが変わると思います。 ビルトインモジュール  コンパイル時に組み込まれたPythonモジュールです。 Pythonスクリプトの実行 import sys print(sys.builtin_module_names) モジュール名 imp sys unicodedata _ast clr exceptions future_builtins array binascii bz2 cmath copy_reg cPickle cStringIO datetime errno gc _md5 _sha _sha256 _sha512 itertools marshal math mmap msvcrt nt operator pyexpat re select signal thread time winsound xxsubtype zipimport zlib _bisect _codecs _collections _csv _ctypes _ctypes_test _functools _heapq _io _locale _random _socket _sre _ssl _struct _subprocess _warnings _weakref _winreg) Pythonのインストールディレクトリ  Python のプラットフォーム依存なファイルがインストールされているディレクトリ名です。 Pythonスクリプト実行 import sys print(sys.exec_prefix) 出力 file:///C:/Program Files (x86)/Power Automate Desktop/IronPython.DLL Pythonの外部モジュール使用  組み込まれていないモジュールを使いたい場合は、IronPythonのサイトから IronPython.2.7.11.zip をダウンロードして解凍します。 Pythonスクリプトの実行で、モジュールフォルダパスに、解凍した中にあるLibフォルダの場所を入れれば、モジュールを使うことができます。  その他、Numpyなどのパッケージをインストールするには ironpkg-1.0.0.py を使って行うという情報がありますが、このファイルがダウンロードできるサイトが消えてしまっているようです。 VBScriptのバージョン VBScriptの実行 WScript.Echo "Major: " & ScriptEngineMajorVersion & vbCrLf & _ "Minor: " & ScriptEngineMinorVersion & vbCrLf Major: 5 Minor: 8
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Power Automate Desktopがなんとなく使える講座 番外編 Pythonのライブラリを調べる

(執筆 2021/5/10)  Power Automate DesktopでPythonが使えるようになっていますが、どのような環境なのか確認します。 Python環境 Pythonのバージョン Pythnスクリプトの実行 import sys print(sys.version) 出力 2.7.9 (IronPython 2.7.9 (2.7.9.0) on .NET 4.0.30319.42000 (64-bit)) Pythonスクリプトの実行 import sys print(sys.platform) 出力 cli  IronPython2.7.9は2018年10月9日にリリースされました。Python2のサポートは終了しており、IronPython3.4が2021年4月20日にリリースされているので、近々メジャーバージョンが変わると思います。 ビルトインモジュール  コンパイル時に組み込まれたPythonモジュールです。 Pythonスクリプトの実行 import sys print(sys.builtin_module_names) モジュール名 imp sys unicodedata _ast clr exceptions future_builtins array binascii bz2 cmath copy_reg cPickle cStringIO datetime errno gc _md5 _sha _sha256 _sha512 itertools marshal math mmap msvcrt nt operator pyexpat re select signal thread time winsound xxsubtype zipimport zlib _bisect _codecs _collections _csv _ctypes _ctypes_test _functools _heapq _io _locale _random _socket _sre _ssl _struct _subprocess _warnings _weakref _winreg) Pythonのインストールディレクトリ  Python のプラットフォーム依存なファイルがインストールされているディレクトリ名です。 Pythonスクリプト実行 import sys print(sys.exec_prefix) 出力 file:///C:/Program Files (x86)/Power Automate Desktop/IronPython.DLL Pythonの外部モジュール使用  組み込まれていないモジュールを使いたい場合は、IronPythonのサイトから IronPython.2.7.11.zip をダウンロードして解凍します。  Pythonスクリプトの実行で、モジュールフォルダパスに、解凍した中にあるLibフォルダの場所を入れれば、モジュールを使うことができます。 ironpkg が使えない  その他、Numpyなどのパッケージをインストールするには ironpkg-1.0.0.py を使って下記のように行うという情報が多数あります。(ここ)  IronPython.2.7.11\net45 のフォルダにironpkg-1.0.0.pyをセットし、以下のコマンドを実行します。 ipy -V PythonContext 2.7.0.40 on .NET 4.0.30319.225 ipy ironpkg-1.0.0.py --install ..\ironpkg scipy numpy-2.0.0b2-1.egg  以下のメッセージが出て、成功しません。無くなってるサイトのフィルを見に行こうとしてるためだと思います。 Python 2.7 のライブラリはうまく動かない  別の手段として、普通の Python 2.7 をインストールして、pipで落としてきたライブラリを使う方法も試しましたが、うまく動きませんでした。  ちなみに、モジュールパスは、1つだけなら、フォルダ名をそのまま入力すればよいのですが、複数を使いたい場合は、リストにして渡します。 VBScriptのバージョン VBScriptの実行 WScript.Echo "Major: " & ScriptEngineMajorVersion & vbCrLf & _ "Minor: " & ScriptEngineMinorVersion & vbCrLf Major: 5 Minor: 8
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[python] リストの特定の要素がいくつ含まれるかをカウントする

背景 ある要素がリスト内にいくつ含まれるのかを知りたいと思ったが、collections.Counterだと要らないのも出てきちゃうなぁと思い、ググってcountメソッドの存在を知った(恥)。 結論 どれか1つ特定の要素のカウントを知りたい場合 some_list = ['foo', 'bar', 'baz', 'bar', 'qux', 'bar', 'bar'] print(some_list.count('bar')) # 4 複数の要素のカウントを知りたい場合 from collections import Counter some_list = ['foo', 'bar', 'baz', 'bar', 'qux', 'bar', 'bar'] print(Counter(some_list)) # Counter({'bar': 4, 'foo': 1, 'baz': 1, 'qux': 1}) print(Counter(some_list)['bar']) # 4 collections.Counterクラス(dictのサブクラス)として得られます。 print(issubclass(type(dict(Counter(some_list))), dict)) # True
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AtCoder Problems Hard No.61~70解説

Hard No.61 : C - 次のアルファベット C - 次のアルファベット 発想 アルファベットに割り当てられているアスキーコードを使うのが良さそうです。アルファベットのアスキーコードは$a$の97から$z$の122まで1ずつ増えていきます。文字列$s$を前から見ていって、その文字を$a$に変えられるか毎回判断していきます。 実装 アルファベットからアスキーコードへの変換はord()関数、逆向きの変換はchr()関数を使います。 操作は$K$回やり切らなければならないこと、そのとき変える文字は最後の1文字だけで良いことに気をつけます。 S = list(input()) K = int(input()) ans = '' #最後の1文字を除いて'a'に変換できるか見ていく for i in range(len(S)-1): if S[i] == 'a': ans += 'a' else: if K >= 123 - ord(S[i]): ans += 'a' K -= 123 - ord(S[i]) else: ans += S[i] #Kは大量に残っている可能性があるので26で割ったあまりを考える K %= 26 ans += chr((ord(S[-1])-97+K)%26+97) print(ans) Hard No.62 : D - Lamp D - Lamp 発想 現在地から4方向にマスが照らされるので、4方向を分けて計算して、最後にその和を取る方針にします。 実装 端の処理をしておく必要があります。現在地は重複して数えていますので、その分を引きます。 H, W = map(int, input().split()) S = [] for i in range(H): s = input() S.append(s) #左側に照らせるマスの個数 L = [] for i in range(H): L.append([0]*W) #右側に照らせるマスの個数 R = [] for i in range(H): R.append([0]*W) #上側に照らせるマスの個数 U = [] for i in range(H): U.append([0]*W) #下側に照らせるマスの個数 D = [] for i in range(H): D.append([0]*W) for i in range(H): for j in range(W): #壁マスは問答無用で0 if S[i][j] == '#': L[i][j] = 0 R[i][j] = 0 U[i][j] = 0 D[i][j] = 0 #端のマスの値を入れておく else: if j == 0: L[i][j] = 1 if j == W-1: R[i][j] = 1 if i == 0: U[i][j] = 1 if i == H-1: D[i][j] = 1 #端以外のマスに値を入れていく for i in range(H): for j in range(W): if S[i][j] == '.': if j > 0: L[i][j] = L[i][j-1] + 1 if i > 0: U[i][j] = U[i-1][j] + 1 #端以外のマスに値を入れていく for i in range(H-1, -1, -1): for j in range(W-1, -1, -1): if S[i][j] == '.': if j < W-1: R[i][j] = R[i][j+1] + 1 if i < H-1: D[i][j] = D[i+1][j] + 1 Ans = [] for i in range(H): Ans.append([0]*W) for i in range(H): for j in range(W): if S[i][j] == '.': #4方向のマスの値の和から重複して数えた現在地の分を引く tmp = L[i][j] + R[i][j] + U[i][j] + D[i][j] - 3 else: tmp = 0 Ans[i][j] = tmp ans = 0 for i in range(H): ans = max(ans, max(Ans[i])) print(ans) Hard No.63 : C - こだわり者いろはちゃん C - こだわり者いろはちゃん 発想 $N$が10000未満です。支払う金額の最大値は99999です。$N$から99999まで順番に調べて初めて条件を満たす数字を答えとすれば良いです。 実装 import collections N, K = map(int, input().split()) D = list(map(int, input().split())) C = collections.Counter(D) for n in range(N, 10000): n = list(str(n)) for i in n: if C[int(i)] >= 1: break else: print(''.join(n)) exit() Hard No.64 : C - Bridge C - Bridge 発想 通らない辺を1つ決めた状態で深さ優先探索をして、到達不可の頂点があれば、その辺は橋です。これを$M$回実行すれば良いです。 実装 N, M = map(int, input().split()) G = [] for i in range(N): G.append([]) for i in range(M): a, b = map(int, input().split()) G[a-1].append(b-1) G[b-1].append(a-1) visited = [False]*N def dfs(k, i, j): visited[k] = True for l in G[k]: #通らないと決めた辺 if i == k and j == l: continue if not visited[l]: dfs(l, i, j) ans = 0 for i in range(N): for j in G[i]: #通らない辺i--jを決めた状態で深さ優先探索をする dfs(0, i, j) for m in range(N): #1つでも訪れなかった頂点があれば答えに1を足す if not visited[m]: ans += 1 break #visitedを初期化 visited = [False]*N print(ans) Hard No.65 : D - Card Eater D - Card Eater 発想 同じ整数が描かれたカードが2枚以上あってはいけないです。答えの最大値は整数の種類の数になります。食べなければならないカードの枚数が偶数の時は、全ての整数が1枚ずつ残り答えは最大値を取ります。奇数の時は1種類の整数が絶滅するので答えは最大値から1引いた数になります。 実装 import collections N = int(input()) A = list(map(int, input().split())) C = collections.Counter(A) tmp = 0 ans = 0 for c in C: if C[c] >= 2: tmp += C[c]-1 if C[c] >= 1: ans += 1 if tmp % 2 == 1: ans -= 1 print(ans) Hard No.66 : B - ABC B - ABC 発想 $s$を左から見ていって、'BC'が現れたら直前まで連続していた'A'を'BC'よりも右側に移動させます。例えば'AAAABC'の場合は4つの'A'を移動させますが、'AABAAABC'の場合は左側の2つの'A'は移動できません。 実装 'BC'があった場合は常に'BC'の塊で考えるので、'BC'を別の文字'D'に置き換えます。 S = input() S = S.replace('BC', 'D') ans = 0 ac = 0 for c in S: if c == 'A': ac += 1 elif c == 'D': ans += ac else: ac = 0 print(ans) Hard No.67 : D - Christmas D - Christmas 発想 レベル$L$のバーガーはレベル$L-1$のバーガーを使って表せるし、レベル$L-1$のバーガーはレベル$L-2$のバーガーを使って表せる。つまり、レベル$N$のバーガーをレベル$N-1$以下のバーガーを使って再帰的に表せる。レベルNのバーガーの厚さ$a_N$は a_N = 2a_{N-1}+3\\ \therefore a_N = 2^{N+2}-3 となる。 また、パティの枚数$p_N$は p_N = 2a_{N-1}+1\\ \therefore p_N = 2^{N+1}-1 となる。$X$の位置がバーガーの中心よりも下側か上側かで場合分けしていきます。 実装 N, X = map(int, input().split()) def dp(n, x): if x == 0: return 0 if n == 0: return 1 #xがバーガーの中心よりも下側の時 if x <= 2**(n+1) - 2: return dp(n-1, x-1) #xがバーガーの中心以上の時 else: return 2**n + dp(n-1, x-2**(n+1)+1) print(dp(N, X)) Hard No.68 : D - String Equivalence D - String Equivalence 発想 同型な文字列の中で辞書順最小の文字列が標準形です。同じ長さを持つ標準形の文字列を列挙した時、その中で辞書順最大の文字列に含まれる文字は全て異なります。例えば文字列の長さが3の時は$abc$になります。ということは、文字列の長さが1増えるごとに、文字列に含まれうる文字の種類は1増えます。 実装 文字列の長さが$N$になるまで文字列を長くしていき、$N$になったときに出力すれば良いです。 N = int(input()) def dfs(S): if len(S) == N: print(S) else: #文字列を長くするときに追加する文字は'a'から現在の最大値+1の文字まで for i in range(97, ord(max(S))+2): dfs(S + chr(i)) dfs('a') Hard No.69 : C - Align C - Align 発想 値が大きいものと小さいものを交互に並べれば最大値になりそうです。ただ、(大)(小)(大)(小)...と並べた場合と(小)(大)(小)(大)...と並べた場合で、どちらが大きくなるかわからないので、両方計算して大きい方を取ります。 実装 末尾の数字を先頭に持ってきた方が求める値が大きくなる場合があるので、その場合も検証します。 from collections import deque N = int(input()) A = [] for i in range(N): A.append(int(input())) A = sorted(A, reverse=True) A = deque(A) B = deque() for i in range(N): B.append(A[i]) Ans1 = deque() Ans2 = deque() #大きい値から始めて大きい値と小さい値を交互に並べる while len(A) > 0: up = A.popleft() Ans1.append(up) if len(A) > 0: down = A.pop() Ans1.append(down) #小さい値から始めて大きい値と小さい値を交互に並べる while len(B) > 0: down = B.pop() Ans2.append(down) if len(B) > 0: up = B.popleft() Ans2.append(up) ans1 = 0 for i in range(N-1): ans1 += abs(Ans1[i]-Ans1[i+1]) #末尾を先頭に持ってきた場合と比較する ans1 = max(ans1, ans1 - abs(Ans1[-1]-Ans1[-2]) + abs(Ans1[0]-Ans1[-1])) ans2 = 0 for i in range(N-1): ans2 += abs(Ans2[i]-Ans2[i+1]) #末尾を先頭に持ってきた場合と比較する ans2 = max(ans2, ans2 - abs(Ans2[-1]-Ans2[-2]) + abs(Ans2[0]-Ans2[-1])) ans = max(ans1, ans2) print(ans) Hard No.70 : C - Snuke Festival C - Snuke Festival 発想 配列Aに対してBの各要素がどの位置に来るかは二分探索で求められます。同様に配列Cに対してBの各要素がどの位置に来るかを二分探索で求めます。あとはBの各要素に対して(BのAに対する位置)×($N-$(BのCに対する位置)を順次計算して答えに足していけば良いです。 実装 import bisect N = int(input()) A = list(map(int, input().split())) B = list(map(int, input().split())) C = list(map(int, input().split())) A = sorted(A) B = sorted(B) C = sorted(C) #Aに対するB[i]の位置 Ba = [] for i in range(N): k = bisect.bisect_left(A, B[i]) Ba.append(k) #Cに対するB[i]の位置 Bc = [] for i in range(N): k = bisect.bisect_right(C, B[i]) Bc.append(N-k) ans = 0 for i in range(N): ans += Ba[i]*Bc[i] print(ans)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AzureのOCR機能(Cognitive Service Read API v3.2)が日本語対応したので使ってみた

はじめに 概要 Azure Cognitive ServiceのOCR機能(Read API v3.2)が日本語に対応したので使ってみました。 非常に精度良く日本語がOCR出来ているので、実際のOCR結果を交えながら紹介したいと思います。 日本語のOCRでお困りの方(特に精度)は是非一度使ってみて頂きたいおススメの機能です。 この記事の想定読者 AzureのOCR機能に興味のある方 現在ご利用されているOCR機能に不満や課題をお持ちの方 機能検証にあたって実施したこと 実際にOCR処理を実施してみたい人向けの内容です。 OCRの検証結果事例を確認されたい方はOCR検証結果へ進んでください。 実行環境の構築 今回は以下の様な構成を作成し、OCR機能の検証を実施しました。 OCR機能のREST APIを実行端末側(オンプレPC側)で呼び出してOCR結果を取得するだけのシンプルな構成にしました。 実行環境の構築においては、大きく3つの作業を実施しています。 それぞれ簡単に説明していきたいと思います。 作業①:(Azure)OCR実行用リソースグループの作成 AzureにCognitive Sereviceのリソースを作成し、OCR処理が実施できる環境を整備します。 [1] 任意のリソースグループを作成します。  必要な情報を入力の上、[確認および作成]ボタンを選択してリソースグループを作成します。 [2] Azure Portalの全てのサービスからCognitive Serviceを検索し、Cognitive Serviceリソースを作成します。 [3] Cognitive Serviceリソースを追加しようとするとMarketplaceからさらにサービスの選択を要求されます。今回はComputer Visionリソースを作成します。 [4] [1]で作成したリソースグループを紐づけ、その他必要な情報を入力してComputer Visionリソースを作成します。 [5] 作成したComputer Visionリソースのキーとエンドポイントから、キー1、エンドポイントを控えておきます。 Azureの準備はこれで完了です。 作業②:OCR実施処理スクリプトの作成 OCRを実行するスクリプトを作成します。 スクリプトの流れとしては以下です。 [1] 各種変数の設定します。 [2] Read APIを呼び出す関数、OCR結果を取得する関数を定義します。 [3] OCR処理を実施し、結果を取得します。 まず、各種変数を定義します。 変数の定義 # OCR対象のファイル名を定義します FILE_NAME = r"D:\\ocr\\OCR_sample_data.pdf" # Computer Visionリソースのサブスクリプションキー、エンドポイント設定 # サブスクリプションキーとエンドポイントは、リソースグループ作成時に控えておいたキー1,エンドポイントを入力します。 SUBSCRIPTION_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxx" ENDPOINT ="https://ai-ocr-demo-20210509.cognitiveservices.azure.com/" # ホストを設定 host = ENDPOINT.split("/")[2] # vision-v3.2のread機能のURLを設定 text_recognition_url = (ENDPOINT + "vision/v3.2/read/analyze") # 読み取り用のヘッダー作成 read_headers = { # サブスクリプションキーの設定 "Ocp-Apim-Subscription-Key":SUBSCRIPTION_KEY, # bodyの形式を指定、json=URL/octet-stream=バイナリデータ "Content-Type":"application/octet-stream" } # 結果取得用のヘッダー作成 result_headers = { # サブスクリプションキーの設定 "Ocp-Apim-Subscription-Key":SUBSCRIPTION_KEY, } 次に、Read APIを呼び出す関数、OCR結果を取得する関数を定義します。 関数の定義 import http.client, urllib.request, urllib.parse import urllib.error, base64 import ast # Read APIを呼ぶ関数 def call_read_api(host, text_recognition_url, body, read_headers): # Read APIの呼び出し try: conn = http.client.HTTPSConnection(host) # 読み取りリクエスト conn.request( method = "POST", url = text_recognition_url, body = body, headers = read_headers, ) # 読み取りレスポンス read_response = conn.getresponse() print(read_response.status) # レスポンスの中から読み取りのOperation-Location URLを取得 OL_url = read_response.headers["Operation-Location"] conn.close() print("read_request:SUCCESS") except Exception as e: print("[ErrNo {0}]{1}".format(e.errno,e.strerror)) return OL_url # OCR結果を取得する関数 def call_get_read_result_api(host, file_name, OL_url, result_headers): result_dict = {} # Read結果取得 try: conn = http.client.HTTPSConnection(host) # 読み取り完了/失敗時にFalseになるフラグ poll = True while(poll): if (OL_url == None): print(file_name + ":None Operation-Location") break # 読み取り結果取得 conn.request( method = "GET", url = OL_url, headers = result_headers, ) result_response = conn.getresponse() result_str = result_response.read().decode() result_dict = ast.literal_eval(result_str) if ("analyzeResult" in result_dict): poll = False print("get_result:SUCCESS") elif ("status" in result_dict and result_dict["status"] == "failed"): poll = False print("get_result:FAILD") else: time.sleep(10) conn.close() except Exception as e: print("[ErrNo {0}] {1}".format(e.errno,e.strerror)) return result_dict これらの変数、関数を使用して、OCRを実行する処理を実装します。 import time import json # body作成 body = open(FILE_NAME,"rb").read() # readAPIを呼んでOperation Location URLを取得 OL_url = call_read_api(host, text_recognition_url, body, read_headers) print(OL_url) # 処理待ち10秒 time.sleep(10) # Read結果取得 result_dict = call_get_read_result_api(host, FILE_NAME, OL_url, result_headers) # OCR結果を保存 output_json_file = r"D:\\ocr\\OCR_sample_data.json" with open(output_json_file,"w",encoding = encoding) as f: json.dump(result_dict,f, indent = 3, ensure_ascii = False) 作業③:OCR結果確認用ファイル作成スクリプトの作成 Read APIを用いたOCR処理だけであれば作業②までで完了ですが、このままではOCR結果がちょっと確認しづらいです。 その為、OCR処理対象のデータに、OCR結果を重ね合わせる処理を実装します。 ※ソースコードを整理後、実装コードはアップします。(早めに欲しい方がいればコメントにてご連絡下さい。) スクリプトを実行すると、OCR結果が元データに重畳された結果確認用データが出力されます。 緑色の枠は文字列の抽出領域を表し、赤文字は領域内のOCR結果を表しています。 また、青文字の「L:X」はOCRの出力順を表します。 この例では、まず「重要事項説明書<第二版>2020年12月」が出力され、次に「重要事項説明書」「本件システムの名称」の順にOCR結果が出力されていることが分かります。 OCR検証結果 検証データ 今回の検証では、こちらのデータ(自作)を使用しました。 IPAで公開されている情報システム・モデル取引・契約書のテンプレート「<重要事項説明書(第二版追補版付属)>」から一部抜粋、変更して自作したデータです。 以下の様な特徴を持ったデータです。 No. データの特徴 1 日本語、英語が混在している 2 表形式の情報が含まれている 3 段組みの記載がある 4 スキャンに失敗し、文書が一部傾いている これらがどのようにOCRされるかを見ていきたいと思います。 OCR検証結果サマリ OCRの検証結果サマリです。 これらを実例を挙げながら紹介していきます。 No. 概要 1 日本語のOCRはぼぼ完璧に出来ている 2 傾いたデータでも問題なくOCRが出来ている 3 縦書きの文字も認識可能 4 段組みデータが自然な順序で出力可能 5 文字の間隔が離れていると別の文字として認識される 1. 日本語のOCRはぼぼ完璧に出来ている 少し見づらいですが、確認する限りほぼ完璧にOCR出来ています。 結果を一部抜粋して載せましたが他の個所でも同等の精度でOCR出来ており、精度は非常に高いことを確認しました。 最下行(L:8)を見てもわかるように「保守性、Saas/ASPにおいては~」など日本語と英語が混在していても問題ありません。 またOCRの出力順も上から下へ意図通りに出力されています。 1点気を付けるべきは、OCRで出力される結果が1行1出力となっている点です。 緑の枠で一つの出力になるので、例えば下2行の文章で「使用許諾契約」という単語が行を分かれて記載されている場合、 「使」と「用許諾契約」という別々の単語として出力されます。 ただ、今回のデータでは出力順も上から下に意図通り出力されているので、この文字列を出力順に繋げてしまえば解決できそうです。 2. 傾いたデータでも問題なくOCRが出来ている 契約書のデータ等をスキャンした際に、少し傾いてしまったりすることは多々あるかと思います。 この様なデータではOCRの精度は下がりがちですが、AzureのRead APIでは問題なくOCR出力できていることを確認しました。 これだけでも試してみる価値は十分にあるのではないかと思います。 3. 縦書きの文字も認識可能 日本語の契約書など、表形式のフォーマットが含まれる文書には縦書きの文字含まれることがあります。 今回の検証データでは、この縦書きの文字も認識出来ました。 下図の左側面部「契約の表示」が一つの文字列としてOCR出来ていることが分かります。 4. 段組みデータも自然な順序で出力可能 契約書などでよく見られますが、1枚のページの中で段組みになっている文書があります。 Read API v3.2の新機能として、段組みが自然な順序でOCRされるようになっています。 詳しくはこちらを参照ください。 公式にはラテン語のみとなっていますが、日本語の段組みでデータでどの様になるかを検証しました。 非公式にはなりますが、日本語でも問題なく段組みデータが自然な順序で出力出来ました。 少し見づらいですが、青色の数字の順番にご注目下さい。 2段組みの文書の左側を順にOCRした後に、右側をOCRしていることが分かります。 これは素晴らしいですね。 5. 文字の間隔が離れていると別の文字として認識される こちらは仕方ない部分もありますが、日本語の表形式のデータなどでは表の項目名がセル内で等間隔になるように、文字の間隔があいてしまう場合があります。 この様の場合、下図の様に「会社名」「住所」など、一つの単語ととして認識されてほしい単語が別の単語として認識される場合がありました。 まとめ 今回は、Azure Cognitive ServiceのOCR機能(Read API v3.2)がどの程度日本語に対応できるかを検証してみました。 OCRの精度や段組みの対応、傾き等に対する頑健性など非常に高品質な機能であることが確認できました。 ちなみに2021年4月に一般提供が開始(General Availability)されており、機能としての品質の担保されたサービスとなっております。 今回は価格については触れませんでしたが、1ページ当たり0.x円(従量課金制でOCR処理枚数によって変化する)と、他社製品に比べて驚異的な低コストで高精度なOCRが実現できます。 他のOCR製品と比べてGUIは持っていないので、実業務で使用する場合には必要に応じてGUIを開発する必要がありますが、 顧客の要望に合わせて必要な機能に絞って開発することでコスト最適化を図れるという意味では非常に良いサービスではないでしょうか。 また、表形式のデータ等にOCRに関しては、Read APIによるOCRよりもForm RecognizerのLayout APIの方が向いていると思います。 次回はこの辺りのサービスについて検証してみたいと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【数理考古学】群論とシミュレーション原理⑦三次元トーラスとしての四元数概念導入

【数理考古学】群論とシミュレーション原理①これまでの投稿内容のまとめ。 吃驚するほどグチャグチャになってしまったので整理を試みます。 三次元トーラスとしての四元数概念導入 リー群の$S_0$空間は実数列(Real Sequence)全体に対応する「一次元トーラス(半径1の単位円=円周群)」、$S_1$空間は複素数列(Complex Sequence)全体に該当する「二次元トーラス(ドーナツ状あるいは円筒状の空間)」に該当します。 【数理考古学】群論とシミュレーション原理⑥二次元トーラス概念への発展 ただし「ネイピア数e=2.718282の近似精度は十分」で「」かつ「」とする。image.gif そしてこの考え方の延長線上においてリー群$S_3$空間を四元数集合(Quaternion Set)と対応させるのです。 【Rで球面幾何学】ハミルトンの四元数は何を表しているのか? これは「(原点0を半径0の内周円とし、外周円を半径4πとし、直交する大半径の軌道に沿って進む)二次元トーラス座標上の小半径円」にさらに$\cos(θ)+\sin(θ)i$の2自由度を加えた場合に相当します。 円概念(観察結果集合)とオイラーの公式$e^{iθ}$や等比数列$±i^{2x}$(演算結果集合)が等号で結べるのは前者においてネイピア数e=2.718282の近似が十分である場合、後者において周回関数$α^n$の冪根αが十分1に近く、かつ周期関数$β^n$の冪根βが十分-1に近い場合に限られる様に、四元数における操作変数(Instrumental Variables)i,j,kも(中心を巡る周回軌道の状態を保ち続ける為に)ある種の相互従属関係を構築し、これが見た目上の交換法則$x・y=y・x$の放棄(そちらを選ぶと次の升目に進んでしまう選択肢の排除)につながっていくのです。 操作変数法 - Wikipedia 交換法則 - Wikipedia 四元数における操作変数i,j,kが以下の関係にあるのは、そういう理由からなんですね。 複素数 どう計算しても隣の升目にはみ出しません。 i^2=-1\\r(θ)=r±ai\\(a+bi)(c+di)=(ac-bd)+(ad+bc)i このうち(ac-bd)の部分がスカラー積=内積となる。 このうち(ad+bc)の部分がベクトル積=外積となる。 複素数同士の掛算 やはり計算結果が隣の升目にはみ出しません。 α=a+ib,β=c+id\\θ=arg(α),ϕ=arg(β) と置き、これを極座標上での掛け算に置き換えると以下となる。 α=|α|(\cosθ+i\sinθ)\\β=|β|(\cosϕ+i\sinϕ)\\αβ=|α||β|(\cos(θ+ϕ)+i\sin(θ+ϕ)) 四元数 隣の升目にはみ出す選択肢の排除を含みます。 i^2=j^2=k^2=ijk=-1\\r(θ,φ)=r±ai±bj±ck\\(ai+bj+ck)(di+ej+fk)=−1*(ad+be+cf)+(bf−ce)i+(cd−af)j+(ae−bd)k このうち(ad+be+cf)の部分がスカラー積=内積となる。 このうち(bf−ce)i+(cd−af)j+(ae−bd)kの部分がベクトル積=外積となる。 【オイラーの多面体定理と正多面体】正方形における平方対角線と立方体における立方対角線の関係について。 という事は? もしかしたらこの辺りの話、テイラー展開を特異点を超えて遂行可能としたローラン展開(Laurent Expansion)において登場する「複素数が描く閉曲線の面積の総和は0となる」数理に立脚している事と関係してくるのかもしれませんね… 物理数学:ローラン展開 ローラン級数のテイラー展開を試す。 $\frac{1}{1-x}$はまぁまぁの収束速度。 $\frac{1}{1+x}$の収束速度は極めて遅い。 この収束の遅さに業を煮やしてオイラーが考案したのがオイラー変換となる。 【Rで球面幾何学】オイラーの公式を導出したマクローリン級数の限界? ) そして関数$\frac{1}{z(1−z)}$の原点z0=0の周りでローラン展開 そんな感じで以下続報…
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

pandas の apply で、今どの行を処理しているのかを見たいとき

結論 def Func(要素): print(<データフレーム名>.query(f'<カラム名> == "{要素}"').index[0]) return <何らかの処理> などのようにする。 詳しく pandas の apply で、DataFrame に関数を適用させることができます。その際、 関数の処理が複雑で時間がかかっていて、今どの行を処理しているのかを見たい。 どこかの行で上手く適用できず、エラーが起きているようだ。その行を知りたい。 なんて場面が起こった時の対処法です。 今回は簡単のために以下のようなデータフレームを想定します。 df = pd.DataFrame(np.array([[1, 2, '2021-04-01'], [3, 4, '20210402'], [5, 6, '2021-04-03']]), columns=['a', 'b', 'c']) df a b c 0 1 2 2021-04-01 1 3 4 20210402 2 5 6 2021-04-03 c のカラムは、年-月-日となっていますが、index が1の要素だけハイフンで区切られていません。今回はこれを月だけにすることを目標にします(コードが汚いのはご了承ください)。 def get_year(elem): print(df.query(f'c == "{elem}"').index[0]) # 要素と一致する時のインデックスを出力 return elem.split('-')[1] df['c'] = df['c'].apply(get_year) 0 1 IndexError Traceback (most recent call last) in () ----> 1 df['c'] = df['c'].apply(get_year) 1 frames pandas/_libs/lib.pyx in pandas._libs.lib.map_infer() in get_year(elem) 1 def get_year(elem): 2 print(df.query(f'c == "{elem}"').index[0]) ----> 3 return elem.split('-')[1] IndexError: list index out of range ハイフンがないためエラーが出ていますが、index を出力しているため、1の行でエラーが起きたんだなとわかります。 今回のような少ないデータだと効果を発揮しませんが、何万行もあるデータの場合、特定が容易になります。 もちろん、何万行もあるデータをいちいち print してたまるか!って場合は、空のリストを作っておいて、try except 文などを用い、エラーとなった index を append して保持する、といった手が現実的かと思います。 間違いや、もっとスムーズな手があるよ!なんて場合はぜひコメント下さい!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Python でマイクをミュート(Windows10)

ビデオ会議中にミュートにしたくて検索したら近いものがありました。  https://stackoverflow.com/questions/65510997/python-control-microphone-level-using-pywin32-windows-10 ミュートしたいとき mute-on.py import win32api WM_APPCOMMAND = 0x319 MIC_MUTE = 24 MIC_DOWN = 25 MIC_UP = 26 win32api.SendMessage(-1, WM_APPCOMMAND, 0x30292, MIC_MUTE * 0x10000) ミュート解除 mute-off.py import win32api WM_APPCOMMAND = 0x319 MIC_MUTE = 24 MIC_DOWN = 25 MIC_UP = 26 win32api.SendMessage(-1, WM_APPCOMMAND, 0x30292, MIC_DOWN * 0x10000) win32api.SendMessage(-1, WM_APPCOMMAND, 0x30292, MIC_UP * 0x10000) 各種数字は以下を参照 https://docs.microsoft.com/ja-jp/windows/win32/inputdev/wm-appcommand 上記ファイルをそれぞれBATで呼び出すようにして、BATのショートカットをデスクトップに作成 ショートカットのプロパティから「ショートカットキー」を登録しておけば、キー操作のみでミュートのオン・オフが操作できます。 こういうのでいいんだよね・・ PowerShell 使う方法だとなかなか複雑だったので、Pythonで簡単にできてよかったです。  ・・PowerShell は何だか方向が間違っているような・・・
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CloudWatchLogsの特定の文字列を含むログをSlackに転送する①

完成例 slack apiにアクセスしてアプリを作成 botの作成の仕方やslackへのメッセージ投稿の仕方は以下の記事を参考にしてください。 Pythonのコードのディレクトリ構造 ディレクトリ構造は以下のようになっています ディレクトリ構造 sendLogToSlack ├── lambda_function.py ├── postslack.py └── slack_sdk slack_sdkのインストール slack_sdkはlambdaの標準モジュールではないので、 pipでインストールしてからzipでパッケージ化する必要があります。 ディレクトリ構造 mkdir sendLogToSlack cd sendLogToSlack pip install slack_sdk -t ./ lambda_function.py lambda_function.py import zlib import base64 import postslack import json def lambda_handler(event, context): data = zlib.decompress(base64.b64decode(event['awslogs']['data']), 16+zlib.MAX_WBITS) data_json = json.loads(data) log_json = json.loads(json.dumps(data_json["logEvents"][0], ensure_ascii=False)) postslack.SendSlackMessage(str(log_json)) こちらの記事を参考に作成させて頂きました。 postslack.py postslack.py from slack_sdk import WebClient from slack_sdk.errors import SlackApiError def SendSlackMessage(message): client = WebClient(token='your_token') response=client.chat_postMessage(channel='your_channel', text=message) slack_sdkの使い方に関してはこちらの記事で紹介しています。 パッケージ化 lambdaにアップロードする為にzipコマンドでパッケージ化します。 sendLogToSlack zip -r sendslack * lambdaにアップロード 続き ここまで出来れば残りの作業はもう少しです。 CloudWatchLogsの特定の文字列を含むログをSlackに転送する②に続きます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CloudWatchLogsの特定の文字列を含むログをSlackに転送する -前編-

完成例 slack apiにアクセスしてアプリを作成 botの作成の仕方やslackへのメッセージ投稿の仕方は以下の記事で紹介しています。 Pythonのコードのディレクトリ構造 ディレクトリ構造は以下のようになっています ディレクトリ構造 sendLogToSlack ├── lambda_function.py ├── postslack.py └── slack_sdk slack_sdkのインストール slack_sdkはlambdaの標準モジュールではないので、 pipでインストールしてからzipでパッケージ化する必要があります。 ディレクトリ構造 mkdir sendLogToSlack cd sendLogToSlack pip install slack_sdk -t ./ lambda_function.py lambda_function.py import zlib import base64 import postslack import json def lambda_handler(event, context): data = zlib.decompress(base64.b64decode(event['awslogs']['data']), 16+zlib.MAX_WBITS) data_json = json.loads(data) log_json = json.loads(json.dumps(data_json["logEvents"][0], ensure_ascii=False)) postslack.SendSlackMessage(str(log_json)) こちらの記事を参考に作成させて頂きました。 postslack.py postslack.py from slack_sdk import WebClient from slack_sdk.errors import SlackApiError def SendSlackMessage(message): client = WebClient(token='your_token') response=client.chat_postMessage(channel='your_channel', text=message) slack_sdkの使い方に関してはこちらの記事で紹介しています。 パッケージ化 lambdaにアップロードする為にzipコマンドでパッケージ化します。 sendLogToSlack zip -r sendslack * lambdaにアップロード 続き ここまで出来れば残りの作業はもう少しです。 CloudWatchLogsの特定の文字列を含むログをSlackに転送する-後編-に続きます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Kubeflow KFServingでscikit-learnの学習済みモデルを用いた推論サービスを公開する

著者: 株式会社 日立ソリューションズ 柳村 明宏 監修: 株式会社 日立製作所 はじめに KubeflowはKubernetes上でMLOpsを実現するためのOSSのツールキットです。2020/3にバージョン1.0がリリースされ、2021/4現在も活発に開発が行われており、機械学習を利用したシステムの開発/運用のライフサイクルを回すための有効な手段の1つとして注目されています。 本連載では、Kubeflowのバージョン1.2(連載開始時点の最新版、2020年11月リリース)について、構築手順、Kubeflow Pipelines、KFServingの基礎的な利用手順についての情報を紹介いたします。 第4回の本稿では、第3回⽬で作成した学習済みモデルを利⽤した推論サービスを、Kubeflowのサービングコンポーネントの1つであるKFServingを利用して公開する⼿順を紹介いたします。 本連載では、Kubernetesの前提バージョンを1.20としています。 ステータスがStableのSeldon Core Servingは、前提とするKubernetesのバージョンが1.12から1.17であったため、ステータスがBetaであるKFservingを利用した検証を行いました。 投稿一覧: 1. MLOpsを実現するKubeflowを前提のKubernetesも含めて構築する(前編) 2. MLOpsを実現するKubeflowを前提のKubernetesも含めて構築する(後編) 3. Kubeflow Pipelinesでscikit-learnの機械学習モデルを訓練・評価してみる 4. Kubeflow KFServingでscikit-learnの学習済みモデルを用いた推論サービスを公開する (本投稿) KFServingの概要 KFServingは、Kubernetes上でのサーバレス推論を実現するコンポーネントで、TensorFlow、XGBoost、Scikit-learn、PyTorch、ONNXなどの一般的な機械学習(ML)フレームワークを抽象度の高いYAMLファイルに記述することで構築することができます。 KFServingの詳細は、Kubeflow公式サイトのKFServingのページを参照してください。 KFServingの利用手順 今回のKFServingの利用手順を次に示します。 今回のKubeflow Pipelinesの利用手順 # 手順 概要 1 KFServingの開発環境を準備 第1回目、および、第2回目でkubeflowを構築したマシンにログインし、KFServingのリポジトリをクローンします。 2 推論サービスのデプロイ scikit-learnのsampleを編集して、第3回目でAmazon S3にアップロードしたscikit-learnの学習済みモデルの読込み、および、推論処理を行えるようにします。編集したコードのDockerイメージをビルドし、推論サービスのデプロイを行います。 3 推論サービスの利用 デプロイした推論サービスを利用し、推論を実行します。 1. KFServingの開発環境を準備 1.1 SSHでログイン 第1回目、および、第2回目で、Kubeflowを構築したマシンにSSHでログインします。 1.2 KFServingのバージョン確認 本稿では、Kubeflow構築済みの環境を前提とするため、KFServingのインストールは不要です。 また、ネームスペースはkubeflowとなります。 KFServingのバージョンは、「2.3 Amazon S3アクセスに必要なAWS認証設定」で編集する、KFServingのAWS認証用の設定ファイルの内容に影響します。 # KFServingのバージョン確認 kubectl get po -n kubeflow -o yaml | grep image.*kfserving-controller: # --- 実行結果例 ここから ------------------------------------------------- # image: gcr.io/kfserving/kfserving-controller:v0.4.1 # image: gcr.io/kfserving/kfserving-controller:v0.4.1 # --- 実行結果例 ここまで ------------------------------------------------- 1.3 KFServingのリポジトリのクローン KFServingのGitHubのリポジトリをクローンします。 # KFServingのリポジトリをクローン git clone https://github.com/kubeflow/kfserving.git scikit-learnのsampleは、次のサンプルを利用します。 YAMLファイルのsample コードのsample 編集するファイルは次のファイルです。 # 記載箇所 ファイルパス 1 2.1 scikit-learnの学習済みモデルを用いた推論処理を作成 ~/kfserving/python/sklearnserver/sklearnserver/model.py 2 2.2 Dockerイメージのビルド ~/kfserving/python/sklearnserver/setup.py 3 2.3 Amazon S3アクセスに必要なAWS認証設定 ~/kfserving/docs/samples/storage/s3/s3_secret.yaml 4 2.4 推論サービスのデプロイ ~/kfserving/docs/samples/v1alpha2/sklearn/sklearn.yaml 2.推論サービスのデプロイ 2.1 scikit-learnの学習済みモデルを用いた推論処理を作成 第3回目でAmazon S3にアップロードしたscikit-learnの学習済みモデルを読込み、KFServingを利用して推論を実行できるように「~/kfserving/python/sklearnserver/sklearnserver/model.py」を編集します。 model.pyの編集後のコードを次に示します。編集前のコード(KFServingのscikit-learnサンプルのmodel.py)については、model.pyのsampleを参照してください。 model.py import kfserving import os import pickle import pandas as pd import sys import json from typing import Dict sys.path.append('/sklearnserver/sklearnserver') from preprocessor import PreProcessor MODEL_BASENAME = "ml_pipeline" MODEL_EXTENSIONS = [".pickle"] class SKLearnModel(kfserving.KFModel): # pylint:disable=c-extension-no-member def __init__(self, name: str, model_dir: str): super().__init__(name) self.name = name self.model_dir = model_dir self.ready = False # モデルファイルの読込み処理 def load(self) -> bool: model_path = kfserving.Storage.download(self.model_dir) paths = [os.path.join(model_path, MODEL_BASENAME + model_extension) for model_extension in MODEL_EXTENSIONS] for path in paths: if os.path.exists(path): self._model = pickle.load(open(path, 'rb')) self.ready = True break return self.ready # 推論処理 def predict(self, request: Dict) -> Dict: # リクエストから値を取得 instances = request["instances"] try: # DataFrame化 X_df = pd.DataFrame(instances) # 予測を実行 pred = self._model.predict(X_df) # 予測結果をJson化 result = {"Survived": int(pred[0])} # 予測結果を返信 return json.dumps(result) except Exception as e: raise Exception("Failed to predict %s" % e) MODEL_BASENAME、MODEL_EXTENSIONSは、第3回目で作成した学習済みモデルを指定します。 model.pyでは、第3回目で作成したpreprocessor.pyをインポートするため、preprocessor.pyを「~/kfserving/python/sklearnserver/sklearnserver/」に配置してください。 2.2 Dockerイメージのビルド 「2.1 scikit-learnの学習済みモデルを用いた推論処理を作成」で編集したコードをビルドしてDockerイメージを作成するために、「~/kfserving/python/sklearnserver/setup.py」を編集します。 setup.pyの編集後のコードを次に示します。ここでは次の編集を実施します。 「install_requires=」のscikit-learnのバージョンを、学習済モデルを作成したときに利用したscikit-learnのバージョンに合わせます。 追加したいライブラリがあれば追加で記載します。今回は「pandas >= 1.0.0"」を記載しています。 編集前のコード(ライブラリ配布用のpythonサンプルのsetup.py)については、setup.pyのsampleを参照してください。 setup.py from setuptools import setup, find_packages tests_require = [ 'pytest', 'pytest-asyncio', 'pytest-tornasync', 'mypy' ] setup( name='sklearnserver', version='0.5.0', author_email='singhan@us.ibm.com', license='https://github.com/kubeflow/kfserving/LICENSE', url='https://github.com/kubeflow/kfserving/python/sklearnserver', description='Model Server implementation for scikit-learn. \ Not intended for use outside KFServing Frameworks Images', long_description=open('README.md').read(), python_requires='>3.4', packages=find_packages("sklearnserver"), install_requires=[ "kfserving>=0.5.0", "scikit-learn == 0.24.1", "pandas >= 1.0.0" ], tests_require=tests_require, extras_require={'test': tests_require} ) インストールするscikit-learnのバージョンは、第3回目で指定したバージョンと同一のバージョンを指定します。 自身のDockerレジストリにログインします。 # docker loginの実行 sudo docker login Dockerイメージを作成します。 参考: Building your own scikit-Learn Server Docker Image # Dockerイメージの作成 sudo docker build -t [Dockerユーザ名]/[イメージ名] -f ~/kfserving/python/sklearn.Dockerfile ~/kfserving/python # --- 実行結果例 ここから ------------------------------------------------------------------------------- # Successfully built 81d6efc54e84 # Successfully tagged [Dockerユーザ名]/[イメージ名]:latest # --- 実行結果例 ここまで ------------------------------------------------------------------------------- # 作成したイメージの確認 sudo docker images --digests [Dockerユーザ名]/[イメージ名]:latest # --- 実行結果例 ここから ------------------------------------------------------------------------------- # REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE # [Dockerユーザ名]/[イメージ名] latest <none> 41909b0f94e0 42 minutes ago 1.36GB # --- 実行結果例 ここまで ------------------------------------------------------------------------------- # 作成したイメージのアップロード sudo docker push [Dockerユーザ名]/[イメージ名]:latest # --- 実行結果例 ここから ------------------------------------------------------------------------------- # The push refers to repository [docker.io/[Dockerユーザ名]/[イメージ名]] # 9ef05367b9dc: Pushed # b84a57dacdd2: Pushed # 1add26dfd9ff: Pushed # 9df36e5bd672: Pushed # 16be529e8612: Pushed # 9ab20c4343be: Layer already exists # 7ebccfde7bb7: Layer already exists # d20676915161: Layer already exists # 852a1bb5386c: Layer already exists # 9437609235f0: Layer already exists # bee1c15bf7e8: Layer already exists # 423d63eb4a27: Layer already exists # 7f9bf938b053: Layer already exists # f2b4f0674ba3: Layer already exists # latest: digest: sha256:66dbf7d11e89d824b8e48f9e568ecd0049f21e2b76f694f5cb3c68365afa5ad0 size: 3272 # --- 実行結果例 ここまで ------------------------------------------------------------------------------- Inference Service用のconfigmapに、作成したscikit-learn のDockerイメージを指定します。 参考: Run SKLearn InferenceService with your own image # Inference Service用のconfigmapの編集 kubectl -n kubeflow edit configmap inferenceservice-config configmap :(省略) predictors: |- { :(省略) "sklearn": { "image": "[Dockerユーザ名]/[イメージ名]" }, :(省略) 2.3 Amazon S3アクセスに必要なAWS認証設定 Amazon S3に格納しているモデルファイルを参照するため、AWS認証用のYAMLファイル「~/kfserving/docs/samples/storage/s3/s3_secret.yaml」について、公式ドキュメントを参考に編集します。 参考: s3_secret.yaml、Store models in S3 bucket 今回、KFServingは0.41を利用しているため、0.4以降のバージョンを利用する場合の例を記載します。 0.3以前のバージョンを利用する場合は、dataタグに指定するAWS_ACCESS_KEY_ID、および、AWS_SECRET_ACCESS_KEYの変数名をそれぞれ、awsAccessKeyID、および、awsSecretAccessKeyと指定します。 AWS_ACCESS_KEY_ID、および、AWS_SECRET_ACCESS_KEYの値をBASE64エンコードして設定 <…の値>部分は環境に合わせて指定します。 export AWS_ACCESS_KEY_ID_BASE64=`echo -n "<AWS_ACCESS_KEY_IDの値>" | base64` export AWS_SECRET_ACCESS_KEY_BASE64=`echo -n "<AWS_SECRET_ACCESS_KEYの値>" | base64` s3_secret.yaml apiVersion: v1 kind: Secret metadata: name: mysecret annotations: serving.kubeflow.org/s3-endpoint: s3.ap-northeast-1.amazonaws.com serving.kubeflow.org/s3-usehttps: "1" serving.kubeflow.org/s3-verifyssl: "1" serving.kubeflow.org/s3-region: ap-northeast-1 type: Opaque data: AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID_BASE64} AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY_BASE64} --- apiVersion: v1 kind: ServiceAccount metadata: name: sa secrets: - name: mysecret s3-endpoint、および、s3-regionは環境に合わせて設定します。 AWS認証情報をKubernetesへ設定します。 # AWS認証情報のKubernetesへの設定 kubectl apply -f s3_secret.yaml # --- 実行結果例 ここから ----------------- # secret/mysecret created # serviceaccount/sa created # --- 実行結果例 ここまで ----------------- 2.4 推論サービスのデプロイ scikit-learn Inference Service用のYAML「~/kfserving/docs/samples/v1alpha2/sklearn/sklearn.yaml」を編集し、推論サービスをデプロイします。 sampleでは、storageUriにGCPのパスが記載されていますが、今回Amazon S3を利用するため、Amazon S3のパスを記載します。 参考: Run SKLearn InferenceService with your own image sklearn.yaml apiVersion: "serving.kubeflow.org/v1alpha2" kind: "InferenceService" metadata: name: "sklearn-iris" spec: default: predictor: serviceAccountName: sa sklearn: storageUri: "s3://kubeflow-pl" serviceAccountNameには、「2.3 Amazon S3アクセスに必要なAWS認証設定」で編集したYAMLファイルのServiceAccountのnameを指定します。 storageUriには、第3回目で学習済みモデルをアップロードしたAmazon S3のUriを指定します。 scikit-learn Inference Serviceをデプロイします。 kubectl apply -f sklearn.yaml # --- 実行結果例 ここから ------------------------------------------------------------------------------- # inferenceservice.serving.kubeflow.org/sklearn-iris created # --- 実行結果例 ここまで ------------------------------------------------------------------------------- # Podの状態確認 kubectl get pods -l model=sklearn-iris # --- 実行結果例 ここから ------------------------------------------------------------------------------- # NAME    READY STATUS RESTARTS AGE # sklearn-iris-predictor-default-6lvmc-deployment-856956bb95sgd5r 2/2  Running 0 89s # --- 実行結果例 ここまで ------------------------------------------------------------------------------- # ログの確認 kubectl logs sklearn-iris-predictor-default-6lvmc-deployment-856956bb95sgd5r kfserving-container # --- 実行結果例 ここから ------------------------------------------------------------------------------- # [I 210310 16:28:10 storage:45] Copying contents of /mnt/models to local # [I 210310 16:28:10 kfserver:115] Registering model: sklearn-iris # [I 210310 16:28:10 kfserver:96] Listening on port 8080 # [I 210310 16:28:10 kfserver:98] Will fork 1 workers # --- 実行結果例 ここまで ------------------------------------------------------------------------------- 3. 推論サービスの利用 推論したいデータをJsonファイルで作成して、推論を実行します。 参考: Run a prediction 正常に動作した場合、「2.1 scikit-learnの学習済みモデルを用いた推論処理を作成」で実装した通り、「{"Survived": 0}または{"Survived": 1}」が返ってきます。 3.1 入力データの準備 推論したいデータをJsonファイルで作成します。 # 推論データの作成 cat <<EOF> ml-input.json { "instances": [ { "PassengerId": 294, "Pclass": 1, "Name": "John, Mr. Smith", "Sex": "male", "Age": 28, "SibSp": 0, "Parch": 0, "Ticket": 312453, "Fare": 18.2500, "Cabin": "NaN", "Embarked": "Q" } ] } EOF 3.2 推論を実行 推論実行時に必要な環境変数を設定します。 MODEL_NAMEは、「2.4 推論サービスのデプロイ」で設定したmetadataタグのnameを指定してします。 MODEL_NAME=sklearn-iris INPUT_PATH=ml-input.json SERVICE_HOSTNAME=$(kubectl get inferenceservice sklearn-iris -o jsonpath='{.status.url}' | cut -d "/" -f 3) export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}') export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}') KFServingのエンドポイントにHTTPリクエストを送信して、推論サービスを呼び出します。 # 推論の実行 curl -v -H "Host: ${SERVICE_HOSTNAME}" http://${INGRESS_HOST}:${INGRESS_PORT}/v1/models/$MODEL_NAME:predict -d $INPUT_PATH # --- 実行結果例 ここから ------------------------------------------------------------------------------- # * Trying [INGRESS_HOSTの値]... # * TCP_NODELAY set # * Connected to [INGRESS_HOSTの値] ([INGRESS_HOSTの値]) port [INGRESS_PORTの値] (#0) # > POST /v1/models/sklearn-iris:predict HTTP/1.1 # > Host: sklearn-iris.default.example.com # > User-Agent: curl/7.58.0 # > Accept: */* # > Content-Length: 263 # > Content-Type: application/x-www-form-urlencoded # > # * upload completely sent off: 263 out of 263 bytes # < HTTP/1.1 200 OK # < content-length: 15 # < content-type: text/html; charset=UTF-8 # < date: Wed, 10 Mar 2021 16:36:26 GMT # < server: istio-envoy # < x-envoy-upstream-service-time: 26 # < # * Connection #0 to host [INGRESS_HOSTの値] left intact # {"Survived": 0} # --- 実行結果例 ここまで ------------------------------------------------------------------------------- Podには下記のようにHTTPリクエストの結果が出力されます。 # ログの確認 kubectl logs sklearn-iris-predictor-default-6lvmc-deployment-856956bb95sgd5r kfserving-container # --- 実行結果例 ここから ------------------------------------------------------------------------------- # [I 210310 16:36:26 web:2243] 200 POST /v1/models/sklearn-iris:predict (127.0.0.1) 22.87ms # --- 実行結果例 ここまで ------------------------------------------------------------------------------- おわりに 本稿では、Kubeflow KFServingでscikit-learnの学習済みモデルを用いた推論サービスを公開する手順を紹介しました。 Kubeflowの公式サイトなどに掲載されている情報やサンプルの多くは、Google Cloud Platform前提です。本投稿ではオンプレミスやGoogle Cloud Platform以外のクラウド環境で利用する方にも、基礎的な情報として参考してもらえればと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ポートフォリオ最適化 ~投資家の意思決定に基づいた分析~

ポートフォリオの最適化には様々な手法がありますが、最適化実装までの記事や参考書では分散最小化モデルが数多く取り上げられており、投資家のリスク選考を反映した最適化については紹介されていなかったのでここでまとめてみました。 Over View: - Pythonでポートフォリオ最適化の実装 - 投資家の意思決定に基づいた最適投資割合の導出 Key Word: - トービンの分離定理, 相対的リスク回避度, 無差別曲線, 資本市場線, 効率的ポートフォリオ 1.ポートフォリオ最適化とは・・・ まず初めにポートフォリオ理論とは、 現代ポートフォリオ理論(げんだいポートフォリオりろん、英: Modern portfolio theory, MPT)とは、金融資産への投資比率(ポートフォリオ)を決定する理論。1952年にハリー・マーコウィッツによって発表された論文[1]を端緒として研究が進められた。投資におけるポートフォリオの収益率の平均 (期待値) と分散のみをコントロールするという特徴がある。 (引用元 : Wikipedia) ポートフォリオ理論とは、金融資産の収益率に着眼点を置き、それの平均(リターン)と変動のばらつき(リスク)を基にポートフォリオを決定する理論になります。 どの投資家にも、リスクを最小化しながらリターンを得るという考えが共通してあります。 こういった投資家の合理性を活用し、ポートフォリオ理論に基いて最適なポートフォリオを導き出すことをポートフォリオ最適化と呼んでいます。 2.ポートフォリオ理論についての参考URL ・【トービンの分離定理】最適ポートフォリオの決定理論 ・マーコビッツの平均分散モデル及びその解法について 3.最適化までの流れ step1.資本市場線の導出 step2.投資家の無差別曲線の導出 step3.最適投資割合の導出 3-1.資本市場線の導出 トービンの分離定理より、$\sigma$-$\mu$平面(リスク-リターン平面)上でマーケットポートフォリオから無リスク資産に引いた線を資本市場線と言います。 以下のような式で表されます。 $$\mu = b\sigma + r_f\tag{1}$$ ($b$は資本市場線の傾き) 全ての投資家は、この資本市場線上で投資することになります。 3-2.投資家の無差別曲線の導出 無差別曲線はそれぞれの線上で投資家の期待効用が等しくなります。(等高線に似てます) リターンが大きいほどそしてリスクが小さいほど、投資家の期待効用が大きくります。 投資家の効用関数から無差別曲線を導出することができますが、効用関数の推定が難しいため無差別曲線は以下の式で表されることがあります。 $$ \mu = \frac{1}{2}\lambda\sigma^{2} + u \tag{2}$$ ~記号の説明~ $\mu$: 期待リターン $\sigma$: リターンの標準偏差 $\lambda$: 相対的リスク回避度 $u$: 期待効用 今回はこの式を用いて無差別曲線を導出しました。 $\lambda$ の推定には、以下の式を用いました。 $$ \lambda = \frac{\mu_{total} - r_f}{\alpha\sigma_{total}^{2}} $$ ~記号の説明~ $\mu_{total}$: 危険資産全体の期待リターン $\sigma_{total}$: 危険資産全体のリターンの標準偏差 $r_f$: リスクフリーレート $\alpha$: 危険資産保有割合 危険資産全体のリターンの期待値・標準偏差は以下の通りです。 $$ \mu_{total} = \sum_{i=1}^{n}w_i\mu_i $$ $$\sigma_{total} = \sqrt{\sum_{i=1}^{n}\sum_{j=1}^{n}w_i w_j\sigma_i\sigma_j}$$ $$ \sum_{i=1}^{n}w_i = 1 $$ ~記号の説明~ $\mu_{k}$: 銘柄 $k$ の期待リターン $\sigma_{k}$: 銘柄 $k$ のリターンの標準偏差 $w_k$: 銘柄 $k$ への投資割合 この式の数学的な説明は、以下の記事に記載しています。 相対リスク回避度の測定方法 3-3.最適投資割合の導出 資本市場線上で、投資家の期待効用が最も大きい箇所で投資を行うことが最適です。 つまり、無差別曲線と資本市場線が一つに交わる点が最適なポートフォリオになります。 交わる点座標( $\sigma_{opt}$, $\mu_{opt}$,)を(1)(2)式に代入し、右辺どうしを比較すると、 $$\frac{1}{2}\lambda\sigma_{opt}^{2} + u = b\sigma_{opt} + r_f$$ $\sigma_{opt}$について解の公式から重解を求めることで、 $$\sigma_{opt} = \frac{b}{\lambda} \tag{3}$$ また、無リスク資産のリスクは0であることから $$\sigma_{opt} = a_{opt} \times \sigma_{p} + (1 - a_{opt}) \times 0 $$ $$\Longleftrightarrow a_{opt} = \frac{\sigma_{opt}}{\sigma_{p}} \tag{4} $$ 4.実装 4-0.データの用意 今回は5種類の銘柄 (マクド・ソニー・東エレ・ファストリ・SBG) を対象商品とします。 stooqで銘柄コードから銘柄情報を取得します。こちらは、APIキー取得は不要。 終値のみを分析対象としています。 pct_changeメソッドを使うことで、株価変化率 (リターン) をdfに格納しています。 import numpy as np import scipy.optimize as sco import scipy.interpolate as sci import matplotlib as mpl import matplotlib.pyplot as plt import datetime import pandas as pd import pandas_datareader.stooq as stooq import cvxpy as cvx def get_stockvalues_tokyo(stockcode, start, end): """ stockcode: market code of each target stock (ex. "NNNN") defined by the Tokyo stock market. start, end: datetime object """ # Get index data from https://stooq.com/ df = stooq.StooqDailyReader(f"{stockcode}.jp", start, end).read() df = df.sort_values(by='Date',ascending=True) df = df.pct_change() return df def get_paneldata_tokyo(stockcodes, start, end): # Use "Close" value only dfs = [] for sc in stockcodes: df = get_stockvalues_tokyo(sc, start, end)[['Close']] df = df.rename(columns={'Close': sc}) dfs.append(df) df_concat = pd.concat(dfs, axis=1) df_concat.index = pd.to_datetime(df_concat.index) return df_concat start = datetime.datetime(2015, 1, 1) end = datetime.datetime(2020, 12, 31) ## マクド・ソニー・東エレ・ファストリ・SBG stockcodes=["2702", "6758", "8035", "9983", "9984"] stock_len=len(stockcodes) df = get_paneldata_tokyo(stockcodes, start, end) df.head() リターンデータを基に、年率のリターン期待値・共分散を求めます。 今回は、リスクフリーレート($r_f$)を3%としています。 Mu = df.mean().values * 245 Covs = df.cov().values * 245 rf = 0.03 4-1.資本市場線の実装 最適化問題を解くためのPythonライブラリ「cvxpy」を使って、マーコビッツの平均分散モデルを解くことで効率的ポートフォリオが得られます。 そこからシャープレシオが最大の箇所をマーケットポートフォリオであり、$r_f$に向けて資本市場線を引きます。 Weight = cvx.Variable(Mu.shape[0]) Target_Return = cvx.Parameter(nonneg=True) Risk_Variance = cvx.quad_form(Weight,Covs) constraints=[Weight.T@Mu == Target_Return, cvx.sum(Weight) == 1.0, Weight >= 0.0] Opt_Portfolio = cvx.Problem(cvx.Minimize(Risk_Variance),constraints) V_Target = np.linspace(max(Mu.min(),rf), Mu.max(), num=1000) V_Risk = np.zeros(V_Target.shape) V_Weight = np.zeros((V_Target.shape[0], Mu.shape[0])) for idx, Target_Return.value in enumerate(V_Target): Opt_Portfolio.solve() V_Weight[idx,:]=Weight.value.T V_Risk[idx]=np.sqrt(Risk_Variance.value) # シャープレシオ grads = (V_Target-rf)/V_Risk # gradients # マーケットポートフォリオ i_P = grads.argmax() grad_P = grads[i_P] sigma_P = V_Risk[i_P] weight_P = V_Weight[i_P] mu_P = V_Target[i_P] ## plot ## x = np.linspace(0, np.sqrt(np.diagonal(Covs)).max(), 100) y = grad_P*x + rf # 資本市場線 plt.figure(figsize=(8, 6)) plt.plot(V_Risk, V_Target, color='#007ee6', lw=4.0, label='Efficient Frontier') plt.plot(x, y, color='#b7282e', label='Capital Market Line') plt.plot(np.sqrt(np.diagonal(Covs)), Mu, 'kx', label='Individual Assets') plt.plot(sigma_P, mu_P, 'ko', label='Market Portfolio') plt.legend(loc='best') plt.xlim(-0.02, 0.4) plt.ylim(-0.02, 0.4) plt.axhline(0, color='k', ls='--', lw=2.0) plt.axvline(0, color='k', ls='--', lw=2.0) plt.xlabel('expected volatility') plt.ylabel('expected return') plt.show() 資本市場線の傾きは、 grad_P 1.0344591798031708 です。 4-2.投資家の無差別曲線の実装 相対的リスク回避度を求めるためには、投資家固有の a : 現在の危険資産保有率 weights : 現在の各銘柄投資割合 が必要となりますが、今回はそれぞれ乱数を与えて初期値を設定しておきます。 def rra_calc(Mu, Covs, weights, rf, a): mu_total = weights.dot(Mu) var_total = np.dot(weights.dot(Covs), weights.T) return (mu_total - rf)/(var_total*a) np.random.seed(999) weights = np.random.random(len(stockcodes)) weights /= np.sum(weights) a = np.random.random(1)[0] rra = rra_calc(Mu, Covs, weights, rf, a) ### plot ### def u(x, rra, u): return (1/2)*rra*x**2 + u x = np.linspace(0, np.sqrt(np.diagonal(Covs)).max(), 100) plt.figure(figsize=(8, 6)) plt.plot(x, u(x, rra, 0.2), color="olive", linestyle="dotted", label="0.2") plt.plot(x, u(x, rra, 0.13), color="g", linestyle="dotted", label="0.13") plt.plot(x, u(x, rra, 0.069), color="purple", linestyle="dotted", label="0.069") plt.plot(x, u(x, rra, 0.04), color="navy", linestyle="dotted", label="0.04") plt.legend(loc='best', frameon=False, title="utility") plt.xlim(-0.02, 0.4) plt.ylim(-0.02, 0.4) plt.axhline(0, color='k', ls='--', lw=2.0) plt.axvline(0, color='k', ls='--', lw=2.0) plt.xlabel('expected volatility') plt.ylabel('expected return') plt.show() この無差別曲線から、リターンが大きいほど・リスクが小さいほど、投資家の期待効用が大きくなっていることが分かります。 4-3.最適投資割合の実装 解の公式から、無差別曲線と資本市場線が一つに交わる点を求めます。 (3)(4)式から、危険資産の最適投資割合を求めています。 sigma_opt = grad_P / rra a_opt = sigma_opt / sigma_P mu_opt = (1 - a_opt)*rf + a_opt*mu_P ### plot ### x = np.linspace(0, np.sqrt(np.diagonal(Covs)).max(), 100) plt.figure(figsize=(8, 6)) plt.plot(x, u(x, rra, 0.2), color="olive", linestyle="dotted") plt.plot(x, u(x, rra, 0.13), color="g", linestyle="dotted") plt.plot(x, u(x, rra, 0.069), color="purple", linestyle="dotted") plt.plot(x, u(x, rra, 0.04), color="navy", linestyle="dotted") plt.plot(V_Risk, V_Target,color='#007ee6', lw=3.0) plt.plot(x, y,color='#b7282e') plt.plot(np.sqrt(np.diagonal(Covs)), Mu, 'kx') plt.plot(sigma_P, mu_P, 'ko') plt.plot(sigma_opt, mu_opt, 'r*', markersize=15.0) plt.xlim(-0.02, 0.4) plt.ylim(-0.02, 0.4) plt.axhline(0, color='k', ls='--', lw=2.0) plt.axvline(0, color='k', ls='--', lw=2.0) plt.xlabel('expected volatility') plt.ylabel('expected return') plt.show() ★に投資するのがベストとなります。 a_optは危険資産の最適投資割合なので、マーケットポートフォリオにおける投資割合に乗じることで個別銘柄の最適投資割合が求まります。 np.abs((weight_P * a_opt).round(3)) array([0.121, 0.116, 0.114, 0.007, 0. ]) よって、この投資家にとっての最適投資割合は、 マクド: 12.1%, ソニー: 11.6%, 東エレ: 11.4%, ファストリ: 0.7%, SBG: 0%, 現金: 64.2% となります!! 5.おまけ ここでは、モンテカルロ法を用いて資本市場線を実装します。 5-1.資本市場線の実装(Monte Carlo method) 以下の書籍を参考にして執筆しました。 Pythonによるファイナンス 第2版 詳しい説明については、この参考書に委ねます。 5-1-1.投資可能集合 各銘柄の投資割合に乱数を発生させ反復試行することで、投資可能集合を生成しています。(モンテカルロ法) np.random.seed(999) def port_ret(weights): return np.sum(Mu*weights) def port_vol(weights): return np.sqrt(np.dot(weights.T,np.dot(Covs, weights))) prets = [] pvols = [] for p in range (100000): weights = np.random.random(stock_len) weights /= np.sum(weights) prets.append(port_ret(weights)) pvols.append(port_vol(weights)) prets = np.array(prets) pvols = np.array(pvols) ### plot ### plt.figure(figsize=(10, 6)) plt.scatter(pvols, prets, c=(prets-rf)/pvols, marker='.', cmap='coolwarm') plt.xlim(-0.02, 0.4) plt.ylim(-0.02, 0.4) plt.axhline(0, color='k', ls='--', lw=2.0) plt.axvline(0, color='k', ls='--', lw=2.0) plt.xlabel('expected volatility') plt.ylabel('expected return') plt.colorbar(label='Sharpe ratio') plt.show() 5-1-2.効率的ポートフォリオ ここでは、minimize関数で最小化を行なっています。 ・シャープレシオの最大化 (負値の最小化) ・一定の期待リターン下でのリスクの最小化 def min_func_sharpe(weights): return -(port_ret(weights) - rf) / port_vol(weights) # シャープレシオの最大化 (負値の最小化) cons = ({'type':'eq', 'fun':lambda x: np.sum(x)-1}) bnds = tuple((0,1) for x in range(stock_len)) eweights = np.array(stock_len * [1./stock_len,]) opts = sco.minimize(min_func_sharpe, eweights, method='SLSQP', bounds=bnds, constraints=cons) cons = ({'type':'eq', 'fun': lambda x: port_ret(x)-tret}, {'type':'eq', 'fun': lambda x: np.sum(x)-1}) bnds = tuple((0,1) for x in weights) trets = np.linspace(Mu.min(), Mu.max(), 50) tvols = [] for tret in trets: # 各期待リターン下でのリスクの最小化 res = sco.minimize(port_vol, eweights, method='SLSQP', bounds=bnds, constraints=cons) tvols.append(res['fun']) tvols = np.array(tvols) ### plot ### plt.figure(figsize=(10, 6)) plt.scatter(pvols, prets, c=prets / pvols, marker='.', alpha=0.8, cmap='coolwarm') plt.plot(tvols, trets, 'b', lw=4.0) plt.plot(port_vol(opts['x']), port_ret(opts['x']), 'y*', markersize=15.0) plt.xlim(-0.02, 0.4) plt.ylim(-0.02, 0.4) plt.axhline(0, color='k', ls='--', lw=2.0) plt.axvline(0, color='k', ls='--', lw=2.0) plt.xlabel('expected volatility') plt.ylabel('expected return') plt.colorbar(label='Sharpe ratio') plt.show() 5-1-3.資本市場線 効率的フロンテイアにスプライン補間することで連続微分可能関数を定義します。 その関数を用いて、資本市場線についての連立方程式を解きます。 ind = np.argmin(tvols) evols = tvols[ind:] erets = trets[ind:] tck = sci.splrep(evols, erets) def f(x): return sci.splev(x, tck, der=0) def df(x): return sci.splev(x, tck, der=1) def equations(p, rf): eq1 = rf - p[0] eq2 = rf + p[1]*p[2]-f(p[2]) eq3 = p[1] - df(p[2]) return eq1, eq2, eq3 opt = sco.fsolve(equations, [0.01, 0.01, 0.01], rf) ### plot ### plt.figure(figsize=(10, 6)) plt.scatter(pvols, prets, c=(prets-rf) / pvols, marker='.', cmap='coolwarm') plt.plot(tvols, trets, 'b', lw=4.0) cx = np.linspace(0.0, Mu.max()) plt.plot(cx, opt[0]+opt[1]*cx, 'r', lw=1.5) plt.plot(opt[2], f(opt[2]), 'y*', markersize=15.0) plt.grid(True) plt.axhline(0, color='k', ls='--', lw=2.0) plt.axvline(0, color='k', ls='--', lw=2.0) plt.xlim(-0.02, 0.4) plt.ylim(-0.02, 0.4) plt.xlabel('expected volatility') plt.ylabel('expected return') plt.colorbar(label='Sharpe ratio') plt.show() 資本市場線の傾きは、 opt[1] 1.0344560719089742 となり、前述の grad_P とほとんど等しくなり、4-1で引いた資本市場線と似た直線になりました!! こちらの記事でも、モンテカルロ法を使った最適化が紹介されているので是非参考にしてみてください。 Pythonを用いての効率的フロンティアとポートフォリオの最適化
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Kubeflow KFServingでscikit-learnの学習済みモデルを用いた推論サービスを公開する

著者: 株式会社 日立ソリューションズ 柳村 明宏 監修: 株式会社 日立製作所 はじめに KubeflowはKubernetes上でMLOpsを実現するためのOSSのツールキットです。2020/3にバージョン1.0がリリースされ、2021/4現在も活発に開発が行われており、機械学習を利用したシステムの開発/運用のライフサイクルを回すための有効な手段の1つとして注目されています。 本連載では、Kubeflowのバージョン1.2(連載開始時点の最新版、2020年11月リリース)について、構築手順、Kubeflow Pipelines、KFServingの基礎的な利用手順についての情報を紹介いたします。 第4回の本稿では、第3回⽬で作成した学習済みモデルを利⽤した推論サービスを、Kubeflowのサービングコンポーネントの1つであるKFServingを利用して公開する⼿順を紹介いたします。 本連載では、Kubernetesの前提バージョンを1.20としています。 ステータスがStableのSeldon Core Servingは、前提とするKubernetesのバージョンが1.12から1.17であったため、ステータスがBetaであるKFservingを利用した検証を行いました。 投稿一覧: 1. MLOpsを実現するKubeflowを前提のKubernetesも含めて構築する(前編) 2. MLOpsを実現するKubeflowを前提のKubernetesも含めて構築する(後編) 3. Kubeflow Pipelinesでscikit-learnの機械学習モデルを訓練・評価してみる 4. Kubeflow KFServingでscikit-learnの学習済みモデルを用いた推論サービスを公開する (本投稿) KFServingの概要 KFServingは、Kubernetes上でのサーバレス推論を実現するコンポーネントで、TensorFlow、XGBoost、Scikit-learn、PyTorch、ONNXなどの一般的な機械学習(ML)フレームワークを抽象度の高いYAMLファイルに記述することで構築することができます。 KFServingの詳細は、Kubeflow公式サイトのKFServingのページを参照してください。 KFServingの利用手順 今回のKFServingの利用手順を次に示します。 今回のKubeflow Pipelinesの利用手順 # 手順 概要 1 KFServingの開発環境を準備 第1回目、および、第2回目でkubeflowを構築したマシンにログインし、KFServingのリポジトリをクローンします。 2 推論サービスのデプロイ scikit-learnのsampleを編集して、第3回目でAmazon S3にアップロードしたscikit-learnの学習済みモデルの読込み、および、推論処理を行えるようにします。編集したコードのDockerイメージをビルドし、推論サービスのデプロイを行います。 3 推論サービスの利用 デプロイした推論サービスを利用し、推論を実行します。 1. KFServingの開発環境を準備 1.1 SSHでログイン 第1回目、および、第2回目で、Kubeflowを構築したマシンにSSHでログインします。 1.2 KFServingのバージョン確認 本稿では、Kubeflow構築済みの環境を前提とするため、KFServingのインストールは不要です。 また、ネームスペースはkubeflowとなります。 KFServingのバージョンは、「2.3 Amazon S3アクセスに必要なAWS認証設定」で編集する、KFServingのAWS認証用の設定ファイルの内容に影響します。 # KFServingのバージョン確認 kubectl get po -n kubeflow -o yaml | grep image.*kfserving-controller: # --- 実行結果例 ここから ------------------------------------------------- # image: gcr.io/kfserving/kfserving-controller:v0.4.1 # image: gcr.io/kfserving/kfserving-controller:v0.4.1 # --- 実行結果例 ここまで ------------------------------------------------- 1.3 KFServingのリポジトリのクローン KFServingのGitHubのリポジトリをクローンします。 # KFServingのリポジトリをクローン git clone https://github.com/kubeflow/kfserving.git scikit-learnのsampleは、次のサンプルを利用します。 YAMLファイルのsample コードのsample 編集するファイルは次のファイルです。 # 記載箇所 ファイルパス 1 2.1 scikit-learnの学習済みモデルを用いた推論処理を作成 ~/kfserving/python/sklearnserver/sklearnserver/model.py 2 2.2 Dockerイメージのビルド ~/kfserving/python/sklearnserver/setup.py 3 2.3 Amazon S3アクセスに必要なAWS認証設定 ~/kfserving/docs/samples/storage/s3/s3_secret.yaml 4 2.4 推論サービスのデプロイ ~/kfserving/docs/samples/v1alpha2/sklearn/sklearn.yaml 2.推論サービスのデプロイ 2.1 scikit-learnの学習済みモデルを用いた推論処理を作成 第3回目でAmazon S3にアップロードしたscikit-learnの学習済みモデルを読込み、KFServingを利用して推論を実行できるように「~/kfserving/python/sklearnserver/sklearnserver/model.py」を編集します。 model.pyの編集後のコードを次に示します。編集前のコード(KFServingのscikit-learnサンプルのmodel.py)については、model.pyのsampleを参照してください。 model.py import kfserving import os import pickle import pandas as pd import sys import json from typing import Dict sys.path.append('/sklearnserver/sklearnserver') from preprocessor import PreProcessor MODEL_BASENAME = "ml_pipeline" MODEL_EXTENSIONS = [".pickle"] class SKLearnModel(kfserving.KFModel): # pylint:disable=c-extension-no-member def __init__(self, name: str, model_dir: str): super().__init__(name) self.name = name self.model_dir = model_dir self.ready = False # モデルファイルの読込み処理 def load(self) -> bool: model_path = kfserving.Storage.download(self.model_dir) paths = [os.path.join(model_path, MODEL_BASENAME + model_extension) for model_extension in MODEL_EXTENSIONS] for path in paths: if os.path.exists(path): self._model = pickle.load(open(path, 'rb')) self.ready = True break return self.ready # 推論処理 def predict(self, request: Dict) -> Dict: # リクエストから値を取得 instances = request["instances"] try: # DataFrame化 X_df = pd.DataFrame(instances) # 予測を実行 pred = self._model.predict(X_df) # 予測結果をJson化 result = {"Survived": int(pred[0])} # 予測結果を返信 return json.dumps(result) except Exception as e: raise Exception("Failed to predict %s" % e) MODEL_BASENAME、MODEL_EXTENSIONSは、第3回目で作成した学習済みモデルを指定します。 model.pyでは、第3回目で作成したpreprocessor.pyをインポートするため、preprocessor.pyを「~/kfserving/python/sklearnserver/sklearnserver/」に配置してください。 2.2 Dockerイメージのビルド 「2.1 scikit-learnの学習済みモデルを用いた推論処理を作成」で編集したコードをビルドしてDockerイメージを作成するために、「~/kfserving/python/sklearnserver/setup.py」を編集します。 setup.pyの編集後のコードを次に示します。ここでは次の編集を実施します。 「install_requires=」のscikit-learnのバージョンを、学習済モデルを作成したときに利用したscikit-learnのバージョンに合わせます。 追加したいライブラリがあれば追加で記載します。今回は「pandas >= 1.0.0"」を記載しています。 編集前のコード(ライブラリ配布用のpythonサンプルのsetup.py)については、setup.pyのsampleを参照してください。 setup.py from setuptools import setup, find_packages tests_require = [ 'pytest', 'pytest-asyncio', 'pytest-tornasync', 'mypy' ] setup( name='sklearnserver', version='0.5.0', author_email='singhan@us.ibm.com', license='https://github.com/kubeflow/kfserving/LICENSE', url='https://github.com/kubeflow/kfserving/python/sklearnserver', description='Model Server implementation for scikit-learn. \ Not intended for use outside KFServing Frameworks Images', long_description=open('README.md').read(), python_requires='>3.4', packages=find_packages("sklearnserver"), install_requires=[ "kfserving>=0.5.0", "scikit-learn == 0.24.1", "pandas >= 1.0.0" ], tests_require=tests_require, extras_require={'test': tests_require} ) インストールするscikit-learnのバージョンは、第3回目で指定したバージョンと同一のバージョンを指定します。 自身のDockerレジストリにログインします。 # docker loginの実行 sudo docker login Dockerイメージを作成します。 参考: Building your own scikit-Learn Server Docker Image # Dockerイメージの作成 sudo docker build -t [Dockerユーザ名]/[イメージ名] -f ~/kfserving/python/sklearn.Dockerfile ~/kfserving/python # --- 実行結果例 ここから ------------------------------------------------------------------------------- # Successfully built 81d6efc54e84 # Successfully tagged [Dockerユーザ名]/[イメージ名]:latest # --- 実行結果例 ここまで ------------------------------------------------------------------------------- # 作成したイメージの確認 sudo docker images --digests [Dockerユーザ名]/[イメージ名]:latest # --- 実行結果例 ここから ------------------------------------------------------------------------------- # REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE # [Dockerユーザ名]/[イメージ名] latest <none> 41909b0f94e0 42 minutes ago 1.36GB # --- 実行結果例 ここまで ------------------------------------------------------------------------------- # 作成したイメージのアップロード sudo docker push [Dockerユーザ名]/[イメージ名]:latest # --- 実行結果例 ここから ------------------------------------------------------------------------------- # The push refers to repository [docker.io/[Dockerユーザ名]/[イメージ名]] # 9ef05367b9dc: Pushed # b84a57dacdd2: Pushed # 1add26dfd9ff: Pushed # 9df36e5bd672: Pushed # 16be529e8612: Pushed # 9ab20c4343be: Layer already exists # 7ebccfde7bb7: Layer already exists # d20676915161: Layer already exists # 852a1bb5386c: Layer already exists # 9437609235f0: Layer already exists # bee1c15bf7e8: Layer already exists # 423d63eb4a27: Layer already exists # 7f9bf938b053: Layer already exists # f2b4f0674ba3: Layer already exists # latest: digest: sha256:66dbf7d11e89d824b8e48f9e568ecd0049f21e2b76f694f5cb3c68365afa5ad0 size: 3272 # --- 実行結果例 ここまで ------------------------------------------------------------------------------- Inference Service用のconfigmapに、作成したscikit-learn のDockerイメージを指定します。 参考: Run SKLearn InferenceService with your own image # Inference Service用のconfigmapの編集 kubectl -n kubeflow edit configmap inferenceservice-config configmap :(省略) predictors: |- { :(省略) "sklearn": { "image": "[Dockerユーザ名]/[イメージ名]" }, :(省略) 2.3 Amazon S3アクセスに必要なAWS認証設定 Amazon S3に格納しているモデルファイルを参照するため、AWS認証用のYAMLファイル「~/kfserving/docs/samples/storage/s3/s3_secret.yaml」について、公式ドキュメントを参考に編集します。 参考: s3_secret.yaml、Store models in S3 bucket 今回、KFServingは0.41を利用しているため、0.4以降のバージョンを利用する場合の例を記載します。 0.3以前のバージョンを利用する場合は、dataタグに指定するAWS_ACCESS_KEY_ID、および、AWS_SECRET_ACCESS_KEYの変数名をそれぞれ、awsAccessKeyID、および、awsSecretAccessKeyと指定します。 AWS_ACCESS_KEY_ID、および、AWS_SECRET_ACCESS_KEYの値をBASE64エンコードして設定 <…の値>部分は環境に合わせて指定します。 export AWS_ACCESS_KEY_ID_BASE64=`echo -n "<AWS_ACCESS_KEY_IDの値>" | base64` export AWS_SECRET_ACCESS_KEY_BASE64=`echo -n "<AWS_SECRET_ACCESS_KEYの値>" | base64` s3_secret.yaml apiVersion: v1 kind: Secret metadata: name: mysecret annotations: serving.kubeflow.org/s3-endpoint: s3.ap-northeast-1.amazonaws.com serving.kubeflow.org/s3-usehttps: "1" serving.kubeflow.org/s3-verifyssl: "1" serving.kubeflow.org/s3-region: ap-northeast-1 type: Opaque data: AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID_BASE64} AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY_BASE64} --- apiVersion: v1 kind: ServiceAccount metadata: name: sa secrets: - name: mysecret s3-endpoint、および、s3-regionは環境に合わせて設定します。 AWS認証情報をKubernetesへ設定します。 # AWS認証情報のKubernetesへの設定 kubectl apply -f s3_secret.yaml # --- 実行結果例 ここから ----------------- # secret/mysecret created # serviceaccount/sa created # --- 実行結果例 ここまで ----------------- 2.4 推論サービスのデプロイ scikit-learn Inference Service用のYAML「~/kfserving/docs/samples/v1alpha2/sklearn/sklearn.yaml」を編集し、推論サービスをデプロイします。 sampleでは、storageUriにGCPのパスが記載されていますが、今回Amazon S3を利用するため、Amazon S3のパスを記載します。 参考: Run SKLearn InferenceService with your own image sklearn.yaml apiVersion: "serving.kubeflow.org/v1alpha2" kind: "InferenceService" metadata: name: "sklearn-iris" spec: default: predictor: serviceAccountName: sa sklearn: storageUri: "s3://kubeflow-pl" serviceAccountNameには、「2.3 Amazon S3アクセスに必要なAWS認証設定」で編集したYAMLファイルのServiceAccountのnameを指定します。 storageUriには、第3回目で学習済みモデルをアップロードしたAmazon S3のUriを指定します。 scikit-learn Inference Serviceをデプロイします。 kubectl apply -f sklearn.yaml # --- 実行結果例 ここから ------------------------------------------------------------------------------- # inferenceservice.serving.kubeflow.org/sklearn-iris created # --- 実行結果例 ここまで ------------------------------------------------------------------------------- # Podの状態確認 kubectl get pods -l model=sklearn-iris # --- 実行結果例 ここから ------------------------------------------------------------------------------- # NAME    READY STATUS RESTARTS AGE # sklearn-iris-predictor-default-6lvmc-deployment-856956bb95sgd5r 2/2  Running 0 89s # --- 実行結果例 ここまで ------------------------------------------------------------------------------- # ログの確認 kubectl logs sklearn-iris-predictor-default-6lvmc-deployment-856956bb95sgd5r kfserving-container # --- 実行結果例 ここから ------------------------------------------------------------------------------- # [I 210310 16:28:10 storage:45] Copying contents of /mnt/models to local # [I 210310 16:28:10 kfserver:115] Registering model: sklearn-iris # [I 210310 16:28:10 kfserver:96] Listening on port 8080 # [I 210310 16:28:10 kfserver:98] Will fork 1 workers # --- 実行結果例 ここまで ------------------------------------------------------------------------------- 3. 推論サービスの利用 推論したいデータをJsonファイルで作成して、推論を実行します。 参考: Run a prediction 正常に動作した場合、「2.1 scikit-learnの学習済みモデルを用いた推論処理を作成」で実装した通り、「{"Survived": 0}または{"Survived": 1}」が返ってきます。 3.1 入力データの準備 推論したいデータをJsonファイルで作成します。 # 推論データの作成 cat <<EOF> ml-input.json { "instances": [ { "PassengerId": 294, "Pclass": 1, "Name": "John, Mr. Smith", "Sex": "male", "Age": 28, "SibSp": 0, "Parch": 0, "Ticket": 312453, "Fare": 18.2500, "Cabin": "NaN", "Embarked": "Q" } ] } EOF 3.2 推論を実行 推論実行時に必要な環境変数を設定します。 MODEL_NAMEは、「2.4 推論サービスのデプロイ」で設定したmetadataタグのnameを指定してします。 MODEL_NAME=sklearn-iris INPUT_PATH=ml-input.json SERVICE_HOSTNAME=$(kubectl get inferenceservice sklearn-iris -o jsonpath='{.status.url}' | cut -d "/" -f 3) export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}') export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}') KFServingのエンドポイントにHTTPリクエストを送信して、推論サービスを呼び出します。 # 推論の実行 curl -v -H "Host: ${SERVICE_HOSTNAME}" http://${INGRESS_HOST}:${INGRESS_PORT}/v1/models/$MODEL_NAME:predict -d $INPUT_PATH # --- 実行結果例 ここから ------------------------------------------------------------------------------- # * Trying [INGRESS_HOSTの値]... # * TCP_NODELAY set # * Connected to [INGRESS_HOSTの値] ([INGRESS_HOSTの値]) port [INGRESS_PORTの値] (#0) # > POST /v1/models/sklearn-iris:predict HTTP/1.1 # > Host: sklearn-iris.default.example.com # > User-Agent: curl/7.58.0 # > Accept: */* # > Content-Length: 263 # > Content-Type: application/x-www-form-urlencoded # > # * upload completely sent off: 263 out of 263 bytes # < HTTP/1.1 200 OK # < content-length: 15 # < content-type: text/html; charset=UTF-8 # < date: Wed, 10 Mar 2021 16:36:26 GMT # < server: istio-envoy # < x-envoy-upstream-service-time: 26 # < # * Connection #0 to host [INGRESS_HOSTの値] left intact # {"Survived": 0} # --- 実行結果例 ここまで ------------------------------------------------------------------------------- Podには下記のようにHTTPリクエストの結果が出力されます。 # ログの確認 kubectl logs sklearn-iris-predictor-default-6lvmc-deployment-856956bb95sgd5r kfserving-container # --- 実行結果例 ここから ------------------------------------------------------------------------------- # [I 210310 16:36:26 web:2243] 200 POST /v1/models/sklearn-iris:predict (127.0.0.1) 22.87ms # --- 実行結果例 ここまで ------------------------------------------------------------------------------- おわりに 本稿では、Kubeflow KFServingでscikit-learnの学習済みモデルを用いた推論サービスを公開する手順を紹介しました。 Kubeflowの公式サイトなどに掲載されている情報やサンプルの多くは、Google Cloud Platform前提です。本投稿ではオンプレミスやGoogle Cloud Platform以外のクラウド環境で利用する方にも、基礎的な情報として参考してもらえればと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

django アプリケーションテスト時のエラー

ImportError ターミナル $ python manage.py test 上記を実行時に ImportError: 'tests' module incorrectly imported fromのエラーが発生。 原因 同じディレクトリ内に「tests」と「tests.py」の両方が存在している事が原因。 diary ├── tests │ └── test_views.py └── tests.py 対処法 既存のtests.pyを削除することで解決。 「tests.py」についてはターミナルでstartupコマンドを実行した際に、自動的に作られてしまうので手動で削除する必要がある。 RuntimeError 上記エラー解消後に発生。 RuntimeError: Model class django.contrib.contenttypes.models.ContentType doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS. INSTALLED_APPS = [ 'django.contrib.contenttypes', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.sites', 'diary.apps.DiaryConfig', 'accounts.apps.AccountsConfig', 'allauth', 'allauth.account', ] settingsにはエラーに書かれているdjango.contrib.contenttypesは書かれているので別のものが原因と思われる。 原因&対処法 このページのコメント欄に書かれている同じディレクトリ内の__init__.pyを削除したところエラーが解消された。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【数理考古学】群論とシミュレーション原理⑤二次元トーラス概念への発展

【数理考古学】群論とシミュレーション原理①これまでの投稿内容のまとめ。 吃驚するほどグチャグチャになってしまったので整理を試みます。 一次元トーラス概念の規定 以下で極座標系(Polar Coordinates System)(r,θ)上の円(Circle)=半径1の単位円×半径(Radius)R=観測結果集合とする円周群=リー群$S_0$=1次元トーラス×半径(Radius)rを規定する演算をまとめました。 【数理考古学】群論とシミュレーション原理②群導出演算としてのガウスの巡回群 この場合では円を正n角形の形で分割し「辺数=∞、辺長$\frac{1}{∞}=0$の場合」が円を規定する。 【数理考古学】群論とシミュレーション原理④群導出演算としてのオイラーの公式 $\cos(θ)=\frac{e^{θi}+e^{-θi}}{2}$ $\sin(θ)=\frac{e^{θi}-e^{-θi}}{2i}$ $e^{ix}\frac{d^n}{dθ^n}=(i e^{i x}(-\log ix),-e^{ix},-i e^{i x}(\log ix),e^{ix},…)$ $\int \int \int … \int e^{ix}(dθ)=(- i e^{i x}(\log ix),- e^{i x},i e^{i x}(-\log ix),e^{ix},…)$ この場合ではネイピア数e=2.718282の近似が十分な精度以上の場合が円を規定する。 【数理考古学】群論とシミュレーション原理⑤群導出演算としての「公比-1の等比数列」 この場合では「周回関数(Rap Function)$α^n$の冪根αが十分1に近く」かつ「周期関数(Cyclyc Function)$−1^n$の冪根βが十分-1に近い」場合が円を規定する。 二次元トーラス概念の規定 上掲の円概念の直積(Direct Product)を求めると二次元デカルト座標系(2D Cartesian Coordinate System)ではなく二次元トーラス(2D Torus)なる新たな座標系へと進むことになります。 【Python演算処理】単位球面¥を巡る数理②そして単位トーラスへ - Qiita とりあえず最初に現れる大半径(Major Radius)Rと小半径(Minor Radius)rの比率が1:1の場合のトーラスを単位トーラス(Unit Torus)と呼び分ける事にしましょう。 上図の通り、その側面図には円概念が実軸0を中心として2個隣接して現れる。「実軸0を中心とする半径1の球面」を偶数系(Even System)の起源と置くなら、これが奇数系(Odd System)の起源となる。【Python演算処理】単位トーラスを巡る数理②トーラス群の設定 この様に二つの半径の組み合わせで表現されるトーラス座標系(Torus Coordinates System)と三次元デカルト座標系(3D Cartesian Coordinate System)の関係は、一般に媒介変数t,p(0≦t≦2π,0≦p≦2π)を用いて以下の様に表されます。 $R×\cos(t)+r×\cos(p)\cos(t)$ $R×cos(t)+r×\cos(p)\sin(t)$ $r×\sin(p)$ 一般の円/球面座標系との関係は以下とされています。 大半径R=0,小半径r=1の時、単位球面(Unit Sphere=半径1の球表面)を二重に描く(3次元極座標系や経緯度法で垂直角を水平角の半分に取るのは、この時出る重複部分を除く為)。【Python演算処理】半径・直径・円周長・円の面積・球の表面積・球の体積の計算上の往復 逆に大半径R=1,小半径r=0の時、Z=0となってただの単一の単位円(Unit Circle=半径1の円弧)を描く。かかる極限状態に向かう展開は「単位円に内接する正N角形とそのさらなる内接円の推移(N=∞に近づくほど、どちらの正N角形としての辺長計も円周長2πに限りなく近づいていく)」そのものである。 さらにRr比(大半径Rと小半径rの比)に注目すると以下の表現となります。 トーラスのRr比が$\frac{\infty}{0}=\infty$に限りなく近づく時、その全体構造は上掲の「二重球面状態」に向かう。 トーラスの Rr比が$\frac{1}{\infty}=0$に限りなく近づく時、その全体構造は上掲の「単円弧状態」に向かう。 この考え方では「二重球面状態」や「単円弧状態」自体には到達不可能となるので、その結果得られる観測結果集合や演算結果集合はこれらを含まない開集合となる(この事により「二重球面状態」や「単円弧状態」自体は特異点化する)。 どうやらこの景色はn次球面について(人間が扱える)3次元までの空間概念のみ抽出して操作する作業イメージに発展させられそうです。とりあえずこの全体像を無限トーラス(Infinity Torus)と呼ぶ事にしましょう。さらに大半径への分枝切断点追加に際して小半径も同様に分割する場合を元、分割数に比例して回転数も上げていく場合を逆元と置けば、分割数1(追加分枝切断点0)を単位元とする乗法群の一種トーラス群(Torus Group)が現れます。 G_n(n=-\infty→-3→-2→-1→0→1→2→3→+\infty)\\=(\infty,…,4,…,3,…,2,…,1,…,\frac{1}{2},…,\frac{1}{3},…,\frac{1}{4},…,0) この過程で上面図に現れる正n角形(1分割状態から始まって辺数無限大、辺長無限小の円弧状態に限りなく近づいていく)はRr比によって一意に定まるので、最終的には$±i^{ax}$関数による表現に統合される形となりそうです。 【数理考古学】群論とシミュレーション原理⑤群導出演算としての「公比-1の等比数列」 その一方で、二次元トーラスを平面展開した平坦トーラス(Flat Torus)は1目盛2πの「方眼」が現れますが(分枝点切断前だと)次の升目に移行する概念が存在しません だからComputer RPGのWorld Mapの様にグルグル堂々巡りするのみ。 【Python演算処理】単位トーラスを巡る数理①平坦トーラスとの往復 群論ではこれを「リー群に対して(対数写像によって)接空間リー代数(リー環)を取る」と表現するのですが、こちらの系統には複素関数理論における「多価関数への分枝点切断(Branch Point Cut)概念の導入」についての言及がありません。 かかる2次元トーラス上の回転運動の軌跡は、それをアイロンでも掛けたかの様に真っ直ぐ伸ばし、分岐切断して連続させると(デカルト座標系につながる)円筒座標系(Cylindrical Coordinate System)に推移する訳だが、群論から入るとこの辺りのイメージが掴み難くなってしまうのである。 一方、複素関数論の系統では、その場合に自明の場合(Trival Case)として選択肢の一つとして現れる「分枝点を2個設定し、目盛の一升のピッチをπとし、偶奇性(Parity)の概念を追加する」考え方への言及がありません。 微積分計算上は「分枝点を1個設定し、目盛の一升のピッチを2πとする」選択の一択だから?【数理考古学】群論とシミュレーション原理③群導出演算としての解析学的アプローチ そんな感じで以下続報…
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【数理考古学】群論とシミュレーション原理⑥二次元トーラス概念への発展

【数理考古学】群論とシミュレーション原理①これまでの投稿内容のまとめ。 吃驚するほどグチャグチャになってしまったので整理を試みます。 一次元トーラス概念の規定 以下で極座標系(Polar Coordinates System)(r,θ)上の円(Circle)=半径1の単位円×半径(Radius)R=観測結果集合とする円周群=リー群$S_0$=1次元トーラス×半径(Radius)rを規定する演算をまとめました。 【数理考古学】群論とシミュレーション原理②群導出演算としてのガウスの巡回群 この場合では円を正n角形の形で分割し「辺数=∞、辺長$\frac{1}{∞}=0$の場合」が円を規定する。 【数理考古学】群論とシミュレーション原理④群導出演算としてのオイラーの公式 $\cos(θ)=\frac{e^{θi}+e^{-θi}}{2}$ $\sin(θ)=\frac{e^{θi}-e^{-θi}}{2i}$ $e^{ix}\frac{d^n}{dθ^n}=(i e^{i x}(-\log ix),-e^{ix},-i e^{i x}(\log ix),e^{ix},…)$ $\int \int \int … \int e^{ix}(dθ)=(- i e^{i x}(\log ix),- e^{i x},i e^{i x}(-\log ix),e^{ix},…)$ この場合ではネイピア数e=2.718282の近似が十分な精度以上の場合が円を規定する。 【数理考古学】群論とシミュレーション原理⑤群導出演算としての「公比-1の等比数列」 この場合では「周回関数(Rap Function)$α^n$の冪根αが十分1に近く」かつ「周期関数(Cyclyc Function)$−1^n$の冪根βが十分-1に近い」場合が円を規定する。 二次元トーラス概念の規定 上掲の円概念の直積(Direct Product)を求めると二次元デカルト座標系(2D Cartesian Coordinate System)ではなく二次元トーラス(2D Torus)なる新たな座標系へと進むことになります。 【Python演算処理】単位球面¥を巡る数理②そして単位トーラスへ - Qiita とりあえず最初に現れる大半径(Major Radius)Rと小半径(Minor Radius)rの比率が1:1の場合のトーラスを単位トーラス(Unit Torus)と呼び分ける事にしましょう。 上図の通り、その側面図には円概念が実軸0を中心として2個隣接して現れる。「実軸0を中心とする半径1の球面」を偶数系(Even System)の起源と置くなら、これが奇数系(Odd System)の起源となる。【Python演算処理】単位トーラスを巡る数理②トーラス群の設定 この様に二つの半径の組み合わせで表現されるトーラス座標系(Torus Coordinates System)と三次元デカルト座標系(3D Cartesian Coordinate System)の関係は、一般に媒介変数t,p(0≦t≦2π,0≦p≦2π)を用いて以下の様に表されます。 $R×\cos(t)+r×\cos(p)\cos(t)$ $R×cos(t)+r×\cos(p)\sin(t)$ $r×\sin(p)$ 一般の円/球面座標系との関係は以下とされています。 大半径R=0,小半径r=1の時、単位球面(Unit Sphere=半径1の球表面)を二重に描く(3次元極座標系や経緯度法で垂直角を水平角の半分に取るのは、この時出る重複部分を除く為)。【Python演算処理】半径・直径・円周長・円の面積・球の表面積・球の体積の計算上の往復 逆に大半径R=1,小半径r=0の時、Z=0となってただの単一の単位円(Unit Circle=半径1の円弧)を描く。かかる極限状態に向かう展開は「単位円に内接する正N角形とそのさらなる内接円の推移(N=∞に近づくほど、どちらの正N角形としての辺長計も円周長2πに限りなく近づいていく)」そのものである。 さらにRr比(大半径Rと小半径rの比)に注目すると以下の表現となります。 トーラスのRr比が$\frac{\infty}{0}=\infty$に限りなく近づく時、その全体構造は上掲の「二重球面状態」に向かう。 トーラスの Rr比が$\frac{1}{\infty}=0$に限りなく近づく時、その全体構造は上掲の「単円弧状態」に向かう。 この考え方では「二重球面状態」や「単円弧状態」自体には到達不可能となるので、その結果得られる観測結果集合や演算結果集合はこれらを含まない開集合となる(この事により「二重球面状態」や「単円弧状態」自体は特異点化する)。 どうやらこの景色はn次球面について(人間が扱える)3次元までの空間概念のみ抽出して操作する作業イメージに発展させられそうです。とりあえずこの全体像を無限トーラス(Infinity Torus)と呼ぶ事にしましょう。さらに大半径への分枝切断点追加に際して小半径も同様に分割する場合を元、分割数に比例して回転数も上げていく場合を逆元と置けば、分割数1(追加分枝切断点0)を単位元とする乗法群の一種トーラス群(Torus Group)が現れます。 G_n(n=-\infty→-3→-2→-1→0→1→2→3→+\infty)\\=(\infty,…,4,…,3,…,2,…,1,…,\frac{1}{2},…,\frac{1}{3},…,\frac{1}{4},…,0) この過程で上面図に現れる正n角形(1分割状態から始まって辺数無限大、辺長無限小の円弧状態に限りなく近づいていく)はRr比によって一意に定まるので、最終的には$±i^{ax}$関数による表現に統合される形となりそうです。 【数理考古学】群論とシミュレーション原理⑤群導出演算としての「公比-1の等比数列」 その一方で、二次元トーラスを平面展開した平坦トーラス(Flat Torus)は1目盛2πの「方眼」が現れますが(分枝点切断前だと)次の升目に移行する概念が存在しません だからComputer RPGのWorld Mapの様にグルグル堂々巡りするのみ。RPG世界の形状についての幾何学的考察と可視化 【Python演算処理】単位トーラスを巡る数理①平坦トーラスとの往復 群論ではこれを「リー群に対して(対数写像によって)接空間リー代数(リー環)を取る」と表現するのですが、こちらの系統には複素関数理論における「多価関数への分枝点切断(Branch Point Cut)概念の導入」についての言及がありません。 かかる2次元トーラス上の回転運動の軌跡は、それをアイロンでも掛けたかの様に真っ直ぐ伸ばし、分岐切断して連続させると(デカルト座標系につながる)円筒座標系(Cylindrical Coordinate System)に推移する訳だが、群論から入るとこの辺りのイメージが掴み難くなってしまうのである。 一方、複素関数論の系統では、その場合に自明の場合(Trival Case)として選択肢の一つとして現れる「分枝点を2個設定し、目盛のピッチをπとし、偶奇性(Parity)の概念を追加する」考え方への言及がありません。 微積分計算上は「分枝点を1個設定し、目盛のピッチを2πとする」選択の一択だからかも?【数理考古学】群論とシミュレーション原理③群導出演算としての解析学的アプローチ そんな感じで以下続報…
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

pythonで親しみやすいRPAを作った備忘録(1)

Pythonのpyautoguiなどのライブラリを使った自作RPAの備忘録。 ライブラリの使い方と実装サンプル。 ↓↓↓自作RPAのソースコード↓↓↓ テキストと画像で簡単操作。 ゲームのスキルバーをイメージ。 ソースコード インストール pyautogui 自動化ライブラリ opencv 1 pynput キー・マウス監視ライブラリ(バージョン1.6.4)2 pyperclip クリップボード操作ライブラリ playsound 音楽再生ライブラリ install pip install pyautogui pip install opencv-python pip install pynput==1.6.4 pip instal pyperclip pip install playsound pyautoguiチュートリアル できること マウス操作 キーボード操作 画面認識(画面の座標・スクリーンショット取得、画面から画像認識) マウス操作 pyautogui-click # GUI automation import pyautogui # 画面サイズの取得 x, y = pyautogui.size() x, y = x / 2, y / 2 x2, y2 = x / 3, y / 3 # カーソルの移動速度(秒) clickduration = 0.5 # クリック pyautogui.click(x,y,duration=clickduration) # ダブルクリック pyautogui.doubleClick(x2,y2,duration=clickduration) # 右クリック pyautogui.rightClick(x,y,duration=clickduration) # カーソル移動 pyautogui.moveTo(x2,y2,duration=clickduration) # ドラッグ(クリック) pyautogui.dragTo(x,y,duration=clickduration,button='left') キーボード操作 typewriteは半角全角の制御が別途必要。 回避策は 入力文字をクリップボードにコピーし、hotkeyを使いctrl+vによる貼り付けなど pyautogui-keyboard # GUI automation import pyautogui # キー入力 pyautogui.press('p') # キーを押し続ける pyautogui.keyDown('ctrl') # キーを離す pyautogui.keyUp('ctrl') # 2キー入力 pyautogui.hotkey('ctrl','c') # 文字列入力 pyautogui.typewrite('typewrite',interval=1) # 複数キー入力は以下で実装可能 pyautogui.keyDown('win') pyautogui.keyDown('shift') pyautogui.press('s') pyautogui.keyUp('win') pyautogui.keyUp('shift') 画面の取得と画像認識 pyautogui-locateonscreen # GUI automation import pyautogui # ターゲット画像のパス imgpath = 'sample1.png' # 画像認識精度(0.0~1.0:値が大きいほど精度が高くなる) confidence = 0.8 # 画面からターゲット画像を取得 target = pyautogui.locateOnScreen(imgpath,confidence=confidence) # ターゲットの中心座標を取得 x, y = pyautogui.center(target) # クリック pyautogui.click(x,y) pynputチュートリアル できること マウス操作の検出 キーボード操作の検出 pynput # マウス・キーボード監視 import pynput # キーを押したときの処理 def press(key): try: # 英字キーを入力したときはこっちに行くみたい print(key.char) except AttributeError: # Enterやタブなど特殊なキーはこっち print(key) # キーを離したときの処理 def release(key): print(key) if key == pynput.keyboard.Key.esc: return False # クリックしたときの処理 def click(x, y, button, pressed): print(x, y) # 押したときだけ処理するならpressedを追加 if pressed: print('pressed') else: print('release') # キーボードリスナー起動 押したときと離したときのイベントを取得 keylistener = pynput.keyboard.Listener(on_press=press,on_release=release) keylistener.start() # マウスリスナー起動 クリックしたときのイベントを取得 with pynput.mouse.Listener(on_click=click) as mouselistener: mouselistener.join() 参考:【Python RPA】マウス・キーボード操作を同時に検知・取得する方法(pynput) pyperclipチュートリアル できること クリップボード監視 pyperclip # クリップボード監視 import pyperclip # クリップボードにテキストを格納 pyperclip.copy('test') # クリップボードの内容を取得 clipboard = pyperclip.paste() print(clipboard) プログラムを実行するとクリップボードが変更される 実装 プログラムのイメージ GUI ゲームのスキルバーをイメージ。 アイコンが横に並んでおり、アイコンをクリックするとRPAプログラムが実行される。 実行中は、赤い太枠をつける。 もう一度アイコンをクリックするか実行し終えると枠が消える。 RPAプログラム本体 命令の書かれたテキストファイルを読み込み、それに沿って処理を実行する。 テキストを一行ずつ解析、処理を行う。 画面認識に使用する画像はあらかじめ用意しておく。 テキストファイルイメージ click/sample.png/ # sample.pngをクリック typing/Hello World!/ # Hello World! と入力 press/enter/ # Enterキーを押す。 end/ # 終了! pyautoguiのオプションに必要 ↩ 1.6.4以外だとpyinstallerでexe化できない ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

pythonでショートカットウィンドウみたいなRPAを作った備忘録(1)

Pythonのpyautoguiなどのライブラリを使った自作RPAの備忘録。 ライブラリの使い方と実装サンプル。 ↓↓↓自作RPAのソースコード↓↓↓ テキストと画像で簡単操作。 ゲームのスキルやアイテムをセットできるショートカットウィンドウをイメージ。 ソースコード 動画 RPAでお絵かきしてみた。 pic.twitter.com/KaFQPcJKrr— ぽこんpͪoͣnͬpͣoͥnͭpͣa͡inͥ ? (@okahpokon) May 11, 2021 インストール pyautogui 自動化ライブラリ opencv 1 pynput キー・マウス監視ライブラリ(バージョン1.6.4)2 pyperclip クリップボード操作ライブラリ playsound 音楽再生ライブラリ install pip install pyautogui pip install opencv-python pip install pynput==1.6.4 pip instal pyperclip pip install playsound pyautoguiチュートリアル できること マウス操作 キーボード操作 画面認識(画面の座標・スクリーンショット取得、画面から画像認識) マウス操作 pyautogui-click # GUI automation import pyautogui # 画面サイズの取得 x, y = pyautogui.size() x, y = x / 2, y / 2 x2, y2 = x / 3, y / 3 # カーソルの移動速度(秒) clickduration = 0.5 # クリック pyautogui.click(x,y,duration=clickduration) # ダブルクリック pyautogui.doubleClick(x2,y2,duration=clickduration) # 右クリック pyautogui.rightClick(x,y,duration=clickduration) # カーソル移動 pyautogui.moveTo(x2,y2,duration=clickduration) # ドラッグ(クリック) pyautogui.dragTo(x,y,duration=clickduration,button='left') # スクロール(ーは下方向) pyautogui.scroll(-100) キーボード操作 typewriteは半角全角の制御が別途必要。 回避策は 入力文字をクリップボードにコピーし、hotkeyを使いctrl+vによる貼り付けなど pyautogui-keyboard # GUI automation import pyautogui # キー入力 pyautogui.press('p') # キーを押し続ける pyautogui.keyDown('ctrl') # キーを離す pyautogui.keyUp('ctrl') # 2キー入力 pyautogui.hotkey('ctrl','c') # 文字列入力 pyautogui.typewrite('typewrite',interval=1) # 複数キー入力は以下で実装可能 pyautogui.keyDown('win') pyautogui.keyDown('shift') pyautogui.press('s') pyautogui.keyUp('win') pyautogui.keyUp('shift') 画面の取得と画像認識 pyautogui-locateonscreen # GUI automation import pyautogui # ターゲット画像のパス imgpath = 'sample1.png' # 画像認識精度(0.0~1.0:値が大きいほど精度が高くなる) confidence = 0.8 # 画面からターゲット画像を取得 target = pyautogui.locateOnScreen(imgpath,confidence=confidence) # ターゲットの中心座標を取得 x, y = pyautogui.center(target) # クリック pyautogui.click(x,y) pynputチュートリアル できること マウス操作の検出 キーボード操作の検出 pynput # マウス・キーボード監視 import pynput # キーを押したときの処理 def press(key): try: # 英字キーを入力したときはこっちに行くみたい print(key.char) except AttributeError: # Enterやタブなど特殊なキーはこっち print(key) # キーを離したときの処理 def release(key): print(key) if key == pynput.keyboard.Key.esc: return False # クリックしたときの処理 def click(x, y, button, pressed): print(x, y) # 押したときだけ処理するならpressedを追加 if pressed: print('pressed') else: print('release') # キーボードリスナー起動 押したときと離したときのイベントを取得 keylistener = pynput.keyboard.Listener(on_press=press,on_release=release) keylistener.start() # マウスリスナー起動 クリックしたときのイベントを取得 with pynput.mouse.Listener(on_click=click) as mouselistener: mouselistener.join() 参考:【Python RPA】マウス・キーボード操作を同時に検知・取得する方法(pynput) pyperclipチュートリアル できること クリップボード監視 pyperclip # クリップボード監視 import pyperclip # クリップボードにテキストを格納 pyperclip.copy('test') # クリップボードの内容を取得 clipboard = pyperclip.paste() print(clipboard) プログラムを実行するとクリップボードが変更される RPAプログラムのイメージ GUI ゲームのスキルバーをイメージ。 アイコンが横に並んでおり、アイコンをクリックするとRPAプログラムが実行される。 実行中は、赤い太枠をつける。 もう一度アイコンをクリックするか実行し終えると枠が消える。 RPAプログラム本体 命令の書かれたテキストファイルを読み込み、それに沿って処理を実行する。 テキストを一行ずつ解析、処理を行う。 画面認識に使用する画像はあらかじめ用意しておく。 テキストファイルイメージ click/sample.png/ # sample.pngをクリック typing/Hello World!/ # Hello World! と入力 press/enter/ # Enterキーを押す。 end/ # 終了 今回はここまで。 次回はRPAプログラム本体のコーディングについて説明する予定です。 pyautoguiのオプションに必要 ↩ 1.6.4以外だとpyinstallerでexe化できない ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

pandasのデータフレームを使用したfor文において脱iterrows()を試みたら実行時間が約70倍高速化した話

背景 pandasのデータフレームを使用したfor文で、データフレームを行ごとに取得して…という処理を書いていました。しかし、実現したい内容に大して現実的でない時間がかかってしまうことが判明しました。いろいろ調べたり確認してみると、以下コードに時間がかかってしまっていることがわかりました。 時間がかかってしまっているコード for id, row in df.iterrows(): 調べてみると.iterrows()に時間がかかるようです。とにかく脱iterrows()を試みて実行時間を高速化する必要がありました。 その中でリストに変換する方法(df.values)がありました。しかし、これはrowの型が変わってしまい、一筋縄ではいきません。具体的には、row['特定のカラム名']と記述できていたものを、row[1]などリストのインデックスを使わなければいけなくなります(1は特定のカラム名に対応するインデックス)。後から見返した時に「この数字何!?あっリストのインデックスか!なんのデータなんだろう?」となってしまいます。 以上を踏まえて、個人的に「これがいいんじゃないか?」と思える改善案を見つけました。 結論 例えば、?の場合… 改善前 for id, row in df.iterrows(): # something to do _ = row['特定のカラム名'] ?のようにするとOK? 改善後 # preparation map_colmun_and_index = {} for index, colmun in enumerate(df.columns, 0): map_colmun_and_index[colmun] = index for row in df.values: # something to do _ = row[map_colmun_and_index['特定のカラム名']] 簡単にまとめると… 実行時間の高速化 df.valuesでリスト化したものでfor文を実施 iterrows()を使用するメリットの一部を残す&改善コストの削減 事前にカラム名とリスト化した場合のインデックスを紐付け、マッピング マッピングを使って、カラム名でリストの値の参照を実現 これにより、約70倍(※)の高速化が実現されます㊗️ (※:後述する実験の条件において算出) 念のため、差分で見たい人向けに、差分も紹介します。 改善前→改善後 + map_colmun_and_index = {} + for index, colmun in enumerate(df.columns, 0): + map_colmun_and_index[colmun] = index + - for id, row in df.iterrows(): + for row in df.values: # something to do - _ = row['特定のカラム名'] + _ = row[map_colmun_and_index['特定のカラム名']] 実験 結論を先に紹介しましたが以下を確認するために実験した様子も紹介します。 本当に高速化が実現する? その効果は何倍? 実験概要 先に紹介した方法(改善後)と高速化を試みる前にiterrows()を使っていた方法(改善前)を比較 10,000回実施した実行時間の中央値から何倍の高速化が実現したかを評価 実験環境 Google Colaboratory 実験&結果 scikit-learnよりiris(アヤメ)のデータを使用します。まずはデータを取得し、データフレームに変換します。 scikit-learnよりirisのデータを取得・データフレームに変換 from sklearn.datasets import load_iris iris = load_iris() iris_df = pd.DataFrame(iris.data, columns=iris.feature_names) 行・列の長さは150、4でした。 行・列の長さを確認 iris_df.shape 行・列の長さを確認(結果) (150, 4) データの中身(上位5件)は以下の通りです。 データの中身(上位5件)を確認 iris_df.head() sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) 5.1 3.5 1.4 0.2 4.9 3.0 1.4 0.2 4.7 3.2 1.3 0.2 4.6 3.1 1.5 0.2 5.0 3.6 1.4 0.2 それでは、実験を実施します。 実験 import time results_pre_kaizen = [] results_post_kaizen = [] for _ in range(10000): start_time = time.time() for id, row in iris_df.iterrows(): # something to do _ = row['sepal length (cm)'] results_pre_kaizen.append(time.time() - start_time) start_time = time.time() # preparation map_colmun_and_index = {} for index, colmun in enumerate(iris_df.columns, 0): map_colmun_and_index[colmun] = index for row in iris_df.values: # something to do _ = row[dict_hoge['sepal length (cm)']] results_post_kaizen.append(time.time() - start_time) 実行結果×10,000をデータフレームに変換し、基本統計量を確認します。 実行結果×10,000を基本統計量で確認 df = pd.DataFrame({"改善前":results_pre_kaizen,"改善後":results_post_kaizen}).describe() df 改善前 改善後 count 10000.000000 10000.000000 mean 0.008074 0.000115 std 0.000852 0.000029 min 0.007478 0.000087 25% 0.007632 0.000105 50% 0.007767 0.000112 75% 0.008166 0.000118 max 0.019278 0.001674 基本統計量における全ての値において、実行時間は改善前より改善後の方が高速であることがわかりました。 最後に中央値(50%)からどれだけの高速化が実現できたのかを確認します。 df["改善前"]["50%"]/df["改善後"]["50%"] 69.06794055201699 約70(≒69.06794055201699)倍の高速化が実現されたことがわかりました! おわりに 「pandasのデータフレームを使用したfor文において脱iterrows()を試みたら実行時間が約70倍高速化した話」を紹介しました。似たような悩み抱く方に響けば嬉しいです。より良い改善案や助言などがありましたら教えてください!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Pylintルール一覧

Category Rule Id Description Async not-async-context-manager E1701 Async context manager '%s' doesn't implement aenter and aexit. Used when an async context manager is used with an object that does not implement the async context management protocol. This message can't be emitted when using Python < 3.5. Async yield-inside-async-function E1700 Yield inside async function Used when an yield or yield from statement is found inside an async function. This message can't be emitted when using Python < 3.5. Basic not-in-loop E0103 %r not properly in loop Used when break or continue keywords are used outside a loop. Basic function-redefined E0102 %s already defined line %s Used when a function / class / method is redefined. Basic continue-in-finally E0116 "'continue' not supported inside 'finally' clause Emitted when the continue keyword is found inside a finally clause, which is a SyntaxError. This message can't be emitted when using Python >= 3.8." Basic abstract-class-instantiated E0110 Abstract class %r with abstract methods instantiated Used when an abstract class with abc.ABCMeta as metaclass has abstract methods and is instantiated. Basic star-needs-assignment-target E0114 Can use starred expression only in assignment target Emitted when a star expression is not used in an assignment target. Basic duplicate-argument-name E0108 Duplicate argument name %s in function definition Duplicate argument names in function definitions are syntax errors. Basic return-in-init E0101 Explicit return in init Used when the special class method init has an explicit return value. Basic too-many-star-expressions E0112 More than one starred expression in assignment Emitted when there are more than one starred expressions (*x) in an assignment. This is a SyntaxError. Basic nonlocal-and-global E0115 Name %r is nonlocal and global Emitted when a name is both nonlocal and global. Basic used-prior-global-declaration E0118 "Name %r is used prior to global declaration Emitted when a name is used prior a global declaration, which results in an error since Python 3.6. This message can't be emitted when using Python < 3.6." Basic return-outside-function E0104 "Return outside function Used when a ""return"" statement is found outside a function or method." Basic return-arg-in-generator E0106 "Return with argument inside generator Used when a ""return"" statement with an argument is found outside in a generator function or method (e.g. with some ""yield"" statements). This message can't be emitted when using Python >= 3.3." Basic invalid-star-assignment-target E0113 Starred assignment target must be in a list or tuple Emitted when a star expression is used as a starred assignment target. Basic bad-reversed-sequence E0111 "The first reversed() argument is not a sequence Used when the first argument to reversed() builtin isn't a sequence (does not implement reversed, nor getitem and len" Basic nonexistent-operator E0107 "Use of the non-existent %s operator Used when you attempt to use the C-style pre-increment or pre-decrement operator -- and ++, which doesn't exist in Python." Basic yield-outside-function E0105 "Yield outside function Used when a ""yield"" statement is found outside a function or method." Basic init-is-generator E0100 init method is a generator Used when the special class method init is turned into a generator by a yield in its body. Basic misplaced-format-function E0119 "format function is not called on str Emitted when format function is not called on str object. e.g doing print(""value: {}"").format(123) instead of print(""value: {}"".format(123)). This might not be what the user intended to do." Basic nonlocal-without-binding E0117 nonlocal name %s found without binding Emitted when a nonlocal variable does not have an attached name somewhere in the parent scopes Basic lost-exception W0150 %s statement in finally block may swallow exception Used when a break or a return statement is found inside the finally clause of a try...finally block: the exceptions raised in the try clause will be silently swallowed instead of being re-raised. Basic assert-on-tuple W0199 "Assert called on a 2-item-tuple. Did you mean 'assert x,y'? A call of assert on a tuple will always evaluate to true if the tuple is not empty, and will always evaluate to false if it is." Basic assert-on-string-literal W0129 "Assert statement has a string literal as its first argument. The assert will %s fail. Used when an assert statement has a string literal as its first argument, which will cause the assert to always pass." Basic self-assigning-variable W0127 Assigning the same variable %r to itself Emitted when we detect that a variable is assigned to itself Basic comparison-with-callable W0143 "Comparing against a callable, did you omit the parenthesis? This message is emitted when pylint detects that a comparison with a callable was made, which might suggest that some parenthesis were omitted, resulting in potential unwanted behaviour." Basic nan-comparison W0177 Comparison %s should be %s Used when an expression is compared to NaNvalues like numpy.NaN and float('nan') Basic dangerous-default-value W0102 Dangerous default value %s as argument Used when a mutable value as list or dictionary is detected in a default value for an argument. Basic duplicate-key W0109 Duplicate key %r in dictionary Used when a dictionary expression binds the same key multiple times. Basic useless-else-on-loop W0120 "Else clause on loop without a break statement Loops should only have an else clause if they can exit early with a break statement, otherwise the statements under else should be on the same scope as the loop itself." Basic expression-not-assigned W0106 "Expression ""%s"" is assigned to nothing Used when an expression that is not a function call is assigned to nothing. Probably something else was intended." Basic confusing-with-statement W0124 "Following ""as"" with another context manager looks like a tuple. Emitted when a with statement component returns multiple values and uses name binding with as only for a part of those values, as in with ctx() as a, b. This can be misleading, since it's not clear if the context manager returns a tuple or if the node without a name binding is another context manager." Basic unnecessary-lambda W0108 Lambda may not be necessary Used when the body of a lambda expression is a function call on the same argument list as the lambda itself; such lambda expressions are in all but a few cases replaceable with the function being called in the body of the lambda. Basic assign-to-new-keyword W0111 Name %s will become a keyword in Python %s Used when assignment will become invalid in future Python release due to introducing new keyword. Basic redeclared-assigned-name W0128 Redeclared variable %r in assignment Emitted when we detect that a variable was redeclared in the same assignment. Basic pointless-statement W0104 Statement seems to have no effect Used when a statement doesn't have (or at least seems to) any effect. Basic pointless-string-statement W0105 "String statement has no effect Used when a string is used as a statement (which of course has no effect). This is a particular case of W0104 with its own message so you can easily disable it if you're using those strings as documentation, instead of comments." Basic unnecessary-pass W0107 "Unnecessary pass statement Used when a ""pass"" statement that can be avoided is encountered." Basic unreachable W0101 "Unreachable code Used when there is some code behind a ""return"" or ""raise"" statement, which will never be accessed." Basic eval-used W0123 "Use of eval Used when you use the ""eval"" function, to discourage its usage. Consider using ast.literal_eval for safely evaluating strings containing Python expressions from untrusted sources." Basic exec-used W0122 "Use of exec Used when you use the ""exec"" statement (function for Python 3), to discourage its usage. That doesn't mean you cannot use it !" Basic using-constant-test W0125 Using a conditional statement with a constant value Emitted when a conditional statement (If or ternary if) uses a constant value for its test. This might not be what the user intended to do. Basic missing-parentheses-for-call-in-test W0126 Using a conditional statement with potentially wrong function or method call due to missing parentheses Emitted when a conditional statement (If or ternary if) seems to wrongly call a function due to missing parentheses Basic literal-comparison R0123 "Comparison to literal Used when comparing an object to a literal, which is usually what you do not want to do, since you can compare to a different literal than what was expected altogether." Basic comparison-with-itself R0124 Redundant comparison - %s Used when something is compared against itself. Basic non-ascii-name C0144 "%s name ""%s"" contains a non-ASCII unicode character Used when the name contains at least one non-ASCII unicode character." Basic invalid-name C0103 "%s name ""%s"" doesn't conform to %s Used when the name doesn't conform to naming rules associated to its type (constant, variable, class...)." Basic singleton-comparison C0121 "Comparison %s should be %s Used when an expression is compared to singleton values like True, False or None." Basic misplaced-comparison-constant C0122 Comparison should be %s Used when the constant is placed on the left side of a comparison. It is usually clearer in intent to place it in the right hand side of the comparison. Basic disallowed-name C0104 "Disallowed name ""%s"" Used when the name matches bad-names or bad-names-rgxs- (unauthorized names)." Basic empty-docstring C0112 "Empty %s docstring Used when a module, function, class or method has an empty docstring (it would be too easy ;)." Basic missing-class-docstring C0115 Missing class docstring Used when a class has no docstring.Even an empty class must have a docstring. Basic missing-function-docstring C0116 Missing function or method docstring Used when a function or method has no docstring.Some special methods like init do not require a docstring. Basic missing-module-docstring C0114 Missing module docstring Used when a module has no docstring.Empty modules do not require a docstring. Basic unidiomatic-typecheck C0123 "Use isinstance() rather than type() for a typecheck. The idiomatic way to perform an explicit typecheck in Python is to use isinstance(x, Y) rather than type(x) == Y, type(x) is Y. Though there are unusual situations where these give different results." Classes access-member-before-definition E0203 Access to member %r before its definition line %s Used when an instance member is accessed before it's actually assigned. Classes method-hidden E0202 An attribute defined in %s line %s hides this method Used when a class defines a method which is hidden by an instance attribute from an ancestor class or set by some client code. Classes assigning-non-slot E0237 Assigning to attribute %r not defined in class slots Used when assigning to an attribute not defined in the class slots. Classes duplicate-bases E0241 Duplicate bases for class %r Used when a class has duplicate bases. Classes inconsistent-mro E0240 Inconsistent method resolution order for class %r Used when a class has an inconsistent method resolution order. Classes inherit-non-class E0239 "Inheriting %r, which is not a class. Used when a class inherits from something which is not a class." Classes invalid-slots E0238 "Invalid slots object Used when an invalid slots is found in class. Only a string, an iterable or a sequence is permitted." Classes invalid-slots-object E0236 "Invalid object %r in slots, must contain only non empty strings Used when an invalid (non-string) object occurs in slots." Classes no-method-argument E0211 Method has no argument Used when a method which should have the bound instance as first argument has no argument defined. Classes no-self-argument E0213 "Method should have ""self"" as first argument Used when a method has an attribute different the ""self"" as first argument. This is considered as an error since this is a so common convention that you shouldn't break it!" Classes unexpected-special-method-signature E0302 "The special method %r expects %s param(s), %d %s given Emitted when a special method was defined with an invalid number of parameters. If it has too few or too many, it might not work at all." Classes class-variable-slots-conflict E0242 "Value %r in slots conflicts with class variable Used when a value in slots conflicts with a class variable, property or method." Classes invalid-bool-returned E0304 bool does not return bool Used when a bool method returns something which is not a bool Classes invalid-bytes-returned E0308 bytes does not return bytes Used when a bytes method returns something which is not bytes Classes invalid-format-returned E0311 format does not return str Used when a format method returns something which is not a string Classes invalid-getnewargs-returned E0312 getnewargs does not return a tuple Used when a getnewargs method returns something which is not a tuple Classes invalid-getnewargs-ex-returned E0313 "getnewargs_ex does not return a tuple containing (tuple, dict) Used when a getnewargs_ex method returns something which is not of the form tuple(tuple, dict)" Classes invalid-hash-returned E0309 hash does not return int Used when a hash method returns something which is not an integer Classes invalid-index-returned E0305 index does not return int Used when an index method returns something which is not an integer Classes non-iterator-returned E0301 iter returns non-iterator Used when an iter method returns something which is not an iterable (i.e. has no next method) Classes invalid-length-returned E0303 len does not return non-negative integer Used when a len method returns something which is not a non-negative integer Classes invalid-length-hint-returned E0310 length_hint does not return non-negative integer Used when a length_hint method returns something which is not a non- negative integer Classes invalid-repr-returned E0306 repr does not return str Used when a repr method returns something which is not a string Classes invalid-str-returned E0307 str does not return str Used when a str method returns something which is not a string Classes protected-access W0212 Access to a protected member %s of a client class Used when a protected member (i.e. class member with a name beginning with an underscore) is access outside the class or a descendant of the class where it's defined. Classes attribute-defined-outside-init W0201 Attribute %r defined outside init Used when an instance attribute is defined outside the init method. Classes no-init W0232 "Class has no init method Used when a class has no init method, neither its parent classes." Classes abstract-method W0223 Method %r is abstract in class %r but is not overridden Used when an abstract method (i.e. raise NotImplementedError) is not overridden in concrete class. Classes invalid-overridden-method W0236 "Method %r was expected to be %r, found it instead as %r Used when we detect that a method was overridden in a way that does not match its base class which could result in potential bugs at runtime." Classes arguments-differ W0221 Parameters differ from %s %r method Used when a method has a different number of arguments than in the implemented interface or in an overridden method. Classes signature-differs W0222 Signature differs from %s %r method Used when a method signature is different than in the implemented interface or in an overridden method. Classes bad-staticmethod-argument W0211 "Static method with %r as first argument Used when a static method has ""self"" or a value specified in valid- classmethod-first-arg option or valid-metaclass-classmethod-first-arg option as first argument." Classes useless-super-delegation W0235 "Useless super delegation in method %r Used whenever we can detect that an overridden method is useless, relying on super() delegation to do the same thing as another method from the MRO." Classes non-parent-init-called W0233 init method from a non direct base class %r is called Used when an init method is called on a class which is not in the direct ancestors for the analysed class. Classes super-init-not-called W0231 init method from base class %r is not called Used when an ancestor class method has an init method which is not called by a derived class. Classes property-with-parameters R0206 "Cannot have defined parameters for properties Used when we detect that a property also has parameters, which are useless, given that properties cannot be called with additional arguments." Classes useless-object-inheritance R0205 "Class %r inherits from object, can be safely removed from bases in python3 Used when a class inherit from object, which under python3 is implicit, hence can be safely removed from bases." Classes no-classmethod-decorator R0202 Consider using a decorator instead of calling classmethod Used when a class method is defined without using the decorator syntax. Classes no-staticmethod-decorator R0203 Consider using a decorator instead of calling staticmethod Used when a static method is defined without using the decorator syntax. Classes no-self-use R0201 "Method could be a function Used when a method doesn't use its bound instance, and so could be written as a function." Classes single-string-used-for-slots C0205 "Class slots should be a non-string iterable Used when a class slots is a simple string, rather than an iterable." Classes bad-classmethod-argument C0202 "Class method %s should have %s as first argument Used when a class method has a first argument named differently than the value specified in valid-classmethod-first-arg option (default to ""cls""), recommended to easily differentiate them from regular instance methods." Classes bad-mcs-classmethod-argument C0204 "Metaclass class method %s should have %s as first argument Used when a metaclass class method has a first argument named differently than the value specified in valid-metaclass-classmethod-first-arg option (default to ""mcs""), recommended to easily differentiate them from regular instance methods." Classes bad-mcs-method-argument C0203 "Metaclass method %s should have %s as first argument Used when a metaclass method has a first argument named differently than the value specified in valid-classmethod-first-arg option (default to ""cls""), recommended to easily differentiate them from regular instance methods." Classes method-check-failed F0202 Unable to check methods signature (%s / %s) Used when Pylint has been unable to check methods signature compatibility for an unexpected reason. Please report this kind if you don't make sense of it. Design too-few-public-methods R0903 "Too few public methods (%s/%s) Used when class has too few public methods, so be sure it's really worth it." Design too-many-ancestors R0901 "Too many ancestors (%s/%s) Used when class has too many parent classes, try to reduce this to get a simpler (and so easier to use) class." Design too-many-arguments R0913 Too many arguments (%s/%s) Used when a function or method takes too many arguments. Design too-many-boolean-expressions R0916 Too many boolean expressions in if statement (%s/%s) Used when an if statement contains too many boolean expressions. Design too-many-branches R0912 "Too many branches (%s/%s) Used when a function or method has too many branches, making it hard to follow." Design too-many-instance-attributes R0902 "Too many instance attributes (%s/%s) Used when class has too many instance attributes, try to reduce this to get a simpler (and so easier to use) class." Design too-many-locals R0914 Too many local variables (%s/%s) Used when a function or method has too many local variables. Design too-many-public-methods R0904 "Too many public methods (%s/%s) Used when class has too many public methods, try to reduce this to get a simpler (and so easier to use) class." Design too-many-return-statements R0911 "Too many return statements (%s/%s) Used when a function or method has too many return statement, making it hard to follow." Design too-many-statements R0915 Too many statements (%s/%s) Used when a function or method has too many statements. You should then split it in smaller functions / methods. Exceptions bad-except-order E0701 "Bad except clauses order (%s) Used when except clauses are not in the correct order (from the more specific to the more generic). If you don't fix the order, some exceptions may not be caught by the most specific handler." Exceptions catching-non-exception E0712 Catching an exception which doesn't inherit from Exception: %s Used when a class which doesn't inherit from Exception is used as an exception in an except clause. Exceptions bad-exception-context E0703 "Exception context set to something which is not an exception, nor None Used when using the syntax ""raise ... from ..."", where the exception context is not an exception, nor None." Exceptions notimplemented-raised E0711 NotImplemented raised - should raise NotImplementedError Used when NotImplemented is raised instead of NotImplementedError Exceptions raising-bad-type E0702 "Raising %s while only classes or instances are allowed Used when something which is neither a class, an instance or a string is raised (i.e. a TypeError will be raised)." Exceptions raising-non-exception E0710 Raising a new style class which doesn't inherit from BaseException Used when a new style class which doesn't inherit from BaseException is raised. Exceptions misplaced-bare-raise E0704 "The raise statement is not inside an except clause Used when a bare raise is not used inside an except clause. This generates an error, since there are no active exceptions to be reraised. An exception to this rule is represented by a bare raise inside a finally clause, which might work, as long as an exception is raised inside the try block, but it is nevertheless a code smell that must not be relied upon." Exceptions duplicate-except W0705 Catching previously caught exception type %s Used when an except catches a type that was already caught by a previous handler. Exceptions broad-except W0703 "Catching too general exception %s Used when an except catches a too general exception, possibly burying unrelated errors." Exceptions raise-missing-from W0707 "Consider explicitly re-raising using the 'from' keyword Python 3's exception chaining means it shows the traceback of the current exception, but also the original exception. Not using raise from makes the traceback inaccurate, because the message implies there is a bug in the exception-handling code itself, which is a separate situation than wrapping an exception." Exceptions raising-format-tuple W0715 "Exception arguments suggest string formatting might be intended Used when passing multiple arguments to an exception constructor, the first of them a string literal containing what appears to be placeholders intended for formatting" Exceptions binary-op-exception W0711 "Exception to catch is the result of a binary ""%s"" operation Used when the exception to catch is of the form ""except A or B:"". If intending to catch multiple, rewrite as ""except (A, B):""" Exceptions wrong-exception-operation W0716 "Invalid exception operation. %s Used when an operation is done against an exception, but the operation is not valid for the exception in question. Usually emitted when having binary operations between exceptions in except handlers." Exceptions bare-except W0702 No exception type(s) specified Used when an except clause doesn't specify exceptions type to catch. Exceptions try-except-raise W0706 The except handler raises immediately Used when an except handler uses raise as its first or only operator. This is useless because it raises back the exception immediately. Remove the raise operator or the entire try-except-raise block! Format bad-indentation W0311 "Bad indentation. Found %s %s, expected %s Used when an unexpected number of indentation's tabulations or spaces has been found." Format unnecessary-semicolon W0301 "Unnecessary semicolon Used when a statement is ended by a semi-colon ("";""), which isn't necessary (that's python, not C ;)." Format missing-final-newline C0304 Final newline missing Used when the last line in a file is missing a newline. Format line-too-long C0301 Line too long (%s/%s) Used when a line is longer than a given number of characters. Format mixed-line-endings C0327 Mixed line endings LF and CRLF Used when there are mixed (LF and CRLF) newline signs in a file. Format multiple-statements C0321 More than one statement on a single line Used when more than on statement are found on the same line. Format too-many-lines C0302 "Too many lines in module (%s/%s) Used when a module has too many lines, reducing its readability." Format trailing-newlines C0305 Trailing newlines Used when there are trailing blank lines in a file. Format trailing-whitespace C0303 Trailing whitespace Used when there is whitespace between the end of a line and the newline. Format unexpected-line-ending-format C0328 Unexpected line ending format. There is '%s' while it should be '%s'. Used when there is different newline than expected. Format superfluous-parens C0325 "Unnecessary parens after %r keyword Used when a single item in parentheses follows an if, for, or other keyword." Imports relative-beyond-top-level E0402 Attempted relative import beyond top-level package Used when a relative import tries to access too many levels in the current package. Imports import-error E0401 Unable to import %s Used when pylint has been unable to import a module. Imports import-self W0406 Module import itself Used when a module is importing itself. Imports preferred-module W0407 Prefer importing %r instead of %r Used when a module imported has a preferred replacement module. Imports reimported W0404 Reimport %r (imported line %s) Used when a module is reimported multiple times. Imports deprecated-module W0402 Uses of a deprecated module %r Used a module marked as deprecated is imported. Imports wildcard-import W0401 Wildcard import %s Used when from module import * is detected. Imports misplaced-future W0410 future import is not the first non docstring statement Python 2.5 and greater require future import to be the first non docstring statement in the module. Imports cyclic-import R0401 Cyclic import (%s) Used when a cyclic import between two or more modules is detected. Imports wrong-import-order C0411 "%s should be placed before %s Used when PEP8 import order is not respected (standard imports first, then third-party libraries, then local imports)" Imports wrong-import-position C0413 "Import ""%s"" should be placed at the top of the module Used when code and imports are mixed" Imports useless-import-alias C0414 Import alias does not rename original package Used when an import alias is same as original package.e.g using import numpy as numpy instead of import numpy as np Imports import-outside-toplevel C0415 Import outside toplevel (%s) Used when an import statement is used anywhere other than the module toplevel. Move this import to the top of the file. Imports ungrouped-imports C0412 Imports from package %s are not grouped Used when imports are not grouped by packages Imports multiple-imports C0410 Multiple imports on one line (%s) Used when import statement importing multiple modules is detected. Logging logging-format-truncated E1201 Logging format string ends in middle of conversion specifier Used when a logging statement format string terminates before the end of a conversion specifier. Logging logging-too-few-args E1206 Not enough arguments for logging format string Used when a logging format string is given too few arguments. Logging logging-too-many-args E1205 Too many arguments for logging format string Used when a logging format string is given too many arguments. Logging logging-unsupported-format E1200 Unsupported logging format character %r (%#02x) at index %d Used when an unsupported format character is used in a logging statement format string. Logging logging-format-interpolation W1202 "Use %s formatting in logging functions Used when a logging statement has a call form of ""logging.(format_string.format(format_args...))"". Use another type of string formatting instead. You can use % formatting but leave interpolation to the logging function by passing the parameters as arguments. If logging-fstring- interpolation is disabled then you can use fstring formatting. If logging- not-lazy is disabled then you can use % formatting as normal." Logging logging-fstring-interpolation W1203 "Use %s formatting in logging functions Used when a logging statement has a call form of ""logging.(f""..."")"".Use another type of string formatting instead. You can use % formatting but leave interpolation to the logging function by passing the parameters as arguments. If logging-format-interpolation is disabled then you can use str.format. If logging-not-lazy is disabled then you can use % formatting as normal." Logging logging-not-lazy W1201 "Use %s formatting in logging functions Used when a logging statement has a call form of ""logging.(format_string % (format_args...))"". Use another type of string formatting instead. You can use % formatting but leave interpolation to the logging function by passing the parameters as arguments. If logging-fstring- interpolation is disabled then you can use fstring formatting. If logging- format-interpolation is disabled then you can use str.format." Miscellaneous fixme W0511 Used when a warning note as FIXME or XXX is detected. Miscellaneous use-symbolic-message-instead I0023 Used when a message is enabled or disabled by id. Newstyle bad-super-call E1003 Bad first argument %r given to super() Used when another argument than the current class is given as first argument of the super builtin. Python3 unpacking-in-except E1603 Implicit unpacking of exceptions is not supported in Python 3 Python3 will not allow implicit unpacking of exceptions in except clauses. See https://www.python.org/dev/peps/pep-3110/ Python3 import-star-module-level E1609 Import * only allowed at module level Used when the import star syntax is used somewhere else than the module level. This message can't be emitted when using Python >= 3.0. Python3 non-ascii-bytes-literal E1610 Non-ascii bytes literals not supported in 3.x Used when non-ascii bytes literals are found in a program. They are no longer supported in Python 3. This message can't be emitted when using Python >= 3.0. Python3 parameter-unpacking E1602 Parameter unpacking specified Used when parameter unpacking is specified for a function(Python 3 doesn't allow it) Python3 long-suffix E1606 "Use of long suffix Used when ""l"" or ""L"" is used to mark a long integer. This will not work in Python 3, since int and long types have merged. This message can't be emitted when using Python >= 3.0." Python3 old-octal-literal E1608 "Use of old octal literal Used when encountering the old octal syntax, removed in Python 3. To use the new syntax, prepend 0o on the number. This message can't be emitted when using Python >= 3.0." Python3 old-ne-operator E1607 "Use of the <> operator Used when the deprecated ""<>"" operator is used instead of ""!="". This is removed in Python 3. This message can't be emitted when using Python >= 3.0." Python3 backtick E1605 "Use of the operator Used when the deprecated """" (backtick) operator is used instead of the str() function." Python3 old-raise-syntax E1604 "Use raise ErrorClass(args) instead of raise ErrorClass, args. Used when the alternate raise syntax 'raise foo, bar' is used instead of 'raise foo(bar)'." Python3 print-statement E1601 print statement used Used when a print statement is used (print is a function in Python 3) Python3 deprecated-types-field W1652 Accessing a deprecated fields on the types module Used when accessing a field on types that has been removed in Python 3. Python3 deprecated-itertools-function W1651 Accessing a deprecated function on the itertools module Used when accessing a function on itertools that has been removed in Python 3. Python3 deprecated-string-function W1649 Accessing a deprecated function on the string module Used when accessing a string function that has been deprecated in Python 3. Python3 deprecated-operator-function W1657 Accessing a removed attribute on the operator module Used when accessing a field on operator module that has been removed in Python 3. Python3 deprecated-sys-function W1660 Accessing a removed attribute on the sys module Used when accessing a field on sys module that has been removed in Python 3. Python3 deprecated-urllib-function W1658 Accessing a removed attribute on the urllib module Used when accessing a field on urllib module that has been removed or moved in Python 3. Python3 xreadlines-attribute W1659 "Accessing a removed xreadlines attribute Used when accessing the xreadlines() function on a file stream, removed in Python 3." Python3 metaclass-assignment W1623 Assigning to a class's metaclass attribute Used when a metaclass is specified by assigning to metaclass (Python 3 specifies the metaclass as a class statement argument) Python3 next-method-called W1622 Called a next() method on an object Used when an object's next() method is called (Python 3 uses the next() built-in function) Python3 dict-iter-method W1620 "Calling a dict.iter*() method Used for calls to dict.iterkeys(), itervalues() or iteritems() (Python 3 lacks these methods)" Python3 dict-view-method W1621 "Calling a dict.view*() method Used for calls to dict.viewkeys(), viewvalues() or viewitems() (Python 3 lacks these methods)" Python3 exception-message-attribute W1645 Exception.message removed in Python 3 Used when the message attribute is accessed on an Exception. Use str(exception) instead. Python3 eq-without-hash W1641 "Implementing eq without also implementing hash Used when a class implements eq but not hash. In Python 2, objects get object.hash as the default implementation, in Python 3 objects get None as their default hash implementation if they also implement eq." Python3 indexing-exception W1624 Indexing exceptions will not work on Python 3 Indexing exceptions will not work on Python 3. Use exception.args[index] instead. Python3 bad-python3-import W1648 Module moved in Python 3 Used when importing a module that no longer exists in Python 3. Python3 raising-string W1625 Raising a string exception Used when a string exception is raised. This will not work on Python 3. Python3 standarderror-builtin W1611 StandardError built-in referenced Used when the StandardError built-in function is referenced (missing from Python 3) Python3 comprehension-escape W1662 "Using a variable that was bound inside a comprehension Emitted when using a variable, that was bound in a comprehension handler, outside of the comprehension itself. On Python 3 these variables will be deleted outside of the comprehension." Python3 exception-escape W1661 "Using an exception object that was bound by an except handler Emitted when using an exception, that was bound in an except handler, outside of the except handler. On Python 3 these exceptions will be deleted once they get out of the except handler." Python3 deprecated-str-translate-call W1650 Using str.translate with deprecated deletechars parameters Used when using the deprecated deletechars parameters from str.translate. Use re.sub to remove the desired characters Python3 using-cmp-argument W1640 "Using the cmp argument for list.sort / sorted Using the cmp argument for list.sort or the sorted builtin should be avoided, since it was removed in Python 3. Using either key or functools.cmp_to_key should be preferred." Python3 cmp-method W1630 cmp method defined Used when a cmp method is defined (method is not used by Python 3) Python3 coerce-method W1614 coerce method defined Used when a coerce method is defined (method is not used by Python 3) Python3 delslice-method W1615 delslice method defined Used when a delslice method is defined (method is not used by Python 3) Python3 div-method W1642 div method defined Used when a div method is defined. Using truediv and setting_div_ = truediv should be preferred.(method is not used by Python 3) Python3 getslice-method W1616 getslice method defined Used when a getslice method is defined (method is not used by Python 3) Python3 hex-method W1628 hex method defined Used when a hex method is defined (method is not used by Python 3) Python3 idiv-method W1643 idiv method defined Used when an idiv method is defined. Using itruediv and setting_idiv_ = itruediv should be preferred.(method is not used by Python 3) Python3 nonzero-method W1629 nonzero method defined Used when a nonzero method is defined (method is not used by Python 3) Python3 oct-method W1627 oct method defined Used when an oct method is defined (method is not used by Python 3) Python3 rdiv-method W1644 rdiv method defined Used when a rdiv method is defined. Using rtruediv and setting_rdiv_ = rtruediv should be preferred.(method is not used by Python 3) Python3 setslice-method W1617 setslice method defined Used when a setslice method is defined (method is not used by Python 3) Python3 apply-builtin W1601 apply built-in referenced Used when the apply built-in function is referenced (missing from Python 3) Python3 basestring-builtin W1602 basestring built-in referenced Used when the basestring built-in function is referenced (missing from Python 3) Python3 buffer-builtin W1603 buffer built-in referenced Used when the buffer built-in function is referenced (missing from Python 3) Python3 cmp-builtin W1604 cmp built-in referenced Used when the cmp built-in function is referenced (missing from Python 3) Python3 coerce-builtin W1605 coerce built-in referenced Used when the coerce built-in function is referenced (missing from Python 3) Python3 dict-items-not-iterating W1654 dict.items referenced when not iterating Used when dict.items is referenced in a non-iterating context (returns an iterator in Python 3) Python3 dict-keys-not-iterating W1655 dict.keys referenced when not iterating Used when dict.keys is referenced in a non-iterating context (returns an iterator in Python 3) Python3 dict-values-not-iterating W1656 dict.values referenced when not iterating Used when dict.values is referenced in a non-iterating context (returns an iterator in Python 3) Python3 old-division W1619 division w/o future statement Used for non-floor division w/o a float literal or from future import division (Python 3 returns a float for int division unconditionally) Python3 execfile-builtin W1606 execfile built-in referenced Used when the execfile built-in function is referenced (missing from Python 3) Python3 file-builtin W1607 file built-in referenced Used when the file built-in function is referenced (missing from Python 3) Python3 filter-builtin-not-iterating W1639 filter built-in referenced when not iterating Used when the filter built-in is referenced in a non-iterating context (returns an iterator in Python 3) Python3 no-absolute-import W1618 import missing from __future__ import absolute_import Used when an import is not accompanied by from future import absolute_import (default behaviour in Python 3) Python3 input-builtin W1632 input built-in referenced Used when the input built-in is referenced (backwards-incompatible semantics in Python 3) Python3 intern-builtin W1634 intern built-in referenced Used when the intern built-in is referenced (Moved to sys.intern in Python 3) Python3 long-builtin W1608 long built-in referenced Used when the long built-in function is referenced (missing from Python 3) Python3 map-builtin-not-iterating W1636 map built-in referenced when not iterating Used when the map built-in is referenced in a non-iterating context (returns an iterator in Python 3) Python3 next-method-defined W1653 next method defined Used when a next method is defined that would be an iterator in Python 2 but is treated as a normal function in Python 3. Python3 invalid-str-codec W1646 non-text encoding used in str.decode Used when using str.encode or str.decode with a non-text encoding. Use codecs module to handle arbitrary codecs. Python3 range-builtin-not-iterating W1638 range built-in referenced when not iterating Used when the range built-in is referenced in a non-iterating context (returns a range in Python 3) Python3 raw_input-builtin W1609 raw_input built-in referenced Used when the raw_input built-in function is referenced (missing from Python 3) Python3 reduce-builtin W1610 reduce built-in referenced Used when the reduce built-in function is referenced (missing from Python 3) Python3 reload-builtin W1626 reload built-in referenced Used when the reload built-in function is referenced (missing from Python 3). You can use instead imp.reload or importlib.reload. Python3 round-builtin W1633 round built-in referenced Used when the round built-in is referenced (backwards-incompatible semantics in Python 3) Python3 sys-max-int W1647 sys.maxint removed in Python 3 Used when accessing sys.maxint. Use sys.maxsize instead. Python3 unichr-builtin W1635 unichr built-in referenced Used when the unichr built-in is referenced (Use chr in Python 3) Python3 unicode-builtin W1612 unicode built-in referenced Used when the unicode built-in function is referenced (missing from Python 3) Python3 xrange-builtin W1613 xrange built-in referenced Used when the xrange built-in function is referenced (missing from Python 3) Python3 zip-builtin-not-iterating W1637 zip built-in referenced when not iterating Used when the zip built-in is referenced in a non-iterating context (returns an iterator in Python 3) Refactoring simplifiable-condition R1726 Boolean condition '%s' may be simplified to '%s' Emitted when a boolean condition is able to be simplified. Refactoring condition-evals-to-constant R1727 Boolean condition '%s' will always evaluate to '%s' Emitted when a boolean condition can be simplified to a constant value. Refactoring simplify-boolean-expression R1709 Boolean expression may be simplified to %s Emitted when redundant pre-python 2.5 ternary syntax is used. Refactoring consider-using-in R1714 "Consider merging these comparisons with ""in"" to %r To check if a variable is equal to one of many values,combine the values into a tuple and check if the variable is contained ""in"" it instead of checking for equality against each of the values.This is faster and less verbose." Refactoring consider-merging-isinstance R1701 "Consider merging these isinstance calls to isinstance(%s, (%s)) Used when multiple consecutive isinstance calls can be merged into one." Refactoring consider-using-max-builtin R1731 Consider using '%s' instead of unnecessary if block Using the max builtin instead of a conditional improves readability and conciseness. Refactoring consider-using-min-builtin R1730 Consider using '%s' instead of unnecessary if block Using the min builtin instead of a conditional improves readability and conciseness. Refactoring consider-using-with R1732 Consider using 'with' for resource-allocating operations Emitted if a resource-allocating assignment or call may be replaced by a 'with' block. By using 'with' the release of the allocated resources is ensured even in the case of an exception. Refactoring super-with-arguments R1725 Consider using Python 3 style super() without arguments Emitted when calling the super() builtin with the current class and instance. On Python 3 these arguments are the default and they can be omitted. Refactoring consider-using-dict-comprehension R1717 "Consider using a dictionary comprehension Emitted when we detect the creation of a dictionary using the dict() callable and a transient list. Although there is nothing syntactically wrong with this code, it is hard to read and can be simplified to a dict comprehension.Also it is faster since you don't need to create another transient list" Refactoring consider-using-generator R1728 Consider using a generator instead '%s(%s)' If your container can be large using a generator will bring better performance. Refactoring consider-using-set-comprehension R1718 "Consider using a set comprehension Although there is nothing syntactically wrong with this code, it is hard to read and can be simplified to a set comprehension.Also it is faster since you don't need to create another transient list" Refactoring consider-using-get R1715 "Consider using dict.get for getting values from a dict if a key is present or a default if not Using the builtin dict.get for getting a value from a dictionary if a key is present or a default if not, is simpler and considered more idiomatic, although sometimes a bit slower" Refactoring consider-using-join R1713 "Consider using str.join(sequence) for concatenating strings from an iterable Using str.join(sequence) is faster, uses less memory and increases readability compared to for-loop iteration." Refactoring consider-using-sys-exit R1722 "Consider using sys.exit() Instead of using exit() or quit(), consider using the sys.exit()." Refactoring consider-using-ternary R1706 Consider using ternary (%s) Used when one of known pre-python 2.5 ternary syntax is used. Refactoring consider-swap-variables R1712 "Consider using tuple unpacking for swapping variables You do not have to use a temporary variable in order to swap variables. Using ""tuple unpacking"" to directly swap variables makes the intention more clear." Refactoring trailing-comma-tuple R1707 "Disallow trailing comma tuple In Python, a tuple is actually created by the comma symbol, not by the parentheses. Unfortunately, one can actually create a tuple by misplacing a trailing comma, which can lead to potential weird bugs in your code. You should always use parentheses explicitly for creating a tuple." Refactoring stop-iteration-return R1708 "Do not raise StopIteration in generator, use return statement instead According to PEP479, the raise of StopIteration to end the loop of a generator may lead to hard to find bugs. This PEP specify that raise StopIteration has to be replaced by a simple return statement" Refactoring inconsistent-return-statements R1710 "Either all return statements in a function should return an expression, or none of them should. According to PEP8, if any return statement returns an expression, any return statements where no value is returned should explicitly state this as return None, and an explicit return statement should be present at the end of the function (if reachable)" Refactoring redefined-argument-from-local R1704 "Redefining argument with the local name %r Used when a local name is redefining an argument, which might suggest a potential error. This is taken in account only for a handful of name binding operations, such as for iteration, with statement assignment and exception handler assignment." Refactoring chained-comparison R1716 "Simplify chained comparison between the operands This message is emitted when pylint encounters boolean operation like""a < b and b < c"", suggesting instead to refactor it to ""a < b < c""" Refactoring simplifiable-if-expression R1719 The if expression can be replaced with %s Used when an if expression can be replaced with 'bool(test)'. Refactoring simplifiable-if-statement R1703 The if statement can be replaced with %s Used when an if statement can be replaced with 'bool(test)'. Refactoring too-many-nested-blocks R1702 Too many nested blocks (%s/%s) Used when a function or a method has too many nested blocks. This makes the code less understandable and maintainable. Refactoring no-else-break R1723 "Unnecessary ""%s"" after ""break"" Used in order to highlight an unnecessary block of code following an if containing a break statement. As such, it will warn when it encounters an else following a chain of ifs, all of them containing a break statement." Refactoring no-else-continue R1724 "Unnecessary ""%s"" after ""continue"" Used in order to highlight an unnecessary block of code following an if containing a continue statement. As such, it will warn when it encounters an else following a chain of ifs, all of them containing a continue statement." Refactoring no-else-raise R1720 "Unnecessary ""%s"" after ""raise"" Used in order to highlight an unnecessary block of code following an if containing a raise statement. As such, it will warn when it encounters an else following a chain of ifs, all of them containing a raise statement." Refactoring no-else-return R1705 "Unnecessary ""%s"" after ""return"" Used in order to highlight an unnecessary block of code following an if containing a return statement. As such, it will warn when it encounters an else following a chain of ifs, all of them containing a return statement." Refactoring unnecessary-comprehension R1721 "Unnecessary use of a comprehension Instead of using an identity comprehension, consider using the list, dict or set constructor. It is faster and simpler." Refactoring use-a-generator R1729 Use a generator instead '%s(%s)' Comprehension inside of 'any' or 'all' is unnecessary. A generator would be sufficient and faster. Refactoring useless-return R1711 "Useless return at end of function or method Emitted when a single ""return"" or ""return None"" statement is found at the end of function or method definition. This statement can safely be removed because Python will implicitly return None" Refactoring unneeded-not C0113 "Consider changing ""%s"" to ""%s"" Used when a boolean expression contains an unneeded negation." Refactoring consider-iterating-dictionary C0201 "Consider iterating the dictionary directly instead of calling .keys() Emitted when the keys of a dictionary are iterated through the .keys() method. It is enough to just iterate through the dictionary itself, as in ""for key in dictionary""." Refactoring consider-using-enumerate C0200 Consider using enumerate instead of iterating with range and len Emitted when code that iterates with range and len is encountered. Such code can be simplified by using the enumerate builtin. Refactoring len-as-condition C1801 "Do not use len(SEQUENCE) without comparison to determine if a sequence is empty Used when Pylint detects that len(sequence) is being used without explicit comparison inside a condition to determine if a sequence is empty. Instead of coercing the length to a boolean, either rely on the fact that empty sequences are false or compare the length against a scalar." Similarities duplicate-code R0801 Similar lines in %s files Indicates that a set of similar lines has been detected among multiple file. This usually means that the code should be refactored to avoid this duplication. Spelling invalid-characters-in-docstring C0403 Invalid characters %r in a docstring Used when a word in docstring cannot be checked by enchant. Spelling wrong-spelling-in-comment C0401 Wrong spelling of a word '%s' in a comment: Used when a word in comment is not spelled correctly. Spelling wrong-spelling-in-docstring C0402 Wrong spelling of a word '%s' in a docstring: Used when a word in docstring is not spelled correctly. Stdlib invalid-envvar-value E1507 %s does not support %s type argument Env manipulation functions support only string type arguments. See https://docs.python.org/3/library/os.html#os.getenv. Stdlib bad-open-mode W1501 "%s is not a valid mode for open. Python supports: r, w, a[, x] modes with b, +, and U (only with r) options. See https://docs.python.org/2/library/functions.html#open" Stdlib invalid-envvar-default W1508 %s default type is %s. Expected str or None. Env manipulation functions return None or str values. Supplying anything different as a default may cause bugs. See https://docs.python.org/3/library/os.html#os.getenv. Stdlib redundant-unittest-assert W1503 "Redundant use of %s with constant value %r The first argument of assertTrue and assertFalse is a condition. If a constant is passed as parameter, that condition will be always true. In this case a warning should be emitted." Stdlib shallow-copy-environ W1507 "Using copy.copy(os.environ). Use os.environ.copy() instead. os.environ is not a dict object but proxy object, so shallow copy has still effects on original object. See https://bugs.python.org/issue15373 for reference." Stdlib boolean-datetime W1502 Using datetime.time in a boolean context. Using datetime.time in a boolean context can hide subtle bugs when the time they represent matches midnight UTC. This behaviour was fixed in Python 3.5. See https://bugs.python.org/issue13936 for reference. This message can't be emitted when using Python >= 3.5. Stdlib deprecated-argument W1511 Using deprecated argument %s of method %s() The argument is marked as deprecated and will be removed in the future. Stdlib deprecated-class W1512 Using deprecated class %s of module %s The class is marked as deprecated and will be removed in the future. Stdlib deprecated-method W1505 Using deprecated method %s() The method is marked as deprecated and will be removed in a future version of Python. Consider looking for an alternative in the documentation. Stdlib subprocess-popen-preexec-fn W1509 "Using preexec_fn keyword which may be unsafe in the presence of threads The preexec_fn parameter is not safe to use in the presence of threads in your application. The child process could deadlock before exec is called. If you must use it, keep it trivial! Minimize the number of libraries you call into.https://docs.python.org/3/library/subprocess.html#popen-constructor" Stdlib subprocess-run-check W1510 Using subprocess.run without explicitly set check is not recommended. The check parameter should always be used with explicitly set check keyword to make clear what the error-handling behavior is.https://docs.python.org/3/library/subprocess.html#subprocess.run Stdlib bad-thread-instantiation W1506 "threading.Thread needs the target function The warning is emitted when a threading.Thread class is instantiated without the target function being passed. By default, the first parameter is the group param, not the target param." String bad-string-format-type E1307 Argument %r does not match format type %r Used when a type required by format string is not suitable for actual argument type String format-needs-mapping E1303 "Expected mapping for format string, not %s Used when a format string that uses named conversion specifiers is used with an argument that is not a mapping." String truncated-format-string E1301 Format string ends in middle of conversion specifier Used when a format string terminates before the end of a conversion specifier. String missing-format-string-key E1304 Missing key %r in format string dictionary Used when a format string that uses named conversion specifiers is used with a dictionary that doesn't contain all the keys required by the format string. String mixed-format-string E1302 Mixing named and unnamed conversion specifiers in format string Used when a format string contains both named (e.g. '%(foo)d') and unnamed (e.g. '%d') conversion specifiers. This is also used when a named conversion specifier contains * for the minimum field width and/or precision. String too-few-format-args E1306 Not enough arguments for format string Used when a format string that uses unnamed conversion specifiers is given too few arguments String bad-str-strip-call E1310 "Suspicious argument in %s.%s call The argument to a str.{l,r,}strip call contains a duplicate character," String too-many-format-args E1305 Too many arguments for format string Used when a format string that uses unnamed conversion specifiers is given too many arguments. String bad-format-character E1300 Unsupported format character %r (%#02x) at index %d Used when an unsupported format character is used in a format string. String anomalous-unicode-escape-in-string W1402 Anomalous Unicode escape in byte string: '%s'. String constant might be missing an r or u prefix. Used when an escape like u is encountered in a byte string where it has no effect. String anomalous-backslash-in-string W1401 Anomalous backslash in string: '%s'. String constant might be missing an r prefix. Used when a backslash is in a literal string but not as an escape. String duplicate-string-formatting-argument W1308 "Duplicate string formatting argument %r, consider passing as named argument Used when we detect that a string formatting is repeating an argument instead of using named string arguments" String format-combined-specification W1305 Format string contains both automatic field numbering and manual field specification Used when a PEP 3101 format string contains both automatic field numbering (e.g. '{}') and manual field specification (e.g. '{0}'). String bad-format-string-key W1300 "Format string dictionary key should be a string, not %s Used when a format string that uses named conversion specifiers is used with a dictionary whose keys are not all strings." String implicit-str-concat W1404 Implicit string concatenation found in %s String literals are implicitly concatenated in a literal iterable definition : maybe a comma is missing ? String bad-format-string W1302 Invalid format string Used when a PEP 3101 format string is invalid. String missing-format-attribute W1306 "Missing format attribute %r in format specifier %r Used when a PEP 3101 format string uses an attribute specifier ({0.length}), but the argument passed for formatting doesn't have that attribute." String missing-format-argument-key W1303 Missing keyword argument %r for format string Used when a PEP 3101 format string that uses named fields doesn't receive one or more required keywords. String inconsistent-quotes W1405 Quote delimiter %s is inconsistent with the rest of the file Quote delimiters are not used consistently throughout a module (with allowances made for avoiding unnecessary escaping). String unused-format-string-argument W1304 Unused format argument %r Used when a PEP 3101 format string that uses named fields is used with an argument that is not required by the format string. String unused-format-string-key W1301 Unused key %r in format string dictionary Used when a format string that uses named conversion specifiers is used with a dictionary that contains keys not required by the format string. String f-string-without-interpolation W1309 "Using an f-string that does not have any interpolated variables Used when we detect an f-string that does not use any interpolation variables, in which case it can be either a normal string or a bug in the code." String invalid-format-index W1307 "Using invalid lookup key %r in format specifier %r Used when a PEP 3101 format string uses a lookup specifier ({a[1]}), but the argument passed for formatting doesn't contain or doesn't have that key as an attribute." Typecheck unsupported-assignment-operation E1137 %r does not support item assignment Emitted when an object does not support item assignment (i.e. doesn't define setitem method). Typecheck unsupported-delete-operation E1138 %r does not support item deletion Emitted when an object does not support item deletion (i.e. doesn't define delitem method). Typecheck invalid-unary-operand-type E1130 Emitted when a unary operand is used on an object which does not support this type of operation. Typecheck unsupported-binary-operation E1131 Emitted when a binary arithmetic operation between two operands is not supported. Typecheck no-member E1101 %s %r has no %r member%s Used when a variable is accessed for an unexistent member. Typecheck not-callable E1102 %s is not callable Used when an object being called has been inferred to a non callable object. Typecheck redundant-keyword-arg E1124 "Argument %r passed by position and keyword in %s call Used when a function call would result in assigning multiple values to a function parameter, one value from a positional argument and one from a keyword argument." Typecheck assignment-from-no-return E1111 "Assigning result of a function call, where the function has no return Used when an assignment is done on a function call but the inferred function doesn't return anything." Typecheck assignment-from-none E1128 "Assigning result of a function call, where the function returns None Used when an assignment is done on a function call but the inferred function returns nothing but None." Typecheck not-context-manager E1129 Context manager '%s' doesn't implement enter and exit. Used when an instance in a with statement doesn't implement the context manager protocol(enter/exit). Typecheck unhashable-dict-key E1140 Dict key is unhashable Emitted when a dict key is not hashable (i.e. doesn't define hash method). Typecheck repeated-keyword E1132 Got multiple values for keyword argument %r in function call Emitted when a function call got multiple values for a keyword. Typecheck invalid-metaclass E1139 "Invalid metaclass %r used Emitted whenever we can detect that a class is using, as a metaclass, something which might be invalid for using as a metaclass." Typecheck missing-kwoa E1125 Missing mandatory keyword argument %r in %s call Used when a function call does not pass a mandatory keyword-only argument. Typecheck no-value-for-parameter E1120 No value for argument %s in %s call Used when a function call passes too few arguments. Typecheck not-an-iterable E1133 Non-iterable value %s is used in an iterating context Used when a non-iterable value is used in place where iterable is expected Typecheck not-a-mapping E1134 Non-mapping value %s is used in a mapping context Used when a non-mapping value is used in place where mapping is expected Typecheck invalid-sequence-index E1126 "Sequence index is not an int, slice, or instance with index Used when a sequence type is indexed with an invalid type. Valid types are ints, slices, and objects with an index method." Typecheck invalid-slice-index E1127 "Slice index is not an int, None, or instance with index Used when a slice index is not an integer, None, or an object with an index method." Typecheck too-many-function-args E1121 Too many positional arguments for %s call Used when a function call passes too many positional arguments. Typecheck unexpected-keyword-arg E1123 Unexpected keyword argument %r in %s call Used when a function call passes a keyword argument that doesn't correspond to one of the function's parameter names. Typecheck dict-iter-missing-items E1141 Unpacking a dictionary in iteration without calling .items() Emitted when trying to iterate through a dict without calling .items() Typecheck unsupported-membership-test E1135 Value '%s' doesn't support membership test Emitted when an instance in membership test expression doesn't implement membership protocol (contains/iter/getitem). Typecheck unsubscriptable-object E1136 Value '%s' is unsubscriptable Emitted when a subscripted value doesn't support subscription (i.e. doesn't define getitem method or class_getitem for a class). Typecheck keyword-arg-before-vararg W1113 "Keyword argument before variable positional arguments list in the definition of %s function When defining a keyword argument before variable positional arguments, one can end up in having multiple values passed for the aforementioned parameter in case the method is called with keyword arguments." Typecheck non-str-assignment-to-dunder-name W1115 Non-string value assigned to name Emitted when a non-string vaue is assigned to name Typecheck arguments-out-of-order W1114 Positional arguments appear to be out of order Emitted when the caller's argument names fully match the parameter names in the function signature but do not have the same order. Typecheck isinstance-second-argument-not-valid-type W1116 Second argument of isinstance is not a type Emitted when the second argument of an isinstance call is not a type. Typecheck c-extension-no-member I1101 "%s %r has no %r member%s, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. Used when a variable is accessed for non-existent member of C extension. Due to unavailability of source static analysis is impossible, but it may be performed by introspecting living objects in run-time." Varialbes unpacking-non-sequence E0633 Attempting to unpack a non-sequence%s Used when something which is not a sequence is used in an unpack assignment Varialbes invalid-all-object E0604 "Invalid object %r in all, must contain only strings Used when an invalid (non-string) object occurs in all." Varialbes no-name-in-module E0611 No name %r in module %r Used when a name cannot be found in a module. Varialbes undefined-variable E0602 Undefined variable %r Used when an undefined variable is accessed. Varialbes undefined-all-variable E0603 Undefined variable name %r in all Used when an undefined variable name is referenced in all. Varialbes used-before-assignment E0601 Using variable %r before assignment Used when a local variable is accessed before its assignment. Varialbes cell-var-from-loop W0640 Cell variable %s defined in loop A variable used in a closure is defined in a loop. This will result in all closures using the same value for the closed-over variable. Varialbes global-variable-undefined W0601 "Global variable %r undefined at the module level Used when a variable is defined through the ""global"" statement but the variable is not defined in the module scope." Varialbes self-cls-assignment W0642 Invalid assignment to %s in method Invalid assignment to self or cls in instance or class method respectively. Varialbes unbalanced-tuple-unpacking W0632 "Possible unbalanced tuple unpacking with sequence%s: left side has %d label(s), right side has %d value(s) Used when there is an unbalanced tuple unpacking in assignment" Varialbes possibly-unused-variable W0641 "Possibly unused variable %r Used when a variable is defined but might not be used. The possibility comes from the fact that locals() might be used, which could consume or not the said variable" Varialbes redefined-builtin W0622 Redefining built-in %r Used when a variable or function override a built-in. Varialbes redefine-in-handler W0623 Redefining name %r from %s in exception handler Used when an exception handler assigns the exception to an existing name Varialbes redefined-outer-name W0621 Redefining name %r from outer scope (line %s) Used when a variable's name hides a name defined in the outer scope. Varialbes unused-import W0611 Unused %s Used when an imported module or variable is not used. Varialbes unused-argument W0613 Unused argument %r Used when a function or method argument is not used. Varialbes unused-wildcard-import W0614 Unused import %s from wildcard import Used when an imported module or variable is not used from a 'from X import *' style import. Varialbes unused-variable W0612 Unused variable %r Used when a variable is defined but not used. Varialbes global-variable-not-assigned W0602 "Using global for %r but no assignment is done Used when a variable is defined through the ""global"" statement but no assignment to this variable is done." Varialbes undefined-loop-variable W0631 Using possibly undefined loop variable %r Used when a loop variable (i.e. defined by a for loop or a list comprehension or a generator expression) is used outside the loop. Varialbes global-statement W0603 "Using the global statement Used when you use the ""global"" statement to update a global variable. Pylint just try to discourage this usage. That doesn't mean you cannot use it !" Varialbes global-at-module-level W0604 "Using the global statement at the module level Used when you use the ""global"" statement at the module level since it has no effect"
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Pylintルール一覧_ja

Category Rule Id Default Disabled Messages Description Async not-async-context-manager E1701 Async context manager '%s' doesn't implement aenter and aexit. Async context manager '%s' doesn't implement aenter and aexit. Used when an async context manager is used with an object that does not implement the async context management protocol. This message can't be emitted when using Python < 3.5. Async yield-inside-async-function E1700 Yield inside async function Yield inside async function Used when an yield or yield from statement is found inside an async function. This message can't be emitted when using Python < 3.5. Basic not-in-loop E0103 %r not properly in loop breakやcontinueがループの外で使用されている。 Basic function-redefined E0102 %s already defined line %s 関数/クラス/メソッドが再定義されている。 Basic continue-in-finally E0116 continue' not supported inside 'finally' clause continueがfinally句内で使用されている。これはSyntaxErrorになる。このメッセージはPython3.8以上で表示されない。 Basic abstract-class-instantiated E0110 Abstract class %r with abstract methods instantiated メタクラスとしてabc.ABCMetaを持つ抽象クラスが抽象メソッドを持ち、かつ、インスタンス化されている。 Basic star-needs-assignment-target E0114 Can use starred expression only in assignment target スター表現が代入対象以外で使用されている。 Basic duplicate-argument-name E0108 Duplicate argument name %s in function definition 関数定義において引数名が重複している。これはSyntaxErrorになる。 Basic return-in-init E0101 Explicit return in init 特殊クラスメソッドinitが明示的な戻り値を持っている。 Basic too-many-star-expressions E0112 More than one starred expression in assignment 引数内にスター表現(*x)が2つ以上存在する。これはSyntaxErrorになる。 Basic nonlocal-and-global E0115 Name %r is nonlocal and global 名前がnonlocalとglobalの両方に存在する。 Basic used-prior-global-declaration E0118 Name %r is used prior to global declaration global宣言の前に名前が使用されている。これはPython3.6以降ではエラーになる。Python3.6より前ではこのメッセージは表示されない。 Basic return-outside-function E0104 Return outside function 関数/メソッドの外にreturn文が存在する。 Basic return-arg-in-generator E0106 Return with argument inside generator ジェネレータ関数またはメソッド(yeild文を含むものなど)の外にreturn文が存在する。このメッセージはPython3.3以降では表示されない。 Basic invalid-star-assignment-target E0113 Starred assignment target must be in a list or tuple スター表現がスター付き代入ターゲットとして使用されている。 Basic bad-reversed-sequence E0111 The first reversed() argument is not a sequence 組み込み関数reversed()の第一引数がシーケンスでない。 Basic nonexistent-operator E0107 Use of the non-existent %s operator C言語スタイルのインクリメント演算子やデクリメント演算子を使用している。これらはPythonには存在しない。 Basic yield-outside-function E0105 Yield outside function yield文が関数またはメソッドの外に存在する。 Basic init-is-generator E0100 init method is a generator 特殊クラスメソッドinitがメソッド内にyeild文があることでジェネレータになっている。 Basic misplaced-format-function E0119 format function is not called on str "strオブジェクトにおいてformat関数が呼び出されていない。例えば、""print(""value: {}"".format(123))""とするべき所を、誤って""print(""value: {}"").format(123)""としている、など。" Basic nonlocal-without-binding E0117 nonlocal name %s found without binding nonlocal変数が親スコープにおいて定義されていない。 Basic lost-exception W0150 %s statement in finally block may swallow exception try-finallyブロックのfinally句内にbreak文やreturn文がある。この時、try句内で発生した例外は再発生することなく暗黙的に握りつぶされる。 Basic assert-on-tuple W0199 "Assert called on a 2-item-tuple. Did you mean 'assert x,y'?" assert文にタプルを渡している。assert文にタプルを渡すと、タプルが空でないときは常にtrueとして、空の時は常にfalseとして評価する。 Basic assert-on-string-literal W0129 Assert statement has a string literal as its first argument. assert文の第一引数が文字列リテラルである。この時、assertは常にtrueと評価し、パスする。 Basic self-assigning-variable W0127 Assigning the same variable %r to itself ある変数がその変数自身に代入されている。(例 x=x) Basic comparison-with-callable W0143 "Comparing against a callable, did you omit the parenthesis?" callableを含む比較がある。括弧が省略されている可能性があり、望ましくないふるまいをする可能性がある。 Basic nan-comparison W0177 Comparison %s should be %s numpy.NaNやfloat('nan')のようなNaN値との比較がある。 Basic dangerous-default-value W0102 Dangerous default value %s as argument 引数のデフォルト値内にリストや辞書のようなミュータブルな値がある。 Basic duplicate-key W0109 Duplicate key %r in dictionary 辞書が同じキーを複数回バインドしている。 Basic useless-else-on-loop W0120 Else clause on loop without a break statement break文を持たないelse句がループにある。break文を持ち早期にexitできるときにのみ、ループはelse句を持つべきである。そうでなければ、else下の文はループと同じスコープにあるべき。 Basic expression-not-assigned W0106 "Expression ""%s"" is assigned to nothing" 関数呼び出し以外の式が何にも代入されていない。 Basic confusing-with-statement W0124 "Following ""as"" with another context manager looks like a tuple." "Following ""as"" with another context manager looks like a tuple. Emitted when a with statement component returns multiple values and uses name binding with as only for a part of those values, as in with ctx() as a, b. This can be misleading, since it's not clear if the context manager returns a tuple or if the node without a name binding is another context manager." Basic unnecessary-lambda W0108 Lambda may not be necessary Used when the body of a lambda expression is a function call on the same argument list as the lambda itself; such lambda expressions are in all but a few cases replaceable with the function being called in the body of the lambda. Basic assign-to-new-keyword W0111 Name %s will become a keyword in Python %s Used when assignment will become invalid in future Python release due to introducing new keyword. Basic redeclared-assigned-name W0128 Redeclared variable %r in assignment Emitted when we detect that a variable was redeclared in the same assignment. Basic pointless-statement W0104 Statement seems to have no effect Used when a statement doesn't have (or at least seems to) any effect. Basic pointless-string-statement W0105 "String statement has no effect Used when a string is used as a statement (which of course has no effect). This is a particular case of W0104 with its own message so you can easily disable it if you're using those strings as documentation, instead of comments." Basic unnecessary-pass W0107 "Unnecessary pass statement Used when a ""pass"" statement that can be avoided is encountered." Basic unreachable W0101 "Unreachable code Used when there is some code behind a ""return"" or ""raise"" statement, which will never be accessed." Basic eval-used W0123 "Use of eval Used when you use the ""eval"" function, to discourage its usage. Consider using ast.literal_eval for safely evaluating strings containing Python expressions from untrusted sources." Basic exec-used W0122 "Use of exec Used when you use the ""exec"" statement (function for Python 3), to discourage its usage. That doesn't mean you cannot use it !" Basic using-constant-test W0125 Using a conditional statement with a constant value Emitted when a conditional statement (If or ternary if) uses a constant value for its test. This might not be what the user intended to do. Basic missing-parentheses-for-call-in-test W0126 Using a conditional statement with potentially wrong function or method call due to missing parentheses Emitted when a conditional statement (If or ternary if) seems to wrongly call a function due to missing parentheses Basic literal-comparison R0123 "Comparison to literal Used when comparing an object to a literal, which is usually what you do not want to do, since you can compare to a different literal than what was expected altogether." Basic comparison-with-itself R0124 Redundant comparison - %s Used when something is compared against itself. Basic non-ascii-name C0144 "%s name ""%s"" contains a non-ASCII unicode character Used when the name contains at least one non-ASCII unicode character." Basic invalid-name C0103 "%s name ""%s"" doesn't conform to %s Used when the name doesn't conform to naming rules associated to its type (constant, variable, class...)." Basic singleton-comparison C0121 "Comparison %s should be %s Used when an expression is compared to singleton values like True, False or None." Basic misplaced-comparison-constant C0122 Comparison should be %s Used when the constant is placed on the left side of a comparison. It is usually clearer in intent to place it in the right hand side of the comparison. Basic disallowed-name C0104 "Disallowed name ""%s"" Used when the name matches bad-names or bad-names-rgxs- (unauthorized names)." Basic empty-docstring C0112 "Empty %s docstring Used when a module, function, class or method has an empty docstring (it would be too easy ;)." Basic missing-class-docstring C0115 Missing class docstring Used when a class has no docstring.Even an empty class must have a docstring. Basic missing-function-docstring C0116 Missing function or method docstring Used when a function or method has no docstring.Some special methods like init do not require a docstring. Basic missing-module-docstring C0114 Missing module docstring Used when a module has no docstring.Empty modules do not require a docstring. Basic unidiomatic-typecheck C0123 "Use isinstance() rather than type() for a typecheck. The idiomatic way to perform an explicit typecheck in Python is to use isinstance(x, Y) rather than type(x) == Y, type(x) is Y. Though there are unusual situations where these give different results." Classes access-member-before-definition E0203 Access to member %r before its definition line %s Used when an instance member is accessed before it's actually assigned. Classes method-hidden E0202 An attribute defined in %s line %s hides this method Used when a class defines a method which is hidden by an instance attribute from an ancestor class or set by some client code. Classes assigning-non-slot E0237 Assigning to attribute %r not defined in class slots Used when assigning to an attribute not defined in the class slots. Classes duplicate-bases E0241 Duplicate bases for class %r Used when a class has duplicate bases. Classes inconsistent-mro E0240 Inconsistent method resolution order for class %r Used when a class has an inconsistent method resolution order. Classes inherit-non-class E0239 "Inheriting %r, which is not a class. Used when a class inherits from something which is not a class." Classes invalid-slots E0238 "Invalid slots object Used when an invalid slots is found in class. Only a string, an iterable or a sequence is permitted." Classes invalid-slots-object E0236 "Invalid object %r in slots, must contain only non empty strings Used when an invalid (non-string) object occurs in slots." Classes no-method-argument E0211 Method has no argument Used when a method which should have the bound instance as first argument has no argument defined. Classes no-self-argument E0213 "Method should have ""self"" as first argument Used when a method has an attribute different the ""self"" as first argument. This is considered as an error since this is a so common convention that you shouldn't break it!" Classes unexpected-special-method-signature E0302 "The special method %r expects %s param(s), %d %s given Emitted when a special method was defined with an invalid number of parameters. If it has too few or too many, it might not work at all." Classes class-variable-slots-conflict E0242 "Value %r in slots conflicts with class variable Used when a value in slots conflicts with a class variable, property or method." Classes invalid-bool-returned E0304 bool does not return bool Used when a bool method returns something which is not a bool Classes invalid-bytes-returned E0308 bytes does not return bytes Used when a bytes method returns something which is not bytes Classes invalid-format-returned E0311 format does not return str Used when a format method returns something which is not a string Classes invalid-getnewargs-returned E0312 getnewargs does not return a tuple Used when a getnewargs method returns something which is not a tuple Classes invalid-getnewargs-ex-returned E0313 "getnewargs_ex does not return a tuple containing (tuple, dict) Used when a getnewargs_ex method returns something which is not of the form tuple(tuple, dict)" Classes invalid-hash-returned E0309 hash does not return int Used when a hash method returns something which is not an integer Classes invalid-index-returned E0305 index does not return int Used when an index method returns something which is not an integer Classes non-iterator-returned E0301 iter returns non-iterator Used when an iter method returns something which is not an iterable (i.e. has no next method) Classes invalid-length-returned E0303 len does not return non-negative integer Used when a len method returns something which is not a non-negative integer Classes invalid-length-hint-returned E0310 length_hint does not return non-negative integer Used when a length_hint method returns something which is not a non- negative integer Classes invalid-repr-returned E0306 repr does not return str Used when a repr method returns something which is not a string Classes invalid-str-returned E0307 str does not return str Used when a str method returns something which is not a string Classes protected-access W0212 Access to a protected member %s of a client class Used when a protected member (i.e. class member with a name beginning with an underscore) is access outside the class or a descendant of the class where it's defined. Classes attribute-defined-outside-init W0201 Attribute %r defined outside init Used when an instance attribute is defined outside the init method. Classes no-init W0232 "Class has no init method Used when a class has no init method, neither its parent classes." Classes abstract-method W0223 Method %r is abstract in class %r but is not overridden Used when an abstract method (i.e. raise NotImplementedError) is not overridden in concrete class. Classes invalid-overridden-method W0236 "Method %r was expected to be %r, found it instead as %r Used when we detect that a method was overridden in a way that does not match its base class which could result in potential bugs at runtime." Classes arguments-differ W0221 Parameters differ from %s %r method Used when a method has a different number of arguments than in the implemented interface or in an overridden method. Classes signature-differs W0222 Signature differs from %s %r method Used when a method signature is different than in the implemented interface or in an overridden method. Classes bad-staticmethod-argument W0211 "Static method with %r as first argument Used when a static method has ""self"" or a value specified in valid- classmethod-first-arg option or valid-metaclass-classmethod-first-arg option as first argument." Classes useless-super-delegation W0235 "Useless super delegation in method %r Used whenever we can detect that an overridden method is useless, relying on super() delegation to do the same thing as another method from the MRO." Classes non-parent-init-called W0233 init method from a non direct base class %r is called Used when an init method is called on a class which is not in the direct ancestors for the analysed class. Classes super-init-not-called W0231 init method from base class %r is not called Used when an ancestor class method has an init method which is not called by a derived class. Classes property-with-parameters R0206 "Cannot have defined parameters for properties Used when we detect that a property also has parameters, which are useless, given that properties cannot be called with additional arguments." Classes useless-object-inheritance R0205 "Class %r inherits from object, can be safely removed from bases in python3 Used when a class inherit from object, which under python3 is implicit, hence can be safely removed from bases." Classes no-classmethod-decorator R0202 Consider using a decorator instead of calling classmethod Used when a class method is defined without using the decorator syntax. Classes no-staticmethod-decorator R0203 Consider using a decorator instead of calling staticmethod Used when a static method is defined without using the decorator syntax. Classes no-self-use R0201 "Method could be a function Used when a method doesn't use its bound instance, and so could be written as a function." Classes single-string-used-for-slots C0205 "Class slots should be a non-string iterable Used when a class slots is a simple string, rather than an iterable." Classes bad-classmethod-argument C0202 "Class method %s should have %s as first argument Used when a class method has a first argument named differently than the value specified in valid-classmethod-first-arg option (default to ""cls""), recommended to easily differentiate them from regular instance methods." Classes bad-mcs-classmethod-argument C0204 "Metaclass class method %s should have %s as first argument Used when a metaclass class method has a first argument named differently than the value specified in valid-metaclass-classmethod-first-arg option (default to ""mcs""), recommended to easily differentiate them from regular instance methods." Classes bad-mcs-method-argument C0203 "Metaclass method %s should have %s as first argument Used when a metaclass method has a first argument named differently than the value specified in valid-classmethod-first-arg option (default to ""cls""), recommended to easily differentiate them from regular instance methods." Classes method-check-failed F0202 Unable to check methods signature (%s / %s) Used when Pylint has been unable to check methods signature compatibility for an unexpected reason. Please report this kind if you don't make sense of it. Design too-few-public-methods R0903 "Too few public methods (%s/%s) Used when class has too few public methods, so be sure it's really worth it." Design too-many-ancestors R0901 "Too many ancestors (%s/%s) Used when class has too many parent classes, try to reduce this to get a simpler (and so easier to use) class." Design too-many-arguments R0913 Too many arguments (%s/%s) Used when a function or method takes too many arguments. Design too-many-boolean-expressions R0916 Too many boolean expressions in if statement (%s/%s) Used when an if statement contains too many boolean expressions. Design too-many-branches R0912 "Too many branches (%s/%s) Used when a function or method has too many branches, making it hard to follow." Design too-many-instance-attributes R0902 "Too many instance attributes (%s/%s) Used when class has too many instance attributes, try to reduce this to get a simpler (and so easier to use) class." Design too-many-locals R0914 Too many local variables (%s/%s) Used when a function or method has too many local variables. Design too-many-public-methods R0904 "Too many public methods (%s/%s) Used when class has too many public methods, try to reduce this to get a simpler (and so easier to use) class." Design too-many-return-statements R0911 "Too many return statements (%s/%s) Used when a function or method has too many return statement, making it hard to follow." Design too-many-statements R0915 Too many statements (%s/%s) Used when a function or method has too many statements. You should then split it in smaller functions / methods. Exceptions bad-except-order E0701 "Bad except clauses order (%s) Used when except clauses are not in the correct order (from the more specific to the more generic). If you don't fix the order, some exceptions may not be caught by the most specific handler." Exceptions catching-non-exception E0712 Catching an exception which doesn't inherit from Exception: %s Used when a class which doesn't inherit from Exception is used as an exception in an except clause. Exceptions bad-exception-context E0703 "Exception context set to something which is not an exception, nor None Used when using the syntax ""raise ... from ..."", where the exception context is not an exception, nor None." Exceptions notimplemented-raised E0711 NotImplemented raised - should raise NotImplementedError Used when NotImplemented is raised instead of NotImplementedError Exceptions raising-bad-type E0702 "Raising %s while only classes or instances are allowed Used when something which is neither a class, an instance or a string is raised (i.e. a TypeError will be raised)." Exceptions raising-non-exception E0710 Raising a new style class which doesn't inherit from BaseException Used when a new style class which doesn't inherit from BaseException is raised. Exceptions misplaced-bare-raise E0704 "The raise statement is not inside an except clause Used when a bare raise is not used inside an except clause. This generates an error, since there are no active exceptions to be reraised. An exception to this rule is represented by a bare raise inside a finally clause, which might work, as long as an exception is raised inside the try block, but it is nevertheless a code smell that must not be relied upon." Exceptions duplicate-except W0705 Catching previously caught exception type %s Used when an except catches a type that was already caught by a previous handler. Exceptions broad-except W0703 "Catching too general exception %s Used when an except catches a too general exception, possibly burying unrelated errors." Exceptions raise-missing-from W0707 "Consider explicitly re-raising using the 'from' keyword Python 3's exception chaining means it shows the traceback of the current exception, but also the original exception. Not using raise from makes the traceback inaccurate, because the message implies there is a bug in the exception-handling code itself, which is a separate situation than wrapping an exception." Exceptions raising-format-tuple W0715 "Exception arguments suggest string formatting might be intended Used when passing multiple arguments to an exception constructor, the first of them a string literal containing what appears to be placeholders intended for formatting" Exceptions binary-op-exception W0711 "Exception to catch is the result of a binary ""%s"" operation Used when the exception to catch is of the form ""except A or B:"". If intending to catch multiple, rewrite as ""except (A, B):""" Exceptions wrong-exception-operation W0716 "Invalid exception operation. %s Used when an operation is done against an exception, but the operation is not valid for the exception in question. Usually emitted when having binary operations between exceptions in except handlers." Exceptions bare-except W0702 No exception type(s) specified Used when an except clause doesn't specify exceptions type to catch. Exceptions try-except-raise W0706 The except handler raises immediately Used when an except handler uses raise as its first or only operator. This is useless because it raises back the exception immediately. Remove the raise operator or the entire try-except-raise block! Format bad-indentation W0311 "Bad indentation. Found %s %s, expected %s Used when an unexpected number of indentation's tabulations or spaces has been found." Format unnecessary-semicolon W0301 "Unnecessary semicolon Used when a statement is ended by a semi-colon ("";""), which isn't necessary (that's python, not C ;)." Format missing-final-newline C0304 Final newline missing Used when the last line in a file is missing a newline. Format line-too-long C0301 Line too long (%s/%s) Used when a line is longer than a given number of characters. Format mixed-line-endings C0327 Mixed line endings LF and CRLF Used when there are mixed (LF and CRLF) newline signs in a file. Format multiple-statements C0321 More than one statement on a single line Used when more than on statement are found on the same line. Format too-many-lines C0302 "Too many lines in module (%s/%s) Used when a module has too many lines, reducing its readability." Format trailing-newlines C0305 Trailing newlines Used when there are trailing blank lines in a file. Format trailing-whitespace C0303 Trailing whitespace Used when there is whitespace between the end of a line and the newline. Format unexpected-line-ending-format C0328 Unexpected line ending format. There is '%s' while it should be '%s'. Used when there is different newline than expected. Format superfluous-parens C0325 "Unnecessary parens after %r keyword Used when a single item in parentheses follows an if, for, or other keyword." Imports relative-beyond-top-level E0402 Attempted relative import beyond top-level package Used when a relative import tries to access too many levels in the current package. Imports import-error E0401 Unable to import %s Used when pylint has been unable to import a module. Imports import-self W0406 Module import itself Used when a module is importing itself. Imports preferred-module W0407 Prefer importing %r instead of %r Used when a module imported has a preferred replacement module. Imports reimported W0404 Reimport %r (imported line %s) Used when a module is reimported multiple times. Imports deprecated-module W0402 Uses of a deprecated module %r Used a module marked as deprecated is imported. Imports wildcard-import W0401 Wildcard import %s Used when from module import * is detected. Imports misplaced-future W0410 future import is not the first non docstring statement Python 2.5 and greater require future import to be the first non docstring statement in the module. Imports cyclic-import R0401 Cyclic import (%s) Used when a cyclic import between two or more modules is detected. Imports wrong-import-order C0411 "%s should be placed before %s Used when PEP8 import order is not respected (standard imports first, then third-party libraries, then local imports)" Imports wrong-import-position C0413 "Import ""%s"" should be placed at the top of the module Used when code and imports are mixed" Imports useless-import-alias C0414 Import alias does not rename original package Used when an import alias is same as original package.e.g using import numpy as numpy instead of import numpy as np Imports import-outside-toplevel C0415 Import outside toplevel (%s) Used when an import statement is used anywhere other than the module toplevel. Move this import to the top of the file. Imports ungrouped-imports C0412 Imports from package %s are not grouped Used when imports are not grouped by packages Imports multiple-imports C0410 Multiple imports on one line (%s) Used when import statement importing multiple modules is detected. Logging logging-format-truncated E1201 Logging format string ends in middle of conversion specifier Used when a logging statement format string terminates before the end of a conversion specifier. Logging logging-too-few-args E1206 Not enough arguments for logging format string Used when a logging format string is given too few arguments. Logging logging-too-many-args E1205 Too many arguments for logging format string Used when a logging format string is given too many arguments. Logging logging-unsupported-format E1200 Unsupported logging format character %r (%#02x) at index %d Used when an unsupported format character is used in a logging statement format string. Logging logging-format-interpolation W1202 "Use %s formatting in logging functions Used when a logging statement has a call form of ""logging.(format_string.format(format_args...))"". Use another type of string formatting instead. You can use % formatting but leave interpolation to the logging function by passing the parameters as arguments. If logging-fstring- interpolation is disabled then you can use fstring formatting. If logging- not-lazy is disabled then you can use % formatting as normal." Logging logging-fstring-interpolation W1203 "Use %s formatting in logging functions Used when a logging statement has a call form of ""logging.(f""..."")"".Use another type of string formatting instead. You can use % formatting but leave interpolation to the logging function by passing the parameters as arguments. If logging-format-interpolation is disabled then you can use str.format. If logging-not-lazy is disabled then you can use % formatting as normal." Logging logging-not-lazy W1201 "Use %s formatting in logging functions Used when a logging statement has a call form of ""logging.(format_string % (format_args...))"". Use another type of string formatting instead. You can use % formatting but leave interpolation to the logging function by passing the parameters as arguments. If logging-fstring- interpolation is disabled then you can use fstring formatting. If logging- format-interpolation is disabled then you can use str.format." Miscellaneous fixme W0511 Used when a warning note as FIXME or XXX is detected. Miscellaneous use-symbolic-message-instead I0023 Used when a message is enabled or disabled by id. Newstyle bad-super-call E1003 Bad first argument %r given to super() Used when another argument than the current class is given as first argument of the super builtin. Python3 unpacking-in-except E1603 Implicit unpacking of exceptions is not supported in Python 3 Python3 will not allow implicit unpacking of exceptions in except clauses. See https://www.python.org/dev/peps/pep-3110/ Python3 import-star-module-level E1609 Import * only allowed at module level Used when the import star syntax is used somewhere else than the module level. This message can't be emitted when using Python >= 3.0. Python3 non-ascii-bytes-literal E1610 Non-ascii bytes literals not supported in 3.x Used when non-ascii bytes literals are found in a program. They are no longer supported in Python 3. This message can't be emitted when using Python >= 3.0. Python3 parameter-unpacking E1602 Parameter unpacking specified Used when parameter unpacking is specified for a function(Python 3 doesn't allow it) Python3 long-suffix E1606 "Use of long suffix Used when ""l"" or ""L"" is used to mark a long integer. This will not work in Python 3, since int and long types have merged. This message can't be emitted when using Python >= 3.0." Python3 old-octal-literal E1608 "Use of old octal literal Used when encountering the old octal syntax, removed in Python 3. To use the new syntax, prepend 0o on the number. This message can't be emitted when using Python >= 3.0." Python3 old-ne-operator E1607 "Use of the <> operator Used when the deprecated ""<>"" operator is used instead of ""!="". This is removed in Python 3. This message can't be emitted when using Python >= 3.0." Python3 backtick E1605 "Use of the operator Used when the deprecated """" (backtick) operator is used instead of the str() function." Python3 old-raise-syntax E1604 "Use raise ErrorClass(args) instead of raise ErrorClass, args. Used when the alternate raise syntax 'raise foo, bar' is used instead of 'raise foo(bar)'." Python3 print-statement E1601 print statement used Used when a print statement is used (print is a function in Python 3) Python3 deprecated-types-field W1652 Accessing a deprecated fields on the types module Used when accessing a field on types that has been removed in Python 3. Python3 deprecated-itertools-function W1651 Accessing a deprecated function on the itertools module Used when accessing a function on itertools that has been removed in Python 3. Python3 deprecated-string-function W1649 Accessing a deprecated function on the string module Used when accessing a string function that has been deprecated in Python 3. Python3 deprecated-operator-function W1657 Accessing a removed attribute on the operator module Used when accessing a field on operator module that has been removed in Python 3. Python3 deprecated-sys-function W1660 Accessing a removed attribute on the sys module Used when accessing a field on sys module that has been removed in Python 3. Python3 deprecated-urllib-function W1658 Accessing a removed attribute on the urllib module Used when accessing a field on urllib module that has been removed or moved in Python 3. Python3 xreadlines-attribute W1659 "Accessing a removed xreadlines attribute Used when accessing the xreadlines() function on a file stream, removed in Python 3." Python3 metaclass-assignment W1623 Assigning to a class's metaclass attribute Used when a metaclass is specified by assigning to metaclass (Python 3 specifies the metaclass as a class statement argument) Python3 next-method-called W1622 Called a next() method on an object Used when an object's next() method is called (Python 3 uses the next() built-in function) Python3 dict-iter-method W1620 "Calling a dict.iter*() method Used for calls to dict.iterkeys(), itervalues() or iteritems() (Python 3 lacks these methods)" Python3 dict-view-method W1621 "Calling a dict.view*() method Used for calls to dict.viewkeys(), viewvalues() or viewitems() (Python 3 lacks these methods)" Python3 exception-message-attribute W1645 Exception.message removed in Python 3 Used when the message attribute is accessed on an Exception. Use str(exception) instead. Python3 eq-without-hash W1641 "Implementing eq without also implementing hash Used when a class implements eq but not hash. In Python 2, objects get object.hash as the default implementation, in Python 3 objects get None as their default hash implementation if they also implement eq." Python3 indexing-exception W1624 Indexing exceptions will not work on Python 3 Indexing exceptions will not work on Python 3. Use exception.args[index] instead. Python3 bad-python3-import W1648 Module moved in Python 3 Used when importing a module that no longer exists in Python 3. Python3 raising-string W1625 Raising a string exception Used when a string exception is raised. This will not work on Python 3. Python3 standarderror-builtin W1611 StandardError built-in referenced Used when the StandardError built-in function is referenced (missing from Python 3) Python3 comprehension-escape W1662 "Using a variable that was bound inside a comprehension Emitted when using a variable, that was bound in a comprehension handler, outside of the comprehension itself. On Python 3 these variables will be deleted outside of the comprehension." Python3 exception-escape W1661 "Using an exception object that was bound by an except handler Emitted when using an exception, that was bound in an except handler, outside of the except handler. On Python 3 these exceptions will be deleted once they get out of the except handler." Python3 deprecated-str-translate-call W1650 Using str.translate with deprecated deletechars parameters Used when using the deprecated deletechars parameters from str.translate. Use re.sub to remove the desired characters Python3 using-cmp-argument W1640 "Using the cmp argument for list.sort / sorted Using the cmp argument for list.sort or the sorted builtin should be avoided, since it was removed in Python 3. Using either key or functools.cmp_to_key should be preferred." Python3 cmp-method W1630 cmp method defined Used when a cmp method is defined (method is not used by Python 3) Python3 coerce-method W1614 coerce method defined Used when a coerce method is defined (method is not used by Python 3) Python3 delslice-method W1615 delslice method defined Used when a delslice method is defined (method is not used by Python 3) Python3 div-method W1642 div method defined Used when a div method is defined. Using truediv and setting_div_ = truediv should be preferred.(method is not used by Python 3) Python3 getslice-method W1616 getslice method defined Used when a getslice method is defined (method is not used by Python 3) Python3 hex-method W1628 hex method defined Used when a hex method is defined (method is not used by Python 3) Python3 idiv-method W1643 idiv method defined Used when an idiv method is defined. Using itruediv and setting_idiv_ = itruediv should be preferred.(method is not used by Python 3) Python3 nonzero-method W1629 nonzero method defined Used when a nonzero method is defined (method is not used by Python 3) Python3 oct-method W1627 oct method defined Used when an oct method is defined (method is not used by Python 3) Python3 rdiv-method W1644 rdiv method defined Used when a rdiv method is defined. Using rtruediv and setting_rdiv_ = rtruediv should be preferred.(method is not used by Python 3) Python3 setslice-method W1617 setslice method defined Used when a setslice method is defined (method is not used by Python 3) Python3 apply-builtin W1601 apply built-in referenced Used when the apply built-in function is referenced (missing from Python 3) Python3 basestring-builtin W1602 basestring built-in referenced Used when the basestring built-in function is referenced (missing from Python 3) Python3 buffer-builtin W1603 buffer built-in referenced Used when the buffer built-in function is referenced (missing from Python 3) Python3 cmp-builtin W1604 cmp built-in referenced Used when the cmp built-in function is referenced (missing from Python 3) Python3 coerce-builtin W1605 coerce built-in referenced Used when the coerce built-in function is referenced (missing from Python 3) Python3 dict-items-not-iterating W1654 dict.items referenced when not iterating Used when dict.items is referenced in a non-iterating context (returns an iterator in Python 3) Python3 dict-keys-not-iterating W1655 dict.keys referenced when not iterating Used when dict.keys is referenced in a non-iterating context (returns an iterator in Python 3) Python3 dict-values-not-iterating W1656 dict.values referenced when not iterating Used when dict.values is referenced in a non-iterating context (returns an iterator in Python 3) Python3 old-division W1619 division w/o future statement Used for non-floor division w/o a float literal or from future import division (Python 3 returns a float for int division unconditionally) Python3 execfile-builtin W1606 execfile built-in referenced Used when the execfile built-in function is referenced (missing from Python 3) Python3 file-builtin W1607 file built-in referenced Used when the file built-in function is referenced (missing from Python 3) Python3 filter-builtin-not-iterating W1639 filter built-in referenced when not iterating Used when the filter built-in is referenced in a non-iterating context (returns an iterator in Python 3) Python3 no-absolute-import W1618 import missing from __future__ import absolute_import Used when an import is not accompanied by from future import absolute_import (default behaviour in Python 3) Python3 input-builtin W1632 input built-in referenced Used when the input built-in is referenced (backwards-incompatible semantics in Python 3) Python3 intern-builtin W1634 intern built-in referenced Used when the intern built-in is referenced (Moved to sys.intern in Python 3) Python3 long-builtin W1608 long built-in referenced Used when the long built-in function is referenced (missing from Python 3) Python3 map-builtin-not-iterating W1636 map built-in referenced when not iterating Used when the map built-in is referenced in a non-iterating context (returns an iterator in Python 3) Python3 next-method-defined W1653 next method defined Used when a next method is defined that would be an iterator in Python 2 but is treated as a normal function in Python 3. Python3 invalid-str-codec W1646 non-text encoding used in str.decode Used when using str.encode or str.decode with a non-text encoding. Use codecs module to handle arbitrary codecs. Python3 range-builtin-not-iterating W1638 range built-in referenced when not iterating Used when the range built-in is referenced in a non-iterating context (returns a range in Python 3) Python3 raw_input-builtin W1609 raw_input built-in referenced Used when the raw_input built-in function is referenced (missing from Python 3) Python3 reduce-builtin W1610 reduce built-in referenced Used when the reduce built-in function is referenced (missing from Python 3) Python3 reload-builtin W1626 reload built-in referenced Used when the reload built-in function is referenced (missing from Python 3). You can use instead imp.reload or importlib.reload. Python3 round-builtin W1633 round built-in referenced Used when the round built-in is referenced (backwards-incompatible semantics in Python 3) Python3 sys-max-int W1647 sys.maxint removed in Python 3 Used when accessing sys.maxint. Use sys.maxsize instead. Python3 unichr-builtin W1635 unichr built-in referenced Used when the unichr built-in is referenced (Use chr in Python 3) Python3 unicode-builtin W1612 unicode built-in referenced Used when the unicode built-in function is referenced (missing from Python 3) Python3 xrange-builtin W1613 xrange built-in referenced Used when the xrange built-in function is referenced (missing from Python 3) Python3 zip-builtin-not-iterating W1637 zip built-in referenced when not iterating Used when the zip built-in is referenced in a non-iterating context (returns an iterator in Python 3) Refactoring simplifiable-condition R1726 Boolean condition '%s' may be simplified to '%s' Emitted when a boolean condition is able to be simplified. Refactoring condition-evals-to-constant R1727 Boolean condition '%s' will always evaluate to '%s' Emitted when a boolean condition can be simplified to a constant value. Refactoring simplify-boolean-expression R1709 Boolean expression may be simplified to %s Emitted when redundant pre-python 2.5 ternary syntax is used. Refactoring consider-using-in R1714 "Consider merging these comparisons with ""in"" to %r To check if a variable is equal to one of many values,combine the values into a tuple and check if the variable is contained ""in"" it instead of checking for equality against each of the values.This is faster and less verbose." Refactoring consider-merging-isinstance R1701 "Consider merging these isinstance calls to isinstance(%s, (%s)) Used when multiple consecutive isinstance calls can be merged into one." Refactoring consider-using-max-builtin R1731 Consider using '%s' instead of unnecessary if block Using the max builtin instead of a conditional improves readability and conciseness. Refactoring consider-using-min-builtin R1730 Consider using '%s' instead of unnecessary if block Using the min builtin instead of a conditional improves readability and conciseness. Refactoring consider-using-with R1732 Consider using 'with' for resource-allocating operations Emitted if a resource-allocating assignment or call may be replaced by a 'with' block. By using 'with' the release of the allocated resources is ensured even in the case of an exception. Refactoring super-with-arguments R1725 Consider using Python 3 style super() without arguments Emitted when calling the super() builtin with the current class and instance. On Python 3 these arguments are the default and they can be omitted. Refactoring consider-using-dict-comprehension R1717 "Consider using a dictionary comprehension Emitted when we detect the creation of a dictionary using the dict() callable and a transient list. Although there is nothing syntactically wrong with this code, it is hard to read and can be simplified to a dict comprehension.Also it is faster since you don't need to create another transient list" Refactoring consider-using-generator R1728 Consider using a generator instead '%s(%s)' If your container can be large using a generator will bring better performance. Refactoring consider-using-set-comprehension R1718 "Consider using a set comprehension Although there is nothing syntactically wrong with this code, it is hard to read and can be simplified to a set comprehension.Also it is faster since you don't need to create another transient list" Refactoring consider-using-get R1715 "Consider using dict.get for getting values from a dict if a key is present or a default if not Using the builtin dict.get for getting a value from a dictionary if a key is present or a default if not, is simpler and considered more idiomatic, although sometimes a bit slower" Refactoring consider-using-join R1713 "Consider using str.join(sequence) for concatenating strings from an iterable Using str.join(sequence) is faster, uses less memory and increases readability compared to for-loop iteration." Refactoring consider-using-sys-exit R1722 "Consider using sys.exit() Instead of using exit() or quit(), consider using the sys.exit()." Refactoring consider-using-ternary R1706 Consider using ternary (%s) Used when one of known pre-python 2.5 ternary syntax is used. Refactoring consider-swap-variables R1712 "Consider using tuple unpacking for swapping variables You do not have to use a temporary variable in order to swap variables. Using ""tuple unpacking"" to directly swap variables makes the intention more clear." Refactoring trailing-comma-tuple R1707 "Disallow trailing comma tuple In Python, a tuple is actually created by the comma symbol, not by the parentheses. Unfortunately, one can actually create a tuple by misplacing a trailing comma, which can lead to potential weird bugs in your code. You should always use parentheses explicitly for creating a tuple." Refactoring stop-iteration-return R1708 "Do not raise StopIteration in generator, use return statement instead According to PEP479, the raise of StopIteration to end the loop of a generator may lead to hard to find bugs. This PEP specify that raise StopIteration has to be replaced by a simple return statement" Refactoring inconsistent-return-statements R1710 "Either all return statements in a function should return an expression, or none of them should. According to PEP8, if any return statement returns an expression, any return statements where no value is returned should explicitly state this as return None, and an explicit return statement should be present at the end of the function (if reachable)" Refactoring redefined-argument-from-local R1704 "Redefining argument with the local name %r Used when a local name is redefining an argument, which might suggest a potential error. This is taken in account only for a handful of name binding operations, such as for iteration, with statement assignment and exception handler assignment." Refactoring chained-comparison R1716 "Simplify chained comparison between the operands This message is emitted when pylint encounters boolean operation like""a < b and b < c"", suggesting instead to refactor it to ""a < b < c""" Refactoring simplifiable-if-expression R1719 The if expression can be replaced with %s Used when an if expression can be replaced with 'bool(test)'. Refactoring simplifiable-if-statement R1703 The if statement can be replaced with %s Used when an if statement can be replaced with 'bool(test)'. Refactoring too-many-nested-blocks R1702 Too many nested blocks (%s/%s) Used when a function or a method has too many nested blocks. This makes the code less understandable and maintainable. Refactoring no-else-break R1723 "Unnecessary ""%s"" after ""break"" Used in order to highlight an unnecessary block of code following an if containing a break statement. As such, it will warn when it encounters an else following a chain of ifs, all of them containing a break statement." Refactoring no-else-continue R1724 "Unnecessary ""%s"" after ""continue"" Used in order to highlight an unnecessary block of code following an if containing a continue statement. As such, it will warn when it encounters an else following a chain of ifs, all of them containing a continue statement." Refactoring no-else-raise R1720 "Unnecessary ""%s"" after ""raise"" Used in order to highlight an unnecessary block of code following an if containing a raise statement. As such, it will warn when it encounters an else following a chain of ifs, all of them containing a raise statement." Refactoring no-else-return R1705 "Unnecessary ""%s"" after ""return"" Used in order to highlight an unnecessary block of code following an if containing a return statement. As such, it will warn when it encounters an else following a chain of ifs, all of them containing a return statement." Refactoring unnecessary-comprehension R1721 "Unnecessary use of a comprehension Instead of using an identity comprehension, consider using the list, dict or set constructor. It is faster and simpler." Refactoring use-a-generator R1729 Use a generator instead '%s(%s)' Comprehension inside of 'any' or 'all' is unnecessary. A generator would be sufficient and faster. Refactoring useless-return R1711 "Useless return at end of function or method Emitted when a single ""return"" or ""return None"" statement is found at the end of function or method definition. This statement can safely be removed because Python will implicitly return None" Refactoring unneeded-not C0113 "Consider changing ""%s"" to ""%s"" Used when a boolean expression contains an unneeded negation." Refactoring consider-iterating-dictionary C0201 "Consider iterating the dictionary directly instead of calling .keys() Emitted when the keys of a dictionary are iterated through the .keys() method. It is enough to just iterate through the dictionary itself, as in ""for key in dictionary""." Refactoring consider-using-enumerate C0200 Consider using enumerate instead of iterating with range and len Emitted when code that iterates with range and len is encountered. Such code can be simplified by using the enumerate builtin. Refactoring len-as-condition C1801 "Do not use len(SEQUENCE) without comparison to determine if a sequence is empty Used when Pylint detects that len(sequence) is being used without explicit comparison inside a condition to determine if a sequence is empty. Instead of coercing the length to a boolean, either rely on the fact that empty sequences are false or compare the length against a scalar." Similarities duplicate-code R0801 Similar lines in %s files Indicates that a set of similar lines has been detected among multiple file. This usually means that the code should be refactored to avoid this duplication. Spelling invalid-characters-in-docstring C0403 Invalid characters %r in a docstring Used when a word in docstring cannot be checked by enchant. Spelling wrong-spelling-in-comment C0401 Wrong spelling of a word '%s' in a comment: Used when a word in comment is not spelled correctly. Spelling wrong-spelling-in-docstring C0402 Wrong spelling of a word '%s' in a docstring: Used when a word in docstring is not spelled correctly. Stdlib invalid-envvar-value E1507 %s does not support %s type argument Env manipulation functions support only string type arguments. See https://docs.python.org/3/library/os.html#os.getenv. Stdlib bad-open-mode W1501 "%s is not a valid mode for open. Python supports: r, w, a[, x] modes with b, +, and U (only with r) options. See https://docs.python.org/2/library/functions.html#open" Stdlib invalid-envvar-default W1508 %s default type is %s. Expected str or None. Env manipulation functions return None or str values. Supplying anything different as a default may cause bugs. See https://docs.python.org/3/library/os.html#os.getenv. Stdlib redundant-unittest-assert W1503 "Redundant use of %s with constant value %r The first argument of assertTrue and assertFalse is a condition. If a constant is passed as parameter, that condition will be always true. In this case a warning should be emitted." Stdlib shallow-copy-environ W1507 "Using copy.copy(os.environ). Use os.environ.copy() instead. os.environ is not a dict object but proxy object, so shallow copy has still effects on original object. See https://bugs.python.org/issue15373 for reference." Stdlib boolean-datetime W1502 Using datetime.time in a boolean context. Using datetime.time in a boolean context can hide subtle bugs when the time they represent matches midnight UTC. This behaviour was fixed in Python 3.5. See https://bugs.python.org/issue13936 for reference. This message can't be emitted when using Python >= 3.5. Stdlib deprecated-argument W1511 Using deprecated argument %s of method %s() The argument is marked as deprecated and will be removed in the future. Stdlib deprecated-class W1512 Using deprecated class %s of module %s The class is marked as deprecated and will be removed in the future. Stdlib deprecated-method W1505 Using deprecated method %s() The method is marked as deprecated and will be removed in a future version of Python. Consider looking for an alternative in the documentation. Stdlib subprocess-popen-preexec-fn W1509 "Using preexec_fn keyword which may be unsafe in the presence of threads The preexec_fn parameter is not safe to use in the presence of threads in your application. The child process could deadlock before exec is called. If you must use it, keep it trivial! Minimize the number of libraries you call into.https://docs.python.org/3/library/subprocess.html#popen-constructor" Stdlib subprocess-run-check W1510 Using subprocess.run without explicitly set check is not recommended. The check parameter should always be used with explicitly set check keyword to make clear what the error-handling behavior is.https://docs.python.org/3/library/subprocess.html#subprocess.run Stdlib bad-thread-instantiation W1506 "threading.Thread needs the target function The warning is emitted when a threading.Thread class is instantiated without the target function being passed. By default, the first parameter is the group param, not the target param." String bad-string-format-type E1307 Argument %r does not match format type %r Used when a type required by format string is not suitable for actual argument type String format-needs-mapping E1303 "Expected mapping for format string, not %s Used when a format string that uses named conversion specifiers is used with an argument that is not a mapping." String truncated-format-string E1301 Format string ends in middle of conversion specifier Used when a format string terminates before the end of a conversion specifier. String missing-format-string-key E1304 Missing key %r in format string dictionary Used when a format string that uses named conversion specifiers is used with a dictionary that doesn't contain all the keys required by the format string. String mixed-format-string E1302 Mixing named and unnamed conversion specifiers in format string Used when a format string contains both named (e.g. '%(foo)d') and unnamed (e.g. '%d') conversion specifiers. This is also used when a named conversion specifier contains * for the minimum field width and/or precision. String too-few-format-args E1306 Not enough arguments for format string Used when a format string that uses unnamed conversion specifiers is given too few arguments String bad-str-strip-call E1310 "Suspicious argument in %s.%s call The argument to a str.{l,r,}strip call contains a duplicate character," String too-many-format-args E1305 Too many arguments for format string Used when a format string that uses unnamed conversion specifiers is given too many arguments. String bad-format-character E1300 Unsupported format character %r (%#02x) at index %d Used when an unsupported format character is used in a format string. String anomalous-unicode-escape-in-string W1402 Anomalous Unicode escape in byte string: '%s'. String constant might be missing an r or u prefix. Used when an escape like u is encountered in a byte string where it has no effect. String anomalous-backslash-in-string W1401 Anomalous backslash in string: '%s'. String constant might be missing an r prefix. Used when a backslash is in a literal string but not as an escape. String duplicate-string-formatting-argument W1308 "Duplicate string formatting argument %r, consider passing as named argument Used when we detect that a string formatting is repeating an argument instead of using named string arguments" String format-combined-specification W1305 Format string contains both automatic field numbering and manual field specification Used when a PEP 3101 format string contains both automatic field numbering (e.g. '{}') and manual field specification (e.g. '{0}'). String bad-format-string-key W1300 "Format string dictionary key should be a string, not %s Used when a format string that uses named conversion specifiers is used with a dictionary whose keys are not all strings." String implicit-str-concat W1404 Implicit string concatenation found in %s String literals are implicitly concatenated in a literal iterable definition : maybe a comma is missing ? String bad-format-string W1302 Invalid format string Used when a PEP 3101 format string is invalid. String missing-format-attribute W1306 "Missing format attribute %r in format specifier %r Used when a PEP 3101 format string uses an attribute specifier ({0.length}), but the argument passed for formatting doesn't have that attribute." String missing-format-argument-key W1303 Missing keyword argument %r for format string Used when a PEP 3101 format string that uses named fields doesn't receive one or more required keywords. String inconsistent-quotes W1405 Quote delimiter %s is inconsistent with the rest of the file Quote delimiters are not used consistently throughout a module (with allowances made for avoiding unnecessary escaping). String unused-format-string-argument W1304 Unused format argument %r Used when a PEP 3101 format string that uses named fields is used with an argument that is not required by the format string. String unused-format-string-key W1301 Unused key %r in format string dictionary Used when a format string that uses named conversion specifiers is used with a dictionary that contains keys not required by the format string. String f-string-without-interpolation W1309 "Using an f-string that does not have any interpolated variables Used when we detect an f-string that does not use any interpolation variables, in which case it can be either a normal string or a bug in the code." String invalid-format-index W1307 "Using invalid lookup key %r in format specifier %r Used when a PEP 3101 format string uses a lookup specifier ({a[1]}), but the argument passed for formatting doesn't contain or doesn't have that key as an attribute." Typecheck unsupported-assignment-operation E1137 %r does not support item assignment Emitted when an object does not support item assignment (i.e. doesn't define setitem method). Typecheck unsupported-delete-operation E1138 %r does not support item deletion Emitted when an object does not support item deletion (i.e. doesn't define delitem method). Typecheck invalid-unary-operand-type E1130 Emitted when a unary operand is used on an object which does not support this type of operation. Typecheck unsupported-binary-operation E1131 Emitted when a binary arithmetic operation between two operands is not supported. Typecheck no-member E1101 %s %r has no %r member%s Used when a variable is accessed for an unexistent member. Typecheck not-callable E1102 %s is not callable Used when an object being called has been inferred to a non callable object. Typecheck redundant-keyword-arg E1124 "Argument %r passed by position and keyword in %s call Used when a function call would result in assigning multiple values to a function parameter, one value from a positional argument and one from a keyword argument." Typecheck assignment-from-no-return E1111 "Assigning result of a function call, where the function has no return Used when an assignment is done on a function call but the inferred function doesn't return anything." Typecheck assignment-from-none E1128 "Assigning result of a function call, where the function returns None Used when an assignment is done on a function call but the inferred function returns nothing but None." Typecheck not-context-manager E1129 Context manager '%s' doesn't implement enter and exit. Used when an instance in a with statement doesn't implement the context manager protocol(enter/exit). Typecheck unhashable-dict-key E1140 Dict key is unhashable Emitted when a dict key is not hashable (i.e. doesn't define hash method). Typecheck repeated-keyword E1132 Got multiple values for keyword argument %r in function call Emitted when a function call got multiple values for a keyword. Typecheck invalid-metaclass E1139 "Invalid metaclass %r used Emitted whenever we can detect that a class is using, as a metaclass, something which might be invalid for using as a metaclass." Typecheck missing-kwoa E1125 Missing mandatory keyword argument %r in %s call Used when a function call does not pass a mandatory keyword-only argument. Typecheck no-value-for-parameter E1120 No value for argument %s in %s call Used when a function call passes too few arguments. Typecheck not-an-iterable E1133 Non-iterable value %s is used in an iterating context Used when a non-iterable value is used in place where iterable is expected Typecheck not-a-mapping E1134 Non-mapping value %s is used in a mapping context Used when a non-mapping value is used in place where mapping is expected Typecheck invalid-sequence-index E1126 "Sequence index is not an int, slice, or instance with index Used when a sequence type is indexed with an invalid type. Valid types are ints, slices, and objects with an index method." Typecheck invalid-slice-index E1127 "Slice index is not an int, None, or instance with index Used when a slice index is not an integer, None, or an object with an index method." Typecheck too-many-function-args E1121 Too many positional arguments for %s call Used when a function call passes too many positional arguments. Typecheck unexpected-keyword-arg E1123 Unexpected keyword argument %r in %s call Used when a function call passes a keyword argument that doesn't correspond to one of the function's parameter names. Typecheck dict-iter-missing-items E1141 Unpacking a dictionary in iteration without calling .items() Emitted when trying to iterate through a dict without calling .items() Typecheck unsupported-membership-test E1135 Value '%s' doesn't support membership test Emitted when an instance in membership test expression doesn't implement membership protocol (contains/iter/getitem). Typecheck unsubscriptable-object E1136 Value '%s' is unsubscriptable Emitted when a subscripted value doesn't support subscription (i.e. doesn't define getitem method or class_getitem for a class). Typecheck keyword-arg-before-vararg W1113 "Keyword argument before variable positional arguments list in the definition of %s function When defining a keyword argument before variable positional arguments, one can end up in having multiple values passed for the aforementioned parameter in case the method is called with keyword arguments." Typecheck non-str-assignment-to-dunder-name W1115 Non-string value assigned to name Emitted when a non-string vaue is assigned to name Typecheck arguments-out-of-order W1114 Positional arguments appear to be out of order Emitted when the caller's argument names fully match the parameter names in the function signature but do not have the same order. Typecheck isinstance-second-argument-not-valid-type W1116 Second argument of isinstance is not a type Emitted when the second argument of an isinstance call is not a type. Typecheck c-extension-no-member I1101 "%s %r has no %r member%s, but source is unavailable. Consider adding this module to extension-pkg-allow-list if you want to perform analysis based on run-time introspection of living objects. Used when a variable is accessed for non-existent member of C extension. Due to unavailability of source static analysis is impossible, but it may be performed by introspecting living objects in run-time." Varialbes unpacking-non-sequence E0633 Attempting to unpack a non-sequence%s Used when something which is not a sequence is used in an unpack assignment Varialbes invalid-all-object E0604 "Invalid object %r in all, must contain only strings Used when an invalid (non-string) object occurs in all." Varialbes no-name-in-module E0611 No name %r in module %r Used when a name cannot be found in a module. Varialbes undefined-variable E0602 Undefined variable %r Used when an undefined variable is accessed. Varialbes undefined-all-variable E0603 Undefined variable name %r in all Used when an undefined variable name is referenced in all. Varialbes used-before-assignment E0601 Using variable %r before assignment Used when a local variable is accessed before its assignment. Varialbes cell-var-from-loop W0640 Cell variable %s defined in loop A variable used in a closure is defined in a loop. This will result in all closures using the same value for the closed-over variable. Varialbes global-variable-undefined W0601 "Global variable %r undefined at the module level Used when a variable is defined through the ""global"" statement but the variable is not defined in the module scope." Varialbes self-cls-assignment W0642 Invalid assignment to %s in method Invalid assignment to self or cls in instance or class method respectively. Varialbes unbalanced-tuple-unpacking W0632 "Possible unbalanced tuple unpacking with sequence%s: left side has %d label(s), right side has %d value(s) Used when there is an unbalanced tuple unpacking in assignment" Varialbes possibly-unused-variable W0641 "Possibly unused variable %r Used when a variable is defined but might not be used. The possibility comes from the fact that locals() might be used, which could consume or not the said variable" Varialbes redefined-builtin W0622 Redefining built-in %r Used when a variable or function override a built-in. Varialbes redefine-in-handler W0623 Redefining name %r from %s in exception handler Used when an exception handler assigns the exception to an existing name Varialbes redefined-outer-name W0621 Redefining name %r from outer scope (line %s) Used when a variable's name hides a name defined in the outer scope. Varialbes unused-import W0611 Unused %s Used when an imported module or variable is not used. Varialbes unused-argument W0613 Unused argument %r Used when a function or method argument is not used. Varialbes unused-wildcard-import W0614 Unused import %s from wildcard import Used when an imported module or variable is not used from a 'from X import *' style import. Varialbes unused-variable W0612 Unused variable %r Used when a variable is defined but not used. Varialbes global-variable-not-assigned W0602 "Using global for %r but no assignment is done Used when a variable is defined through the ""global"" statement but no assignment to this variable is done." Varialbes undefined-loop-variable W0631 Using possibly undefined loop variable %r Used when a loop variable (i.e. defined by a for loop or a list comprehension or a generator expression) is used outside the loop. Varialbes global-statement W0603 "Using the global statement Used when you use the ""global"" statement to update a global variable. Pylint just try to discourage this usage. That doesn't mean you cannot use it !" Varialbes global-at-module-level W0604 "Using the global statement at the module level Used when you use the ""global"" statement at the module level since it has no effect"
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【数理考古学】群論とシミュレーション原理⑤群導出演算としての「公比-1の等比数列」

【数理考古学】群論とシミュレーション原理①これまでの投稿内容のまとめ。 吃驚するほどグチャグチャになってしまったので整理を試みます。 公比-1の等比数列の演算結果集合 これもその演算結果集合が「半径1の単位円」を観測結果集合とする円周群=リー群[tex:S_0]=1次元トーラスに対応する演算の一つで、単振動(Simple Vibration System)Zn(n=−1⇌+1)or(n=0⇌2)Zn(n=−1⇌+1)or(n=0⇌2)上の任意の点で円周上の位置を指定する形となります。 {i^2=-1なので以下となる。\\-1^x=i^2x=(0 \pm 1i)^{2x}\\さらに偶数系の場合は(0 \pm 1i)^{2x}\mp(2n)\\奇数系の場合は(0±1i)^{2x}\mp(2n \pm 1)} 【数理考古学】とある実数列の規定例①等差数列から加法整数群へ ただし、かかる演算結果集合が「半径1の単位円」を観測結果集合とする円周群=リー群[tex:S_0]=1次元トーラスを説明するのはこの場合では「周回関数(Rap Function)$α^n$の冪根αが十分1に近く」かつ「周期関数(Cyclyc Function)$−1^n$の冪根βが十分-1に近い」場合に限られるのです。 \mathbb{N}_n(n=1→\infty)=(…,\sum_{k=1}^{n}1^k,…)=(1^{n_1},1^{n_1}+1^{n_2},1^{n_1}+1^{n_2}+1^{n_3},…,n_\infty)=(1×1,1×2,1×3,…,n_\infty)=(1,2,3,…,n_\infty) ただしこの結果が得られるのは「演算結果が実軸の1の位置に静止する」公比=1の場合のみ。 【数理考古学】とある実数列の規定例②等比数列から乗法群へ 0<公比<1の時…純粋な1次元展開により0へ向けて収束。 公比>1の時…純粋な1次元展開により無限大に向けて発散。 公比=-1の時…X軸上からは-1と1の間の無限往復に見える。 0>公比>-1の時…振幅の幅が0に向けて狭まっていく。 公比<-1の時…振幅の幅が無限大に向けて広がっていく。 また関数$±i^{ax}$全体は以下の様な複雑な軌跡を描く。 【Python演算処理】単位トーラスを巡る数理②トーラス群の設定 そんな感じで以下続報…
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む