VSCode: 突然 Python の構文チェックエラーが増えた時は

VSCode の Python 構文チェックで、ある時から急に見慣れないメッセージが増えたら、それは Pylint のオプション設定が原因かもしれない。

対象

  • Python の構文チェックに Pylint を使っている (VSCode のデフォルト)
  • 構文チェックで、以前は出なかった問題(警告, ヒント)が表示される
  • Pylint のオプションを設定したことがある

原因

VSCode では、pylintrc ファイルまたは設定 UI から Python › Linting: Pylint Args で Pylint 実行時のオプションを指定できる。これらは特定の警告を無効化したいときに便利だ。
しかしながら Pylint のオプションを指定すると、デフォルトで有効な Pylint Use Minimal Checkers が強制的に無効化されてしまう。

この挙動は、双方のオプション同士の衝突を避けるためだと思われるが、なかなか不便だ。それならその可能性を指摘してくれるだけでいいのに…という感じがしないでもない。

対処法

Pylint Use Minimal Checkers の環境を取り戻すには、自動設定されていた Pylint のオプションを手動で設定(Ctrl+,)の Pylint Args (または pylintrc ファイル) に追加する。

追加するオプションは、下記の通り。

  • --disable=all
  • --enable=F,E,unreachable,duplicate-key,unnecessary-semicolon,global-variable-not-assigned,unused-variable,binary-op-exception,bad-format-string,anomalous-backslash-in-string,bad-open-mode

なお、これらのオプションの具体的な意味は、VSCode 公式サイトに記載されている。

都道府県名と地方名の正規表現

大まかな判定をする為の、47都道府県と地方名などの正規表現です。

Python 3 での利用を想定していますが、その他の言語などでも、マルチバイト文字に対応している正規表現ライブラリであれば利用可能です (たぶん)。

長所

  • 「県」や「地方」が付かなくても判定可能。

短所

  • 「中国」や「大分」など、他と判別不能な表現がいくつか有る。
  • 「県」や「地方」を付ける場合と比べて、誤検出が増える。

用途

多数の文字列から、都道府県名や地方名が含まれている可能性がある部分を大まかに抽出するときなど。
まあまあ使えますが、短所で挙げたような語句を多く含む文字列の場合は、ほとんど役に立たないかも。😅

Anacondaのインストール

Anaconda で Python の実行環境を作った際のメモです。

Anacondaとは

Pythonの人気ディストリビューションのひとつ。
Windows, macOS, Linux に対応。

2018年現在の Windows では、公式パッケージよりも Anacondaをインストールするほうが良いようだ。

また、Pythonと一緒に便利な関連ツールもインストールできる。

  • Jupyter Notebook
  • JupyterLab
  • Qt Console
  • Spyder
  • Visual Studio Code (VSCode)

これらはインストール後にランチャーから削除もできるので、とりあえず入れて使ってみるのがオススメ。

anaconda_navigator_ss.png
ランチャーの "Anaconda Navigator"

インストール

Anaconda (Python 3 の 64bit版)を公式サイトからダウンロード。
Miniconda という、最小構成のパッケージもある。ライブラリを自分で入れるならこちらがお薦め。

何れも日本語化はされていないが、英語力はそれほど必要ない。
インストールオプションはデフォルトでも大丈夫。インストール先と、環境変数のパス追加はお好みで変更。インストール時間は15分前後かかる。

Anaconda のインストール後に、続けて VSCode の同時インストールができる。こちらは日本語化済み。

使い方

関連ツールやパッケージ管理のランチャーとして Anaconda Navigator が付属している。初回はこれを使うと機能が解りやすい。
ただ、Navigator の起動はまあまあ重いので、Anaconda Prompt などのコマンドラインから Jupyter Notebook や conda を呼び出すほうが便利かもしれない。

VSCode はもちろん、単独で起動できる。

Python 2.7のインストール

Anaconda では他のバージョンの Python も追加インストールして、いつでも切り替えて利用できる。この機能は一般に仮想環境と呼ばれる。

インストールは Anaconda Prompt を起動して、conda createコマンドで行う。

> conda create -n py27 python=2.7 anaconda

コマンドの最後にanacondaを付けると、各種追加パッケージも一緒にインストールされる。この場合は結構時間がかかるので、調べ物でもしながら気長に待とう。

完了すると py27 という別環境が構築されるので、この名前を指定して切り替える。
すぐに切り替わるので、続けてバージョンを確認。

(base) C:\> activate py27
(py27) C:\> python --version
Python 2.7.14 :: Anaconda, Inc.

deactivateで元の環境(Python 3)に戻る。

> deactivate

conda

conda は Python のパッケージマネージャ。pip に類似したコマンドを持つ。
Pythonの別バージョンの共存インストールもできる(上記参照)。

パッケージのインストールはconda installで行う。

> conda install パッケージ名

conda でパッケージを探して無ければ pip も使える。
但し、conda と pip にはパッケージのフォーマットに互換性がないので、併用する際には双方で管理するパッケージ群が重複しないように注意が必要なようだ。conda には無いパッケージも結構あるので、このあたりが Anaconda の弱点かも。

パッケージ追加エラーの謎

僕の開発環境(Windows 10, 64bit)では、コマンドラインからパッケージを追加すると、毎回赤文字でずらっとエラーが出る。しかしインストールは成功しているようで、再度追加しようとすると今度はインストール済みと表示される。また、モジュールは import して問題なく使える。

インストール時に Windows の管理者権限を付与してもしなくても同じなので、それが原因でもないようだし、良くわからない(´・ω・`)?

PHP7 タイムゾーン設定で日時のズレを修正

XAMPPでPHPを7.1.9に入れ替えたら、どうやらタイムゾーンが変なようでdate()の日時がズレてしまう。
php.iniを確認してみると、

[Date]
date.timezone=Europe/Berlin

ベルリンになってた。なぜベルリン。というわけで修正。

[Date]
date.timezone=Asia/Tokyo

なおdate.timezoneを省略するとUTC扱いになる。省略してもPHP7はWarningが出ない。

<?php
date_default_timezone_set('Asia/Tokyo');

このように実行時に関数でタイムゾーンを設定することもできる。

参考

PHPで文の中間を省略して一定の幅に収める

「文の中間を省略して一定の幅に収める」処理は需要がありそうですが、検索してみた限りでは見つからなかったので作ってみました。

PHPには、文字列が一定の長さ(幅)を超えたら丸める関数 mb_strimwidth()が標準で有ります。しかし、この関数だけでは文字列の中間を省略する事はできませんので、この関数を応用して、一定の幅を超えたら指定位置の文字列を省略する関数にしました。少し長いですが、ソースコードは下記の通りです。

<?php
// 文字列の途中を省略して最大幅以内にする
// string $str        = 対象文字列
// int    $maxWidth   = 最大幅 (mb_strwidth準拠)
// int    $cutPos     = 省略位置。正の値は先頭から(0が先頭)、負の値は末尾からの幅。Falseで中央。
// string $trimMarker = 省略記号にする文字列
// @return string
function sMidTrim ($str, $maxWidth, $cutPos = False, $trimMarker = '..') {

    // 文字列の幅を取得
    $strWidth = mb_strwidth($str);
    if($strWidth <= $maxWidth) { return $str; }

    // マーカーの幅を取得
    $tmWidth = mb_strwidth($trimMarker);
    if($tmWidth + 2 > $maxWidth) { return $str; }

    // カットすべき幅を算出
    $cutoffWidth = $tmWidth + $strWidth - $maxWidth;

    // カットの始点(幅)を算出
    $remain = $strWidth - $cutoffWidth;
    if(!is_int($cutPos)) {
        // 無指定時は中央
        $cutBeginWidth = ceil( $remain / 2 );
    }
    elseif($cutPos >= 0) {
        // 正の値
        if($cutPos > $remain) { $cutPos = $remain; }
        $cutBeginWidth = $cutPos;
    }
    else {
        // 負の値
        $cutBeginWidth = $remain + $cutPos;
        if(0 > $cutBeginWidth) { $cutBeginWidth = 0; }
    }

    // 先頭文字列を切り出す
    $headStr = mb_strimwidth($str, 0, $cutBeginWidth);

    // 末尾文字列を切り出す
    $pos = mb_strlen( mb_strimwidth($str, 0, $cutBeginWidth + $cutoffWidth) );
    $tailStr = mb_substr($str, $pos);

    return $headStr.$trimMarker.$tailStr;
}

解説

出来る限りソースコードのみで解るように書いたつもりですが、いくつか補足します。

引数のうち、第2及び第3引数は「幅」単位で指定するようになっています。 これはmb_strimwidth()で使われる幅と同じものです。

第3引数で指定された位置に省略記号(第4引数で指定可)が挿入されます。 なお、末尾に省略記号を付ける動作はmb_strimwidth()で可能ですので省きました。

第1引数で渡された文字列が第2引数の幅に満たない場合は、何も処理を行わず文字列をそのまま返します。 省略記号が付加されるのは、省略しないと指定された幅に収まらない場合のみです。

関連記事 PHPのmb_strimwidthが意図通り動かない問題

利用時の注意

PHP5.6で動作確認しました。PHP5以降であれば恐らく動くと思います。

マルチバイト文字列関数(mb_*)を呼び出していますので、実際の挙動はそれらの関数に依存します。 予めmb_internal_encoding()で適切な内部文字エンコーディングを設定してからご利用ください。

コードは非商用に限り、そのままご利用頂いても構いません。
適切に動作するよう心がけましたが、不具合があるかもしれません。無保証ですのでその点はご了承願います。利用やバグ等の報告は頂ければ嬉しいです。