We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
前回、コードの再利用性を高めるために、パッケージングを行いました。コードの再利用性を高める方法はもう一つあり、それがここで紹介する CLI (Command Line Interface) ツールとしてコードを切り出すことです。
CLIツールのゴールのイメージは、次のような fizzbuzz-cli というコマンドから、前回までに作ってきた fizzbuzz 関数の結果を取得することになります。
fizzbuzz-cli
fizzbuzz
$ fizzbuzz-cli 7 11 77 5 --fizz 7 --buzz 11 Fizz Buzz FizzBuzz 5
fizzbuzz.py に次のように main 関数を追加してみましょう。
fizzbuzz.py
main
import argparse import sys def fizzbuzz(n: int, fizz: int = 3, buzz: int = 5) -> str: ... def main(): parser = argparse.ArgumentParser(description='Fizz Buzz program.') parser.add_argument('nums', type=int, default=[], nargs='*', help="Number to be applied to FizzBuzz function. If no arguments passed, read from stdin.") parser.add_argument('--fizz', type=int, default=3, help='Number corresponds to Fizz.') parser.add_argument('--buzz', type=int, default=5, help='Number corresponds to Fizz.') args = parser.parse_args() if args.nums: # 数字の列が引数から渡された場合には、それらの数字にFizzBuzzを適用する sys.stderr.write("Reading numbers from arguments ...\n") for n in args.nums: sys.stdout.write(f"{fizzbuzz(n, fizz=args.fizz, buzz=args.buzz)}\n") else: # 数字の列が引数から渡されなかった場合には、標準入力から数字を読み込む sys.stderr.write("Reading numbers from stdin ...\n") try: line = sys.stdin.readline() while line: sys.stdout.write(f"{fizzbuzz(int(line), fizz=args.fizz, buzz=args.buzz)}\n") line = sys.stdin.readline() except KeyboardInterrupt: return
entry_points として、CLI起動時に呼び出される関数を指定します。
entry_points
$ make install を実行し、CLIツールをインストールします。その後、ターミナルを新しく開き、CLIツールを実行してみましょう。
$ make install
$ fizzbuzz-cli 7 11 77 5 --fizz 7 --buzz 11 Reading numbers from arguments ... Fizz Buzz FizzBuzz 5
ここで、 Reading numbers from arguments ... は 標準エラー、 その他の出力は 標準出力 から出力されていることに注意してください。
Reading numbers from arguments ...
$ seq 1 15 | fizzbuzz-cli Reading numbers from stdin ... 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz
最後に、PRを作りマージしましょう。
この設計では、CLIツールが標準入力から入力を受け取り、標準出力から出力を吐き出すことができる設計になっているので、他のUnixコマンドと親和性が高く、再利用性が高くなっています。例えば、 15の倍数が1から100の間にいくつあるかを数える操作は、次のように seq と grep コマンドをパイプを使って組み合わせることで実現できます。
seq
grep
seq 1 100 | fizzbuzz-cli | grep -c "FizzBuzz" Reading numbers from stdin ... 6
seq コマンドを利用することで、1から100の数字全てにFizzBuzzに適用するといった、似たような機能を自分で実装する手間が省けていることに着目してください。つまり、次のような機能は必要ありません。
$ fizzbuzz-cli --range 1 100
CLIツールを作る際には、様々な機能を付けるよりも単一機能の実装にのみに集中し、パイプを使って他のUnixコマンドと組み合わせることが容易になるよう意識しましょう。
特に、 入力を標準入力から一行ずつ受け取り、出力を標準出力から一行ずつ出力する ようにするのが一つのポイントになります。 実際、普段引数と一緒によく使っているコマンドの多くは、標準入力も受け付けることができます。
$ cat test.txt # from args test $ echo "test" | cat # from stdin test
また、標準出力からの出力を壊さないように、人間が読む出力は(今回の例では Reading numbers from stdin ... など)、標準出力ではなく標準エラーから出力するよう心がけてください。機械が読むものは標準出力、人間が読むものは標準エラー とするのが基本的な形になります。
Reading numbers from stdin ...
Unixコマンドは一つ一つはシンプルですが、組み合わせることで強力な武器となります。こんな有名な逸話があります。
テキストファイルからn個の最頻出な単語を取り出し、出現回数と共にソートした上で出力せよ。
という問題に対し、著名な計算機科学者のドナルド・クヌースが10ページに及ぶプログラムを書いたのに対し、パイプの作者 ダグラス・マキルロイ はパイプを使った非常にシンプルな解決法を提示しました(TODO: 出典):
$ cat n_freq.sh #!/bin/bash tr -cs A-Za-z '\n' | tr A-Z a-z | sort | uniq -c | sort -rn | sed ${1}q $ cat README.md | ./n_freq.sh 10 # Example: n = 10 19 python 16 fizzbuzz 13 tutorial 13 sotetsuk 13 https 13 github 13 dev 12 com 11 issues 9 fizz
The text was updated successfully, but these errors were encountered:
Successfully merging a pull request may close this issue.
前回、コードの再利用性を高めるために、パッケージングを行いました。コードの再利用性を高める方法はもう一つあり、それがここで紹介する CLI (Command Line Interface) ツールとしてコードを切り出すことです。
CLIツールのゴールのイメージは、次のような
fizzbuzz-cli
というコマンドから、前回までに作ってきたfizzbuzz
関数の結果を取得することになります。1. CLIツールからエントリーポイントとして呼ばれる関数を実装しよう
fizzbuzz.py
に次のようにmain
関数を追加してみましょう。2. CLIツールを作れるようにsetup.pyを変更しよう
entry_points
として、CLI起動時に呼び出される関数を指定します。3. インストールしてCLIツールを使ってみよう
$ make install
を実行し、CLIツールをインストールします。その後、ターミナルを新しく開き、CLIツールを実行してみましょう。ここで、
Reading numbers from arguments ...
は 標準エラー、 その他の出力は 標準出力 から出力されていることに注意してください。$ seq 1 15 | fizzbuzz-cli Reading numbers from stdin ... 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz
最後に、PRを作りマージしましょう。
4. 再利用性の高いCLIツールの設計
この設計では、CLIツールが標準入力から入力を受け取り、標準出力から出力を吐き出すことができる設計になっているので、他のUnixコマンドと親和性が高く、再利用性が高くなっています。例えば、 15の倍数が1から100の間にいくつあるかを数える操作は、次のように
seq
とgrep
コマンドをパイプを使って組み合わせることで実現できます。seq
コマンドを利用することで、1から100の数字全てにFizzBuzzに適用するといった、似たような機能を自分で実装する手間が省けていることに着目してください。つまり、次のような機能は必要ありません。CLIツールを作る際には、様々な機能を付けるよりも単一機能の実装にのみに集中し、パイプを使って他のUnixコマンドと組み合わせることが容易になるよう意識しましょう。
特に、 入力を標準入力から一行ずつ受け取り、出力を標準出力から一行ずつ出力する ようにするのが一つのポイントになります。 実際、普段引数と一緒によく使っているコマンドの多くは、標準入力も受け付けることができます。
また、標準出力からの出力を壊さないように、人間が読む出力は(今回の例では
Reading numbers from stdin ...
など)、標準出力ではなく標準エラーから出力するよう心がけてください。機械が読むものは標準出力、人間が読むものは標準エラー とするのが基本的な形になります。Unixコマンドは一つ一つはシンプルですが、組み合わせることで強力な武器となります。こんな有名な逸話があります。
という問題に対し、著名な計算機科学者のドナルド・クヌースが10ページに及ぶプログラムを書いたのに対し、パイプの作者 ダグラス・マキルロイ はパイプを使った非常にシンプルな解決法を提示しました(TODO: 出典):
目次
The text was updated successfully, but these errors were encountered: