Windowsのエラーコード

スクリプトを書いていると、処理が失敗したりした場合のエラーコードをどうするか悩むことが多い。

例えば、最近はWindowsPythonスクリプトを書いているけど、Pythonでは以下のようにエラーコードを設定できる。

import sys

sys.exit(0)

正常終了は0でいいのだけれど、それ以外の場合。

で、ちょっと調べてみた。

Windowsでは以下のようにエラーコードが定義されているらしい。

Win32エラーコード一覧

System Error Codes (Windows)

膨大すぎて、ちゃんとやろうとすると大変だ…。

Pythonスクリプトを書くときに頻繁に調べるものをまとめた

たまにしかPythonは書かないので、ちょっとしたスクリプト書くときに毎回ググっているので備忘のためメモする。 ちなみにWindows環境でPython2.7。

Pythonスクリプトの雛形

こんな感じのものをよく書くのでまとめておく。それぞれの解説は後述する。

# coding: utf-8

import argparse
import codecs

def my_method(input_file):
    # ファイルをUTF-8で開いて1行ずつ読み込み
    with codecs.open(input_file, 'r', 'utf-8') as file:
        for line in file:
            print line,


if __name__ == '__main__':
    # parserの初期化
    parser = argparse.ArgumentParser(description='Description for this script.')
    # 位置引数を追加(必須パラメータとなる)
    parser.add_argument('input')
    # オプショナル引数を追加(値なしで、指定されていたらTrueとなる)
    parser.add_argument('-bar', action="store_true")
    
    args = parser.parse_args()
    
    my_method(args.input)

ファイルの文字コード指定

ファイルの1行目に以下を書いておく。

# coding: utf-8

よくあるのは以下だけど、これはEmacs等にPythonコードであることを認識してもらうためなので、別にどちらでもいいと思う。

# -*- coding: utf-8 -*-

実際は以下にマッチすれば何でも良いらしい。

"coding[:=]\s*([-\w.]+)"

参考:

文字コードの指定 - 日本語と文字コード - Python入門

Pythonのエンコードを宣言する

コマンドライン引数を受け取る

単純な方法

テキストファイル等、入力ファイルを引数で指定したいことはよくある。 単純に取得するだけなら以下でいい。

import sys

sys.argv[0] # 実行しているPythonスクリプトファイル名
sys.argv[1] # 引数1
sys.argv[2] # 引数2

やや高度な方法

必須引数や引数の型を指定したり、ちょっとリッチなことをしたいならPython2.7からの標準モジュールargparseを使う。

一度わかってしまえばこっちをargparseを使うほうが良い。

引数には位置引数(Positional Arguments)とオプショナル引数(Optional Arguments)がある。

位置引数は単純に順番に引数として渡す方法で、オプショナル引数は-rなどの後に引数を指定する。

# coding: utf-8

import argparse

# parserの初期化(これだけで--helpなどが使えるようになる)
parser = argparse.ArgumentParser(description=u'ここに説明を書きます')

# 位置引数を追加(必須パラメータとなる)
parser.add_argument('bar')

# オプショナル引数を追加
parser.add_argument('-f', '--foo')

# オプショナル引数を追加(必須パラメータ)
parser.add_argument('-r', required = True)

# オプショナル引数を追加(値なしで、指定されていたらTrueとなる)
parser.add_argument('-t', action="store_true")

# version情報を追加
parser.add_argument('--version', action='version', version='%(prog)s 2.0')

# ここでコマンドラインの引数を実際に解釈する
args = parser.parse_args()

# 引数へのアクセス
print args.bar
print args.foo
print args.r
print args.t

参考:

Python コマンド引数 - @//メモ

[Python] argparseモジュールを使って、コマンドライン引数を本格的に扱う - YoheiM .NET

Pythonでコマンドラインツールを作る方法 - MyEnigma

printの書式

C言語で言うところのprintf()に相当。%sに後半で指定した変数を順番に埋め込む。

print 'something: %s %s' % (foo, bar)

%sは文字列、%dは整数、%eは浮動小数点数

ただし、これは昔からあるやり方で、非推奨らしい。

format()関数を使うほうがよりモダン。

print 'something: {} {}'.format(foo, bar)

# 順番を明示的に指定もできる
print 'something: {0} {1}'.format(foo, bar)

参考:

[python]文字列置換(フォーマット)まとめ(format関数, %dなど) - dackdive's blog

改行なしでprint

2通りある。

以下が簡単。print文の最後に「,」をつけるだけ。ただし、末尾に半角スペースが挿入されるので注意。

print 'something',

ちょっと長くなるけどこちらは半角スペースも挿入されない方法。ただし、こちらは文字列しか指定できないので、文字列以外を指定する場合はstr()を使うと良い。

import sys
sys.stdout.write(string)

# 多用する場合は以下のようにするとちょっと短くできる
write = sys.stdout.write
write(string)

paizaのスキルチェックなんかで、厳密に出力をチェックされる場合はこちらを使う。

参考:

Python Tips:改行なしで文字列を出力したい - Life with Python

テキストファイルを1行ずつ処理

日本語を扱う際は、必ず文字コードを指定してファイルオープンする。 基本的にはUTF-8が統一したほうがよさげ。(日本語版Windowsを使っている限りShift_JISからは逃れられないけど…)

import sys
import codecs

# 引数で入力ファイル、出力ファイルを受け取る
input_file = sys.argv[1]
output_file = sys.argv[2]

# ファイルをUTF-8で開いて1行ずつ読み込み
with codecs.open(input_file, 'r', 'utf-8') as file:
    for line in file:
        print line,

# ファイルをUTF-8で開いて書き込み
with codecs.open(output_file, 'w', 'utf-8') as file:
    file.write('something\n')

# Shift_JISの場合は 'utf-8' を 'shift_jis' にする
# 'a'は追記モード。ファイルが存在しない場合は新規作成される。

withブロックを使うとcloseする必要がないので、この書き方がモダンらしい。

参考:

http://python.civic-apps.com/file-io/

Python でUTF-8, shift_jis, euc_jpなど日本語を使う方法

ファイル中に日本語を含める場合

Python2は日本語の扱いが非常に微妙なので、適当にやっているといつか必ず悩む。

Python2では、以下の2つの文字列が存在するが、基本的にはunicode文字列を使うべき。

  • str文字列(バイト列)
  • unicode文字列

参考:

Python2のstr/unicodeとencode/decode - Qiita

UnicodeDecodeError/UnicodeEncodeErrorに悩まないPython 2.x プログラミング - atsuoishimoto's diary

時刻・日付の扱い

datetimeモジュールを使う。

datetimeは冗長になりがちなので、以下のようにしてdtとしてimportすることが多い。

from datetime import datetime as dt

文字列から日付

d = '2017-06-24 12:34:06'
print dt.strptime(d, '%Y-%m-%d %H:%M:%S')

日付から文字列

now = dt.now()
print now.strftime('%Y-%m-%d %H:%M:%S')

曜日

weekdayメソッドは、0を基準とした数値で曜日を表現する。月曜日は1になり、火曜日は2、…、日曜日は6となる。なので、曜日を文字列として出力したければ以下のようなリストを用意してやる。

youbi_ja = [u'月', u'火', u'水', u'木', u'金', u'土', u'日']
youbi_en = [u'Mon', u'Tue', u'Wed', u'Thu', u'Fri', u'Sat', u'Sun']

now = dt.now()

print youbi_ja[now.weekday()] # => '土'
print youbi_en[now.weekday()] # => 'Sat'

参考:

Pythonで文字列 <-> 日付(date, datetime) の変換 - Qiita

8.1. datetime — 基本的な日付型および時間型 — Python 2.7.13 ドキュメント

Pythonコード研究所 曜日を取得する

文字列操作

改行を除去する

strip()で文字列前後の改行、空白を除去してくれる

string.strip()

置換

単純な置換。

src = 'something'
dst = src.replace(u'置換対象の文字列', u'置換後の文字列')

正規表現による置換。

import re
dst = re.sub(r'aaa.+', 'bbb', src)

r'‘はRaw文字列。’\n'などが特殊文字として扱われなくなる。正規表現でよく使われる。

参考:

Pythonでの文字列置換をマスターする - orangain flavor

Python の raw 文字列を用いて正規表現を書く - Pyxis 開発ブログ

ファイル・ディレクトリの存在確認

import os

path = './path/to/something'

# ファイルまたはディレクトリの存在確認
os.path.exists(path)

# ファイルの存在確認
os.path.isfile(path)

# ディレクトリの存在確認
os.path.isdir(path)

参考:

pythonでファイルの存在を確認する - Qiita

ロギング

ロギングについては勉強中なのでこれから以下を参考に書く。

参考:

ログ出力のための print と import logging はやめてほしい - Qiita

Gmailでメール送信

Gmailで簡単にメール送信 | Make.

ここにあるコードを使わせてもらうとすごく楽。

  1. 上記のコードをgmail.pyと名前を付けて保存し、スクリプトと同じフォルダに置く
  2. スクリプトでimport gmail
  3. Gmailでアプリパスワードを発行する(二段階認証を設定している場合)
  4. gmail.pyのL19, 20のコメントアウトを解除し、それぞれ自分のメールアドレス、3.で発行したパスワードに書き換える
  5. 後はgmail.pyのメイン関数を参考に、gmail.create_message()、gmail.send()する

if __name__ == ‘__main__’:

Pythonスクリプトに頻出の、以下の記法。

if __name__ == '__main__':

これは、そのスクリプト自体を実行したときに実行される内容。どういうことかというと、Pythonスクリプトは他のPythonスクリプトからimportされる場合もあるからだ。その場合はこのブロックは呼ばれないということ。

スクリプト単体で書く場合には必要ないけれど、個人的にはこれがあるほうがぐっとPythonっぽい気がする。

Pythonにおけるシングルクォートとダブルクォートの違い

ない。他の言語ではたいてい意味が異なるが、Pythonの場合はまったくない。

個人的には全部どっちかに統一されていれば良いと思っている。違いがないもので悩むのは時間がもったいないかと。

と言いつつ結構悩んだりしてるんだけど…。

参考:

シングルクォートとダブルクォートの使い分け - YAMAGUCHI::weblog

Windows10 で Electron をさわってみた

Electron は Web の技術でクロスプラットフォームなデスクトップアプリを開発できる環境。 HTML5 + CSS + JavaScript で、まるっきり Web サイトを作るのと変わらない。

導入は超簡単だった。

まず node.js をインストール。

Download | Node.js

その後コマンドプロンプトで以下のコマンドを叩くだけ。

npm -g install electron-prebuilt

びっくりするくらい簡単。

あとはここにあるようなファイルを用意して実行したらなんのトラブルもなく動いた。

ics.media

おお、これはいい!

…と思ったけど、パッケージングしてみると、フォルダ全体のサイズが124MB…!

これはかなり厳しい…。

クロスプラットフォームではないとはいえ、C# .NET アプリだったらこの程度のアプリ1MBもいかないし…。

Windows10 で Visual Studio 2015 + Qt 5.6 環境を構築した

Windows10 で Visual Studio 2015 + Qt 5.6.1 環境を構築したメモ。

以下から Visual Studio Community を入手してインストール。

ダウンロード | Visual Studio

インストールファイル(vs_community_JPN.exe)に特に2015とかもなく、最新版がインストールされるようになっているようだ。

続いて、Qt をインストール。

Qt - Download Open Source Step 3

f:id:posnum:20160705214710p:plain

Qt 5.6.1-1 for Windows 64-bit (VS 2015, 832 MB) をダウンロードしてインストール。(サイズが大きいので注意) そして、最新版をインストールしたつもりだったけど、5.7.0 があることに今気づいた…。

Visual Studio を起動して、(最初でサインインを求められるのでサインインした。しなくてもいいはず。) Qtアドインをインストールする。

ツール -> 拡張機能と更新プログラム で qt を検索。 Qt5Package がヒットするのでインストール。

Visual Studio の再起動を求められるので再起動。 再起動すると、メニューに QT5 が増えている。

この時点で、新規プロジェクトに Qt Application が増えているが、 作成しようとするとエラーが発生する。

Unable to find a Qt build! To solve this problem specify a Qt build

f:id:posnum:20160705215437p:plain

これはパスが通っていないため怒られている。

メニューの QT5 -> Qt Options

f:id:posnum:20160705215518p:plain

Add

f:id:posnum:20160705215619p:plain

Version name: 5.6.1

Path: C:\Qt\Qt5.6.1\5.6\msvc2015_64

注意点としては、binフォルダまでパスに含めるとOKが押せない。

これで、Visual Studio 2015 で Qt Application プロジェクトを作成してビルドできるようになった。

Python の勉強を始めた

久々に新しいプログラミング言語を習得しようと思い立った。

以前から Python に興味はあったが、勉強するほどではなかった。きっかけは仕事で Python のコードを読む機会があったからだ。

本はどれを買おうか、と思ったがやはりそこは安定のオライリー。「入門 Python 3」が出て4ヶ月程度しか経ってなかったのでちょうど良いと思った。(初版が2015年12月1日)

非常に読みやすく、他のプログラミング言語経験者であればサクサク進める。経験者にとっては若干くどい説明があるくらいなので、プログラミング初心者でもいけるのかな?

プログラミング言語は書いて覚えるのが一番なので、何か作りたいなぁと思った。

そこで、以下の本を購入。

「入門 Python 3」の半分程度の厚さ。まだちゃんと読んではいないが、立ち読みの印象ではかなり良さ気。Python だけじゃなく、Web を扱う上での基礎が身につきそう。

やはり新しいプログラミング言語を学ぶのは楽しい。

ListBox(ComboBox)で内部の値とは別に表示する値を自由自在に変更する Part2

以前、こんなエントリを書いた。

ListBoxで内部の値とは別に表示する値を自由自在に変更する - posnum’s blog

もっと良い方法を見つけたのでメモ。

続きを読む