算術を実行するPythonでのコマンドラインアプリケーションの開発



コマンドライン上の算術

導入
番号を追加することは、コマンドラインでそれを行うことは別のことです.Clirithmetic CLIをフロントエンドとPythonと組み合わせて、加算、減算、除算、乗算、モジュロ、指数などのバイナリ演算を行うためにバックエンドを書きます.我々は、我々のコードを管理して、維持するのを簡単にするために、フロントエンドからバックエンドを切り離します.

内容

裏側
バックエンドはフロントエンドとして実装するのがとても簡単です.Pythonのいくつかの知識で、これは読みやすく理解されるでしょう.ファイルを作成するbackend.py 我々のバックエンドコードのために.関数を使うと簡単です.拡大したいClirithmetic 私たちはクラスをよりよく使う.
# backend.py
class Backend:

    def __init__(self, params):
        self.operator, self.operand1, self.operand2 = params
上のコードでは、私たちのクラスですbackend.py ファイル名Backend 演算子と2つのオペランドで構成されるリストを受け取るコンストラクターで.
# backend.py
class Backend:

    ...

    def add(self):
        return self.operand1 + self.operand2

    def mult(self):
        return self.operand1 * self.operand2

    def subt(self):
        return self.operand1 - self.operand2

    def div(self):
        return self.operand1 / self.operand2

    def mod(self):
        return self.operand1 % self.operand2

    def exp(self):
        return self.operand1 ** self.operand2
上記のコードは、算術演算を実行するためのメソッド(クラスのための機能性)を定義します.これらの関数は簡単に読み、理解できますが、どんな問題になっているのでしょうか.
それで、どのように我々はどのようなメソッドを呼び出すには、手術に基づいて知っているつもりですか?別の方法を作りましょうevalBackend これは、演算子に基づいて呼び出す関数を渡します.真実はparser 文字演算子ではなく演算子のインデックスを渡す方が良いでしょう.これにより、呼び出し方法を決定することが容易になります.後でパーザを議論して、実装します.
# backend.py
class Backend:

    ...

    def eval(self):
        # the operator is passed as int from the parser
        # this is the index of the operation needed
        operations = [self.add, self.subt,
            self.mult, self.exp, self.div, self.mod]
        operation = operations[self.operator]

        return operation()

パーサ
我々は演算子に基づいて呼び出す機能を知っているが、どのように我々はそれを行うつもりですか?パーザが必要であるとしましょう.このパーサーの仕事は、入力を中断することです.また、このパーサを使用して、渡される間違ったデータをキャッチします.演算子だけを文字列とオペランドにする必要があります.パーサの機能は以下の通りです.
  • paramsに3つの値があるかどうかを確認する
  • paramsの最初の値が演算子であるかどうかを確認する
  • paramsの2番目と3番目の値がfloat型か整数型かをチェックする
  • paramsの2番目と3番目の値を第1オペランドと第2オペランドとする
  • ゼロ分割エラーチェック
  • 値エラーチェック
  • 演算子は
  • 演算子文字の代わりに演算子のインデックスを渡します
  • 例外を送出し、エラーが発生したときに終了する
  • 解析された値を返す
  • パーサをメソッドとして追加するかどうかを議論できますArithmetic class またはスタンドアロン機能を確認します.クラスのメソッドよりパーサを関数にするには、調整せずに簡単です.私はそれができると思う.あなたはどう思いますか.
    # parser.py
    # data from the CLI is a list - params
    # the parser shall also return a list if the parsing
    # was successful else raise an error and exit with an
    # error message
    
    import sys
    
    # destructure param
    # operator, first operand, second operand = param
    
    
    def parser(params=[]):
        operators = ['+', '-', '*', '**', '/', '%']
    
        # an operand can only be  `int` or `float`
        operand_types = [int, float]
    
        try:
            # only 3 parameters are needed
            if len(params) != 3:
                message = "In essence, an operator and two number"
                message += " operands are required. Eg: + 2 4.6"
                raise ValueError(message)
    
            if not params[0] in operators:
                raise ValueError(f"Unknown operator, choose from {operators}")
    
            if (type(params[1]) in operand_types and
                    type(params[2]) in operand_types):
                raise ValueError(f"A number is required as operand")
    
            parsed_params = [params[0], float(params[1]), float(params[2])]
    
            if parsed_params[0] in operators[4:] and parsed_params[2] == 0:
                message = "None zero second operand is required for division"
                raise ZeroDivisionError(message)
    
            # pass the index of the operator rather than the character
            # we shall use the index to easily determine the operation
            # to call using few or not if statements
            parsed_params[0] = operators.index(parsed_params[0])
    
        except Exception as err_message:
            print(err_message)
            sys.exit()
    
        return parsed_params
    
    
    

    アプリ
    フロントエンドはCLIと関係があります.今、我々はCLIをバックエンドに接続します.ファイルを作成するapp.py . このファイルでは、CLIから入力を取り出し、解析したパーサ関数を使用し、バックエンドを呼び出して評価します.最後に、結果を画面に出力します.
    # app.py
    import sys
    from parser import parser
    from backend import Backend
    
    
    if __name__ == "__main__":
    
        # sys.argv[0] is the file - app.py
        params = parser(sys.argv[1:])
    
        app = Backend(params)
        print(app.eval())
    
    常に最初の要素sys.argv がファイルである.ここで行ったことは、リスト( sys . argv )を2番目の要素からスライスし、パーサをパースします.バックエンドインスタンスを作成し、parsed paramsを渡し、eval ()を呼び出します.

    完全なコードとサンプル出力

    バックエンド
    # backend.py
    class Backend:
    
        def __init__(self, params):
            self.operator, self.operand1, self.operand2 = params
    
        def add(self):
            return self.operand1 + self.operand2
    
        def mult(self):
            return self.operand1 * self.operand2
    
        def subt(self):
            return self.operand1 - self.operand2
    
        def div(self):
            return self.operand1 / self.operand2
    
        def mod(self):
            return self.operand1 % self.operand2
    
        def exp(self):
            return self.operand1 ** self.operand2
    
        def eval(self):
            # the operator is passed as int from the parser
            # this is the index of the operation needed
            operations = [self.add, self.subt,
                          self.mult, self.exp, self.div, self.mod]
            operation = operations[self.operator]
    
            return operation()
    

    パーサー
    # parser.py
    # data from the CLI is a list - params
    # the parser shall also return a list if the parsing
    # was successful else raise an error and exit with an
    # error message
    
    import sys
    
    # destructure param
    # operator, first operand, second operand = param
    
    
    def parser(params=[]):
        operators = ['+', '-', '*', '**', '/', '%']
    
        # an operand can only be `int` or `float`
        operand_types = [int, float]
    
        try:
            # only 3 parameters are needed
            if len(params) != 3:
                message = "In essence, an operator and two number"
                message += " operands are required. Eg: + 2 4.6"
                raise ValueError(message)
    
            if not params[0] in operators:
                raise ValueError(f"Unknown operator, choose from {operators}")
    
            if (type(params[1]) in operand_types and
                    type(params[2]) in operand_types):
                raise ValueError(f"A number is required as operand")
    
            parsed_params = [params[0], float(params[1]), float(params[2])]
    
            if parsed_params[0] in operators[4:] and parsed_params[2] == 0:
                message = "None zero second operand is required for division"
                raise ZeroDivisionError(message)
    
            # pass the index of the operator rather than the character
            # we shall use the index to easily determine the operation
            # to call using few or not if statements
            parsed_params[0] = operators.index(parsed_params[0])
    
        except Exception as err_message:
            print(err_message)
            sys.exit()
    
        return parsed_params
    

    フロントエンド
    # app.py
    import sys
    from parser import parser
    from backend import Backend
    
    
    if __name__ == "__main__":
    
        # sys.argv[0] is the file - app.py
        params = parser(sys.argv[1:])
    
        app = Backend(params)
        print(app.eval())
    

    サンプル出力
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py
    In essence, an operator and two number operands are required. Eg: + 2 4.6
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py  + 23 56
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py  + 23 56
    79.0
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py  + 23
    In essence, an operator and two number operands are required. Eg: + 2 4.6
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py  + 23 0
    23.0
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py  / 23 0
    None zero second operand is required for division
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py  % 23 0
    None zero second operand is required for division
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py + 2 4
    6.0
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py - -3 5
    -8.0
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py ** -3 5
    In essence, an operator and two number operands are required. Eg: + 2 4.6
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py '**' -3 5
    -243.0
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py % -3 5
    2.0
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py / 22 7
    3.142857142857143
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py // 22 7
    Unknown operator, choose from ['+', '-', '*', '**', '/', '%']
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py // 22
    In essence, an operator and two number operands are required. Eg: + 2 4.6
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py /+ 22
    In essence, an operator and two number operands are required. Eg: + 2 4.6
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py + 3 5 7
    In essence, an operator and two number operands are required. Eg: + 2 4.6
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py *5 7
    In essence, an operator and two number operands are required. Eg: + 2 4.6
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py * 5 7
    In essence, an operator and two number operands are required. Eg: + 2 4.6
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py '*' 5 7
    35.0
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$ python3 app.py \* 5 7
    35.0
    otumian@monkey-tail:~/Projects/Clirithmetic-oe$
    

    ソース
  • python-doc
  • Clirithmetic

  • 結論
    clirithmeticはCLIでバイナリ演算を行います.CLIからとられるデータは解析されて、バックエンドコードによって評価されます.いくつかをスキップした例があったif statements 代わりに演算子のインデックスを演算子文字の代わりに渡します.代わりに例外を送出し、デフォルトメッセージに依存するよりもむしろ例外メッセージにカスタムメッセージを渡しました.サンプル出力では、/, %, *, ** 必要なエスケープ.我々は、代わりに引用符で置くことができます.clirithmeticはCLIから値を渡す方法とこれらの値を使用する方法を教えるためのものでした.clirithmeticの高度なバージョンは、計算のためのメモリとしてデータベースを使用する場所です.clirithmeticはバイナリ操作に制限されて、複数のオペランドを受け入れるために拡大されることができます.グッドラック、ハッキングと任意の提案や評論家は歓迎です.