2017年4月15日土曜日

Dell Latitude10の最近の調子

もうすぐWindows10のCreaters Updateがくるかもしれないと思いつつ、 Latitude10はWindows10 Version 1607で使用中です。

 先日、1607用の更新プログラムKB15217が2回ほど失敗し、 3回目にしてようやくインストールされました。 ところが、再起動されないで止まってしまうということに。

電源ケーブルはつないだ状態で使っていましたが、電源ボタンを押しても、反応がありません。

電源ケーブルをはずして、電源ボタンを押すとやっと反応して、ボタン脇のLEDが一瞬点灯します。しかし、起動しません。

バッテリーを外して、少し放置してから再度バッテリーを取り付け試みましたが、LEDが一瞬点灯するだけなのは変わらず。

とうとうハードウェア故障かと覚悟しましたが、突然壊れるものなのかと、あきらめきれず。 電源ケーブルをつないで、一日放置して再度試したところなぜか無事に起動され、 KB15217インストールの再起動後のプロセスが実行され無事に成功しました。

 またしばらく使用して、電源を切り、翌日電源ボタンをいれたところ同じような症状で起動しません。 しかし、今回は電源ケーブルをはずし、数回電源ボタンを押し、LEDが一瞬点灯するのを繰り返し、 また10秒ほどまって再び押したところ起動しました。

電源ボタンの接触の問題なのかと思いますが、LEDは的確に反応しますので、別の原因でしょう。 シャットダウンして、LEDランプが消灯しますが、じつは内部ではなにかがずっと動いているのでしょうか。 ということで、考えられるのはWindowsの高速スタートアップの設定です。 コントロールパネルから電源ボタンの動作設定を見てみると、チェックがはいっています。 はずしてつかっていたつもりでしたが、現状はチェックが入った状態。

とりあえず、高速スタートアップを無効にして、シャットダウンしてみました。 LEDが消灯してから、電源ボタンを押してみると、無事に起動します。 二回ほど試したところで、これを書いていますが、無事に起動しています。

 これが原因か、まだはっきりとはしませんが、覚書として残しておきます。

追加
残念ながら、夜にまた起動できない状態に。LEDランプが一瞬点灯するけど、起動しない。
電源ケーブルをはずして、しばらく経過すると起動に成功しました。
シャットダウンしたあと、電源ケーブルを差しておいたのですが、そういえばアップデートをかけて、電源ケーブルを差して翌朝起動しないということが多い。
電源ケーブルをはずして、しばらく経過したのち電源が入ります。
なにかバッテリー関係の保護が働いているのでしょうか。
今度は、シャットダウンして電源ケーブル接続せずに放置して、どうなるか様子を見ます。





2017年4月1日土曜日

pythonでimport Imageしたらエラーが出た

先日のこと、python 2.7にて、
import Image
Image.open('figure.png')
としたところ、
"cannot identify image file"
と、これまで使えていたスクリプトにもかかわらずエラーが生じました。 'figure.png'が破損でもしたのかと思ったのですが、 ビューアで開くと画像ファイルに問題はありませんでした。

そういえば、最近、reportLabをインストールしたところで、 PIL(Python Imaging Library)としてPillow 4.0.0がインストールされました。 そこで、site-packagesにあるPIL/Image.pyを覗いてみたところ、問題は、 イメージの種類に対応するPluginが正常に登録されていないことでした。

Image.open()を呼び出すと、そこでpreinit()が呼ばれ、 BmpImagePluginやPngImagePluginといった画像の種類に対応したモジュールがimportされます。 それぞれのPluginモジュールは、 Imageモジュール内のregister_open()等の関数を用いて、 Imageモジュールの*トップレベルに作成されたリストや辞書*にID等を登録していきます。

構造としては、ImageモジュールでPluginモジュールをimportして、 Pluginモジュールで、Image.register_open()を呼び出しているわけです。 さて、問題の箇所は、 Imageモジュールの*トップレベルに作成されたリストや辞書*は、 Imageモジュールから見るとglobal変数なのですが、 Pluginモジュールから見るとImageモジュールの変数であり、別物ということです。

以下、確認のためシンプルなスクリプトを4つ用意しました。

#-- module_main.py --
GLOBAL_V =[]
def register(x):
    #global GLOBAL_V
    GLOBAL_V.append(x)

def importer():
    import plugin_100
    import plugin_200

if __name__ == '__main__':
    importer()
    print GLOBAL_V
#-- plugin_100.py --
import module_main
module_main.register(100)
#-- plugin_200.py --
import module_main
module_main.register(200)
#-- using_module.py --
import module_main
module_main.importer()
print module_main.GLOBAL_V

module_mainにあるregister()を呼び出して、 module_mainにあるGLOBAL_Vに値を追加していくものです。

module_main.pyを直接実行してみます。

>python module_main.py
[]

module_main.pyを実行しても、GLOBAL_Vの値は変更されていません。 register()の中にあるglobal GLOBAL_Vがコメントアウトされてているからではありません。 コメントアウトを外して確認できるように、記述しました。

module_mainをimportして利用するusing_module.pyを実行してみます。

>python using_module.py
[100, 200]

と、設定されました。 このGLOBAL_Vは、グローバル変数を意図して作成されたものではなく、 モジュール変数を意図して作成されたもののようです。 (だからregister()内に、global GLOBAL_Vがないのですね)

ということで、Import Imageとすると、Image内で参照されているグローバル変数と、 PluginからImage.open_register()の呼び出しで変更される変数が別物(Imageのモジュール変数) になってしまうということでした。

from PIL import Image
Image.open('figure.png')
とすることで、問題は解決しました。 import Imageでエラーが出なかったため、 はまってしまったのでリマインダとして残しておきます。 (エラーがでなかったのは、以前のPILのPIL.pthが残っていたためです。) PILのimport Imageというimportの方法は、 廃止されるようですね。 問題が分かって検索してみると、 同じようなことが。