ベスパリブ

ベスパもってないです。バイク買いました。

GitHubはリポジトリのコードをスキャンしてセキュリティの脆弱性を指摘してくれるらしい

公開しているGitHubリポジトリに、ある日突然アラートが表示されました。

f:id:takeg:20190717105830p:plain
アラート

We found a potential security vulnerability in one of your dependencies.

(訳)依存関係のひとつに、セキュリティ脆弱性の可能性があるものを見つけました。

「See security alert」をクリック。

f:id:takeg:20190717110006p:plain

GitHub tracks known security vulnerabilities in some dependency manifest files. Learn more about security alerts.

(訳)GitHubは、依存関係マニフェストファイルの既知のセキュリティ脆弱性を追跡します。詳しくはセキュリティアラートについての記事を読んでね。

(2019/07/17現在)Beta版の機能かな?リンクを飛ぶとパッケージファイルのlodashのバージョンを上げるように書かれていたので、言われるがままにそうしました。私はわかっていないので(一応詳細issue読んだあとの感想)。だから信じるよギットハブのコト。もし間違ってても個人開発だし俺が困るだけでしょ。

f:id:takeg:20190717110219p:plain

「Create automated security fix」ボタンをクリックしても特に何も起きませんでしたが、トイレ行って戻ってくるとプルリクエストが作られていました。

f:id:takeg:20190717110512p:plain

プルリクをマージしました。

webpackメモ

参考

インストール

npm install -D webpack
npm install -D webpack-cli
  • バージョン指定
npm install -D webpack@4.35.0
  • package.jsonの内容でインストール

カレントディレクトリにpackage.jsonがある状態で、

npm install

ビルド

$ ./node_modules/webpack-cli/bin/cli.js --mode=development
$ ./node_modules/webpack-cli/bin/cli.js --mode=production
# productionは、出力ファイルをminifyもしてくれる(webpack.config.jsでminifyをfalseにしているとそちらが優先される)
$ ./node_modules/webpack-cli/bin/cli.js --mode=development -w

`Unhandled rejection Error: original.line and original.column are not numbers` エラーの解消

--mode=developではエラーは発生せず、--mode=productionで以下のコマンドを打つとエラーが発生した。

$ ./node_modules/webpack-cli/bin/cli.js --mode=production
Unhandled rejection Error: original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.
    at SourceMapGenerator_validateMapping [as _validateMapping] (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\webpack-sources\node_modules\source-map\lib\source-map-generator.js:276:15)
    at SourceMapGenerator_addMapping [as addMapping] (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\webpack-sources\node_modules\source-map\lib\source-map-generator.js:110:12)
    at C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\webpack-sources\node_modules\source-map\lib\source-map-generator.js:72:17
    at Array.forEach (<anonymous>)
    at BasicSourceMapConsumer.SourceMapConsumer_eachMapping [as eachMapping] (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\webpack-sources\node_modules\source-map\lib\source-map-consumer.js:157:14)
    at Function.SourceMapGenerator_fromSourceMap [as fromSourceMap] (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\webpack-sources\node_modules\source-map\lib\source-map-generator.js:48:24)
    at SourceMapSource.node (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\webpack-sources\lib\SourceMapSource.js:32:35)
    at SourceMapSource.proto.sourceAndMap (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\webpack-sources\lib\SourceAndMapMixin.js:30:18)
    at getTaskForFile (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\webpack\lib\SourceMapDevToolPlugin.js:37:30)
    at files.forEach (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\webpack\lib\SourceMapDevToolPlugin.js:136:20)
    at Array.forEach (<anonymous>)
    at compilation.hooks.afterOptimizeChunkAssets.tap (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\webpack\lib\SourceMapDevToolPlugin.js:130:12)
    at SyncHook.eval [as call] (eval at create (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\tapable\lib\HookCodeFactory.js:19:10), <anonymous>:7:1)
    at SyncHook.lazyCompileHook (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\tapable\lib\Hook.js:154:20)
    at hooks.optimizeChunkAssets.callAsync.err (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\webpack\lib\Compilation.js:1315:42)
    at _err0 (eval at create (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:11:1)
    at taskRunner.run (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\terser-webpack-plugin\dist\index.js:319:9)
    at step (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\terser-webpack-plugin\dist\TaskRunner.js:87:9)
    at _cacache.default.get.then (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\terser-webpack-plugin\dist\TaskRunner.js:111:15)
    at tryCatcher (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\util.js:16:23)
    at Promise._settlePromiseFromHandler (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\promise.js:517:31)
    at Promise._settlePromise (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\promise.js:574:18)
    at Promise._settlePromise0 (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\promise.js:619:10)
    at Promise._settlePromises (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\promise.js:699:18)
    at Promise._fulfill (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\promise.js:643:18)
    at Promise._resolveCallback (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\promise.js:437:57)
    at Promise._settlePromiseFromHandler (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\promise.js:529:17)
    at Promise._settlePromise (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\promise.js:574:18)
    at Promise._settlePromise0 (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\promise.js:619:10)
    at Promise._settlePromises (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\promise.js:699:18)
    at Promise._fulfill (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\promise.js:643:18)
    at Promise._resolveCallback (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\promise.js:437:57)
    at Promise._settlePromiseFromHandler (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\promise.js:529:17)
    at Promise._settlePromise (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\promise.js:574:18)
    at Promise._settlePromise0 (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\promise.js:619:10)
    at Promise._settlePromises (C:\Users\XXXX\workspace\MyProject\MyProject\node_modules\bluebird\js\release\promise.js:699:18)

とりあえずエラー内容でググると、似たような現象の記事を見つけられる。

ざっと見るとsource mapのエラーかな?というのが当たりがつくので、webpack.config.js 内のdevtool: "source-map",を試しにコメントアウト

module.exports = {
    mode: 'development',
    entry: './src/content.js',
    output: {
        path: __dirname + "/dst",
        filename: 'content.js',
    },
    optimization: {
        minimize: true,
    },
    //devtool: "source-map",
    module: {
        rules: [
            {
                test: /\.js$/, // .jsファイルを処理対象として指定
                exclude: /node_modules/,
                use: {  // test プロパティにマッチしたファイルに対する処理を指定
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env']
                    }
                }
            }
        ]
    }
};

するとエラーが消え無事ビルドできました。ちなみによくわかっていません。

pathlibのファイル操作いろいろ

pathlibとは

Python 3.4以上で推奨されているファイル・パス操作のモジュール。 os.path の代替となるモジュール。

docs.python.org

使い方をよく忘れるので備忘録です。

返り値はPathオブジェクトなので、文字列に変換したかったらstr()で囲んでやります。

カレントファイルの絶対パス

from pathlib import Path
this_file = Path(__file__).resolve()
print(str(this_file))
# C:\Users\XXXX\workspace\project\hoge.py

ディレクトリの取得

this_file.parents[0]
# C:\Users\XXXX\workspace\project

this_file.parents[1]
# C:\Users\XXXX\workspace\

パス結合

PROJECT_HOME = this_file.parents[0]
Path(PROJECT_HOME).joinpath("aaa", "bbb", "ccc", "ddd")
# C:\Users\XXXX\workspace\project\aaa\bbb\ccc\ddd

特定ディレクトリ下のファイルの検索

以下のようなフォルダ構成になっているとする

project  +--- aaa
               L aaa.txt
         + --- bbb
               L bbb.txt
         + --- ccc
               L ccc.txt
         + --- README.txt
folders = Path(PROJECT_HOME).glob("*")
for folder in folders:
    print(folder)
"""
WindowsPath('C:/Users/XXXX/workspace/project/aaa')
WindowsPath('C:/Users/XXXX/workspace/project/bbb')
WindowsPath('C:/Users/XXXX/workspace/project/ccc')
WindowsPath('C:/Users/XXXX/workspace/project/README.txt')
"""
folders = Path(PROJECT_HOME).glob("*")
for folder in folders:
    # フォルダでないならスキップ
    if not folder.is_dir():
        continue
    print(folder)
"""
WindowsPath('C:/Users/XXXX/workspace/project/aaa')
WindowsPath('C:/Users/XXXX/workspace/project/bbb')
WindowsPath('C:/Users/XXXX/workspace/project/ccc')
"""

特定ディレクトリ下のファイルの再帰的な検索

files = Path(PROJECT_HOME).rglob("*.txt")
for f in files:
    print(f)
"""
WindowsPath('C:/Users/XXXX/workspace/project/aaa/aaa.txt')
WindowsPath('C:/Users/XXXX/workspace/project/bbb/bbb.txt')
WindowsPath('C:/Users/XXXX/workspace/project/ccc/ccc.txt')
WindowsPath('C:/Users/XXXX/workspace/project/README.txt')
"""

ファイルの削除

files = Path(PROJECT_HOME).rglob("*.txt")
for f in files:
    f.unlink()

フォルダの削除

空のフォルダじゃないと削除できないので、まずはフォルダ内のファイルを再帰的に削除する必要がある。

for folder in folders:
    # フォルダでないならスキップ
    if not folder.is_dir():
        continue

    # フォルダ内のファイルを再帰的に削除する
    files = Path(folder).rglob("*")
    for f in files:
        f.unlink()
        
    # 最後に、フォルダを削除する
    folder.rmdir()

VSCode用スニペットに変換するジェネレータサイト

日本語で検索しても見つからなかった方へ。

お探しのサイトは、以下のサイトです。

snippet-generator.app

AtomSublime Textのスニペットにも変換できます。

Pythonでダイクストラ法

ダイクストラ法とは

ダイクストラ法とは、「重み付きグラフにおける単一始点最短路アルゴリズム

つまり、「始点s から各頂点i までの最短コストを求める」アルゴリズム

使用条件は以下の通り。

  • 負のコストがないこと
  • 有向グラフ、無向グラフともにOK

ベルマンフォード法より高速なので、負のコストがないならばこちらを使うと良い。

ダイクストラ法の処理の流れは以下のサイトが詳しいです。

algorithmalgorithm

実装と使い方

蟻本に書いてあるとおりのプライオリティキューを使った実装です。

辺の数をE、頂点の数をVとすると、計算量は O( E \log(V) )

参考URL

Pythonの辞書(dict)のgetメソッドの速度を調べてみた

辞書(dict)でキーの存在確認をする際の方法としては、

  • in演算子を使いif文で条件分岐する
  • get()メソッドを使う
  • try exceptを使う(そんな人いるか?)

の3種類くらいだと思います。

その中でもget()メソッドはワンライナーで書けて便利なのですが、速度的にはどうなのだろうと気になったのでそれぞれ速度を比較してみました。

プログラム

gist.github.com

結果

  • in_operator1は、in演算子を使い、必ずアクセス成功する処理
  • in_operator2は、in演算子を使い、必ずKeyErrorする処理
  • try_except1は、try exceptを使い、必ずアクセス成功する処理
  • try_except2は、try exceptを使い、必ずKeyErrorする処理
  • get_method1は、get()メソッドを使い、必ずアクセス成功する処理
  • get_method2は、get()メソッドを使い、必ずKeyErrorする処理

時間は小数点第4位まで(5位以下切り捨て)

最速 /最遅

in_operator1 in_operator2 try_except1 try_except2 get_method1 get_method2
N=105 0.0079 0.0039 0.0049 0.0159 0.0109 0.0079
N=106 0.0678 0.0339 0.0458 0.1586 0.1019 0.0799
N= 107 0.6907 0.5215 0.4607 1.8228 1.0414 0.9741
N=108 8.0925 3.4299 4.6398 16.1180 10.2179 8.0003

考察

  • try exceptのexcept処理は遅い
  • get()メソッドは早くない
  • 速度を求めるならin演算子でif文が良い

参考URL

Python dict型でgetメソッドを使おう。(KeyError対策) | DevelopersIO