/>
小さな工夫と発見の蓄積
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
catを使う。flush.consoleは現在の環境では必要なかったが、おまじないとして書いておく。Sys.sleep。'='*10 のような、シンプルに繰り返し文字列をつくるコマンドはないようだ。N <- 500
for (n in 1:N) {
cat(sprintf('\r[%-20s %3.0f%%]',
paste(rep('=', n/N*20), collapse=''), n/N*100))
flush.console()
Sys.sleep(.01)
}
N <- 500
for (n in 1:N) {
ch <- substring('-<>', (n %% 3) + 1, (n %% 3) + 1)
ch <- paste(rep(ch, 10), collapse='')
cat(sprintf('\r%s %3d/%3d %s', ch, n, N, ch))
flush.console()
Sys.sleep(.05)
}
Pythonでのオプション処理には、ずっとgetoptライブラリを使ってきたが、今日、argparseというライブラリの存在を知り、使ってみたところ大分使いやすかった。公式の解説がとても丁寧なのでより詳しくはそちらを参照。
ポイント
* まずはparserオブジェクトを作り、これにどんどん引数やオプションを追加していく。
* -h, --help オプションは自動に追加される(!)
* add_argument で引数・オプションを追加していく。オプションには「-」をつけて区別する。
* 値のタイプを指定できる。
* 値を取らないオプションには、action='store_true'をつけて区別する。
* 入力値は全てparse_args()のインスタント変数として得られる (下の例ではargsに格納)。
* オプションの付け方が複数通りある時は、どれか1つが変数名になる。下の例では、「args.subtract」を「args.s」に変えるとエラーになる。「-s」でも「--subtract」をオプションを指定できるが、名前は「subtract」だけになるらしい。
* 少し試した限り、長い名前があるならそのうちの1つめが選ばれ、長い名前がなければ1文字オプションの1つめが選ばれるようだ。実用的には、長い名前が優先される、と覚えればよい。
import argparse
parser = argparse.ArgumentParser(description='damn calculator')
# necessary arguments
parser.add_argument('x', type=int, help='first number')
parser.add_argument('y', type=int, help='second number')
# options with value
parser.add_argument('-t', type=int, help='how many times', default=1)
# options with no value
parser.add_argument('-s', '--subtract', action='store_true')
parser.add_argument('-m', '--multiply', action='store_true')
parser.add_argument('-d', '--divide', action='store_true')
# parse inputs
args = parser.parse_args()
# values are stored as the attributes of the args object
x = args.x
y = args.y
for _ in range(args.t):
print x + y,
if args.subtract:
print x - y,
if args.multiply:
print x * y,
if args.divide:
print float(x) / y,
print ''
$ python calc.py -h usage: calc.py [-h] [-t T] [-s] [-m] [-d] x y damn calculator positional arguments: x first number y second number optional arguments: -h, --help show this help message and exit -t T how many times -s, --subtract -m, --multiply -d, --divide $ python calc.py 3 6 9 $ python calc.py -t 3 -smd 3 7 10 -4 21 0.428571428571 10 -4 21 0.428571428571 10 -4 21 0.428571428571
printを使うと、どんどん新しい行が追加されて目障りだ。同じ行にとどまって、数字だけが変化していく出力はどうすればできるのか、不思議だったが、その方法がやっと分かった。flushをする。しないと、出力のタイミングが遅れることがある(らしい)。flushは、強制的に出力させる。トイレの水を流すのと同じflush。import sys
from time import sleep
for i in range(1, 21):
sys.stdout.write('\r[ %-20s %3.0f%% ]' % ('='*i, i*100/20))
sys.stdout.flush()
sleep(.1)
import sys
from time import sleep
for i in range(1, 51):
ch = '-<>'[i % 3]
sys.stdout.write('\r%s %3.0f%% done %s' % (ch*10, i*100/50, ch*10))
sys.stdout.flush()
sleep(.1)
printの問題らしく、sys.stdout.writeの代わりに 「print <文字列>,」と末尾にコンマをつけても同じ結果は得られるようだ。しかしそれでもflushは必要なので、sys.stdout.writeを使う方が見栄えがいい。<コード> % (arg1, arg2,...)* 引数が1つならカッコは省略可
'My name is %s' % 'cat' # just replace
'I like: %10s' % 'cat' # fill spaces
'My name is %s, %d years old ' % ('tako', 8) # multiple arg
'%d / %d = %.2f' % (1, 3, 1.0/3) # set decimal places
'%03d, %03d, %01.2f' % (1, 10, 1.5) # fill zeros
'%-15s and %10s' % ('LEFT', 'RIGHT') # flush to left